<*>= [D->] link pretty procedure emit_disassembler(outfilename) local constypes, constype verbose("Emitting disassemblers") f := openfile(outfilename, "w") | error("Could not open ", image(outfilename), " for writing") pp := PPnew(f) pushtrace("DIS") every create_input_print_proc(pp, inputs_of(kept_constructors())) PPxwrite(pp, "$t") constypes := set([&null]) every insert(constypes, kept_constructors().type) every constype := !constypes do { PPwrite(pp, "match pc to") l := [] every push(l, kept_constructors(constype)) # reverse order every emit_disassembler_match(pp, !l) PPwrite(pp, "endmatch") } PPwrite(pp) # flush prettyprinter return end
Definesemit_disassembler
(links are to index).
emit_disassembler_match
emits a line in a matching statement for
constructor cons
.
Right now we emit a bunch of print statments flagrantly borrowed from
the assembler encoding stuff.
Eventually, we will just want indirect calls on encoding procedures.
<*>+= [<-D] procedure emit_disassembler_match(pp, cons) local asmname PPxwrites(pp, "| $t$t$t${", cons.name, "(") <emit operands separated by commas> PPxwrites(pp, ")$} => $b$o") asmname := consname2asm(cons) if *asmname > 0 & /postfix then emit_asm_printf(pp, "%s", image(asmname)) every o := !asmoperands(cons) do case type(o) of { "literal" : emit_asm_printf(pp, "%s", image(o.s)) "input" : PPxwrites(pp, "$n", create_input_print_proc(pp, o), "(", Cnoreserve(o.name), ");") default : impossible("operand type") } if *asmname > 0 & \postfix then emit_asm_printf(pp, "%s", image(asmname)) if cons.type === instructionctype then emit_asm_printf(pp, "\n") PPxwrite(pp, "$b$b") end
Definesemit_disassembler_match
(links are to index).
<emit operands separated by commas>= (U->) pfx := "" every ipt := inputs_of(cons) do { PPxwrites(pp, pfx, ipt.name) pfx := ", $o" }