mirror of
https://github.com/libretro/parallel-dc.git
synced 2026-11-07 12:37:53 -10:00
Linux i686, Windows i686 and Android x86 ran the sound processor through the interpreter: the old reicast recompiler's x86 backend is gone, and upstream flycast has none. They now run the recompiler x86-64 and ARM64 run - arm7_rec.cpp's decoder, blocks, cycle counts and register allocator - with a backend of its own, arm7_rec_x86.cpp, written with xbyak in 32-bit mode after arm7_rec_x64.cpp, instruction for instruction: - a block's cycles come off at its end, and the time slice is over at none left or less; each block jumps on to the next itself, through the address's entry point when it is fixed; - the flags stay in the ARM's register file; a logical instruction that sets them leaves V and takes the shifter's or the constant's carry; RSB and RSC take their carry from the subtraction; a shift by a register takes its low byte; - registers are written back before conditional code and around MSR, as the shared allocator does for every backend; - loads and stores to sound memory are done in line, the rest through the same calls; the program counter loses its low two bits wherever it is written. What differs is the processor: four host registers for the ARM's (ebx, ebp, esi, edi, which C code keeps), eax/ecx/edx for the rest - the operands in edx and eax, the carry in ecx, the values a shift by 32 or more gives taken from memory by cmov, RRX done with bt and rcr; data reached at its absolute address; every call fastcall (ecx, edx), as every handler called is DYNACALL, with the stack at a multiple of 16; four bytes to an entry point. The main loop is written into the code buffer as on x86-64, so the library has no text relocations. build.h turns the ARM7 recompiler on for 32-bit x86 (so the Makefile's i686 unix and win32 builds and jni/Android.mk's x86 have it, through Makefile.common), and the Sound CPU Recompiler core option with it, whose text now names 32-bit x86. tools/arm7/run.sh runs on i686 too (ARCH=i686 with the cross compiler in MAKEARGS). Tested here: - tools/arm7 on i686, 10000 programs (8844 compared) and 10000 with mode changes (8694 compared): the recompiler, the interpreter and switching between the two agree; what the recompiled programs leave is the same as on x86-64 and on AArch64 (qemu), line for line, in both sets - tools/threads/headless.sh passes on Linux i686, on Windows i686 under 32-bit wine, and on Linux x86-64 - tools/determinism, default options (the ARM7 recompiler on on both), Jet Grind Radio from a state, 1000 frames: i686 the same as x86-64 at every frame - Android x86 (NDK r27d) builds and links with no TEXTREL - speed, Linux i686, headless, Jet Grind Radio 1801 frames from a state, two runs each: 3.30-3.40 s with the recompiler, 4.21-4.29 s with the interpreter (about 540 against 425 frames a second) No save-state change. Blocks are compiled as before, when first reached; nothing is allocated or waited for while they run.