aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/softfloat64.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2025-10-14 12:12:12 -0700
committerDavid Chase <drchase@google.com>2025-10-14 12:45:58 -0700
commitbb2a14252b989f89665d17b66417eff815200e3b (patch)
treeb3f14c9798985497758833db1222e409700f8ebc /src/runtime/softfloat64.go
parent3bc9d9fa8348064c33f6e69f376994af4380d3ab (diff)
downloadgo-bb2a14252b989f89665d17b66417eff815200e3b.tar.xz
Revert "runtime: adjust softfloat corner cases to match amd64/arm64"
This reverts commit b9f3accdcf973ca41069e22e6859b9436801aae5. Reason for revert: we need to do this more carefully, at minimum gated by a module version (This should follow the WASM FP conversion revert) Change-Id: Ib98ce7d243348f69c9944db8537397b225c2cc33 Reviewed-on: https://go-review.googlesource.com/c/go/+/711841 Reviewed-by: Keith Randall <khr@golang.org> TryBot-Bypass: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@google.com>
Diffstat (limited to 'src/runtime/softfloat64.go')
-rw-r--r--src/runtime/softfloat64.go93
1 files changed, 23 insertions, 70 deletions
diff --git a/src/runtime/softfloat64.go b/src/runtime/softfloat64.go
index 7b9409f75b..42ef009297 100644
--- a/src/runtime/softfloat64.go
+++ b/src/runtime/softfloat64.go
@@ -26,11 +26,6 @@ const (
neg32 uint32 = 1 << (expbits32 + mantbits32)
)
-// If F is not NaN and not Inf, then f == (-1)**sign * mantissa * 2**(exp-52)
-// The mantissa and exp are adjusted from their stored representation so
-// that the mantissa includes the formerly implicit 1, the exponent bias
-// is removed, and denormalized floats to put a 1 in the expected
-// (1<<mantbits64) position.
func funpack64(f uint64) (sign, mant uint64, exp int, inf, nan bool) {
sign = f & (1 << (mantbits64 + expbits64))
mant = f & (1<<mantbits64 - 1)
@@ -376,25 +371,24 @@ func fcmp64(f, g uint64) (cmp int32, isnan bool) {
return 0, false
}
-// returns saturated-conversion int64 value of f
-// and whether the input was NaN (in which case it
-// may not match the "hardware" conversion).
-func f64toint(f uint64) (val int64, isNan bool) {
+func f64toint(f uint64) (val int64, ok bool) {
fs, fm, fe, fi, fn := funpack64(f)
switch {
-
- case fn: // NaN
- return -0x8000_0000_0000_0000, false
+ case fi, fn: // NaN
+ return 0, false
case fe < -1: // f < 0.5
return 0, false
- case fi || fe >= 63: // |f| >= 2^63, including infinity
+ case fe > 63: // f >= 2^63
+ if fs != 0 && fm == 0 { // f == -2^63
+ return -1 << 63, true
+ }
if fs != 0 {
- return -0x8000_0000_0000_0000, true
+ return 0, false
}
- return 0x7fff_ffff_ffff_ffff, true
+ return 0, false
}
for fe > int(mantbits64) {
@@ -406,51 +400,12 @@ func f64toint(f uint64) (val int64, isNan bool) {
fm >>= 1
}
val = int64(fm)
- if val < 0 {
- if fs != 0 {
- return -0x8000_0000_0000_0000, true
- }
- return 0x7fff_ffff_ffff_ffff, true
- }
if fs != 0 {
val = -val
}
return val, true
}
-// returns saturated-conversion uint64 value of f
-// and whether the input was NaN (in which case it
-// may not match the "hardware" conversion).
-func f64touint(f uint64) (val uint64, isNan bool) {
- fs, fm, fe, fi, fn := funpack64(f)
-
- switch {
-
- case fn: // NaN
- return 0xffff_ffff_ffff_ffff, false
-
- case fs != 0: // all negative, including -Inf, are zero
- return 0, true
-
- case fi || fe >= 64: // positive infinity or f >= 2^64
- return 0xffff_ffff_ffff_ffff, true
-
- case fe < -1: // f < 0.5
- return 0, true
- }
-
- for fe > int(mantbits64) {
- fe--
- fm <<= 1
- }
- for fe < int(mantbits64) {
- fe++
- fm >>= 1
- }
- val = fm
- return val, true
-}
-
func fintto64(val int64) (f uint64) {
fs := uint64(val) & (1 << 63)
mant := uint64(val)
@@ -609,12 +564,6 @@ func fint64to64(x int64) uint64 {
func f32toint32(x uint32) int32 {
val, _ := f64toint(f32to64(x))
- if val >= 0x7fffffff {
- return 0x7fffffff
- }
- if val < -0x80000000 {
- return -0x80000000
- }
return int32(val)
}
@@ -625,12 +574,6 @@ func f32toint64(x uint32) int64 {
func f64toint32(x uint64) int32 {
val, _ := f64toint(x)
- if val >= 0x7fffffff {
- return 0x7fffffff
- }
- if val < -0x80000000 {
- return -0x80000000
- }
return int32(val)
}
@@ -640,13 +583,23 @@ func f64toint64(x uint64) int64 {
}
func f64touint64(x uint64) uint64 {
- val, _ := f64touint(x)
- return val
+ var m uint64 = 0x43e0000000000000 // float64 1<<63
+ if fgt64(m, x) {
+ return uint64(f64toint64(x))
+ }
+ y := fadd64(x, -m)
+ z := uint64(f64toint64(y))
+ return z | (1 << 63)
}
func f32touint64(x uint32) uint64 {
- val, _ := f64touint(f32to64(x))
- return val
+ var m uint32 = 0x5f000000 // float32 1<<63
+ if fgt32(m, x) {
+ return uint64(f32toint64(x))
+ }
+ y := fadd32(x, -m)
+ z := uint64(f32toint64(y))
+ return z | (1 << 63)
}
func fuint64to64(x uint64) uint64 {