aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--amd64/emit.c3
-rw-r--r--amd64/isel.c2
-rw-r--r--c.c2
-rw-r--r--ir.h6
-rw-r--r--irdump.c11
-rw-r--r--regalloc.c16
6 files changed, 23 insertions, 17 deletions
diff --git a/amd64/emit.c b/amd64/emit.c
index c7c6258..21a59b7 100644
--- a/amd64/emit.c
+++ b/amd64/emit.c
@@ -529,10 +529,11 @@ Xjcc(uchar **pcode, enum cc cc, struct block *dst)
}
static void
-Xsetcc(uchar **pcode, enum cc cc, int reg)
+Xsetcc(uchar **pcode, enum cc cc, enum reg reg)
{
int rex = 0;
assert(in_range(cc, 0x0, 0xF));
+ assert(in_range(reg, RAX, R15));
if (in_range(reg, RSP, RDI)) rex = 0x40;
rex |= (reg >> 3); /* REX.B */
diff --git a/amd64/isel.c b/amd64/isel.c
index a613f53..10ff5ea 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -355,7 +355,7 @@ amd64_isel(struct function *fn)
for (i = 0; i < blk->ins.n; ++i) {
struct instr *ins = &instrtab[blk->ins.p[i]];
sel(fn, ins, blk, &i);
- if (ins->op < arraylength(opflags) && kisint(ins->cls)) {
+ if (ins->op < arraylength(opflags) && kisint(insrescls(*ins))) {
if (opflags[ins->op] & ZF) iflagsrc = ins - instrtab;
else if (opflags[ins->op] & CLOBF) iflagsrc = -1;
}
diff --git a/c.c b/c.c
index 6db23be..c3297e8 100644
--- a/c.c
+++ b/c.c
@@ -1520,7 +1520,7 @@ compileexpr(struct function *fn, const struct expr *ex, bool discard)
if (discard) return NOREF;
ins.l = cvt(fn, ty.t, sub[0].ty.t, ins.l);
ins.r = cvt(fn, ty.t, sub[1].ty.t, ins.r);
- ins.cls = cls;
+ ins.cls = type2cls[ty.t];
return addinstr(fn, ins);
case ESET:
assert(isscalar(ex->ty));
diff --git a/ir.h b/ir.h
index 3858d0d..72a0bd5 100644
--- a/ir.h
+++ b/ir.h
@@ -91,7 +91,7 @@ enum op {
#undef _
};
-#define oiscmp(o) in_range(o, Oequ, Oulte)
+#define oiscmp(o) in_range(o, Oequ, Ougte)
#define oisalloca(o) in_range(o, Oalloca1, Oalloca16)
#define oisstore(o) in_range(o, Ostore1, Ostore8)
#define oisload(o) in_range(o, Oloads1, Oloadf8)
@@ -105,7 +105,8 @@ enum intrin {
};
struct instr {
- uchar op, cls;
+ uchar op,
+ cls; /* operation data class; also result class except for cmp ops (always i4) */
uchar skip : 1; /* ignore during codegen: forms part of one machine instruction */
uchar inplace : 1; /* set (by isel) for instructions which modify its first arg in place */
uchar reg; /* 0 -> no reg; else reg + 1 */
@@ -189,6 +190,7 @@ extern struct calltab {vec_of(struct call);} calltab;
extern struct phitab {vec_of(struct phi);} phitab;
extern struct dattab {vec_of(struct irdat);} dattab;
extern struct addr addrht[];
+#define insrescls(ins) (oiscmp((ins).op) ? KI4 : (ins).cls)
#define NOREF ((union ref) {0})
#define ZEROREF ((union ref) {{ RICON, 0 }})
#define mkref(t, x) ((union ref) {{ (t), (x) }})
diff --git a/irdump.c b/irdump.c
index cd7468f..f1a64f5 100644
--- a/irdump.c
+++ b/irdump.c
@@ -166,15 +166,18 @@ dumpinst(const struct instr *ins)
if (ins->op == Omove) {
efmt("move %s ", clsname[ins->cls]);
} else {
+ enum irclass cls = insrescls(*ins);
if (ins->reg) {
- if (ins->cls)
- efmt("%s ", clsname[ins->cls]);
+ if (cls)
+ efmt("%s ", clsname[cls]);
efmt("%s = ", mctarg->rnames[ins->reg - 1]);
- } else if (ins->cls) {
- efmt("%s %%%d", clsname[ins->cls], ins - instrtab);
+ } else if (cls) {
+ efmt("%s %%%d", clsname[cls], ins - instrtab);
efmt(" = ");
}
efmt("%s ", opnames[ins->op]);
+ if (oiscmp(ins->op))
+ efmt("%s ", clsname[ins->cls]);
}
for (i = 0; i < opnarg[ins->op]; ++i) {
if (i) efmt(", ");
diff --git a/regalloc.c b/regalloc.c
index ed5af2c..1b3b765 100644
--- a/regalloc.c
+++ b/regalloc.c
@@ -61,8 +61,8 @@ def(struct rega *ra, struct instr *ins, struct block *blk, int curi)
assert(ra->regs[reg].bits == mkref(RTMP, var).bits);
} else if (alloc->t == ASTACK) {
/* unspill, insert 'store [slot], reg' */
- int reg = allocreg(ra, ins->cls, mkref(RTMP, var), -1);
- struct instr store = mkinstr(Ostore1 + ilog2(cls2siz[ins->cls]), 0,
+ int reg = allocreg(ra, insrescls(*ins), mkref(RTMP, var), -1);
+ struct instr store = mkinstr(Ostore1 + ilog2(cls2siz[insrescls(*ins)]), 0,
mkref(RICON, alloc->a*8), mkref(RREG, reg));
DBG("-- unspill %%%d s%d -> %s\n", var, alloc->a, mctarg->rnames[ins->reg+1]);
addstkslotref(insertinstr(blk, ++curi, store));
@@ -151,7 +151,7 @@ spill(struct rega *ra, int reg, struct block *blk, int curi) {
DBG("-- spill %%%d %s -> s%d\n", var, mctarg->rnames[reg], s);
instrtab[var].reg = 0;
/* insert 'reg = load [slot]' */
- load = mkinstr(Oloads1 + 2*ilog2(cls2siz[instrtab[var].cls]), instrtab[var].cls, mkref(RICON, s*8));
+ load = mkinstr(Oloads1 + 2*ilog2(cls2siz[insrescls(instrtab[var])]), insrescls(instrtab[var]), mkref(RICON, s*8));
load.reg = reg+1;
addstkslotref(insertinstr(blk, ++curi, load));
freereg(ra, reg);
@@ -184,7 +184,7 @@ forcetake(struct rega *ra, int reg, union ref ref, struct block *blk, int curi)
int rename = allocreg(ra, isgpr(reg) ? KI4 : KF4, ra->regs[reg], excl);
if (ccopt.dbg.r)DBG("-- rename %%%d %s -> %s\n", var, mctarg->rnames[reg], mctarg->rnames[rename]);
/* introduce move from rename -> original (since we allocate backwards) */
- insertinstr(blk, ++curi, mkmove(instrtab[var].cls, reg, rename));
+ insertinstr(blk, ++curi, mkmove(insrescls(instrtab[var]), reg, rename));
instrtab[var].reg = rename+1;
ra->regs[rename] = mkref(RTMP, var);
bsset(globusage, rename);
@@ -230,12 +230,12 @@ use(struct rega *ra, struct block *blk, int curi, enum op op, int hint, union re
take(ra, hint, *ref);
ins->reg = hint + 1;
} else {
- ins->reg = allocreg(ra, ins->cls, *ref, excl) + 1;
+ ins->reg = allocreg(ra, insrescls(*ins), *ref, excl) + 1;
}
if (s >= 0) {
/* unspill, insert 'store [slot], reg' */
DBG("-- unspill %%%d s%d -> %s\n", ref->i, s, mctarg->rnames[ins->reg-1]);
- struct instr store = mkinstr(Ostore1 + ilog2(cls2siz[ins->cls]), 0,
+ struct instr store = mkinstr(Ostore1 + ilog2(cls2siz[insrescls(*ins)]), 0,
mkref(RICON, s*8),
mkref(RREG, ins->reg-1));
addstkslotref(insertinstr(blk, ++curi, store));
@@ -335,7 +335,7 @@ regalloc(struct function *fn)
if (ins->reg-1 != ins->l.i) {
/* an in-place operation where the destination does not
* match the first operand, so we need to add a move */
- insertinstr(blk, i, mkmove(ins->cls, ins->reg-1, ins->l.i));
+ insertinstr(blk, i, mkmove(insrescls(*ins), ins->reg-1, ins->l.i));
ins->l.i = ins->reg-1;
}
}
@@ -349,7 +349,7 @@ regalloc(struct function *fn)
/* introduce necessary moves in each pred,
* XXX this doesn't work for backwards branches */
for (int i = 0; i < phi->n; ++i) {
- struct instr mov = mkinstr(Omove, ins->cls, mkref(RREG, ins->reg-1), phi->ref[i]);
+ struct instr mov = mkinstr(Omove, insrescls(*ins), mkref(RREG, ins->reg-1), phi->ref[i]);
insertinstr(phi->blk[i], phi->blk[i]->ins.n, mov);
}
}