diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index 77ab02e230..62e7de4420 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -180,7 +180,6 @@ if(_M_X86)
set(SRCS ${SRCS}
x64MemTools.cpp
PowerPC/Jit64IL/IR_X86.cpp
- PowerPC/Jit64IL/JitILAsm.cpp
PowerPC/Jit64IL/JitIL.cpp
PowerPC/Jit64IL/JitIL_Tables.cpp
PowerPC/Jit64/Jit64_Tables.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 65593f4021..784e7503bd 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -209,7 +209,6 @@
-
@@ -399,7 +398,6 @@
-
@@ -470,4 +468,4 @@
-
+
\ No newline at end of file
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 3ca5e3f970..f25fbe6248 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -641,9 +641,6 @@
PowerPC\JitIL
-
- PowerPC\JitIL
-
PowerPC\Jit64
@@ -1191,9 +1188,6 @@
PowerPC\JitIL
-
- PowerPC\JitIL
-
PowerPC\Jit64
@@ -1211,4 +1205,4 @@
-
+
\ No newline at end of file
diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
index e690d08974..2de7cc31e7 100644
--- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp
@@ -28,8 +28,6 @@ static bool enableDebug = false;
//RBX - Base pointer of memory
//R15 - Pointer to array of block pointers
-Jit64AsmRoutineManager asm_routines;
-
// PLAN: no more block numbers - crazy opcodes just contain offset within
// dynarec buffer
// At this offset - 4, there is an int specifying the block number.
diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.h b/Source/Core/Core/PowerPC/Jit64/JitAsm.h
index f2475ee036..19679247ec 100644
--- a/Source/Core/Core/PowerPC/Jit64/JitAsm.h
+++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.h
@@ -37,5 +37,3 @@ public:
FreeCodeSpace();
}
};
-
-extern Jit64AsmRoutineManager asm_routines;
diff --git a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp
index 53d0323c71..830b787e70 100644
--- a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp
+++ b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp
@@ -1636,7 +1636,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
Jit->ABI_CallFunction((void *)&PowerPC::OnIdleIL);
Jit->MOV(32, M(&PC), Imm32(ibuild->GetImmValue( getOp2(I) )));
- Jit->JMP(((JitIL *)jit)->asm_routines.testExceptions, true);
+ Jit->WriteExceptionExit();
Jit->SetJumpTarget(cont);
if (RI.IInfo[I - RI.FirstI] & 4)
@@ -1691,7 +1691,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
Jit->ABI_CallFunction((void *)&CoreTiming::Idle);
Jit->MOV(32, M(&PC), Imm32(InstLoc));
- Jit->JMP(((JitIL *)jit)->asm_routines.testExceptions, true);
+ Jit->WriteExceptionExit();
break;
}
case SystemCall: {
@@ -1734,7 +1734,8 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
// from PC. Update PC with the latest value in case that happens.
Jit->MOV(32, M(&PC), Imm32(InstLoc));
Jit->SUB(32, M(&CoreTiming::downcount), Jit->js.downcountAmount > 127 ? Imm32(Jit->js.downcountAmount) : Imm8(Jit->js.downcountAmount));
- Jit->JMP(Jit->asm_routines.fpException, true);
+ Jit->OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE));
+ Jit->WriteExceptionExit();
Jit->SetJumpTarget(b1);
break;
}
diff --git a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp
index d0bbea8e47..97d6d162b2 100644
--- a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp
+++ b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp
@@ -14,7 +14,6 @@
#include "Core/PowerPC/Profiler.h"
#include "Core/PowerPC/Jit64IL/JitIL.h"
#include "Core/PowerPC/Jit64IL/JitIL_Tables.h"
-#include "Core/PowerPC/Jit64IL/JitILAsm.h"
using namespace Gen;
using namespace PowerPC;
@@ -427,12 +426,14 @@ void JitIL::WriteExitDestInOpArg(const Gen::OpArg& arg)
void JitIL::WriteRfiExitDestInOpArg(const Gen::OpArg& arg)
{
MOV(32, M(&PC), arg);
+ MOV(32, M(&NPC), arg);
Cleanup();
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
ABI_CallFunction((void *)JitILProfiler::End);
}
+ ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions));
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
- JMP(asm_routines.testExceptions, true);
+ JMP(asm_routines.dispatcher, true);
}
void JitIL::WriteExceptionExit()
@@ -441,8 +442,11 @@ void JitIL::WriteExceptionExit()
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
ABI_CallFunction((void *)JitILProfiler::End);
}
+ MOV(32, R(EAX), M(&PC));
+ MOV(32, M(&NPC), R(EAX));
+ ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions));
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
- JMP(asm_routines.testExceptions, true);
+ JMP(asm_routines.dispatcher, true);
}
void STACKALIGN JitIL::Run()
@@ -549,8 +553,13 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
// This block uses FPU - needs to add FP exception bailout
TEST(32, M(&PowerPC::ppcState.msr), Imm32(1 << 13)); //Test FP enabled bit
FixupBranch b1 = J_CC(CC_NZ);
+
+ // If a FPU exception occurs, the exception handler will read
+ // from PC. Update PC with the latest value in case that happens.
MOV(32, M(&PC), Imm32(js.blockStart));
- JMP(asm_routines.fpException, true);
+ OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE));
+ WriteExceptionExit();
+
SetJumpTarget(b1);
}
diff --git a/Source/Core/Core/PowerPC/Jit64IL/JitIL.h b/Source/Core/Core/PowerPC/Jit64IL/JitIL.h
index 14dc5c69e8..638dafd37e 100644
--- a/Source/Core/Core/PowerPC/Jit64IL/JitIL.h
+++ b/Source/Core/Core/PowerPC/Jit64IL/JitIL.h
@@ -28,7 +28,7 @@
#include "Core/PowerPC/PowerPC.h"
#include "Core/PowerPC/PPCAnalyst.h"
#include "Core/PowerPC/PPCTables.h"
-#include "Core/PowerPC/Jit64IL/JitILAsm.h"
+#include "Core/PowerPC/Jit64/JitAsm.h"
#include "Core/PowerPC/JitCommon/Jit_Util.h"
#include "Core/PowerPC/JitCommon/JitBackpatch.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
@@ -50,7 +50,7 @@ private:
TrampolineCache trampolines;
public:
- JitILAsmRoutineManager asm_routines;
+ Jit64AsmRoutineManager asm_routines;
JitIL() {}
~JitIL() {}
diff --git a/Source/Core/Core/PowerPC/Jit64IL/JitILAsm.cpp b/Source/Core/Core/PowerPC/Jit64IL/JitILAsm.cpp
deleted file mode 100644
index 030ffdc817..0000000000
--- a/Source/Core/Core/PowerPC/Jit64IL/JitILAsm.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#include "Common/CPUDetect.h"
-#include "Common/MemoryUtil.h"
-
-#include "Core/PowerPC/Jit64IL/JitIL.h"
-#include "Core/PowerPC/Jit64IL/JitILAsm.h"
-
-using namespace Gen;
-
-//static int temp32; // unused?
-
-//TODO - make an option
-//#if _DEBUG
-static bool enableDebug = false;
-//#else
-// bool enableDebug = false;
-//#endif
-
-//static bool enableStatistics = false; // unused?
-
-//GLOBAL STATIC ALLOCATIONS x86
-//EAX - ubiquitous scratch register - EVERYBODY scratches this
-
-//GLOBAL STATIC ALLOCATIONS x64
-//EAX - ubiquitous scratch register - EVERYBODY scratches this
-//RBX - Base pointer of memory
-//R15 - Pointer to array of block pointers
-
-JitILAsmRoutineManager jitil_asm_routines;
-
-// PLAN: no more block numbers - crazy opcodes just contain offset within
-// dynarec buffer
-// At this offset - 4, there is an int specifying the block number.
-
-void JitILAsmRoutineManager::Generate()
-{
- enterCode = AlignCode16();
- ABI_PushAllCalleeSavedRegsAndAdjustStack();
-#if _M_X86_64
- // Two statically allocated registers.
- MOV(64, R(RBX), Imm64((u64)Memory::base));
- MOV(64, R(R15), Imm64((u64)jit->GetBlockCache()->GetCodePointers())); //It's below 2GB so 32 bits are good enough
-#endif
-// INT3();
-
- const u8 *outer_loop = GetCodePtr();
- ABI_CallFunction(reinterpret_cast(&CoreTiming::Advance));
- FixupBranch skipToRealDispatch = J(); //skip the sync and compare first time
-
- dispatcher = GetCodePtr();
- //This is the place for CPUCompare!
-
- //The result of slice decrement should be in flags if somebody jumped here
- FixupBranch bail = J_CC(CC_BE, true);
-
- if (Core::g_CoreStartupParameter.bEnableDebugging)
- {
- TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(PowerPC::CPU_STEPPING));
- FixupBranch notStepping = J_CC(CC_Z);
- ABI_CallFunction(reinterpret_cast(&PowerPC::CheckBreakPoints));
- TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
- FixupBranch noBreakpoint = J_CC(CC_Z);
- ABI_PopAllCalleeSavedRegsAndAdjustStack();
- RET();
- SetJumpTarget(noBreakpoint);
- SetJumpTarget(notStepping);
- }
-
- SetJumpTarget(skipToRealDispatch);
-
- dispatcherNoCheck = GetCodePtr();
- MOV(32, R(EAX), M(&PowerPC::ppcState.pc));
- dispatcherPcInEAX = GetCodePtr();
-
- u32 mask = 0;
- FixupBranch no_mem;
- FixupBranch exit_mem;
- FixupBranch exit_vmem;
- if (Core::g_CoreStartupParameter.bWii)
- mask = JIT_ICACHE_EXRAM_BIT;
- if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack)
- mask |= JIT_ICACHE_VMEM_BIT;
- if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack)
- {
- TEST(32, R(EAX), Imm32(mask));
- no_mem = J_CC(CC_NZ);
- }
- AND(32, R(EAX), Imm32(JIT_ICACHE_MASK));
-#if _M_X86_32
- MOV(32, R(EAX), MDisp(EAX, (u32)jit->GetBlockCache()->iCache));
-#else
- MOV(64, R(RSI), Imm64((u64)jit->GetBlockCache()->iCache));
- MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
-#endif
- if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack)
- {
- exit_mem = J();
- SetJumpTarget(no_mem);
- }
- if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack)
- {
- TEST(32, R(EAX), Imm32(JIT_ICACHE_VMEM_BIT));
- FixupBranch no_vmem = J_CC(CC_Z);
- AND(32, R(EAX), Imm32(JIT_ICACHE_MASK));
-#if _M_X86_32
- MOV(32, R(EAX), MDisp(EAX, (u32)jit->GetBlockCache()->iCacheVMEM));
-#else
- MOV(64, R(RSI), Imm64((u64)jit->GetBlockCache()->iCacheVMEM));
- MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
-#endif
- if (Core::g_CoreStartupParameter.bWii) exit_vmem = J();
- SetJumpTarget(no_vmem);
- }
- if (Core::g_CoreStartupParameter.bWii)
- {
- TEST(32, R(EAX), Imm32(JIT_ICACHE_EXRAM_BIT));
- FixupBranch no_exram = J_CC(CC_Z);
- AND(32, R(EAX), Imm32(JIT_ICACHEEX_MASK));
-#if _M_X86_32
- MOV(32, R(EAX), MDisp(EAX, (u32)jit->GetBlockCache()->iCacheEx));
-#else
- MOV(64, R(RSI), Imm64((u64)jit->GetBlockCache()->iCacheEx));
- MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
-#endif
- SetJumpTarget(no_exram);
- }
- if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack)
- SetJumpTarget(exit_mem);
- if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack))
- SetJumpTarget(exit_vmem);
-
- TEST(32, R(EAX), R(EAX));
- FixupBranch notfound = J_CC(CC_L);
- //IDEA - we have 26 bits, why not just use offsets from base of code?
- if (enableDebug)
- {
- ADD(32, M(&PowerPC::ppcState.DebugCount), Imm8(1));
- }
- //grab from list and jump to it
-#if _M_X86_32
- MOV(32, R(EDX), ImmPtr(jit->GetBlockCache()->GetCodePointers()));
- JMPptr(MComplex(EDX, EAX, 4, 0));
-#else
- JMPptr(MComplex(R15, RAX, 8, 0));
-#endif
- SetJumpTarget(notfound);
-
- //Ok, no block, let's jit
-#if _M_X86_32
- ABI_AlignStack(4);
- PUSH(32, M(&PowerPC::ppcState.pc));
- CALL(reinterpret_cast(&Jit));
- ABI_RestoreStack(4);
-#else
- MOV(32, R(ABI_PARAM1), M(&PowerPC::ppcState.pc));
- CALL((void *)&Jit);
-#endif
- JMP(dispatcherNoCheck); // no point in special casing this
-
- //FP blocks test for FPU available, jump here if false
- fpException = AlignCode4();
- MOV(32, R(EAX), M(&PC));
- MOV(32, M(&NPC), R(EAX));
- LOCK();
- OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE));
- ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions));
- MOV(32, R(EAX), M(&NPC));
- MOV(32, M(&PC), R(EAX));
- JMP(dispatcher, true);
-
- SetJumpTarget(bail);
- doTiming = GetCodePtr();
-
- ABI_CallFunction(reinterpret_cast(&CoreTiming::Advance));
-
- testExceptions = GetCodePtr();
- MOV(32, R(EAX), M(&PC));
- MOV(32, M(&NPC), R(EAX));
- ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions));
- MOV(32, R(EAX), M(&NPC));
- MOV(32, M(&PC), R(EAX));
-
- TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
- J_CC(CC_Z, outer_loop, true);
- //Landing pad for drec space
- ABI_PopAllCalleeSavedRegsAndAdjustStack();
- RET();
-
- breakpointBailout = GetCodePtr();
- //Landing pad for drec space
- ABI_PopAllCalleeSavedRegsAndAdjustStack();
- RET();
-
- GenerateCommon();
-}
-
-void JitILAsmRoutineManager::GenerateCommon()
-{
- fifoDirectWrite8 = AlignCode4();
- GenFifoWrite(8);
- fifoDirectWrite16 = AlignCode4();
- GenFifoWrite(16);
- fifoDirectWrite32 = AlignCode4();
- GenFifoWrite(32);
- fifoDirectWriteFloat = AlignCode4();
- GenFifoFloatWrite();
- fifoDirectWriteXmm64 = AlignCode4();
- GenFifoXmm64Write();
-
- GenQuantizedLoads();
- GenQuantizedStores();
- GenQuantizedSingleStores();
-
- //CMPSD(R(XMM0), M(&zero),
- // TODO
-
- // Fast write routines - special case the most common hardware write
- // TODO: use this.
- // Even in x86, the param values will be in the right registers.
- /*
- const u8 *fastMemWrite8 = AlignCode16();
- CMP(32, R(ABI_PARAM2), Imm32(0xCC008000));
- FixupBranch skip_fast_write = J_CC(CC_NE, false);
- MOV(32, EAX, M(&m_gatherPipeCount));
- MOV(8, MDisp(EAX, (u32)&m_gatherPipe), ABI_PARAM1);
- ADD(32, 1, M(&m_gatherPipeCount));
- RET();
- SetJumpTarget(skip_fast_write);
- CALL((void *)&Memory::Write_U8);*/
-}
diff --git a/Source/Core/Core/PowerPC/Jit64IL/JitILAsm.h b/Source/Core/Core/PowerPC/Jit64IL/JitILAsm.h
deleted file mode 100644
index a465df88e2..0000000000
--- a/Source/Core/Core/PowerPC/Jit64IL/JitILAsm.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "Common/x64Emitter.h"
-#include "Core/PowerPC/JitCommon/JitAsmCommon.h"
-
-// In Dolphin, we don't use inline assembly. Instead, we generate all machine-near
-// code at runtime. In the case of fixed code like this, after writing it, we write
-// protect the memory, essentially making it work just like precompiled code.
-
-// There are some advantages to this approach:
-// 1) No need to setup an external assembler in the build.
-// 2) Cross platform, as long as it's x86/x64.
-// 3) Can optimize code at runtime for the specific CPU model.
-// There aren't really any disadvantages other than having to maintain a x86 emitter,
-// which we have to do anyway :)
-//
-// To add a new asm routine, just add another const here, and add the code to Generate.
-// Also, possibly increase the size of the code buffer.
-
-class JitILAsmRoutineManager : public CommonAsmRoutines
-{
-private:
- void Generate();
- void GenerateCommon();
-
-public:
- void Init() {
- AllocCodeSpace(8192);
- Generate();
- WriteProtect();
- }
-
- void Shutdown() {
- FreeCodeSpace();
- }
-};
-
-extern JitILAsmRoutineManager jitil_asm_routines;
diff --git a/Source/Core/Core/PowerPC/JitArm32/Jit.cpp b/Source/Core/Core/PowerPC/JitArm32/Jit.cpp
index 820cace463..581d79f722 100644
--- a/Source/Core/Core/PowerPC/JitArm32/Jit.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/Jit.cpp
@@ -166,17 +166,32 @@ void JitArm::WriteRfiExitDestInR(ARMReg Reg)
Cleanup();
DoDownCount();
- MOVI2R(Reg, (u32)asm_routines.testExceptions);
- B(Reg);
+ ARMReg A = gpr.GetReg(false);
+
+ LDR(A, R9, PPCSTATE_OFF(pc));
+ STR(A, R9, PPCSTATE_OFF(npc));
+ QuickCallFunction(A, (void*)&PowerPC::CheckExceptions);
+ LDR(A, R9, PPCSTATE_OFF(npc));
+ STR(A, R9, PPCSTATE_OFF(pc));
gpr.Unlock(Reg); // This was locked in the instruction beforehand
+
+ MOVI2R(A, (u32)asm_routines.dispatcher);
+ B(A);
}
void JitArm::WriteExceptionExit()
{
- ARMReg A = gpr.GetReg(false);
Cleanup();
DoDownCount();
- MOVI2R(A, (u32)asm_routines.testExceptions);
+ ARMReg A = gpr.GetReg(false);
+
+ LDR(A, R9, PPCSTATE_OFF(pc));
+ STR(A, R9, PPCSTATE_OFF(npc));
+ QuickCallFunction(A, (void*)&PowerPC::CheckExceptions);
+ LDR(A, R9, PPCSTATE_OFF(npc));
+ STR(A, R9, PPCSTATE_OFF(pc));
+
+ MOVI2R(A, (u32)asm_routines.dispatcher);
B(A);
}
void JitArm::WriteExit(u32 destination)
@@ -360,8 +375,17 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo
TST(A, Shift);
SetCC(CC_EQ);
STR(C, R9, PPCSTATE_OFF(pc));
- MOVI2R(A, (u32)asm_routines.fpException);
+
+ LDR(A, R9, PPCSTATE_OFF(Exceptions));
+ ORR(A, A, EXCEPTION_FPU_UNAVAILABLE);
+ STR(A, R9, PPCSTATE_OFF(Exceptions));
+ QuickCallFunction(A, (void*)&PowerPC::CheckExceptions);
+ LDR(A, R9, PPCSTATE_OFF(npc));
+ STR(A, R9, PPCSTATE_OFF(pc));
+
+ MOVI2R(A, (u32)asm_routines.dispatcher);
B(A);
+
SetCC();
gpr.Unlock(A, C);
}
diff --git a/Source/Core/Core/PowerPC/JitArm32/JitArm_Branch.cpp b/Source/Core/Core/PowerPC/JitArm32/JitArm_Branch.cpp
index b1b310b5ad..3ff35e90a9 100644
--- a/Source/Core/Core/PowerPC/JitArm32/JitArm_Branch.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/JitArm_Branch.cpp
@@ -138,8 +138,7 @@ void JitArm::bx(UGeckoInstruction inst)
BL(R14);
MOVI2R(R14, js.compilerPC);
STR(R14, R9, PPCSTATE_OFF(pc));
- MOVI2R(R14, (u32)asm_routines.testExceptions);
- B(R14);
+ WriteExceptionExit();
}
WriteExit(destination);
}
diff --git a/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp b/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp
index 8cec544b9d..fae765798e 100644
--- a/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp
+++ b/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp
@@ -141,17 +141,6 @@ void JitArmAsmRoutineManager::Generate()
B(dispatcherNoCheck);
- // fpException()
- // Floating Point Exception Check, Jumped to if false
- fpException = GetCodePtr();
- LDR(R0, R9, PPCSTATE_OFF(Exceptions));
- ORR(R0, R0, EXCEPTION_FPU_UNAVAILABLE);
- STR(R0, R9, PPCSTATE_OFF(Exceptions));
- QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions);
- LDR(R0, R9, PPCSTATE_OFF(npc));
- STR(R0, R9, PPCSTATE_OFF(pc));
- B(dispatcher);
-
SetJumpTarget(bail);
doTiming = GetCodePtr();
// XXX: In JIT64, Advance() gets called /after/ the exception checking
@@ -159,7 +148,6 @@ void JitArmAsmRoutineManager::Generate()
QuickCallFunction(R14, (void*)&CoreTiming::Advance);
// Does exception checking
- testExceptions = GetCodePtr();
LDR(R0, R9, PPCSTATE_OFF(pc));
STR(R0, R9, PPCSTATE_OFF(npc));
QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions);
diff --git a/Source/Core/Core/PowerPC/JitArmIL/IR_Arm.cpp b/Source/Core/Core/PowerPC/JitArmIL/IR_Arm.cpp
index d85260d15a..26d2616bdb 100644
--- a/Source/Core/Core/PowerPC/JitArmIL/IR_Arm.cpp
+++ b/Source/Core/Core/PowerPC/JitArmIL/IR_Arm.cpp
@@ -604,8 +604,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitArmIL* Jit, u32 exitAddress) {
Jit->BL(R14);
Jit->MOVI2R(R14, InstLoc);
Jit->STR(R14, R9, PPCSTATE_OFF(pc));
- Jit->MOVI2R(R14, (u32)Jit->GetAsmRoutines()->testExceptions);
- Jit->B(R14);
+ Jit->WriteExceptionExit();
break;
}
case InterpreterBranch: {
diff --git a/Source/Core/Core/PowerPC/JitArmIL/JitIL.cpp b/Source/Core/Core/PowerPC/JitArmIL/JitIL.cpp
index 9b8785111e..23507c1d9b 100644
--- a/Source/Core/Core/PowerPC/JitArmIL/JitIL.cpp
+++ b/Source/Core/Core/PowerPC/JitArmIL/JitIL.cpp
@@ -111,15 +111,28 @@ void JitArmIL::WriteRfiExitDestInR(ARMReg Reg)
{
STR(Reg, R9, PPCSTATE_OFF(pc));
DoDownCount();
- MOVI2R(Reg, (u32)asm_routines.testExceptions);
- B(Reg);
+
+ LDR(R0, R9, PPCSTATE_OFF(pc));
+ STR(R0, R9, PPCSTATE_OFF(npc));
+ QuickCallFunction(R0, (void*)&PowerPC::CheckExceptions);
+ LDR(R0, R9, PPCSTATE_OFF(npc));
+ STR(R0, R9, PPCSTATE_OFF(pc));
+
+ MOVI2R(R0, (u32)asm_routines.dispatcher);
+ B(R0);
}
void JitArmIL::WriteExceptionExit()
{
DoDownCount();
- MOVI2R(R14, (u32)asm_routines.testExceptions);
- B(R14);
+ LDR(R0, R9, PPCSTATE_OFF(pc));
+ STR(R0, R9, PPCSTATE_OFF(npc));
+ QuickCallFunction(R0, (void*)&PowerPC::CheckExceptions);
+ LDR(R0, R9, PPCSTATE_OFF(npc));
+ STR(R0, R9, PPCSTATE_OFF(pc));
+
+ MOVI2R(R0, (u32)asm_routines.dispatcher);
+ B(R0);
}
void JitArmIL::WriteExit(u32 destination)
{
diff --git a/Source/Core/Core/PowerPC/JitArmIL/JitILAsm.cpp b/Source/Core/Core/PowerPC/JitArmIL/JitILAsm.cpp
index 72f76ec001..56e2ce1d67 100644
--- a/Source/Core/Core/PowerPC/JitArmIL/JitILAsm.cpp
+++ b/Source/Core/Core/PowerPC/JitArmIL/JitILAsm.cpp
@@ -73,17 +73,6 @@ void JitArmILAsmRoutineManager::Generate()
B(dispatcherNoCheck);
- // fpException()
- // Floating Point Exception Check, Jumped to if false
- fpException = GetCodePtr();
- LDR(R0, R9, PPCSTATE_OFF(Exceptions));
- ORR(R0, R0, EXCEPTION_FPU_UNAVAILABLE);
- STR(R0, R9, PPCSTATE_OFF(Exceptions));
- QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions);
- LDR(R0, R9, PPCSTATE_OFF(npc));
- STR(R0, R9, PPCSTATE_OFF(pc));
- B(dispatcher);
-
SetJumpTarget(bail);
doTiming = GetCodePtr();
// XXX: In JIT64, Advance() gets called /after/ the exception checking
@@ -91,7 +80,6 @@ void JitArmILAsmRoutineManager::Generate()
QuickCallFunction(R14, (void*)&CoreTiming::Advance);
// Does exception checking
- testExceptions = GetCodePtr();
LDR(R0, R9, PPCSTATE_OFF(pc));
STR(R0, R9, PPCSTATE_OFF(npc));
QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions);
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitAsmCommon.h b/Source/Core/Core/PowerPC/JitCommon/JitAsmCommon.h
index 5d6e92a078..72a8675a44 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitAsmCommon.h
+++ b/Source/Core/Core/PowerPC/JitCommon/JitAsmCommon.h
@@ -23,8 +23,6 @@ public:
const u8 *dispatcherNoCheck;
const u8 *dispatcherPcInEAX;
- const u8 *fpException;
- const u8 *testExceptions;
const u8 *testExternalExceptions;
const u8 *dispatchPcInEAX;
const u8 *doTiming;
diff --git a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_SystemRegisters.cpp
index 1188cf1aa3..bc0eac6cc7 100644
--- a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_SystemRegisters.cpp
+++ b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_SystemRegisters.cpp
@@ -148,7 +148,8 @@ void JitILBase::mcrf(UGeckoInstruction inst)
void JitILBase::crXX(UGeckoInstruction inst)
{
- // Ported from Jit_SystemRegister.cpp
+ INSTRUCTION_START
+ JITDISABLE(bJITSystemRegistersOff)
// Get bit CRBA in EAX aligned with bit CRBD
const int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3);