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