From a82a61c53a3f6b15980fcad31c1a0fe69be51f6f Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 16 Dec 2010 22:38:31 +0000 Subject: [PATCH] Core/DSPCore: Fix more memory accesses for linux x64 Core/Common: Add more asserts for too large displacements git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6595 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/x64Emitter.cpp | 22 +++++++++++++------- Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp | 20 ++++++++++++++---- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Source/Core/Common/Src/x64Emitter.cpp b/Source/Core/Common/Src/x64Emitter.cpp index 39c43bc498..ceb2794a2e 100644 --- a/Source/Core/Common/Src/x64Emitter.cpp +++ b/Source/Core/Common/Src/x64Emitter.cpp @@ -299,14 +299,17 @@ void XEmitter::JMP(const u8 *addr, bool force5Bytes) u64 fn = (u64)addr; if (!force5Bytes) { - s32 distance = (s32)(fn - ((u64)code + 2)); //TODO - sanity check + s64 distance = (s64)(fn - ((u64)code + 2)); //TODO - sanity check + _assert_msg_(DYNA_REC, distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true"); //8 bits will do Write8(0xEB); Write8((u8)(s8)distance); } else { - s32 distance = (s32)(fn - ((u64)code + 5)); //TODO - sanity check + s64 distance = (s64)(fn - ((u64)code + 5)); //TODO - sanity check + + _assert_msg_(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register"); Write8(0xE9); Write32((u32)(s32)distance); } @@ -394,15 +397,16 @@ void XEmitter::J_CC(CCFlags conditionCode, const u8 * addr, bool force5Bytes) u64 fn = (u64)addr; if (!force5Bytes) { - s32 distance = (s32)(fn - ((u64)code + 2)); - _assert_msg_(DYNA_REC, distance < 0x80, "Jump target too far away, needs force5Bytes = true"); + s64 distance = (s64)(fn - ((u64)code + 2)); + _assert_msg_(DYNA_REC, distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true"); //8 bits will do Write8(0x70 + conditionCode); Write8((u8)(s8)distance); } else { - s32 distance = (s32)(fn - ((u64)code + 6)); //TODO - sanity check + s64 distance = (s64)(fn - ((u64)code + 6)); //TODO - sanity check + _assert_msg_(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register"); Write8(0x0F); Write8(0x80 + conditionCode); Write32((u32)(s32)distance); @@ -413,13 +417,15 @@ void XEmitter::SetJumpTarget(const FixupBranch &branch) { if (branch.type == 0) { - s32 distance = (s32)(code - branch.ptr); - _assert_msg_(DYNA_REC, distance < 0x80, "Jump target too far away, needs force5Bytes = true"); + s64 distance = (s64)(code - branch.ptr); + _assert_msg_(DYNA_REC, distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true"); branch.ptr[-1] = (u8)(s8)distance; } else if (branch.type == 1) { - ((s32*)branch.ptr)[-1] = (s32)(code - branch.ptr); + s64 distance = (s64)(code - branch.ptr); + _assert_msg_(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register"); + ((s32*)branch.ptr)[-1] = (s32)distance; } } diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp index 551b6d26f6..ed7b1dbed1 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp @@ -40,7 +40,12 @@ const u8* CheckCondition(DSPEmitter& emitter, u8 cond, u8 skipCodeSize) return NULL; //emitter.INT3(); FixupBranch skipCode2; +#ifdef _M_IX86 // All32 emitter.MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR])); +#else + emitter.MOV(64, R(RAX), ImmPtr(&g_dsp.r[DSP_REG_SR])); + emitter.MOV(16, R(EAX), MatR(RAX)); +#endif switch(cond) { case 0x0: // GE - Greater Equal @@ -60,7 +65,12 @@ const u8* CheckCondition(DSPEmitter& emitter, u8 cond, u8 skipCodeSize) //LE: problem in here, half the tests fail skipCode2 = emitter.J_CC(CC_NE); //skipCode2 = emitter.J_CC((CCFlags)(CC_NE - (cond & 1))); +#ifdef _M_IX86 // All32 emitter.MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR])); +#else + emitter.MOV(64, R(RAX), ImmPtr(&g_dsp.r[DSP_REG_SR])); + emitter.MOV(16, R(EAX), MatR(RAX)); +#endif emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO)); break; case 0x4: // NZ - Not Zero @@ -148,7 +158,7 @@ void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter) } #else emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc))); - emitter.MOV(16, MDisp(RAX,0), Imm16(dest)); + emitter.MOV(16, MatR(RAX), Imm16(dest)); // Jump directly to the next block if it has already been compiled. // TODO: Subtract cycles from cyclesLeft @@ -186,9 +196,10 @@ void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter) emitter.MOV(16, R(EAX), M(&g_dsp.r[reg])); emitter.MOV(16, M(&g_dsp.pc), R(EAX)); #else - emitter.MOV(16, R(RSI), M(&g_dsp.r[reg])); + emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg])); + emitter.MOV(16, R(RSI), MatR(RSI)); emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc))); - emitter.MOV(16, MDisp(RAX,0), R(RSI)); + emitter.MOV(16, MatR(RAX), R(RSI)); #endif } // Generic jmpr implementation @@ -253,7 +264,8 @@ void r_callr(const UDSPInstruction opc, DSPEmitter& emitter) emitter.MOV(16, R(EAX), M(&g_dsp.r[reg])); emitter.MOV(16, M(&g_dsp.pc), R(EAX)); #else - emitter.MOV(16, R(RSI), M(&g_dsp.r[reg])); + emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg])); + emitter.MOV(16, R(RSI), MatR(RSI)); emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc))); emitter.MOV(16, MDisp(RAX,0), R(RSI)); #endif