aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-09-14 19:23:21 +0200
committerlemon <lsof@mailbox.org>2025-09-14 19:23:21 +0200
commit6cb4382b0128942f4ba57ab26021be1e5715f2bc (patch)
tree0b63731286acbe503981958930aeae93816b6b34
parent7a318363ec4fdcd80d9d0154cef393c9bf205d5e (diff)
codegen: float cmp, ior; frontend: fix cond expr bug
-rw-r--r--amd64/emit.c19
-rw-r--r--amd64/isel.c7
-rw-r--r--c.c9
-rw-r--r--test/regpressure.c7
-rw-r--r--test/test4.c19
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];
diff --git a/c.c b/c.c
index 2d484c4..d7a9ff6 100644
--- a/c.c
+++ b/c.c
@@ -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;
+}
+