+/* Set the CPSR. Note that some bits of mask must be all-set or all-clear. */
+static inline void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
+{
+ /* NOTE: N = 1 and Z = 1 cannot be stored currently */
+ if (mask & CPSR_NZCV) {
+ env->NZF = (val & 0xc0000000) ^ 0x40000000;
+ env->CF = (val >> 29) & 1;
+ env->VF = (val << 3) & 0x80000000;
+ }
+ if (mask & CPSR_Q)
+ env->QF = ((val & CPSR_Q) != 0);
+ if (mask & CPSR_T)
+ env->thumb = ((val & CPSR_T) != 0);
+
+ if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
+ switch_mode(env, val & CPSR_M);
+ }
+ mask &= ~CACHED_CPSR_BITS;
+ env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
+}
+
+enum arm_cpu_mode {
+ ARM_CPU_MODE_USR = 0x10,
+ ARM_CPU_MODE_FIQ = 0x11,
+ ARM_CPU_MODE_IRQ = 0x12,
+ ARM_CPU_MODE_SVC = 0x13,
+ ARM_CPU_MODE_ABT = 0x17,
+ ARM_CPU_MODE_UND = 0x1b,
+ ARM_CPU_MODE_SYS = 0x1f
+};
+
+#if defined(CONFIG_USER_ONLY)