summaryrefslogtreecommitdiff
path: root/src/cmd/5l/noop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/5l/noop.c')
-rw-r--r--src/cmd/5l/noop.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/cmd/5l/noop.c b/src/cmd/5l/noop.c
index a9439c27a..a5e66f038 100644
--- a/src/cmd/5l/noop.c
+++ b/src/cmd/5l/noop.c
@@ -227,7 +227,7 @@ noops(void)
#ifdef CALLEEBX
if(p->from.sym->foreign){
if(thumb)
- // don't allow literal pool to seperate these
+ // don't allow literal pool to separate these
p = adword(0xe28f7001, 0xe12fff17, p); // arm add 1, pc, r7 and bx r7
// p = aword(0xe12fff17, aword(0xe28f7001, p)); // arm add 1, pc, r7 and bx r7
else
@@ -282,6 +282,7 @@ noops(void)
q1->to.type = D_OREG;
q1->to.offset = -autosize;
q1->to.reg = REGSP;
+ q1->spadj = autosize;
q1->link = p->link;
p->link = q1;
} else if (autosize < StackBig) {
@@ -376,6 +377,7 @@ noops(void)
p->to.type = D_OREG;
p->to.offset = -autosize;
p->to.reg = REGSP;
+ p->spadj = autosize;
} else { // > StackBig
// MOVW $autosize, R1
// MOVW $args, R2
@@ -424,6 +426,7 @@ noops(void)
p->to.type = D_OREG;
p->to.offset = -autosize;
p->to.reg = REGSP;
+ p->spadj = autosize;
}
break;
@@ -527,9 +530,20 @@ noops(void)
p->from.reg = REGSP;
p->to.type = D_REG;
p->to.reg = REGPC;
+ // no spadj because it doesn't fall through
}
break;
+ case AADD:
+ if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP)
+ p->spadj = -p->from.offset;
+ break;
+
+ case ASUB:
+ if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP)
+ p->spadj = p->from.offset;
+ break;
+
case ADIV:
case ADIVU:
case AMOD:
@@ -635,6 +649,7 @@ noops(void)
p->reg = NREG;
p->to.type = D_REG;
p->to.reg = REGSP;
+ p->spadj = -8;
/* SUB $8,SP */
q1->as = ASUB;
@@ -644,6 +659,7 @@ noops(void)
q1->reg = NREG;
q1->to.type = D_REG;
q1->to.reg = REGSP;
+ q1->spadj = 8;
break;
case AMOVW:
@@ -653,6 +669,12 @@ noops(void)
if(a->type == D_CONST && ((a->name == D_NONE && a->reg == REGSP) || a->name == D_AUTO || a->name == D_PARAM) && (a->offset & 3))
diag("SP offset not multiple of 4");
}
+ if((p->scond & C_WBIT) && p->to.type == D_OREG && p->to.reg == REGSP)
+ p->spadj = -p->to.offset;
+ if((p->scond & C_PBIT) && p->from.type == D_OREG && p->from.reg == REGSP && p->to.reg != REGPC)
+ p->spadj = -p->from.offset;
+ if(p->from.type == D_CONST && p->from.reg == REGSP && p->to.type == D_REG && p->to.reg == REGSP)
+ p->spadj = -p->from.offset;
break;
case AMOVB:
case AMOVBU: