Commit da47902d authored by Russ Cox's avatar Russ Cox

cmd/9a, cmd/9g, cmd/9l, liblink: update for portable Prog, Addr

Change-Id: I55afed0eabf3c38e72ff105294782ac36446b66b
Reviewed-on: https://go-review.googlesource.com/3519Reviewed-by: default avatarAram Hăvărneanu <aram@mgk.ro>
parent a5b1baee
......@@ -61,7 +61,7 @@
%token <sym> LNAME LLAB LVAR
%type <lval> con expr pointer offset sreg
%type <addr> addr rreg regaddr name creg freg xlreg lr ctr
%type <addr> imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask
%type <addr> imm ximm fimm rel psr lcr cbit fpscr msr mask
%%
prog:
| prog line
......@@ -101,107 +101,103 @@ inst:
*/
LMOVW rreg ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW addr ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW regaddr ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVB rreg ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVB addr ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVB regaddr ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* load floats
*/
| LFMOV addr ',' freg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LFMOV regaddr ',' freg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LFMOV fimm ',' freg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LFMOV freg ',' freg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LFMOV freg ',' addr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LFMOV freg ',' regaddr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* store ints and bytes
*/
| LMOVW rreg ',' addr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW rreg ',' regaddr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVB rreg ',' addr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVB rreg ',' regaddr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* store floats
*/
| LMOVW freg ',' addr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW freg ',' regaddr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* floating point status
*/
| LMOVW fpscr ',' freg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW freg ',' fpscr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW freg ',' imm ',' fpscr
{
outgcode($1, &$2, NREG, &$4, &$6);
outgcode($1, &$2, 0, &$4, &$6);
}
| LMOVW fpscr ',' creg
{
outcode($1, &$2, NREG, &$4);
}
| LMOVW imm ',' fpscrf
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMTFSB imm ',' con
{
......@@ -212,15 +208,15 @@ inst:
*/
| LMOVW rreg ',' imm ',' lcr
{
outgcode($1, &$2, NREG, &$4, &$6);
outgcode($1, &$2, 0, &$4, &$6);
}
| LMOVW rreg ',' creg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW rreg ',' lcr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* integer operations
......@@ -238,15 +234,15 @@ inst:
}
| LADDW rreg ',' imm ',' rreg
{
outgcode($1, &$2, NREG, &$4, &$6);
outgcode($1, &$2, 0, &$4, &$6);
}
| LADDW rreg ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LADDW imm ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LLOGW rreg ',' sreg ',' rreg
{
......@@ -254,7 +250,7 @@ inst:
}
| LLOGW rreg ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LSHW rreg ',' sreg ',' rreg
{
......@@ -262,7 +258,7 @@ inst:
}
| LSHW rreg ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LSHW imm ',' sreg ',' rreg
{
......@@ -270,15 +266,15 @@ inst:
}
| LSHW imm ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LABS rreg ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LABS rreg
{
outcode($1, &$2, NREG, &$2);
outcode($1, &$2, 0, &$2);
}
/*
* multiply-accumulate
......@@ -292,11 +288,11 @@ inst:
*/
| LMOVW imm ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW ximm ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* condition register operations
......@@ -315,35 +311,35 @@ inst:
*/
| LMOVW creg ',' creg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW psr ',' creg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW lcr ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW psr ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW xlreg ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW rreg ',' xlreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW creg ',' psr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVW rreg ',' psr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* branch, branch conditional
......@@ -352,39 +348,39 @@ inst:
*/
| LBRA rel
{
outcode($1, &nullgen, NREG, &$2);
outcode($1, &nullgen, 0, &$2);
}
| LBRA addr
{
outcode($1, &nullgen, NREG, &$2);
outcode($1, &nullgen, 0, &$2);
}
| LBRA '(' xlreg ')'
{
outcode($1, &nullgen, NREG, &$3);
outcode($1, &nullgen, 0, &$3);
}
| LBRA ',' rel
{
outcode($1, &nullgen, NREG, &$3);
outcode($1, &nullgen, 0, &$3);
}
| LBRA ',' addr
{
outcode($1, &nullgen, NREG, &$3);
outcode($1, &nullgen, 0, &$3);
}
| LBRA ',' '(' xlreg ')'
{
outcode($1, &nullgen, NREG, &$4);
outcode($1, &nullgen, 0, &$4);
}
| LBRA creg ',' rel
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LBRA creg ',' addr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LBRA creg ',' '(' xlreg ')'
{
outcode($1, &$2, NREG, &$5);
outcode($1, &$2, 0, &$5);
}
| LBRA con ',' rel
{
......@@ -402,25 +398,25 @@ inst:
{
Addr g;
g = nullgen;
g.type = D_CONST;
g.type = TYPE_CONST;
g.offset = $2;
outcode($1, &g, $4, &$6);
outcode($1, &g, REG_R0+$4, &$6);
}
| LBRA con ',' con ',' addr
{
Addr g;
g = nullgen;
g.type = D_CONST;
g.type = TYPE_CONST;
g.offset = $2;
outcode($1, &g, $4, &$6);
outcode($1, &g, REG_R0+$4, &$6);
}
| LBRA con ',' con ',' '(' xlreg ')'
{
Addr g;
g = nullgen;
g.type = D_CONST;
g.type = TYPE_CONST;
g.offset = $2;
outcode($1, &g, $4, &$7);
outcode($1, &g, REG_R0+$4, &$7);
}
/*
* conditional trap
......@@ -435,22 +431,22 @@ inst:
}
| LTRAP rreg comma
{
outcode($1, &$2, NREG, &nullgen);
outcode($1, &$2, 0, &nullgen);
}
| LTRAP comma
{
outcode($1, &nullgen, NREG, &nullgen);
outcode($1, &nullgen, 0, &nullgen);
}
/*
* floating point operate
*/
| LFCONV freg ',' freg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LFADD freg ',' freg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LFADD freg ',' freg ',' freg
{
......@@ -462,7 +458,7 @@ inst:
}
| LFCMP freg ',' freg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LFCMP freg ',' freg ',' creg
{
......@@ -473,11 +469,11 @@ inst:
*/
| LCMP rreg ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LCMP rreg ',' imm
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LCMP rreg ',' rreg ',' creg
{
......@@ -511,11 +507,11 @@ inst:
*/
| LMOVMW addr ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LMOVMW rreg ',' addr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* various indexed load/store
......@@ -523,96 +519,96 @@ inst:
*/
| LXLD regaddr ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LXLD regaddr ',' imm ',' rreg
{
outgcode($1, &$2, NREG, &$4, &$6);
outgcode($1, &$2, 0, &$4, &$6);
}
| LXST rreg ',' regaddr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LXST rreg ',' imm ',' regaddr
{
outgcode($1, &$2, NREG, &$4, &$6);
outgcode($1, &$2, 0, &$4, &$6);
}
| LXMV regaddr ',' rreg
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LXMV rreg ',' regaddr
{
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LXOP regaddr
{
outcode($1, &$2, NREG, &nullgen);
outcode($1, &$2, 0, &nullgen);
}
/*
* NOP
*/
| LNOP comma
{
outcode($1, &nullgen, NREG, &nullgen);
outcode($1, &nullgen, 0, &nullgen);
}
| LNOP rreg comma
{
outcode($1, &$2, NREG, &nullgen);
outcode($1, &$2, 0, &nullgen);
}
| LNOP freg comma
{
outcode($1, &$2, NREG, &nullgen);
outcode($1, &$2, 0, &nullgen);
}
| LNOP ',' rreg
{
outcode($1, &nullgen, NREG, &$3);
outcode($1, &nullgen, 0, &$3);
}
| LNOP ',' freg
{
outcode($1, &nullgen, NREG, &$3);
outcode($1, &nullgen, 0, &$3);
}
| LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
{
outcode($1, &$2, NREG, &nullgen);
outcode($1, &$2, 0, &nullgen);
}
/*
* word
*/
| LWORD imm comma
{
outcode($1, &$2, NREG, &nullgen);
outcode($1, &$2, 0, &nullgen);
}
| LWORD ximm comma
{
outcode($1, &$2, NREG, &nullgen);
outcode($1, &$2, 0, &nullgen);
}
/*
* PCDATA
*/
| LPCDAT imm ',' imm
{
if($2.type != D_CONST || $4.type != D_CONST)
if($2.type != TYPE_CONST || $4.type != TYPE_CONST)
yyerror("arguments to PCDATA must be integer constants");
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* FUNCDATA
*/
| LFUNCDAT imm ',' addr
{
if($2.type != D_CONST)
if($2.type != TYPE_CONST)
yyerror("index for FUNCDATA must be integer constant");
if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
if($4.type != NAME_EXTERN && $4.type != NAME_STATIC && $4.type != TYPE_MEM)
yyerror("value for FUNCDATA must be symbol reference");
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
/*
* END
*/
| LEND comma
{
outcode($1, &nullgen, NREG, &nullgen);
outcode($1, &nullgen, 0, &nullgen);
}
/*
* TEXT/GLOBL
......@@ -620,7 +616,7 @@ inst:
| LTEXT name ',' imm
{
settext($2.sym);
outcode($1, &$2, NREG, &$4);
outcode($1, &$2, 0, &$4);
}
| LTEXT name ',' con ',' imm
{
......@@ -656,14 +652,14 @@ inst:
*/
| LRETRN comma
{
outcode($1, &nullgen, NREG, &nullgen);
outcode($1, &nullgen, 0, &nullgen);
}
rel:
con '(' LPC ')'
{
$$ = nullgen;
$$.type = D_BRANCH;
$$.type = TYPE_BRANCH;
$$.offset = $1 + pc;
}
| LNAME offset
......@@ -672,7 +668,7 @@ rel:
$$ = nullgen;
if(pass == 2 && $1->type != LLAB)
yyerror("undefined label: %s", $1->labelname);
$$.type = D_BRANCH;
$$.type = TYPE_BRANCH;
$$.offset = $1->value + $2;
}
......@@ -680,7 +676,7 @@ rreg:
sreg
{
$$ = nullgen;
$$.type = D_REG;
$$.type = TYPE_REG;
$$.reg = $1;
}
......@@ -692,45 +688,48 @@ lr:
LLR
{
$$ = nullgen;
$$.type = D_SPR;
$$.offset = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
lcr:
LCR
{
$$ = nullgen;
$$.type = D_CREG;
$$.reg = NREG; /* whole register */
$$.type = TYPE_REG;
$$.reg = $1; /* whole register */
}
ctr:
LCTR
{
$$ = nullgen;
$$.type = D_SPR;
$$.offset = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
msr:
LMSR
{
$$ = nullgen;
$$.type = D_MSR;
$$.type = TYPE_REG;
$$.reg = $1;
}
psr:
LSPREG
{
$$ = nullgen;
$$.type = D_SPR;
$$.offset = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LSPR '(' con ')'
{
if($3 < 0 || $3 >= 1024)
yyerror("SPR/DCR out of range");
$$ = nullgen;
$$.type = $1;
$$.offset = $3;
$$.type = TYPE_REG;
$$.reg = $1 + $3;
}
| msr
......@@ -738,51 +737,43 @@ fpscr:
LFPSCR
{
$$ = nullgen;
$$.type = D_FPSCR;
$$.reg = NREG;
}
fpscrf:
LFPSCR '(' con ')'
{
$$ = nullgen;
$$.type = D_FPSCR;
$$.reg = $3;
$$.type = TYPE_REG;
$$.reg = $1;
}
freg:
LFREG
{
$$ = nullgen;
$$.type = D_FREG;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LF '(' con ')'
{
$$ = nullgen;
$$.type = D_FREG;
$$.reg = $3;
$$.type = TYPE_REG;
$$.reg = REG_F0 + $3;
}
creg:
LCREG
{
$$ = nullgen;
$$.type = D_CREG;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LCR '(' con ')'
{
$$ = nullgen;
$$.type = D_CREG;
$$.reg = $3;
$$.type = TYPE_REG;
$$.reg = REG_C0 + $3;
}
cbit: con
{
$$ = nullgen;
$$.type = D_REG;
$$.type = TYPE_REG;
$$.reg = $1;
}
......@@ -793,7 +784,7 @@ mask:
uint32 v;
$$ = nullgen;
$$.type = D_CONST;
$$.type = TYPE_CONST;
mb = $1;
me = $3;
if(mb < 0 || mb > 31 || me < 0 || me > 31){
......@@ -811,12 +802,12 @@ ximm:
'$' addr
{
$$ = $2;
$$.type = D_CONST;
$$.type = TYPE_CONST;
}
| '$' LSCONST
{
$$ = nullgen;
$$.type = D_SCONST;
$$.type = TYPE_SCONST;
memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
......@@ -824,20 +815,20 @@ fimm:
'$' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = $2;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = -$3;
}
imm: '$' con
{
$$ = nullgen;
$$.type = D_CONST;
$$.type = TYPE_CONST;
$$.offset = $2;
}
......@@ -847,21 +838,21 @@ sreg:
{
if($$ < 0 || $$ >= NREG)
print("register value out of range\n");
$$ = $3;
$$ = REG_R0 + $3;
}
regaddr:
'(' sreg ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.type = TYPE_MEM;
$$.reg = $2;
$$.offset = 0;
}
| '(' sreg '+' sreg ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.type = TYPE_MEM;
$$.reg = $2;
$$.scale = $4;
$$.offset = 0;
......@@ -872,7 +863,7 @@ addr:
| con '(' sreg ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1;
}
......@@ -881,7 +872,7 @@ name:
con '(' pointer ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.type = TYPE_MEM;
$$.name = $3;
$$.sym = nil;
$$.offset = $1;
......@@ -889,7 +880,7 @@ name:
| LNAME offset '(' pointer ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.type = TYPE_MEM;
$$.name = $4;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
......@@ -897,8 +888,8 @@ name:
| LNAME '<' '>' offset '(' LSB ')'
{
$$ = nullgen;
$$.type = D_OREG;
$$.name = D_STATIC;
$$.type = TYPE_MEM;
$$.name = NAME_STATIC;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $4;
}
......
......@@ -197,97 +197,97 @@ struct
ushort value;
} itab[] =
{
"SP", LSP, D_AUTO,
"SB", LSB, D_EXTERN,
"FP", LFP, D_PARAM,
"PC", LPC, D_BRANCH,
"LR", LLR, D_LR,
"CTR", LCTR, D_CTR,
"XER", LSPREG, D_XER,
"MSR", LMSR, D_MSR,
"FPSCR", LFPSCR, D_FPSCR,
"SPR", LSPR, D_SPR,
"DCR", LSPR, D_DCR,
"CR", LCR, 0,
"CR0", LCREG, 0,
"CR1", LCREG, 1,
"CR2", LCREG, 2,
"CR3", LCREG, 3,
"CR4", LCREG, 4,
"CR5", LCREG, 5,
"CR6", LCREG, 6,
"CR7", LCREG, 7,
"SP", LSP, NAME_AUTO,
"SB", LSB, NAME_EXTERN,
"FP", LFP, NAME_PARAM,
"PC", LPC, TYPE_BRANCH,
"LR", LLR, REG_LR,
"CTR", LCTR, REG_CTR,
"XER", LSPREG, REG_XER,
"MSR", LMSR, REG_MSR,
"FPSCR", LFPSCR, REG_FPSCR,
"SPR", LSPR, REG_SPR0,
"DCR", LSPR, REG_DCR0,
"CR", LCR, REG_CR,
"CR0", LCREG, REG_C0,
"CR1", LCREG, REG_C1,
"CR2", LCREG, REG_C2,
"CR3", LCREG, REG_C3,
"CR4", LCREG, REG_C4,
"CR5", LCREG, REG_C5,
"CR6", LCREG, REG_C6,
"CR7", LCREG, REG_C7,
"R", LR, 0,
"R0", LREG, 0,
"R1", LREG, 1,
"R2", LREG, 2,
"R3", LREG, 3,
"R4", LREG, 4,
"R5", LREG, 5,
"R6", LREG, 6,
"R7", LREG, 7,
"R8", LREG, 8,
"R9", LREG, 9,
"R10", LREG, 10,
"R11", LREG, 11,
"R12", LREG, 12,
"R13", LREG, 13,
"R14", LREG, 14,
"R15", LREG, 15,
"R16", LREG, 16,
"R17", LREG, 17,
"R18", LREG, 18,
"R19", LREG, 19,
"R20", LREG, 20,
"R21", LREG, 21,
"R22", LREG, 22,
"R23", LREG, 23,
"R24", LREG, 24,
"R25", LREG, 25,
"R26", LREG, 26,
"R27", LREG, 27,
"R28", LREG, 28,
"R29", LREG, 29,
"g", LREG, 30, // avoid unintentionally clobbering g using R30
"R31", LREG, 31,
"R0", LREG, REG_R0,
"R1", LREG, REG_R1,
"R2", LREG, REG_R2,
"R3", LREG, REG_R3,
"R4", LREG, REG_R4,
"R5", LREG, REG_R5,
"R6", LREG, REG_R6,
"R7", LREG, REG_R7,
"R8", LREG, REG_R8,
"R9", LREG, REG_R9,
"R10", LREG, REG_R10,
"R11", LREG, REG_R11,
"R12", LREG, REG_R12,
"R13", LREG, REG_R13,
"R14", LREG, REG_R14,
"R15", LREG, REG_R15,
"R16", LREG, REG_R16,
"R17", LREG, REG_R17,
"R18", LREG, REG_R18,
"R19", LREG, REG_R19,
"R20", LREG, REG_R20,
"R21", LREG, REG_R21,
"R22", LREG, REG_R22,
"R23", LREG, REG_R23,
"R24", LREG, REG_R24,
"R25", LREG, REG_R25,
"R26", LREG, REG_R26,
"R27", LREG, REG_R27,
"R28", LREG, REG_R28,
"R29", LREG, REG_R29,
"g", LREG, REG_R30, // avoid unintentionally clobbering g using R30
"R31", LREG, REG_R31,
"F", LF, 0,
"F0", LFREG, 0,
"F1", LFREG, 1,
"F2", LFREG, 2,
"F3", LFREG, 3,
"F4", LFREG, 4,
"F5", LFREG, 5,
"F6", LFREG, 6,
"F7", LFREG, 7,
"F8", LFREG, 8,
"F9", LFREG, 9,
"F10", LFREG, 10,
"F11", LFREG, 11,
"F12", LFREG, 12,
"F13", LFREG, 13,
"F14", LFREG, 14,
"F15", LFREG, 15,
"F16", LFREG, 16,
"F17", LFREG, 17,
"F18", LFREG, 18,
"F19", LFREG, 19,
"F20", LFREG, 20,
"F21", LFREG, 21,
"F22", LFREG, 22,
"F23", LFREG, 23,
"F24", LFREG, 24,
"F25", LFREG, 25,
"F26", LFREG, 26,
"F27", LFREG, 27,
"F28", LFREG, 28,
"F29", LFREG, 29,
"F30", LFREG, 30,
"F31", LFREG, 31,
"F0", LFREG, REG_F0,
"F1", LFREG, REG_F1,
"F2", LFREG, REG_F2,
"F3", LFREG, REG_F3,
"F4", LFREG, REG_F4,
"F5", LFREG, REG_F5,
"F6", LFREG, REG_F6,
"F7", LFREG, REG_F7,
"F8", LFREG, REG_F8,
"F9", LFREG, REG_F9,
"F10", LFREG, REG_F10,
"F11", LFREG, REG_F11,
"F12", LFREG, REG_F12,
"F13", LFREG, REG_F13,
"F14", LFREG, REG_F14,
"F15", LFREG, REG_F15,
"F16", LFREG, REG_F16,
"F17", LFREG, REG_F17,
"F18", LFREG, REG_F18,
"F19", LFREG, REG_F19,
"F20", LFREG, REG_F20,
"F21", LFREG, REG_F21,
"F22", LFREG, REG_F22,
"F23", LFREG, REG_F23,
"F24", LFREG, REG_F24,
"F25", LFREG, REG_F25,
"F26", LFREG, REG_F26,
"F27", LFREG, REG_F27,
"F28", LFREG, REG_F28,
"F29", LFREG, REG_F29,
"F30", LFREG, REG_F30,
"F31", LFREG, REG_F31,
"CREQV", LCROP, ACREQV,
"CRXOR", LCROP, ACRXOR,
......@@ -616,10 +616,10 @@ cinit(void)
Sym *s;
int i;
nullgen.type = D_NONE;
nullgen.name = D_NONE;
nullgen.reg = NREG;
nullgen.scale = NREG; // replaced Gen.xreg with Prog.scale
nullgen.type = TYPE_NONE;
nullgen.name = NAME_NONE;
nullgen.reg = 0;
nullgen.scale = 0; // replaced Gen.xreg with Prog.scale
nerrors = 0;
iostack = I;
......@@ -647,7 +647,7 @@ void
cclean(void)
{
outcode(AEND, &nullgen, NREG, &nullgen);
outcode(AEND, &nullgen, 0, &nullgen);
}
static Prog *lastpc;
......@@ -661,13 +661,13 @@ outcode(int a, Addr *g1, int reg, Addr *g2)
if(pass == 1)
goto out;
if(g1->scale != NREG) {
if(reg != NREG || g2->scale != NREG)
if(g1->scale != 0) {
if(reg != 0 || g2->scale != 0)
yyerror("bad addressing modes");
reg = g1->scale;
} else
if(g2->scale != NREG) {
if(reg != NREG)
if(g2->scale != 0) {
if(reg != 0)
yyerror("bad addressing modes");
reg = g2->scale;
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -731,7 +731,7 @@ agenr(Node *n, Node *a, Node *res)
else {
regalloc(&n4, types[TUINT64], N);
p1 = gins(AMOVD, N, &n4);
p1->from.type = D_CONST;
p1->from.type = TYPE_CONST;
p1->from.offset = nl->type->bound;
}
}
......@@ -749,7 +749,7 @@ agenr(Node *n, Node *a, Node *res)
regalloc(&n3, types[tptr], res);
p1 = gins(AMOVD, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.type = D_CONST;
p1->from.type = TYPE_CONST;
} else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
......@@ -968,7 +968,7 @@ igen(Node *n, Node *a, Node *res)
case OINDREG:
// Increase the refcount of the register so that igen's caller
// has to call regfree.
if(n->val.u.reg != D_R0+REGSP)
if(n->val.u.reg != REGSP)
reg[n->val.u.reg]++;
*a = *n;
return;
......@@ -1006,7 +1006,7 @@ igen(Node *n, Node *a, Node *res)
fp = structfirst(&flist, getoutarg(n->left->type));
memset(a, 0, sizeof *a);
a->op = OINDREG;
a->val.u.reg = D_R0+REGSP;
a->val.u.reg = REGSP;
a->addable = 1;
a->xoffset = fp->width + widthptr; // +widthptr: saved lr at 0(SP)
a->type = n->type;
......@@ -1465,25 +1465,25 @@ sgen(Node *n, Node *ns, int64 w)
}
p = gins(AADD, N, &src);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = w;
p = gins(AADD, N, &dst);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = w;
} else {
p = gins(AADD, N, &src);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = -dir;
p = gins(AADD, N, &dst);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = -dir;
if(c >= 4) {
regalloc(&nend, types[tptr], N);
p = gins(AMOVD, &src, &nend);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = w;
}
}
......@@ -1493,12 +1493,12 @@ sgen(Node *n, Node *ns, int64 w)
// TODO: enable duffcopy for larger copies.
if(c >= 4) {
p = gins(op, &src, &tmp);
p->from.type = D_OREG;
p->from.type = TYPE_MEM;
p->from.offset = dir;
ploop = p;
p = gins(op, &tmp, &dst);
p->to.type = D_OREG;
p->to.type = TYPE_MEM;
p->to.offset = dir;
p = gins(ACMP, &src, &nend);
......@@ -1508,11 +1508,11 @@ sgen(Node *n, Node *ns, int64 w)
} else {
while(c-- > 0) {
p = gins(op, &src, &tmp);
p->from.type = D_OREG;
p->from.type = TYPE_MEM;
p->from.offset = dir;
p = gins(op, &tmp, &dst);
p->to.type = D_OREG;
p->to.type = TYPE_MEM;
p->to.offset = dir;
}
}
......
......@@ -43,14 +43,7 @@ betypeinit(void)
widthint = 8;
widthreg = 8;
zprog.link = P;
zprog.as = AGOK;
zprog.reg = NREG;
zprog.from.name = D_NONE;
zprog.from.type = D_NONE;
zprog.from.reg = NREG;
zprog.to = zprog.from;
zprog.from3 = zprog.from;
arch.zprog = zprog;
listinit9();
......@@ -80,10 +73,6 @@ main(int argc, char **argv)
arch.AUNDEF = AUNDEF;
arch.AVARDEF = AVARDEF;
arch.AVARKILL = AVARKILL;
arch.D_AUTO = D_AUTO;
arch.D_BRANCH = D_BRANCH;
arch.D_NONE = D_NONE;
arch.D_PARAM = D_PARAM;
arch.MAXWIDTH = MAXWIDTH;
arch.afunclit = afunclit;
arch.anyregalloc = anyregalloc;
......
......@@ -72,25 +72,25 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi)
return p;
if(cnt < 4*widthptr) {
for(i = 0; i < cnt; i += widthptr)
p = appendpp(p, AMOVD, D_REG, REGZERO, 0, D_OREG, REGSP, 8+frame+lo+i);
p = appendpp(p, AMOVD, TYPE_REG, REGZERO, 0, TYPE_MEM, REGSP, 8+frame+lo+i);
} else if(cnt <= 128*widthptr) {
p = appendpp(p, AADD, D_CONST, NREG, 8+frame+lo-8, D_REG, REGRT1, 0);
p = appendpp(p, AADD, TYPE_CONST, 0, 8+frame+lo-8, TYPE_REG, REGRT1, 0);
p->reg = REGSP;
p = appendpp(p, ADUFFZERO, D_NONE, NREG, 0, D_OREG, NREG, 0);
p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_MEM, 0, 0);
f = sysfunc("duffzero");
naddr(f, &p->to, 1);
afunclit(&p->to, f);
p->to.offset = 4*(128-cnt/widthptr);
} else {
p = appendpp(p, AMOVD, D_CONST, NREG, 8+frame+lo-8, D_REG, REGTMP, 0);
p = appendpp(p, AADD, D_REG, REGTMP, 0, D_REG, REGRT1, 0);
p = appendpp(p, AMOVD, TYPE_CONST, 0, 8+frame+lo-8, TYPE_REG, REGTMP, 0);
p = appendpp(p, AADD, TYPE_REG, REGTMP, 0, TYPE_REG, REGRT1, 0);
p->reg = REGSP;
p = appendpp(p, AMOVD, D_CONST, NREG, cnt, D_REG, REGTMP, 0);
p = appendpp(p, AADD, D_REG, REGTMP, 0, D_REG, REGRT2, 0);
p = appendpp(p, AMOVD, TYPE_CONST, 0, cnt, TYPE_REG, REGTMP, 0);
p = appendpp(p, AADD, TYPE_REG, REGTMP, 0, TYPE_REG, REGRT2, 0);
p->reg = REGRT1;
p1 = p = appendpp(p, AMOVDU, D_REG, REGZERO, 0, D_OREG, REGRT1, widthptr);
p = appendpp(p, ACMP, D_REG, REGRT1, 0, D_REG, REGRT2, 0);
p = appendpp(p, ABNE, D_NONE, NREG, 0, D_BRANCH, NREG, 0);
p1 = p = appendpp(p, AMOVDU, TYPE_REG, REGZERO, 0, TYPE_MEM, REGRT1, widthptr);
p = appendpp(p, ACMP, TYPE_REG, REGRT1, 0, TYPE_REG, REGRT2, 0);
p = appendpp(p, ABNE, TYPE_NONE, 0, 0, TYPE_BRANCH, 0, 0);
patch(p, p1);
}
return p;
......@@ -138,7 +138,7 @@ fixautoused(Prog *p)
Prog **lp;
for (lp=&p; (p=*lp) != P; ) {
if (p->as == ATYPE && p->from.node && p->from.name == D_AUTO && !((Node*)(p->from.node))->used) {
if (p->as == ATYPE && p->from.node && p->from.name == NAME_AUTO && !((Node*)(p->from.node))->used) {
*lp = p->link;
continue;
}
......@@ -147,15 +147,13 @@ fixautoused(Prog *p)
// VARDEFs are interspersed with other code, and a jump might be using the
// VARDEF as a target. Replace with a no-op instead. A later pass will remove
// the no-ops.
p->to.type = D_NONE;
p->to.node = N;
p->as = ANOP;
nopout(p);
continue;
}
if (p->from.name == D_AUTO && p->from.node)
if (p->from.name == NAME_AUTO && p->from.node)
p->from.offset += ((Node*)(p->from.node))->stkdelta;
if (p->to.name == D_AUTO && p->to.node)
if (p->to.name == NAME_AUTO && p->to.node)
p->to.offset += ((Node*)(p->to.node))->stkdelta;
lp = &p->link;
......@@ -172,11 +170,11 @@ ginsBL(Node *reg, Node *f)
{
Prog *p;
p = gins(AMOVD, f, N);
p->to.type = D_SPR;
p->to.offset = D_CTR;
p->to.type = TYPE_REG;
p->to.reg = REG_CTR;
p = gins(ABL, reg, N);
p->to.type = D_SPR;
p->to.offset = D_CTR;
p->to.type = TYPE_REG;
p->to.reg = REG_CTR;
}
/*
......@@ -221,7 +219,7 @@ ginscall(Node *f, int proc)
// The ppc64 NOP is really or r0, r0, r0; use that description
// because the NOP pseudo-instruction would be removed by
// the linker.
nodreg(&reg, types[TINT], D_R0);
nodreg(&reg, types[TINT], REG_R0);
gins(AOR, &reg, &reg);
}
p = gins(ABL, N, f);
......@@ -230,8 +228,8 @@ ginscall(Node *f, int proc)
gins(AUNDEF, N, N);
break;
}
nodreg(&reg, types[tptr], D_R0+REGENV);
nodreg(&r1, types[tptr], D_R0+3);
nodreg(&reg, types[tptr], REGENV);
nodreg(&r1, types[tptr], REG_R3);
gmove(f, &reg);
reg.op = OINDREG;
gmove(&reg, &r1);
......@@ -246,18 +244,18 @@ ginscall(Node *f, int proc)
case 1: // call in new proc (go)
case 2: // deferred call (defer)
nodconst(&con, types[TINT64], argsize(f->type));
nodreg(&reg, types[TINT64], D_R0+3);
nodreg(&reg2, types[TINT64], D_R0+4);
nodreg(&reg, types[TINT64], REG_R3);
nodreg(&reg2, types[TINT64], REG_R4);
gmove(f, &reg);
gmove(&con, &reg2);
p = gins(AMOVW, &reg2, N);
p->to.type = D_OREG;
p->to.type = TYPE_MEM;
p->to.reg = REGSP;
p->to.offset = 8;
p = gins(AMOVD, &reg, N);
p->to.type = D_OREG;
p->to.type = TYPE_MEM;
p->to.reg = REGSP;
p->to.offset = 16;
......@@ -270,10 +268,10 @@ ginscall(Node *f, int proc)
}
if(proc == 2) {
nodreg(&reg, types[TINT64], D_R0+3);
nodreg(&reg, types[TINT64], REG_R3);
p = gins(ACMP, &reg, N);
p->to.type = D_REG;
p->to.reg = D_R0;
p->to.type = TYPE_REG;
p->to.reg = REG_R0;
p = gbranch(ABEQ, T, +1);
cgen_ret(N);
patch(p, pc);
......@@ -315,7 +313,7 @@ cgen_callinter(Node *n, Node *res, int proc)
// register to hold its address.
igen(i, &nodi, res); // REG = &inter
nodindreg(&nodsp, types[tptr], D_R0+REGSP);
nodindreg(&nodsp, types[tptr], REGSP);
nodsp.xoffset = widthptr;
if(proc != 0)
nodsp.xoffset += 2 * widthptr; // leave room for size & fn
......@@ -342,7 +340,7 @@ cgen_callinter(Node *n, Node *res, int proc)
} else {
// go/defer. generate go func value.
p = gins(AMOVD, &nodo, &nodr); // REG = &(32+offset(REG)) -- i.tab->fun[f]
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
}
nodr.type = n->left->type;
......@@ -424,7 +422,7 @@ cgen_callret(Node *n, Node *res)
memset(&nod, 0, sizeof(nod));
nod.op = OINDREG;
nod.val.u.reg = D_R0+REGSP;
nod.val.u.reg = REGSP;
nod.addable = 1;
nod.xoffset = fp->width + widthptr; // +widthptr: saved LR at 0(R1)
......@@ -454,7 +452,7 @@ cgen_aret(Node *n, Node *res)
memset(&nod1, 0, sizeof(nod1));
nod1.op = OINDREG;
nod1.val.u.reg = D_R0 + REGSP;
nod1.val.u.reg = REGSP;
nod1.addable = 1;
nod1.xoffset = fp->width + widthptr; // +widthptr: saved lr at 0(SP)
......@@ -485,8 +483,8 @@ cgen_ret(Node *n)
genlist(curfn->exit);
p = gins(ARET, N, N);
if(n != N && n->op == ORETJMP) {
p->to.name = D_EXTERN;
p->to.type = D_CONST;
p->to.name = NAME_EXTERN;
p->to.type = TYPE_CONST;
p->to.sym = linksym(n->left->sym);
}
}
......@@ -575,7 +573,7 @@ dodiv(int op, Node *nl, Node *nr, Node *res)
// Handle divide-by-zero panic.
p1 = gins(optoas(OCMP, t), &tr, N);
p1->to.type = D_REG;
p1->to.type = TYPE_REG;
p1->to.reg = REGZERO;
p1 = gbranch(optoas(ONE, t), T, +1);
if(panicdiv == N)
......@@ -774,7 +772,7 @@ cgen_hmul(Node *nl, Node *nr, Node *res)
case TINT32:
gins(optoas(OMUL, t), &n2, &n1);
p = gins(ASRAD, N, &n1);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = w;
break;
case TUINT8:
......@@ -782,7 +780,7 @@ cgen_hmul(Node *nl, Node *nr, Node *res)
case TUINT32:
gins(optoas(OMUL, t), &n2, &n1);
p = gins(ASRD, N, &n1);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = w;
break;
case TINT64:
......@@ -915,23 +913,23 @@ clearfat(Node *nl)
if(reg[REGRT1] > 0)
fatal("R%d in use during clearfat", REGRT1);
nodreg(&r0, types[TUINT64], 0); // r0 is always zero
nodreg(&dst, types[tptr], D_R0+REGRT1);
nodreg(&r0, types[TUINT64], REG_R0); // r0 is always zero
nodreg(&dst, types[tptr], REGRT1);
reg[REGRT1]++;
agen(nl, &dst);
if(q > 128) {
p = gins(ASUB, N, &dst);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = 8;
regalloc(&end, types[tptr], N);
p = gins(AMOVD, &dst, &end);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = q*8;
p = gins(AMOVDU, &r0, &dst);
p->to.type = D_OREG;
p->to.type = TYPE_MEM;
p->to.offset = 8;
pl = p;
......@@ -943,7 +941,7 @@ clearfat(Node *nl)
boff = 8;
} else if(q >= 4) {
p = gins(ASUB, N, &dst);
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = 8;
f = sysfunc("duffzero");
p = gins(ADUFFZERO, N, f);
......@@ -955,7 +953,7 @@ clearfat(Node *nl)
} else {
for(t = 0; t < q; t++) {
p = gins(AMOVD, &r0, &dst);
p->to.type = D_OREG;
p->to.type = TYPE_MEM;
p->to.offset = 8*t;
}
boff = 8*q;
......@@ -963,7 +961,7 @@ clearfat(Node *nl)
for(t = 0; t < c; t++) {
p = gins(AMOVB, &r0, &dst);
p->to.type = D_OREG;
p->to.type = TYPE_MEM;
p->to.offset = t+boff;
}
reg[REGRT1]--;
......@@ -983,7 +981,7 @@ expandchecks(Prog *firstp)
continue;
if(debug_checknil && p->lineno > 1) // p->lineno==1 in generated wrappers
warnl(p->lineno, "generated nil check");
if(p->from.type != D_REG)
if(p->from.type != TYPE_REG)
fatal("invalid nil check %P\n", p);
/*
// check is
......@@ -994,11 +992,11 @@ expandchecks(Prog *firstp)
reg = p->from.reg;
p->as = ATD;
p->from = p->to = p->from3 = zprog.from;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = 4;
p->from.reg = NREG;
p->reg = 0;
p->to.type = D_REG;
p->from.reg = 0;
p->reg = REG_R0;
p->to.type = TYPE_REG;
p->to.reg = reg;
*/
// check is
......@@ -1017,19 +1015,19 @@ expandchecks(Prog *firstp)
p1->pc = 9999;
p2->pc = 9999;
p->as = ACMP;
p->to.type = D_REG;
p->to.type = TYPE_REG;
p->to.reg = REGZERO;
p1->as = ABNE;
//p1->from.type = D_CONST;
//p1->from.type = TYPE_CONST;
//p1->from.offset = 1; // likely
p1->to.type = D_BRANCH;
p1->to.type = TYPE_BRANCH;
p1->to.u.branch = p2->link;
// crash by write to memory address 0.
p2->as = AMOVD;
p2->from.type = D_REG;
p2->from.reg = 0;
p2->to.type = D_OREG;
p2->to.reg = 0;
p2->from.type = TYPE_REG;
p2->from.reg = REG_R0;
p2->to.type = TYPE_MEM;
p2->to.reg = REG_R0;
p2->to.offset = 0;
}
}
......@@ -38,17 +38,15 @@ dsname(Sym *s, int off, char *t, int n)
Prog *p;
p = gins(ADATA, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.offset = off;
p->from.reg = NREG;
p->from.sym = linksym(s);
p->reg = n;
p->to.type = D_SCONST;
p->to.name = D_NONE;
p->to.reg = NREG;
p->to.type = TYPE_SCONST;
p->to.name = NAME_NONE;
p->to.offset = 0;
memmove(p->to.u.sval, t, n);
return off + n;
......@@ -64,11 +62,11 @@ datastring(char *s, int len, Addr *a)
Sym *sym;
sym = stringsym(s, len);
a->type = D_OREG;
a->name = D_EXTERN;
a->type = TYPE_MEM;
a->name = NAME_EXTERN;
a->etype = simtype[TINT];
a->offset = widthptr+widthint; // skip header
a->reg = NREG;
a->reg = 0;
a->sym = linksym(sym);
a->node = sym->def;
}
......@@ -83,10 +81,10 @@ datagostring(Strlit *sval, Addr *a)
Sym *sym;
sym = stringsym(sval->s, sval->len);
a->type = D_OREG;
a->name = D_EXTERN;
a->type = TYPE_MEM;
a->name = NAME_EXTERN;
a->sym = linksym(sym);
a->reg = NREG;
a->reg = 0;
a->node = sym->def;
a->offset = 0; // header
a->etype = TSTRING;
......@@ -122,13 +120,13 @@ gdatacomplex(Node *nam, Mpcplx *cval)
p = gins(ADATA, nam, N);
p->reg = w;
p->to.type = D_FCONST;
p->to.type = TYPE_FCONST;
p->to.u.dval = mpgetflt(&cval->real);
p = gins(ADATA, nam, N);
p->reg = w;
p->from.offset += w;
p->to.type = D_FCONST;
p->to.type = TYPE_FCONST;
p->to.u.dval = mpgetflt(&cval->imag);
}
......@@ -141,7 +139,7 @@ gdatastring(Node *nam, Strlit *sval)
p = gins(ADATA, nam, N);
datastring(sval->s, sval->len, &p->to);
p->reg = types[tptr]->width;
p->to.type = D_CONST;
p->to.type = TYPE_CONST;
p->to.etype = simtype[tptr];
nodconst(&nod1, types[TINT], sval->len);
......@@ -157,14 +155,14 @@ dstringptr(Sym *s, int off, char *str)
off = rnd(off, widthptr);
p = gins(ADATA, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->from.offset = off;
p->reg = widthptr;
datastring(str, strlen(str)+1, &p->to);
p->to.type = D_CONST;
p->to.type = TYPE_CONST;
p->to.etype = simtype[TINT];
off += widthptr;
......@@ -181,13 +179,13 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
off = rnd(off, widthptr);
p = gins(ADATA, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->from.offset = off;
p->reg = widthptr;
datagostring(lit, &p->to);
p->to.type = D_CONST;
p->to.type = TYPE_CONST;
p->to.etype = simtype[TINT];
off += widthptr;
......@@ -218,13 +216,13 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
off = rnd(off, widthptr);
p = gins(ADATA, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->from.offset = off;
p->reg = widthptr;
p->to.type = D_CONST;
p->to.name = D_EXTERN;
p->to.type = TYPE_CONST;
p->to.name = NAME_EXTERN;
p->to.sym = linksym(x);
p->to.offset = xoff;
off += widthptr;
......
......@@ -116,14 +116,14 @@ gbranch(int as, Type *t, int likely)
USED(t);
p = prog(as);
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
p->to.u.branch = P;
// TODO(minux): Enable this code.
// Note: liblink used Bcc CR0, label form, so we need another way
// to set likely/unlikely flag. Also note the y bit is not exactly
// likely/unlikely bit.
if(0 && as != ABR && likely != 0) {
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = likely > 0;
}
return p;
......@@ -135,7 +135,7 @@ gbranch(int as, Type *t, int likely)
void
patch(Prog *p, Prog *to)
{
if(p->to.type != D_BRANCH)
if(p->to.type != TYPE_BRANCH)
fatal("patch: not a branch");
p->to.u.branch = to;
p->to.offset = to->pc;
......@@ -146,7 +146,7 @@ unpatch(Prog *p)
{
Prog *q;
if(p->to.type != D_BRANCH)
if(p->to.type != TYPE_BRANCH)
fatal("unpatch: not a branch");
q = p->to.u.branch;
p->to.u.branch = P;
......@@ -197,7 +197,7 @@ ggloblnod(Node *nam)
p->lineno = nam->lineno;
p->from.sym->gotype = linksym(ngotype(nam));
p->to.sym = nil;
p->to.type = D_CONST;
p->to.type = TYPE_CONST;
p->to.offset = nam->type->width;
if(nam->readonly)
p->reg = RODATA;
......@@ -211,8 +211,8 @@ gtrack(Sym *s)
Prog *p;
p = gins(AUSEFIELD, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
}
......@@ -222,11 +222,11 @@ ggloblsym(Sym *s, int32 width, int8 flags)
Prog *p;
p = gins(AGLOBL, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->to.type = D_CONST;
p->to.name = D_NONE;
p->to.type = TYPE_CONST;
p->to.name = NAME_NONE;
p->to.offset = width;
p->reg = flags;
}
......@@ -253,8 +253,8 @@ isfat(Type *t)
void
afunclit(Addr *a, Node *n)
{
if(a->type == D_CONST && a->name == D_EXTERN) {
a->type = D_OREG;
if(a->type == TYPE_CONST && a->name == NAME_EXTERN) {
a->type = TYPE_MEM;
a->sym = linksym(n->sym);
}
}
......@@ -272,11 +272,11 @@ static int resvd[] =
// TODO(austin): Consolidate REGTLS and REGG?
REGG,
REGTMP, // REGTMP
FREGCVI+NREG,
FREGZERO+NREG,
FREGHALF+NREG,
FREGONE+NREG,
FREGTWO+NREG,
FREGCVI,
FREGZERO,
FREGHALF,
FREGONE,
FREGTWO,
};
void
......@@ -286,13 +286,11 @@ ginit(void)
for(i=0; i<nelem(reg); i++)
reg[i] = 1;
for(i=0; i<NREG; i++)
reg[i] = 0;
for(i=NREG; i<NREG+NREG; i++)
for(i=0; i<NREG+NFREG; i++)
reg[i] = 0;
for(i=0; i<nelem(resvd); i++)
reg[resvd[i]]++;
reg[resvd[i] - REG_R0]++;
}
static uintptr regpc[nelem(reg)];
......@@ -303,11 +301,11 @@ gclean(void)
int i;
for(i=0; i<nelem(resvd); i++)
reg[resvd[i]]--;
reg[resvd[i] - REG_R0]--;
for(i=0; i<nelem(reg); i++)
if(reg[i])
yyerror("reg %R left allocated, %p\n", i, regpc[i]);
yyerror("reg %R left allocated, %p\n", i+REG_R0, regpc[i]);
}
int32
......@@ -345,9 +343,9 @@ regalloc(Node *n, Type *t, Node *o)
if(debug['r']) {
fixfree = 0;
fltfree = 0;
for(i = D_R0; i < D_F0+NREG; i++)
if(reg[i] == 0) {
if(i < D_F0)
for(i = REG_R0; i < REG_F31; i++)
if(reg[i - REG_R0] == 0) {
if(i < REG_F0)
fixfree++;
else
fltfree++;
......@@ -369,34 +367,34 @@ regalloc(Node *n, Type *t, Node *o)
case TBOOL:
if(o != N && o->op == OREGISTER) {
i = o->val.u.reg;
if(i >= D_R0+REGMIN && i <= D_R0+REGMAX)
if(i >= REGMIN && i <= REGMAX)
goto out;
}
for(i=D_R0+REGMIN; i<=D_R0+REGMAX; i++)
if(reg[i] == 0) {
regpc[i] = (uintptr)getcallerpc(&n);
for(i=REGMIN; i<=REGMAX; i++)
if(reg[i - REG_R0] == 0) {
regpc[i - REG_R0] = (uintptr)getcallerpc(&n);
goto out;
}
flusherrors();
for(i=D_R0; i<D_R0+NREG; i++)
print("R%d %p\n", i, regpc[i]);
for(i=REG_R0; i<REG_R0+NREG; i++)
print("R%d %p\n", i, regpc[i - REG_R0]);
fatal("out of fixed registers");
case TFLOAT32:
case TFLOAT64:
if(o != N && o->op == OREGISTER) {
i = o->val.u.reg;
if(i >= D_F0+FREGMIN && i <= D_F0+FREGMAX)
if(i >= FREGMIN && i <= FREGMAX)
goto out;
}
for(i=D_F0+FREGMIN; i<=D_F0+FREGMAX; i++)
if(reg[i] == 0) {
regpc[i] = (uintptr)getcallerpc(&n);
for(i=FREGMIN; i<=FREGMAX; i++)
if(reg[i - REG_R0] == 0) {
regpc[i - REG_R0] = (uintptr)getcallerpc(&n);
goto out;
}
flusherrors();
for(i=D_F0; i<D_F0+NREG; i++)
print("F%d %p\n", i, regpc[i]);
for(i=REG_F0; i<REG_F0+NREG; i++)
print("F%d %p\n", i, regpc[i - REG_R0]);
fatal("out of floating registers");
case TCOMPLEX64:
......@@ -408,7 +406,7 @@ regalloc(Node *n, Type *t, Node *o)
return;
out:
reg[i]++;
reg[i - REG_R0]++;
nodreg(n, t, i);
}
......@@ -421,8 +419,8 @@ regfree(Node *n)
return;
if(n->op != OREGISTER && n->op != OINDREG)
fatal("regfree: not a register");
i = n->val.u.reg;
if(i == D_R0 + REGSP)
i = n->val.u.reg - REG_R0;
if(i == REGSP - REG_R0)
return;
if(i < 0 || i >= nelem(reg))
fatal("regfree: reg out of range");
......@@ -517,7 +515,7 @@ fp:
case 0: // output arg for calling another function
n->op = OINDREG;
n->val.u.reg = D_R0+REGSP;
n->val.u.reg = REGSP;
n->xoffset += 8;
break;
......@@ -528,7 +526,7 @@ fp:
case 2: // offset output arg
fatal("shouldn't be used");
n->op = OINDREG;
n->val.u.reg = D_R0 + REGSP;
n->val.u.reg = REGSP;
n->xoffset += types[tptr]->width;
break;
}
......@@ -883,18 +881,18 @@ gmove(Node *f, Node *t)
regalloc(&r3, types[TINT64], t);
gins(AFCTIDZ, &r1, &r2);
p1 = gins(AFMOVD, &r2, N);
p1->to.type = D_OREG;
p1->to.type = TYPE_MEM;
p1->to.reg = REGSP;
p1->to.offset = -8;
p1 = gins(AMOVD, N, &r3);
p1->from.type = D_OREG;
p1->from.type = TYPE_MEM;
p1->from.reg = REGSP;
p1->from.offset = -8;
regfree(&r2);
regfree(&r1);
if(tt == TUINT64) {
p1 = gbranch(optoas(OLT, types[TFLOAT64]), T, +1); // use CR0 here again
nodreg(&r1, types[TINT64], D_R0+REGTMP);
nodreg(&r1, types[TINT64], REGTMP);
gins(AMOVD, &bigi, &r1);
gins(AADD, &r1, &r3);
patch(p1, pc);
......@@ -931,29 +929,29 @@ gmove(Node *f, Node *t)
regalloc(&r1, types[TINT64], N);
gmove(f, &r1);
if(ft == TUINT64) {
nodreg(&r2, types[TUINT64], D_R0+REGTMP);
nodreg(&r2, types[TUINT64], REGTMP);
gmove(&bigi, &r2);
gins(ACMPU, &r1, &r2);
p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1);
p2 = gins(ASRD, N, &r1);
p2->from.type = D_CONST;
p2->from.type = TYPE_CONST;
p2->from.offset = 1;
patch(p1, pc);
}
regalloc(&r2, types[TFLOAT64], t);
p1 = gins(AMOVD, &r1, N);
p1->to.type = D_OREG;
p1->to.type = TYPE_MEM;
p1->to.reg = REGSP;
p1->to.offset = -8;
p1 = gins(AFMOVD, N, &r2);
p1->from.type = D_OREG;
p1->from.type = TYPE_MEM;
p1->from.reg = REGSP;
p1->from.offset = -8;
gins(AFCFID, &r2, &r2);
regfree(&r1);
if(ft == TUINT64) {
p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1); // use CR0 here again
nodreg(&r1, types[TFLOAT64], D_F0+FREGTWO);
nodreg(&r1, types[TFLOAT64], FREGTWO);
gins(AFMUL, &r1, &r2);
patch(p1, pc);
}
......@@ -1026,8 +1024,6 @@ gins(int as, Node *f, Node *t)
p->from = af;
if(t != N)
p->to = at;
if(as == ATEXT)
p->reg = 0;
if(debug['g'])
print("%P\n", p);
......@@ -1053,12 +1049,12 @@ gins(int as, Node *f, Node *t)
break;
case AMOVD:
case AMOVDU:
if(af.type == D_CONST)
if(af.type == TYPE_CONST)
break;
w = 8;
break;
}
if(w != 0 && ((f != N && af.width < w) || (t != N && at.type != D_REG && at.width > w))) {
if(w != 0 && ((f != N && af.width < w) || (t != N && at.type != TYPE_REG && at.width > w))) {
dump("f", f);
dump("t", t);
fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
......@@ -1076,7 +1072,7 @@ fixlargeoffset(Node *n)
return;
if(n->op != OINDREG)
return;
if(n->val.u.reg == D_R0+REGSP) // stack offset cannot be large
if(n->val.u.reg == REGSP) // stack offset cannot be large
return;
if(n->xoffset != (int32)n->xoffset) {
// TODO(minux): offset too large, move into R31 and add to R31 instead.
......@@ -1102,9 +1098,9 @@ naddr(Node *n, Addr *a, int canemitcode)
{
Sym *s;
a->type = D_NONE;
a->name = D_NONE;
a->reg = NREG;
a->type = TYPE_NONE;
a->name = NAME_NONE;
a->reg = 0;
a->gotype = nil;
a->node = N;
a->etype = 0;
......@@ -1124,7 +1120,7 @@ naddr(Node *n, Addr *a, int canemitcode)
case ONAME:
a->etype = 0;
a->reg = NREG;
a->reg = 0;
if(n->type != T)
a->etype = simtype[n->type->etype];
a->offset = n->xoffset;
......@@ -1141,23 +1137,23 @@ naddr(Node *n, Addr *a, int canemitcode)
s = pkglookup(s->name, n->type->sym->pkg);
}
a->type = D_OREG;
a->type = TYPE_MEM;
switch(n->class) {
default:
fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
case PEXTERN:
a->name = D_EXTERN;
a->name = NAME_EXTERN;
break;
case PAUTO:
a->name = D_AUTO;
a->name = NAME_AUTO;
break;
case PPARAM:
case PPARAMOUT:
a->name = D_PARAM;
a->name = NAME_PARAM;
break;
case PFUNC:
a->name = D_EXTERN;
a->type = D_CONST;
a->name = NAME_EXTERN;
a->type = TYPE_CONST;
a->width = widthptr;
s = funcsym(s);
break;
......@@ -1171,13 +1167,13 @@ naddr(Node *n, Addr *a, int canemitcode)
fatal("naddr: const %lT", n->type);
break;
case CTFLT:
a->type = D_FCONST;
a->type = TYPE_FCONST;
a->u.dval = mpgetflt(n->val.u.fval);
break;
case CTINT:
case CTRUNE:
a->sym = nil;
a->type = D_CONST;
a->type = TYPE_CONST;
a->offset = mpgetfix(n->val.u.xval);
break;
case CTSTR:
......@@ -1185,30 +1181,25 @@ naddr(Node *n, Addr *a, int canemitcode)
break;
case CTBOOL:
a->sym = nil;
a->type = D_CONST;
a->type = TYPE_CONST;
a->offset = n->val.u.bval;
break;
case CTNIL:
a->sym = nil;
a->type = D_CONST;
a->type = TYPE_CONST;
a->offset = 0;
break;
}
break;
case OREGISTER:
if(n->val.u.reg < D_F0) {
a->type = D_REG;
a->reg = n->val.u.reg;
} else {
a->type = D_FREG;
a->reg = n->val.u.reg - D_F0;
}
a->type = TYPE_REG;
a->reg = n->val.u.reg;
a->sym = nil;
break;
case OINDREG:
a->type = D_OREG;
a->type = TYPE_MEM;
a->reg = n->val.u.reg;
a->sym = linksym(n->sym);
a->offset = n->xoffset;
......@@ -1223,15 +1214,15 @@ naddr(Node *n, Addr *a, int canemitcode)
a->width = n->left->type->width;
a->offset = n->xoffset;
a->sym = linksym(n->left->sym);
a->type = D_OREG;
a->name = D_PARAM;
a->type = TYPE_MEM;
a->name = NAME_PARAM;
a->node = n->left->orig;
break;
case OCLOSUREVAR:
if(!curfn->needctxt)
fatal("closurevar without needctxt");
a->type = D_OREG;
a->type = TYPE_MEM;
a->reg = REGENV;
a->offset = n->xoffset;
a->sym = nil;
......@@ -1246,7 +1237,7 @@ naddr(Node *n, Addr *a, int canemitcode)
// itable of interface value
naddr(n->left, a, canemitcode);
a->etype = simtype[tptr];
if(a->type == D_CONST && a->offset == 0)
if(a->type == TYPE_CONST && a->offset == 0)
break; // itab(nil)
a->width = widthptr;
break;
......@@ -1255,7 +1246,7 @@ naddr(Node *n, Addr *a, int canemitcode)
// pointer in a string or slice
naddr(n->left, a, canemitcode);
a->etype = simtype[tptr];
if(a->type == D_CONST && a->offset == 0)
if(a->type == TYPE_CONST && a->offset == 0)
break; // ptr(nil)
a->offset += Array_array;
a->width = widthptr;
......@@ -1265,7 +1256,7 @@ naddr(Node *n, Addr *a, int canemitcode)
// len of string or slice
naddr(n->left, a, canemitcode);
a->etype = simtype[TINT];
if(a->type == D_CONST && a->offset == 0)
if(a->type == TYPE_CONST && a->offset == 0)
break; // len(nil)
a->offset += Array_nel;
a->width = widthint;
......@@ -1275,7 +1266,7 @@ naddr(Node *n, Addr *a, int canemitcode)
// cap of string or slice
naddr(n->left, a, canemitcode);
a->etype = simtype[TINT];
if(a->type == D_CONST && a->offset == 0)
if(a->type == TYPE_CONST && a->offset == 0)
break; // cap(nil)
a->offset += Array_cap;
a->width = widthint;
......@@ -1285,12 +1276,12 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode);
a->etype = tptr;
switch(a->type) {
case D_OREG:
a->type = D_CONST;
case TYPE_MEM:
a->type = TYPE_CONST;
break;
case D_REG:
case D_CONST:
case TYPE_REG:
case TYPE_CONST:
break;
default:
......
......@@ -88,8 +88,8 @@ loop1:
// Convert uses to $0 to uses of R0 and
// propagate R0
if(regzer(&p->from))
if(p->to.type == D_REG) {
p->from.type = D_REG;
if(p->to.type == TYPE_REG) {
p->from.type = TYPE_REG;
p->from.reg = REGZERO;
if(copyprop(r)) {
excise(r);
......@@ -119,7 +119,7 @@ loop1:
case AMOVBZ:
case AMOVW:
case AMOVWZ:
if(p->to.type != D_REG)
if(p->to.type != TYPE_REG)
continue;
break;
}
......@@ -129,9 +129,9 @@ loop1:
p1 = r1->prog;
if(p1->as != p->as)
continue;
if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
if(p1->from.type != TYPE_REG || p1->from.reg != p->to.reg)
continue;
if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
if(p1->to.type != TYPE_REG || p1->to.reg != p->to.reg)
continue;
excise(r1);
}
......@@ -177,7 +177,7 @@ loop1:
if(r1 == nil)
continue;
p1 = r1->prog;
if(p1->to.type != D_REG || p1->to.reg != p->from.reg)
if(p1->to.type != TYPE_REG || p1->to.reg != p->from.reg)
continue;
switch(p1->as) {
case ASUB:
......@@ -185,7 +185,7 @@ loop1:
case AXOR:
case AOR:
/* irregular instructions */
if(p1->from.type == D_CONST)
if(p1->from.type == TYPE_CONST)
continue;
break;
}
......@@ -194,7 +194,7 @@ loop1:
continue;
case AMOVW:
case AMOVD:
if(p1->from.type != D_REG)
if(p1->from.type != TYPE_REG)
continue;
continue;
case AANDCC:
......@@ -342,11 +342,11 @@ excise(Flow *r)
static int
regzer(Addr *a)
{
if(a->type == D_CONST)
if(a->sym == nil && a->reg == NREG)
if(a->type == TYPE_CONST)
if(a->sym == nil && a->reg == 0)
if(a->offset == 0)
return 1;
if(a->type == D_REG)
if(a->type == TYPE_REG)
if(a->reg == REGZERO)
return 1;
return 0;
......@@ -355,15 +355,8 @@ regzer(Addr *a)
int
regtyp(Adr *a)
{
switch(a->type) {
default:
return 0;
case D_REG:
if(a->reg == REGZERO)
return 0;
case D_FREG:
return 1;
}
// TODO(rsc): Floating point register exclusions?
return a->type == TYPE_REG && REG_R0 <= a->reg && a->reg <= REG_F31 && a->reg != REGZERO;
}
/*
......@@ -578,7 +571,7 @@ copy1(Addr *v1, Addr *v2, Flow *r, int f)
int
copyu(Prog *p, Addr *v, Addr *s)
{
if(p->from3.type != D_NONE)
if(p->from3.type != TYPE_NONE)
// 9g never generates a from3
print("copyu: from3 (%D) not implemented\n", p->from3);
......@@ -630,7 +623,7 @@ copyu(Prog *p, Addr *v, Addr *s)
}
if(copyas(&p->to, v)) {
// Fix up implicit from
if(p->from.type == D_NONE)
if(p->from.type == TYPE_NONE)
p->from = p->to;
if(copyau(&p->from, v))
return 4;
......@@ -649,7 +642,7 @@ copyu(Prog *p, Addr *v, Addr *s)
case AMOVHZU:
case AMOVWZU:
case AMOVDU:
if(p->from.type == D_OREG) {
if(p->from.type == TYPE_MEM) {
if(copyas(&p->from, v))
// No s!=nil check; need to fail
// anyway in that case
......@@ -661,7 +654,7 @@ copyu(Prog *p, Addr *v, Addr *s)
}
if(copyas(&p->to, v))
return 3;
} else if (p->to.type == D_OREG) {
} else if (p->to.type == TYPE_MEM) {
if(copyas(&p->to, v))
return 2;
if(s != nil) {
......@@ -740,7 +733,7 @@ copyu(Prog *p, Addr *v, Addr *s)
return 0;
}
if(copyas(&p->to, v)) {
if(p->reg == NREG)
if(p->reg == 0)
// Fix up implicit reg (e.g., ADD
// R3,R4 -> ADD R3,R4,R4) so we can
// update reg and to separately.
......@@ -808,17 +801,20 @@ copyu(Prog *p, Addr *v, Addr *s)
return 3;
case ABL: /* funny */
if(v->type == D_REG) {
if(v->reg <= REGEXT && v->reg > exregoffset)
if(v->type == TYPE_REG) {
// TODO(rsc): REG_R0 and REG_F0 used to be
// (when register numbers started at 0) exregoffset and exfregoffset,
// which are unset entirely.
// It's strange that this handles R0 and F0 differently from the other
// registers. Possible failure to optimize?
if(REG_R0 < v->reg && v->reg <= REGEXT)
return 2;
if(v->reg == REGARG)
return 2;
}
if(v->type == D_FREG) {
if(v->reg <= FREGEXT && v->reg > exfregoffset)
if(REG_F0 < v->reg && v->reg <= FREGEXT)
return 2;
}
if(p->from.type == D_REG && v->type == D_REG && p->from.reg == v->reg)
if(p->from.type == TYPE_REG && v->type == TYPE_REG && p->from.reg == v->reg)
return 2;
if(s != nil) {
......@@ -833,7 +829,7 @@ copyu(Prog *p, Addr *v, Addr *s)
case ADUFFZERO:
// R0 is zero, used by DUFFZERO, cannot be substituted.
// R3 is ptr to memory, used and set, cannot be substituted.
if(v->type == D_REG) {
if(v->type == TYPE_REG) {
if(v->reg == 0)
return 1;
if(v->reg == 3)
......@@ -844,7 +840,7 @@ copyu(Prog *p, Addr *v, Addr *s)
case ADUFFCOPY:
// R3, R4 are ptr to src, dst, used and set, cannot be substituted.
// R5 is scratch, set by DUFFCOPY, cannot be substituted.
if(v->type == D_REG) {
if(v->type == TYPE_REG) {
if(v->reg == 3 || v->reg == 4)
return 2;
if(v->reg == 5)
......@@ -853,7 +849,7 @@ copyu(Prog *p, Addr *v, Addr *s)
return 0;
case ATEXT: /* funny */
if(v->type == D_REG)
if(v->type == TYPE_REG)
if(v->reg == REGARG)
return 3;
return 0;
......@@ -866,18 +862,6 @@ copyu(Prog *p, Addr *v, Addr *s)
}
}
int
a2type(Prog *p)
{
ProgInfo info;
proginfo(&info, p);
if(info.flags & (SizeB|SizeW|SizeL|SizeQ))
return D_REG;
if(info.flags & (SizeF|SizeD))
return D_FREG;
return D_NONE;
}
// copyas returns 1 if a and v address the same register.
//
// If a is the from operand, this means this operation reads the
......@@ -905,8 +889,8 @@ copyau(Addr *a, Addr *v)
{
if(copyas(a, v))
return 1;
if(v->type == D_REG)
if(a->type == D_OREG || (a->type == D_CONST && a->reg != NREG))
if(v->type == TYPE_REG)
if(a->type == TYPE_MEM || (a->type == TYPE_CONST && a->reg != 0))
if(v->reg == a->reg)
return 1;
return 0;
......@@ -917,17 +901,9 @@ copyau(Addr *a, Addr *v)
static int
copyau1(Prog *p, Addr *v)
{
if(regtyp(v))
if(p->from.type == v->type || p->to.type == v->type)
if(p->reg == v->reg) {
// Whether p->reg is a GPR or an FPR is
// implied by the instruction (both are
// numbered from 0). But the type should
// match v->type. Sanity check this.
if(a2type(p) != v->type)
print("botch a2type %P\n", p);
if(regtyp(v) && v->reg != 0)
if(p->reg == v->reg)
return 1;
}
return 0;
}
......@@ -960,7 +936,7 @@ sameaddr(Addr *a, Addr *v)
return 0;
if(regtyp(v) && a->reg == v->reg)
return 1;
if(v->type == D_AUTO || v->type == D_PARAM)
if(v->type == NAME_AUTO || v->type == NAME_PARAM)
if(v->offset == a->offset)
return 1;
return 0;
......@@ -969,7 +945,7 @@ sameaddr(Addr *a, Addr *v)
int
smallindir(Addr *a, Addr *reg)
{
return reg->type == D_REG && a->type == D_OREG &&
return reg->type == TYPE_REG && a->type == TYPE_MEM &&
a->reg == reg->reg &&
0 <= a->offset && a->offset < 4096;
}
......@@ -977,5 +953,5 @@ smallindir(Addr *a, Addr *reg)
int
stackaddr(Addr *a)
{
return a->type == D_REG && a->reg == REGSP;
return a->type == TYPE_REG && a->reg == REGSP;
}
......@@ -137,37 +137,37 @@ proginfo(ProgInfo *info, Prog *p)
fatal("proginfo: unknown instruction %P", p);
}
if((info->flags & RegRead) && p->reg == NREG) {
if((info->flags & RegRead) && p->reg == 0) {
info->flags &= ~RegRead;
info->flags |= /*CanRegRead |*/ RightRead;
}
if((p->from.type == D_OREG || p->from.type == D_CONST) && p->from.reg != NREG) {
if((p->from.type == TYPE_MEM || p->from.type == TYPE_CONST) && p->from.reg != 0) {
info->regindex |= RtoB(p->from.reg);
if(info->flags & PostInc) {
info->regset |= RtoB(p->from.reg);
}
}
if((p->to.type == D_OREG || p->to.type == D_CONST) && p->to.reg != NREG) {
if((p->to.type == TYPE_MEM || p->to.type == TYPE_CONST) && p->to.reg != 0) {
info->regindex |= RtoB(p->to.reg);
if(info->flags & PostInc) {
info->regset |= RtoB(p->to.reg);
}
}
if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
if(p->from.type == TYPE_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
info->flags &= ~LeftRead;
info->flags |= LeftAddr;
}
if(p->as == ADUFFZERO) {
info->reguse |= (1<<D_R0) | RtoB(3);
info->regset |= RtoB(3);
info->reguse |= (1<<0) | RtoB(REG_R3);
info->regset |= RtoB(REG_R3);
}
if(p->as == ADUFFCOPY) {
// TODO(austin) Revisit when duffcopy is implemented
info->reguse |= RtoB(3) | RtoB(4) | RtoB(5);
info->regset |= RtoB(3) | RtoB(4);
info->reguse |= RtoB(REG_R3) | RtoB(REG_R4) | RtoB(REG_R5);
info->regset |= RtoB(REG_R3) | RtoB(REG_R4);
}
}
......
......@@ -185,9 +185,9 @@ regopt(Prog *firstp)
}
// Exclude registers with fixed functions
regbits = (1<<D_R0)|RtoB(REGSP)|RtoB(REGG)|RtoB(REGTLS);
regbits = (1<<0)|RtoB(REGSP)|RtoB(REGG)|RtoB(REGTLS);
// Also exclude floating point registers with fixed constants
regbits |= FtoB(D_F0+27)|FtoB(D_F0+28)|FtoB(D_F0+29)|FtoB(D_F0+30)|FtoB(D_F0+31);
regbits |= RtoB(REG_F27)|RtoB(REG_F28)|RtoB(REG_F29)|RtoB(REG_F30)|RtoB(REG_F31);
externs = zbits;
params = zbits;
consts = zbits;
......@@ -217,7 +217,7 @@ regopt(Prog *firstp)
proginfo(&info, p);
// Avoid making variables for direct-called functions.
if(p->as == ABL && p->to.name == D_EXTERN)
if(p->as == ABL && p->to.name == NAME_EXTERN)
continue;
// from vs to doesn't matter for registers
......@@ -233,16 +233,12 @@ regopt(Prog *firstp)
r->use1.b[z] |= bit.b[z];
// Compute used register for reg
if(info.flags & RegRead) {
if(p->from.type != D_FREG)
r->use1.b[0] |= RtoB(p->reg);
else
r->use1.b[0] |= FtoB(D_F0+p->reg);
}
if(info.flags & RegRead)
r->use1.b[0] |= RtoB(p->reg);
// Currently we never generate three register forms.
// If we do, this will need to change.
if(p->from3.type != D_NONE)
if(p->from3.type != TYPE_NONE)
fatal("regopt not implemented for from3");
// Compute used register for to
......@@ -484,7 +480,7 @@ brk:
for(p=firstp; p!=P; p=p->link) {
while(p->link != P && p->link->as == ANOP)
p->link = p->link->link;
if(p->to.type == D_BRANCH)
if(p->to.type == TYPE_BRANCH)
while(p->to.u.branch != P && p->to.u.branch->as == ANOP)
p->to.u.branch = p->to.u.branch->link;
}
......@@ -556,7 +552,7 @@ addmove(Reg *r, int bn, int rn, int f)
// If there's a stack fixup coming (ADD $n,R1 after BL newproc or BL deferproc),
// delay the load until after the fixup.
p2 = p->link;
if(p2 && p2->as == AADD && p2->to.reg == REGSP && p2->to.type == D_REG)
if(p2 && p2->as == AADD && p2->to.reg == REGSP && p2->to.type == TYPE_REG)
p = p2;
p1->link = p->link;
......@@ -571,9 +567,9 @@ addmove(Reg *r, int bn, int rn, int f)
a->sym = linksym(v->node->sym);
a->offset = v->offset;
a->etype = v->etype;
a->type = D_OREG;
a->type = TYPE_MEM;
if(a->etype == TARRAY || a->sym == nil)
a->type = D_CONST;
a->type = TYPE_CONST;
if(v->addr)
fatal("addmove: shouldn't be doing this %A\n", a);
......@@ -616,21 +612,13 @@ addmove(Reg *r, int bn, int rn, int f)
break;
}
p1->from.type = D_REG;
p1->from.type = TYPE_REG;
p1->from.reg = rn;
if(rn >= NREG) {
p1->from.type = D_FREG;
p1->from.reg = rn-NREG;
}
if(!f) {
p1->from = *a;
*a = zprog.from;
a->type = D_REG;
a->type = TYPE_REG;
a->reg = rn;
if(rn >= NREG) {
a->type = D_FREG;
a->reg = rn-NREG;
}
if(v->etype == TUINT8 || v->etype == TBOOL)
p1->as = AMOVBZ;
if(v->etype == TUINT16)
......@@ -673,42 +661,33 @@ mkvar(Reg *r, Adr *a)
print("type %d %d %D\n", t, a->name, a);
goto none;
case D_NONE:
case TYPE_NONE:
goto none;
case D_BRANCH:
case D_CONST:
case D_FCONST:
case D_SCONST:
case D_SPR:
case D_OREG:
case TYPE_BRANCH:
case TYPE_CONST:
case TYPE_FCONST:
case TYPE_SCONST:
case TYPE_MEM:
break;
case D_REG:
if(a->reg != NREG) {
case TYPE_REG:
if(a->reg != 0) {
bit = zbits;
bit.b[0] = RtoB(a->reg);
return bit;
}
break;
case D_FREG:
if(a->reg != NREG) {
bit = zbits;
bit.b[0] = FtoB(D_F0+a->reg);
return bit;
}
break;
}
switch(a->name) {
default:
goto none;
case D_EXTERN:
case D_STATIC:
case D_AUTO:
case D_PARAM:
case NAME_EXTERN:
case NAME_STATIC:
case NAME_AUTO:
case NAME_PARAM:
n = a->name;
break;
}
......@@ -784,10 +763,10 @@ mkvar(Reg *r, Adr *a)
node->opt = v;
bit = blsh(i);
if(n == D_EXTERN || n == D_STATIC)
if(n == NAME_EXTERN || n == NAME_STATIC)
for(z=0; z<BITS; z++)
externs.b[z] |= bit.b[z];
if(n == D_PARAM)
if(n == NAME_PARAM)
for(z=0; z<BITS; z++)
params.b[z] |= bit.b[z];
......@@ -1014,7 +993,7 @@ allreg(uint64 b, Rgn *r)
i = BtoF(~b);
if(i && r->cost > 0) {
r->regno = i;
return FtoB(i);
return RtoB(i);
}
break;
}
......@@ -1213,13 +1192,9 @@ addreg(Adr *a, int rn)
{
a->sym = nil;
a->node = nil;
a->name = D_NONE;
a->type = D_REG;
a->name = NAME_NONE;
a->type = TYPE_REG;
a->reg = rn;
if(rn >= NREG) {
a->type = D_FREG;
a->reg = rn-NREG;
}
ostats.ncvtreg++;
}
......@@ -1239,8 +1214,10 @@ addreg(Adr *a, int rn)
uint64
RtoB(int r)
{
if(r > D_R0 && r <= D_R0+31)
return 1ULL << (r - D_R0);
if(r > REG_R0 && r <= REG_R31)
return 1ULL << (r - REG_R0);
if(r >= REG_F0 && r <= REG_F31)
return 1ULL << (32 + r - REG_F0);
return 0;
}
......@@ -1250,15 +1227,7 @@ BtoR(uint64 b)
b &= 0xffffffffull;
if(b == 0)
return 0;
return bitno(b) + D_R0;
}
uint64
FtoB(int r)
{
if(r >= D_F0 && r <= D_F0+31)
return 1ULL << (32 + r - D_F0);
return 0;
return bitno(b) + REG_R0;
}
int
......@@ -1267,7 +1236,7 @@ BtoF(uint64 b)
b >>= 32;
if(b == 0)
return 0;
return bitno(b) + D_F0;
return bitno(b) + REG_F0;
}
void
......
......@@ -42,30 +42,118 @@ enum
enum
{
REGZERO = 0, /* set to zero */
REGSP = 1,
REGSB = 2,
REGRET = 3,
REG_R0 = 32,
REG_R1,
REG_R2,
REG_R3,
REG_R4,
REG_R5,
REG_R6,
REG_R7,
REG_R8,
REG_R9,
REG_R10,
REG_R11,
REG_R12,
REG_R13,
REG_R14,
REG_R15,
REG_R16,
REG_R17,
REG_R18,
REG_R19,
REG_R20,
REG_R21,
REG_R22,
REG_R23,
REG_R24,
REG_R25,
REG_R26,
REG_R27,
REG_R28,
REG_R29,
REG_R30,
REG_R31,
REG_F0 = 64,
REG_F1,
REG_F2,
REG_F3,
REG_F4,
REG_F5,
REG_F6,
REG_F7,
REG_F8,
REG_F9,
REG_F10,
REG_F11,
REG_F12,
REG_F13,
REG_F14,
REG_F15,
REG_F16,
REG_F17,
REG_F18,
REG_F19,
REG_F20,
REG_F21,
REG_F22,
REG_F23,
REG_F24,
REG_F25,
REG_F26,
REG_F27,
REG_F28,
REG_F29,
REG_F30,
REG_F31,
REG_SPECIAL = 96,
REG_C0 = 96,
REG_C1,
REG_C2,
REG_C3,
REG_C4,
REG_C5,
REG_C6,
REG_C7,
REG_MSR = 104,
REG_FPSCR,
REG_CR,
REG_SPR0 = 1024, // first of 1024 registers
REG_DCR0 = 2048, // first of 1024 registers
REG_XER = REG_SPR0 + 1,
REG_LR = REG_SPR0 + 8,
REG_CTR = REG_SPR0 + 9,
REGZERO = REG_R0, /* set to zero */
REGSP = REG_R1,
REGSB = REG_R2,
REGRET = REG_R3,
REGARG = -1, /* -1 disables passing the first argument in register */
REGRT1 = 3, /* reserved for runtime, duffzero and duffcopy */
REGRT2 = 4, /* reserved for runtime, duffcopy */
REGMIN = 7, /* register variables allocated from here to REGMAX */
REGENV = 11, /* environment for closures */
REGTLS = 13, /* C ABI TLS base pointer */
REGMAX = 27,
REGEXT = 30, /* external registers allocated from here down */
REGG = 30, /* G */
REGTMP = 31, /* used by the linker */
REGRT1 = REG_R3, /* reserved for runtime, duffzero and duffcopy */
REGRT2 = REG_R4, /* reserved for runtime, duffcopy */
REGMIN = REG_R7, /* register variables allocated from here to REGMAX */
REGENV = REG_R11, /* environment for closures */
REGTLS = REG_R13, /* C ABI TLS base pointer */
REGMAX = REG_R27,
REGEXT = REG_R30, /* external registers allocated from here down */
REGG = REG_R30, /* G */
REGTMP = REG_R31, /* used by the linker */
FREGRET = 0,
FREGMIN = 17, /* first register variable */
FREGMAX = 26, /* last register variable for 9g only */
FREGEXT = 26, /* first external register */
FREGCVI = 27, /* floating conversion constant */
FREGZERO = 28, /* both float and double */
FREGHALF = 29, /* double */
FREGONE = 30, /* double */
FREGTWO = 31 /* double */
FREGRET = REG_F0,
FREGMIN = REG_F17, /* first register variable */
FREGMAX = REG_F26, /* last register variable for 9g only */
FREGEXT = REG_F26, /* first external register */
FREGCVI = REG_F27, /* floating conversion constant */
FREGZERO = REG_F28, /* both float and double */
FREGHALF = REG_F29, /* double */
FREGONE = REG_F30, /* double */
FREGTWO = REG_F31 /* double */
/*
* GENERAL:
*
......@@ -471,50 +559,6 @@ enum
ALAST
};
/* type/name */
enum
{
D_GOK = 0,
D_NONE,
/* name */
D_EXTERN,
D_STATIC,
D_AUTO,
D_PARAM,
/* type */
D_BRANCH,
D_OREG,
D_CONST,
D_FCONST,
D_SCONST,
D_REG,
D_FPSCR,
D_MSR,
D_FREG,
D_CREG,
D_SPR,
D_OPT, /* branch/trap option */
D_FILE,
D_FILE1,
D_DCR, /* device control register */
D_DCONST,
D_ADDR, // not used, use D_CONST with non-empty sym.
D_LAST,
/* reg names for 9g OREGISTER */
D_R0 = 0, // type is D_REG
D_F0 = D_R0+NREG, // type is D_FREG
/* reg names in offset field iff type is D_SPR */
D_XER = 1,
D_LR = 8,
D_CTR = 9
/* and many supervisor level registers */
};
/*
* this is the ranlib header
*/
......
......@@ -543,14 +543,14 @@ span9(Link *ctxt, LSym *cursym)
q->link = p->link;
p->link = q;
q->as = ABR;
q->to.type = D_BRANCH;
q->to.type = TYPE_BRANCH;
q->pcond = p->pcond;
p->pcond = q;
q = ctxt->arch->prg();
q->link = p->link;
p->link = q;
q->as = ABR;
q->to.type = D_BRANCH;
q->to.type = TYPE_BRANCH;
q->pcond = q->link->link;
//addnop(p->link);
//addnop(p);
......@@ -614,57 +614,56 @@ aclass(Link *ctxt, Addr *a)
LSym *s;
switch(a->type) {
case D_NONE:
case TYPE_NONE:
return C_NONE;
case D_REG:
return C_REG;
case D_FREG:
return C_FREG;
case D_CREG:
return C_CREG;
case D_SPR:
if(a->offset == D_LR)
return C_LR;
if(a->offset == D_XER)
return C_XER;
if(a->offset == D_CTR)
return C_CTR;
return C_SPR;
case D_DCR:
return C_SPR;
case D_FPSCR:
return C_FPSCR;
case D_MSR:
return C_MSR;
case TYPE_REG:
if(REG_R0 <= a->reg && a->reg <= REG_R31)
return C_REG;
if(REG_F0 <= a->reg && a->reg <= REG_F31)
return C_FREG;
if(REG_C0 <= a->reg && a->reg <= REG_C7 || a->reg == REG_CR)
return C_CREG;
if(REG_SPR0 <= a->reg && a->reg <= REG_SPR0+1023) {
switch(a->reg) {
case REG_LR:
return C_LR;
case REG_XER:
return C_XER;
case REG_CTR:
return C_CTR;
}
return C_SPR;
}
if(REG_DCR0 <= a->reg && a->reg <= REG_DCR0+1023)
return C_SPR;
if(a->reg == REG_FPSCR)
return C_FPSCR;
if(a->reg == REG_MSR)
return C_MSR;
return C_GOK;
case D_OREG:
case TYPE_MEM:
switch(a->name) {
case D_EXTERN:
case D_STATIC:
case NAME_EXTERN:
case NAME_STATIC:
if(a->sym == nil)
break;
ctxt->instoffset = a->offset;
if(a->sym != nil) // use relocation
return C_ADDR;
return C_LEXT;
case D_AUTO:
case NAME_AUTO:
ctxt->instoffset = ctxt->autosize + a->offset;
if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
return C_SAUTO;
return C_LAUTO;
case D_PARAM:
case NAME_PARAM:
ctxt->instoffset = ctxt->autosize + a->offset + 8L;
if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
return C_SAUTO;
return C_LAUTO;
case D_NONE:
case TYPE_NONE:
ctxt->instoffset = a->offset;
if(ctxt->instoffset == 0)
return C_ZOREG;
......@@ -674,17 +673,11 @@ aclass(Link *ctxt, Addr *a)
}
return C_GOK;
case D_OPT:
ctxt->instoffset = a->offset & 31L;
if(a->name == D_NONE)
return C_SCON;
return C_GOK;
case D_CONST:
case TYPE_CONST:
switch(a->name) {
case D_NONE:
case TYPE_NONE:
ctxt->instoffset = a->offset;
if(a->reg != NREG) {
if(a->reg != 0) {
if(-BIG <= ctxt->instoffset && ctxt->instoffset <= BIG)
return C_SACON;
if(isint32(ctxt->instoffset))
......@@ -693,8 +686,8 @@ aclass(Link *ctxt, Addr *a)
}
goto consize;
case D_EXTERN:
case D_STATIC:
case NAME_EXTERN:
case NAME_STATIC:
s = a->sym;
if(s == nil)
break;
......@@ -706,13 +699,13 @@ aclass(Link *ctxt, Addr *a)
/* not sure why this barfs */
return C_LCON;
case D_AUTO:
case NAME_AUTO:
ctxt->instoffset = ctxt->autosize + a->offset;
if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
return C_SACON;
return C_LACON;
case D_PARAM:
case NAME_PARAM:
ctxt->instoffset = ctxt->autosize + a->offset + 8L;
if(ctxt->instoffset >= -BIG && ctxt->instoffset < BIG)
return C_SACON;
......@@ -742,7 +735,7 @@ aclass(Link *ctxt, Addr *a)
return C_LCON;
return C_DCON;
case D_BRANCH:
case TYPE_BRANCH:
return C_SBRA;
}
return C_GOK;
......@@ -783,7 +776,7 @@ oplook(Link *ctxt, Prog *p)
}
a4--;
a2 = C_NONE;
if(p->reg != NREG)
if(p->reg != 0)
a2 = C_REG;
//print("oplook %P %d %d %d %d\n", p, a1, a2, a3, a4);
r = p->as;
......@@ -1515,7 +1508,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
break;
case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
if(p->to.reg == REGZERO && p->from.type == D_CONST) {
if(p->to.reg == REGZERO && p->from.type == TYPE_CONST) {
v = regoff(ctxt, &p->from);
if(r0iszero && v != 0) {
//nerrors--;
......@@ -1529,7 +1522,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 2: /* int/cr/fp op Rb,[Ra],Rd */
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, p->from.reg);
break;
......@@ -1538,7 +1531,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
d = vregoff(ctxt, &p->from);
v = d;
r = p->from.reg;
if(r == NREG)
if(r == 0)
r = o->param;
if(r0iszero && p->to.reg == 0 && (r != 0 || v != 0))
ctxt->diag("literal operation on R0\n%P", p);
......@@ -1562,7 +1555,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 4: /* add/mul $scon,[r1],r2 */
v = regoff(ctxt, &p->from);
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
if(r0iszero && p->to.reg == 0)
ctxt->diag("literal operation on R0\n%P", p);
......@@ -1577,17 +1570,17 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 6: /* logical op Rb,[Rs,]Ra; no literal */
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o1 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, p->from.reg);
break;
case 7: /* mov r, soreg ==> stw o(r) */
r = p->to.reg;
if(r == NREG)
if(r == 0)
r = o->param;
v = regoff(ctxt, &p->to);
if(p->to.type == D_OREG && p->reg != NREG) {
if(p->to.type == TYPE_MEM && p->reg != 0) {
if(v)
ctxt->diag("illegal indexed instruction\n%P", p);
o1 = AOP_RRR(opstorex(ctxt, p->as), p->from.reg, p->reg, r);
......@@ -1600,10 +1593,10 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
r = p->from.reg;
if(r == NREG)
if(r == 0)
r = o->param;
v = regoff(ctxt, &p->from);
if(p->from.type == D_OREG && p->reg != NREG) {
if(p->from.type == TYPE_MEM && p->reg != 0) {
if(v)
ctxt->diag("illegal indexed instruction\n%P", p);
o1 = AOP_RRR(oploadx(ctxt, p->as), p->to.reg, p->reg, r);
......@@ -1616,10 +1609,10 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
r = p->from.reg;
if(r == NREG)
if(r == 0)
r = o->param;
v = regoff(ctxt, &p->from);
if(p->from.type == D_OREG && p->reg != NREG) {
if(p->from.type == TYPE_MEM && p->reg != 0) {
if(v)
ctxt->diag("illegal indexed instruction\n%P", p);
o1 = AOP_RRR(oploadx(ctxt, p->as), p->to.reg, p->reg, r);
......@@ -1630,7 +1623,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, p->from.reg, r);
break;
......@@ -1663,7 +1656,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
break;
case 12: /* movb r,r (extsb); movw r,r (extsw) */
if(p->to.reg == REGZERO && p->from.type == D_CONST) {
if(p->to.reg == REGZERO && p->from.type == TYPE_CONST) {
v = regoff(ctxt, &p->from);
if(r0iszero && v != 0) {
ctxt->diag("literal operation on R0\n%P", p);
......@@ -1692,7 +1685,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
d = vregoff(ctxt, &p->from3);
maskgen64(ctxt, p, mask, d);
......@@ -1720,10 +1713,10 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 17: /* bc bo,bi,lbra (same for now) */
case 16: /* bc bo,bi,sbra */
a = 0;
if(p->from.type == D_CONST)
if(p->from.type == TYPE_CONST)
a = regoff(ctxt, &p->from);
r = p->reg;
if(r == NREG)
if(r == 0)
r = 0;
v = 0;
if(p->pcond)
......@@ -1743,9 +1736,9 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
else
v = 20; /* unconditional */
r = p->reg;
if(r == NREG)
if(r == 0)
r = 0;
o1 = AOP_RRR(OP_MTSPR, p->to.reg, 0, 0) | ((D_LR&0x1f)<<16) | (((D_LR>>5)&0x1f)<<11);
o1 = AOP_RRR(OP_MTSPR, p->to.reg, 0, 0) | ((REG_LR&0x1f)<<16) | (((REG_LR>>5)&0x1f)<<11);
o2 = OPVCC(19, 16, 0, 0);
if(p->as == ABL || p->as == ABCL)
o2 |= 1;
......@@ -1758,7 +1751,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
else
v = 20; /* unconditional */
r = p->reg;
if(r == NREG)
if(r == 0)
r = 0;
switch(oclass(&p->to)) {
case C_CTR:
......@@ -1792,7 +1785,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 20: /* add $ucon,,r */
v = regoff(ctxt, &p->from);
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
if(p->as == AADD && (!r0iszero && p->reg == 0 || r0iszero && p->to.reg == 0))
ctxt->diag("literal operation on R0\n%P", p);
......@@ -1806,7 +1799,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
o1 = loadu32(REGTMP, d);
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, (int32)d);
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o3 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, REGTMP, r);
if(p->from.sym != nil)
......@@ -1821,7 +1814,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
o1 = loadu32(REGTMP, d);
o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, (int32)d);
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o3 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, REGTMP, r);
if(p->from.sym != nil)
......@@ -1837,7 +1830,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
else if(v > 63)
v = 63;
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
switch(p->as){
case ASLD: case ASLDCC:
......@@ -1869,7 +1862,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
ctxt->diag("can't synthesize large constant\n%P", p);
v = regoff(ctxt, &p->from);
r = p->from.reg;
if(r == NREG)
if(r == 0)
r = o->param;
o1 = AOP_IRR(OP_ADDIS, REGTMP, r, high16adjusted(v));
o2 = AOP_IRR(OP_ADDI, p->to.reg, REGTMP, v);
......@@ -1961,7 +1954,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 32: /* fmul frc,fra,frd */
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, 0)|((p->from.reg&31L)<<6);
break;
......@@ -1980,7 +1973,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
v = regoff(ctxt, &p->to);
r = p->to.reg;
if(r == NREG)
if(r == 0)
r = o->param;
o1 = AOP_IRR(OP_ADDIS, REGTMP, r, high16adjusted(v));
o2 = AOP_IRR(opstore(ctxt, p->as), p->from.reg, REGTMP, v);
......@@ -1989,7 +1982,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
v = regoff(ctxt, &p->from);
r = p->from.reg;
if(r == NREG)
if(r == 0)
r = o->param;
o1 = AOP_IRR(OP_ADDIS, REGTMP, r, high16adjusted(v));
o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
......@@ -1998,7 +1991,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
v = regoff(ctxt, &p->from);
r = p->from.reg;
if(r == NREG)
if(r == 0)
r = o->param;
o1 = AOP_IRR(OP_ADDIS, REGTMP, r, high16adjusted(v));
o2 = AOP_IRR(opload(ctxt, p->as), p->to.reg, REGTMP, v);
......@@ -2019,20 +2012,20 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
r = p->reg;
if(r == NREG)
if(r == 0)
r = 0;
o1 = AOP_RRR(oprrr(ctxt, p->as), 0, r, p->from.reg);
break;
case 44: /* indexed store */
r = p->reg;
if(r == NREG)
if(r == 0)
r = 0;
o1 = AOP_RRR(opstorex(ctxt, p->as), p->from.reg, r, p->to.reg);
break;
case 45: /* indexed load */
r = p->reg;
if(r == NREG)
if(r == 0)
r = 0;
o1 = AOP_RRR(oploadx(ctxt, p->as), p->to.reg, r, p->from.reg);
break;
......@@ -2043,20 +2036,20 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 47: /* op Ra, Rd; also op [Ra,] Rd */
r = p->from.reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o1 = AOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, 0);
break;
case 48: /* op Rs, Ra */
r = p->from.reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o1 = LOP_RRR(oprrr(ctxt, p->as), p->to.reg, r, 0);
break;
case 49: /* op Rb; op $n, Rb */
if(p->from.type != D_REG){ /* tlbie $L, rB */
if(p->from.type != TYPE_REG){ /* tlbie $L, rB */
v = regoff(ctxt, &p->from) & 1;
o1 = AOP_RRR(oprrr(ctxt, p->as), 0, 0, p->to.reg) | (v<<21);
}else
......@@ -2065,7 +2058,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 50: /* rem[u] r1[,r2],r3 */
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
v = oprrr(ctxt, p->as);
t = v & ((1<<10)|1); /* OE|Rc */
......@@ -2081,7 +2074,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 51: /* remd[u] r1[,r2],r3 */
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
v = oprrr(ctxt, p->as);
t = v & ((1<<10)|1); /* OE|Rc */
......@@ -2116,7 +2109,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
v = regoff(ctxt, &p->from);
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o1 = AOP_RRR(opirr(ctxt, p->as), r, p->to.reg, v&31L);
if(p->as == ASRAD && (v&0x20))
......@@ -2126,7 +2119,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 57: /* slw $sh,[s,]a -> rlwinm ... */
v = regoff(ctxt, &p->from);
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
/*
* Let user (gs) shoot himself in the foot.
......@@ -2155,7 +2148,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 58: /* logical $andcon,[s],a */
v = regoff(ctxt, &p->from);
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o1 = LOP_IRR(opirr(ctxt, p->as), p->to.reg, r, v);
break;
......@@ -2163,7 +2156,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
case 59: /* or/and $ucon,,r */
v = regoff(ctxt, &p->from);
r = p->reg;
if(r == NREG)
if(r == 0)
r = p->to.reg;
o1 = LOP_IRR(opirr(ctxt, p->as+AEND), p->to.reg, r, v>>16); /* oris, xoris, andis */
break;
......@@ -2193,7 +2186,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
break;
case 64: /* mtfsf fr[, $m] {,fpcsr} */
if(p->from3.type != D_NONE)
if(p->from3.type != TYPE_NONE)
v = regoff(ctxt, &p->from3)&255L;
else
v = 255;
......@@ -2201,23 +2194,23 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
break;
case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
if(p->to.reg == NREG)
if(p->to.reg == 0)
ctxt->diag("must specify FPSCR(n)\n%P", p);
o1 = OP_MTFSFI | ((p->to.reg&15L)<<23) | ((regoff(ctxt, &p->from)&31L)<<12);
break;
case 66: /* mov spr,r1; mov r1,spr, also dcr */
if(p->from.type == D_REG) {
if(REG_R0 <= p->from.reg && p->from.reg <= REG_R31) {
r = p->from.reg;
v = p->to.offset;
if(p->to.type == D_DCR)
v = p->to.reg;
if(REG_DCR0 <= v && v <= REG_DCR0+1023)
o1 = OPVCC(31,451,0,0); /* mtdcr */
else
o1 = OPVCC(31,467,0,0); /* mtspr */
} else {
r = p->to.reg;
v = p->from.offset;
if(p->from.type == D_DCR)
v = p->from.reg;
if(REG_DCR0 <= v && v <= REG_DCR0+1023)
o1 = OPVCC(31,323,0,0); /* mfdcr */
else
o1 = OPVCC(31,339,0,0); /* mfspr */
......@@ -2226,14 +2219,14 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
break;
case 67: /* mcrf crfD,crfS */
if(p->from.type != D_CREG || p->from.reg == NREG ||
p->to.type != D_CREG || p->to.reg == NREG)
if(p->from.type != TYPE_REG || p->from.reg < REG_C0 || REG_C7 < p->from.reg ||
p->to.type != TYPE_REG || p->to.reg < REG_C0 || REG_C7 < p->to.reg)
ctxt->diag("illegal CR field number\n%P", p);
o1 = AOP_RRR(OP_MCRF, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
break;
case 68: /* mfcr rD; mfocrf CRM,rD */
if(p->from.type == D_CREG && p->from.reg != NREG){
if(p->from.type == TYPE_REG && REG_C0 <= p->from.reg && p->from.reg <= REG_C7) {
v = 1<<(7-(p->to.reg&7)); /* CR(n) */
o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0) | (1<<20) | (v<<12); /* new form, mfocrf */
}else
......@@ -2241,12 +2234,12 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
break;
case 69: /* mtcrf CRM,rS */
if(p->from3.type != D_NONE) {
if(p->to.reg != NREG)
if(p->from3.type != TYPE_NONE) {
if(p->to.reg != 0)
ctxt->diag("can't use both mask and CR(n)\n%P", p);
v = regoff(ctxt, &p->from3) & 0xff;
} else {
if(p->to.reg == NREG)
if(p->to.reg == 0)
v = 0xff; /* CR */
else
v = 1<<(7-(p->to.reg&7)); /* CR(n) */
......@@ -2255,7 +2248,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
break;
case 70: /* [f]cmp r,r,cr*/
if(p->reg == NREG)
if(p->reg == 0)
r = 0;
else
r = (p->reg&7)<<2;
......@@ -2263,7 +2256,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
break;
case 71: /* cmp[l] r,i,cr*/
if(p->reg == NREG)
if(p->reg == 0)
r = 0;
else
r = (p->reg&7)<<2;
......@@ -2275,18 +2268,18 @@ asmout(Link *ctxt, Prog *p, Optab *o, uint32 *out)
break;
case 73: /* mcrfs crfD,crfS */
if(p->from.type != D_FPSCR || p->from.reg == NREG ||
p->to.type != D_CREG || p->to.reg == NREG)
if(p->from.type != TYPE_REG || p->from.reg != REG_FPSCR ||
p->to.type != TYPE_REG || p->to.reg < REG_C0 || REG_C7 < p->to.reg)
ctxt->diag("illegal FPSCR/CR field number\n%P", p);
o1 = AOP_RRR(OP_MCRFS, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
o1 = AOP_RRR(OP_MCRFS, ((p->to.reg&7L)<<2), ((0&7)<<2), 0);
break;
case 77: /* syscall $scon, syscall Rx */
if(p->from.type == D_CONST) {
if(p->from.type == TYPE_CONST) {
if(p->from.offset > BIG || p->from.offset < -BIG)
ctxt->diag("illegal syscall, sysnum too large: %P", p);
o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, p->from.offset);
} else if(p->from.type == D_REG) {
} else if(p->from.type == TYPE_REG) {
o1 = LOP_RRR(OP_OR, REGZERO, p->from.reg, p->from.reg);
} else {
ctxt->diag("illegal syscall: %P", p);
......
......@@ -86,7 +86,7 @@ Pconv(Fmt *fp)
{
char str[STRINGSZ];
Prog *p;
int a, ch;
int a;
p = va_arg(fp->args, Prog*);
bigP = p;
......@@ -108,25 +108,21 @@ Pconv(Fmt *fp)
} else {
if(p->mark & NOSCHED)
sprint(strchr(str, 0), "*");
if(p->reg == NREG && p->from3.type == D_NONE)
if(p->reg == 0 && p->from3.type == TYPE_NONE)
sprint(strchr(str, 0), "%.5lld (%L) %A %D,%D", p->pc, p->lineno, a, &p->from, &p->to);
else
if(a != ATEXT && p->from.type == D_OREG) {
sprint(strchr(str, 0), "%.5lld (%L) %A %lld(R%d+R%d),%D", p->pc, p->lineno, a,
if(a != ATEXT && p->from.type == TYPE_MEM) {
sprint(strchr(str, 0), "%.5lld (%L) %A %lld(%R+%R),%D", p->pc, p->lineno, a,
p->from.offset, p->from.reg, p->reg, &p->to);
} else
if(p->to.type == D_OREG) {
sprint(strchr(str, 0), "%.5lld (%L) %A %D,%lld(R%d+R%d)", p->pc, p->lineno, a,
if(p->to.type == TYPE_MEM) {
sprint(strchr(str, 0), "%.5lld (%L) %A %D,%lld(%R+%R)", p->pc, p->lineno, a,
&p->from, p->to.offset, p->to.reg, p->reg);
} else {
sprint(strchr(str, 0), "%.5lld (%L) %A %D", p->pc, p->lineno, a, &p->from);
if(p->reg != NREG) {
ch = 'R';
if(p->from.type == D_FREG)
ch = 'F';
sprint(strchr(str, 0), ",%c%d", ch, p->reg);
}
if(p->from3.type != D_NONE)
if(p->reg != 0)
sprint(strchr(str, 0), ",%R", p->reg);
if(p->from3.type != TYPE_NONE)
sprint(strchr(str, 0), ",%D", &p->from3);
sprint(strchr(str, 0), ",%D", &p->to);
}
......@@ -159,7 +155,7 @@ Dconv(Fmt *fp)
a = va_arg(fp->args, Addr*);
if(fp->flags & FmtLong) {
if(a->type == D_CONST)
if(a->type == TYPE_CONST)
sprint(str, "$%d-%d", (int32)a->offset, (int32)(a->offset>>32));
else {
// ATEXT dst is not constant
......@@ -173,89 +169,33 @@ Dconv(Fmt *fp)
sprint(str, "GOK-type(%d)", a->type);
break;
case D_NONE:
case TYPE_NONE:
str[0] = 0;
if(a->name != D_NONE || a->reg != NREG || a->sym != nil)
sprint(str, "%M(R%d)(NONE)", a, a->reg);
if(a->name != TYPE_NONE || a->reg != 0 || a->sym != nil)
sprint(str, "%M(%R)(NONE)", a, a->reg);
break;
case D_CONST:
case D_DCONST:
if(a->reg != NREG)
sprint(str, "$%M(R%d)", a, a->reg);
case TYPE_CONST:
if(a->reg != 0)
sprint(str, "$%M(%R)", a, a->reg);
else
sprint(str, "$%M", a);
break;
case D_OREG:
if(a->reg != NREG)
sprint(str, "%M(R%d)", a, a->reg);
case TYPE_MEM:
if(a->reg != 0)
sprint(str, "%M(%R)", a, a->reg);
else
sprint(str, "%M", a);
break;
case D_REG:
sprint(str, "R%d", a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(R%d)(REG)", a, a->reg);
break;
case D_FREG:
sprint(str, "F%d", a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(F%d)(REG)", a, a->reg);
break;
case D_CREG:
if(a->reg == NREG)
strcpy(str, "CR");
else
sprint(str, "CR%d", a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(C%d)(REG)", a, a->reg);
break;
case D_SPR:
if(a->name == D_NONE && a->sym == nil) {
switch((ulong)a->offset) {
case D_XER: sprint(str, "XER"); break;
case D_LR: sprint(str, "LR"); break;
case D_CTR: sprint(str, "CTR"); break;
default: sprint(str, "SPR(%lld)", a->offset); break;
}
break;
}
sprint(str, "SPR-GOK(%d)", a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(SPR-GOK%d)(REG)", a, a->reg);
break;
case D_DCR:
if(a->name == D_NONE && a->sym == nil) {
sprint(str, "DCR(%lld)", a->offset);
break;
}
sprint(str, "DCR-GOK(%d)", a->reg);
if(a->name != D_NONE || a->sym != nil)
sprint(str, "%M(DCR-GOK%d)(REG)", a, a->reg);
case TYPE_REG:
sprint(str, "%R", a->reg);
if(a->name != TYPE_NONE || a->sym != nil)
sprint(str, "%M(%R)(REG)", a, a->reg);
break;
case D_OPT:
sprint(str, "OPT(%d)", a->reg);
break;
case D_FPSCR:
if(a->reg == NREG)
strcpy(str, "FPSCR");
else
sprint(str, "FPSCR(%d)", a->reg);
break;
case D_MSR:
sprint(str, "MSR");
break;
case D_BRANCH:
case TYPE_BRANCH:
if(bigP->pcond != nil) {
v = bigP->pcond->pc;
//if(v >= INITTEXT)
......@@ -272,12 +212,12 @@ Dconv(Fmt *fp)
sprint(str, "%lld(APC)", a->offset);
break;
case D_FCONST:
case TYPE_FCONST:
//sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
sprint(str, "$%.17g", a->u.dval);
break;
case D_SCONST:
case TYPE_SCONST:
sprint(str, "$\"%$\"", a->u.sval);
break;
}
......@@ -309,7 +249,7 @@ Mconv(Fmt *fp)
sprint(str, "GOK-name(%d)", a->name);
break;
case D_NONE:
case TYPE_NONE:
l = a->offset;
if((vlong)l != a->offset)
sprint(str, "0x%llux", a->offset);
......@@ -317,25 +257,25 @@ Mconv(Fmt *fp)
sprint(str, "%lld", a->offset);
break;
case D_EXTERN:
case NAME_EXTERN:
if(a->offset != 0)
sprint(str, "%s+%lld(SB)", s->name, a->offset);
else
sprint(str, "%s(SB)", s->name);
break;
case D_STATIC:
case NAME_STATIC:
sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
break;
case D_AUTO:
case NAME_AUTO:
if(s == nil)
sprint(str, "%lld(SP)", -a->offset);
else
sprint(str, "%s-%lld(SP)", s->name, -a->offset);
break;
case D_PARAM:
case NAME_PARAM:
if(s == nil)
sprint(str, "%lld(FP)", a->offset);
else
......@@ -349,15 +289,38 @@ Mconv(Fmt *fp)
static int
Rconv(Fmt *fp)
{
char str[STRINGSZ];
int r;
r = va_arg(fp->args, int);
if(r < NREG)
sprint(str, "r%d", r);
else
sprint(str, "f%d", r-NREG);
return fmtstrcpy(fp, str);
if(r == 0)
return fmtstrcpy(fp, "NONE");
if(REG_R0 <= r && r <= REG_R31)
return fmtprint(fp, "R%d", r-REG_R0);
if(REG_F0 <= r && r <= REG_F31)
return fmtprint(fp, "F%d", r-REG_F0);
if(REG_C0 <= r && r <= REG_C7)
return fmtprint(fp, "C%d", r-REG_C0);
if(r == REG_CR)
return fmtstrcpy(fp, "CR");
if(REG_SPR0 <= r && r <= REG_SPR0+1023) {
switch(r) {
case REG_XER:
return fmtstrcpy(fp, "XER");
case REG_LR:
return fmtstrcpy(fp, "LR");
case REG_CTR:
return fmtstrcpy(fp, "CTR");
}
return fmtprint(fp, "SPR(%d)", r-REG_SPR0);
}
if(REG_DCR0 <= r && r <= REG_DCR0+1023)
return fmtprint(fp, "DCR(%d)", r-REG_DCR0);
if(r == REG_FPSCR)
return fmtstrcpy(fp, "FPSCR");
if(r == REG_MSR)
return fmtstrcpy(fp, "MSR");
return fmtprint(fp, "badreg(%d)", r);
}
static int
......
......@@ -37,30 +37,8 @@
static Prog zprg = {
.as = AGOK,
.reg = NREG,
.from = {
.name = D_NONE,
.type = D_NONE,
.reg = NREG,
},
.from3 = {
.name = D_NONE,
.type = D_NONE,
.reg = NREG,
},
.to = {
.name = D_NONE,
.type = D_NONE,
.reg = NREG,
},
};
static int
symtype(Addr *a)
{
return a->name;
}
static int
isdata(Prog *p)
{
......@@ -102,7 +80,7 @@ progedit(Link *ctxt, Prog *p)
p->from.class = 0;
p->to.class = 0;
// Rewrite BR/BL to symbol as D_BRANCH.
// Rewrite BR/BL to symbol as TYPE_BRANCH.
switch(p->as) {
case ABR:
case ABL:
......@@ -110,14 +88,14 @@ progedit(Link *ctxt, Prog *p)
case ADUFFZERO:
case ADUFFCOPY:
if(p->to.sym != nil)
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
break;
}
// Rewrite float constants to values stored in memory.
switch(p->as) {
case AFMOVS:
if(p->from.type == D_FCONST) {
if(p->from.type == TYPE_FCONST) {
uint32 i32;
float32 f32;
f32 = p->from.u.dval;
......@@ -125,34 +103,34 @@ progedit(Link *ctxt, Prog *p)
sprint(literal, "$f32.%08ux", i32);
s = linklookup(ctxt, literal, 0);
s->size = 4;
p->from.type = D_OREG;
p->from.type = TYPE_MEM;
p->from.sym = s;
p->from.name = D_EXTERN;
p->from.name = NAME_EXTERN;
p->from.offset = 0;
}
break;
case AFMOVD:
if(p->from.type == D_FCONST) {
if(p->from.type == TYPE_FCONST) {
uint64 i64;
memmove(&i64, &p->from.u.dval, 8);
sprint(literal, "$f64.%016llux", i64);
s = linklookup(ctxt, literal, 0);
s->size = 8;
p->from.type = D_OREG;
p->from.type = TYPE_MEM;
p->from.sym = s;
p->from.name = D_EXTERN;
p->from.name = NAME_EXTERN;
p->from.offset = 0;
}
break;
case AMOVD:
// Put >32-bit constants in memory and load them
if(p->from.type == D_CONST && p->from.name == D_NONE && p->from.reg == NREG && (int32)p->from.offset != p->from.offset) {
if(p->from.type == TYPE_CONST && p->from.name == NAME_NONE && p->from.reg == 0 && (int32)p->from.offset != p->from.offset) {
sprint(literal, "$i64.%016llux", (uvlong)p->from.offset);
s = linklookup(ctxt, literal, 0);
s->size = 8;
p->from.type = D_OREG;
p->from.type = TYPE_MEM;
p->from.sym = s;
p->from.name = D_EXTERN;
p->from.name = NAME_EXTERN;
p->from.offset = 0;
}
}
......@@ -160,21 +138,21 @@ progedit(Link *ctxt, Prog *p)
// Rewrite SUB constants into ADD.
switch(p->as) {
case ASUBC:
if(p->from.type == D_CONST) {
if(p->from.type == TYPE_CONST) {
p->from.offset = -p->from.offset;
p->as = AADDC;
}
break;
case ASUBCCC:
if(p->from.type == D_CONST) {
if(p->from.type == TYPE_CONST) {
p->from.offset = -p->from.offset;
p->as = AADDCCC;
}
break;
case ASUB:
if(p->from.type == D_CONST) {
if(p->from.type == TYPE_CONST) {
p->from.offset = -p->from.offset;
p->as = AADD;
}
......@@ -198,7 +176,7 @@ parsetextconst(vlong arg, vlong *textstksiz, vlong *textarg)
}
static void
addstacksplit(Link *ctxt, LSym *cursym)
preprocess(Link *ctxt, LSym *cursym)
{
Prog *p, *q, *p1, *p2, *q1;
int o, mov, aoffset;
......@@ -246,7 +224,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
case ANOR:
q = p;
if(p->to.type == D_REG)
if(p->to.type == TYPE_REG)
if(p->to.reg == REGZERO)
p->mark |= LABEL|SYNC;
break;
......@@ -288,22 +266,8 @@ addstacksplit(Link *ctxt, LSym *cursym)
case AMOVWZ:
case AMOVD:
q = p;
switch(p->from.type) {
case D_MSR:
case D_SPR:
case D_FPSCR:
case D_CREG:
case D_DCR:
if(p->from.reg >= REG_SPECIAL || p->to.reg >= REG_SPECIAL)
p->mark |= LABEL|SYNC;
}
switch(p->to.type) {
case D_MSR:
case D_SPR:
case D_FPSCR:
case D_CREG:
case D_DCR:
p->mark |= LABEL|SYNC;
}
continue;
case AFABS:
......@@ -429,9 +393,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
q = appendp(ctxt, p);
q->as = AADD;
q->lineno = p->lineno;
q->from.type = D_CONST;
q->from.type = TYPE_CONST;
q->from.offset = -autosize;
q->to.type = D_REG;
q->to.type = TYPE_REG;
q->to.reg = REGSP;
q->spadj = +autosize;
}
......@@ -453,17 +417,17 @@ addstacksplit(Link *ctxt, LSym *cursym)
q = appendp(ctxt, q);
q->as = AMOVD;
q->lineno = p->lineno;
q->from.type = D_SPR;
q->from.offset = D_LR;
q->to.type = D_REG;
q->from.type = TYPE_REG;
q->from.reg = REG_LR;
q->to.type = TYPE_REG;
q->to.reg = REGTMP;
q = appendp(ctxt, q);
q->as = mov;
q->lineno = p->lineno;
q->from.type = D_REG;
q->from.type = TYPE_REG;
q->from.reg = REGTMP;
q->to.type = D_OREG;
q->to.type = TYPE_MEM;
q->to.offset = aoffset;
q->to.reg = REGSP;
if(q->as == AMOVDU)
......@@ -490,66 +454,66 @@ addstacksplit(Link *ctxt, LSym *cursym)
q = appendp(ctxt, q);
q->as = AMOVD;
q->from.type = D_OREG;
q->from.type = TYPE_MEM;
q->from.reg = REGG;
q->from.offset = 4*ctxt->arch->ptrsize; // G.panic
q->to.type = D_REG;
q->to.reg = 3;
q->to.type = TYPE_REG;
q->to.reg = REG_R3;
q = appendp(ctxt, q);
q->as = ACMP;
q->from.type = D_REG;
q->from.reg = 0;
q->to.type = D_REG;
q->to.reg = 3;
q->from.type = TYPE_REG;
q->from.reg = REG_R0;
q->to.type = TYPE_REG;
q->to.reg = REG_R3;
q = appendp(ctxt, q);
q->as = ABEQ;
q->to.type = D_BRANCH;
q->to.type = TYPE_BRANCH;
p1 = q;
q = appendp(ctxt, q);
q->as = AMOVD;
q->from.type = D_OREG;
q->from.reg = 3;
q->from.type = TYPE_MEM;
q->from.reg = REG_R3;
q->from.offset = 0; // Panic.argp
q->to.type = D_REG;
q->to.reg = 4;
q->to.type = TYPE_REG;
q->to.reg = REG_R4;
q = appendp(ctxt, q);
q->as = AADD;
q->from.type = D_CONST;
q->from.type = TYPE_CONST;
q->from.offset = autosize+8;
q->reg = REGSP;
q->to.type = D_REG;
q->to.reg = 5;
q->to.type = TYPE_REG;
q->to.reg = REG_R5;
q = appendp(ctxt, q);
q->as = ACMP;
q->from.type = D_REG;
q->from.reg = 4;
q->to.type = D_REG;
q->to.reg = 5;
q->from.type = TYPE_REG;
q->from.reg = REG_R4;
q->to.type = TYPE_REG;
q->to.reg = REG_R5;
q = appendp(ctxt, q);
q->as = ABNE;
q->to.type = D_BRANCH;
q->to.type = TYPE_BRANCH;
p2 = q;
q = appendp(ctxt, q);
q->as = AADD;
q->from.type = D_CONST;
q->from.type = TYPE_CONST;
q->from.offset = 8;
q->reg = REGSP;
q->to.type = D_REG;
q->to.reg = 6;
q->to.type = TYPE_REG;
q->to.reg = REG_R6;
q = appendp(ctxt, q);
q->as = AMOVD;
q->from.type = D_REG;
q->from.reg = 6;
q->to.type = D_OREG;
q->to.reg = 3;
q->from.type = TYPE_REG;
q->from.reg = REG_R6;
q->to.type = TYPE_MEM;
q->to.reg = REG_R3;
q->to.offset = 0; // Panic.argp
q = appendp(ctxt, q);
......@@ -561,37 +525,37 @@ addstacksplit(Link *ctxt, LSym *cursym)
break;
case ARETURN:
if(p->from.type == D_CONST) {
if(p->from.type == TYPE_CONST) {
ctxt->diag("using BECOME (%P) is not supported!", p);
break;
}
if(p->to.sym) { // retjmp
p->as = ABR;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
break;
}
if(cursym->text->mark & LEAF) {
if(!autosize) {
p->as = ABR;
p->from = zprg.from;
p->to.type = D_SPR;
p->to.offset = D_LR;
p->to.type = TYPE_REG;
p->to.reg = REG_LR;
p->mark |= BRANCH;
break;
}
p->as = AADD;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = autosize;
p->to.type = D_REG;
p->to.type = TYPE_REG;
p->to.reg = REGSP;
p->spadj = -autosize;
q = ctxt->arch->prg();
q->as = ABR;
q->lineno = p->lineno;
q->to.type = D_SPR;
q->to.offset = D_LR;
q->to.type = TYPE_REG;
q->to.reg = REG_LR;
q->mark |= BRANCH;
q->spadj = +autosize;
......@@ -601,19 +565,19 @@ addstacksplit(Link *ctxt, LSym *cursym)
}
p->as = AMOVD;
p->from.type = D_OREG;
p->from.type = TYPE_MEM;
p->from.offset = 0;
p->from.reg = REGSP;
p->to.type = D_REG;
p->to.type = TYPE_REG;
p->to.reg = REGTMP;
q = ctxt->arch->prg();
q->as = AMOVD;
q->lineno = p->lineno;
q->from.type = D_REG;
q->from.type = TYPE_REG;
q->from.reg = REGTMP;
q->to.type = D_SPR;
q->to.offset = D_LR;
q->to.type = TYPE_REG;
q->to.reg = REG_LR;
q->link = p->link;
p->link = q;
......@@ -624,10 +588,10 @@ addstacksplit(Link *ctxt, LSym *cursym)
q = ctxt->arch->prg();
q->as = AMOVD;
q->lineno = p->lineno;
q->from.type = D_OREG;
q->from.type = TYPE_MEM;
q->from.offset = 0;
q->from.reg = REGTMP;
q->to.type = D_REG;
q->to.type = TYPE_REG;
q->to.reg = REGTMP;
q->link = p->link;
......@@ -639,9 +603,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
q = ctxt->arch->prg();
q->as = AADD;
q->lineno = p->lineno;
q->from.type = D_CONST;
q->from.type = TYPE_CONST;
q->from.offset = autosize;
q->to.type = D_REG;
q->to.type = TYPE_REG;
q->to.reg = REGSP;
q->spadj = -autosize;
......@@ -652,8 +616,8 @@ addstacksplit(Link *ctxt, LSym *cursym)
q1 = ctxt->arch->prg();
q1->as = ABR;
q1->lineno = p->lineno;
q1->to.type = D_SPR;
q1->to.offset = D_LR;
q1->to.type = TYPE_REG;
q1->to.reg = REG_LR;
q1->mark |= BRANCH;
q1->spadj = +autosize;
......@@ -662,7 +626,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
break;
case AADD:
if(p->to.type == D_REG && p->to.reg == REGSP && p->from.type == D_CONST)
if(p->to.type == TYPE_REG && p->to.reg == REGSP && p->from.type == TYPE_CONST)
p->spadj = -p->from.offset;
break;
}
......@@ -723,13 +687,13 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// MOVD g_stackguard(g), R3
p = appendp(ctxt, p);
p->as = AMOVD;
p->from.type = D_OREG;
p->from.type = TYPE_MEM;
p->from.reg = REGG;
p->from.offset = 2*ctxt->arch->ptrsize; // G.stackguard0
if(ctxt->cursym->cfunc)
p->from.offset = 3*ctxt->arch->ptrsize; // G.stackguard1
p->to.type = D_REG;
p->to.reg = 3;
p->to.type = TYPE_REG;
p->to.reg = REG_R3;
q = nil;
if(framesize <= StackSmall) {
......@@ -737,9 +701,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// CMP stackguard, SP
p = appendp(ctxt, p);
p->as = ACMPU;
p->from.type = D_REG;
p->from.reg = 3;
p->to.type = D_REG;
p->from.type = TYPE_REG;
p->from.reg = REG_R3;
p->to.type = TYPE_REG;
p->to.reg = REGSP;
} else if(framesize <= StackBig) {
// large stack: SP-framesize < stackguard-StackSmall
......@@ -747,18 +711,18 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// CMP stackguard, R4
p = appendp(ctxt, p);
p->as = AADD;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = -framesize;
p->reg = REGSP;
p->to.type = D_REG;
p->to.reg = 4;
p->to.type = TYPE_REG;
p->to.reg = REG_R4;
p = appendp(ctxt, p);
p->as = ACMPU;
p->from.type = D_REG;
p->from.reg = 3;
p->to.type = D_REG;
p->to.reg = 4;
p->from.type = TYPE_REG;
p->from.reg = REG_R3;
p->to.type = TYPE_REG;
p->to.reg = REG_R4;
} else {
// Such a large stack we need to protect against wraparound.
// If SP is close to zero:
......@@ -777,64 +741,64 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// CMPU R31, R4
p = appendp(ctxt, p);
p->as = ACMP;
p->from.type = D_REG;
p->from.reg = 3;
p->to.type = D_CONST;
p->from.type = TYPE_REG;
p->from.reg = REG_R3;
p->to.type = TYPE_CONST;
p->to.offset = StackPreempt;
q = p = appendp(ctxt, p);
p->as = ABEQ;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
p = appendp(ctxt, p);
p->as = AADD;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = StackGuard;
p->reg = REGSP;
p->to.type = D_REG;
p->to.reg = 4;
p->to.type = TYPE_REG;
p->to.reg = REG_R4;
p = appendp(ctxt, p);
p->as = ASUB;
p->from.type = D_REG;
p->from.reg = 3;
p->to.type = D_REG;
p->to.reg = 4;
p->from.type = TYPE_REG;
p->from.reg = REG_R3;
p->to.type = TYPE_REG;
p->to.reg = REG_R4;
p = appendp(ctxt, p);
p->as = AMOVD;
p->from.type = D_CONST;
p->from.type = TYPE_CONST;
p->from.offset = framesize + StackGuard - StackSmall;
p->to.type = D_REG;
p->to.type = TYPE_REG;
p->to.reg = REGTMP;
p = appendp(ctxt, p);
p->as = ACMPU;
p->from.type = D_REG;
p->from.type = TYPE_REG;
p->from.reg = REGTMP;
p->to.type = D_REG;
p->to.reg = 4;
p->to.type = TYPE_REG;
p->to.reg = REG_R4;
}
// q1: BLT done
q1 = p = appendp(ctxt, p);
p->as = ABLT;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
// MOVD LR, R5
p = appendp(ctxt, p);
p->as = AMOVD;
p->from.type = D_SPR;
p->from.offset = D_LR;
p->to.type = D_REG;
p->to.reg = 5;
p->from.type = TYPE_REG;
p->from.reg = REG_LR;
p->to.type = TYPE_REG;
p->to.reg = REG_R5;
if(q)
q->pcond = p;
// BL runtime.morestack(SB)
p = appendp(ctxt, p);
p->as = ABL;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
if(ctxt->cursym->cfunc)
p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
else
......@@ -843,7 +807,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// BR start
p = appendp(ctxt, p);
p->as = ABR;
p->to.type = D_BRANCH;
p->to.type = TYPE_BRANCH;
p->pcond = ctxt->cursym->text->link;
// placeholder for q1's jump target
......@@ -969,7 +933,7 @@ loop:
q = ctxt->arch->prg();
q->as = a;
q->lineno = p->lineno;
q->to.type = D_BRANCH;
q->to.type = TYPE_BRANCH;
q->to.offset = p->pc;
q->pcond = p;
p = q;
......@@ -1011,7 +975,7 @@ LinkArch linkppc64 = {
.thechar = '9',
.endian = BigEndian,
.addstacksplit = addstacksplit,
.preprocess = preprocess,
.assemble = span9,
.datasize = datasize,
.follow = follow,
......@@ -1020,25 +984,12 @@ LinkArch linkppc64 = {
.prg = prg,
.progedit = progedit,
.settextflag = settextflag,
.symtype = symtype,
.textflag = textflag,
.minlc = 4,
.ptrsize = 8,
.regsize = 8,
.D_ADDR = D_ADDR,
.D_AUTO = D_AUTO,
.D_BRANCH = D_BRANCH,
.D_CONST = D_CONST,
.D_EXTERN = D_EXTERN,
.D_FCONST = D_FCONST,
.D_NONE = D_NONE,
.D_PARAM = D_PARAM,
.D_SCONST = D_SCONST,
.D_STATIC = D_STATIC,
.D_OREG = D_OREG,
.ACALL = ABL,
.ADATA = ADATA,
.AEND = AEND,
......@@ -1058,7 +1009,7 @@ LinkArch linkppc64le = {
.thechar = '9',
.endian = LittleEndian,
.addstacksplit = addstacksplit,
.preprocess = preprocess,
.assemble = span9,
.datasize = datasize,
.follow = follow,
......@@ -1067,25 +1018,12 @@ LinkArch linkppc64le = {
.prg = prg,
.progedit = progedit,
.settextflag = settextflag,
.symtype = symtype,
.textflag = textflag,
.minlc = 4,
.ptrsize = 8,
.regsize = 8,
.D_ADDR = D_ADDR,
.D_AUTO = D_AUTO,
.D_BRANCH = D_BRANCH,
.D_CONST = D_CONST,
.D_EXTERN = D_EXTERN,
.D_FCONST = D_FCONST,
.D_NONE = D_NONE,
.D_PARAM = D_PARAM,
.D_SCONST = D_SCONST,
.D_STATIC = D_STATIC,
.D_OREG = D_OREG,
.ACALL = ABL,
.ADATA = ADATA,
.AEND = AEND,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment