]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/va/a.y
rio, kbdfs: increase read buffer for high latency kbdfs support
[plan9front.git] / sys / src / cmd / va / 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>  LCONST LSP LSB LFP LPC LHI LLO LMREG 
23 %token  <lval>  LTYPEX LREG LFREG LFCREG LR LM LF
24 %token  <lval>  LFCR LSCHED
25 %token  <dval>  LFCONST
26 %token  <sval>  LSCONST
27 %token  <sym>   LNAME LLAB LVAR
28 %type   <lval>  con expr pointer offset sreg
29 %type   <gen>   gen vgen lgen vlgen rel reg freg mreg fcreg
30 %type   <gen>   imm ximm ireg name oreg imr nireg fgen
31 %%
32 prog:
33 |       prog line
34
35 line:
36         LLAB ':'
37         {
38                 if($1->value != pc)
39                         yyerror("redeclaration of %s", $1->name);
40                 $1->value = pc;
41         }
42         line
43 |       LNAME ':'
44         {
45                 $1->type = LLAB;
46                 $1->value = pc;
47         }
48         line
49 |       LNAME '=' expr ';'
50         {
51                 $1->type = LVAR;
52                 $1->value = $3;
53         }
54 |       LVAR '=' expr ';'
55         {
56                 if($1->value != $3)
57                         yyerror("redeclaration of %s", $1->name);
58                 $1->value = $3;
59         }
60 |       LSCHED ';'
61         {
62                 nosched = $1;
63         }
64 |       ';'
65 |       inst ';'
66 |       error ';'
67
68 inst:
69 /*
70  * Immed-type
71  */
72         LTYPE1 imr ',' sreg ',' reg
73         {
74                 outcode($1, &$2, $4, &$6);
75         }
76 |       LTYPE1 imr ',' reg
77         {
78                 outcode($1, &$2, NREG, &$4);
79         }
80 /*
81  * NOR
82  */
83 |       LTYPE2 imr ',' sreg ',' imr
84         {
85                 outcode($1, &$2, $4, &$6);
86         }
87 |       LTYPE2 imr ',' imr
88         {
89                 outcode($1, &$2, NREG, &$4);
90         }
91 /*
92  * LOAD/STORE, but not MOVW
93  */
94 |       LTYPE3 lgen ',' gen
95         {
96                 if(!isreg(&$2) && !isreg(&$4))
97                         print("one side must be register\n");
98                 outcode($1, &$2, NREG, &$4);
99         }
100 /*
101  * SPECIAL
102  */
103 |       LTYPE4 comma
104         {
105                 outcode($1, &nullgen, NREG, &nullgen);
106         }
107 /*
108  * MOVW
109  */
110 |       LTYPE5 vlgen ',' vgen
111         {
112                 if(!isreg(&$2) && !isreg(&$4))
113                         print("one side must be register\n");
114                 outcode($1, &$2, NREG, &$4);
115         }
116 /*
117  * MUL/DIV
118  */
119 |       LTYPE6 reg ',' sreg comma
120         {
121                 outcode($1, &$2, $4, &nullgen);
122         }
123 |       LTYPE6 reg ',' sreg ',' reg
124         {
125                 outcode($1, &$2, $4, &$6);
126         }
127 /*
128  * JMP/JAL
129  */
130 |       LTYPE7 comma rel
131         {
132                 outcode($1, &nullgen, NREG, &$3);
133         }
134 |       LTYPE7 comma nireg
135         {
136                 outcode($1, &nullgen, NREG, &$3);
137         }
138 |       LTYPE8 comma rel
139         {
140                 outcode($1, &nullgen, NREG, &$3);
141         }
142 |       LTYPE8 comma nireg
143         {
144                 outcode($1, &nullgen, NREG, &$3);
145         }
146 |       LTYPE8 sreg ',' nireg
147         {
148                 outcode($1, &nullgen, $2, &$4);
149         }
150 /*
151  * BEQ/BNE
152  */
153 |       LTYPE9 gen ',' rel
154         {
155                 if(!isreg(&$2))
156                         print("left side must be register\n");
157                 outcode($1, &$2, NREG, &$4);
158         }
159 |       LTYPE9 gen ',' sreg ',' rel
160         {
161                 if(!isreg(&$2))
162                         print("left side must be register\n");
163                 outcode($1, &$2, $4, &$6);
164         }
165 /*
166  * B-other
167  */
168 |       LTYPEA gen ',' rel
169         {
170                 if(!isreg(&$2))
171                         print("left side must be register\n");
172                 outcode($1, &$2, NREG, &$4);
173         }
174 /*
175  * TEXT/GLOBL
176  */
177 |       LTYPEB name ',' imm
178         {
179                 outcode($1, &$2, NREG, &$4);
180         }
181 |       LTYPEB name ',' con ',' imm
182         {
183                 outcode($1, &$2, $4, &$6);
184         }
185 /*
186  * DATA
187  */
188 |       LTYPEC name '/' con ',' ximm
189         {
190                 outcode($1, &$2, $4, &$6);
191         }
192 /*
193  * floating-type
194  */
195 |       LTYPED freg ',' freg
196         {
197                 outcode($1, &$2, NREG, &$4);
198         }
199 |       LTYPEE freg ',' freg
200         {
201                 outcode($1, &$2, NREG, &$4);
202         }
203 |       LTYPEE freg ',' LFREG ',' freg
204         {
205                 outcode($1, &$2, $4, &$6);
206         }
207 |       LTYPEF freg ',' LFREG comma
208         {
209                 outcode($1, &$2, $4, &nullgen);
210         }
211 /*
212  * coprocessor branch
213  */
214 |       LTYPEG comma rel
215         {
216                 outcode($1, &nullgen, NREG, &$3);
217         }
218 /*
219  * word
220  */
221 |       LTYPEH comma ximm
222         {
223                 outcode($1, &nullgen, NREG, &$3);
224         }
225 /*
226  * NOP
227  */
228 |       LTYPEI comma
229         {
230                 outcode($1, &nullgen, NREG, &nullgen);
231         }
232 |       LTYPEI ',' vgen
233         {
234                 outcode($1, &nullgen, NREG, &$3);
235         }
236 |       LTYPEI vgen comma
237         {
238                 outcode($1, &$2, NREG, &nullgen);
239         }
240 /*
241  * BREAK -- overloaded with CACHE opcode
242  */
243 |       LTYPEJ comma
244         {
245                 outcode($1, &nullgen, NREG, &nullgen);
246         }
247 |       LTYPEJ vgen ',' vgen
248         {
249                 outcode($1, &$2, NREG, &$4);
250         }
251
252 comma:
253 |       ','
254
255 rel:
256         con '(' LPC ')'
257         {
258                 $$ = nullgen;
259                 $$.type = D_BRANCH;
260                 $$.offset = $1 + pc;
261         }
262 |       LNAME offset
263         {
264                 $$ = nullgen;
265                 if(pass == 2)
266                         yyerror("undefined label: %s", $1->name);
267                 $$.type = D_BRANCH;
268                 $$.sym = $1;
269                 $$.offset = $2;
270         }
271 |       LLAB offset
272         {
273                 $$ = nullgen;
274                 $$.type = D_BRANCH;
275                 $$.sym = $1;
276                 $$.offset = $1->value + $2;
277         }
278
279 vlgen:
280         lgen
281 |       fgen
282 |       mreg
283 |       fcreg
284 |       LHI
285         {
286                 $$ = nullgen;
287                 $$.type = D_HI;
288         }
289 |       LLO
290         {
291                 $$ = nullgen;
292                 $$.type = D_LO;
293         }
294
295 vgen:
296         gen
297 |       fgen
298 |       mreg
299 |       fcreg
300 |       LHI
301         {
302                 $$ = nullgen;
303                 $$.type = D_HI;
304         }
305 |       LLO
306         {
307                 $$ = nullgen;
308                 $$.type = D_LO;
309         }
310
311 lgen:
312         gen
313 |       ximm
314
315 fgen:
316         freg
317
318 mreg:
319         LMREG
320         {
321                 $$ = nullgen;
322                 $$.type = D_MREG;
323                 $$.reg = $1;
324         }
325 |       LM '(' con ')'
326         {
327                 $$ = nullgen;
328                 $$.type = D_MREG;
329                 $$.reg = $3;
330         }
331
332 fcreg:
333         LFCREG
334         {
335                 $$ = nullgen;
336                 $$.type = D_FCREG;
337                 $$.reg = $1;
338         }
339 |       LFCR '(' con ')'
340         {
341                 $$ = nullgen;
342                 $$.type = D_FCREG;
343                 $$.reg = $3;
344         }
345
346 freg:
347         LFREG
348         {
349                 $$ = nullgen;
350                 $$.type = D_FREG;
351                 $$.reg = $1;
352         }
353 |       LF '(' con ')'
354         {
355                 $$ = nullgen;
356                 $$.type = D_FREG;
357                 $$.reg = $3;
358         }
359
360 ximm:   '$' con
361         {
362                 $$ = nullgen;
363                 $$.type = D_CONST;
364                 $$.offset = $2;
365         }
366 |       '$' oreg
367         {
368                 $$ = $2;
369                 $$.type = D_CONST;
370         }
371 |       '$' '*' '$' oreg
372         {
373                 $$ = $4;
374                 $$.type = D_OCONST;
375         }
376 |       '$' LSCONST
377         {
378                 $$ = nullgen;
379                 $$.type = D_SCONST;
380                 memcpy($$.sval, $2, sizeof($$.sval));
381         }
382 |       '$' LFCONST
383         {
384                 $$ = nullgen;
385                 $$.type = D_FCONST;
386                 $$.dval = $2;
387         }
388 |       '$' '-' LFCONST
389         {
390                 $$ = nullgen;
391                 $$.type = D_FCONST;
392                 $$.dval = -$3;
393         }
394
395 nireg:
396         ireg
397 |       con ireg
398         {
399                 if($1 != 0)
400                         yyerror("offset must be zero");
401                 $$ = $2;
402         }
403 |       name
404         {
405                 $$ = $1;
406                 if($1.name != D_EXTERN && $1.name != D_STATIC) {
407                 }
408         }
409
410 ireg:
411         '(' sreg ')'
412         {
413                 $$ = nullgen;
414                 $$.type = D_OREG;
415                 $$.reg = $2;
416                 $$.offset = 0;
417         }
418
419 gen:
420         reg
421 |       con
422         {
423                 $$ = nullgen;
424                 $$.type = D_OREG;
425                 $$.offset = $1;
426         }
427 |       oreg
428
429 oreg:
430         name
431 |       name '(' sreg ')'
432         {
433                 $$ = $1;
434                 $$.type = D_OREG;
435                 $$.reg = $3;
436         }
437 |       '(' sreg ')'
438         {
439                 $$ = nullgen;
440                 $$.type = D_OREG;
441                 $$.reg = $2;
442                 $$.offset = 0;
443         }
444 |       con '(' sreg ')'
445         {
446                 $$ = nullgen;
447                 $$.type = D_OREG;
448                 $$.reg = $3;
449                 $$.offset = $1;
450         }
451
452 imr:
453         reg
454 |       imm
455
456 imm:    '$' con
457         {
458                 $$ = nullgen;
459                 $$.type = D_CONST;
460                 $$.offset = $2;
461         }
462
463 reg:
464         sreg
465         {
466                 $$ = nullgen;
467                 $$.type = D_REG;
468                 $$.reg = $1;
469         }
470
471 sreg:
472         LREG
473 |       LR '(' con ')'
474         {
475                 if($$ < 0 || $$ >= NREG)
476                         print("register value out of range\n");
477                 $$ = $3;
478         }
479
480 name:
481         con '(' pointer ')'
482         {
483                 $$ = nullgen;
484                 $$.type = D_OREG;
485                 $$.name = $3;
486                 $$.sym = S;
487                 $$.offset = $1;
488         }
489 |       LNAME offset '(' pointer ')'
490         {
491                 $$ = nullgen;
492                 $$.type = D_OREG;
493                 $$.name = $4;
494                 $$.sym = $1;
495                 $$.offset = $2;
496         }
497 |       LNAME '<' '>' offset '(' LSB ')'
498         {
499                 $$ = nullgen;
500                 $$.type = D_OREG;
501                 $$.name = D_STATIC;
502                 $$.sym = $1;
503                 $$.offset = $4;
504         }
505
506 offset:
507         {
508                 $$ = 0;
509         }
510 |       '+' con
511         {
512                 $$ = $2;
513         }
514 |       '-' con
515         {
516                 $$ = -$2;
517         }
518
519 pointer:
520         LSB
521 |       LSP
522 |       LFP
523
524 con:
525         LCONST
526 |       LVAR
527         {
528                 $$ = $1->value;
529         }
530 |       '-' con
531         {
532                 $$ = -$2;
533         }
534 |       '+' con
535         {
536                 $$ = $2;
537         }
538 |       '~' con
539         {
540                 $$ = ~$2;
541         }
542 |       '(' expr ')'
543         {
544                 $$ = $2;
545         }
546
547 expr:
548         con
549 |       expr '+' expr
550         {
551                 $$ = $1 + $3;
552         }
553 |       expr '-' expr
554         {
555                 $$ = $1 - $3;
556         }
557 |       expr '*' expr
558         {
559                 $$ = $1 * $3;
560         }
561 |       expr '/' expr
562         {
563                 $$ = $1 / $3;
564         }
565 |       expr '%' expr
566         {
567                 $$ = $1 % $3;
568         }
569 |       expr '<' '<' expr
570         {
571                 $$ = $1 << $4;
572         }
573 |       expr '>' '>' expr
574         {
575                 $$ = $1 >> $4;
576         }
577 |       expr '&' expr
578         {
579                 $$ = $1 & $3;
580         }
581 |       expr '^' expr
582         {
583                 $$ = $1 ^ $3;
584         }
585 |       expr '|' expr
586         {
587                 $$ = $1 | $3;
588         }