ARM7: Flush prefetch cache when loading CPSR via MSR
Jeffrey Pfau jeffrey@endrift.com
Mon, 16 May 2016 01:18:09 -0700
3 files changed,
20 insertions(+),
4 deletions(-)
M
CHANGES
→
CHANGES
@@ -40,6 +40,7 @@ - All: Add QUIET parameter to silence CMake
- GBA Video: Null renderer should return proper register values - Libretro: Disable logging game errors, BIOS calls and stubs in release builds - ARM7: Support forcing Thumb mode via MSR + - ARM7: Flush prefetch cache when loading CPSR via MSR 0.4.0: (2016-02-02) Features:
M
src/arm/isa-arm.c
→
src/arm/isa-arm.c
@@ -636,7 +636,14 @@ if (cpu->privilegeMode != MODE_USER && (mask & PSR_PRIV_MASK)) {
ARMSetPrivilegeMode(cpu, (enum PrivilegeMode) ((operand & 0x0000000F) | 0x00000010)); cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); } - _ARMReadCPSR(cpu);) + _ARMReadCPSR(cpu); + if (cpu->executionMode == MODE_THUMB) { + LOAD_16(cpu->prefetch[0], (cpu->gprs[ARM_PC] - WORD_SIZE_THUMB) & cpu->memory.activeMask, cpu->memory.activeRegion); + LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + } else { + LOAD_32(cpu->prefetch[0], (cpu->gprs[ARM_PC] - WORD_SIZE_ARM) & cpu->memory.activeMask, cpu->memory.activeRegion); + LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + }) DEFINE_INSTRUCTION_ARM(MSRR, int c = opcode & 0x00010000;@@ -663,11 +670,21 @@ int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0);
if (mask & PSR_USER_MASK) { cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_MASK); } + if (mask & PSR_STATE_MASK) { + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK); + } if (cpu->privilegeMode != MODE_USER && (mask & PSR_PRIV_MASK)) { ARMSetPrivilegeMode(cpu, (enum PrivilegeMode) ((operand & 0x0000000F) | 0x00000010)); cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); } - _ARMReadCPSR(cpu);) + _ARMReadCPSR(cpu); + if (cpu->executionMode == MODE_THUMB) { + LOAD_16(cpu->prefetch[0], (cpu->gprs[ARM_PC] - WORD_SIZE_THUMB) & cpu->memory.activeMask, cpu->memory.activeRegion); + LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + } else { + LOAD_32(cpu->prefetch[0], (cpu->gprs[ARM_PC] - WORD_SIZE_ARM) & cpu->memory.activeMask, cpu->memory.activeRegion); + LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + }) DEFINE_INSTRUCTION_ARM(MSRRI, int c = opcode & 0x00010000;
M
src/arm/isa-inlines.h
→
src/arm/isa-inlines.h
@@ -85,8 +85,6 @@ cpu->cpsr.t = 0;
break; case MODE_THUMB: cpu->cpsr.t = 1; - cpu->prefetch[0] &= 0xFFFF; - cpu->prefetch[1] &= 0xFFFF; } cpu->nextEvent = cpu->cycles; }