qemu/target-arm/helper.c
<<
>>
Prefs
   1#include <stdio.h>
   2#include <stdlib.h>
   3#include <string.h>
   4
   5#include "cpu.h"
   6#include "exec-all.h"
   7#include "gdbstub.h"
   8#include "helpers.h"
   9#include "qemu-common.h"
  10#include "host-utils.h"
  11#if !defined(CONFIG_USER_ONLY)
  12#include "hw/loader.h"
  13#endif
  14
  15static uint32_t cortexa9_cp15_c0_c1[8] =
  16{ 0x1031, 0x11, 0x000, 0, 0x00100103, 0x20000000, 0x01230000, 0x00002111 };
  17
  18static uint32_t cortexa9_cp15_c0_c2[8] =
  19{ 0x00101111, 0x13112111, 0x21232041, 0x11112131, 0x00111142, 0, 0, 0 };
  20
  21static uint32_t cortexa8_cp15_c0_c1[8] =
  22{ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 };
  23
  24static uint32_t cortexa8_cp15_c0_c2[8] =
  25{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 };
  26
  27static uint32_t mpcore_cp15_c0_c1[8] =
  28{ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 };
  29
  30static uint32_t mpcore_cp15_c0_c2[8] =
  31{ 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 };
  32
  33static uint32_t arm1136_cp15_c0_c1[8] =
  34{ 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 };
  35
  36static uint32_t arm1136_cp15_c0_c2[8] =
  37{ 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 };
  38
  39static uint32_t cpu_arm_find_by_name(const char *name);
  40
  41static inline void set_feature(CPUARMState *env, int feature)
  42{
  43    env->features |= 1u << feature;
  44}
  45
  46static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
  47{
  48    env->cp15.c0_cpuid = id;
  49    switch (id) {
  50    case ARM_CPUID_ARM926:
  51        set_feature(env, ARM_FEATURE_VFP);
  52        env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
  53        env->cp15.c0_cachetype = 0x1dd20d2;
  54        env->cp15.c1_sys = 0x00090078;
  55        break;
  56    case ARM_CPUID_ARM946:
  57        set_feature(env, ARM_FEATURE_MPU);
  58        env->cp15.c0_cachetype = 0x0f004006;
  59        env->cp15.c1_sys = 0x00000078;
  60        break;
  61    case ARM_CPUID_ARM1026:
  62        set_feature(env, ARM_FEATURE_VFP);
  63        set_feature(env, ARM_FEATURE_AUXCR);
  64        env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
  65        env->cp15.c0_cachetype = 0x1dd20d2;
  66        env->cp15.c1_sys = 0x00090078;
  67        break;
  68    case ARM_CPUID_ARM1136_R2:
  69    case ARM_CPUID_ARM1136:
  70        set_feature(env, ARM_FEATURE_V6);
  71        set_feature(env, ARM_FEATURE_VFP);
  72        set_feature(env, ARM_FEATURE_AUXCR);
  73        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
  74        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
  75        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
  76        memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t));
  77        memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t));
  78        env->cp15.c0_cachetype = 0x1dd20d2;
  79        break;
  80    case ARM_CPUID_ARM11MPCORE:
  81        set_feature(env, ARM_FEATURE_V6);
  82        set_feature(env, ARM_FEATURE_V6K);
  83        set_feature(env, ARM_FEATURE_VFP);
  84        set_feature(env, ARM_FEATURE_AUXCR);
  85        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
  86        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
  87        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
  88        memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t));
  89        memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t));
  90        env->cp15.c0_cachetype = 0x1dd20d2;
  91        break;
  92    case ARM_CPUID_CORTEXA8:
  93        set_feature(env, ARM_FEATURE_V6);
  94        set_feature(env, ARM_FEATURE_V6K);
  95        set_feature(env, ARM_FEATURE_V7);
  96        set_feature(env, ARM_FEATURE_AUXCR);
  97        set_feature(env, ARM_FEATURE_THUMB2);
  98        set_feature(env, ARM_FEATURE_VFP);
  99        set_feature(env, ARM_FEATURE_VFP3);
 100        set_feature(env, ARM_FEATURE_NEON);
 101        set_feature(env, ARM_FEATURE_THUMB2EE);
 102        env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
 103        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
 104        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
 105        memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t));
 106        memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t));
 107        env->cp15.c0_cachetype = 0x82048004;
 108        env->cp15.c0_clid = (1 << 27) | (2 << 24) | 3;
 109        env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */
 110        env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */
 111        env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */
 112        break;
 113    case ARM_CPUID_CORTEXA9:
 114        set_feature(env, ARM_FEATURE_V6);
 115        set_feature(env, ARM_FEATURE_V6K);
 116        set_feature(env, ARM_FEATURE_V7);
 117        set_feature(env, ARM_FEATURE_AUXCR);
 118        set_feature(env, ARM_FEATURE_THUMB2);
 119        set_feature(env, ARM_FEATURE_VFP);
 120        set_feature(env, ARM_FEATURE_VFP3);
 121        set_feature(env, ARM_FEATURE_VFP_FP16);
 122        set_feature(env, ARM_FEATURE_NEON);
 123        set_feature(env, ARM_FEATURE_THUMB2EE);
 124        env->vfp.xregs[ARM_VFP_FPSID] = 0x41034000; /* Guess */
 125        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
 126        env->vfp.xregs[ARM_VFP_MVFR1] = 0x01111111;
 127        memcpy(env->cp15.c0_c1, cortexa9_cp15_c0_c1, 8 * sizeof(uint32_t));
 128        memcpy(env->cp15.c0_c2, cortexa9_cp15_c0_c2, 8 * sizeof(uint32_t));
 129        env->cp15.c0_cachetype = 0x80038003;
 130        env->cp15.c0_clid = (1 << 27) | (1 << 24) | 3;
 131        env->cp15.c0_ccsid[0] = 0xe00fe015; /* 16k L1 dcache. */
 132        env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */
 133        break;
 134    case ARM_CPUID_CORTEXM3:
 135        set_feature(env, ARM_FEATURE_V6);
 136        set_feature(env, ARM_FEATURE_THUMB2);
 137        set_feature(env, ARM_FEATURE_V7);
 138        set_feature(env, ARM_FEATURE_M);
 139        set_feature(env, ARM_FEATURE_DIV);
 140        break;
 141    case ARM_CPUID_ANY: /* For userspace emulation.  */
 142        set_feature(env, ARM_FEATURE_V6);
 143        set_feature(env, ARM_FEATURE_V6K);
 144        set_feature(env, ARM_FEATURE_V7);
 145        set_feature(env, ARM_FEATURE_THUMB2);
 146        set_feature(env, ARM_FEATURE_VFP);
 147        set_feature(env, ARM_FEATURE_VFP3);
 148        set_feature(env, ARM_FEATURE_VFP_FP16);
 149        set_feature(env, ARM_FEATURE_NEON);
 150        set_feature(env, ARM_FEATURE_THUMB2EE);
 151        set_feature(env, ARM_FEATURE_DIV);
 152        break;
 153    case ARM_CPUID_TI915T:
 154    case ARM_CPUID_TI925T:
 155        set_feature(env, ARM_FEATURE_OMAPCP);
 156        env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring.  */
 157        env->cp15.c0_cachetype = 0x5109149;
 158        env->cp15.c1_sys = 0x00000070;
 159        env->cp15.c15_i_max = 0x000;
 160        env->cp15.c15_i_min = 0xff0;
 161        break;
 162    case ARM_CPUID_PXA250:
 163    case ARM_CPUID_PXA255:
 164    case ARM_CPUID_PXA260:
 165    case ARM_CPUID_PXA261:
 166    case ARM_CPUID_PXA262:
 167        set_feature(env, ARM_FEATURE_XSCALE);
 168        /* JTAG_ID is ((id << 28) | 0x09265013) */
 169        env->cp15.c0_cachetype = 0xd172172;
 170        env->cp15.c1_sys = 0x00000078;
 171        break;
 172    case ARM_CPUID_PXA270_A0:
 173    case ARM_CPUID_PXA270_A1:
 174    case ARM_CPUID_PXA270_B0:
 175    case ARM_CPUID_PXA270_B1:
 176    case ARM_CPUID_PXA270_C0:
 177    case ARM_CPUID_PXA270_C5:
 178        set_feature(env, ARM_FEATURE_XSCALE);
 179        /* JTAG_ID is ((id << 28) | 0x09265013) */
 180        set_feature(env, ARM_FEATURE_IWMMXT);
 181        env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
 182        env->cp15.c0_cachetype = 0xd172172;
 183        env->cp15.c1_sys = 0x00000078;
 184        break;
 185    default:
 186        cpu_abort(env, "Bad CPU ID: %x\n", id);
 187        break;
 188    }
 189}
 190
 191void cpu_reset(CPUARMState *env)
 192{
 193    uint32_t id;
 194
 195    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
 196        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
 197        log_cpu_state(env, 0);
 198    }
 199
 200    id = env->cp15.c0_cpuid;
 201    memset(env, 0, offsetof(CPUARMState, breakpoints));
 202    if (id)
 203        cpu_reset_model_id(env, id);
 204#if defined (CONFIG_USER_ONLY)
 205    env->uncached_cpsr = ARM_CPU_MODE_USR;
 206    env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
 207#else
 208    /* SVC mode with interrupts disabled.  */
 209    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
 210    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
 211       clear at reset.  Initial SP and PC are loaded from ROM.  */
 212    if (IS_M(env)) {
 213        uint32_t pc;
 214        uint8_t *rom;
 215        env->uncached_cpsr &= ~CPSR_I;
 216        rom = rom_ptr(0);
 217        if (rom) {
 218            /* We should really use ldl_phys here, in case the guest
 219               modified flash and reset itself.  However images
 220               loaded via -kenrel have not been copied yet, so load the
 221               values directly from there.  */
 222            env->regs[13] = ldl_p(rom);
 223            pc = ldl_p(rom + 4);
 224            env->thumb = pc & 1;
 225            env->regs[15] = pc & ~1;
 226        }
 227    }
 228    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
 229    env->cp15.c2_base_mask = 0xffffc000u;
 230#endif
 231    tlb_flush(env, 1);
 232}
 233
 234static int vfp_gdb_get_reg(CPUState *env, uint8_t *buf, int reg)
 235{
 236    int nregs;
 237
 238    /* VFP data registers are always little-endian.  */
 239    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
 240    if (reg < nregs) {
 241        stfq_le_p(buf, env->vfp.regs[reg]);
 242        return 8;
 243    }
 244    if (arm_feature(env, ARM_FEATURE_NEON)) {
 245        /* Aliases for Q regs.  */
 246        nregs += 16;
 247        if (reg < nregs) {
 248            stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
 249            stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
 250            return 16;
 251        }
 252    }
 253    switch (reg - nregs) {
 254    case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4;
 255    case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4;
 256    case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4;
 257    }
 258    return 0;
 259}
 260
 261static int vfp_gdb_set_reg(CPUState *env, uint8_t *buf, int reg)
 262{
 263    int nregs;
 264
 265    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
 266    if (reg < nregs) {
 267        env->vfp.regs[reg] = ldfq_le_p(buf);
 268        return 8;
 269    }
 270    if (arm_feature(env, ARM_FEATURE_NEON)) {
 271        nregs += 16;
 272        if (reg < nregs) {
 273            env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf);
 274            env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8);
 275            return 16;
 276        }
 277    }
 278    switch (reg - nregs) {
 279    case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
 280    case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4;
 281    case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
 282    }
 283    return 0;
 284}
 285
 286CPUARMState *cpu_arm_init(const char *cpu_model)
 287{
 288    CPUARMState *env;
 289    uint32_t id;
 290    static int inited = 0;
 291
 292    id = cpu_arm_find_by_name(cpu_model);
 293    if (id == 0)
 294        return NULL;
 295    env = qemu_mallocz(sizeof(CPUARMState));
 296    cpu_exec_init(env);
 297    if (!inited) {
 298        inited = 1;
 299        arm_translate_init();
 300    }
 301
 302    env->cpu_model_str = cpu_model;
 303    env->cp15.c0_cpuid = id;
 304    cpu_reset(env);
 305    if (arm_feature(env, ARM_FEATURE_NEON)) {
 306        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
 307                                 51, "arm-neon.xml", 0);
 308    } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
 309        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
 310                                 35, "arm-vfp3.xml", 0);
 311    } else if (arm_feature(env, ARM_FEATURE_VFP)) {
 312        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
 313                                 19, "arm-vfp.xml", 0);
 314    }
 315    qemu_init_vcpu(env);
 316    return env;
 317}
 318
 319struct arm_cpu_t {
 320    uint32_t id;
 321    const char *name;
 322};
 323
 324static const struct arm_cpu_t arm_cpu_names[] = {
 325    { ARM_CPUID_ARM926, "arm926"},
 326    { ARM_CPUID_ARM946, "arm946"},
 327    { ARM_CPUID_ARM1026, "arm1026"},
 328    { ARM_CPUID_ARM1136, "arm1136"},
 329    { ARM_CPUID_ARM1136_R2, "arm1136-r2"},
 330    { ARM_CPUID_ARM11MPCORE, "arm11mpcore"},
 331    { ARM_CPUID_CORTEXM3, "cortex-m3"},
 332    { ARM_CPUID_CORTEXA8, "cortex-a8"},
 333    { ARM_CPUID_CORTEXA9, "cortex-a9"},
 334    { ARM_CPUID_TI925T, "ti925t" },
 335    { ARM_CPUID_PXA250, "pxa250" },
 336    { ARM_CPUID_PXA255, "pxa255" },
 337    { ARM_CPUID_PXA260, "pxa260" },
 338    { ARM_CPUID_PXA261, "pxa261" },
 339    { ARM_CPUID_PXA262, "pxa262" },
 340    { ARM_CPUID_PXA270, "pxa270" },
 341    { ARM_CPUID_PXA270_A0, "pxa270-a0" },
 342    { ARM_CPUID_PXA270_A1, "pxa270-a1" },
 343    { ARM_CPUID_PXA270_B0, "pxa270-b0" },
 344    { ARM_CPUID_PXA270_B1, "pxa270-b1" },
 345    { ARM_CPUID_PXA270_C0, "pxa270-c0" },
 346    { ARM_CPUID_PXA270_C5, "pxa270-c5" },
 347    { ARM_CPUID_ANY, "any"},
 348    { 0, NULL}
 349};
 350
 351void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
 352{
 353    int i;
 354
 355    (*cpu_fprintf)(f, "Available CPUs:\n");
 356    for (i = 0; arm_cpu_names[i].name; i++) {
 357        (*cpu_fprintf)(f, "  %s\n", arm_cpu_names[i].name);
 358    }
 359}
 360
 361/* return 0 if not found */
 362static uint32_t cpu_arm_find_by_name(const char *name)
 363{
 364    int i;
 365    uint32_t id;
 366
 367    id = 0;
 368    for (i = 0; arm_cpu_names[i].name; i++) {
 369        if (strcmp(name, arm_cpu_names[i].name) == 0) {
 370            id = arm_cpu_names[i].id;
 371            break;
 372        }
 373    }
 374    return id;
 375}
 376
 377void cpu_arm_close(CPUARMState *env)
 378{
 379    free(env);
 380}
 381
 382uint32_t cpsr_read(CPUARMState *env)
 383{
 384    int ZF;
 385    ZF = (env->ZF == 0);
 386    return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
 387        (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
 388        | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
 389        | ((env->condexec_bits & 0xfc) << 8)
 390        | (env->GE << 16);
 391}
 392
 393void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 394{
 395    if (mask & CPSR_NZCV) {
 396        env->ZF = (~val) & CPSR_Z;
 397        env->NF = val;
 398        env->CF = (val >> 29) & 1;
 399        env->VF = (val << 3) & 0x80000000;
 400    }
 401    if (mask & CPSR_Q)
 402        env->QF = ((val & CPSR_Q) != 0);
 403    if (mask & CPSR_T)
 404        env->thumb = ((val & CPSR_T) != 0);
 405    if (mask & CPSR_IT_0_1) {
 406        env->condexec_bits &= ~3;
 407        env->condexec_bits |= (val >> 25) & 3;
 408    }
 409    if (mask & CPSR_IT_2_7) {
 410        env->condexec_bits &= 3;
 411        env->condexec_bits |= (val >> 8) & 0xfc;
 412    }
 413    if (mask & CPSR_GE) {
 414        env->GE = (val >> 16) & 0xf;
 415    }
 416
 417    if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
 418        switch_mode(env, val & CPSR_M);
 419    }
 420    mask &= ~CACHED_CPSR_BITS;
 421    env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
 422}
 423
 424/* Sign/zero extend */
 425uint32_t HELPER(sxtb16)(uint32_t x)
 426{
 427    uint32_t res;
 428    res = (uint16_t)(int8_t)x;
 429    res |= (uint32_t)(int8_t)(x >> 16) << 16;
 430    return res;
 431}
 432
 433uint32_t HELPER(uxtb16)(uint32_t x)
 434{
 435    uint32_t res;
 436    res = (uint16_t)(uint8_t)x;
 437    res |= (uint32_t)(uint8_t)(x >> 16) << 16;
 438    return res;
 439}
 440
 441uint32_t HELPER(clz)(uint32_t x)
 442{
 443    return clz32(x);
 444}
 445
 446int32_t HELPER(sdiv)(int32_t num, int32_t den)
 447{
 448    if (den == 0)
 449      return 0;
 450    if (num == INT_MIN && den == -1)
 451      return INT_MIN;
 452    return num / den;
 453}
 454
 455uint32_t HELPER(udiv)(uint32_t num, uint32_t den)
 456{
 457    if (den == 0)
 458      return 0;
 459    return num / den;
 460}
 461
 462uint32_t HELPER(rbit)(uint32_t x)
 463{
 464    x =  ((x & 0xff000000) >> 24)
 465       | ((x & 0x00ff0000) >> 8)
 466       | ((x & 0x0000ff00) << 8)
 467       | ((x & 0x000000ff) << 24);
 468    x =  ((x & 0xf0f0f0f0) >> 4)
 469       | ((x & 0x0f0f0f0f) << 4);
 470    x =  ((x & 0x88888888) >> 3)
 471       | ((x & 0x44444444) >> 1)
 472       | ((x & 0x22222222) << 1)
 473       | ((x & 0x11111111) << 3);
 474    return x;
 475}
 476
 477uint32_t HELPER(abs)(uint32_t x)
 478{
 479    return ((int32_t)x < 0) ? -x : x;
 480}
 481
 482#if defined(CONFIG_USER_ONLY)
 483
 484void do_interrupt (CPUState *env)
 485{
 486    env->exception_index = -1;
 487}
 488
 489int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
 490                              int mmu_idx, int is_softmmu)
 491{
 492    if (rw == 2) {
 493        env->exception_index = EXCP_PREFETCH_ABORT;
 494        env->cp15.c6_insn = address;
 495    } else {
 496        env->exception_index = EXCP_DATA_ABORT;
 497        env->cp15.c6_data = address;
 498    }
 499    return 1;
 500}
 501
 502/* These should probably raise undefined insn exceptions.  */
 503void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
 504{
 505    int op1 = (insn >> 8) & 0xf;
 506    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
 507    return;
 508}
 509
 510uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
 511{
 512    int op1 = (insn >> 8) & 0xf;
 513    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
 514    return 0;
 515}
 516
 517void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
 518{
 519    cpu_abort(env, "cp15 insn %08x\n", insn);
 520}
 521
 522uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
 523{
 524    cpu_abort(env, "cp15 insn %08x\n", insn);
 525}
 526
 527/* These should probably raise undefined insn exceptions.  */
 528void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
 529{
 530    cpu_abort(env, "v7m_mrs %d\n", reg);
 531}
 532
 533uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
 534{
 535    cpu_abort(env, "v7m_mrs %d\n", reg);
 536    return 0;
 537}
 538
 539void switch_mode(CPUState *env, int mode)
 540{
 541    if (mode != ARM_CPU_MODE_USR)
 542        cpu_abort(env, "Tried to switch out of user mode\n");
 543}
 544
 545void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
 546{
 547    cpu_abort(env, "banked r13 write\n");
 548}
 549
 550uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
 551{
 552    cpu_abort(env, "banked r13 read\n");
 553    return 0;
 554}
 555
 556#else
 557
 558extern int semihosting_enabled;
 559
 560/* Map CPU modes onto saved register banks.  */
 561static inline int bank_number (int mode)
 562{
 563    switch (mode) {
 564    case ARM_CPU_MODE_USR:
 565    case ARM_CPU_MODE_SYS:
 566        return 0;
 567    case ARM_CPU_MODE_SVC:
 568        return 1;
 569    case ARM_CPU_MODE_ABT:
 570        return 2;
 571    case ARM_CPU_MODE_UND:
 572        return 3;
 573    case ARM_CPU_MODE_IRQ:
 574        return 4;
 575    case ARM_CPU_MODE_FIQ:
 576        return 5;
 577    }
 578    cpu_abort(cpu_single_env, "Bad mode %x\n", mode);
 579    return -1;
 580}
 581
 582void switch_mode(CPUState *env, int mode)
 583{
 584    int old_mode;
 585    int i;
 586
 587    old_mode = env->uncached_cpsr & CPSR_M;
 588    if (mode == old_mode)
 589        return;
 590
 591    if (old_mode == ARM_CPU_MODE_FIQ) {
 592        memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
 593        memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
 594    } else if (mode == ARM_CPU_MODE_FIQ) {
 595        memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
 596        memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
 597    }
 598
 599    i = bank_number(old_mode);
 600    env->banked_r13[i] = env->regs[13];
 601    env->banked_r14[i] = env->regs[14];
 602    env->banked_spsr[i] = env->spsr;
 603
 604    i = bank_number(mode);
 605    env->regs[13] = env->banked_r13[i];
 606    env->regs[14] = env->banked_r14[i];
 607    env->spsr = env->banked_spsr[i];
 608}
 609
 610static void v7m_push(CPUARMState *env, uint32_t val)
 611{
 612    env->regs[13] -= 4;
 613    stl_phys(env->regs[13], val);
 614}
 615
 616static uint32_t v7m_pop(CPUARMState *env)
 617{
 618    uint32_t val;
 619    val = ldl_phys(env->regs[13]);
 620    env->regs[13] += 4;
 621    return val;
 622}
 623
 624/* Switch to V7M main or process stack pointer.  */
 625static void switch_v7m_sp(CPUARMState *env, int process)
 626{
 627    uint32_t tmp;
 628    if (env->v7m.current_sp != process) {
 629        tmp = env->v7m.other_sp;
 630        env->v7m.other_sp = env->regs[13];
 631        env->regs[13] = tmp;
 632        env->v7m.current_sp = process;
 633    }
 634}
 635
 636static void do_v7m_exception_exit(CPUARMState *env)
 637{
 638    uint32_t type;
 639    uint32_t xpsr;
 640
 641    type = env->regs[15];
 642    if (env->v7m.exception != 0)
 643        armv7m_nvic_complete_irq(env->nvic, env->v7m.exception);
 644
 645    /* Switch to the target stack.  */
 646    switch_v7m_sp(env, (type & 4) != 0);
 647    /* Pop registers.  */
 648    env->regs[0] = v7m_pop(env);
 649    env->regs[1] = v7m_pop(env);
 650    env->regs[2] = v7m_pop(env);
 651    env->regs[3] = v7m_pop(env);
 652    env->regs[12] = v7m_pop(env);
 653    env->regs[14] = v7m_pop(env);
 654    env->regs[15] = v7m_pop(env);
 655    xpsr = v7m_pop(env);
 656    xpsr_write(env, xpsr, 0xfffffdff);
 657    /* Undo stack alignment.  */
 658    if (xpsr & 0x200)
 659        env->regs[13] |= 4;
 660    /* ??? The exception return type specifies Thread/Handler mode.  However
 661       this is also implied by the xPSR value. Not sure what to do
 662       if there is a mismatch.  */
 663    /* ??? Likewise for mismatches between the CONTROL register and the stack
 664       pointer.  */
 665}
 666
 667static void do_interrupt_v7m(CPUARMState *env)
 668{
 669    uint32_t xpsr = xpsr_read(env);
 670    uint32_t lr;
 671    uint32_t addr;
 672
 673    lr = 0xfffffff1;
 674    if (env->v7m.current_sp)
 675        lr |= 4;
 676    if (env->v7m.exception == 0)
 677        lr |= 8;
 678
 679    /* For exceptions we just mark as pending on the NVIC, and let that
 680       handle it.  */
 681    /* TODO: Need to escalate if the current priority is higher than the
 682       one we're raising.  */
 683    switch (env->exception_index) {
 684    case EXCP_UDEF:
 685        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
 686        return;
 687    case EXCP_SWI:
 688        env->regs[15] += 2;
 689        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
 690        return;
 691    case EXCP_PREFETCH_ABORT:
 692    case EXCP_DATA_ABORT:
 693        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
 694        return;
 695    case EXCP_BKPT:
 696        if (semihosting_enabled) {
 697            int nr;
 698            nr = lduw_code(env->regs[15]) & 0xff;
 699            if (nr == 0xab) {
 700                env->regs[15] += 2;
 701                env->regs[0] = do_arm_semihosting(env);
 702                return;
 703            }
 704        }
 705        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG);
 706        return;
 707    case EXCP_IRQ:
 708        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->nvic);
 709        break;
 710    case EXCP_EXCEPTION_EXIT:
 711        do_v7m_exception_exit(env);
 712        return;
 713    default:
 714        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
 715        return; /* Never happens.  Keep compiler happy.  */
 716    }
 717
 718    /* Align stack pointer.  */
 719    /* ??? Should only do this if Configuration Control Register
 720       STACKALIGN bit is set.  */
 721    if (env->regs[13] & 4) {
 722        env->regs[13] -= 4;
 723        xpsr |= 0x200;
 724    }
 725    /* Switch to the handler mode.  */
 726    v7m_push(env, xpsr);
 727    v7m_push(env, env->regs[15]);
 728    v7m_push(env, env->regs[14]);
 729    v7m_push(env, env->regs[12]);
 730    v7m_push(env, env->regs[3]);
 731    v7m_push(env, env->regs[2]);
 732    v7m_push(env, env->regs[1]);
 733    v7m_push(env, env->regs[0]);
 734    switch_v7m_sp(env, 0);
 735    env->uncached_cpsr &= ~CPSR_IT;
 736    env->regs[14] = lr;
 737    addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
 738    env->regs[15] = addr & 0xfffffffe;
 739    env->thumb = addr & 1;
 740}
 741
 742/* Handle a CPU exception.  */
 743void do_interrupt(CPUARMState *env)
 744{
 745    uint32_t addr;
 746    uint32_t mask;
 747    int new_mode;
 748    uint32_t offset;
 749
 750    if (IS_M(env)) {
 751        do_interrupt_v7m(env);
 752        return;
 753    }
 754    /* TODO: Vectored interrupt controller.  */
 755    switch (env->exception_index) {
 756    case EXCP_UDEF:
 757        new_mode = ARM_CPU_MODE_UND;
 758        addr = 0x04;
 759        mask = CPSR_I;
 760        if (env->thumb)
 761            offset = 2;
 762        else
 763            offset = 4;
 764        break;
 765    case EXCP_SWI:
 766        if (semihosting_enabled) {
 767            /* Check for semihosting interrupt.  */
 768            if (env->thumb) {
 769                mask = lduw_code(env->regs[15] - 2) & 0xff;
 770            } else {
 771                mask = ldl_code(env->regs[15] - 4) & 0xffffff;
 772            }
 773            /* Only intercept calls from privileged modes, to provide some
 774               semblance of security.  */
 775            if (((mask == 0x123456 && !env->thumb)
 776                    || (mask == 0xab && env->thumb))
 777                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
 778                env->regs[0] = do_arm_semihosting(env);
 779                return;
 780            }
 781        }
 782        new_mode = ARM_CPU_MODE_SVC;
 783        addr = 0x08;
 784        mask = CPSR_I;
 785        /* The PC already points to the next instruction.  */
 786        offset = 0;
 787        break;
 788    case EXCP_BKPT:
 789        /* See if this is a semihosting syscall.  */
 790        if (env->thumb && semihosting_enabled) {
 791            mask = lduw_code(env->regs[15]) & 0xff;
 792            if (mask == 0xab
 793                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
 794                env->regs[15] += 2;
 795                env->regs[0] = do_arm_semihosting(env);
 796                return;
 797            }
 798        }
 799        /* Fall through to prefetch abort.  */
 800    case EXCP_PREFETCH_ABORT:
 801        new_mode = ARM_CPU_MODE_ABT;
 802        addr = 0x0c;
 803        mask = CPSR_A | CPSR_I;
 804        offset = 4;
 805        break;
 806    case EXCP_DATA_ABORT:
 807        new_mode = ARM_CPU_MODE_ABT;
 808        addr = 0x10;
 809        mask = CPSR_A | CPSR_I;
 810        offset = 8;
 811        break;
 812    case EXCP_IRQ:
 813        new_mode = ARM_CPU_MODE_IRQ;
 814        addr = 0x18;
 815        /* Disable IRQ and imprecise data aborts.  */
 816        mask = CPSR_A | CPSR_I;
 817        offset = 4;
 818        break;
 819    case EXCP_FIQ:
 820        new_mode = ARM_CPU_MODE_FIQ;
 821        addr = 0x1c;
 822        /* Disable FIQ, IRQ and imprecise data aborts.  */
 823        mask = CPSR_A | CPSR_I | CPSR_F;
 824        offset = 4;
 825        break;
 826    default:
 827        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
 828        return; /* Never happens.  Keep compiler happy.  */
 829    }
 830    /* High vectors.  */
 831    if (env->cp15.c1_sys & (1 << 13)) {
 832        addr += 0xffff0000;
 833    }
 834    switch_mode (env, new_mode);
 835    env->spsr = cpsr_read(env);
 836    /* Clear IT bits.  */
 837    env->condexec_bits = 0;
 838    /* Switch to the new mode, and to the correct instruction set.  */
 839    env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
 840    env->uncached_cpsr |= mask;
 841    env->thumb = (env->cp15.c1_sys & (1 << 30)) != 0;
 842    env->regs[14] = env->regs[15] + offset;
 843    env->regs[15] = addr;
 844    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
 845}
 846
 847/* Check section/page access permissions.
 848   Returns the page protection flags, or zero if the access is not
 849   permitted.  */
 850static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
 851                           int is_user)
 852{
 853  int prot_ro;
 854
 855  if (domain == 3)
 856    return PAGE_READ | PAGE_WRITE;
 857
 858  if (access_type == 1)
 859      prot_ro = 0;
 860  else
 861      prot_ro = PAGE_READ;
 862
 863  switch (ap) {
 864  case 0:
 865      if (access_type == 1)
 866          return 0;
 867      switch ((env->cp15.c1_sys >> 8) & 3) {
 868      case 1:
 869          return is_user ? 0 : PAGE_READ;
 870      case 2:
 871          return PAGE_READ;
 872      default:
 873          return 0;
 874      }
 875  case 1:
 876      return is_user ? 0 : PAGE_READ | PAGE_WRITE;
 877  case 2:
 878      if (is_user)
 879          return prot_ro;
 880      else
 881          return PAGE_READ | PAGE_WRITE;
 882  case 3:
 883      return PAGE_READ | PAGE_WRITE;
 884  case 4: /* Reserved.  */
 885      return 0;
 886  case 5:
 887      return is_user ? 0 : prot_ro;
 888  case 6:
 889      return prot_ro;
 890  case 7:
 891      if (!arm_feature (env, ARM_FEATURE_V7))
 892          return 0;
 893      return prot_ro;
 894  default:
 895      abort();
 896  }
 897}
 898
 899static uint32_t get_level1_table_address(CPUState *env, uint32_t address)
 900{
 901    uint32_t table;
 902
 903    if (address & env->cp15.c2_mask)
 904        table = env->cp15.c2_base1 & 0xffffc000;
 905    else
 906        table = env->cp15.c2_base0 & env->cp15.c2_base_mask;
 907
 908    table |= (address >> 18) & 0x3ffc;
 909    return table;
 910}
 911
 912static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
 913                            int is_user, uint32_t *phys_ptr, int *prot,
 914                            target_ulong *page_size)
 915{
 916    int code;
 917    uint32_t table;
 918    uint32_t desc;
 919    int type;
 920    int ap;
 921    int domain;
 922    uint32_t phys_addr;
 923
 924    /* Pagetable walk.  */
 925    /* Lookup l1 descriptor.  */
 926    table = get_level1_table_address(env, address);
 927    desc = ldl_phys(table);
 928    type = (desc & 3);
 929    domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
 930    if (type == 0) {
 931        /* Section translation fault.  */
 932        code = 5;
 933        goto do_fault;
 934    }
 935    if (domain == 0 || domain == 2) {
 936        if (type == 2)
 937            code = 9; /* Section domain fault.  */
 938        else
 939            code = 11; /* Page domain fault.  */
 940        goto do_fault;
 941    }
 942    if (type == 2) {
 943        /* 1Mb section.  */
 944        phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
 945        ap = (desc >> 10) & 3;
 946        code = 13;
 947        *page_size = 1024 * 1024;
 948    } else {
 949        /* Lookup l2 entry.  */
 950        if (type == 1) {
 951            /* Coarse pagetable.  */
 952            table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
 953        } else {
 954            /* Fine pagetable.  */
 955            table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
 956        }
 957        desc = ldl_phys(table);
 958        switch (desc & 3) {
 959        case 0: /* Page translation fault.  */
 960            code = 7;
 961            goto do_fault;
 962        case 1: /* 64k page.  */
 963            phys_addr = (desc & 0xffff0000) | (address & 0xffff);
 964            ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
 965            *page_size = 0x10000;
 966            break;
 967        case 2: /* 4k page.  */
 968            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
 969            ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
 970            *page_size = 0x1000;
 971            break;
 972        case 3: /* 1k page.  */
 973            if (type == 1) {
 974                if (arm_feature(env, ARM_FEATURE_XSCALE)) {
 975                    phys_addr = (desc & 0xfffff000) | (address & 0xfff);
 976                } else {
 977                    /* Page translation fault.  */
 978                    code = 7;
 979                    goto do_fault;
 980                }
 981            } else {
 982                phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
 983            }
 984            ap = (desc >> 4) & 3;
 985            *page_size = 0x400;
 986            break;
 987        default:
 988            /* Never happens, but compiler isn't smart enough to tell.  */
 989            abort();
 990        }
 991        code = 15;
 992    }
 993    *prot = check_ap(env, ap, domain, access_type, is_user);
 994    if (!*prot) {
 995        /* Access permission fault.  */
 996        goto do_fault;
 997    }
 998    *prot |= PAGE_EXEC;
 999    *phys_ptr = phys_addr;
1000    return 0;
1001do_fault:
1002    return code | (domain << 4);
1003}
1004
1005static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
1006                            int is_user, uint32_t *phys_ptr, int *prot,
1007                            target_ulong *page_size)
1008{
1009    int code;
1010    uint32_t table;
1011    uint32_t desc;
1012    uint32_t xn;
1013    int type;
1014    int ap;
1015    int domain;
1016    uint32_t phys_addr;
1017
1018    /* Pagetable walk.  */
1019    /* Lookup l1 descriptor.  */
1020    table = get_level1_table_address(env, address);
1021    desc = ldl_phys(table);
1022    type = (desc & 3);
1023    if (type == 0) {
1024        /* Section translation fault.  */
1025        code = 5;
1026        domain = 0;
1027        goto do_fault;
1028    } else if (type == 2 && (desc & (1 << 18))) {
1029        /* Supersection.  */
1030        domain = 0;
1031    } else {
1032        /* Section or page.  */
1033        domain = (desc >> 4) & 0x1e;
1034    }
1035    domain = (env->cp15.c3 >> domain) & 3;
1036    if (domain == 0 || domain == 2) {
1037        if (type == 2)
1038            code = 9; /* Section domain fault.  */
1039        else
1040            code = 11; /* Page domain fault.  */
1041        goto do_fault;
1042    }
1043    if (type == 2) {
1044        if (desc & (1 << 18)) {
1045            /* Supersection.  */
1046            phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
1047            *page_size = 0x1000000;
1048        } else {
1049            /* Section.  */
1050            phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
1051            *page_size = 0x100000;
1052        }
1053        ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
1054        xn = desc & (1 << 4);
1055        code = 13;
1056    } else {
1057        /* Lookup l2 entry.  */
1058        table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
1059        desc = ldl_phys(table);
1060        ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
1061        switch (desc & 3) {
1062        case 0: /* Page translation fault.  */
1063            code = 7;
1064            goto do_fault;
1065        case 1: /* 64k page.  */
1066            phys_addr = (desc & 0xffff0000) | (address & 0xffff);
1067            xn = desc & (1 << 15);
1068            *page_size = 0x10000;
1069            break;
1070        case 2: case 3: /* 4k page.  */
1071            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
1072            xn = desc & 1;
1073            *page_size = 0x1000;
1074            break;
1075        default:
1076            /* Never happens, but compiler isn't smart enough to tell.  */
1077            abort();
1078        }
1079        code = 15;
1080    }
1081    if (xn && access_type == 2)
1082        goto do_fault;
1083
1084    /* The simplified model uses AP[0] as an access control bit.  */
1085    if ((env->cp15.c1_sys & (1 << 29)) && (ap & 1) == 0) {
1086        /* Access flag fault.  */
1087        code = (code == 15) ? 6 : 3;
1088        goto do_fault;
1089    }
1090    *prot = check_ap(env, ap, domain, access_type, is_user);
1091    if (!*prot) {
1092        /* Access permission fault.  */
1093        goto do_fault;
1094    }
1095    if (!xn) {
1096        *prot |= PAGE_EXEC;
1097    }
1098    *phys_ptr = phys_addr;
1099    return 0;
1100do_fault:
1101    return code | (domain << 4);
1102}
1103
1104static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
1105                             int is_user, uint32_t *phys_ptr, int *prot)
1106{
1107    int n;
1108    uint32_t mask;
1109    uint32_t base;
1110
1111    *phys_ptr = address;
1112    for (n = 7; n >= 0; n--) {
1113        base = env->cp15.c6_region[n];
1114        if ((base & 1) == 0)
1115            continue;
1116        mask = 1 << ((base >> 1) & 0x1f);
1117        /* Keep this shift separate from the above to avoid an
1118           (undefined) << 32.  */
1119        mask = (mask << 1) - 1;
1120        if (((base ^ address) & ~mask) == 0)
1121            break;
1122    }
1123    if (n < 0)
1124        return 2;
1125
1126    if (access_type == 2) {
1127        mask = env->cp15.c5_insn;
1128    } else {
1129        mask = env->cp15.c5_data;
1130    }
1131    mask = (mask >> (n * 4)) & 0xf;
1132    switch (mask) {
1133    case 0:
1134        return 1;
1135    case 1:
1136        if (is_user)
1137          return 1;
1138        *prot = PAGE_READ | PAGE_WRITE;
1139        break;
1140    case 2:
1141        *prot = PAGE_READ;
1142        if (!is_user)
1143            *prot |= PAGE_WRITE;
1144        break;
1145    case 3:
1146        *prot = PAGE_READ | PAGE_WRITE;
1147        break;
1148    case 5:
1149        if (is_user)
1150            return 1;
1151        *prot = PAGE_READ;
1152        break;
1153    case 6:
1154        *prot = PAGE_READ;
1155        break;
1156    default:
1157        /* Bad permission.  */
1158        return 1;
1159    }
1160    *prot |= PAGE_EXEC;
1161    return 0;
1162}
1163
1164static inline int get_phys_addr(CPUState *env, uint32_t address,
1165                                int access_type, int is_user,
1166                                uint32_t *phys_ptr, int *prot,
1167                                target_ulong *page_size)
1168{
1169    /* Fast Context Switch Extension.  */
1170    if (address < 0x02000000)
1171        address += env->cp15.c13_fcse;
1172
1173    if ((env->cp15.c1_sys & 1) == 0) {
1174        /* MMU/MPU disabled.  */
1175        *phys_ptr = address;
1176        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1177        *page_size = TARGET_PAGE_SIZE;
1178        return 0;
1179    } else if (arm_feature(env, ARM_FEATURE_MPU)) {
1180        *page_size = TARGET_PAGE_SIZE;
1181        return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,
1182                                 prot);
1183    } else if (env->cp15.c1_sys & (1 << 23)) {
1184        return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
1185                                prot, page_size);
1186    } else {
1187        return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,
1188                                prot, page_size);
1189    }
1190}
1191
1192int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
1193                              int access_type, int mmu_idx, int is_softmmu)
1194{
1195    uint32_t phys_addr;
1196    target_ulong page_size;
1197    int prot;
1198    int ret, is_user;
1199
1200    is_user = mmu_idx == MMU_USER_IDX;
1201    ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot,
1202                        &page_size);
1203    if (ret == 0) {
1204        /* Map a single [sub]page.  */
1205        phys_addr &= ~(uint32_t)0x3ff;
1206        address &= ~(uint32_t)0x3ff;
1207        tlb_set_page (env, address, phys_addr, prot, mmu_idx, page_size);
1208        return 0;
1209    }
1210
1211    if (access_type == 2) {
1212        env->cp15.c5_insn = ret;
1213        env->cp15.c6_insn = address;
1214        env->exception_index = EXCP_PREFETCH_ABORT;
1215    } else {
1216        env->cp15.c5_data = ret;
1217        if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
1218            env->cp15.c5_data |= (1 << 11);
1219        env->cp15.c6_data = address;
1220        env->exception_index = EXCP_DATA_ABORT;
1221    }
1222    return 1;
1223}
1224
1225target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1226{
1227    uint32_t phys_addr;
1228    target_ulong page_size;
1229    int prot;
1230    int ret;
1231
1232    ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot, &page_size);
1233
1234    if (ret != 0)
1235        return -1;
1236
1237    return phys_addr;
1238}
1239
1240void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
1241{
1242    int cp_num = (insn >> 8) & 0xf;
1243    int cp_info = (insn >> 5) & 7;
1244    int src = (insn >> 16) & 0xf;
1245    int operand = insn & 0xf;
1246
1247    if (env->cp[cp_num].cp_write)
1248        env->cp[cp_num].cp_write(env->cp[cp_num].opaque,
1249                                 cp_info, src, operand, val);
1250}
1251
1252uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
1253{
1254    int cp_num = (insn >> 8) & 0xf;
1255    int cp_info = (insn >> 5) & 7;
1256    int dest = (insn >> 16) & 0xf;
1257    int operand = insn & 0xf;
1258
1259    if (env->cp[cp_num].cp_read)
1260        return env->cp[cp_num].cp_read(env->cp[cp_num].opaque,
1261                                       cp_info, dest, operand);
1262    return 0;
1263}
1264
1265/* Return basic MPU access permission bits.  */
1266static uint32_t simple_mpu_ap_bits(uint32_t val)
1267{
1268    uint32_t ret;
1269    uint32_t mask;
1270    int i;
1271    ret = 0;
1272    mask = 3;
1273    for (i = 0; i < 16; i += 2) {
1274        ret |= (val >> i) & mask;
1275        mask <<= 2;
1276    }
1277    return ret;
1278}
1279
1280/* Pad basic MPU access permission bits to extended format.  */
1281static uint32_t extended_mpu_ap_bits(uint32_t val)
1282{
1283    uint32_t ret;
1284    uint32_t mask;
1285    int i;
1286    ret = 0;
1287    mask = 3;
1288    for (i = 0; i < 16; i += 2) {
1289        ret |= (val & mask) << i;
1290        mask <<= 2;
1291    }
1292    return ret;
1293}
1294
1295void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
1296{
1297    int op1;
1298    int op2;
1299    int crm;
1300
1301    op1 = (insn >> 21) & 7;
1302    op2 = (insn >> 5) & 7;
1303    crm = insn & 0xf;
1304    switch ((insn >> 16) & 0xf) {
1305    case 0:
1306        /* ID codes.  */
1307        if (arm_feature(env, ARM_FEATURE_XSCALE))
1308            break;
1309        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1310            break;
1311        if (arm_feature(env, ARM_FEATURE_V7)
1312                && op1 == 2 && crm == 0 && op2 == 0) {
1313            env->cp15.c0_cssel = val & 0xf;
1314            break;
1315        }
1316        goto bad_reg;
1317    case 1: /* System configuration.  */
1318        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1319            op2 = 0;
1320        switch (op2) {
1321        case 0:
1322            if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
1323                env->cp15.c1_sys = val;
1324            /* ??? Lots of these bits are not implemented.  */
1325            /* This may enable/disable the MMU, so do a TLB flush.  */
1326            tlb_flush(env, 1);
1327            break;
1328        case 1: /* Auxiliary cotrol register.  */
1329            if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1330                env->cp15.c1_xscaleauxcr = val;
1331                break;
1332            }
1333            /* Not implemented.  */
1334            break;
1335        case 2:
1336            if (arm_feature(env, ARM_FEATURE_XSCALE))
1337                goto bad_reg;
1338            if (env->cp15.c1_coproc != val) {
1339                env->cp15.c1_coproc = val;
1340                /* ??? Is this safe when called from within a TB?  */
1341                tb_flush(env);
1342            }
1343            break;
1344        default:
1345            goto bad_reg;
1346        }
1347        break;
1348    case 2: /* MMU Page table control / MPU cache control.  */
1349        if (arm_feature(env, ARM_FEATURE_MPU)) {
1350            switch (op2) {
1351            case 0:
1352                env->cp15.c2_data = val;
1353                break;
1354            case 1:
1355                env->cp15.c2_insn = val;
1356                break;
1357            default:
1358                goto bad_reg;
1359            }
1360        } else {
1361            switch (op2) {
1362            case 0:
1363                env->cp15.c2_base0 = val;
1364                break;
1365            case 1:
1366                env->cp15.c2_base1 = val;
1367                break;
1368            case 2:
1369                val &= 7;
1370                env->cp15.c2_control = val;
1371                env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
1372                env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val);
1373                break;
1374            default:
1375                goto bad_reg;
1376            }
1377        }
1378        break;
1379    case 3: /* MMU Domain access control / MPU write buffer control.  */
1380        env->cp15.c3 = val;
1381        tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
1382        break;
1383    case 4: /* Reserved.  */
1384        goto bad_reg;
1385    case 5: /* MMU Fault status / MPU access permission.  */
1386        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1387            op2 = 0;
1388        switch (op2) {
1389        case 0:
1390            if (arm_feature(env, ARM_FEATURE_MPU))
1391                val = extended_mpu_ap_bits(val);
1392            env->cp15.c5_data = val;
1393            break;
1394        case 1:
1395            if (arm_feature(env, ARM_FEATURE_MPU))
1396                val = extended_mpu_ap_bits(val);
1397            env->cp15.c5_insn = val;
1398            break;
1399        case 2:
1400            if (!arm_feature(env, ARM_FEATURE_MPU))
1401                goto bad_reg;
1402            env->cp15.c5_data = val;
1403            break;
1404        case 3:
1405            if (!arm_feature(env, ARM_FEATURE_MPU))
1406                goto bad_reg;
1407            env->cp15.c5_insn = val;
1408            break;
1409        default:
1410            goto bad_reg;
1411        }
1412        break;
1413    case 6: /* MMU Fault address / MPU base/size.  */
1414        if (arm_feature(env, ARM_FEATURE_MPU)) {
1415            if (crm >= 8)
1416                goto bad_reg;
1417            env->cp15.c6_region[crm] = val;
1418        } else {
1419            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1420                op2 = 0;
1421            switch (op2) {
1422            case 0:
1423                env->cp15.c6_data = val;
1424                break;
1425            case 1: /* ??? This is WFAR on armv6 */
1426            case 2:
1427                env->cp15.c6_insn = val;
1428                break;
1429            default:
1430                goto bad_reg;
1431            }
1432        }
1433        break;
1434    case 7: /* Cache control.  */
1435        env->cp15.c15_i_max = 0x000;
1436        env->cp15.c15_i_min = 0xff0;
1437        /* No cache, so nothing to do.  */
1438        /* ??? MPCore has VA to PA translation functions.  */
1439        break;
1440    case 8: /* MMU TLB control.  */
1441        switch (op2) {
1442        case 0: /* Invalidate all.  */
1443            tlb_flush(env, 0);
1444            break;
1445        case 1: /* Invalidate single TLB entry.  */
1446            tlb_flush_page(env, val & TARGET_PAGE_MASK);
1447            break;
1448        case 2: /* Invalidate on ASID.  */
1449            tlb_flush(env, val == 0);
1450            break;
1451        case 3: /* Invalidate single entry on MVA.  */
1452            /* ??? This is like case 1, but ignores ASID.  */
1453            tlb_flush(env, 1);
1454            break;
1455        default:
1456            goto bad_reg;
1457        }
1458        break;
1459    case 9:
1460        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1461            break;
1462        switch (crm) {
1463        case 0: /* Cache lockdown.  */
1464            switch (op1) {
1465            case 0: /* L1 cache.  */
1466                switch (op2) {
1467                case 0:
1468                    env->cp15.c9_data = val;
1469                    break;
1470                case 1:
1471                    env->cp15.c9_insn = val;
1472                    break;
1473                default:
1474                    goto bad_reg;
1475                }
1476                break;
1477            case 1: /* L2 cache.  */
1478                /* Ignore writes to L2 lockdown/auxiliary registers.  */
1479                break;
1480            default:
1481                goto bad_reg;
1482            }
1483            break;
1484        case 1: /* TCM memory region registers.  */
1485            /* Not implemented.  */
1486            goto bad_reg;
1487        default:
1488            goto bad_reg;
1489        }
1490        break;
1491    case 10: /* MMU TLB lockdown.  */
1492        /* ??? TLB lockdown not implemented.  */
1493        break;
1494    case 12: /* Reserved.  */
1495        goto bad_reg;
1496    case 13: /* Process ID.  */
1497        switch (op2) {
1498        case 0:
1499            /* Unlike real hardware the qemu TLB uses virtual addresses,
1500               not modified virtual addresses, so this causes a TLB flush.
1501             */
1502            if (env->cp15.c13_fcse != val)
1503              tlb_flush(env, 1);
1504            env->cp15.c13_fcse = val;
1505            break;
1506        case 1:
1507            /* This changes the ASID, so do a TLB flush.  */
1508            if (env->cp15.c13_context != val
1509                && !arm_feature(env, ARM_FEATURE_MPU))
1510              tlb_flush(env, 0);
1511            env->cp15.c13_context = val;
1512            break;
1513        default:
1514            goto bad_reg;
1515        }
1516        break;
1517    case 14: /* Reserved.  */
1518        goto bad_reg;
1519    case 15: /* Implementation specific.  */
1520        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1521            if (op2 == 0 && crm == 1) {
1522                if (env->cp15.c15_cpar != (val & 0x3fff)) {
1523                    /* Changes cp0 to cp13 behavior, so needs a TB flush.  */
1524                    tb_flush(env);
1525                    env->cp15.c15_cpar = val & 0x3fff;
1526                }
1527                break;
1528            }
1529            goto bad_reg;
1530        }
1531        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1532            switch (crm) {
1533            case 0:
1534                break;
1535            case 1: /* Set TI925T configuration.  */
1536                env->cp15.c15_ticonfig = val & 0xe7;
1537                env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */
1538                        ARM_CPUID_TI915T : ARM_CPUID_TI925T;
1539                break;
1540            case 2: /* Set I_max.  */
1541                env->cp15.c15_i_max = val;
1542                break;
1543            case 3: /* Set I_min.  */
1544                env->cp15.c15_i_min = val;
1545                break;
1546            case 4: /* Set thread-ID.  */
1547                env->cp15.c15_threadid = val & 0xffff;
1548                break;
1549            case 8: /* Wait-for-interrupt (deprecated).  */
1550                cpu_interrupt(env, CPU_INTERRUPT_HALT);
1551                break;
1552            default:
1553                goto bad_reg;
1554            }
1555        }
1556        break;
1557    }
1558    return;
1559bad_reg:
1560    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1561    cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",
1562              (insn >> 16) & 0xf, crm, op1, op2);
1563}
1564
1565uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
1566{
1567    int op1;
1568    int op2;
1569    int crm;
1570
1571    op1 = (insn >> 21) & 7;
1572    op2 = (insn >> 5) & 7;
1573    crm = insn & 0xf;
1574    switch ((insn >> 16) & 0xf) {
1575    case 0: /* ID codes.  */
1576        switch (op1) {
1577        case 0:
1578            switch (crm) {
1579            case 0:
1580                switch (op2) {
1581                case 0: /* Device ID.  */
1582                    return env->cp15.c0_cpuid;
1583                case 1: /* Cache Type.  */
1584                    return env->cp15.c0_cachetype;
1585                case 2: /* TCM status.  */
1586                    return 0;
1587                case 3: /* TLB type register.  */
1588                    return 0; /* No lockable TLB entries.  */
1589                case 5: /* CPU ID */
1590                    if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
1591                        return env->cpu_index | 0x80000900;
1592                    } else {
1593                        return env->cpu_index;
1594                    }
1595                default:
1596                    goto bad_reg;
1597                }
1598            case 1:
1599                if (!arm_feature(env, ARM_FEATURE_V6))
1600                    goto bad_reg;
1601                return env->cp15.c0_c1[op2];
1602            case 2:
1603                if (!arm_feature(env, ARM_FEATURE_V6))
1604                    goto bad_reg;
1605                return env->cp15.c0_c2[op2];
1606            case 3: case 4: case 5: case 6: case 7:
1607                return 0;
1608            default:
1609                goto bad_reg;
1610            }
1611        case 1:
1612            /* These registers aren't documented on arm11 cores.  However
1613               Linux looks at them anyway.  */
1614            if (!arm_feature(env, ARM_FEATURE_V6))
1615                goto bad_reg;
1616            if (crm != 0)
1617                goto bad_reg;
1618            if (!arm_feature(env, ARM_FEATURE_V7))
1619                return 0;
1620
1621            switch (op2) {
1622            case 0:
1623                return env->cp15.c0_ccsid[env->cp15.c0_cssel];
1624            case 1:
1625                return env->cp15.c0_clid;
1626            case 7:
1627                return 0;
1628            }
1629            goto bad_reg;
1630        case 2:
1631            if (op2 != 0 || crm != 0)
1632                goto bad_reg;
1633            return env->cp15.c0_cssel;
1634        default:
1635            goto bad_reg;
1636        }
1637    case 1: /* System configuration.  */
1638        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1639            op2 = 0;
1640        switch (op2) {
1641        case 0: /* Control register.  */
1642            return env->cp15.c1_sys;
1643        case 1: /* Auxiliary control register.  */
1644            if (arm_feature(env, ARM_FEATURE_XSCALE))
1645                return env->cp15.c1_xscaleauxcr;
1646            if (!arm_feature(env, ARM_FEATURE_AUXCR))
1647                goto bad_reg;
1648            switch (ARM_CPUID(env)) {
1649            case ARM_CPUID_ARM1026:
1650                return 1;
1651            case ARM_CPUID_ARM1136:
1652            case ARM_CPUID_ARM1136_R2:
1653                return 7;
1654            case ARM_CPUID_ARM11MPCORE:
1655                return 1;
1656            case ARM_CPUID_CORTEXA8:
1657                return 2;
1658            case ARM_CPUID_CORTEXA9:
1659                return 0;
1660            default:
1661                goto bad_reg;
1662            }
1663        case 2: /* Coprocessor access register.  */
1664            if (arm_feature(env, ARM_FEATURE_XSCALE))
1665                goto bad_reg;
1666            return env->cp15.c1_coproc;
1667        default:
1668            goto bad_reg;
1669        }
1670    case 2: /* MMU Page table control / MPU cache control.  */
1671        if (arm_feature(env, ARM_FEATURE_MPU)) {
1672            switch (op2) {
1673            case 0:
1674                return env->cp15.c2_data;
1675                break;
1676            case 1:
1677                return env->cp15.c2_insn;
1678                break;
1679            default:
1680                goto bad_reg;
1681            }
1682        } else {
1683            switch (op2) {
1684            case 0:
1685                return env->cp15.c2_base0;
1686            case 1:
1687                return env->cp15.c2_base1;
1688            case 2:
1689                return env->cp15.c2_control;
1690            default:
1691                goto bad_reg;
1692            }
1693        }
1694    case 3: /* MMU Domain access control / MPU write buffer control.  */
1695        return env->cp15.c3;
1696    case 4: /* Reserved.  */
1697        goto bad_reg;
1698    case 5: /* MMU Fault status / MPU access permission.  */
1699        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1700            op2 = 0;
1701        switch (op2) {
1702        case 0:
1703            if (arm_feature(env, ARM_FEATURE_MPU))
1704                return simple_mpu_ap_bits(env->cp15.c5_data);
1705            return env->cp15.c5_data;
1706        case 1:
1707            if (arm_feature(env, ARM_FEATURE_MPU))
1708                return simple_mpu_ap_bits(env->cp15.c5_data);
1709            return env->cp15.c5_insn;
1710        case 2:
1711            if (!arm_feature(env, ARM_FEATURE_MPU))
1712                goto bad_reg;
1713            return env->cp15.c5_data;
1714        case 3:
1715            if (!arm_feature(env, ARM_FEATURE_MPU))
1716                goto bad_reg;
1717            return env->cp15.c5_insn;
1718        default:
1719            goto bad_reg;
1720        }
1721    case 6: /* MMU Fault address.  */
1722        if (arm_feature(env, ARM_FEATURE_MPU)) {
1723            if (crm >= 8)
1724                goto bad_reg;
1725            return env->cp15.c6_region[crm];
1726        } else {
1727            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1728                op2 = 0;
1729            switch (op2) {
1730            case 0:
1731                return env->cp15.c6_data;
1732            case 1:
1733                if (arm_feature(env, ARM_FEATURE_V6)) {
1734                    /* Watchpoint Fault Adrress.  */
1735                    return 0; /* Not implemented.  */
1736                } else {
1737                    /* Instruction Fault Adrress.  */
1738                    /* Arm9 doesn't have an IFAR, but implementing it anyway
1739                       shouldn't do any harm.  */
1740                    return env->cp15.c6_insn;
1741                }
1742            case 2:
1743                if (arm_feature(env, ARM_FEATURE_V6)) {
1744                    /* Instruction Fault Adrress.  */
1745                    return env->cp15.c6_insn;
1746                } else {
1747                    goto bad_reg;
1748                }
1749            default:
1750                goto bad_reg;
1751            }
1752        }
1753    case 7: /* Cache control.  */
1754        /* FIXME: Should only clear Z flag if destination is r15.  */
1755        env->ZF = 0;
1756        return 0;
1757    case 8: /* MMU TLB control.  */
1758        goto bad_reg;
1759    case 9: /* Cache lockdown.  */
1760        switch (op1) {
1761        case 0: /* L1 cache.  */
1762            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1763                return 0;
1764            switch (op2) {
1765            case 0:
1766                return env->cp15.c9_data;
1767            case 1:
1768                return env->cp15.c9_insn;
1769            default:
1770                goto bad_reg;
1771            }
1772        case 1: /* L2 cache */
1773            if (crm != 0)
1774                goto bad_reg;
1775            /* L2 Lockdown and Auxiliary control.  */
1776            return 0;
1777        default:
1778            goto bad_reg;
1779        }
1780    case 10: /* MMU TLB lockdown.  */
1781        /* ??? TLB lockdown not implemented.  */
1782        return 0;
1783    case 11: /* TCM DMA control.  */
1784    case 12: /* Reserved.  */
1785        goto bad_reg;
1786    case 13: /* Process ID.  */
1787        switch (op2) {
1788        case 0:
1789            return env->cp15.c13_fcse;
1790        case 1:
1791            return env->cp15.c13_context;
1792        default:
1793            goto bad_reg;
1794        }
1795    case 14: /* Reserved.  */
1796        goto bad_reg;
1797    case 15: /* Implementation specific.  */
1798        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1799            if (op2 == 0 && crm == 1)
1800                return env->cp15.c15_cpar;
1801
1802            goto bad_reg;
1803        }
1804        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1805            switch (crm) {
1806            case 0:
1807                return 0;
1808            case 1: /* Read TI925T configuration.  */
1809                return env->cp15.c15_ticonfig;
1810            case 2: /* Read I_max.  */
1811                return env->cp15.c15_i_max;
1812            case 3: /* Read I_min.  */
1813                return env->cp15.c15_i_min;
1814            case 4: /* Read thread-ID.  */
1815                return env->cp15.c15_threadid;
1816            case 8: /* TI925T_status */
1817                return 0;
1818            }
1819            /* TODO: Peripheral port remap register:
1820             * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt
1821             * controller base address at $rn & ~0xfff and map size of
1822             * 0x200 << ($rn & 0xfff), when MMU is off.  */
1823            goto bad_reg;
1824        }
1825        return 0;
1826    }
1827bad_reg:
1828    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1829    cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
1830              (insn >> 16) & 0xf, crm, op1, op2);
1831    return 0;
1832}
1833
1834void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
1835{
1836    env->banked_r13[bank_number(mode)] = val;
1837}
1838
1839uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
1840{
1841    return env->banked_r13[bank_number(mode)];
1842}
1843
1844uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
1845{
1846    switch (reg) {
1847    case 0: /* APSR */
1848        return xpsr_read(env) & 0xf8000000;
1849    case 1: /* IAPSR */
1850        return xpsr_read(env) & 0xf80001ff;
1851    case 2: /* EAPSR */
1852        return xpsr_read(env) & 0xff00fc00;
1853    case 3: /* xPSR */
1854        return xpsr_read(env) & 0xff00fdff;
1855    case 5: /* IPSR */
1856        return xpsr_read(env) & 0x000001ff;
1857    case 6: /* EPSR */
1858        return xpsr_read(env) & 0x0700fc00;
1859    case 7: /* IEPSR */
1860        return xpsr_read(env) & 0x0700edff;
1861    case 8: /* MSP */
1862        return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13];
1863    case 9: /* PSP */
1864        return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp;
1865    case 16: /* PRIMASK */
1866        return (env->uncached_cpsr & CPSR_I) != 0;
1867    case 17: /* FAULTMASK */
1868        return (env->uncached_cpsr & CPSR_F) != 0;
1869    case 18: /* BASEPRI */
1870    case 19: /* BASEPRI_MAX */
1871        return env->v7m.basepri;
1872    case 20: /* CONTROL */
1873        return env->v7m.control;
1874    default:
1875        /* ??? For debugging only.  */
1876        cpu_abort(env, "Unimplemented system register read (%d)\n", reg);
1877        return 0;
1878    }
1879}
1880
1881void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
1882{
1883    switch (reg) {
1884    case 0: /* APSR */
1885        xpsr_write(env, val, 0xf8000000);
1886        break;
1887    case 1: /* IAPSR */
1888        xpsr_write(env, val, 0xf8000000);
1889        break;
1890    case 2: /* EAPSR */
1891        xpsr_write(env, val, 0xfe00fc00);
1892        break;
1893    case 3: /* xPSR */
1894        xpsr_write(env, val, 0xfe00fc00);
1895        break;
1896    case 5: /* IPSR */
1897        /* IPSR bits are readonly.  */
1898        break;
1899    case 6: /* EPSR */
1900        xpsr_write(env, val, 0x0600fc00);
1901        break;
1902    case 7: /* IEPSR */
1903        xpsr_write(env, val, 0x0600fc00);
1904        break;
1905    case 8: /* MSP */
1906        if (env->v7m.current_sp)
1907            env->v7m.other_sp = val;
1908        else
1909            env->regs[13] = val;
1910        break;
1911    case 9: /* PSP */
1912        if (env->v7m.current_sp)
1913            env->regs[13] = val;
1914        else
1915            env->v7m.other_sp = val;
1916        break;
1917    case 16: /* PRIMASK */
1918        if (val & 1)
1919            env->uncached_cpsr |= CPSR_I;
1920        else
1921            env->uncached_cpsr &= ~CPSR_I;
1922        break;
1923    case 17: /* FAULTMASK */
1924        if (val & 1)
1925            env->uncached_cpsr |= CPSR_F;
1926        else
1927            env->uncached_cpsr &= ~CPSR_F;
1928        break;
1929    case 18: /* BASEPRI */
1930        env->v7m.basepri = val & 0xff;
1931        break;
1932    case 19: /* BASEPRI_MAX */
1933        val &= 0xff;
1934        if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
1935            env->v7m.basepri = val;
1936        break;
1937    case 20: /* CONTROL */
1938        env->v7m.control = val & 3;
1939        switch_v7m_sp(env, (val & 2) != 0);
1940        break;
1941    default:
1942        /* ??? For debugging only.  */
1943        cpu_abort(env, "Unimplemented system register write (%d)\n", reg);
1944        return;
1945    }
1946}
1947
1948void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
1949                ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
1950                void *opaque)
1951{
1952    if (cpnum < 0 || cpnum > 14) {
1953        cpu_abort(env, "Bad coprocessor number: %i\n", cpnum);
1954        return;
1955    }
1956
1957    env->cp[cpnum].cp_read = cp_read;
1958    env->cp[cpnum].cp_write = cp_write;
1959    env->cp[cpnum].opaque = opaque;
1960}
1961
1962#endif
1963
1964/* Note that signed overflow is undefined in C.  The following routines are
1965   careful to use unsigned types where modulo arithmetic is required.
1966   Failure to do so _will_ break on newer gcc.  */
1967
1968/* Signed saturating arithmetic.  */
1969
1970/* Perform 16-bit signed saturating addition.  */
1971static inline uint16_t add16_sat(uint16_t a, uint16_t b)
1972{
1973    uint16_t res;
1974
1975    res = a + b;
1976    if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
1977        if (a & 0x8000)
1978            res = 0x8000;
1979        else
1980            res = 0x7fff;
1981    }
1982    return res;
1983}
1984
1985/* Perform 8-bit signed saturating addition.  */
1986static inline uint8_t add8_sat(uint8_t a, uint8_t b)
1987{
1988    uint8_t res;
1989
1990    res = a + b;
1991    if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
1992        if (a & 0x80)
1993            res = 0x80;
1994        else
1995            res = 0x7f;
1996    }
1997    return res;
1998}
1999
2000/* Perform 16-bit signed saturating subtraction.  */
2001static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
2002{
2003    uint16_t res;
2004
2005    res = a - b;
2006    if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
2007        if (a & 0x8000)
2008            res = 0x8000;
2009        else
2010            res = 0x7fff;
2011    }
2012    return res;
2013}
2014
2015/* Perform 8-bit signed saturating subtraction.  */
2016static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
2017{
2018    uint8_t res;
2019
2020    res = a - b;
2021    if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
2022        if (a & 0x80)
2023            res = 0x80;
2024        else
2025            res = 0x7f;
2026    }
2027    return res;
2028}
2029
2030#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
2031#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
2032#define ADD8(a, b, n)  RESULT(add8_sat(a, b), n, 8);
2033#define SUB8(a, b, n)  RESULT(sub8_sat(a, b), n, 8);
2034#define PFX q
2035
2036#include "op_addsub.h"
2037
2038/* Unsigned saturating arithmetic.  */
2039static inline uint16_t add16_usat(uint16_t a, uint16_t b)
2040{
2041    uint16_t res;
2042    res = a + b;
2043    if (res < a)
2044        res = 0xffff;
2045    return res;
2046}
2047
2048static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
2049{
2050    if (a > b)
2051        return a - b;
2052    else
2053        return 0;
2054}
2055
2056static inline uint8_t add8_usat(uint8_t a, uint8_t b)
2057{
2058    uint8_t res;
2059    res = a + b;
2060    if (res < a)
2061        res = 0xff;
2062    return res;
2063}
2064
2065static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
2066{
2067    if (a > b)
2068        return a - b;
2069    else
2070        return 0;
2071}
2072
2073#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
2074#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
2075#define ADD8(a, b, n)  RESULT(add8_usat(a, b), n, 8);
2076#define SUB8(a, b, n)  RESULT(sub8_usat(a, b), n, 8);
2077#define PFX uq
2078
2079#include "op_addsub.h"
2080
2081/* Signed modulo arithmetic.  */
2082#define SARITH16(a, b, n, op) do { \
2083    int32_t sum; \
2084    sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \
2085    RESULT(sum, n, 16); \
2086    if (sum >= 0) \
2087        ge |= 3 << (n * 2); \
2088    } while(0)
2089
2090#define SARITH8(a, b, n, op) do { \
2091    int32_t sum; \
2092    sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \
2093    RESULT(sum, n, 8); \
2094    if (sum >= 0) \
2095        ge |= 1 << n; \
2096    } while(0)
2097
2098
2099#define ADD16(a, b, n) SARITH16(a, b, n, +)
2100#define SUB16(a, b, n) SARITH16(a, b, n, -)
2101#define ADD8(a, b, n)  SARITH8(a, b, n, +)
2102#define SUB8(a, b, n)  SARITH8(a, b, n, -)
2103#define PFX s
2104#define ARITH_GE
2105
2106#include "op_addsub.h"
2107
2108/* Unsigned modulo arithmetic.  */
2109#define ADD16(a, b, n) do { \
2110    uint32_t sum; \
2111    sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
2112    RESULT(sum, n, 16); \
2113    if ((sum >> 16) == 1) \
2114        ge |= 3 << (n * 2); \
2115    } while(0)
2116
2117#define ADD8(a, b, n) do { \
2118    uint32_t sum; \
2119    sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
2120    RESULT(sum, n, 8); \
2121    if ((sum >> 8) == 1) \
2122        ge |= 1 << n; \
2123    } while(0)
2124
2125#define SUB16(a, b, n) do { \
2126    uint32_t sum; \
2127    sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
2128    RESULT(sum, n, 16); \
2129    if ((sum >> 16) == 0) \
2130        ge |= 3 << (n * 2); \
2131    } while(0)
2132
2133#define SUB8(a, b, n) do { \
2134    uint32_t sum; \
2135    sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
2136    RESULT(sum, n, 8); \
2137    if ((sum >> 8) == 0) \
2138        ge |= 1 << n; \
2139    } while(0)
2140
2141#define PFX u
2142#define ARITH_GE
2143
2144#include "op_addsub.h"
2145
2146/* Halved signed arithmetic.  */
2147#define ADD16(a, b, n) \
2148  RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
2149#define SUB16(a, b, n) \
2150  RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
2151#define ADD8(a, b, n) \
2152  RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
2153#define SUB8(a, b, n) \
2154  RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
2155#define PFX sh
2156
2157#include "op_addsub.h"
2158
2159/* Halved unsigned arithmetic.  */
2160#define ADD16(a, b, n) \
2161  RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2162#define SUB16(a, b, n) \
2163  RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2164#define ADD8(a, b, n) \
2165  RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2166#define SUB8(a, b, n) \
2167  RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2168#define PFX uh
2169
2170#include "op_addsub.h"
2171
2172static inline uint8_t do_usad(uint8_t a, uint8_t b)
2173{
2174    if (a > b)
2175        return a - b;
2176    else
2177        return b - a;
2178}
2179
2180/* Unsigned sum of absolute byte differences.  */
2181uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
2182{
2183    uint32_t sum;
2184    sum = do_usad(a, b);
2185    sum += do_usad(a >> 8, b >> 8);
2186    sum += do_usad(a >> 16, b >>16);
2187    sum += do_usad(a >> 24, b >> 24);
2188    return sum;
2189}
2190
2191/* For ARMv6 SEL instruction.  */
2192uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
2193{
2194    uint32_t mask;
2195
2196    mask = 0;
2197    if (flags & 1)
2198        mask |= 0xff;
2199    if (flags & 2)
2200        mask |= 0xff00;
2201    if (flags & 4)
2202        mask |= 0xff0000;
2203    if (flags & 8)
2204        mask |= 0xff000000;
2205    return (a & mask) | (b & ~mask);
2206}
2207
2208uint32_t HELPER(logicq_cc)(uint64_t val)
2209{
2210    return (val >> 32) | (val != 0);
2211}
2212
2213/* VFP support.  We follow the convention used for VFP instrunctions:
2214   Single precition routines have a "s" suffix, double precision a
2215   "d" suffix.  */
2216
2217/* Convert host exception flags to vfp form.  */
2218static inline int vfp_exceptbits_from_host(int host_bits)
2219{
2220    int target_bits = 0;
2221
2222    if (host_bits & float_flag_invalid)
2223        target_bits |= 1;
2224    if (host_bits & float_flag_divbyzero)
2225        target_bits |= 2;
2226    if (host_bits & float_flag_overflow)
2227        target_bits |= 4;
2228    if (host_bits & float_flag_underflow)
2229        target_bits |= 8;
2230    if (host_bits & float_flag_inexact)
2231        target_bits |= 0x10;
2232    return target_bits;
2233}
2234
2235uint32_t HELPER(vfp_get_fpscr)(CPUState *env)
2236{
2237    int i;
2238    uint32_t fpscr;
2239
2240    fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
2241            | (env->vfp.vec_len << 16)
2242            | (env->vfp.vec_stride << 20);
2243    i = get_float_exception_flags(&env->vfp.fp_status);
2244    fpscr |= vfp_exceptbits_from_host(i);
2245    return fpscr;
2246}
2247
2248/* Convert vfp exception flags to target form.  */
2249static inline int vfp_exceptbits_to_host(int target_bits)
2250{
2251    int host_bits = 0;
2252
2253    if (target_bits & 1)
2254        host_bits |= float_flag_invalid;
2255    if (target_bits & 2)
2256        host_bits |= float_flag_divbyzero;
2257    if (target_bits & 4)
2258        host_bits |= float_flag_overflow;
2259    if (target_bits & 8)
2260        host_bits |= float_flag_underflow;
2261    if (target_bits & 0x10)
2262        host_bits |= float_flag_inexact;
2263    return host_bits;
2264}
2265
2266void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
2267{
2268    int i;
2269    uint32_t changed;
2270
2271    changed = env->vfp.xregs[ARM_VFP_FPSCR];
2272    env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
2273    env->vfp.vec_len = (val >> 16) & 7;
2274    env->vfp.vec_stride = (val >> 20) & 3;
2275
2276    changed ^= val;
2277    if (changed & (3 << 22)) {
2278        i = (val >> 22) & 3;
2279        switch (i) {
2280        case 0:
2281            i = float_round_nearest_even;
2282            break;
2283        case 1:
2284            i = float_round_up;
2285            break;
2286        case 2:
2287            i = float_round_down;
2288            break;
2289        case 3:
2290            i = float_round_to_zero;
2291            break;
2292        }
2293        set_float_rounding_mode(i, &env->vfp.fp_status);
2294    }
2295    if (changed & (1 << 24))
2296        set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
2297    if (changed & (1 << 25))
2298        set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status);
2299
2300    i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
2301    set_float_exception_flags(i, &env->vfp.fp_status);
2302}
2303
2304#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
2305
2306#define VFP_BINOP(name) \
2307float32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \
2308{ \
2309    return float32_ ## name (a, b, &env->vfp.fp_status); \
2310} \
2311float64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \
2312{ \
2313    return float64_ ## name (a, b, &env->vfp.fp_status); \
2314}
2315VFP_BINOP(add)
2316VFP_BINOP(sub)
2317VFP_BINOP(mul)
2318VFP_BINOP(div)
2319#undef VFP_BINOP
2320
2321float32 VFP_HELPER(neg, s)(float32 a)
2322{
2323    return float32_chs(a);
2324}
2325
2326float64 VFP_HELPER(neg, d)(float64 a)
2327{
2328    return float64_chs(a);
2329}
2330
2331float32 VFP_HELPER(abs, s)(float32 a)
2332{
2333    return float32_abs(a);
2334}
2335
2336float64 VFP_HELPER(abs, d)(float64 a)
2337{
2338    return float64_abs(a);
2339}
2340
2341float32 VFP_HELPER(sqrt, s)(float32 a, CPUState *env)
2342{
2343    return float32_sqrt(a, &env->vfp.fp_status);
2344}
2345
2346float64 VFP_HELPER(sqrt, d)(float64 a, CPUState *env)
2347{
2348    return float64_sqrt(a, &env->vfp.fp_status);
2349}
2350
2351/* XXX: check quiet/signaling case */
2352#define DO_VFP_cmp(p, type) \
2353void VFP_HELPER(cmp, p)(type a, type b, CPUState *env)  \
2354{ \
2355    uint32_t flags; \
2356    switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
2357    case 0: flags = 0x6; break; \
2358    case -1: flags = 0x8; break; \
2359    case 1: flags = 0x2; break; \
2360    default: case 2: flags = 0x3; break; \
2361    } \
2362    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2363        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2364} \
2365void VFP_HELPER(cmpe, p)(type a, type b, CPUState *env) \
2366{ \
2367    uint32_t flags; \
2368    switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
2369    case 0: flags = 0x6; break; \
2370    case -1: flags = 0x8; break; \
2371    case 1: flags = 0x2; break; \
2372    default: case 2: flags = 0x3; break; \
2373    } \
2374    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2375        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2376}
2377DO_VFP_cmp(s, float32)
2378DO_VFP_cmp(d, float64)
2379#undef DO_VFP_cmp
2380
2381/* Helper routines to perform bitwise copies between float and int.  */
2382static inline float32 vfp_itos(uint32_t i)
2383{
2384    union {
2385        uint32_t i;
2386        float32 s;
2387    } v;
2388
2389    v.i = i;
2390    return v.s;
2391}
2392
2393static inline uint32_t vfp_stoi(float32 s)
2394{
2395    union {
2396        uint32_t i;
2397        float32 s;
2398    } v;
2399
2400    v.s = s;
2401    return v.i;
2402}
2403
2404static inline float64 vfp_itod(uint64_t i)
2405{
2406    union {
2407        uint64_t i;
2408        float64 d;
2409    } v;
2410
2411    v.i = i;
2412    return v.d;
2413}
2414
2415static inline uint64_t vfp_dtoi(float64 d)
2416{
2417    union {
2418        uint64_t i;
2419        float64 d;
2420    } v;
2421
2422    v.d = d;
2423    return v.i;
2424}
2425
2426/* Integer to float conversion.  */
2427float32 VFP_HELPER(uito, s)(float32 x, CPUState *env)
2428{
2429    return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
2430}
2431
2432float64 VFP_HELPER(uito, d)(float32 x, CPUState *env)
2433{
2434    return uint32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
2435}
2436
2437float32 VFP_HELPER(sito, s)(float32 x, CPUState *env)
2438{
2439    return int32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
2440}
2441
2442float64 VFP_HELPER(sito, d)(float32 x, CPUState *env)
2443{
2444    return int32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
2445}
2446
2447/* Float to integer conversion.  */
2448float32 VFP_HELPER(toui, s)(float32 x, CPUState *env)
2449{
2450    return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status));
2451}
2452
2453float32 VFP_HELPER(toui, d)(float64 x, CPUState *env)
2454{
2455    return vfp_itos(float64_to_uint32(x, &env->vfp.fp_status));
2456}
2457
2458float32 VFP_HELPER(tosi, s)(float32 x, CPUState *env)
2459{
2460    return vfp_itos(float32_to_int32(x, &env->vfp.fp_status));
2461}
2462
2463float32 VFP_HELPER(tosi, d)(float64 x, CPUState *env)
2464{
2465    return vfp_itos(float64_to_int32(x, &env->vfp.fp_status));
2466}
2467
2468float32 VFP_HELPER(touiz, s)(float32 x, CPUState *env)
2469{
2470    return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status));
2471}
2472
2473float32 VFP_HELPER(touiz, d)(float64 x, CPUState *env)
2474{
2475    return vfp_itos(float64_to_uint32_round_to_zero(x, &env->vfp.fp_status));
2476}
2477
2478float32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
2479{
2480    return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status));
2481}
2482
2483float32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
2484{
2485    return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status));
2486}
2487
2488/* floating point conversion */
2489float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env)
2490{
2491    return float32_to_float64(x, &env->vfp.fp_status);
2492}
2493
2494float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env)
2495{
2496    return float64_to_float32(x, &env->vfp.fp_status);
2497}
2498
2499/* VFP3 fixed point conversion.  */
2500#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
2501ftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \
2502{ \
2503    ftype tmp; \
2504    tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(x), \
2505                                  &env->vfp.fp_status); \
2506    return ftype##_scalbn(tmp, -(int)shift, &env->vfp.fp_status); \
2507} \
2508ftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \
2509{ \
2510    ftype tmp; \
2511    tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \
2512    return vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
2513        &env->vfp.fp_status)); \
2514}
2515
2516VFP_CONV_FIX(sh, d, float64, int16, )
2517VFP_CONV_FIX(sl, d, float64, int32, )
2518VFP_CONV_FIX(uh, d, float64, uint16, u)
2519VFP_CONV_FIX(ul, d, float64, uint32, u)
2520VFP_CONV_FIX(sh, s, float32, int16, )
2521VFP_CONV_FIX(sl, s, float32, int32, )
2522VFP_CONV_FIX(uh, s, float32, uint16, u)
2523VFP_CONV_FIX(ul, s, float32, uint32, u)
2524#undef VFP_CONV_FIX
2525
2526/* Half precision conversions.  */
2527float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUState *env)
2528{
2529    float_status *s = &env->vfp.fp_status;
2530    int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
2531    return float16_to_float32(a, ieee, s);
2532}
2533
2534uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUState *env)
2535{
2536    float_status *s = &env->vfp.fp_status;
2537    int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
2538    return float32_to_float16(a, ieee, s);
2539}
2540
2541float32 HELPER(recps_f32)(float32 a, float32 b, CPUState *env)
2542{
2543    float_status *s = &env->vfp.fp_status;
2544    float32 two = int32_to_float32(2, s);
2545    return float32_sub(two, float32_mul(a, b, s), s);
2546}
2547
2548float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env)
2549{
2550    float_status *s = &env->vfp.fp_status;
2551    float32 three = int32_to_float32(3, s);
2552    return float32_sub(three, float32_mul(a, b, s), s);
2553}
2554
2555/* NEON helpers.  */
2556
2557/* TODO: The architecture specifies the value that the estimate functions
2558   should return.  We return the exact reciprocal/root instead.  */
2559float32 HELPER(recpe_f32)(float32 a, CPUState *env)
2560{
2561    float_status *s = &env->vfp.fp_status;
2562    float32 one = int32_to_float32(1, s);
2563    return float32_div(one, a, s);
2564}
2565
2566float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
2567{
2568    float_status *s = &env->vfp.fp_status;
2569    float32 one = int32_to_float32(1, s);
2570    return float32_div(one, float32_sqrt(a, s), s);
2571}
2572
2573uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
2574{
2575    float_status *s = &env->vfp.fp_status;
2576    float32 tmp;
2577    tmp = int32_to_float32(a, s);
2578    tmp = float32_scalbn(tmp, -32, s);
2579    tmp = helper_recpe_f32(tmp, env);
2580    tmp = float32_scalbn(tmp, 31, s);
2581    return float32_to_int32(tmp, s);
2582}
2583
2584uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
2585{
2586    float_status *s = &env->vfp.fp_status;
2587    float32 tmp;
2588    tmp = int32_to_float32(a, s);
2589    tmp = float32_scalbn(tmp, -32, s);
2590    tmp = helper_rsqrte_f32(tmp, env);
2591    tmp = float32_scalbn(tmp, 31, s);
2592    return float32_to_int32(tmp, s);
2593}
2594
2595void HELPER(set_teecr)(CPUState *env, uint32_t val)
2596{
2597    val &= 1;
2598    if (env->teecr != val) {
2599        env->teecr = val;
2600        tb_flush(env);
2601    }
2602}
2603