mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-08-26 07:25:14 +02:00
Port the x86 and ARM emitters over to use the generic CodeBlock class
This commit is contained in:
+2
-26
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-47
@@ -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<ARMXEmitter> {
|
||||
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
|
||||
|
||||
+13
-1
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-18
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-43
@@ -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<XEmitter> {
|
||||
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
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
|
||||
@@ -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<u32, int> proxyBlockMap_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user