// R5900 branch helper! // Recompiles code for a branch test and/or skip, complete with delay slot // handling. Note, for "likely" branches use iDoBranchImm_Likely instead, which // handles delay slots differently. // Parameters: // jmpSkip - This parameter is the result of the appropriate J32 instruction // (usually JZ32 or JNZ32). void recDoBranchImm( u32* jmpSkip, bool isLikely ) { // All R5900 branches use this format: const u32 branchTo = ((s32)_Imm_ * 4) + pc; // First up is the Branch Taken Path : Save the recompiler's state, compile the // DelaySlot, and issue a BranchTest insertion. The state is reloaded below for // the "did not branch" path (maintains consts, register allocations, and other optimizations). SaveBranchState(); recompileNextInstruction(1); SetBranchImm(branchTo); // Jump target when the branch is *not* taken, skips the branchtest code // insertion above. x86SetJ32(jmpSkip); // if it's a likely branch then we'll need to skip the delay slot here, since // MIPS cancels the delay slot instruction when branches aren't taken. LoadBranchState(); if( !isLikely ) { pc -= 4; // instruction rewinder for delay slot, if non-likely. recompileNextInstruction(1); } SetBranchImm(pc); // start a new recompiled block. }
void recJ() { // SET_FPUSTATE; u32 newpc = (_Target_ << 2) + ( pc & 0xf0000000 ); recompileNextInstruction(1); if (EmuConfig.Gamefixes.GoemonTlbHack) SetBranchImm(vtlb_V2P(newpc)); else SetBranchImm(newpc); }
void recJAL() { u32 newpc = (_Target_ << 2) + ( pc & 0xf0000000 ); _deleteEEreg(31, 0); if(EE_CONST_PROP) { GPR_SET_CONST(31); g_cpuConstRegs[31].UL[0] = pc + 4; g_cpuConstRegs[31].UL[1] = 0; } else { xMOV(ptr32[&cpuRegs.GPR.r[31].UL[0]], pc + 4); xMOV(ptr32[&cpuRegs.GPR.r[31].UL[1]], 0); } recompileNextInstruction(1); if (EmuConfig.Gamefixes.GoemonTlbHack) SetBranchImm(vtlb_V2P(newpc)); else SetBranchImm(newpc); }