mirror of
https://github.com/golang/go
synced 2024-11-14 06:40:22 -07:00
cmd/internal/obj: consolidate AMOVW and AMOVWZ optab entries
This requires consolidating the register move operations into a single case entry in asmout. These moves are also used to sign/zero-extend register values. Combine the three asmout cases for register moves. This allows AMOVWZ and AMOVW to be handled with the same optab entries. Likewise, remove the diagnostic error for non-zero constant loads into R0 using the register move operations, it is not possible to match this asmout case with a non-zero constant. Finally, fix the load constant 0 via "MOV[BHW]{,Z} $0, Rx". These now generate "li Rx, $0" instead of a zero/sign-extend of the contents of R0. Change-Id: Ia4a263661582f10feda27ee21cb121e05ea931dc Reviewed-on: https://go-review.googlesource.com/c/go/+/308190 Run-TryBot: Paul Murphy <murp@ibm.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> Reviewed-by: Carlos Eduardo Seo <carlos.seo@linaro.org> Trust: Carlos Eduardo Seo <carlos.seo@linaro.org>
This commit is contained in:
parent
8009a81f7a
commit
ddd8d7c0a6
9
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
9
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
@ -77,6 +77,15 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
|||||||
MOVBU R4, 1(R3) // 9c830001
|
MOVBU R4, 1(R3) // 9c830001
|
||||||
MOVBU R5, (R3)(R4) // 7ca419ee
|
MOVBU R5, (R3)(R4) // 7ca419ee
|
||||||
|
|
||||||
|
MOVB $0, R4 // 38800000
|
||||||
|
MOVBZ $0, R4 // 38800000
|
||||||
|
MOVH $0, R4 // 38800000
|
||||||
|
MOVHZ $0, R4 // 38800000
|
||||||
|
MOVW $0, R4 // 38800000
|
||||||
|
MOVWZ $0, R4 // 38800000
|
||||||
|
MOVD $0, R4 // 38800000
|
||||||
|
MOVD $0, R0 // 38000000
|
||||||
|
|
||||||
ADD $1, R3 // 38630001
|
ADD $1, R3 // 38630001
|
||||||
ADD $1, R3, R4 // 38830001
|
ADD $1, R3, R4 // 38830001
|
||||||
ADD $-1, R4 // 3884ffff
|
ADD $-1, R4 // 3884ffff
|
||||||
|
@ -209,7 +209,7 @@ var optab = []Optab{
|
|||||||
{as: AMOVB, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
|
{as: AMOVB, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
|
||||||
{as: AMOVB, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
|
{as: AMOVB, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
|
||||||
{as: AMOVB, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
|
{as: AMOVB, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
|
||||||
{as: AMOVB, a1: C_REG, a6: C_REG, type_: 12, size: 4},
|
{as: AMOVB, a1: C_REG, a6: C_REG, type_: 13, size: 4},
|
||||||
|
|
||||||
{as: AMOVBZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
|
{as: AMOVBZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
|
||||||
{as: AMOVBZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
|
{as: AMOVBZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
|
||||||
@ -237,7 +237,7 @@ var optab = []Optab{
|
|||||||
{as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
|
{as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
|
||||||
{as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
|
{as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
|
||||||
{as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
|
{as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
|
||||||
{as: AMOVD, a1: C_REG, a6: C_REG, type_: 1, size: 4},
|
{as: AMOVD, a1: C_REG, a6: C_REG, type_: 13, size: 4},
|
||||||
|
|
||||||
{as: AMOVW, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
|
{as: AMOVW, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
|
||||||
{as: AMOVW, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
|
{as: AMOVW, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
|
||||||
@ -255,25 +255,7 @@ var optab = []Optab{
|
|||||||
{as: AMOVW, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
|
{as: AMOVW, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
|
||||||
{as: AMOVW, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
|
{as: AMOVW, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
|
||||||
{as: AMOVW, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
|
{as: AMOVW, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
|
||||||
{as: AMOVW, a1: C_REG, a6: C_REG, type_: 12, size: 4},
|
{as: AMOVW, a1: C_REG, a6: C_REG, type_: 13, size: 4},
|
||||||
|
|
||||||
{as: AMOVWZ, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
|
|
||||||
{as: AMOVWZ, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
|
|
||||||
{as: AMOVWZ, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
|
|
||||||
{as: AMOVWZ, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
|
|
||||||
{as: AMOVWZ, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
|
|
||||||
{as: AMOVWZ, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
|
|
||||||
{as: AMOVWZ, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
|
|
||||||
{as: AMOVWZ, a1: C_REG, a6: C_REG, type_: 13, size: 4},
|
|
||||||
|
|
||||||
{as: AFMOVD, a1: C_ADDCON, a6: C_FREG, type_: 24, size: 8},
|
{as: AFMOVD, a1: C_ADDCON, a6: C_FREG, type_: 24, size: 8},
|
||||||
{as: AFMOVD, a1: C_SOREG, a6: C_FREG, type_: 8, size: 4},
|
{as: AFMOVD, a1: C_SOREG, a6: C_FREG, type_: 8, size: 4},
|
||||||
@ -1925,6 +1907,9 @@ func buildop(ctxt *obj.Link) {
|
|||||||
case AFTSQRT:
|
case AFTSQRT:
|
||||||
opset(AFTSQRT, r0)
|
opset(AFTSQRT, r0)
|
||||||
|
|
||||||
|
case AMOVW: /* load/store/move word with sign extension; move 32-bit literals */
|
||||||
|
opset(AMOVWZ, r0) /* Same as above, but zero extended */
|
||||||
|
|
||||||
case AADD,
|
case AADD,
|
||||||
AADDIS,
|
AADDIS,
|
||||||
AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
|
AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
|
||||||
@ -1932,9 +1917,6 @@ func buildop(ctxt *obj.Link) {
|
|||||||
AFMOVSX,
|
AFMOVSX,
|
||||||
AFMOVSZ,
|
AFMOVSZ,
|
||||||
ALSW,
|
ALSW,
|
||||||
AMOVW,
|
|
||||||
/* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
|
|
||||||
AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */
|
|
||||||
AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
|
AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
|
||||||
AMOVB, /* macro: move byte with sign extension */
|
AMOVB, /* macro: move byte with sign extension */
|
||||||
AMOVBU, /* macro: move byte with sign extension & update */
|
AMOVBU, /* macro: move byte with sign extension & update */
|
||||||
@ -2392,20 +2374,6 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
case 0: /* pseudo ops */
|
case 0: /* pseudo ops */
|
||||||
break
|
break
|
||||||
|
|
||||||
case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
|
|
||||||
if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
|
|
||||||
v := c.regoff(&p.From)
|
|
||||||
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
|
||||||
//nerrors--;
|
|
||||||
c.ctxt.Diag("literal operation on R0\n%v", p)
|
|
||||||
}
|
|
||||||
|
|
||||||
o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
|
|
||||||
|
|
||||||
case 2: /* int/cr/fp op Rb,[Ra],Rd */
|
case 2: /* int/cr/fp op Rb,[Ra],Rd */
|
||||||
r := int(p.Reg)
|
r := int(p.Reg)
|
||||||
|
|
||||||
@ -2594,34 +2562,35 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
|||||||
}
|
}
|
||||||
o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
|
o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
|
||||||
|
|
||||||
case 12: /* movb r,r (extsb); movw r,r (extsw) */
|
case 13: /* mov[bhwd]{z,} r,r */
|
||||||
if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
|
// This needs to handle "MOV* $0, Rx". This shows up because $0 also
|
||||||
v := c.regoff(&p.From)
|
// matches C_REG if r0iszero. This happens because C_REG sorts before C_ANDCON
|
||||||
if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
|
// TODO: fix the above behavior and cleanup this exception.
|
||||||
c.ctxt.Diag("literal operation on R0\n%v", p)
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
}
|
o1 = LOP_IRR(OP_ADDI, REGZERO, uint32(p.To.Reg), 0)
|
||||||
|
|
||||||
o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if p.To.Type == obj.TYPE_CONST {
|
||||||
if p.As == AMOVW {
|
c.ctxt.Diag("cannot move into constant 0\n%v", p)
|
||||||
o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
|
||||||
} else {
|
|
||||||
o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
|
switch p.As {
|
||||||
if p.As == AMOVBZ {
|
case AMOVB:
|
||||||
|
o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
||||||
|
case AMOVBZ:
|
||||||
o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
|
o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
|
||||||
} else if p.As == AMOVH {
|
case AMOVH:
|
||||||
o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
||||||
} else if p.As == AMOVHZ {
|
case AMOVHZ:
|
||||||
o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
|
o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
|
||||||
} else if p.As == AMOVWZ {
|
case AMOVW:
|
||||||
|
o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
|
||||||
|
case AMOVWZ:
|
||||||
o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
|
o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
|
||||||
} else {
|
case AMOVD:
|
||||||
c.ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
|
o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
|
||||||
|
default:
|
||||||
|
c.ctxt.Diag("internal: bad register move/truncation\n%v", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
|
case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
|
||||||
|
Loading…
Reference in New Issue
Block a user