diff options
author | tomsmeding <tom.smeding@gmail.com> | 2018-01-06 21:38:40 +0100 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2018-01-06 21:38:40 +0100 |
commit | f4b60f43cf636d48f8857676b072371f1575a5b2 (patch) | |
tree | d185ecd5d15b379e64474030bad8a2ab386c4284 /assemble.c | |
parent | c4a376d1c7263993f13e9cf276ebd9e530fd419c (diff) |
Working compiler
Diffstat (limited to 'assemble.c')
-rw-r--r-- | assemble.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/assemble.c b/assemble.c new file mode 100644 index 0000000..cdc584c --- /dev/null +++ b/assemble.c @@ -0,0 +1,117 @@ +#include <stdlib.h> +#include <assert.h> +#include "assemble.h" + + +static void aRef(struct ref ref, FILE *f) { + char buf[40]; + ref_show(ref, buf); + fprintf(f, "%s", buf); +} + +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_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); + } +} |