diff options
author | Peter Crosthwaite <crosthwaitepeter@gmail.com> | 2016-03-04 11:30:19 +0000 |
---|---|---|
committer | Timothy Pearson <tpearson@raptorengineering.com> | 2019-11-29 19:49:12 -0600 |
commit | d6ae1524fd151b28c819a380e3e164e6e3fb561c (patch) | |
tree | aec6c197d2b62987d580434734d55368ad89cfda /target-arm | |
parent | 73095f13798b044196573cf5f0a87a28c6ca76ad (diff) | |
download | hqemu-d6ae1524fd151b28c819a380e3e164e6e3fb561c.zip hqemu-d6ae1524fd151b28c819a380e3e164e6e3fb561c.tar.gz |
arm: cpu: handle BE32 user-mode as BE
endian with address manipulations on subword accesses (to give the
illusion of BE). But user-mode cannot tell the difference and is
already implemented as straight BE. So handle the difference in the
endianess query, where USER mode is BE and system is not.
Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm')
-rw-r--r-- | target-arm/cpu.h | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 6c4e1a1..d425d1b 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -1917,7 +1917,22 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env) /* In 32bit endianness is determined by looking at CPSR's E bit */ if (!is_a64(env)) { - return (env->uncached_cpsr & CPSR_E) ? 1 : 0; + return +#ifdef CONFIG_USER_ONLY + /* In system mode, BE32 is modelled in line with the + * architecture (as word-invariant big-endianness), where loads + * and stores are done little endian but from addresses which + * are adjusted by XORing with the appropriate constant. So the + * endianness to use for the raw data access is not affected by + * SCTLR.B. + * In user mode, however, we model BE32 as byte-invariant + * big-endianness (because user-only code cannot tell the + * difference), and so we need to use a data access endianness + * that depends on SCTLR.B. + */ + arm_sctlr_b(env) || +#endif + ((env->uncached_cpsr & CPSR_E) ? 1 : 0); } cur_el = arm_current_el(env); |