diff options
| author | Russ Cox <rsc@golang.org> | 2015-01-26 15:15:05 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2015-01-30 03:15:58 +0000 |
| commit | 0d599909e9a38ca925c9eaf916eba3fcbea22203 (patch) | |
| tree | 487fec66b4ee1466e0180148e51a0f16142301c9 /src/liblink | |
| parent | 5a2771e286433c64a20fbe5ae6252080418dfa5c (diff) | |
| download | go-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.c | 443 | ||||
| -rw-r--r-- | src/liblink/list5.c | 103 | ||||
| -rw-r--r-- | src/liblink/obj5.c | 300 |
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, |
