]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/5a/a.y
9bootfat: rename open() to fileinit and make it static as its really a internal funct...
[plan9front.git] / sys / src / cmd / 5a / a.y
1 %{
2 #include "a.h"
3 %}
4 %union
5 {
6         Sym     *sym;
7         long    lval;
8         double  dval;
9         char    sval[8];
10         Gen     gen;
11 }
12 %left   '|'
13 %left   '^'
14 %left   '&'
15 %left   '<' '>'
16 %left   '+' '-'
17 %left   '*' '/' '%'
18 %token  <lval>  LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
19 %token  <lval>  LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
20 %token  <lval>  LTYPEB LTYPEC LTYPED LTYPEE LTYPEF
21 %token  <lval>  LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
22 %token  <lval>  LTYPEL LTYPEM LTYPEN LTYPEBX
23 %token  <lval>  LCONST LSP LSB LFP LPC
24 %token  <lval>  LTYPEX LR LREG LF LFREG LC LCREG LPSR LFCR
25 %token  <lval>  LCOND LS LAT
26 %token  <dval>  LFCONST
27 %token  <sval>  LSCONST
28 %token  <sym>   LNAME LLAB LVAR
29 %type   <lval>  con expr oexpr pointer offset sreg spreg creg
30 %type   <lval>  rcon cond reglist
31 %type   <gen>   gen rel reg regreg freg shift fcon frcon
32 %type   <gen>   imm ximm name oreg ireg nireg ioreg imsr
33 %%
34 prog:
35 |       prog line
36
37 line:
38         LLAB ':'
39         {
40                 if($1->value != pc)
41                         yyerror("redeclaration of %s", $1->name);
42                 $1->value = pc;
43         }
44         line
45 |       LNAME ':'
46         {
47                 $1->type = LLAB;
48                 $1->value = pc;
49         }
50         line
51 |       LNAME '=' expr ';'
52         {
53                 $1->type = LVAR;
54                 $1->value = $3;
55         }
56 |       LVAR '=' expr ';'
57         {
58                 if($1->value != $3)
59                         yyerror("redeclaration of %s", $1->name);
60                 $1->value = $3;
61         }
62 |       ';'
63 |       inst ';'
64 |       error ';'
65
66 inst:
67 /*
68  * ADD
69  */
70         LTYPE1 cond imsr ',' spreg ',' reg
71         {
72                 outcode($1, $2, &$3, $5, &$7);
73         }
74 |       LTYPE1 cond imsr ',' spreg ','
75         {
76                 outcode($1, $2, &$3, $5, &nullgen);
77         }
78 |       LTYPE1 cond imsr ',' reg
79         {
80                 outcode($1, $2, &$3, NREG, &$5);
81         }
82 /*
83  * MVN
84  */
85 |       LTYPE2 cond imsr ',' reg
86         {
87                 outcode($1, $2, &$3, NREG, &$5);
88         }
89 /*
90  * MOVW
91  */
92 |       LTYPE3 cond gen ',' gen
93         {
94                 outcode($1, $2, &$3, NREG, &$5);
95         }
96 /*
97  * B/BL
98  */
99 |       LTYPE4 cond comma rel
100         {
101                 outcode($1, $2, &nullgen, NREG, &$4);
102         }
103 |       LTYPE4 cond comma nireg
104         {
105                 outcode($1, $2, &nullgen, NREG, &$4);
106         }
107 /*
108  * BX
109  */
110 |       LTYPEBX comma ireg
111         {
112                 outcode($1, Always, &nullgen, NREG, &$3);
113         }
114 /*
115  * BEQ
116  */
117 |       LTYPE5 comma rel
118         {
119                 outcode($1, Always, &nullgen, NREG, &$3);
120         }
121 /*
122  * SWI
123  */
124 |       LTYPE6 cond comma gen
125         {
126                 outcode($1, $2, &nullgen, NREG, &$4);
127         }
128 /*
129  * CMP
130  */
131 |       LTYPE7 cond imsr ',' spreg comma
132         {
133                 outcode($1, $2, &$3, $5, &nullgen);
134         }
135 /*
136  * MOVM
137  */
138 |       LTYPE8 cond ioreg ',' '[' reglist ']'
139         {
140                 Gen g;
141
142                 g = nullgen;
143                 g.type = D_CONST;
144                 g.offset = $6;
145                 outcode($1, $2, &$3, NREG, &g);
146         }
147 |       LTYPE8 cond '[' reglist ']' ',' ioreg
148         {
149                 Gen g;
150
151                 g = nullgen;
152                 g.type = D_CONST;
153                 g.offset = $4;
154                 outcode($1, $2, &g, NREG, &$7);
155         }
156 /*
157  * SWAP
158  */
159 |       LTYPE9 cond reg ',' ireg ',' reg
160         {
161                 outcode($1, $2, &$5, $3.reg, &$7);
162         }
163 |       LTYPE9 cond reg ',' ireg comma
164         {
165                 outcode($1, $2, &$5, $3.reg, &$3);
166         }
167 |       LTYPE9 cond comma ireg ',' reg
168         {
169                 outcode($1, $2, &$4, $6.reg, &$6);
170         }
171 /*
172  * RET
173  */
174 |       LTYPEA cond comma
175         {
176                 outcode($1, $2, &nullgen, NREG, &nullgen);
177         }
178 /*
179  * TEXT/GLOBL
180  */
181 |       LTYPEB name ',' imm
182         {
183                 outcode($1, Always, &$2, NREG, &$4);
184         }
185 |       LTYPEB name ',' con ',' imm
186         {
187                 outcode($1, Always, &$2, $4, &$6);
188         }
189 /*
190  * DATA
191  */
192 |       LTYPEC name '/' con ',' ximm
193         {
194                 outcode($1, Always, &$2, $4, &$6);
195         }
196 /*
197  * CASE
198  */
199 |       LTYPED cond reg comma
200         {
201                 outcode($1, $2, &$3, NREG, &nullgen);
202         }
203 /*
204  * word
205  */
206 |       LTYPEH comma ximm
207         {
208                 outcode($1, Always, &nullgen, NREG, &$3);
209         }
210 /*
211  * floating-point coprocessor
212  */
213 |       LTYPEI cond freg ',' freg
214         {
215                 outcode($1, $2, &$3, NREG, &$5);
216         }
217 |       LTYPEK cond frcon ',' freg
218         {
219                 outcode($1, $2, &$3, NREG, &$5);
220         }
221 |       LTYPEK cond frcon ',' LFREG ',' freg
222         {
223                 outcode($1, $2, &$3, $5, &$7);
224         }
225 |       LTYPEL cond freg ',' freg comma
226         {
227                 outcode($1, $2, &$3, $5.reg, &nullgen);
228         }
229 /*
230  * MCR MRC
231  */
232 |       LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
233         {
234                 Gen g;
235
236                 g = nullgen;
237                 g.type = D_CONST;
238                 g.offset =
239                         (0xe << 24) |           /* opcode */
240                         ($1 << 20) |            /* MCR/MRC */
241                         ($2 << 28) |            /* scond */
242                         (($3 & 15) << 8) |      /* coprocessor number */
243                         (($5 & 7) << 21) |      /* coprocessor operation */
244                         (($7 & 15) << 12) |     /* arm register */
245                         (($9 & 15) << 16) |     /* Crn */
246                         (($11 & 15) << 0) |     /* Crm */
247                         (($12 & 7) << 5) |      /* coprocessor information */
248                         (1<<4);                 /* must be set */
249                 outcode(AWORD, Always, &nullgen, NREG, &g);
250         }
251 /*
252  * MULL hi,lo,r1,r2
253  */
254 |       LTYPEM cond reg ',' reg ',' regreg
255         {
256                 outcode($1, $2, &$3, $5.reg, &$7);
257         }
258 /*
259  * MULA hi,lo,r1,r2
260  */
261 |       LTYPEN cond reg ',' reg ',' reg ',' spreg 
262         {
263                 $7.type = D_REGREG;
264                 $7.offset = $9;
265                 outcode($1, $2, &$3, $5.reg, &$7);
266         }
267 /*
268  * END
269  */
270 |       LTYPEE comma
271         {
272                 outcode($1, Always, &nullgen, NREG, &nullgen);
273         }
274
275 cond:
276         {
277                 $$ = Always;
278         }
279 |       cond LCOND
280         {
281                 $$ = ($1 & ~C_SCOND) | $2;
282         }
283 |       cond LS
284         {
285                 $$ = $1 | $2;
286         }
287
288 comma:
289 |       ',' comma
290
291 rel:
292         con '(' LPC ')'
293         {
294                 $$ = nullgen;
295                 $$.type = D_BRANCH;
296                 $$.offset = $1 + pc;
297         }
298 |       LNAME offset
299         {
300                 $$ = nullgen;
301                 if(pass == 2)
302                         yyerror("undefined label: %s", $1->name);
303                 $$.type = D_BRANCH;
304                 $$.sym = $1;
305                 $$.offset = $2;
306         }
307 |       LLAB offset
308         {
309                 $$ = nullgen;
310                 $$.type = D_BRANCH;
311                 $$.sym = $1;
312                 $$.offset = $1->value + $2;
313         }
314
315 ximm:   '$' con
316         {
317                 $$ = nullgen;
318                 $$.type = D_CONST;
319                 $$.offset = $2;
320         }
321 |       '$' oreg
322         {
323                 $$ = $2;
324                 $$.type = D_CONST;
325         }
326 |       '$' '*' '$' oreg
327         {
328                 $$ = $4;
329                 $$.type = D_OCONST;
330         }
331 |       '$' LSCONST
332         {
333                 $$ = nullgen;
334                 $$.type = D_SCONST;
335                 memcpy($$.sval, $2, sizeof($$.sval));
336         }
337 |       fcon
338
339 fcon:
340         '$' LFCONST
341         {
342                 $$ = nullgen;
343                 $$.type = D_FCONST;
344                 $$.dval = $2;
345         }
346 |       '$' '-' LFCONST
347         {
348                 $$ = nullgen;
349                 $$.type = D_FCONST;
350                 $$.dval = -$3;
351         }
352
353 reglist:
354         spreg
355         {
356                 $$ = 1 << $1;
357         }
358 |       spreg '-' spreg
359         {
360                 int i;
361                 $$=0;
362                 for(i=$1; i<=$3; i++)
363                         $$ |= 1<<i;
364                 for(i=$3; i<=$1; i++)
365                         $$ |= 1<<i;
366         }
367 |       spreg comma reglist
368         {
369                 $$ = (1<<$1) | $3;
370         }
371
372 gen:
373         reg
374 |       ximm
375 |       shift
376 |       shift '(' spreg ')'
377         {
378                 $$ = $1;
379                 $$.reg = $3;
380         }
381 |       LPSR
382         {
383                 $$ = nullgen;
384                 $$.type = D_PSR;
385                 $$.reg = $1;
386         }
387 |       LFCR
388         {
389                 $$ = nullgen;
390                 $$.type = D_FPCR;
391                 $$.reg = $1;
392         }
393 |       con
394         {
395                 $$ = nullgen;
396                 $$.type = D_OREG;
397                 $$.offset = $1;
398         }
399 |       oreg
400 |       freg
401
402 nireg:
403         ireg
404 |       name
405         {
406                 $$ = $1;
407                 if($1.name != D_EXTERN && $1.name != D_STATIC) {
408                 }
409         }
410
411 ireg:
412         '(' spreg ')'
413         {
414                 $$ = nullgen;
415                 $$.type = D_OREG;
416                 $$.reg = $2;
417                 $$.offset = 0;
418         }
419
420 ioreg:
421         ireg
422 |       con '(' sreg ')'
423         {
424                 $$ = nullgen;
425                 $$.type = D_OREG;
426                 $$.reg = $3;
427                 $$.offset = $1;
428         }
429
430 oreg:
431         name
432 |       name '(' sreg ')'
433         {
434                 $$ = $1;
435                 $$.type = D_OREG;
436                 $$.reg = $3;
437         }
438 |       ioreg
439
440 imsr:
441         reg
442 |       imm
443 |       shift
444
445 imm:    '$' con
446         {
447                 $$ = nullgen;
448                 $$.type = D_CONST;
449                 $$.offset = $2;
450         }
451
452 reg:
453         spreg
454         {
455                 $$ = nullgen;
456                 $$.type = D_REG;
457                 $$.reg = $1;
458         }
459
460 regreg:
461         '(' spreg ',' spreg ')'
462         {
463                 $$ = nullgen;
464                 $$.type = D_REGREG;
465                 $$.reg = $2;
466                 $$.offset = $4;
467         }
468
469 shift:
470         spreg '<' '<' rcon
471         {
472                 $$ = nullgen;
473                 $$.type = D_SHIFT;
474                 $$.offset = $1 | $4 | (0 << 5);
475         }
476 |       spreg '>' '>' rcon
477         {
478                 $$ = nullgen;
479                 $$.type = D_SHIFT;
480                 $$.offset = $1 | $4 | (1 << 5);
481         }
482 |       spreg '-' '>' rcon
483         {
484                 $$ = nullgen;
485                 $$.type = D_SHIFT;
486                 $$.offset = $1 | $4 | (2 << 5);
487         }
488 |       spreg LAT '>' rcon
489         {
490                 $$ = nullgen;
491                 $$.type = D_SHIFT;
492                 $$.offset = $1 | $4 | (3 << 5);
493         }
494
495 rcon:
496         spreg
497         {
498                 if($$ < 0 || $$ >= 16)
499                         print("register value out of range\n");
500                 $$ = (($1&15) << 8) | (1 << 4);
501         }
502 |       con
503         {
504                 if($$ < 0 || $$ >= 32)
505                         print("shift value out of range\n");
506                 $$ = ($1&31) << 7;
507         }
508
509 sreg:
510         LREG
511 |       LPC
512         {
513                 $$ = REGPC;
514         }
515 |       LR '(' expr ')'
516         {
517                 if($3 < 0 || $3 >= NREG)
518                         print("register value out of range\n");
519                 $$ = $3;
520         }
521
522 spreg:
523         sreg
524 |       LSP
525         {
526                 $$ = REGSP;
527         }
528
529 creg:
530         LCREG
531 |       LC '(' expr ')'
532         {
533                 if($3 < 0 || $3 >= NREG)
534                         print("register value out of range\n");
535                 $$ = $3;
536         }
537
538 frcon:
539         freg
540 |       fcon
541
542 freg:
543         LFREG
544         {
545                 $$ = nullgen;
546                 $$.type = D_FREG;
547                 $$.reg = $1;
548         }
549 |       LF '(' con ')'
550         {
551                 $$ = nullgen;
552                 $$.type = D_FREG;
553                 $$.reg = $3;
554         }
555
556 name:
557         con '(' pointer ')'
558         {
559                 $$ = nullgen;
560                 $$.type = D_OREG;
561                 $$.name = $3;
562                 $$.sym = S;
563                 $$.offset = $1;
564         }
565 |       LNAME offset '(' pointer ')'
566         {
567                 $$ = nullgen;
568                 $$.type = D_OREG;
569                 $$.name = $4;
570                 $$.sym = $1;
571                 $$.offset = $2;
572         }
573 |       LNAME '<' '>' offset '(' LSB ')'
574         {
575                 $$ = nullgen;
576                 $$.type = D_OREG;
577                 $$.name = D_STATIC;
578                 $$.sym = $1;
579                 $$.offset = $4;
580         }
581
582 offset:
583         {
584                 $$ = 0;
585         }
586 |       '+' con
587         {
588                 $$ = $2;
589         }
590 |       '-' con
591         {
592                 $$ = -$2;
593         }
594
595 pointer:
596         LSB
597 |       LSP
598 |       LFP
599
600 con:
601         LCONST
602 |       LVAR
603         {
604                 $$ = $1->value;
605         }
606 |       '-' con
607         {
608                 $$ = -$2;
609         }
610 |       '+' con
611         {
612                 $$ = $2;
613         }
614 |       '~' con
615         {
616                 $$ = ~$2;
617         }
618 |       '(' expr ')'
619         {
620                 $$ = $2;
621         }
622
623 oexpr:
624         {
625                 $$ = 0;
626         }
627 |       ',' expr
628         {
629                 $$ = $2;
630         }
631
632 expr:
633         con
634 |       expr '+' expr
635         {
636                 $$ = $1 + $3;
637         }
638 |       expr '-' expr
639         {
640                 $$ = $1 - $3;
641         }
642 |       expr '*' expr
643         {
644                 $$ = $1 * $3;
645         }
646 |       expr '/' expr
647         {
648                 $$ = $1 / $3;
649         }
650 |       expr '%' expr
651         {
652                 $$ = $1 % $3;
653         }
654 |       expr '<' '<' expr
655         {
656                 $$ = $1 << $4;
657         }
658 |       expr '>' '>' expr
659         {
660                 $$ = $1 >> $4;
661         }
662 |       expr '&' expr
663         {
664                 $$ = $1 & $3;
665         }
666 |       expr '^' expr
667         {
668                 $$ = $1 ^ $3;
669         }
670 |       expr '|' expr
671         {
672                 $$ = $1 | $3;
673         }