diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index b3815dd10..da8dd2cf2 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -582,22 +582,31 @@ DEFINE_INSTRUCTION_ARM(MSR, operand = cpu->gprs[opcode & 0x0000000F]; } int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0); - if (opcode & 0x00400000) { - mask &= PSR_USER_MASK | PSR_PRIV_MASK | PSR_STATE_MASK; - cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask); - } else { - if (mask & PSR_USER_MASK) { - cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_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); - } + if (mask & PSR_USER_MASK) { + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_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); }) +DEFINE_INSTRUCTION_ARM(MSRR, + int c = opcode & 0x00010000; + int f = opcode & 0x00080000; + int32_t operand; + if (opcode & 0x02000000) { + int rotate = (opcode & 0x00000F00) >> 8; + operand = ARM_ROR(opcode & 0x000000FF, rotate); + } else { + operand = cpu->gprs[opcode & 0x0000000F]; + } + int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0); + mask &= PSR_USER_MASK | PSR_PRIV_MASK | PSR_STATE_MASK; + cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask);) + DEFINE_INSTRUCTION_ARM(MRS, ARM_STUB) +DEFINE_INSTRUCTION_ARM(MRSR, ARM_STUB) DEFINE_INSTRUCTION_ARM(MSRI, ARM_STUB) -DEFINE_INSTRUCTION_ARM(MRSI, ARM_STUB) DEFINE_INSTRUCTION_ARM(SWI, ARM_STUB) #define DECLARE_INSTRUCTION_ARM(EMITTER, NAME) \ @@ -717,7 +726,7 @@ DEFINE_INSTRUCTION_ARM(SWI, ARM_STUB) DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MRS), \ + DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ @@ -734,7 +743,7 @@ DEFINE_INSTRUCTION_ARM(SWI, ARM_STUB) DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MSR), \ + DECLARE_INSTRUCTION_ARM(EMITTER, MSRR), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ @@ -775,11 +784,11 @@ DEFINE_INSTRUCTION_ARM(SWI, ARM_STUB) DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBCS), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MRS), \ + DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MRS), \ + DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \