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

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

unix.superglobalmegacorp.com

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