summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2014-11-06 14:41:44 -0500
committerAustin Clements <austin@google.com>2014-11-06 14:41:44 -0500
commitdd695a752144db52633e624f3f0b641dfb6332b8 (patch)
tree8adc6b610094ed451d3410374e287f85a822270e
parent5e372b6ca2bc25c5c60027da6ddbe74e537887cb (diff)
downloadgo-dd695a752144db52633e624f3f0b641dfb6332b8.tar.gz
[dev.power64] 9g: fix addr width calculation; enable MOV* width check
9g's naddr was missing assignments to a->width in several cases, so the optimizer was getting bogus width information. Add them. This correct width information also lets us enable the width check in gins for MOV*. LGTM=rsc R=rsc CC=golang-codereviews https://codereview.appspot.com/167310043
-rw-r--r--src/cmd/9g/gsubr.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/src/cmd/9g/gsubr.c b/src/cmd/9g/gsubr.c
index d8b62b1da..f7a429081 100644
--- a/src/cmd/9g/gsubr.c
+++ b/src/cmd/9g/gsubr.c
@@ -1001,10 +1001,13 @@ hard:
Prog*
gins(int as, Node *f, Node *t)
{
- //int32 w;
+ int32 w;
Prog *p;
Addr af, at;
+ // TODO(austin): Add self-move test like in 6g (but be careful
+ // of truncation moves)
+
memset(&af, 0, sizeof af);
memset(&at, 0, sizeof at);
if(f != N)
@@ -1021,9 +1024,6 @@ gins(int as, Node *f, Node *t)
if(debug['g'])
print("%P\n", p);
- // TODO(minux): enable these.
- // right now it fails on MOVD $type."".TypeAssertionError(SB) [width=1], R7 [width=8]
- /*
w = 0;
switch(as) {
case AMOVB:
@@ -1049,12 +1049,11 @@ gins(int as, Node *f, Node *t)
w = 8;
break;
}
- if(w != 0 && ((f != N && af.width < w) || (t != N && at.width > w))) {
+ if(w != 0 && ((f != N && af.width < w) || (t != N && at.type != D_REG && at.width > w))) {
dump("f", f);
dump("t", t);
fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
}
- */
return p;
}
@@ -1116,12 +1115,9 @@ naddr(Node *n, Addr *a, int canemitcode)
case ONAME:
a->etype = 0;
- a->width = 0;
a->reg = NREG;
- if(n->type != T) {
+ if(n->type != T)
a->etype = simtype[n->type->etype];
- a->width = n->type->width;
- }
a->offset = n->xoffset;
s = n->sym;
a->node = n->orig;
@@ -1242,15 +1238,16 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode);
a->etype = simtype[tptr];
if(a->type == D_CONST && a->offset == 0)
- break; // len(nil)
+ break; // itab(nil)
+ a->width = widthptr;
break;
case OSPTR:
// pointer in a string or slice
naddr(n->left, a, canemitcode);
+ a->etype = simtype[tptr];
if(a->type == D_CONST && a->offset == 0)
break; // ptr(nil)
- a->etype = simtype[tptr];
a->offset += Array_array;
a->width = widthptr;
break;
@@ -1262,6 +1259,7 @@ naddr(Node *n, Addr *a, int canemitcode)
if(a->type == D_CONST && a->offset == 0)
break; // len(nil)
a->offset += Array_nel;
+ a->width = widthint;
break;
case OCAP:
@@ -1271,11 +1269,13 @@ naddr(Node *n, Addr *a, int canemitcode)
if(a->type == D_CONST && a->offset == 0)
break; // cap(nil)
a->offset += Array_cap;
+ a->width = widthint;
break;
case OADDR:
naddr(n->left, a, canemitcode);
a->etype = tptr;
+ a->width = widthptr;
switch(a->type) {
case D_OREG:
a->type = D_CONST;
@@ -1288,6 +1288,7 @@ naddr(Node *n, Addr *a, int canemitcode)
default:
fatal("naddr: OADDR %d\n", a->type);
}
+ break;
}
}