diff options
author | Austin Clements <austin@google.com> | 2014-11-06 14:41:44 -0500 |
---|---|---|
committer | Austin Clements <austin@google.com> | 2014-11-06 14:41:44 -0500 |
commit | dd695a752144db52633e624f3f0b641dfb6332b8 (patch) | |
tree | 8adc6b610094ed451d3410374e287f85a822270e /src/cmd/9g | |
parent | 5e372b6ca2bc25c5c60027da6ddbe74e537887cb (diff) | |
download | go-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
Diffstat (limited to 'src/cmd/9g')
-rw-r--r-- | src/cmd/9g/gsubr.c | 25 |
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; } } |