Annotation of qemu/target-arm/helper.c, revision 1.1.1.6

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.