1
0
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:
Carlos Eduardo Seo 2019-01-31 11:22:21 -06:00 committed by Lynn Boger
parent 1f90d08139
commit 259de39375
2 changed files with 12 additions and 6 deletions

View File

@ -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

View File

@ -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 */