aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal
diff options
context:
space:
mode:
authorPaul E. Murphy <murp@ibm.com>2024-03-29 16:11:36 -0500
committerPaul Murphy <murp@ibm.com>2024-04-04 15:24:29 +0000
commitebf7747dbe0204a930815200b3cbc63a09967bf9 (patch)
tree5060f3725293c5ff138926d105d058866584b09b /src/cmd/internal
parent0f10ffec13a1eecb2b18e0b9d75773faf42e7ebd (diff)
downloadgo-ebf7747dbe0204a930815200b3cbc63a09967bf9.tar.xz
cmd/internal/obj/ppc64: on Power10, use xxspltidp for float constants
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>
Diffstat (limited to 'src/cmd/internal')
-rw-r--r--src/cmd/internal/obj/ppc64/obj9.go28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go
index 5b7612429e..a55c402c44 100644
--- a/src/cmd/internal/obj/ppc64/obj9.go
+++ b/src/cmd/internal/obj/ppc64/obj9.go
@@ -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