diff options
| author | David Chase <drchase@google.com> | 2025-09-30 16:27:32 -0400 |
|---|---|---|
| committer | David Chase <drchase@google.com> | 2025-10-09 08:23:30 -0700 |
| commit | 78d75b37992be01326b9bd2666195aaba9bf2ae2 (patch) | |
| tree | b63e9a0f0079973aadd9018cc21de898bd86d724 /src/runtime | |
| parent | 0e466a8d1d89e15e953c7d35bcd9e02d3c89f62b (diff) | |
| download | go-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.s | 10 | ||||
| -rw-r--r-- | src/runtime/stubs_386.go | 1 | ||||
| -rw-r--r-- | src/runtime/vlrt.go | 63 |
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 { |
