mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-25 12:40:08 +00:00
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
This commit is contained in:
parent
a03ffaefce
commit
f1e2598c46
@ -1285,6 +1285,7 @@ static inline uint32_t xpsr_read(CPUARMState *env)
|
|||||||
| (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
|
| (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
|
||||||
| (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
|
| (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
|
||||||
| ((env->condexec_bits & 0xfc) << 8)
|
| ((env->condexec_bits & 0xfc) << 8)
|
||||||
|
| (env->GE << 16)
|
||||||
| env->v7m.exception;
|
| env->v7m.exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1300,6 +1301,9 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
|||||||
if (mask & XPSR_Q) {
|
if (mask & XPSR_Q) {
|
||||||
env->QF = ((val & XPSR_Q) != 0);
|
env->QF = ((val & XPSR_Q) != 0);
|
||||||
}
|
}
|
||||||
|
if (mask & XPSR_GE) {
|
||||||
|
env->GE = (val & XPSR_GE) >> 16;
|
||||||
|
}
|
||||||
if (mask & XPSR_T) {
|
if (mask & XPSR_T) {
|
||||||
env->thumb = ((val & XPSR_T) != 0);
|
env->thumb = ((val & XPSR_T) != 0);
|
||||||
}
|
}
|
||||||
|
@ -8727,7 +8727,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
|
|||||||
{
|
{
|
||||||
CPUARMState *env = &cpu->env;
|
CPUARMState *env = &cpu->env;
|
||||||
uint32_t excret;
|
uint32_t excret;
|
||||||
uint32_t xpsr;
|
uint32_t xpsr, xpsr_mask;
|
||||||
bool ufault = false;
|
bool ufault = false;
|
||||||
bool sfault = false;
|
bool sfault = false;
|
||||||
bool return_to_sp_process;
|
bool return_to_sp_process;
|
||||||
@ -9179,8 +9179,13 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
|
|||||||
}
|
}
|
||||||
*frame_sp_p = frameptr;
|
*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 */
|
/* 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) {
|
if (env->v7m.secure) {
|
||||||
bool sfpa = xpsr & XPSR_SFPA;
|
bool sfpa = xpsr & XPSR_SFPA;
|
||||||
@ -12665,6 +12670,9 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
|
|||||||
}
|
}
|
||||||
if (!(reg & 4)) {
|
if (!(reg & 4)) {
|
||||||
mask |= XPSR_NZCV | XPSR_Q; /* APSR */
|
mask |= XPSR_NZCV | XPSR_Q; /* APSR */
|
||||||
|
if (arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
mask |= XPSR_GE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* EPSR reads as zero */
|
/* EPSR reads as zero */
|
||||||
return xpsr_read(env) & mask;
|
return xpsr_read(env) & mask;
|
||||||
|
Loading…
Reference in New Issue
Block a user