aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--amd64/emit.c5
-rw-r--r--amd64/isel.c14
-rw-r--r--ir.h1
3 files changed, 11 insertions, 9 deletions
diff --git a/amd64/emit.c b/amd64/emit.c
index 670fcef..8b74632 100644
--- a/amd64/emit.c
+++ b/amd64/emit.c
@@ -35,7 +35,7 @@ ref2oper(union ref r)
case RXCON:
if (conht[r.i].cls == KI4)
return mkoper(OIMM, .imm = conht[r.i].i);
- else if (conht[r.i].deref || conht[r.i].issym)
+ else if (!conht[r.i].cls)
return mkoper(OCONR, .con = r.i);
assert(0);
case RMORE: return mkmemoper(r);
@@ -123,6 +123,9 @@ mkmemoper(union ref r)
.index = addr->index.t ? mkregoper(addr->index).reg : NOINDEX,
.disp = addr->disp,
.shift = addr->shift);
+ } else if (r.t == RXCON) {
+ assert(!conht[r.i].cls);
+ return mkoper(OCONR, .con = r.i);
} else {
return mkoper(OMEM, .base = isregref(r) ? ref2oper(r).reg : NOBASE,
.index = NOINDEX,
diff --git a/amd64/isel.c b/amd64/isel.c
index 942e962..43e3aa7 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -99,7 +99,7 @@ aadd(struct addr *addr, union ref r)
if (!aadd(addr, ins->l)) goto Ref;
ins->skip = 1;
} else goto Ref;
- } else if (iscon(r)) {
+ } else if (isnumcon(r)) {
return acon(addr, r);
} else if (r.t == RREG) {
/* temporaries are single assignment, but register aren't, so they can't be *
@@ -119,8 +119,8 @@ fuseaddr(struct function *fn, union ref *r)
struct addr addr = { 0 };
if (r->t == RMORE) return 1;
+ if (r->t == RXCON && (!conht[r->i].cls && !conht[r->i].deref)) return 1;
if (r->t != RTMP) return 0;
-
if (!aadd(&addr, *r)) return 0;
*r = mkaddr(addr);
@@ -244,14 +244,12 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
break;
case Oloads1: case Oloadu1: case Oloads2: case Oloadu2:
case Oloads4: case Oloadu4: case Oloadi8: case Oloadf4: case Oloadf8:
- if (ins->l.t != RTMP && ins->l.t != RREG && ins->l.t != RMORE)
- ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ins->cls, ins->l));
- fuseaddr(fn, &ins->l);
+ if (!fuseaddr(fn, &ins->l) && ins->l.t != RTMP && ins->l.t != RREG)
+ ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, ins->l));
break;
case Ostore1: case Ostore2: case Ostore4: case Ostore8:
- if (ins->l.t != RTMP && ins->l.t != RREG && ins->l.t != RMORE)
- ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ins->cls, ins->l));
- fuseaddr(fn, &ins->l);
+ if (!fuseaddr(fn, &ins->l) && ins->l.t != RTMP && ins->l.t != RREG)
+ ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, ins->l));
fixarg(fn, &ins->r, ins, blk, curi);
break;
case Ocopy:
diff --git a/ir.h b/ir.h
index ca4fe47..b562a03 100644
--- a/ir.h
+++ b/ir.h
@@ -205,6 +205,7 @@ union ref mkfltcon(enum irclass, double);
#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 isnumcon(r) ((r).t == RICON || ((r).t == RXCON && 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 *);