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