Fix some MRS/MSR encoding problems

This commit is contained in:
Jeffrey Pfau 2013-04-18 00:03:39 -07:00
parent 6608ae282c
commit b3832205fc
1 changed files with 25 additions and 16 deletions

View File

@ -582,22 +582,31 @@ DEFINE_INSTRUCTION_ARM(MSR,
operand = cpu->gprs[opcode & 0x0000000F]; operand = cpu->gprs[opcode & 0x0000000F];
} }
int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0); 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) { if (mask & PSR_USER_MASK) {
cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & 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)) { if (cpu->privilegeMode != MODE_USER && (mask & PSR_PRIV_MASK)) {
ARMSetPrivilegeMode(cpu, (enum PrivilegeMode) ((operand & 0x0000000F) | 0x00000010)); ARMSetPrivilegeMode(cpu, (enum PrivilegeMode) ((operand & 0x0000000F) | 0x00000010));
cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); 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(MRS, ARM_STUB)
DEFINE_INSTRUCTION_ARM(MRSR, ARM_STUB)
DEFINE_INSTRUCTION_ARM(MSRI, ARM_STUB) DEFINE_INSTRUCTION_ARM(MSRI, ARM_STUB)
DEFINE_INSTRUCTION_ARM(MRSI, ARM_STUB)
DEFINE_INSTRUCTION_ARM(SWI, ARM_STUB) DEFINE_INSTRUCTION_ARM(SWI, ARM_STUB)
#define DECLARE_INSTRUCTION_ARM(EMITTER, NAME) \ #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_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \ 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), \ 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_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP), \ 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), \ 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, SBCS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS), \ 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, TST), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ), \ 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, CMP), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \