From 190eb820b96c43eb96845b393b6db7771ccefc8b Mon Sep 17 00:00:00 2001 From: Shenghou Ma Date: Wed, 6 Aug 2014 23:41:29 -0400 Subject: [dev.power64] cmd/9a, cmd/9c, cmd/9l, liblink: import code from Vita Nuova. No modifications other than adding copyright header to each file, and concatenating several cmd/9l files together to form the liblink files. LGTM=rsc R=rsc, iant CC=golang-codereviews https://codereview.appspot.com/123840043 --- src/cmd/9a/a.y | 975 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 975 insertions(+) create mode 100644 src/cmd/9a/a.y (limited to 'src/cmd/9a/a.y') diff --git a/src/cmd/9a/a.y b/src/cmd/9a/a.y new file mode 100644 index 000000000..e77d78c6d --- /dev/null +++ b/src/cmd/9a/a.y @@ -0,0 +1,975 @@ +// cmd/9a/a.y from Vita Nuova. +// +// 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-2008 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-2008 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 "a.h" +%} +%union +{ + Sym *sym; + vlong lval; + double dval; + char sval[8]; + Gen gen; +} +%left '|' +%left '^' +%left '&' +%left '<' '>' +%left '+' '-' +%left '*' '/' '%' +%token LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP +%token LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW +%token LNOP LEND LRETT LWORD LTEXT LDATA LRETRN +%token LCONST LSP LSB LFP LPC LCREG LFLUSH +%token LREG LFREG LR LCR LF LFPSCR +%token LLR LCTR LSPR LSPREG LSEG LMSR +%token LSCHED LXLD LXST LXOP LXMV +%token LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA +%token LFCONST +%token LSCONST +%token LNAME LLAB LVAR +%type con expr pointer offset sreg +%type addr rreg regaddr name creg freg xlreg lr ctr +%type imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask +%% +prog: +| prog 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 +| LNAME '=' expr ';' + { + $1->type = LVAR; + $1->value = $3; + } +| LVAR '=' expr ';' + { + if($1->value != $3) + yyerror("redeclaration of %s", $1->name); + $1->value = $3; + } +| LSCHED ';' + { + nosched = $1; + } +| ';' +| inst ';' +| error ';' + +inst: +/* + * load ints and bytes + */ + LMOVW rreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW addr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW regaddr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVB rreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVB addr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVB regaddr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +/* + * load floats + */ +| LFMOV addr ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LFMOV regaddr ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LFMOV fimm ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LFMOV freg ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LFMOV freg ',' addr + { + outcode($1, &$2, NREG, &$4); + } +| LFMOV freg ',' regaddr + { + outcode($1, &$2, NREG, &$4); + } +/* + * store ints and bytes + */ +| LMOVW rreg ',' addr + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW rreg ',' regaddr + { + outcode($1, &$2, NREG, &$4); + } +| LMOVB rreg ',' addr + { + outcode($1, &$2, NREG, &$4); + } +| LMOVB rreg ',' regaddr + { + outcode($1, &$2, NREG, &$4); + } +/* + * store floats + */ +| LMOVW freg ',' addr + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW freg ',' regaddr + { + outcode($1, &$2, NREG, &$4); + } +/* + * floating point status + */ +| LMOVW fpscr ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW freg ',' fpscr + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW freg ',' imm ',' fpscr + { + outgcode($1, &$2, NREG, &$4, &$6); + } +| LMOVW fpscr ',' creg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW imm ',' fpscrf + { + outcode($1, &$2, NREG, &$4); + } +| LMTFSB imm ',' con + { + outcode($1, &$2, $4, &nullgen); + } +/* + * field moves (mtcrf) + */ +| LMOVW rreg ',' imm ',' lcr + { + outgcode($1, &$2, NREG, &$4, &$6); + } +| LMOVW rreg ',' creg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW rreg ',' lcr + { + outcode($1, &$2, NREG, &$4); + } +/* + * integer operations + * logical instructions + * shift instructions + * unary instructions + */ +| LADDW rreg ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } +| LADDW imm ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } +| LADDW rreg ',' imm ',' rreg + { + outgcode($1, &$2, NREG, &$4, &$6); + } +| LADDW rreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LADDW imm ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LLOGW rreg ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } +| LLOGW rreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LSHW rreg ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } +| LSHW rreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LSHW imm ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } +| LSHW imm ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LABS rreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LABS rreg + { + outcode($1, &$2, NREG, &$2); + } +/* + * multiply-accumulate + */ +| LMA rreg ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } +/* + * move immediate: macro for cau+or, addi, addis, and other combinations + */ +| LMOVW imm ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW ximm ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +/* + * condition register operations + */ +| LCROP cbit ',' cbit + { + outcode($1, &$2, $4.reg, &$4); + } +| LCROP cbit ',' con ',' cbit + { + outcode($1, &$2, $4, &$6); + } +/* + * condition register moves + * move from machine state register + */ +| LMOVW creg ',' creg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW psr ',' creg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW lcr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW psr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW xlreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW rreg ',' xlreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW creg ',' psr + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW rreg ',' psr + { + outcode($1, &$2, NREG, &$4); + } +/* + * branch, branch conditional + * branch conditional register + * branch conditional to count register + */ +| LBRA rel + { + outcode($1, &nullgen, NREG, &$2); + } +| LBRA addr + { + outcode($1, &nullgen, NREG, &$2); + } +| LBRA '(' xlreg ')' + { + outcode($1, &nullgen, NREG, &$3); + } +| LBRA ',' rel + { + outcode($1, &nullgen, NREG, &$3); + } +| LBRA ',' addr + { + outcode($1, &nullgen, NREG, &$3); + } +| LBRA ',' '(' xlreg ')' + { + outcode($1, &nullgen, NREG, &$4); + } +| LBRA creg ',' rel + { + outcode($1, &$2, NREG, &$4); + } +| LBRA creg ',' addr + { + outcode($1, &$2, NREG, &$4); + } +| LBRA creg ',' '(' xlreg ')' + { + outcode($1, &$2, NREG, &$5); + } +| LBRA con ',' rel + { + outcode($1, &nullgen, $2, &$4); + } +| LBRA con ',' addr + { + outcode($1, &nullgen, $2, &$4); + } +| LBRA con ',' '(' xlreg ')' + { + outcode($1, &nullgen, $2, &$5); + } +| LBRA con ',' con ',' rel + { + Gen g; + g = nullgen; + g.type = D_CONST; + g.offset = $2; + outcode($1, &g, $4, &$6); + } +| LBRA con ',' con ',' addr + { + Gen g; + g = nullgen; + g.type = D_CONST; + g.offset = $2; + outcode($1, &g, $4, &$6); + } +| LBRA con ',' con ',' '(' xlreg ')' + { + Gen g; + g = nullgen; + g.type = D_CONST; + g.offset = $2; + outcode($1, &g, $4, &$7); + } +/* + * conditional trap + */ +| LTRAP rreg ',' sreg + { + outcode($1, &$2, $4, &nullgen); + } +| LTRAP imm ',' sreg + { + outcode($1, &$2, $4, &nullgen); + } +| LTRAP rreg comma + { + outcode($1, &$2, NREG, &nullgen); + } +| LTRAP comma + { + outcode($1, &nullgen, NREG, &nullgen); + } +/* + * floating point operate + */ +| LFCONV freg ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LFADD freg ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LFADD freg ',' freg ',' freg + { + outcode($1, &$2, $4.reg, &$6); + } +| LFMA freg ',' freg ',' freg ',' freg + { + outgcode($1, &$2, $4.reg, &$6, &$8); + } +| LFCMP freg ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LFCMP freg ',' freg ',' creg + { + outcode($1, &$2, $6.reg, &$4); + } +/* + * CMP + */ +| LCMP rreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LCMP rreg ',' imm + { + outcode($1, &$2, NREG, &$4); + } +| LCMP rreg ',' rreg ',' creg + { + outcode($1, &$2, $6.reg, &$4); + } +| LCMP rreg ',' imm ',' creg + { + outcode($1, &$2, $6.reg, &$4); + } +/* + * rotate and mask + */ +| LRLWM imm ',' rreg ',' imm ',' rreg + { + outgcode($1, &$2, $4.reg, &$6, &$8); + } +| LRLWM imm ',' rreg ',' mask ',' rreg + { + outgcode($1, &$2, $4.reg, &$6, &$8); + } +| LRLWM rreg ',' rreg ',' imm ',' rreg + { + outgcode($1, &$2, $4.reg, &$6, &$8); + } +| LRLWM rreg ',' rreg ',' mask ',' rreg + { + outgcode($1, &$2, $4.reg, &$6, &$8); + } +/* + * load/store multiple + */ +| LMOVMW addr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVMW rreg ',' addr + { + outcode($1, &$2, NREG, &$4); + } +/* + * various indexed load/store + * indexed unary (eg, cache clear) + */ +| LXLD regaddr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LXLD regaddr ',' imm ',' rreg + { + outgcode($1, &$2, NREG, &$4, &$6); + } +| LXST rreg ',' regaddr + { + outcode($1, &$2, NREG, &$4); + } +| LXST rreg ',' imm ',' regaddr + { + outgcode($1, &$2, NREG, &$4, &$6); + } +| LXMV regaddr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LXMV rreg ',' regaddr + { + outcode($1, &$2, NREG, &$4); + } +| LXOP regaddr + { + outcode($1, &$2, NREG, &nullgen); + } +/* + * NOP + */ +| LNOP comma + { + outcode($1, &nullgen, NREG, &nullgen); + } +| LNOP rreg comma + { + outcode($1, &$2, NREG, &nullgen); + } +| LNOP freg comma + { + outcode($1, &$2, NREG, &nullgen); + } +| LNOP ',' rreg + { + outcode($1, &nullgen, NREG, &$3); + } +| LNOP ',' freg + { + outcode($1, &nullgen, NREG, &$3); + } +/* + * word + */ +| LWORD imm comma + { + if($1 == ADWORD && $2.type == D_CONST) + $2.type = D_DCONST; + outcode($1, &$2, NREG, &nullgen); + } +| LWORD ximm comma + { + if($1 == ADWORD && $2.type == D_CONST) + $2.type = D_DCONST; + outcode($1, &$2, NREG, &nullgen); + } +/* + * END + */ +| LEND comma + { + outcode($1, &nullgen, NREG, &nullgen); + } +/* + * TEXT/GLOBL + */ +| LTEXT name ',' imm + { + outcode($1, &$2, NREG, &$4); + } +| LTEXT name ',' con ',' imm + { + outcode($1, &$2, $4, &$6); + } +| LTEXT name ',' imm ':' imm + { + outgcode($1, &$2, NREG, &$6, &$4); + } +| LTEXT name ',' con ',' imm ':' imm + { + outgcode($1, &$2, $4, &$8, &$6); + } +/* + * DATA + */ +| LDATA name '/' con ',' imm + { + outcode($1, &$2, $4, &$6); + } +| LDATA name '/' con ',' ximm + { + outcode($1, &$2, $4, &$6); + } +| LDATA name '/' con ',' fimm + { + outcode($1, &$2, $4, &$6); + } +/* + * RETURN + */ +| LRETRN comma + { + outcode($1, &nullgen, NREG, &nullgen); + } + +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; + } + +rreg: + sreg + { + $$ = nullgen; + $$.type = D_REG; + $$.reg = $1; + } + +xlreg: + lr +| ctr + +lr: + LLR + { + $$ = nullgen; + $$.type = D_SPR; + $$.offset = $1; + } + +lcr: + LCR + { + $$ = nullgen; + $$.type = D_CREG; + $$.reg = NREG; /* whole register */ + } + +ctr: + LCTR + { + $$ = nullgen; + $$.type = D_SPR; + $$.offset = $1; + } + +msr: + LMSR + { + $$ = nullgen; + $$.type = D_MSR; + } + +psr: + LSPREG + { + $$ = nullgen; + $$.type = D_SPR; + $$.offset = $1; + } +| LSPR '(' con ')' + { + $$ = nullgen; + $$.type = $1; + $$.offset = $3; + } +| msr + +fpscr: + LFPSCR + { + $$ = nullgen; + $$.type = D_FPSCR; + $$.reg = NREG; + } + +fpscrf: + LFPSCR '(' con ')' + { + $$ = nullgen; + $$.type = D_FPSCR; + $$.reg = $3; + } + +freg: + LFREG + { + $$ = nullgen; + $$.type = D_FREG; + $$.reg = $1; + } +| LF '(' con ')' + { + $$ = nullgen; + $$.type = D_FREG; + $$.reg = $3; + } + +creg: + LCREG + { + $$ = nullgen; + $$.type = D_CREG; + $$.reg = $1; + } +| LCR '(' con ')' + { + $$ = nullgen; + $$.type = D_CREG; + $$.reg = $3; + } + + +cbit: con + { + $$ = nullgen; + $$.type = D_REG; + $$.reg = $1; + } + +mask: + con ',' con + { + int mb, me; + ulong v; + + $$ = nullgen; + $$.type = D_CONST; + mb = $1; + me = $3; + if(mb < 0 || mb > 31 || me < 0 || me > 31){ + yyerror("illegal mask start/end value(s)"); + mb = me = 0; + } + if(mb <= me) + v = ((ulong)~0L>>mb) & (~0L<<(31-me)); + else + v = ~(((ulong)~0L>>(me+1)) & (~0L<<(31-(mb-1)))); + $$.offset = v; + } + +ximm: + '$' addr + { + $$ = $2; + $$.type = D_CONST; + } +| '$' LSCONST + { + $$ = nullgen; + $$.type = D_SCONST; + memcpy($$.sval, $2, sizeof($$.sval)); + } + +fimm: + '$' LFCONST + { + $$ = nullgen; + $$.type = D_FCONST; + $$.dval = $2; + } +| '$' '-' LFCONST + { + $$ = nullgen; + $$.type = D_FCONST; + $$.dval = -$3; + } + +imm: '$' con + { + $$ = nullgen; + $$.type = D_CONST; + $$.offset = $2; + } + +sreg: + LREG +| LR '(' con ')' + { + if($$ < 0 || $$ >= NREG) + print("register value out of range\n"); + $$ = $3; + } + +regaddr: + '(' sreg ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.reg = $2; + $$.offset = 0; + } +| '(' sreg '+' sreg ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.reg = $2; + $$.xreg = $4; + $$.offset = 0; + } + +addr: + name +| con '(' sreg ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.reg = $3; + $$.offset = $1; + } + +name: + con '(' pointer ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.name = $3; + $$.sym = S; + $$.offset = $1; + } +| LNAME offset '(' pointer ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.name = $4; + $$.sym = $1; + $$.offset = $2; + } +| LNAME '<' '>' offset '(' LSB ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.name = D_STATIC; + $$.sym = $1; + $$.offset = $4; + } + +comma: +| ',' + +offset: + { + $$ = 0; + } +| '+' con + { + $$ = $2; + } +| '-' con + { + $$ = -$2; + } + +pointer: + LSB +| LSP +| LFP + +con: + LCONST +| LVAR + { + $$ = $1->value; + } +| '-' con + { + $$ = -$2; + } +| '+' con + { + $$ = $2; + } +| '~' con + { + $$ = ~$2; + } +| '(' expr ')' + { + $$ = $2; + } + +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; + } -- cgit v1.2.1 From 0178f2a25fe69bf71ea233df543f42267bc2e526 Mon Sep 17 00:00:00 2001 From: Shenghou Ma Date: Thu, 7 Aug 2014 14:49:41 -0400 Subject: [dev.power64] cmd/9a: use liblink, add required additional instructions. LGTM=rsc R=rsc, iant CC=golang-codereviews https://codereview.appspot.com/127730043 --- src/cmd/9a/a.y | 80 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 29 deletions(-) (limited to 'src/cmd/9a/a.y') diff --git a/src/cmd/9a/a.y b/src/cmd/9a/a.y index e77d78c6d..2e0317e06 100644 --- a/src/cmd/9a/a.y +++ b/src/cmd/9a/a.y @@ -28,7 +28,11 @@ // THE SOFTWARE. %{ +#include +#include /* if we don't, bison will, and a.h re-#defines getc */ +#include #include "a.h" +#include "../../pkg/runtime/funcdata.h" %} %union { @@ -36,7 +40,7 @@ vlong lval; double dval; char sval[8]; - Gen gen; + Addr addr; } %left '|' %left '^' @@ -50,14 +54,14 @@ %token LCONST LSP LSB LFP LPC LCREG LFLUSH %token LREG LFREG LR LCR LF LFPSCR %token LLR LCTR LSPR LSPREG LSEG LMSR -%token LSCHED LXLD LXST LXOP LXMV +%token LPCDAT LFUNCDAT LSCHED LXLD LXST LXOP LXMV %token LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA %token LFCONST %token LSCONST %token LNAME LLAB LVAR %type con expr pointer offset sreg -%type addr rreg regaddr name creg freg xlreg lr ctr -%type imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask +%type addr rreg regaddr name creg freg xlreg lr ctr +%type imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask %% prog: | prog line @@ -400,7 +404,7 @@ inst: } | LBRA con ',' con ',' rel { - Gen g; + Addr g; g = nullgen; g.type = D_CONST; g.offset = $2; @@ -408,7 +412,7 @@ inst: } | LBRA con ',' con ',' addr { - Gen g; + Addr g; g = nullgen; g.type = D_CONST; g.offset = $2; @@ -416,7 +420,7 @@ inst: } | LBRA con ',' con ',' '(' xlreg ')' { - Gen g; + Addr g; g = nullgen; g.type = D_CONST; g.offset = $2; @@ -572,21 +576,41 @@ inst: { outcode($1, &nullgen, NREG, &$3); } +| LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */ + { + outcode($1, &$2, NREG, &nullgen); + } /* * word */ | LWORD imm comma { - if($1 == ADWORD && $2.type == D_CONST) - $2.type = D_DCONST; outcode($1, &$2, NREG, &nullgen); } | LWORD ximm comma { - if($1 == ADWORD && $2.type == D_CONST) - $2.type = D_DCONST; outcode($1, &$2, NREG, &nullgen); } +/* + * PCDATA + */ +| LPCDAT imm ',' imm + { + if($2.type != D_CONST || $4.type != D_CONST) + yyerror("arguments to PCDATA must be integer constants"); + outcode($1, &$2, NREG, &$4); + } +/* + * FUNCDATA + */ +| LFUNCDAT imm ',' addr + { + if($2.type != D_CONST) + yyerror("index for FUNCDATA must be integer constant"); + if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG) + yyerror("value for FUNCDATA must be symbol reference"); + outcode($1, &$2, NREG, &$4); + } /* * END */ @@ -603,15 +627,15 @@ inst: } | LTEXT name ',' con ',' imm { + $6.offset &= 0xffffffffull; + $6.offset |= (vlong)ArgsSizeUnknown << 32; outcode($1, &$2, $4, &$6); } -| LTEXT name ',' imm ':' imm +| LTEXT name ',' con ',' imm '-' con { - outgcode($1, &$2, NREG, &$6, &$4); - } -| LTEXT name ',' con ',' imm ':' imm - { - outgcode($1, &$2, $4, &$8, &$6); + $6.offset &= 0xffffffffull; + $6.offset |= ($8 & 0xffffffffull) << 32; + outcode($1, &$2, $4, &$6); } /* * DATA @@ -649,14 +673,12 @@ rel: 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; } @@ -774,7 +796,7 @@ mask: con ',' con { int mb, me; - ulong v; + uint32 v; $$ = nullgen; $$.type = D_CONST; @@ -785,9 +807,9 @@ mask: mb = me = 0; } if(mb <= me) - v = ((ulong)~0L>>mb) & (~0L<<(31-me)); + v = ((uint32)~0L>>mb) & (~0L<<(31-me)); else - v = ~(((ulong)~0L>>(me+1)) & (~0L<<(31-(mb-1)))); + v = ~(((uint32)~0L>>(me+1)) & (~0L<<(31-(mb-1)))); $$.offset = v; } @@ -801,7 +823,7 @@ ximm: { $$ = nullgen; $$.type = D_SCONST; - memcpy($$.sval, $2, sizeof($$.sval)); + memcpy($$.u.sval, $2, sizeof($$.u.sval)); } fimm: @@ -809,13 +831,13 @@ fimm: { $$ = nullgen; $$.type = D_FCONST; - $$.dval = $2; + $$.u.dval = $2; } | '$' '-' LFCONST { $$ = nullgen; $$.type = D_FCONST; - $$.dval = -$3; + $$.u.dval = -$3; } imm: '$' con @@ -847,7 +869,7 @@ regaddr: $$ = nullgen; $$.type = D_OREG; $$.reg = $2; - $$.xreg = $4; + $$.scale = $4; $$.offset = 0; } @@ -867,7 +889,7 @@ name: $$ = nullgen; $$.type = D_OREG; $$.name = $3; - $$.sym = S; + $$.sym = nil; $$.offset = $1; } | LNAME offset '(' pointer ')' @@ -875,7 +897,7 @@ name: $$ = nullgen; $$.type = D_OREG; $$.name = $4; - $$.sym = $1; + $$.sym = linklookup(ctxt, $1->name, 0); $$.offset = $2; } | LNAME '<' '>' offset '(' LSB ')' @@ -883,7 +905,7 @@ name: $$ = nullgen; $$.type = D_OREG; $$.name = D_STATIC; - $$.sym = $1; + $$.sym = linklookup(ctxt, $1->name, 0); $$.offset = $4; } -- cgit v1.2.1 From 05d42f8a61328aa7ea55887f601286b597caf0da Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 28 Oct 2014 21:50:16 -0400 Subject: [dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped I removed support for jumping between functions years ago, as part of doing the instruction layout for each function separately. Given that, it makes sense to treat labels as function-scoped. This lets each function have its own 'loop' label, for example. Makes the assembly much cleaner and removes the last reason anyone would reach for the 123(PC) form instead. Note that this is on the dev.power64 branch, but it changes all the assemblers. The change will ship in Go 1.5 (perhaps after being ported into the new assembler). Came up as part of CL 167730043. LGTM=r R=r CC=austin, dave, golang-codereviews, minux https://codereview.appspot.com/159670043 --- src/cmd/9a/a.y | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'src/cmd/9a/a.y') diff --git a/src/cmd/9a/a.y b/src/cmd/9a/a.y index 41776fd3c..b36614615 100644 --- a/src/cmd/9a/a.y +++ b/src/cmd/9a/a.y @@ -67,15 +67,11 @@ prog: | prog line line: - LLAB ':' - { - if($1->value != pc) - yyerror("redeclaration of %s", $1->name); - $1->value = pc; - } - line -| LNAME ':' + LNAME ':' { + $1 = labellookup($1); + if($1->type == LLAB && $1->value != pc) + yyerror("redeclaration of %s", $1->labelname); $1->type = LLAB; $1->value = pc; } @@ -623,16 +619,19 @@ inst: */ | LTEXT name ',' imm { + settext($2.sym); outcode($1, &$2, NREG, &$4); } | LTEXT name ',' con ',' imm { + settext($2.sym); $6.offset &= 0xffffffffull; $6.offset |= (vlong)ArgsSizeUnknown << 32; outcode($1, &$2, $4, &$6); } | LTEXT name ',' con ',' imm '-' con { + settext($2.sym); $6.offset &= 0xffffffffull; $6.offset |= ($8 & 0xffffffffull) << 32; outcode($1, &$2, $4, &$6); @@ -669,15 +668,10 @@ rel: } | LNAME offset { + $1 = labellookup($1); $$ = nullgen; - if(pass == 2) - yyerror("undefined label: %s", $1->name); - $$.type = D_BRANCH; - $$.offset = $2; - } -| LLAB offset - { - $$ = nullgen; + if(pass == 2 && $1->type != LLAB) + yyerror("undefined label: %s", $1->labelname); $$.type = D_BRANCH; $$.offset = $1->value + $2; } -- cgit v1.2.1