aboutsummaryrefslogtreecommitdiff
path: root/src/irdump.cff
diff options
context:
space:
mode:
Diffstat (limited to 'src/irdump.cff')
-rw-r--r--src/irdump.cff85
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);
+ };
}