From 6464ec389e2da17b1674858858406e211b16e5f6 Mon Sep 17 00:00:00 2001 From: lemon Date: Sun, 23 Nov 2025 21:54:40 +0100 Subject: ir: implement cvtu64f. and other bug fixes compiler is bootstrapping?! however, stage1 and stage2+ executables aren't bit-identical.. small differences in the codegen.. need to look into that --- ir/builder.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'ir/builder.c') diff --git a/ir/builder.c b/ir/builder.c index 752c1bc..c793f80 100644 --- a/ir/builder.c +++ b/ir/builder.c @@ -20,6 +20,7 @@ irbinop(struct function *fn, enum op op, enum irclass k, union ref l, union ref break; case Omul: if (isnumcon(l)) rswap(l, r); /* put const in rhs */ + if (kisflt(k)) break; if (r.bits == ZEROREF.bits) /* x * 0 ==> 0 */ return ZEROREF; if (r.bits == ONE.bits) /* x * 1 ==> x */ @@ -33,6 +34,7 @@ irbinop(struct function *fn, enum op op, enum irclass k, union ref l, union ref case Odiv: break; case Oudiv: + if (kisflt(k)) break; if (isintcon(r) && ispo2(iv = intconval(r))) { /* x / 2^y ==> x >> y */ op = Oslr; @@ -42,6 +44,7 @@ irbinop(struct function *fn, enum op op, enum irclass k, union ref l, union ref case Orem: break; case Ourem: + if (kisflt(k)) break; if (isintcon(r) && ispo2(iv = intconval(r))) { /* x % 2^y ==> x & 2^y-1 */ op = Oand; @@ -123,6 +126,33 @@ cvtfu64(struct function *fn, enum irclass from, union ref x) return addphi(fn, KI64, phiarg); } +/* implements u64 -> f32/f64 conversion */ +static union ref +cvtu64f(struct function *fn, enum irclass to, union ref x) +{ + struct block *t, *f, *merge; + union ref t1, t2, phiarg[2]; + + /* if ((s64)x >= 0) cvts64f(x) else cvts64f((x>>1)|(x&1))*2 */ + + putcondbranch(fn, irbinop(fn, Ogte, KI64, x, ZEROREF), t = newblk(fn), f = newblk(fn)); + + useblk(fn, t); + phiarg[0] = irunop(fn, Ocvts64f, to, x); + putbranch(fn, merge = newblk(fn)); + + useblk(fn, f); + t1 = irbinop(fn, Oslr, KI64, x, mkref(RICON, 1)); + t2 = irbinop(fn, Oand, KI64, x, mkref(RICON, 1)); + t1 = irbinop(fn, Oior, KI64, t1, t2); + t1 = irunop(fn, Ocvts64f, to, t1); + phiarg[1] = irbinop(fn, Oadd, to, t1, t1); + putbranch(fn, merge); + + useblk(fn, merge); + return addphi(fn, to, phiarg); +} + union ref irunop(struct function *fn, enum op op, enum irclass k, union ref a) { @@ -141,6 +171,8 @@ irunop(struct function *fn, enum op op, enum irclass k, union ref a) return ins->l; break; case Ocvtf32s: case Ocvtf32f64: case Ocvtf64s: + case Ocvtf64f32: case Ocvts32f: case Ocvtu32f: + case Ocvts64f: break; case Ocvtf32u: case Ocvtf64u: if (k == KI64) { @@ -150,8 +182,9 @@ irunop(struct function *fn, enum op op, enum irclass k, union ref a) return cvtfu64(fn, op == Ocvtf32u ? KF32 : KF64, a); } break; - case Ocvtf64f32: case Ocvts32f: case Ocvtu32f: - case Ocvts64f: case Ocvtu64f: + case Ocvtu64f: + /* XXX see above */ + return cvtu64f(fn, k, a); case Oexts8: case Oextu8: case Oexts16: case Oextu16: case Oexts32: case Oextu32: case Ocopy: -- cgit v1.2.3