From 259de39375d39a1ba32de640cde5d112b7b80acf Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Seo Date: Thu, 31 Jan 2019 11:22:21 -0600 Subject: [PATCH] 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 Reviewed-by: Lynn Boger Run-TryBot: Bryan C. Mills TryBot-Result: Gobot Gobot --- src/cmd/asm/internal/asm/testdata/ppc64.s | 6 ++++++ src/cmd/internal/obj/ppc64/asm9.go | 12 ++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s index 366c80c0905ae..8440375de6bcf 100644 --- a/src/cmd/asm/internal/asm/testdata/ppc64.s +++ b/src/cmd/asm/internal/asm/testdata/ppc64.s @@ -1021,18 +1021,24 @@ label1: // VSX move from VSR, XX1-form // XS,RA produces // 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 // RA,XT produces // 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 // XA,XB,XT produces diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index a2ea492710b59..f9935d2686e55 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -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 */