implement queueing ldr RORs and sign extension
This commit is contained in:
parent
5698cf1862
commit
ebc1168b60
|
@ -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;
|
||||||
|
|
11
src/ARM.h
11
src/ARM.h
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue