Shadlix
I work on my fork of Shadlix, itself a Bloodborne-focused fork of shadPS4. My focus is its native AArch64 backend and runtime, translating x86-64 guest code for Apple Silicon.
From x86-64 guest to AArch64 host
PS4 binaries use x86-64 instructions. Shadlix lifts each block into an intermediate representation, then emits AArch64 code for Apple Silicon. Memory accesses and runtime calls still have to preserve guest behavior as they cross into the host process.
Memory, flags, and instruction semantics
Recent emitter work covers scalar integer-to-float conversions and shift rules, as well as memory operations with the x86 LOCK prefix. For ADD, SUB, INC, DEC, AND, OR, and XOR, a locked update must keep the read, operation, and write together under contention. Operand alignment determines whether it fits in one atomic container or needs the serialized boundary path.
Flag results must follow the guest operation and operand width too.
The runtime around translated code
The JIT also depends on the system around it: guest memory has to map correctly, host faults have to become guest behavior, and calls between translated code and native code have to respect both ABIs. I work on these boundaries alongside the instruction emitter.
Differential tests for the full state
ELF test cases compare the same guest instructions through the ARM64 JIT and Unicorn, including registers, flags, and memory. The locked-operation cases cover seven operations at 8-, 32-, and 64-bit widths, with aligned, unaligned, and boundary-straddling operands. For a fix, I also check that the regression fails when the old behavior is restored.