Disable Fastmem on JIT64IL. JIT64IL is completely incompatible with Fastmem and doesn't need it since it has its own way to speed up memory accesses. This fixes the JIT64IL core, which I totally didn't break but was blamed for.

This commit is contained in:
Ryan Houdek 2013-11-12 19:37:09 -06:00
parent 7c1ac441f6
commit 39ad5a2f7a
5 changed files with 32 additions and 36 deletions

View File

@ -470,7 +470,7 @@ static void regEmitMemLoad(RegInfo& RI, InstLoc I, unsigned Size) {
X64Reg reg; X64Reg reg;
auto info = regBuildMemAddress(RI, I, getOp1(I), 1, Size, &reg); auto info = regBuildMemAddress(RI, I, getOp1(I), 1, Size, &reg);
RI.Jit->SafeLoadToReg(reg, info.first, Size, info.second, regsInUse(RI), false); RI.Jit->SafeLoadToReg(reg, info.first, Size, info.second, regsInUse(RI), false, EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
if (regReadUse(RI, I)) if (regReadUse(RI, I))
RI.regs[reg] = I; RI.regs[reg] = I;
} }
@ -498,7 +498,7 @@ static void regEmitMemStore(RegInfo& RI, InstLoc I, unsigned Size) {
} else { } else {
RI.Jit->MOV(32, R(EAX), regLocForInst(RI, getOp1(I))); RI.Jit->MOV(32, R(EAX), regLocForInst(RI, getOp1(I)));
} }
RI.Jit->SafeWriteRegToReg(EAX, ECX, Size, 0, regsInUse(RI)); RI.Jit->SafeWriteRegToReg(EAX, ECX, Size, 0, regsInUse(RI), EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
if (RI.IInfo[I - RI.FirstI] & 4) if (RI.IInfo[I - RI.FirstI] & 4)
regClearInst(RI, getOp1(I)); regClearInst(RI, getOp1(I));
} }
@ -1187,7 +1187,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) {
Jit->MOV(32, R(EAX), loc1); Jit->MOV(32, R(EAX), loc1);
} }
Jit->MOV(32, R(ECX), regLocForInst(RI, getOp2(I))); Jit->MOV(32, R(ECX), regLocForInst(RI, getOp2(I)));
RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 0, regsInUse(RI)); RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 0, regsInUse(RI), EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
if (RI.IInfo[I - RI.FirstI] & 4) if (RI.IInfo[I - RI.FirstI] & 4)
fregClearInst(RI, getOp1(I)); fregClearInst(RI, getOp1(I));
if (RI.IInfo[I - RI.FirstI] & 8) if (RI.IInfo[I - RI.FirstI] & 8)
@ -1250,12 +1250,12 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) {
Jit->PSRLQ(XMM0, 32); Jit->PSRLQ(XMM0, 32);
Jit->MOVD_xmm(R(EAX), XMM0); Jit->MOVD_xmm(R(EAX), XMM0);
Jit->MOV(32, R(ECX), address); Jit->MOV(32, R(ECX), address);
RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 0, regsInUse(RI)); RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 0, regsInUse(RI), EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
Jit->MOVAPD(XMM0, value); Jit->MOVAPD(XMM0, value);
Jit->MOVD_xmm(R(EAX), XMM0); Jit->MOVD_xmm(R(EAX), XMM0);
Jit->MOV(32, R(ECX), address); Jit->MOV(32, R(ECX), address);
RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 4, regsInUse(RI)); RI.Jit->SafeWriteRegToReg(EAX, ECX, 32, 4, regsInUse(RI), EmuCodeBlock::SAFE_LOADSTORE_NO_FASTMEM);
Jit->SetJumpTarget(exit); Jit->SetJumpTarget(exit);
if (RI.IInfo[I - RI.FirstI] & 4) if (RI.IInfo[I - RI.FirstI] & 4)

View File

@ -58,14 +58,10 @@ private:
JitBlockCache blocks; JitBlockCache blocks;
TrampolineCache trampolines; TrampolineCache trampolines;
// The default code buffer. We keep it around to not have to alloc/dealloc a
// large chunk of memory for each recompiled block.
PPCAnalyst::CodeBuffer code_buffer;
public: public:
JitILAsmRoutineManager asm_routines; JitILAsmRoutineManager asm_routines;
JitIL() : code_buffer(32000) {} JitIL() {}
~JitIL() {} ~JitIL() {}
// Initialization, etc // Initialization, etc
@ -140,6 +136,4 @@ public:
void DynaRunTable63(UGeckoInstruction _inst) override; void DynaRunTable63(UGeckoInstruction _inst) override;
}; };
void Jit(u32 em_address);
#endif // _JITIL_H #endif // _JITIL_H

View File

@ -196,7 +196,7 @@ void CommonAsmRoutines::GenQuantizedStores()
PACKSSDW(XMM0, R(XMM0)); PACKSSDW(XMM0, R(XMM0));
PACKUSWB(XMM0, R(XMM0)); PACKUSWB(XMM0, R(XMM0));
MOVD_xmm(R(EAX), XMM0); MOVD_xmm(R(EAX), XMM0);
SafeWriteRegToReg(AX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(AX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
RET(); RET();
@ -215,7 +215,7 @@ void CommonAsmRoutines::GenQuantizedStores()
PACKSSWB(XMM0, R(XMM0)); PACKSSWB(XMM0, R(XMM0));
MOVD_xmm(R(EAX), XMM0); MOVD_xmm(R(EAX), XMM0);
SafeWriteRegToReg(AX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(AX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
RET(); RET();
@ -241,7 +241,7 @@ void CommonAsmRoutines::GenQuantizedStores()
MOV(16, R(AX), M((char*)psTemp + 4)); MOV(16, R(AX), M((char*)psTemp + 4));
BSWAP(32, EAX); BSWAP(32, EAX);
SafeWriteRegToReg(EAX, ECX, 32, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(EAX, ECX, 32, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
RET(); RET();
@ -261,7 +261,7 @@ void CommonAsmRoutines::GenQuantizedStores()
MOVD_xmm(R(EAX), XMM0); MOVD_xmm(R(EAX), XMM0);
BSWAP(32, EAX); BSWAP(32, EAX);
ROL(32, R(EAX), Imm8(16)); ROL(32, R(EAX), Imm8(16));
SafeWriteRegToReg(EAX, ECX, 32, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(EAX, ECX, 32, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
RET(); RET();
@ -286,7 +286,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
// Easy! // Easy!
const u8* storeSingleFloat = AlignCode4(); const u8* storeSingleFloat = AlignCode4();
SafeWriteFloatToReg(XMM0, ECX, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteFloatToReg(XMM0, ECX, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
RET(); RET();
/* /*
if (cpu_info.bSSSE3) { if (cpu_info.bSSSE3) {
@ -294,11 +294,11 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
// TODO: SafeWriteFloat // TODO: SafeWriteFloat
MOVSS(M(&psTemp[0]), XMM0); MOVSS(M(&psTemp[0]), XMM0);
MOV(32, R(EAX), M(&psTemp[0])); MOV(32, R(EAX), M(&psTemp[0]));
SafeWriteRegToReg(EAX, ECX, 32, 0, SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(EAX, ECX, 32, 0, SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
} else { } else {
MOVSS(M(&psTemp[0]), XMM0); MOVSS(M(&psTemp[0]), XMM0);
MOV(32, R(EAX), M(&psTemp[0])); MOV(32, R(EAX), M(&psTemp[0]));
SafeWriteRegToReg(EAX, ECX, 32, 0, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(EAX, ECX, 32, 0, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
}*/ }*/
const u8* storeSingleU8 = AlignCode4(); // Used by MKWii const u8* storeSingleU8 = AlignCode4(); // Used by MKWii
@ -309,7 +309,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
MAXSS(XMM0, R(XMM1)); MAXSS(XMM0, R(XMM1));
MINSS(XMM0, M((void *)&m_255)); MINSS(XMM0, M((void *)&m_255));
CVTTSS2SI(EAX, R(XMM0)); CVTTSS2SI(EAX, R(XMM0));
SafeWriteRegToReg(AL, ECX, 8, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(AL, ECX, 8, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
RET(); RET();
const u8* storeSingleS8 = AlignCode4(); const u8* storeSingleS8 = AlignCode4();
@ -319,7 +319,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
MAXSS(XMM0, M((void *)&m_m128)); MAXSS(XMM0, M((void *)&m_m128));
MINSS(XMM0, M((void *)&m_127)); MINSS(XMM0, M((void *)&m_127));
CVTTSS2SI(EAX, R(XMM0)); CVTTSS2SI(EAX, R(XMM0));
SafeWriteRegToReg(AL, ECX, 8, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(AL, ECX, 8, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
RET(); RET();
const u8* storeSingleU16 = AlignCode4(); // Used by MKWii const u8* storeSingleU16 = AlignCode4(); // Used by MKWii
@ -330,7 +330,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
MAXSS(XMM0, R(XMM1)); MAXSS(XMM0, R(XMM1));
MINSS(XMM0, M((void *)&m_65535)); MINSS(XMM0, M((void *)&m_65535));
CVTTSS2SI(EAX, R(XMM0)); CVTTSS2SI(EAX, R(XMM0));
SafeWriteRegToReg(EAX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(EAX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
RET(); RET();
const u8* storeSingleS16 = AlignCode4(); const u8* storeSingleS16 = AlignCode4();
@ -340,7 +340,7 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
MAXSS(XMM0, M((void *)&m_m32768)); MAXSS(XMM0, M((void *)&m_m32768));
MINSS(XMM0, M((void *)&m_32767)); MINSS(XMM0, M((void *)&m_32767));
CVTTSS2SI(EAX, R(XMM0)); CVTTSS2SI(EAX, R(XMM0));
SafeWriteRegToReg(EAX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_WRITE_NO_PROLOG | SAFE_WRITE_NO_FASTMEM); SafeWriteRegToReg(EAX, ECX, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
RET(); RET();
singleStoreQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16())); singleStoreQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16()));

View File

@ -117,18 +117,20 @@ u8 *EmuCodeBlock::UnsafeLoadToReg(X64Reg reg_value, Gen::OpArg opAddress, int ac
return result; return result;
} }
void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend) void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend, int flags)
{ {
if (!jit->js.memcheck) if (!jit->js.memcheck)
{ {
registersInUse &= ~(1 << RAX | 1 << reg_value); registersInUse &= ~(1 << RAX | 1 << reg_value);
} }
#if defined(_M_X64) #if defined(_M_X64)
if (!Core::g_CoreStartupParameter.bMMU &&
Core::g_CoreStartupParameter.bFastmem &&
!(flags & (SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_FASTMEM))
#ifdef ENABLE_MEM_CHECK #ifdef ENABLE_MEM_CHECK
if (!Core::g_CoreStartupParameter.bMMU && !Core::g_CoreStartupParameter.bEnableDebugging && Core::g_CoreStartupParameter.bFastmem) && !Core::g_CoreStartupParameter.bEnableDebugging
#else
if (!Core::g_CoreStartupParameter.bMMU && Core::g_CoreStartupParameter.bFastmem)
#endif #endif
)
{ {
u8 *mov = UnsafeLoadToReg(reg_value, opAddress, accessSize, offset, signExtend); u8 *mov = UnsafeLoadToReg(reg_value, opAddress, accessSize, offset, signExtend);
@ -282,14 +284,14 @@ void EmuCodeBlock::SafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int acce
#if defined(_M_X64) #if defined(_M_X64)
if (!Core::g_CoreStartupParameter.bMMU && if (!Core::g_CoreStartupParameter.bMMU &&
Core::g_CoreStartupParameter.bFastmem && Core::g_CoreStartupParameter.bFastmem &&
!(flags & (SAFE_WRITE_NO_SWAP | SAFE_WRITE_NO_FASTMEM)) !(flags & (SAFE_LOADSTORE_NO_SWAP | SAFE_LOADSTORE_NO_FASTMEM))
#ifdef ENABLE_MEM_CHECK #ifdef ENABLE_MEM_CHECK
&& !Core::g_CoreStartupParameter.bEnableDebugging && !Core::g_CoreStartupParameter.bEnableDebugging
#endif #endif
) )
{ {
MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write
u8 *mov = UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, offset, !(flags & SAFE_WRITE_NO_SWAP)); u8 *mov = UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, offset, !(flags & SAFE_LOADSTORE_NO_SWAP));
if (accessSize == 8) if (accessSize == 8)
{ {
NOP(1); NOP(1);
@ -321,8 +323,8 @@ void EmuCodeBlock::SafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int acce
MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write
TEST(32, R(reg_addr), Imm32(mem_mask)); TEST(32, R(reg_addr), Imm32(mem_mask));
FixupBranch fast = J_CC(CC_Z, true); FixupBranch fast = J_CC(CC_Z, true);
bool noProlog = flags & SAFE_WRITE_NO_PROLOG; bool noProlog = flags & SAFE_LOADSTORE_NO_PROLOG;
bool swap = !(flags & SAFE_WRITE_NO_SWAP); bool swap = !(flags & SAFE_LOADSTORE_NO_SWAP);
ABI_PushRegistersAndAdjustStack(registersInUse, noProlog); ABI_PushRegistersAndAdjustStack(registersInUse, noProlog);
switch (accessSize) switch (accessSize)
{ {

View File

@ -28,13 +28,13 @@ public:
// these return the address of the MOV, for backpatching // these return the address of the MOV, for backpatching
u8 *UnsafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset = 0, bool swap = true); u8 *UnsafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset = 0, bool swap = true);
u8 *UnsafeLoadToReg(Gen::X64Reg reg_value, Gen::OpArg opAddress, int accessSize, s32 offset, bool signExtend); u8 *UnsafeLoadToReg(Gen::X64Reg reg_value, Gen::OpArg opAddress, int accessSize, s32 offset, bool signExtend);
void SafeLoadToReg(Gen::X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend); enum SafeLoadStoreFlags
enum SafeWriteFlags
{ {
SAFE_WRITE_NO_SWAP = 1, SAFE_LOADSTORE_NO_SWAP = 1,
SAFE_WRITE_NO_PROLOG = 2, SAFE_LOADSTORE_NO_PROLOG = 2,
SAFE_WRITE_NO_FASTMEM = 4 SAFE_LOADSTORE_NO_FASTMEM = 4
}; };
void SafeLoadToReg(Gen::X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend, int flags = 0);
void SafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset, u32 registersInUse, int flags = 0); void SafeWriteRegToReg(Gen::X64Reg reg_value, Gen::X64Reg reg_addr, int accessSize, s32 offset, u32 registersInUse, int flags = 0);
// Trashes both inputs and EAX. // Trashes both inputs and EAX.