]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/{asm,compile}: add ANDW, ORW and XORW instructions to s390x
authorMichael Munday <munday@ca.ibm.com>
Tue, 4 Oct 2016 19:35:28 +0000 (15:35 -0400)
committerMichael Munday <munday@ca.ibm.com>
Thu, 6 Oct 2016 02:59:04 +0000 (02:59 +0000)
Adds the following instructions and uses them in the SSA backend:

 - ANDW
 - ORW
 - XORW

The instruction encodings for 32-bit operations are typically shorter,
particularly when an immediate is used. For example, XORW $-1, R1
only requires one instruction, whereas XOR requires two.

Also removes some unused instructions (that were emulated):

 - ANDN
 - NAND
 - ORN
 - NOR

Change-Id: Iff2a16f52004ba498720034e354be9771b10cac4
Reviewed-on: https://go-review.googlesource.com/30291
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/asm/internal/asm/testdata/s390x.s
src/cmd/compile/internal/s390x/prog.go
src/cmd/compile/internal/ssa/gen/S390XOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/internal/obj/s390x/a.out.go
src/cmd/internal/obj/s390x/anames.go
src/cmd/internal/obj/s390x/asmz.go

index 5fc7a8e9b52ccf1cdcfde8cc4f883408dc9e264d..dbf4cf2c095aedb30e1c5d5a67c7888d1c2a8af9 100644 (file)
@@ -108,6 +108,42 @@ TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
        NEGW    R1, R2                // b9130021
        FLOGR   R2, R2                // b9830022
 
+       AND     R1, R2                // b9800021
+       AND     R1, R2, R3            // b9e42031
+       AND     $-2, R1               // a517fffe
+       AND     $-65536, R1           // c01bffff0000
+       AND     $1, R1                // c0a100000001b980001a
+       ANDW    R1, R2                // 1421
+       ANDW    R1, R2, R3            // b9f42031
+       ANDW    $1, R1                // c01b00000001
+       ANDW    $131071, R1           // a5160001
+       ANDW    $65536, R1            // c01b00010000
+       ANDW    $-2, R1               // a517fffe
+       OR      R1, R2                // b9810021
+       OR      R1, R2, R3            // b9e62031
+       OR      $1, R1                // a51b0001
+       OR      $131071, R1           // c01d0001ffff
+       OR      $65536, R1            // c01d00010000
+       OR      $-2, R1               // c0a1fffffffeb981001a
+       ORW     R1, R2                // 1621
+       ORW     R1, R2, R3            // b9f62031
+       ORW     $1, R1                // a51b0001
+       ORW     $131071, R1           // c01d0001ffff
+       ORW     $65536, R1            // a51a0001
+       ORW     $-2, R1               // c01dfffffffe
+       XOR     R1, R2                // b9820021
+       XOR     R1, R2, R3            // b9e72031
+       XOR     $1, R1                // c01700000001
+       XOR     $131071, R1           // c0170001ffff
+       XOR     $65536, R1            // c01700010000
+       XOR     $-2, R1               // c0a1fffffffeb982001a
+       XORW    R1, R2                // 1721
+       XORW    R1, R2, R3            // b9f72031
+       XORW    $1, R1                // c01700000001
+       XORW    $131071, R1           // c0170001ffff
+       XORW    $65536, R1            // c01700010000
+       XORW    $-2, R1               // c017fffffffe
+
        LAA     R1, R2, 524287(R3)    // eb213fff7ff8
        LAAG    R4, R5, -524288(R6)   // eb54600080e8
        LAAL    R7, R8, 8192(R9)      // eb87900002fa
index 055dd436e953b74cd288c1ec9e32956bd0ff0b52..9e974e9125b13bd1c8e25ac178feb1cd31cabc98 100644 (file)
@@ -41,8 +41,11 @@ var progtable = [s390x.ALAST & obj.AMask]gc.ProgInfo{
        s390x.ANEG & obj.AMask:    {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
        s390x.ANEGW & obj.AMask:   {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
        s390x.AAND & obj.AMask:    {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
+       s390x.AANDW & obj.AMask:   {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
        s390x.AOR & obj.AMask:     {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
+       s390x.AORW & obj.AMask:    {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
        s390x.AXOR & obj.AMask:    {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
+       s390x.AXORW & obj.AMask:   {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
        s390x.AMULLD & obj.AMask:  {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
        s390x.AMULLW & obj.AMask:  {Flags: gc.SizeL | gc.LeftRead | gc.RegRead | gc.RightWrite},
        s390x.AMULHD & obj.AMask:  {Flags: gc.SizeQ | gc.LeftRead | gc.RegRead | gc.RightWrite},
index d9b3593c5c2d1cd33e0eb225899ec6efb1e87a2a..39c41593b9411c68338a318c01c79751b839793a 100644 (file)
@@ -208,20 +208,20 @@ func init() {
                {name: "MODDU", argLength: 2, reg: gp21, asm: "MODDU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
                {name: "MODWU", argLength: 2, reg: gp21, asm: "MODWU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
 
-               {name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true},                      // arg0 & arg1
-               {name: "ANDW", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true},                     // arg0 & arg1
-               {name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64", resultInArg0: true, clobberFlags: true},  // arg0 & auxint
-               {name: "ANDWconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
-
-               {name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true, clobberFlags: true},                      // arg0 | arg1
-               {name: "ORW", argLength: 2, reg: gp21, asm: "OR", commutative: true, clobberFlags: true},                     // arg0 | arg1
-               {name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64", resultInArg0: true, clobberFlags: true},  // arg0 | auxint
-               {name: "ORWconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
-
-               {name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, clobberFlags: true},                      // arg0 ^ arg1
-               {name: "XORW", argLength: 2, reg: gp21, asm: "XOR", commutative: true, clobberFlags: true},                     // arg0 ^ arg1
-               {name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", resultInArg0: true, clobberFlags: true},  // arg0 ^ auxint
-               {name: "XORWconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
+               {name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true},                       // arg0 & arg1
+               {name: "ANDW", argLength: 2, reg: gp21, asm: "ANDW", commutative: true, clobberFlags: true},                     // arg0 & arg1
+               {name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64", resultInArg0: true, clobberFlags: true},   // arg0 & auxint
+               {name: "ANDWconst", argLength: 1, reg: gp11, asm: "ANDW", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
+
+               {name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true, clobberFlags: true},                       // arg0 | arg1
+               {name: "ORW", argLength: 2, reg: gp21, asm: "ORW", commutative: true, clobberFlags: true},                     // arg0 | arg1
+               {name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64", resultInArg0: true, clobberFlags: true},   // arg0 | auxint
+               {name: "ORWconst", argLength: 1, reg: gp11, asm: "ORW", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
+
+               {name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, clobberFlags: true},                       // arg0 ^ arg1
+               {name: "XORW", argLength: 2, reg: gp21, asm: "XORW", commutative: true, clobberFlags: true},                     // arg0 ^ arg1
+               {name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", resultInArg0: true, clobberFlags: true},   // arg0 ^ auxint
+               {name: "XORWconst", argLength: 1, reg: gp11, asm: "XORW", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
 
                {name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},   // arg0 compare to arg1
                {name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to arg1
index 000305976785f3b0df2465f23338e7d6d9e56a7d..b3821579226baf25e1ab950b02cd2135c8ea6346 100644 (file)
@@ -16023,7 +16023,7 @@ var opcodeTable = [...]opInfo{
                argLen:       2,
                commutative:  true,
                clobberFlags: true,
-               asm:          s390x.AAND,
+               asm:          s390x.AANDW,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -16056,7 +16056,7 @@ var opcodeTable = [...]opInfo{
                argLen:       1,
                resultInArg0: true,
                clobberFlags: true,
-               asm:          s390x.AAND,
+               asm:          s390x.AANDW,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -16087,7 +16087,7 @@ var opcodeTable = [...]opInfo{
                argLen:       2,
                commutative:  true,
                clobberFlags: true,
-               asm:          s390x.AOR,
+               asm:          s390x.AORW,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -16120,7 +16120,7 @@ var opcodeTable = [...]opInfo{
                argLen:       1,
                resultInArg0: true,
                clobberFlags: true,
-               asm:          s390x.AOR,
+               asm:          s390x.AORW,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -16151,7 +16151,7 @@ var opcodeTable = [...]opInfo{
                argLen:       2,
                commutative:  true,
                clobberFlags: true,
-               asm:          s390x.AXOR,
+               asm:          s390x.AXORW,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -16184,7 +16184,7 @@ var opcodeTable = [...]opInfo{
                argLen:       1,
                resultInArg0: true,
                clobberFlags: true,
-               asm:          s390x.AXOR,
+               asm:          s390x.AXORW,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
index b6d1975c79bd58fc0e597ff574f12a10f5830df2..4c4a2320e7ea931c002e26bdac39635de06aaf03 100644 (file)
@@ -260,12 +260,11 @@ const (
 
        // integer bitwise
        AAND
-       AANDN
-       ANAND
-       ANOR
+       AANDW
        AOR
-       AORN
+       AORW
        AXOR
+       AXORW
        ASLW
        ASLD
        ASRW
index 589206f3aef032c5e7a8da111a984da3519b1ddc..eb1576e21c09dabfc725e305ab184724dea7ff7a 100644 (file)
@@ -51,12 +51,11 @@ var Anames = []string{
        "MOVDNE",
        "FLOGR",
        "AND",
-       "ANDN",
-       "NAND",
-       "NOR",
+       "ANDW",
        "OR",
-       "ORN",
+       "ORW",
        "XOR",
+       "XORW",
        "SLW",
        "SLD",
        "SRW",
index 0627fd1e20569c463da97e8ca7f2abb3cdcdec01..3bfff61374b66d233f270b1855e2ce615e2cd24f 100644 (file)
@@ -162,10 +162,9 @@ var optab = []Optab{
        Optab{AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 0},
        Optab{AAND, C_LCON, C_NONE, C_NONE, C_REG, 23, 0},
        Optab{AAND, C_LCON, C_REG, C_NONE, C_REG, 23, 0},
-       Optab{AOR, C_REG, C_REG, C_NONE, C_REG, 6, 0},
-       Optab{AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 0},
-       Optab{AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 0},
-       Optab{AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 0},
+       Optab{AANDW, C_REG, C_REG, C_NONE, C_REG, 6, 0},
+       Optab{AANDW, C_REG, C_NONE, C_NONE, C_REG, 6, 0},
+       Optab{AANDW, C_LCON, C_NONE, C_NONE, C_REG, 24, 0},
        Optab{ASLD, C_REG, C_NONE, C_NONE, C_REG, 7, 0},
        Optab{ASLD, C_REG, C_REG, C_NONE, C_REG, 7, 0},
        Optab{ASLD, C_SCON, C_REG, C_NONE, C_REG, 7, 0},
@@ -393,7 +392,7 @@ func spanz(ctxt *obj.Link, cursym *obj.LSym) {
        ctxt.Cursym = cursym
        ctxt.Autosize = int32(p.To.Offset)
 
-       if oprange[AANDN&obj.AMask] == nil {
+       if oprange[AORW&obj.AMask] == nil {
                buildop(ctxt)
        }
 
@@ -838,11 +837,6 @@ func buildop(ctxt *obj.Link) {
                        opset(ASTMY, r)
                case ALMG:
                        opset(ALMY, r)
-               case AAND:
-                       opset(AANDN, r)
-                       opset(ANAND, r)
-                       opset(ANOR, r)
-                       opset(AORN, r)
                case AADDME:
                        opset(AADDZE, r)
                        opset(ASUBME, r)
@@ -888,8 +882,12 @@ func buildop(ctxt *obj.Link) {
                case AFCMPO:
                        opset(AFCMPU, r)
                        opset(ACEBR, r)
-               case AOR:
+               case AAND:
+                       opset(AOR, r)
                        opset(AXOR, r)
+               case AANDW:
+                       opset(AORW, r)
+                       opset(AXORW, r)
                case ASLD:
                        opset(ASRD, r)
                        opset(ASLW, r)
@@ -2767,74 +2765,35 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
                zI(op_SVC, 0, asm)
 
        case 6: // logical op reg [reg] reg
-               if p.To.Reg == 0 {
-                       ctxt.Diag("literal operation on R0\n%v", p)
-               }
-
+               var oprr, oprre, oprrf uint32
                switch p.As {
-               case AAND, AOR, AXOR:
-                       var opcode1, opcode2 uint32
-                       switch p.As {
-                       default:
-                       case AAND:
-                               opcode1 = op_NGR
-                               opcode2 = op_NGRK
-                       case AOR:
-                               opcode1 = op_OGR
-                               opcode2 = op_OGRK
-                       case AXOR:
-                               opcode1 = op_XGR
-                               opcode2 = op_XGRK
-                       }
-
-                       r := int(p.Reg)
-                       if r == 0 {
-                               zRRE(opcode1, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-                       } else {
-                               zRRF(opcode2, uint32(r), 0, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-                       }
-
-               case AANDN, AORN:
-                       var opcode1, opcode2 uint32
-                       switch p.As {
-                       default:
-                       case AANDN:
-                               opcode1 = op_NGR
-                               opcode2 = op_NGRK
-                       case AORN:
-                               opcode1 = op_OGR
-                               opcode2 = op_OGRK
-                       }
-
-                       r := int(p.Reg)
-                       if r == 0 {
-                               zRRE(op_LCGR, uint32(p.To.Reg), uint32(p.To.Reg), asm)
-                               zRRE(opcode1, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-                       } else {
-                               zRRE(op_LCGR, REGTMP, uint32(r), asm)
-                               zRRF(opcode2, REGTMP, 0, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-                       }
-
-               case ANAND, ANOR:
-                       var opcode1, opcode2 uint32
-                       switch p.As {
-                       default:
-                       case ANAND:
-                               opcode1 = op_NGR
-                               opcode2 = op_NGRK
-                       case ANOR:
-                               opcode1 = op_OGR
-                               opcode2 = op_OGRK
-                       }
-
-                       r := int(p.Reg)
-                       if r == 0 {
-                               zRRE(opcode1, uint32(p.To.Reg), uint32(p.From.Reg), asm)
+               case AAND:
+                       oprre = op_NGR
+                       oprrf = op_NGRK
+               case AANDW:
+                       oprr = op_NR
+                       oprrf = op_NRK
+               case AOR:
+                       oprre = op_OGR
+                       oprrf = op_OGRK
+               case AORW:
+                       oprr = op_OR
+                       oprrf = op_ORK
+               case AXOR:
+                       oprre = op_XGR
+                       oprrf = op_XGRK
+               case AXORW:
+                       oprr = op_XR
+                       oprrf = op_XRK
+               }
+               if p.Reg == 0 {
+                       if oprr != 0 {
+                               zRR(oprr, uint32(p.To.Reg), uint32(p.From.Reg), asm)
                        } else {
-                               zRRF(opcode2, uint32(r), 0, uint32(p.To.Reg), uint32(p.From.Reg), asm)
+                               zRRE(oprre, uint32(p.To.Reg), uint32(p.From.Reg), asm)
                        }
-
-                       zRRE(op_LCGR, uint32(p.To.Reg), uint32(p.To.Reg), asm)
+               } else {
+                       zRRF(oprrf, uint32(p.Reg), 0, uint32(p.To.Reg), uint32(p.From.Reg), asm)
                }
 
        case 7: // shift/rotate reg [reg] reg
@@ -3043,7 +3002,8 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
                        zRIE(_d, oprie, uint32(p.To.Reg), uint32(r), uint32(v), 0, 0, 0, 0, asm)
                }
 
-       case 23: // logical op $constant [reg] reg
+       case 23: // 64-bit logical op $constant [reg] reg
+               // TODO(mundaym): remove the optional register and merge with case 24.
                v := vregoff(ctxt, &p.From)
                var opcode uint32
                r := p.Reg
@@ -3095,6 +3055,29 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
                        zRRF(opcode, uint32(r), 0, uint32(p.To.Reg), REGTMP, asm)
                }
 
+       case 24: // 32-bit logical op $constant reg
+               v := vregoff(ctxt, &p.From)
+               switch p.As {
+               case AANDW:
+                       if uint32(v&0xffff0000) == 0xffff0000 {
+                               zRI(op_NILL, uint32(p.To.Reg), uint32(v), asm)
+                       } else if uint32(v&0x0000ffff) == 0x0000ffff {
+                               zRI(op_NILH, uint32(p.To.Reg), uint32(v)>>16, asm)
+                       } else {
+                               zRIL(_a, op_NILF, uint32(p.To.Reg), uint32(v), asm)
+                       }
+               case AORW:
+                       if uint32(v&0xffff0000) == 0 {
+                               zRI(op_OILL, uint32(p.To.Reg), uint32(v), asm)
+                       } else if uint32(v&0x0000ffff) == 0 {
+                               zRI(op_OILH, uint32(p.To.Reg), uint32(v)>>16, asm)
+                       } else {
+                               zRIL(_a, op_OILF, uint32(p.To.Reg), uint32(v), asm)
+                       }
+               case AXORW:
+                       zRIL(_a, op_XILF, uint32(p.To.Reg), uint32(v), asm)
+               }
+
        case 26: // MOVD $offset(base)(index), reg
                v := regoff(ctxt, &p.From)
                r := p.From.Reg