diff options
| author | David Chase <drchase@google.com> | 2025-10-14 12:12:12 -0700 |
|---|---|---|
| committer | David Chase <drchase@google.com> | 2025-10-14 12:45:58 -0700 |
| commit | bb2a14252b989f89665d17b66417eff815200e3b (patch) | |
| tree | b3f14c9798985497758833db1222e409700f8ebc /src/runtime/softfloat64.go | |
| parent | 3bc9d9fa8348064c33f6e69f376994af4380d3ab (diff) | |
| download | go-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.go | 93 |
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 { |
