aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-24 09:29:01 +0200
committerlemon <lsof@mailbox.org>2022-08-24 09:29:01 +0200
commit82e537ceec82c4956710e4ef2d08f73fad8bfa01 (patch)
tree54a3859afc17a479bed182883903275d805415c4
parentca3b09c836af6878ce3879ef91d7ba75f9898cb8 (diff)
opaque ptrs
-rw-r--r--examples/vec2f.hff8
-rw-r--r--src/cffc.hff1
-rw-r--r--src/llvm.cff80
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;
}
}