FEX-Emu / FEX-Emu/FEX

X87ReducedPrecision breaks FILD m64int -> FISTP m64int roundtrip

Open
#5,827 5 comments 0 reactions 0 assignees View on GitHub
Game related
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.