aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2018-01-06 20:39:26 +0100
committertomsmeding <tom.smeding@gmail.com>2018-01-06 20:39:26 +0100
commitc4a376d1c7263993f13e9cf276ebd9e530fd419c (patch)
treef36010f188778b1b7c30268fb8cdb723080e056f
parent3272b5d83d2e2167eed24748557df88bd66584ee (diff)
Fix INS_NOT
-rw-r--r--compiler.c7
-rw-r--r--ir.c2
-rw-r--r--ir.h2
3 files changed, 8 insertions, 3 deletions
diff --git a/compiler.c b/compiler.c
index ea9f768..c6adf6a 100644
--- a/compiler.c
+++ b/compiler.c
@@ -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;
}
diff --git a/ir.c b/ir.c
index 69a9d64..54f1259 100644
--- a/ir.c
+++ b/ir.c
@@ -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;
diff --git a/ir.h b/ir.h
index 5d92eed..2390543 100644
--- a/ir.h
+++ b/ir.h
@@ -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