X87ReducedPrecision breaks FILD m64int -> FISTP m64int roundtrip
What Game The Witcher 3: Wild Hunt (classic version)
The issue itself is not game-specific though. I reduced it to a tiny 32bit reproducer below.
Describe the bug
X87ReducedPrecision breaks a valid FILD m64int -> FISTP m64int conversion.
I originally hit this in setup_redlauncher.exe. The installer contains copy helpers that use x87 FILD+FISTP to move 64bit data.
With X87ReducedPrecision=1, strings copied through these helpers get corrupted and the installer fails with Path not found.
The issue also reproduces without Wine or Proton.
To Reproduce
.section .data
src:
.quad 0x0068005c003a005a
dst:
.quad 0
.section .text
.global _start
_start:
fildq src
fistpq dst
movl src, %eax
cmpl dst, %eax
jne bad
movl src+4, %eax
cmpl dst+4, %eax
jne bad
movl $1, %eax
xorl %ebx, %ebx
int $0x80
bad:
movl $1, %eax
movl $1, %ebx
int $0x80Build:
as --32 x87copy.s -o x87copy.o
ld -m elf_i386 x87copy.o -o x87copyRun without reduced precision:
FEX_X87REDUCEDPRECISION=0 ./x87copy
echo $?Result:
0Run with reduced precision:
FEX_X87REDUCEDPRECISION=1 ./x87copy
echo $?Result:
1The original installer contains copy helpers like this:
fild QWORD PTR [eax]
fild QWORD PTR [eax+0x8]
fild QWORD PTR [eax+0x10]
fild QWORD PTR [eax+0x18]
...
fistp QWORD PTR [edx+0x18]
fistp QWORD PTR [edx+0x10]
fistp QWORD PTR [edx+0x8]
fistp QWORD PTR [edx]So x87 is effectively being used to copy 8-byte chunks.
Expected behavior
FILD m64int followed by FISTP m64int, with no arithmetic in between, should preserve the original 64bit integer value.
I'm not sure whether this is considered expected behavior though.
System information:
- OS: Debian arm64 guest
- CPU/SoC: Apple M3 Pro
- Video driver version: N/A
- RootFS used: Ubuntu 24.04 FEX RootFS
- FEX version:
FEX-2604-226-g99662b7 - Thunks Enabled: Yes
Additional context
- Is this an x86 or x86-64 game: x86
- Does this reproduce on AArch64 with Radeon/Intel/Nvidia: Untested
- Is this a Vulkan game: No
Source: FEX-Emu/FEX