]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/7a/a.y
upas/fs: remove useless loop in rf822()
[plan9front.git] / sys / src / cmd / 7a / a.y
1 %{
2 #include "a.h"
3 %}
4 %union
5 {
6         Sym     *sym;
7         vlong   lval;
8         double  dval;
9         char    sval[NSNAME];
10         Gen     gen;
11 }
12 %left   '|'
13 %left   '^'
14 %left   '&'
15 %left   '<' '>'
16 %left   '+' '-'
17 %left   '*' '/' '%'
18 %token  <lval>  LTYPE0 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 LTYPEO LTYPEP LTYPEQ
23 %token  <lval>  LTYPER LTYPES LTYPET LTYPEU LTYPEV LTYPEW LTYPEX LTYPEY LTYPEZ
24 %token  <lval>  LMOVK LDMB LSTXR
25 %token  <lval>  LCONST LSP LSB LFP LPC
26 %token  <lval>  LR LREG LF LFREG LV LVREG LC LCREG LFCR LFCSEL
27 %token  <lval>  LCOND LS LAT LEXT LSPR LSPREG LVTYPE
28 %token  <dval>  LFCONST
29 %token  <sval>  LSCONST
30 %token  <sym>   LNAME LLAB LVAR
31 %type   <lval>  con expr pointer offset sreg spreg
32 %type   <lval>  scon indexreg vset vreglist
33 %type   <gen>   gen rel reg freg vreg shift fcon frcon extreg vlane vgen
34 %type   <gen>   imm ximm name oreg nireg ioreg imsr spr cond sysarg
35 %%
36 prog:
37 |       prog line
38
39 line:
40         LLAB ':'
41         {
42                 if($1->value != pc)
43                         yyerror("redeclaration of %s", $1->name);
44                 $1->value = pc;
45         }
46         line
47 |       LNAME ':'
48         {
49                 $1->type = LLAB;
50                 $1->value = pc;
51         }
52         line
53 |       LNAME '=' expr ';'
54         {
55                 $1->type = LVAR;
56                 $1->value = $3;
57         }
58 |       LVAR '=' expr ';'
59         {
60                 if($1->value != $3)
61                         yyerror("redeclaration of %s", $1->name);
62                 $1->value = $3;
63         }
64 |       ';'
65 |       inst ';'
66 |       error ';'
67
68 inst:
69 /*
70  * ERET
71  */
72         LTYPE0 comma
73         {
74                 outcode($1, &nullgen, NREG, &nullgen);
75         }
76 /*
77  * ADD
78  */
79 |       LTYPE1 imsr ',' spreg ',' reg
80         {
81                 outcode($1, &$2, $4, &$6);
82         }
83 |       LTYPE1 imsr ',' spreg ','
84         {
85                 outcode($1, &$2, $4, &nullgen);
86         }
87 |       LTYPE1 imsr ',' reg
88         {
89                 outcode($1, &$2, NREG, &$4);
90         }
91 /*
92  * CLS
93  */
94 |       LTYPE2 imsr ',' reg
95         {
96                 outcode($1, &$2, NREG, &$4);
97         }
98 /*
99  * MOV
100  */
101 |       LTYPE3 gen ',' gen
102         {
103                 outcode($1, &$2, NREG, &$4);
104         }
105 /*
106  * MOVK
107  */
108 |       LMOVK imm ',' reg
109         {
110                 outcode($1, &$2, NREG, &$4);
111         }
112 |       LMOVK imm '<' '<' con ',' reg
113         {
114                 Gen g;
115                 g = nullgen;
116                 g.type = D_CONST;
117                 g.offset = $5;
118                 outcode4($1, &$2, NREG, &g, &$7);
119         }
120 /*
121  * B/BL
122  */
123 |       LTYPE4 comma rel
124         {
125                 outcode($1, &nullgen, NREG, &$3);
126         }
127 |       LTYPE4 comma nireg
128         {
129                 outcode($1, &nullgen, NREG, &$3);
130         }
131 /*
132  * BEQ
133  */
134 |       LTYPE5 comma rel
135         {
136                 outcode($1, &nullgen, NREG, &$3);
137         }
138 /*
139  * SVC
140  */
141 |       LTYPE6 comma gen
142         {
143                 outcode($1, &nullgen, NREG, &$3);
144         }
145 |       LTYPE6
146         {
147                 outcode($1, &nullgen, NREG, &nullgen);
148         }
149 /*
150  * CMP
151  */
152 |       LTYPE7 imsr ',' spreg comma
153         {
154                 outcode($1, &$2, $4, &nullgen);
155         }
156 /*
157  * CBZ
158  */
159 |       LTYPE8 reg ',' rel
160         {
161                 outcode($1, &$2, NREG, &$4);
162         }
163 /*
164  * CSET
165  */
166 |       LTYPER cond ',' reg
167         {
168                 outcode($1, &$2, NREG, &$4);
169         }
170 /*
171  * CSEL/CINC/CNEG/CINV
172  */
173 |       LTYPES cond ',' reg ',' reg ',' reg
174         {
175                 outcode4($1, &$2, $6.reg, &$4, &$8);
176         }
177 |       LTYPES cond ',' reg ',' reg
178         {
179                 outcode($1, &$2, $4.reg, &$6);
180         }
181 /*
182  * TBZ
183  */
184 |       LTYPET imm ',' reg ',' rel
185         {
186                 outcode($1, &$2, $4.reg, &$6);
187         }
188 /*
189  * CCMN
190  */
191 |       LTYPEU cond ',' imsr ',' reg ',' imm comma
192         {
193                 outcode4($1, &$2, $6.reg, &$4, &$8);
194         }
195 /*
196  * ADR
197  */
198 |       LTYPEV rel ',' reg
199         {
200                 outcode($1, &$2, NREG, &$4);
201         }
202 |       LTYPEV '$' name ',' reg
203         {
204                 outcode($1, &$3, NREG, &$5);
205         }
206 /*
207  * BFM/BFI
208  */
209 |       LTYPEY imm ',' imm ',' spreg ',' reg
210         {
211                 outcode4($1, &$2, $6, &$4, &$8);
212         }
213 /*
214  * EXTR
215  */
216 |       LTYPEP imm ',' reg ',' spreg ',' reg
217         {
218                 outcode4($1, &$2, $6, &$4, &$8);
219         }
220 /*
221  * RET/RETURN
222  */
223 |       LTYPEA comma
224         {
225                 outcode($1, &nullgen, NREG, &nullgen);
226         }
227 |       LTYPEA reg
228         {
229                 outcode($1, &nullgen, NREG, &$2);
230         }
231 /*
232  * NOP
233  */
234 |       LTYPEQ comma
235         {
236                 outcode($1, &nullgen, NREG, &nullgen);
237         }
238 |       LTYPEQ reg comma
239         {
240                 outcode($1, &$2, NREG, &nullgen);
241         }
242 |       LTYPEQ freg comma
243         {
244                 outcode($1, &$2, NREG, &nullgen);
245         }
246 |       LTYPEQ ',' reg
247         {
248                 outcode($1, &nullgen, NREG, &$3);
249         }
250 |       LTYPEQ ',' freg
251         {
252                 outcode($1, &nullgen, NREG, &$3);
253         }
254 /*
255  * TEXT/GLOBL
256  */
257 |       LTYPEB name ',' imm
258         {
259                 outcode($1, &$2, NREG, &$4);
260         }
261 |       LTYPEB name ',' con ',' imm
262         {
263                 outcode($1, &$2, $4, &$6);
264         }
265 /*
266  * DATA
267  */
268 |       LTYPEC name '/' con ',' ximm
269         {
270                 outcode($1, &$2, $4, &$6);
271         }
272 /*
273  * CASE
274  */
275 |       LTYPED reg ',' reg
276         {
277                 outcode($1, &$2, NREG, &$4);
278         }
279 /*
280  * word
281  */
282 |       LTYPEH comma ximm
283         {
284                 outcode($1, &nullgen, NREG, &$3);
285         }
286 /*
287  * floating-point
288  */
289 |       LTYPEI freg ',' freg
290         {
291                 outcode($1, &$2, NREG, &$4);
292         }
293 /*
294  * FADDD
295  */
296 |       LTYPEK frcon ',' freg
297         {
298                 outcode($1, &$2, NREG, &$4);
299         }
300 |       LTYPEK frcon ',' freg ',' freg
301         {
302                 outcode($1, &$2, $4.reg, &$6);
303         }
304 /*
305  * FCMP
306  */
307 |       LTYPEL frcon ',' freg comma
308         {
309                 outcode($1, &$2, $4.reg, &nullgen);
310         }
311 /*
312  * FCCMP
313  */
314 |       LTYPEF cond ',' freg ',' freg ',' imm comma
315         {
316                 outcode4($1, &$2, $6.reg, &$4, &$8);
317         }
318 /*
319  * FMULA
320  */
321 |       LTYPE9 freg ',' freg ', ' freg ',' freg comma
322         {
323                 outcode4($1, &$2, $4.reg, &$6, &$8);
324         }
325 /*
326  * FCSEL
327  */
328 |       LFCSEL cond ',' freg ',' freg ',' freg
329         {
330                 outcode4($1, &$2, $6.reg, &$4, &$8);
331         }
332 /*
333  * SIMD
334  */
335 |       LTYPEW vgen ',' vgen
336         {
337                 outcode($1, &$2, NREG, &$4);
338         }
339 |       LTYPEW vgen ',' vgen ',' vgen
340         {
341                 outcode($1, &$2, $4.reg, &$6);
342         }
343 /*
344  * MOVP/MOVNP
345  */
346 |       LTYPEJ gen ',' sreg ',' gen
347         {
348                 outcode($1, &$2, $4, &$6);
349         }
350 /*
351  * MADD Rn,Rm,Ra,Rd
352  */
353 |       LTYPEM reg ',' reg ',' sreg ',' reg
354         {
355                 outcode4($1, &$2, $6, &$4, &$8);
356         }
357 /*
358  * SYS/SYSL
359  */
360 |       LTYPEN sysarg
361         {
362                 outcode($1, &$2, NREG, &nullgen);
363         }
364 |       LTYPEN reg ',' sysarg
365         {
366                 outcode($1, &$4, $2.reg, &nullgen);
367         }
368 |       LTYPEO sysarg ',' reg
369         {
370                 outcode($1, &$2, NREG, &$4);
371         }
372 /*
373  * DMB, HINT
374  */
375 |       LDMB imm
376         {
377                 outcode($1, &$2, NREG, &nullgen);
378         }
379 /*
380  * STXR
381  */
382 |       LSTXR reg ',' gen ',' sreg
383         {
384                 outcode($1, &$2, $6, &$4);
385         }
386 /*
387  * END
388  */
389 |       LTYPEE comma
390         {
391                 outcode($1, &nullgen, NREG, &nullgen);
392         }
393
394 cond:
395         LCOND
396         {
397                 $$ = nullgen;
398                 $$.type = D_COND;
399                 $$.reg = $1;
400         }
401
402 comma:
403 |       ',' comma
404
405 sysarg:
406         con ',' con ',' con ',' con
407         {
408                 $$ = nullgen;
409                 $$.type = D_CONST;
410                 $$.offset = SYSARG4($1, $3, $5, $7);
411         }
412 |       imm
413
414 rel:
415         con '(' LPC ')'
416         {
417                 $$ = nullgen;
418                 $$.type = D_BRANCH;
419                 $$.offset = $1 + pc;
420         }
421 |       LNAME offset
422         {
423                 $$ = nullgen;
424                 if(pass == 2)
425                         yyerror("undefined label: %s", $1->name);
426                 $$.type = D_BRANCH;
427                 $$.sym = $1;
428                 $$.offset = $2;
429         }
430 |       LLAB offset
431         {
432                 $$ = nullgen;
433                 $$.type = D_BRANCH;
434                 $$.sym = $1;
435                 $$.offset = $1->value + $2;
436         }
437
438 ximm:   '$' con
439         {
440                 $$ = nullgen;
441                 $$.type = D_CONST;
442                 $$.offset = $2;
443         }
444 |       '$' oreg
445         {
446                 $$ = $2;
447                 $$.type = D_CONST;
448         }
449 |       '$' '*' '$' oreg
450         {
451                 $$ = $4;
452                 $$.type = D_OCONST;
453         }
454 |       '$' LSCONST
455         {
456                 $$ = nullgen;
457                 $$.type = D_SCONST;
458                 memmove($$.sval, $2, sizeof($$.sval));
459         }
460 |       fcon
461
462 fcon:
463         '$' LFCONST
464         {
465                 $$ = nullgen;
466                 $$.type = D_FCONST;
467                 $$.dval = $2;
468         }
469 |       '$' '-' LFCONST
470         {
471                 $$ = nullgen;
472                 $$.type = D_FCONST;
473                 $$.dval = -$3;
474         }
475
476 gen:
477         reg
478 |       ximm
479 |       LFCR
480         {
481                 $$ = nullgen;
482                 $$.type = D_SPR;
483                 $$.offset = $1;
484         }
485 |       con
486         {
487                 $$ = nullgen;
488                 $$.type = D_OREG;
489                 $$.offset = $1;
490         }
491 |       oreg
492 |       freg
493 |       vreg
494 |       spr
495
496 nireg:
497         '(' sreg ')'
498         {
499                 $$ = nullgen;
500                 $$.type = D_OREG;
501                 $$.reg = $2;
502                 $$.offset = 0;
503         }
504 |       name
505         {
506                 $$ = $1;
507                 if($1.name != D_EXTERN && $1.name != D_STATIC) {
508                 }
509         }
510
511 oreg:
512         name
513 |       name '(' sreg ')'
514         {
515                 $$ = $1;
516                 $$.type = D_OREG;
517                 $$.reg = $3;
518         }
519 |       ioreg
520
521 ioreg:
522         '(' sreg ')'
523         {
524                 $$ = nullgen;
525                 $$.type = D_OREG;
526                 $$.reg = $2;
527                 $$.offset = 0;
528         }
529 |       con '(' sreg ')'
530         {
531                 $$ = nullgen;
532                 $$.type = D_OREG;
533                 $$.reg = $3;
534                 $$.offset = $1;
535         }
536 |       con '(' sreg ')' '!'
537         {
538                 $$ = nullgen;
539                 $$.type = D_XPRE;
540                 $$.reg = $3;
541                 $$.offset = $1;
542         }
543 |       '(' sreg ')' con '!'
544         {
545                 $$ = nullgen;
546                 $$.type = D_XPOST;
547                 $$.reg = $2;
548                 $$.offset = $4;
549         }
550 |       '(' sreg ')' '(' indexreg ')'
551         {
552                 $$ = nullgen;
553                 $$.type = D_ROFF;
554                 $$.reg = $2;
555                 $$.xreg = $5 & 0x1f;
556                 $$.offset = $5;
557         }
558 |       '(' sreg ')' '[' indexreg ']'
559         {
560                 $$ = nullgen;
561                 $$.type = D_ROFF;
562                 $$.reg = $2;
563                 $$.xreg = $5 & 0x1f;
564                 $$.offset = $5 | (1<<16);
565         }
566
567 imsr:
568         imm
569 |       shift
570 |       extreg
571
572 imm:    '$' con
573         {
574                 $$ = nullgen;
575                 $$.type = D_CONST;
576                 $$.offset = $2;
577         }
578
579 reg:
580         sreg
581         {
582                 $$ = nullgen;
583                 $$.type = D_REG;
584                 $$.reg = $1;
585         }
586 |       LSP
587         {
588                 $$ = nullgen;
589                 $$.type = D_SP;
590                 $$.reg = REGSP;
591         }
592
593 shift:
594         sreg '<' '<' scon
595         {
596                 $$ = nullgen;
597                 $$.type = D_SHIFT;
598                 $$.offset = ($1 << 16) | ($4 << 10) | (0 << 22);
599         }
600 |       sreg '>' '>' scon
601         {
602                 $$ = nullgen;
603                 $$.type = D_SHIFT;
604                 $$.offset = (($1&0x1F) << 16) | ($4 << 10) | (1 << 22);
605         }
606 |       sreg '-' '>' scon
607         {
608                 $$ = nullgen;
609                 $$.type = D_SHIFT;
610                 $$.offset = ($1 << 16) | ($4 << 10) | (2 << 22);
611         }
612 |       sreg LAT '>' scon
613         {
614                 $$ = nullgen;
615                 $$.type = D_SHIFT;
616                 $$.offset = ($1 << 16) | ($4 << 10) | (3 << 22);
617         }
618
619 extreg:
620         sreg
621         {
622                 $$ = nullgen;
623                 $$.type = D_REG;
624                 $$.reg = $1;
625         }
626 |       sreg LEXT
627         {
628                 $$ = nullgen;
629                 $$.type = D_EXTREG;
630                 $$.reg = $1;
631                 $$.offset = ($1 << 16) | ($2 << 13);
632         }
633 |       sreg LEXT '<' '<' con
634         {
635                 if($5 < 0 || $5 > 4)
636                         yyerror("shift value out of range");
637                 $$ = nullgen;
638                 $$.type = D_EXTREG;
639                 $$.reg = $1;
640                 $$.offset = ($1 << 16) | ($2 << 13) | ($5 << 10);
641         }
642
643 indexreg:
644         sreg
645         {
646                 $$ = (3 << 8) | $1;
647         }
648 |       sreg LEXT
649         {
650                 $$ = ($2 << 8) | $1;
651         }
652
653 scon:
654         con
655         {
656                 if($$ < 0 || $$ >= 64)
657                         yyerror("shift value out of range");
658                 $$ = $1&0x3F;
659         }
660
661 sreg:
662         LREG
663 |       LR '(' expr ')'
664         {
665                 if($3 < 0 || $3 >= NREG)
666                         print("register value out of range\n");
667                 $$ = $3;
668         }
669
670 spreg:
671         sreg
672 |       LSP
673         {
674                 $$ = REGSP;
675         }
676
677 spr:
678         LSPREG
679         {
680                 $$ = nullgen;
681                 $$.type = D_SPR;
682                 $$.offset = $1;
683         }
684 |       LSPR '(' con ')'
685         {
686                 $$ = nullgen;
687                 $$.type = $1;
688                 $$.offset = $3;
689         }
690
691 frcon:
692         freg
693 |       fcon
694
695 freg:
696         LFREG
697         {
698                 $$ = nullgen;
699                 $$.type = D_FREG;
700                 $$.reg = $1;
701         }
702 |       LF '(' con ')'
703         {
704                 $$ = nullgen;
705                 $$.type = D_FREG;
706                 $$.reg = $3;
707         }
708
709 vgen:
710         oreg
711 |       vreg
712 |       vlane
713 |       vset
714         {
715                 $$ = nullgen;
716                 $$.type = D_VSET;
717                 $$.offset = $1;
718         }
719
720 vlane:
721         vreg '[' con ']'
722         {
723                 $$.type = D_VLANE;
724                 $$.offset = $3;
725         }
726 |       vset '[' con ']'
727         {
728                 $$.type = D_VLANE;
729                 $$.offset = $3;
730         }
731
732 vset:
733         '{' vreglist '}'
734         {
735                 $$ = $2;
736         }
737
738 vreglist:
739         vreg
740         {
741                 $$ = 1 << $1.reg;
742         }
743 |       vreg '-' vreg
744         {
745                 int i;
746                 $$=0;
747                 for(i=$1.reg; i<=$3.reg; i++)
748                         $$ |= 1<<i;
749                 for(i=$3.reg; i<=$1.reg; i++)
750                         $$ |= 1<<i;
751         }
752 |       vreg comma vreglist
753         {
754                 $$ = (1<<$1.reg) | $3;
755         }
756
757 vreg:
758         LVREG
759         {
760                 $$ = nullgen;
761                 $$.type = D_VREG;
762                 $$.reg = $1;
763                 /* TO DO: slice */
764         }
765 |       LV '(' con ')'
766         {
767                 $$ = nullgen;
768                 $$.type = D_VREG;
769                 $$.reg = $3;
770         }
771
772 name:
773         con '(' pointer ')'
774         {
775                 $$ = nullgen;
776                 $$.type = D_OREG;
777                 $$.name = $3;
778                 $$.sym = S;
779                 $$.offset = $1;
780         }
781 |       LNAME offset '(' pointer ')'
782         {
783                 $$ = nullgen;
784                 $$.type = D_OREG;
785                 $$.name = $4;
786                 $$.sym = $1;
787                 $$.offset = $2;
788         }
789 |       LNAME '<' '>' offset '(' LSB ')'
790         {
791                 $$ = nullgen;
792                 $$.type = D_OREG;
793                 $$.name = D_STATIC;
794                 $$.sym = $1;
795                 $$.offset = $4;
796         }
797
798 offset:
799         {
800                 $$ = 0;
801         }
802 |       '+' con
803         {
804                 $$ = $2;
805         }
806 |       '-' con
807         {
808                 $$ = -$2;
809         }
810
811 pointer:
812         LSB
813 |       LSP
814 |       LFP
815
816 con:
817         LCONST
818 |       LVAR
819         {
820                 $$ = $1->value;
821         }
822 |       '-' con
823         {
824                 $$ = -$2;
825         }
826 |       '+' con
827         {
828                 $$ = $2;
829         }
830 |       '~' con
831         {
832                 $$ = ~$2;
833         }
834 |       '(' expr ')'
835         {
836                 $$ = $2;
837         }
838
839 expr:
840         con
841 |       expr '+' expr
842         {
843                 $$ = $1 + $3;
844         }
845 |       expr '-' expr
846         {
847                 $$ = $1 - $3;
848         }
849 |       expr '*' expr
850         {
851                 $$ = $1 * $3;
852         }
853 |       expr '/' expr
854         {
855                 $$ = $1 / $3;
856         }
857 |       expr '%' expr
858         {
859                 $$ = $1 % $3;
860         }
861 |       expr '<' '<' expr
862         {
863                 $$ = $1 << $4;
864         }
865 |       expr '>' '>' expr
866         {
867                 $$ = $1 >> $4;
868         }
869 |       expr '&' expr
870         {
871                 $$ = $1 & $3;
872         }
873 |       expr '^' expr
874         {
875                 $$ = $1 ^ $3;
876         }
877 |       expr '|' expr
878         {
879                 $$ = $1 | $3;
880         }