From 4ec30d98e191bdb43d3922b6dadd58cf4ab8aabc Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 15 Dec 2014 22:32:55 +0100 Subject: [PATCH] Port the x86 and ARM emitters over to use the generic CodeBlock class --- Common/ArmEmitter.cpp | 28 ++------------- Common/ArmEmitter.h | 50 ++------------------------- Common/CodeBlock.h | 14 +++++++- Common/MipsEmitter.h | 2 -- Common/ppcEmitter.h | 3 -- Common/x64Emitter.cpp | 19 +--------- Common/x64Emitter.h | 46 ++---------------------- Core/MIPS/JitCommon/JitBlockCache.cpp | 2 +- Core/MIPS/JitCommon/JitBlockCache.h | 14 ++++---- 9 files changed, 30 insertions(+), 148 deletions(-) diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index 2d55b8dffa..05664def00 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -3147,36 +3147,12 @@ void ARMXEmitter::VCVTF16F32(ARMReg Dest, ARMReg Src) { Write32((0xF3B6 << 16) | ((Dest & 0x10) << 18) | ((Dest & 0xF) << 12) | 0x600 | (op << 8) | ((Src & 0x10) << 1) | (Src & 0xF)); } -void ARMXCodeBlock::AllocCodeSpace(int size) { - region_size = size; - region = (u8*)AllocateExecutableMemory(region_size); - SetCodePtr(region); -} - // Always clear code space with breakpoints, so that if someone accidentally executes // uninitialized, it just breaks into the debugger. -void ARMXCodeBlock::ClearCodeSpace() { - // x86/64: 0xCC = breakpoint +void ARMXCodeBlock::PoisonMemory() { + // TODO: this isn't right for ARM! memset(region, 0xCC, region_size); ResetCodePtr(); } -void ARMXCodeBlock::FreeCodeSpace() { -#ifdef __SYMBIAN32__ - ResetExecutableMemory(region); -#else - FreeMemoryPages(region, region_size); -#endif - region = NULL; - region_size = 0; -} - -void ARMXCodeBlock::WriteProtect() { - WriteProtectMemory(region, region_size, true); -} - -void ARMXCodeBlock::UnWriteProtect() { - UnWriteProtectMemory(region, region_size, false); -} - } diff --git a/Common/ArmEmitter.h b/Common/ArmEmitter.h index e272e84429..9bf92b8993 100644 --- a/Common/ArmEmitter.h +++ b/Common/ArmEmitter.h @@ -15,8 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -// WARNING - THIS LIBRARY IS NOT THREAD SAFE!!! - #ifndef _DOLPHIN_ARM_CODEGEN_ #define _DOLPHIN_ARM_CODEGEN_ @@ -25,6 +23,7 @@ #include "Common.h" #include "ArmCommon.h" +#include "CodeBlock.h" #include "MsgHandler.h" // TODO: Check if Pandora still needs signal.h/kill here. Symbian doesn't. @@ -887,53 +886,10 @@ public: // Everything that needs to generate machine code should inherit from this. // You get memory management for free, plus, you can use all the MOV etc functions without // having to prefix them with gen-> or something similar. -class ARMXCodeBlock : public ARMXEmitter -{ -protected: - u8 *region; - size_t region_size; +class ARMXCodeBlock : public CodeBlock { public: - ARMXCodeBlock() : region(NULL), region_size(0) {} - virtual ~ARMXCodeBlock() { if (region) FreeCodeSpace(); } - - // Call this before you generate any code. - void AllocCodeSpace(int size); - - // Always clear code space with breakpoints, so that if someone accidentally executes - // uninitialized, it just breaks into the debugger. - void ClearCodeSpace(); - - // Call this when shutting down. Don't rely on the destructor, even though it'll do the job. - void FreeCodeSpace(); - - bool IsInSpace(const u8 *ptr) const - { - return ptr >= region && ptr < region + region_size; - } - - // Cannot currently be undone. Will write protect the entire code region. - // Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()). - void WriteProtect(); - void UnWriteProtect(); - - void ResetCodePtr() - { - SetCodePtr(region); - } - - size_t GetSpaceLeft() const - { - return region_size - (GetCodePtr() - region); - } - - u8 *GetBasePtr() { - return region; - } - - size_t GetOffset(const u8 *ptr) const { - return ptr - region; - } + void PoisonMemory() override; }; // VFP Specific diff --git a/Common/CodeBlock.h b/Common/CodeBlock.h index 2bd2260e93..ea8937b046 100644 --- a/Common/CodeBlock.h +++ b/Common/CodeBlock.h @@ -46,12 +46,16 @@ public: // Call this when shutting down. Don't rely on the destructor, even though it'll do the job. void FreeCodeSpace() { +#ifdef __SYMBIAN32__ + ResetExecutableMemory(region); +#else FreeMemoryPages(region, region_size); +#endif region = nullptr; region_size = 0; } - bool IsInSpace(u8 *ptr) + bool IsInSpace(const u8 *ptr) { return (ptr >= region) && (ptr < (region + region_size)); } @@ -72,5 +76,13 @@ public: { return region_size - (T::GetCodePtr() - region); } + + u8 *GetBasePtr() { + return region; + } + + size_t GetOffset(const u8 *ptr) const { + return ptr - region; + } }; diff --git a/Common/MipsEmitter.h b/Common/MipsEmitter.h index 14fdaba24c..e9dd06c3d0 100644 --- a/Common/MipsEmitter.h +++ b/Common/MipsEmitter.h @@ -15,8 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -// WARNING - THIS LIBRARY IS NOT THREAD SAFE!!! (cargo culted but probably true) - #pragma once // Symbian can't build this due to an old gcc/lib combination, and doesn't need to. // Kind programmer, if you want to translate this to a proper feature-detection diff --git a/Common/ppcEmitter.h b/Common/ppcEmitter.h index 425a9e5d1e..3ed650254f 100644 --- a/Common/ppcEmitter.h +++ b/Common/ppcEmitter.h @@ -15,9 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -// WARNING - THIS LIBRARY IS NOT THREAD SAFE!!! - - // http://www.csd.uwo.ca/~mburrel/stuff/ppc-asm.html // http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.aixassem/doc/alangref/linkage_convent.htm // http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.aixassem/doc/alangref/instruction_set.htm diff --git a/Common/x64Emitter.cpp b/Common/x64Emitter.cpp index d0b376d460..cd749ea912 100644 --- a/Common/x64Emitter.cpp +++ b/Common/x64Emitter.cpp @@ -1970,26 +1970,9 @@ void XEmitter::FNSTSW_AX() { Write8(0xDF); Write8(0xE0); } void XEmitter::RDTSC() { Write8(0x0F); Write8(0x31); } -void XCodeBlock::AllocCodeSpace(int size) { - region_size = size; - region = (u8*)AllocateExecutableMemory(region_size); - SetCodePtr(region); -} - -void XCodeBlock::ClearCodeSpace() { +void XCodeBlock::PoisonMemory() { // x86/64: 0xCC = breakpoint memset(region, 0xCC, region_size); - ResetCodePtr(); -} - -void XCodeBlock::FreeCodeSpace() { - FreeMemoryPages(region, region_size); - region = NULL; - region_size = 0; -} - -void XCodeBlock::WriteProtect() { - WriteProtectMemory(region, region_size, true); } } diff --git a/Common/x64Emitter.h b/Common/x64Emitter.h index fb1c2c5027..b0ab74fcd8 100644 --- a/Common/x64Emitter.h +++ b/Common/x64Emitter.h @@ -15,12 +15,11 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -// WARNING - THIS LIBRARY IS NOT THREAD SAFE!!! - #ifndef _DOLPHIN_INTEL_CODEGEN_ #define _DOLPHIN_INTEL_CODEGEN_ #include "Common.h" +#include "CodeBlock.h" #if defined(_M_X64) && !defined(_ARCH_64) #define _ARCH_64 @@ -1041,49 +1040,10 @@ public: // Everything that needs to generate X86 code should inherit from this. // You get memory management for free, plus, you can use all the MOV etc functions without // having to prefix them with gen-> or something similar. -class XCodeBlock : public XEmitter -{ -protected: - u8 *region; - size_t region_size; +class XCodeBlock : public CodeBlock { public: - XCodeBlock() : region(NULL), region_size(0) {} - virtual ~XCodeBlock() { if (region) FreeCodeSpace(); } - - // Call this before you generate any code. - void AllocCodeSpace(int size); - - // Always clear code space with breakpoints, so that if someone accidentally executes - // uninitialized, it just breaks into the debugger. - void ClearCodeSpace(); - - // Call this when shutting down. Don't rely on the destructor, even though it'll do the job. - void FreeCodeSpace(); - - bool IsInSpace(const u8 *ptr) const { - return ptr >= region && ptr < region + region_size; - } - - // Cannot currently be undone. Will write protect the entire code region. - // Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()). - void WriteProtect(); - - void ResetCodePtr() { - SetCodePtr(region); - } - - size_t GetSpaceLeft() const { - return region_size - (GetCodePtr() - region); - } - - u8 *GetBasePtr() { - return region; - } - - size_t GetOffset(const u8 *ptr) const { - return ptr - region; - } + void PoisonMemory() override; }; } // namespace diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index 93d6cbed7a..8082263d07 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -79,7 +79,7 @@ using namespace Gen; const u32 INVALID_EXIT = 0xFFFFFFFF; const MIPSOpcode INVALID_ORIGINAL_OP = MIPSOpcode(0x00000001); -JitBlockCache::JitBlockCache(MIPSState *mips, CodeBlock *codeBlock) : +JitBlockCache::JitBlockCache(MIPSState *mips, NativeCodeBlock *codeBlock) : mips_(mips), codeBlock_(codeBlock), blocks_(0), num_blocks_(0) { } diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 3ea899a77d..937874cd13 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -37,24 +37,24 @@ namespace std { #if defined(ARM) #include "Common/ArmEmitter.h" namespace ArmGen { class ARMXEmitter; } -typedef ArmGen::ARMXCodeBlock CodeBlock; +typedef ArmGen::ARMXCodeBlock NativeCodeBlock; #elif defined(_M_IX86) || defined(_M_X64) #include "Common/x64Emitter.h" namespace Gen { class XEmitter; } -typedef Gen::XCodeBlock CodeBlock; +typedef Gen::XCodeBlock NativeCodeBlock; #elif defined(PPC) #include "Common/ppcEmitter.h" namespace PpcGen { class PPCXEmitter; } -typedef PpcGen::PPCXCodeBlock CodeBlock; +typedef PpcGen::PPCXCodeBlock NativeCodeBlock; #elif defined(MIPS) #include "Common/MipsEmitter.h" namespace MIPSGen { class MIPSEmitter; } -typedef MIPSGen::MIPSCodeBlock CodeBlock; +typedef MIPSGen::MIPSCodeBlock NativeCodeBlock; #else #warning "Unsupported arch!" #include "Common/FakeEmitter.h" namespace FakeGen { class FakeXEmitter; } -typedef FakeGen::FakeXCodeBlock CodeBlock; +typedef FakeGen::FakeXCodeBlock NativeCodeBlock; #endif #if defined(ARM) @@ -108,7 +108,7 @@ typedef void (*CompiledCode)(); class JitBlockCache { public: - JitBlockCache(MIPSState *mips_, CodeBlock *codeBlock); + JitBlockCache(MIPSState *mips_, NativeCodeBlock *codeBlock); ~JitBlockCache(); int AllocateBlock(u32 em_address); @@ -171,7 +171,7 @@ private: MIPSOpcode GetEmuHackOpForBlock(int block_num) const; MIPSState *mips_; - CodeBlock *codeBlock_; + NativeCodeBlock *codeBlock_; JitBlock *blocks_; std::unordered_multimap proxyBlockMap_;