aboutsummaryrefslogtreecommitdiff
path: root/src/llvm.cff
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm.cff')
-rw-r--r--src/llvm.cff350
1 files changed, 177 insertions, 173 deletions
diff --git a/src/llvm.cff b/src/llvm.cff
index 1a7f24a..1e9eb03 100644
--- a/src/llvm.cff
+++ b/src/llvm.cff
@@ -23,8 +23,6 @@ struct Value {
}
}
-static ty_i1 Type = {}; // dummy
-
fn gen(fmt *const u8, ...) void;
extern fn genagg(ty *const Type) void {
let agg = &ty.u.Agg;
@@ -80,15 +78,14 @@ extern fn llvm_addtype(ty *const Type) void {
}
}
-
fn gendata(ty *const Type, ex *Expr) void;
fn gen(fmt *const u8, ...) void {
let ap va_list #?;
ap->start(fmt);
fn pritype(ty *const Type) void {
- if ty == &ty_i1 {
- gen("i1");
+ if ty == #null {
+ gen("(nil)");
return;
}
switch ty.u {
@@ -139,7 +136,7 @@ fn gen(fmt *const u8, ...) void {
case 's';
fprintf(outfp, "%s", ap->arg(*const u8));
case 'S';
- let str = ap->arg([#]const u8);
+ let str = *ap->arg(*[#]const u8);
fputc('"', outfp);
foreach(c, _, str) {
extern fn isprint(int) int;
@@ -162,7 +159,7 @@ fn gen(fmt *const u8, ...) void {
case 'z';
fprintf(outfp, "%zu", ap->arg(usize));
case 'v';
- let val = ap->arg(Value);
+ let val = ap->arg(*const Value);
switch val.u {
case IImm i; gen("%I", i);
case FImm f; gen(val.ty.size == 4 ? "%f" : "%F", f);
@@ -194,7 +191,7 @@ fn gen(fmt *const u8, ...) void {
}
case StrConstRef id;
gen("@.str.%d", id);
- case StrLit s;
+ case StrLit *s;
gen("c%S", s);
case else
assert(#f, "value? %d", val.u.#tag);
@@ -222,7 +219,7 @@ fn mktmp(ty *const Type) Value {
defmacro gentmp(type, ...rest) [
(do
let $tmp = mktmp(type);
- gen("\t%v = ", $tmp);
+ gen("\t%v = ", &$tmp);
gen(rest);
gen("\n");
$tmp;
@@ -267,18 +264,18 @@ fn genref(f *Fn, ex *Expr) Ref {
switch idx.lhs.ty.u {
case Arr arrty;
let arr = genref(f, idx.lhs).Addr;
- lhs = gentmp(mkptrtype(ex.ty), "getelementptr %t, %t %v, i32 0, i32 0", idx.lhs.ty, arr.ty, arr);
+ lhs = gentmp(mkptrtype(ex.ty), "getelementptr %t, %t %v, i32 0, i32 0", idx.lhs.ty, arr.ty, &arr);
case Ptr;
lhs = genexpr(f, idx.lhs);
case Slice child;
let tmp = genexpr(f, idx.lhs);
- lhs = gentmp(mkptrtype(child), "extractvalue %t %v, 0", tmp.ty, tmp);
+ lhs = gentmp(mkptrtype(child), "extractvalue %t %v, 0", tmp.ty, &tmp);
case else;
assert(#f, "index");
}
let rhs = genexpr(f, idx.rhs);
let addr = gentmp(mkptrtype(ex.ty), "getelementptr %t, %t %v, %t %v",
- ex.ty, lhs.ty, lhs, rhs.ty, rhs);
+ ex.ty, lhs.ty, &lhs, rhs.ty, &rhs);
return :Addr(addr);
case Dot dot;
@@ -297,12 +294,12 @@ fn genref(f *Fn, ex *Expr) Ref {
switch lhs.ty.u.Ptr.u.Agg.kind {
case :Struct;
addr = gentmp(ptrty, "getelementptr %t, %t %v, i32 0, i32 %d",
- lhs.ty.u.Ptr, lhs.ty, lhs, idx);
+ lhs.ty.u.Ptr, lhs.ty, &lhs, idx);
case :Union;
- addr = gentmp(ptrty, "bitcast %t %v to %t", lhs.ty, lhs, ptrty);
+ addr = gentmp(ptrty, "bitcast %t %v to %t", lhs.ty, &lhs, ptrty);
case else
let off int = dot.fld.off;
- addr = gentmp(ptrty, "getelementptr i8, %t %v, i32 %d", lhs.ty, lhs, off);
+ addr = gentmp(ptrty, "getelementptr i8, %t %v, i32 %d", lhs.ty, &lhs, off);
}
return :Addr(addr);
@@ -311,7 +308,7 @@ fn genref(f *Fn, ex *Expr) Ref {
case EUTag eex;
let lhs = eex.ty->is(:Ptr) ? genexpr(f, eex) : genref(f, eex).Addr;
- let addr = gentmp(mkptrtype(ex.ty), "bitcast %t %v to %t", lhs.ty, lhs, mkptrtype(ex.ty));
+ let addr = gentmp(mkptrtype(ex.ty), "bitcast %t %v to %t", lhs.ty, &lhs, mkptrtype(ex.ty));
return :Addr(addr);
case BitRaw ex;
@@ -319,37 +316,39 @@ fn genref(f *Fn, ex *Expr) Ref {
case AggIni ini;
let tmp = gentmp(mkptrtype(ex.ty), "alloca %t", ex.ty);
- gen("\tstore %t zeroinitializer, %t %v\n", ex.ty, tmp.ty, tmp);
+ 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 - 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);
+ 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("\t%v = bitcast %t %v to %t\n", &ptr, tmp.ty, &tmp, ptr.ty);
}
- gen("\tstore %t %v, %t %v\n", fld.ty, convert(f, fld.ty, fex), ptr.ty, ptr);
+ let it = convert(f, fld.ty, fex);
+ gen("\tstore %t %v, %t %v\n", fld.ty, &it, ptr.ty, &ptr);
}
return :Addr(tmp);
case ArrIni ini;
let ty = mkarrtype(ini.maxn, #f, ex.ty.u.Arr.child);
let tmp = gentmp(mkptrtype(ty), "alloca %t", ty);
- gen("\tstore %t zeroinitializer, %t %v\n", ty, tmp.ty, tmp);
+ gen("\tstore %t zeroinitializer, %t %v\n", ty, tmp.ty, &tmp);
foreach(idx, i, ini.idxs) {
let fex = &ini.exs[i];
let ptr = mktmp(mkptrtype(fex.ty));
- gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", ptr, ty, tmp.ty, tmp, idx);
- gen("\tstore %t %v, %t %v\n", fex.ty, convert(f, ty.u.Arr.child, fex), ptr.ty, ptr);
+ gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", &ptr, ty, tmp.ty, &tmp, idx);
+ let it = convert(f, ty.u.Arr.child, fex);
+ gen("\tstore %t %v, %t %v\n", fex.ty, &it, ptr.ty, &ptr);
}
return :Addr(tmp);
case else
let it = genexpr(f, ex);
let tmp = gentmp(mkptrtype(ex.ty), "alloca %t", ex.ty);
- gen("store %t %v, %t %v", it.ty, it, tmp.ty, tmp);
+ gen("store %t %v, %t %v", it.ty, &it, tmp.ty, &tmp);
return :Addr(tmp);
}
assert(#f, "genref %d", ex.u.#tag);
@@ -358,22 +357,22 @@ fn genref(f *Fn, ex *Expr) Ref {
fn genload(f *Fn, ref Ref) Value {
switch ref {
case Addr addr;
- return gentmp(addr.ty.u.Ptr, "load %t, %t %v", addr.ty.u.Ptr, addr.ty, addr);
+ return gentmp(addr.ty.u.Ptr, "load %t, %t %v", addr.ty.u.Ptr, addr.ty, &addr);
case BitDot dot;
let intty = dot.lhs.ty.u.BitF.intty;
let fld = dot.fld;
let lhs = genload(f, :Addr(dot.lhs));
- let shifted = fld.off == 0 ? lhs : gentmp(lhs.ty, "lshr %t %v, %d", lhs.ty, lhs, fld.off);
- let truncd = gentmp(#null, "trunc %t %v to i%d", shifted.ty, shifted, fld.size);
+ let shifted = fld.off == 0 ? lhs : gentmp(lhs.ty, "lshr %t %v, %d", lhs.ty, &lhs, fld.off);
+ let truncd = gentmp(#null, "trunc %t %v to i%d", shifted.ty, &shifted, fld.size);
let res = mktmp(fld.ty);
switch {
case dot.fld.ty->is(:Bool);
- let tmp = gentmp(&ty_i1, "icmp ne i%d %v, 0", fld.size, truncd);
- gen("\t%v = zext i1 %v to %t\n", res, tmp, res.ty);
+ let tmp = gentmp(#null, "icmp ne i%d %v, 0", fld.size, &truncd);
+ gen("\t%v = zext i1 %v to %t\n", &res, &tmp, res.ty);
case dot.fld.ty->is(:Int);
- gen("\t%v = %s i%d %v to %t\n", res,
- dot.fld.ty.u.Int.sgn ? "sext" : "zext", fld.size, truncd, lhs.ty);
+ gen("\t%v = %s i%d %v to %t\n", &res,
+ dot.fld.ty.u.Int.sgn ? "sext" : "zext", fld.size, &truncd, lhs.ty);
case else assert(#f, "");
}
return res;
@@ -382,8 +381,8 @@ fn genload(f *Fn, ref Ref) Value {
fn genstore(f *Fn, ref Ref, v Value) void {
switch ref {
- case Addr addr;
- gen("\tstore %t %v, %t %v\n", v.ty, v, addr.ty, addr);
+ case Addr *addr;
+ gen("\tstore %t %v, %t %v\n", v.ty, &v, addr.ty, addr);
case BitDot dot;
let intty = dot.lhs.ty.u.BitF.intty;
@@ -391,14 +390,14 @@ fn genstore(f *Fn, ref Ref, v Value) void {
let srcmask = fld.size == 64 ? ~0u64 : ((1u64 << fld.size) - 1);
let addr = dot.lhs;
let src0 = v;
- let src = gentmp(intty, "and %t %v, %I", intty, src0, srcmask);
- let src = gentmp(intty, "shl %t %v, %d", src.ty, src, fld.off);
+ let src = gentmp(intty, "and %t %v, %I", intty, &src0, srcmask);
+ let src = gentmp(intty, "shl %t %v, %d", src.ty, &src, fld.off);
let dstmask = ~(srcmask << fld.off);
- let lhs = gentmp(intty, "load %t, %t %v", intty, addr.ty, addr);
+ let lhs = gentmp(intty, "load %t, %t %v", intty, addr.ty, &addr);
let lhs = genload(f, :Addr(addr));
- let lhs = gentmp(lhs.ty, "and %t %v, %I", lhs.ty, lhs, dstmask);
- let raw = gentmp(lhs.ty, "or %t %v, %v", lhs.ty, lhs, src);
- gen("\tstore %t %v, %t %v\n", raw.ty, raw, addr.ty, addr);
+ let lhs = gentmp(lhs.ty, "and %t %v, %I", lhs.ty, &lhs, dstmask);
+ let raw = gentmp(lhs.ty, "or %t %v, %v", lhs.ty, &lhs, &src);
+ gen("\tstore %t %v, %t %v\n", raw.ty, &raw, addr.ty, &addr);
}
}
@@ -411,7 +410,7 @@ fn convert(f *Fn, to *const Type, ex *Expr) Value {
defmacro cvt(inst) [
(do let $t = mktmp(to),
val = genexpr(f, ex);
- gen("\t%v = %s %t %v to %t\n", $t, inst, from, val, to);
+ gen("\t%v = %s %t %v to %t\n", &$t, inst, from, &val, to);
$t;
)
]
@@ -449,26 +448,28 @@ fn convert(f *Fn, to *const Type, ex *Expr) Value {
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);
+ gen("\t%v = fptosi %t %v to %t\n", &t0, from, &val, ty_int);
let t1 = mktmp(to);
- gen("\t%v = trunc %t %v to %t\n", t1, t0.ty, t0, to);
+ gen("\t%v = trunc %t %v to %t\n", &t1, 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(:Int) and from->is(:Bool);
- let t0 = mktmp(&ty_i1);
- gen("\t%v = icmp ne %t %v, 0\n", t0, ex.ty, genexpr(f, ex));
+ let t0 = mktmp(#null);
+ let b = genexpr(f, ex);
+ gen("\t%v = icmp ne %t %v, 0\n", &t0, ex.ty, &b);
let t1 = mktmp(to);
- gen("\t%v = zext %t %v to %t\n", t1, t0.ty, t0, t1.ty);
+ gen("\t%v = zext %t %v to %t\n", &t1, t0.ty, &t0, t1.ty);
return t1;
case to->is(:Bool) and from->is(:Int);
- let t0 = mktmp(&ty_i1);
- gen("\t%v = icmp ne %t %v, 0\n", t0, ex.ty, genexpr(f, ex));
+ let t0 = mktmp(#null);
+ let b = genexpr(f, ex);
+ gen("\t%v = icmp ne %t %v, 0\n", &t0, ex.ty, &b);
let t1 = mktmp(to);
- gen("\t%v = zext %t %v to %t\n", t1, t0.ty, t0, t1.ty);
+ gen("\t%v = zext %t %v to %t\n", &t1, t0.ty, &t0, t1.ty);
return t1;
case to->is(:Ptr) and from->is(:Ptr);
@@ -480,7 +481,7 @@ fn convert(f *Fn, to *const Type, ex *Expr) Value {
case to->is(:Ptr) and from->is(:Arr);
let addr = genref(f, ex).Addr;
let t = mktmp(ex.ty);
- gen("\t%v = getelementptr %t, %t %v, %t 0, %t 0\n", t, addr.ty.u.Ptr, addr.ty, addr,
+ gen("\t%v = getelementptr %t, %t %v, %t 0, %t 0\n", &t, addr.ty.u.Ptr, addr.ty, &addr,
ty_usize, ty_usize);
return t;
@@ -493,6 +494,9 @@ 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 nop() Value {
+ return gentmp(ty_i8, "bitcast i8 0 to i8 ; NOP");
+}
fn genexpr(f *Fn, ex *Expr) Value {
fold(ex);
@@ -510,7 +514,7 @@ fn genexpr(f *Fn, ex *Expr) Value {
let lhs = convert(f, ex.ty, a),
rhs = convert(f, ex.ty, b),
t = mktmp(ex.ty);
- gen("\t%v = %s %t %v, %v\n", t, inst, ex.ty, lhs, rhs);
+ gen("\t%v = %s %t %v, %v\n", &t, inst, ex.ty, &lhs, &rhs);
t;
)
]
@@ -520,27 +524,26 @@ fn genexpr(f *Fn, ex *Expr) Value {
rhs = convert(f, ty2, b.rhs),
t0 = mktmp(ex.ty),
t1 = mktmp(ex.ty);
- gen("\t%v = %s %s %t %v, %v\n", t0, ty2->is(:Flo) ? "fcmp" : "icmp", op,
- ty2, lhs, rhs);
- gen("\t%v = zext i1 %v to %t\n", t1, t0, ex.ty);
+ gen("\t%v = %s %s %t %v, %v\n", &t0, ty2->is(:Flo) ? "fcmp" : "icmp", op,
+ ty2, &lhs, &rhs);
+ gen("\t%v = zext i1 %v to %t\n", &t1, &t0, ex.ty);
return t1;
} ]
defmacro genadd(type, lhs, rhs) [
(do
let res Value #?;
if isnumtype(type) {
- let $t = mktmp(type);
- gen("\t%v = %s %t %v, %v\n", $t, ex.ty->is(:Flo) ? "fadd" : "add", ex.ty, lhs, rhs);
+ let $t = gentmp(type, "%s %t %v, %v", ex.ty->is(:Flo) ? "fadd" : "add", ex.ty, &lhs, &rhs);
res = $t;
} else if lhs.ty->is(:Ptr) {
let $t = mktmp(type);
gen("\t%v = getelementptr %t, %t %v, %t %v\n",
- $t, lhs.ty.u.Ptr, lhs.ty, lhs, rhs.ty, rhs);
+ &$t, lhs.ty.u.Ptr, lhs.ty, &lhs, rhs.ty, &rhs);
res = $t;
} else if rhs.ty->is(:Ptr) {
let $t = mktmp(type);
gen("\t%v = getelementptr %t, %t %v, %t %v\n",
- $t, rhs.ty.u.Ptr, rhs.ty, rhs, rhs.ty, lhs);
+ &$t, rhs.ty.u.Ptr, rhs.ty, &rhs, rhs.ty, &lhs);
res = $t;
} else {
assert(#f, "bad ad");
@@ -553,20 +556,20 @@ fn genexpr(f *Fn, ex *Expr) Value {
let res Value #?;
if isnumtype(type) and !lhs.ty->is(:Ptr) {
let $t = mktmp(type);
- gen("\t%v = %s %t %v, %v\n", $t, ex.ty->is(:Flo) ? "fsub" : "sub", ex.ty, lhs, rhs);
+ gen("\t%v = %s %t %v, %v\n", &$t, ex.ty->is(:Flo) ? "fsub" : "sub", ex.ty, &lhs, &rhs);
res = $t;
} else if lhs.ty->is(:Ptr) and rhs.ty->is(:Int) {
let $off = mktmp(rhs.ty);
- gen("\t%v = sub %t 0, %v\n", $off, rhs.ty, rhs);
+ gen("\t%v = sub %t 0, %v\n", &$off, rhs.ty, &rhs);
let $t = mktmp(type);
gen("\t%v = getelementptr %t, %t %v, %t %v\n",
- $t, lhs.ty.u.Ptr == ty_void ? ty_i8 : lhs.ty.u.Ptr, lhs.ty, lhs, $off.ty, $off);
+ &$t, lhs.ty.u.Ptr == ty_void ? ty_i8 : lhs.ty.u.Ptr, lhs.ty, &lhs, $off.ty, &$off);
res = $t;
} else if lhs.ty->is(:Ptr) and rhs.ty->is(:Ptr) {
- let $l = gentmp(ty_isize, "ptrtoint ptr %v to %t", lhs, ty_isize);
- let $r = gentmp(ty_isize, "ptrtoint ptr %v to %t", rhs, ty_isize);
- let $diff = gentmp(ty_isize, "sub %t %v, %v", ty_isize, $l, $r);
- let $res = gentmp(ty_isize, "sdiv %t %v, %v", ty_isize, $l, $r);
+ let $l = gentmp(ty_isize, "ptrtoint ptr %v to %t", &lhs, ty_isize);
+ let $r = gentmp(ty_isize, "ptrtoint ptr %v to %t", &rhs, ty_isize);
+ let $diff = gentmp(ty_isize, "sub %t %v, %v", ty_isize, &$l, &$r);
+ let $res = gentmp(ty_isize, "sdiv %t %v, %v", ty_isize, &$l, &$r);
return $res;
} else {
assert(#f, "bad sub");
@@ -579,7 +582,7 @@ fn genexpr(f *Fn, ex *Expr) Value {
let ref = genref(f, a);
let rhs = convert(f, a.ty, b);
let lhs0 = genload(f, ref);
- let tmp = gentmp(ex.ty, "%s %t %v, %v", inst, ex.ty, lhs0, rhs);
+ let tmp = gentmp(ex.ty, "%s %t %v, %v", inst, ex.ty, &lhs0, &rhs);
genstore(f, ref, tmp);
genload(f, ref); // load again because value could have overflowed when storing it
)
@@ -648,57 +651,57 @@ fn genexpr(f *Fn, ex *Expr) Value {
static orid int = {};
let id = orid++;
let lhs = genexpr(f, b.lhs);
- let cnd = mktmp(&ty_i1);
+ let cnd = mktmp(#null);
let tmpvar = mktmp(mkptrtype(ex.ty));
let res = mktmp(ex.ty);
- gen("\t%v = alloca %t\n", tmpvar, ex.ty);
- gen("\tstore %t %v, %t %v\n", ex.ty, lhs, tmpvar.ty, tmpvar);
- 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("\t%v = alloca %t\n", &tmpvar, ex.ty);
+ gen("\tstore %t %v, %t %v\n", ex.ty, &lhs, tmpvar.ty, &tmpvar);
+ 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("\tstore %t %v, %t %v\n", ex.ty, rhs, tmpvar.ty, tmpvar);
- gen("\tbr label %%OrT%d\n", cnd, id, id);
+ gen("\tstore %t %v, %t %v\n", ex.ty, &rhs, tmpvar.ty, &tmpvar);
+ gen("\tbr label %%OrT%d\n", id);
gen("OrT%d: ", id);
- gen("\t%v = load %t, %t %v\n", res, ex.ty, tmpvar.ty, tmpvar);
+ gen("\t%v = load %t, %t %v\n", &res, ex.ty, tmpvar.ty, &tmpvar);
return res;
case 'and';
static andid int = {};
let id = andid++;
let lhs = genexpr(f, b.lhs);
- let cnd = mktmp(&ty_i1);
+ let cnd = mktmp(#null);
let tmpvar = mktmp(mkptrtype(ex.ty));
let res = mktmp(ex.ty);
- gen("\t%v = alloca %t\n", tmpvar, ex.ty);
- gen("\tstore %t %v, %t %v\n", ex.ty, lhs, tmpvar.ty, tmpvar);
- 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("\t%v = alloca %t\n", &tmpvar, ex.ty);
+ gen("\tstore %t %v, %t %v\n", ex.ty, &lhs, tmpvar.ty, &tmpvar);
+ 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("\tstore %t %v, %t %v\n", ex.ty, rhs, tmpvar.ty, tmpvar);
- gen("\tbr label %%AndF%d\n", cnd, id, id);
+ gen("\tstore %t %v, %t %v\n", ex.ty, &rhs, tmpvar.ty, &tmpvar);
+ gen("\tbr label %%AndF%d\n", id);
gen("AndF%d: ", id);
- gen("\t%v = load %t, %t %v\n", res, ex.ty, tmpvar.ty, tmpvar);
+ gen("\t%v = load %t, %t %v\n", &res, ex.ty, tmpvar.ty, &tmpvar);
return res;
case '??';
static orid int = {};
let id = orid++;
let lhs = genexpr(f, b.lhs);
- let cnd = mktmp(&ty_i1);
+ let cnd = mktmp(#null);
let tmpvar = mktmp(mkptrtype(ex.ty));
let res = mktmp(ex.ty);
- gen("\t%v = alloca %t\n", tmpvar, ex.ty);
- gen("\tstore %t %v, %t %v\n", ex.ty, lhs, tmpvar.ty, tmpvar);
- gen("\t%v = icmp ne %t %v, null\n", cnd, lhs.ty, lhs);
- gen("\tbr i1 %v, label %%OrT%d, label %%OrF%d\n", cnd, id, id);
+ gen("\t%v = alloca %t\n", &tmpvar, ex.ty);
+ gen("\tstore %t %v, %t %v\n", ex.ty, &lhs, tmpvar.ty, &tmpvar);
+ gen("\t%v = icmp ne %t %v, null\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("\tstore %t %v, %t %v\n", ex.ty, rhs, tmpvar.ty, tmpvar);
- gen("\tbr label %%OrT%d\n", cnd, id, id);
+ gen("\tstore %t %v, %t %v\n", ex.ty, &rhs, tmpvar.ty, &tmpvar);
+ gen("\tbr label %%OrT%d\n", &cnd, id, id);
gen("OrT%d: ", id);
- gen("\t%v = load %t, %t %v\n", res, ex.ty, tmpvar.ty, tmpvar);
+ gen("\t%v = load %t, %t %v\n", &res, ex.ty, tmpvar.ty, &tmpvar);
return res;
case else
@@ -708,45 +711,48 @@ fn genexpr(f *Fn, ex *Expr) Value {
static condid int = {};
let id = condid++;
let lhs = genexpr(f, cond.test);
- let cnd = mktmp(&ty_i1);
+ let cnd = mktmp(#null);
let tmpvar = mktmp(mkptrtype(ex.ty));
let res = mktmp(ex.ty);
- gen("\t%v = alloca %t\n", tmpvar, ex.ty);
- gen("\t%v = icmp ne %t %v, %s\n", cnd, lhs.ty, lhs, lhs.ty->is(:Ptr) ? "null" : "0");
- gen("\tbr i1 %v, label %%CondT%d, label %%CondF%d\n", cnd, id, id);
+ gen("\t%v = alloca %t\n", &tmpvar, ex.ty);
+ gen("\t%v = icmp ne %t %v, %s\n", &cnd, lhs.ty, &lhs, lhs.ty->is(:Ptr) ? "null" : "0");
+ gen("\tbr i1 %v, label %%CondT%d, label %%CondF%d\n", &cnd, id, id);
gen("CondT%d: ", id);
let t = convert(f, ex.ty, cond.t);
- gen("\tstore %t %v, %t %v\n", ex.ty, t, tmpvar.ty, tmpvar);
- gen("\tbr label %%CondFin%d\n", cnd, id, id);
+ gen("\tstore %t %v, %t %v\n", ex.ty, &t, tmpvar.ty, &tmpvar);
+ gen("\tbr label %%CondFin%d\n", id);
gen("CondF%d: ", id);
let f = convert(f, ex.ty, cond.f);
- gen("\tstore %t %v, %t %v\n", ex.ty, f, tmpvar.ty, tmpvar);
- gen("\tbr label %%CondFin%d\n", cnd, id, id);
+ gen("\tstore %t %v, %t %v\n", ex.ty, &f, tmpvar.ty, &tmpvar);
+ gen("\tbr label %%CondFin%d\n", id);
gen("CondFin%d: ", id);
- gen("\t%v = load %t, %t %v\n", res, ex.ty, tmpvar.ty, tmpvar);
+ gen("\t%v = load %t, %t %v\n", &res, ex.ty, tmpvar.ty, &tmpvar);
return res;
case UnOp un;
switch un.op {
case :neg;
let tmp = mktmp(ex.ty);
+ let rhs = convert(f, ex.ty, un.ex);
if ex.ty->is(:Int) {
- gen("\t%v = sub %t 0, %v\n", tmp, ex.ty, convert(f, ex.ty, un.ex));
+ gen("\t%v = sub %t 0, %v\n", &tmp, ex.ty, &rhs);
} else {
- gen("\t%v = fsub %t 0.0, %v\n", tmp, ex.ty, convert(f, ex.ty, un.ex));
+ gen("\t%v = fsub %t 0.0, %v\n", &tmp, ex.ty, &rhs);
}
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));
+ let rhs = convert(f, ex.ty, un.ex);
+ gen("\t%v = xor %t -1, %v\n", &tmp, ex.ty, &rhs);
return tmp;
case :not;
- let tmp = mktmp(&ty_i1);
- gen("\t%v = xor i1 1, %v\n", tmp, ex.ty, llvmbool(f, un.ex));
+ let tmp = mktmp(#null);
+ let rhs = llvmbool(f, un.ex);
+ gen("\t%v = xor i1 1, %v\n", &tmp, &rhs);
let res = mktmp(ex.ty);
- gen("\t%v = zext i1 %v to %t\n", res, tmp, res.ty);
+ gen("\t%v = zext i1 %v to %t\n", &res, &tmp, res.ty);
return res;
case :preinc, :predec;
@@ -755,9 +761,9 @@ fn genexpr(f *Fn, ex *Expr) Value {
let val = mktmp(ex.ty);
let var = genload(f, ref);
if ex.ty->is(:Ptr) {
- gen("\t%v = getelementptr %t, %t %v, i32 %v\n", val, ex.ty.u.Ptr, ex.ty, var, one);
+ 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("\t%v = add %t %v, %v\n", &val, ex.ty, &var, &one);
}
genstore(f, ref, val);
return genload(f, ref); // load again because value could have overflowed when storing it
@@ -768,9 +774,9 @@ fn genexpr(f *Fn, ex *Expr) Value {
let val = mktmp(ex.ty);
let var = genload(f, ref);
if ex.ty->is(:Ptr) {
- gen("\t%v = getelementptr %t, %t %v, i32 %v\n", val, ex.ty.u.Ptr, ex.ty, var, one);
+ 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("\t%v = add %t %v, %v\n", &val, ex.ty, &var, &one);
}
genstore(f, ref, val);
return var;
@@ -778,7 +784,7 @@ fn genexpr(f *Fn, ex *Expr) Value {
case :deref;
let rhs = genexpr(f, un.ex);
let val = mktmp(ex.ty);
- gen("\t%v = load %t, %t %v\n", val, ex.ty, rhs.ty, rhs);
+ gen("\t%v = load %t, %t %v\n", &val, ex.ty, rhs.ty, &rhs);
return val;
case :addrof;
@@ -806,13 +812,13 @@ fn genexpr(f *Fn, ex *Expr) Value {
case SPtr sl;
let sl = genexpr(f, sl);
let ptr = mktmp(mkptrtype(sl.ty.u.Slice));
- gen("\t%v = extractvalue %t %v, 0\n", ptr, sl.ty, sl);
+ gen("\t%v = extractvalue %t %v, 0\n", &ptr, sl.ty, &sl);
return ptr;
case SLen sl;
let sl = genexpr(f, sl);
let len = mktmp(ty_usize);
- gen("\t%v = extractvalue %t %v, 1\n", len, sl.ty, sl);
+ gen("\t%v = extractvalue %t %v, 1\n", &len, sl.ty, &sl);
return len;
case EUTag;
@@ -837,41 +843,41 @@ fn genexpr(f *Fn, ex *Expr) Value {
let begin = convert(f, ty_usize, sl.begin);
let end = convert(f, ty_usize, sl.end);
let len = mktmp(ty_usize);
- gen("\t%v = sub %t %v, %v\n", len, ty_usize, end, begin);
+ gen("\t%v = sub %t %v, %v\n", &len, ty_usize, &end, &begin);
let addr2 = mktmp(addr.ty);
- gen("\t%v = getelementptr %t, %t %v, %t %v\n", addr2, ex.ty.u.Slice, addr.ty, addr, ty_usize, begin);
+ gen("\t%v = getelementptr %t, %t %v, %t %v\n", &addr2, ex.ty.u.Slice, addr.ty, &addr, ty_usize, &begin);
let tmp = mktmp(ex.ty);
- gen("\t%v = insertvalue %t undef, %t %v, 0\n", tmp, ex.ty, addr2.ty, addr2);
+ gen("\t%v = insertvalue %t undef, %t %v, 0\n", &tmp, ex.ty, addr2.ty, &addr2);
let res = mktmp(ex.ty);
- gen("\t%v = insertvalue %t %v, %t %v, 1\n", res, ex.ty, tmp, len.ty, len);
+ gen("\t%v = insertvalue %t %v, %t %v, 1\n", &res, ex.ty, &tmp, len.ty, &len);
return res;
} else if sl.lhs.ty.u.#tag == :Ptr {
let addr = genexpr(f, sl.lhs);
let begin = convert(f, ty_usize, sl.begin);
let end = convert(f, ty_usize, sl.end);
let len = mktmp(ty_usize);
- gen("\t%v = sub %t %v, %v\n", len, ty_usize, end, begin);
+ gen("\t%v = sub %t %v, %v\n", &len, ty_usize, &end, &begin);
let addr2 = mktmp(addr.ty);
- gen("\t%v = getelementptr %t, %t %v, %t %v\n", addr2, ex.ty.u.Slice, addr.ty, addr, ty_usize, begin);
+ gen("\t%v = getelementptr %t, %t %v, %t %v\n", &addr2, ex.ty.u.Slice, addr.ty, &addr, ty_usize, &begin);
let tmp = mktmp(ex.ty);
- gen("\t%v = insertvalue %t undef, %t %v, 0\n", tmp, ex.ty, addr2.ty, addr2);
+ gen("\t%v = insertvalue %t undef, %t %v, 0\n", &tmp, ex.ty, addr2.ty, &addr2);
let res = mktmp(ex.ty);
- gen("\t%v = insertvalue %t %v, %t %v, 1\n", res, ex.ty, tmp, len.ty, len);
+ gen("\t%v = insertvalue %t %v, %t %v, 1\n", &res, ex.ty, &tmp, len.ty, &len);
return res;
} else if sl.lhs.ty.u.#tag == :Slice {
let slice = genexpr(f, sl.lhs);
let begin = convert(f, ty_usize, sl.begin);
let end = convert(f, ty_usize, sl.end);
let addr = mktmp(mkptrtype(slice.ty.u.Slice));
- gen("\t%v = extractvalue %t %v, 0", addr, ex.ty, slice);
+ gen("\t%v = extractvalue %t %v, 0", &addr, ex.ty, &slice);
let len = mktmp(ty_usize);
- gen("\t%v = sub %t %v, %v\n", len, ty_usize, end, begin);
+ gen("\t%v = sub %t %v, %v\n", &len, ty_usize, &end, &begin);
let addr2 = mktmp(addr.ty);
- gen("\t%v = getelementptr %t, %t %v, %t %v\n", addr2, ex.ty.u.Slice, addr.ty, addr, ty_usize, begin);
+ gen("\t%v = getelementptr %t, %t %v, %t %v\n", &addr2, ex.ty.u.Slice, addr.ty, &addr, ty_usize, &begin);
let tmp = mktmp(ex.ty);
- gen("\t%v = insertvalue %t undef, %t %v, 0\n", tmp, ex.ty, addr2.ty, addr2);
+ gen("\t%v = insertvalue %t undef, %t %v, 0\n", &tmp, ex.ty, addr2.ty, &addr2);
let res = mktmp(ex.ty);
- gen("\t%v = insertvalue %t %v, %t %v, 1\n", res, ex.ty, tmp, len.ty, len);
+ gen("\t%v = insertvalue %t %v, %t %v, 1\n", &res, ex.ty, &tmp, len.ty, &len);
return res;
}
@@ -895,14 +901,14 @@ fn genexpr(f *Fn, ex *Expr) Value {
}
let t Value = mktmp(ex.ty);
if fnty.ret->is(:Void) {
- gen("\tcall void %v(", lhs);
+ gen("\tcall void %v(", &lhs);
} else {
t = mktmp(ex.ty);
- gen("\t%v = call %t %v(", t, call.lhs.ty->is(:Ptr) ? call.lhs.ty.u.Ptr : call.lhs.ty, lhs);
+ gen("\t%v = call %t %v(", &t, call.lhs.ty->is(:Ptr) ? call.lhs.ty.u.Ptr : call.lhs.ty, &lhs);
}
foreach_ptr(arg, i, call.args) {
let ty = i < fnty.params.#len ? fnty.params[i] : varargpromote(arg.ty);
- gen("%t %v", ty, args[i]);
+ gen("%t %v", ty, &args[i]);
if i < call.args.#len - 1 {
gen(", ");
}
@@ -918,37 +924,38 @@ fn genexpr(f *Fn, ex *Expr) Value {
let ty = mkarrtype(ini.maxn, #f, ex.ty.u.Arr.child);
let tmp = genref(f, ex).Addr;
let val = mktmp(ty);
- gen("\t%v = load %t, %t %v\n", val, ty, tmp.ty, tmp);
+ gen("\t%v = load %t, %t %v\n", &val, 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);
+ 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);
+ 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);
+ 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);
+ gen("\t%v = load %t, %t %v\n", &res, res.ty, t0.ty, &t0);
return res;
case VaStart ap;
- gen("\tcall void @llvm.va_start(ptr %v)\n", genref(f, ap).Addr);
- return mktmp(ty_void);
+ // gen("\tcall void @llvm.va_start(ptr %v)\n", genref(f, ap).Addr);
+ return nop();
case VaArg ap;
- return gentmp(ex.ty, "va_arg ptr %v, %t", genref(f, ap).Addr, ex.ty);
+ let ap = genref(f, ap).Addr;
+ return gentmp(ex.ty, "va_arg ptr %v, %t", &ap, ex.ty);
case VaEnd ap;
- gen("\tcall void @llvm.va_end(ptr %v)\n", genref(f, ap).Addr);
- return mktmp(ty_void);
+ // gen("\tcall void @llvm.va_end(ptr %v)\n", genref(f, ap).Addr);
+ return nop();
case Stmt block;
switch genblock(f, block) {
@@ -963,19 +970,15 @@ fn genexpr(f *Fn, ex *Expr) Value {
fn llvmbool(f *Fn, ex *Expr) Value {
let v = genexpr(f, ex);
- let t = mktmp(&ty_i1);
+ let t = mktmp(#null);
if v.ty->is(:Bool) or v.ty->is(:Int) {
- gen("\t%v = icmp ne %t %v, 0\n", t, v.ty, v);
+ gen("\t%v = icmp ne %t %v, 0\n", &t, v.ty, &v);
} else {
- gen("\t%v = icmp ne %t %v, null\n", t, v.ty, v);
+ gen("\t%v = icmp ne %t %v, null\n", &t, v.ty, &v);
}
return t;
}
-fn nop() void {
- gen("\t%%t%d = bitcast i8 0 to i8 ; NOP\n", tmpid++);
-}
-
fn genstmt(f *Fn, block *Block, st *Stmt) void {
gen(";; line %d\n", st.loc.line);
switch st.u {
@@ -993,15 +996,16 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
gen("\t%%%s.%d = alloca %t\n", nam, var.id, ty);
switch var.ini {
case Some *ex;
+ let it = convert(f, ty, ex);
gen("\tstore %t %v, %t %%%s.%d\n",
- ty, convert(f, ty, ex), mkptrtype(ty), nam, var.id);
+ ty, &it, mkptrtype(ty), nam, var.id);
}
}
case If *cnd;
static ifid int = {};
let id = ifid++;
- gen("\tbr i1 %v, label %%IfT%d, label %%IfF%d\n",
- llvmbool(f, &cnd.test), id, id);
+ let test = llvmbool(f, &cnd.test);
+ gen("\tbr i1 %v, label %%IfT%d, label %%IfF%d\n", &test, id, id);
gen("IfT%d:", id);
nop();
genblock(f, cnd.t);
@@ -1021,8 +1025,8 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
gen("\tbr label %%Cont%d\n", loop.id);
gen("Cont%d:", loop.id);
nop();
- gen("\tbr i1 %v, label %%Next%d, label %%Brk%d\n",
- llvmbool(f, &loop.test), loop.id, loop.id);
+ let test = llvmbool(f, &loop.test);
+ gen("\tbr i1 %v, label %%Next%d, label %%Brk%d\n", &test, loop.id, loop.id);
gen("Next%d:", loop.id);
nop();
genblock(f, loop.body);
@@ -1038,8 +1042,8 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
gen("\tbr label %%Cont%d\n", loop.id);
gen("Cont%d:", loop.id);
nop();
- gen("\tbr i1 %v, label %%Next%d, label %%Brk%d\n",
- llvmbool(f, &loop.test), loop.id, loop.id);
+ let test = llvmbool(f, &loop.test);
+ gen("\tbr i1 %v, label %%Next%d, label %%Brk%d\n", &test, loop.id, loop.id);
gen("Brk%d:",loop.id);
nop();
@@ -1048,8 +1052,8 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
gen("\tbr label %%Cont%d\n", loop.id);
gen("Cont%d:", loop.id);
nop();
- gen("\tbr i1 %v, label %%Next%d, label %%Brk%d\n",
- llvmbool(f, &loop.test), loop.id, loop.id);
+ let test = llvmbool(f, &loop.test);
+ gen("\tbr i1 %v, label %%Next%d, label %%Brk%d\n", &test, loop.id, loop.id);
gen("Next%d:", loop.id);
nop();
genblock(f, loop.body);
@@ -1077,13 +1081,14 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
gen("\tret void\n");
case Some *e;
let retty = f.ty.u.Fn.ret;
- gen("\tret %t %v\n", retty, convert(f, retty, e));
+ let it = convert(f, retty, e);
+ gen("\tret %t %v\n", retty, &it);
}
case ISwitch *sw;
static swid int = {};
let id = swid++;
let test = genexpr(f, &sw.ex);
- gen("\tswitch %t %v, label %%ISx%d [", test.ty, test, id);
+ gen("\tswitch %t %v, label %%ISx%d [", test.ty, &test, id);
foreach (c, i, sw.cs) {
foreach_ptr (ex, _, c.es) {
assert(ex.u.#tag == :IntLit or ex.u.#tag == :EnumIni, "case");
@@ -1110,21 +1115,21 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
exaddr = genref(f, &sw.ex).Addr;
} else {
exaddr = mktmp(mkptrtype(sw.ex.ty));
- gen("\t%v = alloca %t\n", exaddr, exaddr.ty);
+ gen("\t%v = alloca %t\n", &exaddr, exaddr.ty);
let test = genexpr(f, &sw.ex);
- gen("\tstore %t %v, %t %v\n", test.ty, test, exaddr.ty, exaddr);
+ gen("\tstore %t %v, %t %v\n", test.ty, &test, exaddr.ty, &exaddr);
}
let tag = (do
let addr = mktmp(mkptrtype(sw.ex.ty.u.Agg.enumty));
- gen("\t%v = bitcast %t %v to %t\n", addr, exaddr.ty, exaddr, addr.ty);
+ gen("\t%v = bitcast %t %v to %t\n", &addr, exaddr.ty, &exaddr, addr.ty);
let tmp = mktmp(sw.ex.ty.u.Agg.enumty);
- gen("\t%v = load %t, %t %v\n", tmp, tmp.ty, addr.ty, addr);
+ gen("\t%v = load %t, %t %v\n", &tmp, tmp.ty, addr.ty, &addr);
tmp;
);
- gen("\tswitch %t %v, label %%ESx%d [ ", tag.ty, tag, id);
+ gen("\tswitch %t %v, label %%ESx%d [ ", tag.ty, &tag, id);
foreach (c, i, sw.cs) {
let t = Value{tag.ty, :IImm(c.variant)};
- gen(" %t %v, label %%ES%d.%d ", t.ty, t, id, i);
+ gen(" %t %v, label %%ES%d.%d ", t.ty, &t, id, i);
}
gen(" ]\n");
foreach (c, i, sw.cs) {
@@ -1132,14 +1137,14 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
if c.capt {
gen("\t%%%s.%d = alloca %t\n", c.capt, c.captid, c.captty);
let valaddr = mktmp(mkptrtype(c.fld.ty));
- gen("\t%v = getelementptr i8, %t %v, i32 %d\n", valaddr, exaddr.ty, exaddr,
+ gen("\t%v = getelementptr i8, %t %v, i32 %d\n", &valaddr, exaddr.ty, &exaddr,
as(int)c.fld.off);
if c.captptr {
- gen("\tstore %t %v, %t %%%s.%d\n", valaddr.ty, valaddr, mkptrtype(c.captty), c.capt, c.captid);
+ gen("\tstore %t %v, %t %%%s.%d\n", valaddr.ty, &valaddr, mkptrtype(c.captty), c.capt, c.captid);
} else {
let val = mktmp(c.captty);
- gen("\t%v = load %t, %t %v\n", val, val.ty, valaddr.ty, valaddr);
- gen("\tstore %t %v, %t %%%s.%d\n", val.ty, val, mkptrtype(c.captty), c.capt, c.captid);
+ gen("\t%v = load %t, %t %v\n", &val, val.ty, valaddr.ty, &valaddr);
+ gen("\tstore %t %v, %t %%%s.%d\n", val.ty, &val, mkptrtype(c.captty), c.capt, c.captid);
}
}
genblock(f, c.t);
@@ -1161,7 +1166,7 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
}
foreach (c, i, sw.cs) {
let t = llvmbool(f, &c.test);
- gen("\tbr i1 %v, label %%CST%d.%d, label %%CSF%d.%d\n", t, id, i, id, i);
+ gen("\tbr i1 %v, label %%CST%d.%d, label %%CSF%d.%d\n", &t, id, i, id, i);
gen("CST%d.%d: ", id, i);
genblock(f, c.t);
gen("\tbr label %%CSe%d\n", id);
@@ -1281,7 +1286,6 @@ struct IntTraits<T> {
}
fn gendata(ty *const Type, ex *Expr) void {
-
fn dataaddr(ex *Expr) void {
switch ex.u {
case Symbol decl;
@@ -1306,11 +1310,11 @@ fn gendata(ty *const Type, ex *Expr) void {
case BoolLit b; return gen("%d", b);
case NullLit; return gen("null");
case ZeroIni; return gen("zeroinitializer");
- case StrLit s;
+ case StrLit *s;
if ty->is(:Arr) {
return gen("c%S", s);
} else {
- strs->push(s);
+ strs->push(*s);
return gen("@.str.%z", strs.len - 1);
}
case UnOp un;
@@ -1390,7 +1394,7 @@ extern fn llvm_fini() void {
gen("declare void @llvm.va_copy(ptr, ptr)\n");
gen("declare void @llvm.va_end(ptr)\n");
vec_each(s, i, strs) {
- gen("@.str.%z = private unnamed_addr constant [%z x i8] c%S;\n", i, s.#len + 1, s);
+ gen("@.str.%z = private unnamed_addr constant [%z x i8] c%S;\n", i, s.#len + 1, &s);
}
map_each(g, k, globls) {
if g.t != :Decl {