1 // Inferno utils/5a/a.y
2 // http://code.google.com/p/inferno-os/source/browse/utils/5a/a.y
4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
6 // Portions Copyright © 1997-1999 Vita Nuova Limited
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
8 // Portions Copyright © 2004,2006 Bruce Ellis
9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
11 // Portions Copyright © 2009 The Go Authors. All rights reserved.
13 // Permission is hereby granted, free of charge, to any person obtaining a copy
14 // of this software and associated documentation files (the "Software"), to deal
15 // in the Software without restriction, including without limitation the rights
16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 // copies of the Software, and to permit persons to whom the Software is
18 // furnished to do so, subject to the following conditions:
20 // The above copyright notice and this permission notice shall be included in
21 // all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33 #include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
36 #include "../../runtime/funcdata.h"
52 %token <lval> LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
53 %token <lval> LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
54 %token <lval> LTYPEB LTYPEC LTYPED LTYPEE
55 %token <lval> LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
56 %token <lval> LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
57 %token <lval> LCONST LSP LSB LFP LPC
58 %token <lval> LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
59 %token <lval> LCOND LS LAT
62 %token <sym> LNAME LLAB LVAR
63 %type <lval> con expr oexpr pointer offset sreg spreg creg
64 %type <lval> rcon cond reglist
65 %type <addr> gen rel reg regreg freg shift fcon frcon
66 %type <addr> imm ximm name oreg ireg nireg ioreg imsr
79 if($1->type == LLAB && $1->value != pc)
80 yyerror("redeclaration of %s", $1->labelname);
93 yyerror("redeclaration of %s", $1->name);
104 LTYPE1 cond imsr ',' spreg ',' reg
106 outcode($1, $2, &$3, $5, &$7);
108 | LTYPE1 cond imsr ',' spreg ','
110 outcode($1, $2, &$3, $5, &nullgen);
112 | LTYPE1 cond imsr ',' reg
114 outcode($1, $2, &$3, NREG, &$5);
119 | LTYPE2 cond imsr ',' reg
121 outcode($1, $2, &$3, NREG, &$5);
126 | LTYPE3 cond gen ',' gen
128 outcode($1, $2, &$3, NREG, &$5);
133 | LTYPE4 cond comma rel
135 outcode($1, $2, &nullgen, NREG, &$4);
137 | LTYPE4 cond comma nireg
139 outcode($1, $2, &nullgen, NREG, &$4);
146 outcode($1, Always, &nullgen, NREG, &$3);
153 outcode($1, Always, &nullgen, NREG, &$3);
158 | LTYPE6 cond comma gen
160 outcode($1, $2, &nullgen, NREG, &$4);
165 | LTYPE7 cond imsr ',' spreg comma
167 outcode($1, $2, &$3, $5, &nullgen);
172 | LTYPE8 cond ioreg ',' '[' reglist ']'
179 outcode($1, $2, &$3, NREG, &g);
181 | LTYPE8 cond '[' reglist ']' ',' ioreg
188 outcode($1, $2, &g, NREG, &$7);
193 | LTYPE9 cond reg ',' ireg ',' reg
195 outcode($1, $2, &$5, $3.reg, &$7);
197 | LTYPE9 cond reg ',' ireg comma
199 outcode($1, $2, &$5, $3.reg, &$3);
201 | LTYPE9 cond comma ireg ',' reg
203 outcode($1, $2, &$4, $6.reg, &$6);
210 outcode($1, $2, &nullgen, NREG, &nullgen);
215 | LTYPEB name ',' imm
219 $4.offset2 = ArgsSizeUnknown;
220 outcode($1, Always, &$2, 0, &$4);
222 | LTYPEB name ',' con ',' imm
226 $6.offset2 = ArgsSizeUnknown;
227 outcode($1, Always, &$2, $4, &$6);
229 | LTYPEB name ',' con ',' imm '-' con
234 outcode($1, Always, &$2, $4, &$6);
239 | LTYPEC name '/' con ',' ximm
241 outcode($1, Always, &$2, $4, &$6);
246 | LTYPED cond reg comma
248 outcode($1, $2, &$3, NREG, &nullgen);
255 outcode($1, Always, &nullgen, NREG, &$3);
258 * floating-point coprocessor
260 | LTYPEI cond freg ',' freg
262 outcode($1, $2, &$3, NREG, &$5);
264 | LTYPEK cond frcon ',' freg
266 outcode($1, $2, &$3, NREG, &$5);
268 | LTYPEK cond frcon ',' LFREG ',' freg
270 outcode($1, $2, &$3, $5, &$7);
272 | LTYPEL cond freg ',' freg comma
274 outcode($1, $2, &$3, $5.reg, &nullgen);
279 | LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
286 (0xe << 24) | /* opcode */
287 ($1 << 20) | /* MCR/MRC */
288 ($2 << 28) | /* scond */
289 (($3 & 15) << 8) | /* coprocessor number */
290 (($5 & 7) << 21) | /* coprocessor operation */
291 (($7 & 15) << 12) | /* arm register */
292 (($9 & 15) << 16) | /* Crn */
293 (($11 & 15) << 0) | /* Crm */
294 (($12 & 7) << 5) | /* coprocessor information */
295 (1<<4); /* must be set */
296 outcode(AMRC, Always, &nullgen, NREG, &g);
301 | LTYPEM cond reg ',' reg ',' regreg
303 outcode($1, $2, &$3, $5.reg, &$7);
306 * MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff -> r4
307 * MULAW{T,B} r1,r2,r3,r4
309 | LTYPEN cond reg ',' reg ',' reg ',' spreg
313 outcode($1, $2, &$3, $5.reg, &$7);
320 outcode($1, Always, &$2, NREG, &nullgen);
325 | LTYPEPC gen ',' gen
327 if($2.type != D_CONST || $4.type != D_CONST)
328 yyerror("arguments to PCDATA must be integer constants");
329 outcode($1, Always, &$2, NREG, &$4);
336 if($2.type != D_CONST)
337 yyerror("index for FUNCDATA must be integer constant");
338 if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
339 yyerror("value for FUNCDATA must be symbol reference");
340 outcode($1, Always, &$2, NREG, &$4);
347 outcode($1, Always, &nullgen, NREG, &nullgen);
356 $$ = ($1 & ~C_SCOND) | $2;
375 $1 = labellookup($1);
377 if(pass == 2 && $1->type != LLAB)
378 yyerror("undefined label: %s", $1->labelname);
380 $$.offset = $1->value + $2;
403 memcpy($$.u.sval, $2, sizeof($$.u.sval));
430 for(i=$1; i<=$3; i++)
432 for(i=$3; i<=$1; i++)
435 | spreg comma reglist
444 | shift '(' spreg ')'
475 if($1.name != D_EXTERN && $1.name != D_STATIC) {
529 '(' spreg ',' spreg ')'
542 $$.offset = $1 | $4 | (0 << 5);
548 $$.offset = $1 | $4 | (1 << 5);
554 $$.offset = $1 | $4 | (2 << 5);
560 $$.offset = $1 | $4 | (3 << 5);
566 if($$ < 0 || $$ >= 16)
567 print("register value out of range\n");
568 $$ = (($1&15) << 8) | (1 << 4);
572 if($$ < 0 || $$ >= 32)
573 print("shift value out of range\n");
585 if($3 < 0 || $3 >= NREG)
586 print("register value out of range\n");
601 if($3 < 0 || $3 >= NREG)
602 print("register value out of range\n");
633 | LNAME offset '(' pointer ')'
638 $$.sym = linklookup(ctxt, $1->name, 0);
641 | LNAME '<' '>' offset '(' LSB ')'
646 $$.sym = linklookup(ctxt, $1->name, 1);