mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-21 05:09:46 -06:00
Fix edge case in the division engine, fix edge case in the CPU (#1003)
* Fixed division edge case: Div64/32 and Div64/64 set the remainder to 0 if dividend == INT64_MIN && divisor == -1 * Fixed CPU edge case where ARM9 ALU ops would switch to Thumb even when they shouldn't * Only clear the lowest bit of the jump address in ALU ops with rd==15 (on recommendation of RSDuck)
This commit is contained in:
@ -290,7 +290,7 @@ void A_##x##_REG_ROR_REG(ARM* cpu) \
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -321,7 +321,7 @@ A_IMPLEMENT_ALU_OP(AND,_S)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -352,7 +352,7 @@ A_IMPLEMENT_ALU_OP(EOR,_S)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -385,7 +385,7 @@ A_IMPLEMENT_ALU_OP(SUB,)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -418,7 +418,7 @@ A_IMPLEMENT_ALU_OP(RSB,)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -451,7 +451,7 @@ A_IMPLEMENT_ALU_OP(ADD,)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -486,7 +486,7 @@ A_IMPLEMENT_ALU_OP(ADC,)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -521,7 +521,7 @@ A_IMPLEMENT_ALU_OP(SBC,)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -600,7 +600,7 @@ A_IMPLEMENT_ALU_TEST(CMN,)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -629,7 +629,7 @@ A_IMPLEMENT_ALU_OP(ORR,_S)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(b); \
|
cpu->JumpTo(b & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -673,7 +673,7 @@ void A_MOV_REG_LSL_IMM_DBG(ARM* cpu)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(res); \
|
cpu->JumpTo(res & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
@ -703,7 +703,7 @@ A_IMPLEMENT_ALU_OP(BIC,_S)
|
|||||||
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
cpu->JumpTo(b); \
|
cpu->JumpTo(b & ~1); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
|
@ -1758,6 +1758,7 @@ void DivDone(u32 param)
|
|||||||
else if (num == -0x8000000000000000 && den == -1)
|
else if (num == -0x8000000000000000 && den == -1)
|
||||||
{
|
{
|
||||||
*(s64*)&DivQuotient[0] = 0x8000000000000000;
|
*(s64*)&DivQuotient[0] = 0x8000000000000000;
|
||||||
|
*(s64*)&DivRemainder[0] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1779,6 +1780,7 @@ void DivDone(u32 param)
|
|||||||
else if (num == -0x8000000000000000 && den == -1)
|
else if (num == -0x8000000000000000 && den == -1)
|
||||||
{
|
{
|
||||||
*(s64*)&DivQuotient[0] = 0x8000000000000000;
|
*(s64*)&DivQuotient[0] = 0x8000000000000000;
|
||||||
|
*(s64*)&DivRemainder[0] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user