mirror of https://github.com/golang/go.git
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: Lynn Boger <laboger@linux.vnet.ibm.com>
This commit is contained in:
parent
736390c2bd
commit
ebb67d993a
|
|
@ -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) {
|
||||||
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 @@
|
||||||
(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() {
|
||||||
{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 (
|
||||||
OpPPC64FFLOOR
|
OpPPC64FFLOOR
|
||||||
OpPPC64FCEIL
|
OpPPC64FCEIL
|
||||||
OpPPC64FTRUNC
|
OpPPC64FTRUNC
|
||||||
|
OpPPC64FROUND
|
||||||
OpPPC64FABS
|
OpPPC64FABS
|
||||||
OpPPC64FNABS
|
OpPPC64FNABS
|
||||||
OpPPC64FCPSGN
|
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",
|
name: "FABS",
|
||||||
argLen: 1,
|
argLen: 1,
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
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 (
|
||||||
AFRIPCC
|
AFRIPCC
|
||||||
AFRIZ
|
AFRIZ
|
||||||
AFRIZCC
|
AFRIZCC
|
||||||
|
AFRIN
|
||||||
|
AFRINCC
|
||||||
AFRSQRTE
|
AFRSQRTE
|
||||||
AFRSQRTECC
|
AFRSQRTECC
|
||||||
AFSEL
|
AFSEL
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
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 {
|
||||||
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
|
||||||
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"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue