aboutsummaryrefslogtreecommitdiff
path: root/src/liblink
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2015-01-26 15:15:05 -0500
committerRuss Cox <rsc@golang.org>2015-01-30 03:15:58 +0000
commit0d599909e9a38ca925c9eaf916eba3fcbea22203 (patch)
tree487fec66b4ee1466e0180148e51a0f16142301c9 /src/liblink
parent5a2771e286433c64a20fbe5ae6252080418dfa5c (diff)
downloadgo-0d599909e9a38ca925c9eaf916eba3fcbea22203.tar.xz
cmd/5a, cmd/5g, cmd/5l, liblink: update for portable Prog, Addr
Change-Id: I06762d4fb3bb2616087339b6ae1eb5267a39c46a Reviewed-on: https://go-review.googlesource.com/3516 Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/liblink')
-rw-r--r--src/liblink/asm5.c443
-rw-r--r--src/liblink/list5.c103
-rw-r--r--src/liblink/obj5.c300
3 files changed, 401 insertions, 445 deletions
diff --git a/src/liblink/asm5.c b/src/liblink/asm5.c
index 9d4fe40424..35bd458cdf 100644
--- a/src/liblink/asm5.c
+++ b/src/liblink/asm5.c
@@ -355,17 +355,6 @@ static uchar xcmp[C_GOK+1][C_GOK+1];
static Prog zprg = {
.as = AGOK,
.scond = C_SCOND_NONE,
- .reg = NREG,
- .from = {
- .name = D_NONE,
- .type = D_NONE,
- .reg = NREG,
- },
- .to = {
- .name = D_NONE,
- .type = D_NONE,
- .reg = NREG,
- },
};
static LSym *deferreturn;
@@ -441,20 +430,20 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
break;
case AB:
case ABL:
- if(p->to.type != D_OREG) {
+ if(p->to.type != TYPE_MEM) {
if(out != nil)
asmout(ctxt, p, o, out);
} else {
- if(p->to.offset != 0 || size != 4 || p->to.reg >= 16 || p->to.reg < 0)
+ if(p->to.offset != 0 || size != 4 || p->to.reg > REG_R15 || p->to.reg < REG_R0)
ctxt->diag("unsupported instruction: %P", p);
if((p->pc&15) == 12)
p->pc += 4;
if(out != nil) {
- out[0] = ((p->scond&C_SCOND)<<28) | 0x03c0013f | (p->to.reg << 12) | (p->to.reg << 16); // BIC $0xc000000f, Rx
+ out[0] = ((p->scond&C_SCOND)<<28) | 0x03c0013f | ((p->to.reg&15) << 12) | ((p->to.reg&15) << 16); // BIC $0xc000000f, Rx
if(p->as == AB)
- out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff10 | p->to.reg; // BX Rx
+ out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff10 | (p->to.reg&15)<<0; // BX Rx
else // ABL
- out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff30 | p->to.reg; // BLX Rx
+ out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff30 | (p->to.reg&15)<<0; // BLX Rx
}
size = 8;
}
@@ -482,7 +471,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
case AMOVW:
case ASTREX:
case ASTREXD:
- if(p->to.type == D_REG && p->to.reg == 15 && p->from.reg == 13) { // MOVW.W x(R13), PC
+ if(p->to.type == TYPE_REG && p->to.reg == REG_R15 && p->from.reg == REG_R13) { // MOVW.W x(R13), PC
if(out != nil)
asmout(ctxt, p, o, out);
if(size == 4) {
@@ -514,10 +503,10 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
}
}
- if(p->to.type == D_REG && p->to.reg == 15)
+ if(p->to.type == TYPE_REG && p->to.reg == REG_R15)
ctxt->diag("unsupported instruction (move to another register and use indirect jump instead): %P", p);
- if(p->to.type == D_OREG && p->to.reg == 13 && (p->scond & C_WBIT) && size > 4) {
+ if(p->to.type == TYPE_MEM && p->to.reg == REG_R13 && (p->scond & C_WBIT) && size > 4) {
// function prolog with very large frame size: MOVW.W R14,-100004(R13)
// split it into two instructions:
// ADD $-100004, R13
@@ -526,7 +515,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
p->scond &= ~C_WBIT;
*q = *p;
a = &p->to;
- if(p->to.type == D_OREG)
+ if(p->to.type == TYPE_MEM)
a2 = &q->to;
else
a2 = &q->from;
@@ -539,37 +528,37 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
// make p into ADD $X, R13
p->as = AADD;
p->from = *a;
- p->from.reg = NREG;
- p->from.type = D_CONST;
+ p->from.reg = 0;
+ p->from.type = TYPE_CONST;
p->to = zprg.to;
- p->to.type = D_REG;
- p->to.reg = 13;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R13;
// make q into p but load/store from 0(R13)
q->spadj = 0;
*a2 = zprg.from;
- a2->type = D_OREG;
- a2->reg = 13;
+ a2->type = TYPE_MEM;
+ a2->reg = REG_R13;
a2->sym = nil;
a2->offset = 0;
size = oplook(ctxt, p)->size;
break;
}
- if((p->to.type == D_OREG && p->to.reg != 13 && p->to.reg != 9) || // MOVW Rx, X(Ry), y != 13 && y != 9
- (p->from.type == D_OREG && p->from.reg != 13 && p->from.reg != 9)) { // MOVW X(Rx), Ry, x != 13 && x != 9
- if(p->to.type == D_OREG)
+ if((p->to.type == TYPE_MEM && p->to.reg != REG_R13 && p->to.reg != REG_R9) || // MOVW Rx, X(Ry), y != 13 && y != 9
+ (p->from.type == TYPE_MEM && p->from.reg != REG_R13 && p->from.reg != REG_R9)) { // MOVW X(Rx), Ry, x != 13 && x != 9
+ if(p->to.type == TYPE_MEM)
a = &p->to;
else
a = &p->from;
reg = a->reg;
if(size == 4) {
- // if addr.reg == NREG, then it is probably load from x(FP) with small x, no need to modify.
- if(reg == NREG) {
+ // if addr.reg == 0, then it is probably load from x(FP) with small x, no need to modify.
+ if(reg == 0) {
if(out != nil)
asmout(ctxt, p, o, out);
} else {
if(out != nil)
- out[0] = ((p->scond&C_SCOND)<<28) | 0x03c00103 | (reg << 16) | (reg << 12); // BIC $0xc0000000, Rx
+ out[0] = ((p->scond&C_SCOND)<<28) | 0x03c00103 | ((reg&15) << 16) | ((reg&15) << 12); // BIC $0xc0000000, Rx
if((p->pc&15) == 12)
p->pc += 4;
size += 4;
@@ -587,7 +576,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
ctxt->diag("unsupported instruction (.P/.W): %P", p);
q = ctxt->arch->prg();
*q = *p;
- if(p->to.type == D_OREG)
+ if(p->to.type == TYPE_MEM)
a2 = &q->to;
else
a2 = &q->from;
@@ -600,14 +589,14 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
// make p into MOVW $X(R), R11
p->as = AMOVW;
p->from = *a;
- p->from.type = D_CONST;
+ p->from.type = TYPE_CONST;
p->to = zprg.to;
- p->to.type = D_REG;
- p->to.reg = 11;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R11;
// make q into p but load/store from 0(R11)
*a2 = zprg.from;
- a2->type = D_OREG;
- a2->reg = 11;
+ a2->type = TYPE_MEM;
+ a2->reg = REG_R11;
a2->sym = nil;
a2->offset = 0;
size = oplook(ctxt, p)->size;
@@ -619,12 +608,12 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
}
// destination register specific
- if(p->to.type == D_REG) {
+ if(p->to.type == TYPE_REG) {
switch(p->to.reg) {
- case 9:
+ case REG_R9:
ctxt->diag("invalid instruction, cannot write to R9: %P", p);
break;
- case 13:
+ case REG_R13:
if(out != nil)
out[size/4] = 0xe3cdd103; // BIC $0xc0000000, R13
if(((p->pc+size) & 15) == 0)
@@ -707,7 +696,7 @@ span5(Link *ctxt, LSym *cursym)
flushpool(ctxt, p, 0, 0);
break;
}
- if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == C_SCOND_NONE)
+ if(p->as==AMOVW && p->to.type==TYPE_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == C_SCOND_NONE)
flushpool(ctxt, p, 0, 0);
c += m;
}
@@ -742,14 +731,14 @@ span5(Link *ctxt, LSym *cursym)
q->link = p->link;
p->link = q;
q->as = AB;
- 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 = AB;
- q->to.type = D_BRANCH;
+ q->to.type = TYPE_BRANCH;
q->pcond = q->link->link;
bflag = 1;
}
@@ -865,7 +854,7 @@ flushpool(Link *ctxt, Prog *p, int skip, int force)
if(0 && skip==1)print("note: flush literal pool at %llux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start);
q = ctxt->arch->prg();
q->as = AB;
- q->to.type = D_BRANCH;
+ q->to.type = TYPE_BRANCH;
q->pcond = p->link;
q->link = ctxt->blitrl;
q->lineno = p->lineno;
@@ -931,7 +920,7 @@ addpool(Link *ctxt, Prog *p, Addr *a)
case C_SAUTO:
case C_LAUTO:
case C_LACON:
- t.to.type = D_CONST;
+ t.to.type = TYPE_CONST;
t.to.offset = ctxt->instoffset;
break;
}
@@ -1038,31 +1027,33 @@ aclass(Link *ctxt, Addr *a)
int t;
switch(a->type) {
- case D_NONE:
+ case TYPE_NONE:
return C_NONE;
- case D_REG:
- return C_REG;
+ case TYPE_REG:
+ if(REG_R0 <= a->reg && a->reg <= REG_R15)
+ return C_REG;
+ if(REG_F0 <= a->reg && a->reg <= REG_F15)
+ return C_FREG;
+ if(a->reg == REG_FPSR || a->reg == REG_FPCR)
+ return C_FCR;
+ if(a->reg == REG_CPSR || a->reg == REG_SPSR)
+ return C_PSR;
+ return C_GOK;
- case D_REGREG:
+ case TYPE_REGREG:
return C_REGREG;
- case D_REGREG2:
+ case TYPE_REGREG2:
return C_REGREG2;
- case D_SHIFT:
+ case TYPE_SHIFT:
return C_SHIFT;
- case D_FREG:
- return C_FREG;
-
- case D_FPCR:
- return C_FCR;
-
- case D_OREG:
+ case TYPE_MEM:
switch(a->name) {
- case D_EXTERN:
- case D_STATIC:
+ case NAME_EXTERN:
+ case NAME_STATIC:
if(a->sym == 0 || a->sym->name == 0) {
print("null sym external\n");
return C_GOK;
@@ -1070,7 +1061,7 @@ aclass(Link *ctxt, Addr *a)
ctxt->instoffset = 0; // s.b. unused but just in case
return C_ADDR;
- case D_AUTO:
+ case NAME_AUTO:
ctxt->instoffset = ctxt->autosize + a->offset;
t = immaddr(ctxt->instoffset);
if(t){
@@ -1085,7 +1076,7 @@ aclass(Link *ctxt, Addr *a)
}
return C_LAUTO;
- case D_PARAM:
+ case NAME_PARAM:
ctxt->instoffset = ctxt->autosize + a->offset + 4L;
t = immaddr(ctxt->instoffset);
if(t){
@@ -1099,7 +1090,7 @@ aclass(Link *ctxt, Addr *a)
return C_SAUTO;
}
return C_LAUTO;
- case D_NONE:
+ case TYPE_NONE:
ctxt->instoffset = a->offset;
t = immaddr(ctxt->instoffset);
if(t) {
@@ -1124,32 +1115,20 @@ aclass(Link *ctxt, Addr *a)
}
return C_GOK;
- case D_PSR:
- return C_PSR;
-
- case D_OCONST:
- switch(a->name) {
- case D_EXTERN:
- case D_STATIC:
- ctxt->instoffset = 0; // s.b. unused but just in case
- return C_ADDR;
- }
- return C_GOK;
-
- case D_FCONST:
+ case TYPE_FCONST:
if(chipzero5(ctxt, a->u.dval) >= 0)
return C_ZFCON;
if(chipfloat5(ctxt, a->u.dval) >= 0)
return C_SFCON;
return C_LFCON;
- case D_CONST:
- case D_CONST2:
+ case TYPE_CONST:
+ case TYPE_TEXTSIZE:
switch(a->name) {
- case D_NONE:
+ case TYPE_NONE:
ctxt->instoffset = a->offset;
- if(a->reg != NREG)
+ if(a->reg != 0)
return aconsize(ctxt);
t = immrot(ctxt->instoffset);
@@ -1160,25 +1139,25 @@ aclass(Link *ctxt, Addr *a)
return C_NCON;
return C_LCON;
- case D_EXTERN:
- case D_STATIC:
+ case NAME_EXTERN:
+ case NAME_STATIC:
s = a->sym;
if(s == nil)
break;
ctxt->instoffset = 0; // s.b. unused but just in case
return C_LCONADDR;
- case D_AUTO:
+ case NAME_AUTO:
ctxt->instoffset = ctxt->autosize + a->offset;
return aconsize(ctxt);
- case D_PARAM:
+ case NAME_PARAM:
ctxt->instoffset = ctxt->autosize + a->offset + 4L;
return aconsize(ctxt);
}
return C_GOK;
- case D_BRANCH:
+ case TYPE_BRANCH:
return C_SBRA;
}
return C_GOK;
@@ -1224,7 +1203,7 @@ oplook(Link *ctxt, Prog *p)
}
a3--;
a2 = C_NONE;
- if(p->reg != NREG)
+ if(p->reg != 0)
a2 = C_REG;
r = p->as;
o = oprange[r].start;
@@ -1535,14 +1514,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
rf = p->from.reg;
rt = p->to.reg;
r = p->reg;
- if(p->to.type == D_NONE)
+ if(p->to.type == TYPE_NONE)
rt = 0;
if(p->as == AMOVB || p->as == AMOVH || p->as == AMOVW || p->as == AMVN)
r = 0;
else
- if(r == NREG)
+ if(r == 0)
r = rt;
- o1 |= rf | (r<<16) | (rt<<12);
+ o1 |= ((rf&15)<<0) | ((r&15)<<16) | ((rt&15)<<12);
break;
case 2: /* movbu $I,[R],R */
@@ -1551,13 +1530,13 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= immrot(ctxt->instoffset);
rt = p->to.reg;
r = p->reg;
- if(p->to.type == D_NONE)
+ if(p->to.type == TYPE_NONE)
rt = 0;
if(p->as == AMOVW || p->as == AMVN)
r = 0;
- else if(r == NREG)
+ else if(r == 0)
r = rt;
- o1 |= (r<<16) | (rt<<12);
+ o1 |= ((r&15)<<16) | ((rt&15)<<12);
break;
case 3: /* add R<<[IR],[R],R */
@@ -1569,10 +1548,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 = oprrr(ctxt, AADD, p->scond);
o1 |= immrot(ctxt->instoffset);
r = p->from.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
- o1 |= r << 16;
- o1 |= p->to.reg << 12;
+ o1 |= (r&15) << 16;
+ o1 |= (p->to.reg&15) << 12;
break;
case 5: /* bra s */
@@ -1597,8 +1576,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
aclass(ctxt, &p->to);
o1 = oprrr(ctxt, AADD, p->scond);
o1 |= immrot(ctxt->instoffset);
- o1 |= p->to.reg << 16;
- o1 |= REGPC << 12;
+ o1 |= (p->to.reg&15) << 16;
+ o1 |= (REGPC&15) << 12;
break;
case 7: /* bl (R) -> blx R */
@@ -1606,7 +1585,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0)
ctxt->diag("%P: doesn't support BL offset(REG) where offset != 0", p);
o1 = oprrr(ctxt, ABL, p->scond);
- o1 |= p->to.reg;
+ o1 |= (p->to.reg&15) << 0;
rel = addrel(ctxt->cursym);
rel->off = ctxt->pc;
rel->siz = 0;
@@ -1617,26 +1596,26 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
aclass(ctxt, &p->from);
o1 = oprrr(ctxt, p->as, p->scond);
r = p->reg;
- if(r == NREG)
+ if(r == 0)
r = p->to.reg;
- o1 |= r;
+ o1 |= (r&15) << 0;
o1 |= (ctxt->instoffset&31) << 7;
- o1 |= p->to.reg << 12;
+ o1 |= (p->to.reg&15) << 12;
break;
case 9: /* sll R,[R],R -> mov (R<<R),R */
o1 = oprrr(ctxt, p->as, p->scond);
r = p->reg;
- if(r == NREG)
+ if(r == 0)
r = p->to.reg;
- o1 |= r;
- o1 |= (p->from.reg << 8) | (1<<4);
- o1 |= p->to.reg << 12;
+ o1 |= (r&15) << 0;
+ o1 |= ((p->from.reg&15) << 8) | (1<<4);
+ o1 |= (p->to.reg&15) << 12;
break;
case 10: /* swi [$con] */
o1 = oprrr(ctxt, p->as, p->scond);
- if(p->to.type != D_NONE) {
+ if(p->to.type != TYPE_NONE) {
aclass(ctxt, &p->to);
o1 |= ctxt->instoffset & 0xffffff;
}
@@ -1676,7 +1655,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 12: /* movw $lcon, reg */
o1 = omvl(ctxt, p, &p->from, p->to.reg);
if(o->flag & LPCREL) {
- o2 = oprrr(ctxt, AADD, p->scond) | p->to.reg | REGPC << 16 | p->to.reg << 12;
+ o2 = oprrr(ctxt, AADD, p->scond) | (p->to.reg&15) << 0 | (REGPC&15) << 16 | (p->to.reg&15) << 12;
}
break;
@@ -1685,15 +1664,15 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1)
break;
o2 = oprrr(ctxt, p->as, p->scond);
- o2 |= REGTMP;
+ o2 |= (REGTMP&15);
r = p->reg;
if(p->as == AMOVW || p->as == AMVN)
r = 0;
- else if(r == NREG)
+ else if(r == 0)
r = p->to.reg;
- o2 |= r << 16;
- if(p->to.type != D_NONE)
- o2 |= p->to.reg << 12;
+ o2 |= (r&15) << 16;
+ if(p->to.type != TYPE_NONE)
+ o2 |= (p->to.reg&15) << 12;
break;
case 14: /* movb/movbu/movh/movhu R,R */
@@ -1705,8 +1684,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = oprrr(ctxt, ASRA, p->scond);
r = p->to.reg;
- o1 |= (p->from.reg)|(r<<12);
- o2 |= (r)|(r<<12);
+ o1 |= ((p->from.reg&15)<<0)|((r&15)<<12);
+ o2 |= (r&15)|((r&15)<<12);
if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU) {
o1 |= (24<<7);
o2 |= (24<<7);
@@ -1721,18 +1700,18 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
rf = p->from.reg;
rt = p->to.reg;
r = p->reg;
- if(r == NREG)
+ if(r == 0)
r = rt;
if(rt == r) {
r = rf;
rf = rt;
}
if(0)
- if(rt == r || rf == REGPC || r == REGPC || rt == REGPC) {
+ if(rt == r || rf == (REGPC&15) || r == (REGPC&15) || rt == (REGPC&15)) {
ctxt->diag("bad registers in MUL");
prasm(p);
}
- o1 |= (rf<<8) | r | (rt<<16);
+ o1 |= ((rf&15)<<8) | ((r&15)<<0) | ((rt&15)<<16);
break;
@@ -1747,13 +1726,13 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
rt = p->to.reg;
rt2 = p->to.offset;
r = p->reg;
- o1 |= (rf<<8) | r | (rt<<16) | (rt2<<12);
+ o1 |= ((rf&15)<<8) | ((r&15)<<0) | ((rt&15)<<16) | ((rt2&15)<<12);
break;
case 20: /* mov/movb/movbu R,O(R) */
aclass(ctxt, &p->to);
r = p->to.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
o1 = osr(ctxt, p->as, p->from.reg, ctxt->instoffset, r, p->scond);
break;
@@ -1761,7 +1740,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 21: /* mov/movbu O(R),R -> lr */
aclass(ctxt, &p->from);
r = p->from.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
o1 = olr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond);
if(p->as != AMOVW)
@@ -1773,9 +1752,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1)
break;
r = p->to.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
- o2 = osrr(ctxt, p->from.reg, REGTMP,r, p->scond);
+ o2 = osrr(ctxt, p->from.reg, REGTMP&15, r, p->scond);
if(p->as != AMOVW)
o2 |= 1<<22;
break;
@@ -1785,9 +1764,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1)
break;
r = p->from.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
- o2 = olrr(ctxt, REGTMP,r, p->to.reg, p->scond);
+ o2 = olrr(ctxt, REGTMP&15, r, p->to.reg, p->scond);
if(p->as == AMOVBU || p->as == AMOVBS || p->as == AMOVB)
o2 |= 1<<22;
break;
@@ -1798,20 +1777,20 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
break;
o2 = oprrr(ctxt, AADD, p->scond);
- o2 |= REGTMP;
+ o2 |= (REGTMP&15);
r = p->from.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
- o2 |= r << 16;
- if(p->to.type != D_NONE)
- o2 |= p->to.reg << 12;
+ o2 |= (r&15) << 16;
+ if(p->to.type != TYPE_NONE)
+ o2 |= (p->to.reg&15) << 12;
break;
case 35: /* mov PSR,R */
o1 = (2<<23) | (0xf<<16) | (0<<0);
o1 |= (p->scond & C_SCOND) << 28;
o1 |= (p->from.reg & 1) << 22;
- o1 |= p->to.reg << 12;
+ o1 |= (p->to.reg&15) << 12;
break;
case 36: /* mov R,PSR */
@@ -1820,7 +1799,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 ^= 0x010 << 12;
o1 |= (p->scond & C_SCOND) << 28;
o1 |= (p->to.reg & 1) << 22;
- o1 |= p->from.reg << 0;
+ o1 |= (p->from.reg&15) << 0;
break;
case 37: /* mov $con,PSR */
@@ -1831,7 +1810,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= (p->scond & C_SCOND) << 28;
o1 |= immrot(ctxt->instoffset);
o1 |= (p->to.reg & 1) << 22;
- o1 |= p->from.reg << 0;
+ o1 |= (p->from.reg&15) << 0;
break;
case 38:
@@ -1840,14 +1819,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 38: /* movm $con,oreg -> stm */
o1 = (0x4 << 25);
o1 |= p->from.offset & 0xffff;
- o1 |= p->to.reg << 16;
+ o1 |= (p->to.reg&15) << 16;
aclass(ctxt, &p->to);
break;
case 39: /* movm oreg,$con -> ldm */
o1 = (0x4 << 25) | (1 << 20);
o1 |= p->to.offset & 0xffff;
- o1 |= p->from.reg << 16;
+ o1 |= (p->from.reg&15) << 16;
aclass(ctxt, &p->from);
break;
}
@@ -1871,9 +1850,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 = (0x2<<23) | (0x9<<4);
if(p->as != ASWPW)
o1 |= 1 << 22;
- o1 |= p->from.reg << 16;
- o1 |= p->reg << 0;
- o1 |= p->to.reg << 12;
+ o1 |= (p->from.reg&15) << 16;
+ o1 |= (p->reg&15) << 0;
+ o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28;
break;
@@ -1884,7 +1863,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 50: /* floating point store */
v = regoff(ctxt, &p->to);
r = p->to.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
o1 = ofsr(ctxt, p->as, p->from.reg, v, r, p->scond, p);
break;
@@ -1892,7 +1871,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 51: /* floating point load */
v = regoff(ctxt, &p->from);
r = p->from.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
o1 = ofsr(ctxt, p->as, p->to.reg, v, r, p->scond, p) | (1<<20);
break;
@@ -1902,9 +1881,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1)
break;
r = p->to.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
- o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;
+ o2 = oprrr(ctxt, AADD, p->scond) | ((REGTMP&15) << 12) | ((REGTMP&15) << 16) | ((r&15) << 0);
o3 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p);
break;
@@ -1913,10 +1892,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1)
break;
r = p->from.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
- o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;
- o3 = ofsr(ctxt, p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);
+ o2 = oprrr(ctxt, AADD, p->scond) | ((REGTMP&15) << 12) | ((REGTMP&15) << 16) | ((r&15) << 0);
+ o3 = ofsr(ctxt, p->as, p->to.reg, 0, (REGTMP&15), p->scond, p) | (1<<20);
break;
case 54: /* floating point arith */
@@ -1924,38 +1903,38 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
rf = p->from.reg;
rt = p->to.reg;
r = p->reg;
- if(r == NREG) {
+ if(r == 0) {
r = rt;
if(p->as == AMOVF || p->as == AMOVD || p->as == AMOVFD || p->as == AMOVDF ||
p->as == ASQRTF || p->as == ASQRTD || p->as == AABSF || p->as == AABSD)
r = 0;
}
- o1 |= rf | (r<<16) | (rt<<12);
+ o1 |= ((rf&15)<<0) | ((r&15)<<16) | ((rt&15)<<12);
break;
case 56: /* move to FP[CS]R */
o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
- o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12);
+ o1 |= (((p->to.reg&1)+1)<<21) | ((p->from.reg&15) << 12);
break;
case 57: /* move from FP[CS]R */
o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
- o1 |= ((p->from.reg+1)<<21) | (p->to.reg<<12) | (1<<20);
+ o1 |= (((p->from.reg&1)+1)<<21) | ((p->to.reg&15)<<12) | (1<<20);
break;
case 58: /* movbu R,R */
o1 = oprrr(ctxt, AAND, p->scond);
o1 |= immrot(0xff);
rt = p->to.reg;
r = p->from.reg;
- if(p->to.type == D_NONE)
+ if(p->to.type == TYPE_NONE)
rt = 0;
- if(r == NREG)
+ if(r == 0)
r = rt;
- o1 |= (r<<16) | (rt<<12);
+ o1 |= ((r&15)<<16) | ((rt&15)<<12);
break;
case 59: /* movw/bu R<<I(R),R -> ldr indexed */
- if(p->from.reg == NREG) {
+ if(p->from.reg == 0) {
if(p->as != AMOVW)
ctxt->diag("byte MOV from shifter operand");
o1 = mov(ctxt, p);
@@ -1969,7 +1948,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
break;
case 60: /* movb R(R),R -> ldrsb indexed */
- if(p->from.reg == NREG) {
+ if(p->from.reg == 0) {
ctxt->diag("byte MOV from shifter operand");
o1 = mov(ctxt, p);
break;
@@ -1981,7 +1960,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
break;
case 61: /* movw/b/bu R,R<<[IR](R) -> str indexed */
- if(p->to.reg == NREG)
+ if(p->to.reg == 0)
ctxt->diag("MOV to shifter operand");
o1 = osrr(ctxt, p->from.reg, p->to.offset, p->to.reg, p->scond);
if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU)
@@ -1990,12 +1969,12 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 62: /* case R -> movw R<<2(PC),PC */
if(o->flag & LPCREL) {
- o1 = oprrr(ctxt, AADD, p->scond) | immrot(1) | p->from.reg << 16 | REGTMP << 12;
- o2 = olrr(ctxt, REGTMP, REGPC, REGTMP, p->scond);
+ o1 = oprrr(ctxt, AADD, p->scond) | immrot(1) | (p->from.reg&15) << 16 | (REGTMP&15) << 12;
+ o2 = olrr(ctxt, REGTMP&15, REGPC, REGTMP, p->scond);
o2 |= 2<<7;
- o3 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGPC << 12;
+ o3 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGPC&15) << 12;
} else {
- o1 = olrr(ctxt, p->from.reg, REGPC, REGPC, p->scond);
+ o1 = olrr(ctxt, p->from.reg&15, REGPC, REGPC, p->scond);
o1 |= 2<<7;
}
break;
@@ -2029,7 +2008,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = osr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond);
if(o->flag & LPCREL) {
o3 = o2;
- o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+ o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
}
break;
@@ -2042,7 +2021,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 |= 1<<22;
if(o->flag & LPCREL) {
o3 = o2;
- o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+ o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
}
break;
@@ -2053,7 +2032,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p);
if(o->flag & LPCREL) {
o3 = o2;
- o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+ o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
}
break;
@@ -2061,10 +2040,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o1 = omvl(ctxt, p, &p->from, REGTMP);
if(!o1)
break;
- o2 = ofsr(ctxt, p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);
+ o2 = ofsr(ctxt, p->as, p->to.reg, 0, (REGTMP&15), p->scond, p) | (1<<20);
if(o->flag & LPCREL) {
o3 = o2;
- o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+ o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
}
break;
@@ -2072,14 +2051,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
case 70: /* movh/movhu R,O(R) -> strh */
aclass(ctxt, &p->to);
r = p->to.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
o1 = oshr(ctxt, p->from.reg, ctxt->instoffset, r, p->scond);
break;
case 71: /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */
aclass(ctxt, &p->from);
r = p->from.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
o1 = olhr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond);
if(p->as == AMOVB || p->as == AMOVBS)
@@ -2092,18 +2071,18 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(!o1)
break;
r = p->to.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
- o2 = oshrr(ctxt, p->from.reg, REGTMP,r, p->scond);
+ o2 = oshrr(ctxt, p->from.reg, REGTMP&15, r, p->scond);
break;
case 73: /* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */
o1 = omvl(ctxt, p, &p->from, REGTMP);
if(!o1)
break;
r = p->from.reg;
- if(r == NREG)
+ if(r == 0)
r = o->param;
- o2 = olhrr(ctxt, REGTMP, r, p->to.reg, p->scond);
+ o2 = olhrr(ctxt, REGTMP&15, r, p->to.reg, p->scond);
if(p->as == AMOVB || p->as == AMOVBS)
o2 ^= (1<<5)|(1<<6);
else if(p->as == AMOVH || p->as == AMOVHS)
@@ -2117,16 +2096,16 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0)
ctxt->diag("non-zero offset in ABX");
/*
- o1 = oprrr(ctxt, AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR
- o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg; // BX R
+ o1 = oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12); // mov PC, LR
+ o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | ((p->to.reg&15) << 0); // BX R
*/
// p->to.reg may be REGLINK
o1 = oprrr(ctxt, AADD, p->scond);
o1 |= immrot(ctxt->instoffset);
- o1 |= p->to.reg << 16;
- o1 |= REGTMP << 12;
- o2 = oprrr(ctxt, AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR
- o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // BX Rtmp
+ o1 |= (p->to.reg&15) << 16;
+ o1 |= (REGTMP&15) << 12;
+ o2 = oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12); // mov PC, LR
+ o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | (REGTMP&15); // BX Rtmp
break;
case 76: /* bx O(R) when returning from fn*/
ctxt->diag("ABXRET");
@@ -2136,8 +2115,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0)
ctxt->diag("offset must be zero in LDREX");
o1 = (0x19<<20) | (0xf9f);
- o1 |= p->from.reg << 16;
- o1 |= p->to.reg << 12;
+ o1 |= (p->from.reg&15) << 16;
+ o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28;
break;
case 78: /* strex reg,oreg,reg */
@@ -2145,9 +2124,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0)
ctxt->diag("offset must be zero in STREX");
o1 = (0x18<<20) | (0xf90);
- o1 |= p->from.reg << 16;
- o1 |= p->reg << 0;
- o1 |= p->to.reg << 12;
+ o1 |= (p->from.reg&15) << 16;
+ o1 |= (p->reg&15) << 0;
+ o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28;
break;
case 80: /* fmov zfcon,freg */
@@ -2159,88 +2138,88 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = oprrr(ctxt, ASUBF, p->scond);
}
v = 0x70; // 1.0
- r = p->to.reg;
+ r = (p->to.reg&15) << 0;
// movf $1.0, r
o1 |= (p->scond & C_SCOND) << 28;
- o1 |= r << 12;
+ o1 |= (r&15) << 12;
o1 |= (v&0xf) << 0;
o1 |= (v&0xf0) << 12;
// subf r,r,r
- o2 |= r | (r<<16) | (r<<12);
+ o2 |= ((r&15)<<0) | ((r&15)<<16) | ((r&15)<<12);
break;
case 81: /* fmov sfcon,freg */
o1 = 0x0eb00a00; // VMOV imm 32
if(p->as == AMOVD)
o1 = 0xeeb00b00; // VMOV imm 64
o1 |= (p->scond & C_SCOND) << 28;
- o1 |= p->to.reg << 12;
+ o1 |= (p->to.reg&15) << 12;
v = chipfloat5(ctxt, p->from.u.dval);
o1 |= (v&0xf) << 0;
o1 |= (v&0xf0) << 12;
break;
case 82: /* fcmp freg,freg, */
o1 = oprrr(ctxt, p->as, p->scond);
- o1 |= (p->reg<<12) | (p->from.reg<<0);
+ o1 |= ((p->reg&15)<<12) | ((p->from.reg&15)<<0);
o2 = 0x0ef1fa10; // VMRS R15
o2 |= (p->scond & C_SCOND) << 28;
break;
case 83: /* fcmp freg,, */
o1 = oprrr(ctxt, p->as, p->scond);
- o1 |= (p->from.reg<<12) | (1<<16);
+ o1 |= ((p->from.reg&15)<<12) | (1<<16);
o2 = 0x0ef1fa10; // VMRS R15
o2 |= (p->scond & C_SCOND) << 28;
break;
case 84: /* movfw freg,freg - truncate float-to-fix */
o1 = oprrr(ctxt, p->as, p->scond);
- o1 |= (p->from.reg<<0);
- o1 |= (p->to.reg<<12);
+ o1 |= ((p->from.reg&15)<<0);
+ o1 |= ((p->to.reg&15)<<12);
break;
case 85: /* movwf freg,freg - fix-to-float */
o1 = oprrr(ctxt, p->as, p->scond);
- o1 |= (p->from.reg<<0);
- o1 |= (p->to.reg<<12);
+ o1 |= ((p->from.reg&15)<<0);
+ o1 |= ((p->to.reg&15)<<12);
break;
case 86: /* movfw freg,reg - truncate float-to-fix */
// macro for movfw freg,FTMP; movw FTMP,reg
o1 = oprrr(ctxt, p->as, p->scond);
- o1 |= (p->from.reg<<0);
- o1 |= (FREGTMP<<12);
+ o1 |= ((p->from.reg&15)<<0);
+ o1 |= ((FREGTMP&15)<<12);
o2 = oprrr(ctxt, AMOVFW+AEND, p->scond);
- o2 |= (FREGTMP<<16);
- o2 |= (p->to.reg<<12);
+ o2 |= ((FREGTMP&15)<<16);
+ o2 |= ((p->to.reg&15)<<12);
break;
case 87: /* movwf reg,freg - fix-to-float */
// macro for movw reg,FTMP; movwf FTMP,freg
o1 = oprrr(ctxt, AMOVWF+AEND, p->scond);
- o1 |= (p->from.reg<<12);
- o1 |= (FREGTMP<<16);
+ o1 |= ((p->from.reg&15)<<12);
+ o1 |= ((FREGTMP&15)<<16);
o2 = oprrr(ctxt, p->as, p->scond);
- o2 |= (FREGTMP<<0);
- o2 |= (p->to.reg<<12);
+ o2 |= ((FREGTMP&15)<<0);
+ o2 |= ((p->to.reg&15)<<12);
break;
case 88: /* movw reg,freg */
o1 = oprrr(ctxt, AMOVWF+AEND, p->scond);
- o1 |= (p->from.reg<<12);
- o1 |= (p->to.reg<<16);
+ o1 |= ((p->from.reg&15)<<12);
+ o1 |= ((p->to.reg&15)<<16);
break;
case 89: /* movw freg,reg */
o1 = oprrr(ctxt, AMOVFW+AEND, p->scond);
- o1 |= (p->from.reg<<16);
- o1 |= (p->to.reg<<12);
+ o1 |= ((p->from.reg&15)<<16);
+ o1 |= ((p->to.reg&15)<<12);
break;
case 90: /* tst reg */
o1 = oprrr(ctxt, ACMP+AEND, p->scond);
- o1 |= p->from.reg<<16;
+ o1 |= (p->from.reg&15)<<16;
break;
case 91: /* ldrexd oreg,reg */
aclass(ctxt, &p->from);
if(ctxt->instoffset != 0)
ctxt->diag("offset must be zero in LDREX");
o1 = (0x1b<<20) | (0xf9f);
- o1 |= p->from.reg << 16;
- o1 |= p->to.reg << 12;
+ o1 |= (p->from.reg&15) << 16;
+ o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28;
break;
case 92: /* strexd reg,oreg,reg */
@@ -2248,9 +2227,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
if(ctxt->instoffset != 0)
ctxt->diag("offset must be zero in STREX");
o1 = (0x1a<<20) | (0xf90);
- o1 |= p->from.reg << 16;
- o1 |= p->reg << 0;
- o1 |= p->to.reg << 12;
+ o1 |= (p->from.reg&15) << 16;
+ o1 |= (p->reg&15) << 0;
+ o1 |= (p->to.reg&15) << 12;
o1 |= (p->scond & C_SCOND) << 28;
break;
case 93: /* movb/movh/movhu addr,R -> ldrsb/ldrsh/ldrh */
@@ -2264,7 +2243,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 ^= (1<<6);
if(o->flag & LPCREL) {
o3 = o2;
- o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+ o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
}
break;
case 94: /* movh/movhu R,addr -> strh */
@@ -2274,12 +2253,12 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
o2 = oshr(ctxt, p->from.reg, 0, REGTMP, p->scond);
if(o->flag & LPCREL) {
o3 = o2;
- o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+ o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
}
break;
case 95: /* PLD off(reg) */
o1 = 0xf5d0f000;
- o1 |= p->from.reg << 16;
+ o1 |= (p->from.reg&15) << 16;
if(p->from.offset < 0) {
o1 &= ~(1 << 23);
o1 |= (-p->from.offset) & 0xfff;
@@ -2296,21 +2275,21 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
break;
case 97: /* CLZ Rm, Rd */
o1 = oprrr(ctxt, p->as, p->scond);
- o1 |= p->to.reg << 12;
- o1 |= p->from.reg;
+ o1 |= (p->to.reg&15) << 12;
+ o1 |= (p->from.reg&15) << 0;
break;
case 98: /* MULW{T,B} Rs, Rm, Rd */
o1 = oprrr(ctxt, p->as, p->scond);
- o1 |= p->to.reg << 16;
- o1 |= p->from.reg << 8;
- o1 |= p->reg;
+ o1 |= (p->to.reg&15) << 16;
+ o1 |= (p->from.reg&15) << 8;
+ o1 |= (p->reg&15) << 0;
break;
case 99: /* MULAW{T,B} Rs, Rm, Rn, Rd */
o1 = oprrr(ctxt, p->as, p->scond);
- o1 |= p->to.reg << 12;
- o1 |= p->from.reg << 8;
- o1 |= p->reg;
- o1 |= p->to.offset << 16;
+ o1 |= (p->to.reg&15) << 12;
+ o1 |= (p->from.reg&15) << 8;
+ o1 |= (p->reg&15) << 0;
+ o1 |= (p->to.offset&15) << 16;
break;
case 100:
// DATABUNDLE: BKPT $0x5be0, signify the start of NaCl data bundle;
@@ -2339,14 +2318,14 @@ mov(Link *ctxt, Prog *p)
o1 = oprrr(ctxt, p->as, p->scond);
o1 |= p->from.offset;
rt = p->to.reg;
- r = p->reg;
- if(p->to.type == D_NONE)
+ if(p->to.type == TYPE_NONE)
rt = 0;
+ r = p->reg;
if(p->as == AMOVW || p->as == AMVN)
r = 0;
- else if(r == NREG)
+ else if(r == 0)
r = rt;
- o1 |= (r<<16) | (rt<<12);
+ o1 |= ((r&15)<<16) | ((rt&15)<<12);
return o1;
}
@@ -2523,8 +2502,8 @@ olr(Link *ctxt, int32 v, int b, int r, int sc)
if(v >= (1<<12) || v < 0)
ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp);
o |= v;
- o |= b << 16;
- o |= r << 12;
+ o |= (b&15) << 16;
+ o |= (r&15) << 12;
return o;
}
@@ -2548,8 +2527,8 @@ olhr(Link *ctxt, int32 v, int b, int r, int sc)
if(v >= (1<<8) || v < 0)
ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp);
o |= (v&0xf)|((v>>4)<<8)|(1<<22);
- o |= b << 16;
- o |= r << 12;
+ o |= (b&15) << 16;
+ o |= (r&15) << 12;
return o;
}
@@ -2623,8 +2602,8 @@ ofsr(Link *ctxt, int a, int r, int32 v, int b, int sc, Prog *p)
if(v >= (1<<10) || v < 0)
ctxt->diag("literal span too large: %d\n%P", v, p);
o |= (v>>2) & 0xFF;
- o |= b << 16;
- o |= r << 12;
+ o |= (b&15) << 16;
+ o |= (r&15) << 12;
switch(a) {
default:
@@ -2652,7 +2631,7 @@ omvl(Link *ctxt, Prog *p, Addr *a, int dr)
}
o1 = oprrr(ctxt, AMVN, p->scond&C_SCOND);
o1 |= v;
- o1 |= dr << 12;
+ o1 |= (dr&15) << 12;
} else {
v = p->pcond->pc - p->pc - 8;
o1 = olr(ctxt, v, REGPC, dr, p->scond&C_SCOND);
diff --git a/src/liblink/list5.c b/src/liblink/list5.c
index a91df55e69..f88f579ed9 100644
--- a/src/liblink/list5.c
+++ b/src/liblink/list5.c
@@ -99,10 +99,10 @@ Pconv(Fmt *fp)
if(s & C_UBIT) /* ambiguous with FBIT */
strcat(sc, ".U");
if(a == AMOVM) {
- if(p->from.type == D_CONST)
+ if(p->from.type == TYPE_CONST)
sprint(str, "%.5lld (%L) %A%s %@,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
else
- if(p->to.type == D_CONST)
+ if(p->to.type == TYPE_CONST)
sprint(str, "%.5lld (%L) %A%s %D,%@", p->pc, p->lineno, a, sc, &p->from, &p->to);
else
sprint(str, "%.5lld (%L) %A%s %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
@@ -113,13 +113,10 @@ Pconv(Fmt *fp)
if(p->as == ATEXT)
sprint(str, "%.5lld (%L) %A %D,%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
else
- if(p->reg == NREG)
+ if(p->reg == 0)
sprint(str, "%.5lld (%L) %A%s %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
else
- if(p->from.type != D_FREG)
- sprint(str, "%.5lld (%L) %A%s %D,R%d,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
- else
- sprint(str, "%.5lld (%L) %A%s %D,F%d,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
+ sprint(str, "%.5lld (%L) %A%s %D,%R,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
bigP = nil;
return fmtstrcpy(fp, str);
}
@@ -152,60 +149,48 @@ 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:
- 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_CONST2:
- sprint(str, "$%lld-%d", a->offset, a->offset2);
+ case TYPE_TEXTSIZE:
+ sprint(str, "$%lld-%d", a->offset, a->u.argsize);
break;
- case D_SHIFT:
+ case TYPE_SHIFT:
v = a->offset;
op = &"<<>>->@>"[(((v>>5) & 3) << 1)];
if(v & (1<<4))
sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
else
sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
- if(a->reg != NREG)
- sprint(str+strlen(str), "(R%d)", a->reg);
+ if(a->reg != 0)
+ sprint(str+strlen(str), "(%R)", a->reg);
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(R%d)(REG)", a, a->reg);
- break;
-
- case D_PSR:
- sprint(str, "PSR");
- if(a->name != D_NONE || a->sym != nil)
- sprint(str, "%M(PSR)(REG)", a);
+ 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_BRANCH:
+ case TYPE_BRANCH:
if(a->sym != nil)
sprint(str, "%s(SB)", a->sym->name);
else if(bigP != nil && bigP->pcond != nil)
@@ -216,11 +201,11 @@ Dconv(Fmt *fp)
sprint(str, "%lld(PC)", a->offset/*-pc*/);
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;
}
@@ -237,9 +222,9 @@ RAconv(Fmt *fp)
a = va_arg(fp->args, Addr*);
sprint(str, "GOK-reglist");
switch(a->type) {
- case D_CONST:
- case D_CONST2:
- if(a->reg != NREG)
+ case TYPE_CONST:
+ case TYPE_TEXTSIZE:
+ if(a->reg != 0)
break;
if(a->sym != nil)
break;
@@ -310,11 +295,27 @@ static int
Rconv(Fmt *fp)
{
int r;
- char str[STRINGSZ];
r = va_arg(fp->args, int);
- sprint(str, "R%d", r);
- return fmtstrcpy(fp, str);
+ if(r == 0)
+ return fmtstrcpy(fp, "NONE");
+ if(REG_R0 <= r && r <= REG_R15)
+ return fmtprint(fp, "R%d", r-REG_R0);
+ if(REG_F0 <= r && r <= REG_F15)
+ return fmtprint(fp, "F%d", r-REG_F0);
+
+ switch(r) {
+ case REG_FPSR:
+ return fmtstrcpy(fp, "FPSR");
+ case REG_FPCR:
+ return fmtstrcpy(fp, "FPCR");
+ case REG_CPSR:
+ return fmtstrcpy(fp, "CPSR");
+ case REG_SPSR:
+ return fmtstrcpy(fp, "SPSR");
+ }
+
+ return fmtprint(fp, "badreg(%d)", r);
}
static int
@@ -348,23 +349,23 @@ Mconv(Fmt *fp)
sprint(str, "GOK-name(%d)", a->name);
break;
- case D_NONE:
+ case NAME_NONE:
sprint(str, "%lld", a->offset);
break;
- case D_EXTERN:
+ case NAME_EXTERN:
sprint(str, "%s+%d(SB)", s->name, (int)a->offset);
break;
- case D_STATIC:
+ case NAME_STATIC:
sprint(str, "%s<>+%d(SB)", s->name, (int)a->offset);
break;
- case D_AUTO:
+ case NAME_AUTO:
sprint(str, "%s-%d(SP)", s->name, (int)-a->offset);
break;
- case D_PARAM:
+ case NAME_PARAM:
sprint(str, "%s+%d(FP)", s->name, (int)a->offset);
break;
}
diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c
index 86cb902f9c..0f2e9fa4f2 100644
--- a/src/liblink/obj5.c
+++ b/src/liblink/obj5.c
@@ -38,26 +38,9 @@
static Prog zprg5 = {
.as = AGOK,
.scond = C_SCOND_NONE,
- .reg = NREG,
- .from = {
- .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)
{
return p->as == ADATA || p->as == AGLOBL;
@@ -97,14 +80,14 @@ progedit(Link *ctxt, Prog *p)
p->from.class = 0;
p->to.class = 0;
- // Rewrite B/BL to symbol as D_BRANCH.
+ // Rewrite B/BL to symbol as TYPE_BRANCH.
switch(p->as) {
case AB:
case ABL:
case ADUFFZERO:
case ADUFFCOPY:
- if(p->to.type == D_OREG && (p->to.name == D_EXTERN || p->to.name == D_STATIC) && p->to.sym != nil)
- p->to.type = D_BRANCH;
+ if(p->to.type == TYPE_MEM && (p->to.name == NAME_EXTERN || p->to.name == NAME_STATIC) && p->to.sym != nil)
+ p->to.type = TYPE_BRANCH;
break;
}
@@ -124,24 +107,24 @@ progedit(Link *ctxt, Prog *p)
tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
// MOVW LR, R11
p->as = AMOVW;
- p->from.type = D_REG;
+ p->from.type = TYPE_REG;
p->from.reg = REGLINK;
- p->to.type = D_REG;
+ p->to.type = TYPE_REG;
p->to.reg = REGTMP;
// BL runtime.read_tls_fallback(SB)
p = appendp(ctxt, p);
p->as = ABL;
- p->to.type = D_BRANCH;
+ p->to.type = TYPE_BRANCH;
p->to.sym = tlsfallback;
p->to.offset = 0;
// MOVW R11, LR
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_REG;
+ p->from.type = TYPE_REG;
p->from.reg = REGTMP;
- p->to.type = D_REG;
+ p->to.type = TYPE_REG;
p->to.reg = REGLINK;
break;
}
@@ -154,7 +137,7 @@ progedit(Link *ctxt, Prog *p)
// Rewrite float constants to values stored in memory.
switch(p->as) {
case AMOVF:
- if(p->from.type == D_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
+ if(p->from.type == TYPE_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
(chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
uint32 i32;
float32 f32;
@@ -167,15 +150,15 @@ progedit(Link *ctxt, Prog *p)
adduint32(ctxt, s, i32);
s->reachable = 0;
}
- 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:
- if(p->from.type == D_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
+ if(p->from.type == TYPE_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
(chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
uint64 i64;
memmove(&i64, &p->from.u.dval, 8);
@@ -186,9 +169,9 @@ progedit(Link *ctxt, Prog *p)
adduint64(ctxt, s, i64);
s->reachable = 0;
}
- 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;
@@ -203,10 +186,10 @@ progedit(Link *ctxt, Prog *p)
if(ctxt->tlsg == nil)
ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
- if(p->from.type == D_CONST && p->from.name == D_EXTERN && p->from.sym == ctxt->tlsg)
- p->from.type = D_OREG;
- if(p->to.type == D_CONST && p->to.name == D_EXTERN && p->to.sym == ctxt->tlsg)
- p->to.type = D_OREG;
+ if(p->from.type == TYPE_CONST && p->from.name == NAME_EXTERN && p->from.sym == ctxt->tlsg)
+ p->from.type = TYPE_MEM;
+ if(p->to.type == TYPE_CONST && p->to.name == NAME_EXTERN && p->to.sym == ctxt->tlsg)
+ p->to.type = TYPE_MEM;
}
}
@@ -255,7 +238,7 @@ nocache5(Prog *p)
}
static void
-addstacksplit(Link *ctxt, LSym *cursym)
+preprocess(Link *ctxt, LSym *cursym)
{
Prog *p, *pl, *p1, *p2, *q, *q1, *q2;
int o;
@@ -282,35 +265,35 @@ addstacksplit(Link *ctxt, LSym *cursym)
if(autoffset < 0)
autoffset = 0;
cursym->locals = autoffset;
- cursym->args = p->to.offset2;
+ cursym->args = p->to.u.argsize;
if(ctxt->debugzerostack) {
if(autoffset && !(p->reg&NOSPLIT)) {
// MOVW $4(R13), R1
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_CONST;
- p->from.reg = 13;
+ p->from.type = TYPE_CONST;
+ p->from.reg = REG_R13;
p->from.offset = 4;
- p->to.type = D_REG;
- p->to.reg = 1;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R1;
// MOVW $n(R13), R2
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_CONST;
- p->from.reg = 13;
+ p->from.type = TYPE_CONST;
+ p->from.reg = REG_R13;
p->from.offset = 4 + autoffset;
- p->to.type = D_REG;
- p->to.reg = 2;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R2;
// MOVW $0, R3
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_CONST;
+ p->from.type = TYPE_CONST;
p->from.offset = 0;
- p->to.type = D_REG;
- p->to.reg = 3;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R3;
// L:
// MOVW.nil R3, 0(R1) +4
@@ -318,22 +301,22 @@ addstacksplit(Link *ctxt, LSym *cursym)
// BNE L
p = pl = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_REG;
- p->from.reg = 3;
- p->to.type = D_OREG;
- p->to.reg = 1;
+ p->from.type = TYPE_REG;
+ p->from.reg = REG_R3;
+ p->to.type = TYPE_MEM;
+ p->to.reg = REG_R1;
p->to.offset = 4;
p->scond |= C_PBIT;
p = appendp(ctxt, p);
p->as = ACMP;
- p->from.type = D_REG;
- p->from.reg = 1;
- p->reg = 2;
+ p->from.type = TYPE_REG;
+ p->from.reg = REG_R1;
+ p->reg = REG_R2;
p = appendp(ctxt, p);
p->as = ABNE;
- p->to.type = D_BRANCH;
+ p->to.type = TYPE_BRANCH;
p->pcond = pl;
}
}
@@ -445,9 +428,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p);
p->as = AMOVW;
p->scond |= C_WBIT;
- p->from.type = D_REG;
+ p->from.type = TYPE_REG;
p->from.reg = REGLINK;
- p->to.type = D_OREG;
+ p->to.type = TYPE_MEM;
p->to.offset = -autosize;
p->to.reg = REGSP;
p->spadj = autosize;
@@ -472,64 +455,64 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_OREG;
+ p->from.type = TYPE_MEM;
p->from.reg = REGG;
p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
- p->to.type = D_REG;
- p->to.reg = 1;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R1;
p = appendp(ctxt, p);
p->as = ACMP;
- p->from.type = D_CONST;
+ p->from.type = TYPE_CONST;
p->from.offset = 0;
- p->reg = 1;
+ p->reg = REG_R1;
p = appendp(ctxt, p);
p->as = ABEQ;
- p->to.type = D_BRANCH;
+ p->to.type = TYPE_BRANCH;
p1 = p;
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_OREG;
- p->from.reg = 1;
+ p->from.type = TYPE_MEM;
+ p->from.reg = REG_R1;
p->from.offset = 0; // Panic.argp
- p->to.type = D_REG;
- p->to.reg = 2;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R2;
p = appendp(ctxt, p);
p->as = AADD;
- p->from.type = D_CONST;
+ p->from.type = TYPE_CONST;
p->from.offset = autosize+4;
- p->reg = 13;
- p->to.type = D_REG;
- p->to.reg = 3;
+ p->reg = REG_R13;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R3;
p = appendp(ctxt, p);
p->as = ACMP;
- p->from.type = D_REG;
- p->from.reg = 2;
- p->reg = 3;
+ p->from.type = TYPE_REG;
+ p->from.reg = REG_R2;
+ p->reg = REG_R3;
p = appendp(ctxt, p);
p->as = ABNE;
- p->to.type = D_BRANCH;
+ p->to.type = TYPE_BRANCH;
p2 = p;
p = appendp(ctxt, p);
p->as = AADD;
- p->from.type = D_CONST;
+ p->from.type = TYPE_CONST;
p->from.offset = 4;
- p->reg = 13;
- p->to.type = D_REG;
- p->to.reg = 4;
+ p->reg = REG_R13;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R4;
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_REG;
- p->from.reg = 4;
- p->to.type = D_OREG;
- p->to.reg = 1;
+ p->from.type = TYPE_REG;
+ p->from.reg = REG_R4;
+ p->to.type = TYPE_MEM;
+ p->to.reg = REG_R1;
p->to.offset = 0; // Panic.argp
p = appendp(ctxt, p);
@@ -546,9 +529,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
p->as = AB;
p->from = zprg5.from;
if(p->to.sym) { // retjmp
- p->to.type = D_BRANCH;
+ p->to.type = TYPE_BRANCH;
} else {
- p->to.type = D_OREG;
+ p->to.type = TYPE_MEM;
p->to.offset = 0;
p->to.reg = REGLINK;
}
@@ -558,10 +541,10 @@ addstacksplit(Link *ctxt, LSym *cursym)
p->as = AMOVW;
p->scond |= C_PBIT;
- p->from.type = D_OREG;
+ p->from.type = TYPE_MEM;
p->from.offset = autosize;
p->from.reg = REGSP;
- p->to.type = D_REG;
+ p->to.type = TYPE_REG;
p->to.reg = REGPC;
// If there are instructions following
// this ARET, they come from a branch
@@ -571,7 +554,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
p->to.reg = REGLINK;
q2 = appendp(ctxt, p);
q2->as = AB;
- q2->to.type = D_BRANCH;
+ q2->to.type = TYPE_BRANCH;
q2->to.sym = p->to.sym;
p->to.sym = nil;
p = q2;
@@ -579,12 +562,12 @@ addstacksplit(Link *ctxt, LSym *cursym)
break;
case AADD:
- if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP)
+ if(p->from.type == TYPE_CONST && p->from.reg == 0 && p->to.type == TYPE_REG && p->to.reg == REGSP)
p->spadj = -p->from.offset;
break;
case ASUB:
- if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP)
+ if(p->from.type == TYPE_CONST && p->from.reg == 0 && p->to.type == TYPE_REG && p->to.reg == REGSP)
p->spadj = p->from.offset;
break;
@@ -594,9 +577,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
case AMODU:
if(ctxt->debugdivmod)
break;
- if(p->from.type != D_REG)
+ if(p->from.type != TYPE_REG)
break;
- if(p->to.type != D_REG)
+ if(p->to.type != TYPE_REG)
break;
q1 = p;
@@ -604,9 +587,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p);
p->as = AMOVW;
p->lineno = q1->lineno;
- p->from.type = D_REG;
+ p->from.type = TYPE_REG;
p->from.reg = q1->from.reg;
- p->to.type = D_OREG;
+ p->to.type = TYPE_MEM;
p->to.reg = REGSP;
p->to.offset = 4;
@@ -614,11 +597,11 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p);
p->as = AMOVW;
p->lineno = q1->lineno;
- p->from.type = D_REG;
+ p->from.type = TYPE_REG;
p->from.reg = q1->reg;
- if(q1->reg == NREG)
+ if(q1->reg == 0)
p->from.reg = q1->to.reg;
- p->to.type = D_REG;
+ p->to.type = TYPE_REG;
p->to.reg = REGTMP;
p->to.offset = 0;
@@ -626,7 +609,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p);
p->as = ABL;
p->lineno = q1->lineno;
- p->to.type = D_BRANCH;
+ p->to.type = TYPE_BRANCH;
switch(o) {
case ADIV:
p->to.sym = ctxt->sym_div;
@@ -646,21 +629,21 @@ addstacksplit(Link *ctxt, LSym *cursym)
p = appendp(ctxt, p);
p->as = AMOVW;
p->lineno = q1->lineno;
- p->from.type = D_REG;
+ p->from.type = TYPE_REG;
p->from.reg = REGTMP;
p->from.offset = 0;
- p->to.type = D_REG;
+ p->to.type = TYPE_REG;
p->to.reg = q1->to.reg;
/* ADD $8,SP */
p = appendp(ctxt, p);
p->as = AADD;
p->lineno = q1->lineno;
- p->from.type = D_CONST;
- p->from.reg = NREG;
+ p->from.type = TYPE_CONST;
+ p->from.reg = 0;
p->from.offset = 8;
- p->reg = NREG;
- p->to.type = D_REG;
+ p->reg = 0;
+ p->to.type = TYPE_REG;
p->to.reg = REGSP;
p->spadj = -8;
@@ -668,20 +651,20 @@ addstacksplit(Link *ctxt, LSym *cursym)
/* MOVW 0(SP), REGTMP; MOVW REGTMP, -8!(SP) */
/* TODO: Remove SP adjustments; see issue 6699. */
q1->as = AMOVW;
- q1->from.type = D_OREG;
+ q1->from.type = TYPE_MEM;
q1->from.reg = REGSP;
q1->from.offset = 0;
- q1->reg = NREG;
- q1->to.type = D_REG;
+ q1->reg = 0;
+ q1->to.type = TYPE_REG;
q1->to.reg = REGTMP;
/* SUB $8,SP */
q1 = appendp(ctxt, q1);
q1->as = AMOVW;
- q1->from.type = D_REG;
+ q1->from.type = TYPE_REG;
q1->from.reg = REGTMP;
- q1->reg = NREG;
- q1->to.type = D_OREG;
+ q1->reg = 0;
+ q1->to.type = TYPE_MEM;
q1->to.reg = REGSP;
q1->to.offset = -8;
q1->scond |= C_WBIT;
@@ -689,17 +672,23 @@ addstacksplit(Link *ctxt, LSym *cursym)
break;
case AMOVW:
- if((p->scond & C_WBIT) && p->to.type == D_OREG && p->to.reg == REGSP)
+ if((p->scond & C_WBIT) && p->to.type == TYPE_MEM && p->to.reg == REGSP)
p->spadj = -p->to.offset;
- if((p->scond & C_PBIT) && p->from.type == D_OREG && p->from.reg == REGSP && p->to.reg != REGPC)
+ if((p->scond & C_PBIT) && p->from.type == TYPE_MEM && p->from.reg == REGSP && p->to.reg != REGPC)
p->spadj = -p->from.offset;
- if(p->from.type == D_CONST && p->from.reg == REGSP && p->to.type == D_REG && p->to.reg == REGSP)
+ if(p->from.type == TYPE_CONST && p->from.reg == REGSP && p->to.type == TYPE_REG && p->to.reg == REGSP)
p->spadj = -p->from.offset;
break;
}
}
}
+static int
+isfloatreg(Addr *a)
+{
+ return a->type == TYPE_REG && REG_F0 <= a->reg && a->reg <= REG_F15;
+}
+
static void
softfloat(Link *ctxt, LSym *cursym)
{
@@ -719,7 +708,7 @@ softfloat(Link *ctxt, LSym *cursym)
for(p = cursym->text; p != nil; p = p->link) {
switch(p->as) {
case AMOVW:
- if(p->to.type == D_FREG || p->from.type == D_FREG)
+ if(isfloatreg(&p->to) || isfloatreg(&p->from))
goto soft;
goto notsoft;
@@ -761,7 +750,7 @@ softfloat(Link *ctxt, LSym *cursym)
*p = zprg5;
p->link = next;
p->as = ABL;
- p->to.type = D_BRANCH;
+ p->to.type = TYPE_BRANCH;
p->to.sym = symsfloat;
p->lineno = next->lineno;
@@ -781,21 +770,21 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// MOVW g_stackguard(g), R1
p = appendp(ctxt, p);
p->as = AMOVW;
- 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 = 1;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R1;
if(framesize <= StackSmall) {
// small stack: SP < stackguard
// CMP stackguard, SP
p = appendp(ctxt, p);
p->as = ACMP;
- p->from.type = D_REG;
- p->from.reg = 1;
+ p->from.type = TYPE_REG;
+ p->from.reg = REG_R1;
p->reg = REGSP;
} else if(framesize <= StackBig) {
// large stack: SP-framesize < stackguard-StackSmall
@@ -803,17 +792,17 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// CMP stackguard, R2
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_CONST;
+ p->from.type = TYPE_CONST;
p->from.reg = REGSP;
p->from.offset = -framesize;
- p->to.type = D_REG;
- p->to.reg = 2;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R2;
p = appendp(ctxt, p);
p->as = ACMP;
- p->from.type = D_REG;
- p->from.reg = 1;
- p->reg = 2;
+ p->from.type = TYPE_REG;
+ p->from.reg = REG_R1;
+ p->reg = REG_R2;
} else {
// Such a large stack we need to protect against wraparound
// if SP is close to zero.
@@ -827,40 +816,40 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// CMP.NE R3, R2
p = appendp(ctxt, p);
p->as = ACMP;
- p->from.type = D_CONST;
+ p->from.type = TYPE_CONST;
p->from.offset = (uint32)StackPreempt;
- p->reg = 1;
+ p->reg = REG_R1;
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_CONST;
+ p->from.type = TYPE_CONST;
p->from.reg = REGSP;
p->from.offset = StackGuard;
- p->to.type = D_REG;
- p->to.reg = 2;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R2;
p->scond = C_SCOND_NE;
p = appendp(ctxt, p);
p->as = ASUB;
- p->from.type = D_REG;
- p->from.reg = 1;
- p->to.type = D_REG;
- p->to.reg = 2;
+ p->from.type = TYPE_REG;
+ p->from.reg = REG_R1;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R2;
p->scond = C_SCOND_NE;
p = appendp(ctxt, p);
p->as = AMOVW;
- p->from.type = D_CONST;
+ p->from.type = TYPE_CONST;
p->from.offset = framesize + (StackGuard - StackSmall);
- p->to.type = D_REG;
- p->to.reg = 3;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R3;
p->scond = C_SCOND_NE;
p = appendp(ctxt, p);
p->as = ACMP;
- p->from.type = D_REG;
- p->from.reg = 3;
- p->reg = 2;
+ p->from.type = TYPE_REG;
+ p->from.reg = REG_R3;
+ p->reg = REG_R2;
p->scond = C_SCOND_NE;
}
@@ -868,16 +857,16 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
p = appendp(ctxt, p);
p->as = AMOVW;
p->scond = C_SCOND_LS;
- p->from.type = D_REG;
+ p->from.type = TYPE_REG;
p->from.reg = REGLINK;
- p->to.type = D_REG;
- p->to.reg = 3;
+ p->to.type = TYPE_REG;
+ p->to.reg = REG_R3;
// BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted
p = appendp(ctxt, p);
p->as = ABL;
p->scond = C_SCOND_LS;
- p->to.type = D_BRANCH;
+ p->to.type = TYPE_BRANCH;
if(ctxt->cursym->cfunc)
p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
else
@@ -886,7 +875,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
// BLS start
p = appendp(ctxt, p);
p->as = ABLS;
- p->to.type = D_BRANCH;
+ p->to.type = TYPE_BRANCH;
p->pcond = ctxt->cursym->text->link;
return p;
@@ -1011,7 +1000,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;
@@ -1051,7 +1040,7 @@ LinkArch linkarm = {
.thechar = '5',
.endian = LittleEndian,
- .addstacksplit = addstacksplit,
+ .preprocess = preprocess,
.assemble = span5,
.datasize = datasize,
.follow = follow,
@@ -1060,25 +1049,12 @@ LinkArch linkarm = {
.prg = prg,
.progedit = progedit,
.settextflag = settextflag,
- .symtype = symtype,
.textflag = textflag,
.minlc = 4,
.ptrsize = 4,
.regsize = 4,
- .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,