github FEX-Emu/FEX FEX-2505
FEX Release FEX-2505

latest releases: FEX-2607, FEX-2605, FEX-2604...
14 months ago

Read the blog post at FEX-Emu's Site!

Well look who it is, another month and we have another release. This time around we have a smattering of fixes all over the place, including boring
x87 quirks! Let's get in to it!

Fixes squashfs/erofs mounting with newer libfuse

Over the past couple of months we have gotten reports about erofs and squashfs rootfs mounting being broken. This was something that was seemingly
setup specific because there was trouble reproducing it on our end. This month we were finally able to reproduce the issue and track down what was
going on. It looks like in newer release of the FUSE library, they have changed how they wait on child processes to exit. Due to a weird interaction
with FEX launching and starting erofsfuse/squashfsfuse, it was breaking this behaviour. It was a trivial fix that just required someone to be able to
reproduce it!

Memory leak fixes around thread creation and teardown

This month we encountered a game that had a very peculiar behaviour. It is creating a VLC video
decoder object every tick in Unreal Engine. This VLC in turn creates six threads, and then the game tears it down. This usually isn't too bad but when
the game is doing it roughly 720 times a second then it spirals pretty quickly. This was apparently unnoticed by the original game developers because
thread creation is /relatively/ light on a real x86 system, but under FEX thread creation gets sticky due to opaque threading APIs and other
overheads.

We initially noticed this as a massive memory leak; Turns out this behaviour is really good at finding memory leaks in FEX's thread creation code.
After a couple days of bug squashing, we are no longer leaking memory on thread creation and teardown! This improve's FEX's memory usage in Steam and
other applications that spin up worker threads and shut them down commonly.

Sadly the Linux port of RUINER's in-game Bink videos are broken even on x86 devices, so it is recommended to use the Proton version because of that
which never had this problem anyway.

Fix a couple of syscalls

Recently there has been a new x86/x86-64 emulator for RISC-V devices that has been showing good progress. We have been
comparing notes with their developer about certain implementations and they found some bugs in our 32-bit syscall emulation! It's unknown if these
actually fix any games, but a bug is a bug and it's good to squash them even if we aren't directly affected today. Thanks to the developer for finding
these and fixing them!

Rewrite x87 transcendentals to use Cephes softfloat library directly

This one is fairly boring because it doesn't affect most people, but it has some interesting implications. Before this change FEX would use the
compiler provided long double type to emulate x87's transcendental operations. This includes atan2l, cosl, exp2l, log2l, sinl, and tanl, a very
small number of implementations. We originally implemented these transcendental operations in this way because we knew that glibc implements these
using 128-bit precision to match the precision that long double provides on AArch64 Linux. This is an okay assumption to make initially until we
start running in different environments. Turns out if you're running on a Musl system, then these transcendentals may only be implemented using 64-bit
precision, resulting in less precision than x87 needs. Or if you're running on a WIN32/Wine implementation, then long double is only defined to be
64-bit instead of 128-bit! There's a couple of other situations in which we can't control what the long double implementation will do.

In order to ensure consistency in FEX's emulation, we have now dropped usage of long double in the x87 transcendental operations and use the
Cephes softfloat library directly. This ensures that we are always operating at the full 128-bit precision that we
were previously expecting and unifies the results that we get. In the future we may even go down to the cephes 80-bit softloat library, but we first
need to ensure that it actually provides enough precision on their implementation. Which we might even get a small speed boost from!

Move Interpreter fallback ABI dispatchers to unified location

Speaking of x87, when we hit an instruction that we can't emulate directly in the JIT then we do "interpreter" fallbacks out to C code. This isn't
actually an interpreter but it is a legacy name for when we had an IR interpreter. Anyway, we were emitting a LOT of redundant ABI handling code
whenever we needed to leave the JIT for these handful of x87 operations. This code is doing roughly the same thing for every thread and every
operation, resulting in a ton of wasted memory and icache getting hammered. We are now instead emitting the ABI handlers once, and they get shared
between all the threads, this actually improves performance even though there is an additional jump to get out of the JIT. So hopefully some x87 games
get a minor performance improvement!

More multiblock improvements

"Multiblock" is a JIT technique that makes us be able to emit larger functions of code at any given moment. One of the problems that this can cause is
we do more analysis and code discovery which can hit invalid code. A bunch of little fixes have landed to make FEX more tolerant about hitting invalid
code and continuing to JIT things. This improvements the robustness of this feature so it is less likely to break a game!

Misc cleanups and fixes for WIN32/WINE

Not much to say here other than we are still hammering on our WINE arm64ec support. It's relatively stable at this point and these just keep improving
what's already working pretty well!

Raw Changes

FEX Release FEX-2505

  • Arm64

    • Mark several functions as internally linked (572a58e)
  • CodeEmitter

    • Fix clang-format (02f90fb)

    • Fixes misaligned function (94499ed)

    • ASIMDOps

      • Constrain Q and D register requirements with concept (e0e9f5a)
      • Support RADDHN{2}/RSUBHN{2} (68f8c24)
    • LoadStoreOps

      • Add Memory Copy and Memory Set category (0cbbd91)
    • LoadstoreOps

      • Add Load/store register (PAC) group (79e57c3)
    • ScalarOps

      • Add two more instruction categories (b4eb38e)
  • Emitter

    • Add missing ASIMD crypto operations (571a533)
  • FEXConfig

    • Fix layout issues on Qt 6.9 (c837108)
  • FEXCore

    • Fixes x87 reduced precision (f97cd24)

    • Reduce stack usage in CalculateNumberOfCPUs (5d385c5)

    • Allocator

      • Removes old workaround for kernel 4.17 (e3f8a81)
    • Emitter

      • Stop creating a vector on the heap (45b638f)
    • JIT

      • Switch over to new vl64pair for RIP reconstruction (4f2d2e6)
    • Softfloat

      • Wire up cephes math library for transcendental operations (dd8a1f0)
  • FEXServer

    • Fixes squashfs/erofs with newer fuse releases (40e0a71)
  • FHU

    • Add a non-block thread local ringbuffer (9dbbd44)
  • Frontend

    • Be more tolerant of bad instruction encodings (211bec6)
  • InstcountCI

    • Changes how code size is calculated (3f7ad04)
    • Ensure RIP of blocks is consistent (6069d05)
  • JIT

    • Move interpreter ABI handlers in to the dispatcher (00ff549)
    • Make code patching during (un-/)linking thread-safe (99114e1)
    • Align JITCodeTail to native alignment (6beb4b0)
    • Moves VPCMPESTRX handler to use vectors (23a8462)
    • Fix warning about unused variable (3da6fc3)
  • Linux

    • SMCTracking
      • Stop calling mprotect on a memory region times the number of threads (afcd93f)
  • LinuxEmulation

    • Copy the host persona on thread startup (3ea7c2b)
    • Fixes remaining memory leak on pthread teardown (4d02126)
  • LinuxSyscalls

    • Fixes a major stack memory leak (156b674)
    • Update signal mask at deferring time (8ff7497)
    • Fixes 32-bit llseek result (5b802d1)
  • NFC

    • FEXCore: Removes unused argument on CreateThread (1dff707)
  • OpcodeDispatcher

    • Mark NZCV as dirty when clobbering in FCOMIF64 (73593ad)
  • Scripts

    • InstCountCI
      • Restrict git-add to relevant JSON files only (9ba46e3)
  • Various

    • UBSAN fixes around unaligned accesses (8864637)
  • Windows

    • Misc cleanups and fixes (6680753)
  • X86Tables

    • Set FLAGS_BLOCK_END for more faulting ops (f912295)
  • Misc

    • (a6a203c)
    • Fix 32-bit fadvise64 (31e5f70)
    • Marshal freeram in sysinfo (794c80e)
    • Make shmdt reset the unmapped pages in the 32-bit allocator (cf5fcb2)
    • mprotect last page of CodeBuffer (e1d032b)
    • 80-bit cephes prep work (f99691b)
    • Link to mincore instead of kernelbase on ARM64EC (3c8bb53)
    • updated Dockerfile to reflect latest FEX-Emu releases (8cc23d0)
    • X87 state block reset (b7790e1)
    • Improve tracking of executable mappings (674f939)
    • ASIMD_Tests: Enable PMULL/PMULL2 tests (c42b185)
    • Enable -fno-strict-aliasing (6f5588f)
    • A couple of barrier and timing fixes. (572d6e0)
    • ASIMD_Tests: Re-enable tests disabled due to dissassembly bugs (d7df4be)
    • Add no-sanitize flags to UBSAN (f227722)
    • Fix cast in ValidateCode impl (7c0bc2d)
    • Cleanup info test files for 32bits (2919c32)
    • Cleanup compile warnings (f1d007c)
    • Add option to enable UBSAN (5235190)
    • Softfloat-3e: Add support for f128 (09e622d)
  • cephes

    • Rewrite to use softfloat-3e 128-bit (bc72239)

Don't miss a new FEX release

NewReleases is sending notifications on new releases.