From a298cb75c4f586b83b304c7dc66cb555693ea1b8 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Fri, 5 Jan 2018 17:52:38 +0100 Subject: Stuff --- ir.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 96 insertions(+), 6 deletions(-) (limited to 'ir.c') diff --git a/ir.c b/ir.c index 9d28e2f..cf529dd 100644 --- a/ir.c +++ b/ir.c @@ -1,5 +1,5 @@ -#include #include +#include #include "ir.h" @@ -20,10 +20,94 @@ void ir_delete(struct ir *ir) { free(ir); } +void ir_print(struct ir *ir, FILE *f) { + fprintf(f, "IR [globspace=%d]\n", ir->globspace); + for (int i = 0; i < ir->len; i++) { + irins_print(ir->inss[i], f); + } +} + +static const char* condcode_show(enum condcode condcode) { + switch (condcode) { + case CCZ: return "z"; + case CCNZ: return "nz"; + case CCL: return "l"; + case CCG: return "g"; + case CCLE: return "le"; + case CCGE: return "ge"; + default: assert(false); + } +} + +static const char* ref_show(struct ref ref) { + static char cbuf[3][16]; + static int cbufi = 0; + static const char *special[8] = {"A", "B", "C", "D", "X", "Y", "SP", "BP"}; + + const char *suffix; + if (ref.rel == REFREL_ZERO) suffix = ""; + else if (ref.rel == REFREL_DATA) suffix = ":data"; + else if (ref.rel == REFREL_HEAP) suffix = ":heap"; + else assert(false); + + switch (ref.type) { + case REF_REG: + if (ref.reg == REG_UNUSED) return "<>"; + if (ref.reg < 0) return special[-(ref.reg - REG_A)]; + cbufi = (cbufi + 1) % 3; + sprintf(cbuf[cbufi], "t%d", ref.reg); + return cbuf[cbufi]; + + case REF_MEM: + cbufi = (cbufi + 1) % 3; + if (ref.reg == REG_UNUSED) { + sprintf(cbuf[cbufi], "[%d%s]", ref.offset, suffix); + } else if (ref.reg < 0) { + sprintf(cbuf[cbufi], "[%s + %d%s]", special[-(ref.reg - REG_A)], ref.offset, suffix); + } else { + sprintf(cbuf[cbufi], "[t%d + %d%s]", ref.reg, ref.offset, suffix); + } + return cbuf[cbufi]; + + case REF_IMM: + cbufi = (cbufi + 1) % 3; + sprintf(cbuf[cbufi], "%d", ref.imm); + return cbuf[cbufi]; + + default: + assert(false); + } +} + +void irins_print(struct irins *ins, FILE *f) { + switch (ins->type) { + case INS_ADD: fprintf(f, "\t%s <- %s + %s\n", ref_show(ins->r0), ref_show(ins->r1), ref_show(ins->r2)); break; + case INS_SUB: fprintf(f, "\t%s <- %s - %s\n", ref_show(ins->r0), ref_show(ins->r1), ref_show(ins->r2)); break; + case INS_MUL: fprintf(f, "\t%s <- %s * %s\n", ref_show(ins->r0), ref_show(ins->r1), ref_show(ins->r2)); break; + case INS_DIV: fprintf(f, "\t%s <- %s / %s\n", ref_show(ins->r0), ref_show(ins->r1), ref_show(ins->r2)); break; + case INS_MOD: fprintf(f, "\t%s <- %s %% %s\n", ref_show(ins->r0), ref_show(ins->r1), ref_show(ins->r2)); break; + case INS_NEG: fprintf(f, "\t%s <- -%s\n", ref_show(ins->r0), ref_show(ins->r1)); break; + case INS_NOT: fprintf(f, "\t%s <- !%s\n", ref_show(ins->r0), ref_show(ins->r1)); break; + case INS_TEST: fprintf(f, "\ttest %s, %s\n", ref_show(ins->r1), ref_show(ins->r2)); break; + case INS_PUSH: fprintf(f, "\tpush %s\n", ref_show(ins->r1)); break; + case INS_POP: fprintf(f, "\t%s = pop\n", ref_show(ins->r0)); break; + case INS_CMP: fprintf(f, "\tcmp %s, %s\n", ref_show(ins->r1), ref_show(ins->r2)); break; + case INS_LBL: fprintf(f, "%s:\n", ins->name); break; + case INS_JMP: fprintf(f, "\tjmp %s\n", ins->name); break; + case INS_JCC: fprintf(f, "\tj%s %s\n", condcode_show(ins->condcode), ins->name); break; + case INS_CALL: fprintf(f, "\tcall %s\n", ins->name); break; + case INS_CALLV: fprintf(f, "\t%s <- call %s\n", ref_show(ins->r0), ins->name); break; + case INS_RET: fprintf(f, "\tret\n"); break; + case INS_RETV: fprintf(f, "\tret %s\n", ref_show(ins->r1)); break; + case INS_MOV: fprintf(f, "\t%s <- %s\n", ref_show(ins->r0), ref_show(ins->r1)); break; + default: assert(false); + } +} + struct ref ir_reserve_global(struct ir *ir, int size) { int offset = ir->globspace; ir->globspace += size; - return ref_mem(-1, offset, true); + return ref_mem(REG_UNUSED, offset, REFREL_DATA); } void ir_append(struct ir *ir, struct irins *ins) { @@ -47,6 +131,12 @@ struct irins* irins_make_name(enum instype type, char *name) { return ins; } +struct irins* irins_make_0(enum instype type, struct ref r0) { + struct irins *ins = irins_make(type); + ins->r0 = r0; + return ins; +} + struct irins* irins_make_01(enum instype type, struct ref r0, struct ref r1) { struct irins *ins = irins_make(type); ins->r0 = r0; @@ -93,15 +183,15 @@ char* gen_label_name(void) { } struct ref ref_reg(int reg) { - return (struct ref){REF_REG, reg, 0, false, 0}; + return (struct ref){REF_REG, reg, 0, REFREL_ZERO, 0}; } -struct ref ref_mem(int reg, int offset, bool rel_heap) { - return (struct ref){REF_MEM, reg, offset, rel_heap, 0}; +struct ref ref_mem(int reg, int offset, enum refrel rel) { + return (struct ref){REF_MEM, reg, offset, rel, 0}; } struct ref ref_imm(int imm) { - return (struct ref){REF_IMM, -1, 0, false, imm}; + return (struct ref){REF_IMM, REG_UNUSED, 0, REFREL_ZERO, imm}; } struct ref ref_next_register(void) { -- cgit v1.2.3-54-g00ecf