reimplement changing t bit with arm7

kinda slow though?
This commit is contained in:
Jaklyy 2024-09-20 13:34:27 -04:00
parent 7afa805afc
commit 157e9c5b04
4 changed files with 51 additions and 63 deletions

View File

@ -385,6 +385,7 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr)
if (addr & 0x1)
{
Thumb = true;
addr &= ~0x1;
R[15] = addr+2;
@ -398,6 +399,7 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr)
}
else
{
Thumb = false;
addr &= ~0x3;
R[15] = addr+4;
@ -831,35 +833,63 @@ void ARMv4::Execute()
else
#endif
{
if (CPSR & 0x20) // THUMB
if (Thumb) // THUMB
{
// attempt to delay t bit changes without a pipeline flush (msr) by one instruction
Thumb = CPSR & 0x20;
if constexpr (mode == CPUExecuteMode::InterpreterGDB)
GdbCheckC();
// prefetch
R[15] += 2;
CurInstr = NextInstr[0];
NextInstr[0] = NextInstr[1];
NextInstr[1] = CodeRead16(R[15]);
// thumb bit can change without a flush and is usually delayed 1 instruction
// but if the code fetch takes more than 1 cycle(?) it can take effect early for just the code fetch
if (!Thumb && (NDS.ARM7MemTimings[CodeCycles][2] > 1)) [[unlikely]] // checkme
{
R[15] = (R[15] + 4) & ~0x3;
CurInstr = NextInstr[0];
NextInstr[0] = NextInstr[1];
NextInstr[1] = CodeRead32(R[15]);
}
else
{
R[15] += 2;
CurInstr = NextInstr[0];
NextInstr[0] = NextInstr[1];
NextInstr[1] = CodeRead16(R[15]);
}
if (IRQ && !(CPSR & 0x80)) TriggerIRQ<mode>();
else
{
// actually execute
u32 icode = (CurInstr >> 6);
u32 icode = (CurInstr >> 6) & 0x3FF;
ARMInterpreter::THUMBInstrTable[icode](this);
}
}
else
{
// attempt to delay t bit changes without a pipeline flush (msr) by one instruction
Thumb = CPSR & 0x20;
if constexpr (mode == CPUExecuteMode::InterpreterGDB)
GdbCheckC();
// prefetch
R[15] += 4;
CurInstr = NextInstr[0];
NextInstr[0] = NextInstr[1];
NextInstr[1] = CodeRead32(R[15]);
// thumb bit can change without a flush and is usually delayed 1 instruction
// but if the code fetch takes more than 1 cycle(?) it can take effect early for just the code fetch
if (Thumb && (NDS.ARM7MemTimings[CodeCycles][2] > 1)) [[unlikely]] // checkme?
{
R[15] = (R[15] + 4) & ~0x3;
CurInstr = NextInstr[0];
NextInstr[0] = NextInstr[1];
NextInstr[1] = CodeRead16(R[15]);
}
else
{
R[15] = (R[15] + 4) & ~0x3;
CurInstr = NextInstr[0];
NextInstr[0] = NextInstr[1];
NextInstr[1] = CodeRead32(R[15]);
}
if (IRQ && !(CPSR & 0x80)) TriggerIRQ<mode>();
else if (CheckCondition(CurInstr >> 28)) // actually execute

View File

@ -416,6 +416,9 @@ public:
void AddCycles_CDI() override;
void AddCycles_CD() override;
private:
bool Thumb;
protected:
u8 BusRead8(u32 addr) override;
u16 BusRead16(u32 addr) override;

View File

@ -129,11 +129,11 @@ void A_MSR_IMM(ARM* cpu)
if (cpu->CPSR & 0x20) [[unlikely]]
{
if (cpu->Num == 0) cpu->NextInstr[1] &= 0xFFFF; // checkme: probably not the right way to handle this
else
/*else
{
Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: MSR REG T bit change on ARM7\n");
cpu->CPSR &= ~0x20; // keep it from crashing the emulator at least
}
}*/
}
cpu->AddCycles_C();

View File

@ -585,16 +585,7 @@ A_IMPLEMENT_ALU_OP(RSC,)
!res); \
if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* yes this instruction has a secret rd for some reason */ \
{ \
if (cpu->Num == 1) \
{ \
u32 oldpsr = cpu->CPSR; \
cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \
if (cpu->CPSR & 0x20) \
{ \
Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TST T bit change on ARM7\n"); \
cpu->CPSR &= ~0x20; /* keep it from crashing the emulator at least */ \
} \
} \
if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7 restores cpsr and does ___not___ flush the pipeline. */ \
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TST w/ rd == 15 on ARM9\n"); \
} \
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C();
@ -609,16 +600,7 @@ A_IMPLEMENT_ALU_TEST(TST,_S)
!res); \
if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* yes this instruction has a secret rd for some reason */ \
{ \
if (cpu->Num == 1) \
{ \
u32 oldpsr = cpu->CPSR; \
cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \
if (cpu->CPSR & 0x20) \
{ \
Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TEQ T bit change on ARM7\n"); \
cpu->CPSR &= ~0x20; /* keep it from crashing the emulator at least */ \
} \
} \
if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7 restores cpsr and does ___not___ flush the pipeline. */ \
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TEQ w/ rd == 15 on ARM9\n"); \
} \
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C();
@ -635,16 +617,7 @@ A_IMPLEMENT_ALU_TEST(TEQ,_S)
OverflowSub(a, b)); \
if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* yes this instruction has a secret rd for some reason */ \
{ \
if (cpu->Num == 1) \
{ \
u32 oldpsr = cpu->CPSR; \
cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \
if (cpu->CPSR & 0x20) \
{ \
Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMP T bit change on ARM7\n"); \
cpu->CPSR &= ~0x20; /* keep it from crashing the emulator at least */ \
} \
} \
if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7 restores cpsr and does ___not___ flush the pipeline. */ \
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMP w/ rd == 15 on ARM9\n"); \
} \
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C();
@ -661,16 +634,7 @@ A_IMPLEMENT_ALU_TEST(CMP,)
OverflowAdd(a, b)); \
if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* yes this instruction has a secret rd for some reason */ \
{ \
if (cpu->Num == 1) \
{ \
u32 oldpsr = cpu->CPSR; \
cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \
if (cpu->CPSR & 0x20) \
{ \
Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMN T bit change on ARM7\n"); \
cpu->CPSR &= ~0x20; /* keep it from crashing the emulator at least */ \
} \
} \
if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7 restores cpsr and does ___not___ flush the pipeline. */ \
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMN w/ rd == 15 on ARM9\n"); \
} \
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C();
@ -1627,16 +1591,7 @@ void T_CMP_HIREG(ARM* cpu)
OverflowSub(a, b));
if (rd == 15) [[unlikely]]
{
if (cpu->Num == 1)
{
u32 oldpsr = cpu->CPSR;
cpu->RestoreCPSR(); // ARM7TDMI restores cpsr and does ___not___ flush the pipeline.
if (!(cpu->CPSR & 0x20))
{
Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: MSR REG T bit change on ARM7\n");
cpu->CPSR |= 0x20; // keep it from crashing the emulator at least
}
}
if (cpu->Num == 1) cpu->RestoreCPSR(); // ARM7 restores cpsr and does ___not___ flush the pipeline.
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMP HIREG w/ rd == 15 on ARM9\n");
}
cpu->AddCycles_C();