Fix some MRS/MSR encoding problems
Jeffrey Pfau jeffrey@endrift.com
Thu, 18 Apr 2013 00:03:39 -0700
1 files changed,
25 insertions(+),
16 deletions(-)
jump to
M
src/arm/isa-arm.c
→
src/arm/isa-arm.c
@@ -582,22 +582,31 @@ } else {
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); + 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 { - 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); - } - }) + 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 @@ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
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 @@ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
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 @@ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBC), \
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), \