Statistics
| Branch: | Revision:

root / target-arm / translate.c @ b408a9b0

History | View | Annotate | Download (317.4 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 int gen_neon_unzip(int rd, int rm, int size, int q)
3618
{
3619
    TCGv tmp, tmp2;
3620
    if (size == 3 || (!q && size == 2)) {
3621
        return 1;
3622
    }
3623
    tmp = tcg_const_i32(rd);
3624
    tmp2 = tcg_const_i32(rm);
3625
    if (q) {
3626
        switch (size) {
3627
        case 0:
3628
            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3629
            break;
3630
        case 1:
3631
            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3632
            break;
3633
        case 2:
3634
            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3635
            break;
3636
        default:
3637
            abort();
3638
        }
3639
    } else {
3640
        switch (size) {
3641
        case 0:
3642
            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3643
            break;
3644
        case 1:
3645
            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3646
            break;
3647
        default:
3648
            abort();
3649
        }
3650
    }
3651
    tcg_temp_free_i32(tmp);
3652
    tcg_temp_free_i32(tmp2);
3653
    return 0;
3654
}
3655

    
3656
static int gen_neon_zip(int rd, int rm, int size, int q)
3657
{
3658
    TCGv tmp, tmp2;
3659
    if (size == 3 || (!q && size == 2)) {
3660
        return 1;
3661
    }
3662
    tmp = tcg_const_i32(rd);
3663
    tmp2 = tcg_const_i32(rm);
3664
    if (q) {
3665
        switch (size) {
3666
        case 0:
3667
            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3668
            break;
3669
        case 1:
3670
            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3671
            break;
3672
        case 2:
3673
            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3674
            break;
3675
        default:
3676
            abort();
3677
        }
3678
    } else {
3679
        switch (size) {
3680
        case 0:
3681
            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3682
            break;
3683
        case 1:
3684
            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3685
            break;
3686
        default:
3687
            abort();
3688
        }
3689
    }
3690
    tcg_temp_free_i32(tmp);
3691
    tcg_temp_free_i32(tmp2);
3692
    return 0;
3693
}
3694

    
3695
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3696
{
3697
    TCGv rd, tmp;
3698

    
3699
    rd = new_tmp();
3700
    tmp = new_tmp();
3701

    
3702
    tcg_gen_shli_i32(rd, t0, 8);
3703
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3704
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3705
    tcg_gen_or_i32(rd, rd, tmp);
3706

    
3707
    tcg_gen_shri_i32(t1, t1, 8);
3708
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3709
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3710
    tcg_gen_or_i32(t1, t1, tmp);
3711
    tcg_gen_mov_i32(t0, rd);
3712

    
3713
    dead_tmp(tmp);
3714
    dead_tmp(rd);
3715
}
3716

    
3717
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3718
{
3719
    TCGv rd, tmp;
3720

    
3721
    rd = new_tmp();
3722
    tmp = new_tmp();
3723

    
3724
    tcg_gen_shli_i32(rd, t0, 16);
3725
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3726
    tcg_gen_or_i32(rd, rd, tmp);
3727
    tcg_gen_shri_i32(t1, t1, 16);
3728
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3729
    tcg_gen_or_i32(t1, t1, tmp);
3730
    tcg_gen_mov_i32(t0, rd);
3731

    
3732
    dead_tmp(tmp);
3733
    dead_tmp(rd);
3734
}
3735

    
3736

    
3737
static struct {
3738
    int nregs;
3739
    int interleave;
3740
    int spacing;
3741
} neon_ls_element_type[11] = {
3742
    {4, 4, 1},
3743
    {4, 4, 2},
3744
    {4, 1, 1},
3745
    {4, 2, 1},
3746
    {3, 3, 1},
3747
    {3, 3, 2},
3748
    {3, 1, 1},
3749
    {1, 1, 1},
3750
    {2, 2, 1},
3751
    {2, 2, 2},
3752
    {2, 1, 1}
3753
};
3754

    
3755
/* Translate a NEON load/store element instruction.  Return nonzero if the
3756
   instruction is invalid.  */
3757
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3758
{
3759
    int rd, rn, rm;
3760
    int op;
3761
    int nregs;
3762
    int interleave;
3763
    int spacing;
3764
    int stride;
3765
    int size;
3766
    int reg;
3767
    int pass;
3768
    int load;
3769
    int shift;
3770
    int n;
3771
    TCGv addr;
3772
    TCGv tmp;
3773
    TCGv tmp2;
3774
    TCGv_i64 tmp64;
3775

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

    
3984
        base = load_reg(s, rn);
3985
        if (rm == 13) {
3986
            tcg_gen_addi_i32(base, base, stride);
3987
        } else {
3988
            TCGv index;
3989
            index = load_reg(s, rm);
3990
            tcg_gen_add_i32(base, base, index);
3991
            dead_tmp(index);
3992
        }
3993
        store_reg(s, rn, base);
3994
    }
3995
    return 0;
3996
}
3997

    
3998
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3999
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4000
{
4001
    tcg_gen_and_i32(t, t, c);
4002
    tcg_gen_andc_i32(f, f, c);
4003
    tcg_gen_or_i32(dest, t, f);
4004
}
4005

    
4006
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4007
{
4008
    switch (size) {
4009
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4010
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4011
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4012
    default: abort();
4013
    }
4014
}
4015

    
4016
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4017
{
4018
    switch (size) {
4019
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4020
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4021
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4022
    default: abort();
4023
    }
4024
}
4025

    
4026
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4027
{
4028
    switch (size) {
4029
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4030
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4031
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4032
    default: abort();
4033
    }
4034
}
4035

    
4036
static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4037
{
4038
    switch (size) {
4039
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4040
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4041
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4042
    default: abort();
4043
    }
4044
}
4045

    
4046
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4047
                                         int q, int u)
4048
{
4049
    if (q) {
4050
        if (u) {
4051
            switch (size) {
4052
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4053
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4054
            default: abort();
4055
            }
4056
        } else {
4057
            switch (size) {
4058
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4059
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4060
            default: abort();
4061
            }
4062
        }
4063
    } else {
4064
        if (u) {
4065
            switch (size) {
4066
            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4067
            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4068
            default: abort();
4069
            }
4070
        } else {
4071
            switch (size) {
4072
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4073
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4074
            default: abort();
4075
            }
4076
        }
4077
    }
4078
}
4079

    
4080
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4081
{
4082
    if (u) {
4083
        switch (size) {
4084
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4085
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4086
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4087
        default: abort();
4088
        }
4089
    } else {
4090
        switch (size) {
4091
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4092
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4093
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4094
        default: abort();
4095
        }
4096
    }
4097
    dead_tmp(src);
4098
}
4099

    
4100
static inline void gen_neon_addl(int size)
4101
{
4102
    switch (size) {
4103
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4104
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4105
    case 2: tcg_gen_add_i64(CPU_V001); break;
4106
    default: abort();
4107
    }
4108
}
4109

    
4110
static inline void gen_neon_subl(int size)
4111
{
4112
    switch (size) {
4113
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4114
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4115
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4116
    default: abort();
4117
    }
4118
}
4119

    
4120
static inline void gen_neon_negl(TCGv_i64 var, int size)
4121
{
4122
    switch (size) {
4123
    case 0: gen_helper_neon_negl_u16(var, var); break;
4124
    case 1: gen_helper_neon_negl_u32(var, var); break;
4125
    case 2: gen_helper_neon_negl_u64(var, var); break;
4126
    default: abort();
4127
    }
4128
}
4129

    
4130
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4131
{
4132
    switch (size) {
4133
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4134
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4135
    default: abort();
4136
    }
4137
}
4138

    
4139
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4140
{
4141
    TCGv_i64 tmp;
4142

    
4143
    switch ((size << 1) | u) {
4144
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4145
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4146
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4147
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4148
    case 4:
4149
        tmp = gen_muls_i64_i32(a, b);
4150
        tcg_gen_mov_i64(dest, tmp);
4151
        break;
4152
    case 5:
4153
        tmp = gen_mulu_i64_i32(a, b);
4154
        tcg_gen_mov_i64(dest, tmp);
4155
        break;
4156
    default: abort();
4157
    }
4158

    
4159
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4160
       Don't forget to clean them now.  */
4161
    if (size < 2) {
4162
      dead_tmp(a);
4163
      dead_tmp(b);
4164
    }
4165
}
4166

    
4167
/* Translate a NEON data processing instruction.  Return nonzero if the
4168
   instruction is invalid.
4169
   We process data in a mixture of 32-bit and 64-bit chunks.
4170
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4171

    
4172
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4173
{
4174
    int op;
4175
    int q;
4176
    int rd, rn, rm;
4177
    int size;
4178
    int shift;
4179
    int pass;
4180
    int count;
4181
    int pairwise;
4182
    int u;
4183
    int n;
4184
    uint32_t imm, mask;
4185
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4186
    TCGv_i64 tmp64;
4187

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

    
4300
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4301

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

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

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

    
4618
                for (pass = 0; pass < count; pass++) {
4619
                    if (size == 3) {
4620
                        neon_load_reg64(cpu_V0, rm + pass);
4621
                        tcg_gen_movi_i64(cpu_V1, imm);
4622
                        switch (op) {
4623
                        case 0:  /* VSHR */
4624
                        case 1:  /* VSRA */
4625
                            if (u)
4626
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4627
                            else
4628
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4629
                            break;
4630
                        case 2: /* VRSHR */
4631
                        case 3: /* VRSRA */
4632
                            if (u)
4633
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4634
                            else
4635
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4636
                            break;
4637
                        case 4: /* VSRI */
4638
                            if (!u)
4639
                                return 1;
4640
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4641
                            break;
4642
                        case 5: /* VSHL, VSLI */
4643
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4644
                            break;
4645
                        case 6: /* VQSHLU */
4646
                            if (u) {
4647
                                gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
4648
                                                          cpu_V0, cpu_V1);
4649
                            } else {
4650
                                return 1;
4651
                            }
4652
                            break;
4653
                        case 7: /* VQSHL */
4654
                            if (u) {
4655
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4656
                                                         cpu_V0, cpu_V1);
4657
                            } else {
4658
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4659
                                                         cpu_V0, cpu_V1);
4660
                            }
4661
                            break;
4662
                        }
4663
                        if (op == 1 || op == 3) {
4664
                            /* Accumulate.  */
4665
                            neon_load_reg64(cpu_V1, rd + pass);
4666
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4667
                        } else if (op == 4 || (op == 5 && u)) {
4668
                            /* Insert */
4669
                            neon_load_reg64(cpu_V1, rd + pass);
4670
                            uint64_t mask;
4671
                            if (shift < -63 || shift > 63) {
4672
                                mask = 0;
4673
                            } else {
4674
                                if (op == 4) {
4675
                                    mask = 0xffffffffffffffffull >> -shift;
4676
                                } else {
4677
                                    mask = 0xffffffffffffffffull << shift;
4678
                                }
4679
                            }
4680
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
4681
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4682
                        }
4683
                        neon_store_reg64(cpu_V0, rd + pass);
4684
                    } else { /* size < 3 */
4685
                        /* Operands in T0 and T1.  */
4686
                        tmp = neon_load_reg(rm, pass);
4687
                        tmp2 = new_tmp();
4688
                        tcg_gen_movi_i32(tmp2, imm);
4689
                        switch (op) {
4690
                        case 0:  /* VSHR */
4691
                        case 1:  /* VSRA */
4692
                            GEN_NEON_INTEGER_OP(shl);
4693
                            break;
4694
                        case 2: /* VRSHR */
4695
                        case 3: /* VRSRA */
4696
                            GEN_NEON_INTEGER_OP(rshl);
4697
                            break;
4698
                        case 4: /* VSRI */
4699
                            if (!u)
4700
                                return 1;
4701
                            GEN_NEON_INTEGER_OP(shl);
4702
                            break;
4703
                        case 5: /* VSHL, VSLI */
4704
                            switch (size) {
4705
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4706
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4707
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4708
                            default: return 1;
4709
                            }
4710
                            break;
4711
                        case 6: /* VQSHLU */
4712
                            if (!u) {
4713
                                return 1;
4714
                            }
4715
                            switch (size) {
4716
                            case 0:
4717
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
4718
                                                         tmp, tmp2);
4719
                                break;
4720
                            case 1:
4721
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
4722
                                                          tmp, tmp2);
4723
                                break;
4724
                            case 2:
4725
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
4726
                                                          tmp, tmp2);
4727
                                break;
4728
                            default:
4729
                                return 1;
4730
                            }
4731
                            break;
4732
                        case 7: /* VQSHL */
4733
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4734
                            break;
4735
                        }
4736
                        dead_tmp(tmp2);
4737

    
4738
                        if (op == 1 || op == 3) {
4739
                            /* Accumulate.  */
4740
                            tmp2 = neon_load_reg(rd, pass);
4741
                            gen_neon_add(size, tmp, tmp2);
4742
                            dead_tmp(tmp2);
4743
                        } else if (op == 4 || (op == 5 && u)) {
4744
                            /* Insert */
4745
                            switch (size) {
4746
                            case 0:
4747
                                if (op == 4)
4748
                                    mask = 0xff >> -shift;
4749
                                else
4750
                                    mask = (uint8_t)(0xff << shift);
4751
                                mask |= mask << 8;
4752
                                mask |= mask << 16;
4753
                                break;
4754
                            case 1:
4755
                                if (op == 4)
4756
                                    mask = 0xffff >> -shift;
4757
                                else
4758
                                    mask = (uint16_t)(0xffff << shift);
4759
                                mask |= mask << 16;
4760
                                break;
4761
                            case 2:
4762
                                if (shift < -31 || shift > 31) {
4763
                                    mask = 0;
4764
                                } else {
4765
                                    if (op == 4)
4766
                                        mask = 0xffffffffu >> -shift;
4767
                                    else
4768
                                        mask = 0xffffffffu << shift;
4769
                                }
4770
                                break;
4771
                            default:
4772
                                abort();
4773
                            }
4774
                            tmp2 = neon_load_reg(rd, pass);
4775
                            tcg_gen_andi_i32(tmp, tmp, mask);
4776
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
4777
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4778
                            dead_tmp(tmp2);
4779
                        }
4780
                        neon_store_reg(rd, pass, tmp);
4781
                    }
4782
                } /* for pass */
4783
            } else if (op < 10) {
4784
                /* Shift by immediate and narrow:
4785
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4786
                shift = shift - (1 << (size + 3));
4787
                size++;
4788
                switch (size) {
4789
                case 1:
4790
                    imm = (uint16_t)shift;
4791
                    imm |= imm << 16;
4792
                    tmp2 = tcg_const_i32(imm);
4793
                    TCGV_UNUSED_I64(tmp64);
4794
                    break;
4795
                case 2:
4796
                    imm = (uint32_t)shift;
4797
                    tmp2 = tcg_const_i32(imm);
4798
                    TCGV_UNUSED_I64(tmp64);
4799
                    break;
4800
                case 3:
4801
                    tmp64 = tcg_const_i64(shift);
4802
                    TCGV_UNUSED(tmp2);
4803
                    break;
4804
                default:
4805
                    abort();
4806
                }
4807

    
4808
                for (pass = 0; pass < 2; pass++) {
4809
                    if (size == 3) {
4810
                        neon_load_reg64(cpu_V0, rm + pass);
4811
                        if (q) {
4812
                          if (u)
4813
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4814
                          else
4815
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4816
                        } else {
4817
                          if (u)
4818
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4819
                          else
4820
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4821
                        }
4822
                    } else {
4823
                        tmp = neon_load_reg(rm + pass, 0);
4824
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4825
                        tmp3 = neon_load_reg(rm + pass, 1);
4826
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4827
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4828
                        dead_tmp(tmp);
4829
                        dead_tmp(tmp3);
4830
                    }
4831
                    tmp = new_tmp();
4832
                    if (op == 8 && !u) {
4833
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4834
                    } else {
4835
                        if (op == 8)
4836
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4837
                        else
4838
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4839
                    }
4840
                    neon_store_reg(rd, pass, tmp);
4841
                } /* for pass */
4842
                if (size == 3) {
4843
                    tcg_temp_free_i64(tmp64);
4844
                } else {
4845
                    tcg_temp_free_i32(tmp2);
4846
                }
4847
            } else if (op == 10) {
4848
                /* VSHLL */
4849
                if (q || size == 3)
4850
                    return 1;
4851
                tmp = neon_load_reg(rm, 0);
4852
                tmp2 = neon_load_reg(rm, 1);
4853
                for (pass = 0; pass < 2; pass++) {
4854
                    if (pass == 1)
4855
                        tmp = tmp2;
4856

    
4857
                    gen_neon_widen(cpu_V0, tmp, size, u);
4858

    
4859
                    if (shift != 0) {
4860
                        /* The shift is less than the width of the source
4861
                           type, so we can just shift the whole register.  */
4862
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4863
                        /* Widen the result of shift: we need to clear
4864
                         * the potential overflow bits resulting from
4865
                         * left bits of the narrow input appearing as
4866
                         * right bits of left the neighbour narrow
4867
                         * input.  */
4868
                        if (size < 2 || !u) {
4869
                            uint64_t imm64;
4870
                            if (size == 0) {
4871
                                imm = (0xffu >> (8 - shift));
4872
                                imm |= imm << 16;
4873
                            } else if (size == 1) {
4874
                                imm = 0xffff >> (16 - shift);
4875
                            } else {
4876
                                /* size == 2 */
4877
                                imm = 0xffffffff >> (32 - shift);
4878
                            }
4879
                            if (size < 2) {
4880
                                imm64 = imm | (((uint64_t)imm) << 32);
4881
                            } else {
4882
                                imm64 = imm;
4883
                            }
4884
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
4885
                        }
4886
                    }
4887
                    neon_store_reg64(cpu_V0, rd + pass);
4888
                }
4889
            } else if (op >= 14) {
4890
                /* VCVT fixed-point.  */
4891
                /* We have already masked out the must-be-1 top bit of imm6,
4892
                 * hence this 32-shift where the ARM ARM has 64-imm6.
4893
                 */
4894
                shift = 32 - shift;
4895
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4896
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4897
                    if (!(op & 1)) {
4898
                        if (u)
4899
                            gen_vfp_ulto(0, shift);
4900
                        else
4901
                            gen_vfp_slto(0, shift);
4902
                    } else {
4903
                        if (u)
4904
                            gen_vfp_toul(0, shift);
4905
                        else
4906
                            gen_vfp_tosl(0, shift);
4907
                    }
4908
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4909
                }
4910
            } else {
4911
                return 1;
4912
            }
4913
        } else { /* (insn & 0x00380080) == 0 */
4914
            int invert;
4915

    
4916
            op = (insn >> 8) & 0xf;
4917
            /* One register and immediate.  */
4918
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4919
            invert = (insn & (1 << 5)) != 0;
4920
            switch (op) {
4921
            case 0: case 1:
4922
                /* no-op */
4923
                break;
4924
            case 2: case 3:
4925
                imm <<= 8;
4926
                break;
4927
            case 4: case 5:
4928
                imm <<= 16;
4929
                break;
4930
            case 6: case 7:
4931
                imm <<= 24;
4932
                break;
4933
            case 8: case 9:
4934
                imm |= imm << 16;
4935
                break;
4936
            case 10: case 11:
4937
                imm = (imm << 8) | (imm << 24);
4938
                break;
4939
            case 12:
4940
                imm = (imm << 8) | 0xff;
4941
                break;
4942
            case 13:
4943
                imm = (imm << 16) | 0xffff;
4944
                break;
4945
            case 14:
4946
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4947
                if (invert)
4948
                    imm = ~imm;
4949
                break;
4950
            case 15:
4951
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4952
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4953
                break;
4954
            }
4955
            if (invert)
4956
                imm = ~imm;
4957

    
4958
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4959
                if (op & 1 && op < 12) {
4960
                    tmp = neon_load_reg(rd, pass);
4961
                    if (invert) {
4962
                        /* The immediate value has already been inverted, so
4963
                           BIC becomes AND.  */
4964
                        tcg_gen_andi_i32(tmp, tmp, imm);
4965
                    } else {
4966
                        tcg_gen_ori_i32(tmp, tmp, imm);
4967
                    }
4968
                } else {
4969
                    /* VMOV, VMVN.  */
4970
                    tmp = new_tmp();
4971
                    if (op == 14 && invert) {
4972
                        uint32_t val;
4973
                        val = 0;
4974
                        for (n = 0; n < 4; n++) {
4975
                            if (imm & (1 << (n + (pass & 1) * 4)))
4976
                                val |= 0xff << (n * 8);
4977
                        }
4978
                        tcg_gen_movi_i32(tmp, val);
4979
                    } else {
4980
                        tcg_gen_movi_i32(tmp, imm);
4981
                    }
4982
                }
4983
                neon_store_reg(rd, pass, tmp);
4984
            }
4985
        }
4986
    } else { /* (insn & 0x00800010 == 0x00800000) */
4987
        if (size != 3) {
4988
            op = (insn >> 8) & 0xf;
4989
            if ((insn & (1 << 6)) == 0) {
4990
                /* Three registers of different lengths.  */
4991
                int src1_wide;
4992
                int src2_wide;
4993
                int prewiden;
4994
                /* prewiden, src1_wide, src2_wide */
4995
                static const int neon_3reg_wide[16][3] = {
4996
                    {1, 0, 0}, /* VADDL */
4997
                    {1, 1, 0}, /* VADDW */
4998
                    {1, 0, 0}, /* VSUBL */
4999
                    {1, 1, 0}, /* VSUBW */
5000
                    {0, 1, 1}, /* VADDHN */
5001
                    {0, 0, 0}, /* VABAL */
5002
                    {0, 1, 1}, /* VSUBHN */
5003
                    {0, 0, 0}, /* VABDL */
5004
                    {0, 0, 0}, /* VMLAL */
5005
                    {0, 0, 0}, /* VQDMLAL */
5006
                    {0, 0, 0}, /* VMLSL */
5007
                    {0, 0, 0}, /* VQDMLSL */
5008
                    {0, 0, 0}, /* Integer VMULL */
5009
                    {0, 0, 0}, /* VQDMULL */
5010
                    {0, 0, 0}  /* Polynomial VMULL */
5011
                };
5012

    
5013
                prewiden = neon_3reg_wide[op][0];
5014
                src1_wide = neon_3reg_wide[op][1];
5015
                src2_wide = neon_3reg_wide[op][2];
5016

    
5017
                if (size == 0 && (op == 9 || op == 11 || op == 13))
5018
                    return 1;
5019

    
5020
                /* Avoid overlapping operands.  Wide source operands are
5021
                   always aligned so will never overlap with wide
5022
                   destinations in problematic ways.  */
5023
                if (rd == rm && !src2_wide) {
5024
                    tmp = neon_load_reg(rm, 1);
5025
                    neon_store_scratch(2, tmp);
5026
                } else if (rd == rn && !src1_wide) {
5027
                    tmp = neon_load_reg(rn, 1);
5028
                    neon_store_scratch(2, tmp);
5029
                }
5030
                TCGV_UNUSED(tmp3);
5031
                for (pass = 0; pass < 2; pass++) {
5032
                    if (src1_wide) {
5033
                        neon_load_reg64(cpu_V0, rn + pass);
5034
                        TCGV_UNUSED(tmp);
5035
                    } else {
5036
                        if (pass == 1 && rd == rn) {
5037
                            tmp = neon_load_scratch(2);
5038
                        } else {
5039
                            tmp = neon_load_reg(rn, pass);
5040
                        }
5041
                        if (prewiden) {
5042
                            gen_neon_widen(cpu_V0, tmp, size, u);
5043
                        }
5044
                    }
5045
                    if (src2_wide) {
5046
                        neon_load_reg64(cpu_V1, rm + pass);
5047
                        TCGV_UNUSED(tmp2);
5048
                    } else {
5049
                        if (pass == 1 && rd == rm) {
5050
                            tmp2 = neon_load_scratch(2);
5051
                        } else {
5052
                            tmp2 = neon_load_reg(rm, pass);
5053
                        }
5054
                        if (prewiden) {
5055
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5056
                        }
5057
                    }
5058
                    switch (op) {
5059
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5060
                        gen_neon_addl(size);
5061
                        break;
5062
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5063
                        gen_neon_subl(size);
5064
                        break;
5065
                    case 5: case 7: /* VABAL, VABDL */
5066
                        switch ((size << 1) | u) {
5067
                        case 0:
5068
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5069
                            break;
5070
                        case 1:
5071
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5072
                            break;
5073
                        case 2:
5074
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5075
                            break;
5076
                        case 3:
5077
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5078
                            break;
5079
                        case 4:
5080
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5081
                            break;
5082
                        case 5:
5083
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5084
                            break;
5085
                        default: abort();
5086
                        }
5087
                        dead_tmp(tmp2);
5088
                        dead_tmp(tmp);
5089
                        break;
5090
                    case 8: case 9: case 10: case 11: case 12: case 13:
5091
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5092
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5093
                        break;
5094
                    case 14: /* Polynomial VMULL */
5095
                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5096
                        dead_tmp(tmp2);
5097
                        dead_tmp(tmp);
5098
                        break;
5099
                    default: /* 15 is RESERVED.  */
5100
                        return 1;
5101
                    }
5102
                    if (op == 13) {
5103
                        /* VQDMULL */
5104
                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5105
                        neon_store_reg64(cpu_V0, rd + pass);
5106
                    } else if (op == 5 || (op >= 8 && op <= 11)) {
5107
                        /* Accumulate.  */
5108
                        neon_load_reg64(cpu_V1, rd + pass);
5109
                        switch (op) {
5110
                        case 10: /* VMLSL */
5111
                            gen_neon_negl(cpu_V0, size);
5112
                            /* Fall through */
5113
                        case 5: case 8: /* VABAL, VMLAL */
5114
                            gen_neon_addl(size);
5115
                            break;
5116
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5117
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5118
                            if (op == 11) {
5119
                                gen_neon_negl(cpu_V0, size);
5120
                            }
5121
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5122
                            break;
5123
                        default:
5124
                            abort();
5125
                        }
5126
                        neon_store_reg64(cpu_V0, rd + pass);
5127
                    } else if (op == 4 || op == 6) {
5128
                        /* Narrowing operation.  */
5129
                        tmp = new_tmp();
5130
                        if (!u) {
5131
                            switch (size) {
5132
                            case 0:
5133
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5134
                                break;
5135
                            case 1:
5136
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5137
                                break;
5138
                            case 2:
5139
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5140
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5141
                                break;
5142
                            default: abort();
5143
                            }
5144
                        } else {
5145
                            switch (size) {
5146
                            case 0:
5147
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5148
                                break;
5149
                            case 1:
5150
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5151
                                break;
5152
                            case 2:
5153
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5154
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5155
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5156
                                break;
5157
                            default: abort();
5158
                            }
5159
                        }
5160
                        if (pass == 0) {
5161
                            tmp3 = tmp;
5162
                        } else {
5163
                            neon_store_reg(rd, 0, tmp3);
5164
                            neon_store_reg(rd, 1, tmp);
5165
                        }
5166
                    } else {
5167
                        /* Write back the result.  */
5168
                        neon_store_reg64(cpu_V0, rd + pass);
5169
                    }
5170
                }
5171
            } else {
5172
                /* Two registers and a scalar.  */
5173
                switch (op) {
5174
                case 0: /* Integer VMLA scalar */
5175
                case 1: /* Float VMLA scalar */
5176
                case 4: /* Integer VMLS scalar */
5177
                case 5: /* Floating point VMLS scalar */
5178
                case 8: /* Integer VMUL scalar */
5179
                case 9: /* Floating point VMUL scalar */
5180
                case 12: /* VQDMULH scalar */
5181
                case 13: /* VQRDMULH scalar */
5182
                    tmp = neon_get_scalar(size, rm);
5183
                    neon_store_scratch(0, tmp);
5184
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5185
                        tmp = neon_load_scratch(0);
5186
                        tmp2 = neon_load_reg(rn, pass);
5187
                        if (op == 12) {
5188
                            if (size == 1) {
5189
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5190
                            } else {
5191
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5192
                            }
5193
                        } else if (op == 13) {
5194
                            if (size == 1) {
5195
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5196
                            } else {
5197
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5198
                            }
5199
                        } else if (op & 1) {
5200
                            gen_helper_neon_mul_f32(tmp, tmp, tmp2);
5201
                        } else {
5202
                            switch (size) {
5203
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5204
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5205
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5206
                            default: return 1;
5207
                            }
5208
                        }
5209
                        dead_tmp(tmp2);
5210
                        if (op < 8) {
5211
                            /* Accumulate.  */
5212
                            tmp2 = neon_load_reg(rd, pass);
5213
                            switch (op) {
5214
                            case 0:
5215
                                gen_neon_add(size, tmp, tmp2);
5216
                                break;
5217
                            case 1:
5218
                                gen_helper_neon_add_f32(tmp, tmp, tmp2);
5219
                                break;
5220
                            case 4:
5221
                                gen_neon_rsb(size, tmp, tmp2);
5222
                                break;
5223
                            case 5:
5224
                                gen_helper_neon_sub_f32(tmp, tmp2, tmp);
5225
                                break;
5226
                            default:
5227
                                abort();
5228
                            }
5229
                            dead_tmp(tmp2);
5230
                        }
5231
                        neon_store_reg(rd, pass, tmp);
5232
                    }
5233
                    break;
5234
                case 2: /* VMLAL sclar */
5235
                case 3: /* VQDMLAL scalar */
5236
                case 6: /* VMLSL scalar */
5237
                case 7: /* VQDMLSL scalar */
5238
                case 10: /* VMULL scalar */
5239
                case 11: /* VQDMULL scalar */
5240
                    if (size == 0 && (op == 3 || op == 7 || op == 11))
5241
                        return 1;
5242

    
5243
                    tmp2 = neon_get_scalar(size, rm);
5244
                    /* We need a copy of tmp2 because gen_neon_mull
5245
                     * deletes it during pass 0.  */
5246
                    tmp4 = new_tmp();
5247
                    tcg_gen_mov_i32(tmp4, tmp2);
5248
                    tmp3 = neon_load_reg(rn, 1);
5249

    
5250
                    for (pass = 0; pass < 2; pass++) {
5251
                        if (pass == 0) {
5252
                            tmp = neon_load_reg(rn, 0);
5253
                        } else {
5254
                            tmp = tmp3;
5255
                            tmp2 = tmp4;
5256
                        }
5257
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5258
                        if (op != 11) {
5259
                            neon_load_reg64(cpu_V1, rd + pass);
5260
                        }
5261
                        switch (op) {
5262
                        case 6:
5263
                            gen_neon_negl(cpu_V0, size);
5264
                            /* Fall through */
5265
                        case 2:
5266
                            gen_neon_addl(size);
5267
                            break;
5268
                        case 3: case 7:
5269
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5270
                            if (op == 7) {
5271
                                gen_neon_negl(cpu_V0, size);
5272
                            }
5273
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5274
                            break;
5275
                        case 10:
5276
                            /* no-op */
5277
                            break;
5278
                        case 11:
5279
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5280
                            break;
5281
                        default:
5282
                            abort();
5283
                        }
5284
                        neon_store_reg64(cpu_V0, rd + pass);
5285
                    }
5286

    
5287

    
5288
                    break;
5289
                default: /* 14 and 15 are RESERVED */
5290
                    return 1;
5291
                }
5292
            }
5293
        } else { /* size == 3 */
5294
            if (!u) {
5295
                /* Extract.  */
5296
                imm = (insn >> 8) & 0xf;
5297

    
5298
                if (imm > 7 && !q)
5299
                    return 1;
5300

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

    
5751
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5752
{
5753
    int crn = (insn >> 16) & 0xf;
5754
    int crm = insn & 0xf;
5755
    int op1 = (insn >> 21) & 7;
5756
    int op2 = (insn >> 5) & 7;
5757
    int rt = (insn >> 12) & 0xf;
5758
    TCGv tmp;
5759

    
5760
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5761
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5762
            /* TEECR */
5763
            if (IS_USER(s))
5764
                return 1;
5765
            tmp = load_cpu_field(teecr);
5766
            store_reg(s, rt, tmp);
5767
            return 0;
5768
        }
5769
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5770
            /* TEEHBR */
5771
            if (IS_USER(s) && (env->teecr & 1))
5772
                return 1;
5773
            tmp = load_cpu_field(teehbr);
5774
            store_reg(s, rt, tmp);
5775
            return 0;
5776
        }
5777
    }
5778
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5779
            op1, crn, crm, op2);
5780
    return 1;
5781
}
5782

    
5783
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5784
{
5785
    int crn = (insn >> 16) & 0xf;
5786
    int crm = insn & 0xf;
5787
    int op1 = (insn >> 21) & 7;
5788
    int op2 = (insn >> 5) & 7;
5789
    int rt = (insn >> 12) & 0xf;
5790
    TCGv tmp;
5791

    
5792
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5793
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5794
            /* TEECR */
5795
            if (IS_USER(s))
5796
                return 1;
5797
            tmp = load_reg(s, rt);
5798
            gen_helper_set_teecr(cpu_env, tmp);
5799
            dead_tmp(tmp);
5800
            return 0;
5801
        }
5802
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5803
            /* TEEHBR */
5804
            if (IS_USER(s) && (env->teecr & 1))
5805
                return 1;
5806
            tmp = load_reg(s, rt);
5807
            store_cpu_field(tmp, teehbr);
5808
            return 0;
5809
        }
5810
    }
5811
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5812
            op1, crn, crm, op2);
5813
    return 1;
5814
}
5815

    
5816
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5817
{
5818
    int cpnum;
5819

    
5820
    cpnum = (insn >> 8) & 0xf;
5821
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5822
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5823
        return 1;
5824

    
5825
    switch (cpnum) {
5826
      case 0:
5827
      case 1:
5828
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5829
            return disas_iwmmxt_insn(env, s, insn);
5830
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5831
            return disas_dsp_insn(env, s, insn);
5832
        }
5833
        return 1;
5834
    case 10:
5835
    case 11:
5836
        return disas_vfp_insn (env, s, insn);
5837
    case 14:
5838
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5839
           Unfortunately Intel decided to ignore this.  */
5840
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5841
            goto board;
5842
        if (insn & (1 << 20))
5843
            return disas_cp14_read(env, s, insn);
5844
        else
5845
            return disas_cp14_write(env, s, insn);
5846
    case 15:
5847
        return disas_cp15_insn (env, s, insn);
5848
    default:
5849
    board:
5850
        /* Unknown coprocessor.  See if the board has hooked it.  */
5851
        return disas_cp_insn (env, s, insn);
5852
    }
5853
}
5854

    
5855

    
5856
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5857
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5858
{
5859
    TCGv tmp;
5860
    tmp = new_tmp();
5861
    tcg_gen_trunc_i64_i32(tmp, val);
5862
    store_reg(s, rlow, tmp);
5863
    tmp = new_tmp();
5864
    tcg_gen_shri_i64(val, val, 32);
5865
    tcg_gen_trunc_i64_i32(tmp, val);
5866
    store_reg(s, rhigh, tmp);
5867
}
5868

    
5869
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5870
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5871
{
5872
    TCGv_i64 tmp;
5873
    TCGv tmp2;
5874

    
5875
    /* Load value and extend to 64 bits.  */
5876
    tmp = tcg_temp_new_i64();
5877
    tmp2 = load_reg(s, rlow);
5878
    tcg_gen_extu_i32_i64(tmp, tmp2);
5879
    dead_tmp(tmp2);
5880
    tcg_gen_add_i64(val, val, tmp);
5881
    tcg_temp_free_i64(tmp);
5882
}
5883

    
5884
/* load and add a 64-bit value from a register pair.  */
5885
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5886
{
5887
    TCGv_i64 tmp;
5888
    TCGv tmpl;
5889
    TCGv tmph;
5890

    
5891
    /* Load 64-bit value rd:rn.  */
5892
    tmpl = load_reg(s, rlow);
5893
    tmph = load_reg(s, rhigh);
5894
    tmp = tcg_temp_new_i64();
5895
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5896
    dead_tmp(tmpl);
5897
    dead_tmp(tmph);
5898
    tcg_gen_add_i64(val, val, tmp);
5899
    tcg_temp_free_i64(tmp);
5900
}
5901

    
5902
/* Set N and Z flags from a 64-bit value.  */
5903
static void gen_logicq_cc(TCGv_i64 val)
5904
{
5905
    TCGv tmp = new_tmp();
5906
    gen_helper_logicq_cc(tmp, val);
5907
    gen_logic_CC(tmp);
5908
    dead_tmp(tmp);
5909
}
5910

    
5911
/* Load/Store exclusive instructions are implemented by remembering
5912
   the value/address loaded, and seeing if these are the same
5913
   when the store is performed. This should be is sufficient to implement
5914
   the architecturally mandated semantics, and avoids having to monitor
5915
   regular stores.
5916

5917
   In system emulation mode only one CPU will be running at once, so
5918
   this sequence is effectively atomic.  In user emulation mode we
5919
   throw an exception and handle the atomic operation elsewhere.  */
5920
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
5921
                               TCGv addr, int size)
5922
{
5923
    TCGv tmp;
5924

    
5925
    switch (size) {
5926
    case 0:
5927
        tmp = gen_ld8u(addr, IS_USER(s));
5928
        break;
5929
    case 1:
5930
        tmp = gen_ld16u(addr, IS_USER(s));
5931
        break;
5932
    case 2:
5933
    case 3:
5934
        tmp = gen_ld32(addr, IS_USER(s));
5935
        break;
5936
    default:
5937
        abort();
5938
    }
5939
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
5940
    store_reg(s, rt, tmp);
5941
    if (size == 3) {
5942
        TCGv tmp2 = new_tmp();
5943
        tcg_gen_addi_i32(tmp2, addr, 4);
5944
        tmp = gen_ld32(tmp2, IS_USER(s));
5945
        dead_tmp(tmp2);
5946
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
5947
        store_reg(s, rt2, tmp);
5948
    }
5949
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
5950
}
5951

    
5952
static void gen_clrex(DisasContext *s)
5953
{
5954
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
5955
}
5956

    
5957
#ifdef CONFIG_USER_ONLY
5958
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
5959
                                TCGv addr, int size)
5960
{
5961
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
5962
    tcg_gen_movi_i32(cpu_exclusive_info,
5963
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
5964
    gen_exception_insn(s, 4, EXCP_STREX);
5965
}
5966
#else
5967
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
5968
                                TCGv addr, int size)
5969
{
5970
    TCGv tmp;
5971
    int done_label;
5972
    int fail_label;
5973

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

    
6036
static void disas_arm_insn(CPUState * env, DisasContext *s)
6037
{
6038
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6039
    TCGv tmp;
6040
    TCGv tmp2;
6041
    TCGv tmp3;
6042
    TCGv addr;
6043
    TCGv_i64 tmp64;
6044

    
6045
    insn = ldl_code(s->pc);
6046
    s->pc += 4;
6047

    
6048
    /* M variants do not implement ARM mode.  */
6049
    if (IS_M(env))
6050
        goto illegal_op;
6051
    cond = insn >> 28;
6052
    if (cond == 0xf){
6053
        /* Unconditional instructions.  */
6054
        if (((insn >> 25) & 7) == 1) {
6055
            /* NEON Data processing.  */
6056
            if (!arm_feature(env, ARM_FEATURE_NEON))
6057
                goto illegal_op;
6058

    
6059
            if (disas_neon_data_insn(env, s, insn))
6060
                goto illegal_op;
6061
            return;
6062
        }
6063
        if ((insn & 0x0f100000) == 0x04000000) {
6064
            /* NEON load/store.  */
6065
            if (!arm_feature(env, ARM_FEATURE_NEON))
6066
                goto illegal_op;
6067

    
6068
            if (disas_neon_ls_insn(env, s, insn))
6069
                goto illegal_op;
6070
            return;
6071
        }
6072
        if (((insn & 0x0f30f000) == 0x0510f000) ||
6073
            ((insn & 0x0f30f010) == 0x0710f000)) {
6074
            if ((insn & (1 << 22)) == 0) {
6075
                /* PLDW; v7MP */
6076
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6077
                    goto illegal_op;
6078
                }
6079
            }
6080
            /* Otherwise PLD; v5TE+ */
6081
            return;
6082
        }
6083
        if (((insn & 0x0f70f000) == 0x0450f000) ||
6084
            ((insn & 0x0f70f010) == 0x0650f000)) {
6085
            ARCH(7);
6086
            return; /* PLI; V7 */
6087
        }
6088
        if (((insn & 0x0f700000) == 0x04100000) ||
6089
            ((insn & 0x0f700010) == 0x06100000)) {
6090
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6091
                goto illegal_op;
6092
            }
6093
            return; /* v7MP: Unallocated memory hint: must NOP */
6094
        }
6095

    
6096
        if ((insn & 0x0ffffdff) == 0x01010000) {
6097
            ARCH(6);
6098
            /* setend */
6099
            if (insn & (1 << 9)) {
6100
                /* BE8 mode not implemented.  */
6101
                goto illegal_op;
6102
            }
6103
            return;
6104
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6105
            switch ((insn >> 4) & 0xf) {
6106
            case 1: /* clrex */
6107
                ARCH(6K);
6108
                gen_clrex(s);
6109
                return;
6110
            case 4: /* dsb */
6111
            case 5: /* dmb */
6112
            case 6: /* isb */
6113
                ARCH(7);
6114
                /* We don't emulate caches so these are a no-op.  */
6115
                return;
6116
            default:
6117
                goto illegal_op;
6118
            }
6119
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6120
            /* srs */
6121
            int32_t offset;
6122
            if (IS_USER(s))
6123
                goto illegal_op;
6124
            ARCH(6);
6125
            op1 = (insn & 0x1f);
6126
            addr = new_tmp();
6127
            tmp = tcg_const_i32(op1);
6128
            gen_helper_get_r13_banked(addr, cpu_env, tmp);
6129
            tcg_temp_free_i32(tmp);
6130
            i = (insn >> 23) & 3;
6131
            switch (i) {
6132
            case 0: offset = -4; break; /* DA */
6133
            case 1: offset = 0; break; /* IA */
6134
            case 2: offset = -8; break; /* DB */
6135
            case 3: offset = 4; break; /* IB */
6136
            default: abort();
6137
            }
6138
            if (offset)
6139
                tcg_gen_addi_i32(addr, addr, offset);
6140
            tmp = load_reg(s, 14);
6141
            gen_st32(tmp, addr, 0);
6142
            tmp = load_cpu_field(spsr);
6143
            tcg_gen_addi_i32(addr, addr, 4);
6144
            gen_st32(tmp, addr, 0);
6145
            if (insn & (1 << 21)) {
6146
                /* Base writeback.  */
6147
                switch (i) {
6148
                case 0: offset = -8; break;
6149
                case 1: offset = 4; break;
6150
                case 2: offset = -4; break;
6151
                case 3: offset = 0; break;
6152
                default: abort();
6153
                }
6154
                if (offset)
6155
                    tcg_gen_addi_i32(addr, addr, offset);
6156
                tmp = tcg_const_i32(op1);
6157
                gen_helper_set_r13_banked(cpu_env, tmp, addr);
6158
                tcg_temp_free_i32(tmp);
6159
                dead_tmp(addr);
6160
            } else {
6161
                dead_tmp(addr);
6162
            }
6163
            return;
6164
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6165
            /* rfe */
6166
            int32_t offset;
6167
            if (IS_USER(s))
6168
                goto illegal_op;
6169
            ARCH(6);
6170
            rn = (insn >> 16) & 0xf;
6171
            addr = load_reg(s, rn);
6172
            i = (insn >> 23) & 3;
6173
            switch (i) {
6174
            case 0: offset = -4; break; /* DA */
6175
            case 1: offset = 0; break; /* IA */
6176
            case 2: offset = -8; break; /* DB */
6177
            case 3: offset = 4; break; /* IB */
6178
            default: abort();
6179
            }
6180
            if (offset)
6181
                tcg_gen_addi_i32(addr, addr, offset);
6182
            /* Load PC into tmp and CPSR into tmp2.  */
6183
            tmp = gen_ld32(addr, 0);
6184
            tcg_gen_addi_i32(addr, addr, 4);
6185
            tmp2 = gen_ld32(addr, 0);
6186
            if (insn & (1 << 21)) {
6187
                /* Base writeback.  */
6188
                switch (i) {
6189
                case 0: offset = -8; break;
6190
                case 1: offset = 4; break;
6191
                case 2: offset = -4; break;
6192
                case 3: offset = 0; break;
6193
                default: abort();
6194
                }
6195
                if (offset)
6196
                    tcg_gen_addi_i32(addr, addr, offset);
6197
                store_reg(s, rn, addr);
6198
            } else {
6199
                dead_tmp(addr);
6200
            }
6201
            gen_rfe(s, tmp, tmp2);
6202
            return;
6203
        } else if ((insn & 0x0e000000) == 0x0a000000) {
6204
            /* branch link and change to thumb (blx <offset>) */
6205
            int32_t offset;
6206

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

    
6354
            /* branch link/exchange thumb (blx) */
6355
            tmp = load_reg(s, rm);
6356
            tmp2 = new_tmp();
6357
            tcg_gen_movi_i32(tmp2, s->pc);
6358
            store_reg(s, 14, tmp2);
6359
            gen_bx(s, tmp);
6360
            break;
6361
        case 0x5: /* saturating add/subtract */
6362
            rd = (insn >> 12) & 0xf;
6363
            rn = (insn >> 16) & 0xf;
6364
            tmp = load_reg(s, rm);
6365
            tmp2 = load_reg(s, rn);
6366
            if (op1 & 2)
6367
                gen_helper_double_saturate(tmp2, tmp2);
6368
            if (op1 & 1)
6369
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6370
            else
6371
                gen_helper_add_saturate(tmp, tmp, tmp2);
6372
            dead_tmp(tmp2);
6373
            store_reg(s, rd, tmp);
6374
            break;
6375
        case 7:
6376
            /* SMC instruction (op1 == 3)
6377
               and undefined instructions (op1 == 0 || op1 == 2)
6378
               will trap */
6379
            if (op1 != 1) {
6380
                goto illegal_op;
6381
            }
6382
            /* bkpt */
6383
            gen_exception_insn(s, 4, EXCP_BKPT);
6384
            break;
6385
        case 0x8: /* signed multiply */
6386
        case 0xa:
6387
        case 0xc:
6388
        case 0xe:
6389
            rs = (insn >> 8) & 0xf;
6390
            rn = (insn >> 12) & 0xf;
6391
            rd = (insn >> 16) & 0xf;
6392
            if (op1 == 1) {
6393
                /* (32 * 16) >> 16 */
6394
                tmp = load_reg(s, rm);
6395
                tmp2 = load_reg(s, rs);
6396
                if (sh & 4)
6397
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6398
                else
6399
                    gen_sxth(tmp2);
6400
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
6401
                tcg_gen_shri_i64(tmp64, tmp64, 16);
6402
                tmp = new_tmp();
6403
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6404
                tcg_temp_free_i64(tmp64);
6405
                if ((sh & 2) == 0) {
6406
                    tmp2 = load_reg(s, rn);
6407
                    gen_helper_add_setq(tmp, tmp, tmp2);
6408
                    dead_tmp(tmp2);
6409
                }
6410
                store_reg(s, rd, tmp);
6411
            } else {
6412
                /* 16 * 16 */
6413
                tmp = load_reg(s, rm);
6414
                tmp2 = load_reg(s, rs);
6415
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6416
                dead_tmp(tmp2);
6417
                if (op1 == 2) {
6418
                    tmp64 = tcg_temp_new_i64();
6419
                    tcg_gen_ext_i32_i64(tmp64, tmp);
6420
                    dead_tmp(tmp);
6421
                    gen_addq(s, tmp64, rn, rd);
6422
                    gen_storeq_reg(s, rn, rd, tmp64);
6423
                    tcg_temp_free_i64(tmp64);
6424
                } else {
6425
                    if (op1 == 0) {
6426
                        tmp2 = load_reg(s, rn);
6427
                        gen_helper_add_setq(tmp, tmp, tmp2);
6428
                        dead_tmp(tmp2);
6429
                    }
6430
                    store_reg(s, rd, tmp);
6431
                }
6432
            }
6433
            break;
6434
        default:
6435
            goto illegal_op;
6436
        }
6437
    } else if (((insn & 0x0e000000) == 0 &&
6438
                (insn & 0x00000090) != 0x90) ||
6439
               ((insn & 0x0e000000) == (1 << 25))) {
6440
        int set_cc, logic_cc, shiftop;
6441

    
6442
        op1 = (insn >> 21) & 0xf;
6443
        set_cc = (insn >> 20) & 1;
6444
        logic_cc = table_logic_cc[op1] & set_cc;
6445

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

    
6742
                        /* ??? This is not really atomic.  However we know
6743
                           we never have multiple CPUs running in parallel,
6744
                           so it is good enough.  */
6745
                        addr = load_reg(s, rn);
6746
                        tmp = load_reg(s, rm);
6747
                        if (insn & (1 << 22)) {
6748
                            tmp2 = gen_ld8u(addr, IS_USER(s));
6749
                            gen_st8(tmp, addr, IS_USER(s));
6750
                        } else {
6751
                            tmp2 = gen_ld32(addr, IS_USER(s));
6752
                            gen_st32(tmp, addr, IS_USER(s));
6753
                        }
6754
                        dead_tmp(addr);
6755
                        store_reg(s, rd, tmp2);
6756
                    }
6757
                }
6758
            } else {
6759
                int address_offset;
6760
                int load;
6761
                /* Misc load/store */
6762
                rn = (insn >> 16) & 0xf;
6763
                rd = (insn >> 12) & 0xf;
6764
                addr = load_reg(s, rn);
6765
                if (insn & (1 << 24))
6766
                    gen_add_datah_offset(s, insn, 0, addr);
6767
                address_offset = 0;
6768
                if (insn & (1 << 20)) {
6769
                    /* load */
6770
                    switch(sh) {
6771
                    case 1:
6772
                        tmp = gen_ld16u(addr, IS_USER(s));
6773
                        break;
6774
                    case 2:
6775
                        tmp = gen_ld8s(addr, IS_USER(s));
6776
                        break;
6777
                    default:
6778
                    case 3:
6779
                        tmp = gen_ld16s(addr, IS_USER(s));
6780
                        break;
6781
                    }
6782
                    load = 1;
6783
                } else if (sh & 2) {
6784
                    /* doubleword */
6785
                    if (sh & 1) {
6786
                        /* store */
6787
                        tmp = load_reg(s, rd);
6788
                        gen_st32(tmp, addr, IS_USER(s));
6789
                        tcg_gen_addi_i32(addr, addr, 4);
6790
                        tmp = load_reg(s, rd + 1);
6791
                        gen_st32(tmp, addr, IS_USER(s));
6792
                        load = 0;
6793
                    } else {
6794
                        /* load */
6795
                        tmp = gen_ld32(addr, IS_USER(s));
6796
                        store_reg(s, rd, tmp);
6797
                        tcg_gen_addi_i32(addr, addr, 4);
6798
                        tmp = gen_ld32(addr, IS_USER(s));
6799
                        rd++;
6800
                        load = 1;
6801
                    }
6802
                    address_offset = -4;
6803
                } else {
6804
                    /* store */
6805
                    tmp = load_reg(s, rd);
6806
                    gen_st16(tmp, addr, IS_USER(s));
6807
                    load = 0;
6808
                }
6809
                /* Perform base writeback before the loaded value to
6810
                   ensure correct behavior with overlapping index registers.
6811
                   ldrd with base writeback is is undefined if the
6812
                   destination and index registers overlap.  */
6813
                if (!(insn & (1 << 24))) {
6814
                    gen_add_datah_offset(s, insn, address_offset, addr);
6815
                    store_reg(s, rn, addr);
6816
                } else if (insn & (1 << 21)) {
6817
                    if (address_offset)
6818
                        tcg_gen_addi_i32(addr, addr, address_offset);
6819
                    store_reg(s, rn, addr);
6820
                } else {
6821
                    dead_tmp(addr);
6822
                }
6823
                if (load) {
6824
                    /* Complete the load.  */
6825
                    store_reg(s, rd, tmp);
6826
                }
6827
            }
6828
            break;
6829
        case 0x4:
6830
        case 0x5:
6831
            goto do_ldst;
6832
        case 0x6:
6833
        case 0x7:
6834
            if (insn & (1 << 4)) {
6835
                ARCH(6);
6836
                /* Armv6 Media instructions.  */
6837
                rm = insn & 0xf;
6838
                rn = (insn >> 16) & 0xf;
6839
                rd = (insn >> 12) & 0xf;
6840
                rs = (insn >> 8) & 0xf;
6841
                switch ((insn >> 23) & 3) {
6842
                case 0: /* Parallel add/subtract.  */
6843
                    op1 = (insn >> 20) & 7;
6844
                    tmp = load_reg(s, rn);
6845
                    tmp2 = load_reg(s, rm);
6846
                    sh = (insn >> 5) & 7;
6847
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6848
                        goto illegal_op;
6849
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6850
                    dead_tmp(tmp2);
6851
                    store_reg(s, rd, tmp);
6852
                    break;
6853
                case 1:
6854
                    if ((insn & 0x00700020) == 0) {
6855
                        /* Halfword pack.  */
6856
                        tmp = load_reg(s, rn);
6857
                        tmp2 = load_reg(s, rm);
6858
                        shift = (insn >> 7) & 0x1f;
6859
                        if (insn & (1 << 6)) {
6860
                            /* pkhtb */
6861
                            if (shift == 0)
6862
                                shift = 31;
6863
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
6864
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6865
                            tcg_gen_ext16u_i32(tmp2, tmp2);
6866
                        } else {
6867
                            /* pkhbt */
6868
                            if (shift)
6869
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
6870
                            tcg_gen_ext16u_i32(tmp, tmp);
6871
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6872
                        }
6873
                        tcg_gen_or_i32(tmp, tmp, tmp2);
6874
                        dead_tmp(tmp2);
6875
                        store_reg(s, rd, tmp);
6876
                    } else if ((insn & 0x00200020) == 0x00200000) {
6877
                        /* [us]sat */
6878
                        tmp = load_reg(s, rm);
6879
                        shift = (insn >> 7) & 0x1f;
6880
                        if (insn & (1 << 6)) {
6881
                            if (shift == 0)
6882
                                shift = 31;
6883
                            tcg_gen_sari_i32(tmp, tmp, shift);
6884
                        } else {
6885
                            tcg_gen_shli_i32(tmp, tmp, shift);
6886
                        }
6887
                        sh = (insn >> 16) & 0x1f;
6888
                        tmp2 = tcg_const_i32(sh);
6889
                        if (insn & (1 << 22))
6890
                          gen_helper_usat(tmp, tmp, tmp2);
6891
                        else
6892
                          gen_helper_ssat(tmp, tmp, tmp2);
6893
                        tcg_temp_free_i32(tmp2);
6894
                        store_reg(s, rd, tmp);
6895
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
6896
                        /* [us]sat16 */
6897
                        tmp = load_reg(s, rm);
6898
                        sh = (insn >> 16) & 0x1f;
6899
                        tmp2 = tcg_const_i32(sh);
6900
                        if (insn & (1 << 22))
6901
                          gen_helper_usat16(tmp, tmp, tmp2);
6902
                        else
6903
                          gen_helper_ssat16(tmp, tmp, tmp2);
6904
                        tcg_temp_free_i32(tmp2);
6905
                        store_reg(s, rd, tmp);
6906
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6907
                        /* Select bytes.  */
6908
                        tmp = load_reg(s, rn);
6909
                        tmp2 = load_reg(s, rm);
6910
                        tmp3 = new_tmp();
6911
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6912
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6913
                        dead_tmp(tmp3);
6914
                        dead_tmp(tmp2);
6915
                        store_reg(s, rd, tmp);
6916
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6917
                        tmp = load_reg(s, rm);
6918
                        shift = (insn >> 10) & 3;
6919
                        /* ??? In many cases it's not neccessary to do a
6920
                           rotate, a shift is sufficient.  */
6921
                        if (shift != 0)
6922
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
6923
                        op1 = (insn >> 20) & 7;
6924
                        switch (op1) {
6925
                        case 0: gen_sxtb16(tmp);  break;
6926
                        case 2: gen_sxtb(tmp);    break;
6927
                        case 3: gen_sxth(tmp);    break;
6928
                        case 4: gen_uxtb16(tmp);  break;
6929
                        case 6: gen_uxtb(tmp);    break;
6930
                        case 7: gen_uxth(tmp);    break;
6931
                        default: goto illegal_op;
6932
                        }
6933
                        if (rn != 15) {
6934
                            tmp2 = load_reg(s, rn);
6935
                            if ((op1 & 3) == 0) {
6936
                                gen_add16(tmp, tmp2);
6937
                            } else {
6938
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6939
                                dead_tmp(tmp2);
6940
                            }
6941
                        }
6942
                        store_reg(s, rd, tmp);
6943
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6944
                        /* rev */
6945
                        tmp = load_reg(s, rm);
6946
                        if (insn & (1 << 22)) {
6947
                            if (insn & (1 << 7)) {
6948
                                gen_revsh(tmp);
6949
                            } else {
6950
                                ARCH(6T2);
6951
                                gen_helper_rbit(tmp, tmp);
6952
                            }
6953
                        } else {
6954
                            if (insn & (1 << 7))
6955
                                gen_rev16(tmp);
6956
                            else
6957
                                tcg_gen_bswap32_i32(tmp, tmp);
6958
                        }
6959
                        store_reg(s, rd, tmp);
6960
                    } else {
6961
                        goto illegal_op;
6962
                    }
6963
                    break;
6964
                case 2: /* Multiplies (Type 3).  */
6965
                    tmp = load_reg(s, rm);
6966
                    tmp2 = load_reg(s, rs);
6967
                    if (insn & (1 << 20)) {
6968
                        /* Signed multiply most significant [accumulate].
6969
                           (SMMUL, SMMLA, SMMLS) */
6970
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
6971

    
6972
                        if (rd != 15) {
6973
                            tmp = load_reg(s, rd);
6974
                            if (insn & (1 << 6)) {
6975
                                tmp64 = gen_subq_msw(tmp64, tmp);
6976
                            } else {
6977
                                tmp64 = gen_addq_msw(tmp64, tmp);
6978
                            }
6979
                        }
6980
                        if (insn & (1 << 5)) {
6981
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
6982
                        }
6983
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
6984
                        tmp = new_tmp();
6985
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
6986
                        tcg_temp_free_i64(tmp64);
6987
                        store_reg(s, rn, tmp);
6988
                    } else {
6989
                        if (insn & (1 << 5))
6990
                            gen_swap_half(tmp2);
6991
                        gen_smul_dual(tmp, tmp2);
6992
                        /* This addition cannot overflow.  */
6993
                        if (insn & (1 << 6)) {
6994
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
6995
                        } else {
6996
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6997
                        }
6998
                        dead_tmp(tmp2);
6999
                        if (insn & (1 << 22)) {
7000
                            /* smlald, smlsld */
7001
                            tmp64 = tcg_temp_new_i64();
7002
                            tcg_gen_ext_i32_i64(tmp64, tmp);
7003
                            dead_tmp(tmp);
7004
                            gen_addq(s, tmp64, rd, rn);
7005
                            gen_storeq_reg(s, rd, rn, tmp64);
7006
                            tcg_temp_free_i64(tmp64);
7007
                        } else {
7008
                            /* smuad, smusd, smlad, smlsd */
7009
                            if (rd != 15)
7010
                              {
7011
                                tmp2 = load_reg(s, rd);
7012
                                gen_helper_add_setq(tmp, tmp, tmp2);
7013
                                dead_tmp(tmp2);
7014
                              }
7015
                            store_reg(s, rn, tmp);
7016
                        }
7017
                    }
7018
                    break;
7019
                case 3:
7020
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7021
                    switch (op1) {
7022
                    case 0: /* Unsigned sum of absolute differences.  */
7023
                        ARCH(6);
7024
                        tmp = load_reg(s, rm);
7025
                        tmp2 = load_reg(s, rs);
7026
                        gen_helper_usad8(tmp, tmp, tmp2);
7027
                        dead_tmp(tmp2);
7028
                        if (rd != 15) {
7029
                            tmp2 = load_reg(s, rd);
7030
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7031
                            dead_tmp(tmp2);
7032
                        }
7033
                        store_reg(s, rn, tmp);
7034
                        break;
7035
                    case 0x20: case 0x24: case 0x28: case 0x2c:
7036
                        /* Bitfield insert/clear.  */
7037
                        ARCH(6T2);
7038
                        shift = (insn >> 7) & 0x1f;
7039
                        i = (insn >> 16) & 0x1f;
7040
                        i = i + 1 - shift;
7041
                        if (rm == 15) {
7042
                            tmp = new_tmp();
7043
                            tcg_gen_movi_i32(tmp, 0);
7044
                        } else {
7045
                            tmp = load_reg(s, rm);
7046
                        }
7047
                        if (i != 32) {
7048
                            tmp2 = load_reg(s, rd);
7049
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
7050
                            dead_tmp(tmp2);
7051
                        }
7052
                        store_reg(s, rd, tmp);
7053
                        break;
7054
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7055
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7056
                        ARCH(6T2);
7057
                        tmp = load_reg(s, rm);
7058
                        shift = (insn >> 7) & 0x1f;
7059
                        i = ((insn >> 16) & 0x1f) + 1;
7060
                        if (shift + i > 32)
7061
                            goto illegal_op;
7062
                        if (i < 32) {
7063
                            if (op1 & 0x20) {
7064
                                gen_ubfx(tmp, shift, (1u << i) - 1);
7065
                            } else {
7066
                                gen_sbfx(tmp, shift, i);
7067
                            }
7068
                        }
7069
                        store_reg(s, rd, tmp);
7070
                        break;
7071
                    default:
7072
                        goto illegal_op;
7073
                    }
7074
                    break;
7075
                }
7076
                break;
7077
            }
7078
        do_ldst:
7079
            /* Check for undefined extension instructions
7080
             * per the ARM Bible IE:
7081
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
7082
             */
7083
            sh = (0xf << 20) | (0xf << 4);
7084
            if (op1 == 0x7 && ((insn & sh) == sh))
7085
            {
7086
                goto illegal_op;
7087
            }
7088
            /* load/store byte/word */
7089
            rn = (insn >> 16) & 0xf;
7090
            rd = (insn >> 12) & 0xf;
7091
            tmp2 = load_reg(s, rn);
7092
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7093
            if (insn & (1 << 24))
7094
                gen_add_data_offset(s, insn, tmp2);
7095
            if (insn & (1 << 20)) {
7096
                /* load */
7097
                if (insn & (1 << 22)) {
7098
                    tmp = gen_ld8u(tmp2, i);
7099
                } else {
7100
                    tmp = gen_ld32(tmp2, i);
7101
                }
7102
            } else {
7103
                /* store */
7104
                tmp = load_reg(s, rd);
7105
                if (insn & (1 << 22))
7106
                    gen_st8(tmp, tmp2, i);
7107
                else
7108
                    gen_st32(tmp, tmp2, i);
7109
            }
7110
            if (!(insn & (1 << 24))) {
7111
                gen_add_data_offset(s, insn, tmp2);
7112
                store_reg(s, rn, tmp2);
7113
            } else if (insn & (1 << 21)) {
7114
                store_reg(s, rn, tmp2);
7115
            } else {
7116
                dead_tmp(tmp2);
7117
            }
7118
            if (insn & (1 << 20)) {
7119
                /* Complete the load.  */
7120
                if (rd == 15)
7121
                    gen_bx(s, tmp);
7122
                else
7123
                    store_reg(s, rd, tmp);
7124
            }
7125
            break;
7126
        case 0x08:
7127
        case 0x09:
7128
            {
7129
                int j, n, user, loaded_base;
7130
                TCGv loaded_var;
7131
                /* load/store multiple words */
7132
                /* XXX: store correct base if write back */
7133
                user = 0;
7134
                if (insn & (1 << 22)) {
7135
                    if (IS_USER(s))
7136
                        goto illegal_op; /* only usable in supervisor mode */
7137

    
7138
                    if ((insn & (1 << 15)) == 0)
7139
                        user = 1;
7140
                }
7141
                rn = (insn >> 16) & 0xf;
7142
                addr = load_reg(s, rn);
7143

    
7144
                /* compute total size */
7145
                loaded_base = 0;
7146
                TCGV_UNUSED(loaded_var);
7147
                n = 0;
7148
                for(i=0;i<16;i++) {
7149
                    if (insn & (1 << i))
7150
                        n++;
7151
                }
7152
                /* XXX: test invalid n == 0 case ? */
7153
                if (insn & (1 << 23)) {
7154
                    if (insn & (1 << 24)) {
7155
                        /* pre increment */
7156
                        tcg_gen_addi_i32(addr, addr, 4);
7157
                    } else {
7158
                        /* post increment */
7159
                    }
7160
                } else {
7161
                    if (insn & (1 << 24)) {
7162
                        /* pre decrement */
7163
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
7164
                    } else {
7165
                        /* post decrement */
7166
                        if (n != 1)
7167
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7168
                    }
7169
                }
7170
                j = 0;
7171
                for(i=0;i<16;i++) {
7172
                    if (insn & (1 << i)) {
7173
                        if (insn & (1 << 20)) {
7174
                            /* load */
7175
                            tmp = gen_ld32(addr, IS_USER(s));
7176
                            if (i == 15) {
7177
                                gen_bx(s, tmp);
7178
                            } else if (user) {
7179
                                tmp2 = tcg_const_i32(i);
7180
                                gen_helper_set_user_reg(tmp2, tmp);
7181
                                tcg_temp_free_i32(tmp2);
7182
                                dead_tmp(tmp);
7183
                            } else if (i == rn) {
7184
                                loaded_var = tmp;
7185
                                loaded_base = 1;
7186
                            } else {
7187
                                store_reg(s, i, tmp);
7188
                            }
7189
                        } else {
7190
                            /* store */
7191
                            if (i == 15) {
7192
                                /* special case: r15 = PC + 8 */
7193
                                val = (long)s->pc + 4;
7194
                                tmp = new_tmp();
7195
                                tcg_gen_movi_i32(tmp, val);
7196
                            } else if (user) {
7197
                                tmp = new_tmp();
7198
                                tmp2 = tcg_const_i32(i);
7199
                                gen_helper_get_user_reg(tmp, tmp2);
7200
                                tcg_temp_free_i32(tmp2);
7201
                            } else {
7202
                                tmp = load_reg(s, i);
7203
                            }
7204
                            gen_st32(tmp, addr, IS_USER(s));
7205
                        }
7206
                        j++;
7207
                        /* no need to add after the last transfer */
7208
                        if (j != n)
7209
                            tcg_gen_addi_i32(addr, addr, 4);
7210
                    }
7211
                }
7212
                if (insn & (1 << 21)) {
7213
                    /* write back */
7214
                    if (insn & (1 << 23)) {
7215
                        if (insn & (1 << 24)) {
7216
                            /* pre increment */
7217
                        } else {
7218
                            /* post increment */
7219
                            tcg_gen_addi_i32(addr, addr, 4);
7220
                        }
7221
                    } else {
7222
                        if (insn & (1 << 24)) {
7223
                            /* pre decrement */
7224
                            if (n != 1)
7225
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7226
                        } else {
7227
                            /* post decrement */
7228
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
7229
                        }
7230
                    }
7231
                    store_reg(s, rn, addr);
7232
                } else {
7233
                    dead_tmp(addr);
7234
                }
7235
                if (loaded_base) {
7236
                    store_reg(s, rn, loaded_var);
7237
                }
7238
                if ((insn & (1 << 22)) && !user) {
7239
                    /* Restore CPSR from SPSR.  */
7240
                    tmp = load_cpu_field(spsr);
7241
                    gen_set_cpsr(tmp, 0xffffffff);
7242
                    dead_tmp(tmp);
7243
                    s->is_jmp = DISAS_UPDATE;
7244
                }
7245
            }
7246
            break;
7247
        case 0xa:
7248
        case 0xb:
7249
            {
7250
                int32_t offset;
7251

    
7252
                /* branch (and link) */
7253
                val = (int32_t)s->pc;
7254
                if (insn & (1 << 24)) {
7255
                    tmp = new_tmp();
7256
                    tcg_gen_movi_i32(tmp, val);
7257
                    store_reg(s, 14, tmp);
7258
                }
7259
                offset = (((int32_t)insn << 8) >> 8);
7260
                val += (offset << 2) + 4;
7261
                gen_jmp(s, val);
7262
            }
7263
            break;
7264
        case 0xc:
7265
        case 0xd:
7266
        case 0xe:
7267
            /* Coprocessor.  */
7268
            if (disas_coproc_insn(env, s, insn))
7269
                goto illegal_op;
7270
            break;
7271
        case 0xf:
7272
            /* swi */
7273
            gen_set_pc_im(s->pc);
7274
            s->is_jmp = DISAS_SWI;
7275
            break;
7276
        default:
7277
        illegal_op:
7278
            gen_exception_insn(s, 4, EXCP_UDEF);
7279
            break;
7280
        }
7281
    }
7282
}
7283

    
7284
/* Return true if this is a Thumb-2 logical op.  */
7285
static int
7286
thumb2_logic_op(int op)
7287
{
7288
    return (op < 8);
7289
}
7290

    
7291
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7292
   then set condition code flags based on the result of the operation.
7293
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7294
   to the high bit of T1.
7295
   Returns zero if the opcode is valid.  */
7296

    
7297
static int
7298
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7299
{
7300
    int logic_cc;
7301

    
7302
    logic_cc = 0;
7303
    switch (op) {
7304
    case 0: /* and */
7305
        tcg_gen_and_i32(t0, t0, t1);
7306
        logic_cc = conds;
7307
        break;
7308
    case 1: /* bic */
7309
        tcg_gen_andc_i32(t0, t0, t1);
7310
        logic_cc = conds;
7311
        break;
7312
    case 2: /* orr */
7313
        tcg_gen_or_i32(t0, t0, t1);
7314
        logic_cc = conds;
7315
        break;
7316
    case 3: /* orn */
7317
        tcg_gen_not_i32(t1, t1);
7318
        tcg_gen_or_i32(t0, t0, t1);
7319
        logic_cc = conds;
7320
        break;
7321
    case 4: /* eor */
7322
        tcg_gen_xor_i32(t0, t0, t1);
7323
        logic_cc = conds;
7324
        break;
7325
    case 8: /* add */
7326
        if (conds)
7327
            gen_helper_add_cc(t0, t0, t1);
7328
        else
7329
            tcg_gen_add_i32(t0, t0, t1);
7330
        break;
7331
    case 10: /* adc */
7332
        if (conds)
7333
            gen_helper_adc_cc(t0, t0, t1);
7334
        else
7335
            gen_adc(t0, t1);
7336
        break;
7337
    case 11: /* sbc */
7338
        if (conds)
7339
            gen_helper_sbc_cc(t0, t0, t1);
7340
        else
7341
            gen_sub_carry(t0, t0, t1);
7342
        break;
7343
    case 13: /* sub */
7344
        if (conds)
7345
            gen_helper_sub_cc(t0, t0, t1);
7346
        else
7347
            tcg_gen_sub_i32(t0, t0, t1);
7348
        break;
7349
    case 14: /* rsb */
7350
        if (conds)
7351
            gen_helper_sub_cc(t0, t1, t0);
7352
        else
7353
            tcg_gen_sub_i32(t0, t1, t0);
7354
        break;
7355
    default: /* 5, 6, 7, 9, 12, 15. */
7356
        return 1;
7357
    }
7358
    if (logic_cc) {
7359
        gen_logic_CC(t0);
7360
        if (shifter_out)
7361
            gen_set_CF_bit31(t1);
7362
    }
7363
    return 0;
7364
}
7365

    
7366
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7367
   is not legal.  */
7368
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7369
{
7370
    uint32_t insn, imm, shift, offset;
7371
    uint32_t rd, rn, rm, rs;
7372
    TCGv tmp;
7373
    TCGv tmp2;
7374
    TCGv tmp3;
7375
    TCGv addr;
7376
    TCGv_i64 tmp64;
7377
    int op;
7378
    int shiftop;
7379
    int conds;
7380
    int logic_cc;
7381

    
7382
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7383
          || arm_feature (env, ARM_FEATURE_M))) {
7384
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7385
           16-bit instructions to get correct prefetch abort behavior.  */
7386
        insn = insn_hw1;
7387
        if ((insn & (1 << 12)) == 0) {
7388
            /* Second half of blx.  */
7389
            offset = ((insn & 0x7ff) << 1);
7390
            tmp = load_reg(s, 14);
7391
            tcg_gen_addi_i32(tmp, tmp, offset);
7392
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7393

    
7394
            tmp2 = new_tmp();
7395
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7396
            store_reg(s, 14, tmp2);
7397
            gen_bx(s, tmp);
7398
            return 0;
7399
        }
7400
        if (insn & (1 << 11)) {
7401
            /* Second half of bl.  */
7402
            offset = ((insn & 0x7ff) << 1) | 1;
7403
            tmp = load_reg(s, 14);
7404
            tcg_gen_addi_i32(tmp, tmp, offset);
7405

    
7406
            tmp2 = new_tmp();
7407
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7408
            store_reg(s, 14, tmp2);
7409
            gen_bx(s, tmp);
7410
            return 0;
7411
        }
7412
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7413
            /* Instruction spans a page boundary.  Implement it as two
7414
               16-bit instructions in case the second half causes an
7415
               prefetch abort.  */
7416
            offset = ((int32_t)insn << 21) >> 9;
7417
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7418
            return 0;
7419
        }
7420
        /* Fall through to 32-bit decode.  */
7421
    }
7422

    
7423
    insn = lduw_code(s->pc);
7424
    s->pc += 2;
7425
    insn |= (uint32_t)insn_hw1 << 16;
7426

    
7427
    if ((insn & 0xf800e800) != 0xf000e800) {
7428
        ARCH(6T2);
7429
    }
7430

    
7431
    rn = (insn >> 16) & 0xf;
7432
    rs = (insn >> 12) & 0xf;
7433
    rd = (insn >> 8) & 0xf;
7434
    rm = insn & 0xf;
7435
    switch ((insn >> 25) & 0xf) {
7436
    case 0: case 1: case 2: case 3:
7437
        /* 16-bit instructions.  Should never happen.  */
7438
        abort();
7439
    case 4:
7440
        if (insn & (1 << 22)) {
7441
            /* Other load/store, table branch.  */
7442
            if (insn & 0x01200000) {
7443
                /* Load/store doubleword.  */
7444
                if (rn == 15) {
7445
                    addr = new_tmp();
7446
                    tcg_gen_movi_i32(addr, s->pc & ~3);
7447
                } else {
7448
                    addr = load_reg(s, rn);
7449
                }
7450
                offset = (insn & 0xff) * 4;
7451
                if ((insn & (1 << 23)) == 0)
7452
                    offset = -offset;
7453
                if (insn & (1 << 24)) {
7454
                    tcg_gen_addi_i32(addr, addr, offset);
7455
                    offset = 0;
7456
                }
7457
                if (insn & (1 << 20)) {
7458
                    /* ldrd */
7459
                    tmp = gen_ld32(addr, IS_USER(s));
7460
                    store_reg(s, rs, tmp);
7461
                    tcg_gen_addi_i32(addr, addr, 4);
7462
                    tmp = gen_ld32(addr, IS_USER(s));
7463
                    store_reg(s, rd, tmp);
7464
                } else {
7465
                    /* strd */
7466
                    tmp = load_reg(s, rs);
7467
                    gen_st32(tmp, addr, IS_USER(s));
7468
                    tcg_gen_addi_i32(addr, addr, 4);
7469
                    tmp = load_reg(s, rd);
7470
                    gen_st32(tmp, addr, IS_USER(s));
7471
                }
7472
                if (insn & (1 << 21)) {
7473
                    /* Base writeback.  */
7474
                    if (rn == 15)
7475
                        goto illegal_op;
7476
                    tcg_gen_addi_i32(addr, addr, offset - 4);
7477
                    store_reg(s, rn, addr);
7478
                } else {
7479
                    dead_tmp(addr);
7480
                }
7481
            } else if ((insn & (1 << 23)) == 0) {
7482
                /* Load/store exclusive word.  */
7483
                addr = tcg_temp_local_new();
7484
                load_reg_var(s, addr, rn);
7485
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
7486
                if (insn & (1 << 20)) {
7487
                    gen_load_exclusive(s, rs, 15, addr, 2);
7488
                } else {
7489
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
7490
                }
7491
                tcg_temp_free(addr);
7492
            } else if ((insn & (1 << 6)) == 0) {
7493
                /* Table Branch.  */
7494
                if (rn == 15) {
7495
                    addr = new_tmp();
7496
                    tcg_gen_movi_i32(addr, s->pc);
7497
                } else {
7498
                    addr = load_reg(s, rn);
7499
                }
7500
                tmp = load_reg(s, rm);
7501
                tcg_gen_add_i32(addr, addr, tmp);
7502
                if (insn & (1 << 4)) {
7503
                    /* tbh */
7504
                    tcg_gen_add_i32(addr, addr, tmp);
7505
                    dead_tmp(tmp);
7506
                    tmp = gen_ld16u(addr, IS_USER(s));
7507
                } else { /* tbb */
7508
                    dead_tmp(tmp);
7509
                    tmp = gen_ld8u(addr, IS_USER(s));
7510
                }
7511
                dead_tmp(addr);
7512
                tcg_gen_shli_i32(tmp, tmp, 1);
7513
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7514
                store_reg(s, 15, tmp);
7515
            } else {
7516
                /* Load/store exclusive byte/halfword/doubleword.  */
7517
                ARCH(7);
7518
                op = (insn >> 4) & 0x3;
7519
                if (op == 2) {
7520
                    goto illegal_op;
7521
                }
7522
                addr = tcg_temp_local_new();
7523
                load_reg_var(s, addr, rn);
7524
                if (insn & (1 << 20)) {
7525
                    gen_load_exclusive(s, rs, rd, addr, op);
7526
                } else {
7527
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
7528
                }
7529
                tcg_temp_free(addr);
7530
            }
7531
        } else {
7532
            /* Load/store multiple, RFE, SRS.  */
7533
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7534
                /* Not available in user mode.  */
7535
                if (IS_USER(s))
7536
                    goto illegal_op;
7537
                if (insn & (1 << 20)) {
7538
                    /* rfe */
7539
                    addr = load_reg(s, rn);
7540
                    if ((insn & (1 << 24)) == 0)
7541
                        tcg_gen_addi_i32(addr, addr, -8);
7542
                    /* Load PC into tmp and CPSR into tmp2.  */
7543
                    tmp = gen_ld32(addr, 0);
7544
                    tcg_gen_addi_i32(addr, addr, 4);
7545
                    tmp2 = gen_ld32(addr, 0);
7546
                    if (insn & (1 << 21)) {
7547
                        /* Base writeback.  */
7548
                        if (insn & (1 << 24)) {
7549
                            tcg_gen_addi_i32(addr, addr, 4);
7550
                        } else {
7551
                            tcg_gen_addi_i32(addr, addr, -4);
7552
                        }
7553
                        store_reg(s, rn, addr);
7554
                    } else {
7555
                        dead_tmp(addr);
7556
                    }
7557
                    gen_rfe(s, tmp, tmp2);
7558
                } else {
7559
                    /* srs */
7560
                    op = (insn & 0x1f);
7561
                    addr = new_tmp();
7562
                    tmp = tcg_const_i32(op);
7563
                    gen_helper_get_r13_banked(addr, cpu_env, tmp);
7564
                    tcg_temp_free_i32(tmp);
7565
                    if ((insn & (1 << 24)) == 0) {
7566
                        tcg_gen_addi_i32(addr, addr, -8);
7567
                    }
7568
                    tmp = load_reg(s, 14);
7569
                    gen_st32(tmp, addr, 0);
7570
                    tcg_gen_addi_i32(addr, addr, 4);
7571
                    tmp = new_tmp();
7572
                    gen_helper_cpsr_read(tmp);
7573
                    gen_st32(tmp, addr, 0);
7574
                    if (insn & (1 << 21)) {
7575
                        if ((insn & (1 << 24)) == 0) {
7576
                            tcg_gen_addi_i32(addr, addr, -4);
7577
                        } else {
7578
                            tcg_gen_addi_i32(addr, addr, 4);
7579
                        }
7580
                        tmp = tcg_const_i32(op);
7581
                        gen_helper_set_r13_banked(cpu_env, tmp, addr);
7582
                        tcg_temp_free_i32(tmp);
7583
                    } else {
7584
                        dead_tmp(addr);
7585
                    }
7586
                }
7587
            } else {
7588
                int i;
7589
                /* Load/store multiple.  */
7590
                addr = load_reg(s, rn);
7591
                offset = 0;
7592
                for (i = 0; i < 16; i++) {
7593
                    if (insn & (1 << i))
7594
                        offset += 4;
7595
                }
7596
                if (insn & (1 << 24)) {
7597
                    tcg_gen_addi_i32(addr, addr, -offset);
7598
                }
7599

    
7600
                for (i = 0; i < 16; i++) {
7601
                    if ((insn & (1 << i)) == 0)
7602
                        continue;
7603
                    if (insn & (1 << 20)) {
7604
                        /* Load.  */
7605
                        tmp = gen_ld32(addr, IS_USER(s));
7606
                        if (i == 15) {
7607
                            gen_bx(s, tmp);
7608
                        } else {
7609
                            store_reg(s, i, tmp);
7610
                        }
7611
                    } else {
7612
                        /* Store.  */
7613
                        tmp = load_reg(s, i);
7614
                        gen_st32(tmp, addr, IS_USER(s));
7615
                    }
7616
                    tcg_gen_addi_i32(addr, addr, 4);
7617
                }
7618
                if (insn & (1 << 21)) {
7619
                    /* Base register writeback.  */
7620
                    if (insn & (1 << 24)) {
7621
                        tcg_gen_addi_i32(addr, addr, -offset);
7622
                    }
7623
                    /* Fault if writeback register is in register list.  */
7624
                    if (insn & (1 << rn))
7625
                        goto illegal_op;
7626
                    store_reg(s, rn, addr);
7627
                } else {
7628
                    dead_tmp(addr);
7629
                }
7630
            }
7631
        }
7632
        break;
7633
    case 5:
7634

    
7635
        op = (insn >> 21) & 0xf;
7636
        if (op == 6) {
7637
            /* Halfword pack.  */
7638
            tmp = load_reg(s, rn);
7639
            tmp2 = load_reg(s, rm);
7640
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
7641
            if (insn & (1 << 5)) {
7642
                /* pkhtb */
7643
                if (shift == 0)
7644
                    shift = 31;
7645
                tcg_gen_sari_i32(tmp2, tmp2, shift);
7646
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7647
                tcg_gen_ext16u_i32(tmp2, tmp2);
7648
            } else {
7649
                /* pkhbt */
7650
                if (shift)
7651
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
7652
                tcg_gen_ext16u_i32(tmp, tmp);
7653
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7654
            }
7655
            tcg_gen_or_i32(tmp, tmp, tmp2);
7656
            dead_tmp(tmp2);
7657
            store_reg(s, rd, tmp);
7658
        } else {
7659
            /* Data processing register constant shift.  */
7660
            if (rn == 15) {
7661
                tmp = new_tmp();
7662
                tcg_gen_movi_i32(tmp, 0);
7663
            } else {
7664
                tmp = load_reg(s, rn);
7665
            }
7666
            tmp2 = load_reg(s, rm);
7667

    
7668
            shiftop = (insn >> 4) & 3;
7669
            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7670
            conds = (insn & (1 << 20)) != 0;
7671
            logic_cc = (conds && thumb2_logic_op(op));
7672
            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7673
            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
7674
                goto illegal_op;
7675
            dead_tmp(tmp2);
7676
            if (rd != 15) {
7677
                store_reg(s, rd, tmp);
7678
            } else {
7679
                dead_tmp(tmp);
7680
            }
7681
        }
7682
        break;
7683
    case 13: /* Misc data processing.  */
7684
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7685
        if (op < 4 && (insn & 0xf000) != 0xf000)
7686
            goto illegal_op;
7687
        switch (op) {
7688
        case 0: /* Register controlled shift.  */
7689
            tmp = load_reg(s, rn);
7690
            tmp2 = load_reg(s, rm);
7691
            if ((insn & 0x70) != 0)
7692
                goto illegal_op;
7693
            op = (insn >> 21) & 3;
7694
            logic_cc = (insn & (1 << 20)) != 0;
7695
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7696
            if (logic_cc)
7697
                gen_logic_CC(tmp);
7698
            store_reg_bx(env, s, rd, tmp);
7699
            break;
7700
        case 1: /* Sign/zero extend.  */
7701
            tmp = load_reg(s, rm);
7702
            shift = (insn >> 4) & 3;
7703
            /* ??? In many cases it's not neccessary to do a
7704
               rotate, a shift is sufficient.  */
7705
            if (shift != 0)
7706
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7707
            op = (insn >> 20) & 7;
7708
            switch (op) {
7709
            case 0: gen_sxth(tmp);   break;
7710
            case 1: gen_uxth(tmp);   break;
7711
            case 2: gen_sxtb16(tmp); break;
7712
            case 3: gen_uxtb16(tmp); break;
7713
            case 4: gen_sxtb(tmp);   break;
7714
            case 5: gen_uxtb(tmp);   break;
7715
            default: goto illegal_op;
7716
            }
7717
            if (rn != 15) {
7718
                tmp2 = load_reg(s, rn);
7719
                if ((op >> 1) == 1) {
7720
                    gen_add16(tmp, tmp2);
7721
                } else {
7722
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7723
                    dead_tmp(tmp2);
7724
                }
7725
            }
7726
            store_reg(s, rd, tmp);
7727
            break;
7728
        case 2: /* SIMD add/subtract.  */
7729
            op = (insn >> 20) & 7;
7730
            shift = (insn >> 4) & 7;
7731
            if ((op & 3) == 3 || (shift & 3) == 3)
7732
                goto illegal_op;
7733
            tmp = load_reg(s, rn);
7734
            tmp2 = load_reg(s, rm);
7735
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7736
            dead_tmp(tmp2);
7737
            store_reg(s, rd, tmp);
7738
            break;
7739
        case 3: /* Other data processing.  */
7740
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7741
            if (op < 4) {
7742
                /* Saturating add/subtract.  */
7743
                tmp = load_reg(s, rn);
7744
                tmp2 = load_reg(s, rm);
7745
                if (op & 1)
7746
                    gen_helper_double_saturate(tmp, tmp);
7747
                if (op & 2)
7748
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7749
                else
7750
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7751
                dead_tmp(tmp2);
7752
            } else {
7753
                tmp = load_reg(s, rn);
7754
                switch (op) {
7755
                case 0x0a: /* rbit */
7756
                    gen_helper_rbit(tmp, tmp);
7757
                    break;
7758
                case 0x08: /* rev */
7759
                    tcg_gen_bswap32_i32(tmp, tmp);
7760
                    break;
7761
                case 0x09: /* rev16 */
7762
                    gen_rev16(tmp);
7763
                    break;
7764
                case 0x0b: /* revsh */
7765
                    gen_revsh(tmp);
7766
                    break;
7767
                case 0x10: /* sel */
7768
                    tmp2 = load_reg(s, rm);
7769
                    tmp3 = new_tmp();
7770
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7771
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7772
                    dead_tmp(tmp3);
7773
                    dead_tmp(tmp2);
7774
                    break;
7775
                case 0x18: /* clz */
7776
                    gen_helper_clz(tmp, tmp);
7777
                    break;
7778
                default:
7779
                    goto illegal_op;
7780
                }
7781
            }
7782
            store_reg(s, rd, tmp);
7783
            break;
7784
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7785
            op = (insn >> 4) & 0xf;
7786
            tmp = load_reg(s, rn);
7787
            tmp2 = load_reg(s, rm);
7788
            switch ((insn >> 20) & 7) {
7789
            case 0: /* 32 x 32 -> 32 */
7790
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7791
                dead_tmp(tmp2);
7792
                if (rs != 15) {
7793
                    tmp2 = load_reg(s, rs);
7794
                    if (op)
7795
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7796
                    else
7797
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7798
                    dead_tmp(tmp2);
7799
                }
7800
                break;
7801
            case 1: /* 16 x 16 -> 32 */
7802
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7803
                dead_tmp(tmp2);
7804
                if (rs != 15) {
7805
                    tmp2 = load_reg(s, rs);
7806
                    gen_helper_add_setq(tmp, tmp, tmp2);
7807
                    dead_tmp(tmp2);
7808
                }
7809
                break;
7810
            case 2: /* Dual multiply add.  */
7811
            case 4: /* Dual multiply subtract.  */
7812
                if (op)
7813
                    gen_swap_half(tmp2);
7814
                gen_smul_dual(tmp, tmp2);
7815
                /* This addition cannot overflow.  */
7816
                if (insn & (1 << 22)) {
7817
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7818
                } else {
7819
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7820
                }
7821
                dead_tmp(tmp2);
7822
                if (rs != 15)
7823
                  {
7824
                    tmp2 = load_reg(s, rs);
7825
                    gen_helper_add_setq(tmp, tmp, tmp2);
7826
                    dead_tmp(tmp2);
7827
                  }
7828
                break;
7829
            case 3: /* 32 * 16 -> 32msb */
7830
                if (op)
7831
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7832
                else
7833
                    gen_sxth(tmp2);
7834
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7835
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7836
                tmp = new_tmp();
7837
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7838
                tcg_temp_free_i64(tmp64);
7839
                if (rs != 15)
7840
                  {
7841
                    tmp2 = load_reg(s, rs);
7842
                    gen_helper_add_setq(tmp, tmp, tmp2);
7843
                    dead_tmp(tmp2);
7844
                  }
7845
                break;
7846
            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
7847
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7848
                if (rs != 15) {
7849
                    tmp = load_reg(s, rs);
7850
                    if (insn & (1 << 20)) {
7851
                        tmp64 = gen_addq_msw(tmp64, tmp);
7852
                    } else {
7853
                        tmp64 = gen_subq_msw(tmp64, tmp);
7854
                    }
7855
                }
7856
                if (insn & (1 << 4)) {
7857
                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7858
                }
7859
                tcg_gen_shri_i64(tmp64, tmp64, 32);
7860
                tmp = new_tmp();
7861
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7862
                tcg_temp_free_i64(tmp64);
7863
                break;
7864
            case 7: /* Unsigned sum of absolute differences.  */
7865
                gen_helper_usad8(tmp, tmp, tmp2);
7866
                dead_tmp(tmp2);
7867
                if (rs != 15) {
7868
                    tmp2 = load_reg(s, rs);
7869
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7870
                    dead_tmp(tmp2);
7871
                }
7872
                break;
7873
            }
7874
            store_reg(s, rd, tmp);
7875
            break;
7876
        case 6: case 7: /* 64-bit multiply, Divide.  */
7877
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7878
            tmp = load_reg(s, rn);
7879
            tmp2 = load_reg(s, rm);
7880
            if ((op & 0x50) == 0x10) {
7881
                /* sdiv, udiv */
7882
                if (!arm_feature(env, ARM_FEATURE_DIV))
7883
                    goto illegal_op;
7884
                if (op & 0x20)
7885
                    gen_helper_udiv(tmp, tmp, tmp2);
7886
                else
7887
                    gen_helper_sdiv(tmp, tmp, tmp2);
7888
                dead_tmp(tmp2);
7889
                store_reg(s, rd, tmp);
7890
            } else if ((op & 0xe) == 0xc) {
7891
                /* Dual multiply accumulate long.  */
7892
                if (op & 1)
7893
                    gen_swap_half(tmp2);
7894
                gen_smul_dual(tmp, tmp2);
7895
                if (op & 0x10) {
7896
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7897
                } else {
7898
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7899
                }
7900
                dead_tmp(tmp2);
7901
                /* BUGFIX */
7902
                tmp64 = tcg_temp_new_i64();
7903
                tcg_gen_ext_i32_i64(tmp64, tmp);
7904
                dead_tmp(tmp);
7905
                gen_addq(s, tmp64, rs, rd);
7906
                gen_storeq_reg(s, rs, rd, tmp64);
7907
                tcg_temp_free_i64(tmp64);
7908
            } else {
7909
                if (op & 0x20) {
7910
                    /* Unsigned 64-bit multiply  */
7911
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7912
                } else {
7913
                    if (op & 8) {
7914
                        /* smlalxy */
7915
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7916
                        dead_tmp(tmp2);
7917
                        tmp64 = tcg_temp_new_i64();
7918
                        tcg_gen_ext_i32_i64(tmp64, tmp);
7919
                        dead_tmp(tmp);
7920
                    } else {
7921
                        /* Signed 64-bit multiply  */
7922
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7923
                    }
7924
                }
7925
                if (op & 4) {
7926
                    /* umaal */
7927
                    gen_addq_lo(s, tmp64, rs);
7928
                    gen_addq_lo(s, tmp64, rd);
7929
                } else if (op & 0x40) {
7930
                    /* 64-bit accumulate.  */
7931
                    gen_addq(s, tmp64, rs, rd);
7932
                }
7933
                gen_storeq_reg(s, rs, rd, tmp64);
7934
                tcg_temp_free_i64(tmp64);
7935
            }
7936
            break;
7937
        }
7938
        break;
7939
    case 6: case 7: case 14: case 15:
7940
        /* Coprocessor.  */
7941
        if (((insn >> 24) & 3) == 3) {
7942
            /* Translate into the equivalent ARM encoding.  */
7943
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
7944
            if (disas_neon_data_insn(env, s, insn))
7945
                goto illegal_op;
7946
        } else {
7947
            if (insn & (1 << 28))
7948
                goto illegal_op;
7949
            if (disas_coproc_insn (env, s, insn))
7950
                goto illegal_op;
7951
        }
7952
        break;
7953
    case 8: case 9: case 10: case 11:
7954
        if (insn & (1 << 15)) {
7955
            /* Branches, misc control.  */
7956
            if (insn & 0x5000) {
7957
                /* Unconditional branch.  */
7958
                /* signextend(hw1[10:0]) -> offset[:12].  */
7959
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7960
                /* hw1[10:0] -> offset[11:1].  */
7961
                offset |= (insn & 0x7ff) << 1;
7962
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7963
                   offset[24:22] already have the same value because of the
7964
                   sign extension above.  */
7965
                offset ^= ((~insn) & (1 << 13)) << 10;
7966
                offset ^= ((~insn) & (1 << 11)) << 11;
7967

    
7968
                if (insn & (1 << 14)) {
7969
                    /* Branch and link.  */
7970
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
7971
                }
7972

    
7973
                offset += s->pc;
7974
                if (insn & (1 << 12)) {
7975
                    /* b/bl */
7976
                    gen_jmp(s, offset);
7977
                } else {
7978
                    /* blx */
7979
                    offset &= ~(uint32_t)2;
7980
                    gen_bx_im(s, offset);
7981
                }
7982
            } else if (((insn >> 23) & 7) == 7) {
7983
                /* Misc control */
7984
                if (insn & (1 << 13))
7985
                    goto illegal_op;
7986

    
7987
                if (insn & (1 << 26)) {
7988
                    /* Secure monitor call (v6Z) */
7989
                    goto illegal_op; /* not implemented.  */
7990
                } else {
7991
                    op = (insn >> 20) & 7;
7992
                    switch (op) {
7993
                    case 0: /* msr cpsr.  */
7994
                        if (IS_M(env)) {
7995
                            tmp = load_reg(s, rn);
7996
                            addr = tcg_const_i32(insn & 0xff);
7997
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7998
                            tcg_temp_free_i32(addr);
7999
                            dead_tmp(tmp);
8000
                            gen_lookup_tb(s);
8001
                            break;
8002
                        }
8003
                        /* fall through */
8004
                    case 1: /* msr spsr.  */
8005
                        if (IS_M(env))
8006
                            goto illegal_op;
8007
                        tmp = load_reg(s, rn);
8008
                        if (gen_set_psr(s,
8009
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8010
                              op == 1, tmp))
8011
                            goto illegal_op;
8012
                        break;
8013
                    case 2: /* cps, nop-hint.  */
8014
                        if (((insn >> 8) & 7) == 0) {
8015
                            gen_nop_hint(s, insn & 0xff);
8016
                        }
8017
                        /* Implemented as NOP in user mode.  */
8018
                        if (IS_USER(s))
8019
                            break;
8020
                        offset = 0;
8021
                        imm = 0;
8022
                        if (insn & (1 << 10)) {
8023
                            if (insn & (1 << 7))
8024
                                offset |= CPSR_A;
8025
                            if (insn & (1 << 6))
8026
                                offset |= CPSR_I;
8027
                            if (insn & (1 << 5))
8028
                                offset |= CPSR_F;
8029
                            if (insn & (1 << 9))
8030
                                imm = CPSR_A | CPSR_I | CPSR_F;
8031
                        }
8032
                        if (insn & (1 << 8)) {
8033
                            offset |= 0x1f;
8034
                            imm |= (insn & 0x1f);
8035
                        }
8036
                        if (offset) {
8037
                            gen_set_psr_im(s, offset, 0, imm);
8038
                        }
8039
                        break;
8040
                    case 3: /* Special control operations.  */
8041
                        ARCH(7);
8042
                        op = (insn >> 4) & 0xf;
8043
                        switch (op) {
8044
                        case 2: /* clrex */
8045
                            gen_clrex(s);
8046
                            break;
8047
                        case 4: /* dsb */
8048
                        case 5: /* dmb */
8049
                        case 6: /* isb */
8050
                            /* These execute as NOPs.  */
8051
                            break;
8052
                        default:
8053
                            goto illegal_op;
8054
                        }
8055
                        break;
8056
                    case 4: /* bxj */
8057
                        /* Trivial implementation equivalent to bx.  */
8058
                        tmp = load_reg(s, rn);
8059
                        gen_bx(s, tmp);
8060
                        break;
8061
                    case 5: /* Exception return.  */
8062
                        if (IS_USER(s)) {
8063
                            goto illegal_op;
8064
                        }
8065
                        if (rn != 14 || rd != 15) {
8066
                            goto illegal_op;
8067
                        }
8068
                        tmp = load_reg(s, rn);
8069
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8070
                        gen_exception_return(s, tmp);
8071
                        break;
8072
                    case 6: /* mrs cpsr.  */
8073
                        tmp = new_tmp();
8074
                        if (IS_M(env)) {
8075
                            addr = tcg_const_i32(insn & 0xff);
8076
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
8077
                            tcg_temp_free_i32(addr);
8078
                        } else {
8079
                            gen_helper_cpsr_read(tmp);
8080
                        }
8081
                        store_reg(s, rd, tmp);
8082
                        break;
8083
                    case 7: /* mrs spsr.  */
8084
                        /* Not accessible in user mode.  */
8085
                        if (IS_USER(s) || IS_M(env))
8086
                            goto illegal_op;
8087
                        tmp = load_cpu_field(spsr);
8088
                        store_reg(s, rd, tmp);
8089
                        break;
8090
                    }
8091
                }
8092
            } else {
8093
                /* Conditional branch.  */
8094
                op = (insn >> 22) & 0xf;
8095
                /* Generate a conditional jump to next instruction.  */
8096
                s->condlabel = gen_new_label();
8097
                gen_test_cc(op ^ 1, s->condlabel);
8098
                s->condjmp = 1;
8099

    
8100
                /* offset[11:1] = insn[10:0] */
8101
                offset = (insn & 0x7ff) << 1;
8102
                /* offset[17:12] = insn[21:16].  */
8103
                offset |= (insn & 0x003f0000) >> 4;
8104
                /* offset[31:20] = insn[26].  */
8105
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8106
                /* offset[18] = insn[13].  */
8107
                offset |= (insn & (1 << 13)) << 5;
8108
                /* offset[19] = insn[11].  */
8109
                offset |= (insn & (1 << 11)) << 8;
8110

    
8111
                /* jump to the offset */
8112
                gen_jmp(s, s->pc + offset);
8113
            }
8114
        } else {
8115
            /* Data processing immediate.  */
8116
            if (insn & (1 << 25)) {
8117
                if (insn & (1 << 24)) {
8118
                    if (insn & (1 << 20))
8119
                        goto illegal_op;
8120
                    /* Bitfield/Saturate.  */
8121
                    op = (insn >> 21) & 7;
8122
                    imm = insn & 0x1f;
8123
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8124
                    if (rn == 15) {
8125
                        tmp = new_tmp();
8126
                        tcg_gen_movi_i32(tmp, 0);
8127
                    } else {
8128
                        tmp = load_reg(s, rn);
8129
                    }
8130
                    switch (op) {
8131
                    case 2: /* Signed bitfield extract.  */
8132
                        imm++;
8133
                        if (shift + imm > 32)
8134
                            goto illegal_op;
8135
                        if (imm < 32)
8136
                            gen_sbfx(tmp, shift, imm);
8137
                        break;
8138
                    case 6: /* Unsigned bitfield extract.  */
8139
                        imm++;
8140
                        if (shift + imm > 32)
8141
                            goto illegal_op;
8142
                        if (imm < 32)
8143
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
8144
                        break;
8145
                    case 3: /* Bitfield insert/clear.  */
8146
                        if (imm < shift)
8147
                            goto illegal_op;
8148
                        imm = imm + 1 - shift;
8149
                        if (imm != 32) {
8150
                            tmp2 = load_reg(s, rd);
8151
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
8152
                            dead_tmp(tmp2);
8153
                        }
8154
                        break;
8155
                    case 7:
8156
                        goto illegal_op;
8157
                    default: /* Saturate.  */
8158
                        if (shift) {
8159
                            if (op & 1)
8160
                                tcg_gen_sari_i32(tmp, tmp, shift);
8161
                            else
8162
                                tcg_gen_shli_i32(tmp, tmp, shift);
8163
                        }
8164
                        tmp2 = tcg_const_i32(imm);
8165
                        if (op & 4) {
8166
                            /* Unsigned.  */
8167
                            if ((op & 1) && shift == 0)
8168
                                gen_helper_usat16(tmp, tmp, tmp2);
8169
                            else
8170
                                gen_helper_usat(tmp, tmp, tmp2);
8171
                        } else {
8172
                            /* Signed.  */
8173
                            if ((op & 1) && shift == 0)
8174
                                gen_helper_ssat16(tmp, tmp, tmp2);
8175
                            else
8176
                                gen_helper_ssat(tmp, tmp, tmp2);
8177
                        }
8178
                        tcg_temp_free_i32(tmp2);
8179
                        break;
8180
                    }
8181
                    store_reg(s, rd, tmp);
8182
                } else {
8183
                    imm = ((insn & 0x04000000) >> 15)
8184
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
8185
                    if (insn & (1 << 22)) {
8186
                        /* 16-bit immediate.  */
8187
                        imm |= (insn >> 4) & 0xf000;
8188
                        if (insn & (1 << 23)) {
8189
                            /* movt */
8190
                            tmp = load_reg(s, rd);
8191
                            tcg_gen_ext16u_i32(tmp, tmp);
8192
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
8193
                        } else {
8194
                            /* movw */
8195
                            tmp = new_tmp();
8196
                            tcg_gen_movi_i32(tmp, imm);
8197
                        }
8198
                    } else {
8199
                        /* Add/sub 12-bit immediate.  */
8200
                        if (rn == 15) {
8201
                            offset = s->pc & ~(uint32_t)3;
8202
                            if (insn & (1 << 23))
8203
                                offset -= imm;
8204
                            else
8205
                                offset += imm;
8206
                            tmp = new_tmp();
8207
                            tcg_gen_movi_i32(tmp, offset);
8208
                        } else {
8209
                            tmp = load_reg(s, rn);
8210
                            if (insn & (1 << 23))
8211
                                tcg_gen_subi_i32(tmp, tmp, imm);
8212
                            else
8213
                                tcg_gen_addi_i32(tmp, tmp, imm);
8214
                        }
8215
                    }
8216
                    store_reg(s, rd, tmp);
8217
                }
8218
            } else {
8219
                int shifter_out = 0;
8220
                /* modified 12-bit immediate.  */
8221
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8222
                imm = (insn & 0xff);
8223
                switch (shift) {
8224
                case 0: /* XY */
8225
                    /* Nothing to do.  */
8226
                    break;
8227
                case 1: /* 00XY00XY */
8228
                    imm |= imm << 16;
8229
                    break;
8230
                case 2: /* XY00XY00 */
8231
                    imm |= imm << 16;
8232
                    imm <<= 8;
8233
                    break;
8234
                case 3: /* XYXYXYXY */
8235
                    imm |= imm << 16;
8236
                    imm |= imm << 8;
8237
                    break;
8238
                default: /* Rotated constant.  */
8239
                    shift = (shift << 1) | (imm >> 7);
8240
                    imm |= 0x80;
8241
                    imm = imm << (32 - shift);
8242
                    shifter_out = 1;
8243
                    break;
8244
                }
8245
                tmp2 = new_tmp();
8246
                tcg_gen_movi_i32(tmp2, imm);
8247
                rn = (insn >> 16) & 0xf;
8248
                if (rn == 15) {
8249
                    tmp = new_tmp();
8250
                    tcg_gen_movi_i32(tmp, 0);
8251
                } else {
8252
                    tmp = load_reg(s, rn);
8253
                }
8254
                op = (insn >> 21) & 0xf;
8255
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
8256
                                       shifter_out, tmp, tmp2))
8257
                    goto illegal_op;
8258
                dead_tmp(tmp2);
8259
                rd = (insn >> 8) & 0xf;
8260
                if (rd != 15) {
8261
                    store_reg(s, rd, tmp);
8262
                } else {
8263
                    dead_tmp(tmp);
8264
                }
8265
            }
8266
        }
8267
        break;
8268
    case 12: /* Load/store single data item.  */
8269
        {
8270
        int postinc = 0;
8271
        int writeback = 0;
8272
        int user;
8273
        if ((insn & 0x01100000) == 0x01000000) {
8274
            if (disas_neon_ls_insn(env, s, insn))
8275
                goto illegal_op;
8276
            break;
8277
        }
8278
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8279
        if (rs == 15) {
8280
            if (!(insn & (1 << 20))) {
8281
                goto illegal_op;
8282
            }
8283
            if (op != 2) {
8284
                /* Byte or halfword load space with dest == r15 : memory hints.
8285
                 * Catch them early so we don't emit pointless addressing code.
8286
                 * This space is a mix of:
8287
                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
8288
                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8289
                 *     cores)
8290
                 *  unallocated hints, which must be treated as NOPs
8291
                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
8292
                 *     which is easiest for the decoding logic
8293
                 *  Some space which must UNDEF
8294
                 */
8295
                int op1 = (insn >> 23) & 3;
8296
                int op2 = (insn >> 6) & 0x3f;
8297
                if (op & 2) {
8298
                    goto illegal_op;
8299
                }
8300
                if (rn == 15) {
8301
                    /* UNPREDICTABLE or unallocated hint */
8302
                    return 0;
8303
                }
8304
                if (op1 & 1) {
8305
                    return 0; /* PLD* or unallocated hint */
8306
                }
8307
                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
8308
                    return 0; /* PLD* or unallocated hint */
8309
                }
8310
                /* UNDEF space, or an UNPREDICTABLE */
8311
                return 1;
8312
            }
8313
        }
8314
        user = IS_USER(s);
8315
        if (rn == 15) {
8316
            addr = new_tmp();
8317
            /* PC relative.  */
8318
            /* s->pc has already been incremented by 4.  */
8319
            imm = s->pc & 0xfffffffc;
8320
            if (insn & (1 << 23))
8321
                imm += insn & 0xfff;
8322
            else
8323
                imm -= insn & 0xfff;
8324
            tcg_gen_movi_i32(addr, imm);
8325
        } else {
8326
            addr = load_reg(s, rn);
8327
            if (insn & (1 << 23)) {
8328
                /* Positive offset.  */
8329
                imm = insn & 0xfff;
8330
                tcg_gen_addi_i32(addr, addr, imm);
8331
            } else {
8332
                imm = insn & 0xff;
8333
                switch ((insn >> 8) & 7) {
8334
                case 0: case 8: /* Shifted Register.  */
8335
                    shift = (insn >> 4) & 0xf;
8336
                    if (shift > 3)
8337
                        goto illegal_op;
8338
                    tmp = load_reg(s, rm);
8339
                    if (shift)
8340
                        tcg_gen_shli_i32(tmp, tmp, shift);
8341
                    tcg_gen_add_i32(addr, addr, tmp);
8342
                    dead_tmp(tmp);
8343
                    break;
8344
                case 4: /* Negative offset.  */
8345
                    tcg_gen_addi_i32(addr, addr, -imm);
8346
                    break;
8347
                case 6: /* User privilege.  */
8348
                    tcg_gen_addi_i32(addr, addr, imm);
8349
                    user = 1;
8350
                    break;
8351
                case 1: /* Post-decrement.  */
8352
                    imm = -imm;
8353
                    /* Fall through.  */
8354
                case 3: /* Post-increment.  */
8355
                    postinc = 1;
8356
                    writeback = 1;
8357
                    break;
8358
                case 5: /* Pre-decrement.  */
8359
                    imm = -imm;
8360
                    /* Fall through.  */
8361
                case 7: /* Pre-increment.  */
8362
                    tcg_gen_addi_i32(addr, addr, imm);
8363
                    writeback = 1;
8364
                    break;
8365
                default:
8366
                    goto illegal_op;
8367
                }
8368
            }
8369
        }
8370
        if (insn & (1 << 20)) {
8371
            /* Load.  */
8372
            switch (op) {
8373
            case 0: tmp = gen_ld8u(addr, user); break;
8374
            case 4: tmp = gen_ld8s(addr, user); break;
8375
            case 1: tmp = gen_ld16u(addr, user); break;
8376
            case 5: tmp = gen_ld16s(addr, user); break;
8377
            case 2: tmp = gen_ld32(addr, user); break;
8378
            default: goto illegal_op;
8379
            }
8380
            if (rs == 15) {
8381
                gen_bx(s, tmp);
8382
            } else {
8383
                store_reg(s, rs, tmp);
8384
            }
8385
        } else {
8386
            /* Store.  */
8387
            tmp = load_reg(s, rs);
8388
            switch (op) {
8389
            case 0: gen_st8(tmp, addr, user); break;
8390
            case 1: gen_st16(tmp, addr, user); break;
8391
            case 2: gen_st32(tmp, addr, user); break;
8392
            default: goto illegal_op;
8393
            }
8394
        }
8395
        if (postinc)
8396
            tcg_gen_addi_i32(addr, addr, imm);
8397
        if (writeback) {
8398
            store_reg(s, rn, addr);
8399
        } else {
8400
            dead_tmp(addr);
8401
        }
8402
        }
8403
        break;
8404
    default:
8405
        goto illegal_op;
8406
    }
8407
    return 0;
8408
illegal_op:
8409
    return 1;
8410
}
8411

    
8412
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8413
{
8414
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8415
    int32_t offset;
8416
    int i;
8417
    TCGv tmp;
8418
    TCGv tmp2;
8419
    TCGv addr;
8420

    
8421
    if (s->condexec_mask) {
8422
        cond = s->condexec_cond;
8423
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
8424
          s->condlabel = gen_new_label();
8425
          gen_test_cc(cond ^ 1, s->condlabel);
8426
          s->condjmp = 1;
8427
        }
8428
    }
8429

    
8430
    insn = lduw_code(s->pc);
8431
    s->pc += 2;
8432

    
8433
    switch (insn >> 12) {
8434
    case 0: case 1:
8435

    
8436
        rd = insn & 7;
8437
        op = (insn >> 11) & 3;
8438
        if (op == 3) {
8439
            /* add/subtract */
8440
            rn = (insn >> 3) & 7;
8441
            tmp = load_reg(s, rn);
8442
            if (insn & (1 << 10)) {
8443
                /* immediate */
8444
                tmp2 = new_tmp();
8445
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8446
            } else {
8447
                /* reg */
8448
                rm = (insn >> 6) & 7;
8449
                tmp2 = load_reg(s, rm);
8450
            }
8451
            if (insn & (1 << 9)) {
8452
                if (s->condexec_mask)
8453
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8454
                else
8455
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8456
            } else {
8457
                if (s->condexec_mask)
8458
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8459
                else
8460
                    gen_helper_add_cc(tmp, tmp, tmp2);
8461
            }
8462
            dead_tmp(tmp2);
8463
            store_reg(s, rd, tmp);
8464
        } else {
8465
            /* shift immediate */
8466
            rm = (insn >> 3) & 7;
8467
            shift = (insn >> 6) & 0x1f;
8468
            tmp = load_reg(s, rm);
8469
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8470
            if (!s->condexec_mask)
8471
                gen_logic_CC(tmp);
8472
            store_reg(s, rd, tmp);
8473
        }
8474
        break;
8475
    case 2: case 3:
8476
        /* arithmetic large immediate */
8477
        op = (insn >> 11) & 3;
8478
        rd = (insn >> 8) & 0x7;
8479
        if (op == 0) { /* mov */
8480
            tmp = new_tmp();
8481
            tcg_gen_movi_i32(tmp, insn & 0xff);
8482
            if (!s->condexec_mask)
8483
                gen_logic_CC(tmp);
8484
            store_reg(s, rd, tmp);
8485
        } else {
8486
            tmp = load_reg(s, rd);
8487
            tmp2 = new_tmp();
8488
            tcg_gen_movi_i32(tmp2, insn & 0xff);
8489
            switch (op) {
8490
            case 1: /* cmp */
8491
                gen_helper_sub_cc(tmp, tmp, tmp2);
8492
                dead_tmp(tmp);
8493
                dead_tmp(tmp2);
8494
                break;
8495
            case 2: /* add */
8496
                if (s->condexec_mask)
8497
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8498
                else
8499
                    gen_helper_add_cc(tmp, tmp, tmp2);
8500
                dead_tmp(tmp2);
8501
                store_reg(s, rd, tmp);
8502
                break;
8503
            case 3: /* sub */
8504
                if (s->condexec_mask)
8505
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8506
                else
8507
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8508
                dead_tmp(tmp2);
8509
                store_reg(s, rd, tmp);
8510
                break;
8511
            }
8512
        }
8513
        break;
8514
    case 4:
8515
        if (insn & (1 << 11)) {
8516
            rd = (insn >> 8) & 7;
8517
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8518
            val = s->pc + 2 + ((insn & 0xff) * 4);
8519
            val &= ~(uint32_t)2;
8520
            addr = new_tmp();
8521
            tcg_gen_movi_i32(addr, val);
8522
            tmp = gen_ld32(addr, IS_USER(s));
8523
            dead_tmp(addr);
8524
            store_reg(s, rd, tmp);
8525
            break;
8526
        }
8527
        if (insn & (1 << 10)) {
8528
            /* data processing extended or blx */
8529
            rd = (insn & 7) | ((insn >> 4) & 8);
8530
            rm = (insn >> 3) & 0xf;
8531
            op = (insn >> 8) & 3;
8532
            switch (op) {
8533
            case 0: /* add */
8534
                tmp = load_reg(s, rd);
8535
                tmp2 = load_reg(s, rm);
8536
                tcg_gen_add_i32(tmp, tmp, tmp2);
8537
                dead_tmp(tmp2);
8538
                store_reg(s, rd, tmp);
8539
                break;
8540
            case 1: /* cmp */
8541
                tmp = load_reg(s, rd);
8542
                tmp2 = load_reg(s, rm);
8543
                gen_helper_sub_cc(tmp, tmp, tmp2);
8544
                dead_tmp(tmp2);
8545
                dead_tmp(tmp);
8546
                break;
8547
            case 2: /* mov/cpy */
8548
                tmp = load_reg(s, rm);
8549
                store_reg(s, rd, tmp);
8550
                break;
8551
            case 3:/* branch [and link] exchange thumb register */
8552
                tmp = load_reg(s, rm);
8553
                if (insn & (1 << 7)) {
8554
                    val = (uint32_t)s->pc | 1;
8555
                    tmp2 = new_tmp();
8556
                    tcg_gen_movi_i32(tmp2, val);
8557
                    store_reg(s, 14, tmp2);
8558
                }
8559
                gen_bx(s, tmp);
8560
                break;
8561
            }
8562
            break;
8563
        }
8564

    
8565
        /* data processing register */
8566
        rd = insn & 7;
8567
        rm = (insn >> 3) & 7;
8568
        op = (insn >> 6) & 0xf;
8569
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8570
            /* the shift/rotate ops want the operands backwards */
8571
            val = rm;
8572
            rm = rd;
8573
            rd = val;
8574
            val = 1;
8575
        } else {
8576
            val = 0;
8577
        }
8578

    
8579
        if (op == 9) { /* neg */
8580
            tmp = new_tmp();
8581
            tcg_gen_movi_i32(tmp, 0);
8582
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
8583
            tmp = load_reg(s, rd);
8584
        } else {
8585
            TCGV_UNUSED(tmp);
8586
        }
8587

    
8588
        tmp2 = load_reg(s, rm);
8589
        switch (op) {
8590
        case 0x0: /* and */
8591
            tcg_gen_and_i32(tmp, tmp, tmp2);
8592
            if (!s->condexec_mask)
8593
                gen_logic_CC(tmp);
8594
            break;
8595
        case 0x1: /* eor */
8596
            tcg_gen_xor_i32(tmp, tmp, tmp2);
8597
            if (!s->condexec_mask)
8598
                gen_logic_CC(tmp);
8599
            break;
8600
        case 0x2: /* lsl */
8601
            if (s->condexec_mask) {
8602
                gen_helper_shl(tmp2, tmp2, tmp);
8603
            } else {
8604
                gen_helper_shl_cc(tmp2, tmp2, tmp);
8605
                gen_logic_CC(tmp2);
8606
            }
8607
            break;
8608
        case 0x3: /* lsr */
8609
            if (s->condexec_mask) {
8610
                gen_helper_shr(tmp2, tmp2, tmp);
8611
            } else {
8612
                gen_helper_shr_cc(tmp2, tmp2, tmp);
8613
                gen_logic_CC(tmp2);
8614
            }
8615
            break;
8616
        case 0x4: /* asr */
8617
            if (s->condexec_mask) {
8618
                gen_helper_sar(tmp2, tmp2, tmp);
8619
            } else {
8620
                gen_helper_sar_cc(tmp2, tmp2, tmp);
8621
                gen_logic_CC(tmp2);
8622
            }
8623
            break;
8624
        case 0x5: /* adc */
8625
            if (s->condexec_mask)
8626
                gen_adc(tmp, tmp2);
8627
            else
8628
                gen_helper_adc_cc(tmp, tmp, tmp2);
8629
            break;
8630
        case 0x6: /* sbc */
8631
            if (s->condexec_mask)
8632
                gen_sub_carry(tmp, tmp, tmp2);
8633
            else
8634
                gen_helper_sbc_cc(tmp, tmp, tmp2);
8635
            break;
8636
        case 0x7: /* ror */
8637
            if (s->condexec_mask) {
8638
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
8639
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
8640
            } else {
8641
                gen_helper_ror_cc(tmp2, tmp2, tmp);
8642
                gen_logic_CC(tmp2);
8643
            }
8644
            break;
8645
        case 0x8: /* tst */
8646
            tcg_gen_and_i32(tmp, tmp, tmp2);
8647
            gen_logic_CC(tmp);
8648
            rd = 16;
8649
            break;
8650
        case 0x9: /* neg */
8651
            if (s->condexec_mask)
8652
                tcg_gen_neg_i32(tmp, tmp2);
8653
            else
8654
                gen_helper_sub_cc(tmp, tmp, tmp2);
8655
            break;
8656
        case 0xa: /* cmp */
8657
            gen_helper_sub_cc(tmp, tmp, tmp2);
8658
            rd = 16;
8659
            break;
8660
        case 0xb: /* cmn */
8661
            gen_helper_add_cc(tmp, tmp, tmp2);
8662
            rd = 16;
8663
            break;
8664
        case 0xc: /* orr */
8665
            tcg_gen_or_i32(tmp, tmp, tmp2);
8666
            if (!s->condexec_mask)
8667
                gen_logic_CC(tmp);
8668
            break;
8669
        case 0xd: /* mul */
8670
            tcg_gen_mul_i32(tmp, tmp, tmp2);
8671
            if (!s->condexec_mask)
8672
                gen_logic_CC(tmp);
8673
            break;
8674
        case 0xe: /* bic */
8675
            tcg_gen_andc_i32(tmp, tmp, tmp2);
8676
            if (!s->condexec_mask)
8677
                gen_logic_CC(tmp);
8678
            break;
8679
        case 0xf: /* mvn */
8680
            tcg_gen_not_i32(tmp2, tmp2);
8681
            if (!s->condexec_mask)
8682
                gen_logic_CC(tmp2);
8683
            val = 1;
8684
            rm = rd;
8685
            break;
8686
        }
8687
        if (rd != 16) {
8688
            if (val) {
8689
                store_reg(s, rm, tmp2);
8690
                if (op != 0xf)
8691
                    dead_tmp(tmp);
8692
            } else {
8693
                store_reg(s, rd, tmp);
8694
                dead_tmp(tmp2);
8695
            }
8696
        } else {
8697
            dead_tmp(tmp);
8698
            dead_tmp(tmp2);
8699
        }
8700
        break;
8701

    
8702
    case 5:
8703
        /* load/store register offset.  */
8704
        rd = insn & 7;
8705
        rn = (insn >> 3) & 7;
8706
        rm = (insn >> 6) & 7;
8707
        op = (insn >> 9) & 7;
8708
        addr = load_reg(s, rn);
8709
        tmp = load_reg(s, rm);
8710
        tcg_gen_add_i32(addr, addr, tmp);
8711
        dead_tmp(tmp);
8712

    
8713
        if (op < 3) /* store */
8714
            tmp = load_reg(s, rd);
8715

    
8716
        switch (op) {
8717
        case 0: /* str */
8718
            gen_st32(tmp, addr, IS_USER(s));
8719
            break;
8720
        case 1: /* strh */
8721
            gen_st16(tmp, addr, IS_USER(s));
8722
            break;
8723
        case 2: /* strb */
8724
            gen_st8(tmp, addr, IS_USER(s));
8725
            break;
8726
        case 3: /* ldrsb */
8727
            tmp = gen_ld8s(addr, IS_USER(s));
8728
            break;
8729
        case 4: /* ldr */
8730
            tmp = gen_ld32(addr, IS_USER(s));
8731
            break;
8732
        case 5: /* ldrh */
8733
            tmp = gen_ld16u(addr, IS_USER(s));
8734
            break;
8735
        case 6: /* ldrb */
8736
            tmp = gen_ld8u(addr, IS_USER(s));
8737
            break;
8738
        case 7: /* ldrsh */
8739
            tmp = gen_ld16s(addr, IS_USER(s));
8740
            break;
8741
        }
8742
        if (op >= 3) /* load */
8743
            store_reg(s, rd, tmp);
8744
        dead_tmp(addr);
8745
        break;
8746

    
8747
    case 6:
8748
        /* load/store word immediate offset */
8749
        rd = insn & 7;
8750
        rn = (insn >> 3) & 7;
8751
        addr = load_reg(s, rn);
8752
        val = (insn >> 4) & 0x7c;
8753
        tcg_gen_addi_i32(addr, addr, val);
8754

    
8755
        if (insn & (1 << 11)) {
8756
            /* load */
8757
            tmp = gen_ld32(addr, IS_USER(s));
8758
            store_reg(s, rd, tmp);
8759
        } else {
8760
            /* store */
8761
            tmp = load_reg(s, rd);
8762
            gen_st32(tmp, addr, IS_USER(s));
8763
        }
8764
        dead_tmp(addr);
8765
        break;
8766

    
8767
    case 7:
8768
        /* load/store byte immediate offset */
8769
        rd = insn & 7;
8770
        rn = (insn >> 3) & 7;
8771
        addr = load_reg(s, rn);
8772
        val = (insn >> 6) & 0x1f;
8773
        tcg_gen_addi_i32(addr, addr, val);
8774

    
8775
        if (insn & (1 << 11)) {
8776
            /* load */
8777
            tmp = gen_ld8u(addr, IS_USER(s));
8778
            store_reg(s, rd, tmp);
8779
        } else {
8780
            /* store */
8781
            tmp = load_reg(s, rd);
8782
            gen_st8(tmp, addr, IS_USER(s));
8783
        }
8784
        dead_tmp(addr);
8785
        break;
8786

    
8787
    case 8:
8788
        /* load/store halfword immediate offset */
8789
        rd = insn & 7;
8790
        rn = (insn >> 3) & 7;
8791
        addr = load_reg(s, rn);
8792
        val = (insn >> 5) & 0x3e;
8793
        tcg_gen_addi_i32(addr, addr, val);
8794

    
8795
        if (insn & (1 << 11)) {
8796
            /* load */
8797
            tmp = gen_ld16u(addr, IS_USER(s));
8798
            store_reg(s, rd, tmp);
8799
        } else {
8800
            /* store */
8801
            tmp = load_reg(s, rd);
8802
            gen_st16(tmp, addr, IS_USER(s));
8803
        }
8804
        dead_tmp(addr);
8805
        break;
8806

    
8807
    case 9:
8808
        /* load/store from stack */
8809
        rd = (insn >> 8) & 7;
8810
        addr = load_reg(s, 13);
8811
        val = (insn & 0xff) * 4;
8812
        tcg_gen_addi_i32(addr, addr, val);
8813

    
8814
        if (insn & (1 << 11)) {
8815
            /* load */
8816
            tmp = gen_ld32(addr, IS_USER(s));
8817
            store_reg(s, rd, tmp);
8818
        } else {
8819
            /* store */
8820
            tmp = load_reg(s, rd);
8821
            gen_st32(tmp, addr, IS_USER(s));
8822
        }
8823
        dead_tmp(addr);
8824
        break;
8825

    
8826
    case 10:
8827
        /* add to high reg */
8828
        rd = (insn >> 8) & 7;
8829
        if (insn & (1 << 11)) {
8830
            /* SP */
8831
            tmp = load_reg(s, 13);
8832
        } else {
8833
            /* PC. bit 1 is ignored.  */
8834
            tmp = new_tmp();
8835
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8836
        }
8837
        val = (insn & 0xff) * 4;
8838
        tcg_gen_addi_i32(tmp, tmp, val);
8839
        store_reg(s, rd, tmp);
8840
        break;
8841

    
8842
    case 11:
8843
        /* misc */
8844
        op = (insn >> 8) & 0xf;
8845
        switch (op) {
8846
        case 0:
8847
            /* adjust stack pointer */
8848
            tmp = load_reg(s, 13);
8849
            val = (insn & 0x7f) * 4;
8850
            if (insn & (1 << 7))
8851
                val = -(int32_t)val;
8852
            tcg_gen_addi_i32(tmp, tmp, val);
8853
            store_reg(s, 13, tmp);
8854
            break;
8855

    
8856
        case 2: /* sign/zero extend.  */
8857
            ARCH(6);
8858
            rd = insn & 7;
8859
            rm = (insn >> 3) & 7;
8860
            tmp = load_reg(s, rm);
8861
            switch ((insn >> 6) & 3) {
8862
            case 0: gen_sxth(tmp); break;
8863
            case 1: gen_sxtb(tmp); break;
8864
            case 2: gen_uxth(tmp); break;
8865
            case 3: gen_uxtb(tmp); break;
8866
            }
8867
            store_reg(s, rd, tmp);
8868
            break;
8869
        case 4: case 5: case 0xc: case 0xd:
8870
            /* push/pop */
8871
            addr = load_reg(s, 13);
8872
            if (insn & (1 << 8))
8873
                offset = 4;
8874
            else
8875
                offset = 0;
8876
            for (i = 0; i < 8; i++) {
8877
                if (insn & (1 << i))
8878
                    offset += 4;
8879
            }
8880
            if ((insn & (1 << 11)) == 0) {
8881
                tcg_gen_addi_i32(addr, addr, -offset);
8882
            }
8883
            for (i = 0; i < 8; i++) {
8884
                if (insn & (1 << i)) {
8885
                    if (insn & (1 << 11)) {
8886
                        /* pop */
8887
                        tmp = gen_ld32(addr, IS_USER(s));
8888
                        store_reg(s, i, tmp);
8889
                    } else {
8890
                        /* push */
8891
                        tmp = load_reg(s, i);
8892
                        gen_st32(tmp, addr, IS_USER(s));
8893
                    }
8894
                    /* advance to the next address.  */
8895
                    tcg_gen_addi_i32(addr, addr, 4);
8896
                }
8897
            }
8898
            TCGV_UNUSED(tmp);
8899
            if (insn & (1 << 8)) {
8900
                if (insn & (1 << 11)) {
8901
                    /* pop pc */
8902
                    tmp = gen_ld32(addr, IS_USER(s));
8903
                    /* don't set the pc until the rest of the instruction
8904
                       has completed */
8905
                } else {
8906
                    /* push lr */
8907
                    tmp = load_reg(s, 14);
8908
                    gen_st32(tmp, addr, IS_USER(s));
8909
                }
8910
                tcg_gen_addi_i32(addr, addr, 4);
8911
            }
8912
            if ((insn & (1 << 11)) == 0) {
8913
                tcg_gen_addi_i32(addr, addr, -offset);
8914
            }
8915
            /* write back the new stack pointer */
8916
            store_reg(s, 13, addr);
8917
            /* set the new PC value */
8918
            if ((insn & 0x0900) == 0x0900)
8919
                gen_bx(s, tmp);
8920
            break;
8921

    
8922
        case 1: case 3: case 9: case 11: /* czb */
8923
            rm = insn & 7;
8924
            tmp = load_reg(s, rm);
8925
            s->condlabel = gen_new_label();
8926
            s->condjmp = 1;
8927
            if (insn & (1 << 11))
8928
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8929
            else
8930
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8931
            dead_tmp(tmp);
8932
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8933
            val = (uint32_t)s->pc + 2;
8934
            val += offset;
8935
            gen_jmp(s, val);
8936
            break;
8937

    
8938
        case 15: /* IT, nop-hint.  */
8939
            if ((insn & 0xf) == 0) {
8940
                gen_nop_hint(s, (insn >> 4) & 0xf);
8941
                break;
8942
            }
8943
            /* If Then.  */
8944
            s->condexec_cond = (insn >> 4) & 0xe;
8945
            s->condexec_mask = insn & 0x1f;
8946
            /* No actual code generated for this insn, just setup state.  */
8947
            break;
8948

    
8949
        case 0xe: /* bkpt */
8950
            gen_exception_insn(s, 2, EXCP_BKPT);
8951
            break;
8952

    
8953
        case 0xa: /* rev */
8954
            ARCH(6);
8955
            rn = (insn >> 3) & 0x7;
8956
            rd = insn & 0x7;
8957
            tmp = load_reg(s, rn);
8958
            switch ((insn >> 6) & 3) {
8959
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8960
            case 1: gen_rev16(tmp); break;
8961
            case 3: gen_revsh(tmp); break;
8962
            default: goto illegal_op;
8963
            }
8964
            store_reg(s, rd, tmp);
8965
            break;
8966

    
8967
        case 6: /* cps */
8968
            ARCH(6);
8969
            if (IS_USER(s))
8970
                break;
8971
            if (IS_M(env)) {
8972
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8973
                /* PRIMASK */
8974
                if (insn & 1) {
8975
                    addr = tcg_const_i32(16);
8976
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8977
                    tcg_temp_free_i32(addr);
8978
                }
8979
                /* FAULTMASK */
8980
                if (insn & 2) {
8981
                    addr = tcg_const_i32(17);
8982
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8983
                    tcg_temp_free_i32(addr);
8984
                }
8985
                tcg_temp_free_i32(tmp);
8986
                gen_lookup_tb(s);
8987
            } else {
8988
                if (insn & (1 << 4))
8989
                    shift = CPSR_A | CPSR_I | CPSR_F;
8990
                else
8991
                    shift = 0;
8992
                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
8993
            }
8994
            break;
8995

    
8996
        default:
8997
            goto undef;
8998
        }
8999
        break;
9000

    
9001
    case 12:
9002
        /* load/store multiple */
9003
        rn = (insn >> 8) & 0x7;
9004
        addr = load_reg(s, rn);
9005
        for (i = 0; i < 8; i++) {
9006
            if (insn & (1 << i)) {
9007
                if (insn & (1 << 11)) {
9008
                    /* load */
9009
                    tmp = gen_ld32(addr, IS_USER(s));
9010
                    store_reg(s, i, tmp);
9011
                } else {
9012
                    /* store */
9013
                    tmp = load_reg(s, i);
9014
                    gen_st32(tmp, addr, IS_USER(s));
9015
                }
9016
                /* advance to the next address */
9017
                tcg_gen_addi_i32(addr, addr, 4);
9018
            }
9019
        }
9020
        /* Base register writeback.  */
9021
        if ((insn & (1 << rn)) == 0) {
9022
            store_reg(s, rn, addr);
9023
        } else {
9024
            dead_tmp(addr);
9025
        }
9026
        break;
9027

    
9028
    case 13:
9029
        /* conditional branch or swi */
9030
        cond = (insn >> 8) & 0xf;
9031
        if (cond == 0xe)
9032
            goto undef;
9033

    
9034
        if (cond == 0xf) {
9035
            /* swi */
9036
            gen_set_pc_im(s->pc);
9037
            s->is_jmp = DISAS_SWI;
9038
            break;
9039
        }
9040
        /* generate a conditional jump to next instruction */
9041
        s->condlabel = gen_new_label();
9042
        gen_test_cc(cond ^ 1, s->condlabel);
9043
        s->condjmp = 1;
9044

    
9045
        /* jump to the offset */
9046
        val = (uint32_t)s->pc + 2;
9047
        offset = ((int32_t)insn << 24) >> 24;
9048
        val += offset << 1;
9049
        gen_jmp(s, val);
9050
        break;
9051

    
9052
    case 14:
9053
        if (insn & (1 << 11)) {
9054
            if (disas_thumb2_insn(env, s, insn))
9055
              goto undef32;
9056
            break;
9057
        }
9058
        /* unconditional branch */
9059
        val = (uint32_t)s->pc;
9060
        offset = ((int32_t)insn << 21) >> 21;
9061
        val += (offset << 1) + 2;
9062
        gen_jmp(s, val);
9063
        break;
9064

    
9065
    case 15:
9066
        if (disas_thumb2_insn(env, s, insn))
9067
            goto undef32;
9068
        break;
9069
    }
9070
    return;
9071
undef32:
9072
    gen_exception_insn(s, 4, EXCP_UDEF);
9073
    return;
9074
illegal_op:
9075
undef:
9076
    gen_exception_insn(s, 2, EXCP_UDEF);
9077
}
9078

    
9079
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9080
   basic block 'tb'. If search_pc is TRUE, also generate PC
9081
   information for each intermediate instruction. */
9082
static inline void gen_intermediate_code_internal(CPUState *env,
9083
                                                  TranslationBlock *tb,
9084
                                                  int search_pc)
9085
{
9086
    DisasContext dc1, *dc = &dc1;
9087
    CPUBreakpoint *bp;
9088
    uint16_t *gen_opc_end;
9089
    int j, lj;
9090
    target_ulong pc_start;
9091
    uint32_t next_page_start;
9092
    int num_insns;
9093
    int max_insns;
9094

    
9095
    /* generate intermediate code */
9096
    num_temps = 0;
9097

    
9098
    pc_start = tb->pc;
9099

    
9100
    dc->tb = tb;
9101

    
9102
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9103

    
9104
    dc->is_jmp = DISAS_NEXT;
9105
    dc->pc = pc_start;
9106
    dc->singlestep_enabled = env->singlestep_enabled;
9107
    dc->condjmp = 0;
9108
    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9109
    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9110
    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9111
#if !defined(CONFIG_USER_ONLY)
9112
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9113
#endif
9114
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9115
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9116
    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9117
    cpu_F0s = tcg_temp_new_i32();
9118
    cpu_F1s = tcg_temp_new_i32();
9119
    cpu_F0d = tcg_temp_new_i64();
9120
    cpu_F1d = tcg_temp_new_i64();
9121
    cpu_V0 = cpu_F0d;
9122
    cpu_V1 = cpu_F1d;
9123
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
9124
    cpu_M0 = tcg_temp_new_i64();
9125
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9126
    lj = -1;
9127
    num_insns = 0;
9128
    max_insns = tb->cflags & CF_COUNT_MASK;
9129
    if (max_insns == 0)
9130
        max_insns = CF_COUNT_MASK;
9131

    
9132
    gen_icount_start();
9133

    
9134
    /* A note on handling of the condexec (IT) bits:
9135
     *
9136
     * We want to avoid the overhead of having to write the updated condexec
9137
     * bits back to the CPUState for every instruction in an IT block. So:
9138
     * (1) if the condexec bits are not already zero then we write
9139
     * zero back into the CPUState now. This avoids complications trying
9140
     * to do it at the end of the block. (For example if we don't do this
9141
     * it's hard to identify whether we can safely skip writing condexec
9142
     * at the end of the TB, which we definitely want to do for the case
9143
     * where a TB doesn't do anything with the IT state at all.)
9144
     * (2) if we are going to leave the TB then we call gen_set_condexec()
9145
     * which will write the correct value into CPUState if zero is wrong.
9146
     * This is done both for leaving the TB at the end, and for leaving
9147
     * it because of an exception we know will happen, which is done in
9148
     * gen_exception_insn(). The latter is necessary because we need to
9149
     * leave the TB with the PC/IT state just prior to execution of the
9150
     * instruction which caused the exception.
9151
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9152
     * then the CPUState will be wrong and we need to reset it.
9153
     * This is handled in the same way as restoration of the
9154
     * PC in these situations: we will be called again with search_pc=1
9155
     * and generate a mapping of the condexec bits for each PC in
9156
     * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
9157
     * the condexec bits.
9158
     *
9159
     * Note that there are no instructions which can read the condexec
9160
     * bits, and none which can write non-static values to them, so
9161
     * we don't need to care about whether CPUState is correct in the
9162
     * middle of a TB.
9163
     */
9164

    
9165
    /* Reset the conditional execution bits immediately. This avoids
9166
       complications trying to do it at the end of the block.  */
9167
    if (dc->condexec_mask || dc->condexec_cond)
9168
      {
9169
        TCGv tmp = new_tmp();
9170
        tcg_gen_movi_i32(tmp, 0);
9171
        store_cpu_field(tmp, condexec_bits);
9172
      }
9173
    do {
9174
#ifdef CONFIG_USER_ONLY
9175
        /* Intercept jump to the magic kernel page.  */
9176
        if (dc->pc >= 0xffff0000) {
9177
            /* We always get here via a jump, so know we are not in a
9178
               conditional execution block.  */
9179
            gen_exception(EXCP_KERNEL_TRAP);
9180
            dc->is_jmp = DISAS_UPDATE;
9181
            break;
9182
        }
9183
#else
9184
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9185
            /* We always get here via a jump, so know we are not in a
9186
               conditional execution block.  */
9187
            gen_exception(EXCP_EXCEPTION_EXIT);
9188
            dc->is_jmp = DISAS_UPDATE;
9189
            break;
9190
        }
9191
#endif
9192

    
9193
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9194
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9195
                if (bp->pc == dc->pc) {
9196
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
9197
                    /* Advance PC so that clearing the breakpoint will
9198
                       invalidate this TB.  */
9199
                    dc->pc += 2;
9200
                    goto done_generating;
9201
                    break;
9202
                }
9203
            }
9204
        }
9205
        if (search_pc) {
9206
            j = gen_opc_ptr - gen_opc_buf;
9207
            if (lj < j) {
9208
                lj++;
9209
                while (lj < j)
9210
                    gen_opc_instr_start[lj++] = 0;
9211
            }
9212
            gen_opc_pc[lj] = dc->pc;
9213
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9214
            gen_opc_instr_start[lj] = 1;
9215
            gen_opc_icount[lj] = num_insns;
9216
        }
9217

    
9218
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9219
            gen_io_start();
9220

    
9221
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
9222
            tcg_gen_debug_insn_start(dc->pc);
9223
        }
9224

    
9225
        if (dc->thumb) {
9226
            disas_thumb_insn(env, dc);
9227
            if (dc->condexec_mask) {
9228
                dc->condexec_cond = (dc->condexec_cond & 0xe)
9229
                                   | ((dc->condexec_mask >> 4) & 1);
9230
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9231
                if (dc->condexec_mask == 0) {
9232
                    dc->condexec_cond = 0;
9233
                }
9234
            }
9235
        } else {
9236
            disas_arm_insn(env, dc);
9237
        }
9238
        if (num_temps) {
9239
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
9240
            num_temps = 0;
9241
        }
9242

    
9243
        if (dc->condjmp && !dc->is_jmp) {
9244
            gen_set_label(dc->condlabel);
9245
            dc->condjmp = 0;
9246
        }
9247
        /* Translation stops when a conditional branch is encountered.
9248
         * Otherwise the subsequent code could get translated several times.
9249
         * Also stop translation when a page boundary is reached.  This
9250
         * ensures prefetch aborts occur at the right place.  */
9251
        num_insns ++;
9252
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9253
             !env->singlestep_enabled &&
9254
             !singlestep &&
9255
             dc->pc < next_page_start &&
9256
             num_insns < max_insns);
9257

    
9258
    if (tb->cflags & CF_LAST_IO) {
9259
        if (dc->condjmp) {
9260
            /* FIXME:  This can theoretically happen with self-modifying
9261
               code.  */
9262
            cpu_abort(env, "IO on conditional branch instruction");
9263
        }
9264
        gen_io_end();
9265
    }
9266

    
9267
    /* At this stage dc->condjmp will only be set when the skipped
9268
       instruction was a conditional branch or trap, and the PC has
9269
       already been written.  */
9270
    if (unlikely(env->singlestep_enabled)) {
9271
        /* Make sure the pc is updated, and raise a debug exception.  */
9272
        if (dc->condjmp) {
9273
            gen_set_condexec(dc);
9274
            if (dc->is_jmp == DISAS_SWI) {
9275
                gen_exception(EXCP_SWI);
9276
            } else {
9277
                gen_exception(EXCP_DEBUG);
9278
            }
9279
            gen_set_label(dc->condlabel);
9280
        }
9281
        if (dc->condjmp || !dc->is_jmp) {
9282
            gen_set_pc_im(dc->pc);
9283
            dc->condjmp = 0;
9284
        }
9285
        gen_set_condexec(dc);
9286
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9287
            gen_exception(EXCP_SWI);
9288
        } else {
9289
            /* FIXME: Single stepping a WFI insn will not halt
9290
               the CPU.  */
9291
            gen_exception(EXCP_DEBUG);
9292
        }
9293
    } else {
9294
        /* While branches must always occur at the end of an IT block,
9295
           there are a few other things that can cause us to terminate
9296
           the TB in the middel of an IT block:
9297
            - Exception generating instructions (bkpt, swi, undefined).
9298
            - Page boundaries.
9299
            - Hardware watchpoints.
9300
           Hardware breakpoints have already been handled and skip this code.
9301
         */
9302
        gen_set_condexec(dc);
9303
        switch(dc->is_jmp) {
9304
        case DISAS_NEXT:
9305
            gen_goto_tb(dc, 1, dc->pc);
9306
            break;
9307
        default:
9308
        case DISAS_JUMP:
9309
        case DISAS_UPDATE:
9310
            /* indicate that the hash table must be used to find the next TB */
9311
            tcg_gen_exit_tb(0);
9312
            break;
9313
        case DISAS_TB_JUMP:
9314
            /* nothing more to generate */
9315
            break;
9316
        case DISAS_WFI:
9317
            gen_helper_wfi();
9318
            break;
9319
        case DISAS_SWI:
9320
            gen_exception(EXCP_SWI);
9321
            break;
9322
        }
9323
        if (dc->condjmp) {
9324
            gen_set_label(dc->condlabel);
9325
            gen_set_condexec(dc);
9326
            gen_goto_tb(dc, 1, dc->pc);
9327
            dc->condjmp = 0;
9328
        }
9329
    }
9330

    
9331
done_generating:
9332
    gen_icount_end(tb, num_insns);
9333
    *gen_opc_ptr = INDEX_op_end;
9334

    
9335
#ifdef DEBUG_DISAS
9336
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9337
        qemu_log("----------------\n");
9338
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9339
        log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);
9340
        qemu_log("\n");
9341
    }
9342
#endif
9343
    if (search_pc) {
9344
        j = gen_opc_ptr - gen_opc_buf;
9345
        lj++;
9346
        while (lj <= j)
9347
            gen_opc_instr_start[lj++] = 0;
9348
    } else {
9349
        tb->size = dc->pc - pc_start;
9350
        tb->icount = num_insns;
9351
    }
9352
}
9353

    
9354
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9355
{
9356
    gen_intermediate_code_internal(env, tb, 0);
9357
}
9358

    
9359
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9360
{
9361
    gen_intermediate_code_internal(env, tb, 1);
9362
}
9363

    
9364
static const char *cpu_mode_names[16] = {
9365
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9366
  "???", "???", "???", "und", "???", "???", "???", "sys"
9367
};
9368

    
9369
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
9370
                    int flags)
9371
{
9372
    int i;
9373
#if 0
9374
    union {
9375
        uint32_t i;
9376
        float s;
9377
    } s0, s1;
9378
    CPU_DoubleU d;
9379
    /* ??? This assumes float64 and double have the same layout.
9380
       Oh well, it's only debug dumps.  */
9381
    union {
9382
        float64 f64;
9383
        double d;
9384
    } d0;
9385
#endif
9386
    uint32_t psr;
9387

    
9388
    for(i=0;i<16;i++) {
9389
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9390
        if ((i % 4) == 3)
9391
            cpu_fprintf(f, "\n");
9392
        else
9393
            cpu_fprintf(f, " ");
9394
    }
9395
    psr = cpsr_read(env);
9396
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9397
                psr,
9398
                psr & (1 << 31) ? 'N' : '-',
9399
                psr & (1 << 30) ? 'Z' : '-',
9400
                psr & (1 << 29) ? 'C' : '-',
9401
                psr & (1 << 28) ? 'V' : '-',
9402
                psr & CPSR_T ? 'T' : 'A',
9403
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9404

    
9405
#if 0
9406
    for (i = 0; i < 16; i++) {
9407
        d.d = env->vfp.regs[i];
9408
        s0.i = d.l.lower;
9409
        s1.i = d.l.upper;
9410
        d0.f64 = d.d;
9411
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9412
                    i * 2, (int)s0.i, s0.s,
9413
                    i * 2 + 1, (int)s1.i, s1.s,
9414
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9415
                    d0.d);
9416
    }
9417
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9418
#endif
9419
}
9420

    
9421
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9422
                unsigned long searched_pc, int pc_pos, void *puc)
9423
{
9424
    env->regs[15] = gen_opc_pc[pc_pos];
9425
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
9426
}