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