aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2025-09-30 16:27:32 -0400
committerDavid Chase <drchase@google.com>2025-10-09 08:23:30 -0700
commit78d75b37992be01326b9bd2666195aaba9bf2ae2 (patch)
treeb63e9a0f0079973aadd9018cc21de898bd86d724 /src/runtime
parent0e466a8d1d89e15e953c7d35bcd9e02d3c89f62b (diff)
downloadgo-78d75b37992be01326b9bd2666195aaba9bf2ae2.tar.xz
cmd/compile: make 386 float-to-int conversions match amd64
Change-Id: Iff13b4471f94a6a91d8b159603a9338cb9c89747 Reviewed-on: https://go-review.googlesource.com/c/go/+/708295 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/asm_386.s10
-rw-r--r--src/runtime/stubs_386.go1
-rw-r--r--src/runtime/vlrt.go63
3 files changed, 59 insertions, 15 deletions
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s
index df32e90fda..2a6de64f9f 100644
--- a/src/runtime/asm_386.s
+++ b/src/runtime/asm_386.s
@@ -1407,16 +1407,6 @@ TEXT runtime·uint32tofloat64(SB),NOSPLIT,$8-12
FMOVDP F0, ret+4(FP)
RET
-TEXT runtime·float64touint32(SB),NOSPLIT,$12-12
- FMOVD a+0(FP), F0
- FSTCW 0(SP)
- FLDCW runtime·controlWord64trunc(SB)
- FMOVVP F0, 4(SP)
- FLDCW 0(SP)
- MOVL 4(SP), AX
- MOVL AX, ret+8(FP)
- RET
-
// gcWriteBarrier informs the GC about heap pointer writes.
//
// gcWriteBarrier returns space in a write barrier buffer which
diff --git a/src/runtime/stubs_386.go b/src/runtime/stubs_386.go
index a1dd023974..4f3dcd4fd9 100644
--- a/src/runtime/stubs_386.go
+++ b/src/runtime/stubs_386.go
@@ -6,7 +6,6 @@ package runtime
import "unsafe"
-func float64touint32(a float64) uint32
func uint32tofloat64(a uint32) float64
// stackcheck checks that SP is in range [g->stack.lo, g->stack.hi).
diff --git a/src/runtime/vlrt.go b/src/runtime/vlrt.go
index 4b12f593c8..511eb0dd4e 100644
--- a/src/runtime/vlrt.go
+++ b/src/runtime/vlrt.go
@@ -40,10 +40,17 @@ func float64toint64(d float64) (y uint64) {
}
func float64touint64(d float64) (y uint64) {
- _d2v(&y, d)
+ _d2vu(&y, d)
return
}
+func float64touint32(a float64) uint32 {
+ if a >= 0xffffffff {
+ return 0xffffffff
+ }
+ return uint32(float64touint64(a))
+}
+
func int64tofloat64(y int64) float64 {
if y < 0 {
return -uint64tofloat64(-uint64(y))
@@ -117,12 +124,16 @@ func _d2v(y *uint64, d float64) {
} else {
/* v = (hi||lo) << -sh */
sh := uint32(-sh)
- if sh <= 11 {
+ if sh <= 10 {
ylo = xlo << sh
yhi = xhi<<sh | xlo>>(32-sh)
} else {
- /* overflow */
- yhi = uint32(d) /* causes something awful */
+ if x&sign64 != 0 {
+ *y = 0x8000000000000000
+ } else {
+ *y = 0x7fffffffffffffff
+ }
+ return
}
}
if x&sign64 != 0 {
@@ -136,6 +147,50 @@ func _d2v(y *uint64, d float64) {
*y = uint64(yhi)<<32 | uint64(ylo)
}
+func _d2vu(y *uint64, d float64) {
+ x := *(*uint64)(unsafe.Pointer(&d))
+ if x&sign64 != 0 {
+ *y = 0
+ return
+ }
+
+ xhi := uint32(x>>32)&0xfffff | 0x100000
+ xlo := uint32(x)
+ sh := 1075 - int32(uint32(x>>52)&0x7ff)
+
+ var ylo, yhi uint32
+ if sh >= 0 {
+ sh := uint32(sh)
+ /* v = (hi||lo) >> sh */
+ if sh < 32 {
+ if sh == 0 {
+ ylo = xlo
+ yhi = xhi
+ } else {
+ ylo = xlo>>sh | xhi<<(32-sh)
+ yhi = xhi >> sh
+ }
+ } else {
+ if sh == 32 {
+ ylo = xhi
+ } else if sh < 64 {
+ ylo = xhi >> (sh - 32)
+ }
+ }
+ } else {
+ /* v = (hi||lo) << -sh */
+ sh := uint32(-sh)
+ if sh <= 11 {
+ ylo = xlo << sh
+ yhi = xhi<<sh | xlo>>(32-sh)
+ } else {
+ /* overflow */
+ *y = 0xffffffffffffffff
+ return
+ }
+ }
+ *y = uint64(yhi)<<32 | uint64(ylo)
+}
func uint64div(n, d uint64) uint64 {
// Check for 32 bit operands
if uint32(n>>32) == 0 && uint32(d>>32) == 0 {