18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "cpu.h"
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "exec-all.h"
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "gdbstub.h"
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "helpers.h"
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h"
10ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#ifdef CONFIG_TRACE
11ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#include "trace.h"
12ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#endif
135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck/memcheck_api.h"
155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t cortexa8_cp15_c0_c1[8] =
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 };
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t cortexa8_cp15_c0_c2[8] =
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 };
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t mpcore_cp15_c0_c1[8] =
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 };
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t mpcore_cp15_c0_c2[8] =
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 };
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t arm1136_cp15_c0_c1[8] =
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 };
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t arm1136_cp15_c0_c2[8] =
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 };
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t cpu_arm_find_by_name(const char *name);
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void set_feature(CPUARMState *env, int feature)
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->features |= 1u << feature;
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void cpu_reset_model_id(CPUARMState *env, uint32_t id)
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cp15.c0_cpuid = id;
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (id) {
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_ARM926:
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_VFP);
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c0_cachetype = 0x1dd20d2;
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c1_sys = 0x00090078;
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_ARM946:
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_MPU);
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c0_cachetype = 0x0f004006;
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c1_sys = 0x00000078;
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_ARM1026:
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_VFP);
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_AUXCR);
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c0_cachetype = 0x1dd20d2;
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c1_sys = 0x00090078;
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_ARM1136_R2:
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_ARM1136:
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V6);
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_VFP);
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_AUXCR);
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t));
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t));
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c0_cachetype = 0x1dd20d2;
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_ARM11MPCORE:
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V6);
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V6K);
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_VFP);
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_AUXCR);
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t));
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t));
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c0_cachetype = 0x1dd20d2;
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_CORTEXA8:
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V6);
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V6K);
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V7);
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_AUXCR);
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_THUMB2);
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_VFP);
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_VFP3);
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_NEON);
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        set_feature(env, ARM_FEATURE_THUMB2EE);
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t));
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t));
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->cp15.c0_cachetype = 0x82048004;
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->cp15.c0_clid = (1 << 27) | (2 << 24) | 3;
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_CORTEXM3:
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V6);
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_THUMB2);
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V7);
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_M);
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_DIV);
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_ANY: /* For userspace emulation.  */
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V6);
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V6K);
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_V7);
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_THUMB2);
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_VFP);
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_VFP3);
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_NEON);
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        set_feature(env, ARM_FEATURE_THUMB2EE);
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_DIV);
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_TI915T:
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_TI925T:
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_OMAPCP);
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring.  */
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c0_cachetype = 0x5109149;
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c1_sys = 0x00000070;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c15_i_max = 0x000;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c15_i_min = 0xff0;
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA250:
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA255:
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA260:
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA261:
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA262:
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_XSCALE);
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* JTAG_ID is ((id << 28) | 0x09265013) */
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c0_cachetype = 0xd172172;
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c1_sys = 0x00000078;
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA270_A0:
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA270_A1:
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA270_B0:
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA270_B1:
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA270_C0:
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPUID_PXA270_C5:
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_XSCALE);
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* JTAG_ID is ((id << 28) | 0x09265013) */
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_feature(env, ARM_FEATURE_IWMMXT);
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c0_cachetype = 0xd172172;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c1_sys = 0x00000078;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_abort(env, "Bad CPU ID: %x\n", id);
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_reset(CPUARMState *env)
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t id;
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        log_cpu_state(env, 0);
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    id = env->cp15.c0_cpuid;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(env, 0, offsetof(CPUARMState, breakpoints));
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (id)
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_reset_model_id(env, id);
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined (CONFIG_USER_ONLY)
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->uncached_cpsr = ARM_CPU_MODE_USR;
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* SVC mode with interrupts disabled.  */
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       clear at reset.  */
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (IS_M(env))
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->uncached_cpsr &= ~CPSR_I;
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    env->cp15.c2_base_mask = 0xffffc000u;
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[15] = 0;
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tlb_flush(env, 1);
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vfp_gdb_get_reg(CPUState *env, uint8_t *buf, int reg)
1965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nregs;
1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* VFP data registers are always little-endian.  */
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (reg < nregs) {
2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        stfq_le_p(buf, env->vfp.regs[reg]);
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 8;
2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (arm_feature(env, ARM_FEATURE_NEON)) {
2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Aliases for Q regs.  */
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nregs += 16;
2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (reg < nregs) {
2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 16;
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (reg - nregs) {
2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4;
2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4;
2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4;
2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vfp_gdb_set_reg(CPUState *env, uint8_t *buf, int reg)
2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nregs;
2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (reg < nregs) {
2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->vfp.regs[reg] = ldfq_le_p(buf);
2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 8;
2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (arm_feature(env, ARM_FEATURE_NEON)) {
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nregs += 16;
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (reg < nregs) {
2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf);
2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8);
2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 16;
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (reg - nregs) {
2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4;
2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf); return 4;
2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectCPUARMState *cpu_arm_init(const char *cpu_model)
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CPUARMState *env;
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t id;
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static int inited = 0;
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    id = cpu_arm_find_by_name(cpu_model);
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (id == 0)
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env = qemu_mallocz(sizeof(CPUARMState));
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_exec_init(env);
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!inited) {
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        inited = 1;
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arm_translate_init();
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cpu_model_str = cpu_model;
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cp15.c0_cpuid = id;
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_reset(env);
2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (arm_feature(env, ARM_FEATURE_NEON)) {
2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 51, "arm-neon.xml", 0);
2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 35, "arm-vfp3.xml", 0);
2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (arm_feature(env, ARM_FEATURE_VFP)) {
2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 19, "arm-vfp.xml", 0);
2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_init_vcpu(env);
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return env;
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct arm_cpu_t {
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t id;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *name;
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const struct arm_cpu_t arm_cpu_names[] = {
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_ARM926, "arm926"},
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_ARM946, "arm946"},
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_ARM1026, "arm1026"},
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_ARM1136, "arm1136"},
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_ARM1136_R2, "arm1136-r2"},
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_ARM11MPCORE, "arm11mpcore"},
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_CORTEXM3, "cortex-m3"},
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_CORTEXA8, "cortex-a8"},
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_TI925T, "ti925t" },
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA250, "pxa250" },
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA255, "pxa255" },
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA260, "pxa260" },
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA261, "pxa261" },
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA262, "pxa262" },
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA270, "pxa270" },
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA270_A0, "pxa270-a0" },
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA270_A1, "pxa270-a1" },
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA270_B0, "pxa270-b0" },
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA270_B1, "pxa270-b1" },
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA270_C0, "pxa270-c0" },
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_PXA270_C5, "pxa270-c5" },
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { ARM_CPUID_ANY, "any"},
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { 0, NULL}
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    (*cpu_fprintf)(f, "Available CPUs:\n");
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (i = 0; arm_cpu_names[i].name; i++) {
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        (*cpu_fprintf)(f, "  %s\n", arm_cpu_names[i].name);
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return 0 if not found */
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t cpu_arm_find_by_name(const char *name)
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t id;
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    id = 0;
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (i = 0; arm_cpu_names[i].name; i++) {
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (strcmp(name, arm_cpu_names[i].name) == 0) {
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            id = arm_cpu_names[i].id;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return id;
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_arm_close(CPUARMState *env)
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    free(env);
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t cpsr_read(CPUARMState *env)
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ZF;
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ZF = (env->ZF == 0);
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        | ((env->condexec_bits & 0xfc) << 8)
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        | (env->GE << 16);
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (mask & CPSR_NZCV) {
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->ZF = (~val) & CPSR_Z;
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->NF = val;
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->CF = (val >> 29) & 1;
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->VF = (val << 3) & 0x80000000;
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (mask & CPSR_Q)
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->QF = ((val & CPSR_Q) != 0);
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (mask & CPSR_T)
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->thumb = ((val & CPSR_T) != 0);
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (mask & CPSR_IT_0_1) {
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->condexec_bits &= ~3;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->condexec_bits |= (val >> 25) & 3;
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (mask & CPSR_IT_2_7) {
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->condexec_bits &= 3;
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->condexec_bits |= (val >> 8) & 0xfc;
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (mask & CPSR_GE) {
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->GE = (val >> 16) & 0xf;
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch_mode(env, val & CPSR_M);
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask &= ~CACHED_CPSR_BITS;
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Sign/zero extend */
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(sxtb16)(uint32_t x)
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t res;
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = (uint16_t)(int8_t)x;
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res |= (uint32_t)(int8_t)(x >> 16) << 16;
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(uxtb16)(uint32_t x)
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t res;
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = (uint16_t)(uint8_t)x;
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res |= (uint32_t)(uint8_t)(x >> 16) << 16;
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(clz)(uint32_t x)
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int count;
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (count = 32; x; count--)
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        x >>= 1;
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return count;
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32_t HELPER(sdiv)(int32_t num, int32_t den)
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (den == 0)
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return 0;
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return num / den;
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(udiv)(uint32_t num, uint32_t den)
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (den == 0)
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return 0;
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return num / den;
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(rbit)(uint32_t x)
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x =  ((x & 0xff000000) >> 24)
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       | ((x & 0x00ff0000) >> 8)
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       | ((x & 0x0000ff00) << 8)
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       | ((x & 0x000000ff) << 24);
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x =  ((x & 0xf0f0f0f0) >> 4)
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       | ((x & 0x0f0f0f0f) << 4);
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    x =  ((x & 0x88888888) >> 3)
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       | ((x & 0x44444444) >> 1)
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       | ((x & 0x22222222) << 1)
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       | ((x & 0x11111111) << 3);
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return x;
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(abs)(uint32_t x)
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ((int32_t)x < 0) ? -x : x;
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(CONFIG_USER_ONLY)
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid do_interrupt (CPUState *env)
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->exception_index = -1;
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Structure used to record exclusive memory locations.  */
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct mmon_state {
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct mmon_state *next;
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CPUARMState *cpu_env;
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t addr;
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} mmon_state;
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Chain of current locks.  */
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic mmon_state* mmon_head = NULL;
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              int mmu_idx, int is_softmmu)
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (rw == 2) {
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->exception_index = EXCP_PREFETCH_ABORT;
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c6_insn = address;
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->exception_index = EXCP_DATA_ABORT;
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c6_data = address;
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void allocate_mmon_state(CPUState *env)
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->mmon_entry = malloc(sizeof (mmon_state));
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset (env->mmon_entry, 0, sizeof (mmon_state));
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->mmon_entry->cpu_env = env;
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mmon_head = env->mmon_entry;
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Flush any monitor locks for the specified address.  */
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void flush_mmon(uint32_t addr)
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mmon_state *mon;
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (mon = mmon_head; mon; mon = mon->next)
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (mon->addr != addr)
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          continue;
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mon->addr = 0;
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Mark an address for exclusive access.  */
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(mark_exclusive)(CPUState *env, uint32_t addr)
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!env->mmon_entry)
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        allocate_mmon_state(env);
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Clear any previous locks.  */
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flush_mmon(addr);
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->mmon_entry->addr = addr;
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Test if an exclusive address is still exclusive.  Returns zero
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if the address is still exclusive.   */
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr)
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int res;
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!env->mmon_entry)
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->mmon_entry->addr == addr)
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0;
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 1;
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flush_mmon(addr);
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(clrex)(CPUState *env)
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!(env->mmon_entry && env->mmon_entry->addr))
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flush_mmon(env->mmon_entry->addr);
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttarget_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return addr;
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* These should probably raise undefined insn exceptions.  */
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int op1 = (insn >> 8) & 0xf;
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return;
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int op1 = (insn >> 8) & 0xf;
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "cp15 insn %08x\n", insn);
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "cp15 insn %08x\n", insn);
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* These should probably raise undefined insn exceptions.  */
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "v7m_mrs %d\n", reg);
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "v7m_mrs %d\n", reg);
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid switch_mode(CPUState *env, int mode)
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (mode != ARM_CPU_MODE_USR)
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_abort(env, "Tried to switch out of user mode\n");
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "banked r13 write\n");
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "banked r13 read\n");
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern int semihosting_enabled;
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Map CPU modes onto saved register banks.  */
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int bank_number (int mode)
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (mode) {
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPU_MODE_USR:
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPU_MODE_SYS:
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPU_MODE_SVC:
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPU_MODE_ABT:
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 2;
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPU_MODE_UND:
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 3;
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPU_MODE_IRQ:
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 4;
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case ARM_CPU_MODE_FIQ:
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 5;
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(cpu_single_env, "Bad mode %x\n", mode);
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid switch_mode(CPUState *env, int mode)
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int old_mode;
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    old_mode = env->uncached_cpsr & CPSR_M;
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (mode == old_mode)
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (old_mode == ARM_CPU_MODE_FIQ) {
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (mode == ARM_CPU_MODE_FIQ) {
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i = bank_number(old_mode);
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->banked_r13[i] = env->regs[13];
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->banked_r14[i] = env->regs[14];
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->banked_spsr[i] = env->spsr;
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i = bank_number(mode);
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[13] = env->banked_r13[i];
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[14] = env->banked_r14[i];
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->spsr = env->banked_spsr[i];
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void v7m_push(CPUARMState *env, uint32_t val)
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[13] -= 4;
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stl_phys(env->regs[13], val);
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t v7m_pop(CPUARMState *env)
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t val;
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    val = ldl_phys(env->regs[13]);
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[13] += 4;
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return val;
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Switch to V7M main or process stack pointer.  */
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void switch_v7m_sp(CPUARMState *env, int process)
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t tmp;
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->v7m.current_sp != process) {
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tmp = env->v7m.other_sp;
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->v7m.other_sp = env->regs[13];
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->regs[13] = tmp;
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->v7m.current_sp = process;
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void do_v7m_exception_exit(CPUARMState *env)
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t type;
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t xpsr;
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type = env->regs[15];
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->v7m.exception != 0)
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        armv7m_nvic_complete_irq(env->v7m.nvic, env->v7m.exception);
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Switch to the target stack.  */
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch_v7m_sp(env, (type & 4) != 0);
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Pop registers.  */
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[0] = v7m_pop(env);
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[1] = v7m_pop(env);
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[2] = v7m_pop(env);
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[3] = v7m_pop(env);
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[12] = v7m_pop(env);
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[14] = v7m_pop(env);
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[15] = v7m_pop(env);
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    xpsr = v7m_pop(env);
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    xpsr_write(env, xpsr, 0xfffffdff);
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Undo stack alignment.  */
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (xpsr & 0x200)
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->regs[13] |= 4;
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* ??? The exception return type specifies Thread/Handler mode.  However
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       this is also implied by the xPSR value. Not sure what to do
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       if there is a mismatch.  */
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* ??? Likewise for mismatches between the CONTROL register and the stack
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       pointer.  */
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void do_interrupt_v7m(CPUARMState *env)
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t xpsr = xpsr_read(env);
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t lr;
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t addr;
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    lr = 0xfffffff1;
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->v7m.current_sp)
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        lr |= 4;
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->v7m.exception == 0)
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        lr |= 8;
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* For exceptions we just mark as pending on the NVIC, and let that
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       handle it.  */
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* TODO: Need to escalate if the current priority is higher than the
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       one we're raising.  */
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (env->exception_index) {
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_UDEF:
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_USAGE);
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_SWI:
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->regs[15] += 2;
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_SVC);
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_PREFETCH_ABORT:
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_DATA_ABORT:
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_MEM);
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_BKPT:
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (semihosting_enabled) {
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int nr;
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nr = lduw_code(env->regs[15]) & 0xff;
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (nr == 0xab) {
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->regs[15] += 2;
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->regs[0] = do_arm_semihosting(env);
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return;
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_DEBUG);
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_IRQ:
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->v7m.nvic);
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_EXCEPTION_EXIT:
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        do_v7m_exception_exit(env);
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return; /* Never happens.  Keep compiler happy.  */
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Align stack pointer.  */
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* ??? Should only do this if Configuration Control Register
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       STACKALIGN bit is set.  */
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->regs[13] & 4) {
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->regs[13] -= 4;
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xpsr |= 0x200;
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Switch to the handler mode.  */
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v7m_push(env, xpsr);
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v7m_push(env, env->regs[15]);
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v7m_push(env, env->regs[14]);
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v7m_push(env, env->regs[12]);
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v7m_push(env, env->regs[3]);
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v7m_push(env, env->regs[2]);
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v7m_push(env, env->regs[1]);
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v7m_push(env, env->regs[0]);
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch_v7m_sp(env, 0);
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->uncached_cpsr &= ~CPSR_IT;
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[14] = lr;
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[15] = addr & 0xfffffffe;
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->thumb = addr & 1;
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Handle a CPU exception.  */
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid do_interrupt(CPUARMState *env)
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t addr;
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t mask;
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int new_mode;
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t offset;
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
783ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#ifdef CONFIG_TRACE
784ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra    if (tracing) {
785ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra        trace_exception(env->regs[15]);
786ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra    }
787ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#endif
788ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (IS_M(env)) {
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        do_interrupt_v7m(env);
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* TODO: Vectored interrupt controller.  */
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (env->exception_index) {
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_UDEF:
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        new_mode = ARM_CPU_MODE_UND;
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr = 0x04;
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask = CPSR_I;
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (env->thumb)
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            offset = 2;
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            offset = 4;
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_SWI:
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (semihosting_enabled) {
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Check for semihosting interrupt.  */
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (env->thumb) {
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                mask = lduw_code(env->regs[15] - 2) & 0xff;
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                mask = ldl_code(env->regs[15] - 4) & 0xffffff;
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Only intercept calls from privileged modes, to provide some
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               semblance of security.  */
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (((mask == 0x123456 && !env->thumb)
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    || (mask == 0xab && env->thumb))
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->regs[0] = do_arm_semihosting(env);
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return;
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        new_mode = ARM_CPU_MODE_SVC;
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr = 0x08;
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask = CPSR_I;
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* The PC already points to the next instruction.  */
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        offset = 0;
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_BKPT:
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* See if this is a semihosting syscall.  */
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (env->thumb && semihosting_enabled) {
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            mask = lduw_code(env->regs[15]) & 0xff;
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (mask == 0xab
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->regs[15] += 2;
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->regs[0] = do_arm_semihosting(env);
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return;
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Fall through to prefetch abort.  */
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_PREFETCH_ABORT:
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        new_mode = ARM_CPU_MODE_ABT;
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr = 0x0c;
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask = CPSR_A | CPSR_I;
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        offset = 4;
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_DATA_ABORT:
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        new_mode = ARM_CPU_MODE_ABT;
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr = 0x10;
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask = CPSR_A | CPSR_I;
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        offset = 8;
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_IRQ:
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        new_mode = ARM_CPU_MODE_IRQ;
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr = 0x18;
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Disable IRQ and imprecise data aborts.  */
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask = CPSR_A | CPSR_I;
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        offset = 4;
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case EXCP_FIQ:
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        new_mode = ARM_CPU_MODE_FIQ;
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr = 0x1c;
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Disable FIQ, IRQ and imprecise data aborts.  */
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask = CPSR_A | CPSR_I | CPSR_F;
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        offset = 4;
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return; /* Never happens.  Keep compiler happy.  */
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* High vectors.  */
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->cp15.c1_sys & (1 << 13)) {
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr += 0xffff0000;
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch_mode (env, new_mode);
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->spsr = cpsr_read(env);
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Clear IT bits.  */
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->condexec_bits = 0;
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Switch to the new mode, and switch to Arm mode.  */
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* ??? Thumb interrupt handlers not implemented.  */
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->uncached_cpsr |= mask;
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->thumb = 0;
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[14] = env->regs[15] + offset;
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->regs[15] = addr;
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Check section/page access permissions.
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Returns the page protection flags, or zero if the access is not
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   permitted.  */
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int check_ap(CPUState *env, int ap, int domain, int access_type,
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           int is_user)
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  int prot_ro;
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (domain == 3)
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return PAGE_READ | PAGE_WRITE;
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (access_type == 1)
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      prot_ro = 0;
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  else
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      prot_ro = PAGE_READ;
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  switch (ap) {
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  case 0:
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (access_type == 1)
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          return 0;
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      switch ((env->cp15.c1_sys >> 8) & 3) {
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 1:
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          return is_user ? 0 : PAGE_READ;
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 2:
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          return PAGE_READ;
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      default:
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          return 0;
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  case 1:
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return is_user ? 0 : PAGE_READ | PAGE_WRITE;
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  case 2:
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (is_user)
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          return prot_ro;
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          return PAGE_READ | PAGE_WRITE;
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  case 3:
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return PAGE_READ | PAGE_WRITE;
9245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  case 4: /* Reserved.  */
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return 0;
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  case 5:
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return is_user ? 0 : prot_ro;
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  case 6:
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return prot_ro;
9305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  case 7:
9315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner      if (!arm_feature (env, ARM_FEATURE_V7))
9325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner          return 0;
9335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner      return prot_ro;
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  default:
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      abort();
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t get_level1_table_address(CPUState *env, uint32_t address)
9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t table;
9425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (address & env->cp15.c2_mask)
9445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        table = env->cp15.c2_base1 & 0xffffc000;
9455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
9465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        table = env->cp15.c2_base0 & env->cp15.c2_base_mask;
9475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    table |= (address >> 18) & 0x3ffc;
9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return table;
9505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			    int is_user, uint32_t *phys_ptr, int *prot)
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int code;
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t table;
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t desc;
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int type;
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ap;
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int domain;
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t phys_addr;
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Pagetable walk.  */
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Lookup l1 descriptor.  */
9655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    table = get_level1_table_address(env, address);
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc = ldl_phys(table);
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type = (desc & 3);
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type == 0) {
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Section translation fault.  */
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        code = 5;
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto do_fault;
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (domain == 0 || domain == 2) {
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (type == 2)
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            code = 9; /* Section domain fault.  */
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            code = 11; /* Page domain fault.  */
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto do_fault;
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type == 2) {
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* 1Mb section.  */
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ap = (desc >> 10) & 3;
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        code = 13;
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Lookup l2 entry.  */
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (type == 1) {
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    /* Coarse pagetable.  */
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	} else {
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    /* Fine pagetable.  */
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        desc = ldl_phys(table);
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (desc & 3) {
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0: /* Page translation fault.  */
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            code = 7;
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto do_fault;
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1: /* 64k page.  */
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            phys_addr = (desc & 0xffff0000) | (address & 0xffff);
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2: /* 4k page.  */
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 3: /* 1k page.  */
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    if (type == 1) {
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (arm_feature(env, ARM_FEATURE_XSCALE)) {
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    phys_addr = (desc & 0xfffff000) | (address & 0xfff);
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		} else {
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    /* Page translation fault.  */
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    code = 7;
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    goto do_fault;
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    } else {
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    }
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ap = (desc >> 4) & 3;
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Never happens, but compiler isn't smart enough to tell.  */
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            abort();
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        code = 15;
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *prot = check_ap(env, ap, domain, access_type, is_user);
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!*prot) {
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Access permission fault.  */
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto do_fault;
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *phys_ptr = phys_addr;
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_fault:
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return code | (domain << 4);
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			    int is_user, uint32_t *phys_ptr, int *prot)
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int code;
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t table;
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t desc;
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t xn;
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int type;
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ap;
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int domain;
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t phys_addr;
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Pagetable walk.  */
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Lookup l1 descriptor.  */
10535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    table = get_level1_table_address(env, address);
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    desc = ldl_phys(table);
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    type = (desc & 3);
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type == 0) {
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Section translation fault.  */
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        code = 5;
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        domain = 0;
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto do_fault;
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (type == 2 && (desc & (1 << 18))) {
10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Supersection.  */
10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        domain = 0;
10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Section or page.  */
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        domain = (desc >> 4) & 0x1e;
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    domain = (env->cp15.c3 >> domain) & 3;
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (domain == 0 || domain == 2) {
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (type == 2)
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            code = 9; /* Section domain fault.  */
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            code = 11; /* Page domain fault.  */
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto do_fault;
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type == 2) {
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (desc & (1 << 18)) {
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Supersection.  */
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Section.  */
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xn = desc & (1 << 4);
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        code = 13;
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Lookup l2 entry.  */
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        desc = ldl_phys(table);
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (desc & 3) {
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0: /* Page translation fault.  */
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            code = 7;
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto do_fault;
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1: /* 64k page.  */
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            phys_addr = (desc & 0xffff0000) | (address & 0xffff);
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            xn = desc & (1 << 15);
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2: case 3: /* 4k page.  */
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            xn = desc & 1;
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Never happens, but compiler isn't smart enough to tell.  */
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            abort();
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        code = 15;
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (xn && access_type == 2)
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto do_fault;
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* The simplified model uses AP[0] as an access control bit.  */
11145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ((env->cp15.c1_sys & (1 << 29)) && (ap & 1) == 0) {
11155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Access flag fault.  */
11165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        code = (code == 15) ? 6 : 3;
11175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto do_fault;
11185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *prot = check_ap(env, ap, domain, access_type, is_user);
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!*prot) {
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Access permission fault.  */
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto do_fault;
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *phys_ptr = phys_addr;
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_fault:
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return code | (domain << 4);
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			     int is_user, uint32_t *phys_ptr, int *prot)
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int n;
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t mask;
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t base;
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *phys_ptr = address;
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (n = 7; n >= 0; n--) {
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	base = env->cp15.c6_region[n];
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if ((base & 1) == 0)
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    continue;
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	mask = 1 << ((base >> 1) & 0x1f);
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* Keep this shift separate from the above to avoid an
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	   (undefined) << 32.  */
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	mask = (mask << 1) - 1;
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (((base ^ address) & ~mask) == 0)
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    break;
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (n < 0)
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return 2;
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (access_type == 2) {
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	mask = env->cp15.c5_insn;
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	mask = env->cp15.c5_data;
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = (mask >> (n * 4)) & 0xf;
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (mask) {
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0:
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return 1;
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 1:
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (is_user)
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	  return 1;
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	*prot = PAGE_READ | PAGE_WRITE;
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	break;
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 2:
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	*prot = PAGE_READ;
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (!is_user)
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    *prot |= PAGE_WRITE;
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	break;
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 3:
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	*prot = PAGE_READ | PAGE_WRITE;
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	break;
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 5:
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (is_user)
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    return 1;
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	*prot = PAGE_READ;
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	break;
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 6:
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	*prot = PAGE_READ;
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	break;
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* Bad permission.  */
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return 1;
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int get_phys_addr(CPUState *env, uint32_t address,
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                int access_type, int is_user,
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                uint32_t *phys_ptr, int *prot)
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Fast Context Switch Extension.  */
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (address < 0x02000000)
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        address += env->cp15.c13_fcse;
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((env->cp15.c1_sys & 1) == 0) {
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* MMU/MPU disabled.  */
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *phys_ptr = address;
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *prot = PAGE_READ | PAGE_WRITE;
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (arm_feature(env, ARM_FEATURE_MPU)) {
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				 prot);
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (env->cp15.c1_sys & (1 << 23)) {
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                prot);
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                prot);
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              int access_type, int mmu_idx, int is_softmmu)
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t phys_addr;
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int prot;
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret, is_user;
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    is_user = mmu_idx == MMU_USER_IDX;
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0) {
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Map a single [sub]page.  */
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        phys_addr &= ~(uint32_t)0x3ff;
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        address &= ~(uint32_t)0x3ff;
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return tlb_set_page (env, address, phys_addr, prot, mmu_idx,
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_softmmu);
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (access_type == 2) {
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c5_insn = ret;
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c6_insn = address;
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->exception_index = EXCP_PREFETCH_ABORT;
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c5_data = ret;
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c5_data |= (1 << 11);
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c6_data = address;
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->exception_index = EXCP_DATA_ABORT;
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttarget_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t phys_addr;
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int prot;
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot);
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret != 0)
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return phys_addr;
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Not really implemented.  Need to figure out a sane way of doing this.
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Maybe add generic watchpoint support and use that.  */
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(mark_exclusive)(CPUState *env, uint32_t addr)
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->mmon_addr = addr;
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr)
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (env->mmon_addr != addr);
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(clrex)(CPUState *env)
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->mmon_addr = -1;
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int cp_num = (insn >> 8) & 0xf;
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int cp_info = (insn >> 5) & 7;
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int src = (insn >> 16) & 0xf;
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int operand = insn & 0xf;
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->cp[cp_num].cp_write)
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp[cp_num].cp_write(env->cp[cp_num].opaque,
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                 cp_info, src, operand, val);
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int cp_num = (insn >> 8) & 0xf;
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int cp_info = (insn >> 5) & 7;
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int dest = (insn >> 16) & 0xf;
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int operand = insn & 0xf;
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->cp[cp_num].cp_read)
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return env->cp[cp_num].cp_read(env->cp[cp_num].opaque,
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                       cp_info, dest, operand);
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Return basic MPU access permission bits.  */
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t simple_mpu_ap_bits(uint32_t val)
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t ret;
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t mask;
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = 0;
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = 3;
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (i = 0; i < 16; i += 2) {
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret |= (val >> i) & mask;
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask <<= 2;
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Pad basic MPU access permission bits to extended format.  */
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t extended_mpu_ap_bits(uint32_t val)
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t ret;
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t mask;
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = 0;
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = 3;
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (i = 0; i < 16; i += 2) {
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret |= (val & mask) << i;
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask <<= 2;
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int op1;
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int op2;
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int crm;
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    op1 = (insn >> 21) & 7;
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    op2 = (insn >> 5) & 7;
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    crm = insn & 0xf;
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch ((insn >> 16) & 0xf) {
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0:
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* ID codes.  */
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_XSCALE))
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_OMAPCP))
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (arm_feature(env, ARM_FEATURE_V7)
13495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                && op1 == 2 && crm == 0 && op2 == 0) {
13505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->cp15.c0_cssel = val & 0xf;
13515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
13525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto bad_reg;
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 1: /* System configuration.  */
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_OMAPCP))
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            op2 = 0;
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (op2) {
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0:
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c1_sys = val;
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* ??? Lots of these bits are not implemented.  */
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* This may enable/disable the MMU, so do a TLB flush.  */
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tlb_flush(env, 1);
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1: /* Auxiliary cotrol register.  */
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_XSCALE)) {
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c1_xscaleauxcr = val;
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Not implemented.  */
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2:
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_XSCALE))
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
13755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (env->cp15.c1_coproc != val) {
13765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                env->cp15.c1_coproc = val;
13775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* ??? Is this safe when called from within a TB?  */
13785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tb_flush(env);
13795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 2: /* MMU Page table control / MPU cache control.  */
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_MPU)) {
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (op2) {
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 0:
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c2_data = val;
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 1:
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c2_insn = val;
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    switch (op2) {
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 0:
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		env->cp15.c2_base0 = val;
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		break;
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 1:
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		env->cp15.c2_base1 = val;
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		break;
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 2:
14065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                val &= 7;
14075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                env->cp15.c2_control = val;
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
14095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val);
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		break;
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    default:
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		goto bad_reg;
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    }
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 3: /* MMU Domain access control / MPU write buffer control.  */
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c3 = val;
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 4: /* Reserved.  */
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto bad_reg;
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 5: /* MMU Fault status / MPU access permission.  */
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_OMAPCP))
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            op2 = 0;
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (op2) {
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0:
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_MPU))
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                val = extended_mpu_ap_bits(val);
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c5_data = val;
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1:
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_MPU))
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                val = extended_mpu_ap_bits(val);
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c5_insn = val;
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2:
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!arm_feature(env, ARM_FEATURE_MPU))
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c5_data = val;
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 3:
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!arm_feature(env, ARM_FEATURE_MPU))
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c5_insn = val;
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 6: /* MMU Fault address / MPU base/size.  */
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_MPU)) {
14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (crm >= 8)
14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c6_region[crm] = val;
14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_OMAPCP))
14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                op2 = 0;
14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (op2) {
14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 0:
14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c6_data = val;
14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 1: /* ??? This is WFAR on armv6 */
14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 2:
14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c6_insn = val;
14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 7: /* Cache control.  */
14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c15_i_max = 0x000;
14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->cp15.c15_i_min = 0xff0;
14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* No cache, so nothing to do.  */
14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* ??? MPCore has VA to PA translation functions.  */
14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 8: /* MMU TLB control.  */
14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (op2) {
14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0: /* Invalidate all.  */
14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tlb_flush(env, 0);
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1: /* Invalidate single TLB entry.  */
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* ??? This is wrong for large pages and sections.  */
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* As an ugly hack to make linux work we always flush a 4K
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               pages.  */
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            val &= 0xfffff000;
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tlb_flush_page(env, val);
14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tlb_flush_page(env, val + 0x400);
14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tlb_flush_page(env, val + 0x800);
14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tlb_flush_page(env, val + 0xc00);
14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tlb_flush(env, 1);
14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2: /* Invalidate on ASID.  */
14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tlb_flush(env, val == 0);
14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 3: /* Invalidate single entry on MVA.  */
15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* ??? This is like case 1, but ignores ASID.  */
15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tlb_flush(env, 1);
15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 9:
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_OMAPCP))
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (crm) {
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0: /* Cache lockdown.  */
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    switch (op1) {
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 0: /* L1 cache.  */
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		switch (op2) {
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		case 0:
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    env->cp15.c9_data = val;
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    break;
15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		case 1:
15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    env->cp15.c9_insn = val;
15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    break;
15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		default:
15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    goto bad_reg;
15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		break;
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 1: /* L2 cache.  */
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		/* Ignore writes to L2 lockdown/auxiliary registers.  */
15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		break;
15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    default:
15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		goto bad_reg;
15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    }
15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    break;
15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1: /* TCM memory region registers.  */
15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Not implemented.  */
15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 10: /* MMU TLB lockdown.  */
15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* ??? TLB lockdown not implemented.  */
15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 12: /* Reserved.  */
15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto bad_reg;
15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 13: /* Process ID.  */
15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (op2) {
15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0:
15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Unlike real hardware the qemu TLB uses virtual addresses,
15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               not modified virtual addresses, so this causes a TLB flush.
15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             */
15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (env->cp15.c13_fcse != val)
15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              tlb_flush(env, 1);
15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c13_fcse = val;
15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1:
15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* This changes the ASID, so do a TLB flush.  */
15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (env->cp15.c13_context != val
15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                && !arm_feature(env, ARM_FEATURE_MPU))
15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              tlb_flush(env, 0);
15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c13_context = val;
15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2:
15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c13_tls1 = val;
15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 3:
15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c13_tls2 = val;
15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 4:
15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->cp15.c13_tls3 = val;
15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 14: /* Reserved.  */
15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto bad_reg;
15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 15: /* Implementation specific.  */
15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (op2 == 0 && crm == 1) {
15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (env->cp15.c15_cpar != (val & 0x3fff)) {
15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* Changes cp0 to cp13 behavior, so needs a TB flush.  */
15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tb_flush(env);
15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    env->cp15.c15_cpar = val & 0x3fff;
15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (crm) {
15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 0:
15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 1: /* Set TI925T configuration.  */
15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c15_ticonfig = val & 0xe7;
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */
15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        ARM_CPUID_TI915T : ARM_CPUID_TI925T;
15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 2: /* Set I_max.  */
15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c15_i_max = val;
15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 3: /* Set I_min.  */
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c15_i_min = val;
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 4: /* Set thread-ID.  */
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->cp15.c15_threadid = val & 0xffff;
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 8: /* Wait-for-interrupt (deprecated).  */
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                cpu_interrupt(env, CPU_INTERRUPT_HALT);
16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return;
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbad_reg:
16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* ??? For debugging only.  Should raise illegal instruction exception.  */
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              (insn >> 16) & 0xf, crm, op1, op2);
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int op1;
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int op2;
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int crm;
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    op1 = (insn >> 21) & 7;
16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    op2 = (insn >> 5) & 7;
16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    crm = insn & 0xf;
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch ((insn >> 16) & 0xf) {
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0: /* ID codes.  */
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (op1) {
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0:
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (crm) {
16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 0:
16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                switch (op2) {
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case 0: /* Device ID.  */
16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return env->cp15.c0_cpuid;
16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case 1: /* Cache Type.  */
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    return env->cp15.c0_cachetype;
16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case 2: /* TCM status.  */
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return 0;
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case 3: /* TLB type register.  */
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return 0; /* No lockable TLB entries.  */
16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                case 5: /* CPU ID */
16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return env->cpu_index;
16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                default:
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto bad_reg;
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 1:
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (!arm_feature(env, ARM_FEATURE_V6))
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto bad_reg;
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c0_c1[op2];
16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 2:
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (!arm_feature(env, ARM_FEATURE_V6))
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto bad_reg;
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c0_c2[op2];
16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 3: case 4: case 5: case 6: case 7:
16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return 0;
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1:
16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* These registers aren't documented on arm11 cores.  However
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               Linux looks at them anyway.  */
16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!arm_feature(env, ARM_FEATURE_V6))
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (crm != 0)
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
16715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!arm_feature(env, ARM_FEATURE_V7))
16725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return 0;
16735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            switch (op2) {
16755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case 0:
16765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return env->cp15.c0_ccsid[env->cp15.c0_cssel];
16775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case 1:
16785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return env->cp15.c0_clid;
16795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case 7:
16805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return 0;
16815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
16825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto bad_reg;
16835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 2:
16845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (op2 != 0 || crm != 0)
16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
16865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return env->cp15.c0_cssel;
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 1: /* System configuration.  */
16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_OMAPCP))
16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            op2 = 0;
16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (op2) {
16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0: /* Control register.  */
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c1_sys;
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1: /* Auxiliary control register.  */
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_XSCALE))
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c1_xscaleauxcr;
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!arm_feature(env, ARM_FEATURE_AUXCR))
17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (ARM_CPUID(env)) {
17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case ARM_CPUID_ARM1026:
17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return 1;
17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case ARM_CPUID_ARM1136:
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case ARM_CPUID_ARM1136_R2:
17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return 7;
17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case ARM_CPUID_ARM11MPCORE:
17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return 1;
17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case ARM_CPUID_CORTEXA8:
17105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return 2;
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2: /* Coprocessor access register.  */
17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_XSCALE))
17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c1_coproc;
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 2: /* MMU Page table control / MPU cache control.  */
17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_MPU)) {
17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (op2) {
17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 0:
17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c2_data;
17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 1:
17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c2_insn;
17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    switch (op2) {
17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 0:
17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		return env->cp15.c2_base0;
17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 1:
17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		return env->cp15.c2_base1;
17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 2:
17405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return env->cp15.c2_control;
17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    default:
17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		goto bad_reg;
17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    }
17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 3: /* MMU Domain access control / MPU write buffer control.  */
17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return env->cp15.c3;
17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 4: /* Reserved.  */
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto bad_reg;
17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 5: /* MMU Fault status / MPU access permission.  */
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_OMAPCP))
17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            op2 = 0;
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (op2) {
17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0:
17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_MPU))
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return simple_mpu_ap_bits(env->cp15.c5_data);
17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c5_data;
17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1:
17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_MPU))
17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return simple_mpu_ap_bits(env->cp15.c5_data);
17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c5_insn;
17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2:
17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!arm_feature(env, ARM_FEATURE_MPU))
17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c5_data;
17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 3:
17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!arm_feature(env, ARM_FEATURE_MPU))
17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c5_insn;
17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 6: /* MMU Fault address.  */
17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_MPU)) {
17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (crm >= 8)
17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c6_region[crm];
17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arm_feature(env, ARM_FEATURE_OMAPCP))
17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                op2 = 0;
17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    switch (op2) {
17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 0:
17828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		return env->cp15.c6_data;
17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 1:
17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (arm_feature(env, ARM_FEATURE_V6)) {
17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    /* Watchpoint Fault Adrress.  */
17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    return 0; /* Not implemented.  */
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		} else {
17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    /* Instruction Fault Adrress.  */
17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    /* Arm9 doesn't have an IFAR, but implementing it anyway
17908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		       shouldn't do any harm.  */
17918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    return env->cp15.c6_insn;
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    case 2:
17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (arm_feature(env, ARM_FEATURE_V6)) {
17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    /* Instruction Fault Adrress.  */
17968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    return env->cp15.c6_insn;
17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		} else {
17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    goto bad_reg;
17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    default:
18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		goto bad_reg;
18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    }
18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 7: /* Cache control.  */
18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* FIXME: Should only clear Z flag if destination is r15.  */
18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->ZF = 0;
18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 8: /* MMU TLB control.  */
18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto bad_reg;
18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 9: /* Cache lockdown.  */
18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (op1) {
18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0: /* L1 cache.  */
18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    if (arm_feature(env, ARM_FEATURE_OMAPCP))
18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		return 0;
18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (op2) {
18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 0:
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c9_data;
18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 1:
18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c9_insn;
18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1: /* L2 cache */
18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (crm != 0)
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto bad_reg;
18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* L2 Lockdown and Auxiliary control.  */
18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 10: /* MMU TLB lockdown.  */
18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* ??? TLB lockdown not implemented.  */
18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 11: /* TCM DMA control.  */
18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 12: /* Reserved.  */
18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto bad_reg;
18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 13: /* Process ID.  */
18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (op2) {
18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0:
18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c13_fcse;
18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1:
18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c13_context;
18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2:
18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c13_tls1;
18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 3:
18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c13_tls2;
18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 4:
18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return env->cp15.c13_tls3;
18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 14: /* Reserved.  */
18538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto bad_reg;
18548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 15: /* Implementation specific.  */
18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (op2 == 0 && crm == 1)
18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c15_cpar;
18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (crm) {
18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 0:
18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return 0;
18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 1: /* Read TI925T configuration.  */
18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c15_ticonfig;
18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 2: /* Read I_max.  */
18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c15_i_max;
18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 3: /* Read I_min.  */
18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c15_i_min;
18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 4: /* Read thread-ID.  */
18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return env->cp15.c15_threadid;
18738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 8: /* TI925T_status */
18748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return 0;
18758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
18768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* TODO: Peripheral port remap register:
18778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt
18788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             * controller base address at $rn & ~0xfff and map size of
18798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             * 0x200 << ($rn & 0xfff), when MMU is off.  */
18808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto bad_reg;
18818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
18838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbad_reg:
18858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* ??? For debugging only.  Should raise illegal instruction exception.  */
18868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
18878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              (insn >> 16) & 0xf, crm, op1, op2);
18888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
18898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
18928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->banked_r13[bank_number(mode)] = val;
18948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
18978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return env->banked_r13[bank_number(mode)];
18998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
19028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (reg) {
19048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0: /* APSR */
19058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return xpsr_read(env) & 0xf8000000;
19068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 1: /* IAPSR */
19078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return xpsr_read(env) & 0xf80001ff;
19088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 2: /* EAPSR */
19098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return xpsr_read(env) & 0xff00fc00;
19108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 3: /* xPSR */
19118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return xpsr_read(env) & 0xff00fdff;
19128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 5: /* IPSR */
19138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return xpsr_read(env) & 0x000001ff;
19148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 6: /* EPSR */
19158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return xpsr_read(env) & 0x0700fc00;
19168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 7: /* IEPSR */
19178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return xpsr_read(env) & 0x0700edff;
19188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 8: /* MSP */
19198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13];
19208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 9: /* PSP */
19218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp;
19228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 16: /* PRIMASK */
19238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return (env->uncached_cpsr & CPSR_I) != 0;
19248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 17: /* FAULTMASK */
19258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return (env->uncached_cpsr & CPSR_F) != 0;
19268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 18: /* BASEPRI */
19278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 19: /* BASEPRI_MAX */
19288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return env->v7m.basepri;
19298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 20: /* CONTROL */
19308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return env->v7m.control;
19318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
19328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* ??? For debugging only.  */
19338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_abort(env, "Unimplemented system register read (%d)\n", reg);
19348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
19358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (reg) {
19418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0: /* APSR */
19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xpsr_write(env, val, 0xf8000000);
19438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 1: /* IAPSR */
19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xpsr_write(env, val, 0xf8000000);
19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 2: /* EAPSR */
19488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xpsr_write(env, val, 0xfe00fc00);
19498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 3: /* xPSR */
19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xpsr_write(env, val, 0xfe00fc00);
19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 5: /* IPSR */
19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* IPSR bits are readonly.  */
19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 6: /* EPSR */
19578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xpsr_write(env, val, 0x0600fc00);
19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 7: /* IEPSR */
19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xpsr_write(env, val, 0x0600fc00);
19618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 8: /* MSP */
19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (env->v7m.current_sp)
19648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->v7m.other_sp = val;
19658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->regs[13] = val;
19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 9: /* PSP */
19698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (env->v7m.current_sp)
19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->regs[13] = val;
19718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
19728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->v7m.other_sp = val;
19738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 16: /* PRIMASK */
19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (val & 1)
19768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->uncached_cpsr |= CPSR_I;
19778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
19788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->uncached_cpsr &= ~CPSR_I;
19798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 17: /* FAULTMASK */
19818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (val & 1)
19828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->uncached_cpsr |= CPSR_F;
19838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
19848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->uncached_cpsr &= ~CPSR_F;
19858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 18: /* BASEPRI */
19878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->v7m.basepri = val & 0xff;
19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 19: /* BASEPRI_MAX */
19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val &= 0xff;
19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->v7m.basepri = val;
19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 20: /* CONTROL */
19958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->v7m.control = val & 3;
19968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch_v7m_sp(env, (val & 2) != 0);
19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* ??? For debugging only.  */
20008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_abort(env, "Unimplemented system register write (%d)\n", reg);
20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
20068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                void *opaque)
20088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpnum < 0 || cpnum > 14) {
20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_abort(env, "Bad coprocessor number: %i\n", cpnum);
20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cp[cpnum].cp_read = cp_read;
20158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cp[cpnum].cp_write = cp_write;
20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cp[cpnum].opaque = opaque;
20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note that signed overflow is undefined in C.  The following routines are
20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   careful to use unsigned types where modulo arithmetic is required.
20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Failure to do so _will_ break on newer gcc.  */
20248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Signed saturating arithmetic.  */
20268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Perform 16-bit signed saturating addition.  */
20288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint16_t add16_sat(uint16_t a, uint16_t b)
20298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t res;
20318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = a + b;
20338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
20348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (a & 0x8000)
20358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            res = 0x8000;
20368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
20378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            res = 0x7fff;
20388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
20408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Perform 8-bit signed saturating addition.  */
20438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t add8_sat(uint8_t a, uint8_t b)
20448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t res;
20468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = a + b;
20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (a & 0x80)
20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            res = 0x80;
20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            res = 0x7f;
20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Perform 16-bit signed saturating subtraction.  */
20588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint16_t sub16_sat(uint16_t a, uint16_t b)
20598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t res;
20618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = a - b;
20638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (a & 0x8000)
20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            res = 0x8000;
20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            res = 0x7fff;
20688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Perform 8-bit signed saturating subtraction.  */
20738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t sub8_sat(uint8_t a, uint8_t b)
20748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t res;
20768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = a - b;
20788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
20798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (a & 0x80)
20808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            res = 0x80;
20818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
20828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            res = 0x7f;
20838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
20858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
20888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
20898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n)  RESULT(add8_sat(a, b), n, 8);
20908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n)  RESULT(sub8_sat(a, b), n, 8);
20918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX q
20928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h"
20948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Unsigned saturating arithmetic.  */
20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint16_t add16_usat(uint16_t a, uint16_t b)
20978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t res;
20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = a + b;
21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (res < a)
21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0xffff;
21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint16_t sub16_usat(uint16_t a, uint16_t b)
21068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a < b)
21088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a - b;
21098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t add8_usat(uint8_t a, uint8_t b)
21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t res;
21168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = a + b;
21178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (res < a)
21188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0xff;
21198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t sub8_usat(uint8_t a, uint8_t b)
21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a < b)
21258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a - b;
21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
21278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
21288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
21318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
21328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n)  RESULT(add8_usat(a, b), n, 8);
21338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n)  RESULT(sub8_usat(a, b), n, 8);
21348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX uq
21358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h"
21378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Signed modulo arithmetic.  */
21398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SARITH16(a, b, n, op) do { \
21408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t sum; \
21418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \
21428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RESULT(sum, n, 16); \
21438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sum >= 0) \
21448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ge |= 3 << (n * 2); \
21458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
21468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SARITH8(a, b, n, op) do { \
21488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32_t sum; \
21498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \
21508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RESULT(sum, n, 8); \
21518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sum >= 0) \
21528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ge |= 1 << n; \
21538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
21548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) SARITH16(a, b, n, +)
21578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) SARITH16(a, b, n, -)
21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n)  SARITH8(a, b, n, +)
21598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n)  SARITH8(a, b, n, -)
21608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX s
21618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ARITH_GE
21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h"
21648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Unsigned modulo arithmetic.  */
21668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) do { \
21678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t sum; \
21688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
21698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RESULT(sum, n, 16); \
21708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((sum >> 16) == 1) \
21718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ge |= 3 << (n * 2); \
21728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
21738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n) do { \
21758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t sum; \
21768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
21778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RESULT(sum, n, 8); \
21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((sum >> 8) == 1) \
21798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ge |= 1 << n; \
21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
21818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) do { \
21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t sum; \
21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
21858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RESULT(sum, n, 16); \
21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((sum >> 16) == 0) \
21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ge |= 3 << (n * 2); \
21888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
21898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n) do { \
21918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t sum; \
21928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
21938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RESULT(sum, n, 8); \
21948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((sum >> 8) == 0) \
21958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ge |= 1 << n; \
21968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while(0)
21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX u
21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ARITH_GE
22008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h"
22028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Halved signed arithmetic.  */
22048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) \
22058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
22068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) \
22078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
22088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n) \
22098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
22108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n) \
22118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
22128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX sh
22138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h"
22158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Halved unsigned arithmetic.  */
22178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) \
22188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
22198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) \
22208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
22218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n) \
22228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
22238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n) \
22248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
22258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX uh
22268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h"
22288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t do_usad(uint8_t a, uint8_t b)
22308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a > b)
22328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a - b;
22338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
22348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return b - a;
22358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Unsigned sum of absolute byte differences.  */
22388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(usad8)(uint32_t a, uint32_t b)
22398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t sum;
22418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum = do_usad(a, b);
22428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum += do_usad(a >> 8, b >> 8);
22438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum += do_usad(a >> 16, b >>16);
22448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sum += do_usad(a >> 24, b >> 24);
22458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return sum;
22468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* For ARMv6 SEL instruction.  */
22498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
22508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t mask;
22528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mask = 0;
22548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (flags & 1)
22558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask |= 0xff;
22568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (flags & 2)
22578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask |= 0xff00;
22588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (flags & 4)
22598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask |= 0xff0000;
22608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (flags & 8)
22618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mask |= 0xff000000;
22628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (a & mask) | (b & ~mask);
22638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(logicq_cc)(uint64_t val)
22668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (val >> 32) | (val != 0);
22688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* VFP support.  We follow the convention used for VFP instrunctions:
22718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Single precition routines have a "s" suffix, double precision a
22728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   "d" suffix.  */
22738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Convert host exception flags to vfp form.  */
22758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int vfp_exceptbits_from_host(int host_bits)
22768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int target_bits = 0;
22788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (host_bits & float_flag_invalid)
22808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        target_bits |= 1;
22818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (host_bits & float_flag_divbyzero)
22828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        target_bits |= 2;
22838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (host_bits & float_flag_overflow)
22848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        target_bits |= 4;
22858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (host_bits & float_flag_underflow)
22868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        target_bits |= 8;
22878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (host_bits & float_flag_inexact)
22888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        target_bits |= 0x10;
22898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return target_bits;
22908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(vfp_get_fpscr)(CPUState *env)
22938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
22958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t fpscr;
22968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
22988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | (env->vfp.vec_len << 16)
22998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | (env->vfp.vec_stride << 20);
23008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i = get_float_exception_flags(&env->vfp.fp_status);
23018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fpscr |= vfp_exceptbits_from_host(i);
23028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return fpscr;
23038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Convert vfp exception flags to target form.  */
23068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int vfp_exceptbits_to_host(int target_bits)
23078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int host_bits = 0;
23098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (target_bits & 1)
23118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        host_bits |= float_flag_invalid;
23128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (target_bits & 2)
23138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        host_bits |= float_flag_divbyzero;
23148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (target_bits & 4)
23158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        host_bits |= float_flag_overflow;
23168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (target_bits & 8)
23178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        host_bits |= float_flag_underflow;
23188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (target_bits & 0x10)
23198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        host_bits |= float_flag_inexact;
23208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return host_bits;
23218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
23248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
23268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t changed;
23278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    changed = env->vfp.xregs[ARM_VFP_FPSCR];
23298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
23308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->vfp.vec_len = (val >> 16) & 7;
23318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->vfp.vec_stride = (val >> 20) & 3;
23328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    changed ^= val;
23348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (changed & (3 << 22)) {
23358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        i = (val >> 22) & 3;
23368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (i) {
23378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0:
23388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            i = float_round_nearest_even;
23398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
23408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 1:
23418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            i = float_round_up;
23428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
23438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 2:
23448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            i = float_round_down;
23458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
23468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 3:
23478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            i = float_round_to_zero;
23488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
23498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
23508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        set_float_rounding_mode(i, &env->vfp.fp_status);
23518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
23525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (changed & (1 << 24))
23535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
23545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (changed & (1 << 25))
23555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status);
23568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
23588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    set_float_exception_flags(i, &env->vfp.fp_status);
23598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
23628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define VFP_BINOP(name) \
23648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \
23658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
23668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_ ## name (a, b, &env->vfp.fp_status); \
23678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} \
23688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \
23698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
23708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float64_ ## name (a, b, &env->vfp.fp_status); \
23718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_BINOP(add)
23738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_BINOP(sub)
23748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_BINOP(mul)
23758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_BINOP(div)
23768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef VFP_BINOP
23778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(neg, s)(float32 a)
23798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_chs(a);
23818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(neg, d)(float64 a)
23848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float64_chs(a);
23868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(abs, s)(float32 a)
23898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_abs(a);
23918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(abs, d)(float64 a)
23948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float64_abs(a);
23968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(sqrt, s)(float32 a, CPUState *env)
23998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_sqrt(a, &env->vfp.fp_status);
24018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(sqrt, d)(float64 a, CPUState *env)
24048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float64_sqrt(a, &env->vfp.fp_status);
24068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: check quiet/signaling case */
24098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DO_VFP_cmp(p, type) \
24108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid VFP_HELPER(cmp, p)(type a, type b, CPUState *env)  \
24118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
24128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t flags; \
24138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
24148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0: flags = 0x6; break; \
24158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case -1: flags = 0x8; break; \
24168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 1: flags = 0x2; break; \
24178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default: case 2: flags = 0x3; break; \
24188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
24198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
24208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
24218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} \
24228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid VFP_HELPER(cmpe, p)(type a, type b, CPUState *env) \
24238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
24248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t flags; \
24258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
24268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0: flags = 0x6; break; \
24278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case -1: flags = 0x8; break; \
24288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 1: flags = 0x2; break; \
24298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default: case 2: flags = 0x3; break; \
24308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } \
24318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
24328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
24338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectDO_VFP_cmp(s, float32)
24358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectDO_VFP_cmp(d, float64)
24368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DO_VFP_cmp
24378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Helper routines to perform bitwise copies between float and int.  */
24398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline float32 vfp_itos(uint32_t i)
24408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    union {
24428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t i;
24438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float32 s;
24448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } v;
24458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v.i = i;
24478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return v.s;
24488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint32_t vfp_stoi(float32 s)
24518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    union {
24538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint32_t i;
24548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float32 s;
24558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } v;
24568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v.s = s;
24588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return v.i;
24598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline float64 vfp_itod(uint64_t i)
24628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    union {
24648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t i;
24658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float64 d;
24668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } v;
24678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v.i = i;
24698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return v.d;
24708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint64_t vfp_dtoi(float64 d)
24738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    union {
24758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t i;
24768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float64 d;
24778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } v;
24788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v.d = d;
24808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return v.i;
24818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Integer to float conversion.  */
24848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(uito, s)(float32 x, CPUState *env)
24858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
24878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(uito, d)(float32 x, CPUState *env)
24908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return uint32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
24928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(sito, s)(float32 x, CPUState *env)
24958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return int32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
24978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(sito, d)(float32 x, CPUState *env)
25008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return int32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
25028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Float to integer conversion.  */
25058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(toui, s)(float32 x, CPUState *env)
25068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status));
25088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(toui, d)(float64 x, CPUState *env)
25118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return vfp_itos(float64_to_uint32(x, &env->vfp.fp_status));
25138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(tosi, s)(float32 x, CPUState *env)
25168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return vfp_itos(float32_to_int32(x, &env->vfp.fp_status));
25188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(tosi, d)(float64 x, CPUState *env)
25218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return vfp_itos(float64_to_int32(x, &env->vfp.fp_status));
25238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(touiz, s)(float32 x, CPUState *env)
25268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status));
25288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(touiz, d)(float64 x, CPUState *env)
25318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return vfp_itos(float64_to_uint32_round_to_zero(x, &env->vfp.fp_status));
25338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
25368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status));
25388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
25418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status));
25438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* floating point conversion */
25468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env)
25478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_to_float64(x, &env->vfp.fp_status);
25498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env)
25528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float64_to_float32(x, &env->vfp.fp_status);
25548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* VFP3 fixed point conversion.  */
25578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
25588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \
25598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
25608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ftype tmp; \
25618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(x), \
25628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                  &env->vfp.fp_status); \
25635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ftype##_scalbn(tmp, -(int)shift, &env->vfp.fp_status); \
25648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} \
25658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \
25668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \
25678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ftype tmp; \
25688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \
25698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
25708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        &env->vfp.fp_status)); \
25718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(sh, d, float64, int16, )
25748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(sl, d, float64, int32, )
25758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(uh, d, float64, uint16, u)
25768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(ul, d, float64, uint32, u)
25778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(sh, s, float32, int16, )
25788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(sl, s, float32, int32, )
25798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(uh, s, float32, uint16, u)
25808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(ul, s, float32, uint32, u)
25818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef VFP_CONV_FIX
25828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 HELPER(recps_f32)(float32 a, float32 b, CPUState *env)
25848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_status *s = &env->vfp.fp_status;
25868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float32 two = int32_to_float32(2, s);
25878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_sub(two, float32_mul(a, b, s), s);
25888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env)
25918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_status *s = &env->vfp.fp_status;
25938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float32 three = int32_to_float32(3, s);
25948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_sub(three, float32_mul(a, b, s), s);
25958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* NEON helpers.  */
25988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* TODO: The architecture specifies the value that the estimate functions
26008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   should return.  We return the exact reciprocal/root instead.  */
26018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 HELPER(recpe_f32)(float32 a, CPUState *env)
26028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
26038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_status *s = &env->vfp.fp_status;
26048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float32 one = int32_to_float32(1, s);
26058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_div(one, a, s);
26068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
26078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
26098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
26108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_status *s = &env->vfp.fp_status;
26118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float32 one = int32_to_float32(1, s);
26128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_div(one, float32_sqrt(a, s), s);
26138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
26148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
26168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
26178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_status *s = &env->vfp.fp_status;
26188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float32 tmp;
26198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = int32_to_float32(a, s);
26208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = float32_scalbn(tmp, -32, s);
26218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = helper_recpe_f32(tmp, env);
26228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = float32_scalbn(tmp, 31, s);
26238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_to_int32(tmp, s);
26248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
26258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
26278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
26288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_status *s = &env->vfp.fp_status;
26298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float32 tmp;
26308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = int32_to_float32(a, s);
26318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = float32_scalbn(tmp, -32, s);
26328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = helper_rsqrte_f32(tmp, env);
26338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp = float32_scalbn(tmp, 31, s);
26348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_to_int32(tmp, s);
26358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
26368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_TRACE
26388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "trace.h"
26398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid  HELPER(traceTicks)(uint32_t  ticks)
26408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
26418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sim_time += ticks;
26428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
26438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid  HELPER(traceInsn)(void)
26458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
26468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_insn_helper();
26478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
26488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HOST_LONG_BITS == 32
2650a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turnervoid HELPER(traceBB32)(uint64_t  bb_num, uint32_t  tb)
26518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
26528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb_helper(bb_num, (void*)tb);
26538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
26548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
26558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HOST_LONG_BITS == 64
26578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(traceBB64)(uint64_t  bb_num, uint64_t  tb)
26588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
26598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_bb_helper(bb_num, (void*)tb);
26608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
26618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
26628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* CONFIG_TRACE */
26645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid HELPER(set_teecr)(CPUState *env, uint32_t val)
26665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    val &= 1;
26685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->teecr != val) {
26695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->teecr = val;
26705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tb_flush(env);
26715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
26725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
26755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid HELPER(on_call)(void* pc, void* ret) {
26765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_on_call((target_ulong)pc, (target_ulong)ret);
26775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
26785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
26795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid HELPER(on_ret)(void* ret) {
26805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_on_ret((target_ulong)ret);
26815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
26825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
2683