Pristine Ack-5.5
[Ack-5.5.git] / util / opt / mktab.y
1 %{
2 #ifndef NORCSID
3 static char rcsid[] = "$Id: mktab.y,v 2.6 1994/06/24 10:40:20 ceriel Exp $";
4 #endif
5
6 #include <stdio.h>
7 #include "param.h"
8 #include "types.h"
9 #include "pattern.h"
10 #include <em_spec.h>
11 #include <em_mnem.h>
12 #include "optim.h"
13
14 /*
15  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
16  * See the copyright notice in the ACK home directory, in the file "Copyright".
17  *
18  * Author: Hans van Staveren
19  */
20
21 #define op_CBO  (op_plast+1)
22
23 #define MAXNODES 1000
24 expr_t  nodes[MAXNODES];
25 expr_p  lastnode = nodes+1;
26 int     curind,prevind;
27 int     patlen,maxpatlen,rpllen;
28 int     lino = 1;
29 int     patno=1;
30 #define MAX     100
31 int patmnem[MAX],rplmnem[MAX],rplexpr[MAX];
32 byte    nparam[N_EX_OPS];
33 bool    nonumlab[N_EX_OPS];
34 bool    onlyconst[N_EX_OPS];
35 int     nerrors=0;
36 char    patid[128];
37
38 int CBO_instrs[] = {
39         op_adi,
40         op_adu,
41         op_and,
42         op_ior,
43         op_xor
44         /* don't add op_mli and op_mlu! */
45 };
46
47 int     patCBO;
48 int     rplCBO;
49 %}
50
51 %union {
52         int     y_int;
53 }
54
55 %left OR2
56 %left AND2
57 %left OR1
58 %left XOR1
59 %left AND1
60 %left CMPEQ,CMPNE
61 %left CMPLT,CMPLE,CMPGT,CMPGE
62 %left RSHIFT,LSHIFT
63 %left ARPLUS,ARMINUS
64 %left ARTIMES,ARDIVIDE,ARMOD
65 %nonassoc NOT,COMP,UMINUS
66 %nonassoc '$'
67
68 %token SFIT,UFIT,NOTREG,PSIZE,WSIZE,DEFINED,SAMESIGN,ROM,ROTATE,STRING
69 %token <y_int> MNEM
70 %token <y_int> NUMBER
71 %type <y_int> expr,argno,optexpr
72
73 %start patternlist
74
75 %%
76 patternlist
77         :       /* empty */
78         |       STRING '\n'
79         |       patternlist '\n'
80         |       patternlist pattern
81         ;
82 pattern :
83                 mnemlist optexpr ':' replacement '\n'
84                         {
85                           if (patCBO) {
86                                 register int i;
87
88                                 if (! rplCBO) {
89                                         yyerror("No CBO in replacement");
90                                 }
91                                 for (i=0; i<sizeof(CBO_instrs)/sizeof(int); i++) {
92                                         outpat($2, CBO_instrs[i]);
93                                 }
94                           }
95                           else {
96                                 outpat($2, 0);
97                           }
98                           patCBO = rplCBO = 0;
99                         }
100         |       error '\n'
101                         { yyerrok; }
102         ;
103 replacement
104         :       expr    /* special optimization */
105                         {
106 #ifdef ALLOWSPECIAL
107                           rpllen=1; rplmnem[0]=0; rplexpr[0]=$1;
108 #else
109                           yyerror("No specials allowed");
110 #endif
111                         }
112         |       repllist
113         ;
114 repllist:       /* empty */
115                         { rpllen=0; }
116         |       repllist repl
117         ;
118 repl    :       MNEM    optexpr
119                         { rplmnem[rpllen] = $1; rplexpr[rpllen++] = $2;
120                           if ($1 == op_CBO) {
121                                 if (!patCBO) {
122                                         yyerror("No CBO in pattern");
123                                 }
124                                 if (rplCBO) {
125                                         yyerror("Only one CBO allowed in replacement");
126                                 }
127                                 rplCBO = 1;
128                           }
129                         }
130         ;
131 mnemlist:       MNEM
132                         { patlen=0; patmnem[patlen++] = $1;
133                           if ($1 == op_CBO) {
134                                 if (patCBO) {
135                                         yyerror("Only one CBO allowed in pattern");
136                                 }
137                                 patCBO = 1;
138                           }
139                         }
140         |       mnemlist MNEM
141                         { patmnem[patlen++] = $2;
142                           if ($2 == op_CBO) {
143                                 if (patCBO) {
144                                         yyerror("Only one CBO allowed in pattern");
145                                 }
146                                 patCBO = 1;
147                           }
148                         }
149         ;
150 optexpr :       /* empty */
151                         { $$ = 0; }
152         |       expr
153         ;
154 expr    
155         :       '$' argno
156                         { $$ = lookup(0,EX_ARG,$2,0); }
157         |       NUMBER
158                         { $$ = lookup(0,EX_CON,(int)(short)$1,0); }
159         |       PSIZE
160                         { $$ = lookup(0,EX_POINTERSIZE,0,0); }
161         |       WSIZE
162                         { $$ = lookup(0,EX_WORDSIZE,0,0); }
163         |       DEFINED '(' expr ')'
164                         { $$ = lookup(0,EX_DEFINED,$3,0); }
165         |       SAMESIGN '(' expr ',' expr ')'
166                         { $$ = lookup(1,EX_SAMESIGN,$3,$5); }
167         |       SFIT '(' expr ',' expr ')'
168                         { $$ = lookup(0,EX_SFIT,$3,$5); }
169         |       UFIT '(' expr ',' expr ')'
170                         { $$ = lookup(0,EX_UFIT,$3,$5); }
171         |       ROTATE '(' expr ',' expr ')'
172                         { $$ = lookup(0,EX_ROTATE,$3,$5); }
173         |       NOTREG '(' expr ')'
174                         { $$ = lookup(0,EX_NOTREG,$3,0); }
175         |       ROM '(' argno ',' expr ')'
176                         { $$ = lookup(0,EX_ROM,$3,$5); }
177         |       '(' expr ')'
178                         { $$ = $2; }
179         |       expr CMPEQ expr
180                         { $$ = lookup(1,EX_CMPEQ,$1,$3); }
181         |       expr CMPNE expr
182                         { $$ = lookup(1,EX_CMPNE,$1,$3); }
183         |       expr CMPGT expr
184                         { $$ = lookup(0,EX_CMPGT,$1,$3); }
185         |       expr CMPGE expr
186                         { $$ = lookup(0,EX_CMPGE,$1,$3); }
187         |       expr CMPLT expr
188                         { $$ = lookup(0,EX_CMPLT,$1,$3); }
189         |       expr CMPLE expr
190                         { $$ = lookup(0,EX_CMPLE,$1,$3); }
191         |       expr OR2 expr
192                         { $$ = lookup(0,EX_OR2,$1,$3); }
193         |       expr AND2 expr
194                         { $$ = lookup(0,EX_AND2,$1,$3); }
195         |       expr OR1 expr
196                         { $$ = lookup(1,EX_OR1,$1,$3); }
197         |       expr XOR1 expr
198                         { $$ = lookup(1,EX_XOR1,$1,$3); }
199         |       expr AND1 expr
200                         { $$ = lookup(1,EX_AND1,$1,$3); }
201         |       expr ARPLUS expr
202                         { $$ = lookup(1,EX_PLUS,$1,$3); }
203         |       expr ARMINUS expr
204                         { $$ = lookup(0,EX_MINUS,$1,$3); }
205         |       expr ARTIMES expr
206                         { $$ = lookup(1,EX_TIMES,$1,$3); }
207         |       expr ARDIVIDE expr
208                         { $$ = lookup(0,EX_DIVIDE,$1,$3); }
209         |       expr ARMOD expr
210                         { $$ = lookup(0,EX_MOD,$1,$3); }
211         |       expr LSHIFT expr
212                         { $$ = lookup(0,EX_LSHIFT,$1,$3); }
213         |       expr RSHIFT expr
214                         { $$ = lookup(0,EX_RSHIFT,$1,$3); }
215         |       ARPLUS expr %prec UMINUS
216                         { $$ = $2; }
217         |       ARMINUS expr %prec UMINUS
218                         { $$ = lookup(0,EX_UMINUS,$2,0); }
219         |       NOT expr
220                         { $$ = lookup(0,EX_NOT,$2,0); }
221         |       COMP expr
222                         { $$ = lookup(0,EX_COMP,$2,0); }
223         ;
224 argno   :       NUMBER
225                         { if ($1<1 || $1>patlen) {
226                                 YYERROR;
227                           }
228                           $$ = (int) $1;
229                         }
230         ;
231
232 %%
233
234 extern char em_mnem[][4];
235
236 #define HASHSIZE        (2*(sp_lmnem-sp_fmnem))
237
238 struct hashmnem {
239         char h_name[3];
240         byte h_value;
241 } hashmnem[HASHSIZE];
242
243 inithash() {
244         register i;
245
246         enter("lab",op_lab);
247         enter("LLP",op_LLP);
248         enter("LEP",op_LEP);
249         enter("SLP",op_SLP);
250         enter("SEP",op_SEP);
251         enter("CBO",op_CBO);
252         for(i=0;i<=sp_lmnem-sp_fmnem;i++)
253                 enter(em_mnem[i],i+sp_fmnem);
254 }
255
256 unsigned hashname(name) register char *name; {
257         register unsigned h;
258
259         h = (*name++)&BMASK;
260         h = (h<<4)^((*name++)&BMASK);
261         h = (h<<4)^((*name++)&BMASK);
262         return(h);
263 }
264
265 enter(name,value) char *name; {
266         register unsigned h;
267
268         h=hashname(name)%HASHSIZE;
269         while (hashmnem[h].h_name[0] != 0)
270                 h = (h+1)%HASHSIZE;
271         strncpy(hashmnem[h].h_name,name,3);
272         hashmnem[h].h_value = value;
273 }
274
275 int mlookup(name) char *name; {
276         register unsigned h;
277
278         h = hashname(name)%HASHSIZE;
279         while (strncmp(hashmnem[h].h_name,name,3) != 0 &&
280                hashmnem[h].h_name[0] != 0)
281                 h = (h+1)%HASHSIZE;
282         return(hashmnem[h].h_value&BMASK);      /* 0 if not found */
283 }
284
285 main() {
286
287         inithash();
288         initio();
289         yyparse();
290         if (nerrors==0)
291                 printnodes();
292         return nerrors;
293 }
294
295 yyerror(s) char *s; {
296
297         fprintf(stderr,"line %d: %s\n",lino,s);
298         nerrors++;
299 }
300
301 lookup(comm,operator,lnode,rnode) {
302         register expr_p p;
303
304         for (p=nodes+1;p<lastnode;p++) {
305                 if (p->ex_operator != operator)
306                         continue;
307                 if (!(p->ex_lnode == lnode && p->ex_rnode == rnode ||
308                     comm && p->ex_lnode == rnode && p->ex_rnode == lnode))
309                         continue;
310                 return(p-nodes);
311         }
312         if (lastnode >= &nodes[MAXNODES])
313                 yyerror("node table overflow");
314         lastnode++;
315         p->ex_operator = operator;
316         p->ex_lnode = lnode;
317         p->ex_rnode = rnode;
318         return(p-nodes);
319 }
320
321 printnodes() {
322         register expr_p p;
323
324         printf("};\n\nshort lastind = %d;\n\nexpr_t enodes[] = {\n",prevind);
325         for (p=nodes;p<lastnode;p++)
326                 printf("/* %3d */\t%3d,%6u,%6u,\n",
327                         p-nodes,p->ex_operator,p->ex_lnode,p->ex_rnode);
328         printf("};\n\niarg_t iargs[%d];\n",maxpatlen);
329         if (patid[0])
330                 printf("static char rcsid[] = %s;\n",patid);
331 }
332
333 initio() {
334         register i;
335
336         printf("#include \"param.h\"\n#include \"types.h\"\n");
337         printf("#include \"pattern.h\"\n\n");
338         for(i=0;i<N_EX_OPS;i++) {
339                 nparam[i]=2;
340                 nonumlab[i]=TRUE;
341                 onlyconst[i]=TRUE;
342         }
343         nparam[EX_POINTERSIZE] = 0;
344         nparam[EX_WORDSIZE] = 0;
345         nparam[EX_CON] = 0;
346         nparam[EX_ROM] = 0;
347         nparam[EX_ARG] = 0;
348         nparam[EX_DEFINED] = 0;
349         nparam[EX_OR2] = 1;
350         nparam[EX_AND2] = 1;
351         nparam[EX_UMINUS] = 1;
352         nparam[EX_NOT] = 1;
353         nparam[EX_COMP] = 1;
354         nparam[EX_NOTREG] = 1;
355         nonumlab[EX_CMPEQ] = FALSE;
356         nonumlab[EX_CMPNE] = FALSE;
357         onlyconst[EX_CMPEQ] = FALSE;
358         onlyconst[EX_CMPNE] = FALSE;
359         onlyconst[EX_CMPLE] = FALSE;
360         onlyconst[EX_CMPLT] = FALSE;
361         onlyconst[EX_CMPGE] = FALSE;
362         onlyconst[EX_CMPGT] = FALSE;
363         onlyconst[EX_PLUS] = FALSE;
364         onlyconst[EX_MINUS] = FALSE;
365         printf("byte nparam[] = {");
366         for (i=0;i<N_EX_OPS;i++) printf("%d,",nparam[i]);
367         printf("};\nbool nonumlab[] = {");
368         for (i=0;i<N_EX_OPS;i++) printf("%d,",nonumlab[i]);
369         printf("};\nbool onlyconst[] = {");
370         for (i=0;i<N_EX_OPS;i++) printf("%d,",onlyconst[i]);
371         printf("};\n\nbyte pattern[] = { 0\n");
372         curind = 1;
373 }
374
375 outpat(exprno, instrno)
376 {
377         register int i;
378
379         outbyte(0); outshort(prevind); prevind=curind-3;
380         out(patlen);
381         for (i=0;i<patlen;i++) {
382                 if (patmnem[i] == op_CBO) outbyte(instrno);
383                 else outbyte(patmnem[i]);
384         }
385         out(exprno);
386         out(rpllen);
387         for (i=0;i<rpllen;i++) {
388                 if (rplmnem[i] == op_CBO) outbyte(instrno);
389                 else outbyte(rplmnem[i]);
390                 out(rplexpr[i]);
391         }
392 #ifdef DIAGOPT
393         outshort(patno);
394 #endif
395         patno++;
396         printf("\n");
397         if (patlen>maxpatlen) maxpatlen=patlen;
398 }
399
400 outbyte(b) {
401
402         printf(",%3d",b);
403         curind++;
404 }
405
406 outshort(s) {
407
408         outbyte(s&0377);
409         outbyte((s>>8)&0377);
410 }
411
412 out(w) {
413
414         if (w<255) {
415                 outbyte(w);
416         } else {
417                 outbyte(255);
418                 outshort(w);
419         }
420 }
421
422 #include "scan.c"