aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--aarch64/emit.c10
-rw-r--r--aarch64/isel.c29
-rw-r--r--c/c.c10
-rw-r--r--ir/abi0.c13
-rw-r--r--ir/intrin.c2
-rw-r--r--ir/ir.c5
-rw-r--r--ir/ir.h3
-rw-r--r--ir/mem2reg.c10
-rw-r--r--ir/op.def10
-rw-r--r--ir/regalloc.c6
-rw-r--r--x86_64/emit.c12
-rw-r--r--x86_64/isel.c4
-rw-r--r--x86_64/sysv.c14
13 files changed, 79 insertions, 49 deletions
diff --git a/aarch64/emit.c b/aarch64/emit.c
index 2ca3af9..564ce2a 100644
--- a/aarch64/emit.c
+++ b/aarch64/emit.c
@@ -680,12 +680,12 @@ emitinstr(uchar **pcode, struct function *fn, struct block *blk, int curi, struc
Load:
X2(pcode, cls, reg2oper(ins->reg-1), mkmemoper(8<<(ins->op - Oloads8)/2, ins->l));
break;
- case Ostore8: cls = KI32; X2 = Xstrb; goto Store;
- case Ostore16: cls = KI32; X2 = Xstrh; goto Store;
- case Ostore32: cls = KI32; X2 = Xstr; goto Store;
- case Ostore64: cls = KI64; X2 = Xstr;
+ case Ostorei8: cls = KI32; X2 = Xstrb; goto Store;
+ case Ostorei16: cls = KI32; X2 = Xstrh; goto Store;
+ case Ostorei32: cls = KI32; X2 = Xstr; goto Store;
+ case Ostorei64: cls = KI64; X2 = Xstr;
Store:
- X2(pcode, cls, ref2oper(ins->r), mkmemoper(8<<(ins->op-Ostore8), ins->l));
+ X2(pcode, cls, ref2oper(ins->r), mkmemoper(8<<(ins->op-Ostorei8), ins->l));
break;
case Ocall:
Xcall(pcode, ref2oper(ins->l));
diff --git a/aarch64/isel.c b/aarch64/isel.c
index 6e457d0..2e82361 100644
--- a/aarch64/isel.c
+++ b/aarch64/isel.c
@@ -147,7 +147,7 @@ selcall(struct function *fn, struct instr *ins, struct block *blk, int *curi)
union ref adr = mkaddr((struct addr){mkref(RREG, SP), .disp = abi.stk});
int iargsave = iarg;
if (!abi.ty.isagg) { /* scalar arg in stack */
- *arg = mkinstr(Ostore8+ilog2(cls2siz[abi.ty.cls]), 0, adr, arg->r);
+ *arg = mkinstr(cls2store[abi.ty.cls], 0, adr, arg->r);
if (isaddrcon(arg->r,1) || arg->r.t == RADDR)
arg->r = insertinstr(blk, iarg++, mkinstr(Ocopy, abi.ty.cls, arg->r));
else
@@ -284,11 +284,26 @@ fuseaddr(union ref *r, struct block *blk, int *curi, uint siz/*1,2,4,8*/)
return 1;
}
-
+static const uchar loadsz[] = {
+ [Oloads8 - Oloads8] = 1, [Oloadu8 - Oloads8] = 1,
+ [Oloads16 - Oloads8] = 2, [Oloadu16 - Oloads8] = 2,
+ [Oloads32 - Oloads8] = 4, [Oloadu32 - Oloads8] = 4,
+ [Oloadi64 - Oloads8] = 8,
+ [Oloadf32 - Oloads8] = 4,
+ [Oloadf64 - Oloads8] = 8,
+};
+static const uchar storesz[] = {
+ [Ostorei8 - Ostorei8] = 1,
+ [Ostorei16 - Ostorei8] = 2,
+ [Ostorei32 - Ostorei8] = 4,
+ [Ostorei64 - Ostorei8] = 8,
+ [Ostoref32 - Ostorei8] = 4,
+ [Ostoref64 - Ostorei8] = 8,
+};
static void
loadstoreaddr(struct block *blk, union ref *r, int *curi, enum op op)
{
- uint siz = oisload(op) ? 1<<(op - Oloads8)/2 : 1<<(op - Ostore8);
+ uint siz = oisload(op) ? loadsz[op] : storesz[op];
if (isimm32(*r)) {
*r = mkaddr((struct addr){.base = *r});
} else if (isaddrcon(*r, 0)) {
@@ -306,6 +321,7 @@ static void
sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
{
enum op op = ins->op;
+ enum irclass cls;
if (oisarith(ins->op) && arithfold(ins)) {
fixarg(&ins->l, ins, blk, curi);
@@ -377,9 +393,12 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
case Oloads32: case Oloadu32: case Oloadi64:
loadstoreaddr(blk, &ins->l, curi, op);
break;
- case Ostore8: case Ostore16: case Ostore32: case Ostore64:
+ case Ostorei8: case Ostorei16: case Ostorei32: cls = KI32; goto Store;
+ case Ostorei64: cls = KI64; goto Store;
+ case Ostoref32: cls = KF32; goto Store;
+ case Ostoref64: cls = KF64; Store:
loadstoreaddr(blk, &ins->l, curi, op);
- regarg(&ins->r, op == Ostore64 ? KI64 : KI32, blk, curi);
+ regarg(&ins->r, cls, blk, curi);
break;
}
}
diff --git a/c/c.c b/c/c.c
index fffdccc..d3f97ec 100644
--- a/c/c.c
+++ b/c/c.c
@@ -2951,10 +2951,10 @@ genstore(struct function *fn, union type t, union ref ptr, union ref val)
assert(isscalar(t));
switch (typesize(t)) {
- case 1: ins.op = Ostore8; break;
- case 2: ins.op = Ostore16; break;
- case 4: ins.op = Ostore32; break;
- case 8: ins.op = Ostore64; break;
+ case 1: ins.op = Ostorei8; break;
+ case 2: ins.op = Ostorei16; break;
+ case 4: ins.op = isflt(t) ? Ostoref32 : Ostorei32; break;
+ case 8: ins.op = isflt(t) ? Ostoref64 : Ostorei64; break;
default: assert(0);
}
ins.l = ptr;
@@ -2988,7 +2988,7 @@ geninit(struct function *fn, union type t, union ref dst, const struct expr *src
/* write individual zeros at non initialized gaps */
for (uint i = 0; bsiter(&i, azero, countof(azero)) && i < siz; i += align) {
adr = irbinop(fn, Oadd, KPTR, dst, mkref(RICON, i));
- addinstr(fn, mkinstr(Ostore8 + ilog2(align), 0, .l = adr, .r = ZEROREF));
+ addinstr(fn, mkinstr(Ostorei8 + ilog2(align), 0, .l = adr, .r = ZEROREF));
}
} else {
goto Memset0;
diff --git a/ir/abi0.c b/ir/abi0.c
index 85f7003..d688e03 100644
--- a/ir/abi0.c
+++ b/ir/abi0.c
@@ -121,11 +121,11 @@ patchparam(struct function *fn, int *curi, int *param, int tydat, int nabi, stru
* store* %x, %a
* store* %x + N, %b
*/
- st = mkinstr(Ostore8 + ilog2(cls2siz[abi[0].ty.cls]), 0, alloc, r[0]);
+ st = mkinstr(cls2store[abi[0].ty.cls], 0, alloc, r[0]);
insertinstr(blk, ++*curi, st);
if (nabi > 1) {
struct instr tmp = mkinstr(Oadd, KPTR, alloc, mkref(RICON, r2off));
- st = mkinstr(Ostore8 + ilog2(cls2siz[abi[1].ty.cls]), 0, insertinstr(blk, ++*curi, tmp), r[1]);
+ st = mkinstr(cls2store[abi[1].ty.cls], 0, insertinstr(blk, ++*curi, tmp), r[1]);
insertinstr(blk, ++*curi, st);
}
}
@@ -226,7 +226,7 @@ patcharg(struct block *blk, int *icall, struct call *call,
union ref sadr = off == 0 ? src : insertinstr(blk, ++arginst, mkinstr(Oadd, KPTR, src, mkref(RICON, off)));
union ref tmp = insertinstr(blk, ++arginst, mkinstr(Oloads8+2*ilog2(align), align < 8 ? KI32 : KI64, sadr));
union ref dadr = off == 0 ? dst : insertinstr(blk, ++arginst, mkinstr(Oadd, KPTR, dst, mkref(RICON, off)));
- insertinstr(blk, ++arginst, mkinstr(Ostore8+ilog2(align), 0, dadr, tmp));
+ insertinstr(blk, ++arginst, mkinstr(Ostorei8+ilog2(align), 0, dadr, tmp));
}
*icall = arginst + (call->narg - argidx);
return 1;
@@ -320,12 +320,7 @@ abi0_call(struct function *fn, struct instr *ins, struct block *blk, int *curi)
r[1] = insertinstr(blk, ++*curi, ret2);
}
for (int i = 0; i < nret; ++i) {
- struct instr store = {0};
- switch (call->abiret[i].ty.cls) {
- default: assert(0);
- case KF32: case KI32: store.op = Ostore32; break;
- case KI64: case KF64: store.op = Ostore64; break;
- }
+ struct instr store = { cls2store[call->abiret[i].ty.cls] };
if (i == 0) {
store.l = retmem;
} else {
diff --git a/ir/intrin.c b/ir/intrin.c
index dcd05a5..ca49341 100644
--- a/ir/intrin.c
+++ b/ir/intrin.c
@@ -37,7 +37,7 @@ intrin(struct block *blk, int *curi, enum intrin in, struct arg *args, int narg,
psrc = insertinstr(blk, ++*curi, mkinstr(Oadd, KPTR, *args[1].arg, mkref(RICON, off)));
}
src = insertinstr(blk, ++*curi, mkinstr(Oloads8 + 2*ilog2(step), step < 8 ? KI32 : KI64, psrc));
- insertinstr(blk, ++*curi, mkinstr(Ostore8 + ilog2(step), 0, pdst, src));
+ insertinstr(blk, ++*curi, mkinstr(Ostorei8 + ilog2(step), 0, pdst, src));
}
return 1;
}
diff --git a/ir/ir.c b/ir/ir.c
index 29d52d4..cc16919 100644
--- a/ir/ir.c
+++ b/ir/ir.c
@@ -6,6 +6,9 @@ uchar cls2siz[] = { [KI32] = 4, [KI64] = 8, [KF32] = 4, [KF64] = 8 };
uchar cls2load[] = {
[KI32] = Oloads32, [KI64] = Oloadi64,
[KF32] = Oloadf32, [KF64] = Oloadf64, [KPTR] = -1
+}, cls2store[] = {
+ [KI32] = Ostorei32, [KI64] = Ostorei64,
+ [KF32] = Ostoref32, [KF64] = Ostoref64, [KPTR] = -1
};
const uchar siz2intcls[] = { [1] = KI32, [2] = KI32, [4] = KI32, [8] = KI64 };
@@ -71,6 +74,7 @@ irinit(struct function *fn)
type2cls[TYARRAY] = KPTR;
cls2siz[KPTR] = targ_primsizes[TYPTR];
cls2load[KPTR] = targ_64bit ? Oloadi64 : Oloads32;
+ cls2store[KPTR] = targ_64bit ? Ostorei64 : Ostorei32;
}
fn->entry = fn->curblk = allocz(fn->arena, sizeof(struct block), 0);
fn->nblk = 1;
@@ -513,6 +517,7 @@ replcuses(union ref from, union ref to)
} else if (instrtab[use->u].op == Ophi) {
u = phitab.p[instrtab[use->u].l.i];
n = use->blk->npred;
+ if (use->blk->phi.n == 0) continue; /* shouldn't happen */
} else {
u = &instrtab[use->u].l;
n = 2;
diff --git a/ir/ir.h b/ir/ir.h
index 8402864..5fe5e96 100644
--- a/ir/ir.h
+++ b/ir/ir.h
@@ -101,7 +101,7 @@ enum op {
#define oiscmp(o) in_range(o, Oequ, Ougte)
#define oisarith(o) in_range(o, Oneg, Ougte)
#define oisalloca(o) in_range(o, Oalloca1, Oalloca16)
-#define oisstore(o) in_range(o, Ostore8, Ostore64)
+#define oisstore(o) in_range(o, Ostorei8, Ostoref64)
#define oisload(o) in_range(o, Oloads8, Oloadf64)
extern const char *opnames[];
extern const uchar opnarg[];
@@ -235,6 +235,7 @@ enum { MAXINSTR = 1<<15 };
extern uchar type2cls[];
extern uchar cls2siz[];
extern uchar cls2load[];
+extern uchar cls2store[];
extern const uchar siz2intcls[];
extern struct instr instrtab[];
extern struct use *instruse[];
diff --git a/ir/mem2reg.c b/ir/mem2reg.c
index 4b0b007..7a5874c 100644
--- a/ir/mem2reg.c
+++ b/ir/mem2reg.c
@@ -15,10 +15,18 @@ static const uchar load2ext[] = {
[Oloads32 - Oloads8] = Oexts32, [Oloadu32 - Oloads8] = Oextu32,
[Oloadi64 - Oloads8] = Ocopy,
};
+static const uchar storesz[] = {
+ [Ostorei8 - Ostorei8] = 1,
+ [Ostorei16 - Ostorei8] = 2,
+ [Ostorei32 - Ostorei8] = 4,
+ [Ostorei64 - Ostorei8] = 8,
+ [Ostoref32 - Ostorei8] = 4,
+ [Ostoref64 - Ostorei8] = 8,
+};
#define loadsz(o) (loadszcls[(o) - Oloads8] & 0xF)
#define loadcls(o) (loadszcls[(o) - Oloads8] >> 4)
#define load2ext(o) (load2ext[(o) - Oloads8])
-#define storesz(o) (1 << ((o) - Ostore8))
+#define storesz(o) (storesz[(o) - Ostorei8])
/* Implements algorithm in 'Simple and Efficient Construction of Static Single Assignment' (Braun et al) */
diff --git a/ir/op.def b/ir/op.def
index 2476ecf..ac753c0 100644
--- a/ir/op.def
+++ b/ir/op.def
@@ -57,10 +57,12 @@ _(loadu32, 1)
_(loadi64, 1)
_(loadf32, 1)
_(loadf64, 1)
-_(store8, 2)
-_(store16, 2)
-_(store32, 2)
-_(store64, 2)
+_(storei8, 2)
+_(storei16, 2)
+_(storei32, 2)
+_(storei64, 2)
+_(storef32, 2)
+_(storef64, 2)
_(param, 2)
_(arg, 2)
_(call, 2)
diff --git a/ir/regalloc.c b/ir/regalloc.c
index 9678559..39a3f74 100644
--- a/ir/regalloc.c
+++ b/ir/regalloc.c
@@ -264,7 +264,7 @@ emitmove(enum irclass k, union alloc dst, union alloc src, struct block *blk, in
addstkslotref(insertinstr(blk, curi++, mv).i, src.a*8);
} else reg = src.a;
if (dst.t == ASTACK) {
- mv = mkinstr(Ostore8+ilog2(cls2siz[k]), 0, .r = mkref(RREG, reg));
+ mv = mkinstr(cls2store[k], 0, .r = mkref(RREG, reg));
addstkslotref(insertinstr(blk, curi, mv).i, dst.a*8);
}
}
@@ -1137,7 +1137,7 @@ devirt(struct rega *ra, struct block *blk)
alloc = temp < ra->intervals.ntemps && (it = &ra->intervals.temps[temp]) && it->nrange ? &it->alloc : NULL;
if (alloc && alloc->t == ASTACK) {
enum irclass cls = insrescls(*ins);
- int store = Ostore8 + ilog2(cls2siz[cls]);
+ int store = cls2store[cls];
/* t was spilled, gen store */
if (ins->op == Ocopy && ins->l.t != RADDR) {
ins->op = store;
@@ -1171,7 +1171,7 @@ devirt(struct rega *ra, struct block *blk)
}
}
}
- if (!ins->reg && insrescls(*ins) && ins->op != Omove && !ins->keep && !in_range(ins->op, Ostore8, Ostore64)) {
+ if (!ins->reg && insrescls(*ins) && ins->op != Omove && !ins->keep && !oisstore(ins->op)) {
/* dead */
Nop:
ins->op = Onop;
diff --git a/x86_64/emit.c b/x86_64/emit.c
index b0b4f58..783ea20 100644
--- a/x86_64/emit.c
+++ b/x86_64/emit.c
@@ -979,14 +979,14 @@ emitinstr(uchar **pcode, struct function *fn, struct block *blk, int curi, struc
dst = reg2oper(ins->reg-1);
gencopy(pcode, cls, blk, curi, dst, ins->l);
break;
- case Ostore8: cls = KI32, X = Xmovb; goto Store;
- case Ostore16: cls = KI32, X = Xmovw; goto Store;
- case Ostore32: cls = KI32, X = Xmov; goto Store;
- case Ostore64: cls = KI64, X = Xmov;
+ case Ostorei8: cls = KI32, X = Xmovb; goto Store;
+ case Ostorei16: cls = KI32, X = Xmovw; goto Store;
+ case Ostorei32: cls = KI32, X = Xmov; goto Store;
+ case Ostorei64: cls = KI64, X = Xmov; goto Store;
+ case Ostoref32: cls = KF32, X = Xmov; goto Store;
+ case Ostoref64: cls = KF64, X = Xmov; goto Store;
Store:
src = mkimmregoper(ins->r);
- if (cls == KI32 && src.t == OREG && src.reg >= XMM0) cls = KF32;
- if (cls == KI64 && src.t == OREG && src.reg >= XMM0) cls = KF64;
X(pcode, cls, mkmemoper(ins->l), src);
break;
case Oexts8: src = mkregoper(ins->l); goto Movsxb;
diff --git a/x86_64/isel.c b/x86_64/isel.c
index d69f9ad..8a845ef 100644
--- a/x86_64/isel.c
+++ b/x86_64/isel.c
@@ -139,7 +139,7 @@ selcall(struct function *fn, struct instr *ins, struct block *blk, int *curi)
union ref adr = mkaddr((struct addr){mkref(RREG, RSP), .disp = abi.stk});
int iargsave = iarg;
if (!abi.ty.isagg) { /* scalar arg in stack */
- *arg = mkinstr(Ostore8+ilog2(cls2siz[abi.ty.cls]), 0, adr, arg->r);
+ *arg = mkinstr(cls2store[abi.ty.cls], 0, adr, arg->r);
if (isaddrcon(arg->r,1) || arg->r.t == RADDR)
arg->r = insertinstr(blk, iarg++, mkinstr(Ocopy, abi.ty.cls, arg->r));
else
@@ -497,7 +497,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
case Oloads32: case Oloadu32: case Oloadi64: case Oloadf32: case Oloadf64:
loadstoreaddr(blk, &ins->l, curi);
break;
- case Ostore8: case Ostore16: case Ostore32: case Ostore64:
+ case Ostorei8: case Ostorei16: case Ostorei32: case Ostorei64: case Ostoref32: case Ostoref64:
loadstoreaddr(blk, &ins->l, curi);
if (isaddrcon(ins->r,1) || ins->r.t == RADDR)
ins->r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, ins->r));
diff --git a/x86_64/sysv.c b/x86_64/sysv.c
index 6313b07..317f40f 100644
--- a/x86_64/sysv.c
+++ b/x86_64/sysv.c
@@ -195,16 +195,16 @@ vastart(struct function *fn, struct block *blk, int *curi)
*ins = mkinstr(Oadd, KPTR, ap, mkref(RICON, 16));
dst = mkref(RTMP, ins - instrtab);
int i = *curi + 1;
- insertinstr(blk, i++, mkinstr(Ostore64, 0, dst, rsave));
+ insertinstr(blk, i++, mkinstr(Ostorei64, 0, dst, rsave));
/* set ap->overflow_arg_area */
src = insertinstr(blk, i++, mkinstr(Oadd, KPTR, mkref(RREG, RBP), mkref(RICON, 16+stk0)));
dst = insertinstr(blk, i++, mkinstr(Oadd, KPTR, ap, mkref(RICON, 8)));
- insertinstr(blk, i++, mkinstr(Ostore64, 0, dst, src));
+ insertinstr(blk, i++, mkinstr(Ostorei64, 0, dst, src));
/* set ap->gp_offset */
- insertinstr(blk, i++, mkinstr(Ostore32, 0, ap, mkref(RICON, gpr0*8)));
+ insertinstr(blk, i++, mkinstr(Ostorei32, 0, ap, mkref(RICON, gpr0*8)));
/* set ap->fp_offset */
dst = insertinstr(blk, i++, mkinstr(Oadd, KPTR, ap, mkref(RICON, 4)));
- insertinstr(blk, i++, mkinstr(Ostore32, 0, dst, mkref(RICON, 6*8 + fpr0*16)));
+ insertinstr(blk, i++, mkinstr(Ostorei32, 0, dst, mkref(RICON, 6*8 + fpr0*16)));
*curi = i-1;
}
@@ -246,7 +246,7 @@ vaarg(struct function *fn, struct block *blk, int *curi)
phiargs[0] = irbinop(fn, Oadd, KPTR, sav, roff);
/* l->gp/fp_offset += num_gp/fp * 8(16) */
roff = irbinop(fn, Oadd, KI32, roff, mkref(RICON, ni ? ni * 8 : nf * 16));
- addinstr(fn, mkinstr(Ostore32, 0, irbinop(fn, Oadd, KPTR, ap, mkref(RICON, ni ? 0 : 4)), roff));
+ addinstr(fn, mkinstr(Ostorei32, 0, irbinop(fn, Oadd, KPTR, ap, mkref(RICON, ni ? 0 : 4)), roff));
assert(merge->npred == 1);
blkpred(merge, 0) = blk->s1;
blk->s1->jmp.t = Jb;
@@ -262,7 +262,7 @@ vaarg(struct function *fn, struct block *blk, int *curi)
phiargs[1] = ovf;
/* update l->overflow_arg_area += size */
int siz = 8;
- addinstr(fn, mkinstr(Ostore64, 0, adr, irbinop(fn, Oadd, KPTR, ovf, mkref(RICON, siz))));
+ addinstr(fn, mkinstr(Ostorei64, 0, adr, irbinop(fn, Oadd, KPTR, ovf, mkref(RICON, siz))));
putbranch(fn, merge);
}
assert(merge->npred == 2);
@@ -276,7 +276,7 @@ vaarg(struct function *fn, struct block *blk, int *curi)
} else {
instrtab[var] = mkalloca(8, 8);
tmp = insertinstr(merge, 1, mkinstr(Oloadi64, KI64, phi));
- insertinstr(merge, 2, mkinstr(Ostore64, 0, mkref(RTMP, var), tmp));
+ insertinstr(merge, 2, mkinstr(Ostorei64, 0, mkref(RTMP, var), tmp));
}
fn->prop &= ~FNUSE;
} else {