mirror of https://github.com/golang/go.git
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
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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…
Reference in New Issue