aboutsummaryrefslogtreecommitdiff
path: root/src/irdump.cff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-20 11:06:38 +0200
committerlemon <lsof@mailbox.org>2022-08-20 11:06:38 +0200
commit46e1f128fd310bd29a2b4335b36c60d6cc0aa3a7 (patch)
treefeb93a69cf93773d0542435ae09c76de04e509c8 /src/irdump.cff
parentdf41a4512932f1312e4725d0409757a683b091ed (diff)
initial work on IR
Diffstat (limited to 'src/irdump.cff')
-rw-r--r--src/irdump.cff119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/irdump.cff b/src/irdump.cff
new file mode 100644
index 0000000..4147c8a
--- /dev/null
+++ b/src/irdump.cff
@@ -0,0 +1,119 @@
+import "ir.hff";
+import "common.hff";
+
+fn dump(fmt *const u8, ...) void {
+ let ap va_list #?;
+ ap->start(fmt);
+ for let c = *fmt; c != 0; c = *++fmt {
+ if c != '%' {
+ fputc(c, stderr);
+ continue;
+ }
+ switch (c = *++fmt) {
+ case '%';
+ fputc('%', stderr);
+ case 'd';
+ efmt("%d", ap->arg(int));
+ case 'a';
+ let arg = ap->arg(IRArg);
+ switch arg {
+ case Val val;
+ switch val.u {
+ case IImm i;
+ efmt("%I", i);
+ case FImm f;
+ efmt("%f", f);
+ case SImm s;
+ efmt("%S", s);
+ case BImm b;
+ efmt("%s", b ? "#t" : "#f");
+ case Null;
+ efmt("#null");
+ case Tmp t;
+ efmt("%%%d", t);
+ }
+ case Ty ty; efmt("%t", ty);
+ case Fn decl; efmt("%s", decl.name);
+ case else assert(#f, "arg? %d", arg.#tag);
+ }
+ case 't';
+ efmt("%t", ap->arg(*Type));
+ case else
+ assert(#f, "bad fmt %c", c);
+ }
+ }
+ ap->end();
+}
+
+extern fn irdump(a *IRInst) void {
+ if a == #null { return; }
+
+ dump(" ");
+ #'dump do {
+ defmacro exprinst(tag, nam, n) [
+ if a.t == (tag) {
+ dump("%%%d(%t) = " ## nam ## " ", a.args[0].Val.u.Tmp, a.args[0].Val.ty);
+ for let $i = 1; $i < (n); ++$i {
+ dump("%a", a.args[$i]);
+ if $i < (n) - 1 {
+ dump(", ");
+ }
+ }
+ dump("\n");
+ break #'dump;
+ }
+ ]
+ defmacro stmtinst(tag, nam, n) [
+ if a.t == (tag) {
+ dump(nam##" ");
+ for let $i = 0; $i < (n); ++$i {
+ dump("%a", a.args[$i]);
+ if $i < (n) - 1 {
+ dump(", ");
+ }
+ }
+ dump("\n");
+ break #'dump;
+ }
+ ]
+
+ exprinst(:neg, "neg", 2)
+ exprinst(:compl, "compl", 2)
+ exprinst(:fneg, "fneg", 2)
+ exprinst(:add, "add", 3);
+ exprinst(:sub, "sub", 3);
+ exprinst(:mul, "mul", 3);
+ exprinst(:div, "div", 3);
+ exprinst(:mod, "mod", 3);
+ exprinst(:band, "band", 3);
+ exprinst(:bor, "bor", 3);
+ exprinst(:xor, "xor", 3);
+ exprinst(:lsl, "lsl", 3);
+ exprinst(:lsr, "lsr", 3);
+ exprinst(:asr, "asr", 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;
+ 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);
+ if i < n - 1 {
+ dump(", ");
+ }
+ }
+ dump("\n");
+ break #'dump;
+ }
+
+ stmtinst(:ret0, "ret", 0);
+
+ assert(#f, "inst? %d\n", a.t);
+ } while #f;
+
+ irdump(a.next);
+}