summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorFiora <fioraaeterna@gmail.com>2015-01-02 13:55:16 -0800
committerFiora <fioraaeterna@gmail.com>2015-01-05 10:34:59 -0800
commit9923d705df90fb276ced10cafda94e050305ca0c (patch)
tree89e5eedd7d44c909628baef73810b9cf9935a686 /Source/Core
parent6dc7cf29f3b938330ea0947756b827b5de493daf (diff)
JIT: simplify and optimize memcheck macros
Instead of jumping over update code and similar, just jump directly to the handler. This avoids redundant exception checks in the case where we can't do fastmem memory operations (e.g. paired loadstore).
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.cpp7
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp15
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp9
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_LoadStorePaired.cpp6
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/JitBase.h5
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp16
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/Jit_Util.h12
7 files changed, 34 insertions, 36 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
index 81d126ba3b..77905ca8ae 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
@@ -614,6 +614,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
const GekkoOPInfo *opinfo = ops[i].opinfo;
js.downcountAmount += opinfo->numCycles;
js.fastmemLoadStore = NULL;
+ js.fixupExceptionHandler = false;
if (i == (code_block.m_num_instructions - 1))
{
@@ -767,7 +768,9 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
{
// If we have a fastmem loadstore, we can omit the exception check and let fastmem handle it.
FixupBranch memException;
- if (!js.fastmemLoadStore)
+ _assert_msg_(DYNA_REC, !(js.fastmemLoadStore && js.fixupExceptionHandler),
+ "Fastmem loadstores shouldn't have exception handler fixups (PC=%x)!", ops[i].address);
+ if (!js.fastmemLoadStore && !js.fixupExceptionHandler)
{
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_DSI));
memException = J_CC(CC_NZ, true);
@@ -777,7 +780,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
if (!js.fastmemLoadStore)
{
exceptionHandlerAtLoc[js.fastmemLoadStore] = NULL;
- SetJumpTarget(memException);
+ SetJumpTarget(js.fixupExceptionHandler ? js.exceptionHandler : memException);
}
else
{
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
index ae6b50f9cf..1edd6b3868 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
@@ -258,17 +258,15 @@ void Jit64::lXXx(UGeckoInstruction inst)
if (update && storeAddress)
{
- MEMCHECK_START
+ MemoryExceptionCheck();
MOV(32, gpr.R(a), opAddress);
- MEMCHECK_END
}
// TODO: support no-swap in SafeLoadToReg instead
if (byte_reversed)
{
- MEMCHECK_START
+ MemoryExceptionCheck();
BSWAP(accessSize, gpr.RX(d));
- MEMCHECK_END
}
gpr.UnlockAll();
@@ -372,9 +370,8 @@ void Jit64::stX(UGeckoInstruction inst)
else
{
gpr.KillImmediate(a, true, true);
- MEMCHECK_START
+ MemoryExceptionCheck();
ADD(32, gpr.R(a), Imm32((u32)offset));
- MEMCHECK_END
}
}
}
@@ -404,9 +401,8 @@ void Jit64::stX(UGeckoInstruction inst)
if (update)
{
- MEMCHECK_START
+ MemoryExceptionCheck();
ADD(32, gpr.R(a), Imm32((u32)offset));
- MEMCHECK_END
}
}
gpr.UnlockAll();
@@ -485,9 +481,8 @@ void Jit64::stXx(UGeckoInstruction inst)
if (update)
{
- MEMCHECK_START
+ MemoryExceptionCheck();
MOV(32, gpr.R(a), R(RSCRATCH2));
- MEMCHECK_END;
}
gpr.UnlockAll();
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp
index 061759857c..4cfbc3b756 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp
@@ -72,7 +72,7 @@ void Jit64::lfXXX(UGeckoInstruction inst)
registersInUse[RSCRATCH2] = true;
SafeLoadToReg(RSCRATCH, addr, single ? 32 : 64, offset, registersInUse, false);
- MEMCHECK_START
+ MemoryExceptionCheck();
if (single)
{
ConvertSingleToDouble(fpr.RX(d), RSCRATCH, true);
@@ -84,7 +84,6 @@ void Jit64::lfXXX(UGeckoInstruction inst)
}
if (update && js.memcheck)
MOV(32, gpr.R(a), addr);
- MEMCHECK_END
fpr.UnlockAll();
gpr.UnlockAll();
}
@@ -141,9 +140,8 @@ void Jit64::stfXXX(UGeckoInstruction inst)
else
{
gpr.KillImmediate(a, true, true);
- MEMCHECK_START
+ MemoryExceptionCheck();
ADD(32, gpr.R(a), Imm32((u32)imm));
- MEMCHECK_END
}
}
fpr.UnlockAll();
@@ -187,9 +185,8 @@ void Jit64::stfXXX(UGeckoInstruction inst)
if (update)
{
- MEMCHECK_START
+ MemoryExceptionCheck();
MOV(32, gpr.R(a), R(RSCRATCH2));
- MEMCHECK_END
}
fpr.UnlockAll();
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStorePaired.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStorePaired.cpp
index 160547bf9a..b6dac78f86 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStorePaired.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStorePaired.cpp
@@ -78,12 +78,11 @@ void Jit64::psq_stXX(UGeckoInstruction inst)
if (update && js.memcheck)
{
- MEMCHECK_START
+ MemoryExceptionCheck();
if (indexed)
ADD(32, gpr.R(a), gpr.R(b));
else
ADD(32, gpr.R(a), Imm32((u32)offset));
- MEMCHECK_END
}
gpr.UnlockAll();
gpr.UnlockAllX();
@@ -137,7 +136,7 @@ void Jit64::psq_lXX(UGeckoInstruction inst)
CALLptr(MScaled(RSCRATCH, SCALE_8, (u32)(u64)(&asm_routines.pairedLoadQuantized[w * 8])));
- MEMCHECK_START
+ MemoryExceptionCheck();
CVTPS2PD(fpr.RX(s), R(XMM0));
if (update && js.memcheck)
{
@@ -146,7 +145,6 @@ void Jit64::psq_lXX(UGeckoInstruction inst)
else
ADD(32, gpr.R(a), Imm32((u32)offset));
}
- MEMCHECK_END
gpr.UnlockAll();
gpr.UnlockAllX();
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/PowerPC/JitCommon/JitBase.h
index 99d89e548e..5a526f8f48 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitBase.h
+++ b/Source/Core/Core/PowerPC/JitCommon/JitBase.h
@@ -73,7 +73,12 @@ protected:
int downcountAmount;
u32 numLoadStoreInst;
u32 numFloatingPointInst;
+ // If this is set, we need to generate an exception handler for the fastmem load.
u8* fastmemLoadStore;
+ // If this is set, a load or store already prepared a jump to the exception handler for us,
+ // so just fixup that branch instead of testing for a DSI again.
+ bool fixupExceptionHandler;
+ Gen::FixupBranch exceptionHandler;
bool firstFPInstructionFound;
bool isLastInstruction;
diff --git a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp
index 35a74201ae..fef3e90677 100644
--- a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp
+++ b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.cpp
@@ -13,6 +13,16 @@
using namespace Gen;
+void EmuCodeBlock::MemoryExceptionCheck()
+{
+ if (jit->js.memcheck && !jit->js.fastmemLoadStore && !jit->js.fixupExceptionHandler)
+ {
+ TEST(32, PPCSTATE(Exceptions), Gen::Imm32(EXCEPTION_DSI));
+ jit->js.exceptionHandler = J_CC(Gen::CC_NZ, true);
+ jit->js.fixupExceptionHandler = true;
+ }
+}
+
void EmuCodeBlock::LoadAndSwap(int size, Gen::X64Reg dst, const Gen::OpArg& src)
{
if (cpu_info.bMOVBE)
@@ -350,7 +360,7 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
}
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
- MEMCHECK_START
+ MemoryExceptionCheck();
if (signExtend && accessSize < 32)
{
// Need to sign extend values coming from the Read_U* functions.
@@ -360,7 +370,6 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
{
MOVZX(64, accessSize, reg_value, R(ABI_RETURN));
}
- MEMCHECK_END
}
}
else
@@ -400,7 +409,7 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
}
ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment);
- MEMCHECK_START
+ MemoryExceptionCheck();
if (signExtend && accessSize < 32)
{
// Need to sign extend values coming from the Read_U* functions.
@@ -410,7 +419,6 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
{
MOVZX(64, accessSize, reg_value, R(ABI_RETURN));
}
- MEMCHECK_END
if (farcode.Enabled())
{
diff --git a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.h b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.h
index 322425b9d4..6681808aa7 100644
--- a/Source/Core/Core/PowerPC/JitCommon/Jit_Util.h
+++ b/Source/Core/Core/PowerPC/JitCommon/Jit_Util.h
@@ -12,16 +12,6 @@
namespace MMIO { class Mapping; }
-#define MEMCHECK_START \
- Gen::FixupBranch memException; \
- if (jit->js.memcheck && !jit->js.fastmemLoadStore) \
- { TEST(32, PPCSTATE(Exceptions), Gen::Imm32(EXCEPTION_DSI)); \
- memException = J_CC(Gen::CC_NZ, true); }
-
-#define MEMCHECK_END \
- if (jit->js.memcheck && !jit->js.fastmemLoadStore) \
- SetJumpTarget(memException);
-
// We offset by 0x80 because the range of one byte memory offsets is
// -0x80..0x7f.
#define PPCSTATE(x) MDisp(RPPCSTATE, \
@@ -59,6 +49,8 @@ public:
FarCodeCache farcode;
u8* nearcode; // Backed up when we switch to far code.
+ void MemoryExceptionCheck();
+
// Simple functions to switch between near and far code emitting
void SwitchToFarCode()
{