diff options
| author | 2022-08-24 09:29:01 +0200 | |
|---|---|---|
| committer | 2022-08-24 09:29:01 +0200 | |
| commit | 82e537ceec82c4956710e4ef2d08f73fad8bfa01 (patch) | |
| tree | 54a3859afc17a479bed182883903275d805415c4 | |
| parent | ca3b09c836af6878ce3879ef91d7ba75f9898cb8 (diff) | |
opaque ptrs
| -rw-r--r-- | examples/vec2f.hff | 8 | ||||
| -rw-r--r-- | src/cffc.hff | 1 | ||||
| -rw-r--r-- | src/llvm.cff | 80 |
3 files changed, 62 insertions, 27 deletions
diff --git a/examples/vec2f.hff b/examples/vec2f.hff index 38687eb..0a40b40 100644 --- a/examples/vec2f.hff +++ b/examples/vec2f.hff @@ -9,8 +9,8 @@ struct Vec2f { return v.y; } - #{ fn add(l Vec2f, r Vec2f) Vec2f { - return { l.x + r.x, l.y + r.y }; - } - } +} + +extern fn add(l Vec2f, r Vec2f) Vec2f { + return { l.x + r.x, l.y + r.y }; } diff --git a/src/cffc.hff b/src/cffc.hff index 882793f..7e1e579 100644 --- a/src/cffc.hff +++ b/src/cffc.hff @@ -485,6 +485,5 @@ extern static g_asmbackend Backend; // llvm.cff extern fn llvm_addfn(*Decl) void; extern fn llvm_genfn(externp bool, name *const u8, f *Fn) void; -extern fn llvm_addtype(*const Type) void; extern fn llvm_init(*FILE) void; extern fn llvm_fini() void; diff --git a/src/llvm.cff b/src/llvm.cff index 7a84690..56a28ed 100644 --- a/src/llvm.cff +++ b/src/llvm.cff @@ -28,7 +28,7 @@ fn gen(fmt *const u8, ...) void; extern fn genagg(ty *const Type) void { let agg = &ty.u.Agg; if agg.fwd { - gen("%.type.opaque"); + gen("%%.type.opaque"); } else if agg.flds.#len == 0 { gen("{ i8 }"); } else if agg.kind == :Struct { @@ -85,8 +85,9 @@ fn gen(fmt *const u8, ...) void { case Bool; gen("i%z", ty.size*8); case Int; gen("i%z", ty.size*8); case Flo; gen(ty.size == 4 ? "float" : "double"); - case Ptr p; gen("%t*", p->is(:Void) ? ty_i8 : p); - case Slice p; gen("{ %t*, %t }", p, ty_usize); + // case Ptr p; gen("%t*", p->is(:Void) ? ty_i8 : p); + case Ptr p; gen("ptr"); + case Slice p; gen("{ %t, %t }", mkptrtype(p), ty_usize); case Arr arr; gen("[%z x %t]", arr.length, arr.child); case Agg; genagg(ty); @@ -180,6 +181,7 @@ fn mktmp(ty *const Type) Value { return Value{ty, :Tmp(tmpid++)}; } +fn convert(f *Fn, to *const Type, ex *Expr) Value; fn genexpr(f *Fn, ex *Expr) Value; static arena Arena = {}; static alloc Allocator = {}; @@ -217,16 +219,29 @@ fn genaddr(f *Fn, ex *Expr) Value { } let rhs = genexpr(f, idx.rhs), addr = mktmp(ex.ty); - gen("\t%v = getelementptr %t, %t* %v, %t %v\n", addr, ex.ty, ex.ty, lhs, rhs.ty, rhs); + gen("\t%v = getelementptr %t, %t %v, %t %v\n", addr, ex.ty, lhs.ty, lhs, rhs.ty, rhs); return addr; 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 addr = mktmp(ex.ty); + 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); return addr; + + case AggIni ini; + let tmp = mktmp(mkptrtype(ex.ty)); + gen("\t%v = alloca %t\n", tmp, ex.ty); + gen("\tstore %t zeroinitializer, %t %v\n", ex.ty, tmp.ty, tmp); + 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); + gen("\tstore %t %v, %t %v\n", fex.ty, convert(f, fld.ty, fex), ptr.ty, ptr); + } + return tmp; } assert(#f, "genaddr"); } @@ -302,8 +317,9 @@ fn genexpr(f *Fn, ex *Expr) Value { case FloLit f; return {ex.ty, :FImm(f)}; case BoolLit b; return {ex.ty, :BImm(b)}; case NullLit; return {ex.ty, :Null}; - case ZeroIni; return {ex.ty, :ZeroIni}; - case StrLit s; return {ex.ty, :StrLit(s)}; + case ZeroIni; return {ex.ty, :ZeroIni}; + case EnumIni i; return {ex.ty, :IImm(i)}; + case StrLit s; return {ex.ty, :StrLit(s)}; case BinOp b; defmacro genbinop(a, b, inst) [ (do @@ -375,7 +391,7 @@ fn genexpr(f *Fn, ex *Expr) Value { gen("\t%v = %s %t %v, %v\n", t, inst, ex.ty, lhs0, rhs); t; ); - gen("\tstore %t %v, %t* %v\n", tmp.ty, tmp, ex.ty, addr); + gen("\tstore %t %v, %t %v\n", tmp.ty, tmp, addr.ty, addr); rhs; ) ] @@ -408,7 +424,7 @@ fn genexpr(f *Fn, ex *Expr) Value { case '='; let addr = genaddr(f, b.lhs); let rhs = convert(f, b.lhs.ty, b.rhs); - gen("\tstore %t %v, %t* %v\n", ex.ty, rhs, ex.ty, addr); + gen("\tstore %t %v, %t %v\n", ex.ty, rhs, addr.ty, addr); return rhs; case '+='; let addr = genaddr(f, b.lhs); @@ -416,7 +432,7 @@ fn genexpr(f *Fn, ex *Expr) Value { let lhs0 = mktmp(ex.ty); gen("\t%v = load %t, %t %v\n", lhs0, ex.ty, addr.ty, addr); let tmp = genadd(ex.ty, lhs0, rhs); - gen("\tstore %t %v, %t* %v\n", tmp.ty, tmp, ex.ty, addr); + gen("\tstore %t %v, %t %v\n", tmp.ty, tmp, addr.ty, addr); return rhs; case '-='; @@ -425,7 +441,7 @@ fn genexpr(f *Fn, ex *Expr) Value { let lhs0 = mktmp(ex.ty); gen("\t%v = load %t, %t %v\n", lhs0, ex.ty, addr.ty, addr); let tmp = gensub(ex.ty, lhs0, rhs); - gen("\tstore %t %v, %t* %v\n", tmp.ty, tmp, ex.ty, addr); + gen("\tstore %t %v, %t %v\n", tmp.ty, tmp, addr.ty, addr); return rhs; case '*='; return genassignop(ex.ty->is(:Flo) ? "fdiv" : "mul", ex.ty, b.lhs, b.rhs); @@ -445,18 +461,32 @@ fn genexpr(f *Fn, ex *Expr) Value { } case UnOp un; switch un.op { + case :neg; + let tmp = mktmp(ex.ty); + if ex.ty->is(:Int) { + gen("\t%v = sub %t 0, %v\n", tmp, ex.ty, convert(f, ex.ty, un.ex)); + } else { + gen("\t%v = fsub %t 0.0, %v\n", tmp, ex.ty, convert(f, ex.ty, un.ex)); + } + return tmp; + + case :compl; + let tmp = mktmp(ex.ty); + gen("\t%v = xor %t -1, %v\n", tmp, ex.ty, convert(f, ex.ty, un.ex)); + return tmp; + case :preinc, :predec; let one = Value{ex.ty, :IImm(un.op == :preinc ? 1 : -1)}; let addr = genaddr(f, un.ex); let var = mktmp(ex.ty); let val = mktmp(ex.ty); - gen("\t%v = load %t, %t* %v\n", var, ex.ty, ex.ty, addr); + gen("\t%v = load %t, %t %v\n", var, ex.ty, addr.ty, addr); if ex.ty->is(:Ptr) { gen("\t%v = getelementptr %t, %t %v, i32 %v\n", val, ex.ty.u.Ptr, ex.ty, var, one); } else { gen("\t%v = add %t %v, %v\n", val, ex.ty, var, one); } - gen("\tstore %t %v, %t* %v\n", ex.ty, val, ex.ty, addr); + gen("\tstore %t %v, %t %v\n", ex.ty, val, addr.ty, addr); return val; case :postinc, :postdec; @@ -464,19 +494,19 @@ fn genexpr(f *Fn, ex *Expr) Value { let addr = genaddr(f, un.ex); let var = mktmp(ex.ty); let val = mktmp(ex.ty); - gen("\t%v = load %t, %t* %v\n", var, ex.ty, ex.ty, addr); + gen("\t%v = load %t, %t %v\n", var, ex.ty, addr.ty, addr); if ex.ty->is(:Ptr) { gen("\t%v = getelementptr %t, %t %v, i32 %v\n", val, ex.ty.u.Ptr, ex.ty, var, one); } else { gen("\t%v = add %t %v, %v\n", val, ex.ty, var, one); } - gen("\tstore %t %v, %t* %v\n", ex.ty, val, ex.ty, addr); + gen("\tstore %t %v, %t %v\n", ex.ty, val, addr.ty, addr); return var; case :deref; let rhs = genexpr(f, un.ex); let val = mktmp(ex.ty); - gen("\t%v = load %t, %t* %v\n", val, ex.ty, ex.ty, rhs); + gen("\t%v = load %t, %t %v\n", val, ex.ty, rhs.ty, rhs); return val; case :addrof; @@ -489,13 +519,13 @@ fn genexpr(f *Fn, ex *Expr) Value { case Index; let tmp = mktmp(ex.ty); let addr = genaddr(f, ex); - gen("\t%v = load %t, %t* %v\n", tmp, ex.ty, ex.ty, addr); + gen("\t%v = load %t, %t %v\n", tmp, ex.ty, addr.ty, addr); return tmp; case Dot; let tmp = mktmp(ex.ty); let addr = genaddr(f, ex); - gen("\t%v = load %t, %t* %v\n", tmp, ex.ty, ex.ty, addr); + gen("\t%v = load %t, %t %v\n", tmp, ex.ty, addr.ty, addr); return tmp; case Cast it; @@ -508,7 +538,7 @@ fn genexpr(f *Fn, ex *Expr) Value { case else let tmp = mktmp(ex.ty); let addr = genaddr(f, ex); - gen("\t%v = load %t, %t* %v\n", tmp, ex.ty, ex.ty, addr); + gen("\t%v = load %t, %t %v\n", tmp, ex.ty, addr.ty, addr); return tmp; } case Call call; @@ -538,6 +568,12 @@ fn genexpr(f *Fn, ex *Expr) Value { gen(")\n"); return t; + case AggIni ini; + let tmp = genaddr(f, ex); + let val = mktmp(ex.ty); + gen("\t%v = load %t, %t %v\n", val, ex.ty, tmp.ty, tmp); + return val; + case Stmt block; switch genblock(f, block) { case Some val; return val; @@ -579,8 +615,8 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void { ty = var.ty; gen("\t%%%s.%d = alloca %t\n", nam, var.id, ty); if !var.ini->empty() { - gen("\tstore %t %v, %t* %%%s.%d\n", - ty, convert(f, ty, &var.ini.Some), ty, nam, var.id); + gen("\tstore %t %v, %t %%%s.%d\n", + ty, convert(f, ty, &var.ini.Some), mkptrtype(ty), nam, var.id); } } case If *cnd; @@ -728,7 +764,7 @@ extern fn llvm_genfn(externp bool, name *const u8, f *Fn) void { if nam { let ty = f.ty.u.Fn.params[i]; gen("%%%s.%d = alloca %t ", nam, id, ty); - gen("store %t %%%s, %t* %%%s.%d\n", ty, nam, ty, nam, id); + gen("store %t %%%s, %t %%%s.%d\n", ty, nam, mkptrtype(ty), nam, id); ++id; } } |