From ebc1168b605bdbe84a5d3167afcc0a7278b83c68 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:47:53 -0500 Subject: [PATCH] implement queueing ldr RORs and sign extension --- src/ARM.cpp | 5 ---- src/ARM.h | 11 +++++++- src/ARMInterpreter_LoadStore.cpp | 44 +++++++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/ARM.cpp b/src/ARM.cpp index 0bc138c2..68770b19 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -510,11 +510,6 @@ void ARM::RestoreCPSR() UpdateMode(oldcpsr, CPSR); } -void ARMv5::QueueUpdateMode() -{ - UpdateMode(QueueMode[0], QueueMode[1], true); -} - void ARM::UpdateMode(u32 oldmode, u32 newmode, bool phony) { if ((oldmode & 0x1F) == (newmode & 0x1F)) return; diff --git a/src/ARM.h b/src/ARM.h index 9fb195f4..92052674 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -206,6 +206,8 @@ public: bool BranchRestore; u32 QueueMode[2]; + u8 ExtReg; + u8 ExtROROffs; u64 RetVal; @@ -665,7 +667,14 @@ public: void DWrite16_2(); void DWrite32_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 diff --git a/src/ARMInterpreter_LoadStore.cpp b/src/ARMInterpreter_LoadStore.cpp index 56380e6c..6fb39f74 100644 --- a/src/ARMInterpreter_LoadStore.cpp +++ b/src/ARMInterpreter_LoadStore.cpp @@ -115,9 +115,17 @@ void LoadSingle(ARM* cpu, const u8 rd, const u8 rn, const s32 offset, const u16 ((ARMv5*)cpu)->DataAbort(); 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) { @@ -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 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::None) @@ -508,8 +531,17 @@ inline void SWP(ARM* cpu) { // 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(); if (rd != 15)