diff options
| author | bushing <bushing@gmail.com> | 2008-12-08 05:30:24 +0000 |
|---|---|---|
| committer | bushing <bushing@gmail.com> | 2008-12-08 05:30:24 +0000 |
| commit | 49cfded60bb5b444d1828190eacc52bbb49a9cb8 (patch) | |
| tree | 0823218c1f2f6eec307dadbdec18c5632625f052 /Source/Core/Common/Src/Thunk.cpp | |
| parent | 901fe7c00fec5e2aaf55d184edbcb6d092345d52 (diff) | |
set svn:eol-style=native for **.cpp
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1442 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/Common/Src/Thunk.cpp')
| -rw-r--r-- | Source/Core/Common/Src/Thunk.cpp | 306 |
1 files changed, 153 insertions, 153 deletions
diff --git a/Source/Core/Common/Src/Thunk.cpp b/Source/Core/Common/Src/Thunk.cpp index 73ad098090..a5ba2c9b8d 100644 --- a/Source/Core/Common/Src/Thunk.cpp +++ b/Source/Core/Common/Src/Thunk.cpp @@ -1,153 +1,153 @@ -// Copyright (C) 2003-2008 Dolphin Project.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 2.0.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License 2.0 for more details.
-
-// A copy of the GPL 2.0 should have been included with the program.
-// If not, see http://www.gnu.org/licenses/
-
-// Official SVN repository and contact information can be found at
-// http://code.google.com/p/dolphin-emu/
-
-#include <map>
-
-#include "Common.h"
-#include "Thunk.h"
-#include "x64Emitter.h"
-#include "MemoryUtil.h"
-#include "ABI.h"
-
-using namespace Gen;
-
-#define THUNK_ARENA_SIZE 1024*1024*1
-
-namespace {
-static std::map<void *, const u8 *> thunks;
-u8 GC_ALIGNED32(saved_fp_state[16 * 4 * 4]);
-u8 GC_ALIGNED32(saved_gpr_state[16 * 8]);
-
-static u8 *thunk_memory;
-static u8 *thunk_code;
-static const u8 *save_regs;
-static const u8 *load_regs;
-static u16 saved_mxcsr;
-}
-
-void Thunk_Init()
-{
- thunk_memory = (u8 *)AllocateExecutableMemory(THUNK_ARENA_SIZE);
- thunk_code = thunk_memory;
-
- GenContext ctx(&thunk_code);
- 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 Thunk_Reset()
-{
- thunks.clear();
- thunk_code = thunk_memory;
-}
-
-void Thunk_Shutdown()
-{
- Thunk_Reset();
- FreeMemoryPages(thunk_memory, THUNK_ARENA_SIZE);
- thunk_memory = 0;
- thunk_code = 0;
-}
-
-void *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 (!thunk_memory)
- PanicAlert("Trying to protect functions before the emu is started. Bad bad bad.");
-
- GenContext gen(&thunk_code);
- const u8 *call_point = GetCodePtr();
- // Make sure to align stack.
-#ifdef _M_X64
-#ifdef _WIN32
- SUB(64, R(ESP), Imm8(0x28));
-#else
- SUB(64, R(ESP), Imm8(0x8));
-#endif
- CALL((void*)save_regs);
- CALL((void*)function);
- CALL((void*)load_regs);
-#ifdef _WIN32
- ADD(64, R(ESP), Imm8(0x28));
-#else
- ADD(64, R(ESP), Imm8(0x8));
-#endif
- 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);
- unsigned int alignedSize = ABI_GetAlignedFrameSize(num_params * 4);
- for (int i = 0; i < num_params; i++) {
- // ESP is changing, so we do not need i
- PUSH(32, MDisp(ESP, alignedSize - 4));
- }
- CALL(function);
- ABI_RestoreStack(num_params * 4);
- CALL((void*)load_regs);
- RET();
-#endif
-
- thunks[function] = call_point;
- return (void *)call_point;
-}
+// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include <map> + +#include "Common.h" +#include "Thunk.h" +#include "x64Emitter.h" +#include "MemoryUtil.h" +#include "ABI.h" + +using namespace Gen; + +#define THUNK_ARENA_SIZE 1024*1024*1 + +namespace { +static std::map<void *, const u8 *> thunks; +u8 GC_ALIGNED32(saved_fp_state[16 * 4 * 4]); +u8 GC_ALIGNED32(saved_gpr_state[16 * 8]); + +static u8 *thunk_memory; +static u8 *thunk_code; +static const u8 *save_regs; +static const u8 *load_regs; +static u16 saved_mxcsr; +} + +void Thunk_Init() +{ + thunk_memory = (u8 *)AllocateExecutableMemory(THUNK_ARENA_SIZE); + thunk_code = thunk_memory; + + GenContext ctx(&thunk_code); + 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 Thunk_Reset() +{ + thunks.clear(); + thunk_code = thunk_memory; +} + +void Thunk_Shutdown() +{ + Thunk_Reset(); + FreeMemoryPages(thunk_memory, THUNK_ARENA_SIZE); + thunk_memory = 0; + thunk_code = 0; +} + +void *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 (!thunk_memory) + PanicAlert("Trying to protect functions before the emu is started. Bad bad bad."); + + GenContext gen(&thunk_code); + const u8 *call_point = GetCodePtr(); + // Make sure to align stack. +#ifdef _M_X64 +#ifdef _WIN32 + SUB(64, R(ESP), Imm8(0x28)); +#else + SUB(64, R(ESP), Imm8(0x8)); +#endif + CALL((void*)save_regs); + CALL((void*)function); + CALL((void*)load_regs); +#ifdef _WIN32 + ADD(64, R(ESP), Imm8(0x28)); +#else + ADD(64, R(ESP), Imm8(0x8)); +#endif + 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); + unsigned int alignedSize = ABI_GetAlignedFrameSize(num_params * 4); + for (int i = 0; i < num_params; i++) { + // ESP is changing, so we do not need i + PUSH(32, MDisp(ESP, alignedSize - 4)); + } + CALL(function); + ABI_RestoreStack(num_params * 4); + CALL((void*)load_regs); + RET(); +#endif + + thunks[function] = call_point; + return (void *)call_point; +} |
