Emulator Issues #12526
closedInconsistency between JIT and interpreter (both aarch64 and x64, at the very least on M1)
0%
Description
Game Name?
Non-game-specific (discovered in development version of Metroid Prime's "Practice Mod")
Game ID? (right click the game in the game list, Properties, Info tab)
N/A (GM8E01)
MD5 Hash? (right click the game in the game list, Properties, Verify tab, Verify Integrity button)
N/A
What's the problem? Describe what went wrong.
It appears that there is an inconsistency between the JIT and interpreter in Prime. It seems like it's probably a bug in the JIT, in this case.
The following two blocks of code function differently:
// This crashes, but only in a JIT. Does not crash in interpreter.
CrashAssert((!g.Initialized && !g.SettingsLoaded), "_file_name_", 4136);
// This passes in both JIT and interpreter
CrashAssert((!g.Initialized), "_file_name_", 4138);
CrashAssert((!g.SettingsLoaded), "_file_name_", 4139);
The symbolicated binary from the practice mod is attached; should be loaded at 807c1a78 in production. The code in question begins at 807c37a0 when loaded, or 0x1D28 in the file pre-relocation. A disassembly can be found below.
I have tried to step through to see which instruction it fails on, but it seems to jump right over my breakpoint with JIT enabled.
What steps will reproduce the problem?
Unfortunately I haven't yet figured out how to reproduce it other than to run the development version of the practice mod, which I can't currently provide in a way that can be run outside of the development environment, due to it involving a modified boot.dol, which I can't legally redistribute. I can probably help somebody run the current version of the script which modifies the boot.dol to load the Mod.rel which I can redistribute.
Is the issue present in the latest development version? For future reference, please also write down the version number of the latest development version.
Tested in 14302, the latest development version at time this was written. Both aarch64 and x64 thru Rosetta on an M1 macbook are affected.
Is the issue present in the latest stable version?
aarch64 M1 is not present in stable. Dolphin stable does not support the way I run this in development so it's hard to say.
If the issue isn't present in the latest stable version, which is the first broken version?
Appears to be broken in all builds after M1 support was added. Appears to happen in x64 builds at least as old as 13178, 5 months ago. This is the oldest build I have that seems to function.
If your issue is a graphical issue, please attach screenshots and record a three frame fifolog of the issue if possible.
N/A
What are your PC specifications? (CPU, GPU, Operating System, more)
M1 Macbook Pro
Is there anything else that can help developers narrow down the issue? (e.g. logs, screenshots,
configuration files, savefiles, savestates)
I have attached the binary, in ELF format prior to being converted to .rel, and here is a partial disassembly of the code that seems to be failing:
807c37a0 7c 08 02 a6 mfspr r0,LR
807c37a4 90 01 00 04 stw r0,local_res4(r1)
807c37a8 94 21 ff b0 stwu r1,local_50(r1)
807c37ac 93 e1 00 4c stw r31,local_4(r1)
807c37b0 7c 3f 0b 78 or r31,r1,r1
807c37b4 93 bf 00 44 stw r29,local_c(r31)
807c37b8 93 df 00 48 stw r30,local_8(r31)
807c37bc 90 7f 00 40 stw context,local_10(r31)
807c37c0 80 7f 00 40 lwz context,local_10(r31)
807c37c4 90 7f 00 3c stw context,local_14(r31)
807c37c8 80 7f 00 3c lwz context,local_14(r31)
807c37cc 88 63 00 00 lbz context,context->Initialized(r3)
807c37d0 70 63 00 01 andi. context,context,0x1
807c37d4 4c 42 11 82 crxor eq,eq,eq
807c37d8 41 81 00 18 bgt LAB_807c37f0
807c37dc 48 00 00 04 b LAB_807c37e0
LAB_807c37e0 XREF[1]: 807c37dc(j)
807c37e0 80 7f 00 3c lwz context,local_14(r31)
807c37e4 88 63 2e 9d lbz context,context->SettingsLoaded(r3)
807c37e8 70 63 00 01 andi. context,context,0x1
807c37ec 48 00 00 04 b LAB_807c37f0
LAB_807c37f0 XREF[2]: 807c37d8(j), 807c37ec(j)
807c37f0 38 60 00 00 li context,0x0
807c37f4 3b a0 00 01 li r29,0x1
807c37f8 41 82 00 08 beq LAB_807c3800
807c37fc 48 00 00 08 b LAB_807c3804
LAB_807c3800 XREF[1]: 807c37f8(j)
807c3800 38 7d 00 00 addi context,r29,0x0
LAB_807c3804 XREF[1]: 807c37fc(j)
807c3804 3c 80 80 7d lis r4,-0x7f83
807c3808 3b c4 d6 9e subi r30,r4,0x2962
807c380c 7f c4 f3 78 or r4=>s_/Users/pwootage/projects/prime-p_807cd69 = "/Users/pwootage/projects/prim
807c3810 38 a0 10 28 li r5,0x1028
807c3814 48 00 44 a5 bl CrashAssert void CrashAssert(bool v, char *
807c3818 80 7f 00 3c lwz context,local_14(r31)
807c381c 88 63 00 00 lbz context,context->Initialized(r3)
807c3820 7c 63 18 f8 nor context,context,context
807c3824 54 63 07 fe rlwinm context,context,0x0,0x1f,0x1f
807c3828 7f c4 f3 78 or r4=>s_/Users/pwootage/projects/prime-p_807cd69 = "/Users/pwootage/projects/prim
807c382c 38 a0 10 2a li r5,0x102a
807c3830 48 00 44 89 bl CrashAssert void CrashAssert(bool v, char *
807c3834 80 7f 00 3c lwz context,local_14(r31)
807c3838 88 63 2e 9d lbz context,context->SettingsLoaded(r3)
807c383c 7c 63 18 f8 nor context,context,context
807c3840 54 63 07 fe rlwinm context,context,0x0,0x1f,0x1f
807c3844 7f c4 f3 78 or r4=>s_/Users/pwootage/projects/prime-p_807cd69 = "/Users/pwootage/projects/prim
807c3848 38 a0 10 2b li r5,0x102b
807c384c 48 00 44 6d bl CrashAssert void CrashAssert(bool v, char *
Files
Updated by JosJuice over 3 years ago
A good next step would be to check which instruction is broken by selectively making instructions fall back to the interpreter. To begin, use the Debug menu in Dolphin (available when the debugger is enabled) to disable entire categories of instructions ("JIT Integer Off", "JIT Branch Off", and so on). Then when you know which category the broken instruction is in, the next step (if you're able to build Dolphin - if not, let me know) is go to the source file that implements those instructions (for instance Jit_Integer.cpp for the integer instructions) and try adding the line FALLBACK_IF(true); at the top of the different instructions. This should let you pinpoint which instruction is broken... unless the problem isn't with a particular instruction, in which case you may or may not find that falling back one or more instructions makes the program run correctly.
Updated by pwootage over 3 years ago
After doing some tracking down, it appears to be crXXX, specifically the "Special case: crclr"
Updated by pwootage over 3 years ago
By process of elimination:
This instruction:
4c 42 11 82
Ghidra:
crxor eq,eq,eq
or as dolphin disassembles it:
crclr 2, 2
Updated by JosJuice over 3 years ago
Please try this patch: https://github.com/dolphin-emu/dolphin/pull/9770
Updated by pwootage over 3 years ago
I can confirm this fixes the bug I was seeing, both on x86_64 and aarch64.
Updated by JosJuice over 3 years ago
- Status changed from New to Fixed
- Fixed in set to 5.0-14350