1
0
mirror of https://github.com/golang/go synced 2024-11-19 15:54:46 -07:00

[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://golang.org/cl/167310043
This commit is contained in:
Austin Clements 2014-11-06 14:41:44 -05:00
parent f45fd5753c
commit 22c929f538

View File

@ -1001,10 +1001,13 @@ hard:
Prog* Prog*
gins(int as, Node *f, Node *t) gins(int as, Node *f, Node *t)
{ {
//int32 w; int32 w;
Prog *p; Prog *p;
Addr af, at; Addr af, at;
// TODO(austin): Add self-move test like in 6g (but be careful
// of truncation moves)
memset(&af, 0, sizeof af); memset(&af, 0, sizeof af);
memset(&at, 0, sizeof at); memset(&at, 0, sizeof at);
if(f != N) if(f != N)
@ -1021,9 +1024,6 @@ gins(int as, Node *f, Node *t)
if(debug['g']) if(debug['g'])
print("%P\n", p); print("%P\n", p);
// TODO(minux): enable these.
// right now it fails on MOVD $type."".TypeAssertionError(SB) [width=1], R7 [width=8]
/*
w = 0; w = 0;
switch(as) { switch(as) {
case AMOVB: case AMOVB:
@ -1049,12 +1049,11 @@ gins(int as, Node *f, Node *t)
w = 8; w = 8;
break; 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("f", f);
dump("t", t); dump("t", t);
fatal("bad width: %P (%d, %d)\n", p, af.width, at.width); fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
} }
*/
return p; return p;
} }
@ -1116,12 +1115,9 @@ naddr(Node *n, Addr *a, int canemitcode)
case ONAME: case ONAME:
a->etype = 0; a->etype = 0;
a->width = 0;
a->reg = NREG; a->reg = NREG;
if(n->type != T) { if(n->type != T)
a->etype = simtype[n->type->etype]; a->etype = simtype[n->type->etype];
a->width = n->type->width;
}
a->offset = n->xoffset; a->offset = n->xoffset;
s = n->sym; s = n->sym;
a->node = n->orig; a->node = n->orig;
@ -1242,15 +1238,16 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode); naddr(n->left, a, canemitcode);
a->etype = simtype[tptr]; a->etype = simtype[tptr];
if(a->type == D_CONST && a->offset == 0) if(a->type == D_CONST && a->offset == 0)
break; // len(nil) break; // itab(nil)
a->width = widthptr;
break; break;
case OSPTR: case OSPTR:
// pointer in a string or slice // pointer in a string or slice
naddr(n->left, a, canemitcode); naddr(n->left, a, canemitcode);
a->etype = simtype[tptr];
if(a->type == D_CONST && a->offset == 0) if(a->type == D_CONST && a->offset == 0)
break; // ptr(nil) break; // ptr(nil)
a->etype = simtype[tptr];
a->offset += Array_array; a->offset += Array_array;
a->width = widthptr; a->width = widthptr;
break; break;
@ -1262,6 +1259,7 @@ naddr(Node *n, Addr *a, int canemitcode)
if(a->type == D_CONST && a->offset == 0) if(a->type == D_CONST && a->offset == 0)
break; // len(nil) break; // len(nil)
a->offset += Array_nel; a->offset += Array_nel;
a->width = widthint;
break; break;
case OCAP: case OCAP:
@ -1271,11 +1269,13 @@ naddr(Node *n, Addr *a, int canemitcode)
if(a->type == D_CONST && a->offset == 0) if(a->type == D_CONST && a->offset == 0)
break; // cap(nil) break; // cap(nil)
a->offset += Array_cap; a->offset += Array_cap;
a->width = widthint;
break; break;
case OADDR: case OADDR:
naddr(n->left, a, canemitcode); naddr(n->left, a, canemitcode);
a->etype = tptr; a->etype = tptr;
a->width = widthptr;
switch(a->type) { switch(a->type) {
case D_OREG: case D_OREG:
a->type = D_CONST; a->type = D_CONST;
@ -1288,6 +1288,7 @@ naddr(Node *n, Addr *a, int canemitcode)
default: default:
fatal("naddr: OADDR %d\n", a->type); fatal("naddr: OADDR %d\n", a->type);
} }
break;
} }
} }