diff options
| author | 2022-08-24 11:26:37 +0200 | |
|---|---|---|
| committer | 2022-08-24 11:26:53 +0200 | |
| commit | 333728ad37cae80f3ab53aaeb2c98352eb787b5f (patch) | |
| tree | ded570ab8d21ffc1a9ec6c29f8102771e4d8729c | |
| parent | 82e537ceec82c4956710e4ef2d08f73fad8bfa01 (diff) | |
enum ini
| -rw-r--r-- | bootstrap/test2.cff | 34 | ||||
| -rw-r--r-- | src/llvm.cff | 54 | ||||
| -rw-r--r-- | x | 19 |
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; @@ -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 -} |