1077 lines
32 KiB
C
1077 lines
32 KiB
C
|
|
/***************************************************************************
|
|
*
|
|
Copyright 2013 CertiVox UK Ltd. *
|
|
*
|
|
This file is part of CertiVox MIRACL Crypto SDK. *
|
|
*
|
|
The CertiVox MIRACL Crypto SDK provides developers with an *
|
|
extensive and efficient set of cryptographic functions. *
|
|
For further information about its features and functionalities please *
|
|
refer to http://www.certivox.com *
|
|
*
|
|
* The CertiVox MIRACL Crypto SDK is free software: you can *
|
|
redistribute it and/or modify it under the terms of the *
|
|
GNU Affero General Public License as published by the *
|
|
Free Software Foundation, either version 3 of the License, *
|
|
or (at your option) any later version. *
|
|
*
|
|
* The CertiVox MIRACL Crypto SDK is distributed in the hope *
|
|
that it will be useful, but WITHOUT ANY WARRANTY; without even the *
|
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
See the GNU Affero General Public License for more details. *
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public *
|
|
License along with CertiVox MIRACL Crypto SDK. *
|
|
If not, see <http://www.gnu.org/licenses/>. *
|
|
*
|
|
You can be released from the requirements of the license by purchasing *
|
|
a commercial license. Buying such a license is mandatory as soon as you *
|
|
develop commercial activities involving the CertiVox MIRACL Crypto SDK *
|
|
without disclosing the source code of your own applications, or shipping *
|
|
the CertiVox MIRACL Crypto SDK with a closed source product. *
|
|
*
|
|
***************************************************************************/
|
|
/* mex.c
|
|
*
|
|
* Updated to allow emission of scheduled code.
|
|
*
|
|
* Macro EXpansion program.
|
|
* Expands Macros from a .mcs file into a .tpl file to create a .c file
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef int BOOL;
|
|
#define FALSE 0
|
|
#define TRUE 1
|
|
|
|
/* Define Algorithms */
|
|
|
|
#define MULTIPLY 0
|
|
#define MULTUP 1
|
|
#define SQUARE 2
|
|
#define REDC 3
|
|
#define ADDITION 4
|
|
#define INCREMENT 5
|
|
#define SUBTRACTION 6
|
|
#define DECREMENT 7
|
|
#define SUMMATION 8
|
|
#define INCREMENTATION 9
|
|
#define DECREMENTATION 10
|
|
#define MULTIPLY2 11
|
|
#define ADDITION2 12
|
|
#define SUBTRACTION2 13
|
|
#define PMULT 14
|
|
#define DOUBLEIT 15
|
|
|
|
|
|
/* Define Macros */
|
|
|
|
#define MUL_START 0
|
|
#define STEP 1
|
|
#define STEP1M 2
|
|
#define STEP1A 3
|
|
#define STEP2M 4
|
|
#define STEP2A 5
|
|
#define MFIN 6
|
|
#define MUL_END 7
|
|
#define LAST 8
|
|
#define SQR_START 9
|
|
#define DSTEP 10
|
|
#define DSTEP1M 11
|
|
#define DSTEP1A 12
|
|
#define DSTEP2M 13
|
|
#define DSTEP2A 14
|
|
#define SELF 15
|
|
#define SFIN 16
|
|
#define SQR_END 17
|
|
#define REDC_START 18
|
|
#define RFINU 19
|
|
#define RFIND 20
|
|
#define REDC_END 21
|
|
#define ADD_START 22
|
|
#define ADD 23
|
|
#define ADD_END 24
|
|
#define SUB_START 25
|
|
#define SUB 26
|
|
#define SUB_END 27
|
|
#define INC_START 28
|
|
#define INC 29
|
|
#define INC_END 30
|
|
#define DEC_START 31
|
|
#define DEC 32
|
|
#define DEC_END 33
|
|
#define KADD_START 34
|
|
#define KASL 35
|
|
#define KADD_END 36
|
|
#define KINC_START 37
|
|
#define KIDL 38
|
|
#define KINC_END 39
|
|
#define KDEC_START 40
|
|
#define KDEC_END 41
|
|
#define STEPB 42
|
|
#define STEPB1M 43
|
|
#define STEPB1A 44
|
|
#define STEPB2M 45
|
|
#define STEPB2A 46
|
|
#define H2_MUL_START 47
|
|
#define H2_STEP 48
|
|
#define H2_MFIN 49
|
|
#define H2_MUL_END 50
|
|
#define H2_SQR_START 51
|
|
#define H2_DSTEP 52
|
|
#define H2_SELF 53
|
|
#define H2_SFIN 54
|
|
#define H2_SQR_END 55
|
|
#define H4_MUL_START 56
|
|
#define H4_STEP 57
|
|
#define H4_MFIN 58
|
|
#define H4_MUL_END 59
|
|
#define H4_SQR_START 60
|
|
#define H4_DSTEP 61
|
|
#define H4_SELF 62
|
|
#define H4_SFIN 63
|
|
#define H4_SQR_END 64
|
|
#define H2_LAST 65
|
|
#define H4_LAST 66
|
|
#define PMUL_START 67
|
|
#define PMUL 68
|
|
#define PMUL_END 69
|
|
#define MULB_START 70
|
|
#define MULB_END 71
|
|
#define MBFIN 72
|
|
#define H2_MULB_START 73
|
|
#define H2_MULB_END 74
|
|
#define H2_MBFIN 75
|
|
#define H2_STEPB 76
|
|
#define H4_MULB_START 77
|
|
#define H4_MULB_END 78
|
|
#define H4_MBFIN 79
|
|
#define H4_STEPB 80
|
|
#define H2_REDC_START 81
|
|
#define H2_RFINU 82
|
|
#define H2_RFIND 83
|
|
#define H2_REDC_END 84
|
|
#define H4_REDC_START 85
|
|
#define H4_RFINU 86
|
|
#define H4_RFIND 87
|
|
#define H4_REDC_END 88
|
|
#define DOUBLE_START 89
|
|
#define DOUBLE 90
|
|
#define DOUBLE_END 91
|
|
#define LAST_ONE 92
|
|
|
|
BOOL scheduled;
|
|
int hybrid,hybrid_b,pmp,hybrid_r;
|
|
|
|
int PARAM;
|
|
char *macro[LAST_ONE]; /* macro text */
|
|
|
|
char *functions[]={(char *)"MULTIPLY",(char *)"MULTUP",(char *)"SQUARE",(char *)"REDC",(char *)"ADDITION",(char *)"INCREMENT",
|
|
(char *)"SUBTRACTION",(char *)"DECREMENT",(char *)"SUMMATION",(char *)"INCREMENTATION",
|
|
(char *)"DECREMENTATION",(char *)"MULTIPLY2",(char *)"ADDITION2",(char *)"SUBTRACTION2",(char *)"PMULT",(char *)"DOUBLEIT",NULL};
|
|
|
|
char *names[]={(char *)"MUL_START",(char *)"STEP",(char *)"STEP1M",(char *)"STEP1A",(char *)"STEP2M",
|
|
(char *)"STEP2A",(char *)"MFIN",(char *)"MUL_END",(char *)"LAST",(char *)"SQR_START",(char *)"DSTEP",
|
|
(char *)"DSTEP1M",(char *)"DSTEP1A",(char *)"DSTEP2M",(char *)"DSTEP2A",(char *)"SELF",
|
|
(char *)"SFIN",(char *)"SQR_END",(char *)"REDC_START",(char *)"RFINU",(char *)"RFIND",
|
|
(char *)"REDC_END",(char *)"ADD_START",(char *)"ADD",(char *)"ADD_END",(char *)"SUB_START",(char *)"SUB",
|
|
(char *)"SUB_END",(char *)"INC_START",(char *)"INC",(char *)"INC_END",(char *)"DEC_START",(char *)"DEC",
|
|
(char *)"DEC_END",(char *)"KADD_START",(char *)"KASL",(char *)"KADD_END",(char *)"KINC_START",(char *)"KIDL",
|
|
(char *)"KINC_END",(char *)"KDEC_START",(char *)"KDEC_END",(char *)"STEPB",(char *)"STEPB1M",(char *)"STEPB1A",(char *)"STEPB2M",(char *)"STEPB2A",
|
|
(char *)"H2_MUL_START",(char *)"H2_STEP",(char *)"H2_MFIN",(char *)"H2_MUL_END",
|
|
(char *)"H2_SQR_START",(char *)"H2_DSTEP",(char *)"H2_SELF",(char *)"H2_SFIN",(char *)"H2_SQR_END",
|
|
(char *)"H4_MUL_START",(char *)"H4_STEP",(char *)"H4_MFIN",(char *)"H4_MUL_END",
|
|
(char *)"H4_SQR_START",(char *)"H4_DSTEP",(char *)"H4_SELF",(char *)"H4_SFIN",(char *)"H4_SQR_END",(char *)"H2_LAST",(char *)"H4_LAST",
|
|
(char *)"PMUL_START",(char *)"PMUL",(char *)"PMUL_END",(char *)"MULB_START",(char *)"MULB_END",(char *)"MBFIN",
|
|
(char *)"H2_MULB_START",(char *)"H2_MULB_END",(char *)"H2_MBFIN",(char *)"H2_STEPB",
|
|
(char *)"H4_MULB_START",(char *)"H4_MULB_END",(char *)"H4_MBFIN",(char *)"H4_STEPB",
|
|
(char *)"H2_REDC_START",(char *)"H2_RFINU",(char *)"H2_RFIND",(char *)"H2_REDC_END",
|
|
(char *)"H4_REDC_START",(char *)"H4_RFINU",(char *)"H4_RFIND",(char *)"H4_REDC_END",
|
|
(char *)"DOUBLE_START",(char *)"DOUBLE",(char *)"DOUBLE_END",NULL};
|
|
|
|
BOOL white(char c)
|
|
{
|
|
if (c==' ' || c=='\n' || c=='\r' || c=='\t') return TRUE;
|
|
else return FALSE;
|
|
}
|
|
|
|
int skip(char *c,int i)
|
|
{
|
|
while (white(c[i])) i++;
|
|
return i;
|
|
}
|
|
|
|
int which(char *name,char *names[])
|
|
{
|
|
int ipt=0;
|
|
while (names[ipt]!=NULL)
|
|
{
|
|
if (strcmp(name,names[ipt])==0) return ipt;
|
|
ipt++;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void m_prologue(FILE *dotc,int k,int m)
|
|
{
|
|
fprintf(dotc,macro[STEP1M],k,m);
|
|
}
|
|
|
|
void m_epilogue(FILE *dotc,int x)
|
|
{
|
|
if (x==1) fprintf(dotc,macro[STEP1A]);
|
|
else fprintf(dotc,macro[STEP2A]);
|
|
}
|
|
|
|
void m_schedule(FILE *dotc,int x,int k,int m)
|
|
{
|
|
if (x==1)
|
|
{
|
|
fprintf(dotc,macro[STEP2M],k,m);
|
|
fprintf(dotc,macro[STEP1A]);
|
|
}
|
|
else
|
|
{
|
|
fprintf(dotc,macro[STEP1M],k,m);
|
|
fprintf(dotc,macro[STEP2A]);
|
|
}
|
|
}
|
|
|
|
void m_prologue2(FILE *dotc,int k,int m)
|
|
{
|
|
fprintf(dotc,macro[STEPB1M],k,m);
|
|
}
|
|
|
|
void m_epilogue2(FILE *dotc,int x)
|
|
{
|
|
if (x==1) fprintf(dotc,macro[STEPB1A]);
|
|
else fprintf(dotc,macro[STEPB2A]);
|
|
}
|
|
|
|
void m_schedule2(FILE *dotc,int x,int k,int m)
|
|
{
|
|
if (x==1)
|
|
{
|
|
fprintf(dotc,macro[STEPB2M],k,m);
|
|
fprintf(dotc,macro[STEPB1A]);
|
|
}
|
|
else
|
|
{
|
|
fprintf(dotc,macro[STEPB1M],k,m);
|
|
fprintf(dotc,macro[STEPB2A]);
|
|
}
|
|
}
|
|
|
|
void s_prologue(FILE *dotc,int k,int m)
|
|
{
|
|
fprintf(dotc,macro[DSTEP1M],k,m);
|
|
}
|
|
|
|
void s_epilogue(FILE *dotc,int x)
|
|
{
|
|
if (x==1) fprintf(dotc,macro[DSTEP1A]);
|
|
else fprintf(dotc,macro[DSTEP2A]);
|
|
}
|
|
|
|
void s_schedule(FILE *dotc,int x,int k,int m)
|
|
{
|
|
if (x==1)
|
|
{
|
|
fprintf(dotc,macro[DSTEP2M],k,m);
|
|
fprintf(dotc,macro[DSTEP1A]);
|
|
}
|
|
else
|
|
{
|
|
fprintf(dotc,macro[DSTEP1M],k,m);
|
|
fprintf(dotc,macro[DSTEP2A]);
|
|
}
|
|
}
|
|
|
|
/* Insert functions into template file */
|
|
|
|
void insert(int index,FILE *dotc)
|
|
{
|
|
int i,k,m,n,x,inc;
|
|
switch (index)
|
|
{
|
|
case PMULT:
|
|
if (!pmp) break;
|
|
fprintf(dotc,macro[PMUL_START]);
|
|
for (i=0;i<PARAM;i++)
|
|
{
|
|
fprintf(dotc,macro[PMUL],i,i,i);
|
|
}
|
|
fprintf(dotc,macro[PMUL_END]);
|
|
break;
|
|
case MULTIPLY2:
|
|
inc=1;
|
|
if (hybrid_b)
|
|
{
|
|
inc=hybrid_b;
|
|
if (hybrid_b==2) fprintf(dotc,macro[H2_MULB_START]);
|
|
if (hybrid_b==4) fprintf(dotc,macro[H4_MULB_START]);
|
|
}
|
|
else fprintf(dotc,macro[MULB_START]);
|
|
for (i=n=0;i<PARAM;i+=inc,n+=inc)
|
|
{
|
|
k=0; m=i;
|
|
if (scheduled)
|
|
{
|
|
x=1;
|
|
m_prologue2(dotc,k,m);
|
|
k++; m--;
|
|
|
|
while (k<=i)
|
|
{
|
|
m_schedule2(dotc,x,k,m);
|
|
k++; m--;
|
|
x=3-x;
|
|
}
|
|
|
|
m_epilogue2(dotc,x);
|
|
|
|
}
|
|
else
|
|
{
|
|
while (k<=i)
|
|
{
|
|
if (hybrid_b)
|
|
{
|
|
if (hybrid_b==2) fprintf(dotc,macro[H2_STEPB],k,k,m,m);
|
|
if (hybrid_b==4) fprintf(dotc,macro[H4_STEPB],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[STEPB],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
|
|
}
|
|
if (hybrid_b)
|
|
{
|
|
if (hybrid_b==2) fprintf(dotc,macro[H2_MBFIN],n,n+1);
|
|
if (hybrid_b==4) fprintf(dotc,macro[H4_MBFIN],n,n+1,n+2,n+3);
|
|
}
|
|
else fprintf(dotc,macro[MBFIN],n);
|
|
|
|
}
|
|
for (i=0;i<PARAM-inc;i+=inc,n+=inc)
|
|
{
|
|
k=i+inc; m=PARAM-inc;
|
|
if (scheduled)
|
|
{
|
|
x=1;
|
|
m_prologue2(dotc,k,m);
|
|
k++; m--;
|
|
|
|
while (k<=PARAM-1)
|
|
{
|
|
m_schedule2(dotc,x,k,m);
|
|
k++; m--;
|
|
x=3-x;
|
|
}
|
|
m_epilogue2(dotc,x);
|
|
}
|
|
else
|
|
{
|
|
while (k<=PARAM-inc)
|
|
{
|
|
if (hybrid_b)
|
|
{
|
|
if (hybrid_b==2) fprintf(dotc,macro[H2_STEPB],k,k,m,m);
|
|
if (hybrid_b==4) fprintf(dotc,macro[H4_STEPB],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[STEPB],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
}
|
|
if (hybrid_b)
|
|
{
|
|
if (hybrid_b==2) fprintf(dotc,macro[H2_MBFIN],n,n+1);
|
|
if (hybrid_b==4) fprintf(dotc,macro[H4_MBFIN],n,n+1,n+2,n+3);
|
|
}
|
|
else fprintf(dotc,macro[MBFIN],n);
|
|
|
|
}
|
|
|
|
if (hybrid_b)
|
|
{
|
|
if (hybrid_b==2) fprintf(dotc,macro[H2_MULB_END],2*PARAM-2);
|
|
if (hybrid_b==4) fprintf(dotc,macro[H4_MULB_END],2*PARAM-4,2*PARAM-3,2*PARAM-2);
|
|
}
|
|
else fprintf(dotc,macro[MULB_END]);
|
|
break;
|
|
case MULTIPLY:
|
|
inc=1;
|
|
if (hybrid)
|
|
{
|
|
inc=hybrid;
|
|
if (hybrid==2) fprintf(dotc,macro[H2_MUL_START]);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_MUL_START]);
|
|
}
|
|
else fprintf(dotc,macro[MUL_START]);
|
|
for (i=n=0;i<PARAM;i+=inc,n+=inc)
|
|
{
|
|
k=0; m=i;
|
|
|
|
if (scheduled)
|
|
{
|
|
x=1;
|
|
m_prologue(dotc,k,m);
|
|
k++; m--;
|
|
|
|
while (k<=i)
|
|
{
|
|
m_schedule(dotc,x,k,m);
|
|
k++; m--;
|
|
x=3-x;
|
|
}
|
|
|
|
m_epilogue(dotc,x);
|
|
|
|
}
|
|
else
|
|
{
|
|
while (k<=i)
|
|
{
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[STEP],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
}
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_MFIN],n,n+1);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_MFIN],n,n+1,n+2,n+3);
|
|
}
|
|
else fprintf(dotc,macro[MFIN],n);
|
|
}
|
|
for (i=0;i<PARAM-inc;i+=inc,n+=inc)
|
|
{
|
|
k=i+inc; m=PARAM-inc;
|
|
|
|
if (scheduled)
|
|
{
|
|
x=1;
|
|
m_prologue(dotc,k,m);
|
|
k++; m--;
|
|
|
|
while (k<=PARAM-1)
|
|
{
|
|
m_schedule(dotc,x,k,m);
|
|
k++; m--;
|
|
x=3-x;
|
|
}
|
|
m_epilogue(dotc,x);
|
|
}
|
|
else
|
|
{
|
|
while (k<=PARAM-inc)
|
|
{
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[STEP],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
}
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_MFIN],n,n+1);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_MFIN],n,n+1,n+2,n+3);
|
|
}
|
|
else fprintf(dotc,macro[MFIN],n);
|
|
}
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_MUL_END],2*PARAM-2,2*PARAM-1);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_MUL_END],2*PARAM-4,2*PARAM-3,2*PARAM-2,2*PARAM-1);
|
|
}
|
|
else fprintf(dotc,macro[MUL_END],2*PARAM-1);
|
|
break;
|
|
case MULTUP:
|
|
inc=1;
|
|
if (hybrid)
|
|
{
|
|
inc=hybrid;
|
|
if (hybrid==2) fprintf(dotc,macro[H2_MUL_START]);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_MUL_START]);
|
|
}
|
|
else fprintf(dotc,macro[MUL_START]);
|
|
|
|
for (i=n=0;i<PARAM-inc;i+=inc,n+=inc)
|
|
{
|
|
k=0; m=i;
|
|
|
|
if (scheduled)
|
|
{
|
|
x=1;
|
|
m_prologue(dotc,k,m);
|
|
k++; m--;
|
|
|
|
while (k<=i)
|
|
{
|
|
m_schedule(dotc,x,k,m);
|
|
k++; m--;
|
|
x=3-x;
|
|
}
|
|
m_epilogue(dotc,x);
|
|
}
|
|
else
|
|
{
|
|
while (k<=i)
|
|
{
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[STEP],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
}
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_MFIN],n,n+1);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_MFIN],n,n+1,n+2,n+3);
|
|
}
|
|
else fprintf(dotc,macro[MFIN],n);
|
|
}
|
|
k=0; m=PARAM-inc;
|
|
while (k<=i)
|
|
{
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_LAST],k,k,m,m);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_LAST],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[LAST],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_MUL_END],PARAM-2,PARAM-1);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_MUL_END],PARAM-4,PARAM-3,PARAM-2,PARAM-1);
|
|
}
|
|
else fprintf(dotc,macro[MUL_END],PARAM-1);
|
|
break;
|
|
case SQUARE:
|
|
inc=1;
|
|
if (hybrid)
|
|
{
|
|
inc=hybrid;
|
|
if (hybrid==2) fprintf(dotc,macro[H2_SQR_START]);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_SQR_START]);
|
|
}
|
|
else fprintf(dotc,macro[SQR_START]);
|
|
for (i=n=0;i<PARAM;i+=inc,n+=inc)
|
|
{
|
|
k=0; m=i;
|
|
|
|
if (scheduled)
|
|
{
|
|
if (k<m)
|
|
{
|
|
x=1;
|
|
s_prologue(dotc,k,m);
|
|
k++; m--;
|
|
|
|
while (k<m)
|
|
{
|
|
s_schedule(dotc,x,k,m);
|
|
k++; m--;
|
|
x=3-x;
|
|
}
|
|
s_epilogue(dotc,x);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (k<m)
|
|
{
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_DSTEP],k,k,m,m);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_DSTEP],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[DSTEP],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
}
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2 && n%4==0) fprintf(dotc,macro[H2_SELF],n/2,n/2);
|
|
if (hybrid==4 && n%8==0) fprintf(dotc,macro[H4_SELF],n/2,n/2,n/2,n/2);
|
|
}
|
|
else
|
|
{
|
|
if (n%2==0) fprintf(dotc,macro[SELF],n/2,n/2);
|
|
}
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_SFIN],n,n+1);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_SFIN],n,n+1,n+2,n+3);
|
|
}
|
|
else fprintf(dotc,macro[SFIN],n);
|
|
}
|
|
for (i=0;i<PARAM-inc;i+=inc,n+=inc)
|
|
{
|
|
k=i+inc; m=PARAM-inc;
|
|
|
|
if (scheduled)
|
|
{
|
|
if (k<m)
|
|
{
|
|
x=1;
|
|
s_prologue(dotc,k,m);
|
|
k++; m--;
|
|
|
|
while (k<m)
|
|
{
|
|
s_schedule(dotc,x,k,m);
|
|
k++; m--;
|
|
x=3-x;
|
|
}
|
|
s_epilogue(dotc,x);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (k<m)
|
|
{
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_DSTEP],k,k,m,m);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_DSTEP],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[DSTEP],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
}
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2 && n%4==0) fprintf(dotc,macro[H2_SELF],n/2,n/2);
|
|
if (hybrid==4 && n%8==0) fprintf(dotc,macro[H4_SELF],n/2,n/2,n/2,n/2);
|
|
}
|
|
else
|
|
{
|
|
if (n%2==0) fprintf(dotc,macro[SELF],n/2,n/2);
|
|
}
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_SFIN],n,n+1);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_SFIN],n,n+1,n+2,n+3);
|
|
}
|
|
else fprintf(dotc,macro[SFIN],n);
|
|
}
|
|
if (hybrid)
|
|
{
|
|
if (hybrid==2) fprintf(dotc,macro[H2_SQR_END],2*PARAM-2,2*PARAM-1);
|
|
if (hybrid==4) fprintf(dotc,macro[H4_SQR_END],2*PARAM-4,2*PARAM-3,2*PARAM-2,2*PARAM-1);
|
|
}
|
|
else fprintf(dotc,macro[SQR_END],2*PARAM-1);
|
|
break;
|
|
case REDC:
|
|
inc=1;
|
|
if (hybrid_r)
|
|
{
|
|
inc=hybrid_r;
|
|
if (hybrid_r==2)
|
|
{
|
|
fprintf(dotc,macro[H2_REDC_START]);
|
|
fprintf(dotc,macro[H2_RFINU],0,0,0,0);
|
|
}
|
|
if (hybrid_r==4)
|
|
{
|
|
fprintf(dotc,macro[H4_REDC_START]);
|
|
fprintf(dotc,macro[H4_RFINU],0,0,0,0,0,0,0,0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf(dotc,macro[REDC_START]);
|
|
fprintf(dotc,macro[RFINU],0,0);
|
|
}
|
|
|
|
for (i=n=inc;i<PARAM;i+=inc,n+=inc)
|
|
{
|
|
k=0; m=i;
|
|
|
|
if (scheduled)
|
|
{
|
|
x=1;
|
|
m_prologue(dotc,k,m);
|
|
k++; m--;
|
|
|
|
while (k<i)
|
|
{
|
|
m_schedule(dotc,x,k,m);
|
|
k++; m--;
|
|
x=3-x;
|
|
}
|
|
m_epilogue(dotc,x);
|
|
}
|
|
else
|
|
{
|
|
while (k<i)
|
|
{
|
|
if (hybrid_r)
|
|
{
|
|
if (hybrid_r==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
|
|
if (hybrid_r==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[STEP],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
}
|
|
|
|
if (hybrid_r)
|
|
{
|
|
if (hybrid_r==2) fprintf(dotc,macro[H2_RFINU],n,n,n,n);
|
|
if (hybrid_r==4) fprintf(dotc,macro[H4_RFINU],n,n,n,n,n,n,n,n);
|
|
}
|
|
else fprintf(dotc,macro[RFINU],n,n);
|
|
}
|
|
|
|
for (i=0;i<PARAM-inc;i+=inc,n+=inc)
|
|
{
|
|
k=i+inc; m=PARAM-inc;
|
|
|
|
if (scheduled)
|
|
{
|
|
x=1;
|
|
m_prologue(dotc,k,m);
|
|
k++; m--;
|
|
|
|
while (k<=PARAM-1)
|
|
{
|
|
m_schedule(dotc,x,k,m);
|
|
k++; m--;
|
|
x=3-x;
|
|
}
|
|
m_epilogue(dotc,x);
|
|
}
|
|
else
|
|
{
|
|
while (k<=PARAM-inc)
|
|
{
|
|
if (hybrid_r)
|
|
{
|
|
if (hybrid_r==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
|
|
if (hybrid_r==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
|
|
}
|
|
else fprintf(dotc,macro[STEP],k,m);
|
|
k+=inc; m-=inc;
|
|
}
|
|
}
|
|
|
|
if (hybrid_r)
|
|
{
|
|
if (hybrid_r==2) fprintf(dotc,macro[H2_RFIND],n,n,n,n);
|
|
if (hybrid_r==4) fprintf(dotc,macro[H4_RFIND],n,n,n,n,n,n,n,n);
|
|
}
|
|
else fprintf(dotc,macro[RFIND],n,n);
|
|
}
|
|
if (hybrid_r)
|
|
{
|
|
if (hybrid_r==2) fprintf(dotc,macro[H2_REDC_END],2*PARAM-inc,2*PARAM-inc,2*PARAM-inc);
|
|
if (hybrid_r==4) fprintf(dotc,macro[H4_REDC_END],2*PARAM-inc,2*PARAM-inc,2*PARAM-inc,2*PARAM-inc,2*PARAM-inc);
|
|
}
|
|
else fprintf(dotc,macro[REDC_END],2*PARAM-1,2*PARAM-1);
|
|
|
|
break;
|
|
|
|
case ADDITION:
|
|
fprintf(dotc,macro[ADD_START]);
|
|
for (i=1;i<PARAM;i++)
|
|
fprintf(dotc,macro[ADD],i,i,i);
|
|
fprintf(dotc,macro[ADD_END]);
|
|
break;
|
|
case ADDITION2:
|
|
fprintf(dotc,macro[ADD_START]);
|
|
for (i=1;i<2*PARAM;i++)
|
|
fprintf(dotc,macro[ADD],i,i,i);
|
|
fprintf(dotc,macro[ADD_END]);
|
|
break;
|
|
case INCREMENT:
|
|
fprintf(dotc,macro[INC_START]);
|
|
for (i=1;i<PARAM;i++)
|
|
fprintf(dotc,macro[INC],i,i,i);
|
|
fprintf(dotc,macro[INC_END]);
|
|
break;
|
|
case DOUBLEIT:
|
|
if (macro[DOUBLE_START]!=NULL)
|
|
{
|
|
fprintf(dotc,macro[DOUBLE_START]);
|
|
for (i=1;i<PARAM;i++)
|
|
fprintf(dotc,macro[DOUBLE],i,i);
|
|
fprintf(dotc,macro[DOUBLE_END]);
|
|
}
|
|
else
|
|
{
|
|
fprintf(dotc,macro[INC_START]);
|
|
for (i=1;i<PARAM;i++)
|
|
fprintf(dotc,macro[INC],i,i,i);
|
|
fprintf(dotc,macro[INC_END]);
|
|
}
|
|
break;
|
|
|
|
case SUBTRACTION:
|
|
fprintf(dotc,macro[SUB_START]);
|
|
for (i=1;i<PARAM;i++)
|
|
fprintf(dotc,macro[SUB],i,i,i);
|
|
fprintf(dotc,macro[SUB_END]);
|
|
break;
|
|
case SUBTRACTION2:
|
|
fprintf(dotc,macro[SUB_START]);
|
|
for (i=1;i<2*PARAM;i++)
|
|
fprintf(dotc,macro[SUB],i,i,i);
|
|
fprintf(dotc,macro[SUB_END]);
|
|
break;
|
|
case DECREMENT:
|
|
fprintf(dotc,macro[DEC_START]);
|
|
for (i=1;i<PARAM;i++)
|
|
fprintf(dotc,macro[DEC],i,i,i);
|
|
fprintf(dotc,macro[DEC_END]);
|
|
break;
|
|
case SUMMATION:
|
|
fprintf(dotc,macro[KADD_START],1);
|
|
for (i=0;i<PARAM;i++)
|
|
fprintf(dotc,macro[ADD],i,i,i);
|
|
fprintf(dotc,macro[KASL],2,PARAM,PARAM,PARAM,1,2);
|
|
fprintf(dotc,macro[KADD_END]);
|
|
break;
|
|
case INCREMENTATION:
|
|
fprintf(dotc,macro[KINC_START],3);
|
|
for (i=0;i<PARAM;i++)
|
|
fprintf(dotc,macro[INC],i,i,i);
|
|
fprintf(dotc,macro[KIDL],4,PARAM,PARAM,3,4);
|
|
fprintf(dotc,macro[KINC_END]);
|
|
break;
|
|
case DECREMENTATION:
|
|
fprintf(dotc,macro[KDEC_START],5);
|
|
for (i=0;i<PARAM;i++)
|
|
fprintf(dotc,macro[DEC],i,i,i);
|
|
fprintf(dotc,macro[KIDL],6,PARAM,PARAM,5,6);
|
|
fprintf(dotc,macro[KDEC_END]);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
int main(int argc,char **argv)
|
|
{
|
|
FILE *templat,*macros,*dotc;
|
|
int i,ip,ptr,index,size;
|
|
BOOL open,error;
|
|
char fname[80],tmpl[80],name[20];
|
|
char line[133];
|
|
argc--; argv++;
|
|
if (argc<3 || argc>4)
|
|
{
|
|
printf("Bad arguments\n");
|
|
printf("mex <parameter> <.mcs file> <.tpl file>\n");
|
|
printf("Use flag -s for scheduled code\n");
|
|
printf("Examples:\n");
|
|
printf("mex 6 ms86 mrcomba\n");
|
|
printf("mex -s 8 c mrkcm\n");
|
|
exit(0);
|
|
}
|
|
ip=0;
|
|
scheduled=FALSE;
|
|
if (strcmp(argv[0],"-s")==0)
|
|
{
|
|
ip=1;
|
|
scheduled=TRUE;
|
|
}
|
|
|
|
PARAM=atoi(argv[ip]);
|
|
if (PARAM<2 || PARAM>40)
|
|
{
|
|
printf("Invalid parameter\n");
|
|
exit(0);
|
|
}
|
|
strcpy(fname,argv[ip+1]);
|
|
strcat(fname,".mcs");
|
|
macros=fopen(fname,"rt");
|
|
if (macros==NULL)
|
|
{
|
|
printf("Macro file %s not found\n",fname);
|
|
exit(0);
|
|
}
|
|
|
|
strcpy(tmpl,argv[ip+2]);
|
|
strcat(tmpl,".tpl");
|
|
templat=fopen(tmpl,"rt");
|
|
if (templat==NULL)
|
|
{
|
|
printf("Template file %s file not found\n",tmpl);
|
|
exit(0);
|
|
}
|
|
strcpy(tmpl,argv[ip+2]);
|
|
strcat(tmpl,".c");
|
|
dotc=fopen(tmpl,"wt");
|
|
if (dotc==NULL)
|
|
{
|
|
printf("Unable to open %s for output\n",tmpl);
|
|
exit(0);
|
|
}
|
|
|
|
for (i=0;i<LAST_ONE;i++) macro[i]=NULL;
|
|
|
|
/* read in the macros - first pass to determine size and check for errors */
|
|
open=error=FALSE;
|
|
while (1)
|
|
{
|
|
if (fgets(line,132,macros)==NULL) break;
|
|
if (line[0]==';') continue;
|
|
|
|
if (!open && strncmp(line,"MACRO",5)==0)
|
|
{
|
|
open=TRUE;
|
|
ptr=6; i=0;
|
|
ptr=skip(line,ptr);
|
|
while (!white(line[ptr])) name[i++]=line[ptr++];
|
|
name[i]='\0';
|
|
index=which(name,names);
|
|
if (index<0)
|
|
{
|
|
error=TRUE;
|
|
break;
|
|
}
|
|
size=0;
|
|
continue;
|
|
}
|
|
if (open && strncmp(line,"ENDM",4)==0)
|
|
{
|
|
open=FALSE;
|
|
macro[index]=(char *)malloc(size+1);
|
|
macro[index][0]='\0';
|
|
}
|
|
|
|
if (open) size+=(int)strlen(line);
|
|
}
|
|
fclose(macros);
|
|
if (error)
|
|
{
|
|
printf("no such macro - %s\n",name);
|
|
exit(0);
|
|
}
|
|
|
|
/* read in the macros - second pass to store macros */
|
|
macros=fopen(fname,"rt");
|
|
while (1)
|
|
{
|
|
if (fgets(line,132,macros)==NULL) break;
|
|
if (line[0]==';') continue;
|
|
|
|
if (!open && strncmp(line,"MACRO",5)==0)
|
|
{
|
|
open=TRUE;
|
|
ptr=6; i=0;
|
|
ptr=skip(line,ptr);
|
|
while (!white(line[ptr])) name[i++]=line[ptr++];
|
|
name[i]='\0';
|
|
index=which(name,names);
|
|
continue;
|
|
}
|
|
if (open && strncmp(line,"ENDM",4)==0) open=FALSE;
|
|
|
|
if (open) strcat(macro[index],line);
|
|
}
|
|
fclose(macros);
|
|
|
|
if (macro[PMUL]==NULL)
|
|
{
|
|
/* printf("Pseudo Mersenne Primes not (yet) supported for this architecture in file %s\n",fname); */
|
|
pmp=0;
|
|
}
|
|
else pmp=1;
|
|
|
|
if (scheduled && macro[STEP1M]==NULL)
|
|
{
|
|
printf("Error - scheduling not supported in file %s\n",fname);
|
|
exit(0);
|
|
}
|
|
hybrid=0;
|
|
if (macro[H2_STEP]!=NULL) hybrid=2;
|
|
if (macro[H4_STEP]!=NULL) hybrid=4;
|
|
|
|
hybrid_b=0;
|
|
if (macro[H2_STEPB]!=NULL) hybrid_b=2;
|
|
if (macro[H4_STEPB]!=NULL) hybrid_b=4;
|
|
|
|
hybrid_r=0;
|
|
if (macro[H2_RFINU]!=NULL) hybrid_r=2;
|
|
if (macro[H4_RFINU]!=NULL) hybrid_r=4;
|
|
|
|
if (hybrid)
|
|
{
|
|
printf("Found hybrid macros - max step size = %d\n",hybrid);
|
|
if (PARAM%hybrid!=0)
|
|
{
|
|
printf("Warning - %d should be a multiple of %d for hybrid method\n",PARAM,hybrid);
|
|
hybrid=0;
|
|
}
|
|
}
|
|
|
|
if (hybrid_b)
|
|
{
|
|
printf("Found hybrid macros for binary case - max step size = %d\n",hybrid_b);
|
|
if (PARAM%hybrid_b!=0)
|
|
{
|
|
printf("Warning - %d should be a multiple of %d for hybrid method\n",PARAM,hybrid_b);
|
|
hybrid_b=0;
|
|
}
|
|
}
|
|
|
|
if ((scheduled && hybrid) || (scheduled && hybrid_b))
|
|
{
|
|
printf("Error - scheduling not supported in file %s\n",fname);
|
|
exit(0);
|
|
}
|
|
|
|
/* Insert macros into dotc file */
|
|
|
|
while (1)
|
|
{
|
|
if (fgets(line,132,templat)==NULL) break;
|
|
fputs(line,dotc);
|
|
if (strncmp(line,"/***",4)==0)
|
|
{
|
|
ptr=4; i=0;
|
|
ptr=skip(line,ptr);
|
|
while (!white(line[ptr])) name[i++]=line[ptr++];
|
|
name[i]='\0';
|
|
|
|
index=which(name,functions);
|
|
/* printf("Recognize %s index %d\n",name,index); */
|
|
if (index<0)
|
|
{
|
|
error=TRUE;
|
|
break;
|
|
}
|
|
insert(index,dotc);
|
|
}
|
|
}
|
|
|
|
if (error)
|
|
printf("no such function - %s\n",name);
|
|
|
|
fclose(templat);
|
|
fclose(dotc);
|
|
return 0;
|
|
}
|
|
|