From 3670337097dbdc6461af7a3ac38fd2dc784dfecd Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9my=20Oudompheng?= Date: Thu, 8 Aug 2013 23:28:53 +0200 Subject: [PATCH] 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 --- src/cmd/5c/peep.c | 9 +++++++-- src/cmd/5c/reg.c | 2 ++ src/cmd/5c/txt.c | 24 ++++++++++++------------ src/cmd/5g/gsubr.c | 3 ++- src/cmd/5g/peep.c | 7 ++++++- src/cmd/5g/reg.c | 2 ++ src/cmd/5l/5.out.h | 2 ++ src/cmd/5l/asm.c | 20 ++++++++++---------- src/cmd/5l/optab.c | 24 ++++++++++++++++++++++++ src/cmd/5l/span.c | 2 ++ 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: -- 2.48.1