From 46e1f128fd310bd29a2b4335b36c60d6cc0aa3a7 Mon Sep 17 00:00:00 2001 From: lemon Date: Sat, 20 Aug 2022 11:06:38 +0200 Subject: initial work on IR --- src/irdump.cff | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/irdump.cff (limited to 'src/irdump.cff') 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); +} -- cgit v1.2.3