Skip to content

Commit db26cec

Browse files
authored
Merge pull request #143 from nicolasnoble/redo-setlink-fix
Redo setlink fix.
2 parents 98dfd9c + a24af9a commit db26cec

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

src/core/r3000a.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,24 @@ typedef struct {
251251
#define _JumpTarget_ ((_Target_ * 4) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction
252252
#define _BranchTarget_ ((int16_t)_Im_ * 4 + _PC_) // Calculates the target during a branch instruction
253253

254-
#define _SetLink(x) \
255-
PCSX::g_emulator.m_psxCpu->m_psxRegs.GPR.r[x] = _PC_ + 4 // Sets the return address in the link register
254+
/*
255+
The "SetLink" mechanism uses the delay slot. This may sound counter intuitive, but this is the only way to
256+
properly handle this specific sequence of instructions:
257+
258+
beq someFalseCondition, out
259+
lw $ra, someOffset($sp)
260+
jal someFunction
261+
nop
262+
[...]
263+
out:
264+
jr $ra
265+
nop
266+
267+
Without the change, the lw $ra will apply itself after jal happens, thus overriding the value the jal will
268+
have loaded into this register. This probably means this is also how the real CPU handles this, otherwise,
269+
this wouldn't work at all.
270+
*/
271+
#define _SetLink(x) delayedLoad(x, _PC_ + 4); // Sets the return address in the link register
256272

257273
class R3000Acpu {
258274
public:

0 commit comments

Comments
 (0)