uint32_t teecr;
uint32_t teehbr;
- /* Internal CPU feature flags. */
- uint32_t features;
-
/* VFP coprocessor state. */
struct {
float64 regs[32];
uint32_t cregs[16];
} iwmmxt;
+ /* For mixed endian mode. */
+ bool bswap_code;
+
#if defined(CONFIG_USER_ONLY)
/* For usermode syscall translation. */
int eabi;
/* These fields after the common ones so they are preserved on reset. */
+ /* Internal CPU feature flags. */
+ uint32_t features;
+
/* Coprocessor IO used by peripherals */
struct {
ARMReadCPFunc *cp_read;
const struct arm_boot_info *boot_info;
} CPUARMState;
-CPUARMState *cpu_arm_init(const char *cpu_model);
+#include "cpu-qom.h"
+
+ARMCPU *cpu_arm_init(const char *cpu_model);
void arm_translate_init(void);
int cpu_arm_exec(CPUARMState *s);
-void cpu_arm_close(CPUARMState *s);
void do_interrupt(CPUARMState *);
void switch_mode(CPUARMState *, int);
uint32_t do_arm_semihosting(CPUARMState *env);
#define ARM_IWMMXT_wCGR2 10
#define ARM_IWMMXT_wCGR3 11
+/* If adding a feature bit which corresponds to a Linux ELF
+ * HWCAP bit, remember to update the feature-bit-to-hwcap
+ * mapping in linux-user/elfload.c:get_elf_hwcap().
+ */
enum arm_features {
ARM_FEATURE_VFP,
ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */
ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */
ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
ARM_FEATURE_GENERIC_TIMER,
+ ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
};
static inline int arm_feature(CPUARMState *env, int feature)
#define TARGET_PHYS_ADDR_SPACE_BITS 32
#define TARGET_VIRT_ADDR_SPACE_BITS 32
-#define cpu_init cpu_arm_init
+static inline CPUARMState *cpu_init(const char *cpu_model)
+{
+ ARMCPU *cpu = cpu_arm_init(cpu_model);
+ if (cpu) {
+ return &cpu->env;
+ }
+ return NULL;
+}
+
#define cpu_exec cpu_arm_exec
#define cpu_gen_code cpu_arm_gen_code
#define cpu_signal_handler cpu_arm_signal_handler
#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)
-/* Bits 31..16 are currently unused. */
+#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16
+#define ARM_TBFLAG_BSWAP_CODE_MASK (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
+/* Bits 31..17 are currently unused. */
/* some convenience accessor macros */
#define ARM_TBFLAG_THUMB(F) \
(((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)
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
*flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
| (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
| (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
- | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT);
+ | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
+ | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT);
if (arm_feature(env, ARM_FEATURE_M)) {
privmode = !((env->v7m.exception == 0) && (env->v7m.control & 1));
} else {
env->regs[15] = tb->pc;
}
+/* Load an instruction and return it in the standard little-endian order */
+static inline uint32_t arm_ldl_code(uint32_t addr, bool do_swap)
+{
+ uint32_t insn = ldl_code(addr);
+ if (do_swap) {
+ return bswap32(insn);
+ }
+ return insn;
+}
+
+/* Ditto, for a halfword (Thumb) instruction */
+static inline uint16_t arm_lduw_code(uint32_t addr, bool do_swap)
+{
+ uint16_t insn = lduw_code(addr);
+ if (do_swap) {
+ return bswap16(insn);
+ }
+ return insn;
+}
+
#endif