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
This commit is contained in:
parent
4295f2f008
commit
a82a61c53a
|
@ -299,14 +299,17 @@ void XEmitter::JMP(const u8 *addr, bool force5Bytes)
|
||||||
u64 fn = (u64)addr;
|
u64 fn = (u64)addr;
|
||||||
if (!force5Bytes)
|
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
|
//8 bits will do
|
||||||
Write8(0xEB);
|
Write8(0xEB);
|
||||||
Write8((u8)(s8)distance);
|
Write8((u8)(s8)distance);
|
||||||
}
|
}
|
||||||
else
|
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);
|
Write8(0xE9);
|
||||||
Write32((u32)(s32)distance);
|
Write32((u32)(s32)distance);
|
||||||
}
|
}
|
||||||
|
@ -394,15 +397,16 @@ void XEmitter::J_CC(CCFlags conditionCode, const u8 * addr, bool force5Bytes)
|
||||||
u64 fn = (u64)addr;
|
u64 fn = (u64)addr;
|
||||||
if (!force5Bytes)
|
if (!force5Bytes)
|
||||||
{
|
{
|
||||||
s32 distance = (s32)(fn - ((u64)code + 2));
|
s64 distance = (s64)(fn - ((u64)code + 2));
|
||||||
_assert_msg_(DYNA_REC, distance < 0x80, "Jump target too far away, needs force5Bytes = true");
|
_assert_msg_(DYNA_REC, distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true");
|
||||||
//8 bits will do
|
//8 bits will do
|
||||||
Write8(0x70 + conditionCode);
|
Write8(0x70 + conditionCode);
|
||||||
Write8((u8)(s8)distance);
|
Write8((u8)(s8)distance);
|
||||||
}
|
}
|
||||||
else
|
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(0x0F);
|
||||||
Write8(0x80 + conditionCode);
|
Write8(0x80 + conditionCode);
|
||||||
Write32((u32)(s32)distance);
|
Write32((u32)(s32)distance);
|
||||||
|
@ -413,13 +417,15 @@ void XEmitter::SetJumpTarget(const FixupBranch &branch)
|
||||||
{
|
{
|
||||||
if (branch.type == 0)
|
if (branch.type == 0)
|
||||||
{
|
{
|
||||||
s32 distance = (s32)(code - branch.ptr);
|
s64 distance = (s64)(code - branch.ptr);
|
||||||
_assert_msg_(DYNA_REC, distance < 0x80, "Jump target too far away, needs force5Bytes = true");
|
_assert_msg_(DYNA_REC, distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true");
|
||||||
branch.ptr[-1] = (u8)(s8)distance;
|
branch.ptr[-1] = (u8)(s8)distance;
|
||||||
}
|
}
|
||||||
else if (branch.type == 1)
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,12 @@ const u8* CheckCondition(DSPEmitter& emitter, u8 cond, u8 skipCodeSize)
|
||||||
return NULL;
|
return NULL;
|
||||||
//emitter.INT3();
|
//emitter.INT3();
|
||||||
FixupBranch skipCode2;
|
FixupBranch skipCode2;
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
emitter.MOV(16, R(EAX), M(&g_dsp.r[DSP_REG_SR]));
|
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)
|
switch(cond)
|
||||||
{
|
{
|
||||||
case 0x0: // GE - Greater Equal
|
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
|
//LE: problem in here, half the tests fail
|
||||||
skipCode2 = emitter.J_CC(CC_NE);
|
skipCode2 = emitter.J_CC(CC_NE);
|
||||||
//skipCode2 = emitter.J_CC((CCFlags)(CC_NE - (cond & 1)));
|
//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]));
|
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));
|
emitter.TEST(16, R(EAX), Imm16(SR_ARITH_ZERO));
|
||||||
break;
|
break;
|
||||||
case 0x4: // NZ - Not Zero
|
case 0x4: // NZ - Not Zero
|
||||||
|
@ -148,7 +158,7 @@ void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
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.
|
// Jump directly to the next block if it has already been compiled.
|
||||||
// TODO: Subtract cycles from cyclesLeft
|
// 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, R(EAX), M(&g_dsp.r[reg]));
|
||||||
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
||||||
#else
|
#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(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
emitter.MOV(16, MDisp(RAX,0), R(RSI));
|
emitter.MOV(16, MatR(RAX), R(RSI));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// Generic jmpr implementation
|
// 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, R(EAX), M(&g_dsp.r[reg]));
|
||||||
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
||||||
#else
|
#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(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
emitter.MOV(16, MDisp(RAX,0), R(RSI));
|
emitter.MOV(16, MDisp(RAX,0), R(RSI));
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue