X87ReducedPrecision breaks FILD m64int -> FISTP m64int roundtrip
- Dominant language
- C++
- Stars
- 8k
- Forks
- 351
- Avg merge
- 12h 31m
- Merged PRs (30d)
- 102
Description
**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**
```asm
.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 $0x80
```
Build:
```sh
as --32 x87copy.s -o x87copy.o
ld -m elf_i386 x87copy.o -o x87copy
```
Run without reduced precision:
```sh
FEX_X87REDUCEDPRECISION=0 ./x87copy
echo $?
```
Result:
```text
0
```
Run with reduced precision:
```sh
FEX_X87REDUCEDPRECISION=1 ./x87copy
echo $?
```
Result:
```text
1
```
The original installer contains copy helpers like this:
```asm
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
Contributor guide
Research direction
Start with the x87copy.s 32-bit reproducer and run it with FEX_X87REDUCEDPRECISION=0 and 1 to confirm the differing exit codes. Trace handling of the FILD m64int and FISTP m64int sequence under X87ReducedPrecision. Done means the reproducer exits 0 with reduced precision enabled and preserves the original 64-bit value.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, linux
- Domain
- backend, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100