mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/asm,cmd/compile: support 5 operand RLWNM/RLWMI on ppc64
These instructions are actually 5 argument opcodes as specified by the ISA. Prior to this patch, the MB and ME arguments were merged into a single bitmask operand to workaround the limitations of the ppc64 assembler backend. This limitation no longer exists. Thus, we can pass operands for these opcodes without having to merge the MB and ME arguments in the assembler frontend or compiler backend. Likewise, support for 4 operand variants is unchanged. Change-Id: Ib086774f3581edeaadfd2190d652aaaa8a90daeb Reviewed-on: https://go-review.googlesource.com/c/go/+/298750 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
18510ae88f
commit
48ddf70128
6 changed files with 58 additions and 47 deletions
|
|
@ -799,19 +799,11 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
p.errorf("can't handle %s instruction with 4 operands", op)
|
p.errorf("can't handle %s instruction with 4 operands", op)
|
||||||
return
|
return
|
||||||
case 5:
|
case 5:
|
||||||
if p.arch.Family == sys.PPC64 && arch.IsPPC64RLD(op) {
|
if p.arch.Family == sys.PPC64 {
|
||||||
// Always reg, reg, con, con, reg. (con, con is a 'mask').
|
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
|
// Second arg is always a register type on ppc64.
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
mask1 := p.getConstant(prog, op, &a[2])
|
prog.SetRestArgs([]obj.Addr{a[2], a[3]})
|
||||||
mask2 := p.getConstant(prog, op, &a[3])
|
|
||||||
var mask uint32
|
|
||||||
if mask1 < mask2 {
|
|
||||||
mask = (^uint32(0) >> uint(mask1)) & (^uint32(0) << uint(31-mask2))
|
|
||||||
} else {
|
|
||||||
mask = (^uint32(0) >> uint(mask2+1)) & (^uint32(0) << uint(31-(mask1-1)))
|
|
||||||
}
|
|
||||||
prog.SetFrom3Const(int64(mask))
|
|
||||||
prog.To = a[4]
|
prog.To = a[4]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
6
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
|
|
@ -280,11 +280,17 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||||
ROTLW R3, R4, R5 // 5c85183e
|
ROTLW R3, R4, R5 // 5c85183e
|
||||||
EXTSWSLI $3, R4, R5 // 7c851ef4
|
EXTSWSLI $3, R4, R5 // 7c851ef4
|
||||||
RLWMI $7, R3, $65535, R6 // 50663c3e
|
RLWMI $7, R3, $65535, R6 // 50663c3e
|
||||||
|
RLWMI $7, R3, $16, $31, R6 // 50663c3e
|
||||||
RLWMICC $7, R3, $65535, R6 // 50663c3f
|
RLWMICC $7, R3, $65535, R6 // 50663c3f
|
||||||
|
RLWMICC $7, R3, $16, $31, R6 // 50663c3f
|
||||||
RLWNM $3, R4, $7, R6 // 54861f7e
|
RLWNM $3, R4, $7, R6 // 54861f7e
|
||||||
|
RLWNM $3, R4, $29, $31, R6 // 54861f7e
|
||||||
RLWNM R3, R4, $7, R6 // 5c861f7e
|
RLWNM R3, R4, $7, R6 // 5c861f7e
|
||||||
|
RLWNM R3, R4, $29, $31, R6 // 5c861f7e
|
||||||
RLWNMCC $3, R4, $7, R6 // 54861f7f
|
RLWNMCC $3, R4, $7, R6 // 54861f7f
|
||||||
|
RLWNMCC $3, R4, $29, $31, R6 // 54861f7f
|
||||||
RLWNMCC R3, R4, $7, R6 // 5c861f7f
|
RLWNMCC R3, R4, $7, R6 // 5c861f7f
|
||||||
|
RLWNMCC R3, R4, $29, $31, R6 // 5c861f7f
|
||||||
RLDMI $0, R4, $7, R6 // 7886076c
|
RLDMI $0, R4, $7, R6 // 7886076c
|
||||||
RLDMICC $0, R4, $7, R6 // 7886076d
|
RLDMICC $0, R4, $7, R6 // 7886076d
|
||||||
RLDIMI $0, R4, $7, R6 // 788601cc
|
RLDIMI $0, R4, $7, R6 // 788601cc
|
||||||
|
|
|
||||||
|
|
@ -653,21 +653,21 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
|
|
||||||
// Auxint holds encoded rotate + mask
|
// Auxint holds encoded rotate + mask
|
||||||
case ssa.OpPPC64RLWINM, ssa.OpPPC64RLWMI:
|
case ssa.OpPPC64RLWINM, ssa.OpPPC64RLWMI:
|
||||||
rot, _, _, mask := ssa.DecodePPC64RotateMask(v.AuxInt)
|
rot, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
||||||
p.Reg = v.Args[0].Reg()
|
p.Reg = v.Args[0].Reg()
|
||||||
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(rot)}
|
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(rot)}
|
||||||
p.SetFrom3Const(int64(mask))
|
p.SetRestArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
|
||||||
|
|
||||||
// Auxint holds mask
|
// Auxint holds mask
|
||||||
case ssa.OpPPC64RLWNM:
|
case ssa.OpPPC64RLWNM:
|
||||||
_, _, _, mask := ssa.DecodePPC64RotateMask(v.AuxInt)
|
_, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
|
||||||
p.Reg = v.Args[0].Reg()
|
p.Reg = v.Args[0].Reg()
|
||||||
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()}
|
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()}
|
||||||
p.SetFrom3Const(int64(mask))
|
p.SetRestArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
|
||||||
|
|
||||||
case ssa.OpPPC64MADDLD:
|
case ssa.OpPPC64MADDLD:
|
||||||
r := v.Reg()
|
r := v.Reg()
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,9 @@ var optab = []Optab{
|
||||||
{as: ASRAD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 56, size: 4},
|
{as: ASRAD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 56, size: 4},
|
||||||
{as: ASRAD, a1: C_SCON, a6: C_REG, type_: 56, size: 4},
|
{as: ASRAD, a1: C_SCON, a6: C_REG, type_: 56, size: 4},
|
||||||
{as: ARLWMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
|
{as: ARLWMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
|
||||||
|
{as: ARLWMI, a1: C_SCON, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 102, size: 4},
|
||||||
{as: ARLWMI, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 63, size: 4},
|
{as: ARLWMI, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 63, size: 4},
|
||||||
|
{as: ARLWMI, a1: C_REG, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 103, size: 4},
|
||||||
{as: ACLRLSLWI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
|
{as: ACLRLSLWI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
|
||||||
{as: ARLDMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 30, size: 4},
|
{as: ARLDMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 30, size: 4},
|
||||||
{as: ARLDC, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
|
{as: ARLDC, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
|
||||||
|
|
@ -3861,6 +3863,17 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
||||||
}
|
}
|
||||||
case 101:
|
case 101:
|
||||||
o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
|
o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
|
||||||
|
|
||||||
|
case 102: /* RLWMI $sh,rs,$mb,$me,rt (M-form opcode)*/
|
||||||
|
mb := uint32(c.regoff(&p.RestArgs[0].Addr))
|
||||||
|
me := uint32(c.regoff(&p.RestArgs[1].Addr))
|
||||||
|
sh := uint32(c.regoff(&p.From))
|
||||||
|
o1 = OP_RLW(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), sh, mb, me)
|
||||||
|
|
||||||
|
case 103: /* RLWMI rb,rs,$mb,$me,rt (M-form opcode)*/
|
||||||
|
mb := uint32(c.regoff(&p.RestArgs[0].Addr))
|
||||||
|
me := uint32(c.regoff(&p.RestArgs[1].Addr))
|
||||||
|
o1 = OP_RLW(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), mb, me)
|
||||||
}
|
}
|
||||||
|
|
||||||
out[0] = o1
|
out[0] = o1
|
||||||
|
|
|
||||||
|
|
@ -176,38 +176,38 @@ func f32(x uint32) uint32 {
|
||||||
func checkMaskedRotate32(a []uint32, r int) {
|
func checkMaskedRotate32(a []uint32, r int) {
|
||||||
i := 0
|
i := 0
|
||||||
|
|
||||||
// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]16711680, R[0-9]+"
|
// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
|
||||||
// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]16711680, R[0-9]+"
|
// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
|
||||||
a[i] = bits.RotateLeft32(a[i], 16) & 0xFF0000
|
a[i] = bits.RotateLeft32(a[i], 16) & 0xFF0000
|
||||||
i++
|
i++
|
||||||
// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]16711680, R[0-9]+"
|
// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
|
||||||
// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]16711680, R[0-9]+"
|
// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]8, [$]15, R[0-9]+"
|
||||||
a[i] = bits.RotateLeft32(a[i]&0xFF, 16)
|
a[i] = bits.RotateLeft32(a[i]&0xFF, 16)
|
||||||
i++
|
i++
|
||||||
// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]4080, R[0-9]+"
|
// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]27, R[0-9]+"
|
||||||
// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]4080, R[0-9]+"
|
// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]27, R[0-9]+"
|
||||||
a[i] = bits.RotateLeft32(a[i], 4) & 0xFF0
|
a[i] = bits.RotateLeft32(a[i], 4) & 0xFF0
|
||||||
i++
|
i++
|
||||||
// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]255, R[0-9]+"
|
// ppc64le: "RLWNM\t[$]16, R[0-9]+, [$]24, [$]31, R[0-9]+"
|
||||||
// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]255, R[0-9]+"
|
// ppc64: "RLWNM\t[$]16, R[0-9]+, [$]24, [$]31, R[0-9]+"
|
||||||
a[i] = bits.RotateLeft32(a[i]&0xFF0000, 16)
|
a[i] = bits.RotateLeft32(a[i]&0xFF0000, 16)
|
||||||
i++
|
i++
|
||||||
|
|
||||||
// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]16711680, R[0-9]+"
|
// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+"
|
||||||
// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]16711680, R[0-9]+"
|
// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]8, [$]15, R[0-9]+"
|
||||||
a[i] = bits.RotateLeft32(a[i], r) & 0xFF0000
|
a[i] = bits.RotateLeft32(a[i], r) & 0xFF0000
|
||||||
i++
|
i++
|
||||||
// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]65280, R[0-9]+"
|
// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+"
|
||||||
// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]65280, R[0-9]+"
|
// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]16, [$]23, R[0-9]+"
|
||||||
a[i] = bits.RotateLeft32(a[3], r) & 0xFF00
|
a[i] = bits.RotateLeft32(a[3], r) & 0xFF00
|
||||||
i++
|
i++
|
||||||
|
|
||||||
// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]4293922815, R[0-9]+"
|
// ppc64le: "RLWNM\tR[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+"
|
||||||
// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]4293922815, R[0-9]+"
|
// ppc64: "RLWNM\tR[0-9]+, R[0-9]+, [$]20, [$]11, R[0-9]+"
|
||||||
a[i] = bits.RotateLeft32(a[3], r) & 0xFFF00FFF
|
a[i] = bits.RotateLeft32(a[3], r) & 0xFFF00FFF
|
||||||
i++
|
i++
|
||||||
// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]4293922815, R[0-9]+"
|
// ppc64le: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]11, R[0-9]+"
|
||||||
// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]4293922815, R[0-9]+"
|
// ppc64: "RLWNM\t[$]4, R[0-9]+, [$]20, [$]11, R[0-9]+"
|
||||||
a[i] = bits.RotateLeft32(a[3], 4) & 0xFFF00FFF
|
a[i] = bits.RotateLeft32(a[3], 4) & 0xFFF00FFF
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -240,12 +240,12 @@ func checkWidenAfterShift(v int64, u uint64) (int64, uint64) {
|
||||||
func checkShiftAndMask32(v []uint32) {
|
func checkShiftAndMask32(v []uint32) {
|
||||||
i := 0
|
i := 0
|
||||||
|
|
||||||
// ppc64le: "RLWNM\t[$]24, R[0-9]+, [$]1044480, R[0-9]+"
|
// ppc64le: "RLWNM\t[$]24, R[0-9]+, [$]12, [$]19, R[0-9]+"
|
||||||
// ppc64: "RLWNM\t[$]24, R[0-9]+, [$]1044480, R[0-9]+"
|
// ppc64: "RLWNM\t[$]24, R[0-9]+, [$]12, [$]19, R[0-9]+"
|
||||||
v[i] = (v[i] & 0xFF00000) >> 8
|
v[i] = (v[i] & 0xFF00000) >> 8
|
||||||
i++
|
i++
|
||||||
// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]1020, R[0-9]+"
|
// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]22, [$]29, R[0-9]+"
|
||||||
// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]1020, R[0-9]+"
|
// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]22, [$]29, R[0-9]+"
|
||||||
v[i] = (v[i] & 0xFF00) >> 6
|
v[i] = (v[i] & 0xFF00) >> 6
|
||||||
i++
|
i++
|
||||||
// ppc64le: "MOVW\tR0"
|
// ppc64le: "MOVW\tR0"
|
||||||
|
|
@ -256,12 +256,12 @@ func checkShiftAndMask32(v []uint32) {
|
||||||
// ppc64: "MOVW\tR0"
|
// ppc64: "MOVW\tR0"
|
||||||
v[i] = (v[i] & 0xF000000) >> 28
|
v[i] = (v[i] & 0xF000000) >> 28
|
||||||
i++
|
i++
|
||||||
// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]255, R[0-9]+"
|
// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]24, [$]31, R[0-9]+"
|
||||||
// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]255, R[0-9]+"
|
// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]24, [$]31, R[0-9]+"
|
||||||
v[i] = (v[i] >> 6) & 0xFF
|
v[i] = (v[i] >> 6) & 0xFF
|
||||||
i++
|
i++
|
||||||
// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]1044480, R[0-9]+"
|
// ppc64le: "RLWNM\t[$]26, R[0-9]+, [$]12, [$]19, R[0-9]+"
|
||||||
// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]1044480, R[0-9]+"
|
// ppc64: "RLWNM\t[$]26, R[0-9]+, [$]12, [$]19, R[0-9]+"
|
||||||
v[i] = (v[i] >> 6) & 0xFF000
|
v[i] = (v[i] >> 6) & 0xFF000
|
||||||
i++
|
i++
|
||||||
// ppc64le: "MOVW\tR0"
|
// ppc64le: "MOVW\tR0"
|
||||||
|
|
@ -275,16 +275,16 @@ func checkShiftAndMask32(v []uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkMergedShifts32(a [256]uint32, b [256]uint64, u uint32, v uint32) {
|
func checkMergedShifts32(a [256]uint32, b [256]uint64, u uint32, v uint32) {
|
||||||
//ppc64le: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]1020, R[0-9]+"
|
//ppc64le: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]29, R[0-9]+"
|
||||||
//ppc64: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]1020, R[0-9]+"
|
//ppc64: -"CLRLSLDI", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]29, R[0-9]+"
|
||||||
a[0] = a[uint8(v>>24)]
|
a[0] = a[uint8(v>>24)]
|
||||||
//ppc64le: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]2040, R[0-9]+"
|
//ppc64le: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]21, [$]28, R[0-9]+"
|
||||||
//ppc64: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]2040, R[0-9]+"
|
//ppc64: -"CLRLSLDI", "RLWNM\t[$]11, R[0-9]+, [$]21, [$]28, R[0-9]+"
|
||||||
b[0] = b[uint8(v>>24)]
|
b[0] = b[uint8(v>>24)]
|
||||||
//ppc64le: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]2040, R[0-9]+"
|
//ppc64le: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]21, [$]28, R[0-9]+"
|
||||||
//ppc64: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]2040, R[0-9]+"
|
//ppc64: -"CLRLSLDI", "RLWNM\t[$]15, R[0-9]+, [$]21, [$]28, R[0-9]+"
|
||||||
b[1] = b[(v>>20)&0xFF]
|
b[1] = b[(v>>20)&0xFF]
|
||||||
//ppc64le: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]1016, R[0-9]+"
|
//ppc64le: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]28, R[0-9]+"
|
||||||
//ppc64: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]1016, R[0-9]+"
|
//ppc64: -"SLD", "RLWNM\t[$]10, R[0-9]+, [$]22, [$]28, R[0-9]+"
|
||||||
b[2] = b[v>>25]
|
b[2] = b[v>>25]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue