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