summaryrefslogtreecommitdiff
path: root/src/cmd/6a/a.y
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-09-13 13:13:40 +0200
committerOndřej Surý <ondrej@sury.org>2011-09-13 13:13:40 +0200
commit5ff4c17907d5b19510a62e08fd8d3b11e62b431d (patch)
treec0650497e988f47be9c6f2324fa692a52dea82e1 /src/cmd/6a/a.y
parent80f18fc933cf3f3e829c5455a1023d69f7b86e52 (diff)
downloadgolang-upstream/60.tar.gz
Imported Upstream version 60upstream/60
Diffstat (limited to 'src/cmd/6a/a.y')
-rw-r--r--src/cmd/6a/a.y647
1 files changed, 647 insertions, 0 deletions
diff --git a/src/cmd/6a/a.y b/src/cmd/6a/a.y
new file mode 100644
index 000000000..c0fa4106e
--- /dev/null
+++ b/src/cmd/6a/a.y
@@ -0,0 +1,647 @@
+// Inferno utils/6a/a.y
+// http://code.google.com/p/inferno-os/source/browse/utils/6a/a.y
+//
+// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+// Portions Copyright © 1997-1999 Vita Nuova Limited
+// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+// Portions Copyright © 2004,2006 Bruce Ellis
+// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+// Portions Copyright © 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+%{
+#include <u.h>
+#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
+#include <libc.h>
+#include "a.h"
+%}
+%union {
+ Sym *sym;
+ vlong lval;
+ double dval;
+ char sval[8];
+ Gen gen;
+ Gen2 gen2;
+}
+%left '|'
+%left '^'
+%left '&'
+%left '<' '>'
+%left '+' '-'
+%left '*' '/' '%'
+%token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
+%token <lval> LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPEG
+%token <lval> LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT
+%token <lval> LCONST LFP LPC LSB
+%token <lval> LBREG LLREG LSREG LFREG LMREG LXREG
+%token <dval> LFCONST
+%token <sval> LSCONST LSP
+%token <sym> LNAME LLAB LVAR
+%type <lval> con con2 expr pointer offset
+%type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem
+%type <gen2> nonnon nonrel nonrem rimnon rimrem remrim spec10 spec11
+%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
+%%
+prog:
+| prog
+ {
+ stmtline = lineno;
+ }
+ line
+
+line:
+ LLAB ':'
+ {
+ if($1->value != pc)
+ yyerror("redeclaration of %s", $1->name);
+ $1->value = pc;
+ }
+ line
+| LNAME ':'
+ {
+ $1->type = LLAB;
+ $1->value = pc;
+ }
+ line
+| ';'
+| inst ';'
+| error ';'
+
+inst:
+ LNAME '=' expr
+ {
+ $1->type = LVAR;
+ $1->value = $3;
+ }
+| LVAR '=' expr
+ {
+ if($1->value != $3)
+ yyerror("redeclaration of %s", $1->name);
+ $1->value = $3;
+ }
+| LTYPE0 nonnon { outcode($1, &$2); }
+| LTYPE1 nonrem { outcode($1, &$2); }
+| LTYPE2 rimnon { outcode($1, &$2); }
+| LTYPE3 rimrem { outcode($1, &$2); }
+| LTYPE4 remrim { outcode($1, &$2); }
+| LTYPER nonrel { outcode($1, &$2); }
+| LTYPED spec1 { outcode($1, &$2); }
+| LTYPET spec2 { outcode($1, &$2); }
+| LTYPEC spec3 { outcode($1, &$2); }
+| LTYPEN spec4 { outcode($1, &$2); }
+| LTYPES spec5 { outcode($1, &$2); }
+| LTYPEM spec6 { outcode($1, &$2); }
+| LTYPEI spec7 { outcode($1, &$2); }
+| LTYPEXC spec8 { outcode($1, &$2); }
+| LTYPEX spec9 { outcode($1, &$2); }
+| LTYPERT spec10 { outcode($1, &$2); }
+| LTYPEG spec11 { outcode($1, &$2); }
+
+nonnon:
+ {
+ $$.from = nullgen;
+ $$.to = nullgen;
+ }
+| ','
+ {
+ $$.from = nullgen;
+ $$.to = nullgen;
+ }
+
+rimrem:
+ rim ',' rem
+ {
+ $$.from = $1;
+ $$.to = $3;
+ }
+
+remrim:
+ rem ',' rim
+ {
+ $$.from = $1;
+ $$.to = $3;
+ }
+
+rimnon:
+ rim ','
+ {
+ $$.from = $1;
+ $$.to = nullgen;
+ }
+| rim
+ {
+ $$.from = $1;
+ $$.to = nullgen;
+ }
+
+nonrem:
+ ',' rem
+ {
+ $$.from = nullgen;
+ $$.to = $2;
+ }
+| rem
+ {
+ $$.from = nullgen;
+ $$.to = $1;
+ }
+
+nonrel:
+ ',' rel
+ {
+ $$.from = nullgen;
+ $$.to = $2;
+ }
+| rel
+ {
+ $$.from = nullgen;
+ $$.to = $1;
+ }
+
+spec1: /* DATA */
+ nam '/' con ',' imm
+ {
+ $$.from = $1;
+ $$.from.scale = $3;
+ $$.to = $5;
+ }
+
+spec2: /* TEXT */
+ mem ',' imm2
+ {
+ $$.from = $1;
+ $$.to = $3;
+ }
+| mem ',' con ',' imm2
+ {
+ $$.from = $1;
+ $$.from.scale = $3;
+ $$.to = $5;
+ }
+
+spec3: /* JMP/CALL */
+ ',' rom
+ {
+ $$.from = nullgen;
+ $$.to = $2;
+ }
+| rom
+ {
+ $$.from = nullgen;
+ $$.to = $1;
+ }
+
+spec4: /* NOP */
+ nonnon
+| nonrem
+
+spec5: /* SHL/SHR */
+ rim ',' rem
+ {
+ $$.from = $1;
+ $$.to = $3;
+ }
+| rim ',' rem ':' LLREG
+ {
+ $$.from = $1;
+ $$.to = $3;
+ if($$.from.index != D_NONE)
+ yyerror("dp shift with lhs index");
+ $$.from.index = $5;
+ }
+
+spec6: /* MOVW/MOVL */
+ rim ',' rem
+ {
+ $$.from = $1;
+ $$.to = $3;
+ }
+| rim ',' rem ':' LSREG
+ {
+ $$.from = $1;
+ $$.to = $3;
+ if($$.to.index != D_NONE)
+ yyerror("dp move with lhs index");
+ $$.to.index = $5;
+ }
+
+spec7:
+ rim ','
+ {
+ $$.from = $1;
+ $$.to = nullgen;
+ }
+| rim
+ {
+ $$.from = $1;
+ $$.to = nullgen;
+ }
+| rim ',' rem
+ {
+ $$.from = $1;
+ $$.to = $3;
+ }
+
+spec8: /* CMPPS/CMPPD */
+ reg ',' rem ',' con
+ {
+ $$.from = $1;
+ $$.to = $3;
+ $$.to.offset = $5;
+ }
+
+spec9: /* shufl */
+ imm ',' rem ',' reg
+ {
+ $$.from = $3;
+ $$.to = $5;
+ if($1.type != D_CONST)
+ yyerror("illegal constant");
+ $$.to.offset = $1.offset;
+ }
+
+spec10: /* RET/RETF */
+ {
+ $$.from = nullgen;
+ $$.to = nullgen;
+ }
+| imm
+ {
+ $$.from = $1;
+ $$.to = nullgen;
+ }
+
+spec11: /* GLOBL */
+ mem ',' imm
+ {
+ $$.from = $1;
+ $$.to = $3;
+ }
+| mem ',' con ',' imm
+ {
+ $$.from = $1;
+ $$.from.scale = $3;
+ $$.to = $5;
+ }
+
+rem:
+ reg
+| mem
+
+rom:
+ rel
+| nmem
+| '*' reg
+ {
+ $$ = $2;
+ }
+| '*' omem
+ {
+ $$ = $2;
+ }
+| reg
+| omem
+
+rim:
+ rem
+| imm
+
+rel:
+ con '(' LPC ')'
+ {
+ $$ = nullgen;
+ $$.type = D_BRANCH;
+ $$.offset = $1 + pc;
+ }
+| LNAME offset
+ {
+ $$ = nullgen;
+ if(pass == 2)
+ yyerror("undefined label: %s", $1->name);
+ $$.type = D_BRANCH;
+ $$.sym = $1;
+ $$.offset = $2;
+ }
+| LLAB offset
+ {
+ $$ = nullgen;
+ $$.type = D_BRANCH;
+ $$.sym = $1;
+ $$.offset = $1->value + $2;
+ }
+
+reg:
+ LBREG
+ {
+ $$ = nullgen;
+ $$.type = $1;
+ }
+| LFREG
+ {
+ $$ = nullgen;
+ $$.type = $1;
+ }
+| LLREG
+ {
+ $$ = nullgen;
+ $$.type = $1;
+ }
+| LMREG
+ {
+ $$ = nullgen;
+ $$.type = $1;
+ }
+| LSP
+ {
+ $$ = nullgen;
+ $$.type = D_SP;
+ }
+| LSREG
+ {
+ $$ = nullgen;
+ $$.type = $1;
+ }
+| LXREG
+ {
+ $$ = nullgen;
+ $$.type = $1;
+ }
+imm2:
+ '$' con2
+ {
+ $$ = nullgen;
+ $$.type = D_CONST;
+ $$.offset = $2;
+ }
+
+imm:
+ '$' con
+ {
+ $$ = nullgen;
+ $$.type = D_CONST;
+ $$.offset = $2;
+ }
+| '$' nam
+ {
+ $$ = $2;
+ $$.index = $2.type;
+ $$.type = D_ADDR;
+ /*
+ if($2.type == D_AUTO || $2.type == D_PARAM)
+ yyerror("constant cannot be automatic: %s",
+ $2.sym->name);
+ */
+ }
+| '$' LSCONST
+ {
+ $$ = nullgen;
+ $$.type = D_SCONST;
+ memcpy($$.sval, $2, sizeof($$.sval));
+ }
+| '$' LFCONST
+ {
+ $$ = nullgen;
+ $$.type = D_FCONST;
+ $$.dval = $2;
+ }
+| '$' '(' LFCONST ')'
+ {
+ $$ = nullgen;
+ $$.type = D_FCONST;
+ $$.dval = $3;
+ }
+| '$' '-' LFCONST
+ {
+ $$ = nullgen;
+ $$.type = D_FCONST;
+ $$.dval = -$3;
+ }
+
+mem:
+ omem
+| nmem
+
+omem:
+ con
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+D_NONE;
+ $$.offset = $1;
+ }
+| con '(' LLREG ')'
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+$3;
+ $$.offset = $1;
+ }
+| con '(' LSP ')'
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+D_SP;
+ $$.offset = $1;
+ }
+| con '(' LSREG ')'
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+$3;
+ $$.offset = $1;
+ }
+| con '(' LLREG '*' con ')'
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+D_NONE;
+ $$.offset = $1;
+ $$.index = $3;
+ $$.scale = $5;
+ checkscale($$.scale);
+ }
+| con '(' LLREG ')' '(' LLREG '*' con ')'
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+$3;
+ $$.offset = $1;
+ $$.index = $6;
+ $$.scale = $8;
+ checkscale($$.scale);
+ }
+| '(' LLREG ')'
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+$2;
+ }
+| '(' LSP ')'
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+D_SP;
+ }
+| '(' LLREG '*' con ')'
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+D_NONE;
+ $$.index = $2;
+ $$.scale = $4;
+ checkscale($$.scale);
+ }
+| '(' LLREG ')' '(' LLREG '*' con ')'
+ {
+ $$ = nullgen;
+ $$.type = D_INDIR+$2;
+ $$.index = $5;
+ $$.scale = $7;
+ checkscale($$.scale);
+ }
+
+nmem:
+ nam
+ {
+ $$ = $1;
+ }
+| nam '(' LLREG '*' con ')'
+ {
+ $$ = $1;
+ $$.index = $3;
+ $$.scale = $5;
+ checkscale($$.scale);
+ }
+
+nam:
+ LNAME offset '(' pointer ')'
+ {
+ $$ = nullgen;
+ $$.type = $4;
+ $$.sym = $1;
+ $$.offset = $2;
+ }
+| LNAME '<' '>' offset '(' LSB ')'
+ {
+ $$ = nullgen;
+ $$.type = D_STATIC;
+ $$.sym = $1;
+ $$.offset = $4;
+ }
+
+offset:
+ {
+ $$ = 0;
+ }
+| '+' con
+ {
+ $$ = $2;
+ }
+| '-' con
+ {
+ $$ = -$2;
+ }
+
+pointer:
+ LSB
+| LSP
+ {
+ $$ = D_AUTO;
+ }
+| LFP
+
+con:
+ LCONST
+| LVAR
+ {
+ $$ = $1->value;
+ }
+| '-' con
+ {
+ $$ = -$2;
+ }
+| '+' con
+ {
+ $$ = $2;
+ }
+| '~' con
+ {
+ $$ = ~$2;
+ }
+| '(' expr ')'
+ {
+ $$ = $2;
+ }
+
+con2:
+ LCONST
+ {
+ $$ = $1 & 0xffffffffLL;
+ }
+| '-' LCONST
+ {
+ $$ = -$2 & 0xffffffffLL;
+ }
+| LCONST '-' LCONST
+ {
+ $$ = ($1 & 0xffffffffLL) +
+ (($3 & 0xffffLL) << 32);
+ }
+| '-' LCONST '-' LCONST
+ {
+ $$ = (-$2 & 0xffffffffLL) +
+ (($4 & 0xffffLL) << 32);
+ }
+
+expr:
+ con
+| expr '+' expr
+ {
+ $$ = $1 + $3;
+ }
+| expr '-' expr
+ {
+ $$ = $1 - $3;
+ }
+| expr '*' expr
+ {
+ $$ = $1 * $3;
+ }
+| expr '/' expr
+ {
+ $$ = $1 / $3;
+ }
+| expr '%' expr
+ {
+ $$ = $1 % $3;
+ }
+| expr '<' '<' expr
+ {
+ $$ = $1 << $4;
+ }
+| expr '>' '>' expr
+ {
+ $$ = $1 >> $4;
+ }
+| expr '&' expr
+ {
+ $$ = $1 & $3;
+ }
+| expr '^' expr
+ {
+ $$ = $1 ^ $3;
+ }
+| expr '|' expr
+ {
+ $$ = $1 | $3;
+ }