implement user mode load/stores

This commit is contained in:
Jaklyy 2024-08-26 20:43:27 -04:00
parent f692e7391a
commit a9aad74539
1 changed files with 22 additions and 9 deletions

View File

@ -63,6 +63,7 @@ enum class Writeback
None = 0,
Pre,
Post,
Trans,
};
template<bool signror, int size, Writeback writeback>
@ -71,15 +72,27 @@ void LoadSingle(ARM* cpu, u8 rd, u8 rn, s32 offset)
static_assert((size == 8) || (size == 16) || (size == 32), "dummy this function only takes 8/16/32 for size!!!");
u32 addr;
if constexpr (writeback != Writeback::Post) addr = offset + cpu->R[rn];
if constexpr (writeback < Writeback::Post) addr = offset + cpu->R[rn];
else addr = cpu->R[rn];
if constexpr (writeback == Writeback::Trans)
{
if (cpu->Num == 0)
((ARMv5*)cpu)->PU_Map = ((ARMv5*)cpu)->PU_UserMap;
}
u32 val;
bool dataabort;
if constexpr (size == 8) dataabort = !cpu->DataRead8 (addr, &val);
if constexpr (size == 16) dataabort = !cpu->DataRead16(addr, &val);
if constexpr (size == 32) dataabort = !cpu->DataRead32(addr, &val);
if constexpr (writeback == Writeback::Trans)
{
if (cpu->Num == 0 && (cpu->CPSR & 0x1F) != 0x10)
((ARMv5*)cpu)->PU_Map = ((ARMv5*)cpu)->PU_PrivMap;
}
cpu->AddCycles_CDI();
if (dataabort) return;
@ -125,33 +138,33 @@ void StoreSingle(ARM* cpu, u8 rd, u8 rn, s32 offset)
if (cpu->CurInstr & (1<<21)) StoreSingle<32, Writeback::Pre>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset); \
else StoreSingle<32, Writeback::None>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
// TODO: user mode (bit21)
#define A_STR_POST \
StoreSingle<32, Writeback::Post>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
if (cpu->CurInstr & (1<<21)) StoreSingle<32, Writeback::Trans>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset); \
else StoreSingle<32, Writeback::Post>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
#define A_STRB \
if (cpu->CurInstr & (1<<21)) StoreSingle<8, Writeback::Pre>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset); \
else StoreSingle<8, Writeback::None>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
// TODO: user mode (bit21)
#define A_STRB_POST \
StoreSingle<8, Writeback::Post>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
if (cpu->CurInstr & (1<<21)) StoreSingle<8, Writeback::Trans>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset); \
else StoreSingle<8, Writeback::Post>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
#define A_LDR \
if (cpu->CurInstr & (1<<21)) LoadSingle<true, 32, Writeback::Pre>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset); \
else LoadSingle<true, 32, Writeback::None>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
// TODO: user mode
#define A_LDR_POST \
LoadSingle<true, 32, Writeback::Post>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
if (cpu->CurInstr & (1<<21)) LoadSingle<true, 32, Writeback::Trans>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset); \
else LoadSingle<true, 32, Writeback::Post>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
#define A_LDRB \
if (cpu->CurInstr & (1<<21)) LoadSingle<false, 8, Writeback::Pre>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset); \
else LoadSingle<false, 8, Writeback::None>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
// TODO: user mode
#define A_LDRB_POST \
LoadSingle<false, 8, Writeback::Post>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);
if (cpu->CurInstr & (1<<21)) LoadSingle<false, 8, Writeback::Trans>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset); \
else LoadSingle<false, 8, Writeback::Post>(cpu, ((cpu->CurInstr>>12) & 0xF), ((cpu->CurInstr>>16) & 0xF), offset);