diff options
author | Aram Hăvărneanu <aram@mgk.ro> | 2014-05-30 12:28:01 +0200 |
---|---|---|
committer | Aram Hăvărneanu <aram@mgk.ro> | 2014-05-30 12:28:01 +0200 |
commit | bf0d5c8abbe9d4e3a145df29bee8ef2758d01884 (patch) | |
tree | 19a0ae52aab138503e959b78be3f1ed89bd72fc0 /sys/src/cmd/6c | |
parent | 17d0dea87c80203aaf0199cb33dea0afc4a7f956 (diff) |
6a, 6c, 6l: fix copy propagation
Without an explicit signal for a truncation, copy propagation will
sometimes propagate a 32-bit truncation and end up overwriting uses of
the original 64-bit value.
This was independently discovered and fixed in Go. See:
http://golang.org/issue/1315
https://codereview.appspot.com/6002043/
Thanks Charles Forsyth for tips and advice.
Diffstat (limited to 'sys/src/cmd/6c')
-rw-r--r-- | sys/src/cmd/6c/6.out.h | 2 | ||||
-rw-r--r-- | sys/src/cmd/6c/peep.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/6c/reg.c | 1 | ||||
-rw-r--r-- | sys/src/cmd/6c/txt.c | 70 |
4 files changed, 46 insertions, 29 deletions
diff --git a/sys/src/cmd/6c/6.out.h b/sys/src/cmd/6c/6.out.h index 0766ea3d2..947e5a5ef 100644 --- a/sys/src/cmd/6c/6.out.h +++ b/sys/src/cmd/6c/6.out.h @@ -698,6 +698,8 @@ enum as ASWAPGS, AMODE, + + AMOVQL, ALAST }; diff --git a/sys/src/cmd/6c/peep.c b/sys/src/cmd/6c/peep.c index 351dc887d..e977b5c1f 100644 --- a/sys/src/cmd/6c/peep.c +++ b/sys/src/cmd/6c/peep.c @@ -404,6 +404,7 @@ subprop(Reg *r0) case AMOVSL: case AMOVSQ: + case AMOVQL: return 0; case AMOVL: @@ -602,6 +603,7 @@ copyu(Prog *p, Adr *v, Adr *s) case AMOVWLZX: case AMOVWQSX: case AMOVWQZX: + case AMOVQL: case AMOVSS: case AMOVSD: diff --git a/sys/src/cmd/6c/reg.c b/sys/src/cmd/6c/reg.c index 43e21a4f3..82a32a1db 100644 --- a/sys/src/cmd/6c/reg.c +++ b/sys/src/cmd/6c/reg.c @@ -183,6 +183,7 @@ regopt(Prog *p) case AMOVWLZX: case AMOVWQSX: case AMOVWQZX: + case AMOVQL: case AMOVSS: case AMOVSD: diff --git a/sys/src/cmd/6c/txt.c b/sys/src/cmd/6c/txt.c index e3b9a9ee5..85c4f2a46 100644 --- a/sys/src/cmd/6c/txt.c +++ b/sys/src/cmd/6c/txt.c @@ -767,7 +767,6 @@ gmove(Node *f, Node *t) case CASE( TUINT, TCHAR): case CASE( TLONG, TCHAR): case CASE( TULONG, TCHAR): - case CASE( TIND, TCHAR): case CASE( TCHAR, TUCHAR): case CASE( TUCHAR, TUCHAR): @@ -777,7 +776,6 @@ gmove(Node *f, Node *t) case CASE( TUINT, TUCHAR): case CASE( TLONG, TUCHAR): case CASE( TULONG, TUCHAR): - case CASE( TIND, TUCHAR): case CASE( TSHORT, TSHORT): case CASE( TUSHORT,TSHORT): @@ -785,7 +783,6 @@ gmove(Node *f, Node *t) case CASE( TUINT, TSHORT): case CASE( TLONG, TSHORT): case CASE( TULONG, TSHORT): - case CASE( TIND, TSHORT): case CASE( TSHORT, TUSHORT): case CASE( TUSHORT,TUSHORT): @@ -793,42 +790,26 @@ gmove(Node *f, Node *t) case CASE( TUINT, TUSHORT): case CASE( TLONG, TUSHORT): case CASE( TULONG, TUSHORT): - case CASE( TIND, TUSHORT): case CASE( TINT, TINT): case CASE( TUINT, TINT): case CASE( TLONG, TINT): - case CASE( TULONG, TINT): - case CASE( TIND, TINT): + case CASE( TULONG, TINT):: case CASE( TINT, TUINT): case CASE( TUINT, TUINT): case CASE( TLONG, TUINT): case CASE( TULONG, TUINT): - case CASE( TIND, TUINT): - - case CASE( TUINT, TIND): - case CASE( TVLONG, TUINT): - case CASE( TVLONG, TULONG): - case CASE( TUVLONG, TUINT): - case CASE( TUVLONG, TULONG): *****/ a = AMOVL; break; - case CASE( TVLONG, TCHAR): - case CASE( TVLONG, TSHORT): - case CASE( TVLONG, TINT): - case CASE( TVLONG, TLONG): - case CASE( TUVLONG, TCHAR): - case CASE( TUVLONG, TSHORT): - case CASE( TUVLONG, TINT): - case CASE( TUVLONG, TLONG): + case CASE( TINT, TIND): case CASE( TINT, TVLONG): case CASE( TINT, TUVLONG): - case CASE( TLONG, TVLONG): - case CASE( TINT, TIND): case CASE( TLONG, TIND): + case CASE( TLONG, TVLONG): + case CASE( TLONG, TUVLONG): a = AMOVLQSX; if(f->op == OCONST) { f->vconst &= (uvlong)0xffffffffU; @@ -844,22 +825,53 @@ gmove(Node *f, Node *t) case CASE( TULONG, TVLONG): case CASE( TULONG, TUVLONG): case CASE( TULONG, TIND): - a = AMOVL; /* same effect as AMOVLQZX */ + a = AMOVLQZX; if(f->op == OCONST) { f->vconst &= (uvlong)0xffffffffU; a = AMOVQ; } break; + case CASE( TIND, TCHAR): + case CASE( TIND, TUCHAR): + case CASE( TIND, TSHORT): + case CASE( TIND, TUSHORT): + case CASE( TIND, TINT): + case CASE( TIND, TUINT): + case CASE( TIND, TLONG): + case CASE( TIND, TULONG): + case CASE( TVLONG, TCHAR): + case CASE( TVLONG, TUCHAR): + case CASE( TVLONG, TSHORT): + case CASE( TVLONG, TUSHORT): + case CASE( TVLONG, TINT): + case CASE( TVLONG, TUINT): + case CASE( TVLONG, TLONG): + case CASE( TVLONG, TULONG): + case CASE( TUVLONG, TCHAR): + case CASE( TUVLONG, TUCHAR): + case CASE( TUVLONG, TSHORT): + case CASE( TUVLONG, TUSHORT): + case CASE( TUVLONG, TINT): + case CASE( TUVLONG, TUINT): + case CASE( TUVLONG, TLONG): + case CASE( TUVLONG, TULONG): + a = AMOVQL; + if(f->op == OCONST) { + f->vconst &= 0xffffffffU; + a = AMOVL; + } + break; + + case CASE( TIND, TIND): case CASE( TIND, TVLONG): - case CASE( TVLONG, TVLONG): - case CASE( TUVLONG, TVLONG): - case CASE( TVLONG, TUVLONG): - case CASE( TUVLONG, TUVLONG): case CASE( TIND, TUVLONG): case CASE( TVLONG, TIND): + case CASE( TVLONG, TVLONG): + case CASE( TVLONG, TUVLONG): case CASE( TUVLONG, TIND): - case CASE( TIND, TIND): + case CASE( TUVLONG, TVLONG): + case CASE( TUVLONG, TUVLONG): a = AMOVQ; break; |