mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #459 from unknownbrackets/jit-branch
Jit branch debugging
This commit is contained in:
commit
65203f3833
6 changed files with 147 additions and 44 deletions
|
@ -113,10 +113,10 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx .....
|
|||
ENCODING(Cop2), //cop2
|
||||
INVALID, //copU
|
||||
|
||||
INSTR("beql", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT), //L = likely
|
||||
INSTR("bnel", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT),
|
||||
INSTR("blezl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT),
|
||||
INSTR("bgtzl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT),
|
||||
INSTR("beql", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY), //L = likely
|
||||
INSTR("bnel", &Jit::Comp_RelBranch, Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_RS|IN_RT|DELAYSLOT|LIKELY),
|
||||
INSTR("blezl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY),
|
||||
INSTR("bgtzl", &Jit::Comp_RelBranch, Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY),
|
||||
//24
|
||||
{VFPU0},
|
||||
{VFPU1},
|
||||
|
@ -178,8 +178,8 @@ const MIPSInstruction tableSpecial[64] = /// 000000 ...... ...... .......... xxx
|
|||
INSTR("srav", &Jit::Comp_ShiftType, Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),
|
||||
|
||||
//8
|
||||
INSTR("jr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType,0),
|
||||
INSTR("jalr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType,0),
|
||||
INSTR("jr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, DELAYSLOT),
|
||||
INSTR("jalr", &Jit::Comp_JumpReg, Dis_JumpRegType, Int_JumpRegType, DELAYSLOT),
|
||||
INSTR("movz", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT),
|
||||
INSTR("movn", &Jit::Comp_RType3, Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT),
|
||||
INSTR("syscall", &Jit::Comp_Syscall, Dis_Syscall, Int_Syscall,0),
|
||||
|
@ -327,10 +327,10 @@ const MIPSInstruction tableSpecial3[64] =
|
|||
|
||||
const MIPSInstruction tableRegImm[32] =
|
||||
{
|
||||
INSTR("bltz", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS),
|
||||
INSTR("bgez", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS),
|
||||
INSTR("bltzl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS),
|
||||
INSTR("bgezl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS),
|
||||
INSTR("bltz", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT),
|
||||
INSTR("bgez", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT),
|
||||
INSTR("bltzl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY),
|
||||
INSTR("bgezl", &Jit::Comp_RelBranchRI, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|DELAYSLOT|LIKELY),
|
||||
{-2},
|
||||
{-2},
|
||||
{-2},
|
||||
|
@ -345,10 +345,10 @@ const MIPSInstruction tableRegImm[32] =
|
|||
INSTR("tnei", &Jit::Comp_Generic, Dis_Generic, 0, 0),
|
||||
{-2},
|
||||
|
||||
INSTR("bltzal", &Jit::Comp_Generic, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA),
|
||||
INSTR("bgezal", &Jit::Comp_Generic, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA),
|
||||
INSTR("bltzall", &Jit::Comp_Generic, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA), //L = likely
|
||||
INSTR("bgezall", &Jit::Comp_Generic, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA),
|
||||
INSTR("bltzal", &Jit::Comp_Generic, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT),
|
||||
INSTR("bgezal", &Jit::Comp_Generic, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT),
|
||||
INSTR("bltzall", &Jit::Comp_Generic, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY), //L = likely
|
||||
INSTR("bgezall", &Jit::Comp_Generic, Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_RS|OUT_RA|DELAYSLOT|LIKELY),
|
||||
{-2},
|
||||
{-2},
|
||||
{-2},
|
||||
|
@ -384,10 +384,10 @@ const MIPSInstruction tableCop2[32] =
|
|||
|
||||
const MIPSInstruction tableCop2BC2[4] =
|
||||
{
|
||||
INSTR("bvf", &Jit::Comp_VBranch, Dis_VBranch,Int_VBranch,IS_CONDBRANCH),
|
||||
INSTR("bvt", &Jit::Comp_VBranch, Dis_VBranch,Int_VBranch,IS_CONDBRANCH),
|
||||
INSTR("bvfl", &Jit::Comp_VBranch, Dis_VBranch,Int_VBranch,IS_CONDBRANCH),
|
||||
INSTR("bvtl", &Jit::Comp_VBranch, Dis_VBranch,Int_VBranch,IS_CONDBRANCH),
|
||||
INSTR("bvf", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|DELAYSLOT),
|
||||
INSTR("bvt", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|DELAYSLOT),
|
||||
INSTR("bvfl", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|DELAYSLOT|LIKELY),
|
||||
INSTR("bvtl", &Jit::Comp_VBranch, Dis_VBranch, Int_VBranch, IS_CONDBRANCH|DELAYSLOT|LIKELY),
|
||||
};
|
||||
|
||||
const MIPSInstruction tableCop0[32] =
|
||||
|
@ -467,10 +467,10 @@ const MIPSInstruction tableCop1[32] =
|
|||
|
||||
const MIPSInstruction tableCop1BC[32] =
|
||||
{
|
||||
{-1,"bc1f", &Jit::Comp_FPUBranch, Dis_FPUBranch, Int_FPUBranch,IS_CONDBRANCH|IN_FPUFLAG},
|
||||
{-1,"bc1t", &Jit::Comp_FPUBranch, Dis_FPUBranch, Int_FPUBranch,IS_CONDBRANCH|IN_FPUFLAG},
|
||||
{-1,"bc1fl", &Jit::Comp_FPUBranch, Dis_FPUBranch, Int_FPUBranch,IS_CONDBRANCH|IN_FPUFLAG},
|
||||
{-1,"bc1tl", &Jit::Comp_FPUBranch, Dis_FPUBranch, Int_FPUBranch,IS_CONDBRANCH|IN_FPUFLAG},
|
||||
{-1,"bc1f", &Jit::Comp_FPUBranch, Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_FPUFLAG|DELAYSLOT},
|
||||
{-1,"bc1t", &Jit::Comp_FPUBranch, Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_FPUFLAG|DELAYSLOT},
|
||||
{-1,"bc1fl", &Jit::Comp_FPUBranch, Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_FPUFLAG|DELAYSLOT|LIKELY},
|
||||
{-1,"bc1tl", &Jit::Comp_FPUBranch, Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_FPUFLAG|DELAYSLOT|LIKELY},
|
||||
{-2},{-2},{-2},{-2},
|
||||
{-2},{-2},{-2},{-2},{-2},{-2},{-2},{-2},
|
||||
{-2},{-2},{-2},{-2},{-2},{-2},{-2},{-2},
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define IS_CONDBRANCH 0x100
|
||||
#define IS_JUMP 0x200
|
||||
#define IS_VFPU 0x80000000
|
||||
#define LIKELY 0x80
|
||||
#define UNCONDITIONAL 0x40
|
||||
#define BAD_INSTRUCTION 0x20
|
||||
#define DELAYSLOT 0x10
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "../../HLE/HLE.h"
|
||||
#include "../../Host.h"
|
||||
|
||||
#include "../MIPS.h"
|
||||
#include "../MIPSCodeUtils.h"
|
||||
|
@ -42,11 +43,86 @@ using namespace MIPSAnalyst;
|
|||
// NOTE: Can't use CONDITIONAL_DISABLE in this file, branches are so special
|
||||
// that they cannot be interpreted in the context of the Jit.
|
||||
|
||||
// But we can at least log and compare.
|
||||
// #define DO_CONDITIONAL_LOG 1
|
||||
#define DO_CONDITIONAL_LOG 0
|
||||
|
||||
#if DO_CONDITIONAL_LOG
|
||||
#define CONDITIONAL_LOG BranchLog(op);
|
||||
#define CONDITIONAL_LOG_EXIT(addr) BranchLogExit(op, addr, false);
|
||||
#define CONDITIONAL_LOG_EXIT_EAX() BranchLogExit(op, 0, true);
|
||||
#else
|
||||
#define CONDITIONAL_LOG ;
|
||||
#define CONDITIONAL_LOG_EXIT(addr) ;
|
||||
#define CONDITIONAL_LOG_EXIT_EAX() ;
|
||||
#endif
|
||||
|
||||
namespace MIPSComp
|
||||
{
|
||||
|
||||
static u32 intBranchExit;
|
||||
static u32 jitBranchExit;
|
||||
|
||||
static void JitBranchLog(u32 op, u32 pc)
|
||||
{
|
||||
currentMIPS->pc = pc;
|
||||
currentMIPS->inDelaySlot = false;
|
||||
|
||||
MIPSInterpretFunc func = MIPSGetInterpretFunc(op);
|
||||
u32 info = MIPSGetInfo(op);
|
||||
func(op);
|
||||
|
||||
// Branch taken, use nextPC.
|
||||
if (currentMIPS->inDelaySlot)
|
||||
intBranchExit = currentMIPS->nextPC;
|
||||
else
|
||||
{
|
||||
// Branch not taken, likely delay slot skipped.
|
||||
if (info & LIKELY)
|
||||
intBranchExit = currentMIPS->pc;
|
||||
// Branch not taken, so increment over delay slot.
|
||||
else
|
||||
intBranchExit = currentMIPS->pc + 4;
|
||||
}
|
||||
|
||||
currentMIPS->pc = pc;
|
||||
currentMIPS->inDelaySlot = false;
|
||||
}
|
||||
|
||||
static void JitBranchLogMismatch(u32 op, u32 pc)
|
||||
{
|
||||
char temp[256];
|
||||
MIPSDisAsm(op, pc, temp, true);
|
||||
ERROR_LOG(JIT, "Bad jump: %s - int:%08x jit:%08x", temp, intBranchExit, jitBranchExit);
|
||||
Core_EnableStepping(true);
|
||||
host->SetDebugMode(true);
|
||||
}
|
||||
|
||||
void Jit::BranchLog(u32 op)
|
||||
{
|
||||
FlushAll();
|
||||
ABI_CallFunctionCC(thunks.ProtectFunction((void *) &JitBranchLog, 2), op, js.compilerPC);
|
||||
}
|
||||
|
||||
void Jit::BranchLogExit(u32 op, u32 dest, bool useEAX)
|
||||
{
|
||||
OpArg destArg = useEAX ? R(EAX) : Imm32(dest);
|
||||
|
||||
CMP(32, M((void *) &intBranchExit), destArg);
|
||||
FixupBranch skip = J_CC(CC_E);
|
||||
|
||||
MOV(32, M((void *) &jitBranchExit), destArg);
|
||||
ABI_CallFunctionCC(thunks.ProtectFunction((void *) &JitBranchLogMismatch, 2), op, js.compilerPC);
|
||||
// Restore EAX, we probably ruined it.
|
||||
if (useEAX)
|
||||
MOV(32, R(EAX), M((void *) &jitBranchExit));
|
||||
|
||||
SetJumpTarget(skip);
|
||||
}
|
||||
|
||||
void Jit::BranchRSRTComp(u32 op, Gen::CCFlags cc, bool likely)
|
||||
{
|
||||
CONDITIONAL_LOG;
|
||||
if (js.inDelaySlot) {
|
||||
ERROR_LOG(JIT, "Branch in delay slot at %08x", js.compilerPC);
|
||||
return;
|
||||
|
@ -82,29 +158,31 @@ void Jit::BranchRSRTComp(u32 op, Gen::CCFlags cc, bool likely)
|
|||
Gen::FixupBranch ptr;
|
||||
if (!likely)
|
||||
{
|
||||
CompileDelaySlot(js.compilerPC + 4, !delaySlotIsNice);
|
||||
CompileDelaySlot(!delaySlotIsNice);
|
||||
ptr = J_CC(cc, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = J_CC(cc, true);
|
||||
CompileAt(js.compilerPC + 4);
|
||||
FlushAll();
|
||||
CompileDelaySlot(false);
|
||||
}
|
||||
js.inDelaySlot = false;
|
||||
|
||||
// Take the branch
|
||||
CONDITIONAL_LOG_EXIT(targetAddr);
|
||||
WriteExit(targetAddr, 0);
|
||||
|
||||
SetJumpTarget(ptr);
|
||||
// Not taken
|
||||
WriteExit(js.compilerPC+8, 1);
|
||||
CONDITIONAL_LOG_EXIT(js.compilerPC + 8);
|
||||
WriteExit(js.compilerPC + 8, 1);
|
||||
|
||||
js.compiling = false;
|
||||
}
|
||||
|
||||
void Jit::BranchRSZeroComp(u32 op, Gen::CCFlags cc, bool likely)
|
||||
{
|
||||
CONDITIONAL_LOG;
|
||||
if (js.inDelaySlot) {
|
||||
ERROR_LOG(JIT, "Branch in delay slot at %08x", js.compilerPC);
|
||||
return;
|
||||
|
@ -130,23 +208,25 @@ void Jit::BranchRSZeroComp(u32 op, Gen::CCFlags cc, bool likely)
|
|||
js.inDelaySlot = true;
|
||||
if (!likely)
|
||||
{
|
||||
CompileDelaySlot(js.compilerPC + 4, !delaySlotIsNice);
|
||||
CompileDelaySlot(!delaySlotIsNice);
|
||||
ptr = J_CC(cc, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = J_CC(cc, true);
|
||||
CompileAt(js.compilerPC + 4);
|
||||
FlushAll();
|
||||
CompileDelaySlot(false);
|
||||
}
|
||||
js.inDelaySlot = false;
|
||||
|
||||
// Take the branch
|
||||
CONDITIONAL_LOG_EXIT(targetAddr);
|
||||
WriteExit(targetAddr, 0);
|
||||
|
||||
SetJumpTarget(ptr);
|
||||
// Not taken
|
||||
CONDITIONAL_LOG_EXIT(js.compilerPC + 8);
|
||||
WriteExit(js.compilerPC + 8, 1);
|
||||
|
||||
js.compiling = false;
|
||||
}
|
||||
|
||||
|
@ -193,6 +273,7 @@ void Jit::Comp_RelBranchRI(u32 op)
|
|||
// If likely is set, discard the branch slot if NOT taken.
|
||||
void Jit::BranchFPFlag(u32 op, Gen::CCFlags cc, bool likely)
|
||||
{
|
||||
CONDITIONAL_LOG;
|
||||
if (js.inDelaySlot) {
|
||||
ERROR_LOG(JIT, "Branch in delay slot at %08x", js.compilerPC);
|
||||
return;
|
||||
|
@ -217,22 +298,23 @@ void Jit::BranchFPFlag(u32 op, Gen::CCFlags cc, bool likely)
|
|||
js.inDelaySlot = true;
|
||||
if (!likely)
|
||||
{
|
||||
CompileDelaySlot(js.compilerPC + 4, !delaySlotIsNice);
|
||||
CompileDelaySlot(!delaySlotIsNice);
|
||||
ptr = J_CC(cc, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = J_CC(cc, true);
|
||||
CompileAt(js.compilerPC + 4);
|
||||
FlushAll();
|
||||
CompileDelaySlot(false);
|
||||
}
|
||||
js.inDelaySlot = false;
|
||||
|
||||
// Take the branch
|
||||
CONDITIONAL_LOG_EXIT(targetAddr);
|
||||
WriteExit(targetAddr, 0);
|
||||
|
||||
SetJumpTarget(ptr);
|
||||
// Not taken
|
||||
CONDITIONAL_LOG_EXIT(js.compilerPC + 8);
|
||||
WriteExit(js.compilerPC + 8, 1);
|
||||
|
||||
js.compiling = false;
|
||||
|
@ -257,6 +339,7 @@ void Jit::Comp_FPUBranch(u32 op)
|
|||
// If likely is set, discard the branch slot if NOT taken.
|
||||
void Jit::BranchVFPUFlag(u32 op, Gen::CCFlags cc, bool likely)
|
||||
{
|
||||
CONDITIONAL_LOG;
|
||||
if (js.inDelaySlot) {
|
||||
ERROR_LOG(JIT, "Branch in delay slot at %08x", js.compilerPC);
|
||||
return;
|
||||
|
@ -285,22 +368,23 @@ void Jit::BranchVFPUFlag(u32 op, Gen::CCFlags cc, bool likely)
|
|||
js.inDelaySlot = true;
|
||||
if (!likely)
|
||||
{
|
||||
CompileDelaySlot(js.compilerPC + 4, !delaySlotIsNice);
|
||||
CompileDelaySlot(!delaySlotIsNice);
|
||||
ptr = J_CC(cc, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = J_CC(cc, true);
|
||||
CompileAt(js.compilerPC + 4);
|
||||
FlushAll();
|
||||
CompileDelaySlot(false);
|
||||
}
|
||||
js.inDelaySlot = false;
|
||||
|
||||
// Take the branch
|
||||
CONDITIONAL_LOG_EXIT(targetAddr);
|
||||
WriteExit(targetAddr, 0);
|
||||
|
||||
SetJumpTarget(ptr);
|
||||
// Not taken
|
||||
CONDITIONAL_LOG_EXIT(js.compilerPC + 8);
|
||||
WriteExit(js.compilerPC + 8, 1);
|
||||
|
||||
js.compiling = false;
|
||||
|
@ -324,23 +408,25 @@ void Jit::Comp_VBranch(u32 op)
|
|||
|
||||
void Jit::Comp_Jump(u32 op)
|
||||
{
|
||||
CONDITIONAL_LOG;
|
||||
if (js.inDelaySlot) {
|
||||
ERROR_LOG(JIT, "Branch in delay slot at %08x", js.compilerPC);
|
||||
return;
|
||||
}
|
||||
u32 off = ((op & 0x3FFFFFF) << 2);
|
||||
u32 targetAddr = (js.compilerPC & 0xF0000000) | off;
|
||||
CompileAt(js.compilerPC + 4);
|
||||
FlushAll();
|
||||
CompileDelaySlot(false);
|
||||
|
||||
switch (op >> 26)
|
||||
{
|
||||
case 2: //j
|
||||
CONDITIONAL_LOG_EXIT(targetAddr);
|
||||
WriteExit(targetAddr, 0);
|
||||
break;
|
||||
|
||||
case 3: //jal
|
||||
MOV(32, M(&mips_->r[MIPS_REG_RA]), Imm32(js.compilerPC + 8)); // Save return address
|
||||
CONDITIONAL_LOG_EXIT(targetAddr);
|
||||
WriteExit(targetAddr, 0);
|
||||
break;
|
||||
|
||||
|
@ -355,6 +441,7 @@ static u32 savedPC;
|
|||
|
||||
void Jit::Comp_JumpReg(u32 op)
|
||||
{
|
||||
CONDITIONAL_LOG;
|
||||
if (js.inDelaySlot) {
|
||||
ERROR_LOG(JIT, "Branch in delay slot at %08x", js.compilerPC);
|
||||
return;
|
||||
|
@ -378,8 +465,7 @@ void Jit::Comp_JumpReg(u32 op)
|
|||
gpr.BindToRegister(rs, true, false);
|
||||
MOV(32, M(¤tMIPS->pc), gpr.R(rs)); // for syscalls in delay slot - could be avoided
|
||||
MOV(32, M(&savedPC), gpr.R(rs));
|
||||
CompileAt(js.compilerPC + 4);
|
||||
FlushAll();
|
||||
CompileDelaySlot(false);
|
||||
|
||||
if (!js.compiling)
|
||||
{
|
||||
|
@ -402,6 +488,7 @@ void Jit::Comp_JumpReg(u32 op)
|
|||
break;
|
||||
}
|
||||
|
||||
CONDITIONAL_LOG_EXIT_EAX();
|
||||
WriteExitDestInEAX();
|
||||
js.compiling = false;
|
||||
}
|
||||
|
|
|
@ -122,8 +122,10 @@ void Jit::ClearCacheAt(u32 em_address)
|
|||
ClearCache();
|
||||
}
|
||||
|
||||
void Jit::CompileDelaySlot(u32 addr, bool saveFlags)
|
||||
void Jit::CompileDelaySlot(bool saveFlags)
|
||||
{
|
||||
const u32 addr = js.compilerPC + 4;
|
||||
|
||||
// TODO: If we ever support conditional breakpoints, we need to handle the flags more carefully.
|
||||
CheckJitBreakpoint(addr);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
void Compile(u32 em_address); // Compiles a block at current MIPS PC
|
||||
const u8 *DoJit(u32 em_address, JitBlock *b);
|
||||
|
||||
void CompileDelaySlot(u32 addr, bool saveFlags = false);
|
||||
void CompileDelaySlot(bool saveFlags = false);
|
||||
void CompileAt(u32 addr);
|
||||
void Comp_RunBlock(u32 op);
|
||||
|
||||
|
@ -115,6 +115,8 @@ private:
|
|||
void BranchVFPUFlag(u32 op, Gen::CCFlags cc, bool likely);
|
||||
void BranchRSZeroComp(u32 op, Gen::CCFlags cc, bool likely);
|
||||
void BranchRSRTComp(u32 op, Gen::CCFlags cc, bool likely);
|
||||
void BranchLog(u32 op);
|
||||
void BranchLogExit(u32 op, u32 dest, bool useEAX);
|
||||
|
||||
// Utilities to reduce duplicated code
|
||||
void CompImmLogic(u32 op, void (XEmitter::*arith)(int, const OpArg &, const OpArg &));
|
||||
|
|
|
@ -51,7 +51,7 @@ RegCache::RegCache() : emit(0), mips(0) {
|
|||
|
||||
void RegCache::Start(MIPSState *mips, MIPSAnalyst::AnalysisResults &stats)
|
||||
{
|
||||
this->mips = mips;
|
||||
this->mips = mips;
|
||||
for (int i = 0; i < NUMXREGS; i++)
|
||||
{
|
||||
xregs[i].free = true;
|
||||
|
@ -211,6 +211,10 @@ void RegCache::DiscardRegContentsIfCached(int preg)
|
|||
|
||||
void GPRRegCache::SetImmediate32(int preg, u32 immValue)
|
||||
{
|
||||
// ZERO is always zero. Let's just make sure.
|
||||
if (preg == 0)
|
||||
immValue = 0;
|
||||
|
||||
DiscardRegContentsIfCached(preg);
|
||||
regs[preg].away = true;
|
||||
regs[preg].location = Imm32(immValue);
|
||||
|
@ -282,7 +286,13 @@ void GPRRegCache::BindToRegister(int i, bool doLoad, bool makeDirty)
|
|||
xregs[xr].dirty = makeDirty || regs[i].location.IsImm();
|
||||
OpArg newloc = ::Gen::R(xr);
|
||||
if (doLoad)
|
||||
emit->MOV(32, newloc, regs[i].location);
|
||||
{
|
||||
// Force ZERO to be 0.
|
||||
if (i == 0)
|
||||
emit->MOV(32, newloc, Imm32(0));
|
||||
else
|
||||
emit->MOV(32, newloc, regs[i].location);
|
||||
}
|
||||
for (int j = 0; j < 32; j++)
|
||||
{
|
||||
if (i != j && regs[j].location.IsSimpleReg() && regs[j].location.GetSimpleReg() == xr)
|
||||
|
@ -324,7 +334,8 @@ void GPRRegCache::StoreFromRegister(int i)
|
|||
doStore = true;
|
||||
}
|
||||
OpArg newLoc = GetDefaultLocation(i);
|
||||
if (doStore)
|
||||
// But never store to ZERO.
|
||||
if (doStore && i != 0)
|
||||
emit->MOV(32, newLoc, regs[i].location);
|
||||
regs[i].location = newLoc;
|
||||
regs[i].away = false;
|
||||
|
|
Loading…
Add table
Reference in a new issue