summaryrefslogtreecommitdiff
path: root/target-arm/cpu.h
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-03-04 11:30:19 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-03-04 11:30:19 +0000
commitf9fd40ebe4f55e0048e002925b8d65e66d56e7a7 (patch)
tree17f72ea122a29d8d141271b7387e26e852bd5a77 /target-arm/cpu.h
parent49017bd8b4395ba380c45c2fc41f4353fc2f0f06 (diff)
downloadqemu-f9fd40ebe4f55e0048e002925b8d65e66d56e7a7.tar.gz
target-arm: implement SCTLR.B, drop bswap_code
bswap_code is a CPU property of sorts ("is the iside endianness the opposite way round to TARGET_WORDS_BIGENDIAN?") but it is not the actual CPU state involved here which is SCTLR.B (set for BE32 binaries, clear for BE8). Replace bswap_code with SCTLR.B, and pass that to arm_ld*_code. The next patches will make data fetches honor both SCTLR.B and CPSR.E appropriately. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> [PC changes: * rebased on master (Jan 2016) * s/TARGET_USER_ONLY/CONFIG_USER_ONLY * Use bswap_code() for disas_set_info() instead of raw sctlr_b ] 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/cpu.h')
-rw-r--r--target-arm/cpu.h47
1 files changed, 39 insertions, 8 deletions
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 744f052a67..61b8b03f65 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -478,9 +478,6 @@ typedef struct CPUARMState {
uint32_t cregs[16];
} iwmmxt;
- /* For mixed endian mode. */
- bool bswap_code;
-
#if defined(CONFIG_USER_ONLY)
/* For usermode syscall translation. */
int eabi;
@@ -1898,6 +1895,19 @@ static inline bool arm_singlestep_active(CPUARMState *env)
&& arm_generate_debug_exceptions(env);
}
+static inline bool arm_sctlr_b(CPUARMState *env)
+{
+ return
+ /* We need not implement SCTLR.ITD in user-mode emulation, so
+ * let linux-user ignore the fact that it conflicts with SCTLR_B.
+ * This lets people run BE32 binaries with "-cpu any".
+ */
+#ifndef CONFIG_USER_ONLY
+ !arm_feature(env, ARM_FEATURE_V7) &&
+#endif
+ (env->cp15.sctlr_el[1] & SCTLR_B) != 0;
+}
+
#include "exec/cpu-all.h"
/* Bit usage in the TB flags field: bit 31 indicates whether we are
@@ -1928,8 +1938,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
#define ARM_TBFLAG_VFPEN_MASK (1 << ARM_TBFLAG_VFPEN_SHIFT)
#define ARM_TBFLAG_CONDEXEC_SHIFT 8
#define ARM_TBFLAG_CONDEXEC_MASK (0xff << ARM_TBFLAG_CONDEXEC_SHIFT)
-#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16
-#define ARM_TBFLAG_BSWAP_CODE_MASK (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
+#define ARM_TBFLAG_SCTLR_B_SHIFT 16
+#define ARM_TBFLAG_SCTLR_B_MASK (1 << ARM_TBFLAG_SCTLR_B_SHIFT)
/* We store the bottom two bits of the CPAR as TB flags and handle
* checks on the other bits at runtime
*/
@@ -1965,13 +1975,34 @@ static inline bool arm_singlestep_active(CPUARMState *env)
(((F) & ARM_TBFLAG_VFPEN_MASK) >> ARM_TBFLAG_VFPEN_SHIFT)
#define ARM_TBFLAG_CONDEXEC(F) \
(((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT)
-#define ARM_TBFLAG_BSWAP_CODE(F) \
- (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT)
+#define ARM_TBFLAG_SCTLR_B(F) \
+ (((F) & ARM_TBFLAG_SCTLR_B_MASK) >> ARM_TBFLAG_SCTLR_B_SHIFT)
#define ARM_TBFLAG_XSCALE_CPAR(F) \
(((F) & ARM_TBFLAG_XSCALE_CPAR_MASK) >> ARM_TBFLAG_XSCALE_CPAR_SHIFT)
#define ARM_TBFLAG_NS(F) \
(((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
+static inline bool bswap_code(bool sctlr_b)
+{
+#ifdef CONFIG_USER_ONLY
+ /* BE8 (SCTLR.B = 0, TARGET_WORDS_BIGENDIAN = 1) is mixed endian.
+ * The invalid combination SCTLR.B=1/CPSR.E=1/TARGET_WORDS_BIGENDIAN=0
+ * would also end up as a mixed-endian mode with BE code, LE data.
+ */
+ return
+#ifdef TARGET_WORDS_BIGENDIAN
+ 1 ^
+#endif
+ sctlr_b;
+#else
+ /* We do not implement BE32 mode for system-mode emulation, but
+ * anyway it would always do little-endian accesses with
+ * TARGET_WORDS_BIGENDIAN = 0.
+ */
+ return 0;
+#endif
+}
+
/* Return the exception level to which FP-disabled exceptions should
* be taken, or 0 if FP is enabled.
*/
@@ -2049,7 +2080,7 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
| (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
| (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
| (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
- | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT);
+ | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
if (!(access_secure_reg(env))) {
*flags |= ARM_TBFLAG_NS_MASK;
}