]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/ppc64: fix wrong register encoding in XX1-Form instructions
authorCarlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Thu, 31 Jan 2019 17:22:21 +0000 (11:22 -0600)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Thu, 14 Mar 2019 12:46:18 +0000 (12:46 +0000)
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>

src/cmd/asm/internal/asm/testdata/ppc64.s
src/cmd/internal/obj/ppc64/asm9.go

index 366c80c0905ae26c376f100ee65de0b69807ac57..8440375de6bcf9061947c080f84613fbd053d008 100644 (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
index a2ea492710b59314aa96d0af2ba4bccec5184915..f9935d2686e55bb227b1638c7721e7ab1f951a20 100644 (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 */