aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRémy Oudompheng <oudomphe@phare.normalesup.org>2013-08-08 23:28:53 +0200
committerRémy Oudompheng <oudomphe@phare.normalesup.org>2013-08-08 23:28:53 +0200
commit3670337097dbdc6461af7a3ac38fd2dc784dfecd (patch)
tree14f3adc8351a121218d9c0fb375cbe1281617048 /src
parent9449c18ac8c130df000283d5d533f4cecf6b3afe (diff)
downloadgo-3670337097dbdc6461af7a3ac38fd2dc784dfecd.tar.xz
cmd/5c, cmd/5g, cmd/5l: introduce MOVBS and MOVHS instructions.
MOVBS and MOVHS are defined as duplicates of MOVB and MOVH, and perform sign-extension moving. No change is made to code generation. Update #1837 R=rsc, bradfitz CC=golang-dev https://golang.org/cl/12682043
Diffstat (limited to 'src')
-rw-r--r--src/cmd/5c/peep.c9
-rw-r--r--src/cmd/5c/reg.c2
-rw-r--r--src/cmd/5c/txt.c24
-rw-r--r--src/cmd/5g/gsubr.c3
-rw-r--r--src/cmd/5g/peep.c7
-rw-r--r--src/cmd/5g/reg.c2
-rw-r--r--src/cmd/5l/5.out.h2
-rw-r--r--src/cmd/5l/asm.c20
-rw-r--r--src/cmd/5l/optab.c24
-rw-r--r--src/cmd/5l/span.c2
10 files changed, 69 insertions, 26 deletions
diff --git a/src/cmd/5c/peep.c b/src/cmd/5c/peep.c
index 31c1322757..22328c18c3 100644
--- a/src/cmd/5c/peep.c
+++ b/src/cmd/5c/peep.c
@@ -127,8 +127,10 @@ loop1:
}
continue;
case AMOVH:
+ case AMOVHS:
case AMOVHU:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
if(p->to.type != D_REG)
continue;
@@ -152,6 +154,7 @@ loop1:
switch(p->as) {
case AMOVW:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
if(p->from.type == D_OREG && p->from.offset == 0)
xtramodes(r, &p->from);
@@ -824,7 +827,7 @@ xtramodes(Reg *r, Adr *a)
Adr v;
p = r->prog;
- if(p->as == AMOVB && p->from.type == D_OREG) /* byte load */
+ if((p->as == AMOVB || p->as == AMOVBS) && p->from.type == D_OREG) /* byte load */
return 0;
v = *a;
v.type = D_REG;
@@ -836,7 +839,7 @@ xtramodes(Reg *r, Adr *a)
case AADD:
if(p1->from.type == D_REG ||
(p1->from.type == D_SHIFT && (p1->from.offset&(1<<4)) == 0 &&
- (p->as != AMOVB || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
+ ((p->as != AMOVB && p->as != AMOVBS) || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
(p1->from.type == D_CONST &&
p1->from.offset > -4096 && p1->from.offset < 4096))
if(nochange(uniqs(r1), r, p1)) {
@@ -961,8 +964,10 @@ copyu(Prog *p, Adr *v, Adr *s)
case AMOVF:
case AMOVD:
case AMOVH:
+ case AMOVHS:
case AMOVHU:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
case AMOVDW:
case AMOVWD:
diff --git a/src/cmd/5c/reg.c b/src/cmd/5c/reg.c
index 25bfc58222..c12bd4711d 100644
--- a/src/cmd/5c/reg.c
+++ b/src/cmd/5c/reg.c
@@ -175,8 +175,10 @@ regopt(Prog *p)
*/
case ANOP:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
case AMOVH:
+ case AMOVHS:
case AMOVHU:
case AMOVW:
case AMOVF:
diff --git a/src/cmd/5c/txt.c b/src/cmd/5c/txt.c
index 81da9fb801..6d9b69d001 100644
--- a/src/cmd/5c/txt.c
+++ b/src/cmd/5c/txt.c
@@ -594,13 +594,13 @@ gmove(Node *f, Node *t)
a = AMOVD;
break;
case TCHAR:
- a = AMOVB;
+ a = AMOVBS;
break;
case TUCHAR:
a = AMOVBU;
break;
case TSHORT:
- a = AMOVH;
+ a = AMOVHS;
break;
case TUSHORT:
a = AMOVHU;
@@ -630,13 +630,13 @@ gmove(Node *f, Node *t)
a = AMOVBU;
break;
case TCHAR:
- a = AMOVB;
+ a = AMOVBS;
break;
case TUSHORT:
a = AMOVHU;
break;
case TSHORT:
- a = AMOVH;
+ a = AMOVHS;
break;
case TFLOAT:
a = AMOVF;
@@ -761,13 +761,13 @@ gmove(Node *f, Node *t)
switch(tt) {
case TDOUBLE:
regalloc(&nod, f, Z);
- gins(AMOVH, f, &nod);
+ gins(AMOVHS, f, &nod);
gins(AMOVWD, &nod, t);
regfree(&nod);
return;
case TFLOAT:
regalloc(&nod, f, Z);
- gins(AMOVH, f, &nod);
+ gins(AMOVHS, f, &nod);
gins(AMOVWF, &nod, t);
regfree(&nod);
return;
@@ -776,7 +776,7 @@ gmove(Node *f, Node *t)
case TULONG:
case TLONG:
case TIND:
- a = AMOVH;
+ a = AMOVHS;
break;
case TSHORT:
case TUSHORT:
@@ -819,13 +819,13 @@ gmove(Node *f, Node *t)
switch(tt) {
case TDOUBLE:
regalloc(&nod, f, Z);
- gins(AMOVB, f, &nod);
+ gins(AMOVBS, f, &nod);
gins(AMOVWD, &nod, t);
regfree(&nod);
return;
case TFLOAT:
regalloc(&nod, f, Z);
- gins(AMOVB, f, &nod);
+ gins(AMOVBS, f, &nod);
gins(AMOVWF, &nod, t);
regfree(&nod);
return;
@@ -836,7 +836,7 @@ gmove(Node *f, Node *t)
case TIND:
case TSHORT:
case TUSHORT:
- a = AMOVB;
+ a = AMOVBS;
break;
case TCHAR:
case TUCHAR:
@@ -893,13 +893,13 @@ gmover(Node *f, Node *t)
if(typechlp[ft] && typechlp[tt] && ewidth[ft] >= ewidth[tt]){
switch(tt){
case TSHORT:
- a = AMOVH;
+ a = AMOVHS;
break;
case TUSHORT:
a = AMOVHU;
break;
case TCHAR:
- a = AMOVB;
+ a = AMOVBS;
break;
case TUCHAR:
a = AMOVBU;
diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c
index be4b7df503..2f0009f36c 100644
--- a/src/cmd/5g/gsubr.c
+++ b/src/cmd/5g/gsubr.c
@@ -1877,7 +1877,8 @@ lit:
default:
return 0;
case AADD: case ASUB: case AAND: case AORR: case AEOR:
- case AMOVB: case AMOVBU: case AMOVH: case AMOVHU:
+ case AMOVB: case AMOVBS: case AMOVBU:
+ case AMOVH: case AMOVHS: case AMOVHU:
case AMOVW:
break;
}
diff --git a/src/cmd/5g/peep.c b/src/cmd/5g/peep.c
index c8e8174d36..78785bfe25 100644
--- a/src/cmd/5g/peep.c
+++ b/src/cmd/5g/peep.c
@@ -153,8 +153,10 @@ loop1:
break;
case AMOVH:
+ case AMOVHS:
case AMOVHU:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
/*
* look for MOVB x,R; MOVB R,R
@@ -181,6 +183,7 @@ loop1:
switch(p->as) {
case AMOVW:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
if(p->from.type == D_OREG && p->from.offset == 0)
xtramodes(r, &p->from);
@@ -893,7 +896,7 @@ xtramodes(Reg *r, Adr *a)
break;
if(p1->from.type == D_REG ||
(p1->from.type == D_SHIFT && (p1->from.offset&(1<<4)) == 0 &&
- (p->as != AMOVB || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
+ ((p->as != AMOVB && p->as != AMOVBS) || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
(p1->from.type == D_CONST &&
p1->from.offset > -4096 && p1->from.offset < 4096))
if(nochange(uniqs(r1), r, p1)) {
@@ -1016,8 +1019,10 @@ copyu(Prog *p, Adr *v, Adr *s)
case AMOVF:
case AMOVD:
case AMOVH:
+ case AMOVHS:
case AMOVHU:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
case AMOVFW:
case AMOVWF:
diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c
index 0c2898c4c9..3230ec33c8 100644
--- a/src/cmd/5g/reg.c
+++ b/src/cmd/5g/reg.c
@@ -374,6 +374,7 @@ regopt(Prog *firstp)
*/
case ANOP:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
case AMOVD:
case AMOVDF:
@@ -381,6 +382,7 @@ regopt(Prog *firstp)
case AMOVF:
case AMOVFW:
case AMOVH:
+ case AMOVHS:
case AMOVHU:
case AMOVW:
case AMOVWD:
diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h
index 85dd17a8e5..b47eee3aa9 100644
--- a/src/cmd/5l/5.out.h
+++ b/src/cmd/5l/5.out.h
@@ -135,8 +135,10 @@ enum as
AMODU,
AMOVB,
+ AMOVBS,
AMOVBU,
AMOVH,
+ AMOVHS,
AMOVHU,
AMOVW,
AMOVM,
diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c
index 20ed5e5ae1..92296b5bc9 100644
--- a/src/cmd/5l/asm.c
+++ b/src/cmd/5l/asm.c
@@ -954,7 +954,7 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
r = p->to.reg;
o1 |= (p->from.reg)|(r<<12);
o2 |= (r)|(r<<12);
- if(p->as == AMOVB || p->as == AMOVBU) {
+ if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU) {
o1 |= (24<<7);
o2 |= (24<<7);
} else {
@@ -1035,7 +1035,7 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
if(r == NREG)
r = o->param;
o2 = olrr(REGTMP,r, p->to.reg, p->scond);
- if(p->as == AMOVBU || p->as == AMOVB)
+ if(p->as == AMOVBU || p->as == AMOVBS || p->as == AMOVB)
o2 |= 1<<22;
break;
@@ -1224,7 +1224,7 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
if(p->to.reg == NREG)
diag("MOV to shifter operand");
o1 = osrr(p->from.reg, p->to.offset, p->to.reg, p->scond);
- if(p->as == AMOVB || p->as == AMOVBU)
+ if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU)
o1 |= 1<<22;
break;
@@ -1265,7 +1265,7 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
if(!o1)
break;
o2 = olr(0, REGTMP, p->to.reg, p->scond);
- if(p->as == AMOVBU || p->as == AMOVB)
+ if(p->as == AMOVBU || p->as == AMOVBS || p->as == AMOVB)
o2 |= 1<<22;
if(o->flag & LPCREL) {
o3 = o2;
@@ -1309,9 +1309,9 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
if(r == NREG)
r = o->param;
o1 = olhr(instoffset, r, p->to.reg, p->scond);
- if(p->as == AMOVB)
+ if(p->as == AMOVB || p->as == AMOVBS)
o1 ^= (1<<5)|(1<<6);
- else if(p->as == AMOVH)
+ else if(p->as == AMOVH || p->as == AMOVHS)
o1 ^= (1<<6);
break;
case 72: /* movh/movhu R,L(R) -> strh */
@@ -1331,9 +1331,9 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
if(r == NREG)
r = o->param;
o2 = olhrr(REGTMP, r, p->to.reg, p->scond);
- if(p->as == AMOVB)
+ if(p->as == AMOVB || p->as == AMOVBS)
o2 ^= (1<<5)|(1<<6);
- else if(p->as == AMOVH)
+ else if(p->as == AMOVH || p->as == AMOVHS)
o2 ^= (1<<6);
break;
case 74: /* bx $I */
@@ -1485,9 +1485,9 @@ if(debug['G']) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->name, p-
if(!o1)
break;
o2 = olhr(0, REGTMP, p->to.reg, p->scond);
- if(p->as == AMOVB)
+ if(p->as == AMOVB || p->as == AMOVBS)
o2 ^= (1<<5)|(1<<6);
- else if(p->as == AMOVH)
+ else if(p->as == AMOVH || p->as == AMOVHS)
o2 ^= (1<<6);
if(o->flag & LPCREL) {
o3 = o2;
diff --git a/src/cmd/5l/optab.c b/src/cmd/5l/optab.c
index 91cadbdf45..dfd93f31d1 100644
--- a/src/cmd/5l/optab.c
+++ b/src/cmd/5l/optab.c
@@ -95,8 +95,10 @@ Optab optab[] =
{ ACMP, C_LCON, C_REG, C_NONE, 13, 8, 0, LFROM },
{ AMOVB, C_REG, C_NONE, C_REG, 14, 8, 0 },
+ { AMOVBS, C_REG, C_NONE, C_REG, 14, 8, 0 },
{ AMOVBU, C_REG, C_NONE, C_REG, 58, 4, 0 },
{ AMOVH, C_REG, C_NONE, C_REG, 14, 8, 0 },
+ { AMOVHS, C_REG, C_NONE, C_REG, 14, 8, 0 },
{ AMOVHU, C_REG, C_NONE, C_REG, 14, 8, 0 },
{ AMUL, C_REG, C_REG, C_REG, 15, 4, 0 },
@@ -112,6 +114,8 @@ Optab optab[] =
{ AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0 },
{ AMOVB, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP },
{ AMOVB, C_REG, C_NONE, C_SOREG, 20, 4, 0 },
+ { AMOVBS, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP },
+ { AMOVBS, C_REG, C_NONE, C_SOREG, 20, 4, 0 },
{ AMOVBU, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP },
{ AMOVBU, C_REG, C_NONE, C_SOREG, 20, 4, 0 },
@@ -126,6 +130,9 @@ Optab optab[] =
{ AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO },
{ AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO },
{ AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4 },
+ { AMOVBS, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO },
+ { AMOVBS, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO },
+ { AMOVBS, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4 },
{ AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO },
{ AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO },
{ AMOVBU, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4 },
@@ -176,9 +183,11 @@ Optab optab[] =
{ AMOVBU, C_SHIFT,C_NONE, C_REG, 59, 4, 0 },
{ AMOVB, C_SHIFT,C_NONE, C_REG, 60, 4, 0 },
+ { AMOVBS, C_SHIFT,C_NONE, C_REG, 60, 4, 0 },
{ AMOVW, C_REG, C_NONE, C_SHIFT, 61, 4, 0 },
{ AMOVB, C_REG, C_NONE, C_SHIFT, 61, 4, 0 },
+ { AMOVBS, C_REG, C_NONE, C_SHIFT, 61, 4, 0 },
{ AMOVBU, C_REG, C_NONE, C_SHIFT, 61, 4, 0 },
{ ACASE, C_REG, C_NONE, C_NONE, 62, 4, 0, LPCREL, 8 },
@@ -186,19 +195,28 @@ Optab optab[] =
{ AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0 },
{ AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0 },
+ { AMOVHS, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0 },
+ { AMOVHS, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0 },
{ AMOVHU, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0 },
{ AMOVHU, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0 },
{ AMOVB, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, 0 },
{ AMOVB, C_HOREG,C_NONE, C_REG, 71, 4, 0, 0 },
+ { AMOVBS, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, 0 },
+ { AMOVBS, C_HOREG,C_NONE, C_REG, 71, 4, 0, 0 },
{ AMOVH, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, 0 },
{ AMOVH, C_HOREG,C_NONE, C_REG, 71, 4, 0, 0 },
+ { AMOVHS, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, 0 },
+ { AMOVHS, C_HOREG,C_NONE, C_REG, 71, 4, 0, 0 },
{ AMOVHU, C_HAUTO,C_NONE, C_REG, 71, 4, REGSP, 0 },
{ AMOVHU, C_HOREG,C_NONE, C_REG, 71, 4, 0, 0 },
{ AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO },
{ AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO },
{ AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4 },
+ { AMOVHS, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO },
+ { AMOVHS, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO },
+ { AMOVHS, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4 },
{ AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO },
{ AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO },
{ AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4 },
@@ -206,9 +224,15 @@ Optab optab[] =
{ AMOVB, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
{ AMOVB, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
{ AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4 },
+ { AMOVBS, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
+ { AMOVBS, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
+ { AMOVBS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4 },
{ AMOVH, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
{ AMOVH, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
{ AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4 },
+ { AMOVHS, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
+ { AMOVHS, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
+ { AMOVHS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4 },
{ AMOVHU, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM },
{ AMOVHU, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM },
{ AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4 },
diff --git a/src/cmd/5l/span.c b/src/cmd/5l/span.c
index fe7aface97..7201c006f8 100644
--- a/src/cmd/5l/span.c
+++ b/src/cmd/5l/span.c
@@ -813,8 +813,10 @@ buildop(void)
break;
case AMOVW:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
case AMOVH:
+ case AMOVHS:
case AMOVHU:
break;
case ASWPW: