Skip to content

Commit 259de39

Browse files
ceseolaboger
authored andcommitted
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 <[email protected]> Reviewed-by: Lynn Boger <[email protected]> Run-TryBot: Bryan C. Mills <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 1f90d08 commit 259de39

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

src/cmd/asm/internal/asm/testdata/ppc64.s

+6
Original file line numberDiff line numberDiff line change
@@ -1021,18 +1021,24 @@ label1:
10211021
// VSX move from VSR, XX1-form
10221022
// <MNEMONIC> XS,RA produces
10231023
// <mnemonic> RA,XS
1024+
// Extended mnemonics accept VMX and FP registers as sources
10241025
MFVSRD VS0, R1
10251026
MFVSRWZ VS33, R1
10261027
MFVSRLD VS63, R1
1028+
MFVRD V0, R1
1029+
MFFPRD F0, R1
10271030

10281031
// VSX move to VSR, XX1-form
10291032
// <MNEMONIC> RA,XT produces
10301033
// <mnemonic> XT,RA
1034+
// Extended mnemonics accept VMX and FP registers as targets
10311035
MTVSRD R1, VS0
10321036
MTVSRWA R1, VS31
10331037
MTVSRWZ R1, VS63
10341038
MTVSRDD R1, R2, VS0
10351039
MTVSRWS R1, VS32
1040+
MTVRD R1, V13
1041+
MTFPRD R1, F24
10361042

10371043
// VSX AND, XX3-form
10381044
// <MNEMONIC> XA,XB,XT produces

src/cmd/internal/obj/ppc64/asm9.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -3555,22 +3555,22 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
35553555
if REG_V0 <= xt && xt <= REG_V31 {
35563556
/* Convert V0-V31 to VS32-VS63 */
35573557
xt = xt + 64
3558-
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3558+
o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
35593559
} else if REG_F0 <= xt && xt <= REG_F31 {
35603560
/* Convert F0-F31 to VS0-VS31 */
35613561
xt = xt + 64
3562-
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3562+
o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
35633563
} else if REG_VS0 <= xt && xt <= REG_VS63 {
3564-
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3564+
o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
35653565
} else if REG_V0 <= xs && xs <= REG_V31 {
35663566
/* Likewise for XS */
35673567
xs = xs + 64
3568-
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3568+
o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
35693569
} else if REG_F0 <= xs && xs <= REG_F31 {
35703570
xs = xs + 64
3571-
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3571+
o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
35723572
} else if REG_VS0 <= xs && xs <= REG_VS63 {
3573-
o1 = AOP_XX1(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3573+
o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
35743574
}
35753575

35763576
case 89: /* VSX instructions, XX2-form */

0 commit comments

Comments
 (0)