From d4aa72002e76c09f81a8fd82f37781f5126c9cbe Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Fri, 16 Apr 2021 15:15:17 -0500 Subject: [PATCH] cmd/asm: fix RLDCR const1,reg,const2,reg on ppc64 The extended opcode field (XO) is generated incorrectly. OPVCC assumes an X-form like layout for the XO field. MD-form insns also have an XO field, but it is both smaller and in a different bit position. This hasn't been noticed since const1 == 0 matches as a register argument instead of a constant, thus it is unlikely anyone has attempted to assemble this instruction with a non-zero shift argument. Likewise, update all other MD-form instructions using OPVCC to use the new OPMD function. Change-Id: Id81fa2727fb701431911a05492c2038415ad0a4d Reviewed-on: https://go-review.googlesource.com/c/go/+/310851 Run-TryBot: Paul Murphy TryBot-Result: Go Bot Trust: Lynn Boger Reviewed-by: Carlos Eduardo Seo --- src/cmd/asm/internal/asm/testdata/ppc64.s | 2 ++ src/cmd/internal/obj/ppc64/asm9.go | 33 +++++++++++++---------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s index eaec24b8b76..edaecaea49a 100644 --- a/src/cmd/asm/internal/asm/testdata/ppc64.s +++ b/src/cmd/asm/internal/asm/testdata/ppc64.s @@ -318,6 +318,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 RLDICCC $0, R4, $15, R6 // 788603c9 CLRLSLWI $16, R5, $8, R4 // 54a4422e CLRLSLDI $24, R4, $2, R3 // 78831588 + RLDCR $1, R1, $-16, R1 // 78210ee4 + RLDCRCC $1, R1, $-16, R1 // 78210ee5 BEQ 0(PC) // 41820000 BEQ CR1,0(PC) // 41860000 diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index 373fbedec7e..69c84b21d48 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -1987,6 +1987,11 @@ func OPCC(o uint32, xo uint32, rc uint32) uint32 { return OPVCC(o, xo, 0, rc) } +/* Generate MD-form opcode */ +func OPMD(o, xo, rc uint32) uint32 { + return o<<26 | xo<<2 | rc&1 +} + /* the order is dest, a/s, b/imm for both arithmetic and logical operations */ func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 { return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 @@ -4230,14 +4235,14 @@ func (c *ctxt9) oprrr(a obj.As) uint32 { case ARLDICLCC: return OPVCC(30, 0, 0, 1) case ARLDICR: - return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr + return OPMD(30, 1, 0) // rldicr case ARLDICRCC: - return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr. + return OPMD(30, 1, 1) // rldicr. case ARLDIC: - return OPVCC(30, 0, 0, 0) | 4<<1 // rldic + return OPMD(30, 2, 0) // rldic case ARLDICCC: - return OPVCC(30, 0, 0, 1) | 4<<1 // rldic. + return OPMD(30, 2, 1) // rldic. case ASYSCALL: return OPVCC(17, 1, 0, 0) @@ -4895,30 +4900,30 @@ func (c *ctxt9) opirr(a obj.As) uint32 { case ARLWMICC: return OPVCC(20, 0, 0, 1) case ARLDMI: - return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */ + return OPMD(30, 3, 0) /* rldimi */ case ARLDMICC: - return OPVCC(30, 0, 0, 1) | 3<<2 + return OPMD(30, 3, 1) /* rldimi. */ case ARLDIMI: - return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */ + return OPMD(30, 3, 0) /* rldimi */ case ARLDIMICC: - return OPVCC(30, 0, 0, 1) | 3<<2 + return OPMD(30, 3, 1) /* rldimi. */ case ARLWNM: return OPVCC(21, 0, 0, 0) /* rlwinm */ case ARLWNMCC: return OPVCC(21, 0, 0, 1) case ARLDCL: - return OPVCC(30, 0, 0, 0) /* rldicl */ + return OPMD(30, 0, 0) /* rldicl */ case ARLDCLCC: - return OPVCC(30, 0, 0, 1) + return OPMD(30, 0, 1) /* rldicl. */ case ARLDCR: - return OPVCC(30, 1, 0, 0) /* rldicr */ + return OPMD(30, 1, 0) /* rldicr */ case ARLDCRCC: - return OPVCC(30, 1, 0, 1) + return OPMD(30, 1, 1) /* rldicr. */ case ARLDC: - return OPVCC(30, 0, 0, 0) | 2<<2 + return OPMD(30, 2, 0) /* rldic */ case ARLDCCC: - return OPVCC(30, 0, 0, 1) | 2<<2 + return OPMD(30, 2, 1) /* rldic. */ case ASRAW: return OPVCC(31, 824, 0, 0)