Statistics
| Branch: | Revision:

root / target-arm / helper.c @ fe1479c3

History | View | Annotate | Download (70.5 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

    
11
static uint32_t cortexa8_cp15_c0_c1[8] =
12
{ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 };
13

    
14
static uint32_t cortexa8_cp15_c0_c2[8] =
15
{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 };
16

    
17
static uint32_t mpcore_cp15_c0_c1[8] =
18
{ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 };
19

    
20
static uint32_t mpcore_cp15_c0_c2[8] =
21
{ 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 };
22

    
23
static uint32_t arm1136_cp15_c0_c1[8] =
24
{ 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 };
25

    
26
static uint32_t arm1136_cp15_c0_c2[8] =
27
{ 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 };
28

    
29
static uint32_t cpu_arm_find_by_name(const char *name);
30

    
31
static inline void set_feature(CPUARMState *env, int feature)
32
{
33
    env->features |= 1u << feature;
34
}
35

    
36
static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
37
{
38
    env->cp15.c0_cpuid = id;
39
    switch (id) {
40
    case ARM_CPUID_ARM926:
41
        set_feature(env, ARM_FEATURE_VFP);
42
        env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
43
        env->cp15.c0_cachetype = 0x1dd20d2;
44
        env->cp15.c1_sys = 0x00090078;
45
        break;
46
    case ARM_CPUID_ARM946:
47
        set_feature(env, ARM_FEATURE_MPU);
48
        env->cp15.c0_cachetype = 0x0f004006;
49
        env->cp15.c1_sys = 0x00000078;
50
        break;
51
    case ARM_CPUID_ARM1026:
52
        set_feature(env, ARM_FEATURE_VFP);
53
        set_feature(env, ARM_FEATURE_AUXCR);
54
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
55
        env->cp15.c0_cachetype = 0x1dd20d2;
56
        env->cp15.c1_sys = 0x00090078;
57
        break;
58
    case ARM_CPUID_ARM1136_R2:
59
    case ARM_CPUID_ARM1136:
60
        set_feature(env, ARM_FEATURE_V6);
61
        set_feature(env, ARM_FEATURE_VFP);
62
        set_feature(env, ARM_FEATURE_AUXCR);
63
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
64
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
65
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
66
        memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t));
67
        memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t));
68
        env->cp15.c0_cachetype = 0x1dd20d2;
69
        break;
70
    case ARM_CPUID_ARM11MPCORE:
71
        set_feature(env, ARM_FEATURE_V6);
72
        set_feature(env, ARM_FEATURE_V6K);
73
        set_feature(env, ARM_FEATURE_VFP);
74
        set_feature(env, ARM_FEATURE_AUXCR);
75
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
76
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
77
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
78
        memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t));
79
        memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t));
80
        env->cp15.c0_cachetype = 0x1dd20d2;
81
        break;
82
    case ARM_CPUID_CORTEXA8:
83
        set_feature(env, ARM_FEATURE_V6);
84
        set_feature(env, ARM_FEATURE_V6K);
85
        set_feature(env, ARM_FEATURE_V7);
86
        set_feature(env, ARM_FEATURE_AUXCR);
87
        set_feature(env, ARM_FEATURE_THUMB2);
88
        set_feature(env, ARM_FEATURE_VFP);
89
        set_feature(env, ARM_FEATURE_VFP3);
90
        set_feature(env, ARM_FEATURE_NEON);
91
        set_feature(env, ARM_FEATURE_THUMB2EE);
92
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
93
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
94
        env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
95
        memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t));
96
        memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t));
97
        env->cp15.c0_cachetype = 0x1dd20d2;
98
        break;
99
    case ARM_CPUID_CORTEXM3:
100
        set_feature(env, ARM_FEATURE_V6);
101
        set_feature(env, ARM_FEATURE_THUMB2);
102
        set_feature(env, ARM_FEATURE_V7);
103
        set_feature(env, ARM_FEATURE_M);
104
        set_feature(env, ARM_FEATURE_DIV);
105
        break;
106
    case ARM_CPUID_ANY: /* For userspace emulation.  */
107
        set_feature(env, ARM_FEATURE_V6);
108
        set_feature(env, ARM_FEATURE_V6K);
109
        set_feature(env, ARM_FEATURE_V7);
110
        set_feature(env, ARM_FEATURE_THUMB2);
111
        set_feature(env, ARM_FEATURE_VFP);
112
        set_feature(env, ARM_FEATURE_VFP3);
113
        set_feature(env, ARM_FEATURE_NEON);
114
        set_feature(env, ARM_FEATURE_THUMB2EE);
115
        set_feature(env, ARM_FEATURE_DIV);
116
        break;
117
    case ARM_CPUID_TI915T:
118
    case ARM_CPUID_TI925T:
119
        set_feature(env, ARM_FEATURE_OMAPCP);
120
        env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring.  */
121
        env->cp15.c0_cachetype = 0x5109149;
122
        env->cp15.c1_sys = 0x00000070;
123
        env->cp15.c15_i_max = 0x000;
124
        env->cp15.c15_i_min = 0xff0;
125
        break;
126
    case ARM_CPUID_PXA250:
127
    case ARM_CPUID_PXA255:
128
    case ARM_CPUID_PXA260:
129
    case ARM_CPUID_PXA261:
130
    case ARM_CPUID_PXA262:
131
        set_feature(env, ARM_FEATURE_XSCALE);
132
        /* JTAG_ID is ((id << 28) | 0x09265013) */
133
        env->cp15.c0_cachetype = 0xd172172;
134
        env->cp15.c1_sys = 0x00000078;
135
        break;
136
    case ARM_CPUID_PXA270_A0:
137
    case ARM_CPUID_PXA270_A1:
138
    case ARM_CPUID_PXA270_B0:
139
    case ARM_CPUID_PXA270_B1:
140
    case ARM_CPUID_PXA270_C0:
141
    case ARM_CPUID_PXA270_C5:
142
        set_feature(env, ARM_FEATURE_XSCALE);
143
        /* JTAG_ID is ((id << 28) | 0x09265013) */
144
        set_feature(env, ARM_FEATURE_IWMMXT);
145
        env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
146
        env->cp15.c0_cachetype = 0xd172172;
147
        env->cp15.c1_sys = 0x00000078;
148
        break;
149
    default:
150
        cpu_abort(env, "Bad CPU ID: %x\n", id);
151
        break;
152
    }
153
}
154

    
155
void cpu_reset(CPUARMState *env)
156
{
157
    uint32_t id;
158
    id = env->cp15.c0_cpuid;
159
    memset(env, 0, offsetof(CPUARMState, breakpoints));
160
    if (id)
161
        cpu_reset_model_id(env, id);
162
#if defined (CONFIG_USER_ONLY)
163
    env->uncached_cpsr = ARM_CPU_MODE_USR;
164
    env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
165
#else
166
    /* SVC mode with interrupts disabled.  */
167
    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
168
    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
169
       clear at reset.  */
170
    if (IS_M(env))
171
        env->uncached_cpsr &= ~CPSR_I;
172
    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
173
    env->cp15.c2_base_mask = 0xffffc000u;
174
#endif
175
    env->regs[15] = 0;
176
    tlb_flush(env, 1);
177
}
178

    
179
static int vfp_gdb_get_reg(CPUState *env, uint8_t *buf, int reg)
180
{
181
    int nregs;
182

    
183
    /* VFP data registers are always little-endian.  */
184
    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
185
    if (reg < nregs) {
186
        stfq_le_p(buf, env->vfp.regs[reg]);
187
        return 8;
188
    }
189
    if (arm_feature(env, ARM_FEATURE_NEON)) {
190
        /* Aliases for Q regs.  */
191
        nregs += 16;
192
        if (reg < nregs) {
193
            stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
194
            stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
195
            return 16;
196
        }
197
    }
198
    switch (reg - nregs) {
199
    case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4;
200
    case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4;
201
    case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4;
202
    }
203
    return 0;
204
}
205

    
206
static int vfp_gdb_set_reg(CPUState *env, uint8_t *buf, int reg)
207
{
208
    int nregs;
209

    
210
    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
211
    if (reg < nregs) {
212
        env->vfp.regs[reg] = ldfq_le_p(buf);
213
        return 8;
214
    }
215
    if (arm_feature(env, ARM_FEATURE_NEON)) {
216
        nregs += 16;
217
        if (reg < nregs) {
218
            env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf);
219
            env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8);
220
            return 16;
221
        }
222
    }
223
    switch (reg - nregs) {
224
    case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
225
    case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4;
226
    case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf); return 4;
227
    }
228
    return 0;
229
}
230

    
231
CPUARMState *cpu_arm_init(const char *cpu_model)
232
{
233
    CPUARMState *env;
234
    uint32_t id;
235
    static int inited = 0;
236

    
237
    id = cpu_arm_find_by_name(cpu_model);
238
    if (id == 0)
239
        return NULL;
240
    env = qemu_mallocz(sizeof(CPUARMState));
241
    if (!env)
242
        return NULL;
243
    cpu_exec_init(env);
244
    if (!inited) {
245
        inited = 1;
246
        arm_translate_init();
247
    }
248

    
249
    env->cpu_model_str = cpu_model;
250
    env->cp15.c0_cpuid = id;
251
    cpu_reset(env);
252
    if (arm_feature(env, ARM_FEATURE_NEON)) {
253
        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
254
                                 51, "arm-neon.xml", 0);
255
    } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
256
        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
257
                                 35, "arm-vfp3.xml", 0);
258
    } else if (arm_feature(env, ARM_FEATURE_VFP)) {
259
        gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
260
                                 19, "arm-vfp.xml", 0);
261
    }
262
    return env;
263
}
264

    
265
struct arm_cpu_t {
266
    uint32_t id;
267
    const char *name;
268
};
269

    
270
static const struct arm_cpu_t arm_cpu_names[] = {
271
    { ARM_CPUID_ARM926, "arm926"},
272
    { ARM_CPUID_ARM946, "arm946"},
273
    { ARM_CPUID_ARM1026, "arm1026"},
274
    { ARM_CPUID_ARM1136, "arm1136"},
275
    { ARM_CPUID_ARM1136_R2, "arm1136-r2"},
276
    { ARM_CPUID_ARM11MPCORE, "arm11mpcore"},
277
    { ARM_CPUID_CORTEXM3, "cortex-m3"},
278
    { ARM_CPUID_CORTEXA8, "cortex-a8"},
279
    { ARM_CPUID_TI925T, "ti925t" },
280
    { ARM_CPUID_PXA250, "pxa250" },
281
    { ARM_CPUID_PXA255, "pxa255" },
282
    { ARM_CPUID_PXA260, "pxa260" },
283
    { ARM_CPUID_PXA261, "pxa261" },
284
    { ARM_CPUID_PXA262, "pxa262" },
285
    { ARM_CPUID_PXA270, "pxa270" },
286
    { ARM_CPUID_PXA270_A0, "pxa270-a0" },
287
    { ARM_CPUID_PXA270_A1, "pxa270-a1" },
288
    { ARM_CPUID_PXA270_B0, "pxa270-b0" },
289
    { ARM_CPUID_PXA270_B1, "pxa270-b1" },
290
    { ARM_CPUID_PXA270_C0, "pxa270-c0" },
291
    { ARM_CPUID_PXA270_C5, "pxa270-c5" },
292
    { ARM_CPUID_ANY, "any"},
293
    { 0, NULL}
294
};
295

    
296
void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
297
{
298
    int i;
299

    
300
    (*cpu_fprintf)(f, "Available CPUs:\n");
301
    for (i = 0; arm_cpu_names[i].name; i++) {
302
        (*cpu_fprintf)(f, "  %s\n", arm_cpu_names[i].name);
303
    }
304
}
305

    
306
/* return 0 if not found */
307
static uint32_t cpu_arm_find_by_name(const char *name)
308
{
309
    int i;
310
    uint32_t id;
311

    
312
    id = 0;
313
    for (i = 0; arm_cpu_names[i].name; i++) {
314
        if (strcmp(name, arm_cpu_names[i].name) == 0) {
315
            id = arm_cpu_names[i].id;
316
            break;
317
        }
318
    }
319
    return id;
320
}
321

    
322
void cpu_arm_close(CPUARMState *env)
323
{
324
    free(env);
325
}
326

    
327
uint32_t cpsr_read(CPUARMState *env)
328
{
329
    int ZF;
330
    ZF = (env->ZF == 0);
331
    return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
332
        (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
333
        | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
334
        | ((env->condexec_bits & 0xfc) << 8)
335
        | (env->GE << 16);
336
}
337

    
338
void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
339
{
340
    if (mask & CPSR_NZCV) {
341
        env->ZF = (~val) & CPSR_Z;
342
        env->NF = val;
343
        env->CF = (val >> 29) & 1;
344
        env->VF = (val << 3) & 0x80000000;
345
    }
346
    if (mask & CPSR_Q)
347
        env->QF = ((val & CPSR_Q) != 0);
348
    if (mask & CPSR_T)
349
        env->thumb = ((val & CPSR_T) != 0);
350
    if (mask & CPSR_IT_0_1) {
351
        env->condexec_bits &= ~3;
352
        env->condexec_bits |= (val >> 25) & 3;
353
    }
354
    if (mask & CPSR_IT_2_7) {
355
        env->condexec_bits &= 3;
356
        env->condexec_bits |= (val >> 8) & 0xfc;
357
    }
358
    if (mask & CPSR_GE) {
359
        env->GE = (val >> 16) & 0xf;
360
    }
361

    
362
    if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
363
        switch_mode(env, val & CPSR_M);
364
    }
365
    mask &= ~CACHED_CPSR_BITS;
366
    env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
367
}
368

    
369
/* Sign/zero extend */
370
uint32_t HELPER(sxtb16)(uint32_t x)
371
{
372
    uint32_t res;
373
    res = (uint16_t)(int8_t)x;
374
    res |= (uint32_t)(int8_t)(x >> 16) << 16;
375
    return res;
376
}
377

    
378
uint32_t HELPER(uxtb16)(uint32_t x)
379
{
380
    uint32_t res;
381
    res = (uint16_t)(uint8_t)x;
382
    res |= (uint32_t)(uint8_t)(x >> 16) << 16;
383
    return res;
384
}
385

    
386
uint32_t HELPER(clz)(uint32_t x)
387
{
388
    int count;
389
    for (count = 32; x; count--)
390
        x >>= 1;
391
    return count;
392
}
393

    
394
int32_t HELPER(sdiv)(int32_t num, int32_t den)
395
{
396
    if (den == 0)
397
      return 0;
398
    return num / den;
399
}
400

    
401
uint32_t HELPER(udiv)(uint32_t num, uint32_t den)
402
{
403
    if (den == 0)
404
      return 0;
405
    return num / den;
406
}
407

    
408
uint32_t HELPER(rbit)(uint32_t x)
409
{
410
    x =  ((x & 0xff000000) >> 24)
411
       | ((x & 0x00ff0000) >> 8)
412
       | ((x & 0x0000ff00) << 8)
413
       | ((x & 0x000000ff) << 24);
414
    x =  ((x & 0xf0f0f0f0) >> 4)
415
       | ((x & 0x0f0f0f0f) << 4);
416
    x =  ((x & 0x88888888) >> 3)
417
       | ((x & 0x44444444) >> 1)
418
       | ((x & 0x22222222) << 1)
419
       | ((x & 0x11111111) << 3);
420
    return x;
421
}
422

    
423
uint32_t HELPER(abs)(uint32_t x)
424
{
425
    return ((int32_t)x < 0) ? -x : x;
426
}
427

    
428
#if defined(CONFIG_USER_ONLY)
429

    
430
void do_interrupt (CPUState *env)
431
{
432
    env->exception_index = -1;
433
}
434

    
435
/* Structure used to record exclusive memory locations.  */
436
typedef struct mmon_state {
437
    struct mmon_state *next;
438
    CPUARMState *cpu_env;
439
    uint32_t addr;
440
} mmon_state;
441

    
442
/* Chain of current locks.  */
443
static mmon_state* mmon_head = NULL;
444

    
445
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
446
                              int mmu_idx, int is_softmmu)
447
{
448
    if (rw == 2) {
449
        env->exception_index = EXCP_PREFETCH_ABORT;
450
        env->cp15.c6_insn = address;
451
    } else {
452
        env->exception_index = EXCP_DATA_ABORT;
453
        env->cp15.c6_data = address;
454
    }
455
    return 1;
456
}
457

    
458
static void allocate_mmon_state(CPUState *env)
459
{
460
    env->mmon_entry = malloc(sizeof (mmon_state));
461
    if (!env->mmon_entry)
462
        abort();
463
    memset (env->mmon_entry, 0, sizeof (mmon_state));
464
    env->mmon_entry->cpu_env = env;
465
    mmon_head = env->mmon_entry;
466
}
467

    
468
/* Flush any monitor locks for the specified address.  */
469
static void flush_mmon(uint32_t addr)
470
{
471
    mmon_state *mon;
472

    
473
    for (mon = mmon_head; mon; mon = mon->next)
474
      {
475
        if (mon->addr != addr)
476
          continue;
477

    
478
        mon->addr = 0;
479
        break;
480
      }
481
}
482

    
483
/* Mark an address for exclusive access.  */
484
void HELPER(mark_exclusive)(CPUState *env, uint32_t addr)
485
{
486
    if (!env->mmon_entry)
487
        allocate_mmon_state(env);
488
    /* Clear any previous locks.  */
489
    flush_mmon(addr);
490
    env->mmon_entry->addr = addr;
491
}
492

    
493
/* Test if an exclusive address is still exclusive.  Returns zero
494
   if the address is still exclusive.   */
495
uint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr)
496
{
497
    int res;
498

    
499
    if (!env->mmon_entry)
500
        return 1;
501
    if (env->mmon_entry->addr == addr)
502
        res = 0;
503
    else
504
        res = 1;
505
    flush_mmon(addr);
506
    return res;
507
}
508

    
509
void HELPER(clrex)(CPUState *env)
510
{
511
    if (!(env->mmon_entry && env->mmon_entry->addr))
512
        return;
513
    flush_mmon(env->mmon_entry->addr);
514
}
515

    
516
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
517
{
518
    return addr;
519
}
520

    
521
/* These should probably raise undefined insn exceptions.  */
522
void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
523
{
524
    int op1 = (insn >> 8) & 0xf;
525
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
526
    return;
527
}
528

    
529
uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
530
{
531
    int op1 = (insn >> 8) & 0xf;
532
    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
533
    return 0;
534
}
535

    
536
void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
537
{
538
    cpu_abort(env, "cp15 insn %08x\n", insn);
539
}
540

    
541
uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
542
{
543
    cpu_abort(env, "cp15 insn %08x\n", insn);
544
    return 0;
545
}
546

    
547
/* These should probably raise undefined insn exceptions.  */
548
void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
549
{
550
    cpu_abort(env, "v7m_mrs %d\n", reg);
551
}
552

    
553
uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
554
{
555
    cpu_abort(env, "v7m_mrs %d\n", reg);
556
    return 0;
557
}
558

    
559
void switch_mode(CPUState *env, int mode)
560
{
561
    if (mode != ARM_CPU_MODE_USR)
562
        cpu_abort(env, "Tried to switch out of user mode\n");
563
}
564

    
565
void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
566
{
567
    cpu_abort(env, "banked r13 write\n");
568
}
569

    
570
uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
571
{
572
    cpu_abort(env, "banked r13 read\n");
573
    return 0;
574
}
575

    
576
#else
577

    
578
extern int semihosting_enabled;
579

    
580
/* Map CPU modes onto saved register banks.  */
581
static inline int bank_number (int mode)
582
{
583
    switch (mode) {
584
    case ARM_CPU_MODE_USR:
585
    case ARM_CPU_MODE_SYS:
586
        return 0;
587
    case ARM_CPU_MODE_SVC:
588
        return 1;
589
    case ARM_CPU_MODE_ABT:
590
        return 2;
591
    case ARM_CPU_MODE_UND:
592
        return 3;
593
    case ARM_CPU_MODE_IRQ:
594
        return 4;
595
    case ARM_CPU_MODE_FIQ:
596
        return 5;
597
    }
598
    cpu_abort(cpu_single_env, "Bad mode %x\n", mode);
599
    return -1;
600
}
601

    
602
void switch_mode(CPUState *env, int mode)
603
{
604
    int old_mode;
605
    int i;
606

    
607
    old_mode = env->uncached_cpsr & CPSR_M;
608
    if (mode == old_mode)
609
        return;
610

    
611
    if (old_mode == ARM_CPU_MODE_FIQ) {
612
        memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
613
        memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
614
    } else if (mode == ARM_CPU_MODE_FIQ) {
615
        memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
616
        memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
617
    }
618

    
619
    i = bank_number(old_mode);
620
    env->banked_r13[i] = env->regs[13];
621
    env->banked_r14[i] = env->regs[14];
622
    env->banked_spsr[i] = env->spsr;
623

    
624
    i = bank_number(mode);
625
    env->regs[13] = env->banked_r13[i];
626
    env->regs[14] = env->banked_r14[i];
627
    env->spsr = env->banked_spsr[i];
628
}
629

    
630
static void v7m_push(CPUARMState *env, uint32_t val)
631
{
632
    env->regs[13] -= 4;
633
    stl_phys(env->regs[13], val);
634
}
635

    
636
static uint32_t v7m_pop(CPUARMState *env)
637
{
638
    uint32_t val;
639
    val = ldl_phys(env->regs[13]);
640
    env->regs[13] += 4;
641
    return val;
642
}
643

    
644
/* Switch to V7M main or process stack pointer.  */
645
static void switch_v7m_sp(CPUARMState *env, int process)
646
{
647
    uint32_t tmp;
648
    if (env->v7m.current_sp != process) {
649
        tmp = env->v7m.other_sp;
650
        env->v7m.other_sp = env->regs[13];
651
        env->regs[13] = tmp;
652
        env->v7m.current_sp = process;
653
    }
654
}
655

    
656
static void do_v7m_exception_exit(CPUARMState *env)
657
{
658
    uint32_t type;
659
    uint32_t xpsr;
660

    
661
    type = env->regs[15];
662
    if (env->v7m.exception != 0)
663
        armv7m_nvic_complete_irq(env->v7m.nvic, env->v7m.exception);
664

    
665
    /* Switch to the target stack.  */
666
    switch_v7m_sp(env, (type & 4) != 0);
667
    /* Pop registers.  */
668
    env->regs[0] = v7m_pop(env);
669
    env->regs[1] = v7m_pop(env);
670
    env->regs[2] = v7m_pop(env);
671
    env->regs[3] = v7m_pop(env);
672
    env->regs[12] = v7m_pop(env);
673
    env->regs[14] = v7m_pop(env);
674
    env->regs[15] = v7m_pop(env);
675
    xpsr = v7m_pop(env);
676
    xpsr_write(env, xpsr, 0xfffffdff);
677
    /* Undo stack alignment.  */
678
    if (xpsr & 0x200)
679
        env->regs[13] |= 4;
680
    /* ??? The exception return type specifies Thread/Handler mode.  However
681
       this is also implied by the xPSR value. Not sure what to do
682
       if there is a mismatch.  */
683
    /* ??? Likewise for mismatches between the CONTROL register and the stack
684
       pointer.  */
685
}
686

    
687
void do_interrupt_v7m(CPUARMState *env)
688
{
689
    uint32_t xpsr = xpsr_read(env);
690
    uint32_t lr;
691
    uint32_t addr;
692

    
693
    lr = 0xfffffff1;
694
    if (env->v7m.current_sp)
695
        lr |= 4;
696
    if (env->v7m.exception == 0)
697
        lr |= 8;
698

    
699
    /* For exceptions we just mark as pending on the NVIC, and let that
700
       handle it.  */
701
    /* TODO: Need to escalate if the current priority is higher than the
702
       one we're raising.  */
703
    switch (env->exception_index) {
704
    case EXCP_UDEF:
705
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_USAGE);
706
        return;
707
    case EXCP_SWI:
708
        env->regs[15] += 2;
709
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_SVC);
710
        return;
711
    case EXCP_PREFETCH_ABORT:
712
    case EXCP_DATA_ABORT:
713
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_MEM);
714
        return;
715
    case EXCP_BKPT:
716
        if (semihosting_enabled) {
717
            int nr;
718
            nr = lduw_code(env->regs[15]) & 0xff;
719
            if (nr == 0xab) {
720
                env->regs[15] += 2;
721
                env->regs[0] = do_arm_semihosting(env);
722
                return;
723
            }
724
        }
725
        armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_DEBUG);
726
        return;
727
    case EXCP_IRQ:
728
        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->v7m.nvic);
729
        break;
730
    case EXCP_EXCEPTION_EXIT:
731
        do_v7m_exception_exit(env);
732
        return;
733
    default:
734
        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
735
        return; /* Never happens.  Keep compiler happy.  */
736
    }
737

    
738
    /* Align stack pointer.  */
739
    /* ??? Should only do this if Configuration Control Register
740
       STACKALIGN bit is set.  */
741
    if (env->regs[13] & 4) {
742
        env->regs[13] -= 4;
743
        xpsr |= 0x200;
744
    }
745
    /* Switch to the handler mode.  */
746
    v7m_push(env, xpsr);
747
    v7m_push(env, env->regs[15]);
748
    v7m_push(env, env->regs[14]);
749
    v7m_push(env, env->regs[12]);
750
    v7m_push(env, env->regs[3]);
751
    v7m_push(env, env->regs[2]);
752
    v7m_push(env, env->regs[1]);
753
    v7m_push(env, env->regs[0]);
754
    switch_v7m_sp(env, 0);
755
    env->uncached_cpsr &= ~CPSR_IT;
756
    env->regs[14] = lr;
757
    addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
758
    env->regs[15] = addr & 0xfffffffe;
759
    env->thumb = addr & 1;
760
}
761

    
762
/* Handle a CPU exception.  */
763
void do_interrupt(CPUARMState *env)
764
{
765
    uint32_t addr;
766
    uint32_t mask;
767
    int new_mode;
768
    uint32_t offset;
769

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

    
868
/* Check section/page access permissions.
869
   Returns the page protection flags, or zero if the access is not
870
   permitted.  */
871
static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
872
                           int is_user)
873
{
874
  int prot_ro;
875

    
876
  if (domain == 3)
877
    return PAGE_READ | PAGE_WRITE;
878

    
879
  if (access_type == 1)
880
      prot_ro = 0;
881
  else
882
      prot_ro = PAGE_READ;
883

    
884
  switch (ap) {
885
  case 0:
886
      if (access_type == 1)
887
          return 0;
888
      switch ((env->cp15.c1_sys >> 8) & 3) {
889
      case 1:
890
          return is_user ? 0 : PAGE_READ;
891
      case 2:
892
          return PAGE_READ;
893
      default:
894
          return 0;
895
      }
896
  case 1:
897
      return is_user ? 0 : PAGE_READ | PAGE_WRITE;
898
  case 2:
899
      if (is_user)
900
          return prot_ro;
901
      else
902
          return PAGE_READ | PAGE_WRITE;
903
  case 3:
904
      return PAGE_READ | PAGE_WRITE;
905
  case 4: /* Reserved.  */
906
      return 0;
907
  case 5:
908
      return is_user ? 0 : prot_ro;
909
  case 6:
910
      return prot_ro;
911
  case 7:
912
      if (!arm_feature (env, ARM_FEATURE_V7))
913
          return 0;
914
      return prot_ro;
915
  default:
916
      abort();
917
  }
918
}
919

    
920
static uint32_t get_level1_table_address(CPUState *env, uint32_t address)
921
{
922
    uint32_t table;
923

    
924
    if (address & env->cp15.c2_mask)
925
        table = env->cp15.c2_base1 & 0xffffc000;
926
    else
927
        table = env->cp15.c2_base0 & env->cp15.c2_base_mask;
928

    
929
    table |= (address >> 18) & 0x3ffc;
930
    return table;
931
}
932

    
933
static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
934
                            int is_user, uint32_t *phys_ptr, int *prot)
935
{
936
    int code;
937
    uint32_t table;
938
    uint32_t desc;
939
    int type;
940
    int ap;
941
    int domain;
942
    uint32_t phys_addr;
943

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

    
1020
static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
1021
                            int is_user, uint32_t *phys_ptr, int *prot)
1022
{
1023
    int code;
1024
    uint32_t table;
1025
    uint32_t desc;
1026
    uint32_t xn;
1027
    int type;
1028
    int ap;
1029
    int domain;
1030
    uint32_t phys_addr;
1031

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

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

    
1111
static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
1112
                             int is_user, uint32_t *phys_ptr, int *prot)
1113
{
1114
    int n;
1115
    uint32_t mask;
1116
    uint32_t base;
1117

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

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

    
1170
static inline int get_phys_addr(CPUState *env, uint32_t address,
1171
                                int access_type, int is_user,
1172
                                uint32_t *phys_ptr, int *prot)
1173
{
1174
    /* Fast Context Switch Extension.  */
1175
    if (address < 0x02000000)
1176
        address += env->cp15.c13_fcse;
1177

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

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

    
1202
    is_user = mmu_idx == MMU_USER_IDX;
1203
    ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
1204
    if (ret == 0) {
1205
        /* Map a single [sub]page.  */
1206
        phys_addr &= ~(uint32_t)0x3ff;
1207
        address &= ~(uint32_t)0x3ff;
1208
        return tlb_set_page (env, address, phys_addr, prot, mmu_idx,
1209
                             is_softmmu);
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
    int prot;
1230
    int ret;
1231

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

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

    
1237
    return phys_addr;
1238
}
1239

    
1240
/* Not really implemented.  Need to figure out a sane way of doing this.
1241
   Maybe add generic watchpoint support and use that.  */
1242

    
1243
void HELPER(mark_exclusive)(CPUState *env, uint32_t addr)
1244
{
1245
    env->mmon_addr = addr;
1246
}
1247

    
1248
uint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr)
1249
{
1250
    return (env->mmon_addr != addr);
1251
}
1252

    
1253
void HELPER(clrex)(CPUState *env)
1254
{
1255
    env->mmon_addr = -1;
1256
}
1257

    
1258
void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
1259
{
1260
    int cp_num = (insn >> 8) & 0xf;
1261
    int cp_info = (insn >> 5) & 7;
1262
    int src = (insn >> 16) & 0xf;
1263
    int operand = insn & 0xf;
1264

    
1265
    if (env->cp[cp_num].cp_write)
1266
        env->cp[cp_num].cp_write(env->cp[cp_num].opaque,
1267
                                 cp_info, src, operand, val);
1268
}
1269

    
1270
uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
1271
{
1272
    int cp_num = (insn >> 8) & 0xf;
1273
    int cp_info = (insn >> 5) & 7;
1274
    int dest = (insn >> 16) & 0xf;
1275
    int operand = insn & 0xf;
1276

    
1277
    if (env->cp[cp_num].cp_read)
1278
        return env->cp[cp_num].cp_read(env->cp[cp_num].opaque,
1279
                                       cp_info, dest, operand);
1280
    return 0;
1281
}
1282

    
1283
/* Return basic MPU access permission bits.  */
1284
static uint32_t simple_mpu_ap_bits(uint32_t val)
1285
{
1286
    uint32_t ret;
1287
    uint32_t mask;
1288
    int i;
1289
    ret = 0;
1290
    mask = 3;
1291
    for (i = 0; i < 16; i += 2) {
1292
        ret |= (val >> i) & mask;
1293
        mask <<= 2;
1294
    }
1295
    return ret;
1296
}
1297

    
1298
/* Pad basic MPU access permission bits to extended format.  */
1299
static uint32_t extended_mpu_ap_bits(uint32_t val)
1300
{
1301
    uint32_t ret;
1302
    uint32_t mask;
1303
    int i;
1304
    ret = 0;
1305
    mask = 3;
1306
    for (i = 0; i < 16; i += 2) {
1307
        ret |= (val & mask) << i;
1308
        mask <<= 2;
1309
    }
1310
    return ret;
1311
}
1312

    
1313
void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
1314
{
1315
    int op1;
1316
    int op2;
1317
    int crm;
1318

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

    
1602
uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
1603
{
1604
    int op1;
1605
    int op2;
1606
    int crm;
1607

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

    
1826
            goto bad_reg;
1827
        }
1828
        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1829
            switch (crm) {
1830
            case 0:
1831
                return 0;
1832
            case 1: /* Read TI925T configuration.  */
1833
                return env->cp15.c15_ticonfig;
1834
            case 2: /* Read I_max.  */
1835
                return env->cp15.c15_i_max;
1836
            case 3: /* Read I_min.  */
1837
                return env->cp15.c15_i_min;
1838
            case 4: /* Read thread-ID.  */
1839
                return env->cp15.c15_threadid;
1840
            case 8: /* TI925T_status */
1841
                return 0;
1842
            }
1843
            /* TODO: Peripheral port remap register:
1844
             * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt
1845
             * controller base address at $rn & ~0xfff and map size of
1846
             * 0x200 << ($rn & 0xfff), when MMU is off.  */
1847
            goto bad_reg;
1848
        }
1849
        return 0;
1850
    }
1851
bad_reg:
1852
    /* ??? For debugging only.  Should raise illegal instruction exception.  */
1853
    cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
1854
              (insn >> 16) & 0xf, crm, op1, op2);
1855
    return 0;
1856
}
1857

    
1858
void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
1859
{
1860
    env->banked_r13[bank_number(mode)] = val;
1861
}
1862

    
1863
uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
1864
{
1865
    return env->banked_r13[bank_number(mode)];
1866
}
1867

    
1868
uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
1869
{
1870
    switch (reg) {
1871
    case 0: /* APSR */
1872
        return xpsr_read(env) & 0xf8000000;
1873
    case 1: /* IAPSR */
1874
        return xpsr_read(env) & 0xf80001ff;
1875
    case 2: /* EAPSR */
1876
        return xpsr_read(env) & 0xff00fc00;
1877
    case 3: /* xPSR */
1878
        return xpsr_read(env) & 0xff00fdff;
1879
    case 5: /* IPSR */
1880
        return xpsr_read(env) & 0x000001ff;
1881
    case 6: /* EPSR */
1882
        return xpsr_read(env) & 0x0700fc00;
1883
    case 7: /* IEPSR */
1884
        return xpsr_read(env) & 0x0700edff;
1885
    case 8: /* MSP */
1886
        return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13];
1887
    case 9: /* PSP */
1888
        return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp;
1889
    case 16: /* PRIMASK */
1890
        return (env->uncached_cpsr & CPSR_I) != 0;
1891
    case 17: /* FAULTMASK */
1892
        return (env->uncached_cpsr & CPSR_F) != 0;
1893
    case 18: /* BASEPRI */
1894
    case 19: /* BASEPRI_MAX */
1895
        return env->v7m.basepri;
1896
    case 20: /* CONTROL */
1897
        return env->v7m.control;
1898
    default:
1899
        /* ??? For debugging only.  */
1900
        cpu_abort(env, "Unimplemented system register read (%d)\n", reg);
1901
        return 0;
1902
    }
1903
}
1904

    
1905
void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
1906
{
1907
    switch (reg) {
1908
    case 0: /* APSR */
1909
        xpsr_write(env, val, 0xf8000000);
1910
        break;
1911
    case 1: /* IAPSR */
1912
        xpsr_write(env, val, 0xf8000000);
1913
        break;
1914
    case 2: /* EAPSR */
1915
        xpsr_write(env, val, 0xfe00fc00);
1916
        break;
1917
    case 3: /* xPSR */
1918
        xpsr_write(env, val, 0xfe00fc00);
1919
        break;
1920
    case 5: /* IPSR */
1921
        /* IPSR bits are readonly.  */
1922
        break;
1923
    case 6: /* EPSR */
1924
        xpsr_write(env, val, 0x0600fc00);
1925
        break;
1926
    case 7: /* IEPSR */
1927
        xpsr_write(env, val, 0x0600fc00);
1928
        break;
1929
    case 8: /* MSP */
1930
        if (env->v7m.current_sp)
1931
            env->v7m.other_sp = val;
1932
        else
1933
            env->regs[13] = val;
1934
        break;
1935
    case 9: /* PSP */
1936
        if (env->v7m.current_sp)
1937
            env->regs[13] = val;
1938
        else
1939
            env->v7m.other_sp = val;
1940
        break;
1941
    case 16: /* PRIMASK */
1942
        if (val & 1)
1943
            env->uncached_cpsr |= CPSR_I;
1944
        else
1945
            env->uncached_cpsr &= ~CPSR_I;
1946
        break;
1947
    case 17: /* FAULTMASK */
1948
        if (val & 1)
1949
            env->uncached_cpsr |= CPSR_F;
1950
        else
1951
            env->uncached_cpsr &= ~CPSR_F;
1952
        break;
1953
    case 18: /* BASEPRI */
1954
        env->v7m.basepri = val & 0xff;
1955
        break;
1956
    case 19: /* BASEPRI_MAX */
1957
        val &= 0xff;
1958
        if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
1959
            env->v7m.basepri = val;
1960
        break;
1961
    case 20: /* CONTROL */
1962
        env->v7m.control = val & 3;
1963
        switch_v7m_sp(env, (val & 2) != 0);
1964
        break;
1965
    default:
1966
        /* ??? For debugging only.  */
1967
        cpu_abort(env, "Unimplemented system register write (%d)\n", reg);
1968
        return;
1969
    }
1970
}
1971

    
1972
void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
1973
                ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
1974
                void *opaque)
1975
{
1976
    if (cpnum < 0 || cpnum > 14) {
1977
        cpu_abort(env, "Bad coprocessor number: %i\n", cpnum);
1978
        return;
1979
    }
1980

    
1981
    env->cp[cpnum].cp_read = cp_read;
1982
    env->cp[cpnum].cp_write = cp_write;
1983
    env->cp[cpnum].opaque = opaque;
1984
}
1985

    
1986
#endif
1987

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

    
1992
/* Signed saturating arithmetic.  */
1993

    
1994
/* Perform 16-bit signed saturating addition.  */
1995
static inline uint16_t add16_sat(uint16_t a, uint16_t b)
1996
{
1997
    uint16_t res;
1998

    
1999
    res = a + b;
2000
    if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
2001
        if (a & 0x8000)
2002
            res = 0x8000;
2003
        else
2004
            res = 0x7fff;
2005
    }
2006
    return res;
2007
}
2008

    
2009
/* Perform 8-bit signed saturating addition.  */
2010
static inline uint8_t add8_sat(uint8_t a, uint8_t b)
2011
{
2012
    uint8_t res;
2013

    
2014
    res = a + b;
2015
    if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
2016
        if (a & 0x80)
2017
            res = 0x80;
2018
        else
2019
            res = 0x7f;
2020
    }
2021
    return res;
2022
}
2023

    
2024
/* Perform 16-bit signed saturating subtraction.  */
2025
static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
2026
{
2027
    uint16_t res;
2028

    
2029
    res = a - b;
2030
    if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
2031
        if (a & 0x8000)
2032
            res = 0x8000;
2033
        else
2034
            res = 0x7fff;
2035
    }
2036
    return res;
2037
}
2038

    
2039
/* Perform 8-bit signed saturating subtraction.  */
2040
static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
2041
{
2042
    uint8_t res;
2043

    
2044
    res = a - b;
2045
    if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
2046
        if (a & 0x80)
2047
            res = 0x80;
2048
        else
2049
            res = 0x7f;
2050
    }
2051
    return res;
2052
}
2053

    
2054
#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
2055
#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
2056
#define ADD8(a, b, n)  RESULT(add8_sat(a, b), n, 8);
2057
#define SUB8(a, b, n)  RESULT(sub8_sat(a, b), n, 8);
2058
#define PFX q
2059

    
2060
#include "op_addsub.h"
2061

    
2062
/* Unsigned saturating arithmetic.  */
2063
static inline uint16_t add16_usat(uint16_t a, uint16_t b)
2064
{
2065
    uint16_t res;
2066
    res = a + b;
2067
    if (res < a)
2068
        res = 0xffff;
2069
    return res;
2070
}
2071

    
2072
static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
2073
{
2074
    if (a < b)
2075
        return a - b;
2076
    else
2077
        return 0;
2078
}
2079

    
2080
static inline uint8_t add8_usat(uint8_t a, uint8_t b)
2081
{
2082
    uint8_t res;
2083
    res = a + b;
2084
    if (res < a)
2085
        res = 0xff;
2086
    return res;
2087
}
2088

    
2089
static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
2090
{
2091
    if (a < b)
2092
        return a - b;
2093
    else
2094
        return 0;
2095
}
2096

    
2097
#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
2098
#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
2099
#define ADD8(a, b, n)  RESULT(add8_usat(a, b), n, 8);
2100
#define SUB8(a, b, n)  RESULT(sub8_usat(a, b), n, 8);
2101
#define PFX uq
2102

    
2103
#include "op_addsub.h"
2104

    
2105
/* Signed modulo arithmetic.  */
2106
#define SARITH16(a, b, n, op) do { \
2107
    int32_t sum; \
2108
    sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \
2109
    RESULT(sum, n, 16); \
2110
    if (sum >= 0) \
2111
        ge |= 3 << (n * 2); \
2112
    } while(0)
2113

    
2114
#define SARITH8(a, b, n, op) do { \
2115
    int32_t sum; \
2116
    sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \
2117
    RESULT(sum, n, 8); \
2118
    if (sum >= 0) \
2119
        ge |= 1 << n; \
2120
    } while(0)
2121

    
2122

    
2123
#define ADD16(a, b, n) SARITH16(a, b, n, +)
2124
#define SUB16(a, b, n) SARITH16(a, b, n, -)
2125
#define ADD8(a, b, n)  SARITH8(a, b, n, +)
2126
#define SUB8(a, b, n)  SARITH8(a, b, n, -)
2127
#define PFX s
2128
#define ARITH_GE
2129

    
2130
#include "op_addsub.h"
2131

    
2132
/* Unsigned modulo arithmetic.  */
2133
#define ADD16(a, b, n) do { \
2134
    uint32_t sum; \
2135
    sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
2136
    RESULT(sum, n, 16); \
2137
    if ((sum >> 16) == 1) \
2138
        ge |= 3 << (n * 2); \
2139
    } while(0)
2140

    
2141
#define ADD8(a, b, n) do { \
2142
    uint32_t sum; \
2143
    sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
2144
    RESULT(sum, n, 8); \
2145
    if ((sum >> 8) == 1) \
2146
        ge |= 1 << n; \
2147
    } while(0)
2148

    
2149
#define SUB16(a, b, n) do { \
2150
    uint32_t sum; \
2151
    sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
2152
    RESULT(sum, n, 16); \
2153
    if ((sum >> 16) == 0) \
2154
        ge |= 3 << (n * 2); \
2155
    } while(0)
2156

    
2157
#define SUB8(a, b, n) do { \
2158
    uint32_t sum; \
2159
    sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
2160
    RESULT(sum, n, 8); \
2161
    if ((sum >> 8) == 0) \
2162
        ge |= 1 << n; \
2163
    } while(0)
2164

    
2165
#define PFX u
2166
#define ARITH_GE
2167

    
2168
#include "op_addsub.h"
2169

    
2170
/* Halved signed arithmetic.  */
2171
#define ADD16(a, b, n) \
2172
  RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
2173
#define SUB16(a, b, n) \
2174
  RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
2175
#define ADD8(a, b, n) \
2176
  RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
2177
#define SUB8(a, b, n) \
2178
  RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
2179
#define PFX sh
2180

    
2181
#include "op_addsub.h"
2182

    
2183
/* Halved unsigned arithmetic.  */
2184
#define ADD16(a, b, n) \
2185
  RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2186
#define SUB16(a, b, n) \
2187
  RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2188
#define ADD8(a, b, n) \
2189
  RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2190
#define SUB8(a, b, n) \
2191
  RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2192
#define PFX uh
2193

    
2194
#include "op_addsub.h"
2195

    
2196
static inline uint8_t do_usad(uint8_t a, uint8_t b)
2197
{
2198
    if (a > b)
2199
        return a - b;
2200
    else
2201
        return b - a;
2202
}
2203

    
2204
/* Unsigned sum of absolute byte differences.  */
2205
uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
2206
{
2207
    uint32_t sum;
2208
    sum = do_usad(a, b);
2209
    sum += do_usad(a >> 8, b >> 8);
2210
    sum += do_usad(a >> 16, b >>16);
2211
    sum += do_usad(a >> 24, b >> 24);
2212
    return sum;
2213
}
2214

    
2215
/* For ARMv6 SEL instruction.  */
2216
uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
2217
{
2218
    uint32_t mask;
2219

    
2220
    mask = 0;
2221
    if (flags & 1)
2222
        mask |= 0xff;
2223
    if (flags & 2)
2224
        mask |= 0xff00;
2225
    if (flags & 4)
2226
        mask |= 0xff0000;
2227
    if (flags & 8)
2228
        mask |= 0xff000000;
2229
    return (a & mask) | (b & ~mask);
2230
}
2231

    
2232
uint32_t HELPER(logicq_cc)(uint64_t val)
2233
{
2234
    return (val >> 32) | (val != 0);
2235
}
2236

    
2237
/* VFP support.  We follow the convention used for VFP instrunctions:
2238
   Single precition routines have a "s" suffix, double precision a
2239
   "d" suffix.  */
2240

    
2241
/* Convert host exception flags to vfp form.  */
2242
static inline int vfp_exceptbits_from_host(int host_bits)
2243
{
2244
    int target_bits = 0;
2245

    
2246
    if (host_bits & float_flag_invalid)
2247
        target_bits |= 1;
2248
    if (host_bits & float_flag_divbyzero)
2249
        target_bits |= 2;
2250
    if (host_bits & float_flag_overflow)
2251
        target_bits |= 4;
2252
    if (host_bits & float_flag_underflow)
2253
        target_bits |= 8;
2254
    if (host_bits & float_flag_inexact)
2255
        target_bits |= 0x10;
2256
    return target_bits;
2257
}
2258

    
2259
uint32_t HELPER(vfp_get_fpscr)(CPUState *env)
2260
{
2261
    int i;
2262
    uint32_t fpscr;
2263

    
2264
    fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
2265
            | (env->vfp.vec_len << 16)
2266
            | (env->vfp.vec_stride << 20);
2267
    i = get_float_exception_flags(&env->vfp.fp_status);
2268
    fpscr |= vfp_exceptbits_from_host(i);
2269
    return fpscr;
2270
}
2271

    
2272
/* Convert vfp exception flags to target form.  */
2273
static inline int vfp_exceptbits_to_host(int target_bits)
2274
{
2275
    int host_bits = 0;
2276

    
2277
    if (target_bits & 1)
2278
        host_bits |= float_flag_invalid;
2279
    if (target_bits & 2)
2280
        host_bits |= float_flag_divbyzero;
2281
    if (target_bits & 4)
2282
        host_bits |= float_flag_overflow;
2283
    if (target_bits & 8)
2284
        host_bits |= float_flag_underflow;
2285
    if (target_bits & 0x10)
2286
        host_bits |= float_flag_inexact;
2287
    return host_bits;
2288
}
2289

    
2290
void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
2291
{
2292
    int i;
2293
    uint32_t changed;
2294

    
2295
    changed = env->vfp.xregs[ARM_VFP_FPSCR];
2296
    env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
2297
    env->vfp.vec_len = (val >> 16) & 7;
2298
    env->vfp.vec_stride = (val >> 20) & 3;
2299

    
2300
    changed ^= val;
2301
    if (changed & (3 << 22)) {
2302
        i = (val >> 22) & 3;
2303
        switch (i) {
2304
        case 0:
2305
            i = float_round_nearest_even;
2306
            break;
2307
        case 1:
2308
            i = float_round_up;
2309
            break;
2310
        case 2:
2311
            i = float_round_down;
2312
            break;
2313
        case 3:
2314
            i = float_round_to_zero;
2315
            break;
2316
        }
2317
        set_float_rounding_mode(i, &env->vfp.fp_status);
2318
    }
2319

    
2320
    i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
2321
    set_float_exception_flags(i, &env->vfp.fp_status);
2322
    /* XXX: FZ and DN are not implemented.  */
2323
}
2324

    
2325
#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
2326

    
2327
#define VFP_BINOP(name) \
2328
float32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \
2329
{ \
2330
    return float32_ ## name (a, b, &env->vfp.fp_status); \
2331
} \
2332
float64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \
2333
{ \
2334
    return float64_ ## name (a, b, &env->vfp.fp_status); \
2335
}
2336
VFP_BINOP(add)
2337
VFP_BINOP(sub)
2338
VFP_BINOP(mul)
2339
VFP_BINOP(div)
2340
#undef VFP_BINOP
2341

    
2342
float32 VFP_HELPER(neg, s)(float32 a)
2343
{
2344
    return float32_chs(a);
2345
}
2346

    
2347
float64 VFP_HELPER(neg, d)(float64 a)
2348
{
2349
    return float64_chs(a);
2350
}
2351

    
2352
float32 VFP_HELPER(abs, s)(float32 a)
2353
{
2354
    return float32_abs(a);
2355
}
2356

    
2357
float64 VFP_HELPER(abs, d)(float64 a)
2358
{
2359
    return float64_abs(a);
2360
}
2361

    
2362
float32 VFP_HELPER(sqrt, s)(float32 a, CPUState *env)
2363
{
2364
    return float32_sqrt(a, &env->vfp.fp_status);
2365
}
2366

    
2367
float64 VFP_HELPER(sqrt, d)(float64 a, CPUState *env)
2368
{
2369
    return float64_sqrt(a, &env->vfp.fp_status);
2370
}
2371

    
2372
/* XXX: check quiet/signaling case */
2373
#define DO_VFP_cmp(p, type) \
2374
void VFP_HELPER(cmp, p)(type a, type b, CPUState *env)  \
2375
{ \
2376
    uint32_t flags; \
2377
    switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
2378
    case 0: flags = 0x6; break; \
2379
    case -1: flags = 0x8; break; \
2380
    case 1: flags = 0x2; break; \
2381
    default: case 2: flags = 0x3; break; \
2382
    } \
2383
    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2384
        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2385
} \
2386
void VFP_HELPER(cmpe, p)(type a, type b, CPUState *env) \
2387
{ \
2388
    uint32_t flags; \
2389
    switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
2390
    case 0: flags = 0x6; break; \
2391
    case -1: flags = 0x8; break; \
2392
    case 1: flags = 0x2; break; \
2393
    default: case 2: flags = 0x3; break; \
2394
    } \
2395
    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2396
        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2397
}
2398
DO_VFP_cmp(s, float32)
2399
DO_VFP_cmp(d, float64)
2400
#undef DO_VFP_cmp
2401

    
2402
/* Helper routines to perform bitwise copies between float and int.  */
2403
static inline float32 vfp_itos(uint32_t i)
2404
{
2405
    union {
2406
        uint32_t i;
2407
        float32 s;
2408
    } v;
2409

    
2410
    v.i = i;
2411
    return v.s;
2412
}
2413

    
2414
static inline uint32_t vfp_stoi(float32 s)
2415
{
2416
    union {
2417
        uint32_t i;
2418
        float32 s;
2419
    } v;
2420

    
2421
    v.s = s;
2422
    return v.i;
2423
}
2424

    
2425
static inline float64 vfp_itod(uint64_t i)
2426
{
2427
    union {
2428
        uint64_t i;
2429
        float64 d;
2430
    } v;
2431

    
2432
    v.i = i;
2433
    return v.d;
2434
}
2435

    
2436
static inline uint64_t vfp_dtoi(float64 d)
2437
{
2438
    union {
2439
        uint64_t i;
2440
        float64 d;
2441
    } v;
2442

    
2443
    v.d = d;
2444
    return v.i;
2445
}
2446

    
2447
/* Integer to float conversion.  */
2448
float32 VFP_HELPER(uito, s)(float32 x, CPUState *env)
2449
{
2450
    return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
2451
}
2452

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

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

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

    
2468
/* Float to integer conversion.  */
2469
float32 VFP_HELPER(toui, s)(float32 x, CPUState *env)
2470
{
2471
    return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status));
2472
}
2473

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

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

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

    
2489
float32 VFP_HELPER(touiz, s)(float32 x, CPUState *env)
2490
{
2491
    return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status));
2492
}
2493

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

    
2499
float32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
2500
{
2501
    return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status));
2502
}
2503

    
2504
float32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
2505
{
2506
    return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status));
2507
}
2508

    
2509
/* floating point conversion */
2510
float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env)
2511
{
2512
    return float32_to_float64(x, &env->vfp.fp_status);
2513
}
2514

    
2515
float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env)
2516
{
2517
    return float64_to_float32(x, &env->vfp.fp_status);
2518
}
2519

    
2520
/* VFP3 fixed point conversion.  */
2521
#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
2522
ftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \
2523
{ \
2524
    ftype tmp; \
2525
    tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(x), \
2526
                                  &env->vfp.fp_status); \
2527
    return ftype##_scalbn(tmp, -(int)shift, &env->vfp.fp_status); \
2528
} \
2529
ftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \
2530
{ \
2531
    ftype tmp; \
2532
    tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \
2533
    return vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
2534
        &env->vfp.fp_status)); \
2535
}
2536

    
2537
VFP_CONV_FIX(sh, d, float64, int16, )
2538
VFP_CONV_FIX(sl, d, float64, int32, )
2539
VFP_CONV_FIX(uh, d, float64, uint16, u)
2540
VFP_CONV_FIX(ul, d, float64, uint32, u)
2541
VFP_CONV_FIX(sh, s, float32, int16, )
2542
VFP_CONV_FIX(sl, s, float32, int32, )
2543
VFP_CONV_FIX(uh, s, float32, uint16, u)
2544
VFP_CONV_FIX(ul, s, float32, uint32, u)
2545
#undef VFP_CONV_FIX
2546

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

    
2554
float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env)
2555
{
2556
    float_status *s = &env->vfp.fp_status;
2557
    float32 three = int32_to_float32(3, s);
2558
    return float32_sub(three, float32_mul(a, b, s), s);
2559
}
2560

    
2561
/* NEON helpers.  */
2562

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

    
2572
float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
2573
{
2574
    float_status *s = &env->vfp.fp_status;
2575
    float32 one = int32_to_float32(1, s);
2576
    return float32_div(one, float32_sqrt(a, s), s);
2577
}
2578

    
2579
uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
2580
{
2581
    float_status *s = &env->vfp.fp_status;
2582
    float32 tmp;
2583
    tmp = int32_to_float32(a, s);
2584
    tmp = float32_scalbn(tmp, -32, s);
2585
    tmp = helper_recpe_f32(tmp, env);
2586
    tmp = float32_scalbn(tmp, 31, s);
2587
    return float32_to_int32(tmp, s);
2588
}
2589

    
2590
uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
2591
{
2592
    float_status *s = &env->vfp.fp_status;
2593
    float32 tmp;
2594
    tmp = int32_to_float32(a, s);
2595
    tmp = float32_scalbn(tmp, -32, s);
2596
    tmp = helper_rsqrte_f32(tmp, env);
2597
    tmp = float32_scalbn(tmp, 31, s);
2598
    return float32_to_int32(tmp, s);
2599
}
2600

    
2601
void HELPER(set_teecr)(CPUState *env, uint32_t val)
2602
{
2603
    val &= 1;
2604
    if (env->teecr != val) {
2605
        env->teecr = val;
2606
        tb_flush(env);
2607
    }
2608
}