Commit ebb67d99 authored by Carlos Eduardo Seo's avatar Carlos Eduardo Seo Committed by Lynn Boger

cmd/compile, cmd/internal/obj/ppc64: make math.Round an intrinsic on ppc64x

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: default avatarLynn Boger <laboger@linux.vnet.ibm.com>
parent 736390c2
...@@ -3005,7 +3005,7 @@ func init() { ...@@ -3005,7 +3005,7 @@ func init() {
func(s *state, n *Node, args []*ssa.Value) *ssa.Value { func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
return s.newValue1(ssa.OpRound, types.Types[TFLOAT64], args[0]) return s.newValue1(ssa.OpRound, types.Types[TFLOAT64], args[0])
}, },
sys.ARM64, sys.S390X) sys.ARM64, sys.PPC64, sys.S390X)
addF("math", "RoundToEven", addF("math", "RoundToEven",
func(s *state, n *Node, args []*ssa.Value) *ssa.Value { func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
return s.newValue1(ssa.OpRoundToEven, types.Types[TFLOAT64], args[0]) return s.newValue1(ssa.OpRoundToEven, types.Types[TFLOAT64], args[0])
......
...@@ -581,7 +581,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -581,7 +581,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = ppc64.REGTMP // Ignored; this is for the carry effect. 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() r := v.Reg()
p := s.Prog(v.Op.Asm()) p := s.Prog(v.Op.Asm())
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
......
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
(Floor x) -> (FFLOOR x) (Floor x) -> (FFLOOR x)
(Ceil x) -> (FCEIL x) (Ceil x) -> (FCEIL x)
(Trunc x) -> (FTRUNC x) (Trunc x) -> (FTRUNC x)
(Round x) -> (FROUND x)
(Copysign x y) -> (FCPSGN y x) (Copysign x y) -> (FCPSGN y x)
(Abs x) -> (FABS x) (Abs x) -> (FABS x)
......
...@@ -249,6 +249,7 @@ func init() { ...@@ -249,6 +249,7 @@ func init() {
{name: "FFLOOR", argLength: 1, reg: fp11, asm: "FRIM"}, // floor(arg0), float64 {name: "FFLOOR", argLength: 1, reg: fp11, asm: "FRIM"}, // floor(arg0), float64
{name: "FCEIL", argLength: 1, reg: fp11, asm: "FRIP"}, // ceil(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: "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: "FABS", argLength: 1, reg: fp11, asm: "FABS"}, // abs(arg0), float64
{name: "FNABS", argLength: 1, reg: fp11, asm: "FNABS"}, // -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 {name: "FCPSGN", argLength: 2, reg: fp21, asm: "FCPSGN"}, // copysign arg0 -> arg1, float64
......
...@@ -1541,6 +1541,7 @@ const ( ...@@ -1541,6 +1541,7 @@ const (
OpPPC64FFLOOR OpPPC64FFLOOR
OpPPC64FCEIL OpPPC64FCEIL
OpPPC64FTRUNC OpPPC64FTRUNC
OpPPC64FROUND
OpPPC64FABS OpPPC64FABS
OpPPC64FNABS OpPPC64FNABS
OpPPC64FCPSGN OpPPC64FCPSGN
...@@ -20296,6 +20297,19 @@ var opcodeTable = [...]opInfo{ ...@@ -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", name: "FABS",
argLen: 1, argLen: 1,
......
...@@ -505,6 +505,8 @@ func rewriteValuePPC64(v *Value) bool { ...@@ -505,6 +505,8 @@ func rewriteValuePPC64(v *Value) bool {
return rewriteValuePPC64_OpPopCount64_0(v) return rewriteValuePPC64_OpPopCount64_0(v)
case OpPopCount8: case OpPopCount8:
return rewriteValuePPC64_OpPopCount8_0(v) return rewriteValuePPC64_OpPopCount8_0(v)
case OpRound:
return rewriteValuePPC64_OpRound_0(v)
case OpRound32F: case OpRound32F:
return rewriteValuePPC64_OpRound32F_0(v) return rewriteValuePPC64_OpRound32F_0(v)
case OpRound64F: case OpRound64F:
...@@ -13466,6 +13468,15 @@ func rewriteValuePPC64_OpPopCount8_0(v *Value) bool { ...@@ -13466,6 +13468,15 @@ func rewriteValuePPC64_OpPopCount8_0(v *Value) bool {
return true 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 { func rewriteValuePPC64_OpRound32F_0(v *Value) bool {
// match: (Round32F x) // match: (Round32F x)
// cond: // cond:
......
...@@ -643,6 +643,8 @@ const ( ...@@ -643,6 +643,8 @@ const (
AFRIPCC AFRIPCC
AFRIZ AFRIZ
AFRIZCC AFRIZCC
AFRIN
AFRINCC
AFRSQRTE AFRSQRTE
AFRSQRTECC AFRSQRTECC
AFSEL AFSEL
......
...@@ -245,6 +245,8 @@ var Anames = []string{ ...@@ -245,6 +245,8 @@ var Anames = []string{
"FRIPCC", "FRIPCC",
"FRIZ", "FRIZ",
"FRIZCC", "FRIZCC",
"FRIN",
"FRINCC",
"FRSQRTE", "FRSQRTE",
"FRSQRTECC", "FRSQRTECC",
"FSEL", "FSEL",
......
...@@ -1671,6 +1671,8 @@ func buildop(ctxt *obj.Link) { ...@@ -1671,6 +1671,8 @@ func buildop(ctxt *obj.Link) {
opset(AFRIPCC, r0) opset(AFRIPCC, r0)
opset(AFRIZ, r0) opset(AFRIZ, r0)
opset(AFRIZCC, r0) opset(AFRIZCC, r0)
opset(AFRIN, r0)
opset(AFRINCC, r0)
opset(AFRSQRTE, r0) opset(AFRSQRTE, r0)
opset(AFRSQRTECC, r0) opset(AFRSQRTECC, r0)
opset(AFSQRT, r0) opset(AFSQRT, r0)
...@@ -3898,6 +3900,10 @@ func (c *ctxt9) oprrr(a obj.As) uint32 { ...@@ -3898,6 +3900,10 @@ func (c *ctxt9) oprrr(a obj.As) uint32 {
return OPVCC(63, 424, 0, 0) return OPVCC(63, 424, 0, 0)
case AFRIZCC: case AFRIZCC:
return OPVCC(63, 424, 0, 1) return OPVCC(63, 424, 0, 1)
case AFRIN:
return OPVCC(63, 392, 0, 0)
case AFRINCC:
return OPVCC(63, 392, 0, 1)
case AFRSP: case AFRSP:
return OPVCC(63, 12, 0, 0) return OPVCC(63, 12, 0, 0)
case AFRSPCC: case AFRSPCC:
......
...@@ -13,18 +13,22 @@ var sink64 [8]float64 ...@@ -13,18 +13,22 @@ var sink64 [8]float64
func approx(x float64) { func approx(x float64) {
// s390x:"FIDBR\t[$]6" // s390x:"FIDBR\t[$]6"
// arm64:"FRINTPD" // arm64:"FRINTPD"
// ppc64le:"FRIP"
sink64[0] = math.Ceil(x) sink64[0] = math.Ceil(x)
// s390x:"FIDBR\t[$]7" // s390x:"FIDBR\t[$]7"
// arm64:"FRINTMD" // arm64:"FRINTMD"
// ppc64le:"FRIM"
sink64[1] = math.Floor(x) sink64[1] = math.Floor(x)
// s390x:"FIDBR\t[$]1" // s390x:"FIDBR\t[$]1"
// arm64:"FRINTAD" // arm64:"FRINTAD"
// ppc64le:"FRIN"
sink64[2] = math.Round(x) sink64[2] = math.Round(x)
// s390x:"FIDBR\t[$]5" // s390x:"FIDBR\t[$]5"
// arm64:"FRINTZD" // arm64:"FRINTZD"
// ppc64le:"FRIZ"
sink64[3] = math.Trunc(x) sink64[3] = math.Trunc(x)
// s390x:"FIDBR\t[$]4" // s390x:"FIDBR\t[$]4"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment