diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-01-21 14:15:09 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-01-21 14:15:09 +0000 |
commit | c1e0371442bf3a7e42ad53c2a3d816ed7099f81d (patch) | |
tree | 82a4702083105ecf507d5472c39ea2d2977641b7 /target-arm | |
parent | e393f339af87da7210f6c86902b321df6a2e8bf5 (diff) |
target-arm: ignore ELR_ELx[1] for exception return to 32-bit ARM mode
The architecture requires that for an exception return to AArch32 the
low bits of ELR_ELx are ignored when the PC is set from them:
* if returning to Thumb mode, ignore ELR_ELx[0]
* if returning to ARM mode, ignore ELR_ELx[1:0]
We were only squashing bit 0; also squash bit 1 if the SPSR T bit
indicates this is a return to ARM code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Diffstat (limited to 'target-arm')
-rw-r--r-- | target-arm/op_helper.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 40224a8dfa..a5ee65fe2f 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -738,7 +738,11 @@ void HELPER(exception_return)(CPUARMState *env) } aarch64_sync_64_to_32(env); - env->regs[15] = env->elr_el[cur_el] & ~0x1; + if (spsr & CPSR_T) { + env->regs[15] = env->elr_el[cur_el] & ~0x1; + } else { + env->regs[15] = env->elr_el[cur_el] & ~0x3; + } } else { env->aarch64 = 1; pstate_write(env, spsr); |