1
2 /***************************************************************************
3 *
4 Copyright 2012 CertiVox IOM Ltd. *
5 *
6 This file is part of CertiVox MIRACL Crypto SDK. *
7 *
8 The CertiVox MIRACL Crypto SDK provides developers with an *
9 extensive and efficient set of cryptographic functions. *
10 For further information about its features and functionalities please *
11 refer to http://www.certivox.com *
12 *
13 * The CertiVox MIRACL Crypto SDK is free software: you can *
14 redistribute it and/or modify it under the terms of the *
15 GNU Affero General Public License as published by the *
16 Free Software Foundation, either version 3 of the License, *
17 or (at your option) any later version. *
18 *
19 * The CertiVox MIRACL Crypto SDK is distributed in the hope *
20 that it will be useful, but WITHOUT ANY WARRANTY; without even the *
21 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
22 See the GNU Affero General Public License for more details. *
23 *
24 * You should have received a copy of the GNU Affero General Public *
25 License along with CertiVox MIRACL Crypto SDK. *
26 If not, see <http://www.gnu.org/licenses/>. *
27 *
28 You can be released from the requirements of the license by purchasing *
29 a commercial license. Buying such a license is mandatory as soon as you *
30 develop commercial activities involving the CertiVox MIRACL Crypto SDK *
31 without disclosing the source code of your own applications, or shipping *
32 the CertiVox MIRACL Crypto SDK with a closed source product. *
33 *
34 ***************************************************************************/
35 /* mex.c
36 *
37 * Updated to allow emission of scheduled code.
38 *
39 * Macro EXpansion program.
40 * Expands Macros from a .mcs file into a .tpl file to create a .c file
41 *
42 */
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47
48 typedef int BOOL;
49 #define FALSE 0
50 #define TRUE 1
51
52 /* Define Algorithms */
53
54 #define MULTIPLY 0
55 #define MULTUP 1
56 #define SQUARE 2
57 #define REDC 3
58 #define ADDITION 4
59 #define INCREMENT 5
60 #define SUBTRACTION 6
61 #define DECREMENT 7
62 #define SUMMATION 8
63 #define INCREMENTATION 9
64 #define DECREMENTATION 10
65 #define MULTIPLY2 11
66 #define ADDITION2 12
67 #define SUBTRACTION2 13
68 #define PMULT 14
69 #define DOUBLEIT 15
70
71
72 /* Define Macros */
73
74 #define MUL_START 0
75 #define STEP 1
76 #define STEP1M 2
77 #define STEP1A 3
78 #define STEP2M 4
79 #define STEP2A 5
80 #define MFIN 6
81 #define MUL_END 7
82 #define LAST 8
83 #define SQR_START 9
84 #define DSTEP 10
85 #define DSTEP1M 11
86 #define DSTEP1A 12
87 #define DSTEP2M 13
88 #define DSTEP2A 14
89 #define SELF 15
90 #define SFIN 16
91 #define SQR_END 17
92 #define REDC_START 18
93 #define RFINU 19
94 #define RFIND 20
95 #define REDC_END 21
96 #define ADD_START 22
97 #define ADD 23
98 #define ADD_END 24
99 #define SUB_START 25
100 #define SUB 26
101 #define SUB_END 27
102 #define INC_START 28
103 #define INC 29
104 #define INC_END 30
105 #define DEC_START 31
106 #define DEC 32
107 #define DEC_END 33
108 #define KADD_START 34
109 #define KASL 35
110 #define KADD_END 36
111 #define KINC_START 37
112 #define KIDL 38
113 #define KINC_END 39
114 #define KDEC_START 40
115 #define KDEC_END 41
116 #define STEPB 42
117 #define STEPB1M 43
118 #define STEPB1A 44
119 #define STEPB2M 45
120 #define STEPB2A 46
121 #define H2_MUL_START 47
122 #define H2_STEP 48
123 #define H2_MFIN 49
124 #define H2_MUL_END 50
125 #define H2_SQR_START 51
126 #define H2_DSTEP 52
127 #define H2_SELF 53
128 #define H2_SFIN 54
129 #define H2_SQR_END 55
130 #define H4_MUL_START 56
131 #define H4_STEP 57
132 #define H4_MFIN 58
133 #define H4_MUL_END 59
134 #define H4_SQR_START 60
135 #define H4_DSTEP 61
136 #define H4_SELF 62
137 #define H4_SFIN 63
138 #define H4_SQR_END 64
139 #define H2_LAST 65
140 #define H4_LAST 66
141 #define PMUL_START 67
142 #define PMUL 68
143 #define PMUL_END 69
144 #define MULB_START 70
145 #define MULB_END 71
146 #define MBFIN 72
147 #define H2_MULB_START 73
148 #define H2_MULB_END 74
149 #define H2_MBFIN 75
150 #define H2_STEPB 76
151 #define H4_MULB_START 77
152 #define H4_MULB_END 78
153 #define H4_MBFIN 79
154 #define H4_STEPB 80
155 #define H2_REDC_START 81
156 #define H2_RFINU 82
157 #define H2_RFIND 83
158 #define H2_REDC_END 84
159 #define H4_REDC_START 85
160 #define H4_RFINU 86
161 #define H4_RFIND 87
162 #define H4_REDC_END 88
163 #define DOUBLE_START 89
164 #define DOUBLE 90
165 #define DOUBLE_END 91
166 #define LAST_ONE 92
167
168 BOOL scheduled;
169 int hybrid,hybrid_b,pmp,hybrid_r;
170
171 int PARAM;
172 char *macro[LAST_ONE]; /* macro text */
173
174 char *functions[]={(char *)"MULTIPLY",(char *)"MULTUP",(char *)"SQUARE",(char *)"REDC",(char *)"ADDITION",(char *)"INCREMENT",
175 (char *)"SUBTRACTION",(char *)"DECREMENT",(char *)"SUMMATION",(char *)"INCREMENTATION",
176 (char *)"DECREMENTATION",(char *)"MULTIPLY2",(char *)"ADDITION2",(char *)"SUBTRACTION2",(char *)"PMULT",(char *)"DOUBLEIT",NULL};
177
178 char *names[]={(char *)"MUL_START",(char *)"STEP",(char *)"STEP1M",(char *)"STEP1A",(char *)"STEP2M",
179 (char *)"STEP2A",(char *)"MFIN",(char *)"MUL_END",(char *)"LAST",(char *)"SQR_START",(char *)"DSTEP",
180 (char *)"DSTEP1M",(char *)"DSTEP1A",(char *)"DSTEP2M",(char *)"DSTEP2A",(char *)"SELF",
181 (char *)"SFIN",(char *)"SQR_END",(char *)"REDC_START",(char *)"RFINU",(char *)"RFIND",
182 (char *)"REDC_END",(char *)"ADD_START",(char *)"ADD",(char *)"ADD_END",(char *)"SUB_START",(char *)"SUB",
183 (char *)"SUB_END",(char *)"INC_START",(char *)"INC",(char *)"INC_END",(char *)"DEC_START",(char *)"DEC",
184 (char *)"DEC_END",(char *)"KADD_START",(char *)"KASL",(char *)"KADD_END",(char *)"KINC_START",(char *)"KIDL",
185 (char *)"KINC_END",(char *)"KDEC_START",(char *)"KDEC_END",(char *)"STEPB",(char *)"STEPB1M",(char *)"STEPB1A",(char *)"STEPB2M",(char *)"STEPB2A",
186 (char *)"H2_MUL_START",(char *)"H2_STEP",(char *)"H2_MFIN",(char *)"H2_MUL_END",
187 (char *)"H2_SQR_START",(char *)"H2_DSTEP",(char *)"H2_SELF",(char *)"H2_SFIN",(char *)"H2_SQR_END",
188 (char *)"H4_MUL_START",(char *)"H4_STEP",(char *)"H4_MFIN",(char *)"H4_MUL_END",
189 (char *)"H4_SQR_START",(char *)"H4_DSTEP",(char *)"H4_SELF",(char *)"H4_SFIN",(char *)"H4_SQR_END",(char *)"H2_LAST",(char *)"H4_LAST",
190 (char *)"PMUL_START",(char *)"PMUL",(char *)"PMUL_END",(char *)"MULB_START",(char *)"MULB_END",(char *)"MBFIN",
191 (char *)"H2_MULB_START",(char *)"H2_MULB_END",(char *)"H2_MBFIN",(char *)"H2_STEPB",
192 (char *)"H4_MULB_START",(char *)"H4_MULB_END",(char *)"H4_MBFIN",(char *)"H4_STEPB",
193 (char *)"H2_REDC_START",(char *)"H2_RFINU",(char *)"H2_RFIND",(char *)"H2_REDC_END",
194 (char *)"H4_REDC_START",(char *)"H4_RFINU",(char *)"H4_RFIND",(char *)"H4_REDC_END",
195 (char *)"DOUBLE_START",(char *)"DOUBLE",(char *)"DOUBLE_END",NULL};
196
white(char c)197 BOOL white(char c)
198 {
199 if (c==' ' || c=='\n' || c=='\r' || c=='\t') return TRUE;
200 else return FALSE;
201 }
202
skip(char * c,int i)203 int skip(char *c,int i)
204 {
205 while (white(c[i])) i++;
206 return i;
207 }
208
which(char * name,char * names[])209 int which(char *name,char *names[])
210 {
211 int ipt=0;
212 while (names[ipt]!=NULL)
213 {
214 if (strcmp(name,names[ipt])==0) return ipt;
215 ipt++;
216 }
217 return -1;
218 }
219
m_prologue(FILE * dotc,int k,int m)220 void m_prologue(FILE *dotc,int k,int m)
221 {
222 fprintf(dotc,macro[STEP1M],k,m);
223 }
224
m_epilogue(FILE * dotc,int x)225 void m_epilogue(FILE *dotc,int x)
226 {
227 if (x==1) fprintf(dotc,macro[STEP1A]);
228 else fprintf(dotc,macro[STEP2A]);
229 }
230
m_schedule(FILE * dotc,int x,int k,int m)231 void m_schedule(FILE *dotc,int x,int k,int m)
232 {
233 if (x==1)
234 {
235 fprintf(dotc,macro[STEP2M],k,m);
236 fprintf(dotc,macro[STEP1A]);
237 }
238 else
239 {
240 fprintf(dotc,macro[STEP1M],k,m);
241 fprintf(dotc,macro[STEP2A]);
242 }
243 }
244
m_prologue2(FILE * dotc,int k,int m)245 void m_prologue2(FILE *dotc,int k,int m)
246 {
247 fprintf(dotc,macro[STEPB1M],k,m);
248 }
249
m_epilogue2(FILE * dotc,int x)250 void m_epilogue2(FILE *dotc,int x)
251 {
252 if (x==1) fprintf(dotc,macro[STEPB1A]);
253 else fprintf(dotc,macro[STEPB2A]);
254 }
255
m_schedule2(FILE * dotc,int x,int k,int m)256 void m_schedule2(FILE *dotc,int x,int k,int m)
257 {
258 if (x==1)
259 {
260 fprintf(dotc,macro[STEPB2M],k,m);
261 fprintf(dotc,macro[STEPB1A]);
262 }
263 else
264 {
265 fprintf(dotc,macro[STEPB1M],k,m);
266 fprintf(dotc,macro[STEPB2A]);
267 }
268 }
269
s_prologue(FILE * dotc,int k,int m)270 void s_prologue(FILE *dotc,int k,int m)
271 {
272 fprintf(dotc,macro[DSTEP1M],k,m);
273 }
274
s_epilogue(FILE * dotc,int x)275 void s_epilogue(FILE *dotc,int x)
276 {
277 if (x==1) fprintf(dotc,macro[DSTEP1A]);
278 else fprintf(dotc,macro[DSTEP2A]);
279 }
280
s_schedule(FILE * dotc,int x,int k,int m)281 void s_schedule(FILE *dotc,int x,int k,int m)
282 {
283 if (x==1)
284 {
285 fprintf(dotc,macro[DSTEP2M],k,m);
286 fprintf(dotc,macro[DSTEP1A]);
287 }
288 else
289 {
290 fprintf(dotc,macro[DSTEP1M],k,m);
291 fprintf(dotc,macro[DSTEP2A]);
292 }
293 }
294
295 /* Insert functions into template file */
296
insert(int index,FILE * dotc)297 void insert(int index,FILE *dotc)
298 {
299 int i,k,m,n,x,inc;
300 switch (index)
301 {
302 case PMULT:
303 if (!pmp) break;
304 fprintf(dotc,macro[PMUL_START]);
305 for (i=0;i<PARAM;i++)
306 {
307 fprintf(dotc,macro[PMUL],i,i,i);
308 }
309 fprintf(dotc,macro[PMUL_END]);
310 break;
311 case MULTIPLY2:
312 inc=1;
313 if (hybrid_b)
314 {
315 inc=hybrid_b;
316 if (hybrid_b==2) fprintf(dotc,macro[H2_MULB_START]);
317 if (hybrid_b==4) fprintf(dotc,macro[H4_MULB_START]);
318 }
319 else fprintf(dotc,macro[MULB_START]);
320 for (i=n=0;i<PARAM;i+=inc,n+=inc)
321 {
322 k=0; m=i;
323 if (scheduled)
324 {
325 x=1;
326 m_prologue2(dotc,k,m);
327 k++; m--;
328
329 while (k<=i)
330 {
331 m_schedule2(dotc,x,k,m);
332 k++; m--;
333 x=3-x;
334 }
335
336 m_epilogue2(dotc,x);
337
338 }
339 else
340 {
341 while (k<=i)
342 {
343 if (hybrid_b)
344 {
345 if (hybrid_b==2) fprintf(dotc,macro[H2_STEPB],k,k,m,m);
346 if (hybrid_b==4) fprintf(dotc,macro[H4_STEPB],k,k,k,k,m,m,m,m);
347 }
348 else fprintf(dotc,macro[STEPB],k,m);
349 k+=inc; m-=inc;
350 }
351
352 }
353 if (hybrid_b)
354 {
355 if (hybrid_b==2) fprintf(dotc,macro[H2_MBFIN],n,n+1);
356 if (hybrid_b==4) fprintf(dotc,macro[H4_MBFIN],n,n+1,n+2,n+3);
357 }
358 else fprintf(dotc,macro[MBFIN],n);
359
360 }
361 for (i=0;i<PARAM-inc;i+=inc,n+=inc)
362 {
363 k=i+inc; m=PARAM-inc;
364 if (scheduled)
365 {
366 x=1;
367 m_prologue2(dotc,k,m);
368 k++; m--;
369
370 while (k<=PARAM-1)
371 {
372 m_schedule2(dotc,x,k,m);
373 k++; m--;
374 x=3-x;
375 }
376 m_epilogue2(dotc,x);
377 }
378 else
379 {
380 while (k<=PARAM-inc)
381 {
382 if (hybrid_b)
383 {
384 if (hybrid_b==2) fprintf(dotc,macro[H2_STEPB],k,k,m,m);
385 if (hybrid_b==4) fprintf(dotc,macro[H4_STEPB],k,k,k,k,m,m,m,m);
386 }
387 else fprintf(dotc,macro[STEPB],k,m);
388 k+=inc; m-=inc;
389 }
390 }
391 if (hybrid_b)
392 {
393 if (hybrid_b==2) fprintf(dotc,macro[H2_MBFIN],n,n+1);
394 if (hybrid_b==4) fprintf(dotc,macro[H4_MBFIN],n,n+1,n+2,n+3);
395 }
396 else fprintf(dotc,macro[MBFIN],n);
397
398 }
399
400 if (hybrid_b)
401 {
402 if (hybrid_b==2) fprintf(dotc,macro[H2_MULB_END],2*PARAM-2);
403 if (hybrid_b==4) fprintf(dotc,macro[H4_MULB_END],2*PARAM-4,2*PARAM-3,2*PARAM-2);
404 }
405 else fprintf(dotc,macro[MULB_END]);
406 break;
407 case MULTIPLY:
408 inc=1;
409 if (hybrid)
410 {
411 inc=hybrid;
412 if (hybrid==2) fprintf(dotc,macro[H2_MUL_START]);
413 if (hybrid==4) fprintf(dotc,macro[H4_MUL_START]);
414 }
415 else fprintf(dotc,macro[MUL_START]);
416 for (i=n=0;i<PARAM;i+=inc,n+=inc)
417 {
418 k=0; m=i;
419
420 if (scheduled)
421 {
422 x=1;
423 m_prologue(dotc,k,m);
424 k++; m--;
425
426 while (k<=i)
427 {
428 m_schedule(dotc,x,k,m);
429 k++; m--;
430 x=3-x;
431 }
432
433 m_epilogue(dotc,x);
434
435 }
436 else
437 {
438 while (k<=i)
439 {
440 if (hybrid)
441 {
442 if (hybrid==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
443 if (hybrid==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
444 }
445 else fprintf(dotc,macro[STEP],k,m);
446 k+=inc; m-=inc;
447 }
448 }
449 if (hybrid)
450 {
451 if (hybrid==2) fprintf(dotc,macro[H2_MFIN],n,n+1);
452 if (hybrid==4) fprintf(dotc,macro[H4_MFIN],n,n+1,n+2,n+3);
453 }
454 else fprintf(dotc,macro[MFIN],n);
455 }
456 for (i=0;i<PARAM-inc;i+=inc,n+=inc)
457 {
458 k=i+inc; m=PARAM-inc;
459
460 if (scheduled)
461 {
462 x=1;
463 m_prologue(dotc,k,m);
464 k++; m--;
465
466 while (k<=PARAM-1)
467 {
468 m_schedule(dotc,x,k,m);
469 k++; m--;
470 x=3-x;
471 }
472 m_epilogue(dotc,x);
473 }
474 else
475 {
476 while (k<=PARAM-inc)
477 {
478 if (hybrid)
479 {
480 if (hybrid==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
481 if (hybrid==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
482 }
483 else fprintf(dotc,macro[STEP],k,m);
484 k+=inc; m-=inc;
485 }
486 }
487 if (hybrid)
488 {
489 if (hybrid==2) fprintf(dotc,macro[H2_MFIN],n,n+1);
490 if (hybrid==4) fprintf(dotc,macro[H4_MFIN],n,n+1,n+2,n+3);
491 }
492 else fprintf(dotc,macro[MFIN],n);
493 }
494 if (hybrid)
495 {
496 if (hybrid==2) fprintf(dotc,macro[H2_MUL_END],2*PARAM-2,2*PARAM-1);
497 if (hybrid==4) fprintf(dotc,macro[H4_MUL_END],2*PARAM-4,2*PARAM-3,2*PARAM-2,2*PARAM-1);
498 }
499 else fprintf(dotc,macro[MUL_END],2*PARAM-1);
500 break;
501 case MULTUP:
502 inc=1;
503 if (hybrid)
504 {
505 inc=hybrid;
506 if (hybrid==2) fprintf(dotc,macro[H2_MUL_START]);
507 if (hybrid==4) fprintf(dotc,macro[H4_MUL_START]);
508 }
509 else fprintf(dotc,macro[MUL_START]);
510
511 for (i=n=0;i<PARAM-inc;i+=inc,n+=inc)
512 {
513 k=0; m=i;
514
515 if (scheduled)
516 {
517 x=1;
518 m_prologue(dotc,k,m);
519 k++; m--;
520
521 while (k<=i)
522 {
523 m_schedule(dotc,x,k,m);
524 k++; m--;
525 x=3-x;
526 }
527 m_epilogue(dotc,x);
528 }
529 else
530 {
531 while (k<=i)
532 {
533 if (hybrid)
534 {
535 if (hybrid==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
536 if (hybrid==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
537 }
538 else fprintf(dotc,macro[STEP],k,m);
539 k+=inc; m-=inc;
540 }
541 }
542 if (hybrid)
543 {
544 if (hybrid==2) fprintf(dotc,macro[H2_MFIN],n,n+1);
545 if (hybrid==4) fprintf(dotc,macro[H4_MFIN],n,n+1,n+2,n+3);
546 }
547 else fprintf(dotc,macro[MFIN],n);
548 }
549 k=0; m=PARAM-inc;
550 while (k<=i)
551 {
552 if (hybrid)
553 {
554 if (hybrid==2) fprintf(dotc,macro[H2_LAST],k,k,m,m);
555 if (hybrid==4) fprintf(dotc,macro[H4_LAST],k,k,k,k,m,m,m,m);
556 }
557 else fprintf(dotc,macro[LAST],k,m);
558 k+=inc; m-=inc;
559 }
560
561 if (hybrid)
562 {
563 if (hybrid==2) fprintf(dotc,macro[H2_MUL_END],PARAM-2,PARAM-1);
564 if (hybrid==4) fprintf(dotc,macro[H4_MUL_END],PARAM-4,PARAM-3,PARAM-2,PARAM-1);
565 }
566 else fprintf(dotc,macro[MUL_END],PARAM-1);
567 break;
568 case SQUARE:
569 inc=1;
570 if (hybrid)
571 {
572 inc=hybrid;
573 if (hybrid==2) fprintf(dotc,macro[H2_SQR_START]);
574 if (hybrid==4) fprintf(dotc,macro[H4_SQR_START]);
575 }
576 else fprintf(dotc,macro[SQR_START]);
577 for (i=n=0;i<PARAM;i+=inc,n+=inc)
578 {
579 k=0; m=i;
580
581 if (scheduled)
582 {
583 if (k<m)
584 {
585 x=1;
586 s_prologue(dotc,k,m);
587 k++; m--;
588
589 while (k<m)
590 {
591 s_schedule(dotc,x,k,m);
592 k++; m--;
593 x=3-x;
594 }
595 s_epilogue(dotc,x);
596 }
597 }
598 else
599 {
600 while (k<m)
601 {
602 if (hybrid)
603 {
604 if (hybrid==2) fprintf(dotc,macro[H2_DSTEP],k,k,m,m);
605 if (hybrid==4) fprintf(dotc,macro[H4_DSTEP],k,k,k,k,m,m,m,m);
606 }
607 else fprintf(dotc,macro[DSTEP],k,m);
608 k+=inc; m-=inc;
609 }
610 }
611 if (hybrid)
612 {
613 if (hybrid==2 && n%4==0) fprintf(dotc,macro[H2_SELF],n/2,n/2);
614 if (hybrid==4 && n%8==0) fprintf(dotc,macro[H4_SELF],n/2,n/2,n/2,n/2);
615 }
616 else
617 {
618 if (n%2==0) fprintf(dotc,macro[SELF],n/2,n/2);
619 }
620 if (hybrid)
621 {
622 if (hybrid==2) fprintf(dotc,macro[H2_SFIN],n,n+1);
623 if (hybrid==4) fprintf(dotc,macro[H4_SFIN],n,n+1,n+2,n+3);
624 }
625 else fprintf(dotc,macro[SFIN],n);
626 }
627 for (i=0;i<PARAM-inc;i+=inc,n+=inc)
628 {
629 k=i+inc; m=PARAM-inc;
630
631 if (scheduled)
632 {
633 if (k<m)
634 {
635 x=1;
636 s_prologue(dotc,k,m);
637 k++; m--;
638
639 while (k<m)
640 {
641 s_schedule(dotc,x,k,m);
642 k++; m--;
643 x=3-x;
644 }
645 s_epilogue(dotc,x);
646 }
647 }
648 else
649 {
650 while (k<m)
651 {
652 if (hybrid)
653 {
654 if (hybrid==2) fprintf(dotc,macro[H2_DSTEP],k,k,m,m);
655 if (hybrid==4) fprintf(dotc,macro[H4_DSTEP],k,k,k,k,m,m,m,m);
656 }
657 else fprintf(dotc,macro[DSTEP],k,m);
658 k+=inc; m-=inc;
659 }
660 }
661 if (hybrid)
662 {
663 if (hybrid==2 && n%4==0) fprintf(dotc,macro[H2_SELF],n/2,n/2);
664 if (hybrid==4 && n%8==0) fprintf(dotc,macro[H4_SELF],n/2,n/2,n/2,n/2);
665 }
666 else
667 {
668 if (n%2==0) fprintf(dotc,macro[SELF],n/2,n/2);
669 }
670 if (hybrid)
671 {
672 if (hybrid==2) fprintf(dotc,macro[H2_SFIN],n,n+1);
673 if (hybrid==4) fprintf(dotc,macro[H4_SFIN],n,n+1,n+2,n+3);
674 }
675 else fprintf(dotc,macro[SFIN],n);
676 }
677 if (hybrid)
678 {
679 if (hybrid==2) fprintf(dotc,macro[H2_SQR_END],2*PARAM-2,2*PARAM-1);
680 if (hybrid==4) fprintf(dotc,macro[H4_SQR_END],2*PARAM-4,2*PARAM-3,2*PARAM-2,2*PARAM-1);
681 }
682 else fprintf(dotc,macro[SQR_END],2*PARAM-1);
683 break;
684 case REDC:
685 inc=1;
686 if (hybrid_r)
687 {
688 inc=hybrid_r;
689 if (hybrid_r==2)
690 {
691 fprintf(dotc,macro[H2_REDC_START]);
692 fprintf(dotc,macro[H2_RFINU],0,0,0,0);
693 }
694 if (hybrid_r==4)
695 {
696 fprintf(dotc,macro[H4_REDC_START]);
697 fprintf(dotc,macro[H4_RFINU],0,0,0,0,0,0,0,0);
698 }
699 }
700 else
701 {
702 fprintf(dotc,macro[REDC_START]);
703 fprintf(dotc,macro[RFINU],0,0);
704 }
705
706 for (i=n=inc;i<PARAM;i+=inc,n+=inc)
707 {
708 k=0; m=i;
709
710 if (scheduled)
711 {
712 x=1;
713 m_prologue(dotc,k,m);
714 k++; m--;
715
716 while (k<i)
717 {
718 m_schedule(dotc,x,k,m);
719 k++; m--;
720 x=3-x;
721 }
722 m_epilogue(dotc,x);
723 }
724 else
725 {
726 while (k<i)
727 {
728 if (hybrid_r)
729 {
730 if (hybrid_r==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
731 if (hybrid_r==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
732 }
733 else fprintf(dotc,macro[STEP],k,m);
734 k+=inc; m-=inc;
735 }
736 }
737
738 if (hybrid_r)
739 {
740 if (hybrid_r==2) fprintf(dotc,macro[H2_RFINU],n,n,n,n);
741 if (hybrid_r==4) fprintf(dotc,macro[H4_RFINU],n,n,n,n,n,n,n,n);
742 }
743 else fprintf(dotc,macro[RFINU],n,n);
744 }
745
746 for (i=0;i<PARAM-inc;i+=inc,n+=inc)
747 {
748 k=i+inc; m=PARAM-inc;
749
750 if (scheduled)
751 {
752 x=1;
753 m_prologue(dotc,k,m);
754 k++; m--;
755
756 while (k<=PARAM-1)
757 {
758 m_schedule(dotc,x,k,m);
759 k++; m--;
760 x=3-x;
761 }
762 m_epilogue(dotc,x);
763 }
764 else
765 {
766 while (k<=PARAM-inc)
767 {
768 if (hybrid_r)
769 {
770 if (hybrid_r==2) fprintf(dotc,macro[H2_STEP],k,k,m,m);
771 if (hybrid_r==4) fprintf(dotc,macro[H4_STEP],k,k,k,k,m,m,m,m);
772 }
773 else fprintf(dotc,macro[STEP],k,m);
774 k+=inc; m-=inc;
775 }
776 }
777
778 if (hybrid_r)
779 {
780 if (hybrid_r==2) fprintf(dotc,macro[H2_RFIND],n,n,n,n);
781 if (hybrid_r==4) fprintf(dotc,macro[H4_RFIND],n,n,n,n,n,n,n,n);
782 }
783 else fprintf(dotc,macro[RFIND],n,n);
784 }
785 if (hybrid_r)
786 {
787 if (hybrid_r==2) fprintf(dotc,macro[H2_REDC_END],2*PARAM-inc,2*PARAM-inc,2*PARAM-inc);
788 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);
789 }
790 else fprintf(dotc,macro[REDC_END],2*PARAM-1,2*PARAM-1);
791
792 break;
793
794 case ADDITION:
795 fprintf(dotc,macro[ADD_START]);
796 for (i=1;i<PARAM;i++)
797 fprintf(dotc,macro[ADD],i,i,i);
798 fprintf(dotc,macro[ADD_END]);
799 break;
800 case ADDITION2:
801 fprintf(dotc,macro[ADD_START]);
802 for (i=1;i<2*PARAM;i++)
803 fprintf(dotc,macro[ADD],i,i,i);
804 fprintf(dotc,macro[ADD_END]);
805 break;
806 case INCREMENT:
807 fprintf(dotc,macro[INC_START]);
808 for (i=1;i<PARAM;i++)
809 fprintf(dotc,macro[INC],i,i,i);
810 fprintf(dotc,macro[INC_END]);
811 break;
812 case DOUBLEIT:
813 if (macro[DOUBLE_START]!=NULL)
814 {
815 fprintf(dotc,macro[DOUBLE_START]);
816 for (i=1;i<PARAM;i++)
817 fprintf(dotc,macro[DOUBLE],i,i);
818 fprintf(dotc,macro[DOUBLE_END]);
819 }
820 else
821 {
822 fprintf(dotc,macro[INC_START]);
823 for (i=1;i<PARAM;i++)
824 fprintf(dotc,macro[INC],i,i,i);
825 fprintf(dotc,macro[INC_END]);
826 }
827 break;
828
829 case SUBTRACTION:
830 fprintf(dotc,macro[SUB_START]);
831 for (i=1;i<PARAM;i++)
832 fprintf(dotc,macro[SUB],i,i,i);
833 fprintf(dotc,macro[SUB_END]);
834 break;
835 case SUBTRACTION2:
836 fprintf(dotc,macro[SUB_START]);
837 for (i=1;i<2*PARAM;i++)
838 fprintf(dotc,macro[SUB],i,i,i);
839 fprintf(dotc,macro[SUB_END]);
840 break;
841 case DECREMENT:
842 fprintf(dotc,macro[DEC_START]);
843 for (i=1;i<PARAM;i++)
844 fprintf(dotc,macro[DEC],i,i,i);
845 fprintf(dotc,macro[DEC_END]);
846 break;
847 case SUMMATION:
848 fprintf(dotc,macro[KADD_START],1);
849 for (i=0;i<PARAM;i++)
850 fprintf(dotc,macro[ADD],i,i,i);
851 fprintf(dotc,macro[KASL],2,PARAM,PARAM,PARAM,1,2);
852 fprintf(dotc,macro[KADD_END]);
853 break;
854 case INCREMENTATION:
855 fprintf(dotc,macro[KINC_START],3);
856 for (i=0;i<PARAM;i++)
857 fprintf(dotc,macro[INC],i,i,i);
858 fprintf(dotc,macro[KIDL],4,PARAM,PARAM,3,4);
859 fprintf(dotc,macro[KINC_END]);
860 break;
861 case DECREMENTATION:
862 fprintf(dotc,macro[KDEC_START],5);
863 for (i=0;i<PARAM;i++)
864 fprintf(dotc,macro[DEC],i,i,i);
865 fprintf(dotc,macro[KIDL],6,PARAM,PARAM,5,6);
866 fprintf(dotc,macro[KDEC_END]);
867 break;
868 default:
869 break;
870 }
871 }
872
main(int argc,char ** argv)873 int main(int argc,char **argv)
874 {
875 FILE *templat,*macros,*dotc;
876 int i,ip,ptr,index,size;
877 BOOL open,error;
878 char fname[80],tmpl[80],name[20];
879 char line[133];
880 argc--; argv++;
881 if (argc<3 || argc>4)
882 {
883 printf("Bad arguments\n");
884 printf("mex <parameter> <.mcs file> <.tpl file>\n");
885 printf("Use flag -s for scheduled code\n");
886 printf("Examples:\n");
887 printf("mex 6 ms86 mrcomba\n");
888 printf("mex -s 8 c mrkcm\n");
889 exit(0);
890 }
891 ip=0;
892 scheduled=FALSE;
893 if (strcmp(argv[0],"-s")==0)
894 {
895 ip=1;
896 scheduled=TRUE;
897 }
898
899 PARAM=atoi(argv[ip]);
900 if (PARAM<2 || PARAM>40)
901 {
902 printf("Invalid parameter\n");
903 exit(0);
904 }
905 strcpy(fname,argv[ip+1]);
906 strcat(fname,".mcs");
907 macros=fopen(fname,"rt");
908 if (macros==NULL)
909 {
910 printf("Macro file %s not found\n",fname);
911 exit(0);
912 }
913
914 strcpy(tmpl,argv[ip+2]);
915 strcat(tmpl,".tpl");
916 templat=fopen(tmpl,"rt");
917 if (templat==NULL)
918 {
919 printf("Template file %s file not found\n",tmpl);
920 exit(0);
921 }
922 strcpy(tmpl,argv[ip+2]);
923 strcat(tmpl,".c");
924 dotc=fopen(tmpl,"wt");
925 if (dotc==NULL)
926 {
927 printf("Unable to open %s for output\n",tmpl);
928 exit(0);
929 }
930
931 for (i=0;i<LAST_ONE;i++) macro[i]=NULL;
932
933 /* read in the macros - first pass to determine size and check for errors */
934 open=error=FALSE;
935 while (1)
936 {
937 if (fgets(line,132,macros)==NULL) break;
938 if (line[0]==';') continue;
939
940 if (!open && strncmp(line,"MACRO",5)==0)
941 {
942 open=TRUE;
943 ptr=6; i=0;
944 ptr=skip(line,ptr);
945 while (!white(line[ptr])) name[i++]=line[ptr++];
946 name[i]='\0';
947 index=which(name,names);
948 if (index<0)
949 {
950 error=TRUE;
951 break;
952 }
953 size=0;
954 continue;
955 }
956 if (open && strncmp(line,"ENDM",4)==0)
957 {
958 open=FALSE;
959 macro[index]=(char *)malloc(size+1);
960 macro[index][0]='\0';
961 }
962
963 if (open) size+=(int)strlen(line);
964 }
965 fclose(macros);
966 if (error)
967 {
968 printf("no such macro - %s\n",name);
969 exit(0);
970 }
971
972 /* read in the macros - second pass to store macros */
973 macros=fopen(fname,"rt");
974 while (1)
975 {
976 if (fgets(line,132,macros)==NULL) break;
977 if (line[0]==';') continue;
978
979 if (!open && strncmp(line,"MACRO",5)==0)
980 {
981 open=TRUE;
982 ptr=6; i=0;
983 ptr=skip(line,ptr);
984 while (!white(line[ptr])) name[i++]=line[ptr++];
985 name[i]='\0';
986 index=which(name,names);
987 continue;
988 }
989 if (open && strncmp(line,"ENDM",4)==0) open=FALSE;
990
991 if (open) strcat(macro[index],line);
992 }
993 fclose(macros);
994
995 if (macro[PMUL]==NULL)
996 {
997 /* printf("Pseudo Mersenne Primes not (yet) supported for this architecture in file %s\n",fname); */
998 pmp=0;
999 }
1000 else pmp=1;
1001
1002 if (scheduled && macro[STEP1M]==NULL)
1003 {
1004 printf("Error - scheduling not supported in file %s\n",fname);
1005 exit(0);
1006 }
1007 hybrid=0;
1008 if (macro[H2_STEP]!=NULL) hybrid=2;
1009 if (macro[H4_STEP]!=NULL) hybrid=4;
1010
1011 hybrid_b=0;
1012 if (macro[H2_STEPB]!=NULL) hybrid_b=2;
1013 if (macro[H4_STEPB]!=NULL) hybrid_b=4;
1014
1015 hybrid_r=0;
1016 if (macro[H2_RFINU]!=NULL) hybrid_r=2;
1017 if (macro[H4_RFINU]!=NULL) hybrid_r=4;
1018
1019 if (hybrid)
1020 {
1021 printf("Found hybrid macros - max step size = %d\n",hybrid);
1022 if (PARAM%hybrid!=0)
1023 {
1024 printf("Warning - %d should be a multiple of %d for hybrid method\n",PARAM,hybrid);
1025 hybrid=0;
1026 }
1027 }
1028
1029 if (hybrid_b)
1030 {
1031 printf("Found hybrid macros for binary case - max step size = %d\n",hybrid_b);
1032 if (PARAM%hybrid_b!=0)
1033 {
1034 printf("Warning - %d should be a multiple of %d for hybrid method\n",PARAM,hybrid_b);
1035 hybrid_b=0;
1036 }
1037 }
1038
1039 if ((scheduled && hybrid) || (scheduled && hybrid_b))
1040 {
1041 printf("Error - scheduling not supported in file %s\n",fname);
1042 exit(0);
1043 }
1044
1045 /* Insert macros into dotc file */
1046
1047 while (1)
1048 {
1049 if (fgets(line,132,templat)==NULL) break;
1050 fputs(line,dotc);
1051 if (strncmp(line,"/***",4)==0)
1052 {
1053 ptr=4; i=0;
1054 ptr=skip(line,ptr);
1055 while (!white(line[ptr])) name[i++]=line[ptr++];
1056 name[i]='\0';
1057
1058 index=which(name,functions);
1059 /* printf("Recognize %s index %d\n",name,index); */
1060 if (index<0)
1061 {
1062 error=TRUE;
1063 break;
1064 }
1065 insert(index,dotc);
1066 }
1067 }
1068
1069 if (error)
1070 printf("no such function - %s\n",name);
1071
1072 fclose(templat);
1073 fclose(dotc);
1074 return 0;
1075 }
1076
1077