mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-15 16:59:18 +01:00
misc cleanup, bugfix for x86 display in jit window
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1596 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
cd62fc5c0c
commit
347fc18542
@ -687,6 +687,11 @@ public:
|
|||||||
region_size = 0;
|
region_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsInCodeSpace(u8 *ptr)
|
||||||
|
{
|
||||||
|
return ptr >= region && ptr < region + region_size;
|
||||||
|
}
|
||||||
|
|
||||||
// Cannot currently be undone. Will write protect the entire code region.
|
// Cannot currently be undone. Will write protect the entire code region.
|
||||||
// Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()).
|
// Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()).
|
||||||
void WriteProtect()
|
void WriteProtect()
|
||||||
|
@ -63,10 +63,8 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
|||||||
int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0];
|
int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0];
|
||||||
if (accessType == 8) //Rule out DEP
|
if (accessType == 8) //Rule out DEP
|
||||||
{
|
{
|
||||||
if(PowerPC::state == PowerPC::CPU_POWERDOWN) // Access violation during
|
if (PowerPC::state == PowerPC::CPU_POWERDOWN)
|
||||||
// violent shutdown is fine
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
|
||||||
|
|
||||||
MessageBox(0, _T("Tried to execute code that's not marked executable. This is likely a JIT bug.\n"), 0, 0);
|
MessageBox(0, _T("Tried to execute code that's not marked executable. This is likely a JIT bug.\n"), 0, 0);
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
@ -75,7 +73,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
|||||||
PVOID codeAddr = pPtrs->ExceptionRecord->ExceptionAddress;
|
PVOID codeAddr = pPtrs->ExceptionRecord->ExceptionAddress;
|
||||||
unsigned char *codePtr = (unsigned char*)codeAddr;
|
unsigned char *codePtr = (unsigned char*)codeAddr;
|
||||||
|
|
||||||
if (!jit.IsInJitCode(codePtr)) {
|
if (!jit.IsInCodeSpace(codePtr)) {
|
||||||
// Let's not prevent debugging.
|
// Let's not prevent debugging.
|
||||||
return (DWORD)EXCEPTION_CONTINUE_SEARCH;
|
return (DWORD)EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
@ -91,8 +89,9 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
|||||||
u64 memspaceTop = memspaceBottom + 0x40000000;
|
u64 memspaceTop = memspaceBottom + 0x40000000;
|
||||||
#endif
|
#endif
|
||||||
if (badAddress < memspaceBottom || badAddress >= memspaceTop) {
|
if (badAddress < memspaceBottom || badAddress >= memspaceTop) {
|
||||||
PanicAlert("Exception handler - access outside memory space. %08x%08x",
|
return (DWORD)EXCEPTION_CONTINUE_SEARCH;
|
||||||
badAddress >> 32, badAddress);
|
//PanicAlert("Exception handler - access outside memory space. %08x%08x",
|
||||||
|
// badAddress >> 32, badAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 emAddress = (u32)(badAddress - memspaceBottom);
|
u32 emAddress = (u32)(badAddress - memspaceBottom);
|
||||||
@ -199,7 +198,7 @@ void sigsegv_handler(int signal, siginfo_t *info, void *raw_context)
|
|||||||
#else
|
#else
|
||||||
u8 *fault_instruction_ptr = (u8 *)CREG_EIP(ctx);
|
u8 *fault_instruction_ptr = (u8 *)CREG_EIP(ctx);
|
||||||
#endif
|
#endif
|
||||||
if (!jit.IsInJitCode((const u8 *)fault_instruction_ptr)) {
|
if (!jit.IsInCodeSpace((const u8 *)fault_instruction_ptr)) {
|
||||||
// Let's not prevent debugging.
|
// Let's not prevent debugging.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ namespace CPUCompare
|
|||||||
}
|
}
|
||||||
|
|
||||||
jo.optimizeStack = true;
|
jo.optimizeStack = true;
|
||||||
jo.enableBlocklink = true; // Speed boost, but not 100% safe
|
jo.enableBlocklink = false; // Speed boost, but not 100% safe
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
jo.enableFastMem = Core::GetStartupParameter().bUseFastMem;
|
jo.enableFastMem = Core::GetStartupParameter().bUseFastMem;
|
||||||
#else
|
#else
|
||||||
@ -437,11 +437,12 @@ namespace CPUCompare
|
|||||||
|
|
||||||
gpr.SanityCheck();
|
gpr.SanityCheck();
|
||||||
fpr.SanityCheck();
|
fpr.SanityCheck();
|
||||||
if (js.cancel) break;
|
if (js.cancel)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
b.flags = js.block_flags;
|
b.flags = js.block_flags;
|
||||||
b.codeSize = (u32)(GetCodePtr() - start);
|
b.codeSize = (u32)(GetCodePtr() - normalEntry);
|
||||||
b.originalSize = size;
|
b.originalSize = size;
|
||||||
return normalEntry;
|
return normalEntry;
|
||||||
}
|
}
|
||||||
|
@ -63,29 +63,7 @@ public:
|
|||||||
|
|
||||||
class Jit64 : public Gen::XCodeBlock
|
class Jit64 : public Gen::XCodeBlock
|
||||||
{
|
{
|
||||||
TrampolineCache trampolines;
|
|
||||||
GPRRegCache gpr;
|
|
||||||
FPURegCache fpr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef void (*CompiledCode)();
|
|
||||||
|
|
||||||
void unknown_instruction(UGeckoInstruction _inst);
|
|
||||||
|
|
||||||
//Code pointers are stored separately, they will be accessed much more frequently
|
|
||||||
|
|
||||||
enum BlockFlag
|
|
||||||
{
|
|
||||||
BLOCK_USE_GQR0 = 0x1,
|
|
||||||
BLOCK_USE_GQR1 = 0x2,
|
|
||||||
BLOCK_USE_GQR2 = 0x4,
|
|
||||||
BLOCK_USE_GQR3 = 0x8,
|
|
||||||
BLOCK_USE_GQR4 = 0x10,
|
|
||||||
BLOCK_USE_GQR5 = 0x20,
|
|
||||||
BLOCK_USE_GQR6 = 0x40,
|
|
||||||
BLOCK_USE_GQR7 = 0x80,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO(ector) - optimize this struct for size
|
// TODO(ector) - optimize this struct for size
|
||||||
struct JitBlock
|
struct JitBlock
|
||||||
{
|
{
|
||||||
@ -109,7 +87,13 @@ public:
|
|||||||
bool invalid;
|
bool invalid;
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
private:
|
||||||
|
enum BlockFlag
|
||||||
|
{
|
||||||
|
BLOCK_USE_GQR0 = 0x1, BLOCK_USE_GQR1 = 0x2, BLOCK_USE_GQR2 = 0x4, BLOCK_USE_GQR3 = 0x8,
|
||||||
|
BLOCK_USE_GQR4 = 0x10, BLOCK_USE_GQR5 = 0x20, BLOCK_USE_GQR6 = 0x40, BLOCK_USE_GQR7 = 0x80,
|
||||||
|
};
|
||||||
|
|
||||||
struct JitState
|
struct JitState
|
||||||
{
|
{
|
||||||
u32 compilerPC;
|
u32 compilerPC;
|
||||||
@ -146,11 +130,40 @@ public:
|
|||||||
bool fastInterrupts;
|
bool fastInterrupts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TrampolineCache trampolines;
|
||||||
|
GPRRegCache gpr;
|
||||||
|
FPURegCache fpr;
|
||||||
|
|
||||||
|
u8 **blockCodePointers;
|
||||||
|
|
||||||
|
std::multimap<u32, int> links_to;
|
||||||
|
|
||||||
|
JitBlock *blocks;
|
||||||
|
int numBlocks;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef void (*CompiledCode)();
|
||||||
|
|
||||||
JitState js;
|
JitState js;
|
||||||
JitOptions jo;
|
JitOptions jo;
|
||||||
|
|
||||||
|
// Initialization, etc
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
void PrintStats();
|
void PrintStats();
|
||||||
|
|
||||||
|
// Jit!
|
||||||
|
|
||||||
|
const u8* Jit(u32 emaddress);
|
||||||
|
const u8* DoJit(u32 emaddress, JitBlock &b);
|
||||||
|
|
||||||
|
// Run!
|
||||||
|
|
||||||
void EnterFastRun();
|
void EnterFastRun();
|
||||||
|
const u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx);
|
||||||
|
|
||||||
// Code Cache
|
// Code Cache
|
||||||
|
|
||||||
@ -173,18 +186,9 @@ public:
|
|||||||
void ResetCache();
|
void ResetCache();
|
||||||
void DestroyBlock(int blocknum, bool invalidate);
|
void DestroyBlock(int blocknum, bool invalidate);
|
||||||
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
|
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
|
||||||
bool IsInJitCode(const u8 *codePtr);
|
|
||||||
|
|
||||||
const u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx);
|
|
||||||
|
|
||||||
#define JIT_OPCODE 0
|
#define JIT_OPCODE 0
|
||||||
|
|
||||||
const u8* Jit(u32 emaddress);
|
|
||||||
const u8* DoJit(u32 emaddress, JitBlock &b);
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
void Shutdown();
|
|
||||||
|
|
||||||
// Utilities for use by opcodes
|
// Utilities for use by opcodes
|
||||||
|
|
||||||
void WriteExit(u32 destination, int exit_num);
|
void WriteExit(u32 destination, int exit_num);
|
||||||
@ -214,7 +218,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
// OPCODES
|
// OPCODES
|
||||||
|
void unknown_instruction(UGeckoInstruction _inst);
|
||||||
void Default(UGeckoInstruction _inst);
|
void Default(UGeckoInstruction _inst);
|
||||||
void DoNothing(UGeckoInstruction _inst);
|
void DoNothing(UGeckoInstruction _inst);
|
||||||
void HLEFunction(UGeckoInstruction _inst);
|
void HLEFunction(UGeckoInstruction _inst);
|
||||||
|
@ -147,7 +147,7 @@ const u8 *TrampolineCache::GetWriteTrampoline(const InstructionInfo &info)
|
|||||||
const u8 *Jit64::BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx)
|
const u8 *Jit64::BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx)
|
||||||
{
|
{
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
if (!IsInJitCode(codePtr))
|
if (!jit.IsInCodeSpace(codePtr))
|
||||||
return 0; // this will become a regular crash real soon after this
|
return 0; // this will become a regular crash real soon after this
|
||||||
|
|
||||||
InstructionInfo info;
|
InstructionInfo info;
|
||||||
|
@ -55,9 +55,7 @@ using namespace Gen;
|
|||||||
#ifdef OPROFILE_REPORT
|
#ifdef OPROFILE_REPORT
|
||||||
op_agent_t agent;
|
op_agent_t agent;
|
||||||
#endif
|
#endif
|
||||||
static u8 *codeCache;
|
|
||||||
static u8 *trampolineCache;
|
|
||||||
u8 *trampolineCodePtr;
|
|
||||||
#define INVALID_EXIT 0xFFFFFFFF
|
#define INVALID_EXIT 0xFFFFFFFF
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -67,13 +65,6 @@ using namespace Gen;
|
|||||||
|
|
||||||
int MAX_NUM_BLOCKS = 65536*2;
|
int MAX_NUM_BLOCKS = 65536*2;
|
||||||
|
|
||||||
static u8 **blockCodePointers;
|
|
||||||
|
|
||||||
static std::multimap<u32, int> links_to;
|
|
||||||
|
|
||||||
static Jit64::JitBlock *blocks;
|
|
||||||
static int numBlocks;
|
|
||||||
|
|
||||||
|
|
||||||
void Jit64::PrintStats()
|
void Jit64::PrintStats()
|
||||||
{
|
{
|
||||||
@ -233,10 +224,6 @@ using namespace Gen;
|
|||||||
return blockCodePointers;
|
return blockCodePointers;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Jit64::IsInJitCode(const u8 *codePtr) {
|
|
||||||
return codePtr >= codeCache && codePtr <= GetCodePtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Jit64::EnterFastRun()
|
void Jit64::EnterFastRun()
|
||||||
{
|
{
|
||||||
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
|
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
|
||||||
@ -293,10 +280,6 @@ using namespace Gen;
|
|||||||
return (CompiledCode)blockCodePointers[blockNumber];
|
return (CompiledCode)blockCodePointers[blockNumber];
|
||||||
}
|
}
|
||||||
|
|
||||||
int Jit64::GetCodeSize() {
|
|
||||||
return (int)(GetCodePtr() - codeCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Block linker
|
//Block linker
|
||||||
//Make sure to have as many blocks as possible compiled before calling this
|
//Make sure to have as many blocks as possible compiled before calling this
|
||||||
//It's O(N), so it's fast :)
|
//It's O(N), so it's fast :)
|
||||||
|
@ -141,12 +141,26 @@ void CJitWindow::Compare(u32 em_address)
|
|||||||
int block_num = jit.GetBlockNumberFromAddress(em_address);
|
int block_num = jit.GetBlockNumberFromAddress(em_address);
|
||||||
if (block_num < 0)
|
if (block_num < 0)
|
||||||
{
|
{
|
||||||
ppc_box->SetValue(wxString::FromAscii(StringFromFormat("(non-code address: %08x)", em_address).c_str()));
|
for (int i = 0; i < 500; i++) {
|
||||||
x86_box->SetValue(wxString::FromAscii(StringFromFormat("(no translation)").c_str()));
|
block_num = jit.GetBlockNumberFromAddress(em_address - 4 * i);
|
||||||
return;
|
if (block_num >= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (block_num >= 0) {
|
||||||
|
Jit64::JitBlock *block = jit.GetBlock(block_num);
|
||||||
|
if (!(block->originalAddress <= em_address && block->originalSize + block->originalAddress >= em_address))
|
||||||
|
block_num = -1;
|
||||||
|
}
|
||||||
|
// Do not merge this "if" with the above - block_num changes inside it.
|
||||||
|
if (block_num < 0) {
|
||||||
|
ppc_box->SetValue(wxString::FromAscii(StringFromFormat("(non-code address: %08x)", em_address).c_str()));
|
||||||
|
x86_box->SetValue(wxString::FromAscii(StringFromFormat("(no translation)").c_str()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Jit64::JitBlock *block = jit.GetBlock(block_num);
|
Jit64::JitBlock *block = jit.GetBlock(block_num);
|
||||||
|
|
||||||
|
// 800031f0
|
||||||
// == Fill in x86 box
|
// == Fill in x86 box
|
||||||
|
|
||||||
memset(xDis, 0, 65536);
|
memset(xDis, 0, 65536);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user