mirror of
https://github.com/golang/go
synced 2024-11-21 21:44:40 -07:00
math: Add ARM64 implementation of frexp
The implementation of Frexp on ARM64 has been implemented in this PR. The following benchmark was run on Apple Silicon M1 chips. BenchmarkArchFrexp-8 1.581 ns/op 0 B/op 0 allocs/op BenchmarkFrexpGO-8 2.079 ns/op 0 B/op 0 allocs/op The time spent on each iteration drop 23.95%.
This commit is contained in:
parent
891547e2d4
commit
92fe95f02e
@ -2541,7 +2541,7 @@ func TestFrexp(t *testing.T) {
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(vffrexpBC); i++ {
|
||||
if f, j := Frexp(vffrexpBC[i]); !alike(frexpBC[i].f, f) || frexpBC[i].i != j {
|
||||
if f, j := Frexp(vffrexpBC[i]); !veryclose(frexpBC[i].f, f) || frexpBC[i].i != j {
|
||||
t.Errorf("Frexp(%g) = %g, %d, want %g, %d", vffrexpBC[i], f, j, frexpBC[i].f, frexpBC[i].i)
|
||||
}
|
||||
}
|
||||
@ -3467,6 +3467,16 @@ func BenchmarkFrexp(b *testing.B) {
|
||||
GlobalI = y
|
||||
}
|
||||
|
||||
func BenchmarkFrexpGO(b *testing.B) {
|
||||
x := 0.0
|
||||
y := 0
|
||||
for i := 0; i < b.N; i++ {
|
||||
x, y = FrexpGO(8)
|
||||
}
|
||||
GlobalF = x
|
||||
GlobalI = y
|
||||
}
|
||||
|
||||
func BenchmarkGamma(b *testing.B) {
|
||||
x := 0.0
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
@ -135,12 +135,6 @@ func archPow(x, y float64) float64
|
||||
func powTrampolineSetup(x, y float64) float64
|
||||
func powAsm(x, y float64) float64
|
||||
|
||||
const haveArchFrexp = false
|
||||
|
||||
func archFrexp(x float64) (float64, int) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
const haveArchLdexp = false
|
||||
|
||||
func archLdexp(frac float64, exp int) float64 {
|
||||
|
@ -8,6 +8,7 @@ package math
|
||||
var ExpGo = exp
|
||||
var Exp2Go = exp2
|
||||
var HypotGo = hypot
|
||||
var FrexpGo = frexp
|
||||
var SqrtGo = sqrt
|
||||
var TrigReduce = trigReduce
|
||||
|
||||
|
57
src/math/frexp_arm64.s
Normal file
57
src/math/frexp_arm64.s
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define PosInf 0x7FF0000000000000
|
||||
#define Float64SmallestNormal 2.2250738585072014e-308
|
||||
|
||||
// func archFrexp(x float64) (frac float64, exp int)
|
||||
TEXT ·archFrexp(SB),NOSPLIT,$0-24
|
||||
FMOVD x+0(FP), F0
|
||||
MOVD ZR, R1 // R1 is the ret exp
|
||||
FABSD F0, F3 // F3 is the absolute of 'x'
|
||||
FCMPD $(0.0), F3 // avoid the input floating number is -0.0
|
||||
BEQ isInfOrNaNOrZero
|
||||
|
||||
MOVD $PosInf, R3
|
||||
FMOVD R3, F30 // F30 is PosInf
|
||||
FCMPD F30, F3
|
||||
BGE isInfOrNaNOrZero // isInf
|
||||
FCMPED F0, F0
|
||||
BNE isInfOrNaNOrZero // isNaN
|
||||
|
||||
FMOVD F3, R0
|
||||
UBFX $52, R0, $11, R0
|
||||
|
||||
FMOVD $Float64SmallestNormal, F29
|
||||
FCMPD F29, F3
|
||||
BGE pass
|
||||
|
||||
// if abs(x) < SmallestNormal ,then run the following special case
|
||||
FMOVD $(4503599627370496.0), F2 // 4503599627370496.0 is (1<<52)
|
||||
FMULD F2, F0, F0
|
||||
SUB $(52), R1, R1 // set R1 to -52
|
||||
FMOVD F0, R0
|
||||
// tmp = int((x>>shift)&mask)
|
||||
UBFX $52, R0, $11, R0
|
||||
|
||||
pass:
|
||||
// tmp = tmp - bias + 1
|
||||
SUB $0x3FE, R0, R3
|
||||
// exp = exp + tmp
|
||||
ADD R3, R1, R1
|
||||
|
||||
FMOVD F0, R0
|
||||
AND $0x800FFFFFFFFFFFFF, R0, R0
|
||||
ORR $0x3FE0000000000000, R0, R0
|
||||
FMOVD R0, F0
|
||||
FMOVD F0, frac+8(FP)
|
||||
MOVD R1, exp+16(FP)
|
||||
RET
|
||||
|
||||
isInfOrNaNOrZero:
|
||||
FMOVD F0, frac+8(FP)
|
||||
MOVD R1, exp+16(FP)
|
||||
RET
|
12
src/math/frexp_asm.go
Normal file
12
src/math/frexp_asm.go
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build arm64
|
||||
// +build arm64
|
||||
|
||||
package math
|
||||
|
||||
const haveArchFrexp = true
|
||||
|
||||
func archFrexp(x float64) (frac float64, exp int)
|
14
src/math/frexp_noasm.go
Normal file
14
src/math/frexp_noasm.go
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !arm64
|
||||
// +build !arm64
|
||||
|
||||
package math
|
||||
|
||||
const haveArchFrexp = false
|
||||
|
||||
func archFrexp(x float64) (frac float64, exp int)
|
||||
panic("not implemented")
|
||||
}
|
@ -88,12 +88,6 @@ func archExpm1(x float64) float64 {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
const haveArchFrexp = false
|
||||
|
||||
func archFrexp(x float64) (float64, int) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
const haveArchLdexp = false
|
||||
|
||||
func archLdexp(frac float64, exp int) float64 {
|
||||
|
Loading…
Reference in New Issue
Block a user