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