]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile, cmd/internal/obj/ppc64: make math.Round an intrinsic on ppc64x
authorCarlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Fri, 2 Mar 2018 19:47:54 +0000 (16:47 -0300)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Thu, 26 Apr 2018 14:12:09 +0000 (14:12 +0000)
This change implements math.Round as an intrinsic on ppc64x so it can be
done using a single instruction.

benchmark                   old ns/op     new ns/op     delta
BenchmarkRound-16           2.60          0.69          -73.46%

Change-Id: I9408363e96201abdfc73ced7bcd5f0c29db006a8
Reviewed-on: https://go-review.googlesource.com/109395
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ppc64/ssa.go
src/cmd/compile/internal/ssa/gen/PPC64.rules
src/cmd/compile/internal/ssa/gen/PPC64Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewritePPC64.go
src/cmd/internal/obj/ppc64/a.out.go
src/cmd/internal/obj/ppc64/anames.go
src/cmd/internal/obj/ppc64/asm9.go
test/codegen/math.go

index a3d2230964ba5d373098fe820a6df47e57a9b9a1..6d19e47d38e5a15af3437c4022bdcff2e49a74b0 100644 (file)
@@ -3005,7 +3005,7 @@ func init() {
                func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
                        return s.newValue1(ssa.OpRound, types.Types[TFLOAT64], args[0])
                },
-               sys.ARM64, sys.S390X)
+               sys.ARM64, sys.PPC64, sys.S390X)
        addF("math", "RoundToEven",
                func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
                        return s.newValue1(ssa.OpRoundToEven, types.Types[TFLOAT64], args[0])
index 3c10149eabfc4a5e811d05112d76f156f8a09216..4c91a04a03a38650339cdf3f4ee8135c5b9dfef4 100644 (file)
@@ -581,7 +581,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_REG
                p.To.Reg = ppc64.REGTMP // Ignored; this is for the carry effect.
 
-       case ssa.OpPPC64NEG, ssa.OpPPC64FNEG, ssa.OpPPC64FSQRT, ssa.OpPPC64FSQRTS, ssa.OpPPC64FFLOOR, ssa.OpPPC64FTRUNC, ssa.OpPPC64FCEIL, ssa.OpPPC64FCTIDZ, ssa.OpPPC64FCTIWZ, ssa.OpPPC64FCFID, ssa.OpPPC64FCFIDS, ssa.OpPPC64FRSP, ssa.OpPPC64CNTLZD, ssa.OpPPC64CNTLZW, ssa.OpPPC64POPCNTD, ssa.OpPPC64POPCNTW, ssa.OpPPC64POPCNTB, ssa.OpPPC64MFVSRD, ssa.OpPPC64MTVSRD, ssa.OpPPC64FABS, ssa.OpPPC64FNABS:
+       case ssa.OpPPC64NEG, ssa.OpPPC64FNEG, ssa.OpPPC64FSQRT, ssa.OpPPC64FSQRTS, ssa.OpPPC64FFLOOR, ssa.OpPPC64FTRUNC, ssa.OpPPC64FCEIL, ssa.OpPPC64FCTIDZ, ssa.OpPPC64FCTIWZ, ssa.OpPPC64FCFID, ssa.OpPPC64FCFIDS, ssa.OpPPC64FRSP, ssa.OpPPC64CNTLZD, ssa.OpPPC64CNTLZW, ssa.OpPPC64POPCNTD, ssa.OpPPC64POPCNTW, ssa.OpPPC64POPCNTB, ssa.OpPPC64MFVSRD, ssa.OpPPC64MTVSRD, ssa.OpPPC64FABS, ssa.OpPPC64FNABS, ssa.OpPPC64FROUND:
                r := v.Reg()
                p := s.Prog(v.Op.Asm())
                p.To.Type = obj.TYPE_REG
index 6f3e893d8dd584dbb2d9ce22d6979696468f5d17..5d416151eecde176ba613de7fae1b9bc8be19d43 100644 (file)
@@ -63,6 +63,7 @@
 (Floor x) -> (FFLOOR x)
 (Ceil x) -> (FCEIL x)
 (Trunc x) -> (FTRUNC x)
+(Round x) -> (FROUND x)
 (Copysign x y) -> (FCPSGN y x)
 (Abs x) -> (FABS x)
 
index 567e34ec2a9d9f064ff86b35b8e71ecf20b50b0d..ad68794de0080e7afa9ecbc8cc11dd5836d1d1ad 100644 (file)
@@ -249,6 +249,7 @@ func init() {
                {name: "FFLOOR", argLength: 1, reg: fp11, asm: "FRIM"},                              // floor(arg0), float64
                {name: "FCEIL", argLength: 1, reg: fp11, asm: "FRIP"},                               // ceil(arg0), float64
                {name: "FTRUNC", argLength: 1, reg: fp11, asm: "FRIZ"},                              // trunc(arg0), float64
+               {name: "FROUND", argLength: 1, reg: fp11, asm: "FRIN"},                              // round(arg0), float64
                {name: "FABS", argLength: 1, reg: fp11, asm: "FABS"},                                // abs(arg0), float64
                {name: "FNABS", argLength: 1, reg: fp11, asm: "FNABS"},                              // -abs(arg0), float64
                {name: "FCPSGN", argLength: 2, reg: fp21, asm: "FCPSGN"},                            // copysign arg0 -> arg1, float64
index aea2246e842302c55810bf71dda97d784f8fcf3a..de04eacfa8e72488e6d4935c30b1851211ff36a9 100644 (file)
@@ -1541,6 +1541,7 @@ const (
        OpPPC64FFLOOR
        OpPPC64FCEIL
        OpPPC64FTRUNC
+       OpPPC64FROUND
        OpPPC64FABS
        OpPPC64FNABS
        OpPPC64FCPSGN
@@ -20296,6 +20297,19 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "FROUND",
+               argLen: 1,
+               asm:    ppc64.AFRIN,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+                       },
+                       outputs: []outputInfo{
+                               {0, 576460743713488896}, // F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
+                       },
+               },
+       },
        {
                name:   "FABS",
                argLen: 1,
index 331a8c9232b157701eac5005e736bd722487f1a7..8610f08e7f34cf149463c217f65ef6ce88c7d39f 100644 (file)
@@ -505,6 +505,8 @@ func rewriteValuePPC64(v *Value) bool {
                return rewriteValuePPC64_OpPopCount64_0(v)
        case OpPopCount8:
                return rewriteValuePPC64_OpPopCount8_0(v)
+       case OpRound:
+               return rewriteValuePPC64_OpRound_0(v)
        case OpRound32F:
                return rewriteValuePPC64_OpRound32F_0(v)
        case OpRound64F:
@@ -13466,6 +13468,15 @@ func rewriteValuePPC64_OpPopCount8_0(v *Value) bool {
                return true
        }
 }
+func rewriteValuePPC64_OpRound_0(v *Value) bool {
+       // match: (Round x)
+       // cond:
+       // result: (FROUND x)
+       x := v.Args[0]
+       v.reset(OpPPC64FROUND)
+       v.AddArg(x)
+       return true
+}
 func rewriteValuePPC64_OpRound32F_0(v *Value) bool {
        // match: (Round32F x)
        // cond:
index 8f56da0763d7c2c32b1b3612af893b8412308e15..3c374579ec6a946ba0cb444bc2472b1c38475fc1 100644 (file)
@@ -643,6 +643,8 @@ const (
        AFRIPCC
        AFRIZ
        AFRIZCC
+       AFRIN
+       AFRINCC
        AFRSQRTE
        AFRSQRTECC
        AFSEL
index 6006f15ad64687633a529f34c21382177171cf11..16a27591c71cec3583feb4eb363838928a94b1be 100644 (file)
@@ -245,6 +245,8 @@ var Anames = []string{
        "FRIPCC",
        "FRIZ",
        "FRIZCC",
+       "FRIN",
+       "FRINCC",
        "FRSQRTE",
        "FRSQRTECC",
        "FSEL",
index 4dcb52f9eee265b4511200afc920a46d462d273a..72738f1967e9d0b2f1d0ab926203e0572107c4b8 100644 (file)
@@ -1671,6 +1671,8 @@ func buildop(ctxt *obj.Link) {
                        opset(AFRIPCC, r0)
                        opset(AFRIZ, r0)
                        opset(AFRIZCC, r0)
+                       opset(AFRIN, r0)
+                       opset(AFRINCC, r0)
                        opset(AFRSQRTE, r0)
                        opset(AFRSQRTECC, r0)
                        opset(AFSQRT, r0)
@@ -3898,6 +3900,10 @@ func (c *ctxt9) oprrr(a obj.As) uint32 {
                return OPVCC(63, 424, 0, 0)
        case AFRIZCC:
                return OPVCC(63, 424, 0, 1)
+       case AFRIN:
+               return OPVCC(63, 392, 0, 0)
+       case AFRINCC:
+               return OPVCC(63, 392, 0, 1)
        case AFRSP:
                return OPVCC(63, 12, 0, 0)
        case AFRSPCC:
index efa3a2bc8fd2c4414e03f16678599ea711a904a2..f73321200be62e82c2b963d6d8a67a8e23c455ad 100644 (file)
@@ -13,18 +13,22 @@ var sink64 [8]float64
 func approx(x float64) {
        // s390x:"FIDBR\t[$]6"
        // arm64:"FRINTPD"
+       // ppc64le:"FRIP"
        sink64[0] = math.Ceil(x)
 
        // s390x:"FIDBR\t[$]7"
        // arm64:"FRINTMD"
+       // ppc64le:"FRIM"
        sink64[1] = math.Floor(x)
 
        // s390x:"FIDBR\t[$]1"
        // arm64:"FRINTAD"
+       // ppc64le:"FRIN"
        sink64[2] = math.Round(x)
 
        // s390x:"FIDBR\t[$]5"
        // arm64:"FRINTZD"
+       // ppc64le:"FRIZ"
        sink64[3] = math.Trunc(x)
 
        // s390x:"FIDBR\t[$]4"