diff options
| -rw-r--r-- | amd64/emit.c | 8 | ||||
| -rw-r--r-- | amd64/isel.c | 30 | ||||
| -rw-r--r-- | c.c | 3 | ||||
| -rw-r--r-- | ir.c | 11 | ||||
| -rw-r--r-- | ir.h | 12 | ||||
| -rw-r--r-- | irdump.c | 10 |
6 files changed, 37 insertions, 37 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index 1f6e2b4..4f1a448 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -33,7 +33,7 @@ ref2oper(union ref r) case RICON: return mkoper(OIMM, .imm = r.i); case RXCON: if (conht[r.i].cls == KI4) - return mkoper(OIMM, .imm = conht[r.i].i4); + return mkoper(OIMM, .imm = conht[r.i].i); else if (conht[r.i].deref || conht[r.i].issym) return mkoper(OCONR, .con = r.i); assert(0); @@ -67,8 +67,8 @@ mkregoper(union ref r) static inline struct oper mkimmoper(union ref r) { - assert(r.t == RICON || (r.t == RXCON && conht[r.i].cls == KI4)); - return mkoper(OIMM, .imm = r.t == RICON ? r.i : conht[r.i].i4); + assert(iscon(r) && concls(r) == KI4); + return mkoper(OIMM, .imm = intconval(r)); } #define ismemref(ref) ((ref).t == RTMP && ioper[(ref).i].t == OMEM) @@ -77,7 +77,7 @@ mkimmoper(union ref r) static inline struct oper mkimmregoper(union ref r) { - assert(isregref(r) || r.t == RICON || (r.t == RXCON && conht[r.i].cls == KI4)); + assert(isregref(r) || (iscon(r) && concls(r) == KI4)); return ref2oper(r); } diff --git a/amd64/isel.c b/amd64/isel.c index 58cc49a..6d4c87e 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -9,23 +9,26 @@ fixarg(struct function *fn, union ref *r, struct instr *ins, struct block *blk, if (r->t == RXCON) { struct xcon *con = &conht[r->i]; if (in_range(op, Oshl, Oslr)) { - sh = con->cls == KI4 ? con->i4 : con->i8; + sh = con->i; goto ShiftImm; - } else if (in_range(op, Oadd, Osub) && con->i8 == 2147483648) { + } else if (in_range(op, Oadd, Osub) && con->i == 2147483648) { /* add X, INT32MAX+1 -> sub X, INT32MIN */ ins->op = Oadd + (op == Oadd); *r = mkintcon(KI4, -2147483648); - } else if (in_range(op, Ocopy, Omove) && kisflt(con->cls) - && (con->cls == KF4 ? con->fs == 0.0f : con->fd == 0.0)) - { + } else if (in_range(op, Ocopy, Omove) && kisflt(con->cls) && con->f == 0) { /* copy of float zero -> regular zero, that emit() will turn into xor x,x */ *r = mkref(RICON, 0); } else if (kisflt(con->cls) || con->cls == KI8) { /* float immediates & >32b immediates are loaded from memory */ uchar data[8]; uint siz = cls2siz[con->cls]; - if (con->cls == KI4 || con->cls == KF4) wr32le(data, con->i4); - else wr64le(data, con->i8); + if (ins) assert(ins->cls == con->cls); + if (con->cls == KI4) wr32le(data, con->i); + else if (con->cls != KF4) wr64le(data, con->i); + else { + union { float f; int i; } pun = { con->f }; + wr32le(data, pun.i); + } *r = mkdatref(siz, /*align*/siz, data, siz, /*deref*/1); } else if (in_range(op, Odiv, Ourem) && kisint(ins->cls)) goto DivImm; @@ -39,20 +42,15 @@ fixarg(struct function *fn, union ref *r, struct instr *ins, struct block *blk, } } -#define iscon(r) (in_range((r).t, RICON, RXCON)) -#define isimm32(r) ((r).t == RICON || ((r).t == RXCON && conht[(r).i].cls == KI4)) +#define isimm32(r) (concls(r) == KI4) #define rswap(a,b) do { union ref _t = (a); (a) = (b); (b) = _t; } while (0) static bool acon(struct addr *addr, union ref r) { vlong a = addr->disp; - if (r.t == RICON) { - a += r.i; - } else { - assert(r.t == RXCON && kisint(conht[r.i].cls)); - a += conht[r.i].cls == KI4 ? conht[r.i].i4 : conht[r.i].i8; - } + assert(isintcon(r)); + a += intconval(r); if ((int)a == a) { addr->disp = a; return 1; @@ -88,7 +86,7 @@ aadd(struct addr *addr, union ref r, bool rec) } else if (!rec && ins->op == Ocopy && ins->l.t == RMORE) { struct addr save = *addr, *addr2 = &addrht[ins->l.i]; if ((!addr2->base.t || aadd(addr, addr2->base, 1)) - && aadd(addr, mkintcon(KI4, addr2->disp), 1) + && acon(addr, mkintcon(KI4, addr2->disp)) && (!addr2->index.t || ascale(addr, addr2->index, mkref(RICON, addr2->shift)))) { ins->skip = 1; @@ -1125,7 +1125,8 @@ cvt(struct function *fn, enum typetag to, enum typetag from, union ref ref) } else if (kfrom == KI4 && issignedt(from)) ins.op = Oexts4; else if (kfrom == KI4) ins.op = Oextu4; - else if (ref.t == RXCON && kfrom == KI8) return mkintcon(KI4, (int)(conht[ref.i].i8)); + else if (kto == KI4 && isintcon(ref)) + return issignedt(to) ? mkintcon(kto, (int)intconval(ref)) : mkintcon(kto, (uint)intconval(ref)); else ins.op = Ocopy; } return addinstr(fn, ins); @@ -150,11 +150,10 @@ mkintcon(enum irclass k, vlong i) { if (i < 1l << 28 && i >= -(1l << 28)) { return mkref(RICON, i); - } else if (k == KI4) { - struct xcon con = { .cls = k, .i4 = i }; - return mkref(RXCON, addcon(&con)); } else { - struct xcon con = { .cls = k, .i8 = i }; + struct xcon con = { .cls = k, .i = i }; + if (cls2siz[k] == 4) /* check upper half is zero or -1 */ + assert(in_range((i >> 32) + 1, 0, 1)); return mkref(RXCON, addcon(&con)); } } @@ -162,9 +161,7 @@ mkintcon(enum irclass k, vlong i) union ref mkfltcon(enum irclass k, double f) { - struct xcon con = { .cls = k }; - if (k == KF4) con.fs = f; - else con.fd = f; + struct xcon con = { .cls = k, .f = k == KF4 ? (float) f : f }; return mkref(RXCON, addcon(&con)); } @@ -36,10 +36,8 @@ struct xcon { union { const char *sym; int dat; - int i4; - vlong i8; - float fs; - double fd; + vlong i; + double f; }; }; @@ -197,6 +195,12 @@ void irfini(struct function *); union irtype mkirtype(union type); union ref mkintcon(enum irclass, vlong); union ref mkfltcon(enum irclass, double); +#define iscon(r) in_range((r).t, RICON, RXCON) +#define concls(r) ((r).t == RICON ? KI4 : conht[(r).i].cls) +#define isintcon(r) (iscon(r) && kisint(concls(r))) +#define isfltcon(r) ((r).t == RXCON && kisflt(conht[(r).i].cls)) +#define intconval(r) ((r).t == RICON ? (r).i : conht[(r).i].i) +#define fltconval(r) (conht[(r).i].f) union ref mksymref(const char *); union ref mkdatref(uint siz, uint align, const void *, uint n, bool deref); struct instr mkalloca(uint siz, uint align); @@ -94,11 +94,11 @@ dumpref(enum op o, union ref ref) if (con->issym) efmt("$%s", con->sym); else if (con->isdat) efmt("$.%d", con->dat); else switch (con->cls) { - case KI4: efmt("%d", con->i4); break; - case KI8: efmt("%ld", con->i8); break; - case KPTR: efmt("%'x", con->i8); break; - case KF4: efmt("%fs", con->fs); break; - case KF8: efmt("%fd", con->fd); break; + case KI4: efmt("%d", (int)con->i); break; + case KI8: efmt("%ld", con->i); break; + case KPTR: efmt("%'lx", con->i); break; + case KF4: efmt("%fs", con->f); break; + case KF8: efmt("%fd", con->f); break; default: assert(0); } if (con->deref) efmt("]"); |