Commit a5b1baee authored by Russ Cox's avatar Russ Cox

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

Change-Id: I19ed283962aa0221cf806307bde9ea0773a1bfd4
Reviewed-on: https://go-review.googlesource.com/3518Reviewed-by: default avatarAustin Clements <austin@google.com>
parent 604138e8
......@@ -222,8 +222,7 @@ spec3: /* JMP/CALL */
{
$$.from = nullgen;
$$.to = $2;
$$.to.index = $2.type;
$$.to.type = D_INDIR+D_ADDR;
$$.to.type = TYPE_INDIR;
}
spec4: /* NOP */
......@@ -240,7 +239,7 @@ spec5: /* SHL/SHR */
{
$$.from = $1;
$$.to = $3;
if($$.from.index != D_NONE)
if($$.from.index != TYPE_NONE)
yyerror("dp shift with lhs index");
$$.from.index = $5;
}
......@@ -255,7 +254,7 @@ spec6: /* MOVW/MOVL */
{
$$.from = $1;
$$.to = $3;
if($$.to.index != D_NONE)
if($$.to.index != TYPE_NONE)
yyerror("dp move with lhs index");
$$.to.index = $5;
}
......@@ -303,7 +302,7 @@ spec10: /* PINSRD */
{
$$.from = $3;
$$.to = $5;
if($1.type != D_CONST)
if($1.type != TYPE_CONST)
yyerror("illegal constant");
$$.to.offset = $1.offset;
}
......@@ -311,7 +310,7 @@ spec10: /* PINSRD */
spec11: /* PCDATA */
rim ',' rim
{
if($1.type != D_CONST || $3.type != D_CONST)
if($1.type != TYPE_CONST || $3.type != TYPE_CONST)
yyerror("arguments to PCDATA must be integer constants");
$$.from = $1;
$$.to = $3;
......@@ -320,9 +319,9 @@ spec11: /* PCDATA */
spec12: /* FUNCDATA */
rim ',' rim
{
if($1.type != D_CONST)
if($1.type != TYPE_CONST)
yyerror("index for FUNCDATA must be integer constant");
if($3.type != D_EXTERN && $3.type != D_STATIC)
if($3.type != TYPE_MEM || ($3.name != NAME_EXTERN && $3.name != NAME_STATIC))
yyerror("value for FUNCDATA must be symbol reference");
$$.from = $1;
$$.to = $3;
......@@ -355,7 +354,7 @@ rel:
con '(' LPC ')'
{
$$ = nullgen;
$$.type = D_BRANCH;
$$.type = TYPE_BRANCH;
$$.offset = $1 + pc;
}
| LNAME offset
......@@ -364,7 +363,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;
}
......@@ -372,48 +371,53 @@ reg:
LBREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LFREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LLREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LXREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
| LSP
{
$$ = nullgen;
$$.type = D_SP;
$$.type = TYPE_REG;
$$.reg = REG_SP;
}
| LSREG
{
$$ = nullgen;
$$.type = $1;
$$.type = TYPE_REG;
$$.reg = $1;
}
imm:
'$' con
{
$$ = nullgen;
$$.type = D_CONST;
$$.type = TYPE_CONST;
$$.offset = $2;
}
| '$' nam
{
$$ = $2;
$$.index = $2.type;
$$.type = D_ADDR;
$$.type = TYPE_ADDR;
/*
if($2.type == D_AUTO || $2.type == D_PARAM)
if($2.name == NAME_AUTO || $2.name == NAME_PARAM)
yyerror("constant cannot be automatic: %s",
$2.sym->name);
*/
......@@ -421,31 +425,31 @@ imm:
| '$' LSCONST
{
$$ = nullgen;
$$.type = D_SCONST;
$$.type = TYPE_SCONST;
memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
| '$' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = $2;
}
| '$' '(' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = $3;
}
| '$' '(' '-' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = -$4;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
$$.type = TYPE_FCONST;
$$.u.dval = -$3;
}
......@@ -453,9 +457,9 @@ imm2:
'$' con2
{
$$ = nullgen;
$$.type = D_CONST2;
$$.type = TYPE_TEXTSIZE;
$$.offset = $2.v1;
$$.offset2 = $2.v2;
$$.u.argsize = $2.v2;
}
con2:
......@@ -488,25 +492,29 @@ omem:
con
{
$$ = nullgen;
$$.type = D_INDIR+D_NONE;
$$.type = TYPE_MEM;
$$.reg = REG_NONE;
$$.offset = $1;
}
| con '(' LLREG ')'
{
$$ = nullgen;
$$.type = D_INDIR+$3;
$$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1;
}
| con '(' LSP ')'
{
$$ = nullgen;
$$.type = D_INDIR+D_SP;
$$.type = TYPE_MEM;
$$.reg = REG_SP;
$$.offset = $1;
}
| con '(' LLREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+D_NONE;
$$.type = TYPE_MEM;
$$.reg = REG_NONE;
$$.offset = $1;
$$.index = $3;
$$.scale = $5;
......@@ -515,7 +523,8 @@ omem:
| con '(' LLREG ')' '(' LLREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+$3;
$$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1;
$$.index = $6;
$$.scale = $8;
......@@ -524,7 +533,8 @@ omem:
| con '(' LLREG ')' '(' LSREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+$3;
$$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1;
$$.index = $6;
$$.scale = $8;
......@@ -533,23 +543,27 @@ omem:
| '(' LLREG ')'
{
$$ = nullgen;
$$.type = D_INDIR+$2;
$$.type = TYPE_MEM;
$$.reg = $2;
}
| '(' LSP ')'
{
$$ = nullgen;
$$.type = D_INDIR+D_SP;
$$.type = TYPE_MEM;
$$.reg = REG_SP;
}
| con '(' LSREG ')'
{
$$ = nullgen;
$$.type = D_INDIR+$3;
$$.type = TYPE_MEM;
$$.reg = $3;
$$.offset = $1;
}
| '(' LLREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+D_NONE;
$$.type = TYPE_MEM;
$$.reg = REG_NONE;
$$.index = $2;
$$.scale = $4;
checkscale($$.scale);
......@@ -557,7 +571,8 @@ omem:
| '(' LLREG ')' '(' LLREG '*' con ')'
{
$$ = nullgen;
$$.type = D_INDIR+$2;
$$.type = TYPE_MEM;
$$.reg = $2;
$$.index = $5;
$$.scale = $7;
checkscale($$.scale);
......@@ -580,14 +595,16 @@ nam:
LNAME offset '(' pointer ')'
{
$$ = nullgen;
$$.type = $4;
$$.type = TYPE_MEM;
$$.name = $4;
$$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
{
$$ = nullgen;
$$.type = D_STATIC;
$$.type = TYPE_MEM;
$$.name = NAME_STATIC;
$$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4;
}
......@@ -609,7 +626,7 @@ pointer:
LSB
| LSP
{
$$ = D_AUTO;
$$ = NAME_AUTO;
}
| LFP
......
......@@ -192,87 +192,88 @@ struct
ushort value;
} itab[] =
{
"SP", LSP, D_AUTO,
"SB", LSB, D_EXTERN,
"FP", LFP, D_PARAM,
"PC", LPC, D_BRANCH,
"AL", LBREG, D_AL,
"CL", LBREG, D_CL,
"DL", LBREG, D_DL,
"BL", LBREG, D_BL,
"AH", LBREG, D_AH,
"CH", LBREG, D_CH,
"DH", LBREG, D_DH,
"BH", LBREG, D_BH,
"AX", LLREG, D_AX,
"CX", LLREG, D_CX,
"DX", LLREG, D_DX,
"BX", LLREG, D_BX,
/* "SP", LLREG, D_SP, */
"BP", LLREG, D_BP,
"SI", LLREG, D_SI,
"DI", LLREG, D_DI,
"F0", LFREG, D_F0+0,
"F1", LFREG, D_F0+1,
"F2", LFREG, D_F0+2,
"F3", LFREG, D_F0+3,
"F4", LFREG, D_F0+4,
"F5", LFREG, D_F0+5,
"F6", LFREG, D_F0+6,
"F7", LFREG, D_F0+7,
"X0", LXREG, D_X0+0,
"X1", LXREG, D_X0+1,
"X2", LXREG, D_X0+2,
"X3", LXREG, D_X0+3,
"X4", LXREG, D_X0+4,
"X5", LXREG, D_X0+5,
"X6", LXREG, D_X0+6,
"X7", LXREG, D_X0+7,
"CS", LSREG, D_CS,
"SS", LSREG, D_SS,
"DS", LSREG, D_DS,
"ES", LSREG, D_ES,
"FS", LSREG, D_FS,
"GS", LSREG, D_GS,
"TLS", LSREG, D_TLS,
"GDTR", LBREG, D_GDTR,
"IDTR", LBREG, D_IDTR,
"LDTR", LBREG, D_LDTR,
"MSW", LBREG, D_MSW,
"TASK", LBREG, D_TASK,
"CR0", LBREG, D_CR+0,
"CR1", LBREG, D_CR+1,
"CR2", LBREG, D_CR+2,
"CR3", LBREG, D_CR+3,
"CR4", LBREG, D_CR+4,
"CR5", LBREG, D_CR+5,
"CR6", LBREG, D_CR+6,
"CR7", LBREG, D_CR+7,
"DR0", LBREG, D_DR+0,
"DR1", LBREG, D_DR+1,
"DR2", LBREG, D_DR+2,
"DR3", LBREG, D_DR+3,
"DR4", LBREG, D_DR+4,
"DR5", LBREG, D_DR+5,
"DR6", LBREG, D_DR+6,
"DR7", LBREG, D_DR+7,
"TR0", LBREG, D_TR+0,
"TR1", LBREG, D_TR+1,
"TR2", LBREG, D_TR+2,
"TR3", LBREG, D_TR+3,
"TR4", LBREG, D_TR+4,
"TR5", LBREG, D_TR+5,
"TR6", LBREG, D_TR+6,
"TR7", LBREG, D_TR+7,
"SP", LSP, NAME_AUTO,
"SB", LSB, NAME_EXTERN,
"FP", LFP, NAME_PARAM,
"PC", LPC, TYPE_BRANCH,
"AL", LBREG, REG_AL,
"CL", LBREG, REG_CL,
"DL", LBREG, REG_DL,
"BL", LBREG, REG_BL,
"AH", LBREG, REG_AH,
"CH", LBREG, REG_CH,
"DH", LBREG, REG_DH,
"BH", LBREG, REG_BH,
"AX", LLREG, REG_AX,
"CX", LLREG, REG_CX,
"DX", LLREG, REG_DX,
"BX", LLREG, REG_BX,
/* "SP", LLREG, REG_SP, */
"BP", LLREG, REG_BP,
"SI", LLREG, REG_SI,
"DI", LLREG, REG_DI,
"F0", LFREG, REG_F0+0,
"F1", LFREG, REG_F0+1,
"F2", LFREG, REG_F0+2,
"F3", LFREG, REG_F0+3,
"F4", LFREG, REG_F0+4,
"F5", LFREG, REG_F0+5,
"F6", LFREG, REG_F0+6,
"F7", LFREG, REG_F0+7,
"X0", LXREG, REG_X0+0,
"X1", LXREG, REG_X0+1,
"X2", LXREG, REG_X0+2,
"X3", LXREG, REG_X0+3,
"X4", LXREG, REG_X0+4,
"X5", LXREG, REG_X0+5,
"X6", LXREG, REG_X0+6,
"X7", LXREG, REG_X0+7,
"CS", LSREG, REG_CS,
"SS", LSREG, REG_SS,
"DS", LSREG, REG_DS,
"ES", LSREG, REG_ES,
"FS", LSREG, REG_FS,
"GS", LSREG, REG_GS,
"TLS", LSREG, REG_TLS,
"GDTR", LBREG, REG_GDTR,
"IDTR", LBREG, REG_IDTR,
"LDTR", LBREG, REG_LDTR,
"MSW", LBREG, REG_MSW,
"TASK", LBREG, REG_TASK,
"CR0", LBREG, REG_CR+0,
"CR1", LBREG, REG_CR+1,
"CR2", LBREG, REG_CR+2,
"CR3", LBREG, REG_CR+3,
"CR4", LBREG, REG_CR+4,
"CR5", LBREG, REG_CR+5,
"CR6", LBREG, REG_CR+6,
"CR7", LBREG, REG_CR+7,
"DR0", LBREG, REG_DR+0,
"DR1", LBREG, REG_DR+1,
"DR2", LBREG, REG_DR+2,
"DR3", LBREG, REG_DR+3,
"DR4", LBREG, REG_DR+4,
"DR5", LBREG, REG_DR+5,
"DR6", LBREG, REG_DR+6,
"DR7", LBREG, REG_DR+7,
"TR0", LBREG, REG_TR+0,
"TR1", LBREG, REG_TR+1,
"TR2", LBREG, REG_TR+2,
"TR3", LBREG, REG_TR+3,
"TR4", LBREG, REG_TR+4,
"TR5", LBREG, REG_TR+5,
"TR6", LBREG, REG_TR+6,
"TR7", LBREG, REG_TR+7,
"AAA", LTYPE0, AAAA,
"AAD", LTYPE0, AAAD,
......@@ -829,8 +830,8 @@ cinit(void)
Sym *s;
int i;
nullgen.type = D_NONE;
nullgen.index = D_NONE;
nullgen.type = TYPE_NONE;
nullgen.index = TYPE_NONE;
nerrors = 0;
iostack = I;
......
This diff is collapsed.
......@@ -715,8 +715,9 @@ agen(Node *n, Node *res)
// LEAL (n3)(n2*w), n3
p1 = gins(ALEAL, &n2, &n3);
p1->from.scale = w;
p1->from.index = p1->from.type;
p1->from.type = p1->to.type + D_INDIR;
p1->from.type = TYPE_MEM;
p1->from.index = p1->from.reg;
p1->from.reg = p1->to.reg;
} else {
nodconst(&tmp, types[TUINT32], w);
gins(optoas(OMUL, types[TUINT32]), &tmp, &n2);
......@@ -805,7 +806,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_SP)
if(n->val.u.reg != REG_SP)
reg[n->val.u.reg]++;
*a = *n;
return;
......@@ -856,7 +857,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_SP;
a->val.u.reg = REG_SP;
a->addable = 1;
a->xoffset = fp->width;
a->type = n->type;
......@@ -1262,8 +1263,8 @@ sgen(Node *n, Node *res, int64 w)
return;
}
nodreg(&dst, types[tptr], D_DI);
nodreg(&src, types[tptr], D_SI);
nodreg(&dst, types[tptr], REG_DI);
nodreg(&src, types[tptr], REG_SI);
tempname(&tsrc, types[tptr]);
tempname(&tdst, types[tptr]);
......@@ -1293,23 +1294,23 @@ sgen(Node *n, Node *res, int64 w)
// reverse direction
gins(ASTD, N, N); // set direction flag
if(c > 0) {
gconreg(AADDL, w-1, D_SI);
gconreg(AADDL, w-1, D_DI);
gconreg(AADDL, w-1, REG_SI);
gconreg(AADDL, w-1, REG_DI);
gconreg(AMOVL, c, D_CX);
gconreg(AMOVL, c, REG_CX);
gins(AREP, N, N); // repeat
gins(AMOVSB, N, N); // MOVB *(SI)-,*(DI)-
}
if(q > 0) {
if(c > 0) {
gconreg(AADDL, -3, D_SI);
gconreg(AADDL, -3, D_DI);
gconreg(AADDL, -3, REG_SI);
gconreg(AADDL, -3, REG_DI);
} else {
gconreg(AADDL, w-4, D_SI);
gconreg(AADDL, w-4, D_DI);
gconreg(AADDL, w-4, REG_SI);
gconreg(AADDL, w-4, REG_DI);
}
gconreg(AMOVL, q, D_CX);
gconreg(AMOVL, q, REG_CX);
gins(AREP, N, N); // repeat
gins(AMOVSL, N, N); // MOVL *(SI)-,*(DI)-
}
......@@ -1319,12 +1320,12 @@ sgen(Node *n, Node *res, int64 w)
gins(ACLD, N, N); // paranoia. TODO(rsc): remove?
// normal direction
if(q > 128 || (q >= 4 && nacl)) {
gconreg(AMOVL, q, D_CX);
gconreg(AMOVL, q, REG_CX);
gins(AREP, N, N); // repeat
gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+
} else if(q >= 4) {
p = gins(ADUFFCOPY, N, N);
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
p->to.sym = linksym(pkglookup("duffcopy", runtimepkg));
// 10 and 128 = magic constants: see ../../runtime/asm_386.s
p->to.offset = 10*(128-q);
......
......@@ -73,9 +73,9 @@ cgen64(Node *n, Node *res)
r = &t2;
}
nodreg(&ax, types[TINT32], D_AX);
nodreg(&cx, types[TINT32], D_CX);
nodreg(&dx, types[TINT32], D_DX);
nodreg(&ax, types[TINT32], REG_AX);
nodreg(&cx, types[TINT32], REG_CX);
nodreg(&dx, types[TINT32], REG_DX);
// Setup for binary operation.
split64(l, &lo1, &hi1);
......@@ -159,10 +159,10 @@ cgen64(Node *n, Node *res)
} else {
gins(AMOVL, &dx, &cx);
p1 = gins(ASHLL, ncon(v), &dx);
p1->from.index = D_AX; // double-width shift
p1->from.index = REG_AX; // double-width shift
p1->from.scale = 0;
p1 = gins(ASHLL, ncon(v), &ax);
p1->from.index = D_CX; // double-width shift
p1->from.index = REG_CX; // double-width shift
p1->from.scale = 0;
}
break;
......@@ -198,7 +198,7 @@ cgen64(Node *n, Node *res)
gins(AMOVL, &lo1, &ax);
gins(AMOVL, &hi1, &dx);
p1 = gins(ASHLL, ncon(v), &dx);
p1->from.index = D_AX; // double-width shift
p1->from.index = REG_AX; // double-width shift
p1->from.scale = 0;
gins(ASHLL, ncon(v), &ax);
break;
......@@ -240,7 +240,7 @@ cgen64(Node *n, Node *res)
// general shift
p1 = gins(ASHLL, &cx, &dx);
p1->from.index = D_AX; // double-width shift
p1->from.index = REG_AX; // double-width shift
p1->from.scale = 0;
gins(ASHLL, &cx, &ax);
patch(p2, pc);
......@@ -287,7 +287,7 @@ cgen64(Node *n, Node *res)
gins(AMOVL, &lo1, &ax);
gins(AMOVL, &hi1, &dx);
p1 = gins(ASHRL, ncon(v), &ax);
p1->from.index = D_DX; // double-width shift
p1->from.index = REG_DX; // double-width shift
p1->from.scale = 0;
gins(optoas(ORSH, hi1.type), ncon(v), &dx);
break;
......@@ -339,7 +339,7 @@ cgen64(Node *n, Node *res)
// general shift
p1 = gins(ASHRL, &cx, &ax);
p1->from.index = D_DX; // double-width shift
p1->from.index = REG_DX; // double-width shift
p1->from.scale = 0;
gins(optoas(ORSH, hi1.type), &cx, &dx);
patch(p2, pc);
......
......@@ -38,8 +38,8 @@ betypeinit(void)
zprog.link = P;
zprog.as = AGOK;
zprog.from.type = D_NONE;
zprog.from.index = D_NONE;
zprog.from.type = TYPE_NONE;
zprog.from.index = TYPE_NONE;
zprog.from.scale = 0;
zprog.to = zprog.from;
arch.zprog = zprog;
......@@ -71,10 +71,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;
......
......@@ -20,7 +20,7 @@ enum
};
EXTERN int32 dynloc;
EXTERN uchar reg[D_NONE];
EXTERN uchar reg[MAXREG];
EXTERN int32 pcloc; // instruction counter
EXTERN Strlit emptystring;
EXTERN Prog zprog;
......
......@@ -9,7 +9,7 @@
#include "gg.h"
#include "opt.h"
static Prog *appendpp(Prog*, int, int, vlong, int, vlong);
static Prog *appendpp(Prog*, int, int, int, vlong, int, int, vlong);
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
void
......@@ -22,7 +22,7 @@ defframe(Prog *ptxt)
Node *n;
// fill in argument size
ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
ptxt->to.u.argsize = rnd(curfn->type->argwid, widthptr);
// fill in final stack size
frame = rnd(stksize+maxarg, widthptr);
......@@ -68,28 +68,28 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax)
if(cnt == 0)
return p;
if(*ax == 0) {
p = appendpp(p, AMOVL, D_CONST, 0, D_AX, 0);
p = appendpp(p, AMOVL, TYPE_CONST, 0, 0, TYPE_REG, REG_AX, 0);
*ax = 1;
}
if(cnt <= 4*widthreg) {
for(i = 0; i < cnt; i += widthreg) {
p = appendpp(p, AMOVL, D_AX, 0, D_SP+D_INDIR, frame+lo+i);
p = appendpp(p, AMOVL, TYPE_REG, REG_AX, 0, TYPE_MEM, REG_SP, frame+lo+i);
}
} else if(!nacl && cnt <= 128*widthreg) {
p = appendpp(p, ALEAL, D_SP+D_INDIR, frame+lo, D_DI, 0);
p = appendpp(p, ADUFFZERO, D_NONE, 0, D_ADDR, 1*(128-cnt/widthreg));
p = appendpp(p, ALEAL, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_ADDR, 0, 1*(128-cnt/widthreg));
p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
} else {
p = appendpp(p, AMOVL, D_CONST, cnt/widthreg, D_CX, 0);
p = appendpp(p, ALEAL, D_SP+D_INDIR, frame+lo, D_DI, 0);
p = appendpp(p, AREP, D_NONE, 0, D_NONE, 0);
p = appendpp(p, ASTOSL, D_NONE, 0, D_NONE, 0);
p = appendpp(p, AMOVL, TYPE_CONST, 0, cnt/widthreg, TYPE_REG, REG_CX, 0);
p = appendpp(p, ALEAL, TYPE_MEM, REG_SP, frame+lo, TYPE_REG, REG_DI, 0);
p = appendpp(p, AREP, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
p = appendpp(p, ASTOSL, TYPE_NONE, 0, 0, TYPE_NONE, 0, 0);
}
return p;
}
static Prog*
appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)
appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset)
{
Prog *q;
q = mal(sizeof(*q));
......@@ -97,8 +97,10 @@ appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)
q->as = as;
q->lineno = p->lineno;
q->from.type = ftype;
q->from.reg = freg;
q->from.offset = foffset;
q->to.type = ttype;
q->to.reg = treg;
q->to.offset = toffset;
q->link = p->link;
p->link = q;
......@@ -128,7 +130,7 @@ fixautoused(Prog* p)
Prog **lp;
for (lp=&p; (p=*lp) != P; ) {
if (p->as == ATYPE && p->from.node && p->from.type == 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;
}
......@@ -137,16 +139,14 @@ 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.type == D_AUTO && p->from.node)
if (p->from.type == TYPE_MEM && p->from.name == NAME_AUTO && p->from.node)
p->from.offset += ((Node*)(p->from.node))->stkdelta;
if (p->to.type == D_AUTO && p->to.node)
if (p->to.type == TYPE_MEM && p->to.name == NAME_AUTO && p->to.node)
p->to.offset += ((Node*)(p->to.node))->stkdelta;
lp = &p->link;
......@@ -198,17 +198,17 @@ clearfat(Node *nl)
return;
}
nodreg(&n1, types[tptr], D_DI);
nodreg(&n1, types[tptr], REG_DI);
agen(nl, &n1);
gconreg(AMOVL, 0, D_AX);
gconreg(AMOVL, 0, REG_AX);
if(q > 128 || (q >= 4 && nacl)) {
gconreg(AMOVL, q, D_CX);
gconreg(AMOVL, q, REG_CX);
gins(AREP, N, N); // repeat
gins(ASTOSL, N, N); // STOL AL,*(DI)+
} else if(q >= 4) {
p = gins(ADUFFZERO, N, N);
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
// 1 and 128 = magic constants: see ../../runtime/asm_386.s
p->to.offset = 1*(128-q);
......@@ -265,7 +265,7 @@ ginscall(Node *f, int proc)
// x86 NOP 0x90 is really XCHG AX, AX; use that description
// because the NOP pseudo-instruction will be removed by
// the linker.
nodreg(&reg, types[TINT], D_AX);
nodreg(&reg, types[TINT], REG_AX);
gins(AXCHGL, &reg, &reg);
}
p = gins(ACALL, N, f);
......@@ -274,8 +274,8 @@ ginscall(Node *f, int proc)
gins(AUNDEF, N, N);
break;
}
nodreg(&reg, types[tptr], D_DX);
nodreg(&r1, types[tptr], D_BX);
nodreg(&reg, types[tptr], REG_DX);
nodreg(&r1, types[tptr], REG_BX);
gmove(f, &reg);
reg.op = OINDREG;
gmove(&reg, &r1);
......@@ -291,7 +291,7 @@ ginscall(Node *f, int proc)
case 2: // deferred call (defer)
memset(&stk, 0, sizeof(stk));
stk.op = OINDREG;
stk.val.u.reg = D_SP;
stk.val.u.reg = REG_SP;
stk.xoffset = 0;
// size of arguments at 0(SP)
......@@ -307,7 +307,7 @@ ginscall(Node *f, int proc)
else
ginscall(deferproc, 0);
if(proc == 2) {
nodreg(&reg, types[TINT32], D_AX);
nodreg(&reg, types[TINT32], REG_AX);
gins(ATESTL, &reg, &reg);
p = gbranch(AJEQ, T, +1);
cgen_ret(N);
......@@ -349,7 +349,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_SP);
nodindreg(&nodsp, types[tptr], REG_SP);
nodsp.xoffset = 0;
if(proc != 0)
nodsp.xoffset += 2 * widthptr; // leave room for size & fn
......@@ -458,7 +458,7 @@ cgen_callret(Node *n, Node *res)
memset(&nod, 0, sizeof(nod));
nod.op = OINDREG;
nod.val.u.reg = D_SP;
nod.val.u.reg = REG_SP;
nod.addable = 1;
nod.xoffset = fp->width;
......@@ -488,7 +488,7 @@ cgen_aret(Node *n, Node *res)
memset(&nod1, 0, sizeof(nod1));
nod1.op = OINDREG;
nod1.val.u.reg = D_SP;
nod1.val.u.reg = REG_SP;
nod1.addable = 1;
nod1.xoffset = fp->width;
......@@ -519,7 +519,8 @@ cgen_ret(Node *n)
genlist(curfn->exit);
p = gins(ARET, N, N);
if(n != N && n->op == ORETJMP) {
p->to.type = D_EXTERN;
p->to.type = TYPE_MEM;
p->to.name = NAME_EXTERN;
p->to.sym = linksym(n->left->sym);
}
}
......@@ -830,8 +831,8 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
t = types[TINT32];
else
t = types[TUINT32];
savex(D_AX, &ax, &oldax, res, t);
savex(D_DX, &dx, &olddx, res, t);
savex(REG_AX, &ax, &oldax, res, t);
savex(REG_DX, &dx, &olddx, res, t);
dodiv(op, nl, nr, res, &ax, &dx);
restx(&dx, &olddx);
restx(&ax, &oldax);
......@@ -875,8 +876,8 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
}
memset(&oldcx, 0, sizeof oldcx);
nodreg(&cx, types[TUINT32], D_CX);
if(reg[D_CX] > 1 && !samereg(&cx, res)) {
nodreg(&cx, types[TUINT32], REG_CX);
if(reg[REG_CX] > 1 && !samereg(&cx, res)) {
tempname(&oldcx, types[TUINT32]);
gmove(&cx, &oldcx);
}
......@@ -885,7 +886,7 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
tempname(&nt, nr->type);
n1 = nt;
} else {
nodreg(&n1, types[TUINT32], D_CX);
nodreg(&n1, types[TUINT32], REG_CX);
regalloc(&n1, nr->type, &n1); // to hold the shift type in CX
}
......@@ -905,7 +906,7 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
if(bounded) {
if(nr->type->width > 4) {
// delayed reg alloc
nodreg(&n1, types[TUINT32], D_CX);
nodreg(&n1, types[TUINT32], REG_CX);
regalloc(&n1, types[TUINT32], &n1); // to hold the shift type in CX
split64(&nt, &lo, &hi);
gmove(&lo, &n1);
......@@ -914,7 +915,7 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
} else {
if(nr->type->width > 4) {
// delayed reg alloc
nodreg(&n1, types[TUINT32], D_CX);
nodreg(&n1, types[TUINT32], REG_CX);
regalloc(&n1, types[TUINT32], &n1); // to hold the shift type in CX
split64(&nt, &lo, &hi);
gmove(&lo, &n1);
......@@ -1005,18 +1006,18 @@ cgen_hmul(Node *nl, Node *nr, Node *res)
cgen(nr, &n2);
// multiply.
nodreg(&ax, t, D_AX);
nodreg(&ax, t, REG_AX);
gmove(&n2, &ax);
gins(a, &n1, N);
regfree(&n2);
if(t->width == 1) {
// byte multiply behaves differently.
nodreg(&ax, t, D_AH);
nodreg(&dx, t, D_DX);
nodreg(&ax, t, REG_AH);
nodreg(&dx, t, REG_DX);
gmove(&ax, &dx);
}
nodreg(&dx, t, D_DX);
nodreg(&dx, t, REG_DX);
gmove(&dx, res);
}
......@@ -1083,8 +1084,8 @@ cgen_float387(Node *n, Node *res)
nl = n->left;
nr = n->right;
nodreg(&f0, nl->type, D_F0);
nodreg(&f1, n->type, D_F0+1);
nodreg(&f0, nl->type, REG_F0);
nodreg(&f1, n->type, REG_F0+1);
if(nr != N)
goto flt2;
......@@ -1223,9 +1224,9 @@ x87:
a = brrev(a);
}
nodreg(&tmp, nr->type, D_F0);
nodreg(&n2, nr->type, D_F0 + 1);
nodreg(&ax, types[TUINT16], D_AX);
nodreg(&tmp, nr->type, REG_F0);
nodreg(&n2, nr->type, REG_F0 + 1);
nodreg(&ax, types[TUINT16], REG_AX);
et = simsimtype(nr->type);
if(et == TFLOAT64) {
if(nl->ullman > nr->ullman) {
......@@ -1336,22 +1337,24 @@ expandchecks(Prog *firstp)
p1->pc = 9999;
p2->pc = 9999;
p->as = ACMPL;
p->to.type = D_CONST;
p->to.type = TYPE_CONST;
p->to.offset = 0;
p1->as = AJNE;
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.
// if possible, since we know arg is 0, use 0(arg),
// which will be shorter to encode than plain 0.
p2->as = AMOVL;
p2->from.type = D_AX;
if(regtyp(&p->from))
p2->to.type = p->from.type + D_INDIR;
else
p2->to.type = D_INDIR+D_NONE;
p2->from.type = TYPE_REG;
p2->from.reg = REG_AX;
if(regtyp(&p->from)) {
p2->to.type = TYPE_MEM;
p2->to.reg = p->from.reg;
} else
p2->to.type = TYPE_MEM;
p2->to.offset = 0;
}
}
......@@ -38,14 +38,13 @@ dsname(Sym *s, int off, char *t, int n)
Prog *p;
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.offset = off;
p->from.scale = n;
p->from.sym = linksym(s);
p->to.type = D_SCONST;
p->to.index = D_NONE;
p->to.type = TYPE_SCONST;
memmove(p->to.u.sval, t, n);
return off + n;
}
......@@ -60,7 +59,8 @@ datastring(char *s, int len, Addr *a)
Sym *sym;
sym = stringsym(s, len);
a->type = D_EXTERN;
a->type = TYPE_MEM;
a->name = NAME_EXTERN;
a->sym = linksym(sym);
a->node = sym->def;
a->offset = widthptr+4; // skip header
......@@ -77,7 +77,8 @@ datagostring(Strlit *sval, Addr *a)
Sym *sym;
sym = stringsym(sval->s, sval->len);
a->type = D_EXTERN;
a->type = TYPE_MEM;
a->name = NAME_EXTERN;
a->sym = linksym(sym);
a->node = sym->def;
a->offset = 0; // header
......@@ -125,13 +126,13 @@ gdatacomplex(Node *nam, Mpcplx *cval)
p = gins(ADATA, nam, N);
p->from.scale = w;
p->to.type = D_FCONST;
p->to.type = TYPE_FCONST;
p->to.u.dval = mpgetflt(&cval->real);
p = gins(ADATA, nam, N);
p->from.scale = w;
p->from.offset += w;
p->to.type = D_FCONST;
p->to.type = TYPE_FCONST;
p->to.u.dval = mpgetflt(&cval->imag);
}
......@@ -144,8 +145,7 @@ gdatastring(Node *nam, Strlit *sval)
p = gins(ADATA, nam, N);
datastring(sval->s, sval->len, &p->to);
p->from.scale = types[tptr]->width;
p->to.index = p->to.type;
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
//print("%P\n", p);
nodconst(&nod1, types[TINT32], sval->len);
......@@ -161,15 +161,14 @@ dstringptr(Sym *s, int off, char *str)
off = rnd(off, widthptr);
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
datastring(str, strlen(str)+1, &p->to);
p->to.index = p->to.type;
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
p->to.etype = TINT32;
off += widthptr;
......@@ -186,14 +185,13 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
off = rnd(off, widthptr);
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
datagostring(lit, &p->to);
p->to.index = p->to.type;
p->to.type = D_ADDR;
p->to.type = TYPE_ADDR;
p->to.etype = TINT32;
off += widthptr;
......@@ -224,13 +222,13 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
off = rnd(off, widthptr);
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
p->from.type = TYPE_MEM;
p->from.name = NAME_EXTERN;
p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
p->to.type = D_ADDR;
p->to.index = D_EXTERN;
p->to.type = TYPE_ADDR;
p->to.name = NAME_EXTERN;
p->to.sym = linksym(x);
p->to.offset = xoff;
off += widthptr;
......@@ -242,5 +240,7 @@ void
nopout(Prog *p)
{
p->as = ANOP;
p->from = zprog.from;
p->to = zprog.to;
}
This diff is collapsed.
......@@ -32,9 +32,6 @@
#define Z N
#define Adr Addr
#define D_HI D_NONE
#define D_LO D_NONE
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
......@@ -52,8 +49,6 @@ typedef struct Rgn Rgn;
extern Node *Z;
enum
{
D_HI = D_NONE,
D_LO = D_NONE,
CLOAD = 5,
CREF = 5,
CINF = 1000,
......
......@@ -74,7 +74,7 @@ rnops(Flow *r)
if(r != nil)
for(;;) {
p = r->prog;
if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
if(p->as != ANOP || p->from.type != TYPE_NONE || p->to.type != TYPE_NONE)
break;
r1 = uniqs(r);
if(r1 == nil)
......@@ -110,7 +110,7 @@ peep(Prog *firstp)
case ALEAL:
if(regtyp(&p->to))
if(p->from.sym != nil)
if(p->from.index == D_NONE || p->from.index == D_CONST)
if(p->from.index == REG_NONE)
conprop(r);
break;
......@@ -120,7 +120,7 @@ peep(Prog *firstp)
case AMOVSS:
case AMOVSD:
if(regtyp(&p->to))
if(p->from.type == D_CONST || p->from.type == D_FCONST)
if(p->from.type == TYPE_CONST || p->from.type == TYPE_FCONST)
conprop(r);
break;
}
......@@ -158,7 +158,7 @@ loop1:
r1 = rnops(uniqs(r));
if(r1 != nil) {
p1 = r1->prog;
if(p->as == p1->as && p->to.type == p1->from.type){
if(p->as == p1->as && p->to.type == p1->from.type && p->to.reg == p1->from.reg){
p1->as = AMOVL;
t++;
}
......@@ -168,7 +168,7 @@ loop1:
case AADDL:
case AADDW:
if(p->from.type != D_CONST || needc(p->link))
if(p->from.type != TYPE_CONST || needc(p->link))
break;
if(p->from.offset == -1){
if(p->as == AADDL)
......@@ -190,7 +190,7 @@ loop1:
case ASUBL:
case ASUBW:
if(p->from.type != D_CONST || needc(p->link))
if(p->from.type != TYPE_CONST || needc(p->link))
break;
if(p->from.offset == -1) {
if(p->as == ASUBL)
......@@ -239,9 +239,7 @@ excise(Flow *r)
if(debug['P'] && debug['v'])
print("%P ===delete===\n", p);
p->as = ANOP;
p->from = zprog.from;
p->to = zprog.to;
nopout(p);
ostats.ndelmov++;
}
......@@ -249,14 +247,7 @@ excise(Flow *r)
int
regtyp(Adr *a)
{
int t;
t = a->type;
if(t >= D_AX && t <= D_DI)
return 1;
if(t >= D_X0 && t <= D_X7)
return 1;
return 0;
return a->type == TYPE_REG && (REG_AX <= a->reg && a->reg <= REG_DI || REG_X0 <= a->reg && a->reg <= REG_X7);
}
// movb elimination.
......@@ -293,7 +284,7 @@ elimshortmov(Graph *g)
p->as = ANOTL;
break;
}
if(regtyp(&p->from) || p->from.type == D_CONST) {
if(regtyp(&p->from) || p->from.type == TYPE_CONST) {
// move or artihmetic into partial register.
// from another register or constant can be movl.
// we don't switch to 32-bit arithmetic if it can
......@@ -398,7 +389,7 @@ subprop(Flow *r0)
if(info.reguse | info.regset)
return 0;
if((info.flags & Move) && (info.flags & (SizeL|SizeQ|SizeF|SizeD)) && p->to.type == v1->type)
if((info.flags & Move) && (info.flags & (SizeL|SizeQ|SizeF|SizeD)) && p->to.type == v1->type && p->to.reg == v1->reg)
goto gotit;
if(copyau(&p->from, v2) || copyau(&p->to, v2))
......@@ -412,7 +403,7 @@ gotit:
copysub(&p->to, v1, v2, 1);
if(debug['P']) {
print("gotit: %D->%D\n%P", v1, v2, r->prog);
if(p->from.type == v2->type)
if(p->from.type == v2->type && p->from.reg == v2->reg)
print(" excise");
print("\n");
}
......@@ -423,9 +414,9 @@ gotit:
if(debug['P'])
print("%P\n", r->prog);
}
t = v1->type;
v1->type = v2->type;
v2->type = t;
t = v1->reg;
v1->reg = v2->reg;
v2->reg = t;
if(debug['P'])
print("%P last\n", r->prog);
return 1;
......@@ -566,11 +557,11 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3;
case ACALL:
if(REGEXT && v->type <= REGEXT && v->type > exregoffset)
if(REGEXT && v->type == TYPE_REG && v->reg <= REGEXT && v->reg > exregoffset)
return 2;
if(REGARG >= 0 && v->type == (uchar)REGARG)
if(REGARG >= 0 && v->type == TYPE_REG && v->reg == (uchar)REGARG)
return 2;
if(v->type == p->from.type)
if(v->type == p->from.type && v->reg == p->from.reg)
return 2;
if(s != nil) {
......@@ -583,7 +574,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3;
case ATEXT:
if(REGARG >= 0 && v->type == (uchar)REGARG)
if(REGARG >= 0 && v->type == TYPE_REG && v->reg == (uchar)REGARG)
return 3;
return 0;
}
......@@ -592,7 +583,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0;
proginfo(&info, p);
if((info.reguse|info.regset) & RtoB(v->type))
if((info.reguse|info.regset) & RtoB(v->reg))
return 2;
if(info.flags & LeftAddr)
......@@ -636,16 +627,16 @@ copyu(Prog *p, Adr *v, Adr *s)
static int
copyas(Adr *a, Adr *v)
{
if(D_AL <= a->type && a->type <= D_BL)
if(REG_AL <= a->reg && a->reg <= REG_BL)
fatal("use of byte register");
if(D_AL <= v->type && v->type <= D_BL)
if(REG_AL <= v->reg && v->reg <= REG_BL)
fatal("use of byte register");
if(a->type != v->type)
if(a->type != v->type || a->name != v->name || a->reg != v->reg)
return 0;
if(regtyp(v))
return 1;
if(v->type == D_AUTO || v->type == D_PARAM)
if(v->type == TYPE_MEM && (v->name == NAME_AUTO || v->name == NAME_PARAM))
if(v->offset == a->offset)
return 1;
return 0;
......@@ -654,11 +645,11 @@ copyas(Adr *a, Adr *v)
int
sameaddr(Addr *a, Addr *v)
{
if(a->type != v->type)
if(a->type != v->type || a->name != v->name || a->reg != v->reg)
return 0;
if(regtyp(v))
return 1;
if(v->type == D_AUTO || v->type == D_PARAM)
if(v->type == TYPE_MEM && (v->name == NAME_AUTO || v->name == NAME_PARAM))
if(v->offset == a->offset)
return 1;
return 0;
......@@ -674,9 +665,9 @@ copyau(Adr *a, Adr *v)
if(copyas(a, v))
return 1;
if(regtyp(v)) {
if(a->type-D_INDIR == v->type)
if(a->type == TYPE_MEM && a->reg == v->reg)
return 1;
if(a->index == v->type)
if(a->index == v->reg)
return 1;
}
return 0;
......@@ -689,28 +680,28 @@ copyau(Adr *a, Adr *v)
static int
copysub(Adr *a, Adr *v, Adr *s, int f)
{
int t;
int reg;
if(copyas(a, v)) {
t = s->type;
if(t >= D_AX && t <= D_DI || t >= D_X0 && t <= D_X7) {
reg = s->reg;
if(reg >= REG_AX && reg <= REG_DI || reg >= REG_X0 && reg <= REG_X7) {
if(f)
a->type = t;
a->reg = reg;
}
return 0;
}
if(regtyp(v)) {
t = v->type;
if(a->type == t+D_INDIR) {
if((s->type == D_BP) && a->index != D_NONE)
reg = v->reg;
if(a->type == TYPE_MEM && a->reg == reg) {
if((s->reg == REG_BP) && a->index != TYPE_NONE)
return 1; /* can't use BP-base with index */
if(f)
a->type = s->type+D_INDIR;
a->reg = s->reg;
// return 0;
}
if(a->index == t) {
if(a->index == reg) {
if(f)
a->index = s->type;
a->index = s->reg;
return 0;
}
return 0;
......@@ -751,10 +742,11 @@ loop:
case 3: // set
if(p->as == p0->as)
if(p->from.type == p0->from.type)
if(p->from.reg == p0->from.reg)
if(p->from.node == p0->from.node)
if(p->from.offset == p0->from.offset)
if(p->from.scale == p0->from.scale)
if(p->from.type == D_FCONST && p->from.u.dval == p0->from.u.dval)
if(p->from.type == TYPE_FCONST && p->from.u.dval == p0->from.u.dval)
if(p->from.index == p0->from.index) {
excise(r);
goto loop;
......@@ -767,13 +759,13 @@ int
smallindir(Addr *a, Addr *reg)
{
return regtyp(reg) &&
a->type == D_INDIR + reg->type &&
a->index == D_NONE &&
a->type == TYPE_MEM && a->reg == reg->reg &&
a->index == REG_NONE &&
0 <= a->offset && a->offset < 4096;
}
int
stackaddr(Addr *a)
{
return regtyp(a) && a->type == D_SP;
return a->type == TYPE_REG && a->reg == REG_SP;
}
......@@ -8,15 +8,15 @@
#include "opt.h"
// Matches real RtoB but can be used in global initializer.
#define RtoB(r) (1<<((r)-D_AX))
#define RtoB(r) (1<<((r)-REG_AX))
enum {
AX = RtoB(D_AX),
BX = RtoB(D_BX),
CX = RtoB(D_CX),
DX = RtoB(D_DX),
DI = RtoB(D_DI),
SI = RtoB(D_SI),
AX = RtoB(REG_AX),
BX = RtoB(REG_BX),
CX = RtoB(REG_CX),
DX = RtoB(REG_DX),
DI = RtoB(REG_DI),
SI = RtoB(REG_SI),
LeftRdwr = LeftRead | LeftWrite,
RightRdwr = RightRead | RightWrite,
......@@ -325,11 +325,11 @@ proginfo(ProgInfo *info, Prog *p)
if(info->flags == 0)
fatal("unknown instruction %P", p);
if((info->flags & ShiftCX) && p->from.type != D_CONST)
if((info->flags & ShiftCX) && p->from.type != TYPE_CONST)
info->reguse |= CX;
if(info->flags & ImulAXDX) {
if(p->to.type == D_NONE) {
if(p->to.type == TYPE_NONE) {
info->reguse |= AX;
info->regset |= AX | DX;
} else {
......@@ -338,12 +338,12 @@ proginfo(ProgInfo *info, Prog *p)
}
// Addressing makes some registers used.
if(p->from.type >= D_INDIR)
info->regindex |= RtoB(p->from.type-D_INDIR);
if(p->from.index != D_NONE)
if(p->from.type == TYPE_MEM && p->from.name == NAME_NONE)
info->regindex |= RtoB(p->from.reg);
if(p->from.index != REG_NONE)
info->regindex |= RtoB(p->from.index);
if(p->to.type >= D_INDIR)
info->regindex |= RtoB(p->to.type-D_INDIR);
if(p->to.index != D_NONE)
if(p->to.type == TYPE_MEM && p->to.name == NAME_NONE)
info->regindex |= RtoB(p->to.reg);
if(p->to.index != REG_NONE)
info->regindex |= RtoB(p->to.index);
}
......@@ -104,7 +104,7 @@ regopt(Prog *firstp)
if(first) {
fmtinstall('Q', Qconv);
exregoffset = D_DI; // no externals
exregoffset = REG_DI; // no externals
first = 0;
}
......@@ -123,7 +123,7 @@ regopt(Prog *firstp)
var[i].node = regnodes[i];
}
regbits = RtoB(D_SP);
regbits = RtoB(REG_SP);
for(z=0; z<BITS; z++) {
externs.b[z] = 0;
params.b[z] = 0;
......@@ -155,7 +155,7 @@ regopt(Prog *firstp)
proginfo(&info, p);
// Avoid making variables for direct-called functions.
if(p->as == ACALL && p->to.type == D_EXTERN)
if(p->as == ACALL && p->to.type == TYPE_MEM && p->to.name == NAME_EXTERN)
continue;
r->use1.b[0] |= info.reguse | info.regindex;
......@@ -401,17 +401,17 @@ 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;
}
if(!use_sse)
for(p=firstp; p!=P; p=p->link) {
if(p->from.type >= D_X0 && p->from.type <= D_X7)
fatal("invalid use of %R with GO386=387: %P", p->from.type, p);
if(p->to.type >= D_X0 && p->to.type <= D_X7)
fatal("invalid use of %R with GO386=387: %P", p->to.type, p);
if(p->from.reg >= REG_X0 && p->from.reg <= REG_X7)
fatal("invalid use of %R with GO386=387: %P", p->from.reg, p);
if(p->to.reg >= REG_X0 && p->to.reg <= REG_X7)
fatal("invalid use of %R with GO386=387: %P", p->to.reg, p);
}
if(debug['R']) {
......@@ -492,7 +492,8 @@ addmove(Reg *r, int bn, int rn, int f)
a = &p1->to;
a->offset = v->offset;
a->etype = v->etype;
a->type = v->name;
a->type = TYPE_MEM;
a->name = v->name;
a->node = v->node;
a->sym = linksym(v->node->sym);
......@@ -525,11 +526,14 @@ addmove(Reg *r, int bn, int rn, int f)
break;
}
p1->from.type = rn;
p1->from.type = TYPE_REG;
p1->from.reg = rn;
p1->from.name = 0;
if(!f) {
p1->from = *a;
*a = zprog.from;
a->type = rn;
a->type = TYPE_REG;
a->reg = rn;
if(v->etype == TUINT8)
p1->as = AMOVB;
if(v->etype == TUINT16)
......@@ -546,18 +550,16 @@ doregbits(int r)
uint32 b;
b = 0;
if(r >= D_INDIR)
r -= D_INDIR;
if(r >= D_AX && r <= D_DI)
if(r >= REG_AX && r <= REG_DI)
b |= RtoB(r);
else
if(r >= D_AL && r <= D_BL)
b |= RtoB(r-D_AL+D_AX);
if(r >= REG_AL && r <= REG_BL)
b |= RtoB(r-REG_AL+REG_AX);
else
if(r >= D_AH && r <= D_BH)
b |= RtoB(r-D_AH+D_AX);
if(r >= REG_AH && r <= REG_BH)
b |= RtoB(r-REG_AH+REG_AX);
else
if(r >= D_X0 && r <= D_X0+7)
if(r >= REG_X0 && r <= REG_X0+7)
b |= FtoB(r);
return b;
}
......@@ -580,7 +582,7 @@ Bits
mkvar(Reg *r, Adr *a)
{
Var *v;
int i, t, n, et, z, w, flag, regu;
int i, n, et, z, w, flag, regu;
int32 o;
Bits bit;
Node *node;
......@@ -588,36 +590,38 @@ mkvar(Reg *r, Adr *a)
/*
* mark registers used
*/
t = a->type;
if(t == D_NONE)
if(a->type == TYPE_NONE)
goto none;
if(r != R)
r->use1.b[0] |= doregbits(a->index);
switch(t) {
switch(a->type) {
default:
regu = doregbits(t);
regu = doregbits(a->reg);
if(regu == 0)
goto none;
bit = zbits;
bit.b[0] = regu;
return bit;
case D_ADDR:
a->type = a->index;
case TYPE_ADDR:
a->type = TYPE_MEM;
bit = mkvar(r, a);
setaddrs(bit);
a->type = t;
a->type = TYPE_ADDR;
ostats.naddr++;
goto none;
case D_EXTERN:
case D_STATIC:
case D_PARAM:
case D_AUTO:
n = t;
break;
case TYPE_MEM:
switch(a->name) {
case NAME_EXTERN:
case NAME_STATIC:
case NAME_PARAM:
case NAME_AUTO:
n = a->name;
break;
}
}
node = a->node;
......@@ -693,10 +697,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];
......@@ -967,13 +971,13 @@ paint1(Reg *r, int bn)
if(r->use1.b[z] & bb) {
change += CREF * r->f.loop;
if(p->as == AFMOVL || p->as == AFMOVW)
if(BtoR(bb) != D_F0)
if(BtoR(bb) != REG_F0)
change = -CINF;
}
if((r->use2.b[z]|r->set.b[z]) & bb) {
change += CREF * r->f.loop;
if(p->as == AFMOVL || p->as == AFMOVW)
if(BtoR(bb) != D_F0)
if(BtoR(bb) != REG_F0)
change = -CINF;
}
}
......@@ -981,7 +985,7 @@ paint1(Reg *r, int bn)
if(STORE(r) & r->regdiff.b[z] & bb) {
change -= CLOAD * r->f.loop;
if(p->as == AFMOVL || p->as == AFMOVW)
if(BtoR(bb) != D_F0)
if(BtoR(bb) != REG_F0)
change = -CINF;
}
......@@ -1139,7 +1143,9 @@ addreg(Adr *a, int rn)
a->sym = nil;
a->node = nil;
a->offset = 0;
a->type = rn;
a->type = TYPE_REG;
a->reg = rn;
a->name = 0;
ostats.ncvtreg++;
}
......@@ -1148,9 +1154,9 @@ uint32
RtoB(int r)
{
if(r < D_AX || r > D_DI)
if(r < REG_AX || r > REG_DI)
return 0;
return 1L << (r-D_AX);
return 1L << (r-REG_AX);
}
int
......@@ -1160,15 +1166,15 @@ BtoR(uint32 b)
b &= 0xffL;
if(b == 0)
return 0;
return bitno(b) + D_AX;
return bitno(b) + REG_AX;
}
uint32
FtoB(int f)
{
if(f < D_X0 || f > D_X7)
if(f < REG_X0 || f > REG_X7)
return 0;
return 1L << (f - D_X0 + 8);
return 1L << (f - REG_X0 + 8);
}
int
......@@ -1177,7 +1183,7 @@ BtoF(uint32 b)
b &= 0xFF00L;
if(b == 0)
return 0;
return bitno(b) - 8 + D_X0;
return bitno(b) - 8 + REG_X0;
}
void
......
......@@ -592,72 +592,58 @@ enum
enum
{
D_AL = 0,
D_CL,
D_DL,
D_BL,
D_AH = 4,
D_CH,
D_DH,
D_BH,
D_AX = 8,
D_CX,
D_DX,
D_BX,
D_SP,
D_BP,
D_SI,
D_DI,
D_F0 = 16,
D_F7 = D_F0 + 7,
D_CS = 24,
D_SS,
D_DS,
D_ES,
D_FS,
D_GS,
D_GDTR, /* global descriptor table register */
D_IDTR, /* interrupt descriptor table register */
D_LDTR, /* local descriptor table register */
D_MSW, /* machine status word */
D_TASK, /* task register */
D_CR = 35,
D_DR = 43,
D_TR = 51,
D_X0 = 59,
D_X1,
D_X2,
D_X3,
D_X4,
D_X5,
D_X6,
D_X7,
REG_NONE = 0,
REG_AL = 0+16,
REG_CL,
REG_DL,
REG_BL,
REG_AH = 4+16,
REG_CH,
REG_DH,
REG_BH,
REG_AX = 8+16,
REG_CX,
REG_DX,
REG_BX,
REG_SP,
REG_BP,
REG_SI,
REG_DI,
REG_F0 = 16+16,
REG_F7 = REG_F0 + 7+16,
REG_CS = 24+16,
REG_SS,
REG_DS,
REG_ES,
REG_FS,
REG_GS,
REG_GDTR, /* global descriptor table register */
REG_IDTR, /* interrupt descriptor table register */
REG_LDTR, /* local descriptor table register */
REG_MSW, /* machine status word */
REG_TASK, /* task register */
REG_CR = 35+16,
REG_DR = 43+16,
REG_TR = 51+16,
REG_X0 = 59+16,
REG_X1,
REG_X2,
REG_X3,
REG_X4,
REG_X5,
REG_X6,
REG_X7,
D_TLS = 67,
D_NONE = 68,
D_BRANCH = 69,
D_EXTERN = 70,
D_STATIC = 71,
D_AUTO = 72,
D_PARAM = 73,
D_CONST = 74,
D_FCONST = 75,
D_SCONST = 76,
D_ADDR = 77,
D_INDIR, /* additive */
D_CONST2 = D_INDIR+D_INDIR,
D_LAST,
REG_TLS = 67+16,
MAXREG = 68+16,
T_TYPE = 1<<0,
T_INDEX = 1<<1,
......@@ -669,10 +655,10 @@ enum
T_GOTYPE = 1<<7,
REGARG = -1,
REGRET = D_AX,
FREGRET = D_F0,
REGSP = D_SP,
REGTMP = D_DI,
REGRET = REG_AX,
FREGRET = REG_F0,
REGSP = REG_SP,
REGTMP = REG_DI,
};
/*
......
This diff is collapsed.
......@@ -108,41 +108,38 @@ Dconv(Fmt *fp)
{
char str[STRINGSZ], s[STRINGSZ];
Addr *a;
int i;
a = va_arg(fp->args, Addr*);
i = a->type;
if(fp->flags & FmtLong) {
if(i == D_CONST2)
sprint(str, "$%lld-%d", a->offset, a->offset2);
else {
// ATEXT dst is not constant
sprint(str, "!!%D", a);
}
goto brk;
}
if(i >= D_INDIR) {
if(a->offset)
sprint(str, "%lld(%R)", a->offset, i-D_INDIR);
else
sprint(str, "(%R)", i-D_INDIR);
goto brk;
}
switch(i) {
switch(a->type) {
default:
if(a->offset)
sprint(str, "$%lld,%R", a->offset, i);
else
sprint(str, "%R", i);
sprint(str, "type=%d", a->type);
break;
case D_NONE:
case TYPE_NONE:
str[0] = 0;
break;
case TYPE_REG:
// TODO(rsc): This special case is for instructions like
// PINSRQ CX,$1,X6
// where the $1 is included in the p->to Addr.
// Move into a new field.
if(a->offset != 0) {
sprint(str, "$%lld,%R", a->offset, a->reg);
break;
}
sprint(str, "%R", a->reg);
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX
// Remove.
if(a->index != REG_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
}
break;
case D_BRANCH:
case TYPE_BRANCH:
if(a->sym != nil)
sprint(str, "%s(SB)", a->sym->name);
else if(bigP != nil && bigP->pcond != nil)
......@@ -153,67 +150,78 @@ Dconv(Fmt *fp)
sprint(str, "%lld(PC)", a->offset);
break;
case D_EXTERN:
sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
break;
case D_STATIC:
sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset);
break;
case D_AUTO:
if(a->sym)
sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
else
sprint(str, "%lld(SP)", a->offset);
break;
case D_PARAM:
if(a->sym)
sprint(str, "%s+%lld(FP)", a->sym->name, a->offset);
else
sprint(str, "%lld(FP)", a->offset);
case TYPE_MEM:
switch(a->name) {
default:
sprint(str, "name=%d", a->name);
break;
case NAME_NONE:
if(a->offset)
sprint(str, "%lld(%R)", a->offset, a->reg);
else
sprint(str, "(%R)", a->reg);
break;
case NAME_EXTERN:
sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
break;
case NAME_STATIC:
sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset);
break;
case NAME_AUTO:
if(a->sym)
sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
else
sprint(str, "%lld(SP)", a->offset);
break;
case NAME_PARAM:
if(a->sym)
sprint(str, "%s+%lld(FP)", a->sym->name, a->offset);
else
sprint(str, "%lld(FP)", a->offset);
break;
}
if(a->index != REG_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
}
break;
case D_CONST:
case TYPE_CONST:
sprint(str, "$%lld", a->offset);
// TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX
// Remove.
if(a->index != REG_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
}
break;
case D_CONST2:
if(!(fp->flags & FmtLong)) {
// D_CONST2 outside of ATEXT should not happen
sprint(str, "!!$%lld-%d", a->offset, a->offset2);
}
case TYPE_TEXTSIZE:
sprint(str, "$%lld-%d", a->offset, a->u.argsize);
break;
case D_FCONST:
case TYPE_FCONST:
sprint(str, "$(%.17g)", a->u.dval);
break;
case D_SCONST:
case TYPE_SCONST:
sprint(str, "$\"%$\"", a->u.sval);
break;
case D_ADDR:
a->type = a->index;
a->index = D_NONE;
case TYPE_ADDR:
a->type = TYPE_MEM;
sprint(str, "$%D", a);
a->index = a->type;
a->type = D_ADDR;
goto conv;
}
brk:
if(a->index != D_NONE) {
sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
strcat(str, s);
a->type = TYPE_ADDR;
break;
}
conv:
return fmtstrcpy(fp, str);
}
static char* regstr[] =
{
"AL", /* [D_AL] */
"AL", /* [REG_AL] */
"CL",
"DL",
"BL",
......@@ -222,7 +230,7 @@ static char* regstr[] =
"DH",
"BH",
"AX", /* [D_AX] */
"AX", /* [REG_AX] */
"CX",
"DX",
"BX",
......@@ -231,7 +239,7 @@ static char* regstr[] =
"SI",
"DI",
"F0", /* [D_F0] */
"F0", /* [REG_F0] */
"F1",
"F2",
"F3",
......@@ -240,20 +248,20 @@ static char* regstr[] =
"F6",
"F7",
"CS", /* [D_CS] */
"CS", /* [REG_CS] */
"SS",
"DS",
"ES",
"FS",
"GS",
"GDTR", /* [D_GDTR] */
"IDTR", /* [D_IDTR] */
"LDTR", /* [D_LDTR] */
"MSW", /* [D_MSW] */
"TASK", /* [D_TASK] */
"GDTR", /* [REG_GDTR] */
"IDTR", /* [REG_IDTR] */
"LDTR", /* [REG_LDTR] */
"MSW", /* [REG_MSW] */
"TASK", /* [REG_TASK] */
"CR0", /* [D_CR] */
"CR0", /* [REG_CR] */
"CR1",
"CR2",
"CR3",
......@@ -262,7 +270,7 @@ static char* regstr[] =
"CR6",
"CR7",
"DR0", /* [D_DR] */
"DR0", /* [REG_DR] */
"DR1",
"DR2",
"DR3",
......@@ -271,7 +279,7 @@ static char* regstr[] =
"DR6",
"DR7",
"TR0", /* [D_TR] */
"TR0", /* [REG_TR] */
"TR1",
"TR2",
"TR3",
......@@ -280,7 +288,7 @@ static char* regstr[] =
"TR6",
"TR7",
"X0", /* [D_X0] */
"X0", /* [REG_X0] */
"X1",
"X2",
"X3",
......@@ -289,8 +297,8 @@ static char* regstr[] =
"X6",
"X7",
"TLS", /* [D_TLS] */
"NONE", /* [D_NONE] */
"TLS", /* [REG_TLS] */
"MAXREG", /* [MAXREG] */
};
static int
......@@ -300,8 +308,10 @@ Rconv(Fmt *fp)
int r;
r = va_arg(fp->args, int);
if(r >= D_AL && r <= D_NONE)
sprint(str, "%s", regstr[r-D_AL]);
if(r == REG_NONE)
return fmtstrcpy(fp, "NONE");
if(r >= REG_AL && r-REG_AL < nelem(regstr))
sprint(str, "%s", regstr[r-REG_AL]);
else
sprint(str, "gok(%d)", r);
......
This diff is collapsed.
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