mirror of
https://github.com/golang/go
synced 2024-11-23 20:20:01 -07:00
cmd/internal/obj/ppc64: fix wrong register encoding in XX1-Form instructions
A bug in the encoding of XX1-Form is flipping bit 31 of such instructions. This may result in register clobering when using VSX instructions. This was not exposed before because we currently don't generate these instructions in SSA, and the asm files in which they are present aren't affected by register clobbering. This change fixes the bug and adds a testcase for the problem. Fixes #30112 Change-Id: I77b606159ae1efea33d2ba3e1c74b7fae8d5d2e7 Reviewed-on: https://go-review.googlesource.com/c/go/+/163759 Reviewed-by: Bryan C. Mills <bcmills@google.com> Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
1f90d08139
commit
259de39375
6
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
6
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
@ -1021,18 +1021,24 @@ label1:
|
||||
// VSX move from VSR, XX1-form
|
||||
// <MNEMONIC> XS,RA produces
|
||||
// <mnemonic> RA,XS
|
||||
// Extended mnemonics accept VMX and FP registers as sources
|
||||
MFVSRD VS0, R1
|
||||
MFVSRWZ VS33, R1
|
||||
MFVSRLD VS63, R1
|
||||
MFVRD V0, R1
|
||||
MFFPRD F0, R1
|
||||
|
||||
// VSX move to VSR, XX1-form
|
||||
// <MNEMONIC> RA,XT produces
|
||||
// <mnemonic> XT,RA
|
||||
// Extended mnemonics accept VMX and FP registers as targets
|
||||
MTVSRD R1, VS0
|
||||
MTVSRWA R1, VS31
|
||||
MTVSRWZ R1, VS63
|
||||
MTVSRDD R1, R2, VS0
|
||||
MTVSRWS R1, VS32
|
||||
MTVRD R1, V13
|
||||
MTFPRD R1, F24
|
||||
|
||||
// VSX AND, XX3-form
|
||||
// <MNEMONIC> XA,XB,XT produces
|
||||
|
@ -3555,22 +3555,22 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
|
||||
if REG_V0 <= xt && xt <= REG_V31 {
|
||||
/* Convert V0-V31 to VS32-VS63 */
|
||||
xt = xt + 64
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
|
||||
} else if REG_F0 <= xt && xt <= REG_F31 {
|
||||
/* Convert F0-F31 to VS0-VS31 */
|
||||
xt = xt + 64
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
|
||||
} else if REG_VS0 <= xt && xt <= REG_VS63 {
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
|
||||
} else if REG_V0 <= xs && xs <= REG_V31 {
|
||||
/* Likewise for XS */
|
||||
xs = xs + 64
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
|
||||
} else if REG_F0 <= xs && xs <= REG_F31 {
|
||||
xs = xs + 64
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
|
||||
} else if REG_VS0 <= xs && xs <= REG_VS63 {
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
|
||||
o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
|
||||
}
|
||||
|
||||
case 89: /* VSX instructions, XX2-form */
|
||||
|
Loading…
Reference in New Issue
Block a user