]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/s390x: use 12 bit load and store instruction when possible on s390x
authorRuixin Bao <ruixin.bao@ibm.com>
Tue, 27 Aug 2019 19:22:28 +0000 (15:22 -0400)
committerMichael Munday <mike.munday@ibm.com>
Thu, 12 Sep 2019 15:49:54 +0000 (15:49 +0000)
Originally, we default to use load and store instruction with 20 bit displacement.
However, that is not necessary. Some instructions have a displacement smaller
than 12 bit. This CL allows the usage of 12 bit load and store instruction when
that happens.

This change also reduces the size of .text section in go binary by 19 KB.

Some tests are also added to verify the functionality of the change.

Change-Id: I13edea06ca653d4b9ffeaefe8d010bc2f065c2ba
Reviewed-on: https://go-review.googlesource.com/c/go/+/194857
Reviewed-by: Michael Munday <mike.munday@ibm.com>
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/asm/internal/asm/testdata/s390x.s
src/cmd/internal/obj/s390x/asmz.go

index 4c1ca2361c5329c37494c73021d352e62def49ec..9952c5207fe41e4faedb6b0e755dbb0ac26b7cb1 100644 (file)
@@ -33,12 +33,12 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
        MOVWBR  (R15), R9             // e390f000001e
 
        MOVD    R1, n-8(SP)           // e310f0100024
-       MOVW    R2, n-8(SP)           // e320f0100050
-       MOVH    R3, n-8(SP)           // e330f0100070
-       MOVB    R4, n-8(SP)           // e340f0100072
-       MOVWZ   R5, n-8(SP)           // e350f0100050
-       MOVHZ   R6, n-8(SP)           // e360f0100070
-       MOVBZ   R7, n-8(SP)           // e370f0100072
+       MOVW    R2, n-8(SP)           // 5020f010
+       MOVH    R3, n-8(SP)           // 4030f010
+       MOVB    R4, n-8(SP)           // 4240f010
+       MOVWZ   R5, n-8(SP)           // 5050f010
+       MOVHZ   R6, n-8(SP)           // 4060f010
+       MOVBZ   R7, n-8(SP)           // 4270f010
        MOVDBR  R8, n-8(SP)           // e380f010002f
        MOVWBR  R9, n-8(SP)           // e390f010003e
 
@@ -58,6 +58,20 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
        MOVB    $-128, -524288(R5)    // eb8050008052
        MOVB    $1, -524289(R6)       // c0a1fff7ffff41aa60009201a000
 
+       // RX (12-bit displacement) and RXY (20-bit displacement) instruction encoding (e.g: ST vs STY)
+       MOVW    R1, 4095(R2)(R3)       // 50132fff
+       MOVW    R1, 4096(R2)(R3)       // e31320000150
+       MOVWZ   R1, 4095(R2)(R3)       // 50132fff
+       MOVWZ   R1, 4096(R2)(R3)       // e31320000150
+       MOVH    R1, 4095(R2)(R3)       // 40132fff
+       MOVHZ   R1, 4095(R2)(R3)       // 40132fff
+       MOVH    R1, 4096(R2)(R3)       // e31320000170
+       MOVHZ   R1, 4096(R2)(R3)       // e31320000170
+       MOVB    R1, 4095(R2)(R3)       // 42132fff
+       MOVBZ   R1, 4095(R2)(R3)       // 42132fff
+       MOVB    R1, 4096(R2)(R3)       // e31320000172
+       MOVBZ   R1, 4096(R2)(R3)       // e31320000172
+
        ADD     R1, R2                // b9e81022
        ADD     R1, R2, R3            // b9e81032
        ADD     $8192, R1             // a71b2000
@@ -300,10 +314,22 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
 
        FMOVS   $0, F11                // b37400b0
        FMOVD   $0, F12                // b37500c0
-       FMOVS   (R1)(R2*1), F0         // ed0210000064
-       FMOVS   n-8(SP), F15           // edf0f0100064
-       FMOVD   -9999999(R8)(R9*1), F8 // c0a1ff67698141aa9000ed8a80000065
+       FMOVS   (R1)(R2*1), F0         // 78021000
+       FMOVS   n-8(SP), F15           // 78f0f010
+       FMOVD   -9999999(R8)(R9*1), F8 // c0a1ff67698141aa9000688a8000
        FMOVD   F4, F5                 // 2854
+
+       // RX (12-bit displacement) and RXY (20-bit displacement) instruction encoding (e.g. LD vs LDY)
+       FMOVD   (R1), F0               // 68001000
+       FMOVD   4095(R2), F13          // 68d02fff
+       FMOVD   4096(R2), F15          // edf020000165
+       FMOVS   4095(R2)(R3), F13      // 78d32fff
+       FMOVS   4096(R2)(R4), F15      // edf420000164
+       FMOVD   F0, 4095(R1)           // 60001fff
+       FMOVD   F0, 4096(R1)           // ed0010000167
+       FMOVS   F13, 4095(R2)(R3)      // 70d32fff
+       FMOVS   F13, 4096(R2)(R3)      // edd320000166
+
        FADDS   F0, F15                // b30a00f0
        FADD    F1, F14                // b31a00e1
        FSUBS   F2, F13                // b30b00d2
index d76eb258299480035dd570c953807638f8ff4f82..b6024ae481c2dbc7f0a628d693ccd1c49b673473 100644 (file)
@@ -3320,7 +3320,12 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
                        x2 = REGTMP
                        d2 = 0
                }
-               zRXY(c.zopstore(p.As), uint32(p.From.Reg), uint32(x2), uint32(b2), uint32(d2), asm)
+               // Emits an RX instruction if an appropriate one exists and the displacement fits in 12 bits. Otherwise use an RXY instruction.
+               if op, ok := c.zopstore12(p.As); ok && isU12(d2) {
+                       zRX(op, uint32(p.From.Reg), uint32(x2), uint32(b2), uint32(d2), asm)
+               } else {
+                       zRXY(c.zopstore(p.As), uint32(p.From.Reg), uint32(x2), uint32(b2), uint32(d2), asm)
+               }
 
        case 36: // mov mem reg (no relocation)
                d2 := c.regoff(&p.From)
@@ -3337,7 +3342,12 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
                        x2 = REGTMP
                        d2 = 0
                }
-               zRXY(c.zopload(p.As), uint32(p.To.Reg), uint32(x2), uint32(b2), uint32(d2), asm)
+               // Emits an RX instruction if an appropriate one exists and the displacement fits in 12 bits. Otherwise use an RXY instruction.
+               if op, ok := c.zopload12(p.As); ok && isU12(d2) {
+                       zRX(op, uint32(p.To.Reg), uint32(x2), uint32(b2), uint32(d2), asm)
+               } else {
+                       zRXY(c.zopload(p.As), uint32(p.To.Reg), uint32(x2), uint32(b2), uint32(d2), asm)
+               }
 
        case 40: // word/byte
                wd := uint32(c.regoff(&p.From))
@@ -4215,6 +4225,22 @@ func (c *ctxtz) regoff(a *obj.Addr) int32 {
        return int32(c.vregoff(a))
 }
 
+// find if the displacement is within 12 bit
+func isU12(displacement int32) bool {
+       return displacement >= 0 && displacement < DISP12
+}
+
+// zopload12 returns the RX op with 12 bit displacement for the given load
+func (c *ctxtz) zopload12(a obj.As) (uint32, bool) {
+       switch a {
+       case AFMOVD:
+               return op_LD, true
+       case AFMOVS:
+               return op_LE, true
+       }
+       return 0, false
+}
+
 // zopload returns the RXY op for the given load
 func (c *ctxtz) zopload(a obj.As) uint32 {
        switch a {
@@ -4253,6 +4279,23 @@ func (c *ctxtz) zopload(a obj.As) uint32 {
        return 0
 }
 
+// zopstore12 returns the RX op with 12 bit displacement for the given store
+func (c *ctxtz) zopstore12(a obj.As) (uint32, bool) {
+       switch a {
+       case AFMOVD:
+               return op_STD, true
+       case AFMOVS:
+               return op_STE, true
+       case AMOVW, AMOVWZ:
+               return op_ST, true
+       case AMOVH, AMOVHZ:
+               return op_STH, true
+       case AMOVB, AMOVBZ:
+               return op_STC, true
+       }
+       return 0, false
+}
+
 // zopstore returns the RXY op for the given store
 func (c *ctxtz) zopstore(a obj.As) uint32 {
        switch a {