summaryrefslogtreecommitdiff
path: root/Source/Core/Common
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/Common')
-rw-r--r--Source/Core/Common/CMakeLists.txt1
-rw-r--r--Source/Core/Common/Common.vcxproj2
-rw-r--r--Source/Core/Common/Common.vcxproj.filters2
-rw-r--r--Source/Core/Common/Src/Thunk.h46
-rw-r--r--Source/Core/Common/Src/x64ABI.cpp80
-rw-r--r--Source/Core/Common/Src/x64Emitter.cpp68
-rw-r--r--Source/Core/Common/Src/x64Emitter.h7
-rw-r--r--Source/Core/Common/Src/x64Thunk.cpp121
8 files changed, 84 insertions, 243 deletions
diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt
index 6e230c7fa7..0302ee78c8 100644
--- a/Source/Core/Common/CMakeLists.txt
+++ b/Source/Core/Common/CMakeLists.txt
@@ -37,7 +37,6 @@ else()
if(NOT _M_GENERIC) #X86
set(SRCS ${SRCS}
Src/x64FPURoundMode.cpp
- Src/x64Thunk.cpp
)
endif()
set(SRCS ${SRCS} Src/x64CPUDetect.cpp)
diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj
index 4066febcca..20cf92dfc3 100644
--- a/Source/Core/Common/Common.vcxproj
+++ b/Source/Core/Common/Common.vcxproj
@@ -217,7 +217,6 @@
<ClCompile Include="Src\x64CPUDetect.cpp" />
<ClCompile Include="Src\x64Emitter.cpp" />
<ClCompile Include="Src\x64FPURoundMode.cpp" />
- <ClCompile Include="Src\x64Thunk.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\Atomic.h" />
@@ -263,7 +262,6 @@
<ClInclude Include="Src\SymbolDB.h" />
<ClInclude Include="Src\SysConf.h" />
<ClInclude Include="Src\Thread.h" />
- <ClInclude Include="Src\Thunk.h" />
<ClInclude Include="Src\Timer.h" />
<ClInclude Include="Src\x64ABI.h" />
<ClInclude Include="Src\x64Analyzer.h" />
diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters
index a912cc3d8a..05b9edcb14 100644
--- a/Source/Core/Common/Common.vcxproj.filters
+++ b/Source/Core/Common/Common.vcxproj.filters
@@ -47,7 +47,6 @@
<ClCompile Include="Src\x64ABI.cpp" />
<ClCompile Include="Src\x64CPUDetect.cpp" />
<ClCompile Include="Src\x64FPURoundMode.cpp" />
- <ClCompile Include="Src\x64Thunk.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\Atomic.h" />
@@ -84,7 +83,6 @@
<ClInclude Include="Src\SymbolDB.h" />
<ClInclude Include="Src\SysConf.h" />
<ClInclude Include="Src\Thread.h" />
- <ClInclude Include="Src\Thunk.h" />
<ClInclude Include="Src\Timer.h" />
<ClInclude Include="Src\x64Analyzer.h" />
<ClInclude Include="Src\x64Emitter.h" />
diff --git a/Source/Core/Common/Src/Thunk.h b/Source/Core/Common/Src/Thunk.h
deleted file mode 100644
index b1487badf8..0000000000
--- a/Source/Core/Common/Src/Thunk.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#ifndef _THUNK_H_
-#define _THUNK_H_
-
-#include <map>
-
-#include "Common.h"
-#include "x64Emitter.h"
-
-// This simple class creates a wrapper around a C/C++ function that saves all fp state
-// before entering it, and restores it upon exit. This is required to be able to selectively
-// call functions from generated code, without inflicting the performance hit and increase
-// of complexity that it means to protect the generated code from this problem.
-
-// This process is called thunking.
-
-// There will only ever be one level of thunking on the stack, plus,
-// we don't want to pollute the stack, so we store away regs somewhere global.
-// NOT THREAD SAFE. This may only be used from the CPU thread.
-// Any other thread using this stuff will be FATAL.
-
-class ThunkManager : public Gen::XCodeBlock
-{
- std::map<void *, const u8 *> thunks;
-
- const u8 *save_regs;
- const u8 *load_regs;
-
-public:
- ThunkManager() {
- Init();
- }
- ~ThunkManager() {
- Shutdown();
- }
- void *ProtectFunction(void *function, int num_params);
-private:
- void Init();
- void Shutdown();
- void Reset();
-};
-
-#endif // _THUNK_H_
diff --git a/Source/Core/Common/Src/x64ABI.cpp b/Source/Core/Common/Src/x64ABI.cpp
index 54d19c7775..3750636c3e 100644
--- a/Source/Core/Common/Src/x64ABI.cpp
+++ b/Source/Core/Common/Src/x64ABI.cpp
@@ -57,6 +57,86 @@ void XEmitter::ABI_RestoreStack(unsigned int frameSize, bool noProlog) {
}
}
+void XEmitter::ABI_PushRegistersAndAdjustStack(u32 mask, bool noProlog)
+{
+ int regSize =
+#ifdef _M_X64
+ 8;
+#else
+ 4;
+#endif
+ int shadow = 0;
+#if defined(_WIN32) && defined(_M_X64)
+ shadow = 0x20;
+#endif
+ int count = 0;
+ for (int r = 0; r < 16; r++)
+ {
+ if (mask & (1 << r))
+ {
+ PUSH((X64Reg) r);
+ count++;
+ }
+ }
+ int size = ((noProlog ? -regSize : 0) - (count * regSize)) & 0xf;
+ for (int x = 0; x < 16; x++)
+ {
+ if (mask & (1 << (16 + x)))
+ size += 16;
+ }
+ size += shadow;
+ if (size)
+ SUB(regSize * 8, R(RSP), size >= 0x80 ? Imm32(size) : Imm8(size));
+ int offset = shadow;
+ for (int x = 0; x < 16; x++)
+ {
+ if (mask & (1 << (16 + x)))
+ {
+ MOVAPD(MDisp(RSP, offset), (X64Reg) x);
+ offset += 16;
+ }
+ }
+}
+
+void XEmitter::ABI_PopRegistersAndAdjustStack(u32 mask, bool noProlog)
+{
+ int regSize =
+#ifdef _M_X64
+ 8;
+#else
+ 4;
+#endif
+ int size = 0;
+#if defined(_WIN32) && defined(_M_X64)
+ size += 0x20;
+#endif
+ for (int x = 0; x < 16; x++)
+ {
+ if (mask & (1 << (16 + x)))
+ {
+ MOVAPD((X64Reg) x, MDisp(RSP, size));
+ size += 16;
+ }
+ }
+ int count = 0;
+ for (int r = 0; r < 16; r++)
+ {
+ if (mask & (1 << r))
+ count++;
+ }
+ size += ((noProlog ? -regSize : 0) - (count * regSize)) & 0xf;
+
+ if (size)
+ ADD(regSize * 8, R(RSP), size >= 0x80 ? Imm32(size) : Imm8(size));
+ for (int r = 15; r >= 0; r--)
+ {
+ if (mask & (1 << r))
+ {
+ POP((X64Reg) r);
+ }
+ }
+}
+
#ifdef _M_IX86 // All32
// Shared code between Win32 and Unix32
diff --git a/Source/Core/Common/Src/x64Emitter.cpp b/Source/Core/Common/Src/x64Emitter.cpp
index 9b6731856f..a5d7cb2f0f 100644
--- a/Source/Core/Common/Src/x64Emitter.cpp
+++ b/Source/Core/Common/Src/x64Emitter.cpp
@@ -1634,74 +1634,6 @@ void XEmitter::___CallCdeclImport6(void* impptr, u32 arg0, u32 arg1, u32 arg2, u
CALLptr(M(impptr));
}
-void XEmitter::PushRegistersAndAlignStack(u32 mask)
-{
- int shadow = 0;
-#ifdef _WIN32
- shadow = 0x20;
-#endif
- int count = 0;
- for (int r = 0; r < 16; r++)
- {
- if (mask & (1 << r))
- {
- PUSH((X64Reg) r);
- count++;
- }
- }
- int size = (count & 1) ? 0 : 8;
- for (int x = 0; x < 16; x++)
- {
- if (mask & (1 << (16 + x)))
- size += 16;
- }
- size += shadow;
- if (size)
- SUB(64, R(RSP), size >= 0x80 ? Imm32(size) : Imm8(size));
- int offset = shadow;
- for (int x = 0; x < 16; x++)
- {
- if (mask & (1 << (16 + x)))
- {
- MOVAPD(MDisp(RSP, offset), (X64Reg) x);
- offset += 16;
- }
- }
-}
-
-void XEmitter::PopRegistersAndAlignStack(u32 mask)
-{
- int size = 0;
-#ifdef _WIN32
- size += 0x20;
-#endif
- for (int x = 0; x < 16; x++)
- {
- if (mask & (1 << (16 + x)))
- {
- MOVAPD((X64Reg) x, MDisp(RSP, size));
- size += 16;
- }
- }
- int count = 0;
- for (int r = 0; r < 16; r++)
- {
- if (mask & (1 << r))
- count++;
- }
- size += (count & 1) ? 0 : 8;
-
- if (size)
- ADD(64, R(RSP), size >= 0x80 ? Imm32(size) : Imm8(size));
- for (int r = 15; r >= 0; r--)
- {
- if (mask & (1 << r))
- {
- POP((X64Reg) r);
- }
- }
-}
-
#endif
}
diff --git a/Source/Core/Common/Src/x64Emitter.h b/Source/Core/Common/Src/x64Emitter.h
index 87724a8092..94938b290a 100644
--- a/Source/Core/Common/Src/x64Emitter.h
+++ b/Source/Core/Common/Src/x64Emitter.h
@@ -646,6 +646,10 @@ public:
void ABI_PushAllCalleeSavedRegsAndAdjustStack();
void ABI_PopAllCalleeSavedRegsAndAdjustStack();
+ // A more flexible version of the above.
+ void ABI_PushRegistersAndAdjustStack(u32 mask, bool noProlog);
+ void ABI_PopRegistersAndAdjustStack(u32 mask, bool noProlog);
+
unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize, bool noProlog = false);
void ABI_AlignStack(unsigned int frameSize, bool noProlog = false);
void ABI_RestoreStack(unsigned int frameSize, bool noProlog = false);
@@ -691,9 +695,6 @@ public:
#define DECLARE_IMPORT(x) extern "C" void *__imp_##x
- void PushRegistersAndAlignStack(u32 mask);
- void PopRegistersAndAlignStack(u32 mask);
-
#endif
}; // class XEmitter
diff --git a/Source/Core/Common/Src/x64Thunk.cpp b/Source/Core/Common/Src/x64Thunk.cpp
deleted file mode 100644
index d77d78e40e..0000000000
--- a/Source/Core/Common/Src/x64Thunk.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#include <map>
-
-#include "Common.h"
-#include "MemoryUtil.h"
-#include "x64ABI.h"
-#include "Thunk.h"
-
-#define THUNK_ARENA_SIZE 1024*1024*1
-
-namespace
-{
-
-static u8 GC_ALIGNED32(saved_fp_state[16 * 4 * 4]);
-static u8 GC_ALIGNED32(saved_gpr_state[16 * 8]);
-static u16 saved_mxcsr;
-
-} // namespace
-
-using namespace Gen;
-
-void ThunkManager::Init()
-{
- AllocCodeSpace(THUNK_ARENA_SIZE);
- save_regs = GetCodePtr();
- for (int i = 2; i < ABI_GetNumXMMRegs(); i++)
- MOVAPS(M(saved_fp_state + i * 16), (X64Reg)(XMM0 + i));
- STMXCSR(M(&saved_mxcsr));
-#ifdef _M_X64
- MOV(64, M(saved_gpr_state + 0 ), R(RCX));
- MOV(64, M(saved_gpr_state + 8 ), R(RDX));
- MOV(64, M(saved_gpr_state + 16), R(R8) );
- MOV(64, M(saved_gpr_state + 24), R(R9) );
- MOV(64, M(saved_gpr_state + 32), R(R10));
- MOV(64, M(saved_gpr_state + 40), R(R11));
-#ifndef _WIN32
- MOV(64, M(saved_gpr_state + 48), R(RSI));
- MOV(64, M(saved_gpr_state + 56), R(RDI));
-#endif
- MOV(64, M(saved_gpr_state + 64), R(RBX));
-#else
- MOV(32, M(saved_gpr_state + 0 ), R(RCX));
- MOV(32, M(saved_gpr_state + 4 ), R(RDX));
-#endif
- RET();
- load_regs = GetCodePtr();
- LDMXCSR(M(&saved_mxcsr));
- for (int i = 2; i < ABI_GetNumXMMRegs(); i++)
- MOVAPS((X64Reg)(XMM0 + i), M(saved_fp_state + i * 16));
-#ifdef _M_X64
- MOV(64, R(RCX), M(saved_gpr_state + 0 ));
- MOV(64, R(RDX), M(saved_gpr_state + 8 ));
- MOV(64, R(R8) , M(saved_gpr_state + 16));
- MOV(64, R(R9) , M(saved_gpr_state + 24));
- MOV(64, R(R10), M(saved_gpr_state + 32));
- MOV(64, R(R11), M(saved_gpr_state + 40));
-#ifndef _WIN32
- MOV(64, R(RSI), M(saved_gpr_state + 48));
- MOV(64, R(RDI), M(saved_gpr_state + 56));
-#endif
- MOV(64, R(RBX), M(saved_gpr_state + 64));
-#else
- MOV(32, R(RCX), M(saved_gpr_state + 0 ));
- MOV(32, R(RDX), M(saved_gpr_state + 4 ));
-#endif
- RET();
-}
-
-void ThunkManager::Reset()
-{
- thunks.clear();
- ResetCodePtr();
-}
-
-void ThunkManager::Shutdown()
-{
- Reset();
- FreeCodeSpace();
-}
-
-void *ThunkManager::ProtectFunction(void *function, int num_params)
-{
- std::map<void *, const u8 *>::iterator iter;
- iter = thunks.find(function);
- if (iter != thunks.end())
- return (void *)iter->second;
- if (!region)
- PanicAlert("Trying to protect functions before the emu is started. Bad bad bad.");
-
- const u8 *call_point = GetCodePtr();
-#ifdef _M_X64
- // Make sure to align stack.
- ABI_AlignStack(0, true);
- CALL((void*)save_regs);
- CALL((void*)function);
- CALL((void*)load_regs);
- ABI_RestoreStack(0, true);
- RET();
-#else
- CALL((void*)save_regs);
- // Since parameters are in the previous stack frame, not in registers, this takes some
- // trickery : we simply re-push the parameters. might not be optimal, but that doesn't really
- // matter.
- ABI_AlignStack(num_params * 4, true);
- unsigned int alignedSize = ABI_GetAlignedFrameSize(num_params * 4, true);
- for (int i = 0; i < num_params; i++) {
- // ESP is changing, so we do not need i
- PUSH(32, MDisp(ESP, alignedSize));
- }
- CALL(function);
- ABI_RestoreStack(num_params * 4, true);
- CALL((void*)load_regs);
- RET();
-#endif
-
- thunks[function] = call_point;
- return (void *)call_point;
-}