Statistics
| Branch: | Revision:

root / target-arm / helper.c @ 4f78c9ad

History | View | Annotate | Download (72 kB)

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4

    
5
#include "cpu.h"
6
#include "exec-all.h"
7
#include "gdbstub.h"
8
#include "helpers.h"
9
#include "qemu-common.h"
10
#include "host-utils.h"
11
#if !defined(CONFIG_USER_ONLY)
12
#include "hw/loader.h"
13
#endif
14

    
15
static uint32_t cortexa9_cp15_c0_c1[8] =
16
{ 0x1031, 0x11, 0x000, 0, 0x00100103, 0x20000000, 0x01230000, 0x00002111 };
17

    
18
static uint32_t cortexa9_cp15_c0_c2[8] =
19
{ 0x00101111, 0x13112111, 0x21232041, 0x11112131, 0x00111142, 0, 0, 0 };
20

    
21
static uint32_t cortexa8_cp15_c0_c1[8] =
22
{ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 };
23

    
24
static uint32_t cortexa8_cp15_c0_c2[8] =
25
{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 };
26

    
27
static uint32_t mpcore_cp15_c0_c1[8] =
28
{ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 };
29

    
30
static uint32_t mpcore_cp15_c0_c2[8] =
31
{ 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 };
32

    
33
static uint32_t arm1136_cp15_c0_c1[8] =
34
{ 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 };
35

    
36
static uint32_t arm1136_cp15_c0_c2[8] =
37
{ 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 };
38

    
39
static uint32_t cpu_arm_find_by_name(const char *name);
40

    
41
static inline void set_feature(CPUARMState *env, int feature)
42
{
43
    env->features |= 1u << feature;
44
}
45

    
46
static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
47
{
48
    env->cp15.c0_cpuid = id;
49
    switch (id) {
50
    case ARM_CPUID_ARM926:
51
        set_feature(env, ARM_FEATURE_VFP);
52
        env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
53
        env->cp15.c0_cachetype = 0x1dd20d2;
54
        env->cp15.c1_sys = 0x00090078;
55
        break;
56
    case ARM_CPUID_ARM946:
57
        set_feature(env, ARM_FEATURE_MPU);
58
        env->cp15.c0_cachetype = 0x0f004006;
59
        env->cp15.c1_sys = 0x00000078;
60
        break;
61
    case ARM_CPUID_ARM1026:
62
        set_feature(env, ARM_FEATURE_VFP);
63
        set_feature(env, ARM_FEATURE_AUXCR);
64
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
65
        env->cp15.c0_cachetype = 0x1dd20d2;
66
        env->cp15.c1_sys = 0x00090078;
67
        break;
68
    case ARM_CPUID_ARM1136_R2:
69
    case ARM_CPUID_ARM1136:
70
        set_feature(env, ARM_FEATURE_V6);
71
        set_feature(env, ARM_FEATURE_VFP);
72
        set_feature(env, ARM_FEATURE_AUXCR);
73
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
74
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
75
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
76
        memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t));
77
        memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t));
78
        env->cp15.c0_cachetype = 0x1dd20d2;
79
        break;
80
    case ARM_CPUID_ARM11MPCORE:
81
        set_feature(env, ARM_FEATURE_V6);
82
        set_feature(env, ARM_FEATURE_V6K);
83
        set_feature(env, ARM_FEATURE_VFP);
84
        set_feature(env, ARM_FEATURE_AUXCR);
85
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
86
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
87
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
88
        memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t));
89
        memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t));
90
        env->cp15.c0_cachetype = 0x1dd20d2;
91
        break;
92
    case ARM_CPUID_CORTEXA8:
93
        set_feature(env, ARM_FEATURE_V6);
94
        set_feature(env, ARM_FEATURE_V6K);
95
        set_feature(env, ARM_FEATURE_V7);
96
        set_feature(env, ARM_FEATURE_AUXCR);
97
        set_feature(env, ARM_FEATURE_THUMB2);
98
        set_feature(env, ARM_FEATURE_VFP);
99
        set_feature(env, ARM_FEATURE_VFP3);
100
        set_feature(env, ARM_FEATURE_NEON);
101
        set_feature(env, ARM_FEATURE_THUMB2EE);
102
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
103
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
104
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
105
        memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t));
106
        memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t));
107
        env->cp15.c0_cachetype = 0x82048004;
108
        env->cp15.c0_clid = (1 << 27) | (2 << 24) | 3;
109
        env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */
110
        env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */
111
        env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */
112
        break;
113
    case ARM_CPUID_CORTEXA9:
114
        set_feature(env, ARM_FEATURE_V6);
115
        set_feature(env, ARM_FEATURE_V6K);
116
        set_feature(env, ARM_FEATURE_V7);
117
        set_feature(env, ARM_FEATURE_AUXCR);
118
        set_feature(env, ARM_FEATURE_THUMB2);
119
        set_feature(env, ARM_FEATURE_VFP);
120
        set_feature(env, ARM_FEATURE_VFP3);
121
        set_feature(env, ARM_FEATURE_VFP_FP16);
122
        set_feature(env, ARM_FEATURE_NEON);
123
        set_feature(env, ARM_FEATURE_THUMB2EE);
124
        env->vfp.xregs[ARM_VFP_FPSID] = 0x41034000; /* Guess */
125
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
126
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x01111111;
127
        memcpy(env->cp15.c0_c1, cortexa9_cp15_c0_c1, 8 * sizeof(uint32_t));
128
        memcpy(env->cp15.c0_c2, cortexa9_cp15_c0_c2, 8 * sizeof(uint32_t));
129
        env->cp15.c0_cachetype = 0x80038003;
130
        env->cp15.c0_clid = (1 << 27) | (1 << 24) | 3;
131
        env->cp15.c0_ccsid[0] = 0xe00fe015; /* 16k L1 dcache. */
132
        env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */
133
        break;
134
    case ARM_CPUID_CORTEXM3:
135
        set_feature(env, ARM_FEATURE_V6);
136
        set_feature(env, ARM_FEATURE_THUMB2);
137
        set_feature(env, ARM_FEATURE_V7);
138
        set_feature(env, ARM_FEATURE_M);
139
        set_feature(env, ARM_FEATURE_DIV);
140
        break;
141
    case ARM_CPUID_ANY: /* For userspace emulation.  */
142
        set_feature(env, ARM_FEATURE_V6);
143
        set_feature(env, ARM_FEATURE_V6K);
144
        set_feature(env, ARM_FEATURE_V7);
145
        set_feature(env, ARM_FEATURE_THUMB2);
146
        set_feature(env, ARM_FEATURE_VFP);
147
        set_feature(env, ARM_FEATURE_VFP3);
148
        set_feature(env, ARM_FEATURE_VFP_FP16);
149
        set_feature(env, ARM_FEATURE_NEON);
150
        set_feature(env, ARM_FEATURE_THUMB2EE);
151
        set_feature(env, ARM_FEATURE_DIV);
152
        break;
153
    case ARM_CPUID_TI915T:
154
    case ARM_CPUID_TI925T:
155
        set_feature(env, ARM_FEATURE_OMAPCP);
156
        env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring.  */
157
        env->cp15.c0_cachetype = 0x5109149;
158
        env->cp15.c1_sys = 0x00000070;
159
        env->cp15.c15_i_max = 0x000;
160
        env->cp15.c15_i_min = 0xff0;
161
        break;
162
    case ARM_CPUID_PXA250:
163
    case ARM_CPUID_PXA255:
164
    case ARM_CPUID_PXA260:
165
    case ARM_CPUID_PXA261:
166
    case ARM_CPUID_PXA262:
167
        set_feature(env, ARM_FEATURE_XSCALE);
168
        /* JTAG_ID is ((id << 28) | 0x09265013) */
169
        env->cp15.c0_cachetype = 0xd172172;
170
        env->cp15.c1_sys = 0x00000078;
171
        break;
172
    case ARM_CPUID_PXA270_A0:
173
    case ARM_CPUID_PXA270_A1:
174
    case ARM_CPUID_PXA270_B0:
175
    case ARM_CPUID_PXA270_B1:
176
    case ARM_CPUID_PXA270_C0:
177
    case ARM_CPUID_PXA270_C5:
178
        set_feature(env, ARM_FEATURE_XSCALE);
179
        /* JTAG_ID is ((id << 28) | 0x09265013) */
180
        set_feature(env, ARM_FEATURE_IWMMXT);
181
        env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
182
        env->cp15.c0_cachetype = 0xd172172;
183
        env->cp15.c1_sys = 0x00000078;
184
        break;
185
    default:
186
        cpu_abort(env, "Bad CPU ID: %x\n", id);
187
        break;
188
    }
189
}
190

    
191
void cpu_reset(CPUARMState *env)
192
{
193
    uint32_t id;
194

    
195
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
196
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
197
        log_cpu_state(env, 0);
198
    }
199

    
200
    id = env->cp15.c0_cpuid;
201
    memset(env, 0, offsetof(CPUARMState, breakpoints));
202
    if (id)
203
        cpu_reset_model_id(env, id);
204
#if defined (CONFIG_USER_ONLY)
205
    env->uncached_cpsr = ARM_CPU_MODE_USR;
206
    env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
207
#else
208
    /* SVC mode with interrupts disabled.  */
209
    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
210
    env->regs[15] = 0;
211
    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
212
       clear at reset.  Initial SP and PC are loaded from ROM.  */
213
    if (IS_M(env)) {
214
        uint32_t pc;
215
        uint8_t *rom;
216
        env->uncached_cpsr &= ~CPSR_I;
217
        rom = rom_ptr(0);
218
        if (rom) {
219
            /* We should really use ldl_phys here, in case the guest
220
               modified flash and reset itself.  However images
221
               loaded via -kenrel have not been copied yet, so load the
222
               values directly from there.  */
223
            env->regs[13] = ldl_p(rom);
224
            pc = ldl_p(rom + 4);
225
            env->thumb = pc & 1;
226
            env->regs[15] = pc & ~1;
227
        }
228
    }
229
    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
230
    env->cp15.c2_base_mask = 0xffffc000u;
231
#endif
232
    tlb_flush(env, 1);
233
}
234

    
235
static int vfp_gdb_get_reg(CPUState *env, uint8_t *buf, int reg)
236
{
237
    int nregs;
238

    
239
    /* VFP data registers are always little-endian.  */
240
    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
241
    if (reg < nregs) {
242
        stfq_le_p(buf, env->vfp.regs[reg]);
243
        return 8;
244
    }
245
    if (arm_feature(env, ARM_FEATURE_NEON)) {
246
        /* Aliases for Q regs.  */
247
        nregs += 16;
248
        if (reg < nregs) {
249
            stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
250
            stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
251
            return 16;
252
        }
253
    }
254
    switch (reg - nregs) {
255
    case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4;
256
    case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4;
257
    case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4;
258
    }
259
    return 0;
260
}
261

    
262
static int vfp_gdb_set_reg(CPUState *env, uint8_t *buf, int reg)
263
{
264
    int nregs;
265

    
266
    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
267
    if (reg < nregs) {
268
        env->vfp.regs[reg] = ldfq_le_p(buf);
269
        return 8;
270
    }
271
    if (arm_feature(env, ARM_FEATURE_NEON)) {
272
        nregs += 16;
273
        if (reg < nregs) {
274
            env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf);
275
            env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8);
276
            return 16;
277
        }
278
    }
279
    switch (reg - nregs) {
280
    case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
281
    case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4;
282
    case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
283
    }
284
    return 0;
285
}
286

    
287
CPUARMState *cpu_arm_init(const char *cpu_model)
288
{
289
    CPUARMState *env;
290
    uint32_t id;
291
    static int inited = 0;
292

    
293
    id = cpu_arm_find_by_name(cpu_model);
294
    if (id == 0)
295
        return NULL;
296
    env = qemu_mallocz(sizeof(CPUARMState));
297
    cpu_exec_init(env);
298
    if (!inited) {
299
        inited = 1;
300
        arm_translate_init();
301
    }
302

    
303
    env->cpu_model_str = cpu_model;
304
    env->cp15.c0_cpuid = id;
305
    cpu_reset(env);
306
    if (arm_feature(env, ARM_FEATURE_NEON)) {
307
        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
308
                                 51, "arm-neon.xml", 0);
309
    } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
310
        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
311
                                 35, "arm-vfp3.xml", 0);
312
    } else if (arm_feature(env, ARM_FEATURE_VFP)) {
313
        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
314
                                 19, "arm-vfp.xml", 0);
315
    }
316
    qemu_init_vcpu(env);
317
    return env;
318
}
319

    
320
struct arm_cpu_t {
321
    uint32_t id;
322
    const char *name;
323
};
324

    
325
static const struct arm_cpu_t arm_cpu_names[] = {
326
    { ARM_CPUID_ARM926, "arm926"},
327
    { ARM_CPUID_ARM946, "arm946"},
328
    { ARM_CPUID_ARM1026, "arm1026"},
329
    { ARM_CPUID_ARM1136, "arm1136"},
330
    { ARM_CPUID_ARM1136_R2, "arm1136-r2"},
331
    { ARM_CPUID_ARM11MPCORE, "arm11mpcore"},
332
    { ARM_CPUID_CORTEXM3, "cortex-m3"},
333
    { ARM_CPUID_CORTEXA8, "cortex-a8"},
334
    { ARM_CPUID_CORTEXA9, "cortex-a9"},
335
    { ARM_CPUID_TI925T, "ti925t" },
336
    { ARM_CPUID_PXA250, "pxa250" },
337
    { ARM_CPUID_PXA255, "pxa255" },
338
    { ARM_CPUID_PXA260, "pxa260" },
339
    { ARM_CPUID_PXA261, "pxa261" },
340
    { ARM_CPUID_PXA262, "pxa262" },
341
    { ARM_CPUID_PXA270, "pxa270" },
342
    { ARM_CPUID_PXA270_A0, "pxa270-a0" },
343
    { ARM_CPUID_PXA270_A1, "pxa270-a1" },
344
    { ARM_CPUID_PXA270_B0, "pxa270-b0" },
345
    { ARM_CPUID_PXA270_B1, "pxa270-b1" },
346
    { ARM_CPUID_PXA270_C0, "pxa270-c0" },
347
    { ARM_CPUID_PXA270_C5, "pxa270-c5" },
348
    { ARM_CPUID_ANY, "any"},
349
    { 0, NULL}
350
};
351

    
352
void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
353
{
354
    int i;
355

    
356
    (*cpu_fprintf)(f, "Available CPUs:\n");
357
    for (i = 0; arm_cpu_names[i].name; i++) {
358
        (*cpu_fprintf)(f, "  %s\n", arm_cpu_names[i].name);
359
    }
360
}
361

    
362
/* return 0 if not found */
363
static uint32_t cpu_arm_find_by_name(const char *name)
364
{
365
    int i;
366
    uint32_t id;
367

    
368
    id = 0;
369
    for (i = 0; arm_cpu_names[i].name; i++) {
370
        if (strcmp(name, arm_cpu_names[i].name) == 0) {
371
            id = arm_cpu_names[i].id;
372
            break;
373
        }
374
    }
375
    return id;
376
}
377

    
378
void cpu_arm_close(CPUARMState *env)
379
{
380
    free(env);
381
}
382

    
383
uint32_t cpsr_read(CPUARMState *env)
384
{
385
    int ZF;
386
    ZF = (env->ZF == 0);
387
    return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
388
        (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
389
        | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
390
        | ((env->condexec_bits & 0xfc) << 8)
391
        | (env->GE << 16);
392
}
393

    
394
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
395
{
396
    if (mask & CPSR_NZCV) {
397
        env->ZF = (~val) & CPSR_Z;
398
        env->NF = val;
399
        env->CF = (val >> 29) & 1;
400
        env->VF = (val << 3) & 0x80000000;
401
    }
402
    if (mask & CPSR_Q)
403
        env->QF = ((val & CPSR_Q) != 0);
404
    if (mask & CPSR_T)
405
        env->thumb = ((val & CPSR_T) != 0);
406
    if (mask & CPSR_IT_0_1) {
407
        env->condexec_bits &= ~3;
408
        env->condexec_bits |= (val >> 25) & 3;
409
    }
410
    if (mask & CPSR_IT_2_7) {
411
        env->condexec_bits &= 3;
412
        env->condexec_bits |= (val >> 8) & 0xfc;
413
    }
414
    if (mask & CPSR_GE) {
415
        env->GE = (val >> 16) & 0xf;
416
    }
417

    
418
    if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
419
        switch_mode(env, val & CPSR_M);
420
    }
421
    mask &= ~CACHED_CPSR_BITS;
422
    env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
423
}
424

    
425
/* Sign/zero extend */
426
uint32_t HELPER(sxtb16)(uint32_t x)
427
{
428
    uint32_t res;
429
    res = (uint16_t)(int8_t)x;
430
    res |= (uint32_t)(int8_t)(x >> 16) << 16;
431
    return res;
432
}
433

    
434
uint32_t HELPER(uxtb16)(uint32_t x)
435
{
436
    uint32_t res;
437
    res = (uint16_t)(uint8_t)x;
438
    res |= (uint32_t)(uint8_t)(x >> 16) << 16;
439
    return res;
440
}
441

    
442
uint32_t HELPER(clz)(uint32_t x)
443
{
444
    return clz32(x);
445
}
446

    
447
int32_t HELPER(sdiv)(int32_t num, int32_t den)
448
{
449
    if (den == 0)
450
      return 0;
451
    if (num == INT_MIN && den == -1)
452
      return INT_MIN;
453
    return num / den;
454
}
455

    
456
uint32_t HELPER(udiv)(uint32_t num, uint32_t den)
457
{
458
    if (den == 0)
459
      return 0;
460
    return num / den;
461
}
462

    
463
uint32_t HELPER(rbit)(uint32_t x)
464
{
465
    x =  ((x & 0xff000000) >> 24)
466
       | ((x & 0x00ff0000) >> 8)
467
       | ((x & 0x0000ff00) << 8)
468
       | ((x & 0x000000ff) << 24);
469
    x =  ((x & 0xf0f0f0f0) >> 4)
470
       | ((x & 0x0f0f0f0f) << 4);
471
    x =  ((x & 0x88888888) >> 3)
472
       | ((x & 0x44444444) >> 1)
473
       | ((x & 0x22222222) << 1)
474
       | ((x & 0x11111111) << 3);
475
    return x;
476
}
477

    
478
uint32_t HELPER(abs)(uint32_t x)
479
{
480
    return ((int32_t)x < 0) ? -x : x;
481
}
482

    
483
#if defined(CONFIG_USER_ONLY)
484

    
485
void do_interrupt (CPUState *env)
486
{
487
    env->exception_index = -1;
488
}
489

    
490
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
491
                              int mmu_idx, int is_softmmu)
492
{
493
    if (rw == 2) {
494
        env->exception_index = EXCP_PREFETCH_ABORT;
495
        env->cp15.c6_insn = address;
496
    } else {
497
        env->exception_index = EXCP_DATA_ABORT;
498
        env->cp15.c6_data = address;
499
    }
500
    return 1;
501
}
502

    
503
/* These should probably raise undefined insn exceptions.  */
504
void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
505
{
506
    int op1 = (insn >> 8) & 0xf;
507
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
508
    return;
509
}
510

    
511
uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
512
{
513
    int op1 = (insn >> 8) & 0xf;
514
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
515
    return 0;
516
}
517

    
518
void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
519
{
520
    cpu_abort(env, "cp15 insn %08x\n", insn);
521
}
522

    
523
uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
524
{
525
    cpu_abort(env, "cp15 insn %08x\n", insn);
526
}
527

    
528
/* These should probably raise undefined insn exceptions.  */
529
void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
530
{
531
    cpu_abort(env, "v7m_mrs %d\n", reg);
532
}
533

    
534
uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
535
{
536
    cpu_abort(env, "v7m_mrs %d\n", reg);
537
    return 0;
538
}
539

    
540
void switch_mode(CPUState *env, int mode)
541
{
542
    if (mode != ARM_CPU_MODE_USR)
543
        cpu_abort(env, "Tried to switch out of user mode\n");
544
}
545

    
546
void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
547
{
548
    cpu_abort(env, "banked r13 write\n");
549
}
550

    
551
uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
552
{
553
    cpu_abort(env, "banked r13 read\n");
554
    return 0;
555
}
556

    
557
#else
558

    
559
extern int semihosting_enabled;
560

    
561
/* Map CPU modes onto saved register banks.  */
562
static inline int bank_number (int mode)
563
{
564
    switch (mode) {
565
    case ARM_CPU_MODE_USR:
566
    case ARM_CPU_MODE_SYS:
567
        return 0;
568
    case ARM_CPU_MODE_SVC:
569
        return 1;
570
    case ARM_CPU_MODE_ABT:
571
        return 2;
572
    case ARM_CPU_MODE_UND:
573
        return 3;
574
    case ARM_CPU_MODE_IRQ:
575
        return 4;
576
    case ARM_CPU_MODE_FIQ:
577
        return 5;
578
    }
579
    cpu_abort(cpu_single_env, "Bad mode %x\n", mode);
580
    return -1;
581
}
582

    
583
void switch_mode(CPUState *env, int mode)
584
{
585
    int old_mode;
586
    int i;
587

    
588
    old_mode = env->uncached_cpsr & CPSR_M;
589
    if (mode == old_mode)
590
        return;
591

    
592
    if (old_mode == ARM_CPU_MODE_FIQ) {
593
        memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
594
        memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
595
    } else if (mode == ARM_CPU_MODE_FIQ) {
596
        memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
597
        memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
598
    }
599

    
600
    i = bank_number(old_mode);
601
    env->banked_r13[i] = env->regs[13];
602
    env->banked_r14[i] = env->regs[14];
603
    env->banked_spsr[i] = env->spsr;
604

    
605
    i = bank_number(mode);
606
    env->regs[13] = env->banked_r13[i];
607
    env->regs[14] = env->banked_r14[i];
608
    env->spsr = env->banked_spsr[i];
609
}
610

    
611
static void v7m_push(CPUARMState *env, uint32_t val)
612
{
613
    env->regs[13] -= 4;
614
    stl_phys(env->regs[13], val);
615
}
616

    
617
static uint32_t v7m_pop(CPUARMState *env)
618
{
619
    uint32_t val;
620
    val = ldl_phys(env->regs[13]);
621
    env->regs[13] += 4;
622
    return val;
623
}
624

    
625
/* Switch to V7M main or process stack pointer.  */
626
static void switch_v7m_sp(CPUARMState *env, int process)
627
{
628
    uint32_t tmp;
629
    if (env->v7m.current_sp != process) {
630
        tmp = env->v7m.other_sp;
631
        env->v7m.other_sp = env->regs[13];
632
        env->regs[13] = tmp;
633
        env->v7m.current_sp = process;
634
    }
635
}
636

    
637
static void do_v7m_exception_exit(CPUARMState *env)
638
{
639
    uint32_t type;
640
    uint32_t xpsr;
641

    
642
    type = env->regs[15];
643
    if (env->v7m.exception != 0)
644
        armv7m_nvic_complete_irq(env->nvic, env->v7m.exception);
645

    
646
    /* Switch to the target stack.  */
647
    switch_v7m_sp(env, (type & 4) != 0);
648
    /* Pop registers.  */
649
    env->regs[0] = v7m_pop(env);
650
    env->regs[1] = v7m_pop(env);
651
    env->regs[2] = v7m_pop(env);
652
    env->regs[3] = v7m_pop(env);
653
    env->regs[12] = v7m_pop(env);
654
    env->regs[14] = v7m_pop(env);
655
    env->regs[15] = v7m_pop(env);
656
    xpsr = v7m_pop(env);
657
    xpsr_write(env, xpsr, 0xfffffdff);
658
    /* Undo stack alignment.  */
659
    if (xpsr & 0x200)
660
        env->regs[13] |= 4;
661
    /* ??? The exception return type specifies Thread/Handler mode.  However
662
       this is also implied by the xPSR value. Not sure what to do
663
       if there is a mismatch.  */
664
    /* ??? Likewise for mismatches between the CONTROL register and the stack
665
       pointer.  */
666
}
667

    
668
static void do_interrupt_v7m(CPUARMState *env)
669
{
670
    uint32_t xpsr = xpsr_read(env);
671
    uint32_t lr;
672
    uint32_t addr;
673

    
674
    lr = 0xfffffff1;
675
    if (env->v7m.current_sp)
676
        lr |= 4;
677
    if (env->v7m.exception == 0)
678
        lr |= 8;
679

    
680
    /* For exceptions we just mark as pending on the NVIC, and let that
681
       handle it.  */
682
    /* TODO: Need to escalate if the current priority is higher than the
683
       one we're raising.  */
684
    switch (env->exception_index) {
685
    case EXCP_UDEF:
686
        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
687
        return;
688
    case EXCP_SWI:
689
        env->regs[15] += 2;
690
        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
691
        return;
692
    case EXCP_PREFETCH_ABORT:
693
    case EXCP_DATA_ABORT:
694
        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
695
        return;
696
    case EXCP_BKPT:
697
        if (semihosting_enabled) {
698
            int nr;
699
            nr = lduw_code(env->regs[15]) & 0xff;
700
            if (nr == 0xab) {
701
                env->regs[15] += 2;
702
                env->regs[0] = do_arm_semihosting(env);
703
                return;
704
            }
705
        }
706
        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG);
707
        return;
708
    case EXCP_IRQ:
709
        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->nvic);
710
        break;
711
    case EXCP_EXCEPTION_EXIT:
712
        do_v7m_exception_exit(env);
713
        return;
714
    default:
715
        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
716
        return; /* Never happens.  Keep compiler happy.  */
717
    }
718

    
719
    /* Align stack pointer.  */
720
    /* ??? Should only do this if Configuration Control Register
721
       STACKALIGN bit is set.  */
722
    if (env->regs[13] & 4) {
723
        env->regs[13] -= 4;
724
        xpsr |= 0x200;
725
    }
726
    /* Switch to the handler mode.  */
727
    v7m_push(env, xpsr);
728
    v7m_push(env, env->regs[15]);
729
    v7m_push(env, env->regs[14]);
730
    v7m_push(env, env->regs[12]);
731
    v7m_push(env, env->regs[3]);
732
    v7m_push(env, env->regs[2]);
733
    v7m_push(env, env->regs[1]);
734
    v7m_push(env, env->regs[0]);
735
    switch_v7m_sp(env, 0);
736
    env->uncached_cpsr &= ~CPSR_IT;
737
    env->regs[14] = lr;
738
    addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
739
    env->regs[15] = addr & 0xfffffffe;
740
    env->thumb = addr & 1;
741
}
742

    
743
/* Handle a CPU exception.  */
744
void do_interrupt(CPUARMState *env)
745
{
746
    uint32_t addr;
747
    uint32_t mask;
748
    int new_mode;
749
    uint32_t offset;
750

    
751
    if (IS_M(env)) {
752
        do_interrupt_v7m(env);
753
        return;
754
    }
755
    /* TODO: Vectored interrupt controller.  */
756
    switch (env->exception_index) {
757
    case EXCP_UDEF:
758
        new_mode = ARM_CPU_MODE_UND;
759
        addr = 0x04;
760
        mask = CPSR_I;
761
        if (env->thumb)
762
            offset = 2;
763
        else
764
            offset = 4;
765
        break;
766
    case EXCP_SWI:
767
        if (semihosting_enabled) {
768
            /* Check for semihosting interrupt.  */
769
            if (env->thumb) {
770
                mask = lduw_code(env->regs[15] - 2) & 0xff;
771
            } else {
772
                mask = ldl_code(env->regs[15] - 4) & 0xffffff;
773
            }
774
            /* Only intercept calls from privileged modes, to provide some
775
               semblance of security.  */
776
            if (((mask == 0x123456 && !env->thumb)
777
                    || (mask == 0xab && env->thumb))
778
                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
779
                env->regs[0] = do_arm_semihosting(env);
780
                return;
781
            }
782
        }
783
        new_mode = ARM_CPU_MODE_SVC;
784
        addr = 0x08;
785
        mask = CPSR_I;
786
        /* The PC already points to the next instruction.  */
787
        offset = 0;
788
        break;
789
    case EXCP_BKPT:
790
        /* See if this is a semihosting syscall.  */
791
        if (env->thumb && semihosting_enabled) {
792
            mask = lduw_code(env->regs[15]) & 0xff;
793
            if (mask == 0xab
794
                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
795
                env->regs[15] += 2;
796
                env->regs[0] = do_arm_semihosting(env);
797
                return;
798
            }
799
        }
800
        /* Fall through to prefetch abort.  */
801
    case EXCP_PREFETCH_ABORT:
802
        new_mode = ARM_CPU_MODE_ABT;
803
        addr = 0x0c;
804
        mask = CPSR_A | CPSR_I;
805
        offset = 4;
806
        break;
807
    case EXCP_DATA_ABORT:
808
        new_mode = ARM_CPU_MODE_ABT;
809
        addr = 0x10;
810
        mask = CPSR_A | CPSR_I;
811
        offset = 8;
812
        break;
813
    case EXCP_IRQ:
814
        new_mode = ARM_CPU_MODE_IRQ;
815
        addr = 0x18;
816
        /* Disable IRQ and imprecise data aborts.  */
817
        mask = CPSR_A | CPSR_I;
818
        offset = 4;
819
        break;
820
    case EXCP_FIQ:
821
        new_mode = ARM_CPU_MODE_FIQ;
822
        addr = 0x1c;
823
        /* Disable FIQ, IRQ and imprecise data aborts.  */
824
        mask = CPSR_A | CPSR_I | CPSR_F;
825
        offset = 4;
826
        break;
827
    default:
828
        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
829
        return; /* Never happens.  Keep compiler happy.  */
830
    }
831
    /* High vectors.  */
832
    if (env->cp15.c1_sys & (1 << 13)) {
833
        addr += 0xffff0000;
834
    }
835
    switch_mode (env, new_mode);
836
    env->spsr = cpsr_read(env);
837
    /* Clear IT bits.  */
838
    env->condexec_bits = 0;
839
    /* Switch to the new mode, and to the correct instruction set.  */
840
    env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
841
    env->uncached_cpsr |= mask;
842
    env->thumb = (env->cp15.c1_sys & (1 << 30)) != 0;
843
    env->regs[14] = env->regs[15] + offset;
844
    env->regs[15] = addr;
845
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
846
}
847

    
848
/* Check section/page access permissions.
849
   Returns the page protection flags, or zero if the access is not
850
   permitted.  */
851
static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
852
                           int is_user)
853
{
854
  int prot_ro;
855

    
856
  if (domain == 3)
857
    return PAGE_READ | PAGE_WRITE;
858

    
859
  if (access_type == 1)
860
      prot_ro = 0;
861
  else
862
      prot_ro = PAGE_READ;
863

    
864
  switch (ap) {
865
  case 0:
866
      if (access_type == 1)
867
          return 0;
868
      switch ((env->cp15.c1_sys >> 8) & 3) {
869
      case 1:
870
          return is_user ? 0 : PAGE_READ;
871
      case 2:
872
          return PAGE_READ;
873
      default:
874
          return 0;
875
      }
876
  case 1:
877
      return is_user ? 0 : PAGE_READ | PAGE_WRITE;
878
  case 2:
879
      if (is_user)
880
          return prot_ro;
881
      else
882
          return PAGE_READ | PAGE_WRITE;
883
  case 3:
884
      return PAGE_READ | PAGE_WRITE;
885
  case 4: /* Reserved.  */
886
      return 0;
887
  case 5:
888
      return is_user ? 0 : prot_ro;
889
  case 6:
890
      return prot_ro;
891
  case 7:
892
      if (!arm_feature (env, ARM_FEATURE_V7))
893
          return 0;
894
      return prot_ro;
895
  default:
896
      abort();
897
  }
898
}
899

    
900
static uint32_t get_level1_table_address(CPUState *env, uint32_t address)
901
{
902
    uint32_t table;
903

    
904
    if (address & env->cp15.c2_mask)
905
        table = env->cp15.c2_base1 & 0xffffc000;
906
    else
907
        table = env->cp15.c2_base0 & env->cp15.c2_base_mask;
908

    
909
    table |= (address >> 18) & 0x3ffc;
910
    return table;
911
}
912

    
913
static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
914
                            int is_user, uint32_t *phys_ptr, int *prot,
915
                            target_ulong *page_size)
916
{
917
    int code;
918
    uint32_t table;
919
    uint32_t desc;
920
    int type;
921
    int ap;
922
    int domain;
923
    uint32_t phys_addr;
924

    
925
    /* Pagetable walk.  */
926
    /* Lookup l1 descriptor.  */
927
    table = get_level1_table_address(env, address);
928
    desc = ldl_phys(table);
929
    type = (desc & 3);
930
    domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
931
    if (type == 0) {
932
        /* Section translation fault.  */
933
        code = 5;
934
        goto do_fault;
935
    }
936
    if (domain == 0 || domain == 2) {
937
        if (type == 2)
938
            code = 9; /* Section domain fault.  */
939
        else
940
            code = 11; /* Page domain fault.  */
941
        goto do_fault;
942
    }
943
    if (type == 2) {
944
        /* 1Mb section.  */
945
        phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
946
        ap = (desc >> 10) & 3;
947
        code = 13;
948
        *page_size = 1024 * 1024;
949
    } else {
950
        /* Lookup l2 entry.  */
951
        if (type == 1) {
952
            /* Coarse pagetable.  */
953
            table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
954
        } else {
955
            /* Fine pagetable.  */
956
            table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
957
        }
958
        desc = ldl_phys(table);
959
        switch (desc & 3) {
960
        case 0: /* Page translation fault.  */
961
            code = 7;
962
            goto do_fault;
963
        case 1: /* 64k page.  */
964
            phys_addr = (desc & 0xffff0000) | (address & 0xffff);
965
            ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
966
            *page_size = 0x10000;
967
            break;
968
        case 2: /* 4k page.  */
969
            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
970
            ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
971
            *page_size = 0x1000;
972
            break;
973
        case 3: /* 1k page.  */
974
            if (type == 1) {
975
                if (arm_feature(env, ARM_FEATURE_XSCALE)) {
976
                    phys_addr = (desc & 0xfffff000) | (address & 0xfff);
977
                } else {
978
                    /* Page translation fault.  */
979
                    code = 7;
980
                    goto do_fault;
981
                }
982
            } else {
983
                phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
984
            }
985
            ap = (desc >> 4) & 3;
986
            *page_size = 0x400;
987
            break;
988
        default:
989
            /* Never happens, but compiler isn't smart enough to tell.  */
990
            abort();
991
        }
992
        code = 15;
993
    }
994
    *prot = check_ap(env, ap, domain, access_type, is_user);
995
    if (!*prot) {
996
        /* Access permission fault.  */
997
        goto do_fault;
998
    }
999
    *prot |= PAGE_EXEC;
1000
    *phys_ptr = phys_addr;
1001
    return 0;
1002
do_fault:
1003
    return code | (domain << 4);
1004
}
1005

    
1006
static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
1007
                            int is_user, uint32_t *phys_ptr, int *prot,
1008
                            target_ulong *page_size)
1009
{
1010
    int code;
1011
    uint32_t table;
1012
    uint32_t desc;
1013
    uint32_t xn;
1014
    int type;
1015
    int ap;
1016
    int domain;
1017
    uint32_t phys_addr;
1018

    
1019
    /* Pagetable walk.  */
1020
    /* Lookup l1 descriptor.  */
1021
    table = get_level1_table_address(env, address);
1022
    desc = ldl_phys(table);
1023
    type = (desc & 3);
1024
    if (type == 0) {
1025
        /* Section translation fault.  */
1026
        code = 5;
1027
        domain = 0;
1028
        goto do_fault;
1029
    } else if (type == 2 && (desc & (1 << 18))) {
1030
        /* Supersection.  */
1031
        domain = 0;
1032
    } else {
1033
        /* Section or page.  */
1034
        domain = (desc >> 4) & 0x1e;
1035
    }
1036
    domain = (env->cp15.c3 >> domain) & 3;
1037
    if (domain == 0 || domain == 2) {
1038
        if (type == 2)
1039
            code = 9; /* Section domain fault.  */
1040
        else
1041
            code = 11; /* Page domain fault.  */
1042
        goto do_fault;
1043
    }
1044
    if (type == 2) {
1045
        if (desc & (1 << 18)) {
1046
            /* Supersection.  */
1047
            phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
1048
            *page_size = 0x1000000;
1049
        } else {
1050
            /* Section.  */
1051
            phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
1052
            *page_size = 0x100000;
1053
        }
1054
        ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
1055
        xn = desc & (1 << 4);
1056
        code = 13;
1057
    } else {
1058
        /* Lookup l2 entry.  */
1059
        table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
1060
        desc = ldl_phys(table);
1061
        ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
1062
        switch (desc & 3) {
1063
        case 0: /* Page translation fault.  */
1064
            code = 7;
1065
            goto do_fault;
1066
        case 1: /* 64k page.  */
1067
            phys_addr = (desc & 0xffff0000) | (address & 0xffff);
1068
            xn = desc & (1 << 15);
1069
            *page_size = 0x10000;
1070
            break;
1071
        case 2: case 3: /* 4k page.  */
1072
            phys_addr = (desc & 0xfffff000) | (address & 0xfff);
1073
            xn = desc & 1;
1074
            *page_size = 0x1000;
1075
            break;
1076
        default:
1077
            /* Never happens, but compiler isn't smart enough to tell.  */
1078
            abort();
1079
        }
1080
        code = 15;
1081
    }
1082
    if (xn && access_type == 2)
1083
        goto do_fault;
1084

    
1085
    /* The simplified model uses AP[0] as an access control bit.  */
1086
    if ((env->cp15.c1_sys & (1 << 29)) && (ap & 1) == 0) {
1087
        /* Access flag fault.  */
1088
        code = (code == 15) ? 6 : 3;
1089
        goto do_fault;
1090
    }
1091
    *prot = check_ap(env, ap, domain, access_type, is_user);
1092
    if (!*prot) {
1093
        /* Access permission fault.  */
1094
        goto do_fault;
1095
    }
1096
    if (!xn) {
1097
        *prot |= PAGE_EXEC;
1098
    }
1099
    *phys_ptr = phys_addr;
1100
    return 0;
1101
do_fault:
1102
    return code | (domain << 4);
1103
}
1104

    
1105
static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
1106
                             int is_user, uint32_t *phys_ptr, int *prot)
1107
{
1108
    int n;
1109
    uint32_t mask;
1110
    uint32_t base;
1111

    
1112
    *phys_ptr = address;
1113
    for (n = 7; n >= 0; n--) {
1114
        base = env->cp15.c6_region[n];
1115
        if ((base & 1) == 0)
1116
            continue;
1117
        mask = 1 << ((base >> 1) & 0x1f);
1118
        /* Keep this shift separate from the above to avoid an
1119
           (undefined) << 32.  */
1120
        mask = (mask << 1) - 1;
1121
        if (((base ^ address) & ~mask) == 0)
1122
            break;
1123
    }
1124
    if (n < 0)
1125
        return 2;
1126

    
1127
    if (access_type == 2) {
1128
        mask = env->cp15.c5_insn;
1129
    } else {
1130
        mask = env->cp15.c5_data;
1131
    }
1132
    mask = (mask >> (n * 4)) & 0xf;
1133
    switch (mask) {
1134
    case 0:
1135
        return 1;
1136
    case 1:
1137
        if (is_user)
1138
          return 1;
1139
        *prot = PAGE_READ | PAGE_WRITE;
1140
        break;
1141
    case 2:
1142
        *prot = PAGE_READ;
1143
        if (!is_user)
1144
            *prot |= PAGE_WRITE;
1145
        break;
1146
    case 3:
1147
        *prot = PAGE_READ | PAGE_WRITE;
1148
        break;
1149
    case 5:
1150
        if (is_user)
1151
            return 1;
1152
        *prot = PAGE_READ;
1153
        break;
1154
    case 6:
1155
        *prot = PAGE_READ;
1156
        break;
1157
    default:
1158
        /* Bad permission.  */
1159
        return 1;
1160
    }
1161
    *prot |= PAGE_EXEC;
1162
    return 0;
1163
}
1164

    
1165
static inline int get_phys_addr(CPUState *env, uint32_t address,
1166
                                int access_type, int is_user,
1167
                                uint32_t *phys_ptr, int *prot,
1168
                                target_ulong *page_size)
1169
{
1170
    /* Fast Context Switch Extension.  */
1171
    if (address < 0x02000000)
1172
        address += env->cp15.c13_fcse;
1173

    
1174
    if ((env->cp15.c1_sys & 1) == 0) {
1175
        /* MMU/MPU disabled.  */
1176
        *phys_ptr = address;
1177
        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1178
        *page_size = TARGET_PAGE_SIZE;
1179
        return 0;
1180
    } else if (arm_feature(env, ARM_FEATURE_MPU)) {
1181
        *page_size = TARGET_PAGE_SIZE;
1182
        return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,
1183
                                 prot);
1184
    } else if (env->cp15.c1_sys & (1 << 23)) {
1185
        return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
1186
                                prot, page_size);
1187
    } else {
1188
        return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,
1189
                                prot, page_size);
1190
    }
1191
}
1192

    
1193
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
1194
                              int access_type, int mmu_idx, int is_softmmu)
1195
{
1196
    uint32_t phys_addr;
1197
    target_ulong page_size;
1198
    int prot;
1199
    int ret, is_user;
1200

    
1201
    is_user = mmu_idx == MMU_USER_IDX;
1202
    ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot,
1203
                        &page_size);
1204
    if (ret == 0) {
1205
        /* Map a single [sub]page.  */
1206
        phys_addr &= ~(uint32_t)0x3ff;
1207
        address &= ~(uint32_t)0x3ff;
1208
        tlb_set_page (env, address, phys_addr, prot, mmu_idx, page_size);
1209
        return 0;
1210
    }
1211

    
1212
    if (access_type == 2) {
1213
        env->cp15.c5_insn = ret;
1214
        env->cp15.c6_insn = address;
1215
        env->exception_index = EXCP_PREFETCH_ABORT;
1216
    } else {
1217
        env->cp15.c5_data = ret;
1218
        if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
1219
            env->cp15.c5_data |= (1 << 11);
1220
        env->cp15.c6_data = address;
1221
        env->exception_index = EXCP_DATA_ABORT;
1222
    }
1223
    return 1;
1224
}
1225

    
1226
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1227
{
1228
    uint32_t phys_addr;
1229
    target_ulong page_size;
1230
    int prot;
1231
    int ret;
1232

    
1233
    ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot, &page_size);
1234

    
1235
    if (ret != 0)
1236
        return -1;
1237

    
1238
    return phys_addr;
1239
}
1240

    
1241
void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
1242
{
1243
    int cp_num = (insn >> 8) & 0xf;
1244
    int cp_info = (insn >> 5) & 7;
1245
    int src = (insn >> 16) & 0xf;
1246
    int operand = insn & 0xf;
1247

    
1248
    if (env->cp[cp_num].cp_write)
1249
        env->cp[cp_num].cp_write(env->cp[cp_num].opaque,
1250
                                 cp_info, src, operand, val);
1251
}
1252

    
1253
uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
1254
{
1255
    int cp_num = (insn >> 8) & 0xf;
1256
    int cp_info = (insn >> 5) & 7;
1257
    int dest = (insn >> 16) & 0xf;
1258
    int operand = insn & 0xf;
1259

    
1260
    if (env->cp[cp_num].cp_read)
1261
        return env->cp[cp_num].cp_read(env->cp[cp_num].opaque,
1262
                                       cp_info, dest, operand);
1263
    return 0;
1264
}
1265

    
1266
/* Return basic MPU access permission bits.  */
1267
static uint32_t simple_mpu_ap_bits(uint32_t val)
1268
{
1269
    uint32_t ret;
1270
    uint32_t mask;
1271
    int i;
1272
    ret = 0;
1273
    mask = 3;
1274
    for (i = 0; i < 16; i += 2) {
1275
        ret |= (val >> i) & mask;
1276
        mask <<= 2;
1277
    }
1278
    return ret;
1279
}
1280

    
1281
/* Pad basic MPU access permission bits to extended format.  */
1282
static uint32_t extended_mpu_ap_bits(uint32_t val)
1283
{
1284
    uint32_t ret;
1285
    uint32_t mask;
1286
    int i;
1287
    ret = 0;
1288
    mask = 3;
1289
    for (i = 0; i < 16; i += 2) {
1290
        ret |= (val & mask) << i;
1291
        mask <<= 2;
1292
    }
1293
    return ret;
1294
}
1295

    
1296
void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
1297
{
1298
    int op1;
1299
    int op2;
1300
    int crm;
1301

    
1302
    op1 = (insn >> 21) & 7;
1303
    op2 = (insn >> 5) & 7;
1304
    crm = insn & 0xf;
1305
    switch ((insn >> 16) & 0xf) {
1306
    case 0:
1307
        /* ID codes.  */
1308
        if (arm_feature(env, ARM_FEATURE_XSCALE))
1309
            break;
1310
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1311
            break;
1312
        if (arm_feature(env, ARM_FEATURE_V7)
1313
                && op1 == 2 && crm == 0 && op2 == 0) {
1314
            env->cp15.c0_cssel = val & 0xf;
1315
            break;
1316
        }
1317
        goto bad_reg;
1318
    case 1: /* System configuration.  */
1319
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1320
            op2 = 0;
1321
        switch (op2) {
1322
        case 0:
1323
            if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
1324
                env->cp15.c1_sys = val;
1325
            /* ??? Lots of these bits are not implemented.  */
1326
            /* This may enable/disable the MMU, so do a TLB flush.  */
1327
            tlb_flush(env, 1);
1328
            break;
1329
        case 1: /* Auxiliary cotrol register.  */
1330
            if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1331
                env->cp15.c1_xscaleauxcr = val;
1332
                break;
1333
            }
1334
            /* Not implemented.  */
1335
            break;
1336
        case 2:
1337
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1338
                goto bad_reg;
1339
            if (env->cp15.c1_coproc != val) {
1340
                env->cp15.c1_coproc = val;
1341
                /* ??? Is this safe when called from within a TB?  */
1342
                tb_flush(env);
1343
            }
1344
            break;
1345
        default:
1346
            goto bad_reg;
1347
        }
1348
        break;
1349
    case 2: /* MMU Page table control / MPU cache control.  */
1350
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1351
            switch (op2) {
1352
            case 0:
1353
                env->cp15.c2_data = val;
1354
                break;
1355
            case 1:
1356
                env->cp15.c2_insn = val;
1357
                break;
1358
            default:
1359
                goto bad_reg;
1360
            }
1361
        } else {
1362
            switch (op2) {
1363
            case 0:
1364
                env->cp15.c2_base0 = val;
1365
                break;
1366
            case 1:
1367
                env->cp15.c2_base1 = val;
1368
                break;
1369
            case 2:
1370
                val &= 7;
1371
                env->cp15.c2_control = val;
1372
                env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
1373
                env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val);
1374
                break;
1375
            default:
1376
                goto bad_reg;
1377
            }
1378
        }
1379
        break;
1380
    case 3: /* MMU Domain access control / MPU write buffer control.  */
1381
        env->cp15.c3 = val;
1382
        tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
1383
        break;
1384
    case 4: /* Reserved.  */
1385
        goto bad_reg;
1386
    case 5: /* MMU Fault status / MPU access permission.  */
1387
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1388
            op2 = 0;
1389
        switch (op2) {
1390
        case 0:
1391
            if (arm_feature(env, ARM_FEATURE_MPU))
1392
                val = extended_mpu_ap_bits(val);
1393
            env->cp15.c5_data = val;
1394
            break;
1395
        case 1:
1396
            if (arm_feature(env, ARM_FEATURE_MPU))
1397
                val = extended_mpu_ap_bits(val);
1398
            env->cp15.c5_insn = val;
1399
            break;
1400
        case 2:
1401
            if (!arm_feature(env, ARM_FEATURE_MPU))
1402
                goto bad_reg;
1403
            env->cp15.c5_data = val;
1404
            break;
1405
        case 3:
1406
            if (!arm_feature(env, ARM_FEATURE_MPU))
1407
                goto bad_reg;
1408
            env->cp15.c5_insn = val;
1409
            break;
1410
        default:
1411
            goto bad_reg;
1412
        }
1413
        break;
1414
    case 6: /* MMU Fault address / MPU base/size.  */
1415
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1416
            if (crm >= 8)
1417
                goto bad_reg;
1418
            env->cp15.c6_region[crm] = val;
1419
        } else {
1420
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1421
                op2 = 0;
1422
            switch (op2) {
1423
            case 0:
1424
                env->cp15.c6_data = val;
1425
                break;
1426
            case 1: /* ??? This is WFAR on armv6 */
1427
            case 2:
1428
                env->cp15.c6_insn = val;
1429
                break;
1430
            default:
1431
                goto bad_reg;
1432
            }
1433
        }
1434
        break;
1435
    case 7: /* Cache control.  */
1436
        env->cp15.c15_i_max = 0x000;
1437
        env->cp15.c15_i_min = 0xff0;
1438
        /* No cache, so nothing to do.  */
1439
        /* ??? MPCore has VA to PA translation functions.  */
1440
        break;
1441
    case 8: /* MMU TLB control.  */
1442
        switch (op2) {
1443
        case 0: /* Invalidate all.  */
1444
            tlb_flush(env, 0);
1445
            break;
1446
        case 1: /* Invalidate single TLB entry.  */
1447
            tlb_flush_page(env, val & TARGET_PAGE_MASK);
1448
            break;
1449
        case 2: /* Invalidate on ASID.  */
1450
            tlb_flush(env, val == 0);
1451
            break;
1452
        case 3: /* Invalidate single entry on MVA.  */
1453
            /* ??? This is like case 1, but ignores ASID.  */
1454
            tlb_flush(env, 1);
1455
            break;
1456
        default:
1457
            goto bad_reg;
1458
        }
1459
        break;
1460
    case 9:
1461
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1462
            break;
1463
        switch (crm) {
1464
        case 0: /* Cache lockdown.  */
1465
            switch (op1) {
1466
            case 0: /* L1 cache.  */
1467
                switch (op2) {
1468
                case 0:
1469
                    env->cp15.c9_data = val;
1470
                    break;
1471
                case 1:
1472
                    env->cp15.c9_insn = val;
1473
                    break;
1474
                default:
1475
                    goto bad_reg;
1476
                }
1477
                break;
1478
            case 1: /* L2 cache.  */
1479
                /* Ignore writes to L2 lockdown/auxiliary registers.  */
1480
                break;
1481
            default:
1482
                goto bad_reg;
1483
            }
1484
            break;
1485
        case 1: /* TCM memory region registers.  */
1486
            /* Not implemented.  */
1487
            goto bad_reg;
1488
        default:
1489
            goto bad_reg;
1490
        }
1491
        break;
1492
    case 10: /* MMU TLB lockdown.  */
1493
        /* ??? TLB lockdown not implemented.  */
1494
        break;
1495
    case 12: /* Reserved.  */
1496
        goto bad_reg;
1497
    case 13: /* Process ID.  */
1498
        switch (op2) {
1499
        case 0:
1500
            /* Unlike real hardware the qemu TLB uses virtual addresses,
1501
               not modified virtual addresses, so this causes a TLB flush.
1502
             */
1503
            if (env->cp15.c13_fcse != val)
1504
              tlb_flush(env, 1);
1505
            env->cp15.c13_fcse = val;
1506
            break;
1507
        case 1:
1508
            /* This changes the ASID, so do a TLB flush.  */
1509
            if (env->cp15.c13_context != val
1510
                && !arm_feature(env, ARM_FEATURE_MPU))
1511
              tlb_flush(env, 0);
1512
            env->cp15.c13_context = val;
1513
            break;
1514
        default:
1515
            goto bad_reg;
1516
        }
1517
        break;
1518
    case 14: /* Reserved.  */
1519
        goto bad_reg;
1520
    case 15: /* Implementation specific.  */
1521
        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1522
            if (op2 == 0 && crm == 1) {
1523
                if (env->cp15.c15_cpar != (val & 0x3fff)) {
1524
                    /* Changes cp0 to cp13 behavior, so needs a TB flush.  */
1525
                    tb_flush(env);
1526
                    env->cp15.c15_cpar = val & 0x3fff;
1527
                }
1528
                break;
1529
            }
1530
            goto bad_reg;
1531
        }
1532
        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1533
            switch (crm) {
1534
            case 0:
1535
                break;
1536
            case 1: /* Set TI925T configuration.  */
1537
                env->cp15.c15_ticonfig = val & 0xe7;
1538
                env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */
1539
                        ARM_CPUID_TI915T : ARM_CPUID_TI925T;
1540
                break;
1541
            case 2: /* Set I_max.  */
1542
                env->cp15.c15_i_max = val;
1543
                break;
1544
            case 3: /* Set I_min.  */
1545
                env->cp15.c15_i_min = val;
1546
                break;
1547
            case 4: /* Set thread-ID.  */
1548
                env->cp15.c15_threadid = val & 0xffff;
1549
                break;
1550
            case 8: /* Wait-for-interrupt (deprecated).  */
1551
                cpu_interrupt(env, CPU_INTERRUPT_HALT);
1552
                break;
1553
            default:
1554
                goto bad_reg;
1555
            }
1556
        }
1557
        break;
1558
    }
1559
    return;
1560
bad_reg:
1561
    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1562
    cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",
1563
              (insn >> 16) & 0xf, crm, op1, op2);
1564
}
1565

    
1566
uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
1567
{
1568
    int op1;
1569
    int op2;
1570
    int crm;
1571

    
1572
    op1 = (insn >> 21) & 7;
1573
    op2 = (insn >> 5) & 7;
1574
    crm = insn & 0xf;
1575
    switch ((insn >> 16) & 0xf) {
1576
    case 0: /* ID codes.  */
1577
        switch (op1) {
1578
        case 0:
1579
            switch (crm) {
1580
            case 0:
1581
                switch (op2) {
1582
                case 0: /* Device ID.  */
1583
                    return env->cp15.c0_cpuid;
1584
                case 1: /* Cache Type.  */
1585
                    return env->cp15.c0_cachetype;
1586
                case 2: /* TCM status.  */
1587
                    return 0;
1588
                case 3: /* TLB type register.  */
1589
                    return 0; /* No lockable TLB entries.  */
1590
                case 5: /* CPU ID */
1591
                    if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
1592
                        return env->cpu_index | 0x80000900;
1593
                    } else {
1594
                        return env->cpu_index;
1595
                    }
1596
                default:
1597
                    goto bad_reg;
1598
                }
1599
            case 1:
1600
                if (!arm_feature(env, ARM_FEATURE_V6))
1601
                    goto bad_reg;
1602
                return env->cp15.c0_c1[op2];
1603
            case 2:
1604
                if (!arm_feature(env, ARM_FEATURE_V6))
1605
                    goto bad_reg;
1606
                return env->cp15.c0_c2[op2];
1607
            case 3: case 4: case 5: case 6: case 7:
1608
                return 0;
1609
            default:
1610
                goto bad_reg;
1611
            }
1612
        case 1:
1613
            /* These registers aren't documented on arm11 cores.  However
1614
               Linux looks at them anyway.  */
1615
            if (!arm_feature(env, ARM_FEATURE_V6))
1616
                goto bad_reg;
1617
            if (crm != 0)
1618
                goto bad_reg;
1619
            if (!arm_feature(env, ARM_FEATURE_V7))
1620
                return 0;
1621

    
1622
            switch (op2) {
1623
            case 0:
1624
                return env->cp15.c0_ccsid[env->cp15.c0_cssel];
1625
            case 1:
1626
                return env->cp15.c0_clid;
1627
            case 7:
1628
                return 0;
1629
            }
1630
            goto bad_reg;
1631
        case 2:
1632
            if (op2 != 0 || crm != 0)
1633
                goto bad_reg;
1634
            return env->cp15.c0_cssel;
1635
        default:
1636
            goto bad_reg;
1637
        }
1638
    case 1: /* System configuration.  */
1639
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1640
            op2 = 0;
1641
        switch (op2) {
1642
        case 0: /* Control register.  */
1643
            return env->cp15.c1_sys;
1644
        case 1: /* Auxiliary control register.  */
1645
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1646
                return env->cp15.c1_xscaleauxcr;
1647
            if (!arm_feature(env, ARM_FEATURE_AUXCR))
1648
                goto bad_reg;
1649
            switch (ARM_CPUID(env)) {
1650
            case ARM_CPUID_ARM1026:
1651
                return 1;
1652
            case ARM_CPUID_ARM1136:
1653
            case ARM_CPUID_ARM1136_R2:
1654
                return 7;
1655
            case ARM_CPUID_ARM11MPCORE:
1656
                return 1;
1657
            case ARM_CPUID_CORTEXA8:
1658
                return 2;
1659
            case ARM_CPUID_CORTEXA9:
1660
                return 0;
1661
            default:
1662
                goto bad_reg;
1663
            }
1664
        case 2: /* Coprocessor access register.  */
1665
            if (arm_feature(env, ARM_FEATURE_XSCALE))
1666
                goto bad_reg;
1667
            return env->cp15.c1_coproc;
1668
        default:
1669
            goto bad_reg;
1670
        }
1671
    case 2: /* MMU Page table control / MPU cache control.  */
1672
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1673
            switch (op2) {
1674
            case 0:
1675
                return env->cp15.c2_data;
1676
                break;
1677
            case 1:
1678
                return env->cp15.c2_insn;
1679
                break;
1680
            default:
1681
                goto bad_reg;
1682
            }
1683
        } else {
1684
            switch (op2) {
1685
            case 0:
1686
                return env->cp15.c2_base0;
1687
            case 1:
1688
                return env->cp15.c2_base1;
1689
            case 2:
1690
                return env->cp15.c2_control;
1691
            default:
1692
                goto bad_reg;
1693
            }
1694
        }
1695
    case 3: /* MMU Domain access control / MPU write buffer control.  */
1696
        return env->cp15.c3;
1697
    case 4: /* Reserved.  */
1698
        goto bad_reg;
1699
    case 5: /* MMU Fault status / MPU access permission.  */
1700
        if (arm_feature(env, ARM_FEATURE_OMAPCP))
1701
            op2 = 0;
1702
        switch (op2) {
1703
        case 0:
1704
            if (arm_feature(env, ARM_FEATURE_MPU))
1705
                return simple_mpu_ap_bits(env->cp15.c5_data);
1706
            return env->cp15.c5_data;
1707
        case 1:
1708
            if (arm_feature(env, ARM_FEATURE_MPU))
1709
                return simple_mpu_ap_bits(env->cp15.c5_data);
1710
            return env->cp15.c5_insn;
1711
        case 2:
1712
            if (!arm_feature(env, ARM_FEATURE_MPU))
1713
                goto bad_reg;
1714
            return env->cp15.c5_data;
1715
        case 3:
1716
            if (!arm_feature(env, ARM_FEATURE_MPU))
1717
                goto bad_reg;
1718
            return env->cp15.c5_insn;
1719
        default:
1720
            goto bad_reg;
1721
        }
1722
    case 6: /* MMU Fault address.  */
1723
        if (arm_feature(env, ARM_FEATURE_MPU)) {
1724
            if (crm >= 8)
1725
                goto bad_reg;
1726
            return env->cp15.c6_region[crm];
1727
        } else {
1728
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1729
                op2 = 0;
1730
            switch (op2) {
1731
            case 0:
1732
                return env->cp15.c6_data;
1733
            case 1:
1734
                if (arm_feature(env, ARM_FEATURE_V6)) {
1735
                    /* Watchpoint Fault Adrress.  */
1736
                    return 0; /* Not implemented.  */
1737
                } else {
1738
                    /* Instruction Fault Adrress.  */
1739
                    /* Arm9 doesn't have an IFAR, but implementing it anyway
1740
                       shouldn't do any harm.  */
1741
                    return env->cp15.c6_insn;
1742
                }
1743
            case 2:
1744
                if (arm_feature(env, ARM_FEATURE_V6)) {
1745
                    /* Instruction Fault Adrress.  */
1746
                    return env->cp15.c6_insn;
1747
                } else {
1748
                    goto bad_reg;
1749
                }
1750
            default:
1751
                goto bad_reg;
1752
            }
1753
        }
1754
    case 7: /* Cache control.  */
1755
        /* FIXME: Should only clear Z flag if destination is r15.  */
1756
        env->ZF = 0;
1757
        return 0;
1758
    case 8: /* MMU TLB control.  */
1759
        goto bad_reg;
1760
    case 9: /* Cache lockdown.  */
1761
        switch (op1) {
1762
        case 0: /* L1 cache.  */
1763
            if (arm_feature(env, ARM_FEATURE_OMAPCP))
1764
                return 0;
1765
            switch (op2) {
1766
            case 0:
1767
                return env->cp15.c9_data;
1768
            case 1:
1769
                return env->cp15.c9_insn;
1770
            default:
1771
                goto bad_reg;
1772
            }
1773
        case 1: /* L2 cache */
1774
            if (crm != 0)
1775
                goto bad_reg;
1776
            /* L2 Lockdown and Auxiliary control.  */
1777
            return 0;
1778
        default:
1779
            goto bad_reg;
1780
        }
1781
    case 10: /* MMU TLB lockdown.  */
1782
        /* ??? TLB lockdown not implemented.  */
1783
        return 0;
1784
    case 11: /* TCM DMA control.  */
1785
    case 12: /* Reserved.  */
1786
        goto bad_reg;
1787
    case 13: /* Process ID.  */
1788
        switch (op2) {
1789
        case 0:
1790
            return env->cp15.c13_fcse;
1791
        case 1:
1792
            return env->cp15.c13_context;
1793
        default:
1794
            goto bad_reg;
1795
        }
1796
    case 14: /* Reserved.  */
1797
        goto bad_reg;
1798
    case 15: /* Implementation specific.  */
1799
        if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1800
            if (op2 == 0 && crm == 1)
1801
                return env->cp15.c15_cpar;
1802

    
1803
            goto bad_reg;
1804
        }
1805
        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1806
            switch (crm) {
1807
            case 0:
1808
                return 0;
1809
            case 1: /* Read TI925T configuration.  */
1810
                return env->cp15.c15_ticonfig;
1811
            case 2: /* Read I_max.  */
1812
                return env->cp15.c15_i_max;
1813
            case 3: /* Read I_min.  */
1814
                return env->cp15.c15_i_min;
1815
            case 4: /* Read thread-ID.  */
1816
                return env->cp15.c15_threadid;
1817
            case 8: /* TI925T_status */
1818
                return 0;
1819
            }
1820
            /* TODO: Peripheral port remap register:
1821
             * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt
1822
             * controller base address at $rn & ~0xfff and map size of
1823
             * 0x200 << ($rn & 0xfff), when MMU is off.  */
1824
            goto bad_reg;
1825
        }
1826
        return 0;
1827
    }
1828
bad_reg:
1829
    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1830
    cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
1831
              (insn >> 16) & 0xf, crm, op1, op2);
1832
    return 0;
1833
}
1834

    
1835
void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
1836
{
1837
    env->banked_r13[bank_number(mode)] = val;
1838
}
1839

    
1840
uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
1841
{
1842
    return env->banked_r13[bank_number(mode)];
1843
}
1844

    
1845
uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
1846
{
1847
    switch (reg) {
1848
    case 0: /* APSR */
1849
        return xpsr_read(env) & 0xf8000000;
1850
    case 1: /* IAPSR */
1851
        return xpsr_read(env) & 0xf80001ff;
1852
    case 2: /* EAPSR */
1853
        return xpsr_read(env) & 0xff00fc00;
1854
    case 3: /* xPSR */
1855
        return xpsr_read(env) & 0xff00fdff;
1856
    case 5: /* IPSR */
1857
        return xpsr_read(env) & 0x000001ff;
1858
    case 6: /* EPSR */
1859
        return xpsr_read(env) & 0x0700fc00;
1860
    case 7: /* IEPSR */
1861
        return xpsr_read(env) & 0x0700edff;
1862
    case 8: /* MSP */
1863
        return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13];
1864
    case 9: /* PSP */
1865
        return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp;
1866
    case 16: /* PRIMASK */
1867
        return (env->uncached_cpsr & CPSR_I) != 0;
1868
    case 17: /* FAULTMASK */
1869
        return (env->uncached_cpsr & CPSR_F) != 0;
1870
    case 18: /* BASEPRI */
1871
    case 19: /* BASEPRI_MAX */
1872
        return env->v7m.basepri;
1873
    case 20: /* CONTROL */
1874
        return env->v7m.control;
1875
    default:
1876
        /* ??? For debugging only.  */
1877
        cpu_abort(env, "Unimplemented system register read (%d)\n", reg);
1878
        return 0;
1879
    }
1880
}
1881

    
1882
void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
1883
{
1884
    switch (reg) {
1885
    case 0: /* APSR */
1886
        xpsr_write(env, val, 0xf8000000);
1887
        break;
1888
    case 1: /* IAPSR */
1889
        xpsr_write(env, val, 0xf8000000);
1890
        break;
1891
    case 2: /* EAPSR */
1892
        xpsr_write(env, val, 0xfe00fc00);
1893
        break;
1894
    case 3: /* xPSR */
1895
        xpsr_write(env, val, 0xfe00fc00);
1896
        break;
1897
    case 5: /* IPSR */
1898
        /* IPSR bits are readonly.  */
1899
        break;
1900
    case 6: /* EPSR */
1901
        xpsr_write(env, val, 0x0600fc00);
1902
        break;
1903
    case 7: /* IEPSR */
1904
        xpsr_write(env, val, 0x0600fc00);
1905
        break;
1906
    case 8: /* MSP */
1907
        if (env->v7m.current_sp)
1908
            env->v7m.other_sp = val;
1909
        else
1910
            env->regs[13] = val;
1911
        break;
1912
    case 9: /* PSP */
1913
        if (env->v7m.current_sp)
1914
            env->regs[13] = val;
1915
        else
1916
            env->v7m.other_sp = val;
1917
        break;
1918
    case 16: /* PRIMASK */
1919
        if (val & 1)
1920
            env->uncached_cpsr |= CPSR_I;
1921
        else
1922
            env->uncached_cpsr &= ~CPSR_I;
1923
        break;
1924
    case 17: /* FAULTMASK */
1925
        if (val & 1)
1926
            env->uncached_cpsr |= CPSR_F;
1927
        else
1928
            env->uncached_cpsr &= ~CPSR_F;
1929
        break;
1930
    case 18: /* BASEPRI */
1931
        env->v7m.basepri = val & 0xff;
1932
        break;
1933
    case 19: /* BASEPRI_MAX */
1934
        val &= 0xff;
1935
        if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
1936
            env->v7m.basepri = val;
1937
        break;
1938
    case 20: /* CONTROL */
1939
        env->v7m.control = val & 3;
1940
        switch_v7m_sp(env, (val & 2) != 0);
1941
        break;
1942
    default:
1943
        /* ??? For debugging only.  */
1944
        cpu_abort(env, "Unimplemented system register write (%d)\n", reg);
1945
        return;
1946
    }
1947
}
1948

    
1949
void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
1950
                ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
1951
                void *opaque)
1952
{
1953
    if (cpnum < 0 || cpnum > 14) {
1954
        cpu_abort(env, "Bad coprocessor number: %i\n", cpnum);
1955
        return;
1956
    }
1957

    
1958
    env->cp[cpnum].cp_read = cp_read;
1959
    env->cp[cpnum].cp_write = cp_write;
1960
    env->cp[cpnum].opaque = opaque;
1961
}
1962

    
1963
#endif
1964

    
1965
/* Note that signed overflow is undefined in C.  The following routines are
1966
   careful to use unsigned types where modulo arithmetic is required.
1967
   Failure to do so _will_ break on newer gcc.  */
1968

    
1969
/* Signed saturating arithmetic.  */
1970

    
1971
/* Perform 16-bit signed saturating addition.  */
1972
static inline uint16_t add16_sat(uint16_t a, uint16_t b)
1973
{
1974
    uint16_t res;
1975

    
1976
    res = a + b;
1977
    if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
1978
        if (a & 0x8000)
1979
            res = 0x8000;
1980
        else
1981
            res = 0x7fff;
1982
    }
1983
    return res;
1984
}
1985

    
1986
/* Perform 8-bit signed saturating addition.  */
1987
static inline uint8_t add8_sat(uint8_t a, uint8_t b)
1988
{
1989
    uint8_t res;
1990

    
1991
    res = a + b;
1992
    if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
1993
        if (a & 0x80)
1994
            res = 0x80;
1995
        else
1996
            res = 0x7f;
1997
    }
1998
    return res;
1999
}
2000

    
2001
/* Perform 16-bit signed saturating subtraction.  */
2002
static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
2003
{
2004
    uint16_t res;
2005

    
2006
    res = a - b;
2007
    if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
2008
        if (a & 0x8000)
2009
            res = 0x8000;
2010
        else
2011
            res = 0x7fff;
2012
    }
2013
    return res;
2014
}
2015

    
2016
/* Perform 8-bit signed saturating subtraction.  */
2017
static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
2018
{
2019
    uint8_t res;
2020

    
2021
    res = a - b;
2022
    if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
2023
        if (a & 0x80)
2024
            res = 0x80;
2025
        else
2026
            res = 0x7f;
2027
    }
2028
    return res;
2029
}
2030

    
2031
#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
2032
#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
2033
#define ADD8(a, b, n)  RESULT(add8_sat(a, b), n, 8);
2034
#define SUB8(a, b, n)  RESULT(sub8_sat(a, b), n, 8);
2035
#define PFX q
2036

    
2037
#include "op_addsub.h"
2038

    
2039
/* Unsigned saturating arithmetic.  */
2040
static inline uint16_t add16_usat(uint16_t a, uint16_t b)
2041
{
2042
    uint16_t res;
2043
    res = a + b;
2044
    if (res < a)
2045
        res = 0xffff;
2046
    return res;
2047
}
2048

    
2049
static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
2050
{
2051
    if (a < b)
2052
        return a - b;
2053
    else
2054
        return 0;
2055
}
2056

    
2057
static inline uint8_t add8_usat(uint8_t a, uint8_t b)
2058
{
2059
    uint8_t res;
2060
    res = a + b;
2061
    if (res < a)
2062
        res = 0xff;
2063
    return res;
2064
}
2065

    
2066
static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
2067
{
2068
    if (a < b)
2069
        return a - b;
2070
    else
2071
        return 0;
2072
}
2073

    
2074
#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
2075
#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
2076
#define ADD8(a, b, n)  RESULT(add8_usat(a, b), n, 8);
2077
#define SUB8(a, b, n)  RESULT(sub8_usat(a, b), n, 8);
2078
#define PFX uq
2079

    
2080
#include "op_addsub.h"
2081

    
2082
/* Signed modulo arithmetic.  */
2083
#define SARITH16(a, b, n, op) do { \
2084
    int32_t sum; \
2085
    sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \
2086
    RESULT(sum, n, 16); \
2087
    if (sum >= 0) \
2088
        ge |= 3 << (n * 2); \
2089
    } while(0)
2090

    
2091
#define SARITH8(a, b, n, op) do { \
2092
    int32_t sum; \
2093
    sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \
2094
    RESULT(sum, n, 8); \
2095
    if (sum >= 0) \
2096
        ge |= 1 << n; \
2097
    } while(0)
2098

    
2099

    
2100
#define ADD16(a, b, n) SARITH16(a, b, n, +)
2101
#define SUB16(a, b, n) SARITH16(a, b, n, -)
2102
#define ADD8(a, b, n)  SARITH8(a, b, n, +)
2103
#define SUB8(a, b, n)  SARITH8(a, b, n, -)
2104
#define PFX s
2105
#define ARITH_GE
2106

    
2107
#include "op_addsub.h"
2108

    
2109
/* Unsigned modulo arithmetic.  */
2110
#define ADD16(a, b, n) do { \
2111
    uint32_t sum; \
2112
    sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
2113
    RESULT(sum, n, 16); \
2114
    if ((sum >> 16) == 1) \
2115
        ge |= 3 << (n * 2); \
2116
    } while(0)
2117

    
2118
#define ADD8(a, b, n) do { \
2119
    uint32_t sum; \
2120
    sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
2121
    RESULT(sum, n, 8); \
2122
    if ((sum >> 8) == 1) \
2123
        ge |= 1 << n; \
2124
    } while(0)
2125

    
2126
#define SUB16(a, b, n) do { \
2127
    uint32_t sum; \
2128
    sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
2129
    RESULT(sum, n, 16); \
2130
    if ((sum >> 16) == 0) \
2131
        ge |= 3 << (n * 2); \
2132
    } while(0)
2133

    
2134
#define SUB8(a, b, n) do { \
2135
    uint32_t sum; \
2136
    sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
2137
    RESULT(sum, n, 8); \
2138
    if ((sum >> 8) == 0) \
2139
        ge |= 1 << n; \
2140
    } while(0)
2141

    
2142
#define PFX u
2143
#define ARITH_GE
2144

    
2145
#include "op_addsub.h"
2146

    
2147
/* Halved signed arithmetic.  */
2148
#define ADD16(a, b, n) \
2149
  RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
2150
#define SUB16(a, b, n) \
2151
  RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
2152
#define ADD8(a, b, n) \
2153
  RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
2154
#define SUB8(a, b, n) \
2155
  RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
2156
#define PFX sh
2157

    
2158
#include "op_addsub.h"
2159

    
2160
/* Halved unsigned arithmetic.  */
2161
#define ADD16(a, b, n) \
2162
  RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2163
#define SUB16(a, b, n) \
2164
  RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2165
#define ADD8(a, b, n) \
2166
  RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2167
#define SUB8(a, b, n) \
2168
  RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2169
#define PFX uh
2170

    
2171
#include "op_addsub.h"
2172

    
2173
static inline uint8_t do_usad(uint8_t a, uint8_t b)
2174
{
2175
    if (a > b)
2176
        return a - b;
2177
    else
2178
        return b - a;
2179
}
2180

    
2181
/* Unsigned sum of absolute byte differences.  */
2182
uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
2183
{
2184
    uint32_t sum;
2185
    sum = do_usad(a, b);
2186
    sum += do_usad(a >> 8, b >> 8);
2187
    sum += do_usad(a >> 16, b >>16);
2188
    sum += do_usad(a >> 24, b >> 24);
2189
    return sum;
2190
}
2191

    
2192
/* For ARMv6 SEL instruction.  */
2193
uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
2194
{
2195
    uint32_t mask;
2196

    
2197
    mask = 0;
2198
    if (flags & 1)
2199
        mask |= 0xff;
2200
    if (flags & 2)
2201
        mask |= 0xff00;
2202
    if (flags & 4)
2203
        mask |= 0xff0000;
2204
    if (flags & 8)
2205
        mask |= 0xff000000;
2206
    return (a & mask) | (b & ~mask);
2207
}
2208

    
2209
uint32_t HELPER(logicq_cc)(uint64_t val)
2210
{
2211
    return (val >> 32) | (val != 0);
2212
}
2213

    
2214
/* VFP support.  We follow the convention used for VFP instrunctions:
2215
   Single precition routines have a "s" suffix, double precision a
2216
   "d" suffix.  */
2217

    
2218
/* Convert host exception flags to vfp form.  */
2219
static inline int vfp_exceptbits_from_host(int host_bits)
2220
{
2221
    int target_bits = 0;
2222

    
2223
    if (host_bits & float_flag_invalid)
2224
        target_bits |= 1;
2225
    if (host_bits & float_flag_divbyzero)
2226
        target_bits |= 2;
2227
    if (host_bits & float_flag_overflow)
2228
        target_bits |= 4;
2229
    if (host_bits & float_flag_underflow)
2230
        target_bits |= 8;
2231
    if (host_bits & float_flag_inexact)
2232
        target_bits |= 0x10;
2233
    return target_bits;
2234
}
2235

    
2236
uint32_t HELPER(vfp_get_fpscr)(CPUState *env)
2237
{
2238
    int i;
2239
    uint32_t fpscr;
2240

    
2241
    fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
2242
            | (env->vfp.vec_len << 16)
2243
            | (env->vfp.vec_stride << 20);
2244
    i = get_float_exception_flags(&env->vfp.fp_status);
2245
    fpscr |= vfp_exceptbits_from_host(i);
2246
    return fpscr;
2247
}
2248

    
2249
/* Convert vfp exception flags to target form.  */
2250
static inline int vfp_exceptbits_to_host(int target_bits)
2251
{
2252
    int host_bits = 0;
2253

    
2254
    if (target_bits & 1)
2255
        host_bits |= float_flag_invalid;
2256
    if (target_bits & 2)
2257
        host_bits |= float_flag_divbyzero;
2258
    if (target_bits & 4)
2259
        host_bits |= float_flag_overflow;
2260
    if (target_bits & 8)
2261
        host_bits |= float_flag_underflow;
2262
    if (target_bits & 0x10)
2263
        host_bits |= float_flag_inexact;
2264
    return host_bits;
2265
}
2266

    
2267
void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
2268
{
2269
    int i;
2270
    uint32_t changed;
2271

    
2272
    changed = env->vfp.xregs[ARM_VFP_FPSCR];
2273
    env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
2274
    env->vfp.vec_len = (val >> 16) & 7;
2275
    env->vfp.vec_stride = (val >> 20) & 3;
2276

    
2277
    changed ^= val;
2278
    if (changed & (3 << 22)) {
2279
        i = (val >> 22) & 3;
2280
        switch (i) {
2281
        case 0:
2282
            i = float_round_nearest_even;
2283
            break;
2284
        case 1:
2285
            i = float_round_up;
2286
            break;
2287
        case 2:
2288
            i = float_round_down;
2289
            break;
2290
        case 3:
2291
            i = float_round_to_zero;
2292
            break;
2293
        }
2294
        set_float_rounding_mode(i, &env->vfp.fp_status);
2295
    }
2296
    if (changed & (1 << 24))
2297
        set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
2298
    if (changed & (1 << 25))
2299
        set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status);
2300

    
2301
    i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
2302
    set_float_exception_flags(i, &env->vfp.fp_status);
2303
}
2304

    
2305
#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
2306

    
2307
#define VFP_BINOP(name) \
2308
float32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \
2309
{ \
2310
    return float32_ ## name (a, b, &env->vfp.fp_status); \
2311
} \
2312
float64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \
2313
{ \
2314
    return float64_ ## name (a, b, &env->vfp.fp_status); \
2315
}
2316
VFP_BINOP(add)
2317
VFP_BINOP(sub)
2318
VFP_BINOP(mul)
2319
VFP_BINOP(div)
2320
#undef VFP_BINOP
2321

    
2322
float32 VFP_HELPER(neg, s)(float32 a)
2323
{
2324
    return float32_chs(a);
2325
}
2326

    
2327
float64 VFP_HELPER(neg, d)(float64 a)
2328
{
2329
    return float64_chs(a);
2330
}
2331

    
2332
float32 VFP_HELPER(abs, s)(float32 a)
2333
{
2334
    return float32_abs(a);
2335
}
2336

    
2337
float64 VFP_HELPER(abs, d)(float64 a)
2338
{
2339
    return float64_abs(a);
2340
}
2341

    
2342
float32 VFP_HELPER(sqrt, s)(float32 a, CPUState *env)
2343
{
2344
    return float32_sqrt(a, &env->vfp.fp_status);
2345
}
2346

    
2347
float64 VFP_HELPER(sqrt, d)(float64 a, CPUState *env)
2348
{
2349
    return float64_sqrt(a, &env->vfp.fp_status);
2350
}
2351

    
2352
/* XXX: check quiet/signaling case */
2353
#define DO_VFP_cmp(p, type) \
2354
void VFP_HELPER(cmp, p)(type a, type b, CPUState *env)  \
2355
{ \
2356
    uint32_t flags; \
2357
    switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
2358
    case 0: flags = 0x6; break; \
2359
    case -1: flags = 0x8; break; \
2360
    case 1: flags = 0x2; break; \
2361
    default: case 2: flags = 0x3; break; \
2362
    } \
2363
    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2364
        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2365
} \
2366
void VFP_HELPER(cmpe, p)(type a, type b, CPUState *env) \
2367
{ \
2368
    uint32_t flags; \
2369
    switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
2370
    case 0: flags = 0x6; break; \
2371
    case -1: flags = 0x8; break; \
2372
    case 1: flags = 0x2; break; \
2373
    default: case 2: flags = 0x3; break; \
2374
    } \
2375
    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2376
        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2377
}
2378
DO_VFP_cmp(s, float32)
2379
DO_VFP_cmp(d, float64)
2380
#undef DO_VFP_cmp
2381

    
2382
/* Helper routines to perform bitwise copies between float and int.  */
2383
static inline float32 vfp_itos(uint32_t i)
2384
{
2385
    union {
2386
        uint32_t i;
2387
        float32 s;
2388
    } v;
2389

    
2390
    v.i = i;
2391
    return v.s;
2392
}
2393

    
2394
static inline uint32_t vfp_stoi(float32 s)
2395
{
2396
    union {
2397
        uint32_t i;
2398
        float32 s;
2399
    } v;
2400

    
2401
    v.s = s;
2402
    return v.i;
2403
}
2404

    
2405
static inline float64 vfp_itod(uint64_t i)
2406
{
2407
    union {
2408
        uint64_t i;
2409
        float64 d;
2410
    } v;
2411

    
2412
    v.i = i;
2413
    return v.d;
2414
}
2415

    
2416
static inline uint64_t vfp_dtoi(float64 d)
2417
{
2418
    union {
2419
        uint64_t i;
2420
        float64 d;
2421
    } v;
2422

    
2423
    v.d = d;
2424
    return v.i;
2425
}
2426

    
2427
/* Integer to float conversion.  */
2428
float32 VFP_HELPER(uito, s)(float32 x, CPUState *env)
2429
{
2430
    return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
2431
}
2432

    
2433
float64 VFP_HELPER(uito, d)(float32 x, CPUState *env)
2434
{
2435
    return uint32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
2436
}
2437

    
2438
float32 VFP_HELPER(sito, s)(float32 x, CPUState *env)
2439
{
2440
    return int32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
2441
}
2442

    
2443
float64 VFP_HELPER(sito, d)(float32 x, CPUState *env)
2444
{
2445
    return int32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
2446
}
2447

    
2448
/* Float to integer conversion.  */
2449
float32 VFP_HELPER(toui, s)(float32 x, CPUState *env)
2450
{
2451
    return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status));
2452
}
2453

    
2454
float32 VFP_HELPER(toui, d)(float64 x, CPUState *env)
2455
{
2456
    return vfp_itos(float64_to_uint32(x, &env->vfp.fp_status));
2457
}
2458

    
2459
float32 VFP_HELPER(tosi, s)(float32 x, CPUState *env)
2460
{
2461
    return vfp_itos(float32_to_int32(x, &env->vfp.fp_status));
2462
}
2463

    
2464
float32 VFP_HELPER(tosi, d)(float64 x, CPUState *env)
2465
{
2466
    return vfp_itos(float64_to_int32(x, &env->vfp.fp_status));
2467
}
2468

    
2469
float32 VFP_HELPER(touiz, s)(float32 x, CPUState *env)
2470
{
2471
    return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status));
2472
}
2473

    
2474
float32 VFP_HELPER(touiz, d)(float64 x, CPUState *env)
2475
{
2476
    return vfp_itos(float64_to_uint32_round_to_zero(x, &env->vfp.fp_status));
2477
}
2478

    
2479
float32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
2480
{
2481
    return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status));
2482
}
2483

    
2484
float32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
2485
{
2486
    return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status));
2487
}
2488

    
2489
/* floating point conversion */
2490
float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env)
2491
{
2492
    return float32_to_float64(x, &env->vfp.fp_status);
2493
}
2494

    
2495
float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env)
2496
{
2497
    return float64_to_float32(x, &env->vfp.fp_status);
2498
}
2499

    
2500
/* VFP3 fixed point conversion.  */
2501
#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
2502
ftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \
2503
{ \
2504
    ftype tmp; \
2505
    tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(x), \
2506
                                  &env->vfp.fp_status); \
2507
    return ftype##_scalbn(tmp, -(int)shift, &env->vfp.fp_status); \
2508
} \
2509
ftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \
2510
{ \
2511
    ftype tmp; \
2512
    tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \
2513
    return vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
2514
        &env->vfp.fp_status)); \
2515
}
2516

    
2517
VFP_CONV_FIX(sh, d, float64, int16, )
2518
VFP_CONV_FIX(sl, d, float64, int32, )
2519
VFP_CONV_FIX(uh, d, float64, uint16, u)
2520
VFP_CONV_FIX(ul, d, float64, uint32, u)
2521
VFP_CONV_FIX(sh, s, float32, int16, )
2522
VFP_CONV_FIX(sl, s, float32, int32, )
2523
VFP_CONV_FIX(uh, s, float32, uint16, u)
2524
VFP_CONV_FIX(ul, s, float32, uint32, u)
2525
#undef VFP_CONV_FIX
2526

    
2527
/* Half precision conversions.  */
2528
float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUState *env)
2529
{
2530
    float_status *s = &env->vfp.fp_status;
2531
    int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
2532
    return float16_to_float32(a, ieee, s);
2533
}
2534

    
2535
uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUState *env)
2536
{
2537
    float_status *s = &env->vfp.fp_status;
2538
    int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
2539
    return float32_to_float16(a, ieee, s);
2540
}
2541

    
2542
float32 HELPER(recps_f32)(float32 a, float32 b, CPUState *env)
2543
{
2544
    float_status *s = &env->vfp.fp_status;
2545
    float32 two = int32_to_float32(2, s);
2546
    return float32_sub(two, float32_mul(a, b, s), s);
2547
}
2548

    
2549
float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env)
2550
{
2551
    float_status *s = &env->vfp.fp_status;
2552
    float32 three = int32_to_float32(3, s);
2553
    return float32_sub(three, float32_mul(a, b, s), s);
2554
}
2555

    
2556
/* NEON helpers.  */
2557

    
2558
/* TODO: The architecture specifies the value that the estimate functions
2559
   should return.  We return the exact reciprocal/root instead.  */
2560
float32 HELPER(recpe_f32)(float32 a, CPUState *env)
2561
{
2562
    float_status *s = &env->vfp.fp_status;
2563
    float32 one = int32_to_float32(1, s);
2564
    return float32_div(one, a, s);
2565
}
2566

    
2567
float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
2568
{
2569
    float_status *s = &env->vfp.fp_status;
2570
    float32 one = int32_to_float32(1, s);
2571
    return float32_div(one, float32_sqrt(a, s), s);
2572
}
2573

    
2574
uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
2575
{
2576
    float_status *s = &env->vfp.fp_status;
2577
    float32 tmp;
2578
    tmp = int32_to_float32(a, s);
2579
    tmp = float32_scalbn(tmp, -32, s);
2580
    tmp = helper_recpe_f32(tmp, env);
2581
    tmp = float32_scalbn(tmp, 31, s);
2582
    return float32_to_int32(tmp, s);
2583
}
2584

    
2585
uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
2586
{
2587
    float_status *s = &env->vfp.fp_status;
2588
    float32 tmp;
2589
    tmp = int32_to_float32(a, s);
2590
    tmp = float32_scalbn(tmp, -32, s);
2591
    tmp = helper_rsqrte_f32(tmp, env);
2592
    tmp = float32_scalbn(tmp, 31, s);
2593
    return float32_to_int32(tmp, s);
2594
}
2595

    
2596
void HELPER(set_teecr)(CPUState *env, uint32_t val)
2597
{
2598
    val &= 1;
2599
    if (env->teecr != val) {
2600
        env->teecr = val;
2601
        tb_flush(env);
2602
    }
2603
}