]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/8a/a.y
import updated compilers from sources
[plan9front.git] / sys / src / cmd / 8a / a.y
1 %{
2 #include "a.h"
3 %}
4 %union  {
5         Sym     *sym;
6         long    lval;
7         struct {
8                 long v1;
9                 long v2;
10         } con2;
11         double  dval;
12         char    sval[8];
13         Gen     gen;
14         Gen2    gen2;
15 }
16 %left   '|'
17 %left   '^'
18 %left   '&'
19 %left   '<' '>'
20 %left   '+' '-'
21 %left   '*' '/' '%'
22 %token  <lval>  LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
23 %token  <lval>  LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG
24 %token  <lval>  LCONST LFP LPC LSB
25 %token  <lval>  LBREG LLREG LSREG LFREG
26 %token  <dval>  LFCONST
27 %token  <sval>  LSCONST LSP
28 %token  <sym>   LNAME LLAB LVAR
29 %type   <lval>  con expr pointer offset
30 %type   <con2>  con2
31 %type   <gen>   mem imm imm2 reg nam rel rem rim rom omem nmem
32 %type   <gen2>  nonnon nonrel nonrem rimnon rimrem remrim
33 %type   <gen2>  spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8
34 %%
35 prog:
36 |       prog line
37
38 line:
39         LLAB ':'
40         {
41                 if($1->value != pc)
42                         yyerror("redeclaration of %s", $1->name);
43                 $1->value = pc;
44         }
45         line
46 |       LNAME ':'
47         {
48                 $1->type = LLAB;
49                 $1->value = pc;
50         }
51         line
52 |       ';'
53 |       inst ';'
54 |       error ';'
55
56 inst:
57         LNAME '=' expr
58         {
59                 $1->type = LVAR;
60                 $1->value = $3;
61         }
62 |       LVAR '=' expr
63         {
64                 if($1->value != $3)
65                         yyerror("redeclaration of %s", $1->name);
66                 $1->value = $3;
67         }
68 |       LTYPE0 nonnon   { outcode($1, &$2); }
69 |       LTYPE1 nonrem   { outcode($1, &$2); }
70 |       LTYPE2 rimnon   { outcode($1, &$2); }
71 |       LTYPE3 rimrem   { outcode($1, &$2); }
72 |       LTYPE4 remrim   { outcode($1, &$2); }
73 |       LTYPER nonrel   { outcode($1, &$2); }
74 |       LTYPED spec1    { outcode($1, &$2); }
75 |       LTYPET spec2    { outcode($1, &$2); }
76 |       LTYPEC spec3    { outcode($1, &$2); }
77 |       LTYPEN spec4    { outcode($1, &$2); }
78 |       LTYPES spec5    { outcode($1, &$2); }
79 |       LTYPEM spec6    { outcode($1, &$2); }
80 |       LTYPEI spec7    { outcode($1, &$2); }
81 |       LTYPEG spec8    { outcode($1, &$2); }
82
83 nonnon:
84         {
85                 $$.from = nullgen;
86                 $$.to = nullgen;
87         }
88 |       ','
89         {
90                 $$.from = nullgen;
91                 $$.to = nullgen;
92         }
93
94 rimrem:
95         rim ',' rem
96         {
97                 $$.from = $1;
98                 $$.to = $3;
99         }
100
101 remrim:
102         rem ',' rim
103         {
104                 $$.from = $1;
105                 $$.to = $3;
106         }
107
108 rimnon:
109         rim ','
110         {
111                 $$.from = $1;
112                 $$.to = nullgen;
113         }
114 |       rim
115         {
116                 $$.from = $1;
117                 $$.to = nullgen;
118         }
119
120 nonrem:
121         ',' rem
122         {
123                 $$.from = nullgen;
124                 $$.to = $2;
125         }
126 |       rem
127         {
128                 $$.from = nullgen;
129                 $$.to = $1;
130         }
131
132 nonrel:
133         ',' rel
134         {
135                 $$.from = nullgen;
136                 $$.to = $2;
137         }
138 |       rel
139         {
140                 $$.from = nullgen;
141                 $$.to = $1;
142         }
143
144 spec1:  /* DATA */
145         nam '/' con ',' imm
146         {
147                 $$.from = $1;
148                 $$.from.scale = $3;
149                 $$.to = $5;
150         }
151
152 spec2:  /* TEXT */
153         mem ',' imm
154         {
155                 $$.from = $1;
156                 $$.to = $3;
157         }
158 |       mem ',' con ',' imm
159         {
160                 $$.from = $1;
161                 $$.from.scale = $3;
162                 $$.to = $5;
163         }
164
165 spec3:  /* JMP/CALL */
166         ',' rom
167         {
168                 $$.from = nullgen;
169                 $$.to = $2;
170         }
171 |       rom
172         {
173                 $$.from = nullgen;
174                 $$.to = $1;
175         }
176
177 spec4:  /* NOP */
178         nonnon
179 |       nonrem
180
181 spec5:  /* SHL/SHR */
182         rim ',' rem
183         {
184                 $$.from = $1;
185                 $$.to = $3;
186         }
187 |       rim ',' rem ':' LLREG
188         {
189                 $$.from = $1;
190                 $$.to = $3;
191                 if($$.from.index != D_NONE)
192                         yyerror("dp shift with lhs index");
193                 $$.from.index = $5;
194         }
195
196 spec6:  /* MOVW/MOVL */
197         rim ',' rem
198         {
199                 $$.from = $1;
200                 $$.to = $3;
201         }
202 |       rim ',' rem ':' LSREG
203         {
204                 $$.from = $1;
205                 $$.to = $3;
206                 if($$.to.index != D_NONE)
207                         yyerror("dp move with lhs index");
208                 $$.to.index = $5;
209         }
210
211 spec7:
212         rim ','
213         {
214                 $$.from = $1;
215                 $$.to = nullgen;
216         }
217 |       rim
218         {
219                 $$.from = $1;
220                 $$.to = nullgen;
221         }
222 |       rim ',' rem
223         {
224                 $$.from = $1;
225                 $$.to = $3;
226         }
227
228 spec8:  /* GLOBL */
229         mem ',' imm
230         {
231                 $$.from = $1;
232                 $$.to = $3;
233         }
234 |       mem ',' con ',' imm
235         {
236                 $$.from = $1;
237                 $$.from.scale = $3;
238                 $$.to = $5;
239         }
240
241 rem:
242         reg
243 |       mem
244
245 rom:
246         rel
247 |       nmem
248 |       '*' reg
249         {
250                 $$ = $2;
251         }
252 |       '*' omem
253         {
254                 $$ = $2;
255         }
256 |       reg
257 |       omem
258 |       imm
259
260 rim:
261         rem
262 |       imm
263
264 rel:
265         con '(' LPC ')'
266         {
267                 $$ = nullgen;
268                 $$.type = D_BRANCH;
269                 $$.offset = $1 + pc;
270         }
271 |       LNAME offset
272         {
273                 $$ = nullgen;
274                 if(pass == 2)
275                         yyerror("undefined label: %s", $1->name);
276                 $$.type = D_BRANCH;
277                 $$.sym = $1;
278                 $$.offset = $2;
279         }
280 |       LLAB offset
281         {
282                 $$ = nullgen;
283                 $$.type = D_BRANCH;
284                 $$.sym = $1;
285                 $$.offset = $1->value + $2;
286         }
287
288 reg:
289         LBREG
290         {
291                 $$ = nullgen;
292                 $$.type = $1;
293         }
294 |       LFREG
295         {
296                 $$ = nullgen;
297                 $$.type = $1;
298         }
299 |       LLREG
300         {
301                 $$ = nullgen;
302                 $$.type = $1;
303         }
304 |       LSP
305         {
306                 $$ = nullgen;
307                 $$.type = D_SP;
308         }
309 |       LSREG
310         {
311                 $$ = nullgen;
312                 $$.type = $1;
313         }
314
315 imm:
316         '$' con
317         {
318                 $$ = nullgen;
319                 $$.type = D_CONST;
320                 $$.offset = $2;
321         }
322 |       '$' nam
323         {
324                 $$ = $2;
325                 $$.index = $2.type;
326                 $$.type = D_ADDR;
327                 /*
328                 if($2.type == D_AUTO || $2.type == D_PARAM)
329                         yyerror("constant cannot be automatic: %s",
330                                 $2.sym->name);
331                  */
332         }
333 |       '$' LSCONST
334         {
335                 $$ = nullgen;
336                 $$.type = D_SCONST;
337                 memcpy($$.sval, $2, sizeof($$.sval));
338         }
339 |       '$' LFCONST
340         {
341                 $$ = nullgen;
342                 $$.type = D_FCONST;
343                 $$.dval = $2;
344         }
345 |       '$' '(' LFCONST ')'
346         {
347                 $$ = nullgen;
348                 $$.type = D_FCONST;
349                 $$.dval = $3;
350         }
351 |       '$' '-' LFCONST
352         {
353                 $$ = nullgen;
354                 $$.type = D_FCONST;
355                 $$.dval = -$3;
356         }
357
358 imm2:
359         '$' con2
360         {
361                 $$ = nullgen;
362                 $$.type = D_CONST2;
363                 $$.offset = $2.v1;
364                 $$.offset2 = $2.v2;
365         }
366
367 con2:
368         LCONST
369         {
370                 $$.v1 = $1;
371                 $$.v2 = 0;
372         }
373 |       '-' LCONST
374         {
375                 $$.v1 = -$2;
376                 $$.v2 = 0;
377         }
378 |       LCONST '-' LCONST
379         {
380                 $$.v1 = $1;
381                 $$.v2 = $3;
382         }
383 |       '-' LCONST '-' LCONST
384         {
385                 $$.v1 = -$2;
386                 $$.v2 = $4;
387         }
388
389 mem:
390         omem
391 |       nmem
392
393 omem:
394         con
395         {
396                 $$ = nullgen;
397                 $$.type = D_INDIR+D_NONE;
398                 $$.offset = $1;
399         }
400 |       con '(' LLREG ')'
401         {
402                 $$ = nullgen;
403                 $$.type = D_INDIR+$3;
404                 $$.offset = $1;
405         }
406 |       con '(' LSP ')'
407         {
408                 $$ = nullgen;
409                 $$.type = D_INDIR+D_SP;
410                 $$.offset = $1;
411         }
412 |       con '(' LLREG '*' con ')'
413         {
414                 $$ = nullgen;
415                 $$.type = D_INDIR+D_NONE;
416                 $$.offset = $1;
417                 $$.index = $3;
418                 $$.scale = $5;
419                 checkscale($$.scale);
420         }
421 |       con '(' LLREG ')' '(' LLREG '*' con ')'
422         {
423                 $$ = nullgen;
424                 $$.type = D_INDIR+$3;
425                 $$.offset = $1;
426                 $$.index = $6;
427                 $$.scale = $8;
428                 checkscale($$.scale);
429         }
430 |       '(' LLREG ')'
431         {
432                 $$ = nullgen;
433                 $$.type = D_INDIR+$2;
434         }
435 |       '(' LSP ')'
436         {
437                 $$ = nullgen;
438                 $$.type = D_INDIR+D_SP;
439         }
440 |       con '(' LSREG ')'
441         {
442                 $$ = nullgen;
443                 $$.type = D_INDIR+$3;
444                 $$.offset = $1;
445         }
446 |       '(' LLREG '*' con ')'
447         {
448                 $$ = nullgen;
449                 $$.type = D_INDIR+D_NONE;
450                 $$.index = $2;
451                 $$.scale = $4;
452                 checkscale($$.scale);
453         }
454 |       '(' LLREG ')' '(' LLREG '*' con ')'
455         {
456                 $$ = nullgen;
457                 $$.type = D_INDIR+$2;
458                 $$.index = $5;
459                 $$.scale = $7;
460                 checkscale($$.scale);
461         }
462
463 nmem:
464         nam
465         {
466                 $$ = $1;
467         }
468 |       nam '(' LLREG '*' con ')'
469         {
470                 $$ = $1;
471                 $$.index = $3;
472                 $$.scale = $5;
473                 checkscale($$.scale);
474         }
475
476 nam:
477         LNAME offset '(' pointer ')'
478         {
479                 $$ = nullgen;
480                 $$.type = $4;
481                 $$.sym = $1;
482                 $$.offset = $2;
483         }
484 |       LNAME '<' '>' offset '(' LSB ')'
485         {
486                 $$ = nullgen;
487                 $$.type = D_STATIC;
488                 $$.sym = $1;
489                 $$.offset = $4;
490         }
491
492 offset:
493         {
494                 $$ = 0;
495         }
496 |       '+' con
497         {
498                 $$ = $2;
499         }
500 |       '-' con
501         {
502                 $$ = -$2;
503         }
504
505 pointer:
506         LSB
507 |       LSP
508         {
509                 $$ = D_AUTO;
510         }
511 |       LFP
512
513 con:
514         LCONST
515 |       LVAR
516         {
517                 $$ = $1->value;
518         }
519 |       '-' con
520         {
521                 $$ = -$2;
522         }
523 |       '+' con
524         {
525                 $$ = $2;
526         }
527 |       '~' con
528         {
529                 $$ = ~$2;
530         }
531 |       '(' expr ')'
532         {
533                 $$ = $2;
534         }
535
536 expr:
537         con
538 |       expr '+' expr
539         {
540                 $$ = $1 + $3;
541         }
542 |       expr '-' expr
543         {
544                 $$ = $1 - $3;
545         }
546 |       expr '*' expr
547         {
548                 $$ = $1 * $3;
549         }
550 |       expr '/' expr
551         {
552                 $$ = $1 / $3;
553         }
554 |       expr '%' expr
555         {
556                 $$ = $1 % $3;
557         }
558 |       expr '<' '<' expr
559         {
560                 $$ = $1 << $4;
561         }
562 |       expr '>' '>' expr
563         {
564                 $$ = $1 >> $4;
565         }
566 |       expr '&' expr
567         {
568                 $$ = $1 & $3;
569         }
570 |       expr '^' expr
571         {
572                 $$ = $1 ^ $3;
573         }
574 |       expr '|' expr
575         {
576                 $$ = $1 | $3;
577         }