diff options
-rw-r--r-- | target/arm/cpu.h | 4 | ||||
-rw-r--r-- | target/arm/helper.c | 12 |
2 files changed, 14 insertions, 2 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 0304ddd9f1..733b840a71 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1285,6 +1285,7 @@ static inline uint32_t xpsr_read(CPUARMState *env) | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) | (env->thumb << 24) | ((env->condexec_bits & 3) << 25) | ((env->condexec_bits & 0xfc) << 8) + | (env->GE << 16) | env->v7m.exception; } @@ -1300,6 +1301,9 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) if (mask & XPSR_Q) { env->QF = ((val & XPSR_Q) != 0); } + if (mask & XPSR_GE) { + env->GE = (val & XPSR_GE) >> 16; + } if (mask & XPSR_T) { env->thumb = ((val & XPSR_T) != 0); } diff --git a/target/arm/helper.c b/target/arm/helper.c index 9b805d0e6b..b9745a42ba 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8727,7 +8727,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) { CPUARMState *env = &cpu->env; uint32_t excret; - uint32_t xpsr; + uint32_t xpsr, xpsr_mask; bool ufault = false; bool sfault = false; bool return_to_sp_process; @@ -9179,8 +9179,13 @@ static void do_v7m_exception_exit(ARMCPU *cpu) } *frame_sp_p = frameptr; } + + xpsr_mask = ~(XPSR_SPREALIGN | XPSR_SFPA); + if (!arm_feature(env, ARM_FEATURE_THUMB_DSP)) { + xpsr_mask &= ~XPSR_GE; + } /* This xpsr_write() will invalidate frame_sp_p as it may switch stack */ - xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA)); + xpsr_write(env, xpsr, xpsr_mask); if (env->v7m.secure) { bool sfpa = xpsr & XPSR_SFPA; @@ -12665,6 +12670,9 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) } if (!(reg & 4)) { mask |= XPSR_NZCV | XPSR_Q; /* APSR */ + if (arm_feature(env, ARM_FEATURE_THUMB_DSP)) { + mask |= XPSR_GE; + } } /* EPSR reads as zero */ return xpsr_read(env) & mask; |