summaryrefslogtreecommitdiffstats
path: root/target/arm/helper.c
diff options
context:
space:
mode:
authorPeter Maydell2019-05-07 13:55:04 +0200
committerPeter Maydell2019-05-07 13:55:04 +0200
commitf1e2598c46d480c9e21213a244bc514200762828 (patch)
tree367353f17159f60700969b5153b9f31beb20e538 /target/arm/helper.c
parenthw/intc/armv7m_nvic: Don't enable ARMV7M_EXCP_DEBUG from reset (diff)
downloadqemu-f1e2598c46d480c9e21213a244bc514200762828.tar.gz
qemu-f1e2598c46d480c9e21213a244bc514200762828.tar.xz
qemu-f1e2598c46d480c9e21213a244bc514200762828.zip
target/arm: Implement XPSR GE bits
In the M-profile architecture, if the CPU implements the DSP extension then the XPSR has GE bits, in the same way as the A-profile CPSR. When we added DSP extension support we forgot to add support for reading and writing the GE bits, which are stored in env->GE. We did put in the code to add XPSR_GE to the mask of bits to update in the v7m_msr helper, but forgot it in v7m_mrs. We also must not allow the XPSR we pull off the stack on exception return to set the nonexistent GE bits. Correct these errors: * read and write env->GE in xpsr_read() and xpsr_write() * only set GE bits on exception return if DSP present * read GE bits for MRS if DSP present Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20190430131439.25251-5-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/helper.c')
-rw-r--r--target/arm/helper.c12
1 files changed, 10 insertions, 2 deletions
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;