diff options
| -rw-r--r-- | amd64/emit.c | 19 | ||||
| -rw-r--r-- | amd64/isel.c | 7 | ||||
| -rw-r--r-- | c.c | 9 | ||||
| -rw-r--r-- | test/regpressure.c | 7 | ||||
| -rw-r--r-- | test/test4.c | 19 |
5 files changed, 48 insertions, 13 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index 7c88955..28fda92 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -540,6 +540,14 @@ DEFINSTR2(Xand, {4|8, PGPR, PI32, "\x81", EN_RI32, .ext=4}, /* AND r32/64, imm */ { 8, PGPR, PMEM, "\x23", EN_RM}, /* AND r64, m64 */ ) +DEFINSTR2(Xior, + {4|8, PGPR, PGPR, "\x0B", EN_RR}, /* OR r32/64, r32/64 */ + {4|8, PGPR, PI8, "\x83", EN_RI8, .ext=1}, /* OR r32/64, imm8 */ + {4|8, PRAX, PI32, "\x0D", EN_I32}, /* OR eax/rax, imm */ + {4|8, PGPR, PI32, "\x81", EN_RI32, .ext=1}, /* OR r32/64, imm */ + { 8, PGPR, PMEM, "\x0B", EN_RM}, /* OR r64, m64 */ + {4|8, PFPR, PFPR, "\x0F\x57", EN_RR}, /* ORPS xmm, xmm */ +) DEFINSTR2(Xxor, {4|8, PGPR, PGPR, "\x33", EN_RR}, /* XOR r32/64, r32/64 */ {4|8, PGPR, PI8, "\x83", EN_RI8, .ext=6}, /* XOR r32/64, imm8 */ @@ -586,6 +594,10 @@ DEFINSTR2(Xcmp, {4|8, PRAX, PI32, "\x3D", EN_I32}, /* CMP eax/rax, imm */ {4|8, PGPR, PI32, "\x81", EN_RI32, .ext=7}, /* CMP r32/64, imm */ { 8, PGPR, PMEM, "\x3B", EN_RM}, /* CMP r64, m64 */ + {4 , PFPR, PFPR, "\x0F\x2F", EN_RR}, /* COMISS xmm, xmm */ + {4 , PFPR, PMEM, "\x0F\x2F", EN_RM}, /* COMISS xmm, m32 */ + { 8, PFPR, PFPR, "\x66\x0F\x2F", EN_RR}, /* COMISD xmm, xmm */ + { 8, PFPR, PMEM, "\x66\x0F\x2F", EN_RM}, /* COMISD xmm, m64 */ ) DEFINSTR2(Xtest, {4|8, PRAX, PI8, "\xA8", EN_I8}, /* TEST AL, imm8 */ @@ -896,6 +908,7 @@ emitinstr(uchar **pcode, struct function *fn, struct block *blk, int curi, struc X = Xand; goto ALU2; case Oxor: X = Xxor; goto ALU2; + case Oior: X = Xior; goto ALU2; ALU2: dst = mkregoper(ins->l); assert(ins->reg-1 == dst.reg); @@ -943,10 +956,10 @@ emitinstr(uchar **pcode, struct function *fn, struct block *blk, int curi, struc Xxor(pcode, KI4, dst, dst); regzeroed = 1; } - if (ins->r.bits != ZEROREF.bits) - Xcmp(pcode, cls, dst, src); - else + if (kisint(ins->cls) && ins->r.bits == ZEROREF.bits) Xtest(pcode, cls, dst, dst); + else + Xcmp(pcode, cls, dst, src); if (ins->reg) { enum cc cc; dst = reg2oper(ins->reg-1); diff --git a/amd64/isel.c b/amd64/isel.c index 1054502..5cd5526 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -65,9 +65,12 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi) /* add X, INT32MAX+1 -> sub X, INT32MIN */ ins->op = Oadd + (op == Oadd); *r = mkintcon(KI4, -2147483648); - } else if ((in_range(op, Ocopy, Omove) || op == Ophi) && kisflt(con->cls) && con->f == 0) { + } else if (kisflt(con->cls) && con->f == 0) { /* copy of float zero -> regular zero, that emit() will turn into xor x,x */ - *r = mkref(RICON, 0); + if (in_range(op, Ocopy, Omove) || op == Ophi) + *r = ZEROREF; + else + *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, con->cls, ZEROREF)); } else if (kisflt(con->cls) || con->cls == KI8) { /* float immediates & >32b immediates are loaded from memory */ uchar data[8]; @@ -2531,7 +2531,6 @@ condexprrec(struct function *fn, const struct expr *ex, struct condphis *phis, int boolcon, struct block *const next, struct block *end) { struct block *tr, *fl; - union ref r; while (ex->t == ESEQ) { expreffects(fn, &ex->sub[0]); ex = &ex->sub[1]; @@ -2555,16 +2554,16 @@ condexprrec(struct function *fn, const struct expr *ex, struct condphis *phis, useblk(fn, fl); condexprrec(fn, &ex->sub[2], phis, -1, end, end); } else { - r = exprvalue(fn, ex); + union ref r = exprvalue(fn, ex), val = r; if (boolcon >= 0) { if (!next || next == end) { boolcon = -1; - r = cvt(fn, TYBOOL, ex->ty.t, r); + val = cvt(fn, TYBOOL, ex->ty.t, r); } else { - r = mkref(RICON, boolcon); + val = mkref(RICON, boolcon); } } - vpush(&phis->ref, r); + vpush(&phis->ref, val); if (next && next != end) { putcondbranch(fn, r, next, end); } else { diff --git a/test/regpressure.c b/test/regpressure.c index 6a0708c..1d65294 100644 --- a/test/regpressure.c +++ b/test/regpressure.c @@ -1,8 +1,9 @@ int foo(int a, int b, int c, int d, int e, int f, int (*g)(void)) { - void bar(void); - bar(); + int aa[4]; + void bar(int *); + bar(aa); if (a>0) f-=10*(g()&f); - bar(); + bar(aa); return a + b + c + d + e + f + g(); } diff --git a/test/test4.c b/test/test4.c new file mode 100644 index 0000000..4a127d0 --- /dev/null +++ b/test/test4.c @@ -0,0 +1,19 @@ +int xor(int a) { + return a ^ 3 | 233333; +} + +int cmp(float x, float y) { + return x < y && x > 0.f; +} + +int main() { + int x = 42, + *a = &x, + **b = &a, + ***c = &b, + ****d = &c, + *****e = &d, + ******f = &e; + return ******f; +} + |