diff options
author | Richard Henderson | 2019-10-23 17:00:37 +0200 |
---|---|---|
committer | Peter Maydell | 2019-10-24 18:16:27 +0200 |
commit | 8061a64910a3df76e3ef6905dfcc07d9071879ab (patch) | |
tree | 3042d2f9d67c2548f6df8a06ef363f00e7a1c268 /target/arm/cpu.h | |
parent | target/arm: Split out rebuild_hflags_common_32 (diff) | |
download | qemu-8061a64910a3df76e3ef6905dfcc07d9071879ab.tar.gz qemu-8061a64910a3df76e3ef6905dfcc07d9071879ab.tar.xz qemu-8061a64910a3df76e3ef6905dfcc07d9071879ab.zip |
target/arm: Split arm_cpu_data_is_big_endian
Set TBFLAG_ANY.BE_DATA in rebuild_hflags_common_32 and
rebuild_hflags_a64 instead of rebuild_hflags_common, where we do
not need to re-test is_a64() nor re-compute the various inputs.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20191023150057.25731-5-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/cpu.h')
-rw-r--r-- | target/arm/cpu.h | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index ad79a6153b..4d961474ce 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3108,33 +3108,44 @@ static inline uint64_t arm_sctlr(CPUARMState *env, int el) } } +static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env, + bool sctlr_b) +{ +#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. + */ + if (sctlr_b) { + return true; + } +#endif + /* In 32bit endianness is determined by looking at CPSR's E bit */ + return env->uncached_cpsr & CPSR_E; +} + +static inline bool arm_cpu_data_is_big_endian_a64(int el, uint64_t sctlr) +{ + return sctlr & (el ? SCTLR_EE : SCTLR_E0E); +} /* Return true if the processor is in big-endian mode. */ 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 -#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); + return arm_cpu_data_is_big_endian_a32(env, arm_sctlr_b(env)); } else { int cur_el = arm_current_el(env); uint64_t sctlr = arm_sctlr(env, cur_el); - - return (sctlr & (cur_el ? SCTLR_EE : SCTLR_E0E)) != 0; + return arm_cpu_data_is_big_endian_a64(cur_el, sctlr); } } |