On 32-bit targets without SSE we use the X87 unit to do uint64_t -> f32/f64/f80 conversions by converting a 64-bit integer into 80-bit extended precision using FILD. This is a signed conversion so then we add a fixup that is either 0 or 2^64 based on whether the original number was negative. Then we round the result if the destination type is f32 or f64.
This should work correctly assuming the the PC field in X87's FPCW is set to 80-bit. The FILD is not subject to the PC field, but the fixup FADD is.
On Windows, the PC field defaults to 64-bit. So the fixup FADD will round to the double precision. This means if we're doing a conversion from uint64_t to fp32, we'll round after the fixup FADD and round again when we do the fst to round to f32.
Conversions to f64 should fine since we'll just round after the FADD and the final rounding operation won't do anything.
If someone actually cares about bit-precise f32 values on x87, this is probably not the most important issue... we can't even emit basic arithmetic correctly.
On 32-bit targets without SSE we use the X87 unit to do uint64_t -> f32/f64/f80 conversions by converting a 64-bit integer into 80-bit extended precision using FILD. This is a signed conversion so then we add a fixup that is either 0 or 2^64 based on whether the original number was negative. Then we round the result if the destination type is f32 or f64.
This should work correctly assuming the the PC field in X87's FPCW is set to 80-bit. The FILD is not subject to the PC field, but the fixup FADD is.
On Windows, the PC field defaults to 64-bit. So the fixup FADD will round to the double precision. This means if we're doing a conversion from uint64_t to fp32, we'll round after the fixup FADD and round again when we do the fst to round to f32.
Conversions to f64 should fine since we'll just round after the FADD and the final rounding operation won't do anything.