diff options
author | wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> | 2021-02-20 00:58:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-19 23:58:41 +0100 |
commit | 03b465c5e2f099c12d0816e89e008c98ccbffd8a (patch) | |
tree | dbb5ad8466c3c4bbab2b9dbe42449383a0234eb1 | |
parent | a8b2c22306c7931c5fb4e504dfa87f8462b6fb02 (diff) |
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)
-rw-r--r-- | src/ARMInterpreter_ALU.cpp | 24 | ||||
-rw-r--r-- | src/NDS.cpp | 2 |
2 files changed, 14 insertions, 12 deletions
diff --git a/src/ARMInterpreter_ALU.cpp b/src/ARMInterpreter_ALU.cpp index 2095432..39d14a9 100644 --- a/src/ARMInterpreter_ALU.cpp +++ b/src/ARMInterpreter_ALU.cpp @@ -290,7 +290,7 @@ void A_##x##_REG_ROR_REG(ARM* cpu) \ if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -321,7 +321,7 @@ A_IMPLEMENT_ALU_OP(AND,_S) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -352,7 +352,7 @@ A_IMPLEMENT_ALU_OP(EOR,_S) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -385,7 +385,7 @@ A_IMPLEMENT_ALU_OP(SUB,) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -418,7 +418,7 @@ A_IMPLEMENT_ALU_OP(RSB,) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -451,7 +451,7 @@ A_IMPLEMENT_ALU_OP(ADD,) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -486,7 +486,7 @@ A_IMPLEMENT_ALU_OP(ADC,) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -521,7 +521,7 @@ A_IMPLEMENT_ALU_OP(SBC,) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -600,7 +600,7 @@ A_IMPLEMENT_ALU_TEST(CMN,) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -629,7 +629,7 @@ A_IMPLEMENT_ALU_OP(ORR,_S) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(b); \ + cpu->JumpTo(b & ~1); \ } \ 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 (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(res); \ + cpu->JumpTo(res & ~1); \ } \ else \ { \ @@ -703,7 +703,7 @@ A_IMPLEMENT_ALU_OP(BIC,_S) if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); \ if (((cpu->CurInstr>>12) & 0xF) == 15) \ { \ - cpu->JumpTo(b); \ + cpu->JumpTo(b & ~1); \ } \ else \ { \ diff --git a/src/NDS.cpp b/src/NDS.cpp index 6c41cb5..7313c2a 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1758,6 +1758,7 @@ void DivDone(u32 param) else if (num == -0x8000000000000000 && den == -1) { *(s64*)&DivQuotient[0] = 0x8000000000000000; + *(s64*)&DivRemainder[0] = 0; } else { @@ -1779,6 +1780,7 @@ void DivDone(u32 param) else if (num == -0x8000000000000000 && den == -1) { *(s64*)&DivQuotient[0] = 0x8000000000000000; + *(s64*)&DivRemainder[0] = 0; } else { |