summaryrefslogtreecommitdiff
path: root/src/cmd/9g
diff options
context:
space:
mode:
authorShenghou Ma <minux@golang.org>2014-08-12 19:51:01 -0400
committerShenghou Ma <minux@golang.org>2014-08-12 19:51:01 -0400
commit81f022f35e9234ce3b6945f029bb363c3e4b5b15 (patch)
tree2fbf052f067351eb8615a2b0264700b653c673aa /src/cmd/9g
parent2ba511778ddd2f026b998bce87a30db71b1bcdd2 (diff)
downloadgo-81f022f35e9234ce3b6945f029bb363c3e4b5b15.tar.gz
[dev.power64] cmd/9g: implement zerorange
LGTM=rsc R=rsc, iant CC=golang-codereviews https://codereview.appspot.com/121540043
Diffstat (limited to 'src/cmd/9g')
-rw-r--r--src/cmd/9g/ggen.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/src/cmd/9g/ggen.c b/src/cmd/9g/ggen.c
index 999b630fa..09f51536a 100644
--- a/src/cmd/9g/ggen.c
+++ b/src/cmd/9g/ggen.c
@@ -9,13 +9,13 @@
#include "gg.h"
#include "opt.h"
-//static Prog *appendpp(Prog*, int, int, vlong, int, vlong);
-static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
+static Prog *appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset);
+static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi);
void
defframe(Prog *ptxt)
{
- uint32 frame, r0;
+ uint32 frame;
Prog *p;
vlong hi, lo;
NodeList *l;
@@ -34,7 +34,6 @@ defframe(Prog *ptxt)
// when it looks for pointers.
p = ptxt;
lo = hi = 0;
- r0 = 0;
// iterate through declarations - they are sorted in decreasing xoffset order.
for(l=curfn->dcl; l != nil; l = l->next) {
n = l->n;
@@ -51,43 +50,69 @@ defframe(Prog *ptxt)
continue;
}
// zero old range
- p = zerorange(p, frame, lo, hi, &r0);
+ p = zerorange(p, frame, lo, hi);
// set new range
hi = n->xoffset + n->type->width;
lo = n->xoffset;
}
// zero final range
- zerorange(p, frame, lo, hi, &r0);
+ zerorange(p, frame, lo, hi);
}
static Prog*
-zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0)
+zerorange(Prog *p, vlong frame, vlong lo, vlong hi)
{
- vlong cnt/*, i*/;
+ vlong cnt, i;
+ Prog *p1;
+ Node *f;
cnt = hi - lo;
if(cnt == 0)
return p;
- fprint(2, "zerorange TODO: %P, frame:%lld, lo:%lld, hi:%lld, r0: %p (%d)\n", p, frame, lo, hi, r0, *r0);
+ if(cnt < 4*widthptr) {
+ for(i = 0; i < cnt; i += widthptr)
+ p = appendpp(p, AMOVD, D_REG, REGZERO, 0, D_OREG, REGSP, 8+frame+lo+i);
+ } else if(cnt <= 128*widthptr) {
+ p = appendpp(p, AADD, D_CONST, NREG, 8+frame+lo-8, D_REG, REGRT1, 0);
+ p->reg = REGSP;
+ p = appendpp(p, ADUFFZERO, D_NONE, NREG, 0, D_OREG, NREG, 0);
+ f = sysfunc("duffzero");
+ naddr(f, &p->to, 1);
+ afunclit(&p->to, f);
+ p->to.offset = 4*(128-cnt/widthptr);
+ } else {
+ p = appendpp(p, AMOVD, D_CONST, NREG, 8+frame+lo-8, D_REG, REGTMP, 0);
+ p = appendpp(p, AADD, D_REG, REGTMP, 0, D_REG, REGRT1, 0);
+ p->reg = REGSP;
+ p = appendpp(p, AMOVD, D_CONST, NREG, cnt, D_REG, REGTMP, 0);
+ p = appendpp(p, AADD, D_REG, REGTMP, 0, D_REG, REGRT2, 0);
+ p->reg = REGRT1;
+ p1 = p = appendpp(p, AMOVDU, D_REG, REGZERO, 0, D_OREG, REGRT1, widthptr);
+ p = appendpp(p, ACMP, D_REG, REGRT1, 0, D_REG, REGRT2, 0);
+ p = appendpp(p, ABNE, D_NONE, NREG, 0, D_BRANCH, NREG, 0);
+ patch(p, p1);
+ }
return p;
}
-/*static*/ Prog*
-appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)
+static Prog*
+appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset)
{
Prog *q;
- q = mal(sizeof(*q));
- clearp(q);
- q->as = as;
- q->lineno = p->lineno;
- q->from.type = ftype;
- q->from.offset = foffset;
- q->to.type = ttype;
- q->to.offset = toffset;
- q->link = p->link;
- p->link = q;
- return q;
+ q = mal(sizeof(*q));
+ clearp(q);
+ q->as = as;
+ q->lineno = p->lineno;
+ q->from.type = ftype;
+ q->from.reg = freg;
+ q->from.offset = foffset;
+ q->to.type = ttype;
+ q->to.reg = treg;
+ q->to.offset = toffset;
+ q->link = p->link;
+ p->link = q;
+ return q;
}
// Sweep the prog list to mark any used nodes.