diff options
| author | skidau <skidau@gmail.com> | 2012-01-03 01:17:52 +1100 |
|---|---|---|
| committer | calc84maniac <calc84maniac@gmail.com> | 2012-01-03 01:24:18 -0500 |
| commit | daf7e965219eb61f36c19d2f2a6c12276c5a371e (patch) | |
| tree | 72f216cd2dc7e22162b1d2510792b3315d8ea534 /Source/Core | |
| parent | b9547a07f580410bf565a6de88b20f209ed14f95 (diff) | |
Fixed the safe write path of the stfd instruction in the JIT. Fixes issue 4001.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp | 91 |
1 files changed, 37 insertions, 54 deletions
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp index 55990d6abf..46e888f935 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp @@ -172,80 +172,63 @@ void Jit64::stfd(UGeckoInstruction inst) int s = inst.RS; int a = inst.RA; - if (!a) + + u32 mem_mask = Memory::ADDR_MASK_HW_ACCESS; + if (Core::g_CoreStartupParameter.bMMU || + Core::g_CoreStartupParameter.iTLBHack) { + mem_mask |= Memory::ADDR_MASK_MEM1; + } +#ifdef ENABLE_MEM_CHECK + if (Core::g_CoreStartupParameter.bEnableDebugging) { - Default(inst); - return; + mem_mask |= Memory::EXRAM_MASK; } - s32 offset = (s32)(s16)inst.SIMM_16; +#endif + gpr.FlushLockX(ABI_PARAM1); gpr.Lock(a); fpr.Lock(s); gpr.BindToRegister(a, true, false); + + s32 offset = (s32)(s16)inst.SIMM_16; LEA(32, ABI_PARAM1, MDisp(gpr.R(a).GetSimpleReg(), offset)); - TEST(32, R(ABI_PARAM1), Imm32(0x0c000000)); - FixupBranch not_ram = J_CC(CC_Z); - // Assume that any hardware writes using this instruction will go to the FIFO. - // Star Wars - The Force Unleashed uses this trick. - if (cpu_info.bSSSE3) { - MOVAPD(XMM0, fpr.R(s)); - PSHUFB(XMM0, M((void *)bswapShuffle1x8)); - CALL(asm_routines.fifoDirectWriteXmm64); - } else { - // This ain't working yet - MOVAPD(XMM0, fpr.R(s)); - MOVQ_xmm(M(&temp64), XMM0); - MOV(32, R(EAX), M(&temp64)); - MOV(32, R(ABI_PARAM1), M((void*)((u8 *)&temp64 + 4))); - BSWAP(32, EAX); - BSWAP(32, ABI_PARAM1); - MOV(32, M(((u8 *)&temp64) + 4), R(EAX)); - MOV(32, M((u8 *)&temp64), R(ABI_PARAM1)); - MOVQ_xmm(XMM0, M(&temp64)); - CALL(asm_routines.fifoDirectWriteXmm64); - } - FixupBranch quit = J(false); - SetJumpTarget(not_ram); -#ifdef _M_IX86 - AND(32, R(ABI_PARAM1), Imm32(Memory::MEMVIEW32_MASK)); -#endif + TEST(32, R(ABI_PARAM1), Imm32(mem_mask)); + FixupBranch safe = J_CC(CC_NZ); + + // Fast routine if (cpu_info.bSSSE3) { MOVAPD(XMM0, fpr.R(s)); - PSHUFB(XMM0, M((void *)bswapShuffle1x8)); + PSHUFB(XMM0, M((void*)bswapShuffle1x8)); #ifdef _M_X64 MOVQ_xmm(MComplex(RBX, ABI_PARAM1, SCALE_1, 0), XMM0); #else + AND(32, R(ECX), Imm32(Memory::MEMVIEW32_MASK)); MOVQ_xmm(MDisp(ABI_PARAM1, (u32)Memory::base), XMM0); #endif } else { -#ifdef _M_X64 - fpr.BindToRegister(s, true, false); - MOVSD(M(&temp64), fpr.RX(s)); - - MEMCHECK_START + MOVAPD(XMM0, fpr.R(s)); + MOVD_xmm(R(EAX), XMM0); + UnsafeWriteRegToReg(EAX, ABI_PARAM1, 32, 4); - MOV(64, R(EAX), M(&temp64)); - BSWAP(64, EAX); - MOV(64, MComplex(RBX, ABI_PARAM1, SCALE_1, 0), R(EAX)); + PSRLQ(XMM0, 32); + MOVD_xmm(R(EAX), XMM0); + UnsafeWriteRegToReg(EAX, ABI_PARAM1, 32, 0); + } + FixupBranch exit = J(); + SetJumpTarget(safe); - MEMCHECK_END -#else - fpr.BindToRegister(s, true, false); - MOVSD(M(&temp64), fpr.RX(s)); + // Safe but slow routine + MOVAPD(XMM0, fpr.R(s)); + MOVD_xmm(R(EAX), XMM0); + SafeWriteRegToReg(EAX, ABI_PARAM1, 32, 4); - MEMCHECK_START + PSRLQ(XMM0, 32); + MOVD_xmm(R(EAX), XMM0); + LEA(32, ABI_PARAM1, MDisp(gpr.R(a).GetSimpleReg(), offset)); + SafeWriteRegToReg(EAX, ABI_PARAM1, 32, 0); - MOV(32, R(EAX), M(&temp64)); - BSWAP(32, EAX); - MOV(32, MDisp(ABI_PARAM1, (u32)Memory::base + 4), R(EAX)); - MOV(32, R(EAX), M((void*)((u8 *)&temp64 + 4))); - BSWAP(32, EAX); - MOV(32, MDisp(ABI_PARAM1, (u32)Memory::base), R(EAX)); + SetJumpTarget(exit); - MEMCHECK_END -#endif - } - SetJumpTarget(quit); gpr.UnlockAll(); gpr.UnlockAllX(); fpr.UnlockAll(); |
