Statistics
| Branch: | Revision:

root / target-arm / helper.c @ e03c22a9

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
    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
211
       clear at reset.  Initial SP and PC are loaded from ROM.  */
212
    if (IS_M(env)) {
213
        uint32_t pc;
214
        uint8_t *rom;
215
        env->uncached_cpsr &= ~CPSR_I;
216
        rom = rom_ptr(0);
217
        if (rom) {
218
            /* We should really use ldl_phys here, in case the guest
219
               modified flash and reset itself.  However images
220
               loaded via -kenrel have not been copied yet, so load the
221
               values directly from there.  */
222
            env->regs[13] = ldl_p(rom);
223
            pc = ldl_p(rom + 4);
224
            env->thumb = pc & 1;
225
            env->regs[15] = pc & ~1;
226
        }
227
    }
228
    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
229
    env->cp15.c2_base_mask = 0xffffc000u;
230
#endif
231
    tlb_flush(env, 1);
232
}
233

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
482
#if defined(CONFIG_USER_ONLY)
483

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

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

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

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

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

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

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

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

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

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

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

    
556
#else
557

    
558
extern int semihosting_enabled;
559

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1237
    return phys_addr;
1238
}
1239

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1962
#endif
1963

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

    
1968
/* Signed saturating arithmetic.  */
1969

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

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

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

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

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

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

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

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

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

    
2036
#include "op_addsub.h"
2037

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

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

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

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

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

    
2079
#include "op_addsub.h"
2080

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

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

    
2098

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

    
2106
#include "op_addsub.h"
2107

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

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

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

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

    
2141
#define PFX u
2142
#define ARITH_GE
2143

    
2144
#include "op_addsub.h"
2145

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

    
2157
#include "op_addsub.h"
2158

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

    
2170
#include "op_addsub.h"
2171

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2555
/* NEON helpers.  */
2556

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

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

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

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

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