aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--amd64/emit.c8
-rw-r--r--amd64/isel.c30
-rw-r--r--c.c3
-rw-r--r--ir.c11
-rw-r--r--ir.h12
-rw-r--r--irdump.c10
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;
diff --git a/c.c b/c.c
index 022ef8a..fed56c3 100644
--- a/c.c
+++ b/c.c
@@ -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);
diff --git a/ir.c b/ir.c
index 432a10d..c2abe12 100644
--- a/ir.c
+++ b/ir.c
@@ -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));
}
diff --git a/ir.h b/ir.h
index 1182ed3..d3eeeea 100644
--- a/ir.h
+++ b/ir.h
@@ -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);
diff --git a/irdump.c b/irdump.c
index 49bca6b..362c17d 100644
--- a/irdump.c
+++ b/irdump.c
@@ -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("]");