runtime: fix uint64->float32 conversion for softfloat

The fix for #48807 in CL 354429 forgot that we also need to fix
the softfloat implementation.

Update #48807

Change-Id: I596fb4e14e78145d1ad43c130b2cc5122b73655c
Reviewed-on: https://go-review.googlesource.com/c/go/+/354613
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Keith Randall 2021-10-07 13:29:09 -07:00
parent d7ba1d276b
commit 16a3cefc93
2 changed files with 33 additions and 5 deletions

View File

@ -162,7 +162,7 @@ func TestCode(t *testing.T) {
}
flags := []string{""}
if runtime.GOARCH == "arm" || runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" {
if runtime.GOARCH == "arm" || runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" || runtime.GOARCH == "386" {
flags = append(flags, ",softfloat")
}
for _, flag := range flags {

View File

@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// Software IEEE754 64-bit floating point.
// Only referred to (and thus linked in) by arm port
// Only referred to (and thus linked in) by softfloat targets
// and by tests in this directory.
package runtime
@ -414,6 +414,25 @@ func fintto64(val int64) (f uint64) {
}
return fpack64(fs, mant, int(mantbits64), 0)
}
func fintto32(val int64) (f uint32) {
fs := uint64(val) & (1 << 63)
mant := uint64(val)
if fs != 0 {
mant = -mant
}
// Reduce mantissa size until it fits into a uint32.
// Keep track of the bits we throw away, and if any are
// nonzero or them into the lowest bit.
exp := int(mantbits32)
var trunc uint32
for mant >= 1<<32 {
trunc |= uint32(mant) & 1
mant >>= 1
exp++
}
return fpack32(uint32(fs>>32), uint32(mant), exp, trunc)
}
// 64x64 -> 128 multiply.
// adapted from hacker's delight.
@ -493,6 +512,7 @@ func fmul32(x, y uint32) uint32 {
}
func fdiv32(x, y uint32) uint32 {
// TODO: are there double-rounding problems here? See issue 48807.
return f64to32(fdiv64(f32to64(x), f32to64(y)))
}
@ -527,7 +547,7 @@ func fge64(x, y uint64) bool {
}
func fint32to32(x int32) uint32 {
return f64to32(fintto64(int64(x)))
return fintto32(int64(x))
}
func fint32to64(x int32) uint64 {
@ -535,7 +555,7 @@ func fint32to64(x int32) uint64 {
}
func fint64to32(x int64) uint32 {
return f64to32(fintto64(x))
return fintto32(x)
}
func fint64to64(x int64) uint64 {
@ -595,5 +615,13 @@ func fuint64to64(x uint64) uint64 {
}
func fuint64to32(x uint64) uint32 {
return f64to32(fuint64to64(x))
if int64(x) >= 0 {
return fint64to32(int64(x))
}
// See ../cmd/compile/internal/ssagen/ssa.go:uint64Tofloat
y := x & 1
z := x >> 1
z = z | y
r := fint64to32(int64(z))
return fadd32(r, r)
}