implement queueing ldr RORs and sign extension

This commit is contained in:
Jaklyy 2024-12-05 15:47:53 -05:00
parent 5698cf1862
commit ebc1168b60
3 changed files with 48 additions and 12 deletions

View File

@ -510,11 +510,6 @@ void ARM::RestoreCPSR()
UpdateMode(oldcpsr, CPSR); UpdateMode(oldcpsr, CPSR);
} }
void ARMv5::QueueUpdateMode()
{
UpdateMode(QueueMode[0], QueueMode[1], true);
}
void ARM::UpdateMode(u32 oldmode, u32 newmode, bool phony) void ARM::UpdateMode(u32 oldmode, u32 newmode, bool phony)
{ {
if ((oldmode & 0x1F) == (newmode & 0x1F)) return; if ((oldmode & 0x1F) == (newmode & 0x1F)) return;

View File

@ -206,6 +206,8 @@ public:
bool BranchRestore; bool BranchRestore;
u32 QueueMode[2]; u32 QueueMode[2];
u8 ExtReg;
u8 ExtROROffs;
u64 RetVal; u64 RetVal;
@ -665,7 +667,14 @@ public:
void DWrite16_2(); void DWrite16_2();
void DWrite32_2(); void DWrite32_2();
void DWrite32S_2(); void DWrite32S_2();
void QueueUpdateMode();
void QueueUpdateMode() { UpdateMode(QueueMode[0], QueueMode[1], true); }
void SignExtend8() { R[ExtReg] = (s32)(s8)R[ExtReg]; }
void SignExtend16() { R[ExtReg] = (s32)(s16)R[ExtReg]; }
void ROR32() { R[ExtReg] = ROR(R[ExtReg], ExtROROffs); }
u32 CP15Control; //! CP15 Register 1: Control Register u32 CP15Control; //! CP15 Register 1: Control Register

View File

@ -115,9 +115,17 @@ void LoadSingle(ARM* cpu, const u8 rd, const u8 rn, const s32 offset, const u16
((ARMv5*)cpu)->DataAbort(); ((ARMv5*)cpu)->DataAbort();
return; return;
} }
if ((cpu->MRTrack.Type != MainRAMType::Null) && signextend && cpu->Num == 0) printf("ARGH ME BONES");
if constexpr (size == 8 && signextend) cpu->R[rd] = (s32)(s8)cpu->R[rd]; if constexpr (size == 8 && signextend)
{
if (cpu->Num == 0)
{
cpu->ExtReg = rd;
if (cpu->MRTrack.Type != MainRAMType::Null) ((ARMv5*)cpu)->FuncQueue[cpu->FuncQueueFill++] = &ARMv5::SignExtend8;
else ((ARMv5*)cpu)->SignExtend8();
}
else cpu->R[rd] = (s32)(s8)cpu->R[rd];
}
if constexpr (size == 16) if constexpr (size == 16)
{ {
@ -126,10 +134,25 @@ void LoadSingle(ARM* cpu, const u8 rd, const u8 rn, const s32 offset, const u16
cpu->R[rd] = ROR(cpu->R[rd], ((addr&0x1)<<3)); // unaligned 16 bit loads are ROR'd on arm7 cpu->R[rd] = ROR(cpu->R[rd], ((addr&0x1)<<3)); // unaligned 16 bit loads are ROR'd on arm7
if constexpr (signextend) cpu->R[rd] = (s32)((addr&0x1) ? (s8)cpu->R[rd] : (s16)cpu->R[rd]); // sign extend like a ldrsb if we ror'd the value. if constexpr (signextend) cpu->R[rd] = (s32)((addr&0x1) ? (s8)cpu->R[rd] : (s16)cpu->R[rd]); // sign extend like a ldrsb if we ror'd the value.
} }
else if constexpr (signextend) cpu->R[rd] = (s32)(s16)cpu->R[rd]; else if constexpr (signextend)
{
cpu->ExtReg = rd;
if (cpu->MRTrack.Type != MainRAMType::Null) ((ARMv5*)cpu)->FuncQueue[cpu->FuncQueueFill++] = &ARMv5::SignExtend16;
else ((ARMv5*)cpu)->SignExtend16();
}
} }
if constexpr (size == 32) cpu->R[rd] = ROR(cpu->R[rd], ((addr&0x3)<<3)); if constexpr (size == 32)
{
if (cpu->Num == 0)
{
cpu->ExtReg = rd;
cpu->ExtROROffs = (addr & 0x3) * 8;
if (cpu->MRTrack.Type != MainRAMType::Null) ((ARMv5*)cpu)->FuncQueue[cpu->FuncQueueFill++] = &ARMv5::ROR32;
else ((ARMv5*)cpu)->ROR32();
}
else cpu->R[rd] = ROR(cpu->R[rd], ((addr&0x3)*8));
}
if constexpr (writeback >= Writeback::Post) addr += offset; if constexpr (writeback >= Writeback::Post) addr += offset;
if constexpr (writeback != Writeback::None) if constexpr (writeback != Writeback::None)
@ -508,8 +531,17 @@ inline void SWP(ARM* cpu)
{ {
// rd only gets updated if both read and write succeed // rd only gets updated if both read and write succeed
if constexpr (!byte) cpu->R[rd] = ROR(cpu->R[rd], 8*(base&0x3)); if constexpr (!byte)
{
if (cpu->Num == 0)
{
cpu->ExtReg = rd;
cpu->ExtROROffs = (base & 0x3) * 8;
if (cpu->MRTrack.Type != MainRAMType::Null) ((ARMv5*)cpu)->FuncQueue[cpu->FuncQueueFill++] = &ARMv5::ROR32;
else ((ARMv5*)cpu)->ROR32();
}
else cpu->R[rd] = ROR(cpu->R[rd], ((base&0x3)*8));
}
cpu->AddCycles_CDI(); cpu->AddCycles_CDI();
if (rd != 15) if (rd != 15)