Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 41ba8341

History | View | Annotate | Download (312.3 kB)

1
/*
2
 *  ARM translation
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *  Copyright (c) 2005-2007 CodeSourcery
6
 *  Copyright (c) 2007 OpenedHand, Ltd.
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20
 */
21
#include <stdarg.h>
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <string.h>
25
#include <inttypes.h>
26

    
27
#include "cpu.h"
28
#include "exec-all.h"
29
#include "disas.h"
30
#include "tcg-op.h"
31
#include "qemu-log.h"
32

    
33
#include "helpers.h"
34
#define GEN_HELPER 1
35
#include "helpers.h"
36

    
37
#define ENABLE_ARCH_5J    0
38
#define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
39
#define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
40
#define ENABLE_ARCH_6T2   arm_feature(env, ARM_FEATURE_THUMB2)
41
#define ENABLE_ARCH_7     arm_feature(env, ARM_FEATURE_V7)
42

    
43
#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
44

    
45
/* internal defines */
46
typedef struct DisasContext {
47
    target_ulong pc;
48
    int is_jmp;
49
    /* Nonzero if this instruction has been conditionally skipped.  */
50
    int condjmp;
51
    /* The label that will be jumped to when the instruction is skipped.  */
52
    int condlabel;
53
    /* Thumb-2 condtional execution bits.  */
54
    int condexec_mask;
55
    int condexec_cond;
56
    struct TranslationBlock *tb;
57
    int singlestep_enabled;
58
    int thumb;
59
#if !defined(CONFIG_USER_ONLY)
60
    int user;
61
#endif
62
} DisasContext;
63

    
64
#if defined(CONFIG_USER_ONLY)
65
#define IS_USER(s) 1
66
#else
67
#define IS_USER(s) (s->user)
68
#endif
69

    
70
/* These instructions trap after executing, so defer them until after the
71
   conditional executions state has been updated.  */
72
#define DISAS_WFI 4
73
#define DISAS_SWI 5
74

    
75
static TCGv_ptr cpu_env;
76
/* We reuse the same 64-bit temporaries for efficiency.  */
77
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
78
static TCGv_i32 cpu_R[16];
79
static TCGv_i32 cpu_exclusive_addr;
80
static TCGv_i32 cpu_exclusive_val;
81
static TCGv_i32 cpu_exclusive_high;
82
#ifdef CONFIG_USER_ONLY
83
static TCGv_i32 cpu_exclusive_test;
84
static TCGv_i32 cpu_exclusive_info;
85
#endif
86

    
87
/* FIXME:  These should be removed.  */
88
static TCGv cpu_F0s, cpu_F1s;
89
static TCGv_i64 cpu_F0d, cpu_F1d;
90

    
91
#include "gen-icount.h"
92

    
93
static const char *regnames[] =
94
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
95
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
96

    
97
/* initialize TCG globals.  */
98
void arm_translate_init(void)
99
{
100
    int i;
101

    
102
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
103

    
104
    for (i = 0; i < 16; i++) {
105
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
106
                                          offsetof(CPUState, regs[i]),
107
                                          regnames[i]);
108
    }
109
    cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
110
        offsetof(CPUState, exclusive_addr), "exclusive_addr");
111
    cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
112
        offsetof(CPUState, exclusive_val), "exclusive_val");
113
    cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
114
        offsetof(CPUState, exclusive_high), "exclusive_high");
115
#ifdef CONFIG_USER_ONLY
116
    cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
117
        offsetof(CPUState, exclusive_test), "exclusive_test");
118
    cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
119
        offsetof(CPUState, exclusive_info), "exclusive_info");
120
#endif
121

    
122
#define GEN_HELPER 2
123
#include "helpers.h"
124
}
125

    
126
static int num_temps;
127

    
128
/* Allocate a temporary variable.  */
129
static TCGv_i32 new_tmp(void)
130
{
131
    num_temps++;
132
    return tcg_temp_new_i32();
133
}
134

    
135
/* Release a temporary variable.  */
136
static void dead_tmp(TCGv tmp)
137
{
138
    tcg_temp_free(tmp);
139
    num_temps--;
140
}
141

    
142
static inline TCGv load_cpu_offset(int offset)
143
{
144
    TCGv tmp = new_tmp();
145
    tcg_gen_ld_i32(tmp, cpu_env, offset);
146
    return tmp;
147
}
148

    
149
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
150

    
151
static inline void store_cpu_offset(TCGv var, int offset)
152
{
153
    tcg_gen_st_i32(var, cpu_env, offset);
154
    dead_tmp(var);
155
}
156

    
157
#define store_cpu_field(var, name) \
158
    store_cpu_offset(var, offsetof(CPUState, name))
159

    
160
/* Set a variable to the value of a CPU register.  */
161
static void load_reg_var(DisasContext *s, TCGv var, int reg)
162
{
163
    if (reg == 15) {
164
        uint32_t addr;
165
        /* normaly, since we updated PC, we need only to add one insn */
166
        if (s->thumb)
167
            addr = (long)s->pc + 2;
168
        else
169
            addr = (long)s->pc + 4;
170
        tcg_gen_movi_i32(var, addr);
171
    } else {
172
        tcg_gen_mov_i32(var, cpu_R[reg]);
173
    }
174
}
175

    
176
/* Create a new temporary and set it to the value of a CPU register.  */
177
static inline TCGv load_reg(DisasContext *s, int reg)
178
{
179
    TCGv tmp = new_tmp();
180
    load_reg_var(s, tmp, reg);
181
    return tmp;
182
}
183

    
184
/* Set a CPU register.  The source must be a temporary and will be
185
   marked as dead.  */
186
static void store_reg(DisasContext *s, int reg, TCGv var)
187
{
188
    if (reg == 15) {
189
        tcg_gen_andi_i32(var, var, ~1);
190
        s->is_jmp = DISAS_JUMP;
191
    }
192
    tcg_gen_mov_i32(cpu_R[reg], var);
193
    dead_tmp(var);
194
}
195

    
196
/* Value extensions.  */
197
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
198
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
199
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
200
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
201

    
202
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
203
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
204

    
205

    
206
static inline void gen_set_cpsr(TCGv var, uint32_t mask)
207
{
208
    TCGv tmp_mask = tcg_const_i32(mask);
209
    gen_helper_cpsr_write(var, tmp_mask);
210
    tcg_temp_free_i32(tmp_mask);
211
}
212
/* Set NZCV flags from the high 4 bits of var.  */
213
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
214

    
215
static void gen_exception(int excp)
216
{
217
    TCGv tmp = new_tmp();
218
    tcg_gen_movi_i32(tmp, excp);
219
    gen_helper_exception(tmp);
220
    dead_tmp(tmp);
221
}
222

    
223
static void gen_smul_dual(TCGv a, TCGv b)
224
{
225
    TCGv tmp1 = new_tmp();
226
    TCGv tmp2 = new_tmp();
227
    tcg_gen_ext16s_i32(tmp1, a);
228
    tcg_gen_ext16s_i32(tmp2, b);
229
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
230
    dead_tmp(tmp2);
231
    tcg_gen_sari_i32(a, a, 16);
232
    tcg_gen_sari_i32(b, b, 16);
233
    tcg_gen_mul_i32(b, b, a);
234
    tcg_gen_mov_i32(a, tmp1);
235
    dead_tmp(tmp1);
236
}
237

    
238
/* Byteswap each halfword.  */
239
static void gen_rev16(TCGv var)
240
{
241
    TCGv tmp = new_tmp();
242
    tcg_gen_shri_i32(tmp, var, 8);
243
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
244
    tcg_gen_shli_i32(var, var, 8);
245
    tcg_gen_andi_i32(var, var, 0xff00ff00);
246
    tcg_gen_or_i32(var, var, tmp);
247
    dead_tmp(tmp);
248
}
249

    
250
/* Byteswap low halfword and sign extend.  */
251
static void gen_revsh(TCGv var)
252
{
253
    TCGv tmp = new_tmp();
254
    tcg_gen_shri_i32(tmp, var, 8);
255
    tcg_gen_andi_i32(tmp, tmp, 0x00ff);
256
    tcg_gen_shli_i32(var, var, 8);
257
    tcg_gen_ext8s_i32(var, var);
258
    tcg_gen_or_i32(var, var, tmp);
259
    dead_tmp(tmp);
260
}
261

    
262
/* Unsigned bitfield extract.  */
263
static void gen_ubfx(TCGv var, int shift, uint32_t mask)
264
{
265
    if (shift)
266
        tcg_gen_shri_i32(var, var, shift);
267
    tcg_gen_andi_i32(var, var, mask);
268
}
269

    
270
/* Signed bitfield extract.  */
271
static void gen_sbfx(TCGv var, int shift, int width)
272
{
273
    uint32_t signbit;
274

    
275
    if (shift)
276
        tcg_gen_sari_i32(var, var, shift);
277
    if (shift + width < 32) {
278
        signbit = 1u << (width - 1);
279
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
280
        tcg_gen_xori_i32(var, var, signbit);
281
        tcg_gen_subi_i32(var, var, signbit);
282
    }
283
}
284

    
285
/* Bitfield insertion.  Insert val into base.  Clobbers base and val.  */
286
static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
287
{
288
    tcg_gen_andi_i32(val, val, mask);
289
    tcg_gen_shli_i32(val, val, shift);
290
    tcg_gen_andi_i32(base, base, ~(mask << shift));
291
    tcg_gen_or_i32(dest, base, val);
292
}
293

    
294
/* Round the top 32 bits of a 64-bit value.  */
295
static void gen_roundqd(TCGv a, TCGv b)
296
{
297
    tcg_gen_shri_i32(a, a, 31);
298
    tcg_gen_add_i32(a, a, b);
299
}
300

    
301
/* FIXME: Most targets have native widening multiplication.
302
   It would be good to use that instead of a full wide multiply.  */
303
/* 32x32->64 multiply.  Marks inputs as dead.  */
304
static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
305
{
306
    TCGv_i64 tmp1 = tcg_temp_new_i64();
307
    TCGv_i64 tmp2 = tcg_temp_new_i64();
308

    
309
    tcg_gen_extu_i32_i64(tmp1, a);
310
    dead_tmp(a);
311
    tcg_gen_extu_i32_i64(tmp2, b);
312
    dead_tmp(b);
313
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
314
    tcg_temp_free_i64(tmp2);
315
    return tmp1;
316
}
317

    
318
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
319
{
320
    TCGv_i64 tmp1 = tcg_temp_new_i64();
321
    TCGv_i64 tmp2 = tcg_temp_new_i64();
322

    
323
    tcg_gen_ext_i32_i64(tmp1, a);
324
    dead_tmp(a);
325
    tcg_gen_ext_i32_i64(tmp2, b);
326
    dead_tmp(b);
327
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
328
    tcg_temp_free_i64(tmp2);
329
    return tmp1;
330
}
331

    
332
/* Signed 32x32->64 multiply.  */
333
static void gen_imull(TCGv a, TCGv b)
334
{
335
    TCGv_i64 tmp1 = tcg_temp_new_i64();
336
    TCGv_i64 tmp2 = tcg_temp_new_i64();
337

    
338
    tcg_gen_ext_i32_i64(tmp1, a);
339
    tcg_gen_ext_i32_i64(tmp2, b);
340
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
341
    tcg_temp_free_i64(tmp2);
342
    tcg_gen_trunc_i64_i32(a, tmp1);
343
    tcg_gen_shri_i64(tmp1, tmp1, 32);
344
    tcg_gen_trunc_i64_i32(b, tmp1);
345
    tcg_temp_free_i64(tmp1);
346
}
347

    
348
/* Swap low and high halfwords.  */
349
static void gen_swap_half(TCGv var)
350
{
351
    TCGv tmp = new_tmp();
352
    tcg_gen_shri_i32(tmp, var, 16);
353
    tcg_gen_shli_i32(var, var, 16);
354
    tcg_gen_or_i32(var, var, tmp);
355
    dead_tmp(tmp);
356
}
357

    
358
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
359
    tmp = (t0 ^ t1) & 0x8000;
360
    t0 &= ~0x8000;
361
    t1 &= ~0x8000;
362
    t0 = (t0 + t1) ^ tmp;
363
 */
364

    
365
static void gen_add16(TCGv t0, TCGv t1)
366
{
367
    TCGv tmp = new_tmp();
368
    tcg_gen_xor_i32(tmp, t0, t1);
369
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
370
    tcg_gen_andi_i32(t0, t0, ~0x8000);
371
    tcg_gen_andi_i32(t1, t1, ~0x8000);
372
    tcg_gen_add_i32(t0, t0, t1);
373
    tcg_gen_xor_i32(t0, t0, tmp);
374
    dead_tmp(tmp);
375
    dead_tmp(t1);
376
}
377

    
378
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
379

    
380
/* Set CF to the top bit of var.  */
381
static void gen_set_CF_bit31(TCGv var)
382
{
383
    TCGv tmp = new_tmp();
384
    tcg_gen_shri_i32(tmp, var, 31);
385
    gen_set_CF(tmp);
386
    dead_tmp(tmp);
387
}
388

    
389
/* Set N and Z flags from var.  */
390
static inline void gen_logic_CC(TCGv var)
391
{
392
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
393
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
394
}
395

    
396
/* T0 += T1 + CF.  */
397
static void gen_adc(TCGv t0, TCGv t1)
398
{
399
    TCGv tmp;
400
    tcg_gen_add_i32(t0, t0, t1);
401
    tmp = load_cpu_field(CF);
402
    tcg_gen_add_i32(t0, t0, tmp);
403
    dead_tmp(tmp);
404
}
405

    
406
/* dest = T0 + T1 + CF. */
407
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
408
{
409
    TCGv tmp;
410
    tcg_gen_add_i32(dest, t0, t1);
411
    tmp = load_cpu_field(CF);
412
    tcg_gen_add_i32(dest, dest, tmp);
413
    dead_tmp(tmp);
414
}
415

    
416
/* dest = T0 - T1 + CF - 1.  */
417
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
418
{
419
    TCGv tmp;
420
    tcg_gen_sub_i32(dest, t0, t1);
421
    tmp = load_cpu_field(CF);
422
    tcg_gen_add_i32(dest, dest, tmp);
423
    tcg_gen_subi_i32(dest, dest, 1);
424
    dead_tmp(tmp);
425
}
426

    
427
/* FIXME:  Implement this natively.  */
428
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
429

    
430
static void shifter_out_im(TCGv var, int shift)
431
{
432
    TCGv tmp = new_tmp();
433
    if (shift == 0) {
434
        tcg_gen_andi_i32(tmp, var, 1);
435
    } else {
436
        tcg_gen_shri_i32(tmp, var, shift);
437
        if (shift != 31)
438
            tcg_gen_andi_i32(tmp, tmp, 1);
439
    }
440
    gen_set_CF(tmp);
441
    dead_tmp(tmp);
442
}
443

    
444
/* Shift by immediate.  Includes special handling for shift == 0.  */
445
static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
446
{
447
    switch (shiftop) {
448
    case 0: /* LSL */
449
        if (shift != 0) {
450
            if (flags)
451
                shifter_out_im(var, 32 - shift);
452
            tcg_gen_shli_i32(var, var, shift);
453
        }
454
        break;
455
    case 1: /* LSR */
456
        if (shift == 0) {
457
            if (flags) {
458
                tcg_gen_shri_i32(var, var, 31);
459
                gen_set_CF(var);
460
            }
461
            tcg_gen_movi_i32(var, 0);
462
        } else {
463
            if (flags)
464
                shifter_out_im(var, shift - 1);
465
            tcg_gen_shri_i32(var, var, shift);
466
        }
467
        break;
468
    case 2: /* ASR */
469
        if (shift == 0)
470
            shift = 32;
471
        if (flags)
472
            shifter_out_im(var, shift - 1);
473
        if (shift == 32)
474
          shift = 31;
475
        tcg_gen_sari_i32(var, var, shift);
476
        break;
477
    case 3: /* ROR/RRX */
478
        if (shift != 0) {
479
            if (flags)
480
                shifter_out_im(var, shift - 1);
481
            tcg_gen_rotri_i32(var, var, shift); break;
482
        } else {
483
            TCGv tmp = load_cpu_field(CF);
484
            if (flags)
485
                shifter_out_im(var, 0);
486
            tcg_gen_shri_i32(var, var, 1);
487
            tcg_gen_shli_i32(tmp, tmp, 31);
488
            tcg_gen_or_i32(var, var, tmp);
489
            dead_tmp(tmp);
490
        }
491
    }
492
};
493

    
494
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
495
                                     TCGv shift, int flags)
496
{
497
    if (flags) {
498
        switch (shiftop) {
499
        case 0: gen_helper_shl_cc(var, var, shift); break;
500
        case 1: gen_helper_shr_cc(var, var, shift); break;
501
        case 2: gen_helper_sar_cc(var, var, shift); break;
502
        case 3: gen_helper_ror_cc(var, var, shift); break;
503
        }
504
    } else {
505
        switch (shiftop) {
506
        case 0: gen_helper_shl(var, var, shift); break;
507
        case 1: gen_helper_shr(var, var, shift); break;
508
        case 2: gen_helper_sar(var, var, shift); break;
509
        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
510
                tcg_gen_rotr_i32(var, var, shift); break;
511
        }
512
    }
513
    dead_tmp(shift);
514
}
515

    
516
#define PAS_OP(pfx) \
517
    switch (op2) {  \
518
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
519
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
520
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
521
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
522
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
523
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
524
    }
525
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
526
{
527
    TCGv_ptr tmp;
528

    
529
    switch (op1) {
530
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
531
    case 1:
532
        tmp = tcg_temp_new_ptr();
533
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
534
        PAS_OP(s)
535
        tcg_temp_free_ptr(tmp);
536
        break;
537
    case 5:
538
        tmp = tcg_temp_new_ptr();
539
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
540
        PAS_OP(u)
541
        tcg_temp_free_ptr(tmp);
542
        break;
543
#undef gen_pas_helper
544
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
545
    case 2:
546
        PAS_OP(q);
547
        break;
548
    case 3:
549
        PAS_OP(sh);
550
        break;
551
    case 6:
552
        PAS_OP(uq);
553
        break;
554
    case 7:
555
        PAS_OP(uh);
556
        break;
557
#undef gen_pas_helper
558
    }
559
}
560
#undef PAS_OP
561

    
562
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
563
#define PAS_OP(pfx) \
564
    switch (op2) {  \
565
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
566
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
567
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
568
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
569
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
570
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
571
    }
572
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
573
{
574
    TCGv_ptr tmp;
575

    
576
    switch (op1) {
577
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
578
    case 0:
579
        tmp = tcg_temp_new_ptr();
580
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
581
        PAS_OP(s)
582
        tcg_temp_free_ptr(tmp);
583
        break;
584
    case 4:
585
        tmp = tcg_temp_new_ptr();
586
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
587
        PAS_OP(u)
588
        tcg_temp_free_ptr(tmp);
589
        break;
590
#undef gen_pas_helper
591
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
592
    case 1:
593
        PAS_OP(q);
594
        break;
595
    case 2:
596
        PAS_OP(sh);
597
        break;
598
    case 5:
599
        PAS_OP(uq);
600
        break;
601
    case 6:
602
        PAS_OP(uh);
603
        break;
604
#undef gen_pas_helper
605
    }
606
}
607
#undef PAS_OP
608

    
609
static void gen_test_cc(int cc, int label)
610
{
611
    TCGv tmp;
612
    TCGv tmp2;
613
    int inv;
614

    
615
    switch (cc) {
616
    case 0: /* eq: Z */
617
        tmp = load_cpu_field(ZF);
618
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
619
        break;
620
    case 1: /* ne: !Z */
621
        tmp = load_cpu_field(ZF);
622
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
623
        break;
624
    case 2: /* cs: C */
625
        tmp = load_cpu_field(CF);
626
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
627
        break;
628
    case 3: /* cc: !C */
629
        tmp = load_cpu_field(CF);
630
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
631
        break;
632
    case 4: /* mi: N */
633
        tmp = load_cpu_field(NF);
634
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
635
        break;
636
    case 5: /* pl: !N */
637
        tmp = load_cpu_field(NF);
638
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
639
        break;
640
    case 6: /* vs: V */
641
        tmp = load_cpu_field(VF);
642
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
643
        break;
644
    case 7: /* vc: !V */
645
        tmp = load_cpu_field(VF);
646
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
647
        break;
648
    case 8: /* hi: C && !Z */
649
        inv = gen_new_label();
650
        tmp = load_cpu_field(CF);
651
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
652
        dead_tmp(tmp);
653
        tmp = load_cpu_field(ZF);
654
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
655
        gen_set_label(inv);
656
        break;
657
    case 9: /* ls: !C || Z */
658
        tmp = load_cpu_field(CF);
659
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
660
        dead_tmp(tmp);
661
        tmp = load_cpu_field(ZF);
662
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
663
        break;
664
    case 10: /* ge: N == V -> N ^ V == 0 */
665
        tmp = load_cpu_field(VF);
666
        tmp2 = load_cpu_field(NF);
667
        tcg_gen_xor_i32(tmp, tmp, tmp2);
668
        dead_tmp(tmp2);
669
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
670
        break;
671
    case 11: /* lt: N != V -> N ^ V != 0 */
672
        tmp = load_cpu_field(VF);
673
        tmp2 = load_cpu_field(NF);
674
        tcg_gen_xor_i32(tmp, tmp, tmp2);
675
        dead_tmp(tmp2);
676
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
677
        break;
678
    case 12: /* gt: !Z && N == V */
679
        inv = gen_new_label();
680
        tmp = load_cpu_field(ZF);
681
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
682
        dead_tmp(tmp);
683
        tmp = load_cpu_field(VF);
684
        tmp2 = load_cpu_field(NF);
685
        tcg_gen_xor_i32(tmp, tmp, tmp2);
686
        dead_tmp(tmp2);
687
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
688
        gen_set_label(inv);
689
        break;
690
    case 13: /* le: Z || N != V */
691
        tmp = load_cpu_field(ZF);
692
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
693
        dead_tmp(tmp);
694
        tmp = load_cpu_field(VF);
695
        tmp2 = load_cpu_field(NF);
696
        tcg_gen_xor_i32(tmp, tmp, tmp2);
697
        dead_tmp(tmp2);
698
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
699
        break;
700
    default:
701
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
702
        abort();
703
    }
704
    dead_tmp(tmp);
705
}
706

    
707
static const uint8_t table_logic_cc[16] = {
708
    1, /* and */
709
    1, /* xor */
710
    0, /* sub */
711
    0, /* rsb */
712
    0, /* add */
713
    0, /* adc */
714
    0, /* sbc */
715
    0, /* rsc */
716
    1, /* andl */
717
    1, /* xorl */
718
    0, /* cmp */
719
    0, /* cmn */
720
    1, /* orr */
721
    1, /* mov */
722
    1, /* bic */
723
    1, /* mvn */
724
};
725

    
726
/* Set PC and Thumb state from an immediate address.  */
727
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
728
{
729
    TCGv tmp;
730

    
731
    s->is_jmp = DISAS_UPDATE;
732
    if (s->thumb != (addr & 1)) {
733
        tmp = new_tmp();
734
        tcg_gen_movi_i32(tmp, addr & 1);
735
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
736
        dead_tmp(tmp);
737
    }
738
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
739
}
740

    
741
/* Set PC and Thumb state from var.  var is marked as dead.  */
742
static inline void gen_bx(DisasContext *s, TCGv var)
743
{
744
    s->is_jmp = DISAS_UPDATE;
745
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
746
    tcg_gen_andi_i32(var, var, 1);
747
    store_cpu_field(var, thumb);
748
}
749

    
750
/* Variant of store_reg which uses branch&exchange logic when storing
751
   to r15 in ARM architecture v7 and above. The source must be a temporary
752
   and will be marked as dead. */
753
static inline void store_reg_bx(CPUState *env, DisasContext *s,
754
                                int reg, TCGv var)
755
{
756
    if (reg == 15 && ENABLE_ARCH_7) {
757
        gen_bx(s, var);
758
    } else {
759
        store_reg(s, reg, var);
760
    }
761
}
762

    
763
static inline TCGv gen_ld8s(TCGv addr, int index)
764
{
765
    TCGv tmp = new_tmp();
766
    tcg_gen_qemu_ld8s(tmp, addr, index);
767
    return tmp;
768
}
769
static inline TCGv gen_ld8u(TCGv addr, int index)
770
{
771
    TCGv tmp = new_tmp();
772
    tcg_gen_qemu_ld8u(tmp, addr, index);
773
    return tmp;
774
}
775
static inline TCGv gen_ld16s(TCGv addr, int index)
776
{
777
    TCGv tmp = new_tmp();
778
    tcg_gen_qemu_ld16s(tmp, addr, index);
779
    return tmp;
780
}
781
static inline TCGv gen_ld16u(TCGv addr, int index)
782
{
783
    TCGv tmp = new_tmp();
784
    tcg_gen_qemu_ld16u(tmp, addr, index);
785
    return tmp;
786
}
787
static inline TCGv gen_ld32(TCGv addr, int index)
788
{
789
    TCGv tmp = new_tmp();
790
    tcg_gen_qemu_ld32u(tmp, addr, index);
791
    return tmp;
792
}
793
static inline TCGv_i64 gen_ld64(TCGv addr, int index)
794
{
795
    TCGv_i64 tmp = tcg_temp_new_i64();
796
    tcg_gen_qemu_ld64(tmp, addr, index);
797
    return tmp;
798
}
799
static inline void gen_st8(TCGv val, TCGv addr, int index)
800
{
801
    tcg_gen_qemu_st8(val, addr, index);
802
    dead_tmp(val);
803
}
804
static inline void gen_st16(TCGv val, TCGv addr, int index)
805
{
806
    tcg_gen_qemu_st16(val, addr, index);
807
    dead_tmp(val);
808
}
809
static inline void gen_st32(TCGv val, TCGv addr, int index)
810
{
811
    tcg_gen_qemu_st32(val, addr, index);
812
    dead_tmp(val);
813
}
814
static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
815
{
816
    tcg_gen_qemu_st64(val, addr, index);
817
    tcg_temp_free_i64(val);
818
}
819

    
820
static inline void gen_set_pc_im(uint32_t val)
821
{
822
    tcg_gen_movi_i32(cpu_R[15], val);
823
}
824

    
825
/* Force a TB lookup after an instruction that changes the CPU state.  */
826
static inline void gen_lookup_tb(DisasContext *s)
827
{
828
    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
829
    s->is_jmp = DISAS_UPDATE;
830
}
831

    
832
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
833
                                       TCGv var)
834
{
835
    int val, rm, shift, shiftop;
836
    TCGv offset;
837

    
838
    if (!(insn & (1 << 25))) {
839
        /* immediate */
840
        val = insn & 0xfff;
841
        if (!(insn & (1 << 23)))
842
            val = -val;
843
        if (val != 0)
844
            tcg_gen_addi_i32(var, var, val);
845
    } else {
846
        /* shift/register */
847
        rm = (insn) & 0xf;
848
        shift = (insn >> 7) & 0x1f;
849
        shiftop = (insn >> 5) & 3;
850
        offset = load_reg(s, rm);
851
        gen_arm_shift_im(offset, shiftop, shift, 0);
852
        if (!(insn & (1 << 23)))
853
            tcg_gen_sub_i32(var, var, offset);
854
        else
855
            tcg_gen_add_i32(var, var, offset);
856
        dead_tmp(offset);
857
    }
858
}
859

    
860
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
861
                                        int extra, TCGv var)
862
{
863
    int val, rm;
864
    TCGv offset;
865

    
866
    if (insn & (1 << 22)) {
867
        /* immediate */
868
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
869
        if (!(insn & (1 << 23)))
870
            val = -val;
871
        val += extra;
872
        if (val != 0)
873
            tcg_gen_addi_i32(var, var, val);
874
    } else {
875
        /* register */
876
        if (extra)
877
            tcg_gen_addi_i32(var, var, extra);
878
        rm = (insn) & 0xf;
879
        offset = load_reg(s, rm);
880
        if (!(insn & (1 << 23)))
881
            tcg_gen_sub_i32(var, var, offset);
882
        else
883
            tcg_gen_add_i32(var, var, offset);
884
        dead_tmp(offset);
885
    }
886
}
887

    
888
#define VFP_OP2(name)                                                 \
889
static inline void gen_vfp_##name(int dp)                             \
890
{                                                                     \
891
    if (dp)                                                           \
892
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
893
    else                                                              \
894
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
895
}
896

    
897
VFP_OP2(add)
898
VFP_OP2(sub)
899
VFP_OP2(mul)
900
VFP_OP2(div)
901

    
902
#undef VFP_OP2
903

    
904
static inline void gen_vfp_abs(int dp)
905
{
906
    if (dp)
907
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
908
    else
909
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
910
}
911

    
912
static inline void gen_vfp_neg(int dp)
913
{
914
    if (dp)
915
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
916
    else
917
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
918
}
919

    
920
static inline void gen_vfp_sqrt(int dp)
921
{
922
    if (dp)
923
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
924
    else
925
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
926
}
927

    
928
static inline void gen_vfp_cmp(int dp)
929
{
930
    if (dp)
931
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
932
    else
933
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
934
}
935

    
936
static inline void gen_vfp_cmpe(int dp)
937
{
938
    if (dp)
939
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
940
    else
941
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
942
}
943

    
944
static inline void gen_vfp_F1_ld0(int dp)
945
{
946
    if (dp)
947
        tcg_gen_movi_i64(cpu_F1d, 0);
948
    else
949
        tcg_gen_movi_i32(cpu_F1s, 0);
950
}
951

    
952
static inline void gen_vfp_uito(int dp)
953
{
954
    if (dp)
955
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
956
    else
957
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
958
}
959

    
960
static inline void gen_vfp_sito(int dp)
961
{
962
    if (dp)
963
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
964
    else
965
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
966
}
967

    
968
static inline void gen_vfp_toui(int dp)
969
{
970
    if (dp)
971
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
972
    else
973
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
974
}
975

    
976
static inline void gen_vfp_touiz(int dp)
977
{
978
    if (dp)
979
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
980
    else
981
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
982
}
983

    
984
static inline void gen_vfp_tosi(int dp)
985
{
986
    if (dp)
987
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
988
    else
989
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
990
}
991

    
992
static inline void gen_vfp_tosiz(int dp)
993
{
994
    if (dp)
995
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
996
    else
997
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
998
}
999

    
1000
#define VFP_GEN_FIX(name) \
1001
static inline void gen_vfp_##name(int dp, int shift) \
1002
{ \
1003
    TCGv tmp_shift = tcg_const_i32(shift); \
1004
    if (dp) \
1005
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, cpu_env);\
1006
    else \
1007
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, cpu_env);\
1008
    tcg_temp_free_i32(tmp_shift); \
1009
}
1010
VFP_GEN_FIX(tosh)
1011
VFP_GEN_FIX(tosl)
1012
VFP_GEN_FIX(touh)
1013
VFP_GEN_FIX(toul)
1014
VFP_GEN_FIX(shto)
1015
VFP_GEN_FIX(slto)
1016
VFP_GEN_FIX(uhto)
1017
VFP_GEN_FIX(ulto)
1018
#undef VFP_GEN_FIX
1019

    
1020
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
1021
{
1022
    if (dp)
1023
        tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1024
    else
1025
        tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1026
}
1027

    
1028
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
1029
{
1030
    if (dp)
1031
        tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1032
    else
1033
        tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1034
}
1035

    
1036
static inline long
1037
vfp_reg_offset (int dp, int reg)
1038
{
1039
    if (dp)
1040
        return offsetof(CPUARMState, vfp.regs[reg]);
1041
    else if (reg & 1) {
1042
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1043
          + offsetof(CPU_DoubleU, l.upper);
1044
    } else {
1045
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1046
          + offsetof(CPU_DoubleU, l.lower);
1047
    }
1048
}
1049

    
1050
/* Return the offset of a 32-bit piece of a NEON register.
1051
   zero is the least significant end of the register.  */
1052
static inline long
1053
neon_reg_offset (int reg, int n)
1054
{
1055
    int sreg;
1056
    sreg = reg * 2 + n;
1057
    return vfp_reg_offset(0, sreg);
1058
}
1059

    
1060
static TCGv neon_load_reg(int reg, int pass)
1061
{
1062
    TCGv tmp = new_tmp();
1063
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1064
    return tmp;
1065
}
1066

    
1067
static void neon_store_reg(int reg, int pass, TCGv var)
1068
{
1069
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1070
    dead_tmp(var);
1071
}
1072

    
1073
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1074
{
1075
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1076
}
1077

    
1078
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1079
{
1080
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1081
}
1082

    
1083
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1084
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1085
#define tcg_gen_st_f32 tcg_gen_st_i32
1086
#define tcg_gen_st_f64 tcg_gen_st_i64
1087

    
1088
static inline void gen_mov_F0_vreg(int dp, int reg)
1089
{
1090
    if (dp)
1091
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1092
    else
1093
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1094
}
1095

    
1096
static inline void gen_mov_F1_vreg(int dp, int reg)
1097
{
1098
    if (dp)
1099
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1100
    else
1101
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1102
}
1103

    
1104
static inline void gen_mov_vreg_F0(int dp, int reg)
1105
{
1106
    if (dp)
1107
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1108
    else
1109
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1110
}
1111

    
1112
#define ARM_CP_RW_BIT        (1 << 20)
1113

    
1114
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1115
{
1116
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1117
}
1118

    
1119
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1120
{
1121
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1122
}
1123

    
1124
static inline TCGv iwmmxt_load_creg(int reg)
1125
{
1126
    TCGv var = new_tmp();
1127
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1128
    return var;
1129
}
1130

    
1131
static inline void iwmmxt_store_creg(int reg, TCGv var)
1132
{
1133
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1134
    dead_tmp(var);
1135
}
1136

    
1137
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1138
{
1139
    iwmmxt_store_reg(cpu_M0, rn);
1140
}
1141

    
1142
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1143
{
1144
    iwmmxt_load_reg(cpu_M0, rn);
1145
}
1146

    
1147
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1148
{
1149
    iwmmxt_load_reg(cpu_V1, rn);
1150
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1151
}
1152

    
1153
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1154
{
1155
    iwmmxt_load_reg(cpu_V1, rn);
1156
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1157
}
1158

    
1159
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1160
{
1161
    iwmmxt_load_reg(cpu_V1, rn);
1162
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1163
}
1164

    
1165
#define IWMMXT_OP(name) \
1166
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1167
{ \
1168
    iwmmxt_load_reg(cpu_V1, rn); \
1169
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1170
}
1171

    
1172
#define IWMMXT_OP_ENV(name) \
1173
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1174
{ \
1175
    iwmmxt_load_reg(cpu_V1, rn); \
1176
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1177
}
1178

    
1179
#define IWMMXT_OP_ENV_SIZE(name) \
1180
IWMMXT_OP_ENV(name##b) \
1181
IWMMXT_OP_ENV(name##w) \
1182
IWMMXT_OP_ENV(name##l)
1183

    
1184
#define IWMMXT_OP_ENV1(name) \
1185
static inline void gen_op_iwmmxt_##name##_M0(void) \
1186
{ \
1187
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1188
}
1189

    
1190
IWMMXT_OP(maddsq)
1191
IWMMXT_OP(madduq)
1192
IWMMXT_OP(sadb)
1193
IWMMXT_OP(sadw)
1194
IWMMXT_OP(mulslw)
1195
IWMMXT_OP(mulshw)
1196
IWMMXT_OP(mululw)
1197
IWMMXT_OP(muluhw)
1198
IWMMXT_OP(macsw)
1199
IWMMXT_OP(macuw)
1200

    
1201
IWMMXT_OP_ENV_SIZE(unpackl)
1202
IWMMXT_OP_ENV_SIZE(unpackh)
1203

    
1204
IWMMXT_OP_ENV1(unpacklub)
1205
IWMMXT_OP_ENV1(unpackluw)
1206
IWMMXT_OP_ENV1(unpacklul)
1207
IWMMXT_OP_ENV1(unpackhub)
1208
IWMMXT_OP_ENV1(unpackhuw)
1209
IWMMXT_OP_ENV1(unpackhul)
1210
IWMMXT_OP_ENV1(unpacklsb)
1211
IWMMXT_OP_ENV1(unpacklsw)
1212
IWMMXT_OP_ENV1(unpacklsl)
1213
IWMMXT_OP_ENV1(unpackhsb)
1214
IWMMXT_OP_ENV1(unpackhsw)
1215
IWMMXT_OP_ENV1(unpackhsl)
1216

    
1217
IWMMXT_OP_ENV_SIZE(cmpeq)
1218
IWMMXT_OP_ENV_SIZE(cmpgtu)
1219
IWMMXT_OP_ENV_SIZE(cmpgts)
1220

    
1221
IWMMXT_OP_ENV_SIZE(mins)
1222
IWMMXT_OP_ENV_SIZE(minu)
1223
IWMMXT_OP_ENV_SIZE(maxs)
1224
IWMMXT_OP_ENV_SIZE(maxu)
1225

    
1226
IWMMXT_OP_ENV_SIZE(subn)
1227
IWMMXT_OP_ENV_SIZE(addn)
1228
IWMMXT_OP_ENV_SIZE(subu)
1229
IWMMXT_OP_ENV_SIZE(addu)
1230
IWMMXT_OP_ENV_SIZE(subs)
1231
IWMMXT_OP_ENV_SIZE(adds)
1232

    
1233
IWMMXT_OP_ENV(avgb0)
1234
IWMMXT_OP_ENV(avgb1)
1235
IWMMXT_OP_ENV(avgw0)
1236
IWMMXT_OP_ENV(avgw1)
1237

    
1238
IWMMXT_OP(msadb)
1239

    
1240
IWMMXT_OP_ENV(packuw)
1241
IWMMXT_OP_ENV(packul)
1242
IWMMXT_OP_ENV(packuq)
1243
IWMMXT_OP_ENV(packsw)
1244
IWMMXT_OP_ENV(packsl)
1245
IWMMXT_OP_ENV(packsq)
1246

    
1247
static void gen_op_iwmmxt_set_mup(void)
1248
{
1249
    TCGv tmp;
1250
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1251
    tcg_gen_ori_i32(tmp, tmp, 2);
1252
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1253
}
1254

    
1255
static void gen_op_iwmmxt_set_cup(void)
1256
{
1257
    TCGv tmp;
1258
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1259
    tcg_gen_ori_i32(tmp, tmp, 1);
1260
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1261
}
1262

    
1263
static void gen_op_iwmmxt_setpsr_nz(void)
1264
{
1265
    TCGv tmp = new_tmp();
1266
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1267
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1268
}
1269

    
1270
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1271
{
1272
    iwmmxt_load_reg(cpu_V1, rn);
1273
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1274
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1275
}
1276

    
1277
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1278
{
1279
    int rd;
1280
    uint32_t offset;
1281
    TCGv tmp;
1282

    
1283
    rd = (insn >> 16) & 0xf;
1284
    tmp = load_reg(s, rd);
1285

    
1286
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1287
    if (insn & (1 << 24)) {
1288
        /* Pre indexed */
1289
        if (insn & (1 << 23))
1290
            tcg_gen_addi_i32(tmp, tmp, offset);
1291
        else
1292
            tcg_gen_addi_i32(tmp, tmp, -offset);
1293
        tcg_gen_mov_i32(dest, tmp);
1294
        if (insn & (1 << 21))
1295
            store_reg(s, rd, tmp);
1296
        else
1297
            dead_tmp(tmp);
1298
    } else if (insn & (1 << 21)) {
1299
        /* Post indexed */
1300
        tcg_gen_mov_i32(dest, tmp);
1301
        if (insn & (1 << 23))
1302
            tcg_gen_addi_i32(tmp, tmp, offset);
1303
        else
1304
            tcg_gen_addi_i32(tmp, tmp, -offset);
1305
        store_reg(s, rd, tmp);
1306
    } else if (!(insn & (1 << 23)))
1307
        return 1;
1308
    return 0;
1309
}
1310

    
1311
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1312
{
1313
    int rd = (insn >> 0) & 0xf;
1314
    TCGv tmp;
1315

    
1316
    if (insn & (1 << 8)) {
1317
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1318
            return 1;
1319
        } else {
1320
            tmp = iwmmxt_load_creg(rd);
1321
        }
1322
    } else {
1323
        tmp = new_tmp();
1324
        iwmmxt_load_reg(cpu_V0, rd);
1325
        tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1326
    }
1327
    tcg_gen_andi_i32(tmp, tmp, mask);
1328
    tcg_gen_mov_i32(dest, tmp);
1329
    dead_tmp(tmp);
1330
    return 0;
1331
}
1332

    
1333
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1334
   (ie. an undefined instruction).  */
1335
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1336
{
1337
    int rd, wrd;
1338
    int rdhi, rdlo, rd0, rd1, i;
1339
    TCGv addr;
1340
    TCGv tmp, tmp2, tmp3;
1341

    
1342
    if ((insn & 0x0e000e00) == 0x0c000000) {
1343
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1344
            wrd = insn & 0xf;
1345
            rdlo = (insn >> 12) & 0xf;
1346
            rdhi = (insn >> 16) & 0xf;
1347
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1348
                iwmmxt_load_reg(cpu_V0, wrd);
1349
                tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1350
                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1351
                tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1352
            } else {                                        /* TMCRR */
1353
                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1354
                iwmmxt_store_reg(cpu_V0, wrd);
1355
                gen_op_iwmmxt_set_mup();
1356
            }
1357
            return 0;
1358
        }
1359

    
1360
        wrd = (insn >> 12) & 0xf;
1361
        addr = new_tmp();
1362
        if (gen_iwmmxt_address(s, insn, addr)) {
1363
            dead_tmp(addr);
1364
            return 1;
1365
        }
1366
        if (insn & ARM_CP_RW_BIT) {
1367
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1368
                tmp = new_tmp();
1369
                tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
1370
                iwmmxt_store_creg(wrd, tmp);
1371
            } else {
1372
                i = 1;
1373
                if (insn & (1 << 8)) {
1374
                    if (insn & (1 << 22)) {                /* WLDRD */
1375
                        tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s));
1376
                        i = 0;
1377
                    } else {                                /* WLDRW wRd */
1378
                        tmp = gen_ld32(addr, IS_USER(s));
1379
                    }
1380
                } else {
1381
                    if (insn & (1 << 22)) {                /* WLDRH */
1382
                        tmp = gen_ld16u(addr, IS_USER(s));
1383
                    } else {                                /* WLDRB */
1384
                        tmp = gen_ld8u(addr, IS_USER(s));
1385
                    }
1386
                }
1387
                if (i) {
1388
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
1389
                    dead_tmp(tmp);
1390
                }
1391
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1392
            }
1393
        } else {
1394
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1395
                tmp = iwmmxt_load_creg(wrd);
1396
                gen_st32(tmp, addr, IS_USER(s));
1397
            } else {
1398
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1399
                tmp = new_tmp();
1400
                if (insn & (1 << 8)) {
1401
                    if (insn & (1 << 22)) {                /* WSTRD */
1402
                        dead_tmp(tmp);
1403
                        tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s));
1404
                    } else {                                /* WSTRW wRd */
1405
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1406
                        gen_st32(tmp, addr, IS_USER(s));
1407
                    }
1408
                } else {
1409
                    if (insn & (1 << 22)) {                /* WSTRH */
1410
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1411
                        gen_st16(tmp, addr, IS_USER(s));
1412
                    } else {                                /* WSTRB */
1413
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1414
                        gen_st8(tmp, addr, IS_USER(s));
1415
                    }
1416
                }
1417
            }
1418
        }
1419
        dead_tmp(addr);
1420
        return 0;
1421
    }
1422

    
1423
    if ((insn & 0x0f000000) != 0x0e000000)
1424
        return 1;
1425

    
1426
    switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1427
    case 0x000:                                                /* WOR */
1428
        wrd = (insn >> 12) & 0xf;
1429
        rd0 = (insn >> 0) & 0xf;
1430
        rd1 = (insn >> 16) & 0xf;
1431
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1432
        gen_op_iwmmxt_orq_M0_wRn(rd1);
1433
        gen_op_iwmmxt_setpsr_nz();
1434
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1435
        gen_op_iwmmxt_set_mup();
1436
        gen_op_iwmmxt_set_cup();
1437
        break;
1438
    case 0x011:                                                /* TMCR */
1439
        if (insn & 0xf)
1440
            return 1;
1441
        rd = (insn >> 12) & 0xf;
1442
        wrd = (insn >> 16) & 0xf;
1443
        switch (wrd) {
1444
        case ARM_IWMMXT_wCID:
1445
        case ARM_IWMMXT_wCASF:
1446
            break;
1447
        case ARM_IWMMXT_wCon:
1448
            gen_op_iwmmxt_set_cup();
1449
            /* Fall through.  */
1450
        case ARM_IWMMXT_wCSSF:
1451
            tmp = iwmmxt_load_creg(wrd);
1452
            tmp2 = load_reg(s, rd);
1453
            tcg_gen_andc_i32(tmp, tmp, tmp2);
1454
            dead_tmp(tmp2);
1455
            iwmmxt_store_creg(wrd, tmp);
1456
            break;
1457
        case ARM_IWMMXT_wCGR0:
1458
        case ARM_IWMMXT_wCGR1:
1459
        case ARM_IWMMXT_wCGR2:
1460
        case ARM_IWMMXT_wCGR3:
1461
            gen_op_iwmmxt_set_cup();
1462
            tmp = load_reg(s, rd);
1463
            iwmmxt_store_creg(wrd, tmp);
1464
            break;
1465
        default:
1466
            return 1;
1467
        }
1468
        break;
1469
    case 0x100:                                                /* WXOR */
1470
        wrd = (insn >> 12) & 0xf;
1471
        rd0 = (insn >> 0) & 0xf;
1472
        rd1 = (insn >> 16) & 0xf;
1473
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1474
        gen_op_iwmmxt_xorq_M0_wRn(rd1);
1475
        gen_op_iwmmxt_setpsr_nz();
1476
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1477
        gen_op_iwmmxt_set_mup();
1478
        gen_op_iwmmxt_set_cup();
1479
        break;
1480
    case 0x111:                                                /* TMRC */
1481
        if (insn & 0xf)
1482
            return 1;
1483
        rd = (insn >> 12) & 0xf;
1484
        wrd = (insn >> 16) & 0xf;
1485
        tmp = iwmmxt_load_creg(wrd);
1486
        store_reg(s, rd, tmp);
1487
        break;
1488
    case 0x300:                                                /* WANDN */
1489
        wrd = (insn >> 12) & 0xf;
1490
        rd0 = (insn >> 0) & 0xf;
1491
        rd1 = (insn >> 16) & 0xf;
1492
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1493
        tcg_gen_neg_i64(cpu_M0, cpu_M0);
1494
        gen_op_iwmmxt_andq_M0_wRn(rd1);
1495
        gen_op_iwmmxt_setpsr_nz();
1496
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1497
        gen_op_iwmmxt_set_mup();
1498
        gen_op_iwmmxt_set_cup();
1499
        break;
1500
    case 0x200:                                                /* WAND */
1501
        wrd = (insn >> 12) & 0xf;
1502
        rd0 = (insn >> 0) & 0xf;
1503
        rd1 = (insn >> 16) & 0xf;
1504
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1505
        gen_op_iwmmxt_andq_M0_wRn(rd1);
1506
        gen_op_iwmmxt_setpsr_nz();
1507
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1508
        gen_op_iwmmxt_set_mup();
1509
        gen_op_iwmmxt_set_cup();
1510
        break;
1511
    case 0x810: case 0xa10:                                /* WMADD */
1512
        wrd = (insn >> 12) & 0xf;
1513
        rd0 = (insn >> 0) & 0xf;
1514
        rd1 = (insn >> 16) & 0xf;
1515
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1516
        if (insn & (1 << 21))
1517
            gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1518
        else
1519
            gen_op_iwmmxt_madduq_M0_wRn(rd1);
1520
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1521
        gen_op_iwmmxt_set_mup();
1522
        break;
1523
    case 0x10e: case 0x50e: case 0x90e: case 0xd0e:        /* WUNPCKIL */
1524
        wrd = (insn >> 12) & 0xf;
1525
        rd0 = (insn >> 16) & 0xf;
1526
        rd1 = (insn >> 0) & 0xf;
1527
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1528
        switch ((insn >> 22) & 3) {
1529
        case 0:
1530
            gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1531
            break;
1532
        case 1:
1533
            gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1534
            break;
1535
        case 2:
1536
            gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1537
            break;
1538
        case 3:
1539
            return 1;
1540
        }
1541
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1542
        gen_op_iwmmxt_set_mup();
1543
        gen_op_iwmmxt_set_cup();
1544
        break;
1545
    case 0x10c: case 0x50c: case 0x90c: case 0xd0c:        /* WUNPCKIH */
1546
        wrd = (insn >> 12) & 0xf;
1547
        rd0 = (insn >> 16) & 0xf;
1548
        rd1 = (insn >> 0) & 0xf;
1549
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1550
        switch ((insn >> 22) & 3) {
1551
        case 0:
1552
            gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1553
            break;
1554
        case 1:
1555
            gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1556
            break;
1557
        case 2:
1558
            gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1559
            break;
1560
        case 3:
1561
            return 1;
1562
        }
1563
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1564
        gen_op_iwmmxt_set_mup();
1565
        gen_op_iwmmxt_set_cup();
1566
        break;
1567
    case 0x012: case 0x112: case 0x412: case 0x512:        /* WSAD */
1568
        wrd = (insn >> 12) & 0xf;
1569
        rd0 = (insn >> 16) & 0xf;
1570
        rd1 = (insn >> 0) & 0xf;
1571
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1572
        if (insn & (1 << 22))
1573
            gen_op_iwmmxt_sadw_M0_wRn(rd1);
1574
        else
1575
            gen_op_iwmmxt_sadb_M0_wRn(rd1);
1576
        if (!(insn & (1 << 20)))
1577
            gen_op_iwmmxt_addl_M0_wRn(wrd);
1578
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1579
        gen_op_iwmmxt_set_mup();
1580
        break;
1581
    case 0x010: case 0x110: case 0x210: case 0x310:        /* WMUL */
1582
        wrd = (insn >> 12) & 0xf;
1583
        rd0 = (insn >> 16) & 0xf;
1584
        rd1 = (insn >> 0) & 0xf;
1585
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1586
        if (insn & (1 << 21)) {
1587
            if (insn & (1 << 20))
1588
                gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1589
            else
1590
                gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1591
        } else {
1592
            if (insn & (1 << 20))
1593
                gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1594
            else
1595
                gen_op_iwmmxt_mululw_M0_wRn(rd1);
1596
        }
1597
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1598
        gen_op_iwmmxt_set_mup();
1599
        break;
1600
    case 0x410: case 0x510: case 0x610: case 0x710:        /* WMAC */
1601
        wrd = (insn >> 12) & 0xf;
1602
        rd0 = (insn >> 16) & 0xf;
1603
        rd1 = (insn >> 0) & 0xf;
1604
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1605
        if (insn & (1 << 21))
1606
            gen_op_iwmmxt_macsw_M0_wRn(rd1);
1607
        else
1608
            gen_op_iwmmxt_macuw_M0_wRn(rd1);
1609
        if (!(insn & (1 << 20))) {
1610
            iwmmxt_load_reg(cpu_V1, wrd);
1611
            tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1612
        }
1613
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1614
        gen_op_iwmmxt_set_mup();
1615
        break;
1616
    case 0x006: case 0x406: case 0x806: case 0xc06:        /* WCMPEQ */
1617
        wrd = (insn >> 12) & 0xf;
1618
        rd0 = (insn >> 16) & 0xf;
1619
        rd1 = (insn >> 0) & 0xf;
1620
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1621
        switch ((insn >> 22) & 3) {
1622
        case 0:
1623
            gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1624
            break;
1625
        case 1:
1626
            gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1627
            break;
1628
        case 2:
1629
            gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1630
            break;
1631
        case 3:
1632
            return 1;
1633
        }
1634
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1635
        gen_op_iwmmxt_set_mup();
1636
        gen_op_iwmmxt_set_cup();
1637
        break;
1638
    case 0x800: case 0x900: case 0xc00: case 0xd00:        /* WAVG2 */
1639
        wrd = (insn >> 12) & 0xf;
1640
        rd0 = (insn >> 16) & 0xf;
1641
        rd1 = (insn >> 0) & 0xf;
1642
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1643
        if (insn & (1 << 22)) {
1644
            if (insn & (1 << 20))
1645
                gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1646
            else
1647
                gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1648
        } else {
1649
            if (insn & (1 << 20))
1650
                gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1651
            else
1652
                gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1653
        }
1654
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1655
        gen_op_iwmmxt_set_mup();
1656
        gen_op_iwmmxt_set_cup();
1657
        break;
1658
    case 0x802: case 0x902: case 0xa02: case 0xb02:        /* WALIGNR */
1659
        wrd = (insn >> 12) & 0xf;
1660
        rd0 = (insn >> 16) & 0xf;
1661
        rd1 = (insn >> 0) & 0xf;
1662
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1663
        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1664
        tcg_gen_andi_i32(tmp, tmp, 7);
1665
        iwmmxt_load_reg(cpu_V1, rd1);
1666
        gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1667
        dead_tmp(tmp);
1668
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1669
        gen_op_iwmmxt_set_mup();
1670
        break;
1671
    case 0x601: case 0x605: case 0x609: case 0x60d:        /* TINSR */
1672
        if (((insn >> 6) & 3) == 3)
1673
            return 1;
1674
        rd = (insn >> 12) & 0xf;
1675
        wrd = (insn >> 16) & 0xf;
1676
        tmp = load_reg(s, rd);
1677
        gen_op_iwmmxt_movq_M0_wRn(wrd);
1678
        switch ((insn >> 6) & 3) {
1679
        case 0:
1680
            tmp2 = tcg_const_i32(0xff);
1681
            tmp3 = tcg_const_i32((insn & 7) << 3);
1682
            break;
1683
        case 1:
1684
            tmp2 = tcg_const_i32(0xffff);
1685
            tmp3 = tcg_const_i32((insn & 3) << 4);
1686
            break;
1687
        case 2:
1688
            tmp2 = tcg_const_i32(0xffffffff);
1689
            tmp3 = tcg_const_i32((insn & 1) << 5);
1690
            break;
1691
        default:
1692
            TCGV_UNUSED(tmp2);
1693
            TCGV_UNUSED(tmp3);
1694
        }
1695
        gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1696
        tcg_temp_free(tmp3);
1697
        tcg_temp_free(tmp2);
1698
        dead_tmp(tmp);
1699
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1700
        gen_op_iwmmxt_set_mup();
1701
        break;
1702
    case 0x107: case 0x507: case 0x907: case 0xd07:        /* TEXTRM */
1703
        rd = (insn >> 12) & 0xf;
1704
        wrd = (insn >> 16) & 0xf;
1705
        if (rd == 15 || ((insn >> 22) & 3) == 3)
1706
            return 1;
1707
        gen_op_iwmmxt_movq_M0_wRn(wrd);
1708
        tmp = new_tmp();
1709
        switch ((insn >> 22) & 3) {
1710
        case 0:
1711
            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1712
            tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1713
            if (insn & 8) {
1714
                tcg_gen_ext8s_i32(tmp, tmp);
1715
            } else {
1716
                tcg_gen_andi_i32(tmp, tmp, 0xff);
1717
            }
1718
            break;
1719
        case 1:
1720
            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1721
            tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1722
            if (insn & 8) {
1723
                tcg_gen_ext16s_i32(tmp, tmp);
1724
            } else {
1725
                tcg_gen_andi_i32(tmp, tmp, 0xffff);
1726
            }
1727
            break;
1728
        case 2:
1729
            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1730
            tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1731
            break;
1732
        }
1733
        store_reg(s, rd, tmp);
1734
        break;
1735
    case 0x117: case 0x517: case 0x917: case 0xd17:        /* TEXTRC */
1736
        if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1737
            return 1;
1738
        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1739
        switch ((insn >> 22) & 3) {
1740
        case 0:
1741
            tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1742
            break;
1743
        case 1:
1744
            tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1745
            break;
1746
        case 2:
1747
            tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1748
            break;
1749
        }
1750
        tcg_gen_shli_i32(tmp, tmp, 28);
1751
        gen_set_nzcv(tmp);
1752
        dead_tmp(tmp);
1753
        break;
1754
    case 0x401: case 0x405: case 0x409: case 0x40d:        /* TBCST */
1755
        if (((insn >> 6) & 3) == 3)
1756
            return 1;
1757
        rd = (insn >> 12) & 0xf;
1758
        wrd = (insn >> 16) & 0xf;
1759
        tmp = load_reg(s, rd);
1760
        switch ((insn >> 6) & 3) {
1761
        case 0:
1762
            gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1763
            break;
1764
        case 1:
1765
            gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1766
            break;
1767
        case 2:
1768
            gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1769
            break;
1770
        }
1771
        dead_tmp(tmp);
1772
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1773
        gen_op_iwmmxt_set_mup();
1774
        break;
1775
    case 0x113: case 0x513: case 0x913: case 0xd13:        /* TANDC */
1776
        if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1777
            return 1;
1778
        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1779
        tmp2 = new_tmp();
1780
        tcg_gen_mov_i32(tmp2, tmp);
1781
        switch ((insn >> 22) & 3) {
1782
        case 0:
1783
            for (i = 0; i < 7; i ++) {
1784
                tcg_gen_shli_i32(tmp2, tmp2, 4);
1785
                tcg_gen_and_i32(tmp, tmp, tmp2);
1786
            }
1787
            break;
1788
        case 1:
1789
            for (i = 0; i < 3; i ++) {
1790
                tcg_gen_shli_i32(tmp2, tmp2, 8);
1791
                tcg_gen_and_i32(tmp, tmp, tmp2);
1792
            }
1793
            break;
1794
        case 2:
1795
            tcg_gen_shli_i32(tmp2, tmp2, 16);
1796
            tcg_gen_and_i32(tmp, tmp, tmp2);
1797
            break;
1798
        }
1799
        gen_set_nzcv(tmp);
1800
        dead_tmp(tmp2);
1801
        dead_tmp(tmp);
1802
        break;
1803
    case 0x01c: case 0x41c: case 0x81c: case 0xc1c:        /* WACC */
1804
        wrd = (insn >> 12) & 0xf;
1805
        rd0 = (insn >> 16) & 0xf;
1806
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1807
        switch ((insn >> 22) & 3) {
1808
        case 0:
1809
            gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1810
            break;
1811
        case 1:
1812
            gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1813
            break;
1814
        case 2:
1815
            gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1816
            break;
1817
        case 3:
1818
            return 1;
1819
        }
1820
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1821
        gen_op_iwmmxt_set_mup();
1822
        break;
1823
    case 0x115: case 0x515: case 0x915: case 0xd15:        /* TORC */
1824
        if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1825
            return 1;
1826
        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1827
        tmp2 = new_tmp();
1828
        tcg_gen_mov_i32(tmp2, tmp);
1829
        switch ((insn >> 22) & 3) {
1830
        case 0:
1831
            for (i = 0; i < 7; i ++) {
1832
                tcg_gen_shli_i32(tmp2, tmp2, 4);
1833
                tcg_gen_or_i32(tmp, tmp, tmp2);
1834
            }
1835
            break;
1836
        case 1:
1837
            for (i = 0; i < 3; i ++) {
1838
                tcg_gen_shli_i32(tmp2, tmp2, 8);
1839
                tcg_gen_or_i32(tmp, tmp, tmp2);
1840
            }
1841
            break;
1842
        case 2:
1843
            tcg_gen_shli_i32(tmp2, tmp2, 16);
1844
            tcg_gen_or_i32(tmp, tmp, tmp2);
1845
            break;
1846
        }
1847
        gen_set_nzcv(tmp);
1848
        dead_tmp(tmp2);
1849
        dead_tmp(tmp);
1850
        break;
1851
    case 0x103: case 0x503: case 0x903: case 0xd03:        /* TMOVMSK */
1852
        rd = (insn >> 12) & 0xf;
1853
        rd0 = (insn >> 16) & 0xf;
1854
        if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1855
            return 1;
1856
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1857
        tmp = new_tmp();
1858
        switch ((insn >> 22) & 3) {
1859
        case 0:
1860
            gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1861
            break;
1862
        case 1:
1863
            gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1864
            break;
1865
        case 2:
1866
            gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1867
            break;
1868
        }
1869
        store_reg(s, rd, tmp);
1870
        break;
1871
    case 0x106: case 0x306: case 0x506: case 0x706:        /* WCMPGT */
1872
    case 0x906: case 0xb06: case 0xd06: case 0xf06:
1873
        wrd = (insn >> 12) & 0xf;
1874
        rd0 = (insn >> 16) & 0xf;
1875
        rd1 = (insn >> 0) & 0xf;
1876
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1877
        switch ((insn >> 22) & 3) {
1878
        case 0:
1879
            if (insn & (1 << 21))
1880
                gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1881
            else
1882
                gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1883
            break;
1884
        case 1:
1885
            if (insn & (1 << 21))
1886
                gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1887
            else
1888
                gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
1889
            break;
1890
        case 2:
1891
            if (insn & (1 << 21))
1892
                gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
1893
            else
1894
                gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
1895
            break;
1896
        case 3:
1897
            return 1;
1898
        }
1899
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1900
        gen_op_iwmmxt_set_mup();
1901
        gen_op_iwmmxt_set_cup();
1902
        break;
1903
    case 0x00e: case 0x20e: case 0x40e: case 0x60e:        /* WUNPCKEL */
1904
    case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1905
        wrd = (insn >> 12) & 0xf;
1906
        rd0 = (insn >> 16) & 0xf;
1907
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1908
        switch ((insn >> 22) & 3) {
1909
        case 0:
1910
            if (insn & (1 << 21))
1911
                gen_op_iwmmxt_unpacklsb_M0();
1912
            else
1913
                gen_op_iwmmxt_unpacklub_M0();
1914
            break;
1915
        case 1:
1916
            if (insn & (1 << 21))
1917
                gen_op_iwmmxt_unpacklsw_M0();
1918
            else
1919
                gen_op_iwmmxt_unpackluw_M0();
1920
            break;
1921
        case 2:
1922
            if (insn & (1 << 21))
1923
                gen_op_iwmmxt_unpacklsl_M0();
1924
            else
1925
                gen_op_iwmmxt_unpacklul_M0();
1926
            break;
1927
        case 3:
1928
            return 1;
1929
        }
1930
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1931
        gen_op_iwmmxt_set_mup();
1932
        gen_op_iwmmxt_set_cup();
1933
        break;
1934
    case 0x00c: case 0x20c: case 0x40c: case 0x60c:        /* WUNPCKEH */
1935
    case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1936
        wrd = (insn >> 12) & 0xf;
1937
        rd0 = (insn >> 16) & 0xf;
1938
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1939
        switch ((insn >> 22) & 3) {
1940
        case 0:
1941
            if (insn & (1 << 21))
1942
                gen_op_iwmmxt_unpackhsb_M0();
1943
            else
1944
                gen_op_iwmmxt_unpackhub_M0();
1945
            break;
1946
        case 1:
1947
            if (insn & (1 << 21))
1948
                gen_op_iwmmxt_unpackhsw_M0();
1949
            else
1950
                gen_op_iwmmxt_unpackhuw_M0();
1951
            break;
1952
        case 2:
1953
            if (insn & (1 << 21))
1954
                gen_op_iwmmxt_unpackhsl_M0();
1955
            else
1956
                gen_op_iwmmxt_unpackhul_M0();
1957
            break;
1958
        case 3:
1959
            return 1;
1960
        }
1961
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1962
        gen_op_iwmmxt_set_mup();
1963
        gen_op_iwmmxt_set_cup();
1964
        break;
1965
    case 0x204: case 0x604: case 0xa04: case 0xe04:        /* WSRL */
1966
    case 0x214: case 0x614: case 0xa14: case 0xe14:
1967
        if (((insn >> 22) & 3) == 0)
1968
            return 1;
1969
        wrd = (insn >> 12) & 0xf;
1970
        rd0 = (insn >> 16) & 0xf;
1971
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1972
        tmp = new_tmp();
1973
        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
1974
            dead_tmp(tmp);
1975
            return 1;
1976
        }
1977
        switch ((insn >> 22) & 3) {
1978
        case 1:
1979
            gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
1980
            break;
1981
        case 2:
1982
            gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
1983
            break;
1984
        case 3:
1985
            gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
1986
            break;
1987
        }
1988
        dead_tmp(tmp);
1989
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1990
        gen_op_iwmmxt_set_mup();
1991
        gen_op_iwmmxt_set_cup();
1992
        break;
1993
    case 0x004: case 0x404: case 0x804: case 0xc04:        /* WSRA */
1994
    case 0x014: case 0x414: case 0x814: case 0xc14:
1995
        if (((insn >> 22) & 3) == 0)
1996
            return 1;
1997
        wrd = (insn >> 12) & 0xf;
1998
        rd0 = (insn >> 16) & 0xf;
1999
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2000
        tmp = new_tmp();
2001
        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2002
            dead_tmp(tmp);
2003
            return 1;
2004
        }
2005
        switch ((insn >> 22) & 3) {
2006
        case 1:
2007
            gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2008
            break;
2009
        case 2:
2010
            gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2011
            break;
2012
        case 3:
2013
            gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2014
            break;
2015
        }
2016
        dead_tmp(tmp);
2017
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2018
        gen_op_iwmmxt_set_mup();
2019
        gen_op_iwmmxt_set_cup();
2020
        break;
2021
    case 0x104: case 0x504: case 0x904: case 0xd04:        /* WSLL */
2022
    case 0x114: case 0x514: case 0x914: case 0xd14:
2023
        if (((insn >> 22) & 3) == 0)
2024
            return 1;
2025
        wrd = (insn >> 12) & 0xf;
2026
        rd0 = (insn >> 16) & 0xf;
2027
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2028
        tmp = new_tmp();
2029
        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2030
            dead_tmp(tmp);
2031
            return 1;
2032
        }
2033
        switch ((insn >> 22) & 3) {
2034
        case 1:
2035
            gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2036
            break;
2037
        case 2:
2038
            gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2039
            break;
2040
        case 3:
2041
            gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2042
            break;
2043
        }
2044
        dead_tmp(tmp);
2045
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2046
        gen_op_iwmmxt_set_mup();
2047
        gen_op_iwmmxt_set_cup();
2048
        break;
2049
    case 0x304: case 0x704: case 0xb04: case 0xf04:        /* WROR */
2050
    case 0x314: case 0x714: case 0xb14: case 0xf14:
2051
        if (((insn >> 22) & 3) == 0)
2052
            return 1;
2053
        wrd = (insn >> 12) & 0xf;
2054
        rd0 = (insn >> 16) & 0xf;
2055
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2056
        tmp = new_tmp();
2057
        switch ((insn >> 22) & 3) {
2058
        case 1:
2059
            if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2060
                dead_tmp(tmp);
2061
                return 1;
2062
            }
2063
            gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2064
            break;
2065
        case 2:
2066
            if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2067
                dead_tmp(tmp);
2068
                return 1;
2069
            }
2070
            gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2071
            break;
2072
        case 3:
2073
            if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2074
                dead_tmp(tmp);
2075
                return 1;
2076
            }
2077
            gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2078
            break;
2079
        }
2080
        dead_tmp(tmp);
2081
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2082
        gen_op_iwmmxt_set_mup();
2083
        gen_op_iwmmxt_set_cup();
2084
        break;
2085
    case 0x116: case 0x316: case 0x516: case 0x716:        /* WMIN */
2086
    case 0x916: case 0xb16: case 0xd16: case 0xf16:
2087
        wrd = (insn >> 12) & 0xf;
2088
        rd0 = (insn >> 16) & 0xf;
2089
        rd1 = (insn >> 0) & 0xf;
2090
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2091
        switch ((insn >> 22) & 3) {
2092
        case 0:
2093
            if (insn & (1 << 21))
2094
                gen_op_iwmmxt_minsb_M0_wRn(rd1);
2095
            else
2096
                gen_op_iwmmxt_minub_M0_wRn(rd1);
2097
            break;
2098
        case 1:
2099
            if (insn & (1 << 21))
2100
                gen_op_iwmmxt_minsw_M0_wRn(rd1);
2101
            else
2102
                gen_op_iwmmxt_minuw_M0_wRn(rd1);
2103
            break;
2104
        case 2:
2105
            if (insn & (1 << 21))
2106
                gen_op_iwmmxt_minsl_M0_wRn(rd1);
2107
            else
2108
                gen_op_iwmmxt_minul_M0_wRn(rd1);
2109
            break;
2110
        case 3:
2111
            return 1;
2112
        }
2113
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2114
        gen_op_iwmmxt_set_mup();
2115
        break;
2116
    case 0x016: case 0x216: case 0x416: case 0x616:        /* WMAX */
2117
    case 0x816: case 0xa16: case 0xc16: case 0xe16:
2118
        wrd = (insn >> 12) & 0xf;
2119
        rd0 = (insn >> 16) & 0xf;
2120
        rd1 = (insn >> 0) & 0xf;
2121
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2122
        switch ((insn >> 22) & 3) {
2123
        case 0:
2124
            if (insn & (1 << 21))
2125
                gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2126
            else
2127
                gen_op_iwmmxt_maxub_M0_wRn(rd1);
2128
            break;
2129
        case 1:
2130
            if (insn & (1 << 21))
2131
                gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2132
            else
2133
                gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2134
            break;
2135
        case 2:
2136
            if (insn & (1 << 21))
2137
                gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2138
            else
2139
                gen_op_iwmmxt_maxul_M0_wRn(rd1);
2140
            break;
2141
        case 3:
2142
            return 1;
2143
        }
2144
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2145
        gen_op_iwmmxt_set_mup();
2146
        break;
2147
    case 0x002: case 0x102: case 0x202: case 0x302:        /* WALIGNI */
2148
    case 0x402: case 0x502: case 0x602: case 0x702:
2149
        wrd = (insn >> 12) & 0xf;
2150
        rd0 = (insn >> 16) & 0xf;
2151
        rd1 = (insn >> 0) & 0xf;
2152
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2153
        tmp = tcg_const_i32((insn >> 20) & 3);
2154
        iwmmxt_load_reg(cpu_V1, rd1);
2155
        gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2156
        tcg_temp_free(tmp);
2157
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2158
        gen_op_iwmmxt_set_mup();
2159
        break;
2160
    case 0x01a: case 0x11a: case 0x21a: case 0x31a:        /* WSUB */
2161
    case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2162
    case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2163
    case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2164
        wrd = (insn >> 12) & 0xf;
2165
        rd0 = (insn >> 16) & 0xf;
2166
        rd1 = (insn >> 0) & 0xf;
2167
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2168
        switch ((insn >> 20) & 0xf) {
2169
        case 0x0:
2170
            gen_op_iwmmxt_subnb_M0_wRn(rd1);
2171
            break;
2172
        case 0x1:
2173
            gen_op_iwmmxt_subub_M0_wRn(rd1);
2174
            break;
2175
        case 0x3:
2176
            gen_op_iwmmxt_subsb_M0_wRn(rd1);
2177
            break;
2178
        case 0x4:
2179
            gen_op_iwmmxt_subnw_M0_wRn(rd1);
2180
            break;
2181
        case 0x5:
2182
            gen_op_iwmmxt_subuw_M0_wRn(rd1);
2183
            break;
2184
        case 0x7:
2185
            gen_op_iwmmxt_subsw_M0_wRn(rd1);
2186
            break;
2187
        case 0x8:
2188
            gen_op_iwmmxt_subnl_M0_wRn(rd1);
2189
            break;
2190
        case 0x9:
2191
            gen_op_iwmmxt_subul_M0_wRn(rd1);
2192
            break;
2193
        case 0xb:
2194
            gen_op_iwmmxt_subsl_M0_wRn(rd1);
2195
            break;
2196
        default:
2197
            return 1;
2198
        }
2199
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2200
        gen_op_iwmmxt_set_mup();
2201
        gen_op_iwmmxt_set_cup();
2202
        break;
2203
    case 0x01e: case 0x11e: case 0x21e: case 0x31e:        /* WSHUFH */
2204
    case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2205
    case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2206
    case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2207
        wrd = (insn >> 12) & 0xf;
2208
        rd0 = (insn >> 16) & 0xf;
2209
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2210
        tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2211
        gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2212
        tcg_temp_free(tmp);
2213
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2214
        gen_op_iwmmxt_set_mup();
2215
        gen_op_iwmmxt_set_cup();
2216
        break;
2217
    case 0x018: case 0x118: case 0x218: case 0x318:        /* WADD */
2218
    case 0x418: case 0x518: case 0x618: case 0x718:
2219
    case 0x818: case 0x918: case 0xa18: case 0xb18:
2220
    case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2221
        wrd = (insn >> 12) & 0xf;
2222
        rd0 = (insn >> 16) & 0xf;
2223
        rd1 = (insn >> 0) & 0xf;
2224
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2225
        switch ((insn >> 20) & 0xf) {
2226
        case 0x0:
2227
            gen_op_iwmmxt_addnb_M0_wRn(rd1);
2228
            break;
2229
        case 0x1:
2230
            gen_op_iwmmxt_addub_M0_wRn(rd1);
2231
            break;
2232
        case 0x3:
2233
            gen_op_iwmmxt_addsb_M0_wRn(rd1);
2234
            break;
2235
        case 0x4:
2236
            gen_op_iwmmxt_addnw_M0_wRn(rd1);
2237
            break;
2238
        case 0x5:
2239
            gen_op_iwmmxt_adduw_M0_wRn(rd1);
2240
            break;
2241
        case 0x7:
2242
            gen_op_iwmmxt_addsw_M0_wRn(rd1);
2243
            break;
2244
        case 0x8:
2245
            gen_op_iwmmxt_addnl_M0_wRn(rd1);
2246
            break;
2247
        case 0x9:
2248
            gen_op_iwmmxt_addul_M0_wRn(rd1);
2249
            break;
2250
        case 0xb:
2251
            gen_op_iwmmxt_addsl_M0_wRn(rd1);
2252
            break;
2253
        default:
2254
            return 1;
2255
        }
2256
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2257
        gen_op_iwmmxt_set_mup();
2258
        gen_op_iwmmxt_set_cup();
2259
        break;
2260
    case 0x008: case 0x108: case 0x208: case 0x308:        /* WPACK */
2261
    case 0x408: case 0x508: case 0x608: case 0x708:
2262
    case 0x808: case 0x908: case 0xa08: case 0xb08:
2263
    case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2264
        if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2265
            return 1;
2266
        wrd = (insn >> 12) & 0xf;
2267
        rd0 = (insn >> 16) & 0xf;
2268
        rd1 = (insn >> 0) & 0xf;
2269
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2270
        switch ((insn >> 22) & 3) {
2271
        case 1:
2272
            if (insn & (1 << 21))
2273
                gen_op_iwmmxt_packsw_M0_wRn(rd1);
2274
            else
2275
                gen_op_iwmmxt_packuw_M0_wRn(rd1);
2276
            break;
2277
        case 2:
2278
            if (insn & (1 << 21))
2279
                gen_op_iwmmxt_packsl_M0_wRn(rd1);
2280
            else
2281
                gen_op_iwmmxt_packul_M0_wRn(rd1);
2282
            break;
2283
        case 3:
2284
            if (insn & (1 << 21))
2285
                gen_op_iwmmxt_packsq_M0_wRn(rd1);
2286
            else
2287
                gen_op_iwmmxt_packuq_M0_wRn(rd1);
2288
            break;
2289
        }
2290
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2291
        gen_op_iwmmxt_set_mup();
2292
        gen_op_iwmmxt_set_cup();
2293
        break;
2294
    case 0x201: case 0x203: case 0x205: case 0x207:
2295
    case 0x209: case 0x20b: case 0x20d: case 0x20f:
2296
    case 0x211: case 0x213: case 0x215: case 0x217:
2297
    case 0x219: case 0x21b: case 0x21d: case 0x21f:
2298
        wrd = (insn >> 5) & 0xf;
2299
        rd0 = (insn >> 12) & 0xf;
2300
        rd1 = (insn >> 0) & 0xf;
2301
        if (rd0 == 0xf || rd1 == 0xf)
2302
            return 1;
2303
        gen_op_iwmmxt_movq_M0_wRn(wrd);
2304
        tmp = load_reg(s, rd0);
2305
        tmp2 = load_reg(s, rd1);
2306
        switch ((insn >> 16) & 0xf) {
2307
        case 0x0:                                        /* TMIA */
2308
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2309
            break;
2310
        case 0x8:                                        /* TMIAPH */
2311
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2312
            break;
2313
        case 0xc: case 0xd: case 0xe: case 0xf:                /* TMIAxy */
2314
            if (insn & (1 << 16))
2315
                tcg_gen_shri_i32(tmp, tmp, 16);
2316
            if (insn & (1 << 17))
2317
                tcg_gen_shri_i32(tmp2, tmp2, 16);
2318
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2319
            break;
2320
        default:
2321
            dead_tmp(tmp2);
2322
            dead_tmp(tmp);
2323
            return 1;
2324
        }
2325
        dead_tmp(tmp2);
2326
        dead_tmp(tmp);
2327
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2328
        gen_op_iwmmxt_set_mup();
2329
        break;
2330
    default:
2331
        return 1;
2332
    }
2333

    
2334
    return 0;
2335
}
2336

    
2337
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2338
   (ie. an undefined instruction).  */
2339
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2340
{
2341
    int acc, rd0, rd1, rdhi, rdlo;
2342
    TCGv tmp, tmp2;
2343

    
2344
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2345
        /* Multiply with Internal Accumulate Format */
2346
        rd0 = (insn >> 12) & 0xf;
2347
        rd1 = insn & 0xf;
2348
        acc = (insn >> 5) & 7;
2349

    
2350
        if (acc != 0)
2351
            return 1;
2352

    
2353
        tmp = load_reg(s, rd0);
2354
        tmp2 = load_reg(s, rd1);
2355
        switch ((insn >> 16) & 0xf) {
2356
        case 0x0:                                        /* MIA */
2357
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2358
            break;
2359
        case 0x8:                                        /* MIAPH */
2360
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2361
            break;
2362
        case 0xc:                                        /* MIABB */
2363
        case 0xd:                                        /* MIABT */
2364
        case 0xe:                                        /* MIATB */
2365
        case 0xf:                                        /* MIATT */
2366
            if (insn & (1 << 16))
2367
                tcg_gen_shri_i32(tmp, tmp, 16);
2368
            if (insn & (1 << 17))
2369
                tcg_gen_shri_i32(tmp2, tmp2, 16);
2370
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2371
            break;
2372
        default:
2373
            return 1;
2374
        }
2375
        dead_tmp(tmp2);
2376
        dead_tmp(tmp);
2377

    
2378
        gen_op_iwmmxt_movq_wRn_M0(acc);
2379
        return 0;
2380
    }
2381

    
2382
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2383
        /* Internal Accumulator Access Format */
2384
        rdhi = (insn >> 16) & 0xf;
2385
        rdlo = (insn >> 12) & 0xf;
2386
        acc = insn & 7;
2387

    
2388
        if (acc != 0)
2389
            return 1;
2390

    
2391
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2392
            iwmmxt_load_reg(cpu_V0, acc);
2393
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2394
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2395
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2396
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2397
        } else {                                        /* MAR */
2398
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2399
            iwmmxt_store_reg(cpu_V0, acc);
2400
        }
2401
        return 0;
2402
    }
2403

    
2404
    return 1;
2405
}
2406

    
2407
/* Disassemble system coprocessor instruction.  Return nonzero if
2408
   instruction is not defined.  */
2409
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2410
{
2411
    TCGv tmp, tmp2;
2412
    uint32_t rd = (insn >> 12) & 0xf;
2413
    uint32_t cp = (insn >> 8) & 0xf;
2414
    if (IS_USER(s)) {
2415
        return 1;
2416
    }
2417

    
2418
    if (insn & ARM_CP_RW_BIT) {
2419
        if (!env->cp[cp].cp_read)
2420
            return 1;
2421
        gen_set_pc_im(s->pc);
2422
        tmp = new_tmp();
2423
        tmp2 = tcg_const_i32(insn);
2424
        gen_helper_get_cp(tmp, cpu_env, tmp2);
2425
        tcg_temp_free(tmp2);
2426
        store_reg(s, rd, tmp);
2427
    } else {
2428
        if (!env->cp[cp].cp_write)
2429
            return 1;
2430
        gen_set_pc_im(s->pc);
2431
        tmp = load_reg(s, rd);
2432
        tmp2 = tcg_const_i32(insn);
2433
        gen_helper_set_cp(cpu_env, tmp2, tmp);
2434
        tcg_temp_free(tmp2);
2435
        dead_tmp(tmp);
2436
    }
2437
    return 0;
2438
}
2439

    
2440
static int cp15_user_ok(uint32_t insn)
2441
{
2442
    int cpn = (insn >> 16) & 0xf;
2443
    int cpm = insn & 0xf;
2444
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2445

    
2446
    if (cpn == 13 && cpm == 0) {
2447
        /* TLS register.  */
2448
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2449
            return 1;
2450
    }
2451
    if (cpn == 7) {
2452
        /* ISB, DSB, DMB.  */
2453
        if ((cpm == 5 && op == 4)
2454
                || (cpm == 10 && (op == 4 || op == 5)))
2455
            return 1;
2456
    }
2457
    return 0;
2458
}
2459

    
2460
static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd)
2461
{
2462
    TCGv tmp;
2463
    int cpn = (insn >> 16) & 0xf;
2464
    int cpm = insn & 0xf;
2465
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2466

    
2467
    if (!arm_feature(env, ARM_FEATURE_V6K))
2468
        return 0;
2469

    
2470
    if (!(cpn == 13 && cpm == 0))
2471
        return 0;
2472

    
2473
    if (insn & ARM_CP_RW_BIT) {
2474
        switch (op) {
2475
        case 2:
2476
            tmp = load_cpu_field(cp15.c13_tls1);
2477
            break;
2478
        case 3:
2479
            tmp = load_cpu_field(cp15.c13_tls2);
2480
            break;
2481
        case 4:
2482
            tmp = load_cpu_field(cp15.c13_tls3);
2483
            break;
2484
        default:
2485
            return 0;
2486
        }
2487
        store_reg(s, rd, tmp);
2488

    
2489
    } else {
2490
        tmp = load_reg(s, rd);
2491
        switch (op) {
2492
        case 2:
2493
            store_cpu_field(tmp, cp15.c13_tls1);
2494
            break;
2495
        case 3:
2496
            store_cpu_field(tmp, cp15.c13_tls2);
2497
            break;
2498
        case 4:
2499
            store_cpu_field(tmp, cp15.c13_tls3);
2500
            break;
2501
        default:
2502
            dead_tmp(tmp);
2503
            return 0;
2504
        }
2505
    }
2506
    return 1;
2507
}
2508

    
2509
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2510
   instruction is not defined.  */
2511
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2512
{
2513
    uint32_t rd;
2514
    TCGv tmp, tmp2;
2515

    
2516
    /* M profile cores use memory mapped registers instead of cp15.  */
2517
    if (arm_feature(env, ARM_FEATURE_M))
2518
        return 1;
2519

    
2520
    if ((insn & (1 << 25)) == 0) {
2521
        if (insn & (1 << 20)) {
2522
            /* mrrc */
2523
            return 1;
2524
        }
2525
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2526
        return 0;
2527
    }
2528
    if ((insn & (1 << 4)) == 0) {
2529
        /* cdp */
2530
        return 1;
2531
    }
2532
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2533
        return 1;
2534
    }
2535
    if ((insn & 0x0fff0fff) == 0x0e070f90
2536
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2537
        /* Wait for interrupt.  */
2538
        gen_set_pc_im(s->pc);
2539
        s->is_jmp = DISAS_WFI;
2540
        return 0;
2541
    }
2542
    rd = (insn >> 12) & 0xf;
2543

    
2544
    if (cp15_tls_load_store(env, s, insn, rd))
2545
        return 0;
2546

    
2547
    tmp2 = tcg_const_i32(insn);
2548
    if (insn & ARM_CP_RW_BIT) {
2549
        tmp = new_tmp();
2550
        gen_helper_get_cp15(tmp, cpu_env, tmp2);
2551
        /* If the destination register is r15 then sets condition codes.  */
2552
        if (rd != 15)
2553
            store_reg(s, rd, tmp);
2554
        else
2555
            dead_tmp(tmp);
2556
    } else {
2557
        tmp = load_reg(s, rd);
2558
        gen_helper_set_cp15(cpu_env, tmp2, tmp);
2559
        dead_tmp(tmp);
2560
        /* Normally we would always end the TB here, but Linux
2561
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2562
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2563
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2564
                (insn & 0x0fff0fff) != 0x0e010f10)
2565
            gen_lookup_tb(s);
2566
    }
2567
    tcg_temp_free_i32(tmp2);
2568
    return 0;
2569
}
2570

    
2571
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2572
#define VFP_SREG(insn, bigbit, smallbit) \
2573
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2574
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2575
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2576
        reg = (((insn) >> (bigbit)) & 0x0f) \
2577
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2578
    } else { \
2579
        if (insn & (1 << (smallbit))) \
2580
            return 1; \
2581
        reg = ((insn) >> (bigbit)) & 0x0f; \
2582
    }} while (0)
2583

    
2584
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2585
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2586
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2587
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2588
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2589
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2590

    
2591
/* Move between integer and VFP cores.  */
2592
static TCGv gen_vfp_mrs(void)
2593
{
2594
    TCGv tmp = new_tmp();
2595
    tcg_gen_mov_i32(tmp, cpu_F0s);
2596
    return tmp;
2597
}
2598

    
2599
static void gen_vfp_msr(TCGv tmp)
2600
{
2601
    tcg_gen_mov_i32(cpu_F0s, tmp);
2602
    dead_tmp(tmp);
2603
}
2604

    
2605
static inline int
2606
vfp_enabled(CPUState * env)
2607
{
2608
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2609
}
2610

    
2611
static void gen_neon_dup_u8(TCGv var, int shift)
2612
{
2613
    TCGv tmp = new_tmp();
2614
    if (shift)
2615
        tcg_gen_shri_i32(var, var, shift);
2616
    tcg_gen_ext8u_i32(var, var);
2617
    tcg_gen_shli_i32(tmp, var, 8);
2618
    tcg_gen_or_i32(var, var, tmp);
2619
    tcg_gen_shli_i32(tmp, var, 16);
2620
    tcg_gen_or_i32(var, var, tmp);
2621
    dead_tmp(tmp);
2622
}
2623

    
2624
static void gen_neon_dup_low16(TCGv var)
2625
{
2626
    TCGv tmp = new_tmp();
2627
    tcg_gen_ext16u_i32(var, var);
2628
    tcg_gen_shli_i32(tmp, var, 16);
2629
    tcg_gen_or_i32(var, var, tmp);
2630
    dead_tmp(tmp);
2631
}
2632

    
2633
static void gen_neon_dup_high16(TCGv var)
2634
{
2635
    TCGv tmp = new_tmp();
2636
    tcg_gen_andi_i32(var, var, 0xffff0000);
2637
    tcg_gen_shri_i32(tmp, var, 16);
2638
    tcg_gen_or_i32(var, var, tmp);
2639
    dead_tmp(tmp);
2640
}
2641

    
2642
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2643
   (ie. an undefined instruction).  */
2644
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2645
{
2646
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2647
    int dp, veclen;
2648
    TCGv addr;
2649
    TCGv tmp;
2650
    TCGv tmp2;
2651

    
2652
    if (!arm_feature(env, ARM_FEATURE_VFP))
2653
        return 1;
2654

    
2655
    if (!vfp_enabled(env)) {
2656
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2657
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2658
            return 1;
2659
        rn = (insn >> 16) & 0xf;
2660
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2661
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2662
            return 1;
2663
    }
2664
    dp = ((insn & 0xf00) == 0xb00);
2665
    switch ((insn >> 24) & 0xf) {
2666
    case 0xe:
2667
        if (insn & (1 << 4)) {
2668
            /* single register transfer */
2669
            rd = (insn >> 12) & 0xf;
2670
            if (dp) {
2671
                int size;
2672
                int pass;
2673

    
2674
                VFP_DREG_N(rn, insn);
2675
                if (insn & 0xf)
2676
                    return 1;
2677
                if (insn & 0x00c00060
2678
                    && !arm_feature(env, ARM_FEATURE_NEON))
2679
                    return 1;
2680

    
2681
                pass = (insn >> 21) & 1;
2682
                if (insn & (1 << 22)) {
2683
                    size = 0;
2684
                    offset = ((insn >> 5) & 3) * 8;
2685
                } else if (insn & (1 << 5)) {
2686
                    size = 1;
2687
                    offset = (insn & (1 << 6)) ? 16 : 0;
2688
                } else {
2689
                    size = 2;
2690
                    offset = 0;
2691
                }
2692
                if (insn & ARM_CP_RW_BIT) {
2693
                    /* vfp->arm */
2694
                    tmp = neon_load_reg(rn, pass);
2695
                    switch (size) {
2696
                    case 0:
2697
                        if (offset)
2698
                            tcg_gen_shri_i32(tmp, tmp, offset);
2699
                        if (insn & (1 << 23))
2700
                            gen_uxtb(tmp);
2701
                        else
2702
                            gen_sxtb(tmp);
2703
                        break;
2704
                    case 1:
2705
                        if (insn & (1 << 23)) {
2706
                            if (offset) {
2707
                                tcg_gen_shri_i32(tmp, tmp, 16);
2708
                            } else {
2709
                                gen_uxth(tmp);
2710
                            }
2711
                        } else {
2712
                            if (offset) {
2713
                                tcg_gen_sari_i32(tmp, tmp, 16);
2714
                            } else {
2715
                                gen_sxth(tmp);
2716
                            }
2717
                        }
2718
                        break;
2719
                    case 2:
2720
                        break;
2721
                    }
2722
                    store_reg(s, rd, tmp);
2723
                } else {
2724
                    /* arm->vfp */
2725
                    tmp = load_reg(s, rd);
2726
                    if (insn & (1 << 23)) {
2727
                        /* VDUP */
2728
                        if (size == 0) {
2729
                            gen_neon_dup_u8(tmp, 0);
2730
                        } else if (size == 1) {
2731
                            gen_neon_dup_low16(tmp);
2732
                        }
2733
                        for (n = 0; n <= pass * 2; n++) {
2734
                            tmp2 = new_tmp();
2735
                            tcg_gen_mov_i32(tmp2, tmp);
2736
                            neon_store_reg(rn, n, tmp2);
2737
                        }
2738
                        neon_store_reg(rn, n, tmp);
2739
                    } else {
2740
                        /* VMOV */
2741
                        switch (size) {
2742
                        case 0:
2743
                            tmp2 = neon_load_reg(rn, pass);
2744
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2745
                            dead_tmp(tmp2);
2746
                            break;
2747
                        case 1:
2748
                            tmp2 = neon_load_reg(rn, pass);
2749
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2750
                            dead_tmp(tmp2);
2751
                            break;
2752
                        case 2:
2753
                            break;
2754
                        }
2755
                        neon_store_reg(rn, pass, tmp);
2756
                    }
2757
                }
2758
            } else { /* !dp */
2759
                if ((insn & 0x6f) != 0x00)
2760
                    return 1;
2761
                rn = VFP_SREG_N(insn);
2762
                if (insn & ARM_CP_RW_BIT) {
2763
                    /* vfp->arm */
2764
                    if (insn & (1 << 21)) {
2765
                        /* system register */
2766
                        rn >>= 1;
2767

    
2768
                        switch (rn) {
2769
                        case ARM_VFP_FPSID:
2770
                            /* VFP2 allows access to FSID from userspace.
2771
                               VFP3 restricts all id registers to privileged
2772
                               accesses.  */
2773
                            if (IS_USER(s)
2774
                                && arm_feature(env, ARM_FEATURE_VFP3))
2775
                                return 1;
2776
                            tmp = load_cpu_field(vfp.xregs[rn]);
2777
                            break;
2778
                        case ARM_VFP_FPEXC:
2779
                            if (IS_USER(s))
2780
                                return 1;
2781
                            tmp = load_cpu_field(vfp.xregs[rn]);
2782
                            break;
2783
                        case ARM_VFP_FPINST:
2784
                        case ARM_VFP_FPINST2:
2785
                            /* Not present in VFP3.  */
2786
                            if (IS_USER(s)
2787
                                || arm_feature(env, ARM_FEATURE_VFP3))
2788
                                return 1;
2789
                            tmp = load_cpu_field(vfp.xregs[rn]);
2790
                            break;
2791
                        case ARM_VFP_FPSCR:
2792
                            if (rd == 15) {
2793
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2794
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2795
                            } else {
2796
                                tmp = new_tmp();
2797
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2798
                            }
2799
                            break;
2800
                        case ARM_VFP_MVFR0:
2801
                        case ARM_VFP_MVFR1:
2802
                            if (IS_USER(s)
2803
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2804
                                return 1;
2805
                            tmp = load_cpu_field(vfp.xregs[rn]);
2806
                            break;
2807
                        default:
2808
                            return 1;
2809
                        }
2810
                    } else {
2811
                        gen_mov_F0_vreg(0, rn);
2812
                        tmp = gen_vfp_mrs();
2813
                    }
2814
                    if (rd == 15) {
2815
                        /* Set the 4 flag bits in the CPSR.  */
2816
                        gen_set_nzcv(tmp);
2817
                        dead_tmp(tmp);
2818
                    } else {
2819
                        store_reg(s, rd, tmp);
2820
                    }
2821
                } else {
2822
                    /* arm->vfp */
2823
                    tmp = load_reg(s, rd);
2824
                    if (insn & (1 << 21)) {
2825
                        rn >>= 1;
2826
                        /* system register */
2827
                        switch (rn) {
2828
                        case ARM_VFP_FPSID:
2829
                        case ARM_VFP_MVFR0:
2830
                        case ARM_VFP_MVFR1:
2831
                            /* Writes are ignored.  */
2832
                            break;
2833
                        case ARM_VFP_FPSCR:
2834
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2835
                            dead_tmp(tmp);
2836
                            gen_lookup_tb(s);
2837
                            break;
2838
                        case ARM_VFP_FPEXC:
2839
                            if (IS_USER(s))
2840
                                return 1;
2841
                            /* TODO: VFP subarchitecture support.
2842
                             * For now, keep the EN bit only */
2843
                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2844
                            store_cpu_field(tmp, vfp.xregs[rn]);
2845
                            gen_lookup_tb(s);
2846
                            break;
2847
                        case ARM_VFP_FPINST:
2848
                        case ARM_VFP_FPINST2:
2849
                            store_cpu_field(tmp, vfp.xregs[rn]);
2850
                            break;
2851
                        default:
2852
                            return 1;
2853
                        }
2854
                    } else {
2855
                        gen_vfp_msr(tmp);
2856
                        gen_mov_vreg_F0(0, rn);
2857
                    }
2858
                }
2859
            }
2860
        } else {
2861
            /* data processing */
2862
            /* The opcode is in bits 23, 21, 20 and 6.  */
2863
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2864
            if (dp) {
2865
                if (op == 15) {
2866
                    /* rn is opcode */
2867
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2868
                } else {
2869
                    /* rn is register number */
2870
                    VFP_DREG_N(rn, insn);
2871
                }
2872

    
2873
                if (op == 15 && (rn == 15 || rn > 17)) {
2874
                    /* Integer or single precision destination.  */
2875
                    rd = VFP_SREG_D(insn);
2876
                } else {
2877
                    VFP_DREG_D(rd, insn);
2878
                }
2879

    
2880
                if (op == 15 && (rn == 16 || rn == 17)) {
2881
                    /* Integer source.  */
2882
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2883
                } else {
2884
                    VFP_DREG_M(rm, insn);
2885
                }
2886
            } else {
2887
                rn = VFP_SREG_N(insn);
2888
                if (op == 15 && rn == 15) {
2889
                    /* Double precision destination.  */
2890
                    VFP_DREG_D(rd, insn);
2891
                } else {
2892
                    rd = VFP_SREG_D(insn);
2893
                }
2894
                rm = VFP_SREG_M(insn);
2895
            }
2896

    
2897
            veclen = env->vfp.vec_len;
2898
            if (op == 15 && rn > 3)
2899
                veclen = 0;
2900

    
2901
            /* Shut up compiler warnings.  */
2902
            delta_m = 0;
2903
            delta_d = 0;
2904
            bank_mask = 0;
2905

    
2906
            if (veclen > 0) {
2907
                if (dp)
2908
                    bank_mask = 0xc;
2909
                else
2910
                    bank_mask = 0x18;
2911

    
2912
                /* Figure out what type of vector operation this is.  */
2913
                if ((rd & bank_mask) == 0) {
2914
                    /* scalar */
2915
                    veclen = 0;
2916
                } else {
2917
                    if (dp)
2918
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2919
                    else
2920
                        delta_d = env->vfp.vec_stride + 1;
2921

    
2922
                    if ((rm & bank_mask) == 0) {
2923
                        /* mixed scalar/vector */
2924
                        delta_m = 0;
2925
                    } else {
2926
                        /* vector */
2927
                        delta_m = delta_d;
2928
                    }
2929
                }
2930
            }
2931

    
2932
            /* Load the initial operands.  */
2933
            if (op == 15) {
2934
                switch (rn) {
2935
                case 16:
2936
                case 17:
2937
                    /* Integer source */
2938
                    gen_mov_F0_vreg(0, rm);
2939
                    break;
2940
                case 8:
2941
                case 9:
2942
                    /* Compare */
2943
                    gen_mov_F0_vreg(dp, rd);
2944
                    gen_mov_F1_vreg(dp, rm);
2945
                    break;
2946
                case 10:
2947
                case 11:
2948
                    /* Compare with zero */
2949
                    gen_mov_F0_vreg(dp, rd);
2950
                    gen_vfp_F1_ld0(dp);
2951
                    break;
2952
                case 20:
2953
                case 21:
2954
                case 22:
2955
                case 23:
2956
                case 28:
2957
                case 29:
2958
                case 30:
2959
                case 31:
2960
                    /* Source and destination the same.  */
2961
                    gen_mov_F0_vreg(dp, rd);
2962
                    break;
2963
                default:
2964
                    /* One source operand.  */
2965
                    gen_mov_F0_vreg(dp, rm);
2966
                    break;
2967
                }
2968
            } else {
2969
                /* Two source operands.  */
2970
                gen_mov_F0_vreg(dp, rn);
2971
                gen_mov_F1_vreg(dp, rm);
2972
            }
2973

    
2974
            for (;;) {
2975
                /* Perform the calculation.  */
2976
                switch (op) {
2977
                case 0: /* mac: fd + (fn * fm) */
2978
                    gen_vfp_mul(dp);
2979
                    gen_mov_F1_vreg(dp, rd);
2980
                    gen_vfp_add(dp);
2981
                    break;
2982
                case 1: /* nmac: fd - (fn * fm) */
2983
                    gen_vfp_mul(dp);
2984
                    gen_vfp_neg(dp);
2985
                    gen_mov_F1_vreg(dp, rd);
2986
                    gen_vfp_add(dp);
2987
                    break;
2988
                case 2: /* msc: -fd + (fn * fm) */
2989
                    gen_vfp_mul(dp);
2990
                    gen_mov_F1_vreg(dp, rd);
2991
                    gen_vfp_sub(dp);
2992
                    break;
2993
                case 3: /* nmsc: -fd - (fn * fm)  */
2994
                    gen_vfp_mul(dp);
2995
                    gen_vfp_neg(dp);
2996
                    gen_mov_F1_vreg(dp, rd);
2997
                    gen_vfp_sub(dp);
2998
                    break;
2999
                case 4: /* mul: fn * fm */
3000
                    gen_vfp_mul(dp);
3001
                    break;
3002
                case 5: /* nmul: -(fn * fm) */
3003
                    gen_vfp_mul(dp);
3004
                    gen_vfp_neg(dp);
3005
                    break;
3006
                case 6: /* add: fn + fm */
3007
                    gen_vfp_add(dp);
3008
                    break;
3009
                case 7: /* sub: fn - fm */
3010
                    gen_vfp_sub(dp);
3011
                    break;
3012
                case 8: /* div: fn / fm */
3013
                    gen_vfp_div(dp);
3014
                    break;
3015
                case 14: /* fconst */
3016
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3017
                      return 1;
3018

    
3019
                    n = (insn << 12) & 0x80000000;
3020
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3021
                    if (dp) {
3022
                        if (i & 0x40)
3023
                            i |= 0x3f80;
3024
                        else
3025
                            i |= 0x4000;
3026
                        n |= i << 16;
3027
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3028
                    } else {
3029
                        if (i & 0x40)
3030
                            i |= 0x780;
3031
                        else
3032
                            i |= 0x800;
3033
                        n |= i << 19;
3034
                        tcg_gen_movi_i32(cpu_F0s, n);
3035
                    }
3036
                    break;
3037
                case 15: /* extension space */
3038
                    switch (rn) {
3039
                    case 0: /* cpy */
3040
                        /* no-op */
3041
                        break;
3042
                    case 1: /* abs */
3043
                        gen_vfp_abs(dp);
3044
                        break;
3045
                    case 2: /* neg */
3046
                        gen_vfp_neg(dp);
3047
                        break;
3048
                    case 3: /* sqrt */
3049
                        gen_vfp_sqrt(dp);
3050
                        break;
3051
                    case 4: /* vcvtb.f32.f16 */
3052
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3053
                          return 1;
3054
                        tmp = gen_vfp_mrs();
3055
                        tcg_gen_ext16u_i32(tmp, tmp);
3056
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3057
                        dead_tmp(tmp);
3058
                        break;
3059
                    case 5: /* vcvtt.f32.f16 */
3060
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3061
                          return 1;
3062
                        tmp = gen_vfp_mrs();
3063
                        tcg_gen_shri_i32(tmp, tmp, 16);
3064
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3065
                        dead_tmp(tmp);
3066
                        break;
3067
                    case 6: /* vcvtb.f16.f32 */
3068
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3069
                          return 1;
3070
                        tmp = new_tmp();
3071
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3072
                        gen_mov_F0_vreg(0, rd);
3073
                        tmp2 = gen_vfp_mrs();
3074
                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3075
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3076
                        dead_tmp(tmp2);
3077
                        gen_vfp_msr(tmp);
3078
                        break;
3079
                    case 7: /* vcvtt.f16.f32 */
3080
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3081
                          return 1;
3082
                        tmp = new_tmp();
3083
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3084
                        tcg_gen_shli_i32(tmp, tmp, 16);
3085
                        gen_mov_F0_vreg(0, rd);
3086
                        tmp2 = gen_vfp_mrs();
3087
                        tcg_gen_ext16u_i32(tmp2, tmp2);
3088
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3089
                        dead_tmp(tmp2);
3090
                        gen_vfp_msr(tmp);
3091
                        break;
3092
                    case 8: /* cmp */
3093
                        gen_vfp_cmp(dp);
3094
                        break;
3095
                    case 9: /* cmpe */
3096
                        gen_vfp_cmpe(dp);
3097
                        break;
3098
                    case 10: /* cmpz */
3099
                        gen_vfp_cmp(dp);
3100
                        break;
3101
                    case 11: /* cmpez */
3102
                        gen_vfp_F1_ld0(dp);
3103
                        gen_vfp_cmpe(dp);
3104
                        break;
3105
                    case 15: /* single<->double conversion */
3106
                        if (dp)
3107
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3108
                        else
3109
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3110
                        break;
3111
                    case 16: /* fuito */
3112
                        gen_vfp_uito(dp);
3113
                        break;
3114
                    case 17: /* fsito */
3115
                        gen_vfp_sito(dp);
3116
                        break;
3117
                    case 20: /* fshto */
3118
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3119
                          return 1;
3120
                        gen_vfp_shto(dp, 16 - rm);
3121
                        break;
3122
                    case 21: /* fslto */
3123
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3124
                          return 1;
3125
                        gen_vfp_slto(dp, 32 - rm);
3126
                        break;
3127
                    case 22: /* fuhto */
3128
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3129
                          return 1;
3130
                        gen_vfp_uhto(dp, 16 - rm);
3131
                        break;
3132
                    case 23: /* fulto */
3133
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3134
                          return 1;
3135
                        gen_vfp_ulto(dp, 32 - rm);
3136
                        break;
3137
                    case 24: /* ftoui */
3138
                        gen_vfp_toui(dp);
3139
                        break;
3140
                    case 25: /* ftouiz */
3141
                        gen_vfp_touiz(dp);
3142
                        break;
3143
                    case 26: /* ftosi */
3144
                        gen_vfp_tosi(dp);
3145
                        break;
3146
                    case 27: /* ftosiz */
3147
                        gen_vfp_tosiz(dp);
3148
                        break;
3149
                    case 28: /* ftosh */
3150
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3151
                          return 1;
3152
                        gen_vfp_tosh(dp, 16 - rm);
3153
                        break;
3154
                    case 29: /* ftosl */
3155
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3156
                          return 1;
3157
                        gen_vfp_tosl(dp, 32 - rm);
3158
                        break;
3159
                    case 30: /* ftouh */
3160
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3161
                          return 1;
3162
                        gen_vfp_touh(dp, 16 - rm);
3163
                        break;
3164
                    case 31: /* ftoul */
3165
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3166
                          return 1;
3167
                        gen_vfp_toul(dp, 32 - rm);
3168
                        break;
3169
                    default: /* undefined */
3170
                        printf ("rn:%d\n", rn);
3171
                        return 1;
3172
                    }
3173
                    break;
3174
                default: /* undefined */
3175
                    printf ("op:%d\n", op);
3176
                    return 1;
3177
                }
3178

    
3179
                /* Write back the result.  */
3180
                if (op == 15 && (rn >= 8 && rn <= 11))
3181
                    ; /* Comparison, do nothing.  */
3182
                else if (op == 15 && rn > 17)
3183
                    /* Integer result.  */
3184
                    gen_mov_vreg_F0(0, rd);
3185
                else if (op == 15 && rn == 15)
3186
                    /* conversion */
3187
                    gen_mov_vreg_F0(!dp, rd);
3188
                else
3189
                    gen_mov_vreg_F0(dp, rd);
3190

    
3191
                /* break out of the loop if we have finished  */
3192
                if (veclen == 0)
3193
                    break;
3194

    
3195
                if (op == 15 && delta_m == 0) {
3196
                    /* single source one-many */
3197
                    while (veclen--) {
3198
                        rd = ((rd + delta_d) & (bank_mask - 1))
3199
                             | (rd & bank_mask);
3200
                        gen_mov_vreg_F0(dp, rd);
3201
                    }
3202
                    break;
3203
                }
3204
                /* Setup the next operands.  */
3205
                veclen--;
3206
                rd = ((rd + delta_d) & (bank_mask - 1))
3207
                     | (rd & bank_mask);
3208

    
3209
                if (op == 15) {
3210
                    /* One source operand.  */
3211
                    rm = ((rm + delta_m) & (bank_mask - 1))
3212
                         | (rm & bank_mask);
3213
                    gen_mov_F0_vreg(dp, rm);
3214
                } else {
3215
                    /* Two source operands.  */
3216
                    rn = ((rn + delta_d) & (bank_mask - 1))
3217
                         | (rn & bank_mask);
3218
                    gen_mov_F0_vreg(dp, rn);
3219
                    if (delta_m) {
3220
                        rm = ((rm + delta_m) & (bank_mask - 1))
3221
                             | (rm & bank_mask);
3222
                        gen_mov_F1_vreg(dp, rm);
3223
                    }
3224
                }
3225
            }
3226
        }
3227
        break;
3228
    case 0xc:
3229
    case 0xd:
3230
        if (dp && (insn & 0x03e00000) == 0x00400000) {
3231
            /* two-register transfer */
3232
            rn = (insn >> 16) & 0xf;
3233
            rd = (insn >> 12) & 0xf;
3234
            if (dp) {
3235
                VFP_DREG_M(rm, insn);
3236
            } else {
3237
                rm = VFP_SREG_M(insn);
3238
            }
3239

    
3240
            if (insn & ARM_CP_RW_BIT) {
3241
                /* vfp->arm */
3242
                if (dp) {
3243
                    gen_mov_F0_vreg(0, rm * 2);
3244
                    tmp = gen_vfp_mrs();
3245
                    store_reg(s, rd, tmp);
3246
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3247
                    tmp = gen_vfp_mrs();
3248
                    store_reg(s, rn, tmp);
3249
                } else {
3250
                    gen_mov_F0_vreg(0, rm);
3251
                    tmp = gen_vfp_mrs();
3252
                    store_reg(s, rn, tmp);
3253
                    gen_mov_F0_vreg(0, rm + 1);
3254
                    tmp = gen_vfp_mrs();
3255
                    store_reg(s, rd, tmp);
3256
                }
3257
            } else {
3258
                /* arm->vfp */
3259
                if (dp) {
3260
                    tmp = load_reg(s, rd);
3261
                    gen_vfp_msr(tmp);
3262
                    gen_mov_vreg_F0(0, rm * 2);
3263
                    tmp = load_reg(s, rn);
3264
                    gen_vfp_msr(tmp);
3265
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3266
                } else {
3267
                    tmp = load_reg(s, rn);
3268
                    gen_vfp_msr(tmp);
3269
                    gen_mov_vreg_F0(0, rm);
3270
                    tmp = load_reg(s, rd);
3271
                    gen_vfp_msr(tmp);
3272
                    gen_mov_vreg_F0(0, rm + 1);
3273
                }
3274
            }
3275
        } else {
3276
            /* Load/store */
3277
            rn = (insn >> 16) & 0xf;
3278
            if (dp)
3279
                VFP_DREG_D(rd, insn);
3280
            else
3281
                rd = VFP_SREG_D(insn);
3282
            if (s->thumb && rn == 15) {
3283
                addr = new_tmp();
3284
                tcg_gen_movi_i32(addr, s->pc & ~2);
3285
            } else {
3286
                addr = load_reg(s, rn);
3287
            }
3288
            if ((insn & 0x01200000) == 0x01000000) {
3289
                /* Single load/store */
3290
                offset = (insn & 0xff) << 2;
3291
                if ((insn & (1 << 23)) == 0)
3292
                    offset = -offset;
3293
                tcg_gen_addi_i32(addr, addr, offset);
3294
                if (insn & (1 << 20)) {
3295
                    gen_vfp_ld(s, dp, addr);
3296
                    gen_mov_vreg_F0(dp, rd);
3297
                } else {
3298
                    gen_mov_F0_vreg(dp, rd);
3299
                    gen_vfp_st(s, dp, addr);
3300
                }
3301
                dead_tmp(addr);
3302
            } else {
3303
                /* load/store multiple */
3304
                if (dp)
3305
                    n = (insn >> 1) & 0x7f;
3306
                else
3307
                    n = insn & 0xff;
3308

    
3309
                if (insn & (1 << 24)) /* pre-decrement */
3310
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3311

    
3312
                if (dp)
3313
                    offset = 8;
3314
                else
3315
                    offset = 4;
3316
                for (i = 0; i < n; i++) {
3317
                    if (insn & ARM_CP_RW_BIT) {
3318
                        /* load */
3319
                        gen_vfp_ld(s, dp, addr);
3320
                        gen_mov_vreg_F0(dp, rd + i);
3321
                    } else {
3322
                        /* store */
3323
                        gen_mov_F0_vreg(dp, rd + i);
3324
                        gen_vfp_st(s, dp, addr);
3325
                    }
3326
                    tcg_gen_addi_i32(addr, addr, offset);
3327
                }
3328
                if (insn & (1 << 21)) {
3329
                    /* writeback */
3330
                    if (insn & (1 << 24))
3331
                        offset = -offset * n;
3332
                    else if (dp && (insn & 1))
3333
                        offset = 4;
3334
                    else
3335
                        offset = 0;
3336

    
3337
                    if (offset != 0)
3338
                        tcg_gen_addi_i32(addr, addr, offset);
3339
                    store_reg(s, rn, addr);
3340
                } else {
3341
                    dead_tmp(addr);
3342
                }
3343
            }
3344
        }
3345
        break;
3346
    default:
3347
        /* Should never happen.  */
3348
        return 1;
3349
    }
3350
    return 0;
3351
}
3352

    
3353
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3354
{
3355
    TranslationBlock *tb;
3356

    
3357
    tb = s->tb;
3358
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3359
        tcg_gen_goto_tb(n);
3360
        gen_set_pc_im(dest);
3361
        tcg_gen_exit_tb((long)tb + n);
3362
    } else {
3363
        gen_set_pc_im(dest);
3364
        tcg_gen_exit_tb(0);
3365
    }
3366
}
3367

    
3368
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3369
{
3370
    if (unlikely(s->singlestep_enabled)) {
3371
        /* An indirect jump so that we still trigger the debug exception.  */
3372
        if (s->thumb)
3373
            dest |= 1;
3374
        gen_bx_im(s, dest);
3375
    } else {
3376
        gen_goto_tb(s, 0, dest);
3377
        s->is_jmp = DISAS_TB_JUMP;
3378
    }
3379
}
3380

    
3381
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3382
{
3383
    if (x)
3384
        tcg_gen_sari_i32(t0, t0, 16);
3385
    else
3386
        gen_sxth(t0);
3387
    if (y)
3388
        tcg_gen_sari_i32(t1, t1, 16);
3389
    else
3390
        gen_sxth(t1);
3391
    tcg_gen_mul_i32(t0, t0, t1);
3392
}
3393

    
3394
/* Return the mask of PSR bits set by a MSR instruction.  */
3395
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3396
    uint32_t mask;
3397

    
3398
    mask = 0;
3399
    if (flags & (1 << 0))
3400
        mask |= 0xff;
3401
    if (flags & (1 << 1))
3402
        mask |= 0xff00;
3403
    if (flags & (1 << 2))
3404
        mask |= 0xff0000;
3405
    if (flags & (1 << 3))
3406
        mask |= 0xff000000;
3407

    
3408
    /* Mask out undefined bits.  */
3409
    mask &= ~CPSR_RESERVED;
3410
    if (!arm_feature(env, ARM_FEATURE_V6))
3411
        mask &= ~(CPSR_E | CPSR_GE);
3412
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3413
        mask &= ~CPSR_IT;
3414
    /* Mask out execution state bits.  */
3415
    if (!spsr)
3416
        mask &= ~CPSR_EXEC;
3417
    /* Mask out privileged bits.  */
3418
    if (IS_USER(s))
3419
        mask &= CPSR_USER;
3420
    return mask;
3421
}
3422

    
3423
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3424
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3425
{
3426
    TCGv tmp;
3427
    if (spsr) {
3428
        /* ??? This is also undefined in system mode.  */
3429
        if (IS_USER(s))
3430
            return 1;
3431

    
3432
        tmp = load_cpu_field(spsr);
3433
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3434
        tcg_gen_andi_i32(t0, t0, mask);
3435
        tcg_gen_or_i32(tmp, tmp, t0);
3436
        store_cpu_field(tmp, spsr);
3437
    } else {
3438
        gen_set_cpsr(t0, mask);
3439
    }
3440
    dead_tmp(t0);
3441
    gen_lookup_tb(s);
3442
    return 0;
3443
}
3444

    
3445
/* Returns nonzero if access to the PSR is not permitted.  */
3446
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3447
{
3448
    TCGv tmp;
3449
    tmp = new_tmp();
3450
    tcg_gen_movi_i32(tmp, val);
3451
    return gen_set_psr(s, mask, spsr, tmp);
3452
}
3453

    
3454
/* Generate an old-style exception return. Marks pc as dead. */
3455
static void gen_exception_return(DisasContext *s, TCGv pc)
3456
{
3457
    TCGv tmp;
3458
    store_reg(s, 15, pc);
3459
    tmp = load_cpu_field(spsr);
3460
    gen_set_cpsr(tmp, 0xffffffff);
3461
    dead_tmp(tmp);
3462
    s->is_jmp = DISAS_UPDATE;
3463
}
3464

    
3465
/* Generate a v6 exception return.  Marks both values as dead.  */
3466
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3467
{
3468
    gen_set_cpsr(cpsr, 0xffffffff);
3469
    dead_tmp(cpsr);
3470
    store_reg(s, 15, pc);
3471
    s->is_jmp = DISAS_UPDATE;
3472
}
3473

    
3474
static inline void
3475
gen_set_condexec (DisasContext *s)
3476
{
3477
    if (s->condexec_mask) {
3478
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3479
        TCGv tmp = new_tmp();
3480
        tcg_gen_movi_i32(tmp, val);
3481
        store_cpu_field(tmp, condexec_bits);
3482
    }
3483
}
3484

    
3485
static void gen_nop_hint(DisasContext *s, int val)
3486
{
3487
    switch (val) {
3488
    case 3: /* wfi */
3489
        gen_set_pc_im(s->pc);
3490
        s->is_jmp = DISAS_WFI;
3491
        break;
3492
    case 2: /* wfe */
3493
    case 4: /* sev */
3494
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3495
    default: /* nop */
3496
        break;
3497
    }
3498
}
3499

    
3500
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3501

    
3502
static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3503
{
3504
    switch (size) {
3505
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3506
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3507
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3508
    default: return 1;
3509
    }
3510
    return 0;
3511
}
3512

    
3513
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3514
{
3515
    switch (size) {
3516
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3517
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3518
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3519
    default: return;
3520
    }
3521
}
3522

    
3523
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3524
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3525
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3526
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3527
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3528

    
3529
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3530
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3531
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3532
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3533
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3534

    
3535
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3536
    switch ((size << 1) | u) { \
3537
    case 0: \
3538
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3539
        break; \
3540
    case 1: \
3541
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3542
        break; \
3543
    case 2: \
3544
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3545
        break; \
3546
    case 3: \
3547
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3548
        break; \
3549
    case 4: \
3550
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3551
        break; \
3552
    case 5: \
3553
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3554
        break; \
3555
    default: return 1; \
3556
    }} while (0)
3557

    
3558
#define GEN_NEON_INTEGER_OP(name) do { \
3559
    switch ((size << 1) | u) { \
3560
    case 0: \
3561
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3562
        break; \
3563
    case 1: \
3564
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3565
        break; \
3566
    case 2: \
3567
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3568
        break; \
3569
    case 3: \
3570
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3571
        break; \
3572
    case 4: \
3573
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3574
        break; \
3575
    case 5: \
3576
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3577
        break; \
3578
    default: return 1; \
3579
    }} while (0)
3580

    
3581
static TCGv neon_load_scratch(int scratch)
3582
{
3583
    TCGv tmp = new_tmp();
3584
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3585
    return tmp;
3586
}
3587

    
3588
static void neon_store_scratch(int scratch, TCGv var)
3589
{
3590
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3591
    dead_tmp(var);
3592
}
3593

    
3594
static inline TCGv neon_get_scalar(int size, int reg)
3595
{
3596
    TCGv tmp;
3597
    if (size == 1) {
3598
        tmp = neon_load_reg(reg >> 1, reg & 1);
3599
    } else {
3600
        tmp = neon_load_reg(reg >> 2, (reg >> 1) & 1);
3601
        if (reg & 1) {
3602
            gen_neon_dup_low16(tmp);
3603
        } else {
3604
            gen_neon_dup_high16(tmp);
3605
        }
3606
    }
3607
    return tmp;
3608
}
3609

    
3610
static void gen_neon_unzip_u8(TCGv t0, TCGv t1)
3611
{
3612
    TCGv rd, rm, tmp;
3613

    
3614
    rd = new_tmp();
3615
    rm = new_tmp();
3616
    tmp = new_tmp();
3617

    
3618
    tcg_gen_andi_i32(rd, t0, 0xff);
3619
    tcg_gen_shri_i32(tmp, t0, 8);
3620
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3621
    tcg_gen_or_i32(rd, rd, tmp);
3622
    tcg_gen_shli_i32(tmp, t1, 16);
3623
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3624
    tcg_gen_or_i32(rd, rd, tmp);
3625
    tcg_gen_shli_i32(tmp, t1, 8);
3626
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3627
    tcg_gen_or_i32(rd, rd, tmp);
3628

    
3629
    tcg_gen_shri_i32(rm, t0, 8);
3630
    tcg_gen_andi_i32(rm, rm, 0xff);
3631
    tcg_gen_shri_i32(tmp, t0, 16);
3632
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3633
    tcg_gen_or_i32(rm, rm, tmp);
3634
    tcg_gen_shli_i32(tmp, t1, 8);
3635
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3636
    tcg_gen_or_i32(rm, rm, tmp);
3637
    tcg_gen_andi_i32(tmp, t1, 0xff000000);
3638
    tcg_gen_or_i32(t1, rm, tmp);
3639
    tcg_gen_mov_i32(t0, rd);
3640

    
3641
    dead_tmp(tmp);
3642
    dead_tmp(rm);
3643
    dead_tmp(rd);
3644
}
3645

    
3646
static void gen_neon_zip_u8(TCGv t0, TCGv t1)
3647
{
3648
    TCGv rd, rm, tmp;
3649

    
3650
    rd = new_tmp();
3651
    rm = new_tmp();
3652
    tmp = new_tmp();
3653

    
3654
    tcg_gen_andi_i32(rd, t0, 0xff);
3655
    tcg_gen_shli_i32(tmp, t1, 8);
3656
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3657
    tcg_gen_or_i32(rd, rd, tmp);
3658
    tcg_gen_shli_i32(tmp, t0, 16);
3659
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3660
    tcg_gen_or_i32(rd, rd, tmp);
3661
    tcg_gen_shli_i32(tmp, t1, 24);
3662
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3663
    tcg_gen_or_i32(rd, rd, tmp);
3664

    
3665
    tcg_gen_andi_i32(rm, t1, 0xff000000);
3666
    tcg_gen_shri_i32(tmp, t0, 8);
3667
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3668
    tcg_gen_or_i32(rm, rm, tmp);
3669
    tcg_gen_shri_i32(tmp, t1, 8);
3670
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3671
    tcg_gen_or_i32(rm, rm, tmp);
3672
    tcg_gen_shri_i32(tmp, t0, 16);
3673
    tcg_gen_andi_i32(tmp, tmp, 0xff);
3674
    tcg_gen_or_i32(t1, rm, tmp);
3675
    tcg_gen_mov_i32(t0, rd);
3676

    
3677
    dead_tmp(tmp);
3678
    dead_tmp(rm);
3679
    dead_tmp(rd);
3680
}
3681

    
3682
static void gen_neon_zip_u16(TCGv t0, TCGv t1)
3683
{
3684
    TCGv tmp, tmp2;
3685

    
3686
    tmp = new_tmp();
3687
    tmp2 = new_tmp();
3688

    
3689
    tcg_gen_andi_i32(tmp, t0, 0xffff);
3690
    tcg_gen_shli_i32(tmp2, t1, 16);
3691
    tcg_gen_or_i32(tmp, tmp, tmp2);
3692
    tcg_gen_andi_i32(t1, t1, 0xffff0000);
3693
    tcg_gen_shri_i32(tmp2, t0, 16);
3694
    tcg_gen_or_i32(t1, t1, tmp2);
3695
    tcg_gen_mov_i32(t0, tmp);
3696

    
3697
    dead_tmp(tmp2);
3698
    dead_tmp(tmp);
3699
}
3700

    
3701
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3702
{
3703
    int n;
3704
    TCGv t0, t1;
3705

    
3706
    for (n = 0; n < q + 1; n += 2) {
3707
        t0 = neon_load_reg(reg, n);
3708
        t1 = neon_load_reg(reg, n + 1);
3709
        switch (size) {
3710
        case 0: gen_neon_unzip_u8(t0, t1); break;
3711
        case 1: gen_neon_zip_u16(t0, t1); break; /* zip and unzip are the same.  */
3712
        case 2: /* no-op */; break;
3713
        default: abort();
3714
        }
3715
        neon_store_scratch(tmp + n, t0);
3716
        neon_store_scratch(tmp + n + 1, t1);
3717
    }
3718
}
3719

    
3720
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3721
{
3722
    TCGv rd, tmp;
3723

    
3724
    rd = new_tmp();
3725
    tmp = new_tmp();
3726

    
3727
    tcg_gen_shli_i32(rd, t0, 8);
3728
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3729
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3730
    tcg_gen_or_i32(rd, rd, tmp);
3731

    
3732
    tcg_gen_shri_i32(t1, t1, 8);
3733
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3734
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3735
    tcg_gen_or_i32(t1, t1, tmp);
3736
    tcg_gen_mov_i32(t0, rd);
3737

    
3738
    dead_tmp(tmp);
3739
    dead_tmp(rd);
3740
}
3741

    
3742
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3743
{
3744
    TCGv rd, tmp;
3745

    
3746
    rd = new_tmp();
3747
    tmp = new_tmp();
3748

    
3749
    tcg_gen_shli_i32(rd, t0, 16);
3750
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3751
    tcg_gen_or_i32(rd, rd, tmp);
3752
    tcg_gen_shri_i32(t1, t1, 16);
3753
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3754
    tcg_gen_or_i32(t1, t1, tmp);
3755
    tcg_gen_mov_i32(t0, rd);
3756

    
3757
    dead_tmp(tmp);
3758
    dead_tmp(rd);
3759
}
3760

    
3761

    
3762
static struct {
3763
    int nregs;
3764
    int interleave;
3765
    int spacing;
3766
} neon_ls_element_type[11] = {
3767
    {4, 4, 1},
3768
    {4, 4, 2},
3769
    {4, 1, 1},
3770
    {4, 2, 1},
3771
    {3, 3, 1},
3772
    {3, 3, 2},
3773
    {3, 1, 1},
3774
    {1, 1, 1},
3775
    {2, 2, 1},
3776
    {2, 2, 2},
3777
    {2, 1, 1}
3778
};
3779

    
3780
/* Translate a NEON load/store element instruction.  Return nonzero if the
3781
   instruction is invalid.  */
3782
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3783
{
3784
    int rd, rn, rm;
3785
    int op;
3786
    int nregs;
3787
    int interleave;
3788
    int spacing;
3789
    int stride;
3790
    int size;
3791
    int reg;
3792
    int pass;
3793
    int load;
3794
    int shift;
3795
    int n;
3796
    TCGv addr;
3797
    TCGv tmp;
3798
    TCGv tmp2;
3799
    TCGv_i64 tmp64;
3800

    
3801
    if (!vfp_enabled(env))
3802
      return 1;
3803
    VFP_DREG_D(rd, insn);
3804
    rn = (insn >> 16) & 0xf;
3805
    rm = insn & 0xf;
3806
    load = (insn & (1 << 21)) != 0;
3807
    addr = new_tmp();
3808
    if ((insn & (1 << 23)) == 0) {
3809
        /* Load store all elements.  */
3810
        op = (insn >> 8) & 0xf;
3811
        size = (insn >> 6) & 3;
3812
        if (op > 10)
3813
            return 1;
3814
        nregs = neon_ls_element_type[op].nregs;
3815
        interleave = neon_ls_element_type[op].interleave;
3816
        spacing = neon_ls_element_type[op].spacing;
3817
        if (size == 3 && (interleave | spacing) != 1)
3818
            return 1;
3819
        load_reg_var(s, addr, rn);
3820
        stride = (1 << size) * interleave;
3821
        for (reg = 0; reg < nregs; reg++) {
3822
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3823
                load_reg_var(s, addr, rn);
3824
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3825
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3826
                load_reg_var(s, addr, rn);
3827
                tcg_gen_addi_i32(addr, addr, 1 << size);
3828
            }
3829
            if (size == 3) {
3830
                if (load) {
3831
                    tmp64 = gen_ld64(addr, IS_USER(s));
3832
                    neon_store_reg64(tmp64, rd);
3833
                    tcg_temp_free_i64(tmp64);
3834
                } else {
3835
                    tmp64 = tcg_temp_new_i64();
3836
                    neon_load_reg64(tmp64, rd);
3837
                    gen_st64(tmp64, addr, IS_USER(s));
3838
                }
3839
                tcg_gen_addi_i32(addr, addr, stride);
3840
            } else {
3841
                for (pass = 0; pass < 2; pass++) {
3842
                    if (size == 2) {
3843
                        if (load) {
3844
                            tmp = gen_ld32(addr, IS_USER(s));
3845
                            neon_store_reg(rd, pass, tmp);
3846
                        } else {
3847
                            tmp = neon_load_reg(rd, pass);
3848
                            gen_st32(tmp, addr, IS_USER(s));
3849
                        }
3850
                        tcg_gen_addi_i32(addr, addr, stride);
3851
                    } else if (size == 1) {
3852
                        if (load) {
3853
                            tmp = gen_ld16u(addr, IS_USER(s));
3854
                            tcg_gen_addi_i32(addr, addr, stride);
3855
                            tmp2 = gen_ld16u(addr, IS_USER(s));
3856
                            tcg_gen_addi_i32(addr, addr, stride);
3857
                            tcg_gen_shli_i32(tmp2, tmp2, 16);
3858
                            tcg_gen_or_i32(tmp, tmp, tmp2);
3859
                            dead_tmp(tmp2);
3860
                            neon_store_reg(rd, pass, tmp);
3861
                        } else {
3862
                            tmp = neon_load_reg(rd, pass);
3863
                            tmp2 = new_tmp();
3864
                            tcg_gen_shri_i32(tmp2, tmp, 16);
3865
                            gen_st16(tmp, addr, IS_USER(s));
3866
                            tcg_gen_addi_i32(addr, addr, stride);
3867
                            gen_st16(tmp2, addr, IS_USER(s));
3868
                            tcg_gen_addi_i32(addr, addr, stride);
3869
                        }
3870
                    } else /* size == 0 */ {
3871
                        if (load) {
3872
                            TCGV_UNUSED(tmp2);
3873
                            for (n = 0; n < 4; n++) {
3874
                                tmp = gen_ld8u(addr, IS_USER(s));
3875
                                tcg_gen_addi_i32(addr, addr, stride);
3876
                                if (n == 0) {
3877
                                    tmp2 = tmp;
3878
                                } else {
3879
                                    tcg_gen_shli_i32(tmp, tmp, n * 8);
3880
                                    tcg_gen_or_i32(tmp2, tmp2, tmp);
3881
                                    dead_tmp(tmp);
3882
                                }
3883
                            }
3884
                            neon_store_reg(rd, pass, tmp2);
3885
                        } else {
3886
                            tmp2 = neon_load_reg(rd, pass);
3887
                            for (n = 0; n < 4; n++) {
3888
                                tmp = new_tmp();
3889
                                if (n == 0) {
3890
                                    tcg_gen_mov_i32(tmp, tmp2);
3891
                                } else {
3892
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
3893
                                }
3894
                                gen_st8(tmp, addr, IS_USER(s));
3895
                                tcg_gen_addi_i32(addr, addr, stride);
3896
                            }
3897
                            dead_tmp(tmp2);
3898
                        }
3899
                    }
3900
                }
3901
            }
3902
            rd += spacing;
3903
        }
3904
        stride = nregs * 8;
3905
    } else {
3906
        size = (insn >> 10) & 3;
3907
        if (size == 3) {
3908
            /* Load single element to all lanes.  */
3909
            if (!load)
3910
                return 1;
3911
            size = (insn >> 6) & 3;
3912
            nregs = ((insn >> 8) & 3) + 1;
3913
            stride = (insn & (1 << 5)) ? 2 : 1;
3914
            load_reg_var(s, addr, rn);
3915
            for (reg = 0; reg < nregs; reg++) {
3916
                switch (size) {
3917
                case 0:
3918
                    tmp = gen_ld8u(addr, IS_USER(s));
3919
                    gen_neon_dup_u8(tmp, 0);
3920
                    break;
3921
                case 1:
3922
                    tmp = gen_ld16u(addr, IS_USER(s));
3923
                    gen_neon_dup_low16(tmp);
3924
                    break;
3925
                case 2:
3926
                    tmp = gen_ld32(addr, IS_USER(s));
3927
                    break;
3928
                case 3:
3929
                    return 1;
3930
                default: /* Avoid compiler warnings.  */
3931
                    abort();
3932
                }
3933
                tcg_gen_addi_i32(addr, addr, 1 << size);
3934
                tmp2 = new_tmp();
3935
                tcg_gen_mov_i32(tmp2, tmp);
3936
                neon_store_reg(rd, 0, tmp2);
3937
                neon_store_reg(rd, 1, tmp);
3938
                rd += stride;
3939
            }
3940
            stride = (1 << size) * nregs;
3941
        } else {
3942
            /* Single element.  */
3943
            pass = (insn >> 7) & 1;
3944
            switch (size) {
3945
            case 0:
3946
                shift = ((insn >> 5) & 3) * 8;
3947
                stride = 1;
3948
                break;
3949
            case 1:
3950
                shift = ((insn >> 6) & 1) * 16;
3951
                stride = (insn & (1 << 5)) ? 2 : 1;
3952
                break;
3953
            case 2:
3954
                shift = 0;
3955
                stride = (insn & (1 << 6)) ? 2 : 1;
3956
                break;
3957
            default:
3958
                abort();
3959
            }
3960
            nregs = ((insn >> 8) & 3) + 1;
3961
            load_reg_var(s, addr, rn);
3962
            for (reg = 0; reg < nregs; reg++) {
3963
                if (load) {
3964
                    switch (size) {
3965
                    case 0:
3966
                        tmp = gen_ld8u(addr, IS_USER(s));
3967
                        break;
3968
                    case 1:
3969
                        tmp = gen_ld16u(addr, IS_USER(s));
3970
                        break;
3971
                    case 2:
3972
                        tmp = gen_ld32(addr, IS_USER(s));
3973
                        break;
3974
                    default: /* Avoid compiler warnings.  */
3975
                        abort();
3976
                    }
3977
                    if (size != 2) {
3978
                        tmp2 = neon_load_reg(rd, pass);
3979
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3980
                        dead_tmp(tmp2);
3981
                    }
3982
                    neon_store_reg(rd, pass, tmp);
3983
                } else { /* Store */
3984
                    tmp = neon_load_reg(rd, pass);
3985
                    if (shift)
3986
                        tcg_gen_shri_i32(tmp, tmp, shift);
3987
                    switch (size) {
3988
                    case 0:
3989
                        gen_st8(tmp, addr, IS_USER(s));
3990
                        break;
3991
                    case 1:
3992
                        gen_st16(tmp, addr, IS_USER(s));
3993
                        break;
3994
                    case 2:
3995
                        gen_st32(tmp, addr, IS_USER(s));
3996
                        break;
3997
                    }
3998
                }
3999
                rd += stride;
4000
                tcg_gen_addi_i32(addr, addr, 1 << size);
4001
            }
4002
            stride = nregs * (1 << size);
4003
        }
4004
    }
4005
    dead_tmp(addr);
4006
    if (rm != 15) {
4007
        TCGv base;
4008

    
4009
        base = load_reg(s, rn);
4010
        if (rm == 13) {
4011
            tcg_gen_addi_i32(base, base, stride);
4012
        } else {
4013
            TCGv index;
4014
            index = load_reg(s, rm);
4015
            tcg_gen_add_i32(base, base, index);
4016
            dead_tmp(index);
4017
        }
4018
        store_reg(s, rn, base);
4019
    }
4020
    return 0;
4021
}
4022

    
4023
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4024
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4025
{
4026
    tcg_gen_and_i32(t, t, c);
4027
    tcg_gen_andc_i32(f, f, c);
4028
    tcg_gen_or_i32(dest, t, f);
4029
}
4030

    
4031
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4032
{
4033
    switch (size) {
4034
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4035
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4036
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4037
    default: abort();
4038
    }
4039
}
4040

    
4041
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4042
{
4043
    switch (size) {
4044
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4045
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4046
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4047
    default: abort();
4048
    }
4049
}
4050

    
4051
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4052
{
4053
    switch (size) {
4054
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4055
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4056
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4057
    default: abort();
4058
    }
4059
}
4060

    
4061
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4062
                                         int q, int u)
4063
{
4064
    if (q) {
4065
        if (u) {
4066
            switch (size) {
4067
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4068
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4069
            default: abort();
4070
            }
4071
        } else {
4072
            switch (size) {
4073
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4074
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4075
            default: abort();
4076
            }
4077
        }
4078
    } else {
4079
        if (u) {
4080
            switch (size) {
4081
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4082
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4083
            default: abort();
4084
            }
4085
        } else {
4086
            switch (size) {
4087
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4088
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4089
            default: abort();
4090
            }
4091
        }
4092
    }
4093
}
4094

    
4095
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4096
{
4097
    if (u) {
4098
        switch (size) {
4099
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4100
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4101
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4102
        default: abort();
4103
        }
4104
    } else {
4105
        switch (size) {
4106
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4107
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4108
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4109
        default: abort();
4110
        }
4111
    }
4112
    dead_tmp(src);
4113
}
4114

    
4115
static inline void gen_neon_addl(int size)
4116
{
4117
    switch (size) {
4118
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4119
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4120
    case 2: tcg_gen_add_i64(CPU_V001); break;
4121
    default: abort();
4122
    }
4123
}
4124

    
4125
static inline void gen_neon_subl(int size)
4126
{
4127
    switch (size) {
4128
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4129
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4130
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4131
    default: abort();
4132
    }
4133
}
4134

    
4135
static inline void gen_neon_negl(TCGv_i64 var, int size)
4136
{
4137
    switch (size) {
4138
    case 0: gen_helper_neon_negl_u16(var, var); break;
4139
    case 1: gen_helper_neon_negl_u32(var, var); break;
4140
    case 2: gen_helper_neon_negl_u64(var, var); break;
4141
    default: abort();
4142
    }
4143
}
4144

    
4145
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4146
{
4147
    switch (size) {
4148
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4149
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4150
    default: abort();
4151
    }
4152
}
4153

    
4154
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4155
{
4156
    TCGv_i64 tmp;
4157

    
4158
    switch ((size << 1) | u) {
4159
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4160
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4161
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4162
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4163
    case 4:
4164
        tmp = gen_muls_i64_i32(a, b);
4165
        tcg_gen_mov_i64(dest, tmp);
4166
        break;
4167
    case 5:
4168
        tmp = gen_mulu_i64_i32(a, b);
4169
        tcg_gen_mov_i64(dest, tmp);
4170
        break;
4171
    default: abort();
4172
    }
4173
}
4174

    
4175
/* Translate a NEON data processing instruction.  Return nonzero if the
4176
   instruction is invalid.
4177
   We process data in a mixture of 32-bit and 64-bit chunks.
4178
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4179

    
4180
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4181
{
4182
    int op;
4183
    int q;
4184
    int rd, rn, rm;
4185
    int size;
4186
    int shift;
4187
    int pass;
4188
    int count;
4189
    int pairwise;
4190
    int u;
4191
    int n;
4192
    uint32_t imm, mask;
4193
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4194
    TCGv_i64 tmp64;
4195

    
4196
    if (!vfp_enabled(env))
4197
      return 1;
4198
    q = (insn & (1 << 6)) != 0;
4199
    u = (insn >> 24) & 1;
4200
    VFP_DREG_D(rd, insn);
4201
    VFP_DREG_N(rn, insn);
4202
    VFP_DREG_M(rm, insn);
4203
    size = (insn >> 20) & 3;
4204
    if ((insn & (1 << 23)) == 0) {
4205
        /* Three register same length.  */
4206
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4207
        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4208
                          || op == 10 || op  == 11 || op == 16)) {
4209
            /* 64-bit element instructions.  */
4210
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4211
                neon_load_reg64(cpu_V0, rn + pass);
4212
                neon_load_reg64(cpu_V1, rm + pass);
4213
                switch (op) {
4214
                case 1: /* VQADD */
4215
                    if (u) {
4216
                        gen_helper_neon_add_saturate_u64(CPU_V001);
4217
                    } else {
4218
                        gen_helper_neon_add_saturate_s64(CPU_V001);
4219
                    }
4220
                    break;
4221
                case 5: /* VQSUB */
4222
                    if (u) {
4223
                        gen_helper_neon_sub_saturate_u64(CPU_V001);
4224
                    } else {
4225
                        gen_helper_neon_sub_saturate_s64(CPU_V001);
4226
                    }
4227
                    break;
4228
                case 8: /* VSHL */
4229
                    if (u) {
4230
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4231
                    } else {
4232
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4233
                    }
4234
                    break;
4235
                case 9: /* VQSHL */
4236
                    if (u) {
4237
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4238
                                                 cpu_V0, cpu_V0);
4239
                    } else {
4240
                        gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4241
                                                 cpu_V1, cpu_V0);
4242
                    }
4243
                    break;
4244
                case 10: /* VRSHL */
4245
                    if (u) {
4246
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4247
                    } else {
4248
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4249
                    }
4250
                    break;
4251
                case 11: /* VQRSHL */
4252
                    if (u) {
4253
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4254
                                                  cpu_V1, cpu_V0);
4255
                    } else {
4256
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4257
                                                  cpu_V1, cpu_V0);
4258
                    }
4259
                    break;
4260
                case 16:
4261
                    if (u) {
4262
                        tcg_gen_sub_i64(CPU_V001);
4263
                    } else {
4264
                        tcg_gen_add_i64(CPU_V001);
4265
                    }
4266
                    break;
4267
                default:
4268
                    abort();
4269
                }
4270
                neon_store_reg64(cpu_V0, rd + pass);
4271
            }
4272
            return 0;
4273
        }
4274
        switch (op) {
4275
        case 8: /* VSHL */
4276
        case 9: /* VQSHL */
4277
        case 10: /* VRSHL */
4278
        case 11: /* VQRSHL */
4279
            {
4280
                int rtmp;
4281
                /* Shift instruction operands are reversed.  */
4282
                rtmp = rn;
4283
                rn = rm;
4284
                rm = rtmp;
4285
                pairwise = 0;
4286
            }
4287
            break;
4288
        case 20: /* VPMAX */
4289
        case 21: /* VPMIN */
4290
        case 23: /* VPADD */
4291
            pairwise = 1;
4292
            break;
4293
        case 26: /* VPADD (float) */
4294
            pairwise = (u && size < 2);
4295
            break;
4296
        case 30: /* VPMIN/VPMAX (float) */
4297
            pairwise = u;
4298
            break;
4299
        default:
4300
            pairwise = 0;
4301
            break;
4302
        }
4303

    
4304
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4305

    
4306
        if (pairwise) {
4307
            /* Pairwise.  */
4308
            if (q)
4309
                n = (pass & 1) * 2;
4310
            else
4311
                n = 0;
4312
            if (pass < q + 1) {
4313
                tmp = neon_load_reg(rn, n);
4314
                tmp2 = neon_load_reg(rn, n + 1);
4315
            } else {
4316
                tmp = neon_load_reg(rm, n);
4317
                tmp2 = neon_load_reg(rm, n + 1);
4318
            }
4319
        } else {
4320
            /* Elementwise.  */
4321
            tmp = neon_load_reg(rn, pass);
4322
            tmp2 = neon_load_reg(rm, pass);
4323
        }
4324
        switch (op) {
4325
        case 0: /* VHADD */
4326
            GEN_NEON_INTEGER_OP(hadd);
4327
            break;
4328
        case 1: /* VQADD */
4329
            GEN_NEON_INTEGER_OP_ENV(qadd);
4330
            break;
4331
        case 2: /* VRHADD */
4332
            GEN_NEON_INTEGER_OP(rhadd);
4333
            break;
4334
        case 3: /* Logic ops.  */
4335
            switch ((u << 2) | size) {
4336
            case 0: /* VAND */
4337
                tcg_gen_and_i32(tmp, tmp, tmp2);
4338
                break;
4339
            case 1: /* BIC */
4340
                tcg_gen_andc_i32(tmp, tmp, tmp2);
4341
                break;
4342
            case 2: /* VORR */
4343
                tcg_gen_or_i32(tmp, tmp, tmp2);
4344
                break;
4345
            case 3: /* VORN */
4346
                tcg_gen_orc_i32(tmp, tmp, tmp2);
4347
                break;
4348
            case 4: /* VEOR */
4349
                tcg_gen_xor_i32(tmp, tmp, tmp2);
4350
                break;
4351
            case 5: /* VBSL */
4352
                tmp3 = neon_load_reg(rd, pass);
4353
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4354
                dead_tmp(tmp3);
4355
                break;
4356
            case 6: /* VBIT */
4357
                tmp3 = neon_load_reg(rd, pass);
4358
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4359
                dead_tmp(tmp3);
4360
                break;
4361
            case 7: /* VBIF */
4362
                tmp3 = neon_load_reg(rd, pass);
4363
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4364
                dead_tmp(tmp3);
4365
                break;
4366
            }
4367
            break;
4368
        case 4: /* VHSUB */
4369
            GEN_NEON_INTEGER_OP(hsub);
4370
            break;
4371
        case 5: /* VQSUB */
4372
            GEN_NEON_INTEGER_OP_ENV(qsub);
4373
            break;
4374
        case 6: /* VCGT */
4375
            GEN_NEON_INTEGER_OP(cgt);
4376
            break;
4377
        case 7: /* VCGE */
4378
            GEN_NEON_INTEGER_OP(cge);
4379
            break;
4380
        case 8: /* VSHL */
4381
            GEN_NEON_INTEGER_OP(shl);
4382
            break;
4383
        case 9: /* VQSHL */
4384
            GEN_NEON_INTEGER_OP_ENV(qshl);
4385
            break;
4386
        case 10: /* VRSHL */
4387
            GEN_NEON_INTEGER_OP(rshl);
4388
            break;
4389
        case 11: /* VQRSHL */
4390
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4391
            break;
4392
        case 12: /* VMAX */
4393
            GEN_NEON_INTEGER_OP(max);
4394
            break;
4395
        case 13: /* VMIN */
4396
            GEN_NEON_INTEGER_OP(min);
4397
            break;
4398
        case 14: /* VABD */
4399
            GEN_NEON_INTEGER_OP(abd);
4400
            break;
4401
        case 15: /* VABA */
4402
            GEN_NEON_INTEGER_OP(abd);
4403
            dead_tmp(tmp2);
4404
            tmp2 = neon_load_reg(rd, pass);
4405
            gen_neon_add(size, tmp, tmp2);
4406
            break;
4407
        case 16:
4408
            if (!u) { /* VADD */
4409
                if (gen_neon_add(size, tmp, tmp2))
4410
                    return 1;
4411
            } else { /* VSUB */
4412
                switch (size) {
4413
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4414
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4415
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4416
                default: return 1;
4417
                }
4418
            }
4419
            break;
4420
        case 17:
4421
            if (!u) { /* VTST */
4422
                switch (size) {
4423
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4424
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4425
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4426
                default: return 1;
4427
                }
4428
            } else { /* VCEQ */
4429
                switch (size) {
4430
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4431
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4432
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4433
                default: return 1;
4434
                }
4435
            }
4436
            break;
4437
        case 18: /* Multiply.  */
4438
            switch (size) {
4439
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4440
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4441
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4442
            default: return 1;
4443
            }
4444
            dead_tmp(tmp2);
4445
            tmp2 = neon_load_reg(rd, pass);
4446
            if (u) { /* VMLS */
4447
                gen_neon_rsb(size, tmp, tmp2);
4448
            } else { /* VMLA */
4449
                gen_neon_add(size, tmp, tmp2);
4450
            }
4451
            break;
4452
        case 19: /* VMUL */
4453
            if (u) { /* polynomial */
4454
                gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4455
            } else { /* Integer */
4456
                switch (size) {
4457
                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4458
                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4459
                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4460
                default: return 1;
4461
                }
4462
            }
4463
            break;
4464
        case 20: /* VPMAX */
4465
            GEN_NEON_INTEGER_OP(pmax);
4466
            break;
4467
        case 21: /* VPMIN */
4468
            GEN_NEON_INTEGER_OP(pmin);
4469
            break;
4470
        case 22: /* Hultiply high.  */
4471
            if (!u) { /* VQDMULH */
4472
                switch (size) {
4473
                case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4474
                case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4475
                default: return 1;
4476
                }
4477
            } else { /* VQRDHMUL */
4478
                switch (size) {
4479
                case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4480
                case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4481
                default: return 1;
4482
                }
4483
            }
4484
            break;
4485
        case 23: /* VPADD */
4486
            if (u)
4487
                return 1;
4488
            switch (size) {
4489
            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4490
            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4491
            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4492
            default: return 1;
4493
            }
4494
            break;
4495
        case 26: /* Floating point arithnetic.  */
4496
            switch ((u << 2) | size) {
4497
            case 0: /* VADD */
4498
                gen_helper_neon_add_f32(tmp, tmp, tmp2);
4499
                break;
4500
            case 2: /* VSUB */
4501
                gen_helper_neon_sub_f32(tmp, tmp, tmp2);
4502
                break;
4503
            case 4: /* VPADD */
4504
                gen_helper_neon_add_f32(tmp, tmp, tmp2);
4505
                break;
4506
            case 6: /* VABD */
4507
                gen_helper_neon_abd_f32(tmp, tmp, tmp2);
4508
                break;
4509
            default:
4510
                return 1;
4511
            }
4512
            break;
4513
        case 27: /* Float multiply.  */
4514
            gen_helper_neon_mul_f32(tmp, tmp, tmp2);
4515
            if (!u) {
4516
                dead_tmp(tmp2);
4517
                tmp2 = neon_load_reg(rd, pass);
4518
                if (size == 0) {
4519
                    gen_helper_neon_add_f32(tmp, tmp, tmp2);
4520
                } else {
4521
                    gen_helper_neon_sub_f32(tmp, tmp2, tmp);
4522
                }
4523
            }
4524
            break;
4525
        case 28: /* Float compare.  */
4526
            if (!u) {
4527
                gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
4528
            } else {
4529
                if (size == 0)
4530
                    gen_helper_neon_cge_f32(tmp, tmp, tmp2);
4531
                else
4532
                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
4533
            }
4534
            break;
4535
        case 29: /* Float compare absolute.  */
4536
            if (!u)
4537
                return 1;
4538
            if (size == 0)
4539
                gen_helper_neon_acge_f32(tmp, tmp, tmp2);
4540
            else
4541
                gen_helper_neon_acgt_f32(tmp, tmp, tmp2);
4542
            break;
4543
        case 30: /* Float min/max.  */
4544
            if (size == 0)
4545
                gen_helper_neon_max_f32(tmp, tmp, tmp2);
4546
            else
4547
                gen_helper_neon_min_f32(tmp, tmp, tmp2);
4548
            break;
4549
        case 31:
4550
            if (size == 0)
4551
                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4552
            else
4553
                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4554
            break;
4555
        default:
4556
            abort();
4557
        }
4558
        dead_tmp(tmp2);
4559

    
4560
        /* Save the result.  For elementwise operations we can put it
4561
           straight into the destination register.  For pairwise operations
4562
           we have to be careful to avoid clobbering the source operands.  */
4563
        if (pairwise && rd == rm) {
4564
            neon_store_scratch(pass, tmp);
4565
        } else {
4566
            neon_store_reg(rd, pass, tmp);
4567
        }
4568

    
4569
        } /* for pass */
4570
        if (pairwise && rd == rm) {
4571
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4572
                tmp = neon_load_scratch(pass);
4573
                neon_store_reg(rd, pass, tmp);
4574
            }
4575
        }
4576
        /* End of 3 register same size operations.  */
4577
    } else if (insn & (1 << 4)) {
4578
        if ((insn & 0x00380080) != 0) {
4579
            /* Two registers and shift.  */
4580
            op = (insn >> 8) & 0xf;
4581
            if (insn & (1 << 7)) {
4582
                /* 64-bit shift.   */
4583
                size = 3;
4584
            } else {
4585
                size = 2;
4586
                while ((insn & (1 << (size + 19))) == 0)
4587
                    size--;
4588
            }
4589
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4590
            /* To avoid excessive dumplication of ops we implement shift
4591
               by immediate using the variable shift operations.  */
4592
            if (op < 8) {
4593
                /* Shift by immediate:
4594
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4595
                /* Right shifts are encoded as N - shift, where N is the
4596
                   element size in bits.  */
4597
                if (op <= 4)
4598
                    shift = shift - (1 << (size + 3));
4599
                if (size == 3) {
4600
                    count = q + 1;
4601
                } else {
4602
                    count = q ? 4: 2;
4603
                }
4604
                switch (size) {
4605
                case 0:
4606
                    imm = (uint8_t) shift;
4607
                    imm |= imm << 8;
4608
                    imm |= imm << 16;
4609
                    break;
4610
                case 1:
4611
                    imm = (uint16_t) shift;
4612
                    imm |= imm << 16;
4613
                    break;
4614
                case 2:
4615
                case 3:
4616
                    imm = shift;
4617
                    break;
4618
                default:
4619
                    abort();
4620
                }
4621

    
4622
                for (pass = 0; pass < count; pass++) {
4623
                    if (size == 3) {
4624
                        neon_load_reg64(cpu_V0, rm + pass);
4625
                        tcg_gen_movi_i64(cpu_V1, imm);
4626
                        switch (op) {
4627
                        case 0:  /* VSHR */
4628
                        case 1:  /* VSRA */
4629
                            if (u)
4630
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4631
                            else
4632
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4633
                            break;
4634
                        case 2: /* VRSHR */
4635
                        case 3: /* VRSRA */
4636
                            if (u)
4637
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4638
                            else
4639
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4640
                            break;
4641
                        case 4: /* VSRI */
4642
                            if (!u)
4643
                                return 1;
4644
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4645
                            break;
4646
                        case 5: /* VSHL, VSLI */
4647
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4648
                            break;
4649
                        case 6: /* VQSHL */
4650
                            if (u)
4651
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4652
                            else
4653
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4654
                            break;
4655
                        case 7: /* VQSHLU */
4656
                            gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4657
                            break;
4658
                        }
4659
                        if (op == 1 || op == 3) {
4660
                            /* Accumulate.  */
4661
                            neon_load_reg64(cpu_V0, rd + pass);
4662
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4663
                        } else if (op == 4 || (op == 5 && u)) {
4664
                            /* Insert */
4665
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4666
                        }
4667
                        neon_store_reg64(cpu_V0, rd + pass);
4668
                    } else { /* size < 3 */
4669
                        /* Operands in T0 and T1.  */
4670
                        tmp = neon_load_reg(rm, pass);
4671
                        tmp2 = new_tmp();
4672
                        tcg_gen_movi_i32(tmp2, imm);
4673
                        switch (op) {
4674
                        case 0:  /* VSHR */
4675
                        case 1:  /* VSRA */
4676
                            GEN_NEON_INTEGER_OP(shl);
4677
                            break;
4678
                        case 2: /* VRSHR */
4679
                        case 3: /* VRSRA */
4680
                            GEN_NEON_INTEGER_OP(rshl);
4681
                            break;
4682
                        case 4: /* VSRI */
4683
                            if (!u)
4684
                                return 1;
4685
                            GEN_NEON_INTEGER_OP(shl);
4686
                            break;
4687
                        case 5: /* VSHL, VSLI */
4688
                            switch (size) {
4689
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4690
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4691
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4692
                            default: return 1;
4693
                            }
4694
                            break;
4695
                        case 6: /* VQSHL */
4696
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4697
                            break;
4698
                        case 7: /* VQSHLU */
4699
                            switch (size) {
4700
                            case 0: gen_helper_neon_qshl_u8(tmp, cpu_env, tmp, tmp2); break;
4701
                            case 1: gen_helper_neon_qshl_u16(tmp, cpu_env, tmp, tmp2); break;
4702
                            case 2: gen_helper_neon_qshl_u32(tmp, cpu_env, tmp, tmp2); break;
4703
                            default: return 1;
4704
                            }
4705
                            break;
4706
                        }
4707
                        dead_tmp(tmp2);
4708

    
4709
                        if (op == 1 || op == 3) {
4710
                            /* Accumulate.  */
4711
                            tmp2 = neon_load_reg(rd, pass);
4712
                            gen_neon_add(size, tmp2, tmp);
4713
                            dead_tmp(tmp2);
4714
                        } else if (op == 4 || (op == 5 && u)) {
4715
                            /* Insert */
4716
                            switch (size) {
4717
                            case 0:
4718
                                if (op == 4)
4719
                                    mask = 0xff >> -shift;
4720
                                else
4721
                                    mask = (uint8_t)(0xff << shift);
4722
                                mask |= mask << 8;
4723
                                mask |= mask << 16;
4724
                                break;
4725
                            case 1:
4726
                                if (op == 4)
4727
                                    mask = 0xffff >> -shift;
4728
                                else
4729
                                    mask = (uint16_t)(0xffff << shift);
4730
                                mask |= mask << 16;
4731
                                break;
4732
                            case 2:
4733
                                if (shift < -31 || shift > 31) {
4734
                                    mask = 0;
4735
                                } else {
4736
                                    if (op == 4)
4737
                                        mask = 0xffffffffu >> -shift;
4738
                                    else
4739
                                        mask = 0xffffffffu << shift;
4740
                                }
4741
                                break;
4742
                            default:
4743
                                abort();
4744
                            }
4745
                            tmp2 = neon_load_reg(rd, pass);
4746
                            tcg_gen_andi_i32(tmp, tmp, mask);
4747
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
4748
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4749
                            dead_tmp(tmp2);
4750
                        }
4751
                        neon_store_reg(rd, pass, tmp);
4752
                    }
4753
                } /* for pass */
4754
            } else if (op < 10) {
4755
                /* Shift by immediate and narrow:
4756
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4757
                shift = shift - (1 << (size + 3));
4758
                size++;
4759
                switch (size) {
4760
                case 1:
4761
                    imm = (uint16_t)shift;
4762
                    imm |= imm << 16;
4763
                    tmp2 = tcg_const_i32(imm);
4764
                    TCGV_UNUSED_I64(tmp64);
4765
                    break;
4766
                case 2:
4767
                    imm = (uint32_t)shift;
4768
                    tmp2 = tcg_const_i32(imm);
4769
                    TCGV_UNUSED_I64(tmp64);
4770
                    break;
4771
                case 3:
4772
                    tmp64 = tcg_const_i64(shift);
4773
                    TCGV_UNUSED(tmp2);
4774
                    break;
4775
                default:
4776
                    abort();
4777
                }
4778

    
4779
                for (pass = 0; pass < 2; pass++) {
4780
                    if (size == 3) {
4781
                        neon_load_reg64(cpu_V0, rm + pass);
4782
                        if (q) {
4783
                          if (u)
4784
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4785
                          else
4786
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4787
                        } else {
4788
                          if (u)
4789
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4790
                          else
4791
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4792
                        }
4793
                    } else {
4794
                        tmp = neon_load_reg(rm + pass, 0);
4795
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4796
                        tmp3 = neon_load_reg(rm + pass, 1);
4797
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4798
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4799
                        dead_tmp(tmp);
4800
                        dead_tmp(tmp3);
4801
                    }
4802
                    tmp = new_tmp();
4803
                    if (op == 8 && !u) {
4804
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4805
                    } else {
4806
                        if (op == 8)
4807
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4808
                        else
4809
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4810
                    }
4811
                    neon_store_reg(rd, pass, tmp);
4812
                } /* for pass */
4813
                if (size == 3) {
4814
                    tcg_temp_free_i64(tmp64);
4815
                } else {
4816
                    dead_tmp(tmp2);
4817
                }
4818
            } else if (op == 10) {
4819
                /* VSHLL */
4820
                if (q || size == 3)
4821
                    return 1;
4822
                tmp = neon_load_reg(rm, 0);
4823
                tmp2 = neon_load_reg(rm, 1);
4824
                for (pass = 0; pass < 2; pass++) {
4825
                    if (pass == 1)
4826
                        tmp = tmp2;
4827

    
4828
                    gen_neon_widen(cpu_V0, tmp, size, u);
4829

    
4830
                    if (shift != 0) {
4831
                        /* The shift is less than the width of the source
4832
                           type, so we can just shift the whole register.  */
4833
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4834
                        if (size < 2 || !u) {
4835
                            uint64_t imm64;
4836
                            if (size == 0) {
4837
                                imm = (0xffu >> (8 - shift));
4838
                                imm |= imm << 16;
4839
                            } else {
4840
                                imm = 0xffff >> (16 - shift);
4841
                            }
4842
                            imm64 = imm | (((uint64_t)imm) << 32);
4843
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4844
                        }
4845
                    }
4846
                    neon_store_reg64(cpu_V0, rd + pass);
4847
                }
4848
            } else if (op == 15 || op == 16) {
4849
                /* VCVT fixed-point.  */
4850
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4851
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4852
                    if (op & 1) {
4853
                        if (u)
4854
                            gen_vfp_ulto(0, shift);
4855
                        else
4856
                            gen_vfp_slto(0, shift);
4857
                    } else {
4858
                        if (u)
4859
                            gen_vfp_toul(0, shift);
4860
                        else
4861
                            gen_vfp_tosl(0, shift);
4862
                    }
4863
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4864
                }
4865
            } else {
4866
                return 1;
4867
            }
4868
        } else { /* (insn & 0x00380080) == 0 */
4869
            int invert;
4870

    
4871
            op = (insn >> 8) & 0xf;
4872
            /* One register and immediate.  */
4873
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4874
            invert = (insn & (1 << 5)) != 0;
4875
            switch (op) {
4876
            case 0: case 1:
4877
                /* no-op */
4878
                break;
4879
            case 2: case 3:
4880
                imm <<= 8;
4881
                break;
4882
            case 4: case 5:
4883
                imm <<= 16;
4884
                break;
4885
            case 6: case 7:
4886
                imm <<= 24;
4887
                break;
4888
            case 8: case 9:
4889
                imm |= imm << 16;
4890
                break;
4891
            case 10: case 11:
4892
                imm = (imm << 8) | (imm << 24);
4893
                break;
4894
            case 12:
4895
                imm = (imm << 8) | 0xff;
4896
                break;
4897
            case 13:
4898
                imm = (imm << 16) | 0xffff;
4899
                break;
4900
            case 14:
4901
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4902
                if (invert)
4903
                    imm = ~imm;
4904
                break;
4905
            case 15:
4906
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4907
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4908
                break;
4909
            }
4910
            if (invert)
4911
                imm = ~imm;
4912

    
4913
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4914
                if (op & 1 && op < 12) {
4915
                    tmp = neon_load_reg(rd, pass);
4916
                    if (invert) {
4917
                        /* The immediate value has already been inverted, so
4918
                           BIC becomes AND.  */
4919
                        tcg_gen_andi_i32(tmp, tmp, imm);
4920
                    } else {
4921
                        tcg_gen_ori_i32(tmp, tmp, imm);
4922
                    }
4923
                } else {
4924
                    /* VMOV, VMVN.  */
4925
                    tmp = new_tmp();
4926
                    if (op == 14 && invert) {
4927
                        uint32_t val;
4928
                        val = 0;
4929
                        for (n = 0; n < 4; n++) {
4930
                            if (imm & (1 << (n + (pass & 1) * 4)))
4931
                                val |= 0xff << (n * 8);
4932
                        }
4933
                        tcg_gen_movi_i32(tmp, val);
4934
                    } else {
4935
                        tcg_gen_movi_i32(tmp, imm);
4936
                    }
4937
                }
4938
                neon_store_reg(rd, pass, tmp);
4939
            }
4940
        }
4941
    } else { /* (insn & 0x00800010 == 0x00800000) */
4942
        if (size != 3) {
4943
            op = (insn >> 8) & 0xf;
4944
            if ((insn & (1 << 6)) == 0) {
4945
                /* Three registers of different lengths.  */
4946
                int src1_wide;
4947
                int src2_wide;
4948
                int prewiden;
4949
                /* prewiden, src1_wide, src2_wide */
4950
                static const int neon_3reg_wide[16][3] = {
4951
                    {1, 0, 0}, /* VADDL */
4952
                    {1, 1, 0}, /* VADDW */
4953
                    {1, 0, 0}, /* VSUBL */
4954
                    {1, 1, 0}, /* VSUBW */
4955
                    {0, 1, 1}, /* VADDHN */
4956
                    {0, 0, 0}, /* VABAL */
4957
                    {0, 1, 1}, /* VSUBHN */
4958
                    {0, 0, 0}, /* VABDL */
4959
                    {0, 0, 0}, /* VMLAL */
4960
                    {0, 0, 0}, /* VQDMLAL */
4961
                    {0, 0, 0}, /* VMLSL */
4962
                    {0, 0, 0}, /* VQDMLSL */
4963
                    {0, 0, 0}, /* Integer VMULL */
4964
                    {0, 0, 0}, /* VQDMULL */
4965
                    {0, 0, 0}  /* Polynomial VMULL */
4966
                };
4967

    
4968
                prewiden = neon_3reg_wide[op][0];
4969
                src1_wide = neon_3reg_wide[op][1];
4970
                src2_wide = neon_3reg_wide[op][2];
4971

    
4972
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4973
                    return 1;
4974

    
4975
                /* Avoid overlapping operands.  Wide source operands are
4976
                   always aligned so will never overlap with wide
4977
                   destinations in problematic ways.  */
4978
                if (rd == rm && !src2_wide) {
4979
                    tmp = neon_load_reg(rm, 1);
4980
                    neon_store_scratch(2, tmp);
4981
                } else if (rd == rn && !src1_wide) {
4982
                    tmp = neon_load_reg(rn, 1);
4983
                    neon_store_scratch(2, tmp);
4984
                }
4985
                TCGV_UNUSED(tmp3);
4986
                for (pass = 0; pass < 2; pass++) {
4987
                    if (src1_wide) {
4988
                        neon_load_reg64(cpu_V0, rn + pass);
4989
                        TCGV_UNUSED(tmp);
4990
                    } else {
4991
                        if (pass == 1 && rd == rn) {
4992
                            tmp = neon_load_scratch(2);
4993
                        } else {
4994
                            tmp = neon_load_reg(rn, pass);
4995
                        }
4996
                        if (prewiden) {
4997
                            gen_neon_widen(cpu_V0, tmp, size, u);
4998
                        }
4999
                    }
5000
                    if (src2_wide) {
5001
                        neon_load_reg64(cpu_V1, rm + pass);
5002
                        TCGV_UNUSED(tmp2);
5003
                    } else {
5004
                        if (pass == 1 && rd == rm) {
5005
                            tmp2 = neon_load_scratch(2);
5006
                        } else {
5007
                            tmp2 = neon_load_reg(rm, pass);
5008
                        }
5009
                        if (prewiden) {
5010
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5011
                        }
5012
                    }
5013
                    switch (op) {
5014
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5015
                        gen_neon_addl(size);
5016
                        break;
5017
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5018
                        gen_neon_subl(size);
5019
                        break;
5020
                    case 5: case 7: /* VABAL, VABDL */
5021
                        switch ((size << 1) | u) {
5022
                        case 0:
5023
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5024
                            break;
5025
                        case 1:
5026
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5027
                            break;
5028
                        case 2:
5029
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5030
                            break;
5031
                        case 3:
5032
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5033
                            break;
5034
                        case 4:
5035
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5036
                            break;
5037
                        case 5:
5038
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5039
                            break;
5040
                        default: abort();
5041
                        }
5042
                        dead_tmp(tmp2);
5043
                        dead_tmp(tmp);
5044
                        break;
5045
                    case 8: case 9: case 10: case 11: case 12: case 13:
5046
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5047
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5048
                        dead_tmp(tmp2);
5049
                        dead_tmp(tmp);
5050
                        break;
5051
                    case 14: /* Polynomial VMULL */
5052
                        cpu_abort(env, "Polynomial VMULL not implemented");
5053

    
5054
                    default: /* 15 is RESERVED.  */
5055
                        return 1;
5056
                    }
5057
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
5058
                        /* Accumulate.  */
5059
                        if (op == 10 || op == 11) {
5060
                            gen_neon_negl(cpu_V0, size);
5061
                        }
5062

    
5063
                        if (op != 13) {
5064
                            neon_load_reg64(cpu_V1, rd + pass);
5065
                        }
5066

    
5067
                        switch (op) {
5068
                        case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
5069
                            gen_neon_addl(size);
5070
                            break;
5071
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5072
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5073
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5074
                            break;
5075
                            /* Fall through.  */
5076
                        case 13: /* VQDMULL */
5077
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5078
                            break;
5079
                        default:
5080
                            abort();
5081
                        }
5082
                        neon_store_reg64(cpu_V0, rd + pass);
5083
                    } else if (op == 4 || op == 6) {
5084
                        /* Narrowing operation.  */
5085
                        tmp = new_tmp();
5086
                        if (!u) {
5087
                            switch (size) {
5088
                            case 0:
5089
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5090
                                break;
5091
                            case 1:
5092
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5093
                                break;
5094
                            case 2:
5095
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5096
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5097
                                break;
5098
                            default: abort();
5099
                            }
5100
                        } else {
5101
                            switch (size) {
5102
                            case 0:
5103
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5104
                                break;
5105
                            case 1:
5106
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5107
                                break;
5108
                            case 2:
5109
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5110
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5111
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5112
                                break;
5113
                            default: abort();
5114
                            }
5115
                        }
5116
                        if (pass == 0) {
5117
                            tmp3 = tmp;
5118
                        } else {
5119
                            neon_store_reg(rd, 0, tmp3);
5120
                            neon_store_reg(rd, 1, tmp);
5121
                        }
5122
                    } else {
5123
                        /* Write back the result.  */
5124
                        neon_store_reg64(cpu_V0, rd + pass);
5125
                    }
5126
                }
5127
            } else {
5128
                /* Two registers and a scalar.  */
5129
                switch (op) {
5130
                case 0: /* Integer VMLA scalar */
5131
                case 1: /* Float VMLA scalar */
5132
                case 4: /* Integer VMLS scalar */
5133
                case 5: /* Floating point VMLS scalar */
5134
                case 8: /* Integer VMUL scalar */
5135
                case 9: /* Floating point VMUL scalar */
5136
                case 12: /* VQDMULH scalar */
5137
                case 13: /* VQRDMULH scalar */
5138
                    tmp = neon_get_scalar(size, rm);
5139
                    neon_store_scratch(0, tmp);
5140
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5141
                        tmp = neon_load_scratch(0);
5142
                        tmp2 = neon_load_reg(rn, pass);
5143
                        if (op == 12) {
5144
                            if (size == 1) {
5145
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5146
                            } else {
5147
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5148
                            }
5149
                        } else if (op == 13) {
5150
                            if (size == 1) {
5151
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5152
                            } else {
5153
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5154
                            }
5155
                        } else if (op & 1) {
5156
                            gen_helper_neon_mul_f32(tmp, tmp, tmp2);
5157
                        } else {
5158
                            switch (size) {
5159
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5160
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5161
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5162
                            default: return 1;
5163
                            }
5164
                        }
5165
                        dead_tmp(tmp2);
5166
                        if (op < 8) {
5167
                            /* Accumulate.  */
5168
                            tmp2 = neon_load_reg(rd, pass);
5169
                            switch (op) {
5170
                            case 0:
5171
                                gen_neon_add(size, tmp, tmp2);
5172
                                break;
5173
                            case 1:
5174
                                gen_helper_neon_add_f32(tmp, tmp, tmp2);
5175
                                break;
5176
                            case 4:
5177
                                gen_neon_rsb(size, tmp, tmp2);
5178
                                break;
5179
                            case 5:
5180
                                gen_helper_neon_sub_f32(tmp, tmp2, tmp);
5181
                                break;
5182
                            default:
5183
                                abort();
5184
                            }
5185
                            dead_tmp(tmp2);
5186
                        }
5187
                        neon_store_reg(rd, pass, tmp);
5188
                    }
5189
                    break;
5190
                case 2: /* VMLAL sclar */
5191
                case 3: /* VQDMLAL scalar */
5192
                case 6: /* VMLSL scalar */
5193
                case 7: /* VQDMLSL scalar */
5194
                case 10: /* VMULL scalar */
5195
                case 11: /* VQDMULL scalar */
5196
                    if (size == 0 && (op == 3 || op == 7 || op == 11))
5197
                        return 1;
5198

    
5199
                    tmp2 = neon_get_scalar(size, rm);
5200
                    tmp3 = neon_load_reg(rn, 1);
5201

    
5202
                    for (pass = 0; pass < 2; pass++) {
5203
                        if (pass == 0) {
5204
                            tmp = neon_load_reg(rn, 0);
5205
                        } else {
5206
                            tmp = tmp3;
5207
                        }
5208
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5209
                        dead_tmp(tmp);
5210
                        if (op == 6 || op == 7) {
5211
                            gen_neon_negl(cpu_V0, size);
5212
                        }
5213
                        if (op != 11) {
5214
                            neon_load_reg64(cpu_V1, rd + pass);
5215
                        }
5216
                        switch (op) {
5217
                        case 2: case 6:
5218
                            gen_neon_addl(size);
5219
                            break;
5220
                        case 3: case 7:
5221
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5222
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5223
                            break;
5224
                        case 10:
5225
                            /* no-op */
5226
                            break;
5227
                        case 11:
5228
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5229
                            break;
5230
                        default:
5231
                            abort();
5232
                        }
5233
                        neon_store_reg64(cpu_V0, rd + pass);
5234
                    }
5235

    
5236
                    dead_tmp(tmp2);
5237

    
5238
                    break;
5239
                default: /* 14 and 15 are RESERVED */
5240
                    return 1;
5241
                }
5242
            }
5243
        } else { /* size == 3 */
5244
            if (!u) {
5245
                /* Extract.  */
5246
                imm = (insn >> 8) & 0xf;
5247

    
5248
                if (imm > 7 && !q)
5249
                    return 1;
5250

    
5251
                if (imm == 0) {
5252
                    neon_load_reg64(cpu_V0, rn);
5253
                    if (q) {
5254
                        neon_load_reg64(cpu_V1, rn + 1);
5255
                    }
5256
                } else if (imm == 8) {
5257
                    neon_load_reg64(cpu_V0, rn + 1);
5258
                    if (q) {
5259
                        neon_load_reg64(cpu_V1, rm);
5260
                    }
5261
                } else if (q) {
5262
                    tmp64 = tcg_temp_new_i64();
5263
                    if (imm < 8) {
5264
                        neon_load_reg64(cpu_V0, rn);
5265
                        neon_load_reg64(tmp64, rn + 1);
5266
                    } else {
5267
                        neon_load_reg64(cpu_V0, rn + 1);
5268
                        neon_load_reg64(tmp64, rm);
5269
                    }
5270
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5271
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5272
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5273
                    if (imm < 8) {
5274
                        neon_load_reg64(cpu_V1, rm);
5275
                    } else {
5276
                        neon_load_reg64(cpu_V1, rm + 1);
5277
                        imm -= 8;
5278
                    }
5279
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5280
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5281
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5282
                    tcg_temp_free_i64(tmp64);
5283
                } else {
5284
                    /* BUGFIX */
5285
                    neon_load_reg64(cpu_V0, rn);
5286
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5287
                    neon_load_reg64(cpu_V1, rm);
5288
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5289
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5290
                }
5291
                neon_store_reg64(cpu_V0, rd);
5292
                if (q) {
5293
                    neon_store_reg64(cpu_V1, rd + 1);
5294
                }
5295
            } else if ((insn & (1 << 11)) == 0) {
5296
                /* Two register misc.  */
5297
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5298
                size = (insn >> 18) & 3;
5299
                switch (op) {
5300
                case 0: /* VREV64 */
5301
                    if (size == 3)
5302
                        return 1;
5303
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
5304
                        tmp = neon_load_reg(rm, pass * 2);
5305
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
5306
                        switch (size) {
5307
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5308
                        case 1: gen_swap_half(tmp); break;
5309
                        case 2: /* no-op */ break;
5310
                        default: abort();
5311
                        }
5312
                        neon_store_reg(rd, pass * 2 + 1, tmp);
5313
                        if (size == 2) {
5314
                            neon_store_reg(rd, pass * 2, tmp2);
5315
                        } else {
5316
                            switch (size) {
5317
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5318
                            case 1: gen_swap_half(tmp2); break;
5319
                            default: abort();
5320
                            }
5321
                            neon_store_reg(rd, pass * 2, tmp2);
5322
                        }
5323
                    }
5324
                    break;
5325
                case 4: case 5: /* VPADDL */
5326
                case 12: case 13: /* VPADAL */
5327
                    if (size == 3)
5328
                        return 1;
5329
                    for (pass = 0; pass < q + 1; pass++) {
5330
                        tmp = neon_load_reg(rm, pass * 2);
5331
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
5332
                        tmp = neon_load_reg(rm, pass * 2 + 1);
5333
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
5334
                        switch (size) {
5335
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5336
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5337
                        case 2: tcg_gen_add_i64(CPU_V001); break;
5338
                        default: abort();
5339
                        }
5340
                        if (op >= 12) {
5341
                            /* Accumulate.  */
5342
                            neon_load_reg64(cpu_V1, rd + pass);
5343
                            gen_neon_addl(size);
5344
                        }
5345
                        neon_store_reg64(cpu_V0, rd + pass);
5346
                    }
5347
                    break;
5348
                case 33: /* VTRN */
5349
                    if (size == 2) {
5350
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
5351
                            tmp = neon_load_reg(rm, n);
5352
                            tmp2 = neon_load_reg(rd, n + 1);
5353
                            neon_store_reg(rm, n, tmp2);
5354
                            neon_store_reg(rd, n + 1, tmp);
5355
                        }
5356
                    } else {
5357
                        goto elementwise;
5358
                    }
5359
                    break;
5360
                case 34: /* VUZP */
5361
                    /* Reg  Before       After
5362
                       Rd   A3 A2 A1 A0  B2 B0 A2 A0
5363
                       Rm   B3 B2 B1 B0  B3 B1 A3 A1
5364
                     */
5365
                    if (size == 3)
5366
                        return 1;
5367
                    gen_neon_unzip(rd, q, 0, size);
5368
                    gen_neon_unzip(rm, q, 4, size);
5369
                    if (q) {
5370
                        static int unzip_order_q[8] =
5371
                            {0, 2, 4, 6, 1, 3, 5, 7};
5372
                        for (n = 0; n < 8; n++) {
5373
                            int reg = (n < 4) ? rd : rm;
5374
                            tmp = neon_load_scratch(unzip_order_q[n]);
5375
                            neon_store_reg(reg, n % 4, tmp);
5376
                        }
5377
                    } else {
5378
                        static int unzip_order[4] =
5379
                            {0, 4, 1, 5};
5380
                        for (n = 0; n < 4; n++) {
5381
                            int reg = (n < 2) ? rd : rm;
5382
                            tmp = neon_load_scratch(unzip_order[n]);
5383
                            neon_store_reg(reg, n % 2, tmp);
5384
                        }
5385
                    }
5386
                    break;
5387
                case 35: /* VZIP */
5388
                    /* Reg  Before       After
5389
                       Rd   A3 A2 A1 A0  B1 A1 B0 A0
5390
                       Rm   B3 B2 B1 B0  B3 A3 B2 A2
5391
                     */
5392
                    if (size == 3)
5393
                        return 1;
5394
                    count = (q ? 4 : 2);
5395
                    for (n = 0; n < count; n++) {
5396
                        tmp = neon_load_reg(rd, n);
5397
                        tmp2 = neon_load_reg(rd, n);
5398
                        switch (size) {
5399
                        case 0: gen_neon_zip_u8(tmp, tmp2); break;
5400
                        case 1: gen_neon_zip_u16(tmp, tmp2); break;
5401
                        case 2: /* no-op */; break;
5402
                        default: abort();
5403
                        }
5404
                        neon_store_scratch(n * 2, tmp);
5405
                        neon_store_scratch(n * 2 + 1, tmp2);
5406
                    }
5407
                    for (n = 0; n < count * 2; n++) {
5408
                        int reg = (n < count) ? rd : rm;
5409
                        tmp = neon_load_scratch(n);
5410
                        neon_store_reg(reg, n % count, tmp);
5411
                    }
5412
                    break;
5413
                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5414
                    if (size == 3)
5415
                        return 1;
5416
                    TCGV_UNUSED(tmp2);
5417
                    for (pass = 0; pass < 2; pass++) {
5418
                        neon_load_reg64(cpu_V0, rm + pass);
5419
                        tmp = new_tmp();
5420
                        if (op == 36 && q == 0) {
5421
                            gen_neon_narrow(size, tmp, cpu_V0);
5422
                        } else if (q) {
5423
                            gen_neon_narrow_satu(size, tmp, cpu_V0);
5424
                        } else {
5425
                            gen_neon_narrow_sats(size, tmp, cpu_V0);
5426
                        }
5427
                        if (pass == 0) {
5428
                            tmp2 = tmp;
5429
                        } else {
5430
                            neon_store_reg(rd, 0, tmp2);
5431
                            neon_store_reg(rd, 1, tmp);
5432
                        }
5433
                    }
5434
                    break;
5435
                case 38: /* VSHLL */
5436
                    if (q || size == 3)
5437
                        return 1;
5438
                    tmp = neon_load_reg(rm, 0);
5439
                    tmp2 = neon_load_reg(rm, 1);
5440
                    for (pass = 0; pass < 2; pass++) {
5441
                        if (pass == 1)
5442
                            tmp = tmp2;
5443
                        gen_neon_widen(cpu_V0, tmp, size, 1);
5444
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5445
                        neon_store_reg64(cpu_V0, rd + pass);
5446
                    }
5447
                    break;
5448
                case 44: /* VCVT.F16.F32 */
5449
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5450
                      return 1;
5451
                    tmp = new_tmp();
5452
                    tmp2 = new_tmp();
5453
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5454
                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5455
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5456
                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5457
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5458
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5459
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5460
                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5461
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5462
                    neon_store_reg(rd, 0, tmp2);
5463
                    tmp2 = new_tmp();
5464
                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5465
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5466
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5467
                    neon_store_reg(rd, 1, tmp2);
5468
                    dead_tmp(tmp);
5469
                    break;
5470
                case 46: /* VCVT.F32.F16 */
5471
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5472
                      return 1;
5473
                    tmp3 = new_tmp();
5474
                    tmp = neon_load_reg(rm, 0);
5475
                    tmp2 = neon_load_reg(rm, 1);
5476
                    tcg_gen_ext16u_i32(tmp3, tmp);
5477
                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5478
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5479
                    tcg_gen_shri_i32(tmp3, tmp, 16);
5480
                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5481
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5482
                    dead_tmp(tmp);
5483
                    tcg_gen_ext16u_i32(tmp3, tmp2);
5484
                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5485
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5486
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
5487
                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5488
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5489
                    dead_tmp(tmp2);
5490
                    dead_tmp(tmp3);
5491
                    break;
5492
                default:
5493
                elementwise:
5494
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
5495
                        if (op == 30 || op == 31 || op >= 58) {
5496
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
5497
                                           neon_reg_offset(rm, pass));
5498
                            TCGV_UNUSED(tmp);
5499
                        } else {
5500
                            tmp = neon_load_reg(rm, pass);
5501
                        }
5502
                        switch (op) {
5503
                        case 1: /* VREV32 */
5504
                            switch (size) {
5505
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5506
                            case 1: gen_swap_half(tmp); break;
5507
                            default: return 1;
5508
                            }
5509
                            break;
5510
                        case 2: /* VREV16 */
5511
                            if (size != 0)
5512
                                return 1;
5513
                            gen_rev16(tmp);
5514
                            break;
5515
                        case 8: /* CLS */
5516
                            switch (size) {
5517
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5518
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5519
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5520
                            default: return 1;
5521
                            }
5522
                            break;
5523
                        case 9: /* CLZ */
5524
                            switch (size) {
5525
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5526
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5527
                            case 2: gen_helper_clz(tmp, tmp); break;
5528
                            default: return 1;
5529
                            }
5530
                            break;
5531
                        case 10: /* CNT */
5532
                            if (size != 0)
5533
                                return 1;
5534
                            gen_helper_neon_cnt_u8(tmp, tmp);
5535
                            break;
5536
                        case 11: /* VNOT */
5537
                            if (size != 0)
5538
                                return 1;
5539
                            tcg_gen_not_i32(tmp, tmp);
5540
                            break;
5541
                        case 14: /* VQABS */
5542
                            switch (size) {
5543
                            case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
5544
                            case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
5545
                            case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
5546
                            default: return 1;
5547
                            }
5548
                            break;
5549
                        case 15: /* VQNEG */
5550
                            switch (size) {
5551
                            case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
5552
                            case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
5553
                            case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
5554
                            default: return 1;
5555
                            }
5556
                            break;
5557
                        case 16: case 19: /* VCGT #0, VCLE #0 */
5558
                            tmp2 = tcg_const_i32(0);
5559
                            switch(size) {
5560
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5561
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5562
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5563
                            default: return 1;
5564
                            }
5565
                            tcg_temp_free(tmp2);
5566
                            if (op == 19)
5567
                                tcg_gen_not_i32(tmp, tmp);
5568
                            break;
5569
                        case 17: case 20: /* VCGE #0, VCLT #0 */
5570
                            tmp2 = tcg_const_i32(0);
5571
                            switch(size) {
5572
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
5573
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
5574
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
5575
                            default: return 1;
5576
                            }
5577
                            tcg_temp_free(tmp2);
5578
                            if (op == 20)
5579
                                tcg_gen_not_i32(tmp, tmp);
5580
                            break;
5581
                        case 18: /* VCEQ #0 */
5582
                            tmp2 = tcg_const_i32(0);
5583
                            switch(size) {
5584
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5585
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5586
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5587
                            default: return 1;
5588
                            }
5589
                            tcg_temp_free(tmp2);
5590
                            break;
5591
                        case 22: /* VABS */
5592
                            switch(size) {
5593
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
5594
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
5595
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
5596
                            default: return 1;
5597
                            }
5598
                            break;
5599
                        case 23: /* VNEG */
5600
                            if (size == 3)
5601
                                return 1;
5602
                            tmp2 = tcg_const_i32(0);
5603
                            gen_neon_rsb(size, tmp, tmp2);
5604
                            tcg_temp_free(tmp2);
5605
                            break;
5606
                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5607
                            tmp2 = tcg_const_i32(0);
5608
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
5609
                            tcg_temp_free(tmp2);
5610
                            if (op == 27)
5611
                                tcg_gen_not_i32(tmp, tmp);
5612
                            break;
5613
                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5614
                            tmp2 = tcg_const_i32(0);
5615
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2);
5616
                            tcg_temp_free(tmp2);
5617
                            if (op == 28)
5618
                                tcg_gen_not_i32(tmp, tmp);
5619
                            break;
5620
                        case 26: /* Float VCEQ #0 */
5621
                            tmp2 = tcg_const_i32(0);
5622
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
5623
                            tcg_temp_free(tmp2);
5624
                            break;
5625
                        case 30: /* Float VABS */
5626
                            gen_vfp_abs(0);
5627
                            break;
5628
                        case 31: /* Float VNEG */
5629
                            gen_vfp_neg(0);
5630
                            break;
5631
                        case 32: /* VSWP */
5632
                            tmp2 = neon_load_reg(rd, pass);
5633
                            neon_store_reg(rm, pass, tmp2);
5634
                            break;
5635
                        case 33: /* VTRN */
5636
                            tmp2 = neon_load_reg(rd, pass);
5637
                            switch (size) {
5638
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
5639
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
5640
                            case 2: abort();
5641
                            default: return 1;
5642
                            }
5643
                            neon_store_reg(rm, pass, tmp2);
5644
                            break;
5645
                        case 56: /* Integer VRECPE */
5646
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
5647
                            break;
5648
                        case 57: /* Integer VRSQRTE */
5649
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
5650
                            break;
5651
                        case 58: /* Float VRECPE */
5652
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5653
                            break;
5654
                        case 59: /* Float VRSQRTE */
5655
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5656
                            break;
5657
                        case 60: /* VCVT.F32.S32 */
5658
                            gen_vfp_tosiz(0);
5659
                            break;
5660
                        case 61: /* VCVT.F32.U32 */
5661
                            gen_vfp_touiz(0);
5662
                            break;
5663
                        case 62: /* VCVT.S32.F32 */
5664
                            gen_vfp_sito(0);
5665
                            break;
5666
                        case 63: /* VCVT.U32.F32 */
5667
                            gen_vfp_uito(0);
5668
                            break;
5669
                        default:
5670
                            /* Reserved: 21, 29, 39-56 */
5671
                            return 1;
5672
                        }
5673
                        if (op == 30 || op == 31 || op >= 58) {
5674
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
5675
                                           neon_reg_offset(rd, pass));
5676
                        } else {
5677
                            neon_store_reg(rd, pass, tmp);
5678
                        }
5679
                    }
5680
                    break;
5681
                }
5682
            } else if ((insn & (1 << 10)) == 0) {
5683
                /* VTBL, VTBX.  */
5684
                n = ((insn >> 5) & 0x18) + 8;
5685
                if (insn & (1 << 6)) {
5686
                    tmp = neon_load_reg(rd, 0);
5687
                } else {
5688
                    tmp = new_tmp();
5689
                    tcg_gen_movi_i32(tmp, 0);
5690
                }
5691
                tmp2 = neon_load_reg(rm, 0);
5692
                tmp4 = tcg_const_i32(rn);
5693
                tmp5 = tcg_const_i32(n);
5694
                gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
5695
                dead_tmp(tmp);
5696
                if (insn & (1 << 6)) {
5697
                    tmp = neon_load_reg(rd, 1);
5698
                } else {
5699
                    tmp = new_tmp();
5700
                    tcg_gen_movi_i32(tmp, 0);
5701
                }
5702
                tmp3 = neon_load_reg(rm, 1);
5703
                gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
5704
                tcg_temp_free_i32(tmp5);
5705
                tcg_temp_free_i32(tmp4);
5706
                neon_store_reg(rd, 0, tmp2);
5707
                neon_store_reg(rd, 1, tmp3);
5708
                dead_tmp(tmp);
5709
            } else if ((insn & 0x380) == 0) {
5710
                /* VDUP */
5711
                if (insn & (1 << 19)) {
5712
                    tmp = neon_load_reg(rm, 1);
5713
                } else {
5714
                    tmp = neon_load_reg(rm, 0);
5715
                }
5716
                if (insn & (1 << 16)) {
5717
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
5718
                } else if (insn & (1 << 17)) {
5719
                    if ((insn >> 18) & 1)
5720
                        gen_neon_dup_high16(tmp);
5721
                    else
5722
                        gen_neon_dup_low16(tmp);
5723
                }
5724
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5725
                    tmp2 = new_tmp();
5726
                    tcg_gen_mov_i32(tmp2, tmp);
5727
                    neon_store_reg(rd, pass, tmp2);
5728
                }
5729
                dead_tmp(tmp);
5730
            } else {
5731
                return 1;
5732
            }
5733
        }
5734
    }
5735
    return 0;
5736
}
5737

    
5738
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5739
{
5740
    int crn = (insn >> 16) & 0xf;
5741
    int crm = insn & 0xf;
5742
    int op1 = (insn >> 21) & 7;
5743
    int op2 = (insn >> 5) & 7;
5744
    int rt = (insn >> 12) & 0xf;
5745
    TCGv tmp;
5746

    
5747
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5748
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5749
            /* TEECR */
5750
            if (IS_USER(s))
5751
                return 1;
5752
            tmp = load_cpu_field(teecr);
5753
            store_reg(s, rt, tmp);
5754
            return 0;
5755
        }
5756
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5757
            /* TEEHBR */
5758
            if (IS_USER(s) && (env->teecr & 1))
5759
                return 1;
5760
            tmp = load_cpu_field(teehbr);
5761
            store_reg(s, rt, tmp);
5762
            return 0;
5763
        }
5764
    }
5765
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5766
            op1, crn, crm, op2);
5767
    return 1;
5768
}
5769

    
5770
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5771
{
5772
    int crn = (insn >> 16) & 0xf;
5773
    int crm = insn & 0xf;
5774
    int op1 = (insn >> 21) & 7;
5775
    int op2 = (insn >> 5) & 7;
5776
    int rt = (insn >> 12) & 0xf;
5777
    TCGv tmp;
5778

    
5779
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5780
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5781
            /* TEECR */
5782
            if (IS_USER(s))
5783
                return 1;
5784
            tmp = load_reg(s, rt);
5785
            gen_helper_set_teecr(cpu_env, tmp);
5786
            dead_tmp(tmp);
5787
            return 0;
5788
        }
5789
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5790
            /* TEEHBR */
5791
            if (IS_USER(s) && (env->teecr & 1))
5792
                return 1;
5793
            tmp = load_reg(s, rt);
5794
            store_cpu_field(tmp, teehbr);
5795
            return 0;
5796
        }
5797
    }
5798
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5799
            op1, crn, crm, op2);
5800
    return 1;
5801
}
5802

    
5803
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5804
{
5805
    int cpnum;
5806

    
5807
    cpnum = (insn >> 8) & 0xf;
5808
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5809
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5810
        return 1;
5811

    
5812
    switch (cpnum) {
5813
      case 0:
5814
      case 1:
5815
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5816
            return disas_iwmmxt_insn(env, s, insn);
5817
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5818
            return disas_dsp_insn(env, s, insn);
5819
        }
5820
        return 1;
5821
    case 10:
5822
    case 11:
5823
        return disas_vfp_insn (env, s, insn);
5824
    case 14:
5825
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5826
           Unfortunately Intel decided to ignore this.  */
5827
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5828
            goto board;
5829
        if (insn & (1 << 20))
5830
            return disas_cp14_read(env, s, insn);
5831
        else
5832
            return disas_cp14_write(env, s, insn);
5833
    case 15:
5834
        return disas_cp15_insn (env, s, insn);
5835
    default:
5836
    board:
5837
        /* Unknown coprocessor.  See if the board has hooked it.  */
5838
        return disas_cp_insn (env, s, insn);
5839
    }
5840
}
5841

    
5842

    
5843
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5844
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5845
{
5846
    TCGv tmp;
5847
    tmp = new_tmp();
5848
    tcg_gen_trunc_i64_i32(tmp, val);
5849
    store_reg(s, rlow, tmp);
5850
    tmp = new_tmp();
5851
    tcg_gen_shri_i64(val, val, 32);
5852
    tcg_gen_trunc_i64_i32(tmp, val);
5853
    store_reg(s, rhigh, tmp);
5854
}
5855

    
5856
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5857
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5858
{
5859
    TCGv_i64 tmp;
5860
    TCGv tmp2;
5861

    
5862
    /* Load value and extend to 64 bits.  */
5863
    tmp = tcg_temp_new_i64();
5864
    tmp2 = load_reg(s, rlow);
5865
    tcg_gen_extu_i32_i64(tmp, tmp2);
5866
    dead_tmp(tmp2);
5867
    tcg_gen_add_i64(val, val, tmp);
5868
    tcg_temp_free_i64(tmp);
5869
}
5870

    
5871
/* load and add a 64-bit value from a register pair.  */
5872
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5873
{
5874
    TCGv_i64 tmp;
5875
    TCGv tmpl;
5876
    TCGv tmph;
5877

    
5878
    /* Load 64-bit value rd:rn.  */
5879
    tmpl = load_reg(s, rlow);
5880
    tmph = load_reg(s, rhigh);
5881
    tmp = tcg_temp_new_i64();
5882
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5883
    dead_tmp(tmpl);
5884
    dead_tmp(tmph);
5885
    tcg_gen_add_i64(val, val, tmp);
5886
    tcg_temp_free_i64(tmp);
5887
}
5888

    
5889
/* Set N and Z flags from a 64-bit value.  */
5890
static void gen_logicq_cc(TCGv_i64 val)
5891
{
5892
    TCGv tmp = new_tmp();
5893
    gen_helper_logicq_cc(tmp, val);
5894
    gen_logic_CC(tmp);
5895
    dead_tmp(tmp);
5896
}
5897

    
5898
/* Load/Store exclusive instructions are implemented by remembering
5899
   the value/address loaded, and seeing if these are the same
5900
   when the store is performed. This should be is sufficient to implement
5901
   the architecturally mandated semantics, and avoids having to monitor
5902
   regular stores.
5903

5904
   In system emulation mode only one CPU will be running at once, so
5905
   this sequence is effectively atomic.  In user emulation mode we
5906
   throw an exception and handle the atomic operation elsewhere.  */
5907
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
5908
                               TCGv addr, int size)
5909
{
5910
    TCGv tmp;
5911

    
5912
    switch (size) {
5913
    case 0:
5914
        tmp = gen_ld8u(addr, IS_USER(s));
5915
        break;
5916
    case 1:
5917
        tmp = gen_ld16u(addr, IS_USER(s));
5918
        break;
5919
    case 2:
5920
    case 3:
5921
        tmp = gen_ld32(addr, IS_USER(s));
5922
        break;
5923
    default:
5924
        abort();
5925
    }
5926
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
5927
    store_reg(s, rt, tmp);
5928
    if (size == 3) {
5929
        tcg_gen_addi_i32(addr, addr, 4);
5930
        tmp = gen_ld32(addr, IS_USER(s));
5931
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
5932
        store_reg(s, rt2, tmp);
5933
    }
5934
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
5935
}
5936

    
5937
static void gen_clrex(DisasContext *s)
5938
{
5939
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
5940
}
5941

    
5942
#ifdef CONFIG_USER_ONLY
5943
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
5944
                                TCGv addr, int size)
5945
{
5946
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
5947
    tcg_gen_movi_i32(cpu_exclusive_info,
5948
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
5949
    gen_set_condexec(s);
5950
    gen_set_pc_im(s->pc - 4);
5951
    gen_exception(EXCP_STREX);
5952
    s->is_jmp = DISAS_JUMP;
5953
}
5954
#else
5955
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
5956
                                TCGv addr, int size)
5957
{
5958
    TCGv tmp;
5959
    int done_label;
5960
    int fail_label;
5961

    
5962
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
5963
         [addr] = {Rt};
5964
         {Rd} = 0;
5965
       } else {
5966
         {Rd} = 1;
5967
       } */
5968
    fail_label = gen_new_label();
5969
    done_label = gen_new_label();
5970
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
5971
    switch (size) {
5972
    case 0:
5973
        tmp = gen_ld8u(addr, IS_USER(s));
5974
        break;
5975
    case 1:
5976
        tmp = gen_ld16u(addr, IS_USER(s));
5977
        break;
5978
    case 2:
5979
    case 3:
5980
        tmp = gen_ld32(addr, IS_USER(s));
5981
        break;
5982
    default:
5983
        abort();
5984
    }
5985
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
5986
    dead_tmp(tmp);
5987
    if (size == 3) {
5988
        TCGv tmp2 = new_tmp();
5989
        tcg_gen_addi_i32(tmp2, addr, 4);
5990
        tmp = gen_ld32(addr, IS_USER(s));
5991
        dead_tmp(tmp2);
5992
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
5993
        dead_tmp(tmp);
5994
    }
5995
    tmp = load_reg(s, rt);
5996
    switch (size) {
5997
    case 0:
5998
        gen_st8(tmp, addr, IS_USER(s));
5999
        break;
6000
    case 1:
6001
        gen_st16(tmp, addr, IS_USER(s));
6002
        break;
6003
    case 2:
6004
    case 3:
6005
        gen_st32(tmp, addr, IS_USER(s));
6006
        break;
6007
    default:
6008
        abort();
6009
    }
6010
    if (size == 3) {
6011
        tcg_gen_addi_i32(addr, addr, 4);
6012
        tmp = load_reg(s, rt2);
6013
        gen_st32(tmp, addr, IS_USER(s));
6014
    }
6015
    tcg_gen_movi_i32(cpu_R[rd], 0);
6016
    tcg_gen_br(done_label);
6017
    gen_set_label(fail_label);
6018
    tcg_gen_movi_i32(cpu_R[rd], 1);
6019
    gen_set_label(done_label);
6020
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6021
}
6022
#endif
6023

    
6024
static void disas_arm_insn(CPUState * env, DisasContext *s)
6025
{
6026
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6027
    TCGv tmp;
6028
    TCGv tmp2;
6029
    TCGv tmp3;
6030
    TCGv addr;
6031
    TCGv_i64 tmp64;
6032

    
6033
    insn = ldl_code(s->pc);
6034
    s->pc += 4;
6035

    
6036
    /* M variants do not implement ARM mode.  */
6037
    if (IS_M(env))
6038
        goto illegal_op;
6039
    cond = insn >> 28;
6040
    if (cond == 0xf){
6041
        /* Unconditional instructions.  */
6042
        if (((insn >> 25) & 7) == 1) {
6043
            /* NEON Data processing.  */
6044
            if (!arm_feature(env, ARM_FEATURE_NEON))
6045
                goto illegal_op;
6046

    
6047
            if (disas_neon_data_insn(env, s, insn))
6048
                goto illegal_op;
6049
            return;
6050
        }
6051
        if ((insn & 0x0f100000) == 0x04000000) {
6052
            /* NEON load/store.  */
6053
            if (!arm_feature(env, ARM_FEATURE_NEON))
6054
                goto illegal_op;
6055

    
6056
            if (disas_neon_ls_insn(env, s, insn))
6057
                goto illegal_op;
6058
            return;
6059
        }
6060
        if ((insn & 0x0d70f000) == 0x0550f000)
6061
            return; /* PLD */
6062
        else if ((insn & 0x0ffffdff) == 0x01010000) {
6063
            ARCH(6);
6064
            /* setend */
6065
            if (insn & (1 << 9)) {
6066
                /* BE8 mode not implemented.  */
6067
                goto illegal_op;
6068
            }
6069
            return;
6070
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6071
            switch ((insn >> 4) & 0xf) {
6072
            case 1: /* clrex */
6073
                ARCH(6K);
6074
                gen_clrex(s);
6075
                return;
6076
            case 4: /* dsb */
6077
            case 5: /* dmb */
6078
            case 6: /* isb */
6079
                ARCH(7);
6080
                /* We don't emulate caches so these are a no-op.  */
6081
                return;
6082
            default:
6083
                goto illegal_op;
6084
            }
6085
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6086
            /* srs */
6087
            int32_t offset;
6088
            if (IS_USER(s))
6089
                goto illegal_op;
6090
            ARCH(6);
6091
            op1 = (insn & 0x1f);
6092
            if (op1 == (env->uncached_cpsr & CPSR_M)) {
6093
                addr = load_reg(s, 13);
6094
            } else {
6095
                addr = new_tmp();
6096
                tmp = tcg_const_i32(op1);
6097
                gen_helper_get_r13_banked(addr, cpu_env, tmp);
6098
                tcg_temp_free_i32(tmp);
6099
            }
6100
            i = (insn >> 23) & 3;
6101
            switch (i) {
6102
            case 0: offset = -4; break; /* DA */
6103
            case 1: offset = 0; break; /* IA */
6104
            case 2: offset = -8; break; /* DB */
6105
            case 3: offset = 4; break; /* IB */
6106
            default: abort();
6107
            }
6108
            if (offset)
6109
                tcg_gen_addi_i32(addr, addr, offset);
6110
            tmp = load_reg(s, 14);
6111
            gen_st32(tmp, addr, 0);
6112
            tmp = load_cpu_field(spsr);
6113
            tcg_gen_addi_i32(addr, addr, 4);
6114
            gen_st32(tmp, addr, 0);
6115
            if (insn & (1 << 21)) {
6116
                /* Base writeback.  */
6117
                switch (i) {
6118
                case 0: offset = -8; break;
6119
                case 1: offset = 4; break;
6120
                case 2: offset = -4; break;
6121
                case 3: offset = 0; break;
6122
                default: abort();
6123
                }
6124
                if (offset)
6125
                    tcg_gen_addi_i32(addr, addr, offset);
6126
                if (op1 == (env->uncached_cpsr & CPSR_M)) {
6127
                    store_reg(s, 13, addr);
6128
                } else {
6129
                    tmp = tcg_const_i32(op1);
6130
                    gen_helper_set_r13_banked(cpu_env, tmp, addr);
6131
                    tcg_temp_free_i32(tmp);
6132
                    dead_tmp(addr);
6133
                }
6134
            } else {
6135
                dead_tmp(addr);
6136
            }
6137
            return;
6138
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6139
            /* rfe */
6140
            int32_t offset;
6141
            if (IS_USER(s))
6142
                goto illegal_op;
6143
            ARCH(6);
6144
            rn = (insn >> 16) & 0xf;
6145
            addr = load_reg(s, rn);
6146
            i = (insn >> 23) & 3;
6147
            switch (i) {
6148
            case 0: offset = -4; break; /* DA */
6149
            case 1: offset = 0; break; /* IA */
6150
            case 2: offset = -8; break; /* DB */
6151
            case 3: offset = 4; break; /* IB */
6152
            default: abort();
6153
            }
6154
            if (offset)
6155
                tcg_gen_addi_i32(addr, addr, offset);
6156
            /* Load PC into tmp and CPSR into tmp2.  */
6157
            tmp = gen_ld32(addr, 0);
6158
            tcg_gen_addi_i32(addr, addr, 4);
6159
            tmp2 = gen_ld32(addr, 0);
6160
            if (insn & (1 << 21)) {
6161
                /* Base writeback.  */
6162
                switch (i) {
6163
                case 0: offset = -8; break;
6164
                case 1: offset = 4; break;
6165
                case 2: offset = -4; break;
6166
                case 3: offset = 0; break;
6167
                default: abort();
6168
                }
6169
                if (offset)
6170
                    tcg_gen_addi_i32(addr, addr, offset);
6171
                store_reg(s, rn, addr);
6172
            } else {
6173
                dead_tmp(addr);
6174
            }
6175
            gen_rfe(s, tmp, tmp2);
6176
            return;
6177
        } else if ((insn & 0x0e000000) == 0x0a000000) {
6178
            /* branch link and change to thumb (blx <offset>) */
6179
            int32_t offset;
6180

    
6181
            val = (uint32_t)s->pc;
6182
            tmp = new_tmp();
6183
            tcg_gen_movi_i32(tmp, val);
6184
            store_reg(s, 14, tmp);
6185
            /* Sign-extend the 24-bit offset */
6186
            offset = (((int32_t)insn) << 8) >> 8;
6187
            /* offset * 4 + bit24 * 2 + (thumb bit) */
6188
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
6189
            /* pipeline offset */
6190
            val += 4;
6191
            gen_bx_im(s, val);
6192
            return;
6193
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
6194
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6195
                /* iWMMXt register transfer.  */
6196
                if (env->cp15.c15_cpar & (1 << 1))
6197
                    if (!disas_iwmmxt_insn(env, s, insn))
6198
                        return;
6199
            }
6200
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
6201
            /* Coprocessor double register transfer.  */
6202
        } else if ((insn & 0x0f000010) == 0x0e000010) {
6203
            /* Additional coprocessor register transfer.  */
6204
        } else if ((insn & 0x0ff10020) == 0x01000000) {
6205
            uint32_t mask;
6206
            uint32_t val;
6207
            /* cps (privileged) */
6208
            if (IS_USER(s))
6209
                return;
6210
            mask = val = 0;
6211
            if (insn & (1 << 19)) {
6212
                if (insn & (1 << 8))
6213
                    mask |= CPSR_A;
6214
                if (insn & (1 << 7))
6215
                    mask |= CPSR_I;
6216
                if (insn & (1 << 6))
6217
                    mask |= CPSR_F;
6218
                if (insn & (1 << 18))
6219
                    val |= mask;
6220
            }
6221
            if (insn & (1 << 17)) {
6222
                mask |= CPSR_M;
6223
                val |= (insn & 0x1f);
6224
            }
6225
            if (mask) {
6226
                gen_set_psr_im(s, mask, 0, val);
6227
            }
6228
            return;
6229
        }
6230
        goto illegal_op;
6231
    }
6232
    if (cond != 0xe) {
6233
        /* if not always execute, we generate a conditional jump to
6234
           next instruction */
6235
        s->condlabel = gen_new_label();
6236
        gen_test_cc(cond ^ 1, s->condlabel);
6237
        s->condjmp = 1;
6238
    }
6239
    if ((insn & 0x0f900000) == 0x03000000) {
6240
        if ((insn & (1 << 21)) == 0) {
6241
            ARCH(6T2);
6242
            rd = (insn >> 12) & 0xf;
6243
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6244
            if ((insn & (1 << 22)) == 0) {
6245
                /* MOVW */
6246
                tmp = new_tmp();
6247
                tcg_gen_movi_i32(tmp, val);
6248
            } else {
6249
                /* MOVT */
6250
                tmp = load_reg(s, rd);
6251
                tcg_gen_ext16u_i32(tmp, tmp);
6252
                tcg_gen_ori_i32(tmp, tmp, val << 16);
6253
            }
6254
            store_reg(s, rd, tmp);
6255
        } else {
6256
            if (((insn >> 12) & 0xf) != 0xf)
6257
                goto illegal_op;
6258
            if (((insn >> 16) & 0xf) == 0) {
6259
                gen_nop_hint(s, insn & 0xff);
6260
            } else {
6261
                /* CPSR = immediate */
6262
                val = insn & 0xff;
6263
                shift = ((insn >> 8) & 0xf) * 2;
6264
                if (shift)
6265
                    val = (val >> shift) | (val << (32 - shift));
6266
                i = ((insn & (1 << 22)) != 0);
6267
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6268
                    goto illegal_op;
6269
            }
6270
        }
6271
    } else if ((insn & 0x0f900000) == 0x01000000
6272
               && (insn & 0x00000090) != 0x00000090) {
6273
        /* miscellaneous instructions */
6274
        op1 = (insn >> 21) & 3;
6275
        sh = (insn >> 4) & 0xf;
6276
        rm = insn & 0xf;
6277
        switch (sh) {
6278
        case 0x0: /* move program status register */
6279
            if (op1 & 1) {
6280
                /* PSR = reg */
6281
                tmp = load_reg(s, rm);
6282
                i = ((op1 & 2) != 0);
6283
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6284
                    goto illegal_op;
6285
            } else {
6286
                /* reg = PSR */
6287
                rd = (insn >> 12) & 0xf;
6288
                if (op1 & 2) {
6289
                    if (IS_USER(s))
6290
                        goto illegal_op;
6291
                    tmp = load_cpu_field(spsr);
6292
                } else {
6293
                    tmp = new_tmp();
6294
                    gen_helper_cpsr_read(tmp);
6295
                }
6296
                store_reg(s, rd, tmp);
6297
            }
6298
            break;
6299
        case 0x1:
6300
            if (op1 == 1) {
6301
                /* branch/exchange thumb (bx).  */
6302
                tmp = load_reg(s, rm);
6303
                gen_bx(s, tmp);
6304
            } else if (op1 == 3) {
6305
                /* clz */
6306
                rd = (insn >> 12) & 0xf;
6307
                tmp = load_reg(s, rm);
6308
                gen_helper_clz(tmp, tmp);
6309
                store_reg(s, rd, tmp);
6310
            } else {
6311
                goto illegal_op;
6312
            }
6313
            break;
6314
        case 0x2:
6315
            if (op1 == 1) {
6316
                ARCH(5J); /* bxj */
6317
                /* Trivial implementation equivalent to bx.  */
6318
                tmp = load_reg(s, rm);
6319
                gen_bx(s, tmp);
6320
            } else {
6321
                goto illegal_op;
6322
            }
6323
            break;
6324
        case 0x3:
6325
            if (op1 != 1)
6326
              goto illegal_op;
6327

    
6328
            /* branch link/exchange thumb (blx) */
6329
            tmp = load_reg(s, rm);
6330
            tmp2 = new_tmp();
6331
            tcg_gen_movi_i32(tmp2, s->pc);
6332
            store_reg(s, 14, tmp2);
6333
            gen_bx(s, tmp);
6334
            break;
6335
        case 0x5: /* saturating add/subtract */
6336
            rd = (insn >> 12) & 0xf;
6337
            rn = (insn >> 16) & 0xf;
6338
            tmp = load_reg(s, rm);
6339
            tmp2 = load_reg(s, rn);
6340
            if (op1 & 2)
6341
                gen_helper_double_saturate(tmp2, tmp2);
6342
            if (op1 & 1)
6343
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6344
            else
6345
                gen_helper_add_saturate(tmp, tmp, tmp2);
6346
            dead_tmp(tmp2);
6347
            store_reg(s, rd, tmp);
6348
            break;
6349
        case 7: /* bkpt */
6350
            gen_set_condexec(s);
6351
            gen_set_pc_im(s->pc - 4);
6352
            gen_exception(EXCP_BKPT);
6353
            s->is_jmp = DISAS_JUMP;
6354
            break;
6355
        case 0x8: /* signed multiply */
6356
        case 0xa:
6357
        case 0xc:
6358
        case 0xe:
6359
            rs = (insn >> 8) & 0xf;
6360
            rn = (insn >> 12) & 0xf;
6361
            rd = (insn >> 16) & 0xf;
6362
            if (op1 == 1) {
6363
                /* (32 * 16) >> 16 */
6364
                tmp = load_reg(s, rm);
6365
                tmp2 = load_reg(s, rs);
6366
                if (sh & 4)
6367
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6368
                else
6369
                    gen_sxth(tmp2);
6370
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
6371
                tcg_gen_shri_i64(tmp64, tmp64, 16);
6372
                tmp = new_tmp();
6373
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6374
                tcg_temp_free_i64(tmp64);
6375
                if ((sh & 2) == 0) {
6376
                    tmp2 = load_reg(s, rn);
6377
                    gen_helper_add_setq(tmp, tmp, tmp2);
6378
                    dead_tmp(tmp2);
6379
                }
6380
                store_reg(s, rd, tmp);
6381
            } else {
6382
                /* 16 * 16 */
6383
                tmp = load_reg(s, rm);
6384
                tmp2 = load_reg(s, rs);
6385
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6386
                dead_tmp(tmp2);
6387
                if (op1 == 2) {
6388
                    tmp64 = tcg_temp_new_i64();
6389
                    tcg_gen_ext_i32_i64(tmp64, tmp);
6390
                    dead_tmp(tmp);
6391
                    gen_addq(s, tmp64, rn, rd);
6392
                    gen_storeq_reg(s, rn, rd, tmp64);
6393
                    tcg_temp_free_i64(tmp64);
6394
                } else {
6395
                    if (op1 == 0) {
6396
                        tmp2 = load_reg(s, rn);
6397
                        gen_helper_add_setq(tmp, tmp, tmp2);
6398
                        dead_tmp(tmp2);
6399
                    }
6400
                    store_reg(s, rd, tmp);
6401
                }
6402
            }
6403
            break;
6404
        default:
6405
            goto illegal_op;
6406
        }
6407
    } else if (((insn & 0x0e000000) == 0 &&
6408
                (insn & 0x00000090) != 0x90) ||
6409
               ((insn & 0x0e000000) == (1 << 25))) {
6410
        int set_cc, logic_cc, shiftop;
6411

    
6412
        op1 = (insn >> 21) & 0xf;
6413
        set_cc = (insn >> 20) & 1;
6414
        logic_cc = table_logic_cc[op1] & set_cc;
6415

    
6416
        /* data processing instruction */
6417
        if (insn & (1 << 25)) {
6418
            /* immediate operand */
6419
            val = insn & 0xff;
6420
            shift = ((insn >> 8) & 0xf) * 2;
6421
            if (shift) {
6422
                val = (val >> shift) | (val << (32 - shift));
6423
            }
6424
            tmp2 = new_tmp();
6425
            tcg_gen_movi_i32(tmp2, val);
6426
            if (logic_cc && shift) {
6427
                gen_set_CF_bit31(tmp2);
6428
            }
6429
        } else {
6430
            /* register */
6431
            rm = (insn) & 0xf;
6432
            tmp2 = load_reg(s, rm);
6433
            shiftop = (insn >> 5) & 3;
6434
            if (!(insn & (1 << 4))) {
6435
                shift = (insn >> 7) & 0x1f;
6436
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6437
            } else {
6438
                rs = (insn >> 8) & 0xf;
6439
                tmp = load_reg(s, rs);
6440
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6441
            }
6442
        }
6443
        if (op1 != 0x0f && op1 != 0x0d) {
6444
            rn = (insn >> 16) & 0xf;
6445
            tmp = load_reg(s, rn);
6446
        } else {
6447
            TCGV_UNUSED(tmp);
6448
        }
6449
        rd = (insn >> 12) & 0xf;
6450
        switch(op1) {
6451
        case 0x00:
6452
            tcg_gen_and_i32(tmp, tmp, tmp2);
6453
            if (logic_cc) {
6454
                gen_logic_CC(tmp);
6455
            }
6456
            store_reg_bx(env, s, rd, tmp);
6457
            break;
6458
        case 0x01:
6459
            tcg_gen_xor_i32(tmp, tmp, tmp2);
6460
            if (logic_cc) {
6461
                gen_logic_CC(tmp);
6462
            }
6463
            store_reg_bx(env, s, rd, tmp);
6464
            break;
6465
        case 0x02:
6466
            if (set_cc && rd == 15) {
6467
                /* SUBS r15, ... is used for exception return.  */
6468
                if (IS_USER(s)) {
6469
                    goto illegal_op;
6470
                }
6471
                gen_helper_sub_cc(tmp, tmp, tmp2);
6472
                gen_exception_return(s, tmp);
6473
            } else {
6474
                if (set_cc) {
6475
                    gen_helper_sub_cc(tmp, tmp, tmp2);
6476
                } else {
6477
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
6478
                }
6479
                store_reg_bx(env, s, rd, tmp);
6480
            }
6481
            break;
6482
        case 0x03:
6483
            if (set_cc) {
6484
                gen_helper_sub_cc(tmp, tmp2, tmp);
6485
            } else {
6486
                tcg_gen_sub_i32(tmp, tmp2, tmp);
6487
            }
6488
            store_reg_bx(env, s, rd, tmp);
6489
            break;
6490
        case 0x04:
6491
            if (set_cc) {
6492
                gen_helper_add_cc(tmp, tmp, tmp2);
6493
            } else {
6494
                tcg_gen_add_i32(tmp, tmp, tmp2);
6495
            }
6496
            store_reg_bx(env, s, rd, tmp);
6497
            break;
6498
        case 0x05:
6499
            if (set_cc) {
6500
                gen_helper_adc_cc(tmp, tmp, tmp2);
6501
            } else {
6502
                gen_add_carry(tmp, tmp, tmp2);
6503
            }
6504
            store_reg_bx(env, s, rd, tmp);
6505
            break;
6506
        case 0x06:
6507
            if (set_cc) {
6508
                gen_helper_sbc_cc(tmp, tmp, tmp2);
6509
            } else {
6510
                gen_sub_carry(tmp, tmp, tmp2);
6511
            }
6512
            store_reg_bx(env, s, rd, tmp);
6513
            break;
6514
        case 0x07:
6515
            if (set_cc) {
6516
                gen_helper_sbc_cc(tmp, tmp2, tmp);
6517
            } else {
6518
                gen_sub_carry(tmp, tmp2, tmp);
6519
            }
6520
            store_reg_bx(env, s, rd, tmp);
6521
            break;
6522
        case 0x08:
6523
            if (set_cc) {
6524
                tcg_gen_and_i32(tmp, tmp, tmp2);
6525
                gen_logic_CC(tmp);
6526
            }
6527
            dead_tmp(tmp);
6528
            break;
6529
        case 0x09:
6530
            if (set_cc) {
6531
                tcg_gen_xor_i32(tmp, tmp, tmp2);
6532
                gen_logic_CC(tmp);
6533
            }
6534
            dead_tmp(tmp);
6535
            break;
6536
        case 0x0a:
6537
            if (set_cc) {
6538
                gen_helper_sub_cc(tmp, tmp, tmp2);
6539
            }
6540
            dead_tmp(tmp);
6541
            break;
6542
        case 0x0b:
6543
            if (set_cc) {
6544
                gen_helper_add_cc(tmp, tmp, tmp2);
6545
            }
6546
            dead_tmp(tmp);
6547
            break;
6548
        case 0x0c:
6549
            tcg_gen_or_i32(tmp, tmp, tmp2);
6550
            if (logic_cc) {
6551
                gen_logic_CC(tmp);
6552
            }
6553
            store_reg_bx(env, s, rd, tmp);
6554
            break;
6555
        case 0x0d:
6556
            if (logic_cc && rd == 15) {
6557
                /* MOVS r15, ... is used for exception return.  */
6558
                if (IS_USER(s)) {
6559
                    goto illegal_op;
6560
                }
6561
                gen_exception_return(s, tmp2);
6562
            } else {
6563
                if (logic_cc) {
6564
                    gen_logic_CC(tmp2);
6565
                }
6566
                store_reg_bx(env, s, rd, tmp2);
6567
            }
6568
            break;
6569
        case 0x0e:
6570
            tcg_gen_andc_i32(tmp, tmp, tmp2);
6571
            if (logic_cc) {
6572
                gen_logic_CC(tmp);
6573
            }
6574
            store_reg_bx(env, s, rd, tmp);
6575
            break;
6576
        default:
6577
        case 0x0f:
6578
            tcg_gen_not_i32(tmp2, tmp2);
6579
            if (logic_cc) {
6580
                gen_logic_CC(tmp2);
6581
            }
6582
            store_reg_bx(env, s, rd, tmp2);
6583
            break;
6584
        }
6585
        if (op1 != 0x0f && op1 != 0x0d) {
6586
            dead_tmp(tmp2);
6587
        }
6588
    } else {
6589
        /* other instructions */
6590
        op1 = (insn >> 24) & 0xf;
6591
        switch(op1) {
6592
        case 0x0:
6593
        case 0x1:
6594
            /* multiplies, extra load/stores */
6595
            sh = (insn >> 5) & 3;
6596
            if (sh == 0) {
6597
                if (op1 == 0x0) {
6598
                    rd = (insn >> 16) & 0xf;
6599
                    rn = (insn >> 12) & 0xf;
6600
                    rs = (insn >> 8) & 0xf;
6601
                    rm = (insn) & 0xf;
6602
                    op1 = (insn >> 20) & 0xf;
6603
                    switch (op1) {
6604
                    case 0: case 1: case 2: case 3: case 6:
6605
                        /* 32 bit mul */
6606
                        tmp = load_reg(s, rs);
6607
                        tmp2 = load_reg(s, rm);
6608
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
6609
                        dead_tmp(tmp2);
6610
                        if (insn & (1 << 22)) {
6611
                            /* Subtract (mls) */
6612
                            ARCH(6T2);
6613
                            tmp2 = load_reg(s, rn);
6614
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
6615
                            dead_tmp(tmp2);
6616
                        } else if (insn & (1 << 21)) {
6617
                            /* Add */
6618
                            tmp2 = load_reg(s, rn);
6619
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6620
                            dead_tmp(tmp2);
6621
                        }
6622
                        if (insn & (1 << 20))
6623
                            gen_logic_CC(tmp);
6624
                        store_reg(s, rd, tmp);
6625
                        break;
6626
                    default:
6627
                        /* 64 bit mul */
6628
                        tmp = load_reg(s, rs);
6629
                        tmp2 = load_reg(s, rm);
6630
                        if (insn & (1 << 22))
6631
                            tmp64 = gen_muls_i64_i32(tmp, tmp2);
6632
                        else
6633
                            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6634
                        if (insn & (1 << 21)) /* mult accumulate */
6635
                            gen_addq(s, tmp64, rn, rd);
6636
                        if (!(insn & (1 << 23))) { /* double accumulate */
6637
                            ARCH(6);
6638
                            gen_addq_lo(s, tmp64, rn);
6639
                            gen_addq_lo(s, tmp64, rd);
6640
                        }
6641
                        if (insn & (1 << 20))
6642
                            gen_logicq_cc(tmp64);
6643
                        gen_storeq_reg(s, rn, rd, tmp64);
6644
                        tcg_temp_free_i64(tmp64);
6645
                        break;
6646
                    }
6647
                } else {
6648
                    rn = (insn >> 16) & 0xf;
6649
                    rd = (insn >> 12) & 0xf;
6650
                    if (insn & (1 << 23)) {
6651
                        /* load/store exclusive */
6652
                        op1 = (insn >> 21) & 0x3;
6653
                        if (op1)
6654
                            ARCH(6K);
6655
                        else
6656
                            ARCH(6);
6657
                        addr = tcg_temp_local_new_i32();
6658
                        load_reg_var(s, addr, rn);
6659
                        if (insn & (1 << 20)) {
6660
                            switch (op1) {
6661
                            case 0: /* ldrex */
6662
                                gen_load_exclusive(s, rd, 15, addr, 2);
6663
                                break;
6664
                            case 1: /* ldrexd */
6665
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
6666
                                break;
6667
                            case 2: /* ldrexb */
6668
                                gen_load_exclusive(s, rd, 15, addr, 0);
6669
                                break;
6670
                            case 3: /* ldrexh */
6671
                                gen_load_exclusive(s, rd, 15, addr, 1);
6672
                                break;
6673
                            default:
6674
                                abort();
6675
                            }
6676
                        } else {
6677
                            rm = insn & 0xf;
6678
                            switch (op1) {
6679
                            case 0:  /*  strex */
6680
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
6681
                                break;
6682
                            case 1: /*  strexd */
6683
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
6684
                                break;
6685
                            case 2: /*  strexb */
6686
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
6687
                                break;
6688
                            case 3: /* strexh */
6689
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
6690
                                break;
6691
                            default:
6692
                                abort();
6693
                            }
6694
                        }
6695
                        tcg_temp_free(addr);
6696
                    } else {
6697
                        /* SWP instruction */
6698
                        rm = (insn) & 0xf;
6699

    
6700
                        /* ??? This is not really atomic.  However we know
6701
                           we never have multiple CPUs running in parallel,
6702
                           so it is good enough.  */
6703
                        addr = load_reg(s, rn);
6704
                        tmp = load_reg(s, rm);
6705
                        if (insn & (1 << 22)) {
6706
                            tmp2 = gen_ld8u(addr, IS_USER(s));
6707
                            gen_st8(tmp, addr, IS_USER(s));
6708
                        } else {
6709
                            tmp2 = gen_ld32(addr, IS_USER(s));
6710
                            gen_st32(tmp, addr, IS_USER(s));
6711
                        }
6712
                        dead_tmp(addr);
6713
                        store_reg(s, rd, tmp2);
6714
                    }
6715
                }
6716
            } else {
6717
                int address_offset;
6718
                int load;
6719
                /* Misc load/store */
6720
                rn = (insn >> 16) & 0xf;
6721
                rd = (insn >> 12) & 0xf;
6722
                addr = load_reg(s, rn);
6723
                if (insn & (1 << 24))
6724
                    gen_add_datah_offset(s, insn, 0, addr);
6725
                address_offset = 0;
6726
                if (insn & (1 << 20)) {
6727
                    /* load */
6728
                    switch(sh) {
6729
                    case 1:
6730
                        tmp = gen_ld16u(addr, IS_USER(s));
6731
                        break;
6732
                    case 2:
6733
                        tmp = gen_ld8s(addr, IS_USER(s));
6734
                        break;
6735
                    default:
6736
                    case 3:
6737
                        tmp = gen_ld16s(addr, IS_USER(s));
6738
                        break;
6739
                    }
6740
                    load = 1;
6741
                } else if (sh & 2) {
6742
                    /* doubleword */
6743
                    if (sh & 1) {
6744
                        /* store */
6745
                        tmp = load_reg(s, rd);
6746
                        gen_st32(tmp, addr, IS_USER(s));
6747
                        tcg_gen_addi_i32(addr, addr, 4);
6748
                        tmp = load_reg(s, rd + 1);
6749
                        gen_st32(tmp, addr, IS_USER(s));
6750
                        load = 0;
6751
                    } else {
6752
                        /* load */
6753
                        tmp = gen_ld32(addr, IS_USER(s));
6754
                        store_reg(s, rd, tmp);
6755
                        tcg_gen_addi_i32(addr, addr, 4);
6756
                        tmp = gen_ld32(addr, IS_USER(s));
6757
                        rd++;
6758
                        load = 1;
6759
                    }
6760
                    address_offset = -4;
6761
                } else {
6762
                    /* store */
6763
                    tmp = load_reg(s, rd);
6764
                    gen_st16(tmp, addr, IS_USER(s));
6765
                    load = 0;
6766
                }
6767
                /* Perform base writeback before the loaded value to
6768
                   ensure correct behavior with overlapping index registers.
6769
                   ldrd with base writeback is is undefined if the
6770
                   destination and index registers overlap.  */
6771
                if (!(insn & (1 << 24))) {
6772
                    gen_add_datah_offset(s, insn, address_offset, addr);
6773
                    store_reg(s, rn, addr);
6774
                } else if (insn & (1 << 21)) {
6775
                    if (address_offset)
6776
                        tcg_gen_addi_i32(addr, addr, address_offset);
6777
                    store_reg(s, rn, addr);
6778
                } else {
6779
                    dead_tmp(addr);
6780
                }
6781
                if (load) {
6782
                    /* Complete the load.  */
6783
                    store_reg(s, rd, tmp);
6784
                }
6785
            }
6786
            break;
6787
        case 0x4:
6788
        case 0x5:
6789
            goto do_ldst;
6790
        case 0x6:
6791
        case 0x7:
6792
            if (insn & (1 << 4)) {
6793
                ARCH(6);
6794
                /* Armv6 Media instructions.  */
6795
                rm = insn & 0xf;
6796
                rn = (insn >> 16) & 0xf;
6797
                rd = (insn >> 12) & 0xf;
6798
                rs = (insn >> 8) & 0xf;
6799
                switch ((insn >> 23) & 3) {
6800
                case 0: /* Parallel add/subtract.  */
6801
                    op1 = (insn >> 20) & 7;
6802
                    tmp = load_reg(s, rn);
6803
                    tmp2 = load_reg(s, rm);
6804
                    sh = (insn >> 5) & 7;
6805
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6806
                        goto illegal_op;
6807
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6808
                    dead_tmp(tmp2);
6809
                    store_reg(s, rd, tmp);
6810
                    break;
6811
                case 1:
6812
                    if ((insn & 0x00700020) == 0) {
6813
                        /* Halfword pack.  */
6814
                        tmp = load_reg(s, rn);
6815
                        tmp2 = load_reg(s, rm);
6816
                        shift = (insn >> 7) & 0x1f;
6817
                        if (insn & (1 << 6)) {
6818
                            /* pkhtb */
6819
                            if (shift == 0)
6820
                                shift = 31;
6821
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
6822
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6823
                            tcg_gen_ext16u_i32(tmp2, tmp2);
6824
                        } else {
6825
                            /* pkhbt */
6826
                            if (shift)
6827
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
6828
                            tcg_gen_ext16u_i32(tmp, tmp);
6829
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6830
                        }
6831
                        tcg_gen_or_i32(tmp, tmp, tmp2);
6832
                        dead_tmp(tmp2);
6833
                        store_reg(s, rd, tmp);
6834
                    } else if ((insn & 0x00200020) == 0x00200000) {
6835
                        /* [us]sat */
6836
                        tmp = load_reg(s, rm);
6837
                        shift = (insn >> 7) & 0x1f;
6838
                        if (insn & (1 << 6)) {
6839
                            if (shift == 0)
6840
                                shift = 31;
6841
                            tcg_gen_sari_i32(tmp, tmp, shift);
6842
                        } else {
6843
                            tcg_gen_shli_i32(tmp, tmp, shift);
6844
                        }
6845
                        sh = (insn >> 16) & 0x1f;
6846
                        if (sh != 0) {
6847
                            tmp2 = tcg_const_i32(sh);
6848
                            if (insn & (1 << 22))
6849
                                gen_helper_usat(tmp, tmp, tmp2);
6850
                            else
6851
                                gen_helper_ssat(tmp, tmp, tmp2);
6852
                            tcg_temp_free_i32(tmp2);
6853
                        }
6854
                        store_reg(s, rd, tmp);
6855
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
6856
                        /* [us]sat16 */
6857
                        tmp = load_reg(s, rm);
6858
                        sh = (insn >> 16) & 0x1f;
6859
                        if (sh != 0) {
6860
                            tmp2 = tcg_const_i32(sh);
6861
                            if (insn & (1 << 22))
6862
                                gen_helper_usat16(tmp, tmp, tmp2);
6863
                            else
6864
                                gen_helper_ssat16(tmp, tmp, tmp2);
6865
                            tcg_temp_free_i32(tmp2);
6866
                        }
6867
                        store_reg(s, rd, tmp);
6868
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6869
                        /* Select bytes.  */
6870
                        tmp = load_reg(s, rn);
6871
                        tmp2 = load_reg(s, rm);
6872
                        tmp3 = new_tmp();
6873
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6874
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6875
                        dead_tmp(tmp3);
6876
                        dead_tmp(tmp2);
6877
                        store_reg(s, rd, tmp);
6878
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6879
                        tmp = load_reg(s, rm);
6880
                        shift = (insn >> 10) & 3;
6881
                        /* ??? In many cases it's not neccessary to do a
6882
                           rotate, a shift is sufficient.  */
6883
                        if (shift != 0)
6884
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
6885
                        op1 = (insn >> 20) & 7;
6886
                        switch (op1) {
6887
                        case 0: gen_sxtb16(tmp);  break;
6888
                        case 2: gen_sxtb(tmp);    break;
6889
                        case 3: gen_sxth(tmp);    break;
6890
                        case 4: gen_uxtb16(tmp);  break;
6891
                        case 6: gen_uxtb(tmp);    break;
6892
                        case 7: gen_uxth(tmp);    break;
6893
                        default: goto illegal_op;
6894
                        }
6895
                        if (rn != 15) {
6896
                            tmp2 = load_reg(s, rn);
6897
                            if ((op1 & 3) == 0) {
6898
                                gen_add16(tmp, tmp2);
6899
                            } else {
6900
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6901
                                dead_tmp(tmp2);
6902
                            }
6903
                        }
6904
                        store_reg(s, rd, tmp);
6905
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6906
                        /* rev */
6907
                        tmp = load_reg(s, rm);
6908
                        if (insn & (1 << 22)) {
6909
                            if (insn & (1 << 7)) {
6910
                                gen_revsh(tmp);
6911
                            } else {
6912
                                ARCH(6T2);
6913
                                gen_helper_rbit(tmp, tmp);
6914
                            }
6915
                        } else {
6916
                            if (insn & (1 << 7))
6917
                                gen_rev16(tmp);
6918
                            else
6919
                                tcg_gen_bswap32_i32(tmp, tmp);
6920
                        }
6921
                        store_reg(s, rd, tmp);
6922
                    } else {
6923
                        goto illegal_op;
6924
                    }
6925
                    break;
6926
                case 2: /* Multiplies (Type 3).  */
6927
                    tmp = load_reg(s, rm);
6928
                    tmp2 = load_reg(s, rs);
6929
                    if (insn & (1 << 20)) {
6930
                        /* Signed multiply most significant [accumulate].  */
6931
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
6932
                        if (insn & (1 << 5))
6933
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
6934
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
6935
                        tmp = new_tmp();
6936
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
6937
                        tcg_temp_free_i64(tmp64);
6938
                        if (rd != 15) {
6939
                            tmp2 = load_reg(s, rd);
6940
                            if (insn & (1 << 6)) {
6941
                                tcg_gen_sub_i32(tmp, tmp, tmp2);
6942
                            } else {
6943
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6944
                            }
6945
                            dead_tmp(tmp2);
6946
                        }
6947
                        store_reg(s, rn, tmp);
6948
                    } else {
6949
                        if (insn & (1 << 5))
6950
                            gen_swap_half(tmp2);
6951
                        gen_smul_dual(tmp, tmp2);
6952
                        /* This addition cannot overflow.  */
6953
                        if (insn & (1 << 6)) {
6954
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
6955
                        } else {
6956
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6957
                        }
6958
                        dead_tmp(tmp2);
6959
                        if (insn & (1 << 22)) {
6960
                            /* smlald, smlsld */
6961
                            tmp64 = tcg_temp_new_i64();
6962
                            tcg_gen_ext_i32_i64(tmp64, tmp);
6963
                            dead_tmp(tmp);
6964
                            gen_addq(s, tmp64, rd, rn);
6965
                            gen_storeq_reg(s, rd, rn, tmp64);
6966
                            tcg_temp_free_i64(tmp64);
6967
                        } else {
6968
                            /* smuad, smusd, smlad, smlsd */
6969
                            if (rd != 15)
6970
                              {
6971
                                tmp2 = load_reg(s, rd);
6972
                                gen_helper_add_setq(tmp, tmp, tmp2);
6973
                                dead_tmp(tmp2);
6974
                              }
6975
                            store_reg(s, rn, tmp);
6976
                        }
6977
                    }
6978
                    break;
6979
                case 3:
6980
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6981
                    switch (op1) {
6982
                    case 0: /* Unsigned sum of absolute differences.  */
6983
                        ARCH(6);
6984
                        tmp = load_reg(s, rm);
6985
                        tmp2 = load_reg(s, rs);
6986
                        gen_helper_usad8(tmp, tmp, tmp2);
6987
                        dead_tmp(tmp2);
6988
                        if (rd != 15) {
6989
                            tmp2 = load_reg(s, rd);
6990
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6991
                            dead_tmp(tmp2);
6992
                        }
6993
                        store_reg(s, rn, tmp);
6994
                        break;
6995
                    case 0x20: case 0x24: case 0x28: case 0x2c:
6996
                        /* Bitfield insert/clear.  */
6997
                        ARCH(6T2);
6998
                        shift = (insn >> 7) & 0x1f;
6999
                        i = (insn >> 16) & 0x1f;
7000
                        i = i + 1 - shift;
7001
                        if (rm == 15) {
7002
                            tmp = new_tmp();
7003
                            tcg_gen_movi_i32(tmp, 0);
7004
                        } else {
7005
                            tmp = load_reg(s, rm);
7006
                        }
7007
                        if (i != 32) {
7008
                            tmp2 = load_reg(s, rd);
7009
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
7010
                            dead_tmp(tmp2);
7011
                        }
7012
                        store_reg(s, rd, tmp);
7013
                        break;
7014
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7015
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7016
                        ARCH(6T2);
7017
                        tmp = load_reg(s, rm);
7018
                        shift = (insn >> 7) & 0x1f;
7019
                        i = ((insn >> 16) & 0x1f) + 1;
7020
                        if (shift + i > 32)
7021
                            goto illegal_op;
7022
                        if (i < 32) {
7023
                            if (op1 & 0x20) {
7024
                                gen_ubfx(tmp, shift, (1u << i) - 1);
7025
                            } else {
7026
                                gen_sbfx(tmp, shift, i);
7027
                            }
7028
                        }
7029
                        store_reg(s, rd, tmp);
7030
                        break;
7031
                    default:
7032
                        goto illegal_op;
7033
                    }
7034
                    break;
7035
                }
7036
                break;
7037
            }
7038
        do_ldst:
7039
            /* Check for undefined extension instructions
7040
             * per the ARM Bible IE:
7041
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
7042
             */
7043
            sh = (0xf << 20) | (0xf << 4);
7044
            if (op1 == 0x7 && ((insn & sh) == sh))
7045
            {
7046
                goto illegal_op;
7047
            }
7048
            /* load/store byte/word */
7049
            rn = (insn >> 16) & 0xf;
7050
            rd = (insn >> 12) & 0xf;
7051
            tmp2 = load_reg(s, rn);
7052
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7053
            if (insn & (1 << 24))
7054
                gen_add_data_offset(s, insn, tmp2);
7055
            if (insn & (1 << 20)) {
7056
                /* load */
7057
                if (insn & (1 << 22)) {
7058
                    tmp = gen_ld8u(tmp2, i);
7059
                } else {
7060
                    tmp = gen_ld32(tmp2, i);
7061
                }
7062
            } else {
7063
                /* store */
7064
                tmp = load_reg(s, rd);
7065
                if (insn & (1 << 22))
7066
                    gen_st8(tmp, tmp2, i);
7067
                else
7068
                    gen_st32(tmp, tmp2, i);
7069
            }
7070
            if (!(insn & (1 << 24))) {
7071
                gen_add_data_offset(s, insn, tmp2);
7072
                store_reg(s, rn, tmp2);
7073
            } else if (insn & (1 << 21)) {
7074
                store_reg(s, rn, tmp2);
7075
            } else {
7076
                dead_tmp(tmp2);
7077
            }
7078
            if (insn & (1 << 20)) {
7079
                /* Complete the load.  */
7080
                if (rd == 15)
7081
                    gen_bx(s, tmp);
7082
                else
7083
                    store_reg(s, rd, tmp);
7084
            }
7085
            break;
7086
        case 0x08:
7087
        case 0x09:
7088
            {
7089
                int j, n, user, loaded_base;
7090
                TCGv loaded_var;
7091
                /* load/store multiple words */
7092
                /* XXX: store correct base if write back */
7093
                user = 0;
7094
                if (insn & (1 << 22)) {
7095
                    if (IS_USER(s))
7096
                        goto illegal_op; /* only usable in supervisor mode */
7097

    
7098
                    if ((insn & (1 << 15)) == 0)
7099
                        user = 1;
7100
                }
7101
                rn = (insn >> 16) & 0xf;
7102
                addr = load_reg(s, rn);
7103

    
7104
                /* compute total size */
7105
                loaded_base = 0;
7106
                TCGV_UNUSED(loaded_var);
7107
                n = 0;
7108
                for(i=0;i<16;i++) {
7109
                    if (insn & (1 << i))
7110
                        n++;
7111
                }
7112
                /* XXX: test invalid n == 0 case ? */
7113
                if (insn & (1 << 23)) {
7114
                    if (insn & (1 << 24)) {
7115
                        /* pre increment */
7116
                        tcg_gen_addi_i32(addr, addr, 4);
7117
                    } else {
7118
                        /* post increment */
7119
                    }
7120
                } else {
7121
                    if (insn & (1 << 24)) {
7122
                        /* pre decrement */
7123
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
7124
                    } else {
7125
                        /* post decrement */
7126
                        if (n != 1)
7127
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7128
                    }
7129
                }
7130
                j = 0;
7131
                for(i=0;i<16;i++) {
7132
                    if (insn & (1 << i)) {
7133
                        if (insn & (1 << 20)) {
7134
                            /* load */
7135
                            tmp = gen_ld32(addr, IS_USER(s));
7136
                            if (i == 15) {
7137
                                gen_bx(s, tmp);
7138
                            } else if (user) {
7139
                                tmp2 = tcg_const_i32(i);
7140
                                gen_helper_set_user_reg(tmp2, tmp);
7141
                                tcg_temp_free_i32(tmp2);
7142
                                dead_tmp(tmp);
7143
                            } else if (i == rn) {
7144
                                loaded_var = tmp;
7145
                                loaded_base = 1;
7146
                            } else {
7147
                                store_reg(s, i, tmp);
7148
                            }
7149
                        } else {
7150
                            /* store */
7151
                            if (i == 15) {
7152
                                /* special case: r15 = PC + 8 */
7153
                                val = (long)s->pc + 4;
7154
                                tmp = new_tmp();
7155
                                tcg_gen_movi_i32(tmp, val);
7156
                            } else if (user) {
7157
                                tmp = new_tmp();
7158
                                tmp2 = tcg_const_i32(i);
7159
                                gen_helper_get_user_reg(tmp, tmp2);
7160
                                tcg_temp_free_i32(tmp2);
7161
                            } else {
7162
                                tmp = load_reg(s, i);
7163
                            }
7164
                            gen_st32(tmp, addr, IS_USER(s));
7165
                        }
7166
                        j++;
7167
                        /* no need to add after the last transfer */
7168
                        if (j != n)
7169
                            tcg_gen_addi_i32(addr, addr, 4);
7170
                    }
7171
                }
7172
                if (insn & (1 << 21)) {
7173
                    /* write back */
7174
                    if (insn & (1 << 23)) {
7175
                        if (insn & (1 << 24)) {
7176
                            /* pre increment */
7177
                        } else {
7178
                            /* post increment */
7179
                            tcg_gen_addi_i32(addr, addr, 4);
7180
                        }
7181
                    } else {
7182
                        if (insn & (1 << 24)) {
7183
                            /* pre decrement */
7184
                            if (n != 1)
7185
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7186
                        } else {
7187
                            /* post decrement */
7188
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
7189
                        }
7190
                    }
7191
                    store_reg(s, rn, addr);
7192
                } else {
7193
                    dead_tmp(addr);
7194
                }
7195
                if (loaded_base) {
7196
                    store_reg(s, rn, loaded_var);
7197
                }
7198
                if ((insn & (1 << 22)) && !user) {
7199
                    /* Restore CPSR from SPSR.  */
7200
                    tmp = load_cpu_field(spsr);
7201
                    gen_set_cpsr(tmp, 0xffffffff);
7202
                    dead_tmp(tmp);
7203
                    s->is_jmp = DISAS_UPDATE;
7204
                }
7205
            }
7206
            break;
7207
        case 0xa:
7208
        case 0xb:
7209
            {
7210
                int32_t offset;
7211

    
7212
                /* branch (and link) */
7213
                val = (int32_t)s->pc;
7214
                if (insn & (1 << 24)) {
7215
                    tmp = new_tmp();
7216
                    tcg_gen_movi_i32(tmp, val);
7217
                    store_reg(s, 14, tmp);
7218
                }
7219
                offset = (((int32_t)insn << 8) >> 8);
7220
                val += (offset << 2) + 4;
7221
                gen_jmp(s, val);
7222
            }
7223
            break;
7224
        case 0xc:
7225
        case 0xd:
7226
        case 0xe:
7227
            /* Coprocessor.  */
7228
            if (disas_coproc_insn(env, s, insn))
7229
                goto illegal_op;
7230
            break;
7231
        case 0xf:
7232
            /* swi */
7233
            gen_set_pc_im(s->pc);
7234
            s->is_jmp = DISAS_SWI;
7235
            break;
7236
        default:
7237
        illegal_op:
7238
            gen_set_condexec(s);
7239
            gen_set_pc_im(s->pc - 4);
7240
            gen_exception(EXCP_UDEF);
7241
            s->is_jmp = DISAS_JUMP;
7242
            break;
7243
        }
7244
    }
7245
}
7246

    
7247
/* Return true if this is a Thumb-2 logical op.  */
7248
static int
7249
thumb2_logic_op(int op)
7250
{
7251
    return (op < 8);
7252
}
7253

    
7254
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7255
   then set condition code flags based on the result of the operation.
7256
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7257
   to the high bit of T1.
7258
   Returns zero if the opcode is valid.  */
7259

    
7260
static int
7261
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7262
{
7263
    int logic_cc;
7264

    
7265
    logic_cc = 0;
7266
    switch (op) {
7267
    case 0: /* and */
7268
        tcg_gen_and_i32(t0, t0, t1);
7269
        logic_cc = conds;
7270
        break;
7271
    case 1: /* bic */
7272
        tcg_gen_andc_i32(t0, t0, t1);
7273
        logic_cc = conds;
7274
        break;
7275
    case 2: /* orr */
7276
        tcg_gen_or_i32(t0, t0, t1);
7277
        logic_cc = conds;
7278
        break;
7279
    case 3: /* orn */
7280
        tcg_gen_not_i32(t1, t1);
7281
        tcg_gen_or_i32(t0, t0, t1);
7282
        logic_cc = conds;
7283
        break;
7284
    case 4: /* eor */
7285
        tcg_gen_xor_i32(t0, t0, t1);
7286
        logic_cc = conds;
7287
        break;
7288
    case 8: /* add */
7289
        if (conds)
7290
            gen_helper_add_cc(t0, t0, t1);
7291
        else
7292
            tcg_gen_add_i32(t0, t0, t1);
7293
        break;
7294
    case 10: /* adc */
7295
        if (conds)
7296
            gen_helper_adc_cc(t0, t0, t1);
7297
        else
7298
            gen_adc(t0, t1);
7299
        break;
7300
    case 11: /* sbc */
7301
        if (conds)
7302
            gen_helper_sbc_cc(t0, t0, t1);
7303
        else
7304
            gen_sub_carry(t0, t0, t1);
7305
        break;
7306
    case 13: /* sub */
7307
        if (conds)
7308
            gen_helper_sub_cc(t0, t0, t1);
7309
        else
7310
            tcg_gen_sub_i32(t0, t0, t1);
7311
        break;
7312
    case 14: /* rsb */
7313
        if (conds)
7314
            gen_helper_sub_cc(t0, t1, t0);
7315
        else
7316
            tcg_gen_sub_i32(t0, t1, t0);
7317
        break;
7318
    default: /* 5, 6, 7, 9, 12, 15. */
7319
        return 1;
7320
    }
7321
    if (logic_cc) {
7322
        gen_logic_CC(t0);
7323
        if (shifter_out)
7324
            gen_set_CF_bit31(t1);
7325
    }
7326
    return 0;
7327
}
7328

    
7329
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7330
   is not legal.  */
7331
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7332
{
7333
    uint32_t insn, imm, shift, offset;
7334
    uint32_t rd, rn, rm, rs;
7335
    TCGv tmp;
7336
    TCGv tmp2;
7337
    TCGv tmp3;
7338
    TCGv addr;
7339
    TCGv_i64 tmp64;
7340
    int op;
7341
    int shiftop;
7342
    int conds;
7343
    int logic_cc;
7344

    
7345
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7346
          || arm_feature (env, ARM_FEATURE_M))) {
7347
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7348
           16-bit instructions to get correct prefetch abort behavior.  */
7349
        insn = insn_hw1;
7350
        if ((insn & (1 << 12)) == 0) {
7351
            /* Second half of blx.  */
7352
            offset = ((insn & 0x7ff) << 1);
7353
            tmp = load_reg(s, 14);
7354
            tcg_gen_addi_i32(tmp, tmp, offset);
7355
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7356

    
7357
            tmp2 = new_tmp();
7358
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7359
            store_reg(s, 14, tmp2);
7360
            gen_bx(s, tmp);
7361
            return 0;
7362
        }
7363
        if (insn & (1 << 11)) {
7364
            /* Second half of bl.  */
7365
            offset = ((insn & 0x7ff) << 1) | 1;
7366
            tmp = load_reg(s, 14);
7367
            tcg_gen_addi_i32(tmp, tmp, offset);
7368

    
7369
            tmp2 = new_tmp();
7370
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7371
            store_reg(s, 14, tmp2);
7372
            gen_bx(s, tmp);
7373
            return 0;
7374
        }
7375
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7376
            /* Instruction spans a page boundary.  Implement it as two
7377
               16-bit instructions in case the second half causes an
7378
               prefetch abort.  */
7379
            offset = ((int32_t)insn << 21) >> 9;
7380
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7381
            return 0;
7382
        }
7383
        /* Fall through to 32-bit decode.  */
7384
    }
7385

    
7386
    insn = lduw_code(s->pc);
7387
    s->pc += 2;
7388
    insn |= (uint32_t)insn_hw1 << 16;
7389

    
7390
    if ((insn & 0xf800e800) != 0xf000e800) {
7391
        ARCH(6T2);
7392
    }
7393

    
7394
    rn = (insn >> 16) & 0xf;
7395
    rs = (insn >> 12) & 0xf;
7396
    rd = (insn >> 8) & 0xf;
7397
    rm = insn & 0xf;
7398
    switch ((insn >> 25) & 0xf) {
7399
    case 0: case 1: case 2: case 3:
7400
        /* 16-bit instructions.  Should never happen.  */
7401
        abort();
7402
    case 4:
7403
        if (insn & (1 << 22)) {
7404
            /* Other load/store, table branch.  */
7405
            if (insn & 0x01200000) {
7406
                /* Load/store doubleword.  */
7407
                if (rn == 15) {
7408
                    addr = new_tmp();
7409
                    tcg_gen_movi_i32(addr, s->pc & ~3);
7410
                } else {
7411
                    addr = load_reg(s, rn);
7412
                }
7413
                offset = (insn & 0xff) * 4;
7414
                if ((insn & (1 << 23)) == 0)
7415
                    offset = -offset;
7416
                if (insn & (1 << 24)) {
7417
                    tcg_gen_addi_i32(addr, addr, offset);
7418
                    offset = 0;
7419
                }
7420
                if (insn & (1 << 20)) {
7421
                    /* ldrd */
7422
                    tmp = gen_ld32(addr, IS_USER(s));
7423
                    store_reg(s, rs, tmp);
7424
                    tcg_gen_addi_i32(addr, addr, 4);
7425
                    tmp = gen_ld32(addr, IS_USER(s));
7426
                    store_reg(s, rd, tmp);
7427
                } else {
7428
                    /* strd */
7429
                    tmp = load_reg(s, rs);
7430
                    gen_st32(tmp, addr, IS_USER(s));
7431
                    tcg_gen_addi_i32(addr, addr, 4);
7432
                    tmp = load_reg(s, rd);
7433
                    gen_st32(tmp, addr, IS_USER(s));
7434
                }
7435
                if (insn & (1 << 21)) {
7436
                    /* Base writeback.  */
7437
                    if (rn == 15)
7438
                        goto illegal_op;
7439
                    tcg_gen_addi_i32(addr, addr, offset - 4);
7440
                    store_reg(s, rn, addr);
7441
                } else {
7442
                    dead_tmp(addr);
7443
                }
7444
            } else if ((insn & (1 << 23)) == 0) {
7445
                /* Load/store exclusive word.  */
7446
                addr = tcg_temp_local_new();
7447
                load_reg_var(s, addr, rn);
7448
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
7449
                if (insn & (1 << 20)) {
7450
                    gen_load_exclusive(s, rs, 15, addr, 2);
7451
                } else {
7452
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
7453
                }
7454
                tcg_temp_free(addr);
7455
            } else if ((insn & (1 << 6)) == 0) {
7456
                /* Table Branch.  */
7457
                if (rn == 15) {
7458
                    addr = new_tmp();
7459
                    tcg_gen_movi_i32(addr, s->pc);
7460
                } else {
7461
                    addr = load_reg(s, rn);
7462
                }
7463
                tmp = load_reg(s, rm);
7464
                tcg_gen_add_i32(addr, addr, tmp);
7465
                if (insn & (1 << 4)) {
7466
                    /* tbh */
7467
                    tcg_gen_add_i32(addr, addr, tmp);
7468
                    dead_tmp(tmp);
7469
                    tmp = gen_ld16u(addr, IS_USER(s));
7470
                } else { /* tbb */
7471
                    dead_tmp(tmp);
7472
                    tmp = gen_ld8u(addr, IS_USER(s));
7473
                }
7474
                dead_tmp(addr);
7475
                tcg_gen_shli_i32(tmp, tmp, 1);
7476
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7477
                store_reg(s, 15, tmp);
7478
            } else {
7479
                /* Load/store exclusive byte/halfword/doubleword.  */
7480
                ARCH(7);
7481
                op = (insn >> 4) & 0x3;
7482
                if (op == 2) {
7483
                    goto illegal_op;
7484
                }
7485
                addr = tcg_temp_local_new();
7486
                load_reg_var(s, addr, rn);
7487
                if (insn & (1 << 20)) {
7488
                    gen_load_exclusive(s, rs, rd, addr, op);
7489
                } else {
7490
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
7491
                }
7492
                tcg_temp_free(addr);
7493
            }
7494
        } else {
7495
            /* Load/store multiple, RFE, SRS.  */
7496
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7497
                /* Not available in user mode.  */
7498
                if (IS_USER(s))
7499
                    goto illegal_op;
7500
                if (insn & (1 << 20)) {
7501
                    /* rfe */
7502
                    addr = load_reg(s, rn);
7503
                    if ((insn & (1 << 24)) == 0)
7504
                        tcg_gen_addi_i32(addr, addr, -8);
7505
                    /* Load PC into tmp and CPSR into tmp2.  */
7506
                    tmp = gen_ld32(addr, 0);
7507
                    tcg_gen_addi_i32(addr, addr, 4);
7508
                    tmp2 = gen_ld32(addr, 0);
7509
                    if (insn & (1 << 21)) {
7510
                        /* Base writeback.  */
7511
                        if (insn & (1 << 24)) {
7512
                            tcg_gen_addi_i32(addr, addr, 4);
7513
                        } else {
7514
                            tcg_gen_addi_i32(addr, addr, -4);
7515
                        }
7516
                        store_reg(s, rn, addr);
7517
                    } else {
7518
                        dead_tmp(addr);
7519
                    }
7520
                    gen_rfe(s, tmp, tmp2);
7521
                } else {
7522
                    /* srs */
7523
                    op = (insn & 0x1f);
7524
                    if (op == (env->uncached_cpsr & CPSR_M)) {
7525
                        addr = load_reg(s, 13);
7526
                    } else {
7527
                        addr = new_tmp();
7528
                        tmp = tcg_const_i32(op);
7529
                        gen_helper_get_r13_banked(addr, cpu_env, tmp);
7530
                        tcg_temp_free_i32(tmp);
7531
                    }
7532
                    if ((insn & (1 << 24)) == 0) {
7533
                        tcg_gen_addi_i32(addr, addr, -8);
7534
                    }
7535
                    tmp = load_reg(s, 14);
7536
                    gen_st32(tmp, addr, 0);
7537
                    tcg_gen_addi_i32(addr, addr, 4);
7538
                    tmp = new_tmp();
7539
                    gen_helper_cpsr_read(tmp);
7540
                    gen_st32(tmp, addr, 0);
7541
                    if (insn & (1 << 21)) {
7542
                        if ((insn & (1 << 24)) == 0) {
7543
                            tcg_gen_addi_i32(addr, addr, -4);
7544
                        } else {
7545
                            tcg_gen_addi_i32(addr, addr, 4);
7546
                        }
7547
                        if (op == (env->uncached_cpsr & CPSR_M)) {
7548
                            store_reg(s, 13, addr);
7549
                        } else {
7550
                            tmp = tcg_const_i32(op);
7551
                            gen_helper_set_r13_banked(cpu_env, tmp, addr);
7552
                            tcg_temp_free_i32(tmp);
7553
                        }
7554
                    } else {
7555
                        dead_tmp(addr);
7556
                    }
7557
                }
7558
            } else {
7559
                int i;
7560
                /* Load/store multiple.  */
7561
                addr = load_reg(s, rn);
7562
                offset = 0;
7563
                for (i = 0; i < 16; i++) {
7564
                    if (insn & (1 << i))
7565
                        offset += 4;
7566
                }
7567
                if (insn & (1 << 24)) {
7568
                    tcg_gen_addi_i32(addr, addr, -offset);
7569
                }
7570

    
7571
                for (i = 0; i < 16; i++) {
7572
                    if ((insn & (1 << i)) == 0)
7573
                        continue;
7574
                    if (insn & (1 << 20)) {
7575
                        /* Load.  */
7576
                        tmp = gen_ld32(addr, IS_USER(s));
7577
                        if (i == 15) {
7578
                            gen_bx(s, tmp);
7579
                        } else {
7580
                            store_reg(s, i, tmp);
7581
                        }
7582
                    } else {
7583
                        /* Store.  */
7584
                        tmp = load_reg(s, i);
7585
                        gen_st32(tmp, addr, IS_USER(s));
7586
                    }
7587
                    tcg_gen_addi_i32(addr, addr, 4);
7588
                }
7589
                if (insn & (1 << 21)) {
7590
                    /* Base register writeback.  */
7591
                    if (insn & (1 << 24)) {
7592
                        tcg_gen_addi_i32(addr, addr, -offset);
7593
                    }
7594
                    /* Fault if writeback register is in register list.  */
7595
                    if (insn & (1 << rn))
7596
                        goto illegal_op;
7597
                    store_reg(s, rn, addr);
7598
                } else {
7599
                    dead_tmp(addr);
7600
                }
7601
            }
7602
        }
7603
        break;
7604
    case 5: /* Data processing register constant shift.  */
7605
        if (rn == 15) {
7606
            tmp = new_tmp();
7607
            tcg_gen_movi_i32(tmp, 0);
7608
        } else {
7609
            tmp = load_reg(s, rn);
7610
        }
7611
        tmp2 = load_reg(s, rm);
7612
        op = (insn >> 21) & 0xf;
7613
        shiftop = (insn >> 4) & 3;
7614
        shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7615
        conds = (insn & (1 << 20)) != 0;
7616
        logic_cc = (conds && thumb2_logic_op(op));
7617
        gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7618
        if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
7619
            goto illegal_op;
7620
        dead_tmp(tmp2);
7621
        if (rd != 15) {
7622
            store_reg(s, rd, tmp);
7623
        } else {
7624
            dead_tmp(tmp);
7625
        }
7626
        break;
7627
    case 13: /* Misc data processing.  */
7628
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7629
        if (op < 4 && (insn & 0xf000) != 0xf000)
7630
            goto illegal_op;
7631
        switch (op) {
7632
        case 0: /* Register controlled shift.  */
7633
            tmp = load_reg(s, rn);
7634
            tmp2 = load_reg(s, rm);
7635
            if ((insn & 0x70) != 0)
7636
                goto illegal_op;
7637
            op = (insn >> 21) & 3;
7638
            logic_cc = (insn & (1 << 20)) != 0;
7639
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7640
            if (logic_cc)
7641
                gen_logic_CC(tmp);
7642
            store_reg_bx(env, s, rd, tmp);
7643
            break;
7644
        case 1: /* Sign/zero extend.  */
7645
            tmp = load_reg(s, rm);
7646
            shift = (insn >> 4) & 3;
7647
            /* ??? In many cases it's not neccessary to do a
7648
               rotate, a shift is sufficient.  */
7649
            if (shift != 0)
7650
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7651
            op = (insn >> 20) & 7;
7652
            switch (op) {
7653
            case 0: gen_sxth(tmp);   break;
7654
            case 1: gen_uxth(tmp);   break;
7655
            case 2: gen_sxtb16(tmp); break;
7656
            case 3: gen_uxtb16(tmp); break;
7657
            case 4: gen_sxtb(tmp);   break;
7658
            case 5: gen_uxtb(tmp);   break;
7659
            default: goto illegal_op;
7660
            }
7661
            if (rn != 15) {
7662
                tmp2 = load_reg(s, rn);
7663
                if ((op >> 1) == 1) {
7664
                    gen_add16(tmp, tmp2);
7665
                } else {
7666
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7667
                    dead_tmp(tmp2);
7668
                }
7669
            }
7670
            store_reg(s, rd, tmp);
7671
            break;
7672
        case 2: /* SIMD add/subtract.  */
7673
            op = (insn >> 20) & 7;
7674
            shift = (insn >> 4) & 7;
7675
            if ((op & 3) == 3 || (shift & 3) == 3)
7676
                goto illegal_op;
7677
            tmp = load_reg(s, rn);
7678
            tmp2 = load_reg(s, rm);
7679
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7680
            dead_tmp(tmp2);
7681
            store_reg(s, rd, tmp);
7682
            break;
7683
        case 3: /* Other data processing.  */
7684
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7685
            if (op < 4) {
7686
                /* Saturating add/subtract.  */
7687
                tmp = load_reg(s, rn);
7688
                tmp2 = load_reg(s, rm);
7689
                if (op & 2)
7690
                    gen_helper_double_saturate(tmp, tmp);
7691
                if (op & 1)
7692
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7693
                else
7694
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7695
                dead_tmp(tmp2);
7696
            } else {
7697
                tmp = load_reg(s, rn);
7698
                switch (op) {
7699
                case 0x0a: /* rbit */
7700
                    gen_helper_rbit(tmp, tmp);
7701
                    break;
7702
                case 0x08: /* rev */
7703
                    tcg_gen_bswap32_i32(tmp, tmp);
7704
                    break;
7705
                case 0x09: /* rev16 */
7706
                    gen_rev16(tmp);
7707
                    break;
7708
                case 0x0b: /* revsh */
7709
                    gen_revsh(tmp);
7710
                    break;
7711
                case 0x10: /* sel */
7712
                    tmp2 = load_reg(s, rm);
7713
                    tmp3 = new_tmp();
7714
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7715
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7716
                    dead_tmp(tmp3);
7717
                    dead_tmp(tmp2);
7718
                    break;
7719
                case 0x18: /* clz */
7720
                    gen_helper_clz(tmp, tmp);
7721
                    break;
7722
                default:
7723
                    goto illegal_op;
7724
                }
7725
            }
7726
            store_reg(s, rd, tmp);
7727
            break;
7728
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7729
            op = (insn >> 4) & 0xf;
7730
            tmp = load_reg(s, rn);
7731
            tmp2 = load_reg(s, rm);
7732
            switch ((insn >> 20) & 7) {
7733
            case 0: /* 32 x 32 -> 32 */
7734
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7735
                dead_tmp(tmp2);
7736
                if (rs != 15) {
7737
                    tmp2 = load_reg(s, rs);
7738
                    if (op)
7739
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7740
                    else
7741
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7742
                    dead_tmp(tmp2);
7743
                }
7744
                break;
7745
            case 1: /* 16 x 16 -> 32 */
7746
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7747
                dead_tmp(tmp2);
7748
                if (rs != 15) {
7749
                    tmp2 = load_reg(s, rs);
7750
                    gen_helper_add_setq(tmp, tmp, tmp2);
7751
                    dead_tmp(tmp2);
7752
                }
7753
                break;
7754
            case 2: /* Dual multiply add.  */
7755
            case 4: /* Dual multiply subtract.  */
7756
                if (op)
7757
                    gen_swap_half(tmp2);
7758
                gen_smul_dual(tmp, tmp2);
7759
                /* This addition cannot overflow.  */
7760
                if (insn & (1 << 22)) {
7761
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7762
                } else {
7763
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7764
                }
7765
                dead_tmp(tmp2);
7766
                if (rs != 15)
7767
                  {
7768
                    tmp2 = load_reg(s, rs);
7769
                    gen_helper_add_setq(tmp, tmp, tmp2);
7770
                    dead_tmp(tmp2);
7771
                  }
7772
                break;
7773
            case 3: /* 32 * 16 -> 32msb */
7774
                if (op)
7775
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7776
                else
7777
                    gen_sxth(tmp2);
7778
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7779
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7780
                tmp = new_tmp();
7781
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7782
                tcg_temp_free_i64(tmp64);
7783
                if (rs != 15)
7784
                  {
7785
                    tmp2 = load_reg(s, rs);
7786
                    gen_helper_add_setq(tmp, tmp, tmp2);
7787
                    dead_tmp(tmp2);
7788
                  }
7789
                break;
7790
            case 5: case 6: /* 32 * 32 -> 32msb */
7791
                gen_imull(tmp, tmp2);
7792
                if (insn & (1 << 5)) {
7793
                    gen_roundqd(tmp, tmp2);
7794
                    dead_tmp(tmp2);
7795
                } else {
7796
                    dead_tmp(tmp);
7797
                    tmp = tmp2;
7798
                }
7799
                if (rs != 15) {
7800
                    tmp2 = load_reg(s, rs);
7801
                    if (insn & (1 << 21)) {
7802
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7803
                    } else {
7804
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7805
                    }
7806
                    dead_tmp(tmp2);
7807
                }
7808
                break;
7809
            case 7: /* Unsigned sum of absolute differences.  */
7810
                gen_helper_usad8(tmp, tmp, tmp2);
7811
                dead_tmp(tmp2);
7812
                if (rs != 15) {
7813
                    tmp2 = load_reg(s, rs);
7814
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7815
                    dead_tmp(tmp2);
7816
                }
7817
                break;
7818
            }
7819
            store_reg(s, rd, tmp);
7820
            break;
7821
        case 6: case 7: /* 64-bit multiply, Divide.  */
7822
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7823
            tmp = load_reg(s, rn);
7824
            tmp2 = load_reg(s, rm);
7825
            if ((op & 0x50) == 0x10) {
7826
                /* sdiv, udiv */
7827
                if (!arm_feature(env, ARM_FEATURE_DIV))
7828
                    goto illegal_op;
7829
                if (op & 0x20)
7830
                    gen_helper_udiv(tmp, tmp, tmp2);
7831
                else
7832
                    gen_helper_sdiv(tmp, tmp, tmp2);
7833
                dead_tmp(tmp2);
7834
                store_reg(s, rd, tmp);
7835
            } else if ((op & 0xe) == 0xc) {
7836
                /* Dual multiply accumulate long.  */
7837
                if (op & 1)
7838
                    gen_swap_half(tmp2);
7839
                gen_smul_dual(tmp, tmp2);
7840
                if (op & 0x10) {
7841
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7842
                } else {
7843
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7844
                }
7845
                dead_tmp(tmp2);
7846
                /* BUGFIX */
7847
                tmp64 = tcg_temp_new_i64();
7848
                tcg_gen_ext_i32_i64(tmp64, tmp);
7849
                dead_tmp(tmp);
7850
                gen_addq(s, tmp64, rs, rd);
7851
                gen_storeq_reg(s, rs, rd, tmp64);
7852
                tcg_temp_free_i64(tmp64);
7853
            } else {
7854
                if (op & 0x20) {
7855
                    /* Unsigned 64-bit multiply  */
7856
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7857
                } else {
7858
                    if (op & 8) {
7859
                        /* smlalxy */
7860
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7861
                        dead_tmp(tmp2);
7862
                        tmp64 = tcg_temp_new_i64();
7863
                        tcg_gen_ext_i32_i64(tmp64, tmp);
7864
                        dead_tmp(tmp);
7865
                    } else {
7866
                        /* Signed 64-bit multiply  */
7867
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7868
                    }
7869
                }
7870
                if (op & 4) {
7871
                    /* umaal */
7872
                    gen_addq_lo(s, tmp64, rs);
7873
                    gen_addq_lo(s, tmp64, rd);
7874
                } else if (op & 0x40) {
7875
                    /* 64-bit accumulate.  */
7876
                    gen_addq(s, tmp64, rs, rd);
7877
                }
7878
                gen_storeq_reg(s, rs, rd, tmp64);
7879
                tcg_temp_free_i64(tmp64);
7880
            }
7881
            break;
7882
        }
7883
        break;
7884
    case 6: case 7: case 14: case 15:
7885
        /* Coprocessor.  */
7886
        if (((insn >> 24) & 3) == 3) {
7887
            /* Translate into the equivalent ARM encoding.  */
7888
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7889
            if (disas_neon_data_insn(env, s, insn))
7890
                goto illegal_op;
7891
        } else {
7892
            if (insn & (1 << 28))
7893
                goto illegal_op;
7894
            if (disas_coproc_insn (env, s, insn))
7895
                goto illegal_op;
7896
        }
7897
        break;
7898
    case 8: case 9: case 10: case 11:
7899
        if (insn & (1 << 15)) {
7900
            /* Branches, misc control.  */
7901
            if (insn & 0x5000) {
7902
                /* Unconditional branch.  */
7903
                /* signextend(hw1[10:0]) -> offset[:12].  */
7904
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7905
                /* hw1[10:0] -> offset[11:1].  */
7906
                offset |= (insn & 0x7ff) << 1;
7907
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7908
                   offset[24:22] already have the same value because of the
7909
                   sign extension above.  */
7910
                offset ^= ((~insn) & (1 << 13)) << 10;
7911
                offset ^= ((~insn) & (1 << 11)) << 11;
7912

    
7913
                if (insn & (1 << 14)) {
7914
                    /* Branch and link.  */
7915
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
7916
                }
7917

    
7918
                offset += s->pc;
7919
                if (insn & (1 << 12)) {
7920
                    /* b/bl */
7921
                    gen_jmp(s, offset);
7922
                } else {
7923
                    /* blx */
7924
                    offset &= ~(uint32_t)2;
7925
                    gen_bx_im(s, offset);
7926
                }
7927
            } else if (((insn >> 23) & 7) == 7) {
7928
                /* Misc control */
7929
                if (insn & (1 << 13))
7930
                    goto illegal_op;
7931

    
7932
                if (insn & (1 << 26)) {
7933
                    /* Secure monitor call (v6Z) */
7934
                    goto illegal_op; /* not implemented.  */
7935
                } else {
7936
                    op = (insn >> 20) & 7;
7937
                    switch (op) {
7938
                    case 0: /* msr cpsr.  */
7939
                        if (IS_M(env)) {
7940
                            tmp = load_reg(s, rn);
7941
                            addr = tcg_const_i32(insn & 0xff);
7942
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7943
                            tcg_temp_free_i32(addr);
7944
                            dead_tmp(tmp);
7945
                            gen_lookup_tb(s);
7946
                            break;
7947
                        }
7948
                        /* fall through */
7949
                    case 1: /* msr spsr.  */
7950
                        if (IS_M(env))
7951
                            goto illegal_op;
7952
                        tmp = load_reg(s, rn);
7953
                        if (gen_set_psr(s,
7954
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7955
                              op == 1, tmp))
7956
                            goto illegal_op;
7957
                        break;
7958
                    case 2: /* cps, nop-hint.  */
7959
                        if (((insn >> 8) & 7) == 0) {
7960
                            gen_nop_hint(s, insn & 0xff);
7961
                        }
7962
                        /* Implemented as NOP in user mode.  */
7963
                        if (IS_USER(s))
7964
                            break;
7965
                        offset = 0;
7966
                        imm = 0;
7967
                        if (insn & (1 << 10)) {
7968
                            if (insn & (1 << 7))
7969
                                offset |= CPSR_A;
7970
                            if (insn & (1 << 6))
7971
                                offset |= CPSR_I;
7972
                            if (insn & (1 << 5))
7973
                                offset |= CPSR_F;
7974
                            if (insn & (1 << 9))
7975
                                imm = CPSR_A | CPSR_I | CPSR_F;
7976
                        }
7977
                        if (insn & (1 << 8)) {
7978
                            offset |= 0x1f;
7979
                            imm |= (insn & 0x1f);
7980
                        }
7981
                        if (offset) {
7982
                            gen_set_psr_im(s, offset, 0, imm);
7983
                        }
7984
                        break;
7985
                    case 3: /* Special control operations.  */
7986
                        ARCH(7);
7987
                        op = (insn >> 4) & 0xf;
7988
                        switch (op) {
7989
                        case 2: /* clrex */
7990
                            gen_clrex(s);
7991
                            break;
7992
                        case 4: /* dsb */
7993
                        case 5: /* dmb */
7994
                        case 6: /* isb */
7995
                            /* These execute as NOPs.  */
7996
                            break;
7997
                        default:
7998
                            goto illegal_op;
7999
                        }
8000
                        break;
8001
                    case 4: /* bxj */
8002
                        /* Trivial implementation equivalent to bx.  */
8003
                        tmp = load_reg(s, rn);
8004
                        gen_bx(s, tmp);
8005
                        break;
8006
                    case 5: /* Exception return.  */
8007
                        if (IS_USER(s)) {
8008
                            goto illegal_op;
8009
                        }
8010
                        if (rn != 14 || rd != 15) {
8011
                            goto illegal_op;
8012
                        }
8013
                        tmp = load_reg(s, rn);
8014
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8015
                        gen_exception_return(s, tmp);
8016
                        break;
8017
                    case 6: /* mrs cpsr.  */
8018
                        tmp = new_tmp();
8019
                        if (IS_M(env)) {
8020
                            addr = tcg_const_i32(insn & 0xff);
8021
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
8022
                            tcg_temp_free_i32(addr);
8023
                        } else {
8024
                            gen_helper_cpsr_read(tmp);
8025
                        }
8026
                        store_reg(s, rd, tmp);
8027
                        break;
8028
                    case 7: /* mrs spsr.  */
8029
                        /* Not accessible in user mode.  */
8030
                        if (IS_USER(s) || IS_M(env))
8031
                            goto illegal_op;
8032
                        tmp = load_cpu_field(spsr);
8033
                        store_reg(s, rd, tmp);
8034
                        break;
8035
                    }
8036
                }
8037
            } else {
8038
                /* Conditional branch.  */
8039
                op = (insn >> 22) & 0xf;
8040
                /* Generate a conditional jump to next instruction.  */
8041
                s->condlabel = gen_new_label();
8042
                gen_test_cc(op ^ 1, s->condlabel);
8043
                s->condjmp = 1;
8044

    
8045
                /* offset[11:1] = insn[10:0] */
8046
                offset = (insn & 0x7ff) << 1;
8047
                /* offset[17:12] = insn[21:16].  */
8048
                offset |= (insn & 0x003f0000) >> 4;
8049
                /* offset[31:20] = insn[26].  */
8050
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8051
                /* offset[18] = insn[13].  */
8052
                offset |= (insn & (1 << 13)) << 5;
8053
                /* offset[19] = insn[11].  */
8054
                offset |= (insn & (1 << 11)) << 8;
8055

    
8056
                /* jump to the offset */
8057
                gen_jmp(s, s->pc + offset);
8058
            }
8059
        } else {
8060
            /* Data processing immediate.  */
8061
            if (insn & (1 << 25)) {
8062
                if (insn & (1 << 24)) {
8063
                    if (insn & (1 << 20))
8064
                        goto illegal_op;
8065
                    /* Bitfield/Saturate.  */
8066
                    op = (insn >> 21) & 7;
8067
                    imm = insn & 0x1f;
8068
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8069
                    if (rn == 15) {
8070
                        tmp = new_tmp();
8071
                        tcg_gen_movi_i32(tmp, 0);
8072
                    } else {
8073
                        tmp = load_reg(s, rn);
8074
                    }
8075
                    switch (op) {
8076
                    case 2: /* Signed bitfield extract.  */
8077
                        imm++;
8078
                        if (shift + imm > 32)
8079
                            goto illegal_op;
8080
                        if (imm < 32)
8081
                            gen_sbfx(tmp, shift, imm);
8082
                        break;
8083
                    case 6: /* Unsigned bitfield extract.  */
8084
                        imm++;
8085
                        if (shift + imm > 32)
8086
                            goto illegal_op;
8087
                        if (imm < 32)
8088
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
8089
                        break;
8090
                    case 3: /* Bitfield insert/clear.  */
8091
                        if (imm < shift)
8092
                            goto illegal_op;
8093
                        imm = imm + 1 - shift;
8094
                        if (imm != 32) {
8095
                            tmp2 = load_reg(s, rd);
8096
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
8097
                            dead_tmp(tmp2);
8098
                        }
8099
                        break;
8100
                    case 7:
8101
                        goto illegal_op;
8102
                    default: /* Saturate.  */
8103
                        if (shift) {
8104
                            if (op & 1)
8105
                                tcg_gen_sari_i32(tmp, tmp, shift);
8106
                            else
8107
                                tcg_gen_shli_i32(tmp, tmp, shift);
8108
                        }
8109
                        tmp2 = tcg_const_i32(imm);
8110
                        if (op & 4) {
8111
                            /* Unsigned.  */
8112
                            if ((op & 1) && shift == 0)
8113
                                gen_helper_usat16(tmp, tmp, tmp2);
8114
                            else
8115
                                gen_helper_usat(tmp, tmp, tmp2);
8116
                        } else {
8117
                            /* Signed.  */
8118
                            if ((op & 1) && shift == 0)
8119
                                gen_helper_ssat16(tmp, tmp, tmp2);
8120
                            else
8121
                                gen_helper_ssat(tmp, tmp, tmp2);
8122
                        }
8123
                        tcg_temp_free_i32(tmp2);
8124
                        break;
8125
                    }
8126
                    store_reg(s, rd, tmp);
8127
                } else {
8128
                    imm = ((insn & 0x04000000) >> 15)
8129
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
8130
                    if (insn & (1 << 22)) {
8131
                        /* 16-bit immediate.  */
8132
                        imm |= (insn >> 4) & 0xf000;
8133
                        if (insn & (1 << 23)) {
8134
                            /* movt */
8135
                            tmp = load_reg(s, rd);
8136
                            tcg_gen_ext16u_i32(tmp, tmp);
8137
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
8138
                        } else {
8139
                            /* movw */
8140
                            tmp = new_tmp();
8141
                            tcg_gen_movi_i32(tmp, imm);
8142
                        }
8143
                    } else {
8144
                        /* Add/sub 12-bit immediate.  */
8145
                        if (rn == 15) {
8146
                            offset = s->pc & ~(uint32_t)3;
8147
                            if (insn & (1 << 23))
8148
                                offset -= imm;
8149
                            else
8150
                                offset += imm;
8151
                            tmp = new_tmp();
8152
                            tcg_gen_movi_i32(tmp, offset);
8153
                        } else {
8154
                            tmp = load_reg(s, rn);
8155
                            if (insn & (1 << 23))
8156
                                tcg_gen_subi_i32(tmp, tmp, imm);
8157
                            else
8158
                                tcg_gen_addi_i32(tmp, tmp, imm);
8159
                        }
8160
                    }
8161
                    store_reg(s, rd, tmp);
8162
                }
8163
            } else {
8164
                int shifter_out = 0;
8165
                /* modified 12-bit immediate.  */
8166
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8167
                imm = (insn & 0xff);
8168
                switch (shift) {
8169
                case 0: /* XY */
8170
                    /* Nothing to do.  */
8171
                    break;
8172
                case 1: /* 00XY00XY */
8173
                    imm |= imm << 16;
8174
                    break;
8175
                case 2: /* XY00XY00 */
8176
                    imm |= imm << 16;
8177
                    imm <<= 8;
8178
                    break;
8179
                case 3: /* XYXYXYXY */
8180
                    imm |= imm << 16;
8181
                    imm |= imm << 8;
8182
                    break;
8183
                default: /* Rotated constant.  */
8184
                    shift = (shift << 1) | (imm >> 7);
8185
                    imm |= 0x80;
8186
                    imm = imm << (32 - shift);
8187
                    shifter_out = 1;
8188
                    break;
8189
                }
8190
                tmp2 = new_tmp();
8191
                tcg_gen_movi_i32(tmp2, imm);
8192
                rn = (insn >> 16) & 0xf;
8193
                if (rn == 15) {
8194
                    tmp = new_tmp();
8195
                    tcg_gen_movi_i32(tmp, 0);
8196
                } else {
8197
                    tmp = load_reg(s, rn);
8198
                }
8199
                op = (insn >> 21) & 0xf;
8200
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
8201
                                       shifter_out, tmp, tmp2))
8202
                    goto illegal_op;
8203
                dead_tmp(tmp2);
8204
                rd = (insn >> 8) & 0xf;
8205
                if (rd != 15) {
8206
                    store_reg(s, rd, tmp);
8207
                } else {
8208
                    dead_tmp(tmp);
8209
                }
8210
            }
8211
        }
8212
        break;
8213
    case 12: /* Load/store single data item.  */
8214
        {
8215
        int postinc = 0;
8216
        int writeback = 0;
8217
        int user;
8218
        if ((insn & 0x01100000) == 0x01000000) {
8219
            if (disas_neon_ls_insn(env, s, insn))
8220
                goto illegal_op;
8221
            break;
8222
        }
8223
        user = IS_USER(s);
8224
        if (rn == 15) {
8225
            addr = new_tmp();
8226
            /* PC relative.  */
8227
            /* s->pc has already been incremented by 4.  */
8228
            imm = s->pc & 0xfffffffc;
8229
            if (insn & (1 << 23))
8230
                imm += insn & 0xfff;
8231
            else
8232
                imm -= insn & 0xfff;
8233
            tcg_gen_movi_i32(addr, imm);
8234
        } else {
8235
            addr = load_reg(s, rn);
8236
            if (insn & (1 << 23)) {
8237
                /* Positive offset.  */
8238
                imm = insn & 0xfff;
8239
                tcg_gen_addi_i32(addr, addr, imm);
8240
            } else {
8241
                op = (insn >> 8) & 7;
8242
                imm = insn & 0xff;
8243
                switch (op) {
8244
                case 0: case 8: /* Shifted Register.  */
8245
                    shift = (insn >> 4) & 0xf;
8246
                    if (shift > 3)
8247
                        goto illegal_op;
8248
                    tmp = load_reg(s, rm);
8249
                    if (shift)
8250
                        tcg_gen_shli_i32(tmp, tmp, shift);
8251
                    tcg_gen_add_i32(addr, addr, tmp);
8252
                    dead_tmp(tmp);
8253
                    break;
8254
                case 4: /* Negative offset.  */
8255
                    tcg_gen_addi_i32(addr, addr, -imm);
8256
                    break;
8257
                case 6: /* User privilege.  */
8258
                    tcg_gen_addi_i32(addr, addr, imm);
8259
                    user = 1;
8260
                    break;
8261
                case 1: /* Post-decrement.  */
8262
                    imm = -imm;
8263
                    /* Fall through.  */
8264
                case 3: /* Post-increment.  */
8265
                    postinc = 1;
8266
                    writeback = 1;
8267
                    break;
8268
                case 5: /* Pre-decrement.  */
8269
                    imm = -imm;
8270
                    /* Fall through.  */
8271
                case 7: /* Pre-increment.  */
8272
                    tcg_gen_addi_i32(addr, addr, imm);
8273
                    writeback = 1;
8274
                    break;
8275
                default:
8276
                    goto illegal_op;
8277
                }
8278
            }
8279
        }
8280
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8281
        if (insn & (1 << 20)) {
8282
            /* Load.  */
8283
            if (rs == 15 && op != 2) {
8284
                if (op & 2)
8285
                    goto illegal_op;
8286
                /* Memory hint.  Implemented as NOP.  */
8287
            } else {
8288
                switch (op) {
8289
                case 0: tmp = gen_ld8u(addr, user); break;
8290
                case 4: tmp = gen_ld8s(addr, user); break;
8291
                case 1: tmp = gen_ld16u(addr, user); break;
8292
                case 5: tmp = gen_ld16s(addr, user); break;
8293
                case 2: tmp = gen_ld32(addr, user); break;
8294
                default: goto illegal_op;
8295
                }
8296
                if (rs == 15) {
8297
                    gen_bx(s, tmp);
8298
                } else {
8299
                    store_reg(s, rs, tmp);
8300
                }
8301
            }
8302
        } else {
8303
            /* Store.  */
8304
            if (rs == 15)
8305
                goto illegal_op;
8306
            tmp = load_reg(s, rs);
8307
            switch (op) {
8308
            case 0: gen_st8(tmp, addr, user); break;
8309
            case 1: gen_st16(tmp, addr, user); break;
8310
            case 2: gen_st32(tmp, addr, user); break;
8311
            default: goto illegal_op;
8312
            }
8313
        }
8314
        if (postinc)
8315
            tcg_gen_addi_i32(addr, addr, imm);
8316
        if (writeback) {
8317
            store_reg(s, rn, addr);
8318
        } else {
8319
            dead_tmp(addr);
8320
        }
8321
        }
8322
        break;
8323
    default:
8324
        goto illegal_op;
8325
    }
8326
    return 0;
8327
illegal_op:
8328
    return 1;
8329
}
8330

    
8331
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8332
{
8333
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8334
    int32_t offset;
8335
    int i;
8336
    TCGv tmp;
8337
    TCGv tmp2;
8338
    TCGv addr;
8339

    
8340
    if (s->condexec_mask) {
8341
        cond = s->condexec_cond;
8342
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
8343
          s->condlabel = gen_new_label();
8344
          gen_test_cc(cond ^ 1, s->condlabel);
8345
          s->condjmp = 1;
8346
        }
8347
    }
8348

    
8349
    insn = lduw_code(s->pc);
8350
    s->pc += 2;
8351

    
8352
    switch (insn >> 12) {
8353
    case 0: case 1:
8354

    
8355
        rd = insn & 7;
8356
        op = (insn >> 11) & 3;
8357
        if (op == 3) {
8358
            /* add/subtract */
8359
            rn = (insn >> 3) & 7;
8360
            tmp = load_reg(s, rn);
8361
            if (insn & (1 << 10)) {
8362
                /* immediate */
8363
                tmp2 = new_tmp();
8364
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8365
            } else {
8366
                /* reg */
8367
                rm = (insn >> 6) & 7;
8368
                tmp2 = load_reg(s, rm);
8369
            }
8370
            if (insn & (1 << 9)) {
8371
                if (s->condexec_mask)
8372
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8373
                else
8374
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8375
            } else {
8376
                if (s->condexec_mask)
8377
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8378
                else
8379
                    gen_helper_add_cc(tmp, tmp, tmp2);
8380
            }
8381
            dead_tmp(tmp2);
8382
            store_reg(s, rd, tmp);
8383
        } else {
8384
            /* shift immediate */
8385
            rm = (insn >> 3) & 7;
8386
            shift = (insn >> 6) & 0x1f;
8387
            tmp = load_reg(s, rm);
8388
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8389
            if (!s->condexec_mask)
8390
                gen_logic_CC(tmp);
8391
            store_reg(s, rd, tmp);
8392
        }
8393
        break;
8394
    case 2: case 3:
8395
        /* arithmetic large immediate */
8396
        op = (insn >> 11) & 3;
8397
        rd = (insn >> 8) & 0x7;
8398
        if (op == 0) { /* mov */
8399
            tmp = new_tmp();
8400
            tcg_gen_movi_i32(tmp, insn & 0xff);
8401
            if (!s->condexec_mask)
8402
                gen_logic_CC(tmp);
8403
            store_reg(s, rd, tmp);
8404
        } else {
8405
            tmp = load_reg(s, rd);
8406
            tmp2 = new_tmp();
8407
            tcg_gen_movi_i32(tmp2, insn & 0xff);
8408
            switch (op) {
8409
            case 1: /* cmp */
8410
                gen_helper_sub_cc(tmp, tmp, tmp2);
8411
                dead_tmp(tmp);
8412
                dead_tmp(tmp2);
8413
                break;
8414
            case 2: /* add */
8415
                if (s->condexec_mask)
8416
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8417
                else
8418
                    gen_helper_add_cc(tmp, tmp, tmp2);
8419
                dead_tmp(tmp2);
8420
                store_reg(s, rd, tmp);
8421
                break;
8422
            case 3: /* sub */
8423
                if (s->condexec_mask)
8424
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8425
                else
8426
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8427
                dead_tmp(tmp2);
8428
                store_reg(s, rd, tmp);
8429
                break;
8430
            }
8431
        }
8432
        break;
8433
    case 4:
8434
        if (insn & (1 << 11)) {
8435
            rd = (insn >> 8) & 7;
8436
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8437
            val = s->pc + 2 + ((insn & 0xff) * 4);
8438
            val &= ~(uint32_t)2;
8439
            addr = new_tmp();
8440
            tcg_gen_movi_i32(addr, val);
8441
            tmp = gen_ld32(addr, IS_USER(s));
8442
            dead_tmp(addr);
8443
            store_reg(s, rd, tmp);
8444
            break;
8445
        }
8446
        if (insn & (1 << 10)) {
8447
            /* data processing extended or blx */
8448
            rd = (insn & 7) | ((insn >> 4) & 8);
8449
            rm = (insn >> 3) & 0xf;
8450
            op = (insn >> 8) & 3;
8451
            switch (op) {
8452
            case 0: /* add */
8453
                tmp = load_reg(s, rd);
8454
                tmp2 = load_reg(s, rm);
8455
                tcg_gen_add_i32(tmp, tmp, tmp2);
8456
                dead_tmp(tmp2);
8457
                store_reg(s, rd, tmp);
8458
                break;
8459
            case 1: /* cmp */
8460
                tmp = load_reg(s, rd);
8461
                tmp2 = load_reg(s, rm);
8462
                gen_helper_sub_cc(tmp, tmp, tmp2);
8463
                dead_tmp(tmp2);
8464
                dead_tmp(tmp);
8465
                break;
8466
            case 2: /* mov/cpy */
8467
                tmp = load_reg(s, rm);
8468
                store_reg(s, rd, tmp);
8469
                break;
8470
            case 3:/* branch [and link] exchange thumb register */
8471
                tmp = load_reg(s, rm);
8472
                if (insn & (1 << 7)) {
8473
                    val = (uint32_t)s->pc | 1;
8474
                    tmp2 = new_tmp();
8475
                    tcg_gen_movi_i32(tmp2, val);
8476
                    store_reg(s, 14, tmp2);
8477
                }
8478
                gen_bx(s, tmp);
8479
                break;
8480
            }
8481
            break;
8482
        }
8483

    
8484
        /* data processing register */
8485
        rd = insn & 7;
8486
        rm = (insn >> 3) & 7;
8487
        op = (insn >> 6) & 0xf;
8488
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8489
            /* the shift/rotate ops want the operands backwards */
8490
            val = rm;
8491
            rm = rd;
8492
            rd = val;
8493
            val = 1;
8494
        } else {
8495
            val = 0;
8496
        }
8497

    
8498
        if (op == 9) { /* neg */
8499
            tmp = new_tmp();
8500
            tcg_gen_movi_i32(tmp, 0);
8501
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
8502
            tmp = load_reg(s, rd);
8503
        } else {
8504
            TCGV_UNUSED(tmp);
8505
        }
8506

    
8507
        tmp2 = load_reg(s, rm);
8508
        switch (op) {
8509
        case 0x0: /* and */
8510
            tcg_gen_and_i32(tmp, tmp, tmp2);
8511
            if (!s->condexec_mask)
8512
                gen_logic_CC(tmp);
8513
            break;
8514
        case 0x1: /* eor */
8515
            tcg_gen_xor_i32(tmp, tmp, tmp2);
8516
            if (!s->condexec_mask)
8517
                gen_logic_CC(tmp);
8518
            break;
8519
        case 0x2: /* lsl */
8520
            if (s->condexec_mask) {
8521
                gen_helper_shl(tmp2, tmp2, tmp);
8522
            } else {
8523
                gen_helper_shl_cc(tmp2, tmp2, tmp);
8524
                gen_logic_CC(tmp2);
8525
            }
8526
            break;
8527
        case 0x3: /* lsr */
8528
            if (s->condexec_mask) {
8529
                gen_helper_shr(tmp2, tmp2, tmp);
8530
            } else {
8531
                gen_helper_shr_cc(tmp2, tmp2, tmp);
8532
                gen_logic_CC(tmp2);
8533
            }
8534
            break;
8535
        case 0x4: /* asr */
8536
            if (s->condexec_mask) {
8537
                gen_helper_sar(tmp2, tmp2, tmp);
8538
            } else {
8539
                gen_helper_sar_cc(tmp2, tmp2, tmp);
8540
                gen_logic_CC(tmp2);
8541
            }
8542
            break;
8543
        case 0x5: /* adc */
8544
            if (s->condexec_mask)
8545
                gen_adc(tmp, tmp2);
8546
            else
8547
                gen_helper_adc_cc(tmp, tmp, tmp2);
8548
            break;
8549
        case 0x6: /* sbc */
8550
            if (s->condexec_mask)
8551
                gen_sub_carry(tmp, tmp, tmp2);
8552
            else
8553
                gen_helper_sbc_cc(tmp, tmp, tmp2);
8554
            break;
8555
        case 0x7: /* ror */
8556
            if (s->condexec_mask) {
8557
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
8558
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
8559
            } else {
8560
                gen_helper_ror_cc(tmp2, tmp2, tmp);
8561
                gen_logic_CC(tmp2);
8562
            }
8563
            break;
8564
        case 0x8: /* tst */
8565
            tcg_gen_and_i32(tmp, tmp, tmp2);
8566
            gen_logic_CC(tmp);
8567
            rd = 16;
8568
            break;
8569
        case 0x9: /* neg */
8570
            if (s->condexec_mask)
8571
                tcg_gen_neg_i32(tmp, tmp2);
8572
            else
8573
                gen_helper_sub_cc(tmp, tmp, tmp2);
8574
            break;
8575
        case 0xa: /* cmp */
8576
            gen_helper_sub_cc(tmp, tmp, tmp2);
8577
            rd = 16;
8578
            break;
8579
        case 0xb: /* cmn */
8580
            gen_helper_add_cc(tmp, tmp, tmp2);
8581
            rd = 16;
8582
            break;
8583
        case 0xc: /* orr */
8584
            tcg_gen_or_i32(tmp, tmp, tmp2);
8585
            if (!s->condexec_mask)
8586
                gen_logic_CC(tmp);
8587
            break;
8588
        case 0xd: /* mul */
8589
            tcg_gen_mul_i32(tmp, tmp, tmp2);
8590
            if (!s->condexec_mask)
8591
                gen_logic_CC(tmp);
8592
            break;
8593
        case 0xe: /* bic */
8594
            tcg_gen_andc_i32(tmp, tmp, tmp2);
8595
            if (!s->condexec_mask)
8596
                gen_logic_CC(tmp);
8597
            break;
8598
        case 0xf: /* mvn */
8599
            tcg_gen_not_i32(tmp2, tmp2);
8600
            if (!s->condexec_mask)
8601
                gen_logic_CC(tmp2);
8602
            val = 1;
8603
            rm = rd;
8604
            break;
8605
        }
8606
        if (rd != 16) {
8607
            if (val) {
8608
                store_reg(s, rm, tmp2);
8609
                if (op != 0xf)
8610
                    dead_tmp(tmp);
8611
            } else {
8612
                store_reg(s, rd, tmp);
8613
                dead_tmp(tmp2);
8614
            }
8615
        } else {
8616
            dead_tmp(tmp);
8617
            dead_tmp(tmp2);
8618
        }
8619
        break;
8620

    
8621
    case 5:
8622
        /* load/store register offset.  */
8623
        rd = insn & 7;
8624
        rn = (insn >> 3) & 7;
8625
        rm = (insn >> 6) & 7;
8626
        op = (insn >> 9) & 7;
8627
        addr = load_reg(s, rn);
8628
        tmp = load_reg(s, rm);
8629
        tcg_gen_add_i32(addr, addr, tmp);
8630
        dead_tmp(tmp);
8631

    
8632
        if (op < 3) /* store */
8633
            tmp = load_reg(s, rd);
8634

    
8635
        switch (op) {
8636
        case 0: /* str */
8637
            gen_st32(tmp, addr, IS_USER(s));
8638
            break;
8639
        case 1: /* strh */
8640
            gen_st16(tmp, addr, IS_USER(s));
8641
            break;
8642
        case 2: /* strb */
8643
            gen_st8(tmp, addr, IS_USER(s));
8644
            break;
8645
        case 3: /* ldrsb */
8646
            tmp = gen_ld8s(addr, IS_USER(s));
8647
            break;
8648
        case 4: /* ldr */
8649
            tmp = gen_ld32(addr, IS_USER(s));
8650
            break;
8651
        case 5: /* ldrh */
8652
            tmp = gen_ld16u(addr, IS_USER(s));
8653
            break;
8654
        case 6: /* ldrb */
8655
            tmp = gen_ld8u(addr, IS_USER(s));
8656
            break;
8657
        case 7: /* ldrsh */
8658
            tmp = gen_ld16s(addr, IS_USER(s));
8659
            break;
8660
        }
8661
        if (op >= 3) /* load */
8662
            store_reg(s, rd, tmp);
8663
        dead_tmp(addr);
8664
        break;
8665

    
8666
    case 6:
8667
        /* load/store word immediate offset */
8668
        rd = insn & 7;
8669
        rn = (insn >> 3) & 7;
8670
        addr = load_reg(s, rn);
8671
        val = (insn >> 4) & 0x7c;
8672
        tcg_gen_addi_i32(addr, addr, val);
8673

    
8674
        if (insn & (1 << 11)) {
8675
            /* load */
8676
            tmp = gen_ld32(addr, IS_USER(s));
8677
            store_reg(s, rd, tmp);
8678
        } else {
8679
            /* store */
8680
            tmp = load_reg(s, rd);
8681
            gen_st32(tmp, addr, IS_USER(s));
8682
        }
8683
        dead_tmp(addr);
8684
        break;
8685

    
8686
    case 7:
8687
        /* load/store byte immediate offset */
8688
        rd = insn & 7;
8689
        rn = (insn >> 3) & 7;
8690
        addr = load_reg(s, rn);
8691
        val = (insn >> 6) & 0x1f;
8692
        tcg_gen_addi_i32(addr, addr, val);
8693

    
8694
        if (insn & (1 << 11)) {
8695
            /* load */
8696
            tmp = gen_ld8u(addr, IS_USER(s));
8697
            store_reg(s, rd, tmp);
8698
        } else {
8699
            /* store */
8700
            tmp = load_reg(s, rd);
8701
            gen_st8(tmp, addr, IS_USER(s));
8702
        }
8703
        dead_tmp(addr);
8704
        break;
8705

    
8706
    case 8:
8707
        /* load/store halfword immediate offset */
8708
        rd = insn & 7;
8709
        rn = (insn >> 3) & 7;
8710
        addr = load_reg(s, rn);
8711
        val = (insn >> 5) & 0x3e;
8712
        tcg_gen_addi_i32(addr, addr, val);
8713

    
8714
        if (insn & (1 << 11)) {
8715
            /* load */
8716
            tmp = gen_ld16u(addr, IS_USER(s));
8717
            store_reg(s, rd, tmp);
8718
        } else {
8719
            /* store */
8720
            tmp = load_reg(s, rd);
8721
            gen_st16(tmp, addr, IS_USER(s));
8722
        }
8723
        dead_tmp(addr);
8724
        break;
8725

    
8726
    case 9:
8727
        /* load/store from stack */
8728
        rd = (insn >> 8) & 7;
8729
        addr = load_reg(s, 13);
8730
        val = (insn & 0xff) * 4;
8731
        tcg_gen_addi_i32(addr, addr, val);
8732

    
8733
        if (insn & (1 << 11)) {
8734
            /* load */
8735
            tmp = gen_ld32(addr, IS_USER(s));
8736
            store_reg(s, rd, tmp);
8737
        } else {
8738
            /* store */
8739
            tmp = load_reg(s, rd);
8740
            gen_st32(tmp, addr, IS_USER(s));
8741
        }
8742
        dead_tmp(addr);
8743
        break;
8744

    
8745
    case 10:
8746
        /* add to high reg */
8747
        rd = (insn >> 8) & 7;
8748
        if (insn & (1 << 11)) {
8749
            /* SP */
8750
            tmp = load_reg(s, 13);
8751
        } else {
8752
            /* PC. bit 1 is ignored.  */
8753
            tmp = new_tmp();
8754
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8755
        }
8756
        val = (insn & 0xff) * 4;
8757
        tcg_gen_addi_i32(tmp, tmp, val);
8758
        store_reg(s, rd, tmp);
8759
        break;
8760

    
8761
    case 11:
8762
        /* misc */
8763
        op = (insn >> 8) & 0xf;
8764
        switch (op) {
8765
        case 0:
8766
            /* adjust stack pointer */
8767
            tmp = load_reg(s, 13);
8768
            val = (insn & 0x7f) * 4;
8769
            if (insn & (1 << 7))
8770
                val = -(int32_t)val;
8771
            tcg_gen_addi_i32(tmp, tmp, val);
8772
            store_reg(s, 13, tmp);
8773
            break;
8774

    
8775
        case 2: /* sign/zero extend.  */
8776
            ARCH(6);
8777
            rd = insn & 7;
8778
            rm = (insn >> 3) & 7;
8779
            tmp = load_reg(s, rm);
8780
            switch ((insn >> 6) & 3) {
8781
            case 0: gen_sxth(tmp); break;
8782
            case 1: gen_sxtb(tmp); break;
8783
            case 2: gen_uxth(tmp); break;
8784
            case 3: gen_uxtb(tmp); break;
8785
            }
8786
            store_reg(s, rd, tmp);
8787
            break;
8788
        case 4: case 5: case 0xc: case 0xd:
8789
            /* push/pop */
8790
            addr = load_reg(s, 13);
8791
            if (insn & (1 << 8))
8792
                offset = 4;
8793
            else
8794
                offset = 0;
8795
            for (i = 0; i < 8; i++) {
8796
                if (insn & (1 << i))
8797
                    offset += 4;
8798
            }
8799
            if ((insn & (1 << 11)) == 0) {
8800
                tcg_gen_addi_i32(addr, addr, -offset);
8801
            }
8802
            for (i = 0; i < 8; i++) {
8803
                if (insn & (1 << i)) {
8804
                    if (insn & (1 << 11)) {
8805
                        /* pop */
8806
                        tmp = gen_ld32(addr, IS_USER(s));
8807
                        store_reg(s, i, tmp);
8808
                    } else {
8809
                        /* push */
8810
                        tmp = load_reg(s, i);
8811
                        gen_st32(tmp, addr, IS_USER(s));
8812
                    }
8813
                    /* advance to the next address.  */
8814
                    tcg_gen_addi_i32(addr, addr, 4);
8815
                }
8816
            }
8817
            TCGV_UNUSED(tmp);
8818
            if (insn & (1 << 8)) {
8819
                if (insn & (1 << 11)) {
8820
                    /* pop pc */
8821
                    tmp = gen_ld32(addr, IS_USER(s));
8822
                    /* don't set the pc until the rest of the instruction
8823
                       has completed */
8824
                } else {
8825
                    /* push lr */
8826
                    tmp = load_reg(s, 14);
8827
                    gen_st32(tmp, addr, IS_USER(s));
8828
                }
8829
                tcg_gen_addi_i32(addr, addr, 4);
8830
            }
8831
            if ((insn & (1 << 11)) == 0) {
8832
                tcg_gen_addi_i32(addr, addr, -offset);
8833
            }
8834
            /* write back the new stack pointer */
8835
            store_reg(s, 13, addr);
8836
            /* set the new PC value */
8837
            if ((insn & 0x0900) == 0x0900)
8838
                gen_bx(s, tmp);
8839
            break;
8840

    
8841
        case 1: case 3: case 9: case 11: /* czb */
8842
            rm = insn & 7;
8843
            tmp = load_reg(s, rm);
8844
            s->condlabel = gen_new_label();
8845
            s->condjmp = 1;
8846
            if (insn & (1 << 11))
8847
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8848
            else
8849
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8850
            dead_tmp(tmp);
8851
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8852
            val = (uint32_t)s->pc + 2;
8853
            val += offset;
8854
            gen_jmp(s, val);
8855
            break;
8856

    
8857
        case 15: /* IT, nop-hint.  */
8858
            if ((insn & 0xf) == 0) {
8859
                gen_nop_hint(s, (insn >> 4) & 0xf);
8860
                break;
8861
            }
8862
            /* If Then.  */
8863
            s->condexec_cond = (insn >> 4) & 0xe;
8864
            s->condexec_mask = insn & 0x1f;
8865
            /* No actual code generated for this insn, just setup state.  */
8866
            break;
8867

    
8868
        case 0xe: /* bkpt */
8869
            gen_set_condexec(s);
8870
            gen_set_pc_im(s->pc - 2);
8871
            gen_exception(EXCP_BKPT);
8872
            s->is_jmp = DISAS_JUMP;
8873
            break;
8874

    
8875
        case 0xa: /* rev */
8876
            ARCH(6);
8877
            rn = (insn >> 3) & 0x7;
8878
            rd = insn & 0x7;
8879
            tmp = load_reg(s, rn);
8880
            switch ((insn >> 6) & 3) {
8881
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8882
            case 1: gen_rev16(tmp); break;
8883
            case 3: gen_revsh(tmp); break;
8884
            default: goto illegal_op;
8885
            }
8886
            store_reg(s, rd, tmp);
8887
            break;
8888

    
8889
        case 6: /* cps */
8890
            ARCH(6);
8891
            if (IS_USER(s))
8892
                break;
8893
            if (IS_M(env)) {
8894
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8895
                /* PRIMASK */
8896
                if (insn & 1) {
8897
                    addr = tcg_const_i32(16);
8898
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8899
                    tcg_temp_free_i32(addr);
8900
                }
8901
                /* FAULTMASK */
8902
                if (insn & 2) {
8903
                    addr = tcg_const_i32(17);
8904
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8905
                    tcg_temp_free_i32(addr);
8906
                }
8907
                tcg_temp_free_i32(tmp);
8908
                gen_lookup_tb(s);
8909
            } else {
8910
                if (insn & (1 << 4))
8911
                    shift = CPSR_A | CPSR_I | CPSR_F;
8912
                else
8913
                    shift = 0;
8914
                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
8915
            }
8916
            break;
8917

    
8918
        default:
8919
            goto undef;
8920
        }
8921
        break;
8922

    
8923
    case 12:
8924
        /* load/store multiple */
8925
        rn = (insn >> 8) & 0x7;
8926
        addr = load_reg(s, rn);
8927
        for (i = 0; i < 8; i++) {
8928
            if (insn & (1 << i)) {
8929
                if (insn & (1 << 11)) {
8930
                    /* load */
8931
                    tmp = gen_ld32(addr, IS_USER(s));
8932
                    store_reg(s, i, tmp);
8933
                } else {
8934
                    /* store */
8935
                    tmp = load_reg(s, i);
8936
                    gen_st32(tmp, addr, IS_USER(s));
8937
                }
8938
                /* advance to the next address */
8939
                tcg_gen_addi_i32(addr, addr, 4);
8940
            }
8941
        }
8942
        /* Base register writeback.  */
8943
        if ((insn & (1 << rn)) == 0) {
8944
            store_reg(s, rn, addr);
8945
        } else {
8946
            dead_tmp(addr);
8947
        }
8948
        break;
8949

    
8950
    case 13:
8951
        /* conditional branch or swi */
8952
        cond = (insn >> 8) & 0xf;
8953
        if (cond == 0xe)
8954
            goto undef;
8955

    
8956
        if (cond == 0xf) {
8957
            /* swi */
8958
            gen_set_condexec(s);
8959
            gen_set_pc_im(s->pc);
8960
            s->is_jmp = DISAS_SWI;
8961
            break;
8962
        }
8963
        /* generate a conditional jump to next instruction */
8964
        s->condlabel = gen_new_label();
8965
        gen_test_cc(cond ^ 1, s->condlabel);
8966
        s->condjmp = 1;
8967

    
8968
        /* jump to the offset */
8969
        val = (uint32_t)s->pc + 2;
8970
        offset = ((int32_t)insn << 24) >> 24;
8971
        val += offset << 1;
8972
        gen_jmp(s, val);
8973
        break;
8974

    
8975
    case 14:
8976
        if (insn & (1 << 11)) {
8977
            if (disas_thumb2_insn(env, s, insn))
8978
              goto undef32;
8979
            break;
8980
        }
8981
        /* unconditional branch */
8982
        val = (uint32_t)s->pc;
8983
        offset = ((int32_t)insn << 21) >> 21;
8984
        val += (offset << 1) + 2;
8985
        gen_jmp(s, val);
8986
        break;
8987

    
8988
    case 15:
8989
        if (disas_thumb2_insn(env, s, insn))
8990
            goto undef32;
8991
        break;
8992
    }
8993
    return;
8994
undef32:
8995
    gen_set_condexec(s);
8996
    gen_set_pc_im(s->pc - 4);
8997
    gen_exception(EXCP_UDEF);
8998
    s->is_jmp = DISAS_JUMP;
8999
    return;
9000
illegal_op:
9001
undef:
9002
    gen_set_condexec(s);
9003
    gen_set_pc_im(s->pc - 2);
9004
    gen_exception(EXCP_UDEF);
9005
    s->is_jmp = DISAS_JUMP;
9006
}
9007

    
9008
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9009
   basic block 'tb'. If search_pc is TRUE, also generate PC
9010
   information for each intermediate instruction. */
9011
static inline void gen_intermediate_code_internal(CPUState *env,
9012
                                                  TranslationBlock *tb,
9013
                                                  int search_pc)
9014
{
9015
    DisasContext dc1, *dc = &dc1;
9016
    CPUBreakpoint *bp;
9017
    uint16_t *gen_opc_end;
9018
    int j, lj;
9019
    target_ulong pc_start;
9020
    uint32_t next_page_start;
9021
    int num_insns;
9022
    int max_insns;
9023

    
9024
    /* generate intermediate code */
9025
    num_temps = 0;
9026

    
9027
    pc_start = tb->pc;
9028

    
9029
    dc->tb = tb;
9030

    
9031
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9032

    
9033
    dc->is_jmp = DISAS_NEXT;
9034
    dc->pc = pc_start;
9035
    dc->singlestep_enabled = env->singlestep_enabled;
9036
    dc->condjmp = 0;
9037
    dc->thumb = env->thumb;
9038
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
9039
    dc->condexec_cond = env->condexec_bits >> 4;
9040
#if !defined(CONFIG_USER_ONLY)
9041
    if (IS_M(env)) {
9042
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
9043
    } else {
9044
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
9045
    }
9046
#endif
9047
    cpu_F0s = tcg_temp_new_i32();
9048
    cpu_F1s = tcg_temp_new_i32();
9049
    cpu_F0d = tcg_temp_new_i64();
9050
    cpu_F1d = tcg_temp_new_i64();
9051
    cpu_V0 = cpu_F0d;
9052
    cpu_V1 = cpu_F1d;
9053
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
9054
    cpu_M0 = tcg_temp_new_i64();
9055
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9056
    lj = -1;
9057
    num_insns = 0;
9058
    max_insns = tb->cflags & CF_COUNT_MASK;
9059
    if (max_insns == 0)
9060
        max_insns = CF_COUNT_MASK;
9061

    
9062
    gen_icount_start();
9063
    /* Reset the conditional execution bits immediately. This avoids
9064
       complications trying to do it at the end of the block.  */
9065
    if (env->condexec_bits)
9066
      {
9067
        TCGv tmp = new_tmp();
9068
        tcg_gen_movi_i32(tmp, 0);
9069
        store_cpu_field(tmp, condexec_bits);
9070
      }
9071
    do {
9072
#ifdef CONFIG_USER_ONLY
9073
        /* Intercept jump to the magic kernel page.  */
9074
        if (dc->pc >= 0xffff0000) {
9075
            /* We always get here via a jump, so know we are not in a
9076
               conditional execution block.  */
9077
            gen_exception(EXCP_KERNEL_TRAP);
9078
            dc->is_jmp = DISAS_UPDATE;
9079
            break;
9080
        }
9081
#else
9082
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9083
            /* We always get here via a jump, so know we are not in a
9084
               conditional execution block.  */
9085
            gen_exception(EXCP_EXCEPTION_EXIT);
9086
            dc->is_jmp = DISAS_UPDATE;
9087
            break;
9088
        }
9089
#endif
9090

    
9091
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9092
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9093
                if (bp->pc == dc->pc) {
9094
                    gen_set_condexec(dc);
9095
                    gen_set_pc_im(dc->pc);
9096
                    gen_exception(EXCP_DEBUG);
9097
                    dc->is_jmp = DISAS_JUMP;
9098
                    /* Advance PC so that clearing the breakpoint will
9099
                       invalidate this TB.  */
9100
                    dc->pc += 2;
9101
                    goto done_generating;
9102
                    break;
9103
                }
9104
            }
9105
        }
9106
        if (search_pc) {
9107
            j = gen_opc_ptr - gen_opc_buf;
9108
            if (lj < j) {
9109
                lj++;
9110
                while (lj < j)
9111
                    gen_opc_instr_start[lj++] = 0;
9112
            }
9113
            gen_opc_pc[lj] = dc->pc;
9114
            gen_opc_instr_start[lj] = 1;
9115
            gen_opc_icount[lj] = num_insns;
9116
        }
9117

    
9118
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9119
            gen_io_start();
9120

    
9121
        if (env->thumb) {
9122
            disas_thumb_insn(env, dc);
9123
            if (dc->condexec_mask) {
9124
                dc->condexec_cond = (dc->condexec_cond & 0xe)
9125
                                   | ((dc->condexec_mask >> 4) & 1);
9126
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9127
                if (dc->condexec_mask == 0) {
9128
                    dc->condexec_cond = 0;
9129
                }
9130
            }
9131
        } else {
9132
            disas_arm_insn(env, dc);
9133
        }
9134
        if (num_temps) {
9135
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
9136
            num_temps = 0;
9137
        }
9138

    
9139
        if (dc->condjmp && !dc->is_jmp) {
9140
            gen_set_label(dc->condlabel);
9141
            dc->condjmp = 0;
9142
        }
9143
        /* Translation stops when a conditional branch is encountered.
9144
         * Otherwise the subsequent code could get translated several times.
9145
         * Also stop translation when a page boundary is reached.  This
9146
         * ensures prefetch aborts occur at the right place.  */
9147
        num_insns ++;
9148
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9149
             !env->singlestep_enabled &&
9150
             !singlestep &&
9151
             dc->pc < next_page_start &&
9152
             num_insns < max_insns);
9153

    
9154
    if (tb->cflags & CF_LAST_IO) {
9155
        if (dc->condjmp) {
9156
            /* FIXME:  This can theoretically happen with self-modifying
9157
               code.  */
9158
            cpu_abort(env, "IO on conditional branch instruction");
9159
        }
9160
        gen_io_end();
9161
    }
9162

    
9163
    /* At this stage dc->condjmp will only be set when the skipped
9164
       instruction was a conditional branch or trap, and the PC has
9165
       already been written.  */
9166
    if (unlikely(env->singlestep_enabled)) {
9167
        /* Make sure the pc is updated, and raise a debug exception.  */
9168
        if (dc->condjmp) {
9169
            gen_set_condexec(dc);
9170
            if (dc->is_jmp == DISAS_SWI) {
9171
                gen_exception(EXCP_SWI);
9172
            } else {
9173
                gen_exception(EXCP_DEBUG);
9174
            }
9175
            gen_set_label(dc->condlabel);
9176
        }
9177
        if (dc->condjmp || !dc->is_jmp) {
9178
            gen_set_pc_im(dc->pc);
9179
            dc->condjmp = 0;
9180
        }
9181
        gen_set_condexec(dc);
9182
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9183
            gen_exception(EXCP_SWI);
9184
        } else {
9185
            /* FIXME: Single stepping a WFI insn will not halt
9186
               the CPU.  */
9187
            gen_exception(EXCP_DEBUG);
9188
        }
9189
    } else {
9190
        /* While branches must always occur at the end of an IT block,
9191
           there are a few other things that can cause us to terminate
9192
           the TB in the middel of an IT block:
9193
            - Exception generating instructions (bkpt, swi, undefined).
9194
            - Page boundaries.
9195
            - Hardware watchpoints.
9196
           Hardware breakpoints have already been handled and skip this code.
9197
         */
9198
        gen_set_condexec(dc);
9199
        switch(dc->is_jmp) {
9200
        case DISAS_NEXT:
9201
            gen_goto_tb(dc, 1, dc->pc);
9202
            break;
9203
        default:
9204
        case DISAS_JUMP:
9205
        case DISAS_UPDATE:
9206
            /* indicate that the hash table must be used to find the next TB */
9207
            tcg_gen_exit_tb(0);
9208
            break;
9209
        case DISAS_TB_JUMP:
9210
            /* nothing more to generate */
9211
            break;
9212
        case DISAS_WFI:
9213
            gen_helper_wfi();
9214
            break;
9215
        case DISAS_SWI:
9216
            gen_exception(EXCP_SWI);
9217
            break;
9218
        }
9219
        if (dc->condjmp) {
9220
            gen_set_label(dc->condlabel);
9221
            gen_set_condexec(dc);
9222
            gen_goto_tb(dc, 1, dc->pc);
9223
            dc->condjmp = 0;
9224
        }
9225
    }
9226

    
9227
done_generating:
9228
    gen_icount_end(tb, num_insns);
9229
    *gen_opc_ptr = INDEX_op_end;
9230

    
9231
#ifdef DEBUG_DISAS
9232
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9233
        qemu_log("----------------\n");
9234
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9235
        log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
9236
        qemu_log("\n");
9237
    }
9238
#endif
9239
    if (search_pc) {
9240
        j = gen_opc_ptr - gen_opc_buf;
9241
        lj++;
9242
        while (lj <= j)
9243
            gen_opc_instr_start[lj++] = 0;
9244
    } else {
9245
        tb->size = dc->pc - pc_start;
9246
        tb->icount = num_insns;
9247
    }
9248
}
9249

    
9250
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9251
{
9252
    gen_intermediate_code_internal(env, tb, 0);
9253
}
9254

    
9255
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9256
{
9257
    gen_intermediate_code_internal(env, tb, 1);
9258
}
9259

    
9260
static const char *cpu_mode_names[16] = {
9261
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9262
  "???", "???", "???", "und", "???", "???", "???", "sys"
9263
};
9264

    
9265
void cpu_dump_state(CPUState *env, FILE *f,
9266
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9267
                    int flags)
9268
{
9269
    int i;
9270
#if 0
9271
    union {
9272
        uint32_t i;
9273
        float s;
9274
    } s0, s1;
9275
    CPU_DoubleU d;
9276
    /* ??? This assumes float64 and double have the same layout.
9277
       Oh well, it's only debug dumps.  */
9278
    union {
9279
        float64 f64;
9280
        double d;
9281
    } d0;
9282
#endif
9283
    uint32_t psr;
9284

    
9285
    for(i=0;i<16;i++) {
9286
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9287
        if ((i % 4) == 3)
9288
            cpu_fprintf(f, "\n");
9289
        else
9290
            cpu_fprintf(f, " ");
9291
    }
9292
    psr = cpsr_read(env);
9293
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9294
                psr,
9295
                psr & (1 << 31) ? 'N' : '-',
9296
                psr & (1 << 30) ? 'Z' : '-',
9297
                psr & (1 << 29) ? 'C' : '-',
9298
                psr & (1 << 28) ? 'V' : '-',
9299
                psr & CPSR_T ? 'T' : 'A',
9300
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9301

    
9302
#if 0
9303
    for (i = 0; i < 16; i++) {
9304
        d.d = env->vfp.regs[i];
9305
        s0.i = d.l.lower;
9306
        s1.i = d.l.upper;
9307
        d0.f64 = d.d;
9308
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9309
                    i * 2, (int)s0.i, s0.s,
9310
                    i * 2 + 1, (int)s1.i, s1.s,
9311
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9312
                    d0.d);
9313
    }
9314
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9315
#endif
9316
}
9317

    
9318
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9319
                unsigned long searched_pc, int pc_pos, void *puc)
9320
{
9321
    env->regs[15] = gen_opc_pc[pc_pos];
9322
}