jit(arm64): various float instructions (#257)

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
Takeshi Yoneda
2022-02-18 14:05:24 +09:00
committed by GitHub
parent 43b40e4884
commit fbe153bb2c
6 changed files with 722 additions and 91 deletions

View File

@@ -1,4 +1,4 @@
package internal
package moremath
import "math"
@@ -44,3 +44,47 @@ func WasmCompatMax(x, y float64) float64 {
}
return y
}
// WasmCompatNearestF32 is the Wasm spec compatible variant of math.Round, which is used for Nearest instruction.
// For example, this converts 1.9 to 2.0, and this has the semantics of LLVM's rint instrinsic: https://llvm.org/docs/LangRef.html#llvm-rint-intrinsic.
// For the difference from math.Round, math.Round(-4.5) results in -5 while this produces -4.
func WasmCompatNearestF32(f float32) float32 {
// TODO: look at https://github.com/bytecodealliance/wasmtime/pull/2171 and reconsider this algorithm
if f != -0 && f != 0 {
ceil := float32(math.Ceil(float64(f)))
floor := float32(math.Floor(float64(f)))
distToCeil := math.Abs(float64(f - ceil))
distToFloor := math.Abs(float64(f - floor))
h := ceil / 2.0
if distToCeil < distToFloor {
f = ceil
} else if distToCeil == distToFloor && float32(math.Floor(float64(h))) == h {
f = ceil
} else {
f = floor
}
}
return f
}
// WasmCompatNearestF64 is the Wasm spec compatible variant of math.Round, which is used for Nearest instruction.
// For example, this converts 1.9 to 2.0, and this has the semantics of LLVM's rint instrinsic: https://llvm.org/docs/LangRef.html#llvm-rint-intrinsic.
// For the difference from math.Round, math.Round(-4.5) results in -5 while this produces -4.
func WasmCompatNearestF64(f float64) float64 {
// TODO: look at https://github.com/bytecodealliance/wasmtime/pull/2171 and reconsider this algorithm
if f != -0 && f != 0 {
ceil := math.Ceil(f)
floor := math.Floor(f)
distToCeil := math.Abs(f - ceil)
distToFloor := math.Abs(f - floor)
h := ceil / 2.0
if distToCeil < distToFloor {
f = ceil
} else if distToCeil == distToFloor && math.Floor(float64(h)) == h {
f = ceil
} else {
f = floor
}
}
return f
}