#include #include #include "assemble.h" static void aRef(struct ref ref, FILE *f) { fprintf(f, "%s", ref_show(ref)); } static void assemble_ins(const struct irins *ins, FILE *f) { switch (ins->type) { case INS_ADD: assert(ref_equal(ins->r0, ins->r1)); fprintf(f, "\tadd "); aRef(ins->r1, f); fprintf(f, ", "); aRef(ins->r2, f); fprintf(f, "\n"); break; case INS_SUB: assert(ref_equal(ins->r0, ins->r1)); fprintf(f, "\tsub "); aRef(ins->r1, f); fprintf(f, ", "); aRef(ins->r2, f); fprintf(f, "\n"); break; case INS_MUL: assert(ref_equal(ins->r0, ref_reg(REG_A))); assert(ref_equal(ins->r0, ins->r1)); fprintf(f, "\tmul "); aRef(ins->r2, f); fprintf(f, "\n"); break; case INS_DIV: fprintf(stderr, "DIV not implemented...\n"); exit(1); assert(ref_equal(ins->r0, ins->r1)); fprintf(f, "\tdiv "); aRef(ins->r1, f); fprintf(f, ", "); aRef(ins->r2, f); fprintf(f, "\n"); break; case INS_MOD: fprintf(stderr, "MOD not implemented...\n"); exit(1); assert(ref_equal(ins->r0, ins->r1)); fprintf(f, "\tmod "); aRef(ins->r1, f); fprintf(f, ", "); aRef(ins->r2, f); fprintf(f, "\n"); break; case INS_NEG: fprintf(f, "\tneg "); aRef(ins->r1, f); fprintf(f, "\n"); break; case INS_NOT: fprintf(f, "\tnot "); aRef(ins->r1, f); fprintf(f, "\n"); break; case INS_TEST: fprintf(f, "\ttest "); aRef(ins->r1, f); fprintf(f, ", "); aRef(ins->r2, f); fprintf(f, "\n"); break; case INS_PUSH: fprintf(f, "\tpush "); aRef(ins->r1, f); fprintf(f, "\n"); break; case INS_POP: fprintf(f, "\tpop "); aRef(ins->r0, f); fprintf(f, "\n"); break; case INS_CMP: fprintf(f, "\tcmp "); aRef(ins->r1, f); fprintf(f, ", "); aRef(ins->r2, f); fprintf(f, "\n"); 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_RET: fprintf(f, "\tret\n"); break; case INS_MOV: fprintf(f, "\tmov "); aRef(ins->r0, f); fprintf(f, ", "); aRef(ins->r1, f); fprintf(f, "\n"); break; case INS_BRK: fprintf(f, "\tbrk\n"); break; case INS_HWI: fprintf(f, "\thwi "); aRef(ins->r1, f); fprintf(f, "\n"); break; case INS_CALLV: case INS_RETV: assert(false); default: assert(false); } } void assemble(const struct ir *ir, FILE *f) { if (ir->globspace > 0) { fprintf(f, ".data\n\tdw "); for (int i = 0; i < ir->globspace; i++) { if (i != 0) fprintf(f, ", "); fprintf(f, "0"); } fprintf(f, "\n"); } fprintf(f, ".text\n"); for (int i = 0; i < ir->len; i++) { assemble_ins(ir->inss[i], f); } }