diff --git a/sys/src/cmd/7l/asmout.c b/sys/src/cmd/7l/asmout.c index 1e993439b..55f93a905 100644 --- a/sys/src/cmd/7l/asmout.c +++ b/sys/src/cmd/7l/asmout.c @@ -74,7 +74,6 @@ void asmout(Prog *p, Optab *o) { long o1, o2, o3, o4, o5, v, hi; - ulong u; vlong d; int r, s, rf, rt, ra, nzcv, cond, i, as; Mask *mask; @@ -223,8 +222,6 @@ asmout(Prog *p, Optab *o) case 13: /* addop $lcon, [R], R (64 bit literal); cmp $lcon,R -> addop $lcon,R, ZR */ o1 = omovlit(AMOV, p, &p->from, REGTMP); - if(!o1) - break; rt = p->to.reg; if(p->to.type == D_NONE) rt = REGZERO; @@ -427,8 +424,6 @@ asmout(Prog *p, Optab *o) case 28: /* logop $lcon, [R], R (64 bit literal) */ o1 = omovlit(AMOV, p, &p->from, REGTMP); - if(!o1) - break; r = p->reg; if(r == NREG) r = p->to.reg; @@ -448,10 +443,10 @@ asmout(Prog *p, Optab *o) if(s < 0) diag("unexpected long move, op %A tab %A\n%P", p->as, o->as, p); v = regoff(&p->to); - if(v < 0) - diag("negative large offset\n%P", p); if((v & ((1<>s) >= (1<<24)) + goto Hugestxr; hi = v - (v & (0xFFF<as, o->as, p); v = regoff(&p->from); - if(v < 0) - diag("negative large offset\n%P", p); if((v & ((1<>s) >= (1<<24)) + goto Hugeldxr; hi = v - (v & (0xFFF< strT (huge offset) */ - o1 = omovlit(AMOVW, p, &p->to, REGTMP); - if(!o1) - break; + Hugestxr: + o1 = omovlit(AMOV, p, &p->to, REGTMP); r = p->to.reg; if(r == NREG) r = o->param; - o2 = olsxrr(p->as, REGTMP,r, p->from.reg); + o2 = LD2STR(olsxrr(p->as, REGTMP, r, p->from.reg)); + o2 |= 7<<13; // REGTMP.SX break; case 48: /* movT V(R), R -> ldrT (huge offset) */ - o1 = omovlit(AMOVW, p, &p->from, REGTMP); - if(!o1) - break; + Hugeldxr: + o1 = omovlit(AMOV, p, &p->from, REGTMP); r = p->from.reg; if(r == NREG) r = o->param; - o2 = olsxrr(p->as, REGTMP,r, p->to.reg); + o2 = olsxrr(p->as, REGTMP, r, p->to.reg); + o2 |= 7<<13; // REGTMP.SX break; case 50: /* sys/sysl */ @@ -845,15 +840,11 @@ asmout(Prog *p, Optab *o) /* reloc ops */ case 64: /* movT R,addr */ o1 = omovlit(AMOV, p, &p->to, REGTMP); - if(!o1) - break; o2 = olsr12u(opstr12(p->as), 0, REGTMP, p->from.reg); break; case 65: /* movT addr,R */ o1 = omovlit(AMOV, p, &p->from, REGTMP); - if(!o1) - break; o2 = olsr12u(opldr12(p->as), 0, REGTMP, p->to.reg); break; } @@ -1572,8 +1563,7 @@ opldrpp(int a) static long olsxrr(int a, int b, int c, int d) { - diag("need load/store extended register\n%P", curp); - return -1; + return opldrpp(a) | 1<<21 | b<<16 | 2<<10 | c<<5 | d; } static long @@ -1598,7 +1588,6 @@ omovlit(int as, Prog *p, Adr *a, int dr) if(p->cond == nil){ /* not in literal pool */ aclass(a); -fprint(2, "omovlit add %lld (%#llux)\n", instoffset, instoffset); /* TO DO: could be clever, and use general constant builder */ o1 = opirr(AADD); v = instoffset; @@ -1606,6 +1595,8 @@ fprint(2, "omovlit add %lld (%#llux)\n", instoffset, instoffset); v >>= 12; o1 |= 1<<22; /* shift, by 12 */ } + if(v < 0 || v > 0xFFF) + diag("literal out of range\n%P", p); o1 |= ((v& 0xFFF) << 10) | (REGZERO<<5) | dr; }else{ fp = 0; diff --git a/sys/src/cmd/7l/optab.c b/sys/src/cmd/7l/optab.c index a2d5bae36..9b52a6864 100644 --- a/sys/src/cmd/7l/optab.c +++ b/sys/src/cmd/7l/optab.c @@ -141,7 +141,7 @@ Optab optab[] = { AWORD, C_NONE, C_NONE, C_ADDR, 14, 4, 0 }, { AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM }, - { AMOV, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM }, + { AMOV, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM }, { AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO }, { AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO }, @@ -236,54 +236,62 @@ Optab optab[] = { AMOV, C_UOREG32K,C_NONE, C_REG, 21, 4, REGSP }, { AMOV, C_NSOREG,C_NONE, C_REG, 21, 4, REGSP }, - /* long displacement store */ - { AMOVB, C_REG, C_NONE, C_LEXT, 30, 8, REGSB }, // - { AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP }, // - { AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0 }, // - { AMOVH, C_REG, C_NONE, C_LEXT, 30, 8, REGSB }, // - { AMOVH, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP }, // - { AMOVH, C_REG, C_NONE, C_LOREG, 30, 8, 0 }, // - { AMOVW, C_REG, C_NONE, C_LEXT, 30, 8, REGSB }, // - { AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP }, // - { AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0 }, // - { AMOV, C_REG, C_NONE, C_LEXT, 30, 8, REGSB }, // - { AMOV, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP }, // - { AMOV, C_REG, C_NONE, C_LOREG, 30, 8, 0 }, // + /* large displacement store */ + { AMOVB, C_REG, C_NONE, C_LEXT, 30, 8, REGSB, LTO }, + { AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, + { AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, + { AMOVBU, C_REG, C_NONE, C_LEXT, 30, 8, REGSB, LTO }, + { AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, + { AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, - /* long displacement load */ - { AMOVB, C_LEXT, C_NONE, C_REG, 31, 8, REGSB }, // - { AMOVB, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP }, // - { AMOVB, C_LOREG,C_NONE, C_REG, 31, 8, 0 }, // - { AMOVB, C_LOREG,C_NONE, C_REG, 31, 8, 0 }, // - { AMOVH, C_LEXT, C_NONE, C_REG, 31, 8, REGSB }, // - { AMOVH, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP }, // - { AMOVH, C_LOREG,C_NONE, C_REG, 31, 8, 0 }, // - { AMOVH, C_LOREG,C_NONE, C_REG, 31, 8, 0 }, // - { AMOVW, C_LEXT, C_NONE, C_REG, 31, 8, REGSB }, // - { AMOVW, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP }, // - { AMOVW, C_LOREG,C_NONE, C_REG, 31, 8, 0 }, // - { AMOVW, C_LOREG,C_NONE, C_REG, 31, 8, 0 }, // - { AMOV, C_LEXT, C_NONE, C_REG, 31, 8, REGSB }, // - { AMOV, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP }, // - { AMOV, C_LOREG,C_NONE, C_REG, 31, 8, 0 }, // - { AMOV, C_LOREG,C_NONE, C_REG, 31, 8, 0 }, // + { AMOVH, C_REG, C_NONE, C_LEXT, 30, 8, REGSB, LTO }, + { AMOVH, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, + { AMOVH, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, - /* load long effective stack address (load long offset and add) */ - { AMOV, C_LACON,C_NONE, C_REG, 34, 8, REGSP, LFROM }, // + { AMOVW, C_REG, C_NONE, C_LEXT, 30, 8, REGSB, LTO }, + { AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, + { AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, + + { AMOV, C_REG, C_NONE, C_LEXT, 30, 8, REGSB, LTO }, + { AMOV, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO }, + { AMOV, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO }, + + /* large displacement load */ + { AMOVB, C_LEXT, C_NONE, C_REG, 31, 8, REGSB, LFROM }, + { AMOVB, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM }, + { AMOVB, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM }, + { AMOVBU, C_LEXT, C_NONE, C_REG, 31, 8, REGSB, LFROM }, + { AMOVBU, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM }, + { AMOVBU, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM }, + + { AMOVH, C_LEXT, C_NONE, C_REG, 31, 8, REGSB, LFROM }, + { AMOVH, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM }, + { AMOVH, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM }, + + { AMOVW, C_LEXT, C_NONE, C_REG, 31, 8, REGSB, LFROM }, + { AMOVW, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM }, + { AMOVW, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM }, + + { AMOV, C_LEXT, C_NONE, C_REG, 31, 8, REGSB, LFROM }, + { AMOV, C_LAUTO,C_NONE, C_REG, 31, 8, REGSP, LFROM }, + { AMOV, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM }, + + /* load large effective stack address (load large offset and add) */ + { AMOV, C_LACON,C_NONE, C_REG, 34, 8, REGSP, LFROM }, /* pre/post-indexed load (unscaled, signed 9-bit offset) */ { AMOV, C_XPOST, C_NONE, C_REG, 22, 4, 0 }, { AMOVW, C_XPOST, C_NONE, C_REG, 22, 4, 0 }, - { AMOVH, C_XPOST, C_NONE, C_REG, 22, 4, 0 }, - { AMOVB, C_XPOST, C_NONE, C_REG, 22, 4, 0 }, + { AMOVH, C_XPOST, C_NONE, C_REG, 22, 4, 0 }, + { AMOVB, C_XPOST, C_NONE, C_REG, 22, 4, 0 }, { AMOVBU, C_XPOST, C_NONE, C_REG, 22, 4, 0 }, { AFMOVS, C_XPOST, C_NONE, C_FREG, 22, 4, 0 }, { AFMOVD, C_XPOST, C_NONE, C_FREG, 22, 4, 0 }, { AMOV, C_XPRE, C_NONE, C_REG, 22, 4, 0 }, { AMOVW, C_XPRE, C_NONE, C_REG, 22, 4, 0 }, - { AMOVH, C_XPRE, C_NONE, C_REG, 22, 4, 0 }, - { AMOVB, C_XPRE, C_NONE, C_REG, 22, 4, 0 }, + { AMOVH, C_XPRE, C_NONE, C_REG, 22, 4, 0 }, + { AMOVB, C_XPRE, C_NONE, C_REG, 22, 4, 0 }, { AMOVBU, C_XPRE, C_NONE, C_REG, 22, 4, 0 }, { AFMOVS, C_XPRE, C_NONE, C_FREG, 22, 4, 0 }, { AFMOVD, C_XPRE, C_NONE, C_FREG, 22, 4, 0 }, diff --git a/sys/src/cmd/7l/span.c b/sys/src/cmd/7l/span.c index c9e4e4e89..fe4244099 100644 --- a/sys/src/cmd/7l/span.c +++ b/sys/src/cmd/7l/span.c @@ -200,23 +200,21 @@ void addpool(Prog *p, Adr *a) { Prog *q, t; - int c, sz; + int sz; - c = aclass(a); t = zprg; t.as = AWORD; sz = 4; - if(p->as == AMOV || (cmp(C_VCON, c) && (ulong)(a->offset & 0xFFFFFFFF) != a->offset)) { - t.as = ADWORD; - sz = 8; - } - - switch(c) { + switch(aclass(a)) { default: + if(p->as == AMOV && (a->name == D_EXTERN || a->name == D_STATIC) + || (a->offset >> 32) != 0 && (a->offset >> 31) != -1){ + t.as = ADWORD; + sz = 8; + } t.to = *a; break; - case C_PSAUTO: case C_PPAUTO: case C_UAUTO4K: @@ -237,9 +235,11 @@ addpool(Prog *p, Adr *a) case C_NSOREG: case C_NPOREG: case C_LOREG: + case C_LACON: + if((instoffset >> 32) != 0 && (instoffset >> 31) != -1) + diag("offset too large\n%P", p); t.to.type = D_CONST; t.to.offset = instoffset; - sz = 4; break; } @@ -741,7 +741,8 @@ oplook(Prog *p) if(c1[o->a1]) if(c3[o->a3]) { if(0) - print("%P\t-> %d (%d %d %d)\n", p, o->type, o->a1, o->a2, o->a3); + print("%P\t-> %d (%d %d %d)\n", p, o->type, + o->a1, o->a2, o->a3); p->optab = (o-optab)+1; return o; }