aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-24 16:00:45 +0200
committerlemon <lsof@mailbox.org>2022-08-24 16:00:45 +0200
commita61dd9694409ef82fd24178bc99a794df55e1f04 (patch)
tree2dcf053740477ef7e87b2a8e97cab8b918907984
parent9f320002800b0a8b7601528334f97ba64182bdd6 (diff)
and/or
-rw-r--r--examples/life.cff4
-rw-r--r--src/llvm.cff45
2 files changed, 40 insertions, 9 deletions
diff --git a/examples/life.cff b/examples/life.cff
index cd1cc2e..791916f 100644
--- a/examples/life.cff
+++ b/examples/life.cff
@@ -32,9 +32,7 @@ fn next(b *Board) void {
set(b, x, y, #f);
if get(&temp, x, y) {
set(b, x, y, n == 3);
- } else if n == 2 {
- set(b, x, y, #t);
- } else if n == 3 {
+ } else if n == 2 or n == 3 {
set(b, x, y, #t);
}
}
diff --git a/src/llvm.cff b/src/llvm.cff
index 57390a0..e2659af 100644
--- a/src/llvm.cff
+++ b/src/llvm.cff
@@ -356,6 +356,7 @@ fn convert(f *Fn, to *const Type, ex *Expr) Value {
}
fn genblock(f *Fn, block Block) Option<Value>;
+fn llvmbool(f *Fn, ex *Expr) Value;
fn genexpr(f *Fn, ex *Expr) Value {
fold(ex);
@@ -502,9 +503,39 @@ fn genexpr(f *Fn, ex *Expr) Value {
case '^='; return genassignop("xor", ex.ty, b.lhs, b.rhs);
case'<<='; return genassignop("shl", ex.ty, b.lhs, b.rhs);
case'>>='; return genassignop(ex.ty.u.Int.sgn ? "ashr" : "lshr", ex.ty, b.lhs, b.rhs);
- // case 'and';
- // case 'or';
-
+ case 'or';
+ static orid int = {};
+ let id = orid++;
+ let lhs = genexpr(f, b.lhs);
+ let cnd = mktmp(ty_i1);
+ let res = mktmp(ex.ty);
+ gen("\tbr label %%OrEntry%d\n", id);
+ gen("OrEntry%d: ", id);
+ gen("\t%v = icmp ne %t %v, 0\n", cnd, lhs.ty, lhs);
+ gen("\tbr i1 %v, label %%OrT%d, label %%OrF%d\n", cnd, id, id);
+ gen("OrF%d: ", id);
+ let rhs = genexpr(f, b.rhs);
+ gen("\tbr label %%OrT%d\n", cnd, id, id);
+ gen("OrT%d: ", id);
+ gen("\t%v = phi %t [ %v, %%OrEntry%d ], [ %v, %%OrF%d ]\n", res, ex.ty, lhs, id, rhs, id);
+ return res;
+
+ case 'and';
+ static andid int = {};
+ let id = andid++;
+ let lhs = genexpr(f, b.lhs);
+ let cnd = mktmp(ty_i1);
+ let res = mktmp(ex.ty);
+ gen("\tbr label %%AndEntry%d\n", id);
+ gen("AndEntry%d: ", id);
+ gen("\t%v = icmp ne %t %v, 0\n", cnd, lhs.ty, lhs);
+ gen("\tbr i1 %v, label %%AndT%d, label %%AndF%d\n", cnd, id, id);
+ gen("AndT%d: ", id);
+ let rhs = genexpr(f, b.rhs);
+ gen("\tbr label %%AndF%d\n", cnd, id, id);
+ gen("AndF%d: ", id);
+ gen("\t%v = phi %t [ %v, %%AndEntry%d ], [ %v, %%AndT%d ]\n", res, ex.ty, lhs, id, rhs, id);
+ return res;
case else
assert(#f, "binop? %c", b.op);
@@ -526,9 +557,11 @@ fn genexpr(f *Fn, ex *Expr) Value {
return tmp;
case :not;
- let tmp = mktmp(ex.ty);
- gen("\t%v = xor %t 1, %v\n", tmp, ex.ty, convert(f, ex.ty, un.ex));
- return tmp;
+ let tmp = mktmp(ty_i1);
+ gen("\t%v = xor i1 1, %v\n", tmp, ex.ty, llvmbool(f, un.ex));
+ let res = mktmp(ex.ty);
+ gen("\t%v = zext i1 %v to %t\n", res, tmp, res.ty);
+ return res;
case :preinc, :predec;
let one = Value{ex.ty, :IImm(un.op == :preinc ? 1 : -1)};