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
This diff is collapsed.
......@@ -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;
......
This diff is collapsed.
......@@ -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
*/
......
This diff is collapsed.
......@@ -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
......
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