]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal: add shift opcodes with shift operands on ppc64x
authorLynn Boger <laboger@linux.vnet.ibm.com>
Mon, 24 Oct 2016 19:40:42 +0000 (14:40 -0500)
committerDavid Chase <drchase@google.com>
Tue, 25 Oct 2016 14:56:20 +0000 (14:56 +0000)
Some original shift opcodes for ppc64x expected an operand to be
a mask instead of a shift count, preventing some valid shift counts
from being written.

This adds new opcodes for shifts where needed, using mnemonics that
match the ppc64 asm and allowing the assembler to accept the full set
of valid shift counts.

Fixes #15016

Change-Id: Id573489f852038d06def279c13fd0523736878a7
Reviewed-on: https://go-review.googlesource.com/31853
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/asm/internal/asm/testdata/ppc64.s
src/cmd/internal/obj/ppc64/a.out.go
src/cmd/internal/obj/ppc64/anames.go
src/cmd/internal/obj/ppc64/asm9.go

index f5fa0af9de8fde3314f96c77667dedcf1c7e0a0e..a5e8bc0927c7c7783e0db387c18a6af059a07590 100644 (file)
@@ -594,6 +594,15 @@ label1:
 //     }
        RLWMI   R1, R2, 4, 5, R3 // RLWMI       R1, R2, $201326592, R3
 
+
+// opcodes added with constant shift counts, not masks
+
+       RLDICR  $3, R2, $24, R4
+
+       RLDICL  $1, R2, $61, R6
+
+       RLDIMI  $7, R2, $52, R7
+
 //
 // load/store multiple
 //
index ac1126e8f20e38d00ac7ca81fa5252b02f08f724..2a565f114bab03fa64926b7d02d04e35624c13c1 100644 (file)
@@ -594,12 +594,18 @@ const (
        ARFID
        ARLDMI
        ARLDMICC
+       ARLDIMI
+       ARLDIMICC
        ARLDC
        ARLDCCC
        ARLDCR
        ARLDCRCC
+       ARLDICR
+       ARLDICRCC
        ARLDCL
        ARLDCLCC
+       ARLDICL
+       ARLDICLCC
        ASLBIA
        ASLBIE
        ASLBMFEE
index 9e26666dbe1e53f7ae74cc9cab41dc8d671bebb8..d402b04b82486f1ff9040c08d701da60813cdeb8 100644 (file)
@@ -286,12 +286,18 @@ var Anames = []string{
        "RFID",
        "RLDMI",
        "RLDMICC",
+       "RLDIMI",
+       "RLDIMICC",
        "RLDC",
        "RLDCCC",
        "RLDCR",
        "RLDCRCC",
+       "RLDICR",
+       "RLDICRCC",
        "RLDCL",
        "RLDCLCC",
+       "RLDICL",
+       "RLDICLCC",
        "SLBIA",
        "SLBIE",
        "SLBMFEE",
index 0b3e667f605ad6c617168983cfd8320f6ad99d5f..fcb73950777aaefc434e7edccfbc6ed243fd321e 100644 (file)
@@ -139,6 +139,8 @@ var optab = []Optab{
        {ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
        {ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
        {ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
+       {ARLDICL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
+       {ARLDICL, C_SCON, C_REG, C_LCON, C_REG, 14, 4, 0},
        {ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0},
        {AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0},
        {AFADD, C_FREG, C_FREG, C_NONE, C_FREG, 2, 4, 0},
@@ -1484,6 +1486,8 @@ func buildop(ctxt *obj.Link) {
 
                case ARLDMI:
                        opset(ARLDMICC, r0)
+                       opset(ARLDIMI, r0)
+                       opset(ARLDIMICC, r0)
 
                case ARLDC:
                        opset(ARLDCCC, r0)
@@ -1493,6 +1497,11 @@ func buildop(ctxt *obj.Link) {
                        opset(ARLDCLCC, r0)
                        opset(ARLDCRCC, r0)
 
+               case ARLDICL:
+                       opset(ARLDICLCC, r0)
+                       opset(ARLDICR, r0)
+                       opset(ARLDICRCC, r0)
+
                case AFMOVD:
                        opset(AFMOVDCC, r0)
                        opset(AFMOVDU, r0)
@@ -2107,22 +2116,34 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
                        r = int(p.To.Reg)
                }
                d := vregoff(ctxt, p.From3)
-               var mask [2]uint8
-               maskgen64(ctxt, p, mask[:], uint64(d))
                var a int
                switch p.As {
+
+               // These opcodes expect a mask operand that has to be converted into the
+               // appropriate operand.  The way these were defined, not all valid masks are possible.
+               // Left here for compatibility in case they were used or generated.
                case ARLDCL, ARLDCLCC:
+                       var mask [2]uint8
+                       maskgen64(ctxt, p, mask[:], uint64(d))
+
                        a = int(mask[0]) /* MB */
                        if mask[1] != 63 {
                                ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
                        }
 
                case ARLDCR, ARLDCRCC:
+                       var mask [2]uint8
+                       maskgen64(ctxt, p, mask[:], uint64(d))
+
                        a = int(mask[1]) /* ME */
                        if mask[0] != 0 {
                                ctxt.Diag("invalid mask for rotate: %x (start != 0)\n%v", uint64(d), p)
                        }
 
+               // These opcodes use a shift count like the ppc64 asm, no mask conversion done
+               case ARLDICR, ARLDICRCC, ARLDICL, ARLDICLCC:
+                       a = int(d)
+
                default:
                        ctxt.Diag("unexpected op in rldc case\n%v", p)
                        a = 0
@@ -2403,18 +2424,32 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
                v := regoff(ctxt, &p.From)
 
                d := vregoff(ctxt, p.From3)
-               var mask [2]uint8
-               maskgen64(ctxt, p, mask[:], uint64(d))
-               if int32(mask[1]) != (63 - v) {
-                       ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
-               }
-               o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
-               o1 |= (uint32(mask[0]) & 31) << 6
-               if v&0x20 != 0 {
-                       o1 |= 1 << 1
-               }
-               if mask[0]&0x20 != 0 {
-                       o1 |= 1 << 5 /* mb[5] is top bit */
+
+               // Original opcodes had mask operands which had to be converted to a shift count as expected by
+               // the ppc64 asm.
+               switch p.As {
+               case ARLDMI, ARLDMICC:
+                       var mask [2]uint8
+                       maskgen64(ctxt, p, mask[:], uint64(d))
+                       if int32(mask[1]) != (63 - v) {
+                               ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
+                       }
+                       o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
+                       o1 |= (uint32(mask[0]) & 31) << 6
+                       if v&0x20 != 0 {
+                               o1 |= 1 << 1
+                       }
+                       if mask[0]&0x20 != 0 {
+                               o1 |= 1 << 5 /* mb[5] is top bit */
+                       }
+
+               // Opcodes with shift count operands.
+               case ARLDIMI, ARLDIMICC:
+                       o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
+                       o1 |= (uint32(d) & 31) << 6
+                       if v&0x20 != 0 {
+                               o1 |= 1 << 1
+                       }
                }
 
        case 31: /* dword */
@@ -3340,6 +3375,15 @@ func oprrr(ctxt *obj.Link, a obj.As) uint32 {
        case ARLDCR:
                return OPVCC(30, 9, 0, 0)
 
+       case ARLDICL:
+               return OPVCC(30, 0, 0, 0)
+       case ARLDICLCC:
+               return OPVCC(30, 0, 0, 1)
+       case ARLDICR:
+               return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr
+       case ARLDICRCC:
+               return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr.
+
        case ASYSCALL:
                return OPVCC(17, 1, 0, 0)
 
@@ -3771,7 +3815,10 @@ func opirr(ctxt *obj.Link, a obj.As) uint32 {
                return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
        case ARLDMICC:
                return OPVCC(30, 0, 0, 1) | 3<<2
-
+       case ARLDIMI:
+               return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
+       case ARLDIMICC:
+               return OPVCC(30, 0, 0, 1) | 3<<2
        case ARLWNM:
                return OPVCC(21, 0, 0, 0) /* rlwinm */
        case ARLWNMCC: