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