diff options
| author | Ondřej Surý <ondrej@sury.org> | 2011-06-28 15:28:34 +0200 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2011-06-28 15:28:34 +0200 |
| commit | 8d00b02d82d86abe51773dc2c1751843bb538ae5 (patch) | |
| tree | 6656d166a046fc751548e88f071fedbeb9355443 /src/cmd/5g/gsubr.c | |
| parent | c29cace1e8f3260389ea78fa4ef86d80cd5e5275 (diff) | |
| download | golang-8d00b02d82d86abe51773dc2c1751843bb538ae5.tar.gz | |
Imported Upstream version 2011.06.23upstream-weekly/2011.06.23
Diffstat (limited to 'src/cmd/5g/gsubr.c')
| -rw-r--r-- | src/cmd/5g/gsubr.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index bc39912ea..2d9218461 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -102,6 +102,19 @@ patch(Prog *p, Prog *to) p->to.offset = to->loc; } +Prog* +unpatch(Prog *p) +{ + Prog *q; + + if(p->to.type != D_BRANCH) + fatal("unpatch: not a branch"); + q = p->to.branch; + p->to.branch = P; + p->to.offset = 0; + return q; +} + /* * start a new Prog list. */ @@ -125,6 +138,64 @@ newplist(void) } void +clearstk(void) +{ + Plist *pl; + Prog *p, *p1, *p2, *p3; + Node dst, end, zero, con; + + if(plast->firstpc->to.offset <= 0) + return; + + // reestablish context for inserting code + // at beginning of function. + pl = plast; + p1 = pl->firstpc; + p2 = p1->link; + pc = mal(sizeof(*pc)); + clearp(pc); + p1->link = pc; + + // zero stack frame + + // MOVW $4(SP), R1 + nodreg(&dst, types[tptr], 1); + p = gins(AMOVW, N, &dst); + p->from.type = D_CONST; + p->from.reg = REGSP; + p->from.offset = 4; + + // MOVW $n(R1), R2 + nodreg(&end, types[tptr], 2); + p = gins(AMOVW, N, &end); + p->from.type = D_CONST; + p->from.reg = 1; + p->from.offset = p1->to.offset; + + // MOVW $0, R3 + nodreg(&zero, types[TUINT32], 3); + nodconst(&con, types[TUINT32], 0); + gmove(&con, &zero); + + // L: + // MOVW.P R3, 0(R1) +4 + // CMP R1, R2 + // BNE L + p = gins(AMOVW, &zero, &dst); + p->to.type = D_OREG; + p->to.offset = 4; + p->scond |= C_PBIT; + p3 = p; + p = gins(ACMP, &dst, N); + raddr(&end, p); + patch(gbranch(ABNE, T), p3); + + // continue with original code. + gins(ANOP, N, N)->link = p2; + pc = P; +} + +void gused(Node *n) { gins(ANOP, n, N); // used |
