diff options
Diffstat (limited to 'src/llvm.cff')
| -rw-r--r-- | src/llvm.cff | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/llvm.cff b/src/llvm.cff index fd853f0..2b49337 100644 --- a/src/llvm.cff +++ b/src/llvm.cff @@ -142,7 +142,7 @@ fn gen(fmt *const u8, ...) void { fprintf(outfp, "%lld", as(c_llong)ap->arg(i64)); case 'f'; let f f64 = as(f32)ap->arg(f64); - fprintf(outfp, "%#.16llx", *as(*u64)&f); + fprintf(outfp, "0x%.16llx", *as(*u64)&f); case 'F'; fprintf(outfp, "%e", ap->arg(f64)); case 'z'; @@ -434,7 +434,7 @@ fn convert(f *Fn, to *const Type, ex *Expr) Value { 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); + gen("\t%v = trunc %t %v to %t\n", t1, t0.ty, t0, to); return t1; case to->is(:Int) and from->is(:Flo); @@ -580,8 +580,8 @@ fn genexpr(f *Fn, ex *Expr) Value { case '^'; return genbinop(b.lhs, b.rhs, "xor"); case '<<'; return genbinop(b.lhs, b.rhs, "shl"); case '>>'; return genbinop(b.lhs, b.rhs, ex.ty.u.Int.sgn ? "ashr" : "lshr"); - case '=='; gencmp("eq"); - case '!='; gencmp("ne"); + case '=='; gencmp(ty2->is(:Flo) ? "oeq" : "eq"); + case '!='; gencmp(ty2->is(:Flo) ? "une" : "ne"); case '<'; gencmp(ty2->is(:Flo) ? "olt" : ty2.u.Int.sgn ? "slt" : "ult"); case '<='; gencmp(ty2->is(:Flo) ? "ole" : ty2.u.Int.sgn ? "sle" : "ule"); case '>'; gencmp(ty2->is(:Flo) ? "ogt" : ty2.u.Int.sgn ? "sgt" : "ugt"); @@ -1227,6 +1227,20 @@ struct I64Traits { } fn gendata(ty *const Type, ex *Expr) void { + + fn dataaddr(ex *Expr) void { + switch ex.u { + case Symbol decl; + switch decl.u { + case Fn f; + if !decl.externp { gen("@%s.%d", decl.name, f.id); + } else { gen("@%s", decl.name); } + return; + } + } + assert(#f, "bad static addr"); + } + fold(ex); switch ex.u { case IntLit i; return gen("%I", i.i); @@ -1241,6 +1255,11 @@ fn gendata(ty *const Type, ex *Expr) void { strs->push(s); return gen("@.str.%z", strs.len - 1); } + case UnOp un; + switch un.op { + case :addrof; + return dataaddr(un.ex); + } case ArrIni ini; assert(ty->is(:Arr), "not arr arr ini"); @@ -1265,7 +1284,7 @@ fn gendata(ty *const Type, ex *Expr) void { gen(" ]"); return; } - assert(#f, "bad static"); + assert(#f, "bad static %d", ex.u.#tag); } extern fn llvm_genstatic(externp bool, name *const u8, var *Var) void { |