]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/ppc64: on Power10, use xxspltidp for float constants
authorPaul E. Murphy <murp@ibm.com>
Fri, 29 Mar 2024 21:11:36 +0000 (16:11 -0500)
committerPaul Murphy <murp@ibm.com>
Thu, 4 Apr 2024 15:24:29 +0000 (15:24 +0000)
Any normal float32 constant can be generated by this instruction;
use xxspltidp when possible. This prefixed instruction is much
faster than the two instruction load sequence from the
float32/float64 constant pool.

Change-Id: Id751d9ffdae71463adbde66427b986f0b2ef74c2
Reviewed-on: https://go-review.googlesource.com/c/go/+/575555
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Paul Murphy <murp@ibm.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
src/cmd/internal/obj/ppc64/obj9.go
test/codegen/floats.go
test/codegen/math.go

index 5b7612429ebc62ac9b774ba7c5dde1cff39b8186..a55c402c44288055a723c1ee3716bbb8c87bcbbe 100644 (file)
@@ -37,6 +37,7 @@ import (
        "internal/abi"
        "internal/buildcfg"
        "log"
+       "math"
        "math/bits"
        "strings"
 )
@@ -90,6 +91,29 @@ func isNOTOCfunc(name string) bool {
        }
 }
 
+// Try converting FMOVD/FMOVS to XXSPLTIDP. If it is converted,
+// return true.
+func convertFMOVtoXXSPLTIDP(p *obj.Prog) bool {
+       if p.From.Type != obj.TYPE_FCONST || buildcfg.GOPPC64 < 10 {
+               return false
+       }
+       v := p.From.Val.(float64)
+       if float64(float32(v)) != v {
+               return false
+       }
+       // Secondly, is this value a normal value?
+       ival := int64(math.Float32bits(float32(v)))
+       isDenorm := ival&0x7F800000 == 0 && ival&0x007FFFFF != 0
+       if !isDenorm {
+               p.As = AXXSPLTIDP
+               p.From.Type = obj.TYPE_CONST
+               p.From.Offset = ival
+               // Convert REG_Fx into equivalent REG_VSx
+               p.To.Reg = REG_VS0 + (p.To.Reg & 31)
+       }
+       return !isDenorm
+}
+
 func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
        p.From.Class = 0
        p.To.Class = 0
@@ -111,7 +135,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
        // Rewrite float constants to values stored in memory.
        switch p.As {
        case AFMOVS:
-               if p.From.Type == obj.TYPE_FCONST {
+               if p.From.Type == obj.TYPE_FCONST && !convertFMOVtoXXSPLTIDP(p) {
                        f32 := float32(p.From.Val.(float64))
                        p.From.Type = obj.TYPE_MEM
                        p.From.Sym = ctxt.Float32Sym(f32)
@@ -123,7 +147,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
                if p.From.Type == obj.TYPE_FCONST {
                        f64 := p.From.Val.(float64)
                        // Constant not needed in memory for float +/- 0
-                       if f64 != 0 {
+                       if f64 != 0 && !convertFMOVtoXXSPLTIDP(p) {
                                p.From.Type = obj.TYPE_MEM
                                p.From.Sym = ctxt.Float64Sym(f64)
                                p.From.Name = obj.NAME_EXTERN
index d5c5475567850dd2c00faf66b88015b6be6b06fa..baa745bdeece5bf92e805ef8f02ea3b97f9162c4 100644 (file)
@@ -196,3 +196,34 @@ func Float32Max(a, b float32) float32 {
        // ppc64/power10:"XSMAXJDP"
        return max(a, b)
 }
+
+// ------------------------ //
+//  Constant Optimizations  //
+// ------------------------ //
+
+func Float32Constant() float32 {
+       // ppc64x/power8:"FMOVS\t[$]f32\\.42440000\\(SB\\)"
+       // ppc64x/power9:"FMOVS\t[$]f32\\.42440000\\(SB\\)"
+       // ppc64x/power10:"XXSPLTIDP\t[$]1111752704,"
+       return 49.0
+}
+
+func Float64Constant() float64 {
+       // ppc64x/power8:"FMOVD\t[$]f64\\.4048800000000000\\(SB\\)"
+       // ppc64x/power9:"FMOVD\t[$]f64\\.4048800000000000\\(SB\\)"
+       // ppc64x/power10:"XXSPLTIDP\t[$]1111752704,"
+       return 49.0
+}
+
+func Float32DenormalConstant() float32 {
+       // ppc64x:"FMOVS\t[$]f32\\.00400000\\(SB\\)"
+       return 0x1p-127
+}
+
+// A float64 constant which can be exactly represented as a
+// denormal float32 value. On ppc64x, denormal values cannot
+// be used with XXSPLTIDP.
+func Float64DenormalFloat32Constant() float64 {
+       // ppc64x:"FMOVD\t[$]f64\\.3800000000000000\\(SB\\)"
+       return 0x1p-127
+}
index 331ebbe6094bb18a5a567d485fb6da707eede1da..eb6e927dec92fbf77ee2349f76c4762b9f067887 100644 (file)
@@ -204,7 +204,9 @@ func constantCheck32() bool {
 func constantConvert32(x float32) float32 {
        // amd64:"MOVSS\t[$]f32.3f800000\\(SB\\)"
        // s390x:"FMOVS\t[$]f32.3f800000\\(SB\\)"
-       // ppc64x:"FMOVS\t[$]f32.3f800000\\(SB\\)"
+       // ppc64x/power8:"FMOVS\t[$]f32.3f800000\\(SB\\)"
+       // ppc64x/power9:"FMOVS\t[$]f32.3f800000\\(SB\\)"
+       // ppc64x/power10:"XXSPLTIDP\t[$]1065353216, VS0"
        // arm64:"FMOVS\t[$]\\(1.0\\)"
        if x > math.Float32frombits(0x3f800000) {
                return -x