-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PCSX2: Fix stall on branch .. in delay slot #1783
Conversation
Fixes stall when loading a stage in WRC 3. Removes patch that served as workaround.
That was quick! I assumed branches in the delay slot would be handled like the vu ones, which would be a pig to fix. Trying to think if there's any other games that do this too. Good job |
Apparently wrc really evolved and possibly midnight club 2 suffered from these too |
@FlatOutPS2 Do you know if this fixes enabling MTVU for Thrillville (you have the game right)? |
This won't fix games that break when hacks are enabled. The mtvu issue is completely separate |
May I ask how you came to this solution? Were you checking what the hack did? I guess there is no forum in the web where people discussed 'well, if you have a stall in branch … delay slot, just put these lines and the errors are gone…' and ps2 documentation also rather seems poor... |
PS2 documentation is poor and I'm not sure how the EE handles it. On the VU side, what happens is the VU will take the first branch, read the first instruction, then take the second branch (if it succeeded). Of course if the first branch wasn't taken, as long as it isn't a Likely branch (speaking from the EE side, the VU doesn't have likely's), it would take the second branch only. however it seems there is an exception for when there is a branch in the branch delay slot, so it's possible the EE does handle it completely differently and just hands it off to the exception manager to deal with. That said we aren't actually setting the BD bit, we're just clearing it? |
I would suggest to run the EE PS2 testsuite. Initial code got an infinite function call loop. |
Woho, an EE recompiler fix. Awesome! |
This looks interesting. Will test it thoroughly after my tournament ends in two days time. |
g_cpuFlushedPC = false; | ||
g_cpuFlushedCode = false; | ||
if (g_maySignalException) | ||
xAND(ptr32[&cpuRegs.CP0.n.Cause], ~(1 << 31)); // BD |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Yeah, doesn't make sense to me either. According to the sources, we only need to set BD when encountering exceptions other than the reset, NMI, performance counter and debug on the delay slot. I don't seem to find any information about clearing the bit at any cases. Also seems like @sudonim1 was the one who introduced it in d4bc1a6, so assigning this to him as he probably knows how this works. |
@ssakash here the theory
2nd load will generate a TLB miss. So you save the PC (here 0x404) in the EPC register. You execute the TLB miss handler. Then you return to the program with a Now imagine, that exception occurred in a delay slot.
Again the CPU will save the PC of the instruction that raise the exception. Here 0x408. Handler will be executed. And finally jump $EPC (reminder 0x408). So next instruction will be 0x40C and 0x410. As you can see you didn't resume the execution correctly (will print 1). An exception/interrupt must never change the program behavior. So instead you save $EPC + the BD flag. This way, you will jump back to $EPC-4 (so 0x404) so program will resume correctly (will print 0). There is 2 level of exceptions, hence BD/BD2. It is easier to handle in the CPU (and potentially it allow lvl2 exception in lvl1 exception). LVL2 exception must never happen in the emulation. Now remain to answer the behavior of what must happen if there is a branch in the delay slot case. I don't remember the exact behavior. Either 2nd jump is a NOP or final address is the one of the 2nd jump. Behavior can be checked with the testsuite.
BD will be cleared when you resume program execution (check ERET opcode). Potentially the behavior is equivalent to (for every cycle)
|
@FlatOutPS2 |
Thanks for the write up, really appreciated. :)
Agreed, I was also planning on mentioning it but forgot about it for some reasons. |
I think that commit of mine was just preparation for future work that has only kind of happened because at least at the time it was impossible for any recompiler instruction to raise an exception. |
Please add a common function. And note to self, I need to run the test suite. |
do you have the instructions around the branch in branch delay slot. From the HW testsuite:
So far we return 1 (even with this PR), and the HW 2. |
So basically branch in branch delay slot on real hardware works like you'd
expect. The delay slot is fetched/the first branch executed, the first
branch target fetched/the second branch executed, the first branch target
executed/the second branch target fetched, execution continues from the
second branch target.
…On 30 January 2017 at 17:51, Gregory Hainaut ***@***.***> wrote:
do you have the instructions around the branch in branch delay slot.
From the HW testsuite:
// This is technically not valid MIPS anyway.
// But it seems to always take target 2?
asm volatile (
".set noreorder\n"
"li $t0, 0\n"
"beq $t0, $t0, target1_%=\n"
"beq $t0, $t0, target2_%=\n"
"beq $t0, $t0, target3_%=\n"
"beq $t0, $t0, target4_%=\n"
"nop\n"
"target1_%=:\n"
"li %0, 1\n"
"j skip_%=\n"
"nop\n"
"target2_%=:\n"
"li %0, 2\n"
"j skip_%=\n"
"nop\n"
"target3_%=:\n"
"li %0, 3\n"
"j skip_%=\n"
"nop\n"
"target4_%=:\n"
"li %0, 4\n"
"j skip_%=\n"
"nop\n"
"skip_%=:\n"
: "+r"(result)
);
printf("beq: delay branch: %08x\n", result);
So far we return 1 (even with this PR), and the HW 2.
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#1783 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AGvnmTx9eTNemv7ve3kmBD6PB54M94_Nks5rXiMKgaJpZM4LnOF8>
.
|
@FlatOutPS2 could you create a generic function ? |
I already did, but I was still to look into some possibly related issues before updating the PR. I just haven't gotten around to it yet. |
Any status? |
I don't think this will be merged anytime soon. Flatout was in charge and well, he's gone for now. |
Apparently Midnight club games are fixed with this PR. |
They all work fine, not sure what you mean? |
Someone once said != actually true. I don't see any post on the forum about testing this PR with that game. |
No. The only other mentions of this issue are due to cheats/hacks. |
The only other game I know I mentioned earlier in the thread is WRC 4 i think it is |
WRC Evolved. ;) Though it should also affect WRC 4, but that has other issues not related to this PR. |
I tested this PR with a lot of games and I have 2 improvement: -Action replay MAX I think it's safe to merge as I did not notice any regression with it. |
@refractionpcsx2 , @ramapcsx2 what are your thoughts, what are we gonna do with this? |
If it works, merge it. Better than what we've got. however due tot he gamedb conflicts you might have to open a new PR |
@lightningterror I feel this bit shouldn't be lost. A comment could either link here, or summarize that there's still problems with the test suite. Edit: Link to that specific test: |
Fixes stall when loading a stage in WRC 3. Original pr #1783 Collaborator: lightningterror
Closing in favor of #2919 |
Fixes stall when loading a stage in WRC 3. Original pr #1783 Collaborator: lightningterror
Fixes stall when loading a stage in WRC 3. Original pr #1783 Collaborator: lightningterror
Fixes stall when loading a stage in WRC 3.
Removes patch that served as workaround.