FEX 2509 Tagged

After last month’s enormous improvements, this release will look quite tame in comparison. Although we still did a bunch of work, so let’s dive in.

More JIT improvements

Not quite as striking, but we still did work on the JIT this last month as usual. As usual too many to go over individually so here’s a list.

  • Move Arm64EC EC entrypoint check to L1 branch target lookup
  • Fix 32-bit zero-extend semantics on CMPXCHG
  • Fix 16-bit operand ENTER/LEAVE instructions
  • Implement support for JMPF/CALLF/RETF with operating mode switch
    • Mode switch will still cause crashes until remaining implementation details are sorted
  • Optimize x87 FTW calculation
  • Fix IEEE 754 unordered comparison in x87
  • Various JIT execution time improvements to reduce stutters
  • Recheck TF flag after POPF instruction to ensure correct behaviour
  • Fix some OOB reads for specific float instructions
  • Always explore fallthrough conditional branches

Mono specific performance hacks for ARM64EC/WOW64

Mono’s JIT has consistently been a pain for us where it’s use of self-modifying code causes significant code invalidation and stutters due to how we interact with each other. When JITs get stacked in emulation it is almost always a bad time. We now detect Mono on Arm64EC/WOW64 and will do some very specific optimizations. I won’t go in to the details since it’s fairly complex, but when Mono is detected, we will end up having less stutter, more performance, and less likely to crash when TSO memory model emulation is disabled.

Disable 3DNow! by default on Wine WOW64 binary

We found out this month that Fallout: New Vegas will only render a black screen when 3DNow! is enabled. This is seemingly due to specific optimized code routines that the D3D9X support library uses for various things. We are currently assuming that this is due to how we implemented the 3DNow! reciprocal instructions, where they behave like the Geode implementation rather than “typical” AMD 3DNow! versions. This could mean that these games also render black screens on Geodes, but getting an OLPC XO-1 today to try the game seems a bit excessive. Instead we have built a Phenom system to ensure the game renders fine on a real Phenom and to confirm our suspicions. It renders fine on real hardware, so until we have a soft-float implementation of these instructions we won’t have complete proof but something to work towards.

Until then, we are going to disable 3DNow! in this configuration, which causes this d3d9x support library to use SSE2 codepaths instead; Resolving the black screen rendering in the process.

Fix BRK size calculation

When emulating a Linux application, we need to setup a small amount of memory higher in the address space for the “program break”. This is a bit of legacy memory allocation that tends to get used early in a program’s life-cycle and then everything ends up using mmap later. Our original size calculation for this was actually incorrect which was causing part of our ELF loading to overlap this range. Usually not a problem because it usually meant some overlap with a BSS segment of the ELF that was aligned to some larger page size and didn’t do any harm.

The bigger problem is that we could have inadvertently allowed 32-bit applications to allocate memory in to the low pages of 64-bit memory space which could result in emulation bugs. Additionally we were always reserving a full 8MB of virtual memory space, which while it isn’t a lot, there are late generation 32-bit games that run in to Virtual Address space exhaustion, so giving back as much of that 8MB as possible means they are less likely to OOM themselves.

It’s a little thing, but nice to see fixed.

Force WOW64 allocations outside of the 32-bit memory space

Turns out FEX was accidentally allocating some memory in the 32-bit address space when running in WOW64 Wine emulation mode. Oops! We have now fixed this which similar to the last point, means 32-bit games are less likely to OOM.

Updates to downstream FEX packages

We have news for users of the FEX packages included in certain Linux distributions:

Apple Silicon users running Fedora Asahi Remix (and others that use muvm) may have seen an issue where FEX failed to start after customizing its configuration. The issue was that our graphical FEXConfig tool overrode muvm’s internal RootFS setup, so we fixed the problem by no longer touching settings managed by the microVM. With the new FEX release, you can use FEXConfig like on any other distribution: To configure logging, to change TSO configuration, to enable library forwarding, and more.

Speaking of library forwarding: This feature provides significant speed-ups by omitting costly emulation and instead directly calling into native ARM64 libraries. Unfortunately only few distributions have so far been able to provide this feature in their FEX packages: Our Ubuntu PPA includes it out of the box, and Fedora users can install fex-emu-thunks from the official repositories. Joining these ranks this month is NixOS thanks to our nixpkgs pull request being merged. This support is somewhat preliminary since there are open questions around the unique approach to dynamic linking taken in Nix/NixOS, but nixpkgs community members are already looking into this problem. Hopefully it won’t be long until enjoyers of reproducible builds will have the same fluent experience as Fedora and Ubuntu users!


See the 2509 Release Notes or the detailed change log in Github.

Written on September 9, 2025