diff options
| author | 2022-08-24 16:00:45 +0200 | |
|---|---|---|
| committer | 2022-08-24 16:00:45 +0200 | |
| commit | a61dd9694409ef82fd24178bc99a794df55e1f04 (patch) | |
| tree | 2dcf053740477ef7e87b2a8e97cab8b918907984 | |
| parent | 9f320002800b0a8b7601528334f97ba64182bdd6 (diff) | |
and/or
| -rw-r--r-- | examples/life.cff | 4 | ||||
| -rw-r--r-- | src/llvm.cff | 45 |
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)}; |