]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/2a/a.y
abaco: cleanup, handle image/x-icon, don't use backspace as a hotkey, and remove...
[plan9front.git] / sys / src / cmd / 2a / a.y
1 %{
2 #include "a.h"
3 %}
4 %union  {
5         Sym     *sym;
6         long    lval;
7         double  dval;
8         char    sval[8];
9         Addr    addr;
10         Gen     gen;
11         Gen2    gen2;
12 }
13 %left   '|'
14 %left   '^'
15 %left   '&'
16 %left   '<' '>'
17 %left   '+' '-'
18 %left   '*' '/' '%'
19 %token  <lval>  LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
20 %token  <lval>  LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA LTYPEB
21 %token  <lval>  LCONST LSP LSB LFP LPC LTOS LAREG LDREG LFREG LWID
22 %token  <dval>  LFCONST
23 %token  <sval>  LSCONST
24 %token  <sym>   LNAME LLAB LVAR
25 %type   <lval>  con expr scale type pointer reg offset
26 %type   <addr>  name areg xreg
27 %type   <gen>   gen rel
28 %type   <gen2>  noaddr gengen dstgen spec1 spec2 spec3 srcgen dstrel genrel
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 |       LTYPE1 gengen   { outcode($1, &$2); }
64 |       LTYPE2 noaddr   { outcode($1, &$2); }
65 |       LTYPE3 dstgen   { outcode($1, &$2); }
66 |       LTYPE4 spec1    { outcode($1, &$2); }
67 |       LTYPE5 srcgen   { outcode($1, &$2); }
68 |       LTYPE6 dstrel   { outcode($1, &$2); }
69 |       LTYPE7 genrel   { outcode($1, &$2); }
70 |       LTYPE8 dstgen   { outcode($1, &$2); }
71 |       LTYPE8 gengen   { outcode($1, &$2); }
72 |       LTYPE9 noaddr   { outcode($1, &$2); }
73 |       LTYPE9 dstgen   { outcode($1, &$2); }
74 |       LTYPEA spec2    { outcode($1, &$2); }
75 |       LTYPEB spec3    { outcode($1, &$2); }
76
77 noaddr:
78         {
79                 $$.from = nullgen;
80                 $$.to = nullgen;
81         }
82 |       ','
83         {
84                 $$.from = nullgen;
85                 $$.to = nullgen;
86         }
87
88 srcgen:
89         gen
90         {
91                 $$.from = $1;
92                 $$.to = nullgen;
93         }
94 |       gen ','
95         {
96                 $$.from = $1;
97                 $$.to = nullgen;
98         }
99
100 dstgen:
101         gen
102         {
103                 $$.from = nullgen;
104                 $$.to = $1;
105         }
106 |       ',' gen
107         {
108                 $$.from = nullgen;
109                 $$.to = $2;
110         }
111
112 gengen:
113         gen ',' gen
114         {
115                 $$.from = $1;
116                 $$.to = $3;
117         }
118
119 dstrel:
120         rel
121         {
122                 $$.from = nullgen;
123                 $$.to = $1;
124         }
125 |       ',' rel
126         {
127                 $$.from = nullgen;
128                 $$.to = $2;
129         }
130
131 genrel:
132         gen ',' rel
133         {
134                 $$.from = $1;
135                 $$.to = $3;
136         }
137
138 spec1:  /* DATA opcode */
139         gen '/' con ',' gen
140         {
141                 $1.displace = $3;
142                 $$.from = $1;
143                 $$.to = $5;
144         }
145
146 spec2:  /* bit field opcodes */
147         gen ',' gen ',' con ',' con
148         {
149                 $1.field = $7;
150                 $3.field = $5;
151                 $$.from = $1;
152                 $$.to = $3;
153         }
154
155 spec3:  /* TEXT opcode */
156         gengen
157 |       gen ',' con ',' gen
158         {
159                 $1.displace = $3;
160                 $$.from = $1;
161                 $$.to = $5;
162         }
163
164 rel:
165         con '(' LPC ')'
166         {
167                 $$ = nullgen;
168                 $$.type = D_BRANCH;
169                 $$.offset = $1 + pc;
170         }
171 |       LNAME offset
172         {
173                 $$ = nullgen;
174                 if(pass == 2)
175                         yyerror("undefined label: %s", $1->name);
176                 $$.type = D_BRANCH;
177                 $$.sym = $1;
178                 $$.offset = $2;
179         }
180 |       LLAB offset
181         {
182                 $$ = nullgen;
183                 $$.type = D_BRANCH;
184                 $$.sym = $1;
185                 $$.offset = $1->value + $2;
186         }
187
188 gen:
189         type
190         {
191                 $$ = nullgen;
192                 $$.type = $1;
193         }
194 |       '$' con
195         {
196                 $$ = nullgen;
197                 $$.type = D_CONST;
198                 $$.offset = $2;
199         }
200 |       '$' name
201         {
202                 $$ = nullgen;
203                 {
204                         Addr *a;
205                         a = &$$;
206                         *a = $2;
207                 }
208                 if($2.type == D_AUTO || $2.type == D_PARAM)
209                         yyerror("constant cannot be automatic: %s",
210                                 $2.sym->name);
211                 $$.type = $2.type | I_ADDR;
212         }
213 |       '$' LSCONST
214         {
215                 $$ = nullgen;
216                 $$.type = D_SCONST;
217                 memcpy($$.sval, $2, sizeof($$.sval));
218         }
219 |       '$' LFCONST
220         {
221                 $$ = nullgen;
222                 $$.type = D_FCONST;
223                 $$.dval = $2;
224         }
225 |       '$' '-' LFCONST
226         {
227                 $$ = nullgen;
228                 $$.type = D_FCONST;
229                 $$.dval = -$3;
230         }
231 |       LTOS '+' con
232         {
233                 $$ = nullgen;
234                 $$.type = D_STACK;
235                 $$.offset = $3;
236         }
237 |       LTOS '-' con
238         {
239                 $$ = nullgen;
240                 $$.type = D_STACK;
241                 $$.offset = -$3;
242         }
243 |       con
244         {
245                 $$ = nullgen;
246                 $$.type = D_CONST | I_INDIR;
247                 $$.offset = $1;
248         }
249 |       '-' '(' LAREG ')'
250         {
251                 $$ = nullgen;
252                 $$.type = $3 | I_INDDEC;
253         }
254 |       '(' LAREG ')' '+'
255         {
256                 $$ = nullgen;
257                 $$.type = $2 | I_INDINC;
258         }
259 |       areg
260         {
261                 $$ = nullgen;
262                 $$.type = $1.type;
263                 {
264                         Addr *a;
265                         a = &$$;
266                         *a = $1;
267                 }
268                 if(($$.type & D_MASK) == D_NONE) {
269                         $$.index = D_NONE | I_INDEX1;
270                         $$.scale = 0;
271                         $$.displace = 0;
272                 }
273         }
274 |       areg xreg
275         {
276                 $$ = nullgen;
277                 $$.type = $1.type;
278                 {
279                         Addr *a;
280                         a = &$$;
281                         *a = $1;
282                 }
283                 $$.index = $2.type | I_INDEX1;
284                 $$.scale = $2.offset;
285         }
286 |       '(' areg ')' xreg
287         {
288                 $$ = nullgen;
289                 $$.type = $2.type;
290                 {
291                         Addr *a;
292                         a = &$$;
293                         *a = $2;
294                 }
295                 $$.index = $4.type | I_INDEX2;
296                 $$.scale = $4.offset;
297                 $$.displace = 0;
298         }
299 |       con '(' areg ')' xreg
300         {
301                 $$ = nullgen;
302                 $$.type = $3.type;
303                 {
304                         Addr *a;
305                         a = &$$;
306                         *a = $3;
307                 }
308                 $$.index = $5.type | I_INDEX2;
309                 $$.scale = $5.offset;
310                 $$.displace = $1;
311         }
312 |       '(' areg ')'
313         {
314                 $$ = nullgen;
315                 $$.type = $2.type;
316                 {
317                         Addr *a;
318                         a = &$$;
319                         *a = $2;
320                 }
321                 $$.index = D_NONE | I_INDEX3;
322                 $$.scale = 0;
323                 $$.displace = 0;
324         }
325 |       con '(' areg ')'
326         {
327                 $$ = nullgen;
328                 $$.type = $3.type;
329                 {
330                         Addr *a;
331                         a = &$$;
332                         *a = $3;
333                 }
334                 $$.index = D_NONE | I_INDEX3;
335                 $$.scale = 0;
336                 $$.displace = $1;
337         }
338 |       '(' areg xreg ')'
339         {
340                 $$ = nullgen;
341                 $$.type = $2.type;
342                 {
343                         Addr *a;
344                         a = &$$;
345                         *a = $2;
346                 }
347                 $$.index = $3.type | I_INDEX3;
348                 $$.scale = $3.offset;
349                 $$.displace = 0;
350         }
351 |       con '(' areg xreg ')'
352         {
353                 $$ = nullgen;
354                 $$.type = $3.type;
355                 {
356                         Addr *a;
357                         a = &$$;
358                         *a = $3;
359                 }
360                 $$.index = $4.type | I_INDEX3;
361                 $$.scale = $4.offset;
362                 $$.displace = $1;
363         }
364
365 type:
366         reg
367 |       LFREG
368
369 xreg:
370         /*
371          *      .W*1    0
372          *      .W*2    1
373          *      .W*4    2
374          *      .W*8    3
375          *      .L*1    4
376          *      .L*2    5
377          *      .L*4    6
378          *      .L*8    7
379          */
380         '(' reg LWID scale ')'
381         {
382                 $$.type = $2;
383                 $$.offset = $3+$4;
384                 $$.sym = S;
385         }
386
387 reg:
388         LAREG
389 |       LDREG
390 |       LTOS
391
392 scale:
393         '*' con
394         {
395                 switch($2) {
396                 case 1:
397                         $$ = 0;
398                         break;
399
400                 case 2:
401                         $$ = 1;
402                         break;
403
404                 default:
405                         yyerror("bad scale: %ld", $2);
406
407                 case 4:
408                         $$ = 2;
409                         break;
410
411                 case 8:
412                         $$ = 3;
413                         break;
414                 }
415         }
416
417 areg:
418         '(' LAREG ')'
419         {
420                 $$.type = $2 | I_INDIR;
421                 $$.sym = S;
422                 $$.offset = 0;
423         }
424 |       con '(' LAREG ')'
425         {
426                 $$.type = $3 | I_INDIR;
427                 $$.sym = S;
428                 $$.offset = $1;
429         }
430 |       '(' ')'
431         {
432                 $$.type = D_NONE | I_INDIR;
433                 $$.sym = S;
434                 $$.offset = 0;
435         }
436 |       con '(' ')'
437         {
438                 $$.type = D_NONE | I_INDIR;
439                 $$.sym = S;
440                 $$.offset = $1;
441         }
442 |       name
443
444 name:
445         LNAME offset '(' pointer ')'
446         {
447                 $$.type = $4;
448                 $$.sym = $1;
449                 $$.offset = $2;
450         }
451 |       LNAME '<' '>' offset '(' LSB ')'
452         {
453                 $$.type = D_STATIC;
454                 $$.sym = $1;
455                 $$.offset = $4;
456         }
457
458 offset:
459         {
460                 $$ = 0;
461         }
462 |       '+' con
463         {
464                 $$ = $2;
465         }
466 |       '-' con
467         {
468                 $$ = -$2;
469         }
470
471 pointer:
472         LSB
473 |       LSP
474 |       LFP
475
476 con:
477         LCONST
478 |       LVAR
479         {
480                 $$ = $1->value;
481         }
482 |       '-' con
483         {
484                 $$ = -$2;
485         }
486 |       '+' con
487         {
488                 $$ = $2;
489         }
490 |       '~' con
491         {
492                 $$ = ~$2;
493         }
494 |       '(' expr ')'
495         {
496                 $$ = $2;
497         }
498
499 expr:
500         con
501 |       expr '+' expr
502         {
503                 $$ = $1 + $3;
504         }
505 |       expr '-' expr
506         {
507                 $$ = $1 - $3;
508         }
509 |       expr '*' expr
510         {
511                 $$ = $1 * $3;
512         }
513 |       expr '/' expr
514         {
515                 $$ = $1 / $3;
516         }
517 |       expr '%' expr
518         {
519                 $$ = $1 % $3;
520         }
521 |       expr '<' '<' expr
522         {
523                 $$ = $1 << $4;
524         }
525 |       expr '>' '>' expr
526         {
527                 $$ = $1 >> $4;
528         }
529 |       expr '&' expr
530         {
531                 $$ = $1 & $3;
532         }
533 |       expr '^' expr
534         {
535                 $$ = $1 ^ $3;
536         }
537 |       expr '|' expr
538         {
539                 $$ = $1 | $3;
540         }