diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
commit | 5ff4c17907d5b19510a62e08fd8d3b11e62b431d (patch) | |
tree | c0650497e988f47be9c6f2324fa692a52dea82e1 /src/cmd/6a/a.y | |
parent | 80f18fc933cf3f3e829c5455a1023d69f7b86e52 (diff) | |
download | golang-upstream/60.tar.gz |
Imported Upstream version 60upstream/60
Diffstat (limited to 'src/cmd/6a/a.y')
-rw-r--r-- | src/cmd/6a/a.y | 647 |
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; + } |