]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/{asm,internal/obj/s390x}, math: remove emulated float instructions
authorMichael Munday <munday@ca.ibm.com>
Thu, 17 Nov 2016 16:53:21 +0000 (11:53 -0500)
committerMichael Munday <munday@ca.ibm.com>
Fri, 10 Feb 2017 16:11:25 +0000 (16:11 +0000)
The s390x port was based on the ppc64 port and, because of the way the
port was done, inherited some instructions from it. ppc64 supports
3-operand (4-operand for FMADD etc.) floating point instructions
but s390x doesn't (the destination register is always an input) and
so these were emulated.

There is a bug in the emulation of FMADD whereby if the destination
register is also a source for the multiplication it will be
clobbered. This doesn't break any assembly code in the std lib but
could affect future work.

To fix this I have gone through the floating point instructions and
removed all unnecessary 3-/4-operand emulation. The compiler doesn't
need it and assembly writers don't need it, it's just a source of
bugs.

I've also deleted the FNMADD family of emulated instructions. They
aren't used anywhere.

Change-Id: Ic07cedcf141a6a3b43a0c84895460f6cfbf56c04
Reviewed-on: https://go-review.googlesource.com/33350
Run-TryBot: Michael Munday <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/asm/internal/arch/s390x.go
src/cmd/asm/internal/asm/testdata/s390x.s
src/cmd/internal/obj/s390x/a.out.go
src/cmd/internal/obj/s390x/anames.go
src/cmd/internal/obj/s390x/asmz.go
src/cmd/internal/obj/s390x/objz.go
src/math/cosh_s390x.s
src/math/log10_s390x.s
src/math/sin_s390x.s
src/math/sinh_s390x.s
src/math/tanh_s390x.s

index 1836f87b5733060835329fd93b48b719cd6684ef..115f7e06d8f8af028e0adcc98d6d3340cb052c2f 100644 (file)
@@ -48,24 +48,6 @@ func jumpS390x(word string) bool {
        return false
 }
 
-// IsS390xRLD reports whether the op (as defined by an s390x.A* constant) is
-// one of the RLD-like instructions that require special handling.
-// The FMADD-like instructions behave similarly.
-func IsS390xRLD(op obj.As) bool {
-       switch op {
-       case s390x.AFMADD,
-               s390x.AFMADDS,
-               s390x.AFMSUB,
-               s390x.AFMSUBS,
-               s390x.AFNMADD,
-               s390x.AFNMADDS,
-               s390x.AFNMSUB,
-               s390x.AFNMSUBS:
-               return true
-       }
-       return false
-}
-
 // IsS390xCMP reports whether the op (as defined by an s390x.A* constant) is
 // one of the CMP instructions that require special handling.
 func IsS390xCMP(op obj.As) bool {
index 198ca1d312d3834085fbab9f6e9f98ad6efdc196..55df0f953aaabead876828e12dfcaaf88e0d04bd 100644 (file)
@@ -281,6 +281,10 @@ TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
        FSQRT   F5, F15                // b31500f5
        FIEBR   $0, F0, F1             // b3570010
        FIDBR   $7, F2, F3             // b35f7032
+       FMADD   F1, F1, F1             // b31e1011
+       FMADDS  F1, F2, F3             // b30e3012
+       FMSUB   F4, F5, F5             // b31f5045
+       FMSUBS  F6, F6, F7             // b30f7066
 
        VL      (R15), V1              // e710f0000006
        VST     V1, (R15)              // e710f000000e
index 87ee971e2575a74666e1472270c0dd57ad0bb6a0..765b97dadd3d6109c21279b099609d553b7ccc49 100644 (file)
@@ -290,10 +290,6 @@ const (
        AFNABS
        AFNEG
        AFNEGS
-       AFNMADD
-       AFNMADDS
-       AFNMSUB
-       AFNMSUBS
        ALEDBR
        ALDEBR
        AFSUB
index 51b9ffc5f9b44298bb9bc0ac0a663a2f930bc282..67fa2e8d3dc5236d62dd234d593ef9c3f7b77f00 100644 (file)
@@ -79,10 +79,6 @@ var Anames = []string{
        "FNABS",
        "FNEG",
        "FNEGS",
-       "FNMADD",
-       "FNMADDS",
-       "FNMSUB",
-       "FNMSUBS",
        "LEDBR",
        "LDEBR",
        "FSUB",
index 42028347d63d24ccdf0b70851d381d6aa91b566b..cd9f5da1801ee44bac89839dbd011efc03b78207 100644 (file)
@@ -177,13 +177,11 @@ var optab = []Optab{
        Optab{ACSG, C_REG, C_REG, C_NONE, C_SOREG, 79, 0},
 
        // floating point
-       Optab{AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 0},
-       Optab{AFADD, C_FREG, C_FREG, C_NONE, C_FREG, 2, 0},
+       Optab{AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 32, 0},
        Optab{AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 0},
        Optab{AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 0},
-       Optab{AFMADD, C_FREG, C_FREG, C_FREG, C_FREG, 34, 0},
+       Optab{AFMADD, C_FREG, C_FREG, C_NONE, C_FREG, 34, 0},
        Optab{AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 0},
-       Optab{AFMUL, C_FREG, C_FREG, C_NONE, C_FREG, 32, 0},
        Optab{AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, REGSP},
        Optab{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 0},
        Optab{AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 0},
@@ -872,10 +870,6 @@ func buildop(ctxt *obj.Link) {
                        opset(AFMADDS, r)
                        opset(AFMSUB, r)
                        opset(AFMSUBS, r)
-                       opset(AFNMADD, r)
-                       opset(AFNMADDS, r)
-                       opset(AFNMSUB, r)
-                       opset(AFNMSUBS, r)
                case AFMUL:
                        opset(AFMULS, r)
                case AFCMPO:
@@ -2628,18 +2622,6 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
                        opcode = op_DSGR
                case ADIVDU, AMODDU:
                        opcode = op_DLGR
-               case AFADD:
-                       opcode = op_ADBR
-               case AFADDS:
-                       opcode = op_AEBR
-               case AFSUB:
-                       opcode = op_SDBR
-               case AFSUBS:
-                       opcode = op_SEBR
-               case AFDIV:
-                       opcode = op_DDBR
-               case AFDIVS:
-                       opcode = op_DEBR
                }
 
                switch p.As {
@@ -2678,29 +2660,6 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
                        zRRE(opcode, REGTMP, uint32(p.From.Reg), asm)
                        zRRE(op_LGR, uint32(p.To.Reg), REGTMP, asm)
 
-               case AFADD, AFADDS:
-                       if r == p.To.Reg {
-                               zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-                       } else if p.From.Reg == p.To.Reg {
-                               zRRE(opcode, uint32(p.To.Reg), uint32(r), asm)
-                       } else {
-                               zRR(op_LDR, uint32(p.To.Reg), uint32(r), asm)
-                               zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-                       }
-
-               case AFSUB, AFSUBS, AFDIV, AFDIVS:
-                       if r == p.To.Reg {
-                               zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-                       } else if p.From.Reg == p.To.Reg {
-                               zRRE(op_LGDR, REGTMP, uint32(r), asm)
-                               zRRE(opcode, uint32(r), uint32(p.From.Reg), asm)
-                               zRR(op_LDR, uint32(p.To.Reg), uint32(r), asm)
-                               zRRE(op_LDGR, uint32(r), REGTMP, asm)
-                       } else {
-                               zRR(op_LDR, uint32(p.To.Reg), uint32(r), asm)
-                               zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-                       }
-
                }
 
        case 3: // mov $constant reg
@@ -3146,31 +3105,29 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
                        uint8(wd>>8),
                        uint8(wd))
 
-       case 32: // fmul freg [freg] freg
-               r := int(p.Reg)
-               if r == 0 {
-                       r = int(p.To.Reg)
-               }
-
+       case 32: // float op freg freg
                var opcode uint32
-
                switch p.As {
                default:
                        ctxt.Diag("invalid opcode")
+               case AFADD:
+                       opcode = op_ADBR
+               case AFADDS:
+                       opcode = op_AEBR
+               case AFDIV:
+                       opcode = op_DDBR
+               case AFDIVS:
+                       opcode = op_DEBR
                case AFMUL:
                        opcode = op_MDBR
                case AFMULS:
                        opcode = op_MEEBR
+               case AFSUB:
+                       opcode = op_SDBR
+               case AFSUBS:
+                       opcode = op_SEBR
                }
-
-               if r == int(p.To.Reg) {
-                       zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-               } else if p.From.Reg == p.To.Reg {
-                       zRRE(opcode, uint32(p.To.Reg), uint32(r), asm)
-               } else {
-                       zRR(op_LDR, uint32(p.To.Reg), uint32(r), asm)
-                       zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
-               }
+               zRRE(opcode, uint32(p.To.Reg), uint32(p.From.Reg), asm)
 
        case 33: // float op [freg] freg
                r := p.From.Reg
@@ -3199,9 +3156,8 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
                }
                zRRE(opcode, uint32(p.To.Reg), uint32(r), asm)
 
-       case 34: // float multiply-add freg freg freg freg
+       case 34: // float multiply-add freg freg freg
                var opcode uint32
-
                switch p.As {
                default:
                        ctxt.Diag("invalid opcode")
@@ -3213,22 +3169,8 @@ func asmout(ctxt *obj.Link, asm *[]byte) {
                        opcode = op_MSDBR
                case AFMSUBS:
                        opcode = op_MSEBR
-               case AFNMADD:
-                       opcode = op_MADBR
-               case AFNMADDS:
-                       opcode = op_MAEBR
-               case AFNMSUB:
-                       opcode = op_MSDBR
-               case AFNMSUBS:
-                       opcode = op_MSEBR
-               }
-
-               zRR(op_LDR, uint32(p.To.Reg), uint32(p.Reg), asm)
-               zRRD(opcode, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From3.Reg), asm)
-
-               if p.As == AFNMADD || p.As == AFNMADDS || p.As == AFNMSUB || p.As == AFNMSUBS {
-                       zRRE(op_LCDFR, uint32(p.To.Reg), uint32(p.To.Reg), asm)
                }
+               zRRD(opcode, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), asm)
 
        case 35: // mov reg mem (no relocation)
                d2 := regoff(ctxt, &p.To)
index 9d2d931af12f36b3da480ddebc00fb13eb54a018..348c9108ad1ddff6ece9a4643b490618dc89ad8a 100644 (file)
@@ -281,8 +281,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
                        AFMUL,
                        AFNABS,
                        AFNEG,
-                       AFNMADD,
-                       AFNMSUB,
                        ALEDBR,
                        ALDEBR,
                        AFSUB:
index d061bd06804eec55dcb6956091d00526a38e6f51..c5e165514736cba807eb742b2f82630fb8946a23 100644 (file)
@@ -127,7 +127,7 @@ L14:
        MOVD    $coshtab<>+0(SB), R3
        WFMADB  V3, V6, V1, V6
        WORD    $0x68043000     //ld    %f0,0(%r4,%r3)
-       FMSUB   F0, F3, F2, F2
+       FMSUB   F0, F3, F2
        WORD    $0xA71AF000     //ahi   %r1,-4096
        WFMADB  V2, V6, V0, V6
 L17:
@@ -135,7 +135,7 @@ L17:
        BYTE    $0x30
        BYTE    $0x59
        WORD    $0xB3C10022     //ldgr %f2,%r2
-       FMADD   F2, F6, F2, F2
+       FMADD   F2, F6, F2
        MOVD    $coshx4ff<>+0(SB), R1
        FMOVD   0(R1), F0
        FMUL    F2, F0
@@ -153,7 +153,7 @@ L20:
        FMOVD   coshrodataL23<>+8(SB), F4
        FADD    F3, F2
        MOVD    $coshe6<>+0(SB), R1
-       FMSUB   F4, F2, F0, F0
+       FMSUB   F4, F2, F0
        FMOVD   0(R1), F6
        WFMDB   V0, V0, V1
        MOVD    $coshe4<>+0(SB), R1
@@ -161,7 +161,7 @@ L20:
        MOVD    $coshe5<>+0(SB), R1
        FMOVD   coshrodataL23<>+0(SB), F5
        WFMADB  V1, V6, V4, V6
-       FMADD   F5, F2, F0, F0
+       FMADD   F5, F2, F0
        FMOVD   0(R1), F2
        MOVD    $coshe3<>+0(SB), R1
        FMOVD   0(R1), F4
@@ -183,13 +183,13 @@ L20:
        WORD    $0x68145000     //ld %f1,0(%r4,%r5)
        WFMSDB  V4, V1, V0, V2
        WORD    $0xA7487FBE     //lhi %r4,32702
-       FMADD   F3, F2, F1, F1
+       FMADD   F3, F2, F1
        SUBW    R1, R4
        WORD    $0xECC439BC     //risbg %r12,%r4,57,128+60,3
        BYTE    $0x03
        BYTE    $0x55
        WORD    $0x682C5000     //ld %f2,0(%r12,%r5)
-       FMSUB   F2, F4, F0, F0
+       FMSUB   F2, F4, F0
        WORD    $0xEC21000F     //risbgn %r2,%r1,64-64+0,64-64+0+16-1,64-0-16
        BYTE    $0x30
        BYTE    $0x59
@@ -199,8 +199,8 @@ L20:
        BYTE    $0x59
        WORD    $0xB3C10022     //ldgr %f2,%r2
        WORD    $0xB3C10003     //ldgr %f0,%r3
-       FMADD   F2, F1, F2, F2
-       FMADD   F0, F6, F0, F0
+       FMADD   F2, F1, F2
+       FMADD   F0, F6, F0
        FADD    F2, F0
        FMOVD   F0, ret+8(FP)
        RET
@@ -214,7 +214,7 @@ L22:
        BYTE    $0x03
        BYTE    $0x55
        WORD    $0x68034000     //ld %f0,0(%r3,%r4)
-       FMSUB   F0, F3, F2, F2
+       FMSUB   F0, F3, F2
        WORD    $0xA7386FBE     //lhi %r3,28606
        WFMADB  V2, V6, V0, V6
        SUBW    R1, R3, R1
index 460bcd95bc8e0727ff42329f8ee17cb20d6d2ebe..1b6c79de35fdc5a85df19f67869e279c0f709541 100644 (file)
@@ -140,7 +140,7 @@ L4:
        WORD    $0x68331000     //ld %f3,0(%r3,%r1)
        WFMADB  V0, V4, V3, V0
        FMOVD   log10rodataL19<>+24(SB), F4
-       FMADD   F4, F2, F0, F0
+       FMADD   F4, F2, F0
        FMOVD   F0, ret+8(FP)
        RET
 
index 5dc823c07f5c5b3ee70309007ed42e6ba0a43b4a..0bf8136881125664ece5d3ca75dc583653826586 100644 (file)
@@ -100,10 +100,10 @@ L2:
        FADD    F3, F6
        MOVD    $sincosxpi2h<>+0(SB), R1
        FMOVD   0(R1), F2
-       FMSUB   F2, F6, F0, F0
+       FMSUB   F2, F6, F0
        MOVD    $sincosxpi2m<>+0(SB), R1
        FMOVD   0(R1), F4
-       FMADD   F4, F6, F0, F0
+       FMADD   F4, F6, F0
        MOVD    $sincosxpi2l<>+0(SB), R1
        WFMDB   V0, V0, V1
        FMOVD   0(R1), F7
@@ -156,7 +156,7 @@ L6:
        WFMADB  V6, V7, V0, V6
        FMOVD   0(R2), F0
        MOVD    $sincoss4<>+0(SB), R2
-       FMADD   F4, F1, F0, F0
+       FMADD   F4, F1, F0
        FMOVD   0(R2), F3
        MOVD    $sincoss2<>+0(SB), R2
        FMOVD   0(R2), F4
@@ -192,7 +192,7 @@ L18:
        WFMADB  V2, V6, V3, V6
        FMUL    F0, F2
        WFMADB  V1, V4, V6, V4
-       FMADD   F4, F2, F0, F0
+       FMADD   F4, F2, F0
        FMOVD   F0, ret+8(FP)
        RET
 
@@ -312,16 +312,16 @@ L25:
        FMOVD   0(R2), F7
        WFMADB  V6, V3, V7, V3
        MOVD    $sincoss3<>+0(SB), R2
-       FMADD   F5, F4, F0, F0
+       FMADD   F5, F4, F0
        FMOVD   0(R2), F4
        MOVD    $sincoss1<>+0(SB), R2
-       FMADD   F1, F6, F4, F4
+       FMADD   F1, F6, F4
        FMOVD   0(R2), F1
-       FMADD   F3, F2, F1, F1
+       FMADD   F3, F2, F1
        FMUL    F0, F2
        WFMADB  V6, V4, V1, V6
        WORD    $0xA7110002     //tmll  %r1,2
-       FMADD   F6, F2, F0, F0
+       FMADD   F6, F2, F0
        BNE     L34
        FMOVD   F0, ret+8(FP)
        RET
index e492415e84a7e0d204d20ae197624e5e16c44003..e4752eb7b25818ef4663c0c03e15451e976b22c5 100644 (file)
@@ -182,11 +182,11 @@ L20:
        FMOVD   sinhrodataL21<>+8(SB), F0
        FADD    F6, F2
        MOVD    $sinhe9<>+0(SB), R2
-       FMSUB   F0, F2, F4, F4
+       FMSUB   F0, F2, F4
        FMOVD   0(R2), F1
        FMOVD   sinhrodataL21<>+0(SB), F3
        MOVD    $sinhe7<>+0(SB), R2
-       FMADD   F3, F2, F4, F4
+       FMADD   F3, F2, F4
        FMOVD   0(R2), F0
        MOVD    $sinhe8<>+0(SB), R2
        WFMDB   V4, V4, V2
index 1b76c14486eb0a1b2b4b8c7da1317d86e5795dcc..31ea836cf85e253ac923c3d0052ce41551584af6 100644 (file)
@@ -102,7 +102,7 @@ L2:
 L3:
        FADD    F4, F2
        FMOVD   tanhrodataL18<>+80(SB), F4
-       FMADD   F4, F2, F0, F0
+       FMADD   F4, F2, F0
        FMOVD   tanhrodataL18<>+72(SB), F1
        WFMDB   V0, V0, V3
        FMOVD   tanhrodataL18<>+64(SB), F2
@@ -154,7 +154,7 @@ L15:
 L16:
        FADD    F6, F2
        FMOVD   tanhrodataL18<>+8(SB), F0
-       FMADD   F4, F2, F0, F0
+       FMADD   F4, F2, F0
        FMOVD   tanhrodataL18<>+0(SB), F4
        FNEG    F0, F0
        WFMADB  V0, V2, V4, V0