Project

General

Profile

Actions

Emulator Issues #12526

closed

Inconsistency between JIT and interpreter (both aarch64 and x64, at the very least on M1)

Added by pwootage over 3 years ago. Updated over 3 years ago.

Status:
Fixed
Priority:
Normal
Assignee:
-
% Done:

0%

Operating system:
N/A
Issue type:
Bug
Milestone:
Regression:
No
Relates to usability:
No
Relates to performance:
No
Easy:
No
Relates to maintainability:
No
Regression start:
Fixed in:
5.0-14350

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

prime-practice (1.69 MB) prime-practice pwootage, 05/27/2021 04:35 AM
Actions #1

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.

Actions #2

Updated by pwootage over 3 years ago

After doing some tracking down, it appears to be crXXX, specifically the "Special case: crclr"

Actions #3

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

Actions #5

Updated by pwootage over 3 years ago

I can confirm this fixes the bug I was seeing, both on x86_64 and aarch64.

Actions #6

Updated by JosJuice over 3 years ago

  • Status changed from New to Fixed
  • Fixed in set to 5.0-14350
Actions

Also available in: Atom PDF