summaryrefslogtreecommitdiff
path: root/src/cmd/5l/pass.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/5l/pass.c')
-rw-r--r--src/cmd/5l/pass.c77
1 files changed, 72 insertions, 5 deletions
diff --git a/src/cmd/5l/pass.c b/src/cmd/5l/pass.c
index 0f2afbd85..c22b86085 100644
--- a/src/cmd/5l/pass.c
+++ b/src/cmd/5l/pass.c
@@ -119,7 +119,7 @@ loop:
i--;
continue;
}
- if(a == AB || (a == ARET && q->scond == 14) || a == ARFE)
+ if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF)
goto copy;
if(q->cond == P || (q->cond->mark&FOLL))
continue;
@@ -140,7 +140,7 @@ loop:
}
(*last)->link = r;
*last = r;
- if(a == AB || (a == ARET && q->scond == 14) || a == ARFE)
+ if(a == AB || (a == ARET && q->scond == 14) || a == ARFE || a == AUNDEF)
return;
r->as = ABNE;
if(a == ABNE)
@@ -166,7 +166,7 @@ loop:
p->mark |= FOLL;
(*last)->link = p;
*last = p;
- if(a == AB || (a == ARET && p->scond == 14) || a == ARFE){
+ if(a == AB || (a == ARET && p->scond == 14) || a == ARFE || a == AUNDEF){
return;
}
if(p->cond != P)
@@ -215,7 +215,7 @@ patch(void)
s = p->to.sym;
if(s->text == nil)
continue;
- switch(s->type) {
+ switch(s->type&SMASK) {
default:
diag("undefined: %s", s->name);
s->type = STEXT;
@@ -231,7 +231,7 @@ patch(void)
if(p->to.type != D_BRANCH)
continue;
c = p->to.offset;
- for(q = textp->text; q != P;) {
+ for(q = cursym->text; q != P;) {
if(c == q->pc)
break;
if(q->forwd != P && c >= q->forwd->pc)
@@ -333,3 +333,70 @@ rnd(int32 v, int32 r)
v -= c;
return v;
}
+
+void
+dozerostk(void)
+{
+ Prog *p, *pl;
+ int32 autoffset;
+
+ for(cursym = textp; cursym != nil; cursym = cursym->next) {
+ if(cursym->text == nil || cursym->text->link == nil)
+ continue;
+ p = cursym->text;
+ autoffset = p->to.offset;
+ if(autoffset < 0)
+ autoffset = 0;
+ if(autoffset && !(p->reg&NOSPLIT)) {
+ // MOVW $4(R13), R1
+ p = appendp(p);
+ p->as = AMOVW;
+ p->from.type = D_CONST;
+ p->from.reg = 13;
+ p->from.offset = 4;
+ p->to.type = D_REG;
+ p->to.reg = 1;
+
+ // MOVW $n(R13), R2
+ p = appendp(p);
+ p->as = AMOVW;
+ p->from.type = D_CONST;
+ p->from.reg = 13;
+ p->from.offset = 4 + autoffset;
+ p->to.type = D_REG;
+ p->to.reg = 2;
+
+ // MOVW $0, R3
+ p = appendp(p);
+ p->as = AMOVW;
+ p->from.type = D_CONST;
+ p->from.offset = 0;
+ p->to.type = D_REG;
+ p->to.reg = 3;
+
+ // L:
+ // MOVW.P R3, 0(R1) +4
+ // CMP R1, R2
+ // BNE L
+ p = pl = appendp(p);
+ p->as = AMOVW;
+ p->from.type = D_REG;
+ p->from.reg = 3;
+ p->to.type = D_OREG;
+ p->to.reg = 1;
+ p->to.offset = 4;
+ p->scond |= C_PBIT;
+
+ p = appendp(p);
+ p->as = ACMP;
+ p->from.type = D_REG;
+ p->from.reg = 1;
+ p->reg = 2;
+
+ p = appendp(p);
+ p->as = ABNE;
+ p->to.type = D_BRANCH;
+ p->cond = pl;
+ }
+ }
+}