Skip to content

Commit ebf7747

Browse files
committed
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 <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Paul Murphy <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Lynn Boger <[email protected]>
1 parent 0f10ffe commit ebf7747

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

src/cmd/internal/obj/ppc64/obj9.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"internal/abi"
3838
"internal/buildcfg"
3939
"log"
40+
"math"
4041
"math/bits"
4142
"strings"
4243
)
@@ -90,6 +91,29 @@ func isNOTOCfunc(name string) bool {
9091
}
9192
}
9293

94+
// Try converting FMOVD/FMOVS to XXSPLTIDP. If it is converted,
95+
// return true.
96+
func convertFMOVtoXXSPLTIDP(p *obj.Prog) bool {
97+
if p.From.Type != obj.TYPE_FCONST || buildcfg.GOPPC64 < 10 {
98+
return false
99+
}
100+
v := p.From.Val.(float64)
101+
if float64(float32(v)) != v {
102+
return false
103+
}
104+
// Secondly, is this value a normal value?
105+
ival := int64(math.Float32bits(float32(v)))
106+
isDenorm := ival&0x7F800000 == 0 && ival&0x007FFFFF != 0
107+
if !isDenorm {
108+
p.As = AXXSPLTIDP
109+
p.From.Type = obj.TYPE_CONST
110+
p.From.Offset = ival
111+
// Convert REG_Fx into equivalent REG_VSx
112+
p.To.Reg = REG_VS0 + (p.To.Reg & 31)
113+
}
114+
return !isDenorm
115+
}
116+
93117
func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
94118
p.From.Class = 0
95119
p.To.Class = 0
@@ -111,7 +135,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
111135
// Rewrite float constants to values stored in memory.
112136
switch p.As {
113137
case AFMOVS:
114-
if p.From.Type == obj.TYPE_FCONST {
138+
if p.From.Type == obj.TYPE_FCONST && !convertFMOVtoXXSPLTIDP(p) {
115139
f32 := float32(p.From.Val.(float64))
116140
p.From.Type = obj.TYPE_MEM
117141
p.From.Sym = ctxt.Float32Sym(f32)
@@ -123,7 +147,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
123147
if p.From.Type == obj.TYPE_FCONST {
124148
f64 := p.From.Val.(float64)
125149
// Constant not needed in memory for float +/- 0
126-
if f64 != 0 {
150+
if f64 != 0 && !convertFMOVtoXXSPLTIDP(p) {
127151
p.From.Type = obj.TYPE_MEM
128152
p.From.Sym = ctxt.Float64Sym(f64)
129153
p.From.Name = obj.NAME_EXTERN

test/codegen/floats.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,34 @@ func Float32Max(a, b float32) float32 {
196196
// ppc64/power10:"XSMAXJDP"
197197
return max(a, b)
198198
}
199+
200+
// ------------------------ //
201+
// Constant Optimizations //
202+
// ------------------------ //
203+
204+
func Float32Constant() float32 {
205+
// ppc64x/power8:"FMOVS\t[$]f32\\.42440000\\(SB\\)"
206+
// ppc64x/power9:"FMOVS\t[$]f32\\.42440000\\(SB\\)"
207+
// ppc64x/power10:"XXSPLTIDP\t[$]1111752704,"
208+
return 49.0
209+
}
210+
211+
func Float64Constant() float64 {
212+
// ppc64x/power8:"FMOVD\t[$]f64\\.4048800000000000\\(SB\\)"
213+
// ppc64x/power9:"FMOVD\t[$]f64\\.4048800000000000\\(SB\\)"
214+
// ppc64x/power10:"XXSPLTIDP\t[$]1111752704,"
215+
return 49.0
216+
}
217+
218+
func Float32DenormalConstant() float32 {
219+
// ppc64x:"FMOVS\t[$]f32\\.00400000\\(SB\\)"
220+
return 0x1p-127
221+
}
222+
223+
// A float64 constant which can be exactly represented as a
224+
// denormal float32 value. On ppc64x, denormal values cannot
225+
// be used with XXSPLTIDP.
226+
func Float64DenormalFloat32Constant() float64 {
227+
// ppc64x:"FMOVD\t[$]f64\\.3800000000000000\\(SB\\)"
228+
return 0x1p-127
229+
}

test/codegen/math.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ func constantCheck32() bool {
204204
func constantConvert32(x float32) float32 {
205205
// amd64:"MOVSS\t[$]f32.3f800000\\(SB\\)"
206206
// s390x:"FMOVS\t[$]f32.3f800000\\(SB\\)"
207-
// ppc64x:"FMOVS\t[$]f32.3f800000\\(SB\\)"
207+
// ppc64x/power8:"FMOVS\t[$]f32.3f800000\\(SB\\)"
208+
// ppc64x/power9:"FMOVS\t[$]f32.3f800000\\(SB\\)"
209+
// ppc64x/power10:"XXSPLTIDP\t[$]1065353216, VS0"
208210
// arm64:"FMOVS\t[$]\\(1.0\\)"
209211
if x > math.Float32frombits(0x3f800000) {
210212
return -x

0 commit comments

Comments
 (0)