summaryrefslogtreecommitdiff
path: root/sys/src/cmd/6c
diff options
context:
space:
mode:
authorAram Hăvărneanu <aram@mgk.ro>2014-05-30 12:28:01 +0200
committerAram Hăvărneanu <aram@mgk.ro>2014-05-30 12:28:01 +0200
commitbf0d5c8abbe9d4e3a145df29bee8ef2758d01884 (patch)
tree19a0ae52aab138503e959b78be3f1ed89bd72fc0 /sys/src/cmd/6c
parent17d0dea87c80203aaf0199cb33dea0afc4a7f956 (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.h2
-rw-r--r--sys/src/cmd/6c/peep.c2
-rw-r--r--sys/src/cmd/6c/reg.c1
-rw-r--r--sys/src/cmd/6c/txt.c70
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;