Statistics
| Branch: | Revision:

root / target-arm / translate.c @ e5ca24cb

History | View | Annotate | Download (320.2 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
    int vfp_enabled;
63
    int vec_len;
64
    int vec_stride;
65
} DisasContext;
66

    
67
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
68

    
69
#if defined(CONFIG_USER_ONLY)
70
#define IS_USER(s) 1
71
#else
72
#define IS_USER(s) (s->user)
73
#endif
74

    
75
/* These instructions trap after executing, so defer them until after the
76
   conditional executions state has been updated.  */
77
#define DISAS_WFI 4
78
#define DISAS_SWI 5
79

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

    
92
/* FIXME:  These should be removed.  */
93
static TCGv cpu_F0s, cpu_F1s;
94
static TCGv_i64 cpu_F0d, cpu_F1d;
95

    
96
#include "gen-icount.h"
97

    
98
static const char *regnames[] =
99
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
100
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
101

    
102
/* initialize TCG globals.  */
103
void arm_translate_init(void)
104
{
105
    int i;
106

    
107
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
108

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

    
127
#define GEN_HELPER 2
128
#include "helpers.h"
129
}
130

    
131
static int num_temps;
132

    
133
/* Allocate a temporary variable.  */
134
static TCGv_i32 new_tmp(void)
135
{
136
    num_temps++;
137
    return tcg_temp_new_i32();
138
}
139

    
140
/* Release a temporary variable.  */
141
static void dead_tmp(TCGv tmp)
142
{
143
    tcg_temp_free(tmp);
144
    num_temps--;
145
}
146

    
147
static inline TCGv load_cpu_offset(int offset)
148
{
149
    TCGv tmp = new_tmp();
150
    tcg_gen_ld_i32(tmp, cpu_env, offset);
151
    return tmp;
152
}
153

    
154
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
155

    
156
static inline void store_cpu_offset(TCGv var, int offset)
157
{
158
    tcg_gen_st_i32(var, cpu_env, offset);
159
    dead_tmp(var);
160
}
161

    
162
#define store_cpu_field(var, name) \
163
    store_cpu_offset(var, offsetof(CPUState, name))
164

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

    
181
/* Create a new temporary and set it to the value of a CPU register.  */
182
static inline TCGv load_reg(DisasContext *s, int reg)
183
{
184
    TCGv tmp = new_tmp();
185
    load_reg_var(s, tmp, reg);
186
    return tmp;
187
}
188

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

    
201
/* Value extensions.  */
202
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
203
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
204
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
205
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
206

    
207
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
208
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
209

    
210

    
211
static inline void gen_set_cpsr(TCGv var, uint32_t mask)
212
{
213
    TCGv tmp_mask = tcg_const_i32(mask);
214
    gen_helper_cpsr_write(var, tmp_mask);
215
    tcg_temp_free_i32(tmp_mask);
216
}
217
/* Set NZCV flags from the high 4 bits of var.  */
218
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
219

    
220
static void gen_exception(int excp)
221
{
222
    TCGv tmp = new_tmp();
223
    tcg_gen_movi_i32(tmp, excp);
224
    gen_helper_exception(tmp);
225
    dead_tmp(tmp);
226
}
227

    
228
static void gen_smul_dual(TCGv a, TCGv b)
229
{
230
    TCGv tmp1 = new_tmp();
231
    TCGv tmp2 = new_tmp();
232
    tcg_gen_ext16s_i32(tmp1, a);
233
    tcg_gen_ext16s_i32(tmp2, b);
234
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
235
    dead_tmp(tmp2);
236
    tcg_gen_sari_i32(a, a, 16);
237
    tcg_gen_sari_i32(b, b, 16);
238
    tcg_gen_mul_i32(b, b, a);
239
    tcg_gen_mov_i32(a, tmp1);
240
    dead_tmp(tmp1);
241
}
242

    
243
/* Byteswap each halfword.  */
244
static void gen_rev16(TCGv var)
245
{
246
    TCGv tmp = new_tmp();
247
    tcg_gen_shri_i32(tmp, var, 8);
248
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
249
    tcg_gen_shli_i32(var, var, 8);
250
    tcg_gen_andi_i32(var, var, 0xff00ff00);
251
    tcg_gen_or_i32(var, var, tmp);
252
    dead_tmp(tmp);
253
}
254

    
255
/* Byteswap low halfword and sign extend.  */
256
static void gen_revsh(TCGv var)
257
{
258
    tcg_gen_ext16u_i32(var, var);
259
    tcg_gen_bswap16_i32(var, var);
260
    tcg_gen_ext16s_i32(var, var);
261
}
262

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

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

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

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

    
295
/* Return (b << 32) + a. Mark inputs as dead */
296
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b)
297
{
298
    TCGv_i64 tmp64 = tcg_temp_new_i64();
299

    
300
    tcg_gen_extu_i32_i64(tmp64, b);
301
    dead_tmp(b);
302
    tcg_gen_shli_i64(tmp64, tmp64, 32);
303
    tcg_gen_add_i64(a, tmp64, a);
304

    
305
    tcg_temp_free_i64(tmp64);
306
    return a;
307
}
308

    
309
/* Return (b << 32) - a. Mark inputs as dead. */
310
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
311
{
312
    TCGv_i64 tmp64 = tcg_temp_new_i64();
313

    
314
    tcg_gen_extu_i32_i64(tmp64, b);
315
    dead_tmp(b);
316
    tcg_gen_shli_i64(tmp64, tmp64, 32);
317
    tcg_gen_sub_i64(a, tmp64, a);
318

    
319
    tcg_temp_free_i64(tmp64);
320
    return a;
321
}
322

    
323
/* FIXME: Most targets have native widening multiplication.
324
   It would be good to use that instead of a full wide multiply.  */
325
/* 32x32->64 multiply.  Marks inputs as dead.  */
326
static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
327
{
328
    TCGv_i64 tmp1 = tcg_temp_new_i64();
329
    TCGv_i64 tmp2 = tcg_temp_new_i64();
330

    
331
    tcg_gen_extu_i32_i64(tmp1, a);
332
    dead_tmp(a);
333
    tcg_gen_extu_i32_i64(tmp2, b);
334
    dead_tmp(b);
335
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
336
    tcg_temp_free_i64(tmp2);
337
    return tmp1;
338
}
339

    
340
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
341
{
342
    TCGv_i64 tmp1 = tcg_temp_new_i64();
343
    TCGv_i64 tmp2 = tcg_temp_new_i64();
344

    
345
    tcg_gen_ext_i32_i64(tmp1, a);
346
    dead_tmp(a);
347
    tcg_gen_ext_i32_i64(tmp2, b);
348
    dead_tmp(b);
349
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
350
    tcg_temp_free_i64(tmp2);
351
    return tmp1;
352
}
353

    
354
/* Swap low and high halfwords.  */
355
static void gen_swap_half(TCGv var)
356
{
357
    TCGv tmp = new_tmp();
358
    tcg_gen_shri_i32(tmp, var, 16);
359
    tcg_gen_shli_i32(var, var, 16);
360
    tcg_gen_or_i32(var, var, tmp);
361
    dead_tmp(tmp);
362
}
363

    
364
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
365
    tmp = (t0 ^ t1) & 0x8000;
366
    t0 &= ~0x8000;
367
    t1 &= ~0x8000;
368
    t0 = (t0 + t1) ^ tmp;
369
 */
370

    
371
static void gen_add16(TCGv t0, TCGv t1)
372
{
373
    TCGv tmp = new_tmp();
374
    tcg_gen_xor_i32(tmp, t0, t1);
375
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
376
    tcg_gen_andi_i32(t0, t0, ~0x8000);
377
    tcg_gen_andi_i32(t1, t1, ~0x8000);
378
    tcg_gen_add_i32(t0, t0, t1);
379
    tcg_gen_xor_i32(t0, t0, tmp);
380
    dead_tmp(tmp);
381
    dead_tmp(t1);
382
}
383

    
384
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
385

    
386
/* Set CF to the top bit of var.  */
387
static void gen_set_CF_bit31(TCGv var)
388
{
389
    TCGv tmp = new_tmp();
390
    tcg_gen_shri_i32(tmp, var, 31);
391
    gen_set_CF(tmp);
392
    dead_tmp(tmp);
393
}
394

    
395
/* Set N and Z flags from var.  */
396
static inline void gen_logic_CC(TCGv var)
397
{
398
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
399
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
400
}
401

    
402
/* T0 += T1 + CF.  */
403
static void gen_adc(TCGv t0, TCGv t1)
404
{
405
    TCGv tmp;
406
    tcg_gen_add_i32(t0, t0, t1);
407
    tmp = load_cpu_field(CF);
408
    tcg_gen_add_i32(t0, t0, tmp);
409
    dead_tmp(tmp);
410
}
411

    
412
/* dest = T0 + T1 + CF. */
413
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
414
{
415
    TCGv tmp;
416
    tcg_gen_add_i32(dest, t0, t1);
417
    tmp = load_cpu_field(CF);
418
    tcg_gen_add_i32(dest, dest, tmp);
419
    dead_tmp(tmp);
420
}
421

    
422
/* dest = T0 - T1 + CF - 1.  */
423
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
424
{
425
    TCGv tmp;
426
    tcg_gen_sub_i32(dest, t0, t1);
427
    tmp = load_cpu_field(CF);
428
    tcg_gen_add_i32(dest, dest, tmp);
429
    tcg_gen_subi_i32(dest, dest, 1);
430
    dead_tmp(tmp);
431
}
432

    
433
/* FIXME:  Implement this natively.  */
434
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
435

    
436
static void shifter_out_im(TCGv var, int shift)
437
{
438
    TCGv tmp = new_tmp();
439
    if (shift == 0) {
440
        tcg_gen_andi_i32(tmp, var, 1);
441
    } else {
442
        tcg_gen_shri_i32(tmp, var, shift);
443
        if (shift != 31)
444
            tcg_gen_andi_i32(tmp, tmp, 1);
445
    }
446
    gen_set_CF(tmp);
447
    dead_tmp(tmp);
448
}
449

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

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

    
522
#define PAS_OP(pfx) \
523
    switch (op2) {  \
524
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
525
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
526
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
527
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
528
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
529
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
530
    }
531
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
532
{
533
    TCGv_ptr tmp;
534

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

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

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

    
615
static void gen_test_cc(int cc, int label)
616
{
617
    TCGv tmp;
618
    TCGv tmp2;
619
    int inv;
620

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

    
713
static const uint8_t table_logic_cc[16] = {
714
    1, /* and */
715
    1, /* xor */
716
    0, /* sub */
717
    0, /* rsb */
718
    0, /* add */
719
    0, /* adc */
720
    0, /* sbc */
721
    0, /* rsc */
722
    1, /* andl */
723
    1, /* xorl */
724
    0, /* cmp */
725
    0, /* cmn */
726
    1, /* orr */
727
    1, /* mov */
728
    1, /* bic */
729
    1, /* mvn */
730
};
731

    
732
/* Set PC and Thumb state from an immediate address.  */
733
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
734
{
735
    TCGv tmp;
736

    
737
    s->is_jmp = DISAS_UPDATE;
738
    if (s->thumb != (addr & 1)) {
739
        tmp = new_tmp();
740
        tcg_gen_movi_i32(tmp, addr & 1);
741
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
742
        dead_tmp(tmp);
743
    }
744
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
745
}
746

    
747
/* Set PC and Thumb state from var.  var is marked as dead.  */
748
static inline void gen_bx(DisasContext *s, TCGv var)
749
{
750
    s->is_jmp = DISAS_UPDATE;
751
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
752
    tcg_gen_andi_i32(var, var, 1);
753
    store_cpu_field(var, thumb);
754
}
755

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

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

    
826
static inline void gen_set_pc_im(uint32_t val)
827
{
828
    tcg_gen_movi_i32(cpu_R[15], val);
829
}
830

    
831
/* Force a TB lookup after an instruction that changes the CPU state.  */
832
static inline void gen_lookup_tb(DisasContext *s)
833
{
834
    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
835
    s->is_jmp = DISAS_UPDATE;
836
}
837

    
838
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
839
                                       TCGv var)
840
{
841
    int val, rm, shift, shiftop;
842
    TCGv offset;
843

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

    
866
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
867
                                        int extra, TCGv var)
868
{
869
    int val, rm;
870
    TCGv offset;
871

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

    
894
#define VFP_OP2(name)                                                 \
895
static inline void gen_vfp_##name(int dp)                             \
896
{                                                                     \
897
    if (dp)                                                           \
898
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
899
    else                                                              \
900
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
901
}
902

    
903
VFP_OP2(add)
904
VFP_OP2(sub)
905
VFP_OP2(mul)
906
VFP_OP2(div)
907

    
908
#undef VFP_OP2
909

    
910
static inline void gen_vfp_abs(int dp)
911
{
912
    if (dp)
913
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
914
    else
915
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
916
}
917

    
918
static inline void gen_vfp_neg(int dp)
919
{
920
    if (dp)
921
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
922
    else
923
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
924
}
925

    
926
static inline void gen_vfp_sqrt(int dp)
927
{
928
    if (dp)
929
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
930
    else
931
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
932
}
933

    
934
static inline void gen_vfp_cmp(int dp)
935
{
936
    if (dp)
937
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
938
    else
939
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
940
}
941

    
942
static inline void gen_vfp_cmpe(int dp)
943
{
944
    if (dp)
945
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
946
    else
947
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
948
}
949

    
950
static inline void gen_vfp_F1_ld0(int dp)
951
{
952
    if (dp)
953
        tcg_gen_movi_i64(cpu_F1d, 0);
954
    else
955
        tcg_gen_movi_i32(cpu_F1s, 0);
956
}
957

    
958
static inline void gen_vfp_uito(int dp)
959
{
960
    if (dp)
961
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
962
    else
963
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
964
}
965

    
966
static inline void gen_vfp_sito(int dp)
967
{
968
    if (dp)
969
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
970
    else
971
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
972
}
973

    
974
static inline void gen_vfp_toui(int dp)
975
{
976
    if (dp)
977
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
978
    else
979
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
980
}
981

    
982
static inline void gen_vfp_touiz(int dp)
983
{
984
    if (dp)
985
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
986
    else
987
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
988
}
989

    
990
static inline void gen_vfp_tosi(int dp)
991
{
992
    if (dp)
993
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
994
    else
995
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
996
}
997

    
998
static inline void gen_vfp_tosiz(int dp)
999
{
1000
    if (dp)
1001
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1002
    else
1003
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1004
}
1005

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

    
1026
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
1027
{
1028
    if (dp)
1029
        tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1030
    else
1031
        tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1032
}
1033

    
1034
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
1035
{
1036
    if (dp)
1037
        tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1038
    else
1039
        tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1040
}
1041

    
1042
static inline long
1043
vfp_reg_offset (int dp, int reg)
1044
{
1045
    if (dp)
1046
        return offsetof(CPUARMState, vfp.regs[reg]);
1047
    else if (reg & 1) {
1048
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1049
          + offsetof(CPU_DoubleU, l.upper);
1050
    } else {
1051
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1052
          + offsetof(CPU_DoubleU, l.lower);
1053
    }
1054
}
1055

    
1056
/* Return the offset of a 32-bit piece of a NEON register.
1057
   zero is the least significant end of the register.  */
1058
static inline long
1059
neon_reg_offset (int reg, int n)
1060
{
1061
    int sreg;
1062
    sreg = reg * 2 + n;
1063
    return vfp_reg_offset(0, sreg);
1064
}
1065

    
1066
static TCGv neon_load_reg(int reg, int pass)
1067
{
1068
    TCGv tmp = new_tmp();
1069
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1070
    return tmp;
1071
}
1072

    
1073
static void neon_store_reg(int reg, int pass, TCGv var)
1074
{
1075
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1076
    dead_tmp(var);
1077
}
1078

    
1079
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1080
{
1081
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1082
}
1083

    
1084
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1085
{
1086
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1087
}
1088

    
1089
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1090
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1091
#define tcg_gen_st_f32 tcg_gen_st_i32
1092
#define tcg_gen_st_f64 tcg_gen_st_i64
1093

    
1094
static inline void gen_mov_F0_vreg(int dp, int reg)
1095
{
1096
    if (dp)
1097
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1098
    else
1099
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1100
}
1101

    
1102
static inline void gen_mov_F1_vreg(int dp, int reg)
1103
{
1104
    if (dp)
1105
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1106
    else
1107
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1108
}
1109

    
1110
static inline void gen_mov_vreg_F0(int dp, int reg)
1111
{
1112
    if (dp)
1113
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1114
    else
1115
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1116
}
1117

    
1118
#define ARM_CP_RW_BIT        (1 << 20)
1119

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

    
1125
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1126
{
1127
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1128
}
1129

    
1130
static inline TCGv iwmmxt_load_creg(int reg)
1131
{
1132
    TCGv var = new_tmp();
1133
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1134
    return var;
1135
}
1136

    
1137
static inline void iwmmxt_store_creg(int reg, TCGv var)
1138
{
1139
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1140
    dead_tmp(var);
1141
}
1142

    
1143
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1144
{
1145
    iwmmxt_store_reg(cpu_M0, rn);
1146
}
1147

    
1148
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1149
{
1150
    iwmmxt_load_reg(cpu_M0, rn);
1151
}
1152

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

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

    
1165
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1166
{
1167
    iwmmxt_load_reg(cpu_V1, rn);
1168
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1169
}
1170

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

    
1178
#define IWMMXT_OP_ENV(name) \
1179
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1180
{ \
1181
    iwmmxt_load_reg(cpu_V1, rn); \
1182
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1183
}
1184

    
1185
#define IWMMXT_OP_ENV_SIZE(name) \
1186
IWMMXT_OP_ENV(name##b) \
1187
IWMMXT_OP_ENV(name##w) \
1188
IWMMXT_OP_ENV(name##l)
1189

    
1190
#define IWMMXT_OP_ENV1(name) \
1191
static inline void gen_op_iwmmxt_##name##_M0(void) \
1192
{ \
1193
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1194
}
1195

    
1196
IWMMXT_OP(maddsq)
1197
IWMMXT_OP(madduq)
1198
IWMMXT_OP(sadb)
1199
IWMMXT_OP(sadw)
1200
IWMMXT_OP(mulslw)
1201
IWMMXT_OP(mulshw)
1202
IWMMXT_OP(mululw)
1203
IWMMXT_OP(muluhw)
1204
IWMMXT_OP(macsw)
1205
IWMMXT_OP(macuw)
1206

    
1207
IWMMXT_OP_ENV_SIZE(unpackl)
1208
IWMMXT_OP_ENV_SIZE(unpackh)
1209

    
1210
IWMMXT_OP_ENV1(unpacklub)
1211
IWMMXT_OP_ENV1(unpackluw)
1212
IWMMXT_OP_ENV1(unpacklul)
1213
IWMMXT_OP_ENV1(unpackhub)
1214
IWMMXT_OP_ENV1(unpackhuw)
1215
IWMMXT_OP_ENV1(unpackhul)
1216
IWMMXT_OP_ENV1(unpacklsb)
1217
IWMMXT_OP_ENV1(unpacklsw)
1218
IWMMXT_OP_ENV1(unpacklsl)
1219
IWMMXT_OP_ENV1(unpackhsb)
1220
IWMMXT_OP_ENV1(unpackhsw)
1221
IWMMXT_OP_ENV1(unpackhsl)
1222

    
1223
IWMMXT_OP_ENV_SIZE(cmpeq)
1224
IWMMXT_OP_ENV_SIZE(cmpgtu)
1225
IWMMXT_OP_ENV_SIZE(cmpgts)
1226

    
1227
IWMMXT_OP_ENV_SIZE(mins)
1228
IWMMXT_OP_ENV_SIZE(minu)
1229
IWMMXT_OP_ENV_SIZE(maxs)
1230
IWMMXT_OP_ENV_SIZE(maxu)
1231

    
1232
IWMMXT_OP_ENV_SIZE(subn)
1233
IWMMXT_OP_ENV_SIZE(addn)
1234
IWMMXT_OP_ENV_SIZE(subu)
1235
IWMMXT_OP_ENV_SIZE(addu)
1236
IWMMXT_OP_ENV_SIZE(subs)
1237
IWMMXT_OP_ENV_SIZE(adds)
1238

    
1239
IWMMXT_OP_ENV(avgb0)
1240
IWMMXT_OP_ENV(avgb1)
1241
IWMMXT_OP_ENV(avgw0)
1242
IWMMXT_OP_ENV(avgw1)
1243

    
1244
IWMMXT_OP(msadb)
1245

    
1246
IWMMXT_OP_ENV(packuw)
1247
IWMMXT_OP_ENV(packul)
1248
IWMMXT_OP_ENV(packuq)
1249
IWMMXT_OP_ENV(packsw)
1250
IWMMXT_OP_ENV(packsl)
1251
IWMMXT_OP_ENV(packsq)
1252

    
1253
static void gen_op_iwmmxt_set_mup(void)
1254
{
1255
    TCGv tmp;
1256
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1257
    tcg_gen_ori_i32(tmp, tmp, 2);
1258
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1259
}
1260

    
1261
static void gen_op_iwmmxt_set_cup(void)
1262
{
1263
    TCGv tmp;
1264
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1265
    tcg_gen_ori_i32(tmp, tmp, 1);
1266
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1267
}
1268

    
1269
static void gen_op_iwmmxt_setpsr_nz(void)
1270
{
1271
    TCGv tmp = new_tmp();
1272
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1273
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1274
}
1275

    
1276
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1277
{
1278
    iwmmxt_load_reg(cpu_V1, rn);
1279
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1280
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1281
}
1282

    
1283
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1284
{
1285
    int rd;
1286
    uint32_t offset;
1287
    TCGv tmp;
1288

    
1289
    rd = (insn >> 16) & 0xf;
1290
    tmp = load_reg(s, rd);
1291

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

    
1317
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1318
{
1319
    int rd = (insn >> 0) & 0xf;
1320
    TCGv tmp;
1321

    
1322
    if (insn & (1 << 8)) {
1323
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1324
            return 1;
1325
        } else {
1326
            tmp = iwmmxt_load_creg(rd);
1327
        }
1328
    } else {
1329
        tmp = new_tmp();
1330
        iwmmxt_load_reg(cpu_V0, rd);
1331
        tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1332
    }
1333
    tcg_gen_andi_i32(tmp, tmp, mask);
1334
    tcg_gen_mov_i32(dest, tmp);
1335
    dead_tmp(tmp);
1336
    return 0;
1337
}
1338

    
1339
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1340
   (ie. an undefined instruction).  */
1341
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1342
{
1343
    int rd, wrd;
1344
    int rdhi, rdlo, rd0, rd1, i;
1345
    TCGv addr;
1346
    TCGv tmp, tmp2, tmp3;
1347

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

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

    
1429
    if ((insn & 0x0f000000) != 0x0e000000)
1430
        return 1;
1431

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

    
2340
    return 0;
2341
}
2342

    
2343
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2344
   (ie. an undefined instruction).  */
2345
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2346
{
2347
    int acc, rd0, rd1, rdhi, rdlo;
2348
    TCGv tmp, tmp2;
2349

    
2350
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2351
        /* Multiply with Internal Accumulate Format */
2352
        rd0 = (insn >> 12) & 0xf;
2353
        rd1 = insn & 0xf;
2354
        acc = (insn >> 5) & 7;
2355

    
2356
        if (acc != 0)
2357
            return 1;
2358

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

    
2384
        gen_op_iwmmxt_movq_wRn_M0(acc);
2385
        return 0;
2386
    }
2387

    
2388
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2389
        /* Internal Accumulator Access Format */
2390
        rdhi = (insn >> 16) & 0xf;
2391
        rdlo = (insn >> 12) & 0xf;
2392
        acc = insn & 7;
2393

    
2394
        if (acc != 0)
2395
            return 1;
2396

    
2397
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2398
            iwmmxt_load_reg(cpu_V0, acc);
2399
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2400
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2401
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2402
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2403
        } else {                                        /* MAR */
2404
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2405
            iwmmxt_store_reg(cpu_V0, acc);
2406
        }
2407
        return 0;
2408
    }
2409

    
2410
    return 1;
2411
}
2412

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

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

    
2446
static int cp15_user_ok(uint32_t insn)
2447
{
2448
    int cpn = (insn >> 16) & 0xf;
2449
    int cpm = insn & 0xf;
2450
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2451

    
2452
    if (cpn == 13 && cpm == 0) {
2453
        /* TLS register.  */
2454
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2455
            return 1;
2456
    }
2457
    if (cpn == 7) {
2458
        /* ISB, DSB, DMB.  */
2459
        if ((cpm == 5 && op == 4)
2460
                || (cpm == 10 && (op == 4 || op == 5)))
2461
            return 1;
2462
    }
2463
    return 0;
2464
}
2465

    
2466
static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd)
2467
{
2468
    TCGv tmp;
2469
    int cpn = (insn >> 16) & 0xf;
2470
    int cpm = insn & 0xf;
2471
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2472

    
2473
    if (!arm_feature(env, ARM_FEATURE_V6K))
2474
        return 0;
2475

    
2476
    if (!(cpn == 13 && cpm == 0))
2477
        return 0;
2478

    
2479
    if (insn & ARM_CP_RW_BIT) {
2480
        switch (op) {
2481
        case 2:
2482
            tmp = load_cpu_field(cp15.c13_tls1);
2483
            break;
2484
        case 3:
2485
            tmp = load_cpu_field(cp15.c13_tls2);
2486
            break;
2487
        case 4:
2488
            tmp = load_cpu_field(cp15.c13_tls3);
2489
            break;
2490
        default:
2491
            return 0;
2492
        }
2493
        store_reg(s, rd, tmp);
2494

    
2495
    } else {
2496
        tmp = load_reg(s, rd);
2497
        switch (op) {
2498
        case 2:
2499
            store_cpu_field(tmp, cp15.c13_tls1);
2500
            break;
2501
        case 3:
2502
            store_cpu_field(tmp, cp15.c13_tls2);
2503
            break;
2504
        case 4:
2505
            store_cpu_field(tmp, cp15.c13_tls3);
2506
            break;
2507
        default:
2508
            dead_tmp(tmp);
2509
            return 0;
2510
        }
2511
    }
2512
    return 1;
2513
}
2514

    
2515
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2516
   instruction is not defined.  */
2517
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2518
{
2519
    uint32_t rd;
2520
    TCGv tmp, tmp2;
2521

    
2522
    /* M profile cores use memory mapped registers instead of cp15.  */
2523
    if (arm_feature(env, ARM_FEATURE_M))
2524
        return 1;
2525

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

    
2550
    if (cp15_tls_load_store(env, s, insn, rd))
2551
        return 0;
2552

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

    
2577
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2578
#define VFP_SREG(insn, bigbit, smallbit) \
2579
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2580
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2581
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2582
        reg = (((insn) >> (bigbit)) & 0x0f) \
2583
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2584
    } else { \
2585
        if (insn & (1 << (smallbit))) \
2586
            return 1; \
2587
        reg = ((insn) >> (bigbit)) & 0x0f; \
2588
    }} while (0)
2589

    
2590
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2591
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2592
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2593
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2594
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2595
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2596

    
2597
/* Move between integer and VFP cores.  */
2598
static TCGv gen_vfp_mrs(void)
2599
{
2600
    TCGv tmp = new_tmp();
2601
    tcg_gen_mov_i32(tmp, cpu_F0s);
2602
    return tmp;
2603
}
2604

    
2605
static void gen_vfp_msr(TCGv tmp)
2606
{
2607
    tcg_gen_mov_i32(cpu_F0s, tmp);
2608
    dead_tmp(tmp);
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 (!s->vfp_enabled) {
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 & 0x1c) == 0x18))) {
2874
                    /* Integer or single precision destination.  */
2875
                    rd = VFP_SREG_D(insn);
2876
                } else {
2877
                    VFP_DREG_D(rd, insn);
2878
                }
2879
                if (op == 15 &&
2880
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2881
                    /* VCVT from int is always from S reg regardless of dp bit.
2882
                     * VCVT with immediate frac_bits has same format as SREG_M
2883
                     */
2884
                    rm = VFP_SREG_M(insn);
2885
                } else {
2886
                    VFP_DREG_M(rm, insn);
2887
                }
2888
            } else {
2889
                rn = VFP_SREG_N(insn);
2890
                if (op == 15 && rn == 15) {
2891
                    /* Double precision destination.  */
2892
                    VFP_DREG_D(rd, insn);
2893
                } else {
2894
                    rd = VFP_SREG_D(insn);
2895
                }
2896
                /* NB that we implicitly rely on the encoding for the frac_bits
2897
                 * in VCVT of fixed to float being the same as that of an SREG_M
2898
                 */
2899
                rm = VFP_SREG_M(insn);
2900
            }
2901

    
2902
            veclen = s->vec_len;
2903
            if (op == 15 && rn > 3)
2904
                veclen = 0;
2905

    
2906
            /* Shut up compiler warnings.  */
2907
            delta_m = 0;
2908
            delta_d = 0;
2909
            bank_mask = 0;
2910

    
2911
            if (veclen > 0) {
2912
                if (dp)
2913
                    bank_mask = 0xc;
2914
                else
2915
                    bank_mask = 0x18;
2916

    
2917
                /* Figure out what type of vector operation this is.  */
2918
                if ((rd & bank_mask) == 0) {
2919
                    /* scalar */
2920
                    veclen = 0;
2921
                } else {
2922
                    if (dp)
2923
                        delta_d = (s->vec_stride >> 1) + 1;
2924
                    else
2925
                        delta_d = s->vec_stride + 1;
2926

    
2927
                    if ((rm & bank_mask) == 0) {
2928
                        /* mixed scalar/vector */
2929
                        delta_m = 0;
2930
                    } else {
2931
                        /* vector */
2932
                        delta_m = delta_d;
2933
                    }
2934
                }
2935
            }
2936

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

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

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

    
3184
                /* Write back the result.  */
3185
                if (op == 15 && (rn >= 8 && rn <= 11))
3186
                    ; /* Comparison, do nothing.  */
3187
                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3188
                    /* VCVT double to int: always integer result. */
3189
                    gen_mov_vreg_F0(0, rd);
3190
                else if (op == 15 && rn == 15)
3191
                    /* conversion */
3192
                    gen_mov_vreg_F0(!dp, rd);
3193
                else
3194
                    gen_mov_vreg_F0(dp, rd);
3195

    
3196
                /* break out of the loop if we have finished  */
3197
                if (veclen == 0)
3198
                    break;
3199

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

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

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

    
3314
                if (insn & (1 << 24)) /* pre-decrement */
3315
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3316

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

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

    
3358
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3359
{
3360
    TranslationBlock *tb;
3361

    
3362
    tb = s->tb;
3363
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3364
        tcg_gen_goto_tb(n);
3365
        gen_set_pc_im(dest);
3366
        tcg_gen_exit_tb((long)tb + n);
3367
    } else {
3368
        gen_set_pc_im(dest);
3369
        tcg_gen_exit_tb(0);
3370
    }
3371
}
3372

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

    
3386
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3387
{
3388
    if (x)
3389
        tcg_gen_sari_i32(t0, t0, 16);
3390
    else
3391
        gen_sxth(t0);
3392
    if (y)
3393
        tcg_gen_sari_i32(t1, t1, 16);
3394
    else
3395
        gen_sxth(t1);
3396
    tcg_gen_mul_i32(t0, t0, t1);
3397
}
3398

    
3399
/* Return the mask of PSR bits set by a MSR instruction.  */
3400
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3401
    uint32_t mask;
3402

    
3403
    mask = 0;
3404
    if (flags & (1 << 0))
3405
        mask |= 0xff;
3406
    if (flags & (1 << 1))
3407
        mask |= 0xff00;
3408
    if (flags & (1 << 2))
3409
        mask |= 0xff0000;
3410
    if (flags & (1 << 3))
3411
        mask |= 0xff000000;
3412

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

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

    
3437
        tmp = load_cpu_field(spsr);
3438
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3439
        tcg_gen_andi_i32(t0, t0, mask);
3440
        tcg_gen_or_i32(tmp, tmp, t0);
3441
        store_cpu_field(tmp, spsr);
3442
    } else {
3443
        gen_set_cpsr(t0, mask);
3444
    }
3445
    dead_tmp(t0);
3446
    gen_lookup_tb(s);
3447
    return 0;
3448
}
3449

    
3450
/* Returns nonzero if access to the PSR is not permitted.  */
3451
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3452
{
3453
    TCGv tmp;
3454
    tmp = new_tmp();
3455
    tcg_gen_movi_i32(tmp, val);
3456
    return gen_set_psr(s, mask, spsr, tmp);
3457
}
3458

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

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

    
3479
static inline void
3480
gen_set_condexec (DisasContext *s)
3481
{
3482
    if (s->condexec_mask) {
3483
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3484
        TCGv tmp = new_tmp();
3485
        tcg_gen_movi_i32(tmp, val);
3486
        store_cpu_field(tmp, condexec_bits);
3487
    }
3488
}
3489

    
3490
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3491
{
3492
    gen_set_condexec(s);
3493
    gen_set_pc_im(s->pc - offset);
3494
    gen_exception(excp);
3495
    s->is_jmp = DISAS_JUMP;
3496
}
3497

    
3498
static void gen_nop_hint(DisasContext *s, int val)
3499
{
3500
    switch (val) {
3501
    case 3: /* wfi */
3502
        gen_set_pc_im(s->pc);
3503
        s->is_jmp = DISAS_WFI;
3504
        break;
3505
    case 2: /* wfe */
3506
    case 4: /* sev */
3507
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3508
    default: /* nop */
3509
        break;
3510
    }
3511
}
3512

    
3513
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3514

    
3515
static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3516
{
3517
    switch (size) {
3518
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3519
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3520
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3521
    default: return 1;
3522
    }
3523
    return 0;
3524
}
3525

    
3526
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3527
{
3528
    switch (size) {
3529
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3530
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3531
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3532
    default: return;
3533
    }
3534
}
3535

    
3536
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3537
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3538
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3539
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3540
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3541

    
3542
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3543
    switch ((size << 1) | u) { \
3544
    case 0: \
3545
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3546
        break; \
3547
    case 1: \
3548
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3549
        break; \
3550
    case 2: \
3551
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3552
        break; \
3553
    case 3: \
3554
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3555
        break; \
3556
    case 4: \
3557
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3558
        break; \
3559
    case 5: \
3560
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3561
        break; \
3562
    default: return 1; \
3563
    }} while (0)
3564

    
3565
#define GEN_NEON_INTEGER_OP(name) do { \
3566
    switch ((size << 1) | u) { \
3567
    case 0: \
3568
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3569
        break; \
3570
    case 1: \
3571
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3572
        break; \
3573
    case 2: \
3574
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3575
        break; \
3576
    case 3: \
3577
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3578
        break; \
3579
    case 4: \
3580
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3581
        break; \
3582
    case 5: \
3583
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3584
        break; \
3585
    default: return 1; \
3586
    }} while (0)
3587

    
3588
static TCGv neon_load_scratch(int scratch)
3589
{
3590
    TCGv tmp = new_tmp();
3591
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3592
    return tmp;
3593
}
3594

    
3595
static void neon_store_scratch(int scratch, TCGv var)
3596
{
3597
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3598
    dead_tmp(var);
3599
}
3600

    
3601
static inline TCGv neon_get_scalar(int size, int reg)
3602
{
3603
    TCGv tmp;
3604
    if (size == 1) {
3605
        tmp = neon_load_reg(reg & 7, reg >> 4);
3606
        if (reg & 8) {
3607
            gen_neon_dup_high16(tmp);
3608
        } else {
3609
            gen_neon_dup_low16(tmp);
3610
        }
3611
    } else {
3612
        tmp = neon_load_reg(reg & 15, reg >> 4);
3613
    }
3614
    return tmp;
3615
}
3616

    
3617
static void gen_neon_unzip_u8(TCGv t0, TCGv t1)
3618
{
3619
    TCGv rd, rm, tmp;
3620

    
3621
    rd = new_tmp();
3622
    rm = new_tmp();
3623
    tmp = new_tmp();
3624

    
3625
    tcg_gen_andi_i32(rd, t0, 0xff);
3626
    tcg_gen_shri_i32(tmp, t0, 8);
3627
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3628
    tcg_gen_or_i32(rd, rd, tmp);
3629
    tcg_gen_shli_i32(tmp, t1, 16);
3630
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3631
    tcg_gen_or_i32(rd, rd, tmp);
3632
    tcg_gen_shli_i32(tmp, t1, 8);
3633
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3634
    tcg_gen_or_i32(rd, rd, tmp);
3635

    
3636
    tcg_gen_shri_i32(rm, t0, 8);
3637
    tcg_gen_andi_i32(rm, rm, 0xff);
3638
    tcg_gen_shri_i32(tmp, t0, 16);
3639
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3640
    tcg_gen_or_i32(rm, rm, tmp);
3641
    tcg_gen_shli_i32(tmp, t1, 8);
3642
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3643
    tcg_gen_or_i32(rm, rm, tmp);
3644
    tcg_gen_andi_i32(tmp, t1, 0xff000000);
3645
    tcg_gen_or_i32(t1, rm, tmp);
3646
    tcg_gen_mov_i32(t0, rd);
3647

    
3648
    dead_tmp(tmp);
3649
    dead_tmp(rm);
3650
    dead_tmp(rd);
3651
}
3652

    
3653
static void gen_neon_zip_u8(TCGv t0, TCGv t1)
3654
{
3655
    TCGv rd, rm, tmp;
3656

    
3657
    rd = new_tmp();
3658
    rm = new_tmp();
3659
    tmp = new_tmp();
3660

    
3661
    tcg_gen_andi_i32(rd, t0, 0xff);
3662
    tcg_gen_shli_i32(tmp, t1, 8);
3663
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3664
    tcg_gen_or_i32(rd, rd, tmp);
3665
    tcg_gen_shli_i32(tmp, t0, 16);
3666
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3667
    tcg_gen_or_i32(rd, rd, tmp);
3668
    tcg_gen_shli_i32(tmp, t1, 24);
3669
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3670
    tcg_gen_or_i32(rd, rd, tmp);
3671

    
3672
    tcg_gen_andi_i32(rm, t1, 0xff000000);
3673
    tcg_gen_shri_i32(tmp, t0, 8);
3674
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3675
    tcg_gen_or_i32(rm, rm, tmp);
3676
    tcg_gen_shri_i32(tmp, t1, 8);
3677
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3678
    tcg_gen_or_i32(rm, rm, tmp);
3679
    tcg_gen_shri_i32(tmp, t0, 16);
3680
    tcg_gen_andi_i32(tmp, tmp, 0xff);
3681
    tcg_gen_or_i32(t1, rm, tmp);
3682
    tcg_gen_mov_i32(t0, rd);
3683

    
3684
    dead_tmp(tmp);
3685
    dead_tmp(rm);
3686
    dead_tmp(rd);
3687
}
3688

    
3689
static void gen_neon_zip_u16(TCGv t0, TCGv t1)
3690
{
3691
    TCGv tmp, tmp2;
3692

    
3693
    tmp = new_tmp();
3694
    tmp2 = new_tmp();
3695

    
3696
    tcg_gen_andi_i32(tmp, t0, 0xffff);
3697
    tcg_gen_shli_i32(tmp2, t1, 16);
3698
    tcg_gen_or_i32(tmp, tmp, tmp2);
3699
    tcg_gen_andi_i32(t1, t1, 0xffff0000);
3700
    tcg_gen_shri_i32(tmp2, t0, 16);
3701
    tcg_gen_or_i32(t1, t1, tmp2);
3702
    tcg_gen_mov_i32(t0, tmp);
3703

    
3704
    dead_tmp(tmp2);
3705
    dead_tmp(tmp);
3706
}
3707

    
3708
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3709
{
3710
    int n;
3711
    TCGv t0, t1;
3712

    
3713
    for (n = 0; n < q + 1; n += 2) {
3714
        t0 = neon_load_reg(reg, n);
3715
        t1 = neon_load_reg(reg, n + 1);
3716
        switch (size) {
3717
        case 0: gen_neon_unzip_u8(t0, t1); break;
3718
        case 1: gen_neon_zip_u16(t0, t1); break; /* zip and unzip are the same.  */
3719
        case 2: /* no-op */; break;
3720
        default: abort();
3721
        }
3722
        neon_store_scratch(tmp + n, t0);
3723
        neon_store_scratch(tmp + n + 1, t1);
3724
    }
3725
}
3726

    
3727
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3728
{
3729
    TCGv rd, tmp;
3730

    
3731
    rd = new_tmp();
3732
    tmp = new_tmp();
3733

    
3734
    tcg_gen_shli_i32(rd, t0, 8);
3735
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3736
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3737
    tcg_gen_or_i32(rd, rd, tmp);
3738

    
3739
    tcg_gen_shri_i32(t1, t1, 8);
3740
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3741
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3742
    tcg_gen_or_i32(t1, t1, tmp);
3743
    tcg_gen_mov_i32(t0, rd);
3744

    
3745
    dead_tmp(tmp);
3746
    dead_tmp(rd);
3747
}
3748

    
3749
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3750
{
3751
    TCGv rd, tmp;
3752

    
3753
    rd = new_tmp();
3754
    tmp = new_tmp();
3755

    
3756
    tcg_gen_shli_i32(rd, t0, 16);
3757
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3758
    tcg_gen_or_i32(rd, rd, tmp);
3759
    tcg_gen_shri_i32(t1, t1, 16);
3760
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3761
    tcg_gen_or_i32(t1, t1, tmp);
3762
    tcg_gen_mov_i32(t0, rd);
3763

    
3764
    dead_tmp(tmp);
3765
    dead_tmp(rd);
3766
}
3767

    
3768

    
3769
static struct {
3770
    int nregs;
3771
    int interleave;
3772
    int spacing;
3773
} neon_ls_element_type[11] = {
3774
    {4, 4, 1},
3775
    {4, 4, 2},
3776
    {4, 1, 1},
3777
    {4, 2, 1},
3778
    {3, 3, 1},
3779
    {3, 3, 2},
3780
    {3, 1, 1},
3781
    {1, 1, 1},
3782
    {2, 2, 1},
3783
    {2, 2, 2},
3784
    {2, 1, 1}
3785
};
3786

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

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

    
4016
        base = load_reg(s, rn);
4017
        if (rm == 13) {
4018
            tcg_gen_addi_i32(base, base, stride);
4019
        } else {
4020
            TCGv index;
4021
            index = load_reg(s, rm);
4022
            tcg_gen_add_i32(base, base, index);
4023
            dead_tmp(index);
4024
        }
4025
        store_reg(s, rn, base);
4026
    }
4027
    return 0;
4028
}
4029

    
4030
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4031
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4032
{
4033
    tcg_gen_and_i32(t, t, c);
4034
    tcg_gen_andc_i32(f, f, c);
4035
    tcg_gen_or_i32(dest, t, f);
4036
}
4037

    
4038
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4039
{
4040
    switch (size) {
4041
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4042
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4043
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4044
    default: abort();
4045
    }
4046
}
4047

    
4048
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4049
{
4050
    switch (size) {
4051
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4052
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4053
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4054
    default: abort();
4055
    }
4056
}
4057

    
4058
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4059
{
4060
    switch (size) {
4061
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4062
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4063
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4064
    default: abort();
4065
    }
4066
}
4067

    
4068
static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4069
{
4070
    switch (size) {
4071
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4072
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4073
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4074
    default: abort();
4075
    }
4076
}
4077

    
4078
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4079
                                         int q, int u)
4080
{
4081
    if (q) {
4082
        if (u) {
4083
            switch (size) {
4084
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4085
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4086
            default: abort();
4087
            }
4088
        } else {
4089
            switch (size) {
4090
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4091
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4092
            default: abort();
4093
            }
4094
        }
4095
    } else {
4096
        if (u) {
4097
            switch (size) {
4098
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4099
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4100
            default: abort();
4101
            }
4102
        } else {
4103
            switch (size) {
4104
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4105
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4106
            default: abort();
4107
            }
4108
        }
4109
    }
4110
}
4111

    
4112
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4113
{
4114
    if (u) {
4115
        switch (size) {
4116
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4117
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4118
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4119
        default: abort();
4120
        }
4121
    } else {
4122
        switch (size) {
4123
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4124
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4125
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4126
        default: abort();
4127
        }
4128
    }
4129
    dead_tmp(src);
4130
}
4131

    
4132
static inline void gen_neon_addl(int size)
4133
{
4134
    switch (size) {
4135
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4136
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4137
    case 2: tcg_gen_add_i64(CPU_V001); break;
4138
    default: abort();
4139
    }
4140
}
4141

    
4142
static inline void gen_neon_subl(int size)
4143
{
4144
    switch (size) {
4145
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4146
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4147
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4148
    default: abort();
4149
    }
4150
}
4151

    
4152
static inline void gen_neon_negl(TCGv_i64 var, int size)
4153
{
4154
    switch (size) {
4155
    case 0: gen_helper_neon_negl_u16(var, var); break;
4156
    case 1: gen_helper_neon_negl_u32(var, var); break;
4157
    case 2: gen_helper_neon_negl_u64(var, var); break;
4158
    default: abort();
4159
    }
4160
}
4161

    
4162
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4163
{
4164
    switch (size) {
4165
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4166
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4167
    default: abort();
4168
    }
4169
}
4170

    
4171
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4172
{
4173
    TCGv_i64 tmp;
4174

    
4175
    switch ((size << 1) | u) {
4176
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4177
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4178
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4179
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4180
    case 4:
4181
        tmp = gen_muls_i64_i32(a, b);
4182
        tcg_gen_mov_i64(dest, tmp);
4183
        break;
4184
    case 5:
4185
        tmp = gen_mulu_i64_i32(a, b);
4186
        tcg_gen_mov_i64(dest, tmp);
4187
        break;
4188
    default: abort();
4189
    }
4190

    
4191
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4192
       Don't forget to clean them now.  */
4193
    if (size < 2) {
4194
      dead_tmp(a);
4195
      dead_tmp(b);
4196
    }
4197
}
4198

    
4199
/* Translate a NEON data processing instruction.  Return nonzero if the
4200
   instruction is invalid.
4201
   We process data in a mixture of 32-bit and 64-bit chunks.
4202
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4203

    
4204
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4205
{
4206
    int op;
4207
    int q;
4208
    int rd, rn, rm;
4209
    int size;
4210
    int shift;
4211
    int pass;
4212
    int count;
4213
    int pairwise;
4214
    int u;
4215
    int n;
4216
    uint32_t imm, mask;
4217
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4218
    TCGv_i64 tmp64;
4219

    
4220
    if (!s->vfp_enabled)
4221
      return 1;
4222
    q = (insn & (1 << 6)) != 0;
4223
    u = (insn >> 24) & 1;
4224
    VFP_DREG_D(rd, insn);
4225
    VFP_DREG_N(rn, insn);
4226
    VFP_DREG_M(rm, insn);
4227
    size = (insn >> 20) & 3;
4228
    if ((insn & (1 << 23)) == 0) {
4229
        /* Three register same length.  */
4230
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4231
        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4232
                          || op == 10 || op  == 11 || op == 16)) {
4233
            /* 64-bit element instructions.  */
4234
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4235
                neon_load_reg64(cpu_V0, rn + pass);
4236
                neon_load_reg64(cpu_V1, rm + pass);
4237
                switch (op) {
4238
                case 1: /* VQADD */
4239
                    if (u) {
4240
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4241
                                                 cpu_V0, cpu_V1);
4242
                    } else {
4243
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4244
                                                 cpu_V0, cpu_V1);
4245
                    }
4246
                    break;
4247
                case 5: /* VQSUB */
4248
                    if (u) {
4249
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4250
                                                 cpu_V0, cpu_V1);
4251
                    } else {
4252
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4253
                                                 cpu_V0, cpu_V1);
4254
                    }
4255
                    break;
4256
                case 8: /* VSHL */
4257
                    if (u) {
4258
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4259
                    } else {
4260
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4261
                    }
4262
                    break;
4263
                case 9: /* VQSHL */
4264
                    if (u) {
4265
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4266
                                                 cpu_V1, cpu_V0);
4267
                    } else {
4268
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4269
                                                 cpu_V1, cpu_V0);
4270
                    }
4271
                    break;
4272
                case 10: /* VRSHL */
4273
                    if (u) {
4274
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4275
                    } else {
4276
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4277
                    }
4278
                    break;
4279
                case 11: /* VQRSHL */
4280
                    if (u) {
4281
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4282
                                                  cpu_V1, cpu_V0);
4283
                    } else {
4284
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4285
                                                  cpu_V1, cpu_V0);
4286
                    }
4287
                    break;
4288
                case 16:
4289
                    if (u) {
4290
                        tcg_gen_sub_i64(CPU_V001);
4291
                    } else {
4292
                        tcg_gen_add_i64(CPU_V001);
4293
                    }
4294
                    break;
4295
                default:
4296
                    abort();
4297
                }
4298
                neon_store_reg64(cpu_V0, rd + pass);
4299
            }
4300
            return 0;
4301
        }
4302
        switch (op) {
4303
        case 8: /* VSHL */
4304
        case 9: /* VQSHL */
4305
        case 10: /* VRSHL */
4306
        case 11: /* VQRSHL */
4307
            {
4308
                int rtmp;
4309
                /* Shift instruction operands are reversed.  */
4310
                rtmp = rn;
4311
                rn = rm;
4312
                rm = rtmp;
4313
                pairwise = 0;
4314
            }
4315
            break;
4316
        case 20: /* VPMAX */
4317
        case 21: /* VPMIN */
4318
        case 23: /* VPADD */
4319
            pairwise = 1;
4320
            break;
4321
        case 26: /* VPADD (float) */
4322
            pairwise = (u && size < 2);
4323
            break;
4324
        case 30: /* VPMIN/VPMAX (float) */
4325
            pairwise = u;
4326
            break;
4327
        default:
4328
            pairwise = 0;
4329
            break;
4330
        }
4331

    
4332
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4333

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

    
4588
        /* Save the result.  For elementwise operations we can put it
4589
           straight into the destination register.  For pairwise operations
4590
           we have to be careful to avoid clobbering the source operands.  */
4591
        if (pairwise && rd == rm) {
4592
            neon_store_scratch(pass, tmp);
4593
        } else {
4594
            neon_store_reg(rd, pass, tmp);
4595
        }
4596

    
4597
        } /* for pass */
4598
        if (pairwise && rd == rm) {
4599
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4600
                tmp = neon_load_scratch(pass);
4601
                neon_store_reg(rd, pass, tmp);
4602
            }
4603
        }
4604
        /* End of 3 register same size operations.  */
4605
    } else if (insn & (1 << 4)) {
4606
        if ((insn & 0x00380080) != 0) {
4607
            /* Two registers and shift.  */
4608
            op = (insn >> 8) & 0xf;
4609
            if (insn & (1 << 7)) {
4610
                /* 64-bit shift.   */
4611
                size = 3;
4612
            } else {
4613
                size = 2;
4614
                while ((insn & (1 << (size + 19))) == 0)
4615
                    size--;
4616
            }
4617
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4618
            /* To avoid excessive dumplication of ops we implement shift
4619
               by immediate using the variable shift operations.  */
4620
            if (op < 8) {
4621
                /* Shift by immediate:
4622
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4623
                /* Right shifts are encoded as N - shift, where N is the
4624
                   element size in bits.  */
4625
                if (op <= 4)
4626
                    shift = shift - (1 << (size + 3));
4627
                if (size == 3) {
4628
                    count = q + 1;
4629
                } else {
4630
                    count = q ? 4: 2;
4631
                }
4632
                switch (size) {
4633
                case 0:
4634
                    imm = (uint8_t) shift;
4635
                    imm |= imm << 8;
4636
                    imm |= imm << 16;
4637
                    break;
4638
                case 1:
4639
                    imm = (uint16_t) shift;
4640
                    imm |= imm << 16;
4641
                    break;
4642
                case 2:
4643
                case 3:
4644
                    imm = shift;
4645
                    break;
4646
                default:
4647
                    abort();
4648
                }
4649

    
4650
                for (pass = 0; pass < count; pass++) {
4651
                    if (size == 3) {
4652
                        neon_load_reg64(cpu_V0, rm + pass);
4653
                        tcg_gen_movi_i64(cpu_V1, imm);
4654
                        switch (op) {
4655
                        case 0:  /* VSHR */
4656
                        case 1:  /* VSRA */
4657
                            if (u)
4658
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4659
                            else
4660
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4661
                            break;
4662
                        case 2: /* VRSHR */
4663
                        case 3: /* VRSRA */
4664
                            if (u)
4665
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4666
                            else
4667
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4668
                            break;
4669
                        case 4: /* VSRI */
4670
                            if (!u)
4671
                                return 1;
4672
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4673
                            break;
4674
                        case 5: /* VSHL, VSLI */
4675
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4676
                            break;
4677
                        case 6: /* VQSHLU */
4678
                            if (u) {
4679
                                gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
4680
                                                          cpu_V0, cpu_V1);
4681
                            } else {
4682
                                return 1;
4683
                            }
4684
                            break;
4685
                        case 7: /* VQSHL */
4686
                            if (u) {
4687
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4688
                                                         cpu_V0, cpu_V1);
4689
                            } else {
4690
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4691
                                                         cpu_V0, cpu_V1);
4692
                            }
4693
                            break;
4694
                        }
4695
                        if (op == 1 || op == 3) {
4696
                            /* Accumulate.  */
4697
                            neon_load_reg64(cpu_V1, rd + pass);
4698
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4699
                        } else if (op == 4 || (op == 5 && u)) {
4700
                            /* Insert */
4701
                            neon_load_reg64(cpu_V1, rd + pass);
4702
                            uint64_t mask;
4703
                            if (shift < -63 || shift > 63) {
4704
                                mask = 0;
4705
                            } else {
4706
                                if (op == 4) {
4707
                                    mask = 0xffffffffffffffffull >> -shift;
4708
                                } else {
4709
                                    mask = 0xffffffffffffffffull << shift;
4710
                                }
4711
                            }
4712
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
4713
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4714
                        }
4715
                        neon_store_reg64(cpu_V0, rd + pass);
4716
                    } else { /* size < 3 */
4717
                        /* Operands in T0 and T1.  */
4718
                        tmp = neon_load_reg(rm, pass);
4719
                        tmp2 = new_tmp();
4720
                        tcg_gen_movi_i32(tmp2, imm);
4721
                        switch (op) {
4722
                        case 0:  /* VSHR */
4723
                        case 1:  /* VSRA */
4724
                            GEN_NEON_INTEGER_OP(shl);
4725
                            break;
4726
                        case 2: /* VRSHR */
4727
                        case 3: /* VRSRA */
4728
                            GEN_NEON_INTEGER_OP(rshl);
4729
                            break;
4730
                        case 4: /* VSRI */
4731
                            if (!u)
4732
                                return 1;
4733
                            GEN_NEON_INTEGER_OP(shl);
4734
                            break;
4735
                        case 5: /* VSHL, VSLI */
4736
                            switch (size) {
4737
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4738
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4739
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4740
                            default: return 1;
4741
                            }
4742
                            break;
4743
                        case 6: /* VQSHLU */
4744
                            if (!u) {
4745
                                return 1;
4746
                            }
4747
                            switch (size) {
4748
                            case 0:
4749
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
4750
                                                         tmp, tmp2);
4751
                                break;
4752
                            case 1:
4753
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
4754
                                                          tmp, tmp2);
4755
                                break;
4756
                            case 2:
4757
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
4758
                                                          tmp, tmp2);
4759
                                break;
4760
                            default:
4761
                                return 1;
4762
                            }
4763
                            break;
4764
                        case 7: /* VQSHL */
4765
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4766
                            break;
4767
                        }
4768
                        dead_tmp(tmp2);
4769

    
4770
                        if (op == 1 || op == 3) {
4771
                            /* Accumulate.  */
4772
                            tmp2 = neon_load_reg(rd, pass);
4773
                            gen_neon_add(size, tmp, tmp2);
4774
                            dead_tmp(tmp2);
4775
                        } else if (op == 4 || (op == 5 && u)) {
4776
                            /* Insert */
4777
                            switch (size) {
4778
                            case 0:
4779
                                if (op == 4)
4780
                                    mask = 0xff >> -shift;
4781
                                else
4782
                                    mask = (uint8_t)(0xff << shift);
4783
                                mask |= mask << 8;
4784
                                mask |= mask << 16;
4785
                                break;
4786
                            case 1:
4787
                                if (op == 4)
4788
                                    mask = 0xffff >> -shift;
4789
                                else
4790
                                    mask = (uint16_t)(0xffff << shift);
4791
                                mask |= mask << 16;
4792
                                break;
4793
                            case 2:
4794
                                if (shift < -31 || shift > 31) {
4795
                                    mask = 0;
4796
                                } else {
4797
                                    if (op == 4)
4798
                                        mask = 0xffffffffu >> -shift;
4799
                                    else
4800
                                        mask = 0xffffffffu << shift;
4801
                                }
4802
                                break;
4803
                            default:
4804
                                abort();
4805
                            }
4806
                            tmp2 = neon_load_reg(rd, pass);
4807
                            tcg_gen_andi_i32(tmp, tmp, mask);
4808
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
4809
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4810
                            dead_tmp(tmp2);
4811
                        }
4812
                        neon_store_reg(rd, pass, tmp);
4813
                    }
4814
                } /* for pass */
4815
            } else if (op < 10) {
4816
                /* Shift by immediate and narrow:
4817
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4818
                shift = shift - (1 << (size + 3));
4819
                size++;
4820
                switch (size) {
4821
                case 1:
4822
                    imm = (uint16_t)shift;
4823
                    imm |= imm << 16;
4824
                    tmp2 = tcg_const_i32(imm);
4825
                    TCGV_UNUSED_I64(tmp64);
4826
                    break;
4827
                case 2:
4828
                    imm = (uint32_t)shift;
4829
                    tmp2 = tcg_const_i32(imm);
4830
                    TCGV_UNUSED_I64(tmp64);
4831
                    break;
4832
                case 3:
4833
                    tmp64 = tcg_const_i64(shift);
4834
                    TCGV_UNUSED(tmp2);
4835
                    break;
4836
                default:
4837
                    abort();
4838
                }
4839

    
4840
                for (pass = 0; pass < 2; pass++) {
4841
                    if (size == 3) {
4842
                        neon_load_reg64(cpu_V0, rm + pass);
4843
                        if (q) {
4844
                          if (u)
4845
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4846
                          else
4847
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4848
                        } else {
4849
                          if (u)
4850
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4851
                          else
4852
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4853
                        }
4854
                    } else {
4855
                        tmp = neon_load_reg(rm + pass, 0);
4856
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4857
                        tmp3 = neon_load_reg(rm + pass, 1);
4858
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4859
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4860
                        dead_tmp(tmp);
4861
                        dead_tmp(tmp3);
4862
                    }
4863
                    tmp = new_tmp();
4864
                    if (op == 8 && !u) {
4865
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4866
                    } else {
4867
                        if (op == 8)
4868
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4869
                        else
4870
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4871
                    }
4872
                    neon_store_reg(rd, pass, tmp);
4873
                } /* for pass */
4874
                if (size == 3) {
4875
                    tcg_temp_free_i64(tmp64);
4876
                } else {
4877
                    tcg_temp_free_i32(tmp2);
4878
                }
4879
            } else if (op == 10) {
4880
                /* VSHLL */
4881
                if (q || size == 3)
4882
                    return 1;
4883
                tmp = neon_load_reg(rm, 0);
4884
                tmp2 = neon_load_reg(rm, 1);
4885
                for (pass = 0; pass < 2; pass++) {
4886
                    if (pass == 1)
4887
                        tmp = tmp2;
4888

    
4889
                    gen_neon_widen(cpu_V0, tmp, size, u);
4890

    
4891
                    if (shift != 0) {
4892
                        /* The shift is less than the width of the source
4893
                           type, so we can just shift the whole register.  */
4894
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4895
                        /* Widen the result of shift: we need to clear
4896
                         * the potential overflow bits resulting from
4897
                         * left bits of the narrow input appearing as
4898
                         * right bits of left the neighbour narrow
4899
                         * input.  */
4900
                        if (size < 2 || !u) {
4901
                            uint64_t imm64;
4902
                            if (size == 0) {
4903
                                imm = (0xffu >> (8 - shift));
4904
                                imm |= imm << 16;
4905
                            } else if (size == 1) {
4906
                                imm = 0xffff >> (16 - shift);
4907
                            } else {
4908
                                /* size == 2 */
4909
                                imm = 0xffffffff >> (32 - shift);
4910
                            }
4911
                            if (size < 2) {
4912
                                imm64 = imm | (((uint64_t)imm) << 32);
4913
                            } else {
4914
                                imm64 = imm;
4915
                            }
4916
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
4917
                        }
4918
                    }
4919
                    neon_store_reg64(cpu_V0, rd + pass);
4920
                }
4921
            } else if (op >= 14) {
4922
                /* VCVT fixed-point.  */
4923
                /* We have already masked out the must-be-1 top bit of imm6,
4924
                 * hence this 32-shift where the ARM ARM has 64-imm6.
4925
                 */
4926
                shift = 32 - shift;
4927
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4928
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4929
                    if (!(op & 1)) {
4930
                        if (u)
4931
                            gen_vfp_ulto(0, shift);
4932
                        else
4933
                            gen_vfp_slto(0, shift);
4934
                    } else {
4935
                        if (u)
4936
                            gen_vfp_toul(0, shift);
4937
                        else
4938
                            gen_vfp_tosl(0, shift);
4939
                    }
4940
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4941
                }
4942
            } else {
4943
                return 1;
4944
            }
4945
        } else { /* (insn & 0x00380080) == 0 */
4946
            int invert;
4947

    
4948
            op = (insn >> 8) & 0xf;
4949
            /* One register and immediate.  */
4950
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4951
            invert = (insn & (1 << 5)) != 0;
4952
            switch (op) {
4953
            case 0: case 1:
4954
                /* no-op */
4955
                break;
4956
            case 2: case 3:
4957
                imm <<= 8;
4958
                break;
4959
            case 4: case 5:
4960
                imm <<= 16;
4961
                break;
4962
            case 6: case 7:
4963
                imm <<= 24;
4964
                break;
4965
            case 8: case 9:
4966
                imm |= imm << 16;
4967
                break;
4968
            case 10: case 11:
4969
                imm = (imm << 8) | (imm << 24);
4970
                break;
4971
            case 12:
4972
                imm = (imm << 8) | 0xff;
4973
                break;
4974
            case 13:
4975
                imm = (imm << 16) | 0xffff;
4976
                break;
4977
            case 14:
4978
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4979
                if (invert)
4980
                    imm = ~imm;
4981
                break;
4982
            case 15:
4983
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4984
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4985
                break;
4986
            }
4987
            if (invert)
4988
                imm = ~imm;
4989

    
4990
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4991
                if (op & 1 && op < 12) {
4992
                    tmp = neon_load_reg(rd, pass);
4993
                    if (invert) {
4994
                        /* The immediate value has already been inverted, so
4995
                           BIC becomes AND.  */
4996
                        tcg_gen_andi_i32(tmp, tmp, imm);
4997
                    } else {
4998
                        tcg_gen_ori_i32(tmp, tmp, imm);
4999
                    }
5000
                } else {
5001
                    /* VMOV, VMVN.  */
5002
                    tmp = new_tmp();
5003
                    if (op == 14 && invert) {
5004
                        uint32_t val;
5005
                        val = 0;
5006
                        for (n = 0; n < 4; n++) {
5007
                            if (imm & (1 << (n + (pass & 1) * 4)))
5008
                                val |= 0xff << (n * 8);
5009
                        }
5010
                        tcg_gen_movi_i32(tmp, val);
5011
                    } else {
5012
                        tcg_gen_movi_i32(tmp, imm);
5013
                    }
5014
                }
5015
                neon_store_reg(rd, pass, tmp);
5016
            }
5017
        }
5018
    } else { /* (insn & 0x00800010 == 0x00800000) */
5019
        if (size != 3) {
5020
            op = (insn >> 8) & 0xf;
5021
            if ((insn & (1 << 6)) == 0) {
5022
                /* Three registers of different lengths.  */
5023
                int src1_wide;
5024
                int src2_wide;
5025
                int prewiden;
5026
                /* prewiden, src1_wide, src2_wide */
5027
                static const int neon_3reg_wide[16][3] = {
5028
                    {1, 0, 0}, /* VADDL */
5029
                    {1, 1, 0}, /* VADDW */
5030
                    {1, 0, 0}, /* VSUBL */
5031
                    {1, 1, 0}, /* VSUBW */
5032
                    {0, 1, 1}, /* VADDHN */
5033
                    {0, 0, 0}, /* VABAL */
5034
                    {0, 1, 1}, /* VSUBHN */
5035
                    {0, 0, 0}, /* VABDL */
5036
                    {0, 0, 0}, /* VMLAL */
5037
                    {0, 0, 0}, /* VQDMLAL */
5038
                    {0, 0, 0}, /* VMLSL */
5039
                    {0, 0, 0}, /* VQDMLSL */
5040
                    {0, 0, 0}, /* Integer VMULL */
5041
                    {0, 0, 0}, /* VQDMULL */
5042
                    {0, 0, 0}  /* Polynomial VMULL */
5043
                };
5044

    
5045
                prewiden = neon_3reg_wide[op][0];
5046
                src1_wide = neon_3reg_wide[op][1];
5047
                src2_wide = neon_3reg_wide[op][2];
5048

    
5049
                if (size == 0 && (op == 9 || op == 11 || op == 13))
5050
                    return 1;
5051

    
5052
                /* Avoid overlapping operands.  Wide source operands are
5053
                   always aligned so will never overlap with wide
5054
                   destinations in problematic ways.  */
5055
                if (rd == rm && !src2_wide) {
5056
                    tmp = neon_load_reg(rm, 1);
5057
                    neon_store_scratch(2, tmp);
5058
                } else if (rd == rn && !src1_wide) {
5059
                    tmp = neon_load_reg(rn, 1);
5060
                    neon_store_scratch(2, tmp);
5061
                }
5062
                TCGV_UNUSED(tmp3);
5063
                for (pass = 0; pass < 2; pass++) {
5064
                    if (src1_wide) {
5065
                        neon_load_reg64(cpu_V0, rn + pass);
5066
                        TCGV_UNUSED(tmp);
5067
                    } else {
5068
                        if (pass == 1 && rd == rn) {
5069
                            tmp = neon_load_scratch(2);
5070
                        } else {
5071
                            tmp = neon_load_reg(rn, pass);
5072
                        }
5073
                        if (prewiden) {
5074
                            gen_neon_widen(cpu_V0, tmp, size, u);
5075
                        }
5076
                    }
5077
                    if (src2_wide) {
5078
                        neon_load_reg64(cpu_V1, rm + pass);
5079
                        TCGV_UNUSED(tmp2);
5080
                    } else {
5081
                        if (pass == 1 && rd == rm) {
5082
                            tmp2 = neon_load_scratch(2);
5083
                        } else {
5084
                            tmp2 = neon_load_reg(rm, pass);
5085
                        }
5086
                        if (prewiden) {
5087
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5088
                        }
5089
                    }
5090
                    switch (op) {
5091
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5092
                        gen_neon_addl(size);
5093
                        break;
5094
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5095
                        gen_neon_subl(size);
5096
                        break;
5097
                    case 5: case 7: /* VABAL, VABDL */
5098
                        switch ((size << 1) | u) {
5099
                        case 0:
5100
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5101
                            break;
5102
                        case 1:
5103
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5104
                            break;
5105
                        case 2:
5106
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5107
                            break;
5108
                        case 3:
5109
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5110
                            break;
5111
                        case 4:
5112
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5113
                            break;
5114
                        case 5:
5115
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5116
                            break;
5117
                        default: abort();
5118
                        }
5119
                        dead_tmp(tmp2);
5120
                        dead_tmp(tmp);
5121
                        break;
5122
                    case 8: case 9: case 10: case 11: case 12: case 13:
5123
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5124
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5125
                        break;
5126
                    case 14: /* Polynomial VMULL */
5127
                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5128
                        dead_tmp(tmp2);
5129
                        dead_tmp(tmp);
5130
                        break;
5131
                    default: /* 15 is RESERVED.  */
5132
                        return 1;
5133
                    }
5134
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
5135
                        /* Accumulate.  */
5136
                        if (op == 10 || op == 11) {
5137
                            gen_neon_negl(cpu_V0, size);
5138
                        }
5139

    
5140
                        if (op != 13) {
5141
                            neon_load_reg64(cpu_V1, rd + pass);
5142
                        }
5143

    
5144
                        switch (op) {
5145
                        case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
5146
                            gen_neon_addl(size);
5147
                            break;
5148
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5149
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5150
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5151
                            break;
5152
                            /* Fall through.  */
5153
                        case 13: /* VQDMULL */
5154
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5155
                            break;
5156
                        default:
5157
                            abort();
5158
                        }
5159
                        neon_store_reg64(cpu_V0, rd + pass);
5160
                    } else if (op == 4 || op == 6) {
5161
                        /* Narrowing operation.  */
5162
                        tmp = new_tmp();
5163
                        if (!u) {
5164
                            switch (size) {
5165
                            case 0:
5166
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5167
                                break;
5168
                            case 1:
5169
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5170
                                break;
5171
                            case 2:
5172
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5173
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5174
                                break;
5175
                            default: abort();
5176
                            }
5177
                        } else {
5178
                            switch (size) {
5179
                            case 0:
5180
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5181
                                break;
5182
                            case 1:
5183
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5184
                                break;
5185
                            case 2:
5186
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5187
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5188
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5189
                                break;
5190
                            default: abort();
5191
                            }
5192
                        }
5193
                        if (pass == 0) {
5194
                            tmp3 = tmp;
5195
                        } else {
5196
                            neon_store_reg(rd, 0, tmp3);
5197
                            neon_store_reg(rd, 1, tmp);
5198
                        }
5199
                    } else {
5200
                        /* Write back the result.  */
5201
                        neon_store_reg64(cpu_V0, rd + pass);
5202
                    }
5203
                }
5204
            } else {
5205
                /* Two registers and a scalar.  */
5206
                switch (op) {
5207
                case 0: /* Integer VMLA scalar */
5208
                case 1: /* Float VMLA scalar */
5209
                case 4: /* Integer VMLS scalar */
5210
                case 5: /* Floating point VMLS scalar */
5211
                case 8: /* Integer VMUL scalar */
5212
                case 9: /* Floating point VMUL scalar */
5213
                case 12: /* VQDMULH scalar */
5214
                case 13: /* VQRDMULH scalar */
5215
                    tmp = neon_get_scalar(size, rm);
5216
                    neon_store_scratch(0, tmp);
5217
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5218
                        tmp = neon_load_scratch(0);
5219
                        tmp2 = neon_load_reg(rn, pass);
5220
                        if (op == 12) {
5221
                            if (size == 1) {
5222
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5223
                            } else {
5224
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5225
                            }
5226
                        } else if (op == 13) {
5227
                            if (size == 1) {
5228
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5229
                            } else {
5230
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5231
                            }
5232
                        } else if (op & 1) {
5233
                            gen_helper_neon_mul_f32(tmp, tmp, tmp2);
5234
                        } else {
5235
                            switch (size) {
5236
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5237
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5238
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5239
                            default: return 1;
5240
                            }
5241
                        }
5242
                        dead_tmp(tmp2);
5243
                        if (op < 8) {
5244
                            /* Accumulate.  */
5245
                            tmp2 = neon_load_reg(rd, pass);
5246
                            switch (op) {
5247
                            case 0:
5248
                                gen_neon_add(size, tmp, tmp2);
5249
                                break;
5250
                            case 1:
5251
                                gen_helper_neon_add_f32(tmp, tmp, tmp2);
5252
                                break;
5253
                            case 4:
5254
                                gen_neon_rsb(size, tmp, tmp2);
5255
                                break;
5256
                            case 5:
5257
                                gen_helper_neon_sub_f32(tmp, tmp2, tmp);
5258
                                break;
5259
                            default:
5260
                                abort();
5261
                            }
5262
                            dead_tmp(tmp2);
5263
                        }
5264
                        neon_store_reg(rd, pass, tmp);
5265
                    }
5266
                    break;
5267
                case 2: /* VMLAL sclar */
5268
                case 3: /* VQDMLAL scalar */
5269
                case 6: /* VMLSL scalar */
5270
                case 7: /* VQDMLSL scalar */
5271
                case 10: /* VMULL scalar */
5272
                case 11: /* VQDMULL scalar */
5273
                    if (size == 0 && (op == 3 || op == 7 || op == 11))
5274
                        return 1;
5275

    
5276
                    tmp2 = neon_get_scalar(size, rm);
5277
                    /* We need a copy of tmp2 because gen_neon_mull
5278
                     * deletes it during pass 0.  */
5279
                    tmp4 = new_tmp();
5280
                    tcg_gen_mov_i32(tmp4, tmp2);
5281
                    tmp3 = neon_load_reg(rn, 1);
5282

    
5283
                    for (pass = 0; pass < 2; pass++) {
5284
                        if (pass == 0) {
5285
                            tmp = neon_load_reg(rn, 0);
5286
                        } else {
5287
                            tmp = tmp3;
5288
                            tmp2 = tmp4;
5289
                        }
5290
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5291
                        if (op == 6 || op == 7) {
5292
                            gen_neon_negl(cpu_V0, size);
5293
                        }
5294
                        if (op != 11) {
5295
                            neon_load_reg64(cpu_V1, rd + pass);
5296
                        }
5297
                        switch (op) {
5298
                        case 2: case 6:
5299
                            gen_neon_addl(size);
5300
                            break;
5301
                        case 3: case 7:
5302
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5303
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5304
                            break;
5305
                        case 10:
5306
                            /* no-op */
5307
                            break;
5308
                        case 11:
5309
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5310
                            break;
5311
                        default:
5312
                            abort();
5313
                        }
5314
                        neon_store_reg64(cpu_V0, rd + pass);
5315
                    }
5316

    
5317

    
5318
                    break;
5319
                default: /* 14 and 15 are RESERVED */
5320
                    return 1;
5321
                }
5322
            }
5323
        } else { /* size == 3 */
5324
            if (!u) {
5325
                /* Extract.  */
5326
                imm = (insn >> 8) & 0xf;
5327

    
5328
                if (imm > 7 && !q)
5329
                    return 1;
5330

    
5331
                if (imm == 0) {
5332
                    neon_load_reg64(cpu_V0, rn);
5333
                    if (q) {
5334
                        neon_load_reg64(cpu_V1, rn + 1);
5335
                    }
5336
                } else if (imm == 8) {
5337
                    neon_load_reg64(cpu_V0, rn + 1);
5338
                    if (q) {
5339
                        neon_load_reg64(cpu_V1, rm);
5340
                    }
5341
                } else if (q) {
5342
                    tmp64 = tcg_temp_new_i64();
5343
                    if (imm < 8) {
5344
                        neon_load_reg64(cpu_V0, rn);
5345
                        neon_load_reg64(tmp64, rn + 1);
5346
                    } else {
5347
                        neon_load_reg64(cpu_V0, rn + 1);
5348
                        neon_load_reg64(tmp64, rm);
5349
                    }
5350
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5351
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5352
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5353
                    if (imm < 8) {
5354
                        neon_load_reg64(cpu_V1, rm);
5355
                    } else {
5356
                        neon_load_reg64(cpu_V1, rm + 1);
5357
                        imm -= 8;
5358
                    }
5359
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5360
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5361
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5362
                    tcg_temp_free_i64(tmp64);
5363
                } else {
5364
                    /* BUGFIX */
5365
                    neon_load_reg64(cpu_V0, rn);
5366
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5367
                    neon_load_reg64(cpu_V1, rm);
5368
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5369
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5370
                }
5371
                neon_store_reg64(cpu_V0, rd);
5372
                if (q) {
5373
                    neon_store_reg64(cpu_V1, rd + 1);
5374
                }
5375
            } else if ((insn & (1 << 11)) == 0) {
5376
                /* Two register misc.  */
5377
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5378
                size = (insn >> 18) & 3;
5379
                switch (op) {
5380
                case 0: /* VREV64 */
5381
                    if (size == 3)
5382
                        return 1;
5383
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
5384
                        tmp = neon_load_reg(rm, pass * 2);
5385
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
5386
                        switch (size) {
5387
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5388
                        case 1: gen_swap_half(tmp); break;
5389
                        case 2: /* no-op */ break;
5390
                        default: abort();
5391
                        }
5392
                        neon_store_reg(rd, pass * 2 + 1, tmp);
5393
                        if (size == 2) {
5394
                            neon_store_reg(rd, pass * 2, tmp2);
5395
                        } else {
5396
                            switch (size) {
5397
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5398
                            case 1: gen_swap_half(tmp2); break;
5399
                            default: abort();
5400
                            }
5401
                            neon_store_reg(rd, pass * 2, tmp2);
5402
                        }
5403
                    }
5404
                    break;
5405
                case 4: case 5: /* VPADDL */
5406
                case 12: case 13: /* VPADAL */
5407
                    if (size == 3)
5408
                        return 1;
5409
                    for (pass = 0; pass < q + 1; pass++) {
5410
                        tmp = neon_load_reg(rm, pass * 2);
5411
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
5412
                        tmp = neon_load_reg(rm, pass * 2 + 1);
5413
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
5414
                        switch (size) {
5415
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5416
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5417
                        case 2: tcg_gen_add_i64(CPU_V001); break;
5418
                        default: abort();
5419
                        }
5420
                        if (op >= 12) {
5421
                            /* Accumulate.  */
5422
                            neon_load_reg64(cpu_V1, rd + pass);
5423
                            gen_neon_addl(size);
5424
                        }
5425
                        neon_store_reg64(cpu_V0, rd + pass);
5426
                    }
5427
                    break;
5428
                case 33: /* VTRN */
5429
                    if (size == 2) {
5430
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
5431
                            tmp = neon_load_reg(rm, n);
5432
                            tmp2 = neon_load_reg(rd, n + 1);
5433
                            neon_store_reg(rm, n, tmp2);
5434
                            neon_store_reg(rd, n + 1, tmp);
5435
                        }
5436
                    } else {
5437
                        goto elementwise;
5438
                    }
5439
                    break;
5440
                case 34: /* VUZP */
5441
                    /* Reg  Before       After
5442
                       Rd   A3 A2 A1 A0  B2 B0 A2 A0
5443
                       Rm   B3 B2 B1 B0  B3 B1 A3 A1
5444
                     */
5445
                    if (size == 3)
5446
                        return 1;
5447
                    gen_neon_unzip(rd, q, 0, size);
5448
                    gen_neon_unzip(rm, q, 4, size);
5449
                    if (q) {
5450
                        static int unzip_order_q[8] =
5451
                            {0, 2, 4, 6, 1, 3, 5, 7};
5452
                        for (n = 0; n < 8; n++) {
5453
                            int reg = (n < 4) ? rd : rm;
5454
                            tmp = neon_load_scratch(unzip_order_q[n]);
5455
                            neon_store_reg(reg, n % 4, tmp);
5456
                        }
5457
                    } else {
5458
                        static int unzip_order[4] =
5459
                            {0, 4, 1, 5};
5460
                        for (n = 0; n < 4; n++) {
5461
                            int reg = (n < 2) ? rd : rm;
5462
                            tmp = neon_load_scratch(unzip_order[n]);
5463
                            neon_store_reg(reg, n % 2, tmp);
5464
                        }
5465
                    }
5466
                    break;
5467
                case 35: /* VZIP */
5468
                    /* Reg  Before       After
5469
                       Rd   A3 A2 A1 A0  B1 A1 B0 A0
5470
                       Rm   B3 B2 B1 B0  B3 A3 B2 A2
5471
                     */
5472
                    if (size == 3)
5473
                        return 1;
5474
                    count = (q ? 4 : 2);
5475
                    for (n = 0; n < count; n++) {
5476
                        tmp = neon_load_reg(rd, n);
5477
                        tmp2 = neon_load_reg(rd, n);
5478
                        switch (size) {
5479
                        case 0: gen_neon_zip_u8(tmp, tmp2); break;
5480
                        case 1: gen_neon_zip_u16(tmp, tmp2); break;
5481
                        case 2: /* no-op */; break;
5482
                        default: abort();
5483
                        }
5484
                        neon_store_scratch(n * 2, tmp);
5485
                        neon_store_scratch(n * 2 + 1, tmp2);
5486
                    }
5487
                    for (n = 0; n < count * 2; n++) {
5488
                        int reg = (n < count) ? rd : rm;
5489
                        tmp = neon_load_scratch(n);
5490
                        neon_store_reg(reg, n % count, tmp);
5491
                    }
5492
                    break;
5493
                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5494
                    if (size == 3)
5495
                        return 1;
5496
                    TCGV_UNUSED(tmp2);
5497
                    for (pass = 0; pass < 2; pass++) {
5498
                        neon_load_reg64(cpu_V0, rm + pass);
5499
                        tmp = new_tmp();
5500
                        if (op == 36) {
5501
                            if (q) { /* VQMOVUN */
5502
                                gen_neon_unarrow_sats(size, tmp, cpu_V0);
5503
                            } else { /* VMOVN */
5504
                                gen_neon_narrow(size, tmp, cpu_V0);
5505
                            }
5506
                        } else { /* VQMOVN */
5507
                            if (q) {
5508
                                gen_neon_narrow_satu(size, tmp, cpu_V0);
5509
                            } else {
5510
                                gen_neon_narrow_sats(size, tmp, cpu_V0);
5511
                            }
5512
                        }
5513
                        if (pass == 0) {
5514
                            tmp2 = tmp;
5515
                        } else {
5516
                            neon_store_reg(rd, 0, tmp2);
5517
                            neon_store_reg(rd, 1, tmp);
5518
                        }
5519
                    }
5520
                    break;
5521
                case 38: /* VSHLL */
5522
                    if (q || size == 3)
5523
                        return 1;
5524
                    tmp = neon_load_reg(rm, 0);
5525
                    tmp2 = neon_load_reg(rm, 1);
5526
                    for (pass = 0; pass < 2; pass++) {
5527
                        if (pass == 1)
5528
                            tmp = tmp2;
5529
                        gen_neon_widen(cpu_V0, tmp, size, 1);
5530
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5531
                        neon_store_reg64(cpu_V0, rd + pass);
5532
                    }
5533
                    break;
5534
                case 44: /* VCVT.F16.F32 */
5535
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5536
                      return 1;
5537
                    tmp = new_tmp();
5538
                    tmp2 = new_tmp();
5539
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5540
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5541
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5542
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5543
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5544
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5545
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5546
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5547
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5548
                    neon_store_reg(rd, 0, tmp2);
5549
                    tmp2 = new_tmp();
5550
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5551
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5552
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5553
                    neon_store_reg(rd, 1, tmp2);
5554
                    dead_tmp(tmp);
5555
                    break;
5556
                case 46: /* VCVT.F32.F16 */
5557
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5558
                      return 1;
5559
                    tmp3 = new_tmp();
5560
                    tmp = neon_load_reg(rm, 0);
5561
                    tmp2 = neon_load_reg(rm, 1);
5562
                    tcg_gen_ext16u_i32(tmp3, tmp);
5563
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5564
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5565
                    tcg_gen_shri_i32(tmp3, tmp, 16);
5566
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5567
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5568
                    dead_tmp(tmp);
5569
                    tcg_gen_ext16u_i32(tmp3, tmp2);
5570
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5571
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5572
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
5573
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5574
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5575
                    dead_tmp(tmp2);
5576
                    dead_tmp(tmp3);
5577
                    break;
5578
                default:
5579
                elementwise:
5580
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
5581
                        if (op == 30 || op == 31 || op >= 58) {
5582
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
5583
                                           neon_reg_offset(rm, pass));
5584
                            TCGV_UNUSED(tmp);
5585
                        } else {
5586
                            tmp = neon_load_reg(rm, pass);
5587
                        }
5588
                        switch (op) {
5589
                        case 1: /* VREV32 */
5590
                            switch (size) {
5591
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5592
                            case 1: gen_swap_half(tmp); break;
5593
                            default: return 1;
5594
                            }
5595
                            break;
5596
                        case 2: /* VREV16 */
5597
                            if (size != 0)
5598
                                return 1;
5599
                            gen_rev16(tmp);
5600
                            break;
5601
                        case 8: /* CLS */
5602
                            switch (size) {
5603
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5604
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5605
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5606
                            default: return 1;
5607
                            }
5608
                            break;
5609
                        case 9: /* CLZ */
5610
                            switch (size) {
5611
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5612
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5613
                            case 2: gen_helper_clz(tmp, tmp); break;
5614
                            default: return 1;
5615
                            }
5616
                            break;
5617
                        case 10: /* CNT */
5618
                            if (size != 0)
5619
                                return 1;
5620
                            gen_helper_neon_cnt_u8(tmp, tmp);
5621
                            break;
5622
                        case 11: /* VNOT */
5623
                            if (size != 0)
5624
                                return 1;
5625
                            tcg_gen_not_i32(tmp, tmp);
5626
                            break;
5627
                        case 14: /* VQABS */
5628
                            switch (size) {
5629
                            case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
5630
                            case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
5631
                            case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
5632
                            default: return 1;
5633
                            }
5634
                            break;
5635
                        case 15: /* VQNEG */
5636
                            switch (size) {
5637
                            case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
5638
                            case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
5639
                            case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
5640
                            default: return 1;
5641
                            }
5642
                            break;
5643
                        case 16: case 19: /* VCGT #0, VCLE #0 */
5644
                            tmp2 = tcg_const_i32(0);
5645
                            switch(size) {
5646
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5647
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5648
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5649
                            default: return 1;
5650
                            }
5651
                            tcg_temp_free(tmp2);
5652
                            if (op == 19)
5653
                                tcg_gen_not_i32(tmp, tmp);
5654
                            break;
5655
                        case 17: case 20: /* VCGE #0, VCLT #0 */
5656
                            tmp2 = tcg_const_i32(0);
5657
                            switch(size) {
5658
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
5659
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
5660
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
5661
                            default: return 1;
5662
                            }
5663
                            tcg_temp_free(tmp2);
5664
                            if (op == 20)
5665
                                tcg_gen_not_i32(tmp, tmp);
5666
                            break;
5667
                        case 18: /* VCEQ #0 */
5668
                            tmp2 = tcg_const_i32(0);
5669
                            switch(size) {
5670
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5671
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5672
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5673
                            default: return 1;
5674
                            }
5675
                            tcg_temp_free(tmp2);
5676
                            break;
5677
                        case 22: /* VABS */
5678
                            switch(size) {
5679
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
5680
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
5681
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
5682
                            default: return 1;
5683
                            }
5684
                            break;
5685
                        case 23: /* VNEG */
5686
                            if (size == 3)
5687
                                return 1;
5688
                            tmp2 = tcg_const_i32(0);
5689
                            gen_neon_rsb(size, tmp, tmp2);
5690
                            tcg_temp_free(tmp2);
5691
                            break;
5692
                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5693
                            tmp2 = tcg_const_i32(0);
5694
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
5695
                            tcg_temp_free(tmp2);
5696
                            if (op == 27)
5697
                                tcg_gen_not_i32(tmp, tmp);
5698
                            break;
5699
                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5700
                            tmp2 = tcg_const_i32(0);
5701
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2);
5702
                            tcg_temp_free(tmp2);
5703
                            if (op == 28)
5704
                                tcg_gen_not_i32(tmp, tmp);
5705
                            break;
5706
                        case 26: /* Float VCEQ #0 */
5707
                            tmp2 = tcg_const_i32(0);
5708
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
5709
                            tcg_temp_free(tmp2);
5710
                            break;
5711
                        case 30: /* Float VABS */
5712
                            gen_vfp_abs(0);
5713
                            break;
5714
                        case 31: /* Float VNEG */
5715
                            gen_vfp_neg(0);
5716
                            break;
5717
                        case 32: /* VSWP */
5718
                            tmp2 = neon_load_reg(rd, pass);
5719
                            neon_store_reg(rm, pass, tmp2);
5720
                            break;
5721
                        case 33: /* VTRN */
5722
                            tmp2 = neon_load_reg(rd, pass);
5723
                            switch (size) {
5724
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
5725
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
5726
                            case 2: abort();
5727
                            default: return 1;
5728
                            }
5729
                            neon_store_reg(rm, pass, tmp2);
5730
                            break;
5731
                        case 56: /* Integer VRECPE */
5732
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
5733
                            break;
5734
                        case 57: /* Integer VRSQRTE */
5735
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
5736
                            break;
5737
                        case 58: /* Float VRECPE */
5738
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5739
                            break;
5740
                        case 59: /* Float VRSQRTE */
5741
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5742
                            break;
5743
                        case 60: /* VCVT.F32.S32 */
5744
                            gen_vfp_sito(0);
5745
                            break;
5746
                        case 61: /* VCVT.F32.U32 */
5747
                            gen_vfp_uito(0);
5748
                            break;
5749
                        case 62: /* VCVT.S32.F32 */
5750
                            gen_vfp_tosiz(0);
5751
                            break;
5752
                        case 63: /* VCVT.U32.F32 */
5753
                            gen_vfp_touiz(0);
5754
                            break;
5755
                        default:
5756
                            /* Reserved: 21, 29, 39-56 */
5757
                            return 1;
5758
                        }
5759
                        if (op == 30 || op == 31 || op >= 58) {
5760
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
5761
                                           neon_reg_offset(rd, pass));
5762
                        } else {
5763
                            neon_store_reg(rd, pass, tmp);
5764
                        }
5765
                    }
5766
                    break;
5767
                }
5768
            } else if ((insn & (1 << 10)) == 0) {
5769
                /* VTBL, VTBX.  */
5770
                n = ((insn >> 5) & 0x18) + 8;
5771
                if (insn & (1 << 6)) {
5772
                    tmp = neon_load_reg(rd, 0);
5773
                } else {
5774
                    tmp = new_tmp();
5775
                    tcg_gen_movi_i32(tmp, 0);
5776
                }
5777
                tmp2 = neon_load_reg(rm, 0);
5778
                tmp4 = tcg_const_i32(rn);
5779
                tmp5 = tcg_const_i32(n);
5780
                gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
5781
                dead_tmp(tmp);
5782
                if (insn & (1 << 6)) {
5783
                    tmp = neon_load_reg(rd, 1);
5784
                } else {
5785
                    tmp = new_tmp();
5786
                    tcg_gen_movi_i32(tmp, 0);
5787
                }
5788
                tmp3 = neon_load_reg(rm, 1);
5789
                gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
5790
                tcg_temp_free_i32(tmp5);
5791
                tcg_temp_free_i32(tmp4);
5792
                neon_store_reg(rd, 0, tmp2);
5793
                neon_store_reg(rd, 1, tmp3);
5794
                dead_tmp(tmp);
5795
            } else if ((insn & 0x380) == 0) {
5796
                /* VDUP */
5797
                if (insn & (1 << 19)) {
5798
                    tmp = neon_load_reg(rm, 1);
5799
                } else {
5800
                    tmp = neon_load_reg(rm, 0);
5801
                }
5802
                if (insn & (1 << 16)) {
5803
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
5804
                } else if (insn & (1 << 17)) {
5805
                    if ((insn >> 18) & 1)
5806
                        gen_neon_dup_high16(tmp);
5807
                    else
5808
                        gen_neon_dup_low16(tmp);
5809
                }
5810
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5811
                    tmp2 = new_tmp();
5812
                    tcg_gen_mov_i32(tmp2, tmp);
5813
                    neon_store_reg(rd, pass, tmp2);
5814
                }
5815
                dead_tmp(tmp);
5816
            } else {
5817
                return 1;
5818
            }
5819
        }
5820
    }
5821
    return 0;
5822
}
5823

    
5824
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5825
{
5826
    int crn = (insn >> 16) & 0xf;
5827
    int crm = insn & 0xf;
5828
    int op1 = (insn >> 21) & 7;
5829
    int op2 = (insn >> 5) & 7;
5830
    int rt = (insn >> 12) & 0xf;
5831
    TCGv tmp;
5832

    
5833
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5834
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5835
            /* TEECR */
5836
            if (IS_USER(s))
5837
                return 1;
5838
            tmp = load_cpu_field(teecr);
5839
            store_reg(s, rt, tmp);
5840
            return 0;
5841
        }
5842
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5843
            /* TEEHBR */
5844
            if (IS_USER(s) && (env->teecr & 1))
5845
                return 1;
5846
            tmp = load_cpu_field(teehbr);
5847
            store_reg(s, rt, tmp);
5848
            return 0;
5849
        }
5850
    }
5851
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5852
            op1, crn, crm, op2);
5853
    return 1;
5854
}
5855

    
5856
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5857
{
5858
    int crn = (insn >> 16) & 0xf;
5859
    int crm = insn & 0xf;
5860
    int op1 = (insn >> 21) & 7;
5861
    int op2 = (insn >> 5) & 7;
5862
    int rt = (insn >> 12) & 0xf;
5863
    TCGv tmp;
5864

    
5865
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5866
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5867
            /* TEECR */
5868
            if (IS_USER(s))
5869
                return 1;
5870
            tmp = load_reg(s, rt);
5871
            gen_helper_set_teecr(cpu_env, tmp);
5872
            dead_tmp(tmp);
5873
            return 0;
5874
        }
5875
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5876
            /* TEEHBR */
5877
            if (IS_USER(s) && (env->teecr & 1))
5878
                return 1;
5879
            tmp = load_reg(s, rt);
5880
            store_cpu_field(tmp, teehbr);
5881
            return 0;
5882
        }
5883
    }
5884
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5885
            op1, crn, crm, op2);
5886
    return 1;
5887
}
5888

    
5889
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5890
{
5891
    int cpnum;
5892

    
5893
    cpnum = (insn >> 8) & 0xf;
5894
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5895
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5896
        return 1;
5897

    
5898
    switch (cpnum) {
5899
      case 0:
5900
      case 1:
5901
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5902
            return disas_iwmmxt_insn(env, s, insn);
5903
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5904
            return disas_dsp_insn(env, s, insn);
5905
        }
5906
        return 1;
5907
    case 10:
5908
    case 11:
5909
        return disas_vfp_insn (env, s, insn);
5910
    case 14:
5911
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5912
           Unfortunately Intel decided to ignore this.  */
5913
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5914
            goto board;
5915
        if (insn & (1 << 20))
5916
            return disas_cp14_read(env, s, insn);
5917
        else
5918
            return disas_cp14_write(env, s, insn);
5919
    case 15:
5920
        return disas_cp15_insn (env, s, insn);
5921
    default:
5922
    board:
5923
        /* Unknown coprocessor.  See if the board has hooked it.  */
5924
        return disas_cp_insn (env, s, insn);
5925
    }
5926
}
5927

    
5928

    
5929
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5930
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5931
{
5932
    TCGv tmp;
5933
    tmp = new_tmp();
5934
    tcg_gen_trunc_i64_i32(tmp, val);
5935
    store_reg(s, rlow, tmp);
5936
    tmp = new_tmp();
5937
    tcg_gen_shri_i64(val, val, 32);
5938
    tcg_gen_trunc_i64_i32(tmp, val);
5939
    store_reg(s, rhigh, tmp);
5940
}
5941

    
5942
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5943
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5944
{
5945
    TCGv_i64 tmp;
5946
    TCGv tmp2;
5947

    
5948
    /* Load value and extend to 64 bits.  */
5949
    tmp = tcg_temp_new_i64();
5950
    tmp2 = load_reg(s, rlow);
5951
    tcg_gen_extu_i32_i64(tmp, tmp2);
5952
    dead_tmp(tmp2);
5953
    tcg_gen_add_i64(val, val, tmp);
5954
    tcg_temp_free_i64(tmp);
5955
}
5956

    
5957
/* load and add a 64-bit value from a register pair.  */
5958
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5959
{
5960
    TCGv_i64 tmp;
5961
    TCGv tmpl;
5962
    TCGv tmph;
5963

    
5964
    /* Load 64-bit value rd:rn.  */
5965
    tmpl = load_reg(s, rlow);
5966
    tmph = load_reg(s, rhigh);
5967
    tmp = tcg_temp_new_i64();
5968
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5969
    dead_tmp(tmpl);
5970
    dead_tmp(tmph);
5971
    tcg_gen_add_i64(val, val, tmp);
5972
    tcg_temp_free_i64(tmp);
5973
}
5974

    
5975
/* Set N and Z flags from a 64-bit value.  */
5976
static void gen_logicq_cc(TCGv_i64 val)
5977
{
5978
    TCGv tmp = new_tmp();
5979
    gen_helper_logicq_cc(tmp, val);
5980
    gen_logic_CC(tmp);
5981
    dead_tmp(tmp);
5982
}
5983

    
5984
/* Load/Store exclusive instructions are implemented by remembering
5985
   the value/address loaded, and seeing if these are the same
5986
   when the store is performed. This should be is sufficient to implement
5987
   the architecturally mandated semantics, and avoids having to monitor
5988
   regular stores.
5989

5990
   In system emulation mode only one CPU will be running at once, so
5991
   this sequence is effectively atomic.  In user emulation mode we
5992
   throw an exception and handle the atomic operation elsewhere.  */
5993
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
5994
                               TCGv addr, int size)
5995
{
5996
    TCGv tmp;
5997

    
5998
    switch (size) {
5999
    case 0:
6000
        tmp = gen_ld8u(addr, IS_USER(s));
6001
        break;
6002
    case 1:
6003
        tmp = gen_ld16u(addr, IS_USER(s));
6004
        break;
6005
    case 2:
6006
    case 3:
6007
        tmp = gen_ld32(addr, IS_USER(s));
6008
        break;
6009
    default:
6010
        abort();
6011
    }
6012
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6013
    store_reg(s, rt, tmp);
6014
    if (size == 3) {
6015
        TCGv tmp2 = new_tmp();
6016
        tcg_gen_addi_i32(tmp2, addr, 4);
6017
        tmp = gen_ld32(tmp2, IS_USER(s));
6018
        dead_tmp(tmp2);
6019
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6020
        store_reg(s, rt2, tmp);
6021
    }
6022
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6023
}
6024

    
6025
static void gen_clrex(DisasContext *s)
6026
{
6027
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6028
}
6029

    
6030
#ifdef CONFIG_USER_ONLY
6031
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6032
                                TCGv addr, int size)
6033
{
6034
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
6035
    tcg_gen_movi_i32(cpu_exclusive_info,
6036
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
6037
    gen_exception_insn(s, 4, EXCP_STREX);
6038
}
6039
#else
6040
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6041
                                TCGv addr, int size)
6042
{
6043
    TCGv tmp;
6044
    int done_label;
6045
    int fail_label;
6046

    
6047
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6048
         [addr] = {Rt};
6049
         {Rd} = 0;
6050
       } else {
6051
         {Rd} = 1;
6052
       } */
6053
    fail_label = gen_new_label();
6054
    done_label = gen_new_label();
6055
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6056
    switch (size) {
6057
    case 0:
6058
        tmp = gen_ld8u(addr, IS_USER(s));
6059
        break;
6060
    case 1:
6061
        tmp = gen_ld16u(addr, IS_USER(s));
6062
        break;
6063
    case 2:
6064
    case 3:
6065
        tmp = gen_ld32(addr, IS_USER(s));
6066
        break;
6067
    default:
6068
        abort();
6069
    }
6070
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6071
    dead_tmp(tmp);
6072
    if (size == 3) {
6073
        TCGv tmp2 = new_tmp();
6074
        tcg_gen_addi_i32(tmp2, addr, 4);
6075
        tmp = gen_ld32(tmp2, IS_USER(s));
6076
        dead_tmp(tmp2);
6077
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6078
        dead_tmp(tmp);
6079
    }
6080
    tmp = load_reg(s, rt);
6081
    switch (size) {
6082
    case 0:
6083
        gen_st8(tmp, addr, IS_USER(s));
6084
        break;
6085
    case 1:
6086
        gen_st16(tmp, addr, IS_USER(s));
6087
        break;
6088
    case 2:
6089
    case 3:
6090
        gen_st32(tmp, addr, IS_USER(s));
6091
        break;
6092
    default:
6093
        abort();
6094
    }
6095
    if (size == 3) {
6096
        tcg_gen_addi_i32(addr, addr, 4);
6097
        tmp = load_reg(s, rt2);
6098
        gen_st32(tmp, addr, IS_USER(s));
6099
    }
6100
    tcg_gen_movi_i32(cpu_R[rd], 0);
6101
    tcg_gen_br(done_label);
6102
    gen_set_label(fail_label);
6103
    tcg_gen_movi_i32(cpu_R[rd], 1);
6104
    gen_set_label(done_label);
6105
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6106
}
6107
#endif
6108

    
6109
static void disas_arm_insn(CPUState * env, DisasContext *s)
6110
{
6111
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6112
    TCGv tmp;
6113
    TCGv tmp2;
6114
    TCGv tmp3;
6115
    TCGv addr;
6116
    TCGv_i64 tmp64;
6117

    
6118
    insn = ldl_code(s->pc);
6119
    s->pc += 4;
6120

    
6121
    /* M variants do not implement ARM mode.  */
6122
    if (IS_M(env))
6123
        goto illegal_op;
6124
    cond = insn >> 28;
6125
    if (cond == 0xf){
6126
        /* Unconditional instructions.  */
6127
        if (((insn >> 25) & 7) == 1) {
6128
            /* NEON Data processing.  */
6129
            if (!arm_feature(env, ARM_FEATURE_NEON))
6130
                goto illegal_op;
6131

    
6132
            if (disas_neon_data_insn(env, s, insn))
6133
                goto illegal_op;
6134
            return;
6135
        }
6136
        if ((insn & 0x0f100000) == 0x04000000) {
6137
            /* NEON load/store.  */
6138
            if (!arm_feature(env, ARM_FEATURE_NEON))
6139
                goto illegal_op;
6140

    
6141
            if (disas_neon_ls_insn(env, s, insn))
6142
                goto illegal_op;
6143
            return;
6144
        }
6145
        if (((insn & 0x0f30f000) == 0x0510f000) ||
6146
            ((insn & 0x0f30f010) == 0x0710f000)) {
6147
            if ((insn & (1 << 22)) == 0) {
6148
                /* PLDW; v7MP */
6149
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6150
                    goto illegal_op;
6151
                }
6152
            }
6153
            /* Otherwise PLD; v5TE+ */
6154
            return;
6155
        }
6156
        if (((insn & 0x0f70f000) == 0x0450f000) ||
6157
            ((insn & 0x0f70f010) == 0x0650f000)) {
6158
            ARCH(7);
6159
            return; /* PLI; V7 */
6160
        }
6161
        if (((insn & 0x0f700000) == 0x04100000) ||
6162
            ((insn & 0x0f700010) == 0x06100000)) {
6163
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6164
                goto illegal_op;
6165
            }
6166
            return; /* v7MP: Unallocated memory hint: must NOP */
6167
        }
6168

    
6169
        if ((insn & 0x0ffffdff) == 0x01010000) {
6170
            ARCH(6);
6171
            /* setend */
6172
            if (insn & (1 << 9)) {
6173
                /* BE8 mode not implemented.  */
6174
                goto illegal_op;
6175
            }
6176
            return;
6177
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6178
            switch ((insn >> 4) & 0xf) {
6179
            case 1: /* clrex */
6180
                ARCH(6K);
6181
                gen_clrex(s);
6182
                return;
6183
            case 4: /* dsb */
6184
            case 5: /* dmb */
6185
            case 6: /* isb */
6186
                ARCH(7);
6187
                /* We don't emulate caches so these are a no-op.  */
6188
                return;
6189
            default:
6190
                goto illegal_op;
6191
            }
6192
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6193
            /* srs */
6194
            int32_t offset;
6195
            if (IS_USER(s))
6196
                goto illegal_op;
6197
            ARCH(6);
6198
            op1 = (insn & 0x1f);
6199
            addr = new_tmp();
6200
            tmp = tcg_const_i32(op1);
6201
            gen_helper_get_r13_banked(addr, cpu_env, tmp);
6202
            tcg_temp_free_i32(tmp);
6203
            i = (insn >> 23) & 3;
6204
            switch (i) {
6205
            case 0: offset = -4; break; /* DA */
6206
            case 1: offset = 0; break; /* IA */
6207
            case 2: offset = -8; break; /* DB */
6208
            case 3: offset = 4; break; /* IB */
6209
            default: abort();
6210
            }
6211
            if (offset)
6212
                tcg_gen_addi_i32(addr, addr, offset);
6213
            tmp = load_reg(s, 14);
6214
            gen_st32(tmp, addr, 0);
6215
            tmp = load_cpu_field(spsr);
6216
            tcg_gen_addi_i32(addr, addr, 4);
6217
            gen_st32(tmp, addr, 0);
6218
            if (insn & (1 << 21)) {
6219
                /* Base writeback.  */
6220
                switch (i) {
6221
                case 0: offset = -8; break;
6222
                case 1: offset = 4; break;
6223
                case 2: offset = -4; break;
6224
                case 3: offset = 0; break;
6225
                default: abort();
6226
                }
6227
                if (offset)
6228
                    tcg_gen_addi_i32(addr, addr, offset);
6229
                tmp = tcg_const_i32(op1);
6230
                gen_helper_set_r13_banked(cpu_env, tmp, addr);
6231
                tcg_temp_free_i32(tmp);
6232
                dead_tmp(addr);
6233
            } else {
6234
                dead_tmp(addr);
6235
            }
6236
            return;
6237
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6238
            /* rfe */
6239
            int32_t offset;
6240
            if (IS_USER(s))
6241
                goto illegal_op;
6242
            ARCH(6);
6243
            rn = (insn >> 16) & 0xf;
6244
            addr = load_reg(s, rn);
6245
            i = (insn >> 23) & 3;
6246
            switch (i) {
6247
            case 0: offset = -4; break; /* DA */
6248
            case 1: offset = 0; break; /* IA */
6249
            case 2: offset = -8; break; /* DB */
6250
            case 3: offset = 4; break; /* IB */
6251
            default: abort();
6252
            }
6253
            if (offset)
6254
                tcg_gen_addi_i32(addr, addr, offset);
6255
            /* Load PC into tmp and CPSR into tmp2.  */
6256
            tmp = gen_ld32(addr, 0);
6257
            tcg_gen_addi_i32(addr, addr, 4);
6258
            tmp2 = gen_ld32(addr, 0);
6259
            if (insn & (1 << 21)) {
6260
                /* Base writeback.  */
6261
                switch (i) {
6262
                case 0: offset = -8; break;
6263
                case 1: offset = 4; break;
6264
                case 2: offset = -4; break;
6265
                case 3: offset = 0; break;
6266
                default: abort();
6267
                }
6268
                if (offset)
6269
                    tcg_gen_addi_i32(addr, addr, offset);
6270
                store_reg(s, rn, addr);
6271
            } else {
6272
                dead_tmp(addr);
6273
            }
6274
            gen_rfe(s, tmp, tmp2);
6275
            return;
6276
        } else if ((insn & 0x0e000000) == 0x0a000000) {
6277
            /* branch link and change to thumb (blx <offset>) */
6278
            int32_t offset;
6279

    
6280
            val = (uint32_t)s->pc;
6281
            tmp = new_tmp();
6282
            tcg_gen_movi_i32(tmp, val);
6283
            store_reg(s, 14, tmp);
6284
            /* Sign-extend the 24-bit offset */
6285
            offset = (((int32_t)insn) << 8) >> 8;
6286
            /* offset * 4 + bit24 * 2 + (thumb bit) */
6287
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
6288
            /* pipeline offset */
6289
            val += 4;
6290
            gen_bx_im(s, val);
6291
            return;
6292
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
6293
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6294
                /* iWMMXt register transfer.  */
6295
                if (env->cp15.c15_cpar & (1 << 1))
6296
                    if (!disas_iwmmxt_insn(env, s, insn))
6297
                        return;
6298
            }
6299
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
6300
            /* Coprocessor double register transfer.  */
6301
        } else if ((insn & 0x0f000010) == 0x0e000010) {
6302
            /* Additional coprocessor register transfer.  */
6303
        } else if ((insn & 0x0ff10020) == 0x01000000) {
6304
            uint32_t mask;
6305
            uint32_t val;
6306
            /* cps (privileged) */
6307
            if (IS_USER(s))
6308
                return;
6309
            mask = val = 0;
6310
            if (insn & (1 << 19)) {
6311
                if (insn & (1 << 8))
6312
                    mask |= CPSR_A;
6313
                if (insn & (1 << 7))
6314
                    mask |= CPSR_I;
6315
                if (insn & (1 << 6))
6316
                    mask |= CPSR_F;
6317
                if (insn & (1 << 18))
6318
                    val |= mask;
6319
            }
6320
            if (insn & (1 << 17)) {
6321
                mask |= CPSR_M;
6322
                val |= (insn & 0x1f);
6323
            }
6324
            if (mask) {
6325
                gen_set_psr_im(s, mask, 0, val);
6326
            }
6327
            return;
6328
        }
6329
        goto illegal_op;
6330
    }
6331
    if (cond != 0xe) {
6332
        /* if not always execute, we generate a conditional jump to
6333
           next instruction */
6334
        s->condlabel = gen_new_label();
6335
        gen_test_cc(cond ^ 1, s->condlabel);
6336
        s->condjmp = 1;
6337
    }
6338
    if ((insn & 0x0f900000) == 0x03000000) {
6339
        if ((insn & (1 << 21)) == 0) {
6340
            ARCH(6T2);
6341
            rd = (insn >> 12) & 0xf;
6342
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6343
            if ((insn & (1 << 22)) == 0) {
6344
                /* MOVW */
6345
                tmp = new_tmp();
6346
                tcg_gen_movi_i32(tmp, val);
6347
            } else {
6348
                /* MOVT */
6349
                tmp = load_reg(s, rd);
6350
                tcg_gen_ext16u_i32(tmp, tmp);
6351
                tcg_gen_ori_i32(tmp, tmp, val << 16);
6352
            }
6353
            store_reg(s, rd, tmp);
6354
        } else {
6355
            if (((insn >> 12) & 0xf) != 0xf)
6356
                goto illegal_op;
6357
            if (((insn >> 16) & 0xf) == 0) {
6358
                gen_nop_hint(s, insn & 0xff);
6359
            } else {
6360
                /* CPSR = immediate */
6361
                val = insn & 0xff;
6362
                shift = ((insn >> 8) & 0xf) * 2;
6363
                if (shift)
6364
                    val = (val >> shift) | (val << (32 - shift));
6365
                i = ((insn & (1 << 22)) != 0);
6366
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6367
                    goto illegal_op;
6368
            }
6369
        }
6370
    } else if ((insn & 0x0f900000) == 0x01000000
6371
               && (insn & 0x00000090) != 0x00000090) {
6372
        /* miscellaneous instructions */
6373
        op1 = (insn >> 21) & 3;
6374
        sh = (insn >> 4) & 0xf;
6375
        rm = insn & 0xf;
6376
        switch (sh) {
6377
        case 0x0: /* move program status register */
6378
            if (op1 & 1) {
6379
                /* PSR = reg */
6380
                tmp = load_reg(s, rm);
6381
                i = ((op1 & 2) != 0);
6382
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6383
                    goto illegal_op;
6384
            } else {
6385
                /* reg = PSR */
6386
                rd = (insn >> 12) & 0xf;
6387
                if (op1 & 2) {
6388
                    if (IS_USER(s))
6389
                        goto illegal_op;
6390
                    tmp = load_cpu_field(spsr);
6391
                } else {
6392
                    tmp = new_tmp();
6393
                    gen_helper_cpsr_read(tmp);
6394
                }
6395
                store_reg(s, rd, tmp);
6396
            }
6397
            break;
6398
        case 0x1:
6399
            if (op1 == 1) {
6400
                /* branch/exchange thumb (bx).  */
6401
                tmp = load_reg(s, rm);
6402
                gen_bx(s, tmp);
6403
            } else if (op1 == 3) {
6404
                /* clz */
6405
                rd = (insn >> 12) & 0xf;
6406
                tmp = load_reg(s, rm);
6407
                gen_helper_clz(tmp, tmp);
6408
                store_reg(s, rd, tmp);
6409
            } else {
6410
                goto illegal_op;
6411
            }
6412
            break;
6413
        case 0x2:
6414
            if (op1 == 1) {
6415
                ARCH(5J); /* bxj */
6416
                /* Trivial implementation equivalent to bx.  */
6417
                tmp = load_reg(s, rm);
6418
                gen_bx(s, tmp);
6419
            } else {
6420
                goto illegal_op;
6421
            }
6422
            break;
6423
        case 0x3:
6424
            if (op1 != 1)
6425
              goto illegal_op;
6426

    
6427
            /* branch link/exchange thumb (blx) */
6428
            tmp = load_reg(s, rm);
6429
            tmp2 = new_tmp();
6430
            tcg_gen_movi_i32(tmp2, s->pc);
6431
            store_reg(s, 14, tmp2);
6432
            gen_bx(s, tmp);
6433
            break;
6434
        case 0x5: /* saturating add/subtract */
6435
            rd = (insn >> 12) & 0xf;
6436
            rn = (insn >> 16) & 0xf;
6437
            tmp = load_reg(s, rm);
6438
            tmp2 = load_reg(s, rn);
6439
            if (op1 & 2)
6440
                gen_helper_double_saturate(tmp2, tmp2);
6441
            if (op1 & 1)
6442
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6443
            else
6444
                gen_helper_add_saturate(tmp, tmp, tmp2);
6445
            dead_tmp(tmp2);
6446
            store_reg(s, rd, tmp);
6447
            break;
6448
        case 7:
6449
            /* SMC instruction (op1 == 3)
6450
               and undefined instructions (op1 == 0 || op1 == 2)
6451
               will trap */
6452
            if (op1 != 1) {
6453
                goto illegal_op;
6454
            }
6455
            /* bkpt */
6456
            gen_exception_insn(s, 4, EXCP_BKPT);
6457
            break;
6458
        case 0x8: /* signed multiply */
6459
        case 0xa:
6460
        case 0xc:
6461
        case 0xe:
6462
            rs = (insn >> 8) & 0xf;
6463
            rn = (insn >> 12) & 0xf;
6464
            rd = (insn >> 16) & 0xf;
6465
            if (op1 == 1) {
6466
                /* (32 * 16) >> 16 */
6467
                tmp = load_reg(s, rm);
6468
                tmp2 = load_reg(s, rs);
6469
                if (sh & 4)
6470
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6471
                else
6472
                    gen_sxth(tmp2);
6473
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
6474
                tcg_gen_shri_i64(tmp64, tmp64, 16);
6475
                tmp = new_tmp();
6476
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6477
                tcg_temp_free_i64(tmp64);
6478
                if ((sh & 2) == 0) {
6479
                    tmp2 = load_reg(s, rn);
6480
                    gen_helper_add_setq(tmp, tmp, tmp2);
6481
                    dead_tmp(tmp2);
6482
                }
6483
                store_reg(s, rd, tmp);
6484
            } else {
6485
                /* 16 * 16 */
6486
                tmp = load_reg(s, rm);
6487
                tmp2 = load_reg(s, rs);
6488
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6489
                dead_tmp(tmp2);
6490
                if (op1 == 2) {
6491
                    tmp64 = tcg_temp_new_i64();
6492
                    tcg_gen_ext_i32_i64(tmp64, tmp);
6493
                    dead_tmp(tmp);
6494
                    gen_addq(s, tmp64, rn, rd);
6495
                    gen_storeq_reg(s, rn, rd, tmp64);
6496
                    tcg_temp_free_i64(tmp64);
6497
                } else {
6498
                    if (op1 == 0) {
6499
                        tmp2 = load_reg(s, rn);
6500
                        gen_helper_add_setq(tmp, tmp, tmp2);
6501
                        dead_tmp(tmp2);
6502
                    }
6503
                    store_reg(s, rd, tmp);
6504
                }
6505
            }
6506
            break;
6507
        default:
6508
            goto illegal_op;
6509
        }
6510
    } else if (((insn & 0x0e000000) == 0 &&
6511
                (insn & 0x00000090) != 0x90) ||
6512
               ((insn & 0x0e000000) == (1 << 25))) {
6513
        int set_cc, logic_cc, shiftop;
6514

    
6515
        op1 = (insn >> 21) & 0xf;
6516
        set_cc = (insn >> 20) & 1;
6517
        logic_cc = table_logic_cc[op1] & set_cc;
6518

    
6519
        /* data processing instruction */
6520
        if (insn & (1 << 25)) {
6521
            /* immediate operand */
6522
            val = insn & 0xff;
6523
            shift = ((insn >> 8) & 0xf) * 2;
6524
            if (shift) {
6525
                val = (val >> shift) | (val << (32 - shift));
6526
            }
6527
            tmp2 = new_tmp();
6528
            tcg_gen_movi_i32(tmp2, val);
6529
            if (logic_cc && shift) {
6530
                gen_set_CF_bit31(tmp2);
6531
            }
6532
        } else {
6533
            /* register */
6534
            rm = (insn) & 0xf;
6535
            tmp2 = load_reg(s, rm);
6536
            shiftop = (insn >> 5) & 3;
6537
            if (!(insn & (1 << 4))) {
6538
                shift = (insn >> 7) & 0x1f;
6539
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6540
            } else {
6541
                rs = (insn >> 8) & 0xf;
6542
                tmp = load_reg(s, rs);
6543
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6544
            }
6545
        }
6546
        if (op1 != 0x0f && op1 != 0x0d) {
6547
            rn = (insn >> 16) & 0xf;
6548
            tmp = load_reg(s, rn);
6549
        } else {
6550
            TCGV_UNUSED(tmp);
6551
        }
6552
        rd = (insn >> 12) & 0xf;
6553
        switch(op1) {
6554
        case 0x00:
6555
            tcg_gen_and_i32(tmp, tmp, tmp2);
6556
            if (logic_cc) {
6557
                gen_logic_CC(tmp);
6558
            }
6559
            store_reg_bx(env, s, rd, tmp);
6560
            break;
6561
        case 0x01:
6562
            tcg_gen_xor_i32(tmp, tmp, tmp2);
6563
            if (logic_cc) {
6564
                gen_logic_CC(tmp);
6565
            }
6566
            store_reg_bx(env, s, rd, tmp);
6567
            break;
6568
        case 0x02:
6569
            if (set_cc && rd == 15) {
6570
                /* SUBS r15, ... is used for exception return.  */
6571
                if (IS_USER(s)) {
6572
                    goto illegal_op;
6573
                }
6574
                gen_helper_sub_cc(tmp, tmp, tmp2);
6575
                gen_exception_return(s, tmp);
6576
            } else {
6577
                if (set_cc) {
6578
                    gen_helper_sub_cc(tmp, tmp, tmp2);
6579
                } else {
6580
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
6581
                }
6582
                store_reg_bx(env, s, rd, tmp);
6583
            }
6584
            break;
6585
        case 0x03:
6586
            if (set_cc) {
6587
                gen_helper_sub_cc(tmp, tmp2, tmp);
6588
            } else {
6589
                tcg_gen_sub_i32(tmp, tmp2, tmp);
6590
            }
6591
            store_reg_bx(env, s, rd, tmp);
6592
            break;
6593
        case 0x04:
6594
            if (set_cc) {
6595
                gen_helper_add_cc(tmp, tmp, tmp2);
6596
            } else {
6597
                tcg_gen_add_i32(tmp, tmp, tmp2);
6598
            }
6599
            store_reg_bx(env, s, rd, tmp);
6600
            break;
6601
        case 0x05:
6602
            if (set_cc) {
6603
                gen_helper_adc_cc(tmp, tmp, tmp2);
6604
            } else {
6605
                gen_add_carry(tmp, tmp, tmp2);
6606
            }
6607
            store_reg_bx(env, s, rd, tmp);
6608
            break;
6609
        case 0x06:
6610
            if (set_cc) {
6611
                gen_helper_sbc_cc(tmp, tmp, tmp2);
6612
            } else {
6613
                gen_sub_carry(tmp, tmp, tmp2);
6614
            }
6615
            store_reg_bx(env, s, rd, tmp);
6616
            break;
6617
        case 0x07:
6618
            if (set_cc) {
6619
                gen_helper_sbc_cc(tmp, tmp2, tmp);
6620
            } else {
6621
                gen_sub_carry(tmp, tmp2, tmp);
6622
            }
6623
            store_reg_bx(env, s, rd, tmp);
6624
            break;
6625
        case 0x08:
6626
            if (set_cc) {
6627
                tcg_gen_and_i32(tmp, tmp, tmp2);
6628
                gen_logic_CC(tmp);
6629
            }
6630
            dead_tmp(tmp);
6631
            break;
6632
        case 0x09:
6633
            if (set_cc) {
6634
                tcg_gen_xor_i32(tmp, tmp, tmp2);
6635
                gen_logic_CC(tmp);
6636
            }
6637
            dead_tmp(tmp);
6638
            break;
6639
        case 0x0a:
6640
            if (set_cc) {
6641
                gen_helper_sub_cc(tmp, tmp, tmp2);
6642
            }
6643
            dead_tmp(tmp);
6644
            break;
6645
        case 0x0b:
6646
            if (set_cc) {
6647
                gen_helper_add_cc(tmp, tmp, tmp2);
6648
            }
6649
            dead_tmp(tmp);
6650
            break;
6651
        case 0x0c:
6652
            tcg_gen_or_i32(tmp, tmp, tmp2);
6653
            if (logic_cc) {
6654
                gen_logic_CC(tmp);
6655
            }
6656
            store_reg_bx(env, s, rd, tmp);
6657
            break;
6658
        case 0x0d:
6659
            if (logic_cc && rd == 15) {
6660
                /* MOVS r15, ... is used for exception return.  */
6661
                if (IS_USER(s)) {
6662
                    goto illegal_op;
6663
                }
6664
                gen_exception_return(s, tmp2);
6665
            } else {
6666
                if (logic_cc) {
6667
                    gen_logic_CC(tmp2);
6668
                }
6669
                store_reg_bx(env, s, rd, tmp2);
6670
            }
6671
            break;
6672
        case 0x0e:
6673
            tcg_gen_andc_i32(tmp, tmp, tmp2);
6674
            if (logic_cc) {
6675
                gen_logic_CC(tmp);
6676
            }
6677
            store_reg_bx(env, s, rd, tmp);
6678
            break;
6679
        default:
6680
        case 0x0f:
6681
            tcg_gen_not_i32(tmp2, tmp2);
6682
            if (logic_cc) {
6683
                gen_logic_CC(tmp2);
6684
            }
6685
            store_reg_bx(env, s, rd, tmp2);
6686
            break;
6687
        }
6688
        if (op1 != 0x0f && op1 != 0x0d) {
6689
            dead_tmp(tmp2);
6690
        }
6691
    } else {
6692
        /* other instructions */
6693
        op1 = (insn >> 24) & 0xf;
6694
        switch(op1) {
6695
        case 0x0:
6696
        case 0x1:
6697
            /* multiplies, extra load/stores */
6698
            sh = (insn >> 5) & 3;
6699
            if (sh == 0) {
6700
                if (op1 == 0x0) {
6701
                    rd = (insn >> 16) & 0xf;
6702
                    rn = (insn >> 12) & 0xf;
6703
                    rs = (insn >> 8) & 0xf;
6704
                    rm = (insn) & 0xf;
6705
                    op1 = (insn >> 20) & 0xf;
6706
                    switch (op1) {
6707
                    case 0: case 1: case 2: case 3: case 6:
6708
                        /* 32 bit mul */
6709
                        tmp = load_reg(s, rs);
6710
                        tmp2 = load_reg(s, rm);
6711
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
6712
                        dead_tmp(tmp2);
6713
                        if (insn & (1 << 22)) {
6714
                            /* Subtract (mls) */
6715
                            ARCH(6T2);
6716
                            tmp2 = load_reg(s, rn);
6717
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
6718
                            dead_tmp(tmp2);
6719
                        } else if (insn & (1 << 21)) {
6720
                            /* Add */
6721
                            tmp2 = load_reg(s, rn);
6722
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6723
                            dead_tmp(tmp2);
6724
                        }
6725
                        if (insn & (1 << 20))
6726
                            gen_logic_CC(tmp);
6727
                        store_reg(s, rd, tmp);
6728
                        break;
6729
                    case 4:
6730
                        /* 64 bit mul double accumulate (UMAAL) */
6731
                        ARCH(6);
6732
                        tmp = load_reg(s, rs);
6733
                        tmp2 = load_reg(s, rm);
6734
                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6735
                        gen_addq_lo(s, tmp64, rn);
6736
                        gen_addq_lo(s, tmp64, rd);
6737
                        gen_storeq_reg(s, rn, rd, tmp64);
6738
                        tcg_temp_free_i64(tmp64);
6739
                        break;
6740
                    case 8: case 9: case 10: case 11:
6741
                    case 12: case 13: case 14: case 15:
6742
                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
6743
                        tmp = load_reg(s, rs);
6744
                        tmp2 = load_reg(s, rm);
6745
                        if (insn & (1 << 22)) {
6746
                            tmp64 = gen_muls_i64_i32(tmp, tmp2);
6747
                        } else {
6748
                            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6749
                        }
6750
                        if (insn & (1 << 21)) { /* mult accumulate */
6751
                            gen_addq(s, tmp64, rn, rd);
6752
                        }
6753
                        if (insn & (1 << 20)) {
6754
                            gen_logicq_cc(tmp64);
6755
                        }
6756
                        gen_storeq_reg(s, rn, rd, tmp64);
6757
                        tcg_temp_free_i64(tmp64);
6758
                        break;
6759
                    default:
6760
                        goto illegal_op;
6761
                    }
6762
                } else {
6763
                    rn = (insn >> 16) & 0xf;
6764
                    rd = (insn >> 12) & 0xf;
6765
                    if (insn & (1 << 23)) {
6766
                        /* load/store exclusive */
6767
                        op1 = (insn >> 21) & 0x3;
6768
                        if (op1)
6769
                            ARCH(6K);
6770
                        else
6771
                            ARCH(6);
6772
                        addr = tcg_temp_local_new_i32();
6773
                        load_reg_var(s, addr, rn);
6774
                        if (insn & (1 << 20)) {
6775
                            switch (op1) {
6776
                            case 0: /* ldrex */
6777
                                gen_load_exclusive(s, rd, 15, addr, 2);
6778
                                break;
6779
                            case 1: /* ldrexd */
6780
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
6781
                                break;
6782
                            case 2: /* ldrexb */
6783
                                gen_load_exclusive(s, rd, 15, addr, 0);
6784
                                break;
6785
                            case 3: /* ldrexh */
6786
                                gen_load_exclusive(s, rd, 15, addr, 1);
6787
                                break;
6788
                            default:
6789
                                abort();
6790
                            }
6791
                        } else {
6792
                            rm = insn & 0xf;
6793
                            switch (op1) {
6794
                            case 0:  /*  strex */
6795
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
6796
                                break;
6797
                            case 1: /*  strexd */
6798
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
6799
                                break;
6800
                            case 2: /*  strexb */
6801
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
6802
                                break;
6803
                            case 3: /* strexh */
6804
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
6805
                                break;
6806
                            default:
6807
                                abort();
6808
                            }
6809
                        }
6810
                        tcg_temp_free(addr);
6811
                    } else {
6812
                        /* SWP instruction */
6813
                        rm = (insn) & 0xf;
6814

    
6815
                        /* ??? This is not really atomic.  However we know
6816
                           we never have multiple CPUs running in parallel,
6817
                           so it is good enough.  */
6818
                        addr = load_reg(s, rn);
6819
                        tmp = load_reg(s, rm);
6820
                        if (insn & (1 << 22)) {
6821
                            tmp2 = gen_ld8u(addr, IS_USER(s));
6822
                            gen_st8(tmp, addr, IS_USER(s));
6823
                        } else {
6824
                            tmp2 = gen_ld32(addr, IS_USER(s));
6825
                            gen_st32(tmp, addr, IS_USER(s));
6826
                        }
6827
                        dead_tmp(addr);
6828
                        store_reg(s, rd, tmp2);
6829
                    }
6830
                }
6831
            } else {
6832
                int address_offset;
6833
                int load;
6834
                /* Misc load/store */
6835
                rn = (insn >> 16) & 0xf;
6836
                rd = (insn >> 12) & 0xf;
6837
                addr = load_reg(s, rn);
6838
                if (insn & (1 << 24))
6839
                    gen_add_datah_offset(s, insn, 0, addr);
6840
                address_offset = 0;
6841
                if (insn & (1 << 20)) {
6842
                    /* load */
6843
                    switch(sh) {
6844
                    case 1:
6845
                        tmp = gen_ld16u(addr, IS_USER(s));
6846
                        break;
6847
                    case 2:
6848
                        tmp = gen_ld8s(addr, IS_USER(s));
6849
                        break;
6850
                    default:
6851
                    case 3:
6852
                        tmp = gen_ld16s(addr, IS_USER(s));
6853
                        break;
6854
                    }
6855
                    load = 1;
6856
                } else if (sh & 2) {
6857
                    /* doubleword */
6858
                    if (sh & 1) {
6859
                        /* store */
6860
                        tmp = load_reg(s, rd);
6861
                        gen_st32(tmp, addr, IS_USER(s));
6862
                        tcg_gen_addi_i32(addr, addr, 4);
6863
                        tmp = load_reg(s, rd + 1);
6864
                        gen_st32(tmp, addr, IS_USER(s));
6865
                        load = 0;
6866
                    } else {
6867
                        /* load */
6868
                        tmp = gen_ld32(addr, IS_USER(s));
6869
                        store_reg(s, rd, tmp);
6870
                        tcg_gen_addi_i32(addr, addr, 4);
6871
                        tmp = gen_ld32(addr, IS_USER(s));
6872
                        rd++;
6873
                        load = 1;
6874
                    }
6875
                    address_offset = -4;
6876
                } else {
6877
                    /* store */
6878
                    tmp = load_reg(s, rd);
6879
                    gen_st16(tmp, addr, IS_USER(s));
6880
                    load = 0;
6881
                }
6882
                /* Perform base writeback before the loaded value to
6883
                   ensure correct behavior with overlapping index registers.
6884
                   ldrd with base writeback is is undefined if the
6885
                   destination and index registers overlap.  */
6886
                if (!(insn & (1 << 24))) {
6887
                    gen_add_datah_offset(s, insn, address_offset, addr);
6888
                    store_reg(s, rn, addr);
6889
                } else if (insn & (1 << 21)) {
6890
                    if (address_offset)
6891
                        tcg_gen_addi_i32(addr, addr, address_offset);
6892
                    store_reg(s, rn, addr);
6893
                } else {
6894
                    dead_tmp(addr);
6895
                }
6896
                if (load) {
6897
                    /* Complete the load.  */
6898
                    store_reg(s, rd, tmp);
6899
                }
6900
            }
6901
            break;
6902
        case 0x4:
6903
        case 0x5:
6904
            goto do_ldst;
6905
        case 0x6:
6906
        case 0x7:
6907
            if (insn & (1 << 4)) {
6908
                ARCH(6);
6909
                /* Armv6 Media instructions.  */
6910
                rm = insn & 0xf;
6911
                rn = (insn >> 16) & 0xf;
6912
                rd = (insn >> 12) & 0xf;
6913
                rs = (insn >> 8) & 0xf;
6914
                switch ((insn >> 23) & 3) {
6915
                case 0: /* Parallel add/subtract.  */
6916
                    op1 = (insn >> 20) & 7;
6917
                    tmp = load_reg(s, rn);
6918
                    tmp2 = load_reg(s, rm);
6919
                    sh = (insn >> 5) & 7;
6920
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6921
                        goto illegal_op;
6922
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6923
                    dead_tmp(tmp2);
6924
                    store_reg(s, rd, tmp);
6925
                    break;
6926
                case 1:
6927
                    if ((insn & 0x00700020) == 0) {
6928
                        /* Halfword pack.  */
6929
                        tmp = load_reg(s, rn);
6930
                        tmp2 = load_reg(s, rm);
6931
                        shift = (insn >> 7) & 0x1f;
6932
                        if (insn & (1 << 6)) {
6933
                            /* pkhtb */
6934
                            if (shift == 0)
6935
                                shift = 31;
6936
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
6937
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6938
                            tcg_gen_ext16u_i32(tmp2, tmp2);
6939
                        } else {
6940
                            /* pkhbt */
6941
                            if (shift)
6942
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
6943
                            tcg_gen_ext16u_i32(tmp, tmp);
6944
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6945
                        }
6946
                        tcg_gen_or_i32(tmp, tmp, tmp2);
6947
                        dead_tmp(tmp2);
6948
                        store_reg(s, rd, tmp);
6949
                    } else if ((insn & 0x00200020) == 0x00200000) {
6950
                        /* [us]sat */
6951
                        tmp = load_reg(s, rm);
6952
                        shift = (insn >> 7) & 0x1f;
6953
                        if (insn & (1 << 6)) {
6954
                            if (shift == 0)
6955
                                shift = 31;
6956
                            tcg_gen_sari_i32(tmp, tmp, shift);
6957
                        } else {
6958
                            tcg_gen_shli_i32(tmp, tmp, shift);
6959
                        }
6960
                        sh = (insn >> 16) & 0x1f;
6961
                        tmp2 = tcg_const_i32(sh);
6962
                        if (insn & (1 << 22))
6963
                          gen_helper_usat(tmp, tmp, tmp2);
6964
                        else
6965
                          gen_helper_ssat(tmp, tmp, tmp2);
6966
                        tcg_temp_free_i32(tmp2);
6967
                        store_reg(s, rd, tmp);
6968
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
6969
                        /* [us]sat16 */
6970
                        tmp = load_reg(s, rm);
6971
                        sh = (insn >> 16) & 0x1f;
6972
                        tmp2 = tcg_const_i32(sh);
6973
                        if (insn & (1 << 22))
6974
                          gen_helper_usat16(tmp, tmp, tmp2);
6975
                        else
6976
                          gen_helper_ssat16(tmp, tmp, tmp2);
6977
                        tcg_temp_free_i32(tmp2);
6978
                        store_reg(s, rd, tmp);
6979
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6980
                        /* Select bytes.  */
6981
                        tmp = load_reg(s, rn);
6982
                        tmp2 = load_reg(s, rm);
6983
                        tmp3 = new_tmp();
6984
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6985
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6986
                        dead_tmp(tmp3);
6987
                        dead_tmp(tmp2);
6988
                        store_reg(s, rd, tmp);
6989
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6990
                        tmp = load_reg(s, rm);
6991
                        shift = (insn >> 10) & 3;
6992
                        /* ??? In many cases it's not neccessary to do a
6993
                           rotate, a shift is sufficient.  */
6994
                        if (shift != 0)
6995
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
6996
                        op1 = (insn >> 20) & 7;
6997
                        switch (op1) {
6998
                        case 0: gen_sxtb16(tmp);  break;
6999
                        case 2: gen_sxtb(tmp);    break;
7000
                        case 3: gen_sxth(tmp);    break;
7001
                        case 4: gen_uxtb16(tmp);  break;
7002
                        case 6: gen_uxtb(tmp);    break;
7003
                        case 7: gen_uxth(tmp);    break;
7004
                        default: goto illegal_op;
7005
                        }
7006
                        if (rn != 15) {
7007
                            tmp2 = load_reg(s, rn);
7008
                            if ((op1 & 3) == 0) {
7009
                                gen_add16(tmp, tmp2);
7010
                            } else {
7011
                                tcg_gen_add_i32(tmp, tmp, tmp2);
7012
                                dead_tmp(tmp2);
7013
                            }
7014
                        }
7015
                        store_reg(s, rd, tmp);
7016
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7017
                        /* rev */
7018
                        tmp = load_reg(s, rm);
7019
                        if (insn & (1 << 22)) {
7020
                            if (insn & (1 << 7)) {
7021
                                gen_revsh(tmp);
7022
                            } else {
7023
                                ARCH(6T2);
7024
                                gen_helper_rbit(tmp, tmp);
7025
                            }
7026
                        } else {
7027
                            if (insn & (1 << 7))
7028
                                gen_rev16(tmp);
7029
                            else
7030
                                tcg_gen_bswap32_i32(tmp, tmp);
7031
                        }
7032
                        store_reg(s, rd, tmp);
7033
                    } else {
7034
                        goto illegal_op;
7035
                    }
7036
                    break;
7037
                case 2: /* Multiplies (Type 3).  */
7038
                    tmp = load_reg(s, rm);
7039
                    tmp2 = load_reg(s, rs);
7040
                    if (insn & (1 << 20)) {
7041
                        /* Signed multiply most significant [accumulate].
7042
                           (SMMUL, SMMLA, SMMLS) */
7043
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7044

    
7045
                        if (rd != 15) {
7046
                            tmp = load_reg(s, rd);
7047
                            if (insn & (1 << 6)) {
7048
                                tmp64 = gen_subq_msw(tmp64, tmp);
7049
                            } else {
7050
                                tmp64 = gen_addq_msw(tmp64, tmp);
7051
                            }
7052
                        }
7053
                        if (insn & (1 << 5)) {
7054
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7055
                        }
7056
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
7057
                        tmp = new_tmp();
7058
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
7059
                        tcg_temp_free_i64(tmp64);
7060
                        store_reg(s, rn, tmp);
7061
                    } else {
7062
                        if (insn & (1 << 5))
7063
                            gen_swap_half(tmp2);
7064
                        gen_smul_dual(tmp, tmp2);
7065
                        /* This addition cannot overflow.  */
7066
                        if (insn & (1 << 6)) {
7067
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
7068
                        } else {
7069
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7070
                        }
7071
                        dead_tmp(tmp2);
7072
                        if (insn & (1 << 22)) {
7073
                            /* smlald, smlsld */
7074
                            tmp64 = tcg_temp_new_i64();
7075
                            tcg_gen_ext_i32_i64(tmp64, tmp);
7076
                            dead_tmp(tmp);
7077
                            gen_addq(s, tmp64, rd, rn);
7078
                            gen_storeq_reg(s, rd, rn, tmp64);
7079
                            tcg_temp_free_i64(tmp64);
7080
                        } else {
7081
                            /* smuad, smusd, smlad, smlsd */
7082
                            if (rd != 15)
7083
                              {
7084
                                tmp2 = load_reg(s, rd);
7085
                                gen_helper_add_setq(tmp, tmp, tmp2);
7086
                                dead_tmp(tmp2);
7087
                              }
7088
                            store_reg(s, rn, tmp);
7089
                        }
7090
                    }
7091
                    break;
7092
                case 3:
7093
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7094
                    switch (op1) {
7095
                    case 0: /* Unsigned sum of absolute differences.  */
7096
                        ARCH(6);
7097
                        tmp = load_reg(s, rm);
7098
                        tmp2 = load_reg(s, rs);
7099
                        gen_helper_usad8(tmp, tmp, tmp2);
7100
                        dead_tmp(tmp2);
7101
                        if (rd != 15) {
7102
                            tmp2 = load_reg(s, rd);
7103
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7104
                            dead_tmp(tmp2);
7105
                        }
7106
                        store_reg(s, rn, tmp);
7107
                        break;
7108
                    case 0x20: case 0x24: case 0x28: case 0x2c:
7109
                        /* Bitfield insert/clear.  */
7110
                        ARCH(6T2);
7111
                        shift = (insn >> 7) & 0x1f;
7112
                        i = (insn >> 16) & 0x1f;
7113
                        i = i + 1 - shift;
7114
                        if (rm == 15) {
7115
                            tmp = new_tmp();
7116
                            tcg_gen_movi_i32(tmp, 0);
7117
                        } else {
7118
                            tmp = load_reg(s, rm);
7119
                        }
7120
                        if (i != 32) {
7121
                            tmp2 = load_reg(s, rd);
7122
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
7123
                            dead_tmp(tmp2);
7124
                        }
7125
                        store_reg(s, rd, tmp);
7126
                        break;
7127
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7128
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7129
                        ARCH(6T2);
7130
                        tmp = load_reg(s, rm);
7131
                        shift = (insn >> 7) & 0x1f;
7132
                        i = ((insn >> 16) & 0x1f) + 1;
7133
                        if (shift + i > 32)
7134
                            goto illegal_op;
7135
                        if (i < 32) {
7136
                            if (op1 & 0x20) {
7137
                                gen_ubfx(tmp, shift, (1u << i) - 1);
7138
                            } else {
7139
                                gen_sbfx(tmp, shift, i);
7140
                            }
7141
                        }
7142
                        store_reg(s, rd, tmp);
7143
                        break;
7144
                    default:
7145
                        goto illegal_op;
7146
                    }
7147
                    break;
7148
                }
7149
                break;
7150
            }
7151
        do_ldst:
7152
            /* Check for undefined extension instructions
7153
             * per the ARM Bible IE:
7154
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
7155
             */
7156
            sh = (0xf << 20) | (0xf << 4);
7157
            if (op1 == 0x7 && ((insn & sh) == sh))
7158
            {
7159
                goto illegal_op;
7160
            }
7161
            /* load/store byte/word */
7162
            rn = (insn >> 16) & 0xf;
7163
            rd = (insn >> 12) & 0xf;
7164
            tmp2 = load_reg(s, rn);
7165
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7166
            if (insn & (1 << 24))
7167
                gen_add_data_offset(s, insn, tmp2);
7168
            if (insn & (1 << 20)) {
7169
                /* load */
7170
                if (insn & (1 << 22)) {
7171
                    tmp = gen_ld8u(tmp2, i);
7172
                } else {
7173
                    tmp = gen_ld32(tmp2, i);
7174
                }
7175
            } else {
7176
                /* store */
7177
                tmp = load_reg(s, rd);
7178
                if (insn & (1 << 22))
7179
                    gen_st8(tmp, tmp2, i);
7180
                else
7181
                    gen_st32(tmp, tmp2, i);
7182
            }
7183
            if (!(insn & (1 << 24))) {
7184
                gen_add_data_offset(s, insn, tmp2);
7185
                store_reg(s, rn, tmp2);
7186
            } else if (insn & (1 << 21)) {
7187
                store_reg(s, rn, tmp2);
7188
            } else {
7189
                dead_tmp(tmp2);
7190
            }
7191
            if (insn & (1 << 20)) {
7192
                /* Complete the load.  */
7193
                if (rd == 15)
7194
                    gen_bx(s, tmp);
7195
                else
7196
                    store_reg(s, rd, tmp);
7197
            }
7198
            break;
7199
        case 0x08:
7200
        case 0x09:
7201
            {
7202
                int j, n, user, loaded_base;
7203
                TCGv loaded_var;
7204
                /* load/store multiple words */
7205
                /* XXX: store correct base if write back */
7206
                user = 0;
7207
                if (insn & (1 << 22)) {
7208
                    if (IS_USER(s))
7209
                        goto illegal_op; /* only usable in supervisor mode */
7210

    
7211
                    if ((insn & (1 << 15)) == 0)
7212
                        user = 1;
7213
                }
7214
                rn = (insn >> 16) & 0xf;
7215
                addr = load_reg(s, rn);
7216

    
7217
                /* compute total size */
7218
                loaded_base = 0;
7219
                TCGV_UNUSED(loaded_var);
7220
                n = 0;
7221
                for(i=0;i<16;i++) {
7222
                    if (insn & (1 << i))
7223
                        n++;
7224
                }
7225
                /* XXX: test invalid n == 0 case ? */
7226
                if (insn & (1 << 23)) {
7227
                    if (insn & (1 << 24)) {
7228
                        /* pre increment */
7229
                        tcg_gen_addi_i32(addr, addr, 4);
7230
                    } else {
7231
                        /* post increment */
7232
                    }
7233
                } else {
7234
                    if (insn & (1 << 24)) {
7235
                        /* pre decrement */
7236
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
7237
                    } else {
7238
                        /* post decrement */
7239
                        if (n != 1)
7240
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7241
                    }
7242
                }
7243
                j = 0;
7244
                for(i=0;i<16;i++) {
7245
                    if (insn & (1 << i)) {
7246
                        if (insn & (1 << 20)) {
7247
                            /* load */
7248
                            tmp = gen_ld32(addr, IS_USER(s));
7249
                            if (i == 15) {
7250
                                gen_bx(s, tmp);
7251
                            } else if (user) {
7252
                                tmp2 = tcg_const_i32(i);
7253
                                gen_helper_set_user_reg(tmp2, tmp);
7254
                                tcg_temp_free_i32(tmp2);
7255
                                dead_tmp(tmp);
7256
                            } else if (i == rn) {
7257
                                loaded_var = tmp;
7258
                                loaded_base = 1;
7259
                            } else {
7260
                                store_reg(s, i, tmp);
7261
                            }
7262
                        } else {
7263
                            /* store */
7264
                            if (i == 15) {
7265
                                /* special case: r15 = PC + 8 */
7266
                                val = (long)s->pc + 4;
7267
                                tmp = new_tmp();
7268
                                tcg_gen_movi_i32(tmp, val);
7269
                            } else if (user) {
7270
                                tmp = new_tmp();
7271
                                tmp2 = tcg_const_i32(i);
7272
                                gen_helper_get_user_reg(tmp, tmp2);
7273
                                tcg_temp_free_i32(tmp2);
7274
                            } else {
7275
                                tmp = load_reg(s, i);
7276
                            }
7277
                            gen_st32(tmp, addr, IS_USER(s));
7278
                        }
7279
                        j++;
7280
                        /* no need to add after the last transfer */
7281
                        if (j != n)
7282
                            tcg_gen_addi_i32(addr, addr, 4);
7283
                    }
7284
                }
7285
                if (insn & (1 << 21)) {
7286
                    /* write back */
7287
                    if (insn & (1 << 23)) {
7288
                        if (insn & (1 << 24)) {
7289
                            /* pre increment */
7290
                        } else {
7291
                            /* post increment */
7292
                            tcg_gen_addi_i32(addr, addr, 4);
7293
                        }
7294
                    } else {
7295
                        if (insn & (1 << 24)) {
7296
                            /* pre decrement */
7297
                            if (n != 1)
7298
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7299
                        } else {
7300
                            /* post decrement */
7301
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
7302
                        }
7303
                    }
7304
                    store_reg(s, rn, addr);
7305
                } else {
7306
                    dead_tmp(addr);
7307
                }
7308
                if (loaded_base) {
7309
                    store_reg(s, rn, loaded_var);
7310
                }
7311
                if ((insn & (1 << 22)) && !user) {
7312
                    /* Restore CPSR from SPSR.  */
7313
                    tmp = load_cpu_field(spsr);
7314
                    gen_set_cpsr(tmp, 0xffffffff);
7315
                    dead_tmp(tmp);
7316
                    s->is_jmp = DISAS_UPDATE;
7317
                }
7318
            }
7319
            break;
7320
        case 0xa:
7321
        case 0xb:
7322
            {
7323
                int32_t offset;
7324

    
7325
                /* branch (and link) */
7326
                val = (int32_t)s->pc;
7327
                if (insn & (1 << 24)) {
7328
                    tmp = new_tmp();
7329
                    tcg_gen_movi_i32(tmp, val);
7330
                    store_reg(s, 14, tmp);
7331
                }
7332
                offset = (((int32_t)insn << 8) >> 8);
7333
                val += (offset << 2) + 4;
7334
                gen_jmp(s, val);
7335
            }
7336
            break;
7337
        case 0xc:
7338
        case 0xd:
7339
        case 0xe:
7340
            /* Coprocessor.  */
7341
            if (disas_coproc_insn(env, s, insn))
7342
                goto illegal_op;
7343
            break;
7344
        case 0xf:
7345
            /* swi */
7346
            gen_set_pc_im(s->pc);
7347
            s->is_jmp = DISAS_SWI;
7348
            break;
7349
        default:
7350
        illegal_op:
7351
            gen_exception_insn(s, 4, EXCP_UDEF);
7352
            break;
7353
        }
7354
    }
7355
}
7356

    
7357
/* Return true if this is a Thumb-2 logical op.  */
7358
static int
7359
thumb2_logic_op(int op)
7360
{
7361
    return (op < 8);
7362
}
7363

    
7364
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7365
   then set condition code flags based on the result of the operation.
7366
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7367
   to the high bit of T1.
7368
   Returns zero if the opcode is valid.  */
7369

    
7370
static int
7371
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7372
{
7373
    int logic_cc;
7374

    
7375
    logic_cc = 0;
7376
    switch (op) {
7377
    case 0: /* and */
7378
        tcg_gen_and_i32(t0, t0, t1);
7379
        logic_cc = conds;
7380
        break;
7381
    case 1: /* bic */
7382
        tcg_gen_andc_i32(t0, t0, t1);
7383
        logic_cc = conds;
7384
        break;
7385
    case 2: /* orr */
7386
        tcg_gen_or_i32(t0, t0, t1);
7387
        logic_cc = conds;
7388
        break;
7389
    case 3: /* orn */
7390
        tcg_gen_not_i32(t1, t1);
7391
        tcg_gen_or_i32(t0, t0, t1);
7392
        logic_cc = conds;
7393
        break;
7394
    case 4: /* eor */
7395
        tcg_gen_xor_i32(t0, t0, t1);
7396
        logic_cc = conds;
7397
        break;
7398
    case 8: /* add */
7399
        if (conds)
7400
            gen_helper_add_cc(t0, t0, t1);
7401
        else
7402
            tcg_gen_add_i32(t0, t0, t1);
7403
        break;
7404
    case 10: /* adc */
7405
        if (conds)
7406
            gen_helper_adc_cc(t0, t0, t1);
7407
        else
7408
            gen_adc(t0, t1);
7409
        break;
7410
    case 11: /* sbc */
7411
        if (conds)
7412
            gen_helper_sbc_cc(t0, t0, t1);
7413
        else
7414
            gen_sub_carry(t0, t0, t1);
7415
        break;
7416
    case 13: /* sub */
7417
        if (conds)
7418
            gen_helper_sub_cc(t0, t0, t1);
7419
        else
7420
            tcg_gen_sub_i32(t0, t0, t1);
7421
        break;
7422
    case 14: /* rsb */
7423
        if (conds)
7424
            gen_helper_sub_cc(t0, t1, t0);
7425
        else
7426
            tcg_gen_sub_i32(t0, t1, t0);
7427
        break;
7428
    default: /* 5, 6, 7, 9, 12, 15. */
7429
        return 1;
7430
    }
7431
    if (logic_cc) {
7432
        gen_logic_CC(t0);
7433
        if (shifter_out)
7434
            gen_set_CF_bit31(t1);
7435
    }
7436
    return 0;
7437
}
7438

    
7439
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7440
   is not legal.  */
7441
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7442
{
7443
    uint32_t insn, imm, shift, offset;
7444
    uint32_t rd, rn, rm, rs;
7445
    TCGv tmp;
7446
    TCGv tmp2;
7447
    TCGv tmp3;
7448
    TCGv addr;
7449
    TCGv_i64 tmp64;
7450
    int op;
7451
    int shiftop;
7452
    int conds;
7453
    int logic_cc;
7454

    
7455
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7456
          || arm_feature (env, ARM_FEATURE_M))) {
7457
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7458
           16-bit instructions to get correct prefetch abort behavior.  */
7459
        insn = insn_hw1;
7460
        if ((insn & (1 << 12)) == 0) {
7461
            /* Second half of blx.  */
7462
            offset = ((insn & 0x7ff) << 1);
7463
            tmp = load_reg(s, 14);
7464
            tcg_gen_addi_i32(tmp, tmp, offset);
7465
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7466

    
7467
            tmp2 = new_tmp();
7468
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7469
            store_reg(s, 14, tmp2);
7470
            gen_bx(s, tmp);
7471
            return 0;
7472
        }
7473
        if (insn & (1 << 11)) {
7474
            /* Second half of bl.  */
7475
            offset = ((insn & 0x7ff) << 1) | 1;
7476
            tmp = load_reg(s, 14);
7477
            tcg_gen_addi_i32(tmp, tmp, offset);
7478

    
7479
            tmp2 = new_tmp();
7480
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7481
            store_reg(s, 14, tmp2);
7482
            gen_bx(s, tmp);
7483
            return 0;
7484
        }
7485
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7486
            /* Instruction spans a page boundary.  Implement it as two
7487
               16-bit instructions in case the second half causes an
7488
               prefetch abort.  */
7489
            offset = ((int32_t)insn << 21) >> 9;
7490
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7491
            return 0;
7492
        }
7493
        /* Fall through to 32-bit decode.  */
7494
    }
7495

    
7496
    insn = lduw_code(s->pc);
7497
    s->pc += 2;
7498
    insn |= (uint32_t)insn_hw1 << 16;
7499

    
7500
    if ((insn & 0xf800e800) != 0xf000e800) {
7501
        ARCH(6T2);
7502
    }
7503

    
7504
    rn = (insn >> 16) & 0xf;
7505
    rs = (insn >> 12) & 0xf;
7506
    rd = (insn >> 8) & 0xf;
7507
    rm = insn & 0xf;
7508
    switch ((insn >> 25) & 0xf) {
7509
    case 0: case 1: case 2: case 3:
7510
        /* 16-bit instructions.  Should never happen.  */
7511
        abort();
7512
    case 4:
7513
        if (insn & (1 << 22)) {
7514
            /* Other load/store, table branch.  */
7515
            if (insn & 0x01200000) {
7516
                /* Load/store doubleword.  */
7517
                if (rn == 15) {
7518
                    addr = new_tmp();
7519
                    tcg_gen_movi_i32(addr, s->pc & ~3);
7520
                } else {
7521
                    addr = load_reg(s, rn);
7522
                }
7523
                offset = (insn & 0xff) * 4;
7524
                if ((insn & (1 << 23)) == 0)
7525
                    offset = -offset;
7526
                if (insn & (1 << 24)) {
7527
                    tcg_gen_addi_i32(addr, addr, offset);
7528
                    offset = 0;
7529
                }
7530
                if (insn & (1 << 20)) {
7531
                    /* ldrd */
7532
                    tmp = gen_ld32(addr, IS_USER(s));
7533
                    store_reg(s, rs, tmp);
7534
                    tcg_gen_addi_i32(addr, addr, 4);
7535
                    tmp = gen_ld32(addr, IS_USER(s));
7536
                    store_reg(s, rd, tmp);
7537
                } else {
7538
                    /* strd */
7539
                    tmp = load_reg(s, rs);
7540
                    gen_st32(tmp, addr, IS_USER(s));
7541
                    tcg_gen_addi_i32(addr, addr, 4);
7542
                    tmp = load_reg(s, rd);
7543
                    gen_st32(tmp, addr, IS_USER(s));
7544
                }
7545
                if (insn & (1 << 21)) {
7546
                    /* Base writeback.  */
7547
                    if (rn == 15)
7548
                        goto illegal_op;
7549
                    tcg_gen_addi_i32(addr, addr, offset - 4);
7550
                    store_reg(s, rn, addr);
7551
                } else {
7552
                    dead_tmp(addr);
7553
                }
7554
            } else if ((insn & (1 << 23)) == 0) {
7555
                /* Load/store exclusive word.  */
7556
                addr = tcg_temp_local_new();
7557
                load_reg_var(s, addr, rn);
7558
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
7559
                if (insn & (1 << 20)) {
7560
                    gen_load_exclusive(s, rs, 15, addr, 2);
7561
                } else {
7562
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
7563
                }
7564
                tcg_temp_free(addr);
7565
            } else if ((insn & (1 << 6)) == 0) {
7566
                /* Table Branch.  */
7567
                if (rn == 15) {
7568
                    addr = new_tmp();
7569
                    tcg_gen_movi_i32(addr, s->pc);
7570
                } else {
7571
                    addr = load_reg(s, rn);
7572
                }
7573
                tmp = load_reg(s, rm);
7574
                tcg_gen_add_i32(addr, addr, tmp);
7575
                if (insn & (1 << 4)) {
7576
                    /* tbh */
7577
                    tcg_gen_add_i32(addr, addr, tmp);
7578
                    dead_tmp(tmp);
7579
                    tmp = gen_ld16u(addr, IS_USER(s));
7580
                } else { /* tbb */
7581
                    dead_tmp(tmp);
7582
                    tmp = gen_ld8u(addr, IS_USER(s));
7583
                }
7584
                dead_tmp(addr);
7585
                tcg_gen_shli_i32(tmp, tmp, 1);
7586
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7587
                store_reg(s, 15, tmp);
7588
            } else {
7589
                /* Load/store exclusive byte/halfword/doubleword.  */
7590
                ARCH(7);
7591
                op = (insn >> 4) & 0x3;
7592
                if (op == 2) {
7593
                    goto illegal_op;
7594
                }
7595
                addr = tcg_temp_local_new();
7596
                load_reg_var(s, addr, rn);
7597
                if (insn & (1 << 20)) {
7598
                    gen_load_exclusive(s, rs, rd, addr, op);
7599
                } else {
7600
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
7601
                }
7602
                tcg_temp_free(addr);
7603
            }
7604
        } else {
7605
            /* Load/store multiple, RFE, SRS.  */
7606
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7607
                /* Not available in user mode.  */
7608
                if (IS_USER(s))
7609
                    goto illegal_op;
7610
                if (insn & (1 << 20)) {
7611
                    /* rfe */
7612
                    addr = load_reg(s, rn);
7613
                    if ((insn & (1 << 24)) == 0)
7614
                        tcg_gen_addi_i32(addr, addr, -8);
7615
                    /* Load PC into tmp and CPSR into tmp2.  */
7616
                    tmp = gen_ld32(addr, 0);
7617
                    tcg_gen_addi_i32(addr, addr, 4);
7618
                    tmp2 = gen_ld32(addr, 0);
7619
                    if (insn & (1 << 21)) {
7620
                        /* Base writeback.  */
7621
                        if (insn & (1 << 24)) {
7622
                            tcg_gen_addi_i32(addr, addr, 4);
7623
                        } else {
7624
                            tcg_gen_addi_i32(addr, addr, -4);
7625
                        }
7626
                        store_reg(s, rn, addr);
7627
                    } else {
7628
                        dead_tmp(addr);
7629
                    }
7630
                    gen_rfe(s, tmp, tmp2);
7631
                } else {
7632
                    /* srs */
7633
                    op = (insn & 0x1f);
7634
                    addr = new_tmp();
7635
                    tmp = tcg_const_i32(op);
7636
                    gen_helper_get_r13_banked(addr, cpu_env, tmp);
7637
                    tcg_temp_free_i32(tmp);
7638
                    if ((insn & (1 << 24)) == 0) {
7639
                        tcg_gen_addi_i32(addr, addr, -8);
7640
                    }
7641
                    tmp = load_reg(s, 14);
7642
                    gen_st32(tmp, addr, 0);
7643
                    tcg_gen_addi_i32(addr, addr, 4);
7644
                    tmp = new_tmp();
7645
                    gen_helper_cpsr_read(tmp);
7646
                    gen_st32(tmp, addr, 0);
7647
                    if (insn & (1 << 21)) {
7648
                        if ((insn & (1 << 24)) == 0) {
7649
                            tcg_gen_addi_i32(addr, addr, -4);
7650
                        } else {
7651
                            tcg_gen_addi_i32(addr, addr, 4);
7652
                        }
7653
                        tmp = tcg_const_i32(op);
7654
                        gen_helper_set_r13_banked(cpu_env, tmp, addr);
7655
                        tcg_temp_free_i32(tmp);
7656
                    } else {
7657
                        dead_tmp(addr);
7658
                    }
7659
                }
7660
            } else {
7661
                int i;
7662
                /* Load/store multiple.  */
7663
                addr = load_reg(s, rn);
7664
                offset = 0;
7665
                for (i = 0; i < 16; i++) {
7666
                    if (insn & (1 << i))
7667
                        offset += 4;
7668
                }
7669
                if (insn & (1 << 24)) {
7670
                    tcg_gen_addi_i32(addr, addr, -offset);
7671
                }
7672

    
7673
                for (i = 0; i < 16; i++) {
7674
                    if ((insn & (1 << i)) == 0)
7675
                        continue;
7676
                    if (insn & (1 << 20)) {
7677
                        /* Load.  */
7678
                        tmp = gen_ld32(addr, IS_USER(s));
7679
                        if (i == 15) {
7680
                            gen_bx(s, tmp);
7681
                        } else {
7682
                            store_reg(s, i, tmp);
7683
                        }
7684
                    } else {
7685
                        /* Store.  */
7686
                        tmp = load_reg(s, i);
7687
                        gen_st32(tmp, addr, IS_USER(s));
7688
                    }
7689
                    tcg_gen_addi_i32(addr, addr, 4);
7690
                }
7691
                if (insn & (1 << 21)) {
7692
                    /* Base register writeback.  */
7693
                    if (insn & (1 << 24)) {
7694
                        tcg_gen_addi_i32(addr, addr, -offset);
7695
                    }
7696
                    /* Fault if writeback register is in register list.  */
7697
                    if (insn & (1 << rn))
7698
                        goto illegal_op;
7699
                    store_reg(s, rn, addr);
7700
                } else {
7701
                    dead_tmp(addr);
7702
                }
7703
            }
7704
        }
7705
        break;
7706
    case 5:
7707

    
7708
        op = (insn >> 21) & 0xf;
7709
        if (op == 6) {
7710
            /* Halfword pack.  */
7711
            tmp = load_reg(s, rn);
7712
            tmp2 = load_reg(s, rm);
7713
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
7714
            if (insn & (1 << 5)) {
7715
                /* pkhtb */
7716
                if (shift == 0)
7717
                    shift = 31;
7718
                tcg_gen_sari_i32(tmp2, tmp2, shift);
7719
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7720
                tcg_gen_ext16u_i32(tmp2, tmp2);
7721
            } else {
7722
                /* pkhbt */
7723
                if (shift)
7724
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
7725
                tcg_gen_ext16u_i32(tmp, tmp);
7726
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7727
            }
7728
            tcg_gen_or_i32(tmp, tmp, tmp2);
7729
            dead_tmp(tmp2);
7730
            store_reg(s, rd, tmp);
7731
        } else {
7732
            /* Data processing register constant shift.  */
7733
            if (rn == 15) {
7734
                tmp = new_tmp();
7735
                tcg_gen_movi_i32(tmp, 0);
7736
            } else {
7737
                tmp = load_reg(s, rn);
7738
            }
7739
            tmp2 = load_reg(s, rm);
7740

    
7741
            shiftop = (insn >> 4) & 3;
7742
            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7743
            conds = (insn & (1 << 20)) != 0;
7744
            logic_cc = (conds && thumb2_logic_op(op));
7745
            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7746
            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
7747
                goto illegal_op;
7748
            dead_tmp(tmp2);
7749
            if (rd != 15) {
7750
                store_reg(s, rd, tmp);
7751
            } else {
7752
                dead_tmp(tmp);
7753
            }
7754
        }
7755
        break;
7756
    case 13: /* Misc data processing.  */
7757
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7758
        if (op < 4 && (insn & 0xf000) != 0xf000)
7759
            goto illegal_op;
7760
        switch (op) {
7761
        case 0: /* Register controlled shift.  */
7762
            tmp = load_reg(s, rn);
7763
            tmp2 = load_reg(s, rm);
7764
            if ((insn & 0x70) != 0)
7765
                goto illegal_op;
7766
            op = (insn >> 21) & 3;
7767
            logic_cc = (insn & (1 << 20)) != 0;
7768
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7769
            if (logic_cc)
7770
                gen_logic_CC(tmp);
7771
            store_reg_bx(env, s, rd, tmp);
7772
            break;
7773
        case 1: /* Sign/zero extend.  */
7774
            tmp = load_reg(s, rm);
7775
            shift = (insn >> 4) & 3;
7776
            /* ??? In many cases it's not neccessary to do a
7777
               rotate, a shift is sufficient.  */
7778
            if (shift != 0)
7779
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7780
            op = (insn >> 20) & 7;
7781
            switch (op) {
7782
            case 0: gen_sxth(tmp);   break;
7783
            case 1: gen_uxth(tmp);   break;
7784
            case 2: gen_sxtb16(tmp); break;
7785
            case 3: gen_uxtb16(tmp); break;
7786
            case 4: gen_sxtb(tmp);   break;
7787
            case 5: gen_uxtb(tmp);   break;
7788
            default: goto illegal_op;
7789
            }
7790
            if (rn != 15) {
7791
                tmp2 = load_reg(s, rn);
7792
                if ((op >> 1) == 1) {
7793
                    gen_add16(tmp, tmp2);
7794
                } else {
7795
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7796
                    dead_tmp(tmp2);
7797
                }
7798
            }
7799
            store_reg(s, rd, tmp);
7800
            break;
7801
        case 2: /* SIMD add/subtract.  */
7802
            op = (insn >> 20) & 7;
7803
            shift = (insn >> 4) & 7;
7804
            if ((op & 3) == 3 || (shift & 3) == 3)
7805
                goto illegal_op;
7806
            tmp = load_reg(s, rn);
7807
            tmp2 = load_reg(s, rm);
7808
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7809
            dead_tmp(tmp2);
7810
            store_reg(s, rd, tmp);
7811
            break;
7812
        case 3: /* Other data processing.  */
7813
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7814
            if (op < 4) {
7815
                /* Saturating add/subtract.  */
7816
                tmp = load_reg(s, rn);
7817
                tmp2 = load_reg(s, rm);
7818
                if (op & 1)
7819
                    gen_helper_double_saturate(tmp, tmp);
7820
                if (op & 2)
7821
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7822
                else
7823
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7824
                dead_tmp(tmp2);
7825
            } else {
7826
                tmp = load_reg(s, rn);
7827
                switch (op) {
7828
                case 0x0a: /* rbit */
7829
                    gen_helper_rbit(tmp, tmp);
7830
                    break;
7831
                case 0x08: /* rev */
7832
                    tcg_gen_bswap32_i32(tmp, tmp);
7833
                    break;
7834
                case 0x09: /* rev16 */
7835
                    gen_rev16(tmp);
7836
                    break;
7837
                case 0x0b: /* revsh */
7838
                    gen_revsh(tmp);
7839
                    break;
7840
                case 0x10: /* sel */
7841
                    tmp2 = load_reg(s, rm);
7842
                    tmp3 = new_tmp();
7843
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7844
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7845
                    dead_tmp(tmp3);
7846
                    dead_tmp(tmp2);
7847
                    break;
7848
                case 0x18: /* clz */
7849
                    gen_helper_clz(tmp, tmp);
7850
                    break;
7851
                default:
7852
                    goto illegal_op;
7853
                }
7854
            }
7855
            store_reg(s, rd, tmp);
7856
            break;
7857
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7858
            op = (insn >> 4) & 0xf;
7859
            tmp = load_reg(s, rn);
7860
            tmp2 = load_reg(s, rm);
7861
            switch ((insn >> 20) & 7) {
7862
            case 0: /* 32 x 32 -> 32 */
7863
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7864
                dead_tmp(tmp2);
7865
                if (rs != 15) {
7866
                    tmp2 = load_reg(s, rs);
7867
                    if (op)
7868
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7869
                    else
7870
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7871
                    dead_tmp(tmp2);
7872
                }
7873
                break;
7874
            case 1: /* 16 x 16 -> 32 */
7875
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7876
                dead_tmp(tmp2);
7877
                if (rs != 15) {
7878
                    tmp2 = load_reg(s, rs);
7879
                    gen_helper_add_setq(tmp, tmp, tmp2);
7880
                    dead_tmp(tmp2);
7881
                }
7882
                break;
7883
            case 2: /* Dual multiply add.  */
7884
            case 4: /* Dual multiply subtract.  */
7885
                if (op)
7886
                    gen_swap_half(tmp2);
7887
                gen_smul_dual(tmp, tmp2);
7888
                /* This addition cannot overflow.  */
7889
                if (insn & (1 << 22)) {
7890
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7891
                } else {
7892
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7893
                }
7894
                dead_tmp(tmp2);
7895
                if (rs != 15)
7896
                  {
7897
                    tmp2 = load_reg(s, rs);
7898
                    gen_helper_add_setq(tmp, tmp, tmp2);
7899
                    dead_tmp(tmp2);
7900
                  }
7901
                break;
7902
            case 3: /* 32 * 16 -> 32msb */
7903
                if (op)
7904
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7905
                else
7906
                    gen_sxth(tmp2);
7907
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7908
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7909
                tmp = new_tmp();
7910
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7911
                tcg_temp_free_i64(tmp64);
7912
                if (rs != 15)
7913
                  {
7914
                    tmp2 = load_reg(s, rs);
7915
                    gen_helper_add_setq(tmp, tmp, tmp2);
7916
                    dead_tmp(tmp2);
7917
                  }
7918
                break;
7919
            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
7920
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7921
                if (rs != 15) {
7922
                    tmp = load_reg(s, rs);
7923
                    if (insn & (1 << 20)) {
7924
                        tmp64 = gen_addq_msw(tmp64, tmp);
7925
                    } else {
7926
                        tmp64 = gen_subq_msw(tmp64, tmp);
7927
                    }
7928
                }
7929
                if (insn & (1 << 4)) {
7930
                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7931
                }
7932
                tcg_gen_shri_i64(tmp64, tmp64, 32);
7933
                tmp = new_tmp();
7934
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7935
                tcg_temp_free_i64(tmp64);
7936
                break;
7937
            case 7: /* Unsigned sum of absolute differences.  */
7938
                gen_helper_usad8(tmp, tmp, tmp2);
7939
                dead_tmp(tmp2);
7940
                if (rs != 15) {
7941
                    tmp2 = load_reg(s, rs);
7942
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7943
                    dead_tmp(tmp2);
7944
                }
7945
                break;
7946
            }
7947
            store_reg(s, rd, tmp);
7948
            break;
7949
        case 6: case 7: /* 64-bit multiply, Divide.  */
7950
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7951
            tmp = load_reg(s, rn);
7952
            tmp2 = load_reg(s, rm);
7953
            if ((op & 0x50) == 0x10) {
7954
                /* sdiv, udiv */
7955
                if (!arm_feature(env, ARM_FEATURE_DIV))
7956
                    goto illegal_op;
7957
                if (op & 0x20)
7958
                    gen_helper_udiv(tmp, tmp, tmp2);
7959
                else
7960
                    gen_helper_sdiv(tmp, tmp, tmp2);
7961
                dead_tmp(tmp2);
7962
                store_reg(s, rd, tmp);
7963
            } else if ((op & 0xe) == 0xc) {
7964
                /* Dual multiply accumulate long.  */
7965
                if (op & 1)
7966
                    gen_swap_half(tmp2);
7967
                gen_smul_dual(tmp, tmp2);
7968
                if (op & 0x10) {
7969
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7970
                } else {
7971
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7972
                }
7973
                dead_tmp(tmp2);
7974
                /* BUGFIX */
7975
                tmp64 = tcg_temp_new_i64();
7976
                tcg_gen_ext_i32_i64(tmp64, tmp);
7977
                dead_tmp(tmp);
7978
                gen_addq(s, tmp64, rs, rd);
7979
                gen_storeq_reg(s, rs, rd, tmp64);
7980
                tcg_temp_free_i64(tmp64);
7981
            } else {
7982
                if (op & 0x20) {
7983
                    /* Unsigned 64-bit multiply  */
7984
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7985
                } else {
7986
                    if (op & 8) {
7987
                        /* smlalxy */
7988
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7989
                        dead_tmp(tmp2);
7990
                        tmp64 = tcg_temp_new_i64();
7991
                        tcg_gen_ext_i32_i64(tmp64, tmp);
7992
                        dead_tmp(tmp);
7993
                    } else {
7994
                        /* Signed 64-bit multiply  */
7995
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7996
                    }
7997
                }
7998
                if (op & 4) {
7999
                    /* umaal */
8000
                    gen_addq_lo(s, tmp64, rs);
8001
                    gen_addq_lo(s, tmp64, rd);
8002
                } else if (op & 0x40) {
8003
                    /* 64-bit accumulate.  */
8004
                    gen_addq(s, tmp64, rs, rd);
8005
                }
8006
                gen_storeq_reg(s, rs, rd, tmp64);
8007
                tcg_temp_free_i64(tmp64);
8008
            }
8009
            break;
8010
        }
8011
        break;
8012
    case 6: case 7: case 14: case 15:
8013
        /* Coprocessor.  */
8014
        if (((insn >> 24) & 3) == 3) {
8015
            /* Translate into the equivalent ARM encoding.  */
8016
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
8017
            if (disas_neon_data_insn(env, s, insn))
8018
                goto illegal_op;
8019
        } else {
8020
            if (insn & (1 << 28))
8021
                goto illegal_op;
8022
            if (disas_coproc_insn (env, s, insn))
8023
                goto illegal_op;
8024
        }
8025
        break;
8026
    case 8: case 9: case 10: case 11:
8027
        if (insn & (1 << 15)) {
8028
            /* Branches, misc control.  */
8029
            if (insn & 0x5000) {
8030
                /* Unconditional branch.  */
8031
                /* signextend(hw1[10:0]) -> offset[:12].  */
8032
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8033
                /* hw1[10:0] -> offset[11:1].  */
8034
                offset |= (insn & 0x7ff) << 1;
8035
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8036
                   offset[24:22] already have the same value because of the
8037
                   sign extension above.  */
8038
                offset ^= ((~insn) & (1 << 13)) << 10;
8039
                offset ^= ((~insn) & (1 << 11)) << 11;
8040

    
8041
                if (insn & (1 << 14)) {
8042
                    /* Branch and link.  */
8043
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8044
                }
8045

    
8046
                offset += s->pc;
8047
                if (insn & (1 << 12)) {
8048
                    /* b/bl */
8049
                    gen_jmp(s, offset);
8050
                } else {
8051
                    /* blx */
8052
                    offset &= ~(uint32_t)2;
8053
                    gen_bx_im(s, offset);
8054
                }
8055
            } else if (((insn >> 23) & 7) == 7) {
8056
                /* Misc control */
8057
                if (insn & (1 << 13))
8058
                    goto illegal_op;
8059

    
8060
                if (insn & (1 << 26)) {
8061
                    /* Secure monitor call (v6Z) */
8062
                    goto illegal_op; /* not implemented.  */
8063
                } else {
8064
                    op = (insn >> 20) & 7;
8065
                    switch (op) {
8066
                    case 0: /* msr cpsr.  */
8067
                        if (IS_M(env)) {
8068
                            tmp = load_reg(s, rn);
8069
                            addr = tcg_const_i32(insn & 0xff);
8070
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
8071
                            tcg_temp_free_i32(addr);
8072
                            dead_tmp(tmp);
8073
                            gen_lookup_tb(s);
8074
                            break;
8075
                        }
8076
                        /* fall through */
8077
                    case 1: /* msr spsr.  */
8078
                        if (IS_M(env))
8079
                            goto illegal_op;
8080
                        tmp = load_reg(s, rn);
8081
                        if (gen_set_psr(s,
8082
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8083
                              op == 1, tmp))
8084
                            goto illegal_op;
8085
                        break;
8086
                    case 2: /* cps, nop-hint.  */
8087
                        if (((insn >> 8) & 7) == 0) {
8088
                            gen_nop_hint(s, insn & 0xff);
8089
                        }
8090
                        /* Implemented as NOP in user mode.  */
8091
                        if (IS_USER(s))
8092
                            break;
8093
                        offset = 0;
8094
                        imm = 0;
8095
                        if (insn & (1 << 10)) {
8096
                            if (insn & (1 << 7))
8097
                                offset |= CPSR_A;
8098
                            if (insn & (1 << 6))
8099
                                offset |= CPSR_I;
8100
                            if (insn & (1 << 5))
8101
                                offset |= CPSR_F;
8102
                            if (insn & (1 << 9))
8103
                                imm = CPSR_A | CPSR_I | CPSR_F;
8104
                        }
8105
                        if (insn & (1 << 8)) {
8106
                            offset |= 0x1f;
8107
                            imm |= (insn & 0x1f);
8108
                        }
8109
                        if (offset) {
8110
                            gen_set_psr_im(s, offset, 0, imm);
8111
                        }
8112
                        break;
8113
                    case 3: /* Special control operations.  */
8114
                        ARCH(7);
8115
                        op = (insn >> 4) & 0xf;
8116
                        switch (op) {
8117
                        case 2: /* clrex */
8118
                            gen_clrex(s);
8119
                            break;
8120
                        case 4: /* dsb */
8121
                        case 5: /* dmb */
8122
                        case 6: /* isb */
8123
                            /* These execute as NOPs.  */
8124
                            break;
8125
                        default:
8126
                            goto illegal_op;
8127
                        }
8128
                        break;
8129
                    case 4: /* bxj */
8130
                        /* Trivial implementation equivalent to bx.  */
8131
                        tmp = load_reg(s, rn);
8132
                        gen_bx(s, tmp);
8133
                        break;
8134
                    case 5: /* Exception return.  */
8135
                        if (IS_USER(s)) {
8136
                            goto illegal_op;
8137
                        }
8138
                        if (rn != 14 || rd != 15) {
8139
                            goto illegal_op;
8140
                        }
8141
                        tmp = load_reg(s, rn);
8142
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8143
                        gen_exception_return(s, tmp);
8144
                        break;
8145
                    case 6: /* mrs cpsr.  */
8146
                        tmp = new_tmp();
8147
                        if (IS_M(env)) {
8148
                            addr = tcg_const_i32(insn & 0xff);
8149
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
8150
                            tcg_temp_free_i32(addr);
8151
                        } else {
8152
                            gen_helper_cpsr_read(tmp);
8153
                        }
8154
                        store_reg(s, rd, tmp);
8155
                        break;
8156
                    case 7: /* mrs spsr.  */
8157
                        /* Not accessible in user mode.  */
8158
                        if (IS_USER(s) || IS_M(env))
8159
                            goto illegal_op;
8160
                        tmp = load_cpu_field(spsr);
8161
                        store_reg(s, rd, tmp);
8162
                        break;
8163
                    }
8164
                }
8165
            } else {
8166
                /* Conditional branch.  */
8167
                op = (insn >> 22) & 0xf;
8168
                /* Generate a conditional jump to next instruction.  */
8169
                s->condlabel = gen_new_label();
8170
                gen_test_cc(op ^ 1, s->condlabel);
8171
                s->condjmp = 1;
8172

    
8173
                /* offset[11:1] = insn[10:0] */
8174
                offset = (insn & 0x7ff) << 1;
8175
                /* offset[17:12] = insn[21:16].  */
8176
                offset |= (insn & 0x003f0000) >> 4;
8177
                /* offset[31:20] = insn[26].  */
8178
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8179
                /* offset[18] = insn[13].  */
8180
                offset |= (insn & (1 << 13)) << 5;
8181
                /* offset[19] = insn[11].  */
8182
                offset |= (insn & (1 << 11)) << 8;
8183

    
8184
                /* jump to the offset */
8185
                gen_jmp(s, s->pc + offset);
8186
            }
8187
        } else {
8188
            /* Data processing immediate.  */
8189
            if (insn & (1 << 25)) {
8190
                if (insn & (1 << 24)) {
8191
                    if (insn & (1 << 20))
8192
                        goto illegal_op;
8193
                    /* Bitfield/Saturate.  */
8194
                    op = (insn >> 21) & 7;
8195
                    imm = insn & 0x1f;
8196
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8197
                    if (rn == 15) {
8198
                        tmp = new_tmp();
8199
                        tcg_gen_movi_i32(tmp, 0);
8200
                    } else {
8201
                        tmp = load_reg(s, rn);
8202
                    }
8203
                    switch (op) {
8204
                    case 2: /* Signed bitfield extract.  */
8205
                        imm++;
8206
                        if (shift + imm > 32)
8207
                            goto illegal_op;
8208
                        if (imm < 32)
8209
                            gen_sbfx(tmp, shift, imm);
8210
                        break;
8211
                    case 6: /* Unsigned bitfield extract.  */
8212
                        imm++;
8213
                        if (shift + imm > 32)
8214
                            goto illegal_op;
8215
                        if (imm < 32)
8216
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
8217
                        break;
8218
                    case 3: /* Bitfield insert/clear.  */
8219
                        if (imm < shift)
8220
                            goto illegal_op;
8221
                        imm = imm + 1 - shift;
8222
                        if (imm != 32) {
8223
                            tmp2 = load_reg(s, rd);
8224
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
8225
                            dead_tmp(tmp2);
8226
                        }
8227
                        break;
8228
                    case 7:
8229
                        goto illegal_op;
8230
                    default: /* Saturate.  */
8231
                        if (shift) {
8232
                            if (op & 1)
8233
                                tcg_gen_sari_i32(tmp, tmp, shift);
8234
                            else
8235
                                tcg_gen_shli_i32(tmp, tmp, shift);
8236
                        }
8237
                        tmp2 = tcg_const_i32(imm);
8238
                        if (op & 4) {
8239
                            /* Unsigned.  */
8240
                            if ((op & 1) && shift == 0)
8241
                                gen_helper_usat16(tmp, tmp, tmp2);
8242
                            else
8243
                                gen_helper_usat(tmp, tmp, tmp2);
8244
                        } else {
8245
                            /* Signed.  */
8246
                            if ((op & 1) && shift == 0)
8247
                                gen_helper_ssat16(tmp, tmp, tmp2);
8248
                            else
8249
                                gen_helper_ssat(tmp, tmp, tmp2);
8250
                        }
8251
                        tcg_temp_free_i32(tmp2);
8252
                        break;
8253
                    }
8254
                    store_reg(s, rd, tmp);
8255
                } else {
8256
                    imm = ((insn & 0x04000000) >> 15)
8257
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
8258
                    if (insn & (1 << 22)) {
8259
                        /* 16-bit immediate.  */
8260
                        imm |= (insn >> 4) & 0xf000;
8261
                        if (insn & (1 << 23)) {
8262
                            /* movt */
8263
                            tmp = load_reg(s, rd);
8264
                            tcg_gen_ext16u_i32(tmp, tmp);
8265
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
8266
                        } else {
8267
                            /* movw */
8268
                            tmp = new_tmp();
8269
                            tcg_gen_movi_i32(tmp, imm);
8270
                        }
8271
                    } else {
8272
                        /* Add/sub 12-bit immediate.  */
8273
                        if (rn == 15) {
8274
                            offset = s->pc & ~(uint32_t)3;
8275
                            if (insn & (1 << 23))
8276
                                offset -= imm;
8277
                            else
8278
                                offset += imm;
8279
                            tmp = new_tmp();
8280
                            tcg_gen_movi_i32(tmp, offset);
8281
                        } else {
8282
                            tmp = load_reg(s, rn);
8283
                            if (insn & (1 << 23))
8284
                                tcg_gen_subi_i32(tmp, tmp, imm);
8285
                            else
8286
                                tcg_gen_addi_i32(tmp, tmp, imm);
8287
                        }
8288
                    }
8289
                    store_reg(s, rd, tmp);
8290
                }
8291
            } else {
8292
                int shifter_out = 0;
8293
                /* modified 12-bit immediate.  */
8294
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8295
                imm = (insn & 0xff);
8296
                switch (shift) {
8297
                case 0: /* XY */
8298
                    /* Nothing to do.  */
8299
                    break;
8300
                case 1: /* 00XY00XY */
8301
                    imm |= imm << 16;
8302
                    break;
8303
                case 2: /* XY00XY00 */
8304
                    imm |= imm << 16;
8305
                    imm <<= 8;
8306
                    break;
8307
                case 3: /* XYXYXYXY */
8308
                    imm |= imm << 16;
8309
                    imm |= imm << 8;
8310
                    break;
8311
                default: /* Rotated constant.  */
8312
                    shift = (shift << 1) | (imm >> 7);
8313
                    imm |= 0x80;
8314
                    imm = imm << (32 - shift);
8315
                    shifter_out = 1;
8316
                    break;
8317
                }
8318
                tmp2 = new_tmp();
8319
                tcg_gen_movi_i32(tmp2, imm);
8320
                rn = (insn >> 16) & 0xf;
8321
                if (rn == 15) {
8322
                    tmp = new_tmp();
8323
                    tcg_gen_movi_i32(tmp, 0);
8324
                } else {
8325
                    tmp = load_reg(s, rn);
8326
                }
8327
                op = (insn >> 21) & 0xf;
8328
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
8329
                                       shifter_out, tmp, tmp2))
8330
                    goto illegal_op;
8331
                dead_tmp(tmp2);
8332
                rd = (insn >> 8) & 0xf;
8333
                if (rd != 15) {
8334
                    store_reg(s, rd, tmp);
8335
                } else {
8336
                    dead_tmp(tmp);
8337
                }
8338
            }
8339
        }
8340
        break;
8341
    case 12: /* Load/store single data item.  */
8342
        {
8343
        int postinc = 0;
8344
        int writeback = 0;
8345
        int user;
8346
        if ((insn & 0x01100000) == 0x01000000) {
8347
            if (disas_neon_ls_insn(env, s, insn))
8348
                goto illegal_op;
8349
            break;
8350
        }
8351
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8352
        if (rs == 15) {
8353
            if (!(insn & (1 << 20))) {
8354
                goto illegal_op;
8355
            }
8356
            if (op != 2) {
8357
                /* Byte or halfword load space with dest == r15 : memory hints.
8358
                 * Catch them early so we don't emit pointless addressing code.
8359
                 * This space is a mix of:
8360
                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
8361
                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8362
                 *     cores)
8363
                 *  unallocated hints, which must be treated as NOPs
8364
                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
8365
                 *     which is easiest for the decoding logic
8366
                 *  Some space which must UNDEF
8367
                 */
8368
                int op1 = (insn >> 23) & 3;
8369
                int op2 = (insn >> 6) & 0x3f;
8370
                if (op & 2) {
8371
                    goto illegal_op;
8372
                }
8373
                if (rn == 15) {
8374
                    /* UNPREDICTABLE or unallocated hint */
8375
                    return 0;
8376
                }
8377
                if (op1 & 1) {
8378
                    return 0; /* PLD* or unallocated hint */
8379
                }
8380
                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
8381
                    return 0; /* PLD* or unallocated hint */
8382
                }
8383
                /* UNDEF space, or an UNPREDICTABLE */
8384
                return 1;
8385
            }
8386
        }
8387
        user = IS_USER(s);
8388
        if (rn == 15) {
8389
            addr = new_tmp();
8390
            /* PC relative.  */
8391
            /* s->pc has already been incremented by 4.  */
8392
            imm = s->pc & 0xfffffffc;
8393
            if (insn & (1 << 23))
8394
                imm += insn & 0xfff;
8395
            else
8396
                imm -= insn & 0xfff;
8397
            tcg_gen_movi_i32(addr, imm);
8398
        } else {
8399
            addr = load_reg(s, rn);
8400
            if (insn & (1 << 23)) {
8401
                /* Positive offset.  */
8402
                imm = insn & 0xfff;
8403
                tcg_gen_addi_i32(addr, addr, imm);
8404
            } else {
8405
                imm = insn & 0xff;
8406
                switch ((insn >> 8) & 7) {
8407
                case 0: case 8: /* Shifted Register.  */
8408
                    shift = (insn >> 4) & 0xf;
8409
                    if (shift > 3)
8410
                        goto illegal_op;
8411
                    tmp = load_reg(s, rm);
8412
                    if (shift)
8413
                        tcg_gen_shli_i32(tmp, tmp, shift);
8414
                    tcg_gen_add_i32(addr, addr, tmp);
8415
                    dead_tmp(tmp);
8416
                    break;
8417
                case 4: /* Negative offset.  */
8418
                    tcg_gen_addi_i32(addr, addr, -imm);
8419
                    break;
8420
                case 6: /* User privilege.  */
8421
                    tcg_gen_addi_i32(addr, addr, imm);
8422
                    user = 1;
8423
                    break;
8424
                case 1: /* Post-decrement.  */
8425
                    imm = -imm;
8426
                    /* Fall through.  */
8427
                case 3: /* Post-increment.  */
8428
                    postinc = 1;
8429
                    writeback = 1;
8430
                    break;
8431
                case 5: /* Pre-decrement.  */
8432
                    imm = -imm;
8433
                    /* Fall through.  */
8434
                case 7: /* Pre-increment.  */
8435
                    tcg_gen_addi_i32(addr, addr, imm);
8436
                    writeback = 1;
8437
                    break;
8438
                default:
8439
                    goto illegal_op;
8440
                }
8441
            }
8442
        }
8443
        if (insn & (1 << 20)) {
8444
            /* Load.  */
8445
            switch (op) {
8446
            case 0: tmp = gen_ld8u(addr, user); break;
8447
            case 4: tmp = gen_ld8s(addr, user); break;
8448
            case 1: tmp = gen_ld16u(addr, user); break;
8449
            case 5: tmp = gen_ld16s(addr, user); break;
8450
            case 2: tmp = gen_ld32(addr, user); break;
8451
            default: goto illegal_op;
8452
            }
8453
            if (rs == 15) {
8454
                gen_bx(s, tmp);
8455
            } else {
8456
                store_reg(s, rs, tmp);
8457
            }
8458
        } else {
8459
            /* Store.  */
8460
            tmp = load_reg(s, rs);
8461
            switch (op) {
8462
            case 0: gen_st8(tmp, addr, user); break;
8463
            case 1: gen_st16(tmp, addr, user); break;
8464
            case 2: gen_st32(tmp, addr, user); break;
8465
            default: goto illegal_op;
8466
            }
8467
        }
8468
        if (postinc)
8469
            tcg_gen_addi_i32(addr, addr, imm);
8470
        if (writeback) {
8471
            store_reg(s, rn, addr);
8472
        } else {
8473
            dead_tmp(addr);
8474
        }
8475
        }
8476
        break;
8477
    default:
8478
        goto illegal_op;
8479
    }
8480
    return 0;
8481
illegal_op:
8482
    return 1;
8483
}
8484

    
8485
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8486
{
8487
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8488
    int32_t offset;
8489
    int i;
8490
    TCGv tmp;
8491
    TCGv tmp2;
8492
    TCGv addr;
8493

    
8494
    if (s->condexec_mask) {
8495
        cond = s->condexec_cond;
8496
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
8497
          s->condlabel = gen_new_label();
8498
          gen_test_cc(cond ^ 1, s->condlabel);
8499
          s->condjmp = 1;
8500
        }
8501
    }
8502

    
8503
    insn = lduw_code(s->pc);
8504
    s->pc += 2;
8505

    
8506
    switch (insn >> 12) {
8507
    case 0: case 1:
8508

    
8509
        rd = insn & 7;
8510
        op = (insn >> 11) & 3;
8511
        if (op == 3) {
8512
            /* add/subtract */
8513
            rn = (insn >> 3) & 7;
8514
            tmp = load_reg(s, rn);
8515
            if (insn & (1 << 10)) {
8516
                /* immediate */
8517
                tmp2 = new_tmp();
8518
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8519
            } else {
8520
                /* reg */
8521
                rm = (insn >> 6) & 7;
8522
                tmp2 = load_reg(s, rm);
8523
            }
8524
            if (insn & (1 << 9)) {
8525
                if (s->condexec_mask)
8526
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8527
                else
8528
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8529
            } else {
8530
                if (s->condexec_mask)
8531
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8532
                else
8533
                    gen_helper_add_cc(tmp, tmp, tmp2);
8534
            }
8535
            dead_tmp(tmp2);
8536
            store_reg(s, rd, tmp);
8537
        } else {
8538
            /* shift immediate */
8539
            rm = (insn >> 3) & 7;
8540
            shift = (insn >> 6) & 0x1f;
8541
            tmp = load_reg(s, rm);
8542
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8543
            if (!s->condexec_mask)
8544
                gen_logic_CC(tmp);
8545
            store_reg(s, rd, tmp);
8546
        }
8547
        break;
8548
    case 2: case 3:
8549
        /* arithmetic large immediate */
8550
        op = (insn >> 11) & 3;
8551
        rd = (insn >> 8) & 0x7;
8552
        if (op == 0) { /* mov */
8553
            tmp = new_tmp();
8554
            tcg_gen_movi_i32(tmp, insn & 0xff);
8555
            if (!s->condexec_mask)
8556
                gen_logic_CC(tmp);
8557
            store_reg(s, rd, tmp);
8558
        } else {
8559
            tmp = load_reg(s, rd);
8560
            tmp2 = new_tmp();
8561
            tcg_gen_movi_i32(tmp2, insn & 0xff);
8562
            switch (op) {
8563
            case 1: /* cmp */
8564
                gen_helper_sub_cc(tmp, tmp, tmp2);
8565
                dead_tmp(tmp);
8566
                dead_tmp(tmp2);
8567
                break;
8568
            case 2: /* add */
8569
                if (s->condexec_mask)
8570
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8571
                else
8572
                    gen_helper_add_cc(tmp, tmp, tmp2);
8573
                dead_tmp(tmp2);
8574
                store_reg(s, rd, tmp);
8575
                break;
8576
            case 3: /* sub */
8577
                if (s->condexec_mask)
8578
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8579
                else
8580
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8581
                dead_tmp(tmp2);
8582
                store_reg(s, rd, tmp);
8583
                break;
8584
            }
8585
        }
8586
        break;
8587
    case 4:
8588
        if (insn & (1 << 11)) {
8589
            rd = (insn >> 8) & 7;
8590
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8591
            val = s->pc + 2 + ((insn & 0xff) * 4);
8592
            val &= ~(uint32_t)2;
8593
            addr = new_tmp();
8594
            tcg_gen_movi_i32(addr, val);
8595
            tmp = gen_ld32(addr, IS_USER(s));
8596
            dead_tmp(addr);
8597
            store_reg(s, rd, tmp);
8598
            break;
8599
        }
8600
        if (insn & (1 << 10)) {
8601
            /* data processing extended or blx */
8602
            rd = (insn & 7) | ((insn >> 4) & 8);
8603
            rm = (insn >> 3) & 0xf;
8604
            op = (insn >> 8) & 3;
8605
            switch (op) {
8606
            case 0: /* add */
8607
                tmp = load_reg(s, rd);
8608
                tmp2 = load_reg(s, rm);
8609
                tcg_gen_add_i32(tmp, tmp, tmp2);
8610
                dead_tmp(tmp2);
8611
                store_reg(s, rd, tmp);
8612
                break;
8613
            case 1: /* cmp */
8614
                tmp = load_reg(s, rd);
8615
                tmp2 = load_reg(s, rm);
8616
                gen_helper_sub_cc(tmp, tmp, tmp2);
8617
                dead_tmp(tmp2);
8618
                dead_tmp(tmp);
8619
                break;
8620
            case 2: /* mov/cpy */
8621
                tmp = load_reg(s, rm);
8622
                store_reg(s, rd, tmp);
8623
                break;
8624
            case 3:/* branch [and link] exchange thumb register */
8625
                tmp = load_reg(s, rm);
8626
                if (insn & (1 << 7)) {
8627
                    val = (uint32_t)s->pc | 1;
8628
                    tmp2 = new_tmp();
8629
                    tcg_gen_movi_i32(tmp2, val);
8630
                    store_reg(s, 14, tmp2);
8631
                }
8632
                gen_bx(s, tmp);
8633
                break;
8634
            }
8635
            break;
8636
        }
8637

    
8638
        /* data processing register */
8639
        rd = insn & 7;
8640
        rm = (insn >> 3) & 7;
8641
        op = (insn >> 6) & 0xf;
8642
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8643
            /* the shift/rotate ops want the operands backwards */
8644
            val = rm;
8645
            rm = rd;
8646
            rd = val;
8647
            val = 1;
8648
        } else {
8649
            val = 0;
8650
        }
8651

    
8652
        if (op == 9) { /* neg */
8653
            tmp = new_tmp();
8654
            tcg_gen_movi_i32(tmp, 0);
8655
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
8656
            tmp = load_reg(s, rd);
8657
        } else {
8658
            TCGV_UNUSED(tmp);
8659
        }
8660

    
8661
        tmp2 = load_reg(s, rm);
8662
        switch (op) {
8663
        case 0x0: /* and */
8664
            tcg_gen_and_i32(tmp, tmp, tmp2);
8665
            if (!s->condexec_mask)
8666
                gen_logic_CC(tmp);
8667
            break;
8668
        case 0x1: /* eor */
8669
            tcg_gen_xor_i32(tmp, tmp, tmp2);
8670
            if (!s->condexec_mask)
8671
                gen_logic_CC(tmp);
8672
            break;
8673
        case 0x2: /* lsl */
8674
            if (s->condexec_mask) {
8675
                gen_helper_shl(tmp2, tmp2, tmp);
8676
            } else {
8677
                gen_helper_shl_cc(tmp2, tmp2, tmp);
8678
                gen_logic_CC(tmp2);
8679
            }
8680
            break;
8681
        case 0x3: /* lsr */
8682
            if (s->condexec_mask) {
8683
                gen_helper_shr(tmp2, tmp2, tmp);
8684
            } else {
8685
                gen_helper_shr_cc(tmp2, tmp2, tmp);
8686
                gen_logic_CC(tmp2);
8687
            }
8688
            break;
8689
        case 0x4: /* asr */
8690
            if (s->condexec_mask) {
8691
                gen_helper_sar(tmp2, tmp2, tmp);
8692
            } else {
8693
                gen_helper_sar_cc(tmp2, tmp2, tmp);
8694
                gen_logic_CC(tmp2);
8695
            }
8696
            break;
8697
        case 0x5: /* adc */
8698
            if (s->condexec_mask)
8699
                gen_adc(tmp, tmp2);
8700
            else
8701
                gen_helper_adc_cc(tmp, tmp, tmp2);
8702
            break;
8703
        case 0x6: /* sbc */
8704
            if (s->condexec_mask)
8705
                gen_sub_carry(tmp, tmp, tmp2);
8706
            else
8707
                gen_helper_sbc_cc(tmp, tmp, tmp2);
8708
            break;
8709
        case 0x7: /* ror */
8710
            if (s->condexec_mask) {
8711
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
8712
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
8713
            } else {
8714
                gen_helper_ror_cc(tmp2, tmp2, tmp);
8715
                gen_logic_CC(tmp2);
8716
            }
8717
            break;
8718
        case 0x8: /* tst */
8719
            tcg_gen_and_i32(tmp, tmp, tmp2);
8720
            gen_logic_CC(tmp);
8721
            rd = 16;
8722
            break;
8723
        case 0x9: /* neg */
8724
            if (s->condexec_mask)
8725
                tcg_gen_neg_i32(tmp, tmp2);
8726
            else
8727
                gen_helper_sub_cc(tmp, tmp, tmp2);
8728
            break;
8729
        case 0xa: /* cmp */
8730
            gen_helper_sub_cc(tmp, tmp, tmp2);
8731
            rd = 16;
8732
            break;
8733
        case 0xb: /* cmn */
8734
            gen_helper_add_cc(tmp, tmp, tmp2);
8735
            rd = 16;
8736
            break;
8737
        case 0xc: /* orr */
8738
            tcg_gen_or_i32(tmp, tmp, tmp2);
8739
            if (!s->condexec_mask)
8740
                gen_logic_CC(tmp);
8741
            break;
8742
        case 0xd: /* mul */
8743
            tcg_gen_mul_i32(tmp, tmp, tmp2);
8744
            if (!s->condexec_mask)
8745
                gen_logic_CC(tmp);
8746
            break;
8747
        case 0xe: /* bic */
8748
            tcg_gen_andc_i32(tmp, tmp, tmp2);
8749
            if (!s->condexec_mask)
8750
                gen_logic_CC(tmp);
8751
            break;
8752
        case 0xf: /* mvn */
8753
            tcg_gen_not_i32(tmp2, tmp2);
8754
            if (!s->condexec_mask)
8755
                gen_logic_CC(tmp2);
8756
            val = 1;
8757
            rm = rd;
8758
            break;
8759
        }
8760
        if (rd != 16) {
8761
            if (val) {
8762
                store_reg(s, rm, tmp2);
8763
                if (op != 0xf)
8764
                    dead_tmp(tmp);
8765
            } else {
8766
                store_reg(s, rd, tmp);
8767
                dead_tmp(tmp2);
8768
            }
8769
        } else {
8770
            dead_tmp(tmp);
8771
            dead_tmp(tmp2);
8772
        }
8773
        break;
8774

    
8775
    case 5:
8776
        /* load/store register offset.  */
8777
        rd = insn & 7;
8778
        rn = (insn >> 3) & 7;
8779
        rm = (insn >> 6) & 7;
8780
        op = (insn >> 9) & 7;
8781
        addr = load_reg(s, rn);
8782
        tmp = load_reg(s, rm);
8783
        tcg_gen_add_i32(addr, addr, tmp);
8784
        dead_tmp(tmp);
8785

    
8786
        if (op < 3) /* store */
8787
            tmp = load_reg(s, rd);
8788

    
8789
        switch (op) {
8790
        case 0: /* str */
8791
            gen_st32(tmp, addr, IS_USER(s));
8792
            break;
8793
        case 1: /* strh */
8794
            gen_st16(tmp, addr, IS_USER(s));
8795
            break;
8796
        case 2: /* strb */
8797
            gen_st8(tmp, addr, IS_USER(s));
8798
            break;
8799
        case 3: /* ldrsb */
8800
            tmp = gen_ld8s(addr, IS_USER(s));
8801
            break;
8802
        case 4: /* ldr */
8803
            tmp = gen_ld32(addr, IS_USER(s));
8804
            break;
8805
        case 5: /* ldrh */
8806
            tmp = gen_ld16u(addr, IS_USER(s));
8807
            break;
8808
        case 6: /* ldrb */
8809
            tmp = gen_ld8u(addr, IS_USER(s));
8810
            break;
8811
        case 7: /* ldrsh */
8812
            tmp = gen_ld16s(addr, IS_USER(s));
8813
            break;
8814
        }
8815
        if (op >= 3) /* load */
8816
            store_reg(s, rd, tmp);
8817
        dead_tmp(addr);
8818
        break;
8819

    
8820
    case 6:
8821
        /* load/store word immediate offset */
8822
        rd = insn & 7;
8823
        rn = (insn >> 3) & 7;
8824
        addr = load_reg(s, rn);
8825
        val = (insn >> 4) & 0x7c;
8826
        tcg_gen_addi_i32(addr, addr, val);
8827

    
8828
        if (insn & (1 << 11)) {
8829
            /* load */
8830
            tmp = gen_ld32(addr, IS_USER(s));
8831
            store_reg(s, rd, tmp);
8832
        } else {
8833
            /* store */
8834
            tmp = load_reg(s, rd);
8835
            gen_st32(tmp, addr, IS_USER(s));
8836
        }
8837
        dead_tmp(addr);
8838
        break;
8839

    
8840
    case 7:
8841
        /* load/store byte immediate offset */
8842
        rd = insn & 7;
8843
        rn = (insn >> 3) & 7;
8844
        addr = load_reg(s, rn);
8845
        val = (insn >> 6) & 0x1f;
8846
        tcg_gen_addi_i32(addr, addr, val);
8847

    
8848
        if (insn & (1 << 11)) {
8849
            /* load */
8850
            tmp = gen_ld8u(addr, IS_USER(s));
8851
            store_reg(s, rd, tmp);
8852
        } else {
8853
            /* store */
8854
            tmp = load_reg(s, rd);
8855
            gen_st8(tmp, addr, IS_USER(s));
8856
        }
8857
        dead_tmp(addr);
8858
        break;
8859

    
8860
    case 8:
8861
        /* load/store halfword immediate offset */
8862
        rd = insn & 7;
8863
        rn = (insn >> 3) & 7;
8864
        addr = load_reg(s, rn);
8865
        val = (insn >> 5) & 0x3e;
8866
        tcg_gen_addi_i32(addr, addr, val);
8867

    
8868
        if (insn & (1 << 11)) {
8869
            /* load */
8870
            tmp = gen_ld16u(addr, IS_USER(s));
8871
            store_reg(s, rd, tmp);
8872
        } else {
8873
            /* store */
8874
            tmp = load_reg(s, rd);
8875
            gen_st16(tmp, addr, IS_USER(s));
8876
        }
8877
        dead_tmp(addr);
8878
        break;
8879

    
8880
    case 9:
8881
        /* load/store from stack */
8882
        rd = (insn >> 8) & 7;
8883
        addr = load_reg(s, 13);
8884
        val = (insn & 0xff) * 4;
8885
        tcg_gen_addi_i32(addr, addr, val);
8886

    
8887
        if (insn & (1 << 11)) {
8888
            /* load */
8889
            tmp = gen_ld32(addr, IS_USER(s));
8890
            store_reg(s, rd, tmp);
8891
        } else {
8892
            /* store */
8893
            tmp = load_reg(s, rd);
8894
            gen_st32(tmp, addr, IS_USER(s));
8895
        }
8896
        dead_tmp(addr);
8897
        break;
8898

    
8899
    case 10:
8900
        /* add to high reg */
8901
        rd = (insn >> 8) & 7;
8902
        if (insn & (1 << 11)) {
8903
            /* SP */
8904
            tmp = load_reg(s, 13);
8905
        } else {
8906
            /* PC. bit 1 is ignored.  */
8907
            tmp = new_tmp();
8908
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8909
        }
8910
        val = (insn & 0xff) * 4;
8911
        tcg_gen_addi_i32(tmp, tmp, val);
8912
        store_reg(s, rd, tmp);
8913
        break;
8914

    
8915
    case 11:
8916
        /* misc */
8917
        op = (insn >> 8) & 0xf;
8918
        switch (op) {
8919
        case 0:
8920
            /* adjust stack pointer */
8921
            tmp = load_reg(s, 13);
8922
            val = (insn & 0x7f) * 4;
8923
            if (insn & (1 << 7))
8924
                val = -(int32_t)val;
8925
            tcg_gen_addi_i32(tmp, tmp, val);
8926
            store_reg(s, 13, tmp);
8927
            break;
8928

    
8929
        case 2: /* sign/zero extend.  */
8930
            ARCH(6);
8931
            rd = insn & 7;
8932
            rm = (insn >> 3) & 7;
8933
            tmp = load_reg(s, rm);
8934
            switch ((insn >> 6) & 3) {
8935
            case 0: gen_sxth(tmp); break;
8936
            case 1: gen_sxtb(tmp); break;
8937
            case 2: gen_uxth(tmp); break;
8938
            case 3: gen_uxtb(tmp); break;
8939
            }
8940
            store_reg(s, rd, tmp);
8941
            break;
8942
        case 4: case 5: case 0xc: case 0xd:
8943
            /* push/pop */
8944
            addr = load_reg(s, 13);
8945
            if (insn & (1 << 8))
8946
                offset = 4;
8947
            else
8948
                offset = 0;
8949
            for (i = 0; i < 8; i++) {
8950
                if (insn & (1 << i))
8951
                    offset += 4;
8952
            }
8953
            if ((insn & (1 << 11)) == 0) {
8954
                tcg_gen_addi_i32(addr, addr, -offset);
8955
            }
8956
            for (i = 0; i < 8; i++) {
8957
                if (insn & (1 << i)) {
8958
                    if (insn & (1 << 11)) {
8959
                        /* pop */
8960
                        tmp = gen_ld32(addr, IS_USER(s));
8961
                        store_reg(s, i, tmp);
8962
                    } else {
8963
                        /* push */
8964
                        tmp = load_reg(s, i);
8965
                        gen_st32(tmp, addr, IS_USER(s));
8966
                    }
8967
                    /* advance to the next address.  */
8968
                    tcg_gen_addi_i32(addr, addr, 4);
8969
                }
8970
            }
8971
            TCGV_UNUSED(tmp);
8972
            if (insn & (1 << 8)) {
8973
                if (insn & (1 << 11)) {
8974
                    /* pop pc */
8975
                    tmp = gen_ld32(addr, IS_USER(s));
8976
                    /* don't set the pc until the rest of the instruction
8977
                       has completed */
8978
                } else {
8979
                    /* push lr */
8980
                    tmp = load_reg(s, 14);
8981
                    gen_st32(tmp, addr, IS_USER(s));
8982
                }
8983
                tcg_gen_addi_i32(addr, addr, 4);
8984
            }
8985
            if ((insn & (1 << 11)) == 0) {
8986
                tcg_gen_addi_i32(addr, addr, -offset);
8987
            }
8988
            /* write back the new stack pointer */
8989
            store_reg(s, 13, addr);
8990
            /* set the new PC value */
8991
            if ((insn & 0x0900) == 0x0900)
8992
                gen_bx(s, tmp);
8993
            break;
8994

    
8995
        case 1: case 3: case 9: case 11: /* czb */
8996
            rm = insn & 7;
8997
            tmp = load_reg(s, rm);
8998
            s->condlabel = gen_new_label();
8999
            s->condjmp = 1;
9000
            if (insn & (1 << 11))
9001
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9002
            else
9003
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9004
            dead_tmp(tmp);
9005
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9006
            val = (uint32_t)s->pc + 2;
9007
            val += offset;
9008
            gen_jmp(s, val);
9009
            break;
9010

    
9011
        case 15: /* IT, nop-hint.  */
9012
            if ((insn & 0xf) == 0) {
9013
                gen_nop_hint(s, (insn >> 4) & 0xf);
9014
                break;
9015
            }
9016
            /* If Then.  */
9017
            s->condexec_cond = (insn >> 4) & 0xe;
9018
            s->condexec_mask = insn & 0x1f;
9019
            /* No actual code generated for this insn, just setup state.  */
9020
            break;
9021

    
9022
        case 0xe: /* bkpt */
9023
            gen_exception_insn(s, 2, EXCP_BKPT);
9024
            break;
9025

    
9026
        case 0xa: /* rev */
9027
            ARCH(6);
9028
            rn = (insn >> 3) & 0x7;
9029
            rd = insn & 0x7;
9030
            tmp = load_reg(s, rn);
9031
            switch ((insn >> 6) & 3) {
9032
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9033
            case 1: gen_rev16(tmp); break;
9034
            case 3: gen_revsh(tmp); break;
9035
            default: goto illegal_op;
9036
            }
9037
            store_reg(s, rd, tmp);
9038
            break;
9039

    
9040
        case 6: /* cps */
9041
            ARCH(6);
9042
            if (IS_USER(s))
9043
                break;
9044
            if (IS_M(env)) {
9045
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9046
                /* PRIMASK */
9047
                if (insn & 1) {
9048
                    addr = tcg_const_i32(16);
9049
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9050
                    tcg_temp_free_i32(addr);
9051
                }
9052
                /* FAULTMASK */
9053
                if (insn & 2) {
9054
                    addr = tcg_const_i32(17);
9055
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9056
                    tcg_temp_free_i32(addr);
9057
                }
9058
                tcg_temp_free_i32(tmp);
9059
                gen_lookup_tb(s);
9060
            } else {
9061
                if (insn & (1 << 4))
9062
                    shift = CPSR_A | CPSR_I | CPSR_F;
9063
                else
9064
                    shift = 0;
9065
                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9066
            }
9067
            break;
9068

    
9069
        default:
9070
            goto undef;
9071
        }
9072
        break;
9073

    
9074
    case 12:
9075
        /* load/store multiple */
9076
        rn = (insn >> 8) & 0x7;
9077
        addr = load_reg(s, rn);
9078
        for (i = 0; i < 8; i++) {
9079
            if (insn & (1 << i)) {
9080
                if (insn & (1 << 11)) {
9081
                    /* load */
9082
                    tmp = gen_ld32(addr, IS_USER(s));
9083
                    store_reg(s, i, tmp);
9084
                } else {
9085
                    /* store */
9086
                    tmp = load_reg(s, i);
9087
                    gen_st32(tmp, addr, IS_USER(s));
9088
                }
9089
                /* advance to the next address */
9090
                tcg_gen_addi_i32(addr, addr, 4);
9091
            }
9092
        }
9093
        /* Base register writeback.  */
9094
        if ((insn & (1 << rn)) == 0) {
9095
            store_reg(s, rn, addr);
9096
        } else {
9097
            dead_tmp(addr);
9098
        }
9099
        break;
9100

    
9101
    case 13:
9102
        /* conditional branch or swi */
9103
        cond = (insn >> 8) & 0xf;
9104
        if (cond == 0xe)
9105
            goto undef;
9106

    
9107
        if (cond == 0xf) {
9108
            /* swi */
9109
            gen_set_pc_im(s->pc);
9110
            s->is_jmp = DISAS_SWI;
9111
            break;
9112
        }
9113
        /* generate a conditional jump to next instruction */
9114
        s->condlabel = gen_new_label();
9115
        gen_test_cc(cond ^ 1, s->condlabel);
9116
        s->condjmp = 1;
9117

    
9118
        /* jump to the offset */
9119
        val = (uint32_t)s->pc + 2;
9120
        offset = ((int32_t)insn << 24) >> 24;
9121
        val += offset << 1;
9122
        gen_jmp(s, val);
9123
        break;
9124

    
9125
    case 14:
9126
        if (insn & (1 << 11)) {
9127
            if (disas_thumb2_insn(env, s, insn))
9128
              goto undef32;
9129
            break;
9130
        }
9131
        /* unconditional branch */
9132
        val = (uint32_t)s->pc;
9133
        offset = ((int32_t)insn << 21) >> 21;
9134
        val += (offset << 1) + 2;
9135
        gen_jmp(s, val);
9136
        break;
9137

    
9138
    case 15:
9139
        if (disas_thumb2_insn(env, s, insn))
9140
            goto undef32;
9141
        break;
9142
    }
9143
    return;
9144
undef32:
9145
    gen_exception_insn(s, 4, EXCP_UDEF);
9146
    return;
9147
illegal_op:
9148
undef:
9149
    gen_exception_insn(s, 2, EXCP_UDEF);
9150
}
9151

    
9152
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9153
   basic block 'tb'. If search_pc is TRUE, also generate PC
9154
   information for each intermediate instruction. */
9155
static inline void gen_intermediate_code_internal(CPUState *env,
9156
                                                  TranslationBlock *tb,
9157
                                                  int search_pc)
9158
{
9159
    DisasContext dc1, *dc = &dc1;
9160
    CPUBreakpoint *bp;
9161
    uint16_t *gen_opc_end;
9162
    int j, lj;
9163
    target_ulong pc_start;
9164
    uint32_t next_page_start;
9165
    int num_insns;
9166
    int max_insns;
9167

    
9168
    /* generate intermediate code */
9169
    num_temps = 0;
9170

    
9171
    pc_start = tb->pc;
9172

    
9173
    dc->tb = tb;
9174

    
9175
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9176

    
9177
    dc->is_jmp = DISAS_NEXT;
9178
    dc->pc = pc_start;
9179
    dc->singlestep_enabled = env->singlestep_enabled;
9180
    dc->condjmp = 0;
9181
    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9182
    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9183
    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9184
#if !defined(CONFIG_USER_ONLY)
9185
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9186
#endif
9187
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9188
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9189
    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9190
    cpu_F0s = tcg_temp_new_i32();
9191
    cpu_F1s = tcg_temp_new_i32();
9192
    cpu_F0d = tcg_temp_new_i64();
9193
    cpu_F1d = tcg_temp_new_i64();
9194
    cpu_V0 = cpu_F0d;
9195
    cpu_V1 = cpu_F1d;
9196
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
9197
    cpu_M0 = tcg_temp_new_i64();
9198
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9199
    lj = -1;
9200
    num_insns = 0;
9201
    max_insns = tb->cflags & CF_COUNT_MASK;
9202
    if (max_insns == 0)
9203
        max_insns = CF_COUNT_MASK;
9204

    
9205
    gen_icount_start();
9206

    
9207
    /* A note on handling of the condexec (IT) bits:
9208
     *
9209
     * We want to avoid the overhead of having to write the updated condexec
9210
     * bits back to the CPUState for every instruction in an IT block. So:
9211
     * (1) if the condexec bits are not already zero then we write
9212
     * zero back into the CPUState now. This avoids complications trying
9213
     * to do it at the end of the block. (For example if we don't do this
9214
     * it's hard to identify whether we can safely skip writing condexec
9215
     * at the end of the TB, which we definitely want to do for the case
9216
     * where a TB doesn't do anything with the IT state at all.)
9217
     * (2) if we are going to leave the TB then we call gen_set_condexec()
9218
     * which will write the correct value into CPUState if zero is wrong.
9219
     * This is done both for leaving the TB at the end, and for leaving
9220
     * it because of an exception we know will happen, which is done in
9221
     * gen_exception_insn(). The latter is necessary because we need to
9222
     * leave the TB with the PC/IT state just prior to execution of the
9223
     * instruction which caused the exception.
9224
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9225
     * then the CPUState will be wrong and we need to reset it.
9226
     * This is handled in the same way as restoration of the
9227
     * PC in these situations: we will be called again with search_pc=1
9228
     * and generate a mapping of the condexec bits for each PC in
9229
     * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
9230
     * the condexec bits.
9231
     *
9232
     * Note that there are no instructions which can read the condexec
9233
     * bits, and none which can write non-static values to them, so
9234
     * we don't need to care about whether CPUState is correct in the
9235
     * middle of a TB.
9236
     */
9237

    
9238
    /* Reset the conditional execution bits immediately. This avoids
9239
       complications trying to do it at the end of the block.  */
9240
    if (dc->condexec_mask || dc->condexec_cond)
9241
      {
9242
        TCGv tmp = new_tmp();
9243
        tcg_gen_movi_i32(tmp, 0);
9244
        store_cpu_field(tmp, condexec_bits);
9245
      }
9246
    do {
9247
#ifdef CONFIG_USER_ONLY
9248
        /* Intercept jump to the magic kernel page.  */
9249
        if (dc->pc >= 0xffff0000) {
9250
            /* We always get here via a jump, so know we are not in a
9251
               conditional execution block.  */
9252
            gen_exception(EXCP_KERNEL_TRAP);
9253
            dc->is_jmp = DISAS_UPDATE;
9254
            break;
9255
        }
9256
#else
9257
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9258
            /* We always get here via a jump, so know we are not in a
9259
               conditional execution block.  */
9260
            gen_exception(EXCP_EXCEPTION_EXIT);
9261
            dc->is_jmp = DISAS_UPDATE;
9262
            break;
9263
        }
9264
#endif
9265

    
9266
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9267
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9268
                if (bp->pc == dc->pc) {
9269
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
9270
                    /* Advance PC so that clearing the breakpoint will
9271
                       invalidate this TB.  */
9272
                    dc->pc += 2;
9273
                    goto done_generating;
9274
                    break;
9275
                }
9276
            }
9277
        }
9278
        if (search_pc) {
9279
            j = gen_opc_ptr - gen_opc_buf;
9280
            if (lj < j) {
9281
                lj++;
9282
                while (lj < j)
9283
                    gen_opc_instr_start[lj++] = 0;
9284
            }
9285
            gen_opc_pc[lj] = dc->pc;
9286
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9287
            gen_opc_instr_start[lj] = 1;
9288
            gen_opc_icount[lj] = num_insns;
9289
        }
9290

    
9291
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9292
            gen_io_start();
9293

    
9294
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
9295
            tcg_gen_debug_insn_start(dc->pc);
9296
        }
9297

    
9298
        if (dc->thumb) {
9299
            disas_thumb_insn(env, dc);
9300
            if (dc->condexec_mask) {
9301
                dc->condexec_cond = (dc->condexec_cond & 0xe)
9302
                                   | ((dc->condexec_mask >> 4) & 1);
9303
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9304
                if (dc->condexec_mask == 0) {
9305
                    dc->condexec_cond = 0;
9306
                }
9307
            }
9308
        } else {
9309
            disas_arm_insn(env, dc);
9310
        }
9311
        if (num_temps) {
9312
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
9313
            num_temps = 0;
9314
        }
9315

    
9316
        if (dc->condjmp && !dc->is_jmp) {
9317
            gen_set_label(dc->condlabel);
9318
            dc->condjmp = 0;
9319
        }
9320
        /* Translation stops when a conditional branch is encountered.
9321
         * Otherwise the subsequent code could get translated several times.
9322
         * Also stop translation when a page boundary is reached.  This
9323
         * ensures prefetch aborts occur at the right place.  */
9324
        num_insns ++;
9325
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9326
             !env->singlestep_enabled &&
9327
             !singlestep &&
9328
             dc->pc < next_page_start &&
9329
             num_insns < max_insns);
9330

    
9331
    if (tb->cflags & CF_LAST_IO) {
9332
        if (dc->condjmp) {
9333
            /* FIXME:  This can theoretically happen with self-modifying
9334
               code.  */
9335
            cpu_abort(env, "IO on conditional branch instruction");
9336
        }
9337
        gen_io_end();
9338
    }
9339

    
9340
    /* At this stage dc->condjmp will only be set when the skipped
9341
       instruction was a conditional branch or trap, and the PC has
9342
       already been written.  */
9343
    if (unlikely(env->singlestep_enabled)) {
9344
        /* Make sure the pc is updated, and raise a debug exception.  */
9345
        if (dc->condjmp) {
9346
            gen_set_condexec(dc);
9347
            if (dc->is_jmp == DISAS_SWI) {
9348
                gen_exception(EXCP_SWI);
9349
            } else {
9350
                gen_exception(EXCP_DEBUG);
9351
            }
9352
            gen_set_label(dc->condlabel);
9353
        }
9354
        if (dc->condjmp || !dc->is_jmp) {
9355
            gen_set_pc_im(dc->pc);
9356
            dc->condjmp = 0;
9357
        }
9358
        gen_set_condexec(dc);
9359
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9360
            gen_exception(EXCP_SWI);
9361
        } else {
9362
            /* FIXME: Single stepping a WFI insn will not halt
9363
               the CPU.  */
9364
            gen_exception(EXCP_DEBUG);
9365
        }
9366
    } else {
9367
        /* While branches must always occur at the end of an IT block,
9368
           there are a few other things that can cause us to terminate
9369
           the TB in the middel of an IT block:
9370
            - Exception generating instructions (bkpt, swi, undefined).
9371
            - Page boundaries.
9372
            - Hardware watchpoints.
9373
           Hardware breakpoints have already been handled and skip this code.
9374
         */
9375
        gen_set_condexec(dc);
9376
        switch(dc->is_jmp) {
9377
        case DISAS_NEXT:
9378
            gen_goto_tb(dc, 1, dc->pc);
9379
            break;
9380
        default:
9381
        case DISAS_JUMP:
9382
        case DISAS_UPDATE:
9383
            /* indicate that the hash table must be used to find the next TB */
9384
            tcg_gen_exit_tb(0);
9385
            break;
9386
        case DISAS_TB_JUMP:
9387
            /* nothing more to generate */
9388
            break;
9389
        case DISAS_WFI:
9390
            gen_helper_wfi();
9391
            break;
9392
        case DISAS_SWI:
9393
            gen_exception(EXCP_SWI);
9394
            break;
9395
        }
9396
        if (dc->condjmp) {
9397
            gen_set_label(dc->condlabel);
9398
            gen_set_condexec(dc);
9399
            gen_goto_tb(dc, 1, dc->pc);
9400
            dc->condjmp = 0;
9401
        }
9402
    }
9403

    
9404
done_generating:
9405
    gen_icount_end(tb, num_insns);
9406
    *gen_opc_ptr = INDEX_op_end;
9407

    
9408
#ifdef DEBUG_DISAS
9409
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9410
        qemu_log("----------------\n");
9411
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9412
        log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);
9413
        qemu_log("\n");
9414
    }
9415
#endif
9416
    if (search_pc) {
9417
        j = gen_opc_ptr - gen_opc_buf;
9418
        lj++;
9419
        while (lj <= j)
9420
            gen_opc_instr_start[lj++] = 0;
9421
    } else {
9422
        tb->size = dc->pc - pc_start;
9423
        tb->icount = num_insns;
9424
    }
9425
}
9426

    
9427
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9428
{
9429
    gen_intermediate_code_internal(env, tb, 0);
9430
}
9431

    
9432
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9433
{
9434
    gen_intermediate_code_internal(env, tb, 1);
9435
}
9436

    
9437
static const char *cpu_mode_names[16] = {
9438
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9439
  "???", "???", "???", "und", "???", "???", "???", "sys"
9440
};
9441

    
9442
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
9443
                    int flags)
9444
{
9445
    int i;
9446
#if 0
9447
    union {
9448
        uint32_t i;
9449
        float s;
9450
    } s0, s1;
9451
    CPU_DoubleU d;
9452
    /* ??? This assumes float64 and double have the same layout.
9453
       Oh well, it's only debug dumps.  */
9454
    union {
9455
        float64 f64;
9456
        double d;
9457
    } d0;
9458
#endif
9459
    uint32_t psr;
9460

    
9461
    for(i=0;i<16;i++) {
9462
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9463
        if ((i % 4) == 3)
9464
            cpu_fprintf(f, "\n");
9465
        else
9466
            cpu_fprintf(f, " ");
9467
    }
9468
    psr = cpsr_read(env);
9469
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9470
                psr,
9471
                psr & (1 << 31) ? 'N' : '-',
9472
                psr & (1 << 30) ? 'Z' : '-',
9473
                psr & (1 << 29) ? 'C' : '-',
9474
                psr & (1 << 28) ? 'V' : '-',
9475
                psr & CPSR_T ? 'T' : 'A',
9476
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9477

    
9478
#if 0
9479
    for (i = 0; i < 16; i++) {
9480
        d.d = env->vfp.regs[i];
9481
        s0.i = d.l.lower;
9482
        s1.i = d.l.upper;
9483
        d0.f64 = d.d;
9484
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9485
                    i * 2, (int)s0.i, s0.s,
9486
                    i * 2 + 1, (int)s1.i, s1.s,
9487
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9488
                    d0.d);
9489
    }
9490
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9491
#endif
9492
}
9493

    
9494
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9495
                unsigned long searched_pc, int pc_pos, void *puc)
9496
{
9497
    env->regs[15] = gen_opc_pc[pc_pos];
9498
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
9499
}