diff options
-rw-r--r-- | compiler.c | 7 | ||||
-rw-r--r-- | ir.c | 2 | ||||
-rw-r--r-- | ir.h | 2 |
3 files changed, 8 insertions, 3 deletions
@@ -148,7 +148,12 @@ static struct ref compile_expr(struct ir *ir, struct symtab *symtab, struct node case OP_NOT: { struct ref r0 = ref_next_register(); struct ref r1 = compile_expr(ir, symtab, node->child1); - ir_append(ir, irins_make_01(INS_NOT, r0, r1)); + const char *afterlbl = gen_label_name(); + ir_append(ir, irins_make_12(INS_TEST, r1, r1)); + ir_append(ir, irins_make_01(INS_MOV, r0, ref_imm(0))); + ir_append(ir, irins_make_jcc(afterlbl, CCNZ)); + ir_append(ir, irins_make_01(INS_MOV, r0, ref_imm(1))); + ir_append(ir, irins_make_name(INS_LBL, afterlbl)); return r0; } @@ -108,7 +108,7 @@ void irins_print(struct irins *ins, FILE *f) { 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_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; @@ -13,7 +13,7 @@ enum instype { INS_DIV, // r0 = r1 / r2 INS_MOD, // r0 = r1 % r2 INS_NEG, // r0 = -r1 - INS_NOT, // r0 = !r1 + INS_NOT, // r0 = ~r1 INS_TEST, // r1 & r2 (flags) INS_PUSH, // push r1 INS_POP, // r0 = pop |