diff --git a/Core/MIPS/x86/CompFPU.cpp b/Core/MIPS/x86/CompFPU.cpp index 620fdc216a..e154df5170 100644 --- a/Core/MIPS/x86/CompFPU.cpp +++ b/Core/MIPS/x86/CompFPU.cpp @@ -106,7 +106,7 @@ void Jit::Comp_FPULS(u32 op) JitSafeMem safe(this, rs, offset); OpArg src; - if (safe.PrepareRead(src)) + if (safe.PrepareRead(src, 4)) MOVSS(fpr.RX(ft), src); if (safe.PrepareSlowRead((void *) &Memory::Read_U32)) { @@ -127,7 +127,7 @@ void Jit::Comp_FPULS(u32 op) JitSafeMem safe(this, rs, offset); OpArg dest; - if (safe.PrepareWrite(dest)) + if (safe.PrepareWrite(dest, 4)) MOVSS(dest, fpr.RX(ft)); if (safe.PrepareSlowWrite()) { diff --git a/Core/MIPS/x86/CompLoadStore.cpp b/Core/MIPS/x86/CompLoadStore.cpp index f0dc88e1d2..2ab903c4d0 100644 --- a/Core/MIPS/x86/CompLoadStore.cpp +++ b/Core/MIPS/x86/CompLoadStore.cpp @@ -53,7 +53,7 @@ namespace MIPSComp JitSafeMem safe(this, rs, offset); OpArg src; - if (safe.PrepareRead(src)) + if (safe.PrepareRead(src, 4)) (this->*mov)(32, bits, gpr.RX(rt), src); if (safe.PrepareSlowRead(safeFunc)) (this->*mov)(32, bits, gpr.RX(rt), R(EAX)); @@ -83,7 +83,7 @@ namespace MIPSComp JitSafeMem safe(this, rs, offset); OpArg dest; - if (safe.PrepareWrite(dest)) + if (safe.PrepareWrite(dest, 4)) { if (needSwap) { diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index c099e488e2..a2b0f34779 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -210,7 +210,7 @@ void Jit::Comp_SV(u32 op) { JitSafeMem safe(this, rs, imm); safe.SetFar(); OpArg src; - if (safe.PrepareRead(src)) + if (safe.PrepareRead(src, 4)) { MOVSS(fpr.VX(vt), safe.NextFastAddress(0)); } @@ -236,7 +236,7 @@ void Jit::Comp_SV(u32 op) { JitSafeMem safe(this, rs, imm); safe.SetFar(); OpArg dest; - if (safe.PrepareWrite(dest)) + if (safe.PrepareWrite(dest, 4)) { MOVSS(safe.NextFastAddress(0), fpr.VX(vt)); } @@ -278,7 +278,7 @@ void Jit::Comp_SVQ(u32 op) JitSafeMem safe(this, rs, imm); safe.SetFar(); OpArg src; - if (safe.PrepareRead(src)) + if (safe.PrepareRead(src, 16)) { // Just copy 4 words the easiest way while not wasting registers. for (int i = 0; i < 4; i++) @@ -312,7 +312,7 @@ void Jit::Comp_SVQ(u32 op) JitSafeMem safe(this, rs, imm); safe.SetFar(); OpArg dest; - if (safe.PrepareWrite(dest)) + if (safe.PrepareWrite(dest, 16)) { for (int i = 0; i < 4; i++) MOVSS(safe.NextFastAddress(i * 4), fpr.VX(vregs[i])); diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index f2a7e0666d..a58aac5aff 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -248,6 +248,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b) js.curBlock = b; js.compiling = true; js.inDelaySlot = false; + js.needCheckCoreState = false; js.PrefixStart(); // We add a check before the block, used when entering from a linked block. @@ -331,7 +332,10 @@ void Jit::WriteExit(u32 destination, int exit_num) // Link opportunity! int block = blocks.GetBlockNumberFromStartAddress(destination); - if (block >= 0 && jo.enableBlocklink) { + if (js.needCheckCoreState) { + MOV(32, M(&mips_->pc), Imm32(destination)); + JMP(asm_.dispatcherCheckCoreState, true); + } else if (block >= 0 && jo.enableBlocklink) { // It exists! Joy of joy! JMP(blocks.GetBlock(block)->checkedEntry, true); b->linkStatus[exit_num] = true; @@ -378,6 +382,8 @@ void Jit::WriteExitDestInEAX() SUB(32, M(¤tMIPS->downcount), Imm32(0)); J_CC(CC_NE, asm_.dispatcher, true); } + else if (js.needCheckCoreState) + JMP(asm_.dispatcherCheckCoreState, true); else JMP(asm_.dispatcher, true); } @@ -422,13 +428,15 @@ void Jit::JitSafeMem::SetFar() far_ = true; } -bool Jit::JitSafeMem::PrepareWrite(OpArg &dest) +bool Jit::JitSafeMem::PrepareWrite(OpArg &dest, int size) { // If it's an immediate, we can do the write if valid. if (iaddr_ != (u32) -1) { if (Memory::IsValidAddress(iaddr_)) { + MemCheckImm(MEM_WRITE, size); + #ifdef _M_IX86 dest = M(Memory::base + (iaddr_ & Memory::MEMVIEW32_MASK)); #else @@ -441,16 +449,18 @@ bool Jit::JitSafeMem::PrepareWrite(OpArg &dest) } // Otherwise, we always can do the write (conditionally.) else - dest = PrepareMemoryOpArg(); + dest = PrepareMemoryOpArg(MEM_WRITE, size); return true; } -bool Jit::JitSafeMem::PrepareRead(OpArg &src) +bool Jit::JitSafeMem::PrepareRead(OpArg &src, int size) { if (iaddr_ != (u32) -1) { if (Memory::IsValidAddress(iaddr_)) { + MemCheckImm(MEM_READ, size); + #ifdef _M_IX86 src = M(Memory::base + (iaddr_ & Memory::MEMVIEW32_MASK)); #else @@ -462,7 +472,7 @@ bool Jit::JitSafeMem::PrepareRead(OpArg &src) return false; } else - src = PrepareMemoryOpArg(); + src = PrepareMemoryOpArg(MEM_READ, size); return true; } @@ -486,7 +496,7 @@ OpArg Jit::JitSafeMem::NextFastAddress(int suboffset) #endif } -OpArg Jit::JitSafeMem::PrepareMemoryOpArg() +OpArg Jit::JitSafeMem::PrepareMemoryOpArg(ReadType type, int size) { // We may not even need to move into EAX as a temporary. // TODO: Except on x86 in fastmem mode. @@ -501,6 +511,8 @@ OpArg Jit::JitSafeMem::PrepareMemoryOpArg() xaddr_ = EAX; } + MemCheckAsm(type, size); + if (!g_Config.bFastMemory) { // Is it in physical ram? @@ -636,6 +648,16 @@ void Jit::JitSafeMem::Finish() jit_->SetJumpTarget(skip_); } +void Jit::JitSafeMem::MemCheckImm(ReadType type, int size) +{ + // TODO +} + +void Jit::JitSafeMem::MemCheckAsm(ReadType type, int size) +{ + // TODO +} + void Jit::Comp_DoNothing(u32 op) { } } // namespace diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 8cbfda4f82..2967655277 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -60,6 +60,7 @@ struct JitState u32 blockStart; bool cancel; bool inDelaySlot; + bool needCheckCoreState; int downcountAmount; int numInstructions; bool compiling; // TODO: get rid of this in favor of using analysis results to determine end of block @@ -269,14 +270,14 @@ private: JitSafeMem(Jit *jit, int raddr, s32 offset); // Emit code necessary for a memory write, returns true if MOV to dest is needed. - bool PrepareWrite(OpArg &dest); + bool PrepareWrite(OpArg &dest, int size); // Emit code proceeding a slow write call, returns true if slow write is needed. bool PrepareSlowWrite(); // Emit a slow write from src. void DoSlowWrite(void *safeFunc, const OpArg src, int suboffset = 0); // Emit code necessary for a memory read, returns true if MOV from src is needed. - bool PrepareRead(OpArg &src); + bool PrepareRead(OpArg &src, int size); // Emit code for a slow read call, and returns true if result is in EAX. bool PrepareSlowRead(void *safeFunc); @@ -291,8 +292,16 @@ private: void NextSlowRead(void *safeFunc, int suboffset); private: - OpArg PrepareMemoryOpArg(); + enum ReadType + { + MEM_READ, + MEM_WRITE, + }; + + OpArg PrepareMemoryOpArg(ReadType type, int size); void PrepareSlowAccess(); + void MemCheckImm(ReadType type, int size); + void MemCheckAsm(ReadType type, int size); Jit *jit_; int raddr_;