Fix #1520
This commit is contained in:
@ -1264,6 +1264,7 @@ typedef enum CPSRWriteType {
|
||||
CPSRWriteExceptionReturn = 1, /* from guest exception return insn */
|
||||
CPSRWriteRaw = 2, /* trust values, do not switch reg banks */
|
||||
CPSRWriteByGDBStub = 3, /* from the GDB stub */
|
||||
CPSRWriteByUnicorn = 4 /* from uc_reg_write */
|
||||
} CPSRWriteType;
|
||||
|
||||
/* Set the CPSR. Note that some bits of mask must be all-set or all-clear.*/
|
||||
|
@ -7983,9 +7983,12 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
|
||||
* to switch mode. (Those are caught by translate.c for writes
|
||||
* triggered by guest instructions.)
|
||||
*/
|
||||
// mask &= ~CPSR_M;
|
||||
// Unicorn: No, it can also be uc_reg_write
|
||||
switch_mode(env, val & CPSR_M);
|
||||
mask &= ~CPSR_M;
|
||||
|
||||
// Unicorn: No, it can also be uc_reg_write, let user switch registers banks.
|
||||
if (write_type == CPSRWriteByUnicorn) {
|
||||
switch_mode(env, val & CPSR_M);
|
||||
}
|
||||
} else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
|
||||
/* Attempt to switch to an invalid mode: this is UNPREDICTABLE in
|
||||
* v7, and has defined behaviour in v8:
|
||||
|
@ -251,17 +251,17 @@ static void reg_write(CPUARMState *env, unsigned int regid, const void *value)
|
||||
case UC_ARM_REG_APSR:
|
||||
if (!arm_feature(env, ARM_FEATURE_M)) {
|
||||
cpsr_write(env, *(uint32_t *)value,
|
||||
(CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByInstr);
|
||||
(CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByUnicorn);
|
||||
} else {
|
||||
// Same with UC_ARM_REG_APSR_NZCVQ
|
||||
v7m_msr_xpsr(env, 0b1000, 0, *(uint32_t *)value);
|
||||
}
|
||||
break;
|
||||
case UC_ARM_REG_APSR_NZCV:
|
||||
cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteByInstr);
|
||||
cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteByUnicorn);
|
||||
break;
|
||||
case UC_ARM_REG_CPSR:
|
||||
cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByInstr);
|
||||
cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByUnicorn);
|
||||
break;
|
||||
case UC_ARM_REG_SPSR:
|
||||
env->spsr = *(uint32_t *)value;
|
||||
|
Reference in New Issue
Block a user