mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-01 14:24:02 +00:00
indentation
This commit is contained in:
parent
c4c43655aa
commit
3eb1696e09
@ -38,343 +38,343 @@
|
||||
|
||||
namespace PpcGen
|
||||
{
|
||||
enum PPCReg
|
||||
{
|
||||
// GPRs (32)
|
||||
// Behaves as zero does in some instructions
|
||||
R0 = 0,
|
||||
// Stack pointer (SP)
|
||||
R1,
|
||||
// Reserved
|
||||
R2,
|
||||
// Used to pass integer function parameters and return values
|
||||
R3, R4,
|
||||
// Used to pass integer function parameters
|
||||
R5, R6, R7, R8, R9, R10,
|
||||
// General purpose
|
||||
R11,
|
||||
// Scratch
|
||||
R12,
|
||||
// Unused by the compiler reserved
|
||||
R13,
|
||||
// General purpose
|
||||
R14, R15, R16, R17, R18, R19,
|
||||
R20, R21, R22, R23, R24, R25,
|
||||
R26, R27, R28, R29, R30, R31,
|
||||
|
||||
// CRs (7)
|
||||
CR0 = 0,
|
||||
|
||||
// FPRs (32)
|
||||
// Scratch
|
||||
FPR0,
|
||||
// Used to pass double word function parameters and return values
|
||||
FPR1, FPR2, FPR3, FPR4,
|
||||
FPR5, FPR6, FPR7, FPR8,
|
||||
FPR9, FPR10, FPR11, FPR12,
|
||||
FPR13,
|
||||
// General purpose
|
||||
FPR14, FPR15, FPR16, FPR17,
|
||||
FPR18, FPR19, FPR20, FPR21,
|
||||
FPR22, FPR23, FPR24, FPR25,
|
||||
FPR26, FPR27, FPR28, FPR29,
|
||||
FPR30, FPR31,
|
||||
|
||||
|
||||
// Vmx (128)
|
||||
VR0,
|
||||
// Used to pass vector function parameters and return values
|
||||
VR1, VR2, VR3, VR4,
|
||||
VR5, VR6, VR7, VR8,
|
||||
VR9, VR10, VR11, VR12,
|
||||
VR13, // ...
|
||||
|
||||
// Others regs
|
||||
LR, CTR, XER, FPSCR,
|
||||
|
||||
// End
|
||||
|
||||
INVALID_REG = 0xFFFFFFFF
|
||||
};
|
||||
enum IntegerSize
|
||||
{
|
||||
I_I8 = 0,
|
||||
I_I16,
|
||||
I_I32,
|
||||
I_I64
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NUMGPRs = 31,
|
||||
};
|
||||
|
||||
typedef const u8* JumpTarget;
|
||||
|
||||
|
||||
enum FixupBranchType {
|
||||
_B,
|
||||
_BEQ,
|
||||
_BNE,
|
||||
_BLT,
|
||||
_BLE,
|
||||
_BGT,
|
||||
_BGE,
|
||||
// Link register
|
||||
_BL
|
||||
};
|
||||
|
||||
struct FixupBranch
|
||||
{
|
||||
u8 *ptr;
|
||||
u32 condition; // Remembers our codition at the time
|
||||
FixupBranchType type; //0 = B 1 = BL
|
||||
};
|
||||
|
||||
class PPCXEmitter
|
||||
{
|
||||
private:
|
||||
u8 *code, *startcode;
|
||||
u8 *lastCacheFlushEnd;
|
||||
u32 condition;
|
||||
|
||||
protected:
|
||||
// Weite opcode
|
||||
inline void Write32(u32 value) {*(u32*)code = value; code+=4;}
|
||||
|
||||
public:
|
||||
PPCXEmitter() : code(0), startcode(0), lastCacheFlushEnd(0) {
|
||||
}
|
||||
PPCXEmitter(u8 *code_ptr) {
|
||||
code = code_ptr;
|
||||
lastCacheFlushEnd = code_ptr;
|
||||
startcode = code_ptr;
|
||||
}
|
||||
virtual ~PPCXEmitter() {}
|
||||
|
||||
void SetCodePtr(u8 *ptr);
|
||||
void ReserveCodeSpace(u32 bytes);
|
||||
const u8 *AlignCode16();
|
||||
const u8 *AlignCodePage();
|
||||
const u8 *GetCodePtr() const;
|
||||
void FlushIcache();
|
||||
void FlushIcacheSection(u8 *start, u8 *end);
|
||||
u8 *GetWritableCodePtr();
|
||||
|
||||
|
||||
// Special purpose instructions
|
||||
|
||||
// Debug Breakpoint
|
||||
void BKPT(u16 arg);
|
||||
|
||||
// Hint instruction
|
||||
void YIELD();
|
||||
|
||||
// Do nothing
|
||||
void NOP(int count = 1); //nop padding - TODO: fast nop slides, for amd and intel (check their manuals)
|
||||
|
||||
// FixupBranch ops
|
||||
FixupBranch B();
|
||||
FixupBranch BL();
|
||||
FixupBranch BNE();
|
||||
FixupBranch BLT();
|
||||
FixupBranch BLE();
|
||||
|
||||
FixupBranch B_Cond(FixupBranchType type);
|
||||
|
||||
void SetJumpTarget(FixupBranch const &branch);
|
||||
|
||||
// Branch ops
|
||||
void B (const void *fnptr);
|
||||
void BL(const void *fnptr);
|
||||
void BA (const void *fnptr);
|
||||
void BLA(const void *fnptr);
|
||||
void BEQ(const void *fnptr);
|
||||
void BLE(const void *fnptr);
|
||||
void BLT(const void *fnptr);
|
||||
void BGT(const void *fnptr);
|
||||
void BEQ (PPCReg r);
|
||||
|
||||
void BLR();
|
||||
void BGTLR(); // ??? used ?
|
||||
void BLTCTR();
|
||||
void BGTCTR();
|
||||
void BLECTR();
|
||||
void BGECTR();
|
||||
void BCTRL ();
|
||||
void BCTR();
|
||||
|
||||
// Link Register
|
||||
void MFLR(PPCReg r);
|
||||
void MTLR(PPCReg r);
|
||||
void MTCTR(PPCReg r);
|
||||
|
||||
|
||||
// Logical Ops
|
||||
void AND (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void ANDI (PPCReg Rs, PPCReg Ra, unsigned short imm);
|
||||
void ANDIS(PPCReg Rs, PPCReg Ra, unsigned short imm);
|
||||
void NAND (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void OR (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void ORC (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void NOR (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void XOR (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void NEG (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
|
||||
// Arithmetics ops
|
||||
void ADD (PPCReg Rd, PPCReg Ra, PPCReg Rb);
|
||||
void ADDI (PPCReg Rd, PPCReg Ra, short imm);
|
||||
void ADDIS (PPCReg Rd, PPCReg Ra, short imm);
|
||||
void ADDC (PPCReg Rd, PPCReg Ra, PPCReg Rb);
|
||||
void SUB (PPCReg Rd, PPCReg Ra, PPCReg Rb) {
|
||||
// reverse ?
|
||||
SUBF(Rd, Rb, Ra);
|
||||
}
|
||||
void SUBF (PPCReg Rd, PPCReg Ra, PPCReg Rb, int RCFlags = 0);
|
||||
void SUBFC (PPCReg Rd, PPCReg Ra, PPCReg Rb);
|
||||
|
||||
// Floating ops
|
||||
void DIVW(PPCReg dest, PPCReg dividend, PPCReg divisor);
|
||||
void DIVWU(PPCReg dest, PPCReg dividend, PPCReg divisor);
|
||||
void MULLW(PPCReg dest, PPCReg src, PPCReg op2);
|
||||
void MULHW (PPCReg dest, PPCReg src, PPCReg op2);
|
||||
void MULHWS(PPCReg dest, PPCReg src, PPCReg op2);
|
||||
|
||||
void ORI (PPCReg src, PPCReg dest, unsigned short imm);
|
||||
|
||||
// Memory load/store operations
|
||||
void LI (PPCReg dest, unsigned short imm);
|
||||
void LIS (PPCReg dest, unsigned short imm);
|
||||
// dest = LIS(imm) + ORI(+imm)
|
||||
void MOVI2R (PPCReg dest, unsigned int imm);
|
||||
|
||||
// 8bit
|
||||
void LBZ (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void LBZX (PPCReg dest, PPCReg a, PPCReg b);
|
||||
|
||||
// 16bit
|
||||
void LHZ (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void LHBRX (PPCReg dest, PPCReg src, PPCReg offset);
|
||||
// 32 bit
|
||||
void LWZ (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void LWBRX (PPCReg dest, PPCReg src, PPCReg offset);
|
||||
// 64 bit
|
||||
void LD (PPCReg dest, PPCReg src, int offset = 0);
|
||||
|
||||
// 8 bit
|
||||
void STB (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void STBX (PPCReg dest, PPCReg a, PPCReg b);
|
||||
// 16 bit
|
||||
void STH (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void STHBRX (PPCReg dest, PPCReg src, PPCReg offset);
|
||||
// 32 bit
|
||||
void STW (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void STWU (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void STWBRX (PPCReg dest, PPCReg src, PPCReg offset);
|
||||
// 64 bit
|
||||
void STD (PPCReg dest, PPCReg src, int offset = 0);
|
||||
|
||||
// sign
|
||||
void EXTSB (PPCReg dest, PPCReg src);
|
||||
void EXTSH (PPCReg dest, PPCReg src);
|
||||
|
||||
void RLWINM (PPCReg dest, PPCReg src, int shift, int start, int end);
|
||||
|
||||
// Compare
|
||||
void CMPLI (PPCReg dest, unsigned short imm);
|
||||
void CMPI (PPCReg dest, unsigned short imm);
|
||||
void CMPL (PPCReg a, PPCReg b);
|
||||
void CMP (PPCReg a, PPCReg b);
|
||||
|
||||
void Prologue();
|
||||
void Epilogue();
|
||||
|
||||
// Debug !
|
||||
void Break() {
|
||||
Write32(0x0FE00016);
|
||||
}
|
||||
|
||||
void MR (PPCReg to, PPCReg from) {
|
||||
OR(to, from, from);
|
||||
}
|
||||
|
||||
void QuickCallFunction(void *func);
|
||||
protected:
|
||||
|
||||
}; // class PPCXEmitter
|
||||
|
||||
|
||||
// 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 PPCXCodeBlock : public PPCXEmitter
|
||||
{
|
||||
protected:
|
||||
u8 *region;
|
||||
size_t region_size;
|
||||
|
||||
public:
|
||||
PPCXCodeBlock() : region(NULL), region_size(0) {}
|
||||
virtual ~PPCXCodeBlock() { if (region) FreeCodeSpace(); }
|
||||
|
||||
// Call this before you generate any code.
|
||||
void AllocCodeSpace(int size)
|
||||
enum PPCReg
|
||||
{
|
||||
region_size = size;
|
||||
region = (u8*)AllocateExecutableMemory(region_size);
|
||||
SetCodePtr(region);
|
||||
}
|
||||
// GPRs (32)
|
||||
// Behaves as zero does in some instructions
|
||||
R0 = 0,
|
||||
// Stack pointer (SP)
|
||||
R1,
|
||||
// Reserved
|
||||
R2,
|
||||
// Used to pass integer function parameters and return values
|
||||
R3, R4,
|
||||
// Used to pass integer function parameters
|
||||
R5, R6, R7, R8, R9, R10,
|
||||
// General purpose
|
||||
R11,
|
||||
// Scratch
|
||||
R12,
|
||||
// Unused by the compiler reserved
|
||||
R13,
|
||||
// General purpose
|
||||
R14, R15, R16, R17, R18, R19,
|
||||
R20, R21, R22, R23, R24, R25,
|
||||
R26, R27, R28, R29, R30, R31,
|
||||
|
||||
// Always clear code space with breakpoints, so that if someone accidentally executes
|
||||
// uninitialized, it just breaks into the debugger.
|
||||
void ClearCodeSpace()
|
||||
// CRs (7)
|
||||
CR0 = 0,
|
||||
|
||||
// FPRs (32)
|
||||
// Scratch
|
||||
FPR0,
|
||||
// Used to pass double word function parameters and return values
|
||||
FPR1, FPR2, FPR3, FPR4,
|
||||
FPR5, FPR6, FPR7, FPR8,
|
||||
FPR9, FPR10, FPR11, FPR12,
|
||||
FPR13,
|
||||
// General purpose
|
||||
FPR14, FPR15, FPR16, FPR17,
|
||||
FPR18, FPR19, FPR20, FPR21,
|
||||
FPR22, FPR23, FPR24, FPR25,
|
||||
FPR26, FPR27, FPR28, FPR29,
|
||||
FPR30, FPR31,
|
||||
|
||||
|
||||
// Vmx (128)
|
||||
VR0,
|
||||
// Used to pass vector function parameters and return values
|
||||
VR1, VR2, VR3, VR4,
|
||||
VR5, VR6, VR7, VR8,
|
||||
VR9, VR10, VR11, VR12,
|
||||
VR13, // ...
|
||||
|
||||
// Others regs
|
||||
LR, CTR, XER, FPSCR,
|
||||
|
||||
// End
|
||||
|
||||
INVALID_REG = 0xFFFFFFFF
|
||||
};
|
||||
enum IntegerSize
|
||||
{
|
||||
// x86/64: 0xCC = breakpoint
|
||||
memset(region, 0xCC, region_size);
|
||||
ResetCodePtr();
|
||||
}
|
||||
I_I8 = 0,
|
||||
I_I16,
|
||||
I_I32,
|
||||
I_I64
|
||||
};
|
||||
|
||||
// Call this when shutting down. Don't rely on the destructor, even though it'll do the job.
|
||||
void FreeCodeSpace()
|
||||
enum
|
||||
{
|
||||
region = NULL;
|
||||
region_size = 0;
|
||||
}
|
||||
NUMGPRs = 31,
|
||||
};
|
||||
|
||||
bool IsInSpace(u8 *ptr)
|
||||
typedef const u8* JumpTarget;
|
||||
|
||||
|
||||
enum FixupBranchType {
|
||||
_B,
|
||||
_BEQ,
|
||||
_BNE,
|
||||
_BLT,
|
||||
_BLE,
|
||||
_BGT,
|
||||
_BGE,
|
||||
// Link register
|
||||
_BL
|
||||
};
|
||||
|
||||
struct FixupBranch
|
||||
{
|
||||
return ptr >= region && ptr < region + region_size;
|
||||
}
|
||||
u8 *ptr;
|
||||
u32 condition; // Remembers our codition at the time
|
||||
FixupBranchType type; //0 = B 1 = BL
|
||||
};
|
||||
|
||||
// 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()
|
||||
class PPCXEmitter
|
||||
{
|
||||
//WriteProtectMemory(region, region_size, true);
|
||||
}
|
||||
void UnWriteProtect()
|
||||
private:
|
||||
u8 *code, *startcode;
|
||||
u8 *lastCacheFlushEnd;
|
||||
u32 condition;
|
||||
|
||||
protected:
|
||||
// Weite opcode
|
||||
inline void Write32(u32 value) {*(u32*)code = value; code+=4;}
|
||||
|
||||
public:
|
||||
PPCXEmitter() : code(0), startcode(0), lastCacheFlushEnd(0) {
|
||||
}
|
||||
PPCXEmitter(u8 *code_ptr) {
|
||||
code = code_ptr;
|
||||
lastCacheFlushEnd = code_ptr;
|
||||
startcode = code_ptr;
|
||||
}
|
||||
virtual ~PPCXEmitter() {}
|
||||
|
||||
void SetCodePtr(u8 *ptr);
|
||||
void ReserveCodeSpace(u32 bytes);
|
||||
const u8 *AlignCode16();
|
||||
const u8 *AlignCodePage();
|
||||
const u8 *GetCodePtr() const;
|
||||
void FlushIcache();
|
||||
void FlushIcacheSection(u8 *start, u8 *end);
|
||||
u8 *GetWritableCodePtr();
|
||||
|
||||
|
||||
// Special purpose instructions
|
||||
|
||||
// Debug Breakpoint
|
||||
void BKPT(u16 arg);
|
||||
|
||||
// Hint instruction
|
||||
void YIELD();
|
||||
|
||||
// Do nothing
|
||||
void NOP(int count = 1); //nop padding - TODO: fast nop slides, for amd and intel (check their manuals)
|
||||
|
||||
// FixupBranch ops
|
||||
FixupBranch B();
|
||||
FixupBranch BL();
|
||||
FixupBranch BNE();
|
||||
FixupBranch BLT();
|
||||
FixupBranch BLE();
|
||||
|
||||
FixupBranch B_Cond(FixupBranchType type);
|
||||
|
||||
void SetJumpTarget(FixupBranch const &branch);
|
||||
|
||||
// Branch ops
|
||||
void B (const void *fnptr);
|
||||
void BL(const void *fnptr);
|
||||
void BA (const void *fnptr);
|
||||
void BLA(const void *fnptr);
|
||||
void BEQ(const void *fnptr);
|
||||
void BLE(const void *fnptr);
|
||||
void BLT(const void *fnptr);
|
||||
void BGT(const void *fnptr);
|
||||
void BEQ (PPCReg r);
|
||||
|
||||
void BLR();
|
||||
void BGTLR(); // ??? used ?
|
||||
void BLTCTR();
|
||||
void BGTCTR();
|
||||
void BLECTR();
|
||||
void BGECTR();
|
||||
void BCTRL ();
|
||||
void BCTR();
|
||||
|
||||
// Link Register
|
||||
void MFLR(PPCReg r);
|
||||
void MTLR(PPCReg r);
|
||||
void MTCTR(PPCReg r);
|
||||
|
||||
|
||||
// Logical Ops
|
||||
void AND (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void ANDI (PPCReg Rs, PPCReg Ra, unsigned short imm);
|
||||
void ANDIS(PPCReg Rs, PPCReg Ra, unsigned short imm);
|
||||
void NAND (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void OR (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void ORC (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void NOR (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void XOR (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
void NEG (PPCReg Rs, PPCReg Ra, PPCReg Rb);
|
||||
|
||||
// Arithmetics ops
|
||||
void ADD (PPCReg Rd, PPCReg Ra, PPCReg Rb);
|
||||
void ADDI (PPCReg Rd, PPCReg Ra, short imm);
|
||||
void ADDIS (PPCReg Rd, PPCReg Ra, short imm);
|
||||
void ADDC (PPCReg Rd, PPCReg Ra, PPCReg Rb);
|
||||
void SUB (PPCReg Rd, PPCReg Ra, PPCReg Rb) {
|
||||
// reverse ?
|
||||
SUBF(Rd, Rb, Ra);
|
||||
}
|
||||
void SUBF (PPCReg Rd, PPCReg Ra, PPCReg Rb, int RCFlags = 0);
|
||||
void SUBFC (PPCReg Rd, PPCReg Ra, PPCReg Rb);
|
||||
|
||||
// Floating ops
|
||||
void DIVW(PPCReg dest, PPCReg dividend, PPCReg divisor);
|
||||
void DIVWU(PPCReg dest, PPCReg dividend, PPCReg divisor);
|
||||
void MULLW(PPCReg dest, PPCReg src, PPCReg op2);
|
||||
void MULHW (PPCReg dest, PPCReg src, PPCReg op2);
|
||||
void MULHWS(PPCReg dest, PPCReg src, PPCReg op2);
|
||||
|
||||
void ORI (PPCReg src, PPCReg dest, unsigned short imm);
|
||||
|
||||
// Memory load/store operations
|
||||
void LI (PPCReg dest, unsigned short imm);
|
||||
void LIS (PPCReg dest, unsigned short imm);
|
||||
// dest = LIS(imm) + ORI(+imm)
|
||||
void MOVI2R (PPCReg dest, unsigned int imm);
|
||||
|
||||
// 8bit
|
||||
void LBZ (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void LBZX (PPCReg dest, PPCReg a, PPCReg b);
|
||||
|
||||
// 16bit
|
||||
void LHZ (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void LHBRX (PPCReg dest, PPCReg src, PPCReg offset);
|
||||
// 32 bit
|
||||
void LWZ (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void LWBRX (PPCReg dest, PPCReg src, PPCReg offset);
|
||||
// 64 bit
|
||||
void LD (PPCReg dest, PPCReg src, int offset = 0);
|
||||
|
||||
// 8 bit
|
||||
void STB (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void STBX (PPCReg dest, PPCReg a, PPCReg b);
|
||||
// 16 bit
|
||||
void STH (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void STHBRX (PPCReg dest, PPCReg src, PPCReg offset);
|
||||
// 32 bit
|
||||
void STW (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void STWU (PPCReg dest, PPCReg src, int offset = 0);
|
||||
void STWBRX (PPCReg dest, PPCReg src, PPCReg offset);
|
||||
// 64 bit
|
||||
void STD (PPCReg dest, PPCReg src, int offset = 0);
|
||||
|
||||
// sign
|
||||
void EXTSB (PPCReg dest, PPCReg src);
|
||||
void EXTSH (PPCReg dest, PPCReg src);
|
||||
|
||||
void RLWINM (PPCReg dest, PPCReg src, int shift, int start, int end);
|
||||
|
||||
// Compare
|
||||
void CMPLI (PPCReg dest, unsigned short imm);
|
||||
void CMPI (PPCReg dest, unsigned short imm);
|
||||
void CMPL (PPCReg a, PPCReg b);
|
||||
void CMP (PPCReg a, PPCReg b);
|
||||
|
||||
void Prologue();
|
||||
void Epilogue();
|
||||
|
||||
// Debug !
|
||||
void Break() {
|
||||
Write32(0x0FE00016);
|
||||
}
|
||||
|
||||
void MR (PPCReg to, PPCReg from) {
|
||||
OR(to, from, from);
|
||||
}
|
||||
|
||||
void QuickCallFunction(void *func);
|
||||
protected:
|
||||
|
||||
}; // class PPCXEmitter
|
||||
|
||||
|
||||
// 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 PPCXCodeBlock : public PPCXEmitter
|
||||
{
|
||||
//UnWriteProtectMemory(region, region_size, false);
|
||||
}
|
||||
protected:
|
||||
u8 *region;
|
||||
size_t region_size;
|
||||
|
||||
void ResetCodePtr()
|
||||
{
|
||||
SetCodePtr(region);
|
||||
}
|
||||
public:
|
||||
PPCXCodeBlock() : region(NULL), region_size(0) {}
|
||||
virtual ~PPCXCodeBlock() { if (region) FreeCodeSpace(); }
|
||||
|
||||
size_t GetSpaceLeft() const
|
||||
{
|
||||
return region_size - (GetCodePtr() - region);
|
||||
}
|
||||
// Call this before you generate any code.
|
||||
void AllocCodeSpace(int size)
|
||||
{
|
||||
region_size = size;
|
||||
region = (u8*)AllocateExecutableMemory(region_size);
|
||||
SetCodePtr(region);
|
||||
}
|
||||
|
||||
u8 *GetBasePtr() {
|
||||
return region;
|
||||
}
|
||||
// Always clear code space with breakpoints, so that if someone accidentally executes
|
||||
// uninitialized, it just breaks into the debugger.
|
||||
void ClearCodeSpace()
|
||||
{
|
||||
// x86/64: 0xCC = breakpoint
|
||||
memset(region, 0xCC, region_size);
|
||||
ResetCodePtr();
|
||||
}
|
||||
|
||||
size_t GetOffset(u8 *ptr) {
|
||||
return ptr - region;
|
||||
}
|
||||
};
|
||||
// Call this when shutting down. Don't rely on the destructor, even though it'll do the job.
|
||||
void FreeCodeSpace()
|
||||
{
|
||||
region = NULL;
|
||||
region_size = 0;
|
||||
}
|
||||
|
||||
bool IsInSpace(u8 *ptr)
|
||||
{
|
||||
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()
|
||||
{
|
||||
//WriteProtectMemory(region, region_size, true);
|
||||
}
|
||||
void UnWriteProtect()
|
||||
{
|
||||
//UnWriteProtectMemory(region, region_size, false);
|
||||
}
|
||||
|
||||
void ResetCodePtr()
|
||||
{
|
||||
SetCodePtr(region);
|
||||
}
|
||||
|
||||
size_t GetSpaceLeft() const
|
||||
{
|
||||
return region_size - (GetCodePtr() - region);
|
||||
}
|
||||
|
||||
u8 *GetBasePtr() {
|
||||
return region;
|
||||
}
|
||||
|
||||
size_t GetOffset(u8 *ptr) {
|
||||
return ptr - region;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user