x86jit: Add proxy blocks for continuing.

This commit is contained in:
Unknown W. Brackets 2014-10-12 17:15:31 -07:00
parent 01f9521dc5
commit d98adf27d6
4 changed files with 29 additions and 3 deletions

View file

@ -64,6 +64,8 @@ namespace MIPSComp {
u32 compilerPC; u32 compilerPC;
u32 blockStart; u32 blockStart;
u32 lastContinuedPC;
u32 initialBlockSize;
int nextExit; int nextExit;
bool cancel; bool cancel;
bool inDelaySlot; bool inDelaySlot;

View file

@ -215,6 +215,7 @@ void Jit::CompBranchExits(CCFlags cc, u32 targetAddr, u32 notTakenAddr, bool del
if (likely) if (likely)
CompileDelaySlot(DELAYSLOT_NICE); CompileDelaySlot(DELAYSLOT_NICE);
AddContinuedBlock(targetAddr);
// Account for the increment in the loop. // Account for the increment in the loop.
js.compilerPC = targetAddr - 4; js.compilerPC = targetAddr - 4;
// In case the delay slot was a break or something. // In case the delay slot was a break or something.
@ -328,6 +329,7 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely)
// Branch taken. Always compile the delay slot, and then go to dest. // Branch taken. Always compile the delay slot, and then go to dest.
CompileDelaySlot(DELAYSLOT_NICE); CompileDelaySlot(DELAYSLOT_NICE);
AddContinuedBlock(targetAddr);
// Account for the increment in the loop. // Account for the increment in the loop.
js.compilerPC = targetAddr - 4; js.compilerPC = targetAddr - 4;
// In case the delay slot was a break or something. // In case the delay slot was a break or something.
@ -406,6 +408,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li
if (andLink) if (andLink)
gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8); gpr.SetImm(MIPS_REG_RA, js.compilerPC + 8);
AddContinuedBlock(targetAddr);
// Account for the increment in the loop. // Account for the increment in the loop.
js.compilerPC = targetAddr - 4; js.compilerPC = targetAddr - 4;
// In case the delay slot was a break or something. // In case the delay slot was a break or something.
@ -585,6 +588,7 @@ void Jit::Comp_Jump(MIPSOpcode op) {
CompileDelaySlot(DELAYSLOT_NICE); CompileDelaySlot(DELAYSLOT_NICE);
if (jo.continueJumps && js.numInstructions < jo.continueMaxInstructions) if (jo.continueJumps && js.numInstructions < jo.continueMaxInstructions)
{ {
AddContinuedBlock(targetAddr);
// Account for the increment in the loop. // Account for the increment in the loop.
js.compilerPC = targetAddr - 4; js.compilerPC = targetAddr - 4;
// In case the delay slot was a break or something. // In case the delay slot was a break or something.
@ -609,6 +613,7 @@ void Jit::Comp_Jump(MIPSOpcode op) {
CompileDelaySlot(DELAYSLOT_NICE); CompileDelaySlot(DELAYSLOT_NICE);
if (jo.continueJumps && js.numInstructions < jo.continueMaxInstructions) if (jo.continueJumps && js.numInstructions < jo.continueMaxInstructions)
{ {
AddContinuedBlock(targetAddr);
// Account for the increment in the loop. // Account for the increment in the loop.
js.compilerPC = targetAddr - 4; js.compilerPC = targetAddr - 4;
// In case the delay slot was a break or something. // In case the delay slot was a break or something.
@ -679,6 +684,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op)
if (jo.continueJumps && gpr.IsImm(rs) && js.numInstructions < jo.continueMaxInstructions) if (jo.continueJumps && gpr.IsImm(rs) && js.numInstructions < jo.continueMaxInstructions)
{ {
AddContinuedBlock(gpr.GetImm(rs));
// Account for the increment in the loop. // Account for the increment in the loop.
js.compilerPC = gpr.GetImm(rs) - 4; js.compilerPC = gpr.GetImm(rs) - 4;
// In case the delay slot was a break or something. // In case the delay slot was a break or something.

View file

@ -116,8 +116,6 @@ static void JitLogMiss(MIPSOpcode op)
JitOptions::JitOptions() JitOptions::JitOptions()
{ {
enableBlocklink = true; enableBlocklink = true;
// WARNING: These options don't work properly with cache clearing.
// Need to find a smart way to handle before enabling.
immBranches = false; immBranches = false;
continueBranches = false; continueBranches = false;
continueJumps = false; continueJumps = false;
@ -396,6 +394,8 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
{ {
js.cancel = false; js.cancel = false;
js.blockStart = js.compilerPC = mips_->pc; js.blockStart = js.compilerPC = mips_->pc;
js.lastContinuedPC = 0;
js.initialBlockSize = 0;
js.nextExit = 0; js.nextExit = 0;
js.downcountAmount = 0; js.downcountAmount = 0;
js.curBlock = b; js.curBlock = b;
@ -466,10 +466,27 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
b->codeSize = (u32)(GetCodePtr() - b->normalEntry); b->codeSize = (u32)(GetCodePtr() - b->normalEntry);
NOP(); NOP();
AlignCode4(); AlignCode4();
b->originalSize = js.numInstructions; if (js.lastContinuedPC == 0)
b->originalSize = js.numInstructions;
else
{
// We continued at least once. Add the last proxy and set the originalSize correctly.
blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr());
b->originalSize = js.initialBlockSize;
}
return b->normalEntry; return b->normalEntry;
} }
void Jit::AddContinuedBlock(u32 dest)
{
// The first block is the root block. When we continue, we create proxy blocks after that.
if (js.lastContinuedPC == 0)
js.initialBlockSize = js.numInstructions;
else
blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr());
js.lastContinuedPC = dest;
}
bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name) bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name)
{ {
u32 jitAddr = blocks.GetAddressFromBlockPtr(ptr); u32 jitAddr = blocks.GetAddressFromBlockPtr(ptr);

View file

@ -193,6 +193,7 @@ private:
CompileDelaySlot(flags, &state); CompileDelaySlot(flags, &state);
} }
void EatInstruction(MIPSOpcode op); void EatInstruction(MIPSOpcode op);
void AddContinuedBlock(u32 dest);
void WriteExit(u32 destination, int exit_num); void WriteExit(u32 destination, int exit_num);
void WriteExitDestInReg(X64Reg reg); void WriteExitDestInReg(X64Reg reg);