Commit 259de393 authored by Carlos Eduardo Seo's avatar Carlos Eduardo Seo Committed by Lynn Boger

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/+/163759Reviewed-by: default avatarBryan C. Mills <bcmills@google.com>
Reviewed-by: default avatarLynn Boger <laboger@linux.vnet.ibm.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 1f90d081
......@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment