mirror of
https://github.com/golang/go
synced 2024-11-12 10:20:27 -07:00
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
This commit is contained in:
parent
9449c18ac8
commit
3670337097
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -135,8 +135,10 @@ enum as
|
||||
AMODU,
|
||||
|
||||
AMOVB,
|
||||
AMOVBS,
|
||||
AMOVBU,
|
||||
AMOVH,
|
||||
AMOVHS,
|
||||
AMOVHU,
|
||||
AMOVW,
|
||||
AMOVM,
|
||||
|
@ -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;
|
||||
|
@ -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 },
|
||||
|
@ -813,8 +813,10 @@ buildop(void)
|
||||
break;
|
||||
case AMOVW:
|
||||
case AMOVB:
|
||||
case AMOVBS:
|
||||
case AMOVBU:
|
||||
case AMOVH:
|
||||
case AMOVHS:
|
||||
case AMOVHU:
|
||||
break;
|
||||
case ASWPW:
|
||||
|
Loading…
Reference in New Issue
Block a user