示例#1
0
// 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.
}
示例#2
0
void recJ()
{
	// SET_FPUSTATE;
	u32 newpc = (_Target_ << 2) + ( pc & 0xf0000000 );
	recompileNextInstruction(1);
	if (EmuConfig.Gamefixes.GoemonTlbHack)
		SetBranchImm(vtlb_V2P(newpc));
	else
		SetBranchImm(newpc);
}
示例#3
0
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);
}