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