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

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

unix.superglobalmegacorp.com

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