1 // Inferno utils/8a/a.y
2 // http://code.google.com/p/inferno-os/source/browse/utils/8a/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
37 . "cmd/internal/obj/i386"
60 %token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
61 %token <lval> LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG LTYPEXC
62 %token <lval> LTYPEX LTYPEPC LTYPEF LCONST LFP LPC LSB
63 %token <lval> LBREG LLREG LSREG LFREG LXREG
65 %token <sval> LSCONST LSP
66 %token <sym> LNAME LLAB LVAR
67 %type <lval> con expr pointer offset
69 %type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
70 %type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
71 %type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12
76 stmtline = asm.Lineno;
83 $1 = asm.LabelLookup($1);
84 if $1.Type == LLAB && $1.Value != int64(asm.PC) {
85 yyerror("redeclaration of %s", $1.Labelname)
88 $1.Value = int64(asm.PC)
103 if $1.Value != int64($3) {
104 yyerror("redeclaration of %s", $1.Name);
108 | LTYPE0 nonnon { outcode(int($1), &$2); }
109 | LTYPE1 nonrem { outcode(int($1), &$2); }
110 | LTYPE2 rimnon { outcode(int($1), &$2); }
111 | LTYPE3 rimrem { outcode(int($1), &$2); }
112 | LTYPE4 remrim { outcode(int($1), &$2); }
113 | LTYPER nonrel { outcode(int($1), &$2); }
114 | LTYPED spec1 { outcode(int($1), &$2); }
115 | LTYPET spec2 { outcode(int($1), &$2); }
116 | LTYPEC spec3 { outcode(int($1), &$2); }
117 | LTYPEN spec4 { outcode(int($1), &$2); }
118 | LTYPES spec5 { outcode(int($1), &$2); }
119 | LTYPEM spec6 { outcode(int($1), &$2); }
120 | LTYPEI spec7 { outcode(int($1), &$2); }
121 | LTYPEG spec8 { outcode(int($1), &$2); }
122 | LTYPEXC spec9 { outcode(int($1), &$2); }
123 | LTYPEX spec10 { outcode(int($1), &$2); }
124 | LTYPEPC spec11 { outcode(int($1), &$2); }
125 | LTYPEF spec12 { outcode(int($1), &$2); }
197 $$.from.Scale = int8($3);
208 | mem ',' con ',' imm2
212 $$.from.Scale = int8($3);
216 spec3: /* JMP/CALL */
231 $$.to.Index = uint8($2.Type_)
232 $$.to.Type_ = D_INDIR+D_ADDR;
245 | rim ',' rem ':' LLREG
249 if $$.from.Index != D_NONE {
250 yyerror("dp shift with lhs index");
252 $$.from.Index = uint8($5);
255 spec6: /* MOVW/MOVL */
261 | rim ',' rem ':' LSREG
265 if $$.to.Index != D_NONE {
266 yyerror("dp move with lhs index");
268 $$.to.Index = uint8($5);
294 | mem ',' con ',' imm
297 $$.from.Scale = int8($3);
301 spec9: /* CMPPS/CMPPD */
314 if $1.Type_ != D_CONST {
315 yyerror("illegal constant")
317 $$.to.Offset = $1.Offset;
323 if $1.Type_ != D_CONST || $3.Type_ != D_CONST {
324 yyerror("arguments to PCDATA must be integer constants");
330 spec12: /* FUNCDATA */
333 if $1.Type_ != D_CONST {
334 yyerror("index for FUNCDATA must be integer constant");
336 if $3.Type_ != D_EXTERN && $3.Type_ != D_STATIC {
337 yyerror("value for FUNCDATA must be symbol reference");
371 $$.Offset = $1 + int64(asm.PC);
375 $1 = asm.LabelLookup($1);
377 if asm.Pass == 2 && $1.Type != LLAB {
378 yyerror("undefined label: %s", $1.Labelname);
381 $$.Offset = $1.Value + $2;
388 $$.Type_ = int16($1);
393 $$.Type_ = int16($1);
398 $$.Type_ = int16($1);
403 $$.Type_ = int16($1);
413 $$.Type_ = int16($1);
426 $$.Index = uint8($2.Type_);
429 if($2.Type_ == D_AUTO || $2.Type_ == D_PARAM)
430 yyerror("constant cannot be automatic: %s",
446 | '$' '(' LFCONST ')'
452 | '$' '(' '-' LFCONST ')'
470 $$.Offset = int64($2.v1);
471 $$.Offset2 = int32($2.v2);
478 $$.v2 = -obj.ArgsSizeUnknown
483 $$.v2 = -obj.ArgsSizeUnknown;
490 | '-' LCONST '-' LCONST
504 $$.Type_ = D_INDIR+D_NONE;
510 $$.Type_ = int16(D_INDIR+$3);
516 $$.Type_ = D_INDIR+D_SP;
519 | con '(' LLREG '*' con ')'
522 $$.Type_ = D_INDIR+D_NONE;
524 $$.Index = uint8($3);
526 checkscale($$.Scale);
528 | con '(' LLREG ')' '(' LLREG '*' con ')'
531 $$.Type_ = int16(D_INDIR+$3);
533 $$.Index = uint8($6);
535 checkscale($$.Scale);
537 | con '(' LLREG ')' '(' LSREG '*' con ')'
540 $$.Type_ = int16(D_INDIR+$3);
542 $$.Index = uint8($6);
544 checkscale($$.Scale);
549 $$.Type_ = int16(D_INDIR+$2);
554 $$.Type_ = D_INDIR+D_SP;
559 $$.Type_ = int16(D_INDIR+$3);
562 | '(' LLREG '*' con ')'
565 $$.Type_ = D_INDIR+D_NONE;
566 $$.Index = uint8($2);
568 checkscale($$.Scale);
570 | '(' LLREG ')' '(' LLREG '*' con ')'
573 $$.Type_ = int16(D_INDIR+$2);
574 $$.Index = uint8($5);
576 checkscale($$.Scale);
584 | nam '(' LLREG '*' con ')'
587 $$.Index = uint8($3);
589 checkscale($$.Scale);
593 LNAME offset '(' pointer ')'
596 $$.Type_ = int16($4);
597 $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
600 | LNAME '<' '>' offset '(' LSB ')'
604 $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);