diff options
Diffstat (limited to 'src/irdump.cff')
| -rw-r--r-- | src/irdump.cff | 85 |
1 files changed, 61 insertions, 24 deletions
diff --git a/src/irdump.cff b/src/irdump.cff index 4147c8a..9d9318b 100644 --- a/src/irdump.cff +++ b/src/irdump.cff @@ -1,5 +1,6 @@ import "ir.hff"; import "common.hff"; +import "map.hff"; fn dump(fmt *const u8, ...) void { let ap va_list #?; @@ -31,9 +32,13 @@ fn dump(fmt *const u8, ...) void { efmt("#null"); case Tmp t; efmt("%%%d", t); + case Local l; + efmt("$%s.%d", l.name, l.u.Let.id); + case Global g; + efmt("@%s.%d", g.name, g.u.Static.id); } case Ty ty; efmt("%t", ty); - case Fn decl; efmt("%s", decl.name); + case Fn decl; efmt("@%s", decl.name); case else assert(#f, "arg? %d", arg.#tag); } case 't'; @@ -45,39 +50,59 @@ fn dump(fmt *const u8, ...) void { ap->end(); } -extern fn irdump(a *IRInst) void { - if a == #null { return; } +extern fn irdump(inst *IRInst) void { + let labels Map<*IRInst, int, struct { + fn hash(a *IRInst) u32 { return as(iptrint)a; } + fn eq(a *IRInst, b *IRInst) bool { return a == b; } + }> = {}; + defer labels->clear(); + let labid = 0; + for let a = inst; a; a = a.next { + if a.branch { + let slot = labels->get_slot(a.branch); + if *slot == 0 { + *slot = ++labid; + } + } + } - dump(" "); - #'dump do { + + #'dump for ; inst; inst = inst.next { + let label = labels->get(inst); + if label { + dump(".L%d:\t", *label); + } else { + dump("\t"); + } defmacro exprinst(tag, nam, n) [ - if a.t == (tag) { - dump("%%%d(%t) = " ## nam ## " ", a.args[0].Val.u.Tmp, a.args[0].Val.ty); + if inst.t == (tag) { + dump("%%%d(%t) = " ## nam ## " ", inst.args[0].Val.u.Tmp, inst.args[0].Val.ty); for let $i = 1; $i < (n); ++$i { - dump("%a", a.args[$i]); + dump("%a", inst.args[$i]); if $i < (n) - 1 { dump(", "); } } dump("\n"); - break #'dump; + continue #'dump; } ] defmacro stmtinst(tag, nam, n) [ - if a.t == (tag) { + if inst.t == (tag) { dump(nam##" "); for let $i = 0; $i < (n); ++$i { - dump("%a", a.args[$i]); + dump("%a", inst.args[$i]); if $i < (n) - 1 { dump(", "); } } dump("\n"); - break #'dump; + continue #'dump; } ] exprinst(:neg, "neg", 2) + exprinst(:not, "not", 2) exprinst(:compl, "compl", 2) exprinst(:fneg, "fneg", 2) exprinst(:add, "add", 3); @@ -91,29 +116,41 @@ extern fn irdump(a *IRInst) void { exprinst(:lsl, "lsl", 3); exprinst(:lsr, "lsr", 3); exprinst(:asr, "asr", 3); + exprinst(:eq, "eq", 3); + exprinst(:neq, "neq", 3); + exprinst(:lt, "lt", 3); + exprinst(:lteq, "lteq", 3); exprinst(:fadd, "fadd", 3); exprinst(:fsub, "fsub", 3); exprinst(:fmul, "fmul", 3); exprinst(:fdiv, "fdiv", 3); - if a.t == :call { - let fnty = a.args[1].Fn.u.Fn.ty.u.Fn; - dump("%%%d(%t) = call %a, ", a.args[0].Val.u.Tmp, a.args[0].Val.ty, a.args[1]); - let n = a.call_nargs; + if inst.t == :call { + let fnty = inst.args[1].Fn.u.Fn.ty.u.Fn; + dump("%%%d(%t) = call %a, ", inst.args[0].Val.u.Tmp, inst.args[0].Val.ty, inst.args[1]); + let n = inst.call_nargs; for let i = 0; i < n; ++i { - dump("%a(%t)", a.args[i + 2], - i < fnty.params.#len ? fnty.params[i] : a.args[i + 2].Val.ty); + dump("%a(%t)", inst.args[i + 2], + i < fnty.params.#len ? fnty.params[i] : inst.args[i + 2].Val.ty); if i < n - 1 { dump(", "); } } dump("\n"); - break #'dump; + continue #'dump; } - + exprinst(:copy, "copy", 2) + stmtinst(:nop, "nop", 0); stmtinst(:ret0, "ret", 0); + stmtinst(:ret, "ret", 1); + if inst.t == :beqz { + dump("beqz %a, .L%d\n", inst.args[0], *labels->get(inst.branch)); + continue #'dump; + } + if inst.t == :b { + dump("b .L%d\n", *labels->get(inst.branch)); + continue #'dump; + } - assert(#f, "inst? %d\n", a.t); - } while #f; - - irdump(a.next); + assert(#f, "inst? %d\n", inst.t); + }; } |