aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2018-01-24 23:00:31 +0100
committertomsmeding <tom.smeding@gmail.com>2018-01-24 23:00:31 +0100
commit1fc88ae00940e04ee76cbdf13a5df429faf72451 (patch)
tree59692bd2354819ee8b7fea2253fcefacdf1ecce9
parentbd7ef7a572f3faa58a550baca46a1b4f95e9b95d (diff)
Also do the BP dance if no spills occur
This is because arguments are annoyingly generated relative to BP, which fails completely if the stack frame is not set up nicely. TODO do stuff relative to SP so BP is just a general purpose register.
-rw-r--r--test/t2.c1
-rw-r--r--to_assembly.c13
2 files changed, 10 insertions, 4 deletions
diff --git a/test/t2.c b/test/t2.c
index 11ce9b8..0f9432c 100644
--- a/test/t2.c
+++ b/test/t2.c
@@ -14,6 +14,7 @@ void main() {
mov b, @dir
hwi 1 // legs
}
+ holo_dec(dir);
dir = dir + 1;
if (dir == 4) dir = 0;
}
diff --git a/to_assembly.c b/to_assembly.c
index bd680b3..6f40e2d 100644
--- a/to_assembly.c
+++ b/to_assembly.c
@@ -81,13 +81,18 @@ static void fix_function(struct ir *ir, int startidx, struct allocation *ral) {
}
free(offsets);
-
- if (spillspace == 0) return;
+
+ // TODO: Really, nothing should be relative to BP, instead everything should use SP. That
+ // would completely eliminate this BP dance anyway.
+
+ // if (spillspace == 0) return;
ir_insert_before(ir, startidx + 0, irins_make_1(INS_PUSH, ref_reg(REG_BP)));
ir_insert_before(ir, startidx + 1, irins_make_01(INS_MOV, ref_reg(REG_BP), ref_reg(REG_SP)));
- ir_insert_before(ir, startidx + 2,
- irins_make_012(INS_SUB, ref_reg(REG_SP), ref_reg(REG_SP), ref_imm(spillspace)));
+ if (spillspace != 0) {
+ ir_insert_before(ir, startidx + 2,
+ irins_make_012(INS_SUB, ref_reg(REG_SP), ref_reg(REG_SP), ref_imm(spillspace)));
+ }
for (int idx = startidx + 1; idx < ir->len; idx++) {
struct irins *ins = ir->inss[idx];