target-arm: Add write_type argument to cpsr_write()

Add an argument to cpsr_write() to indicate what kind of CPSR
write is being requested, since the exact behaviour should
differ for the different cases.

Backports commit 50866ba5a2cfe922aaf3edb79f6eac5b0653477a from qemu
This commit is contained in:
Peter Maydell 2018-02-20 22:10:52 -05:00 committed by Lioncash
parent 6ae2357be6
commit 611d4dad4b
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
5 changed files with 19 additions and 9 deletions

View file

@ -724,8 +724,17 @@ static inline void pstate_write(CPUARMState *env, uint32_t val)
/* Return the current CPSR value. */
uint32_t cpsr_read(CPUARMState *env);
/* Set the CPSR. Note that some bits of mask must be all-set or all-clear. */
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask);
typedef enum CPSRWriteType {
CPSRWriteByInstr = 0, /* from guest MSR or CPS */
CPSRWriteExceptionReturn = 1, /* from guest exception return insn */
CPSRWriteRaw = 2, /* trust values, do not switch reg banks */
CPSRWriteByGDBStub = 3, /* from the GDB stub */
} CPSRWriteType;
/* Set the CPSR. Note that some bits of mask must be all-set or all-clear.*/
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
CPSRWriteType write_type);
/* Return the current xPSR value. */
static inline uint32_t xpsr_read(CPUARMState *env)

View file

@ -4536,7 +4536,8 @@ uint32_t cpsr_read(CPUARMState *env)
| (env->GE << 16) | (env->daif & CPSR_AIF);
}
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
CPSRWriteType write_type)
{
uint32_t changed_daif;

View file

@ -422,13 +422,13 @@ uint32_t HELPER(cpsr_read)(CPUARMState *env)
void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
{
cpsr_write(env, val, mask);
cpsr_write(env, val, mask, CPSRWriteByInstr);
}
/* Write the CPSR for a 32-bit exception return */
void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
{
cpsr_write(env, val, CPSR_ERET_MASK);
cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn);
}
/* Access to user mode registers from privileged modes. */
@ -780,7 +780,7 @@ void HELPER(exception_return)(CPUARMState *env)
if (!return_to_aa64) {
env->aarch64 = 0;
env->uncached_cpsr = spsr & CPSR_M;
cpsr_write(env, spsr, ~0);
cpsr_write(env, spsr, ~0, CPSRWriteRaw);
if (!arm_singlestep_active(env)) {
env->uncached_cpsr &= ~PSTATE_SS;
}

View file

@ -181,7 +181,7 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals,
ARM_CPU(uc, mycpu)->env.xregs[31] = *(uint64_t *)value;
break;
case UC_ARM64_REG_NZCV:
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *) value, CPSR_NZCV);
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *) value, CPSR_NZCV, CPSRWriteRaw);
break;
case UC_ARM64_REG_PSTATE:
pstate_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value);

View file

@ -112,10 +112,10 @@ int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, i
else {
switch(regid) {
case UC_ARM_REG_APSR:
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, CPSR_NZCV);
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteRaw);
break;
case UC_ARM_REG_CPSR:
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, ~0);
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, ~0, CPSRWriteRaw);
break;
//case UC_ARM_REG_SP:
case UC_ARM_REG_R13: