aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-24 11:26:37 +0200
committerlemon <lsof@mailbox.org>2022-08-24 11:26:53 +0200
commit333728ad37cae80f3ab53aaeb2c98352eb787b5f (patch)
treeded570ab8d21ffc1a9ec6c29f8102771e4d8729c
parent82e537ceec82c4956710e4ef2d08f73fad8bfa01 (diff)
enum ini
-rw-r--r--bootstrap/test2.cff34
-rw-r--r--src/llvm.cff54
-rw-r--r--x19
3 files changed, 50 insertions, 57 deletions
diff --git a/bootstrap/test2.cff b/bootstrap/test2.cff
index d267036..0c546bb 100644
--- a/bootstrap/test2.cff
+++ b/bootstrap/test2.cff
@@ -45,37 +45,5 @@ extern fn main() void {
x = X + 1 + Y;
let const v= Value:None;
- switch v {
- case None;
- case Int i;
- i;
- case Flo *f;
- let x f32 = *f;
- }
- let t = v.#tag;
- let i = v.Int;
- // v.#tag++;
-
- #'outer for let i = 0; i++ < 10; {
- printf("%d\n", i);
- while #t {
- if i < 2 {
- continue #'outer;
- }
- break #'outer;
- }
- }
-
- let x = Option<int>:Some(3);
- let x = Option<f32>:None;
-
- printf("n %d\n", n.value);
- printf("n link %d\n", n.link.value);
-
- let x Node<f32> = {};
- n->ok();
- x->ok();
-
- Bit<i32>:foo(3);
- Bit<i64>:foo(3);
+ v = :Int(1 + x);
}
diff --git a/src/llvm.cff b/src/llvm.cff
index 56a28ed..d266cbb 100644
--- a/src/llvm.cff
+++ b/src/llvm.cff
@@ -225,9 +225,14 @@ fn genaddr(f *Fn, ex *Expr) Value {
case Dot dot;
let lhs = dot.lhs.ty->is(:Ptr) ? genexpr(f, dot.lhs) : genaddr(f, dot.lhs);
assert(dot.fld.off % dot.fld.ty.align == 0, "field align");
- let idx int = dot.fld.off / dot.fld.ty.align;
+ let idx int = dot.fld - ex.ty.u.Agg.flds.#ptr;
let addr = mktmp(mkptrtype(ex.ty));
- gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", addr, lhs.ty.u.Ptr, lhs.ty, lhs, idx);
+ switch lhs.ty.u.Ptr.u.Agg.kind {
+ case :Struct;
+ gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", addr, lhs.ty.u.Ptr, lhs.ty, lhs, idx);
+ case :Union;
+ gen("\t%v = bitcast %t %v to %v", addr, lhs.ty, lhs, addr.ty);
+ }
return addr;
case AggIni ini;
@@ -237,8 +242,13 @@ fn genaddr(f *Fn, ex *Expr) Value {
foreach(fld, i, ini.flds) {
let fex = &ini.exs[i];
let ptr = mktmp(mkptrtype(fex.ty));
- let idx int = fld.off / fld.ty.align;
- gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", ptr, ex.ty, tmp.ty, tmp, idx);
+ let idx int = fld - ex.ty.u.Agg.flds.#ptr;
+ switch ex.ty.u.Agg.kind {
+ case :Struct;
+ gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", ptr, ex.ty, tmp.ty, tmp, idx);
+ case :Union;
+ gen("\t%v = bitcast %t %v to %t\n", ptr, tmp.ty, tmp, ptr.ty);
+ }
gen("\tstore %t %v, %t %v\n", fex.ty, convert(f, fld.ty, fex), ptr.ty, ptr);
}
return tmp;
@@ -247,7 +257,8 @@ fn genaddr(f *Fn, ex *Expr) Value {
}
fn convert(f *Fn, to *const Type, ex *Expr) Value {
- let from = ex.ty;
+ to = unconstify(to);
+ let from = unconstify(ex.ty);
defmacro cvt(inst) [
(do let t = mktmp(to),
@@ -286,6 +297,21 @@ fn convert(f *Fn, to *const Type, ex *Expr) Value {
case to->is(:Flo) and from->is(:Flo) and to.size < from.size;
return cvt("fptrunc");
+
+ case to->is(:Flo) and from->is(:Int);
+ return cvt(from.u.Int.sgn ? "sitofp" : "uitofp");
+
+ case to->is(:Int) and from->is(:Flo) and to.size < ty_int.size;
+ let t0 = mktmp(ty_int);
+ let val = genexpr(f, ex);
+ gen("\t%v = fptosi %t %v to %t\n", t0, from, val, ty_int);
+ let t1 = mktmp(to);
+ gen("\t%v =%s %t %v to %t\n", t1, to.u.Int.sgn ? "sext" : "zext", t0.ty, t0, to);
+ return t1;
+
+ case to->is(:Int) and from->is(:Flo);
+ return cvt(to.u.Int.sgn ? "fptosi" : "fptoui");
+
case to->is(:Ptr) and from->is(:Ptr);
let t = mktmp(to),
@@ -574,6 +600,24 @@ fn genexpr(f *Fn, ex *Expr) Value {
gen("\t%v = load %t, %t %v\n", val, ex.ty, tmp.ty, tmp);
return val;
+ case EUnionIni ini;
+ let t0 = mktmp(mkptrtype(ex.ty));
+ let vidx = ini.var - ex.ty.u.Agg.flds.#ptr;
+ gen("\t%v = alloca %t\n", t0, ex.ty);
+ gen("\tstore %t zeroinitializer, %t %v\n", ex.ty, t0.ty, t0);
+ gen("\tstore %t %d, %t %v\n", ex.ty.u.Agg.enumty.u.Enum.intty, vidx, t0.ty, t0);
+ if ini.var.ty != #null {
+ let tini = convert(f, ini.var.ty, ini.ex);
+ let t1 = mktmp(mkptrtype(ini.var.ty));
+ gen("\t%v = bitcast %t %v to %t\n", t1, t0.ty, t0, t1.ty);
+ let t2 = mktmp(t1.ty);
+ gen("\t%v = getelementptr %t, %t %v, i32 1\n", t2, ini.var.ty, t1.ty, t1);
+ gen("\tstore %t %v, %t %v\n", tini.ty, tini, t2.ty, t2);
+ }
+ let res = mktmp(ex.ty);
+ gen("\t%v = load %t, %t %v\n", res, res.ty, t0.ty, t0);
+ return res;
+
case Stmt block;
switch genblock(f, block) {
case Some val; return val;
diff --git a/x b/x
deleted file mode 100644
index d04c37d..0000000
--- a/x
+++ /dev/null
@@ -1,19 +0,0 @@
-target triple = "x86_64-pc-linux-gnu"
-%Vec2f.0 = type opaque
-%Vec2f.0 = type { float, float }
-
-define internal float @x.1(%Vec2f.0 %v) {
-%v.0 = alloca %Vec2f.0 store %Vec2f.0 %v, %Vec2f.0* %v.0
- %t1 = getelementptr %Vec2f.0, %Vec2f.0* %v.0, i32 0, i32 0
- %t0 = load float, float* %t1
- ret float %t0
- ret float undef
-}
-define internal float @y.2(%Vec2f.0* %v) {
-%v.0 = alloca %Vec2f.0* store %Vec2f.0* %v, %Vec2f.0** %v.0
- %t1 = load %Vec2f.0*, %Vec2f.0** %v.0
- %t2 = getelementptr %Vec2f.0, %Vec2f.0* %t1, i32 0, i32 1
- %t0 = load float, float* %t2
- ret float %t0
- ret float undef
-}