diff options
| author | 2022-08-25 18:08:54 +0200 | |
|---|---|---|
| committer | 2022-08-25 18:08:54 +0200 | |
| commit | 09c083ea08b7436a9ca39734e5c6b82c6198746e (patch) | |
| tree | 0c570c3f6e3becdca3989d189f638d71e304143f /src | |
| parent | 9eeb4f4641481279895a927f97503d7a6938b2e5 (diff) | |
now test.cff kinda
Diffstat (limited to 'src')
| -rw-r--r-- | src/env.cff | 1 | ||||
| -rw-r--r-- | src/llvm.cff | 74 | ||||
| -rw-r--r-- | src/parse.cff | 1 |
3 files changed, 64 insertions, 12 deletions
diff --git a/src/env.cff b/src/env.cff index 04dc81d..d45e373 100644 --- a/src/env.cff +++ b/src/env.cff @@ -32,6 +32,7 @@ extern fn envput_alloc(env *Env, alloc *Allocator, decl Decl, old **const Decl) switch { case old.u.#tag == :Fn and decl.u.#tag == :Fn and decl.u.Fn.ty == old.u.Fn.ty and (old.u.Fn.body->empty() or decl.u.Fn.body->empty()); + decl.u.Fn.id = old.u.Fn.id; case old.u.#tag == :Ty and decl.u.#tag == :Ty and old.u.Ty == decl.u.Ty; diff --git a/src/llvm.cff b/src/llvm.cff index ba4b556..3dcebe6 100644 --- a/src/llvm.cff +++ b/src/llvm.cff @@ -19,6 +19,7 @@ struct Value { LocalRef *Var, GlobalRef *Var, Fn *Fn, + FnRef *Fn, } } @@ -90,7 +91,8 @@ fn gen(fmt *const u8, ...) void { 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); + assert(arr.length >= 0, "arr length"); + gen("[%z x %t]", arr.length, arr.child); case Agg; genagg(ty); case Enum enu; pritype(enu.intty); @@ -138,13 +140,17 @@ fn gen(fmt *const u8, ...) void { case 'I'; fprintf(outfp, "%lld", as(c_llong)ap->arg(i64)); case 'f'; - fprintf(outfp, "%.17f", ap->arg(f64)); + let f f64 = as(f32)ap->arg(f64); + fprintf(outfp, "%#.16llx", *as(*u64)&f); + case 'F'; + fprintf(outfp, "%e", ap->arg(f64)); case 'z'; fprintf(outfp, "%zu", ap->arg(usize)); case 'v'; - switch ap->arg(Value).u { + let val = ap->arg(Value); + switch val.u { case IImm i; gen("%I", i); - case FImm f; gen("%f", f); + case FImm f; gen(val.ty.size == 4 ? "%f" : "%F", f); case BImm b; gen("%d", as(int)b); case Null; gen("null"); case ZeroIni; gen("zeroinitializer"); @@ -164,6 +170,13 @@ fn gen(fmt *const u8, ...) void { } else { gen("@%s", decl.name); } + case FnRef f; + let decl = container_of(f, Decl, u.Fn); + if !decl.externp { + gen("@%s.%d", decl.name, f.id); + } else { + gen("@%s", decl.name); + } case StrConstRef id; gen("@.str.%d", id); @@ -206,6 +219,7 @@ fn genaddr(f *Fn, ex *Expr) Value { switch decl.u { case Let *var; return {mkptrtype(var.ty), :LocalRef(var)}; case Static *var; return {mkptrtype(var.ty), :GlobalRef(var)}; + case Fn *f; return {mkptrtype(f.ty), :FnRef(f)}; } case UnOp un; switch un.op { @@ -217,12 +231,19 @@ fn genaddr(f *Fn, ex *Expr) Value { } case Index idx; let lhs Value #?; - if idx.lhs.ty->is(:Arr) { + switch idx.lhs.ty.u { + case Arr arrty; let arr = genaddr(f, idx.lhs); lhs = mktmp(mkptrtype(ex.ty)); - gen("\t%v = getelementptr %t, %t %v, i32 0, i32 0\n", lhs, arr.ty.u.Arr.child, arr.ty, arr); - } else { + gen("\t%v = getelementptr %t, %t %v, i32 0, i32 0\n", lhs, idx.lhs.ty, arr.ty, arr); + case Ptr; lhs = genexpr(f, idx.lhs); + case Slice child; + let tmp = genexpr(f, idx.lhs); + lhs = mktmp(mkptrtype(child)); + gen("\t%v = extractvalue %t %v, 0\n", lhs, tmp.ty, tmp); + case else; + assert(#f, "index"); } let rhs = genexpr(f, idx.rhs), addr = mktmp(mkptrtype(ex.ty)); @@ -271,7 +292,20 @@ fn genaddr(f *Fn, ex *Expr) Value { 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); + gen("\tstore %t %v, %t %v\n", fld.ty, convert(f, fld.ty, fex), ptr.ty, ptr); + } + return tmp; + + case ArrIni ini; + let ty = mkarrtype(ini.maxn, #f, ex.ty.u.Arr.child); + let tmp = mktmp(mkptrtype(ty)); + gen("\t%v = alloca %t\n", tmp, ty); + 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); } return tmp; } @@ -695,7 +729,16 @@ fn genexpr(f *Fn, ex *Expr) Value { case Slice sl; if sl.lhs.ty.u.#tag == :Arr { - assert(#f,""); + let addr = genaddr(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); + let tmp = mktmp(ex.ty); + gen("\t%v = insertvalue %t undef, %t %v, 0\n", tmp, ex.ty, addr.ty, addr); + let res = mktmp(ex.ty); + 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); @@ -755,6 +798,13 @@ fn genexpr(f *Fn, ex *Expr) Value { gen("\t%v = load %t, %t %v\n", val, ex.ty, tmp.ty, tmp); return val; + case ArrIni ini; + let ty = mkarrtype(ini.maxn, #f, ex.ty.u.Arr.child); + let tmp = genaddr(f, ex); + let val = mktmp(ty); + 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; @@ -907,8 +957,8 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void { gen("\tswitch %t %v, label %%ISx%d [", test.ty, test); foreach (c, i, sw.cs) { foreach_ptr (ex, _, c.es) { - let t = convert(f, test.ty, ex); - gen(" %t %v, label %%IS%d.%d ", t.ty, t, id, i); + assert(ex.u.#tag == :IntLit or ex.u.#tag == :EnumIni, "case"); + gen(" %t %I, label %%IS%d.%d ", test.ty, ex.u.IntLit.i, id, i); } } gen(" ]\n"); @@ -1043,7 +1093,7 @@ struct GloblKeyTraits { static globls Map<GloblKey, GloblEntry, GloblKeyTraits> = {}; extern fn llvm_addglobl(decl *Decl, staticp bool) void { - assert(decl.toplevel, "llvm-addfn"); + assert(decl.toplevel or decl.externp, "llvm-addfn %d", decl.u.#tag); let slot = globls->get_slot({decl.name, decl.externp}); if slot.t != :Def { slot.t = :Decl; diff --git a/src/parse.cff b/src/parse.cff index 0eb251d..3512c96 100644 --- a/src/parse.cff +++ b/src/parse.cff @@ -2584,6 +2584,7 @@ fn parsefn(P *Parser, loc Loc, toplevel bool, externp bool, name *const u8) *Dec Fn.id = ++id; // TODO tlalloc necessary for templates. but it leaks some memory let decl = putdecl_alloc(P, P.tlalloc, loc, decl); + let Fn = &decl.u.Fn; decl.toplevel = toplevel; if !lexmatch(P, #null, '{') { |