]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix uint64->float32 conversion for softfloat
authorKeith Randall <khr@golang.org>
Thu, 7 Oct 2021 20:29:09 +0000 (13:29 -0700)
committerKeith Randall <khr@golang.org>
Fri, 8 Oct 2021 17:58:41 +0000 (17:58 +0000)
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>
src/cmd/compile/internal/test/ssa_test.go
src/runtime/softfloat64.go

index 2f3e24c2d37ca0b6c9b6226e6611de369ff39cc9..af7d9626f95f9efb596614bf2c6061d5a502eed3 100644 (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 {
index 084aa132d9c6bd2636b6a58a452798264544e37b..42ef0092970b3e2525b65fa1c4cf5559d51b44d7 100644 (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)
 }