Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 2bee5105

History | View | Annotate | Download (344.1 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 "disas.h"
29
#include "tcg-op.h"
30
#include "qemu-log.h"
31

    
32
#include "helper.h"
33
#define GEN_HELPER 1
34
#include "helper.h"
35

    
36
#define ENABLE_ARCH_4T    arm_feature(env, ARM_FEATURE_V4T)
37
#define ENABLE_ARCH_5     arm_feature(env, ARM_FEATURE_V5)
38
/* currently all emulated v5 cores are also v5TE, so don't bother */
39
#define ENABLE_ARCH_5TE   arm_feature(env, ARM_FEATURE_V5)
40
#define ENABLE_ARCH_5J    0
41
#define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
42
#define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
43
#define ENABLE_ARCH_6T2   arm_feature(env, ARM_FEATURE_THUMB2)
44
#define ENABLE_ARCH_7     arm_feature(env, ARM_FEATURE_V7)
45

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

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

    
71
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
72

    
73
#if defined(CONFIG_USER_ONLY)
74
#define IS_USER(s) 1
75
#else
76
#define IS_USER(s) (s->user)
77
#endif
78

    
79
/* These instructions trap after executing, so defer them until after the
80
   conditional executions state has been updated.  */
81
#define DISAS_WFI 4
82
#define DISAS_SWI 5
83

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

    
96
/* FIXME:  These should be removed.  */
97
static TCGv cpu_F0s, cpu_F1s;
98
static TCGv_i64 cpu_F0d, cpu_F1d;
99

    
100
#include "gen-icount.h"
101

    
102
static const char *regnames[] =
103
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
104
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
105

    
106
/* initialize TCG globals.  */
107
void arm_translate_init(void)
108
{
109
    int i;
110

    
111
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
112

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

    
131
#define GEN_HELPER 2
132
#include "helper.h"
133
}
134

    
135
static inline TCGv load_cpu_offset(int offset)
136
{
137
    TCGv tmp = tcg_temp_new_i32();
138
    tcg_gen_ld_i32(tmp, cpu_env, offset);
139
    return tmp;
140
}
141

    
142
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
143

    
144
static inline void store_cpu_offset(TCGv var, int offset)
145
{
146
    tcg_gen_st_i32(var, cpu_env, offset);
147
    tcg_temp_free_i32(var);
148
}
149

    
150
#define store_cpu_field(var, name) \
151
    store_cpu_offset(var, offsetof(CPUARMState, name))
152

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

    
169
/* Create a new temporary and set it to the value of a CPU register.  */
170
static inline TCGv load_reg(DisasContext *s, int reg)
171
{
172
    TCGv tmp = tcg_temp_new_i32();
173
    load_reg_var(s, tmp, reg);
174
    return tmp;
175
}
176

    
177
/* Set a CPU register.  The source must be a temporary and will be
178
   marked as dead.  */
179
static void store_reg(DisasContext *s, int reg, TCGv var)
180
{
181
    if (reg == 15) {
182
        tcg_gen_andi_i32(var, var, ~1);
183
        s->is_jmp = DISAS_JUMP;
184
    }
185
    tcg_gen_mov_i32(cpu_R[reg], var);
186
    tcg_temp_free_i32(var);
187
}
188

    
189
/* Value extensions.  */
190
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
191
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
192
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
193
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
194

    
195
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
196
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
197

    
198

    
199
static inline void gen_set_cpsr(TCGv var, uint32_t mask)
200
{
201
    TCGv tmp_mask = tcg_const_i32(mask);
202
    gen_helper_cpsr_write(var, tmp_mask);
203
    tcg_temp_free_i32(tmp_mask);
204
}
205
/* Set NZCV flags from the high 4 bits of var.  */
206
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
207

    
208
static void gen_exception(int excp)
209
{
210
    TCGv tmp = tcg_temp_new_i32();
211
    tcg_gen_movi_i32(tmp, excp);
212
    gen_helper_exception(tmp);
213
    tcg_temp_free_i32(tmp);
214
}
215

    
216
static void gen_smul_dual(TCGv a, TCGv b)
217
{
218
    TCGv tmp1 = tcg_temp_new_i32();
219
    TCGv tmp2 = tcg_temp_new_i32();
220
    tcg_gen_ext16s_i32(tmp1, a);
221
    tcg_gen_ext16s_i32(tmp2, b);
222
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
223
    tcg_temp_free_i32(tmp2);
224
    tcg_gen_sari_i32(a, a, 16);
225
    tcg_gen_sari_i32(b, b, 16);
226
    tcg_gen_mul_i32(b, b, a);
227
    tcg_gen_mov_i32(a, tmp1);
228
    tcg_temp_free_i32(tmp1);
229
}
230

    
231
/* Byteswap each halfword.  */
232
static void gen_rev16(TCGv var)
233
{
234
    TCGv tmp = tcg_temp_new_i32();
235
    tcg_gen_shri_i32(tmp, var, 8);
236
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
237
    tcg_gen_shli_i32(var, var, 8);
238
    tcg_gen_andi_i32(var, var, 0xff00ff00);
239
    tcg_gen_or_i32(var, var, tmp);
240
    tcg_temp_free_i32(tmp);
241
}
242

    
243
/* Byteswap low halfword and sign extend.  */
244
static void gen_revsh(TCGv var)
245
{
246
    tcg_gen_ext16u_i32(var, var);
247
    tcg_gen_bswap16_i32(var, var);
248
    tcg_gen_ext16s_i32(var, var);
249
}
250

    
251
/* Unsigned bitfield extract.  */
252
static void gen_ubfx(TCGv var, int shift, uint32_t mask)
253
{
254
    if (shift)
255
        tcg_gen_shri_i32(var, var, shift);
256
    tcg_gen_andi_i32(var, var, mask);
257
}
258

    
259
/* Signed bitfield extract.  */
260
static void gen_sbfx(TCGv var, int shift, int width)
261
{
262
    uint32_t signbit;
263

    
264
    if (shift)
265
        tcg_gen_sari_i32(var, var, shift);
266
    if (shift + width < 32) {
267
        signbit = 1u << (width - 1);
268
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
269
        tcg_gen_xori_i32(var, var, signbit);
270
        tcg_gen_subi_i32(var, var, signbit);
271
    }
272
}
273

    
274
/* Bitfield insertion.  Insert val into base.  Clobbers base and val.  */
275
static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
276
{
277
    tcg_gen_andi_i32(val, val, mask);
278
    tcg_gen_shli_i32(val, val, shift);
279
    tcg_gen_andi_i32(base, base, ~(mask << shift));
280
    tcg_gen_or_i32(dest, base, val);
281
}
282

    
283
/* Return (b << 32) + a. Mark inputs as dead */
284
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b)
285
{
286
    TCGv_i64 tmp64 = tcg_temp_new_i64();
287

    
288
    tcg_gen_extu_i32_i64(tmp64, b);
289
    tcg_temp_free_i32(b);
290
    tcg_gen_shli_i64(tmp64, tmp64, 32);
291
    tcg_gen_add_i64(a, tmp64, a);
292

    
293
    tcg_temp_free_i64(tmp64);
294
    return a;
295
}
296

    
297
/* Return (b << 32) - a. Mark inputs as dead. */
298
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
299
{
300
    TCGv_i64 tmp64 = tcg_temp_new_i64();
301

    
302
    tcg_gen_extu_i32_i64(tmp64, b);
303
    tcg_temp_free_i32(b);
304
    tcg_gen_shli_i64(tmp64, tmp64, 32);
305
    tcg_gen_sub_i64(a, tmp64, a);
306

    
307
    tcg_temp_free_i64(tmp64);
308
    return a;
309
}
310

    
311
/* FIXME: Most targets have native widening multiplication.
312
   It would be good to use that instead of a full wide multiply.  */
313
/* 32x32->64 multiply.  Marks inputs as dead.  */
314
static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
315
{
316
    TCGv_i64 tmp1 = tcg_temp_new_i64();
317
    TCGv_i64 tmp2 = tcg_temp_new_i64();
318

    
319
    tcg_gen_extu_i32_i64(tmp1, a);
320
    tcg_temp_free_i32(a);
321
    tcg_gen_extu_i32_i64(tmp2, b);
322
    tcg_temp_free_i32(b);
323
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
324
    tcg_temp_free_i64(tmp2);
325
    return tmp1;
326
}
327

    
328
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
329
{
330
    TCGv_i64 tmp1 = tcg_temp_new_i64();
331
    TCGv_i64 tmp2 = tcg_temp_new_i64();
332

    
333
    tcg_gen_ext_i32_i64(tmp1, a);
334
    tcg_temp_free_i32(a);
335
    tcg_gen_ext_i32_i64(tmp2, b);
336
    tcg_temp_free_i32(b);
337
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
338
    tcg_temp_free_i64(tmp2);
339
    return tmp1;
340
}
341

    
342
/* Swap low and high halfwords.  */
343
static void gen_swap_half(TCGv var)
344
{
345
    TCGv tmp = tcg_temp_new_i32();
346
    tcg_gen_shri_i32(tmp, var, 16);
347
    tcg_gen_shli_i32(var, var, 16);
348
    tcg_gen_or_i32(var, var, tmp);
349
    tcg_temp_free_i32(tmp);
350
}
351

    
352
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
353
    tmp = (t0 ^ t1) & 0x8000;
354
    t0 &= ~0x8000;
355
    t1 &= ~0x8000;
356
    t0 = (t0 + t1) ^ tmp;
357
 */
358

    
359
static void gen_add16(TCGv t0, TCGv t1)
360
{
361
    TCGv tmp = tcg_temp_new_i32();
362
    tcg_gen_xor_i32(tmp, t0, t1);
363
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
364
    tcg_gen_andi_i32(t0, t0, ~0x8000);
365
    tcg_gen_andi_i32(t1, t1, ~0x8000);
366
    tcg_gen_add_i32(t0, t0, t1);
367
    tcg_gen_xor_i32(t0, t0, tmp);
368
    tcg_temp_free_i32(tmp);
369
    tcg_temp_free_i32(t1);
370
}
371

    
372
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, CF))
373

    
374
/* Set CF to the top bit of var.  */
375
static void gen_set_CF_bit31(TCGv var)
376
{
377
    TCGv tmp = tcg_temp_new_i32();
378
    tcg_gen_shri_i32(tmp, var, 31);
379
    gen_set_CF(tmp);
380
    tcg_temp_free_i32(tmp);
381
}
382

    
383
/* Set N and Z flags from var.  */
384
static inline void gen_logic_CC(TCGv var)
385
{
386
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, NF));
387
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, ZF));
388
}
389

    
390
/* T0 += T1 + CF.  */
391
static void gen_adc(TCGv t0, TCGv t1)
392
{
393
    TCGv tmp;
394
    tcg_gen_add_i32(t0, t0, t1);
395
    tmp = load_cpu_field(CF);
396
    tcg_gen_add_i32(t0, t0, tmp);
397
    tcg_temp_free_i32(tmp);
398
}
399

    
400
/* dest = T0 + T1 + CF. */
401
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
402
{
403
    TCGv tmp;
404
    tcg_gen_add_i32(dest, t0, t1);
405
    tmp = load_cpu_field(CF);
406
    tcg_gen_add_i32(dest, dest, tmp);
407
    tcg_temp_free_i32(tmp);
408
}
409

    
410
/* dest = T0 - T1 + CF - 1.  */
411
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
412
{
413
    TCGv tmp;
414
    tcg_gen_sub_i32(dest, t0, t1);
415
    tmp = load_cpu_field(CF);
416
    tcg_gen_add_i32(dest, dest, tmp);
417
    tcg_gen_subi_i32(dest, dest, 1);
418
    tcg_temp_free_i32(tmp);
419
}
420

    
421
/* FIXME:  Implement this natively.  */
422
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
423

    
424
static void shifter_out_im(TCGv var, int shift)
425
{
426
    TCGv tmp = tcg_temp_new_i32();
427
    if (shift == 0) {
428
        tcg_gen_andi_i32(tmp, var, 1);
429
    } else {
430
        tcg_gen_shri_i32(tmp, var, shift);
431
        if (shift != 31)
432
            tcg_gen_andi_i32(tmp, tmp, 1);
433
    }
434
    gen_set_CF(tmp);
435
    tcg_temp_free_i32(tmp);
436
}
437

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

    
488
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
489
                                     TCGv shift, int flags)
490
{
491
    if (flags) {
492
        switch (shiftop) {
493
        case 0: gen_helper_shl_cc(var, var, shift); break;
494
        case 1: gen_helper_shr_cc(var, var, shift); break;
495
        case 2: gen_helper_sar_cc(var, var, shift); break;
496
        case 3: gen_helper_ror_cc(var, var, shift); break;
497
        }
498
    } else {
499
        switch (shiftop) {
500
        case 0: gen_helper_shl(var, var, shift); break;
501
        case 1: gen_helper_shr(var, var, shift); break;
502
        case 2: gen_helper_sar(var, var, shift); break;
503
        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
504
                tcg_gen_rotr_i32(var, var, shift); break;
505
        }
506
    }
507
    tcg_temp_free_i32(shift);
508
}
509

    
510
#define PAS_OP(pfx) \
511
    switch (op2) {  \
512
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
513
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
514
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
515
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
516
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
517
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
518
    }
519
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
520
{
521
    TCGv_ptr tmp;
522

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

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

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

    
603
static void gen_test_cc(int cc, int label)
604
{
605
    TCGv tmp;
606
    TCGv tmp2;
607
    int inv;
608

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

    
701
static const uint8_t table_logic_cc[16] = {
702
    1, /* and */
703
    1, /* xor */
704
    0, /* sub */
705
    0, /* rsb */
706
    0, /* add */
707
    0, /* adc */
708
    0, /* sbc */
709
    0, /* rsc */
710
    1, /* andl */
711
    1, /* xorl */
712
    0, /* cmp */
713
    0, /* cmn */
714
    1, /* orr */
715
    1, /* mov */
716
    1, /* bic */
717
    1, /* mvn */
718
};
719

    
720
/* Set PC and Thumb state from an immediate address.  */
721
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
722
{
723
    TCGv tmp;
724

    
725
    s->is_jmp = DISAS_UPDATE;
726
    if (s->thumb != (addr & 1)) {
727
        tmp = tcg_temp_new_i32();
728
        tcg_gen_movi_i32(tmp, addr & 1);
729
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
730
        tcg_temp_free_i32(tmp);
731
    }
732
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
733
}
734

    
735
/* Set PC and Thumb state from var.  var is marked as dead.  */
736
static inline void gen_bx(DisasContext *s, TCGv var)
737
{
738
    s->is_jmp = DISAS_UPDATE;
739
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
740
    tcg_gen_andi_i32(var, var, 1);
741
    store_cpu_field(var, thumb);
742
}
743

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

    
757
/* Variant of store_reg which uses branch&exchange logic when storing
758
 * to r15 in ARM architecture v5T and above. This is used for storing
759
 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
760
 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
761
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
762
                                int reg, TCGv var)
763
{
764
    if (reg == 15 && ENABLE_ARCH_5) {
765
        gen_bx(s, var);
766
    } else {
767
        store_reg(s, reg, var);
768
    }
769
}
770

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

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

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

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

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

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

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

    
896
static TCGv_ptr get_fpstatus_ptr(int neon)
897
{
898
    TCGv_ptr statusptr = tcg_temp_new_ptr();
899
    int offset;
900
    if (neon) {
901
        offset = offsetof(CPUARMState, vfp.standard_fp_status);
902
    } else {
903
        offset = offsetof(CPUARMState, vfp.fp_status);
904
    }
905
    tcg_gen_addi_ptr(statusptr, cpu_env, offset);
906
    return statusptr;
907
}
908

    
909
#define VFP_OP2(name)                                                 \
910
static inline void gen_vfp_##name(int dp)                             \
911
{                                                                     \
912
    TCGv_ptr fpst = get_fpstatus_ptr(0);                              \
913
    if (dp) {                                                         \
914
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst);    \
915
    } else {                                                          \
916
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst);    \
917
    }                                                                 \
918
    tcg_temp_free_ptr(fpst);                                          \
919
}
920

    
921
VFP_OP2(add)
922
VFP_OP2(sub)
923
VFP_OP2(mul)
924
VFP_OP2(div)
925

    
926
#undef VFP_OP2
927

    
928
static inline void gen_vfp_F1_mul(int dp)
929
{
930
    /* Like gen_vfp_mul() but put result in F1 */
931
    TCGv_ptr fpst = get_fpstatus_ptr(0);
932
    if (dp) {
933
        gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
934
    } else {
935
        gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
936
    }
937
    tcg_temp_free_ptr(fpst);
938
}
939

    
940
static inline void gen_vfp_F1_neg(int dp)
941
{
942
    /* Like gen_vfp_neg() but put result in F1 */
943
    if (dp) {
944
        gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
945
    } else {
946
        gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
947
    }
948
}
949

    
950
static inline void gen_vfp_abs(int dp)
951
{
952
    if (dp)
953
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
954
    else
955
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
956
}
957

    
958
static inline void gen_vfp_neg(int dp)
959
{
960
    if (dp)
961
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
962
    else
963
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
964
}
965

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

    
974
static inline void gen_vfp_cmp(int dp)
975
{
976
    if (dp)
977
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
978
    else
979
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
980
}
981

    
982
static inline void gen_vfp_cmpe(int dp)
983
{
984
    if (dp)
985
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
986
    else
987
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
988
}
989

    
990
static inline void gen_vfp_F1_ld0(int dp)
991
{
992
    if (dp)
993
        tcg_gen_movi_i64(cpu_F1d, 0);
994
    else
995
        tcg_gen_movi_i32(cpu_F1s, 0);
996
}
997

    
998
#define VFP_GEN_ITOF(name) \
999
static inline void gen_vfp_##name(int dp, int neon) \
1000
{ \
1001
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1002
    if (dp) { \
1003
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1004
    } else { \
1005
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1006
    } \
1007
    tcg_temp_free_ptr(statusptr); \
1008
}
1009

    
1010
VFP_GEN_ITOF(uito)
1011
VFP_GEN_ITOF(sito)
1012
#undef VFP_GEN_ITOF
1013

    
1014
#define VFP_GEN_FTOI(name) \
1015
static inline void gen_vfp_##name(int dp, int neon) \
1016
{ \
1017
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1018
    if (dp) { \
1019
        gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1020
    } else { \
1021
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1022
    } \
1023
    tcg_temp_free_ptr(statusptr); \
1024
}
1025

    
1026
VFP_GEN_FTOI(toui)
1027
VFP_GEN_FTOI(touiz)
1028
VFP_GEN_FTOI(tosi)
1029
VFP_GEN_FTOI(tosiz)
1030
#undef VFP_GEN_FTOI
1031

    
1032
#define VFP_GEN_FIX(name) \
1033
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1034
{ \
1035
    TCGv tmp_shift = tcg_const_i32(shift); \
1036
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1037
    if (dp) { \
1038
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1039
    } else { \
1040
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1041
    } \
1042
    tcg_temp_free_i32(tmp_shift); \
1043
    tcg_temp_free_ptr(statusptr); \
1044
}
1045
VFP_GEN_FIX(tosh)
1046
VFP_GEN_FIX(tosl)
1047
VFP_GEN_FIX(touh)
1048
VFP_GEN_FIX(toul)
1049
VFP_GEN_FIX(shto)
1050
VFP_GEN_FIX(slto)
1051
VFP_GEN_FIX(uhto)
1052
VFP_GEN_FIX(ulto)
1053
#undef VFP_GEN_FIX
1054

    
1055
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
1056
{
1057
    if (dp)
1058
        tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1059
    else
1060
        tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1061
}
1062

    
1063
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
1064
{
1065
    if (dp)
1066
        tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1067
    else
1068
        tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1069
}
1070

    
1071
static inline long
1072
vfp_reg_offset (int dp, int reg)
1073
{
1074
    if (dp)
1075
        return offsetof(CPUARMState, vfp.regs[reg]);
1076
    else if (reg & 1) {
1077
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1078
          + offsetof(CPU_DoubleU, l.upper);
1079
    } else {
1080
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1081
          + offsetof(CPU_DoubleU, l.lower);
1082
    }
1083
}
1084

    
1085
/* Return the offset of a 32-bit piece of a NEON register.
1086
   zero is the least significant end of the register.  */
1087
static inline long
1088
neon_reg_offset (int reg, int n)
1089
{
1090
    int sreg;
1091
    sreg = reg * 2 + n;
1092
    return vfp_reg_offset(0, sreg);
1093
}
1094

    
1095
static TCGv neon_load_reg(int reg, int pass)
1096
{
1097
    TCGv tmp = tcg_temp_new_i32();
1098
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1099
    return tmp;
1100
}
1101

    
1102
static void neon_store_reg(int reg, int pass, TCGv var)
1103
{
1104
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1105
    tcg_temp_free_i32(var);
1106
}
1107

    
1108
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1109
{
1110
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1111
}
1112

    
1113
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1114
{
1115
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1116
}
1117

    
1118
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1119
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1120
#define tcg_gen_st_f32 tcg_gen_st_i32
1121
#define tcg_gen_st_f64 tcg_gen_st_i64
1122

    
1123
static inline void gen_mov_F0_vreg(int dp, int reg)
1124
{
1125
    if (dp)
1126
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1127
    else
1128
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1129
}
1130

    
1131
static inline void gen_mov_F1_vreg(int dp, int reg)
1132
{
1133
    if (dp)
1134
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1135
    else
1136
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1137
}
1138

    
1139
static inline void gen_mov_vreg_F0(int dp, int reg)
1140
{
1141
    if (dp)
1142
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1143
    else
1144
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1145
}
1146

    
1147
#define ARM_CP_RW_BIT        (1 << 20)
1148

    
1149
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1150
{
1151
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1152
}
1153

    
1154
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1155
{
1156
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1157
}
1158

    
1159
static inline TCGv iwmmxt_load_creg(int reg)
1160
{
1161
    TCGv var = tcg_temp_new_i32();
1162
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1163
    return var;
1164
}
1165

    
1166
static inline void iwmmxt_store_creg(int reg, TCGv var)
1167
{
1168
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1169
    tcg_temp_free_i32(var);
1170
}
1171

    
1172
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1173
{
1174
    iwmmxt_store_reg(cpu_M0, rn);
1175
}
1176

    
1177
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1178
{
1179
    iwmmxt_load_reg(cpu_M0, rn);
1180
}
1181

    
1182
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1183
{
1184
    iwmmxt_load_reg(cpu_V1, rn);
1185
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1186
}
1187

    
1188
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1189
{
1190
    iwmmxt_load_reg(cpu_V1, rn);
1191
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1192
}
1193

    
1194
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1195
{
1196
    iwmmxt_load_reg(cpu_V1, rn);
1197
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1198
}
1199

    
1200
#define IWMMXT_OP(name) \
1201
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1202
{ \
1203
    iwmmxt_load_reg(cpu_V1, rn); \
1204
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1205
}
1206

    
1207
#define IWMMXT_OP_ENV(name) \
1208
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1209
{ \
1210
    iwmmxt_load_reg(cpu_V1, rn); \
1211
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1212
}
1213

    
1214
#define IWMMXT_OP_ENV_SIZE(name) \
1215
IWMMXT_OP_ENV(name##b) \
1216
IWMMXT_OP_ENV(name##w) \
1217
IWMMXT_OP_ENV(name##l)
1218

    
1219
#define IWMMXT_OP_ENV1(name) \
1220
static inline void gen_op_iwmmxt_##name##_M0(void) \
1221
{ \
1222
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1223
}
1224

    
1225
IWMMXT_OP(maddsq)
1226
IWMMXT_OP(madduq)
1227
IWMMXT_OP(sadb)
1228
IWMMXT_OP(sadw)
1229
IWMMXT_OP(mulslw)
1230
IWMMXT_OP(mulshw)
1231
IWMMXT_OP(mululw)
1232
IWMMXT_OP(muluhw)
1233
IWMMXT_OP(macsw)
1234
IWMMXT_OP(macuw)
1235

    
1236
IWMMXT_OP_ENV_SIZE(unpackl)
1237
IWMMXT_OP_ENV_SIZE(unpackh)
1238

    
1239
IWMMXT_OP_ENV1(unpacklub)
1240
IWMMXT_OP_ENV1(unpackluw)
1241
IWMMXT_OP_ENV1(unpacklul)
1242
IWMMXT_OP_ENV1(unpackhub)
1243
IWMMXT_OP_ENV1(unpackhuw)
1244
IWMMXT_OP_ENV1(unpackhul)
1245
IWMMXT_OP_ENV1(unpacklsb)
1246
IWMMXT_OP_ENV1(unpacklsw)
1247
IWMMXT_OP_ENV1(unpacklsl)
1248
IWMMXT_OP_ENV1(unpackhsb)
1249
IWMMXT_OP_ENV1(unpackhsw)
1250
IWMMXT_OP_ENV1(unpackhsl)
1251

    
1252
IWMMXT_OP_ENV_SIZE(cmpeq)
1253
IWMMXT_OP_ENV_SIZE(cmpgtu)
1254
IWMMXT_OP_ENV_SIZE(cmpgts)
1255

    
1256
IWMMXT_OP_ENV_SIZE(mins)
1257
IWMMXT_OP_ENV_SIZE(minu)
1258
IWMMXT_OP_ENV_SIZE(maxs)
1259
IWMMXT_OP_ENV_SIZE(maxu)
1260

    
1261
IWMMXT_OP_ENV_SIZE(subn)
1262
IWMMXT_OP_ENV_SIZE(addn)
1263
IWMMXT_OP_ENV_SIZE(subu)
1264
IWMMXT_OP_ENV_SIZE(addu)
1265
IWMMXT_OP_ENV_SIZE(subs)
1266
IWMMXT_OP_ENV_SIZE(adds)
1267

    
1268
IWMMXT_OP_ENV(avgb0)
1269
IWMMXT_OP_ENV(avgb1)
1270
IWMMXT_OP_ENV(avgw0)
1271
IWMMXT_OP_ENV(avgw1)
1272

    
1273
IWMMXT_OP(msadb)
1274

    
1275
IWMMXT_OP_ENV(packuw)
1276
IWMMXT_OP_ENV(packul)
1277
IWMMXT_OP_ENV(packuq)
1278
IWMMXT_OP_ENV(packsw)
1279
IWMMXT_OP_ENV(packsl)
1280
IWMMXT_OP_ENV(packsq)
1281

    
1282
static void gen_op_iwmmxt_set_mup(void)
1283
{
1284
    TCGv tmp;
1285
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1286
    tcg_gen_ori_i32(tmp, tmp, 2);
1287
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1288
}
1289

    
1290
static void gen_op_iwmmxt_set_cup(void)
1291
{
1292
    TCGv tmp;
1293
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1294
    tcg_gen_ori_i32(tmp, tmp, 1);
1295
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1296
}
1297

    
1298
static void gen_op_iwmmxt_setpsr_nz(void)
1299
{
1300
    TCGv tmp = tcg_temp_new_i32();
1301
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1302
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1303
}
1304

    
1305
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1306
{
1307
    iwmmxt_load_reg(cpu_V1, rn);
1308
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1309
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1310
}
1311

    
1312
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1313
{
1314
    int rd;
1315
    uint32_t offset;
1316
    TCGv tmp;
1317

    
1318
    rd = (insn >> 16) & 0xf;
1319
    tmp = load_reg(s, rd);
1320

    
1321
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1322
    if (insn & (1 << 24)) {
1323
        /* Pre indexed */
1324
        if (insn & (1 << 23))
1325
            tcg_gen_addi_i32(tmp, tmp, offset);
1326
        else
1327
            tcg_gen_addi_i32(tmp, tmp, -offset);
1328
        tcg_gen_mov_i32(dest, tmp);
1329
        if (insn & (1 << 21))
1330
            store_reg(s, rd, tmp);
1331
        else
1332
            tcg_temp_free_i32(tmp);
1333
    } else if (insn & (1 << 21)) {
1334
        /* Post indexed */
1335
        tcg_gen_mov_i32(dest, tmp);
1336
        if (insn & (1 << 23))
1337
            tcg_gen_addi_i32(tmp, tmp, offset);
1338
        else
1339
            tcg_gen_addi_i32(tmp, tmp, -offset);
1340
        store_reg(s, rd, tmp);
1341
    } else if (!(insn & (1 << 23)))
1342
        return 1;
1343
    return 0;
1344
}
1345

    
1346
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1347
{
1348
    int rd = (insn >> 0) & 0xf;
1349
    TCGv tmp;
1350

    
1351
    if (insn & (1 << 8)) {
1352
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1353
            return 1;
1354
        } else {
1355
            tmp = iwmmxt_load_creg(rd);
1356
        }
1357
    } else {
1358
        tmp = tcg_temp_new_i32();
1359
        iwmmxt_load_reg(cpu_V0, rd);
1360
        tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1361
    }
1362
    tcg_gen_andi_i32(tmp, tmp, mask);
1363
    tcg_gen_mov_i32(dest, tmp);
1364
    tcg_temp_free_i32(tmp);
1365
    return 0;
1366
}
1367

    
1368
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occurred
1369
   (ie. an undefined instruction).  */
1370
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1371
{
1372
    int rd, wrd;
1373
    int rdhi, rdlo, rd0, rd1, i;
1374
    TCGv addr;
1375
    TCGv tmp, tmp2, tmp3;
1376

    
1377
    if ((insn & 0x0e000e00) == 0x0c000000) {
1378
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1379
            wrd = insn & 0xf;
1380
            rdlo = (insn >> 12) & 0xf;
1381
            rdhi = (insn >> 16) & 0xf;
1382
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1383
                iwmmxt_load_reg(cpu_V0, wrd);
1384
                tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1385
                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1386
                tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1387
            } else {                                        /* TMCRR */
1388
                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1389
                iwmmxt_store_reg(cpu_V0, wrd);
1390
                gen_op_iwmmxt_set_mup();
1391
            }
1392
            return 0;
1393
        }
1394

    
1395
        wrd = (insn >> 12) & 0xf;
1396
        addr = tcg_temp_new_i32();
1397
        if (gen_iwmmxt_address(s, insn, addr)) {
1398
            tcg_temp_free_i32(addr);
1399
            return 1;
1400
        }
1401
        if (insn & ARM_CP_RW_BIT) {
1402
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1403
                tmp = tcg_temp_new_i32();
1404
                tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
1405
                iwmmxt_store_creg(wrd, tmp);
1406
            } else {
1407
                i = 1;
1408
                if (insn & (1 << 8)) {
1409
                    if (insn & (1 << 22)) {                /* WLDRD */
1410
                        tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s));
1411
                        i = 0;
1412
                    } else {                                /* WLDRW wRd */
1413
                        tmp = gen_ld32(addr, IS_USER(s));
1414
                    }
1415
                } else {
1416
                    if (insn & (1 << 22)) {                /* WLDRH */
1417
                        tmp = gen_ld16u(addr, IS_USER(s));
1418
                    } else {                                /* WLDRB */
1419
                        tmp = gen_ld8u(addr, IS_USER(s));
1420
                    }
1421
                }
1422
                if (i) {
1423
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
1424
                    tcg_temp_free_i32(tmp);
1425
                }
1426
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1427
            }
1428
        } else {
1429
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1430
                tmp = iwmmxt_load_creg(wrd);
1431
                gen_st32(tmp, addr, IS_USER(s));
1432
            } else {
1433
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1434
                tmp = tcg_temp_new_i32();
1435
                if (insn & (1 << 8)) {
1436
                    if (insn & (1 << 22)) {                /* WSTRD */
1437
                        tcg_temp_free_i32(tmp);
1438
                        tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s));
1439
                    } else {                                /* WSTRW wRd */
1440
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1441
                        gen_st32(tmp, addr, IS_USER(s));
1442
                    }
1443
                } else {
1444
                    if (insn & (1 << 22)) {                /* WSTRH */
1445
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1446
                        gen_st16(tmp, addr, IS_USER(s));
1447
                    } else {                                /* WSTRB */
1448
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1449
                        gen_st8(tmp, addr, IS_USER(s));
1450
                    }
1451
                }
1452
            }
1453
        }
1454
        tcg_temp_free_i32(addr);
1455
        return 0;
1456
    }
1457

    
1458
    if ((insn & 0x0f000000) != 0x0e000000)
1459
        return 1;
1460

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

    
2369
    return 0;
2370
}
2371

    
2372
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occurred
2373
   (ie. an undefined instruction).  */
2374
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2375
{
2376
    int acc, rd0, rd1, rdhi, rdlo;
2377
    TCGv tmp, tmp2;
2378

    
2379
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2380
        /* Multiply with Internal Accumulate Format */
2381
        rd0 = (insn >> 12) & 0xf;
2382
        rd1 = insn & 0xf;
2383
        acc = (insn >> 5) & 7;
2384

    
2385
        if (acc != 0)
2386
            return 1;
2387

    
2388
        tmp = load_reg(s, rd0);
2389
        tmp2 = load_reg(s, rd1);
2390
        switch ((insn >> 16) & 0xf) {
2391
        case 0x0:                                        /* MIA */
2392
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2393
            break;
2394
        case 0x8:                                        /* MIAPH */
2395
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2396
            break;
2397
        case 0xc:                                        /* MIABB */
2398
        case 0xd:                                        /* MIABT */
2399
        case 0xe:                                        /* MIATB */
2400
        case 0xf:                                        /* MIATT */
2401
            if (insn & (1 << 16))
2402
                tcg_gen_shri_i32(tmp, tmp, 16);
2403
            if (insn & (1 << 17))
2404
                tcg_gen_shri_i32(tmp2, tmp2, 16);
2405
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2406
            break;
2407
        default:
2408
            return 1;
2409
        }
2410
        tcg_temp_free_i32(tmp2);
2411
        tcg_temp_free_i32(tmp);
2412

    
2413
        gen_op_iwmmxt_movq_wRn_M0(acc);
2414
        return 0;
2415
    }
2416

    
2417
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2418
        /* Internal Accumulator Access Format */
2419
        rdhi = (insn >> 16) & 0xf;
2420
        rdlo = (insn >> 12) & 0xf;
2421
        acc = insn & 7;
2422

    
2423
        if (acc != 0)
2424
            return 1;
2425

    
2426
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2427
            iwmmxt_load_reg(cpu_V0, acc);
2428
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2429
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2430
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2431
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2432
        } else {                                        /* MAR */
2433
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2434
            iwmmxt_store_reg(cpu_V0, acc);
2435
        }
2436
        return 0;
2437
    }
2438

    
2439
    return 1;
2440
}
2441

    
2442
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2443
#define VFP_SREG(insn, bigbit, smallbit) \
2444
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2445
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2446
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2447
        reg = (((insn) >> (bigbit)) & 0x0f) \
2448
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2449
    } else { \
2450
        if (insn & (1 << (smallbit))) \
2451
            return 1; \
2452
        reg = ((insn) >> (bigbit)) & 0x0f; \
2453
    }} while (0)
2454

    
2455
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2456
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2457
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2458
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2459
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2460
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2461

    
2462
/* Move between integer and VFP cores.  */
2463
static TCGv gen_vfp_mrs(void)
2464
{
2465
    TCGv tmp = tcg_temp_new_i32();
2466
    tcg_gen_mov_i32(tmp, cpu_F0s);
2467
    return tmp;
2468
}
2469

    
2470
static void gen_vfp_msr(TCGv tmp)
2471
{
2472
    tcg_gen_mov_i32(cpu_F0s, tmp);
2473
    tcg_temp_free_i32(tmp);
2474
}
2475

    
2476
static void gen_neon_dup_u8(TCGv var, int shift)
2477
{
2478
    TCGv tmp = tcg_temp_new_i32();
2479
    if (shift)
2480
        tcg_gen_shri_i32(var, var, shift);
2481
    tcg_gen_ext8u_i32(var, var);
2482
    tcg_gen_shli_i32(tmp, var, 8);
2483
    tcg_gen_or_i32(var, var, tmp);
2484
    tcg_gen_shli_i32(tmp, var, 16);
2485
    tcg_gen_or_i32(var, var, tmp);
2486
    tcg_temp_free_i32(tmp);
2487
}
2488

    
2489
static void gen_neon_dup_low16(TCGv var)
2490
{
2491
    TCGv tmp = tcg_temp_new_i32();
2492
    tcg_gen_ext16u_i32(var, var);
2493
    tcg_gen_shli_i32(tmp, var, 16);
2494
    tcg_gen_or_i32(var, var, tmp);
2495
    tcg_temp_free_i32(tmp);
2496
}
2497

    
2498
static void gen_neon_dup_high16(TCGv var)
2499
{
2500
    TCGv tmp = tcg_temp_new_i32();
2501
    tcg_gen_andi_i32(var, var, 0xffff0000);
2502
    tcg_gen_shri_i32(tmp, var, 16);
2503
    tcg_gen_or_i32(var, var, tmp);
2504
    tcg_temp_free_i32(tmp);
2505
}
2506

    
2507
static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size)
2508
{
2509
    /* Load a single Neon element and replicate into a 32 bit TCG reg */
2510
    TCGv tmp;
2511
    switch (size) {
2512
    case 0:
2513
        tmp = gen_ld8u(addr, IS_USER(s));
2514
        gen_neon_dup_u8(tmp, 0);
2515
        break;
2516
    case 1:
2517
        tmp = gen_ld16u(addr, IS_USER(s));
2518
        gen_neon_dup_low16(tmp);
2519
        break;
2520
    case 2:
2521
        tmp = gen_ld32(addr, IS_USER(s));
2522
        break;
2523
    default: /* Avoid compiler warnings.  */
2524
        abort();
2525
    }
2526
    return tmp;
2527
}
2528

    
2529
/* Disassemble a VFP instruction.  Returns nonzero if an error occurred
2530
   (ie. an undefined instruction).  */
2531
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2532
{
2533
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2534
    int dp, veclen;
2535
    TCGv addr;
2536
    TCGv tmp;
2537
    TCGv tmp2;
2538

    
2539
    if (!arm_feature(env, ARM_FEATURE_VFP))
2540
        return 1;
2541

    
2542
    if (!s->vfp_enabled) {
2543
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2544
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2545
            return 1;
2546
        rn = (insn >> 16) & 0xf;
2547
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2548
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2549
            return 1;
2550
    }
2551
    dp = ((insn & 0xf00) == 0xb00);
2552
    switch ((insn >> 24) & 0xf) {
2553
    case 0xe:
2554
        if (insn & (1 << 4)) {
2555
            /* single register transfer */
2556
            rd = (insn >> 12) & 0xf;
2557
            if (dp) {
2558
                int size;
2559
                int pass;
2560

    
2561
                VFP_DREG_N(rn, insn);
2562
                if (insn & 0xf)
2563
                    return 1;
2564
                if (insn & 0x00c00060
2565
                    && !arm_feature(env, ARM_FEATURE_NEON))
2566
                    return 1;
2567

    
2568
                pass = (insn >> 21) & 1;
2569
                if (insn & (1 << 22)) {
2570
                    size = 0;
2571
                    offset = ((insn >> 5) & 3) * 8;
2572
                } else if (insn & (1 << 5)) {
2573
                    size = 1;
2574
                    offset = (insn & (1 << 6)) ? 16 : 0;
2575
                } else {
2576
                    size = 2;
2577
                    offset = 0;
2578
                }
2579
                if (insn & ARM_CP_RW_BIT) {
2580
                    /* vfp->arm */
2581
                    tmp = neon_load_reg(rn, pass);
2582
                    switch (size) {
2583
                    case 0:
2584
                        if (offset)
2585
                            tcg_gen_shri_i32(tmp, tmp, offset);
2586
                        if (insn & (1 << 23))
2587
                            gen_uxtb(tmp);
2588
                        else
2589
                            gen_sxtb(tmp);
2590
                        break;
2591
                    case 1:
2592
                        if (insn & (1 << 23)) {
2593
                            if (offset) {
2594
                                tcg_gen_shri_i32(tmp, tmp, 16);
2595
                            } else {
2596
                                gen_uxth(tmp);
2597
                            }
2598
                        } else {
2599
                            if (offset) {
2600
                                tcg_gen_sari_i32(tmp, tmp, 16);
2601
                            } else {
2602
                                gen_sxth(tmp);
2603
                            }
2604
                        }
2605
                        break;
2606
                    case 2:
2607
                        break;
2608
                    }
2609
                    store_reg(s, rd, tmp);
2610
                } else {
2611
                    /* arm->vfp */
2612
                    tmp = load_reg(s, rd);
2613
                    if (insn & (1 << 23)) {
2614
                        /* VDUP */
2615
                        if (size == 0) {
2616
                            gen_neon_dup_u8(tmp, 0);
2617
                        } else if (size == 1) {
2618
                            gen_neon_dup_low16(tmp);
2619
                        }
2620
                        for (n = 0; n <= pass * 2; n++) {
2621
                            tmp2 = tcg_temp_new_i32();
2622
                            tcg_gen_mov_i32(tmp2, tmp);
2623
                            neon_store_reg(rn, n, tmp2);
2624
                        }
2625
                        neon_store_reg(rn, n, tmp);
2626
                    } else {
2627
                        /* VMOV */
2628
                        switch (size) {
2629
                        case 0:
2630
                            tmp2 = neon_load_reg(rn, pass);
2631
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2632
                            tcg_temp_free_i32(tmp2);
2633
                            break;
2634
                        case 1:
2635
                            tmp2 = neon_load_reg(rn, pass);
2636
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2637
                            tcg_temp_free_i32(tmp2);
2638
                            break;
2639
                        case 2:
2640
                            break;
2641
                        }
2642
                        neon_store_reg(rn, pass, tmp);
2643
                    }
2644
                }
2645
            } else { /* !dp */
2646
                if ((insn & 0x6f) != 0x00)
2647
                    return 1;
2648
                rn = VFP_SREG_N(insn);
2649
                if (insn & ARM_CP_RW_BIT) {
2650
                    /* vfp->arm */
2651
                    if (insn & (1 << 21)) {
2652
                        /* system register */
2653
                        rn >>= 1;
2654

    
2655
                        switch (rn) {
2656
                        case ARM_VFP_FPSID:
2657
                            /* VFP2 allows access to FSID from userspace.
2658
                               VFP3 restricts all id registers to privileged
2659
                               accesses.  */
2660
                            if (IS_USER(s)
2661
                                && arm_feature(env, ARM_FEATURE_VFP3))
2662
                                return 1;
2663
                            tmp = load_cpu_field(vfp.xregs[rn]);
2664
                            break;
2665
                        case ARM_VFP_FPEXC:
2666
                            if (IS_USER(s))
2667
                                return 1;
2668
                            tmp = load_cpu_field(vfp.xregs[rn]);
2669
                            break;
2670
                        case ARM_VFP_FPINST:
2671
                        case ARM_VFP_FPINST2:
2672
                            /* Not present in VFP3.  */
2673
                            if (IS_USER(s)
2674
                                || arm_feature(env, ARM_FEATURE_VFP3))
2675
                                return 1;
2676
                            tmp = load_cpu_field(vfp.xregs[rn]);
2677
                            break;
2678
                        case ARM_VFP_FPSCR:
2679
                            if (rd == 15) {
2680
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2681
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2682
                            } else {
2683
                                tmp = tcg_temp_new_i32();
2684
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2685
                            }
2686
                            break;
2687
                        case ARM_VFP_MVFR0:
2688
                        case ARM_VFP_MVFR1:
2689
                            if (IS_USER(s)
2690
                                || !arm_feature(env, ARM_FEATURE_MVFR))
2691
                                return 1;
2692
                            tmp = load_cpu_field(vfp.xregs[rn]);
2693
                            break;
2694
                        default:
2695
                            return 1;
2696
                        }
2697
                    } else {
2698
                        gen_mov_F0_vreg(0, rn);
2699
                        tmp = gen_vfp_mrs();
2700
                    }
2701
                    if (rd == 15) {
2702
                        /* Set the 4 flag bits in the CPSR.  */
2703
                        gen_set_nzcv(tmp);
2704
                        tcg_temp_free_i32(tmp);
2705
                    } else {
2706
                        store_reg(s, rd, tmp);
2707
                    }
2708
                } else {
2709
                    /* arm->vfp */
2710
                    tmp = load_reg(s, rd);
2711
                    if (insn & (1 << 21)) {
2712
                        rn >>= 1;
2713
                        /* system register */
2714
                        switch (rn) {
2715
                        case ARM_VFP_FPSID:
2716
                        case ARM_VFP_MVFR0:
2717
                        case ARM_VFP_MVFR1:
2718
                            /* Writes are ignored.  */
2719
                            break;
2720
                        case ARM_VFP_FPSCR:
2721
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2722
                            tcg_temp_free_i32(tmp);
2723
                            gen_lookup_tb(s);
2724
                            break;
2725
                        case ARM_VFP_FPEXC:
2726
                            if (IS_USER(s))
2727
                                return 1;
2728
                            /* TODO: VFP subarchitecture support.
2729
                             * For now, keep the EN bit only */
2730
                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2731
                            store_cpu_field(tmp, vfp.xregs[rn]);
2732
                            gen_lookup_tb(s);
2733
                            break;
2734
                        case ARM_VFP_FPINST:
2735
                        case ARM_VFP_FPINST2:
2736
                            store_cpu_field(tmp, vfp.xregs[rn]);
2737
                            break;
2738
                        default:
2739
                            return 1;
2740
                        }
2741
                    } else {
2742
                        gen_vfp_msr(tmp);
2743
                        gen_mov_vreg_F0(0, rn);
2744
                    }
2745
                }
2746
            }
2747
        } else {
2748
            /* data processing */
2749
            /* The opcode is in bits 23, 21, 20 and 6.  */
2750
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2751
            if (dp) {
2752
                if (op == 15) {
2753
                    /* rn is opcode */
2754
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2755
                } else {
2756
                    /* rn is register number */
2757
                    VFP_DREG_N(rn, insn);
2758
                }
2759

    
2760
                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2761
                    /* Integer or single precision destination.  */
2762
                    rd = VFP_SREG_D(insn);
2763
                } else {
2764
                    VFP_DREG_D(rd, insn);
2765
                }
2766
                if (op == 15 &&
2767
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2768
                    /* VCVT from int is always from S reg regardless of dp bit.
2769
                     * VCVT with immediate frac_bits has same format as SREG_M
2770
                     */
2771
                    rm = VFP_SREG_M(insn);
2772
                } else {
2773
                    VFP_DREG_M(rm, insn);
2774
                }
2775
            } else {
2776
                rn = VFP_SREG_N(insn);
2777
                if (op == 15 && rn == 15) {
2778
                    /* Double precision destination.  */
2779
                    VFP_DREG_D(rd, insn);
2780
                } else {
2781
                    rd = VFP_SREG_D(insn);
2782
                }
2783
                /* NB that we implicitly rely on the encoding for the frac_bits
2784
                 * in VCVT of fixed to float being the same as that of an SREG_M
2785
                 */
2786
                rm = VFP_SREG_M(insn);
2787
            }
2788

    
2789
            veclen = s->vec_len;
2790
            if (op == 15 && rn > 3)
2791
                veclen = 0;
2792

    
2793
            /* Shut up compiler warnings.  */
2794
            delta_m = 0;
2795
            delta_d = 0;
2796
            bank_mask = 0;
2797

    
2798
            if (veclen > 0) {
2799
                if (dp)
2800
                    bank_mask = 0xc;
2801
                else
2802
                    bank_mask = 0x18;
2803

    
2804
                /* Figure out what type of vector operation this is.  */
2805
                if ((rd & bank_mask) == 0) {
2806
                    /* scalar */
2807
                    veclen = 0;
2808
                } else {
2809
                    if (dp)
2810
                        delta_d = (s->vec_stride >> 1) + 1;
2811
                    else
2812
                        delta_d = s->vec_stride + 1;
2813

    
2814
                    if ((rm & bank_mask) == 0) {
2815
                        /* mixed scalar/vector */
2816
                        delta_m = 0;
2817
                    } else {
2818
                        /* vector */
2819
                        delta_m = delta_d;
2820
                    }
2821
                }
2822
            }
2823

    
2824
            /* Load the initial operands.  */
2825
            if (op == 15) {
2826
                switch (rn) {
2827
                case 16:
2828
                case 17:
2829
                    /* Integer source */
2830
                    gen_mov_F0_vreg(0, rm);
2831
                    break;
2832
                case 8:
2833
                case 9:
2834
                    /* Compare */
2835
                    gen_mov_F0_vreg(dp, rd);
2836
                    gen_mov_F1_vreg(dp, rm);
2837
                    break;
2838
                case 10:
2839
                case 11:
2840
                    /* Compare with zero */
2841
                    gen_mov_F0_vreg(dp, rd);
2842
                    gen_vfp_F1_ld0(dp);
2843
                    break;
2844
                case 20:
2845
                case 21:
2846
                case 22:
2847
                case 23:
2848
                case 28:
2849
                case 29:
2850
                case 30:
2851
                case 31:
2852
                    /* Source and destination the same.  */
2853
                    gen_mov_F0_vreg(dp, rd);
2854
                    break;
2855
                case 4:
2856
                case 5:
2857
                case 6:
2858
                case 7:
2859
                    /* VCVTB, VCVTT: only present with the halfprec extension,
2860
                     * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2861
                     */
2862
                    if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
2863
                        return 1;
2864
                    }
2865
                    /* Otherwise fall through */
2866
                default:
2867
                    /* One source operand.  */
2868
                    gen_mov_F0_vreg(dp, rm);
2869
                    break;
2870
                }
2871
            } else {
2872
                /* Two source operands.  */
2873
                gen_mov_F0_vreg(dp, rn);
2874
                gen_mov_F1_vreg(dp, rm);
2875
            }
2876

    
2877
            for (;;) {
2878
                /* Perform the calculation.  */
2879
                switch (op) {
2880
                case 0: /* VMLA: fd + (fn * fm) */
2881
                    /* Note that order of inputs to the add matters for NaNs */
2882
                    gen_vfp_F1_mul(dp);
2883
                    gen_mov_F0_vreg(dp, rd);
2884
                    gen_vfp_add(dp);
2885
                    break;
2886
                case 1: /* VMLS: fd + -(fn * fm) */
2887
                    gen_vfp_mul(dp);
2888
                    gen_vfp_F1_neg(dp);
2889
                    gen_mov_F0_vreg(dp, rd);
2890
                    gen_vfp_add(dp);
2891
                    break;
2892
                case 2: /* VNMLS: -fd + (fn * fm) */
2893
                    /* Note that it isn't valid to replace (-A + B) with (B - A)
2894
                     * or similar plausible looking simplifications
2895
                     * because this will give wrong results for NaNs.
2896
                     */
2897
                    gen_vfp_F1_mul(dp);
2898
                    gen_mov_F0_vreg(dp, rd);
2899
                    gen_vfp_neg(dp);
2900
                    gen_vfp_add(dp);
2901
                    break;
2902
                case 3: /* VNMLA: -fd + -(fn * fm) */
2903
                    gen_vfp_mul(dp);
2904
                    gen_vfp_F1_neg(dp);
2905
                    gen_mov_F0_vreg(dp, rd);
2906
                    gen_vfp_neg(dp);
2907
                    gen_vfp_add(dp);
2908
                    break;
2909
                case 4: /* mul: fn * fm */
2910
                    gen_vfp_mul(dp);
2911
                    break;
2912
                case 5: /* nmul: -(fn * fm) */
2913
                    gen_vfp_mul(dp);
2914
                    gen_vfp_neg(dp);
2915
                    break;
2916
                case 6: /* add: fn + fm */
2917
                    gen_vfp_add(dp);
2918
                    break;
2919
                case 7: /* sub: fn - fm */
2920
                    gen_vfp_sub(dp);
2921
                    break;
2922
                case 8: /* div: fn / fm */
2923
                    gen_vfp_div(dp);
2924
                    break;
2925
                case 10: /* VFNMA : fd = muladd(-fd,  fn, fm) */
2926
                case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
2927
                case 12: /* VFMA  : fd = muladd( fd,  fn, fm) */
2928
                case 13: /* VFMS  : fd = muladd( fd, -fn, fm) */
2929
                    /* These are fused multiply-add, and must be done as one
2930
                     * floating point operation with no rounding between the
2931
                     * multiplication and addition steps.
2932
                     * NB that doing the negations here as separate steps is
2933
                     * correct : an input NaN should come out with its sign bit
2934
                     * flipped if it is a negated-input.
2935
                     */
2936
                    if (!arm_feature(env, ARM_FEATURE_VFP4)) {
2937
                        return 1;
2938
                    }
2939
                    if (dp) {
2940
                        TCGv_ptr fpst;
2941
                        TCGv_i64 frd;
2942
                        if (op & 1) {
2943
                            /* VFNMS, VFMS */
2944
                            gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
2945
                        }
2946
                        frd = tcg_temp_new_i64();
2947
                        tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
2948
                        if (op & 2) {
2949
                            /* VFNMA, VFNMS */
2950
                            gen_helper_vfp_negd(frd, frd);
2951
                        }
2952
                        fpst = get_fpstatus_ptr(0);
2953
                        gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
2954
                                               cpu_F1d, frd, fpst);
2955
                        tcg_temp_free_ptr(fpst);
2956
                        tcg_temp_free_i64(frd);
2957
                    } else {
2958
                        TCGv_ptr fpst;
2959
                        TCGv_i32 frd;
2960
                        if (op & 1) {
2961
                            /* VFNMS, VFMS */
2962
                            gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
2963
                        }
2964
                        frd = tcg_temp_new_i32();
2965
                        tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
2966
                        if (op & 2) {
2967
                            gen_helper_vfp_negs(frd, frd);
2968
                        }
2969
                        fpst = get_fpstatus_ptr(0);
2970
                        gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
2971
                                               cpu_F1s, frd, fpst);
2972
                        tcg_temp_free_ptr(fpst);
2973
                        tcg_temp_free_i32(frd);
2974
                    }
2975
                    break;
2976
                case 14: /* fconst */
2977
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
2978
                      return 1;
2979

    
2980
                    n = (insn << 12) & 0x80000000;
2981
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
2982
                    if (dp) {
2983
                        if (i & 0x40)
2984
                            i |= 0x3f80;
2985
                        else
2986
                            i |= 0x4000;
2987
                        n |= i << 16;
2988
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
2989
                    } else {
2990
                        if (i & 0x40)
2991
                            i |= 0x780;
2992
                        else
2993
                            i |= 0x800;
2994
                        n |= i << 19;
2995
                        tcg_gen_movi_i32(cpu_F0s, n);
2996
                    }
2997
                    break;
2998
                case 15: /* extension space */
2999
                    switch (rn) {
3000
                    case 0: /* cpy */
3001
                        /* no-op */
3002
                        break;
3003
                    case 1: /* abs */
3004
                        gen_vfp_abs(dp);
3005
                        break;
3006
                    case 2: /* neg */
3007
                        gen_vfp_neg(dp);
3008
                        break;
3009
                    case 3: /* sqrt */
3010
                        gen_vfp_sqrt(dp);
3011
                        break;
3012
                    case 4: /* vcvtb.f32.f16 */
3013
                        tmp = gen_vfp_mrs();
3014
                        tcg_gen_ext16u_i32(tmp, tmp);
3015
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3016
                        tcg_temp_free_i32(tmp);
3017
                        break;
3018
                    case 5: /* vcvtt.f32.f16 */
3019
                        tmp = gen_vfp_mrs();
3020
                        tcg_gen_shri_i32(tmp, tmp, 16);
3021
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3022
                        tcg_temp_free_i32(tmp);
3023
                        break;
3024
                    case 6: /* vcvtb.f16.f32 */
3025
                        tmp = tcg_temp_new_i32();
3026
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3027
                        gen_mov_F0_vreg(0, rd);
3028
                        tmp2 = gen_vfp_mrs();
3029
                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3030
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3031
                        tcg_temp_free_i32(tmp2);
3032
                        gen_vfp_msr(tmp);
3033
                        break;
3034
                    case 7: /* vcvtt.f16.f32 */
3035
                        tmp = tcg_temp_new_i32();
3036
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3037
                        tcg_gen_shli_i32(tmp, tmp, 16);
3038
                        gen_mov_F0_vreg(0, rd);
3039
                        tmp2 = gen_vfp_mrs();
3040
                        tcg_gen_ext16u_i32(tmp2, tmp2);
3041
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3042
                        tcg_temp_free_i32(tmp2);
3043
                        gen_vfp_msr(tmp);
3044
                        break;
3045
                    case 8: /* cmp */
3046
                        gen_vfp_cmp(dp);
3047
                        break;
3048
                    case 9: /* cmpe */
3049
                        gen_vfp_cmpe(dp);
3050
                        break;
3051
                    case 10: /* cmpz */
3052
                        gen_vfp_cmp(dp);
3053
                        break;
3054
                    case 11: /* cmpez */
3055
                        gen_vfp_F1_ld0(dp);
3056
                        gen_vfp_cmpe(dp);
3057
                        break;
3058
                    case 15: /* single<->double conversion */
3059
                        if (dp)
3060
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3061
                        else
3062
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3063
                        break;
3064
                    case 16: /* fuito */
3065
                        gen_vfp_uito(dp, 0);
3066
                        break;
3067
                    case 17: /* fsito */
3068
                        gen_vfp_sito(dp, 0);
3069
                        break;
3070
                    case 20: /* fshto */
3071
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3072
                          return 1;
3073
                        gen_vfp_shto(dp, 16 - rm, 0);
3074
                        break;
3075
                    case 21: /* fslto */
3076
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3077
                          return 1;
3078
                        gen_vfp_slto(dp, 32 - rm, 0);
3079
                        break;
3080
                    case 22: /* fuhto */
3081
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3082
                          return 1;
3083
                        gen_vfp_uhto(dp, 16 - rm, 0);
3084
                        break;
3085
                    case 23: /* fulto */
3086
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3087
                          return 1;
3088
                        gen_vfp_ulto(dp, 32 - rm, 0);
3089
                        break;
3090
                    case 24: /* ftoui */
3091
                        gen_vfp_toui(dp, 0);
3092
                        break;
3093
                    case 25: /* ftouiz */
3094
                        gen_vfp_touiz(dp, 0);
3095
                        break;
3096
                    case 26: /* ftosi */
3097
                        gen_vfp_tosi(dp, 0);
3098
                        break;
3099
                    case 27: /* ftosiz */
3100
                        gen_vfp_tosiz(dp, 0);
3101
                        break;
3102
                    case 28: /* ftosh */
3103
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3104
                          return 1;
3105
                        gen_vfp_tosh(dp, 16 - rm, 0);
3106
                        break;
3107
                    case 29: /* ftosl */
3108
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3109
                          return 1;
3110
                        gen_vfp_tosl(dp, 32 - rm, 0);
3111
                        break;
3112
                    case 30: /* ftouh */
3113
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3114
                          return 1;
3115
                        gen_vfp_touh(dp, 16 - rm, 0);
3116
                        break;
3117
                    case 31: /* ftoul */
3118
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3119
                          return 1;
3120
                        gen_vfp_toul(dp, 32 - rm, 0);
3121
                        break;
3122
                    default: /* undefined */
3123
                        return 1;
3124
                    }
3125
                    break;
3126
                default: /* undefined */
3127
                    return 1;
3128
                }
3129

    
3130
                /* Write back the result.  */
3131
                if (op == 15 && (rn >= 8 && rn <= 11))
3132
                    ; /* Comparison, do nothing.  */
3133
                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3134
                    /* VCVT double to int: always integer result. */
3135
                    gen_mov_vreg_F0(0, rd);
3136
                else if (op == 15 && rn == 15)
3137
                    /* conversion */
3138
                    gen_mov_vreg_F0(!dp, rd);
3139
                else
3140
                    gen_mov_vreg_F0(dp, rd);
3141

    
3142
                /* break out of the loop if we have finished  */
3143
                if (veclen == 0)
3144
                    break;
3145

    
3146
                if (op == 15 && delta_m == 0) {
3147
                    /* single source one-many */
3148
                    while (veclen--) {
3149
                        rd = ((rd + delta_d) & (bank_mask - 1))
3150
                             | (rd & bank_mask);
3151
                        gen_mov_vreg_F0(dp, rd);
3152
                    }
3153
                    break;
3154
                }
3155
                /* Setup the next operands.  */
3156
                veclen--;
3157
                rd = ((rd + delta_d) & (bank_mask - 1))
3158
                     | (rd & bank_mask);
3159

    
3160
                if (op == 15) {
3161
                    /* One source operand.  */
3162
                    rm = ((rm + delta_m) & (bank_mask - 1))
3163
                         | (rm & bank_mask);
3164
                    gen_mov_F0_vreg(dp, rm);
3165
                } else {
3166
                    /* Two source operands.  */
3167
                    rn = ((rn + delta_d) & (bank_mask - 1))
3168
                         | (rn & bank_mask);
3169
                    gen_mov_F0_vreg(dp, rn);
3170
                    if (delta_m) {
3171
                        rm = ((rm + delta_m) & (bank_mask - 1))
3172
                             | (rm & bank_mask);
3173
                        gen_mov_F1_vreg(dp, rm);
3174
                    }
3175
                }
3176
            }
3177
        }
3178
        break;
3179
    case 0xc:
3180
    case 0xd:
3181
        if ((insn & 0x03e00000) == 0x00400000) {
3182
            /* two-register transfer */
3183
            rn = (insn >> 16) & 0xf;
3184
            rd = (insn >> 12) & 0xf;
3185
            if (dp) {
3186
                VFP_DREG_M(rm, insn);
3187
            } else {
3188
                rm = VFP_SREG_M(insn);
3189
            }
3190

    
3191
            if (insn & ARM_CP_RW_BIT) {
3192
                /* vfp->arm */
3193
                if (dp) {
3194
                    gen_mov_F0_vreg(0, rm * 2);
3195
                    tmp = gen_vfp_mrs();
3196
                    store_reg(s, rd, tmp);
3197
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3198
                    tmp = gen_vfp_mrs();
3199
                    store_reg(s, rn, tmp);
3200
                } else {
3201
                    gen_mov_F0_vreg(0, rm);
3202
                    tmp = gen_vfp_mrs();
3203
                    store_reg(s, rd, tmp);
3204
                    gen_mov_F0_vreg(0, rm + 1);
3205
                    tmp = gen_vfp_mrs();
3206
                    store_reg(s, rn, tmp);
3207
                }
3208
            } else {
3209
                /* arm->vfp */
3210
                if (dp) {
3211
                    tmp = load_reg(s, rd);
3212
                    gen_vfp_msr(tmp);
3213
                    gen_mov_vreg_F0(0, rm * 2);
3214
                    tmp = load_reg(s, rn);
3215
                    gen_vfp_msr(tmp);
3216
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3217
                } else {
3218
                    tmp = load_reg(s, rd);
3219
                    gen_vfp_msr(tmp);
3220
                    gen_mov_vreg_F0(0, rm);
3221
                    tmp = load_reg(s, rn);
3222
                    gen_vfp_msr(tmp);
3223
                    gen_mov_vreg_F0(0, rm + 1);
3224
                }
3225
            }
3226
        } else {
3227
            /* Load/store */
3228
            rn = (insn >> 16) & 0xf;
3229
            if (dp)
3230
                VFP_DREG_D(rd, insn);
3231
            else
3232
                rd = VFP_SREG_D(insn);
3233
            if ((insn & 0x01200000) == 0x01000000) {
3234
                /* Single load/store */
3235
                offset = (insn & 0xff) << 2;
3236
                if ((insn & (1 << 23)) == 0)
3237
                    offset = -offset;
3238
                if (s->thumb && rn == 15) {
3239
                    /* This is actually UNPREDICTABLE */
3240
                    addr = tcg_temp_new_i32();
3241
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3242
                } else {
3243
                    addr = load_reg(s, rn);
3244
                }
3245
                tcg_gen_addi_i32(addr, addr, offset);
3246
                if (insn & (1 << 20)) {
3247
                    gen_vfp_ld(s, dp, addr);
3248
                    gen_mov_vreg_F0(dp, rd);
3249
                } else {
3250
                    gen_mov_F0_vreg(dp, rd);
3251
                    gen_vfp_st(s, dp, addr);
3252
                }
3253
                tcg_temp_free_i32(addr);
3254
            } else {
3255
                /* load/store multiple */
3256
                int w = insn & (1 << 21);
3257
                if (dp)
3258
                    n = (insn >> 1) & 0x7f;
3259
                else
3260
                    n = insn & 0xff;
3261

    
3262
                if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3263
                    /* P == U , W == 1  => UNDEF */
3264
                    return 1;
3265
                }
3266
                if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3267
                    /* UNPREDICTABLE cases for bad immediates: we choose to
3268
                     * UNDEF to avoid generating huge numbers of TCG ops
3269
                     */
3270
                    return 1;
3271
                }
3272
                if (rn == 15 && w) {
3273
                    /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3274
                    return 1;
3275
                }
3276

    
3277
                if (s->thumb && rn == 15) {
3278
                    /* This is actually UNPREDICTABLE */
3279
                    addr = tcg_temp_new_i32();
3280
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3281
                } else {
3282
                    addr = load_reg(s, rn);
3283
                }
3284
                if (insn & (1 << 24)) /* pre-decrement */
3285
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3286

    
3287
                if (dp)
3288
                    offset = 8;
3289
                else
3290
                    offset = 4;
3291
                for (i = 0; i < n; i++) {
3292
                    if (insn & ARM_CP_RW_BIT) {
3293
                        /* load */
3294
                        gen_vfp_ld(s, dp, addr);
3295
                        gen_mov_vreg_F0(dp, rd + i);
3296
                    } else {
3297
                        /* store */
3298
                        gen_mov_F0_vreg(dp, rd + i);
3299
                        gen_vfp_st(s, dp, addr);
3300
                    }
3301
                    tcg_gen_addi_i32(addr, addr, offset);
3302
                }
3303
                if (w) {
3304
                    /* writeback */
3305
                    if (insn & (1 << 24))
3306
                        offset = -offset * n;
3307
                    else if (dp && (insn & 1))
3308
                        offset = 4;
3309
                    else
3310
                        offset = 0;
3311

    
3312
                    if (offset != 0)
3313
                        tcg_gen_addi_i32(addr, addr, offset);
3314
                    store_reg(s, rn, addr);
3315
                } else {
3316
                    tcg_temp_free_i32(addr);
3317
                }
3318
            }
3319
        }
3320
        break;
3321
    default:
3322
        /* Should never happen.  */
3323
        return 1;
3324
    }
3325
    return 0;
3326
}
3327

    
3328
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3329
{
3330
    TranslationBlock *tb;
3331

    
3332
    tb = s->tb;
3333
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3334
        tcg_gen_goto_tb(n);
3335
        gen_set_pc_im(dest);
3336
        tcg_gen_exit_tb((tcg_target_long)tb + n);
3337
    } else {
3338
        gen_set_pc_im(dest);
3339
        tcg_gen_exit_tb(0);
3340
    }
3341
}
3342

    
3343
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3344
{
3345
    if (unlikely(s->singlestep_enabled)) {
3346
        /* An indirect jump so that we still trigger the debug exception.  */
3347
        if (s->thumb)
3348
            dest |= 1;
3349
        gen_bx_im(s, dest);
3350
    } else {
3351
        gen_goto_tb(s, 0, dest);
3352
        s->is_jmp = DISAS_TB_JUMP;
3353
    }
3354
}
3355

    
3356
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3357
{
3358
    if (x)
3359
        tcg_gen_sari_i32(t0, t0, 16);
3360
    else
3361
        gen_sxth(t0);
3362
    if (y)
3363
        tcg_gen_sari_i32(t1, t1, 16);
3364
    else
3365
        gen_sxth(t1);
3366
    tcg_gen_mul_i32(t0, t0, t1);
3367
}
3368

    
3369
/* Return the mask of PSR bits set by a MSR instruction.  */
3370
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3371
    uint32_t mask;
3372

    
3373
    mask = 0;
3374
    if (flags & (1 << 0))
3375
        mask |= 0xff;
3376
    if (flags & (1 << 1))
3377
        mask |= 0xff00;
3378
    if (flags & (1 << 2))
3379
        mask |= 0xff0000;
3380
    if (flags & (1 << 3))
3381
        mask |= 0xff000000;
3382

    
3383
    /* Mask out undefined bits.  */
3384
    mask &= ~CPSR_RESERVED;
3385
    if (!arm_feature(env, ARM_FEATURE_V4T))
3386
        mask &= ~CPSR_T;
3387
    if (!arm_feature(env, ARM_FEATURE_V5))
3388
        mask &= ~CPSR_Q; /* V5TE in reality*/
3389
    if (!arm_feature(env, ARM_FEATURE_V6))
3390
        mask &= ~(CPSR_E | CPSR_GE);
3391
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3392
        mask &= ~CPSR_IT;
3393
    /* Mask out execution state bits.  */
3394
    if (!spsr)
3395
        mask &= ~CPSR_EXEC;
3396
    /* Mask out privileged bits.  */
3397
    if (IS_USER(s))
3398
        mask &= CPSR_USER;
3399
    return mask;
3400
}
3401

    
3402
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3403
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3404
{
3405
    TCGv tmp;
3406
    if (spsr) {
3407
        /* ??? This is also undefined in system mode.  */
3408
        if (IS_USER(s))
3409
            return 1;
3410

    
3411
        tmp = load_cpu_field(spsr);
3412
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3413
        tcg_gen_andi_i32(t0, t0, mask);
3414
        tcg_gen_or_i32(tmp, tmp, t0);
3415
        store_cpu_field(tmp, spsr);
3416
    } else {
3417
        gen_set_cpsr(t0, mask);
3418
    }
3419
    tcg_temp_free_i32(t0);
3420
    gen_lookup_tb(s);
3421
    return 0;
3422
}
3423

    
3424
/* Returns nonzero if access to the PSR is not permitted.  */
3425
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3426
{
3427
    TCGv tmp;
3428
    tmp = tcg_temp_new_i32();
3429
    tcg_gen_movi_i32(tmp, val);
3430
    return gen_set_psr(s, mask, spsr, tmp);
3431
}
3432

    
3433
/* Generate an old-style exception return. Marks pc as dead. */
3434
static void gen_exception_return(DisasContext *s, TCGv pc)
3435
{
3436
    TCGv tmp;
3437
    store_reg(s, 15, pc);
3438
    tmp = load_cpu_field(spsr);
3439
    gen_set_cpsr(tmp, 0xffffffff);
3440
    tcg_temp_free_i32(tmp);
3441
    s->is_jmp = DISAS_UPDATE;
3442
}
3443

    
3444
/* Generate a v6 exception return.  Marks both values as dead.  */
3445
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3446
{
3447
    gen_set_cpsr(cpsr, 0xffffffff);
3448
    tcg_temp_free_i32(cpsr);
3449
    store_reg(s, 15, pc);
3450
    s->is_jmp = DISAS_UPDATE;
3451
}
3452

    
3453
static inline void
3454
gen_set_condexec (DisasContext *s)
3455
{
3456
    if (s->condexec_mask) {
3457
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3458
        TCGv tmp = tcg_temp_new_i32();
3459
        tcg_gen_movi_i32(tmp, val);
3460
        store_cpu_field(tmp, condexec_bits);
3461
    }
3462
}
3463

    
3464
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3465
{
3466
    gen_set_condexec(s);
3467
    gen_set_pc_im(s->pc - offset);
3468
    gen_exception(excp);
3469
    s->is_jmp = DISAS_JUMP;
3470
}
3471

    
3472
static void gen_nop_hint(DisasContext *s, int val)
3473
{
3474
    switch (val) {
3475
    case 3: /* wfi */
3476
        gen_set_pc_im(s->pc);
3477
        s->is_jmp = DISAS_WFI;
3478
        break;
3479
    case 2: /* wfe */
3480
    case 4: /* sev */
3481
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3482
    default: /* nop */
3483
        break;
3484
    }
3485
}
3486

    
3487
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3488

    
3489
static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
3490
{
3491
    switch (size) {
3492
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3493
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3494
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3495
    default: abort();
3496
    }
3497
}
3498

    
3499
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3500
{
3501
    switch (size) {
3502
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3503
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3504
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3505
    default: return;
3506
    }
3507
}
3508

    
3509
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3510
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3511
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3512
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3513
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3514

    
3515
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3516
    switch ((size << 1) | u) { \
3517
    case 0: \
3518
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3519
        break; \
3520
    case 1: \
3521
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3522
        break; \
3523
    case 2: \
3524
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3525
        break; \
3526
    case 3: \
3527
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3528
        break; \
3529
    case 4: \
3530
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3531
        break; \
3532
    case 5: \
3533
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3534
        break; \
3535
    default: return 1; \
3536
    }} while (0)
3537

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

    
3561
static TCGv neon_load_scratch(int scratch)
3562
{
3563
    TCGv tmp = tcg_temp_new_i32();
3564
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3565
    return tmp;
3566
}
3567

    
3568
static void neon_store_scratch(int scratch, TCGv var)
3569
{
3570
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3571
    tcg_temp_free_i32(var);
3572
}
3573

    
3574
static inline TCGv neon_get_scalar(int size, int reg)
3575
{
3576
    TCGv tmp;
3577
    if (size == 1) {
3578
        tmp = neon_load_reg(reg & 7, reg >> 4);
3579
        if (reg & 8) {
3580
            gen_neon_dup_high16(tmp);
3581
        } else {
3582
            gen_neon_dup_low16(tmp);
3583
        }
3584
    } else {
3585
        tmp = neon_load_reg(reg & 15, reg >> 4);
3586
    }
3587
    return tmp;
3588
}
3589

    
3590
static int gen_neon_unzip(int rd, int rm, int size, int q)
3591
{
3592
    TCGv tmp, tmp2;
3593
    if (!q && size == 2) {
3594
        return 1;
3595
    }
3596
    tmp = tcg_const_i32(rd);
3597
    tmp2 = tcg_const_i32(rm);
3598
    if (q) {
3599
        switch (size) {
3600
        case 0:
3601
            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3602
            break;
3603
        case 1:
3604
            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3605
            break;
3606
        case 2:
3607
            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3608
            break;
3609
        default:
3610
            abort();
3611
        }
3612
    } else {
3613
        switch (size) {
3614
        case 0:
3615
            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3616
            break;
3617
        case 1:
3618
            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3619
            break;
3620
        default:
3621
            abort();
3622
        }
3623
    }
3624
    tcg_temp_free_i32(tmp);
3625
    tcg_temp_free_i32(tmp2);
3626
    return 0;
3627
}
3628

    
3629
static int gen_neon_zip(int rd, int rm, int size, int q)
3630
{
3631
    TCGv tmp, tmp2;
3632
    if (!q && size == 2) {
3633
        return 1;
3634
    }
3635
    tmp = tcg_const_i32(rd);
3636
    tmp2 = tcg_const_i32(rm);
3637
    if (q) {
3638
        switch (size) {
3639
        case 0:
3640
            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3641
            break;
3642
        case 1:
3643
            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3644
            break;
3645
        case 2:
3646
            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3647
            break;
3648
        default:
3649
            abort();
3650
        }
3651
    } else {
3652
        switch (size) {
3653
        case 0:
3654
            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3655
            break;
3656
        case 1:
3657
            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3658
            break;
3659
        default:
3660
            abort();
3661
        }
3662
    }
3663
    tcg_temp_free_i32(tmp);
3664
    tcg_temp_free_i32(tmp2);
3665
    return 0;
3666
}
3667

    
3668
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3669
{
3670
    TCGv rd, tmp;
3671

    
3672
    rd = tcg_temp_new_i32();
3673
    tmp = tcg_temp_new_i32();
3674

    
3675
    tcg_gen_shli_i32(rd, t0, 8);
3676
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3677
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3678
    tcg_gen_or_i32(rd, rd, tmp);
3679

    
3680
    tcg_gen_shri_i32(t1, t1, 8);
3681
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3682
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3683
    tcg_gen_or_i32(t1, t1, tmp);
3684
    tcg_gen_mov_i32(t0, rd);
3685

    
3686
    tcg_temp_free_i32(tmp);
3687
    tcg_temp_free_i32(rd);
3688
}
3689

    
3690
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3691
{
3692
    TCGv rd, tmp;
3693

    
3694
    rd = tcg_temp_new_i32();
3695
    tmp = tcg_temp_new_i32();
3696

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

    
3705
    tcg_temp_free_i32(tmp);
3706
    tcg_temp_free_i32(rd);
3707
}
3708

    
3709

    
3710
static struct {
3711
    int nregs;
3712
    int interleave;
3713
    int spacing;
3714
} neon_ls_element_type[11] = {
3715
    {4, 4, 1},
3716
    {4, 4, 2},
3717
    {4, 1, 1},
3718
    {4, 2, 1},
3719
    {3, 3, 1},
3720
    {3, 3, 2},
3721
    {3, 1, 1},
3722
    {1, 1, 1},
3723
    {2, 2, 1},
3724
    {2, 2, 2},
3725
    {2, 1, 1}
3726
};
3727

    
3728
/* Translate a NEON load/store element instruction.  Return nonzero if the
3729
   instruction is invalid.  */
3730
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
3731
{
3732
    int rd, rn, rm;
3733
    int op;
3734
    int nregs;
3735
    int interleave;
3736
    int spacing;
3737
    int stride;
3738
    int size;
3739
    int reg;
3740
    int pass;
3741
    int load;
3742
    int shift;
3743
    int n;
3744
    TCGv addr;
3745
    TCGv tmp;
3746
    TCGv tmp2;
3747
    TCGv_i64 tmp64;
3748

    
3749
    if (!s->vfp_enabled)
3750
      return 1;
3751
    VFP_DREG_D(rd, insn);
3752
    rn = (insn >> 16) & 0xf;
3753
    rm = insn & 0xf;
3754
    load = (insn & (1 << 21)) != 0;
3755
    if ((insn & (1 << 23)) == 0) {
3756
        /* Load store all elements.  */
3757
        op = (insn >> 8) & 0xf;
3758
        size = (insn >> 6) & 3;
3759
        if (op > 10)
3760
            return 1;
3761
        /* Catch UNDEF cases for bad values of align field */
3762
        switch (op & 0xc) {
3763
        case 4:
3764
            if (((insn >> 5) & 1) == 1) {
3765
                return 1;
3766
            }
3767
            break;
3768
        case 8:
3769
            if (((insn >> 4) & 3) == 3) {
3770
                return 1;
3771
            }
3772
            break;
3773
        default:
3774
            break;
3775
        }
3776
        nregs = neon_ls_element_type[op].nregs;
3777
        interleave = neon_ls_element_type[op].interleave;
3778
        spacing = neon_ls_element_type[op].spacing;
3779
        if (size == 3 && (interleave | spacing) != 1)
3780
            return 1;
3781
        addr = tcg_temp_new_i32();
3782
        load_reg_var(s, addr, rn);
3783
        stride = (1 << size) * interleave;
3784
        for (reg = 0; reg < nregs; reg++) {
3785
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3786
                load_reg_var(s, addr, rn);
3787
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3788
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3789
                load_reg_var(s, addr, rn);
3790
                tcg_gen_addi_i32(addr, addr, 1 << size);
3791
            }
3792
            if (size == 3) {
3793
                if (load) {
3794
                    tmp64 = gen_ld64(addr, IS_USER(s));
3795
                    neon_store_reg64(tmp64, rd);
3796
                    tcg_temp_free_i64(tmp64);
3797
                } else {
3798
                    tmp64 = tcg_temp_new_i64();
3799
                    neon_load_reg64(tmp64, rd);
3800
                    gen_st64(tmp64, addr, IS_USER(s));
3801
                }
3802
                tcg_gen_addi_i32(addr, addr, stride);
3803
            } else {
3804
                for (pass = 0; pass < 2; pass++) {
3805
                    if (size == 2) {
3806
                        if (load) {
3807
                            tmp = gen_ld32(addr, IS_USER(s));
3808
                            neon_store_reg(rd, pass, tmp);
3809
                        } else {
3810
                            tmp = neon_load_reg(rd, pass);
3811
                            gen_st32(tmp, addr, IS_USER(s));
3812
                        }
3813
                        tcg_gen_addi_i32(addr, addr, stride);
3814
                    } else if (size == 1) {
3815
                        if (load) {
3816
                            tmp = gen_ld16u(addr, IS_USER(s));
3817
                            tcg_gen_addi_i32(addr, addr, stride);
3818
                            tmp2 = gen_ld16u(addr, IS_USER(s));
3819
                            tcg_gen_addi_i32(addr, addr, stride);
3820
                            tcg_gen_shli_i32(tmp2, tmp2, 16);
3821
                            tcg_gen_or_i32(tmp, tmp, tmp2);
3822
                            tcg_temp_free_i32(tmp2);
3823
                            neon_store_reg(rd, pass, tmp);
3824
                        } else {
3825
                            tmp = neon_load_reg(rd, pass);
3826
                            tmp2 = tcg_temp_new_i32();
3827
                            tcg_gen_shri_i32(tmp2, tmp, 16);
3828
                            gen_st16(tmp, addr, IS_USER(s));
3829
                            tcg_gen_addi_i32(addr, addr, stride);
3830
                            gen_st16(tmp2, addr, IS_USER(s));
3831
                            tcg_gen_addi_i32(addr, addr, stride);
3832
                        }
3833
                    } else /* size == 0 */ {
3834
                        if (load) {
3835
                            TCGV_UNUSED(tmp2);
3836
                            for (n = 0; n < 4; n++) {
3837
                                tmp = gen_ld8u(addr, IS_USER(s));
3838
                                tcg_gen_addi_i32(addr, addr, stride);
3839
                                if (n == 0) {
3840
                                    tmp2 = tmp;
3841
                                } else {
3842
                                    tcg_gen_shli_i32(tmp, tmp, n * 8);
3843
                                    tcg_gen_or_i32(tmp2, tmp2, tmp);
3844
                                    tcg_temp_free_i32(tmp);
3845
                                }
3846
                            }
3847
                            neon_store_reg(rd, pass, tmp2);
3848
                        } else {
3849
                            tmp2 = neon_load_reg(rd, pass);
3850
                            for (n = 0; n < 4; n++) {
3851
                                tmp = tcg_temp_new_i32();
3852
                                if (n == 0) {
3853
                                    tcg_gen_mov_i32(tmp, tmp2);
3854
                                } else {
3855
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
3856
                                }
3857
                                gen_st8(tmp, addr, IS_USER(s));
3858
                                tcg_gen_addi_i32(addr, addr, stride);
3859
                            }
3860
                            tcg_temp_free_i32(tmp2);
3861
                        }
3862
                    }
3863
                }
3864
            }
3865
            rd += spacing;
3866
        }
3867
        tcg_temp_free_i32(addr);
3868
        stride = nregs * 8;
3869
    } else {
3870
        size = (insn >> 10) & 3;
3871
        if (size == 3) {
3872
            /* Load single element to all lanes.  */
3873
            int a = (insn >> 4) & 1;
3874
            if (!load) {
3875
                return 1;
3876
            }
3877
            size = (insn >> 6) & 3;
3878
            nregs = ((insn >> 8) & 3) + 1;
3879

    
3880
            if (size == 3) {
3881
                if (nregs != 4 || a == 0) {
3882
                    return 1;
3883
                }
3884
                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3885
                size = 2;
3886
            }
3887
            if (nregs == 1 && a == 1 && size == 0) {
3888
                return 1;
3889
            }
3890
            if (nregs == 3 && a == 1) {
3891
                return 1;
3892
            }
3893
            addr = tcg_temp_new_i32();
3894
            load_reg_var(s, addr, rn);
3895
            if (nregs == 1) {
3896
                /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3897
                tmp = gen_load_and_replicate(s, addr, size);
3898
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
3899
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
3900
                if (insn & (1 << 5)) {
3901
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
3902
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
3903
                }
3904
                tcg_temp_free_i32(tmp);
3905
            } else {
3906
                /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3907
                stride = (insn & (1 << 5)) ? 2 : 1;
3908
                for (reg = 0; reg < nregs; reg++) {
3909
                    tmp = gen_load_and_replicate(s, addr, size);
3910
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
3911
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
3912
                    tcg_temp_free_i32(tmp);
3913
                    tcg_gen_addi_i32(addr, addr, 1 << size);
3914
                    rd += stride;
3915
                }
3916
            }
3917
            tcg_temp_free_i32(addr);
3918
            stride = (1 << size) * nregs;
3919
        } else {
3920
            /* Single element.  */
3921
            int idx = (insn >> 4) & 0xf;
3922
            pass = (insn >> 7) & 1;
3923
            switch (size) {
3924
            case 0:
3925
                shift = ((insn >> 5) & 3) * 8;
3926
                stride = 1;
3927
                break;
3928
            case 1:
3929
                shift = ((insn >> 6) & 1) * 16;
3930
                stride = (insn & (1 << 5)) ? 2 : 1;
3931
                break;
3932
            case 2:
3933
                shift = 0;
3934
                stride = (insn & (1 << 6)) ? 2 : 1;
3935
                break;
3936
            default:
3937
                abort();
3938
            }
3939
            nregs = ((insn >> 8) & 3) + 1;
3940
            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3941
            switch (nregs) {
3942
            case 1:
3943
                if (((idx & (1 << size)) != 0) ||
3944
                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3945
                    return 1;
3946
                }
3947
                break;
3948
            case 3:
3949
                if ((idx & 1) != 0) {
3950
                    return 1;
3951
                }
3952
                /* fall through */
3953
            case 2:
3954
                if (size == 2 && (idx & 2) != 0) {
3955
                    return 1;
3956
                }
3957
                break;
3958
            case 4:
3959
                if ((size == 2) && ((idx & 3) == 3)) {
3960
                    return 1;
3961
                }
3962
                break;
3963
            default:
3964
                abort();
3965
            }
3966
            if ((rd + stride * (nregs - 1)) > 31) {
3967
                /* Attempts to write off the end of the register file
3968
                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3969
                 * the neon_load_reg() would write off the end of the array.
3970
                 */
3971
                return 1;
3972
            }
3973
            addr = tcg_temp_new_i32();
3974
            load_reg_var(s, addr, rn);
3975
            for (reg = 0; reg < nregs; reg++) {
3976
                if (load) {
3977
                    switch (size) {
3978
                    case 0:
3979
                        tmp = gen_ld8u(addr, IS_USER(s));
3980
                        break;
3981
                    case 1:
3982
                        tmp = gen_ld16u(addr, IS_USER(s));
3983
                        break;
3984
                    case 2:
3985
                        tmp = gen_ld32(addr, IS_USER(s));
3986
                        break;
3987
                    default: /* Avoid compiler warnings.  */
3988
                        abort();
3989
                    }
3990
                    if (size != 2) {
3991
                        tmp2 = neon_load_reg(rd, pass);
3992
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3993
                        tcg_temp_free_i32(tmp2);
3994
                    }
3995
                    neon_store_reg(rd, pass, tmp);
3996
                } else { /* Store */
3997
                    tmp = neon_load_reg(rd, pass);
3998
                    if (shift)
3999
                        tcg_gen_shri_i32(tmp, tmp, shift);
4000
                    switch (size) {
4001
                    case 0:
4002
                        gen_st8(tmp, addr, IS_USER(s));
4003
                        break;
4004
                    case 1:
4005
                        gen_st16(tmp, addr, IS_USER(s));
4006
                        break;
4007
                    case 2:
4008
                        gen_st32(tmp, addr, IS_USER(s));
4009
                        break;
4010
                    }
4011
                }
4012
                rd += stride;
4013
                tcg_gen_addi_i32(addr, addr, 1 << size);
4014
            }
4015
            tcg_temp_free_i32(addr);
4016
            stride = nregs * (1 << size);
4017
        }
4018
    }
4019
    if (rm != 15) {
4020
        TCGv base;
4021

    
4022
        base = load_reg(s, rn);
4023
        if (rm == 13) {
4024
            tcg_gen_addi_i32(base, base, stride);
4025
        } else {
4026
            TCGv index;
4027
            index = load_reg(s, rm);
4028
            tcg_gen_add_i32(base, base, index);
4029
            tcg_temp_free_i32(index);
4030
        }
4031
        store_reg(s, rn, base);
4032
    }
4033
    return 0;
4034
}
4035

    
4036
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4037
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4038
{
4039
    tcg_gen_and_i32(t, t, c);
4040
    tcg_gen_andc_i32(f, f, c);
4041
    tcg_gen_or_i32(dest, t, f);
4042
}
4043

    
4044
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4045
{
4046
    switch (size) {
4047
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4048
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4049
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4050
    default: abort();
4051
    }
4052
}
4053

    
4054
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4055
{
4056
    switch (size) {
4057
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4058
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4059
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4060
    default: abort();
4061
    }
4062
}
4063

    
4064
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4065
{
4066
    switch (size) {
4067
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4068
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4069
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4070
    default: abort();
4071
    }
4072
}
4073

    
4074
static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4075
{
4076
    switch (size) {
4077
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4078
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4079
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4080
    default: abort();
4081
    }
4082
}
4083

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

    
4118
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4119
{
4120
    if (u) {
4121
        switch (size) {
4122
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4123
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4124
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4125
        default: abort();
4126
        }
4127
    } else {
4128
        switch (size) {
4129
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4130
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4131
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4132
        default: abort();
4133
        }
4134
    }
4135
    tcg_temp_free_i32(src);
4136
}
4137

    
4138
static inline void gen_neon_addl(int size)
4139
{
4140
    switch (size) {
4141
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4142
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4143
    case 2: tcg_gen_add_i64(CPU_V001); break;
4144
    default: abort();
4145
    }
4146
}
4147

    
4148
static inline void gen_neon_subl(int size)
4149
{
4150
    switch (size) {
4151
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4152
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4153
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4154
    default: abort();
4155
    }
4156
}
4157

    
4158
static inline void gen_neon_negl(TCGv_i64 var, int size)
4159
{
4160
    switch (size) {
4161
    case 0: gen_helper_neon_negl_u16(var, var); break;
4162
    case 1: gen_helper_neon_negl_u32(var, var); break;
4163
    case 2: gen_helper_neon_negl_u64(var, var); break;
4164
    default: abort();
4165
    }
4166
}
4167

    
4168
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4169
{
4170
    switch (size) {
4171
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4172
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4173
    default: abort();
4174
    }
4175
}
4176

    
4177
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4178
{
4179
    TCGv_i64 tmp;
4180

    
4181
    switch ((size << 1) | u) {
4182
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4183
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4184
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4185
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4186
    case 4:
4187
        tmp = gen_muls_i64_i32(a, b);
4188
        tcg_gen_mov_i64(dest, tmp);
4189
        tcg_temp_free_i64(tmp);
4190
        break;
4191
    case 5:
4192
        tmp = gen_mulu_i64_i32(a, b);
4193
        tcg_gen_mov_i64(dest, tmp);
4194
        tcg_temp_free_i64(tmp);
4195
        break;
4196
    default: abort();
4197
    }
4198

    
4199
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4200
       Don't forget to clean them now.  */
4201
    if (size < 2) {
4202
        tcg_temp_free_i32(a);
4203
        tcg_temp_free_i32(b);
4204
    }
4205
}
4206

    
4207
static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
4208
{
4209
    if (op) {
4210
        if (u) {
4211
            gen_neon_unarrow_sats(size, dest, src);
4212
        } else {
4213
            gen_neon_narrow(size, dest, src);
4214
        }
4215
    } else {
4216
        if (u) {
4217
            gen_neon_narrow_satu(size, dest, src);
4218
        } else {
4219
            gen_neon_narrow_sats(size, dest, src);
4220
        }
4221
    }
4222
}
4223

    
4224
/* Symbolic constants for op fields for Neon 3-register same-length.
4225
 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4226
 * table A7-9.
4227
 */
4228
#define NEON_3R_VHADD 0
4229
#define NEON_3R_VQADD 1
4230
#define NEON_3R_VRHADD 2
4231
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4232
#define NEON_3R_VHSUB 4
4233
#define NEON_3R_VQSUB 5
4234
#define NEON_3R_VCGT 6
4235
#define NEON_3R_VCGE 7
4236
#define NEON_3R_VSHL 8
4237
#define NEON_3R_VQSHL 9
4238
#define NEON_3R_VRSHL 10
4239
#define NEON_3R_VQRSHL 11
4240
#define NEON_3R_VMAX 12
4241
#define NEON_3R_VMIN 13
4242
#define NEON_3R_VABD 14
4243
#define NEON_3R_VABA 15
4244
#define NEON_3R_VADD_VSUB 16
4245
#define NEON_3R_VTST_VCEQ 17
4246
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4247
#define NEON_3R_VMUL 19
4248
#define NEON_3R_VPMAX 20
4249
#define NEON_3R_VPMIN 21
4250
#define NEON_3R_VQDMULH_VQRDMULH 22
4251
#define NEON_3R_VPADD 23
4252
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4253
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4254
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4255
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4256
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4257
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4258
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4259

    
4260
static const uint8_t neon_3r_sizes[] = {
4261
    [NEON_3R_VHADD] = 0x7,
4262
    [NEON_3R_VQADD] = 0xf,
4263
    [NEON_3R_VRHADD] = 0x7,
4264
    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4265
    [NEON_3R_VHSUB] = 0x7,
4266
    [NEON_3R_VQSUB] = 0xf,
4267
    [NEON_3R_VCGT] = 0x7,
4268
    [NEON_3R_VCGE] = 0x7,
4269
    [NEON_3R_VSHL] = 0xf,
4270
    [NEON_3R_VQSHL] = 0xf,
4271
    [NEON_3R_VRSHL] = 0xf,
4272
    [NEON_3R_VQRSHL] = 0xf,
4273
    [NEON_3R_VMAX] = 0x7,
4274
    [NEON_3R_VMIN] = 0x7,
4275
    [NEON_3R_VABD] = 0x7,
4276
    [NEON_3R_VABA] = 0x7,
4277
    [NEON_3R_VADD_VSUB] = 0xf,
4278
    [NEON_3R_VTST_VCEQ] = 0x7,
4279
    [NEON_3R_VML] = 0x7,
4280
    [NEON_3R_VMUL] = 0x7,
4281
    [NEON_3R_VPMAX] = 0x7,
4282
    [NEON_3R_VPMIN] = 0x7,
4283
    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4284
    [NEON_3R_VPADD] = 0x7,
4285
    [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4286
    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4287
    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4288
    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4289
    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4290
    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4291
    [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4292
};
4293

    
4294
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4295
 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4296
 * table A7-13.
4297
 */
4298
#define NEON_2RM_VREV64 0
4299
#define NEON_2RM_VREV32 1
4300
#define NEON_2RM_VREV16 2
4301
#define NEON_2RM_VPADDL 4
4302
#define NEON_2RM_VPADDL_U 5
4303
#define NEON_2RM_VCLS 8
4304
#define NEON_2RM_VCLZ 9
4305
#define NEON_2RM_VCNT 10
4306
#define NEON_2RM_VMVN 11
4307
#define NEON_2RM_VPADAL 12
4308
#define NEON_2RM_VPADAL_U 13
4309
#define NEON_2RM_VQABS 14
4310
#define NEON_2RM_VQNEG 15
4311
#define NEON_2RM_VCGT0 16
4312
#define NEON_2RM_VCGE0 17
4313
#define NEON_2RM_VCEQ0 18
4314
#define NEON_2RM_VCLE0 19
4315
#define NEON_2RM_VCLT0 20
4316
#define NEON_2RM_VABS 22
4317
#define NEON_2RM_VNEG 23
4318
#define NEON_2RM_VCGT0_F 24
4319
#define NEON_2RM_VCGE0_F 25
4320
#define NEON_2RM_VCEQ0_F 26
4321
#define NEON_2RM_VCLE0_F 27
4322
#define NEON_2RM_VCLT0_F 28
4323
#define NEON_2RM_VABS_F 30
4324
#define NEON_2RM_VNEG_F 31
4325
#define NEON_2RM_VSWP 32
4326
#define NEON_2RM_VTRN 33
4327
#define NEON_2RM_VUZP 34
4328
#define NEON_2RM_VZIP 35
4329
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4330
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4331
#define NEON_2RM_VSHLL 38
4332
#define NEON_2RM_VCVT_F16_F32 44
4333
#define NEON_2RM_VCVT_F32_F16 46
4334
#define NEON_2RM_VRECPE 56
4335
#define NEON_2RM_VRSQRTE 57
4336
#define NEON_2RM_VRECPE_F 58
4337
#define NEON_2RM_VRSQRTE_F 59
4338
#define NEON_2RM_VCVT_FS 60
4339
#define NEON_2RM_VCVT_FU 61
4340
#define NEON_2RM_VCVT_SF 62
4341
#define NEON_2RM_VCVT_UF 63
4342

    
4343
static int neon_2rm_is_float_op(int op)
4344
{
4345
    /* Return true if this neon 2reg-misc op is float-to-float */
4346
    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4347
            op >= NEON_2RM_VRECPE_F);
4348
}
4349

    
4350
/* Each entry in this array has bit n set if the insn allows
4351
 * size value n (otherwise it will UNDEF). Since unallocated
4352
 * op values will have no bits set they always UNDEF.
4353
 */
4354
static const uint8_t neon_2rm_sizes[] = {
4355
    [NEON_2RM_VREV64] = 0x7,
4356
    [NEON_2RM_VREV32] = 0x3,
4357
    [NEON_2RM_VREV16] = 0x1,
4358
    [NEON_2RM_VPADDL] = 0x7,
4359
    [NEON_2RM_VPADDL_U] = 0x7,
4360
    [NEON_2RM_VCLS] = 0x7,
4361
    [NEON_2RM_VCLZ] = 0x7,
4362
    [NEON_2RM_VCNT] = 0x1,
4363
    [NEON_2RM_VMVN] = 0x1,
4364
    [NEON_2RM_VPADAL] = 0x7,
4365
    [NEON_2RM_VPADAL_U] = 0x7,
4366
    [NEON_2RM_VQABS] = 0x7,
4367
    [NEON_2RM_VQNEG] = 0x7,
4368
    [NEON_2RM_VCGT0] = 0x7,
4369
    [NEON_2RM_VCGE0] = 0x7,
4370
    [NEON_2RM_VCEQ0] = 0x7,
4371
    [NEON_2RM_VCLE0] = 0x7,
4372
    [NEON_2RM_VCLT0] = 0x7,
4373
    [NEON_2RM_VABS] = 0x7,
4374
    [NEON_2RM_VNEG] = 0x7,
4375
    [NEON_2RM_VCGT0_F] = 0x4,
4376
    [NEON_2RM_VCGE0_F] = 0x4,
4377
    [NEON_2RM_VCEQ0_F] = 0x4,
4378
    [NEON_2RM_VCLE0_F] = 0x4,
4379
    [NEON_2RM_VCLT0_F] = 0x4,
4380
    [NEON_2RM_VABS_F] = 0x4,
4381
    [NEON_2RM_VNEG_F] = 0x4,
4382
    [NEON_2RM_VSWP] = 0x1,
4383
    [NEON_2RM_VTRN] = 0x7,
4384
    [NEON_2RM_VUZP] = 0x7,
4385
    [NEON_2RM_VZIP] = 0x7,
4386
    [NEON_2RM_VMOVN] = 0x7,
4387
    [NEON_2RM_VQMOVN] = 0x7,
4388
    [NEON_2RM_VSHLL] = 0x7,
4389
    [NEON_2RM_VCVT_F16_F32] = 0x2,
4390
    [NEON_2RM_VCVT_F32_F16] = 0x2,
4391
    [NEON_2RM_VRECPE] = 0x4,
4392
    [NEON_2RM_VRSQRTE] = 0x4,
4393
    [NEON_2RM_VRECPE_F] = 0x4,
4394
    [NEON_2RM_VRSQRTE_F] = 0x4,
4395
    [NEON_2RM_VCVT_FS] = 0x4,
4396
    [NEON_2RM_VCVT_FU] = 0x4,
4397
    [NEON_2RM_VCVT_SF] = 0x4,
4398
    [NEON_2RM_VCVT_UF] = 0x4,
4399
};
4400

    
4401
/* Translate a NEON data processing instruction.  Return nonzero if the
4402
   instruction is invalid.
4403
   We process data in a mixture of 32-bit and 64-bit chunks.
4404
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4405

    
4406
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4407
{
4408
    int op;
4409
    int q;
4410
    int rd, rn, rm;
4411
    int size;
4412
    int shift;
4413
    int pass;
4414
    int count;
4415
    int pairwise;
4416
    int u;
4417
    uint32_t imm, mask;
4418
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4419
    TCGv_i64 tmp64;
4420

    
4421
    if (!s->vfp_enabled)
4422
      return 1;
4423
    q = (insn & (1 << 6)) != 0;
4424
    u = (insn >> 24) & 1;
4425
    VFP_DREG_D(rd, insn);
4426
    VFP_DREG_N(rn, insn);
4427
    VFP_DREG_M(rm, insn);
4428
    size = (insn >> 20) & 3;
4429
    if ((insn & (1 << 23)) == 0) {
4430
        /* Three register same length.  */
4431
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4432
        /* Catch invalid op and bad size combinations: UNDEF */
4433
        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4434
            return 1;
4435
        }
4436
        /* All insns of this form UNDEF for either this condition or the
4437
         * superset of cases "Q==1"; we catch the latter later.
4438
         */
4439
        if (q && ((rd | rn | rm) & 1)) {
4440
            return 1;
4441
        }
4442
        if (size == 3 && op != NEON_3R_LOGIC) {
4443
            /* 64-bit element instructions. */
4444
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4445
                neon_load_reg64(cpu_V0, rn + pass);
4446
                neon_load_reg64(cpu_V1, rm + pass);
4447
                switch (op) {
4448
                case NEON_3R_VQADD:
4449
                    if (u) {
4450
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4451
                                                 cpu_V0, cpu_V1);
4452
                    } else {
4453
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4454
                                                 cpu_V0, cpu_V1);
4455
                    }
4456
                    break;
4457
                case NEON_3R_VQSUB:
4458
                    if (u) {
4459
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4460
                                                 cpu_V0, cpu_V1);
4461
                    } else {
4462
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4463
                                                 cpu_V0, cpu_V1);
4464
                    }
4465
                    break;
4466
                case NEON_3R_VSHL:
4467
                    if (u) {
4468
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4469
                    } else {
4470
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4471
                    }
4472
                    break;
4473
                case NEON_3R_VQSHL:
4474
                    if (u) {
4475
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4476
                                                 cpu_V1, cpu_V0);
4477
                    } else {
4478
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4479
                                                 cpu_V1, cpu_V0);
4480
                    }
4481
                    break;
4482
                case NEON_3R_VRSHL:
4483
                    if (u) {
4484
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4485
                    } else {
4486
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4487
                    }
4488
                    break;
4489
                case NEON_3R_VQRSHL:
4490
                    if (u) {
4491
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4492
                                                  cpu_V1, cpu_V0);
4493
                    } else {
4494
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4495
                                                  cpu_V1, cpu_V0);
4496
                    }
4497
                    break;
4498
                case NEON_3R_VADD_VSUB:
4499
                    if (u) {
4500
                        tcg_gen_sub_i64(CPU_V001);
4501
                    } else {
4502
                        tcg_gen_add_i64(CPU_V001);
4503
                    }
4504
                    break;
4505
                default:
4506
                    abort();
4507
                }
4508
                neon_store_reg64(cpu_V0, rd + pass);
4509
            }
4510
            return 0;
4511
        }
4512
        pairwise = 0;
4513
        switch (op) {
4514
        case NEON_3R_VSHL:
4515
        case NEON_3R_VQSHL:
4516
        case NEON_3R_VRSHL:
4517
        case NEON_3R_VQRSHL:
4518
            {
4519
                int rtmp;
4520
                /* Shift instruction operands are reversed.  */
4521
                rtmp = rn;
4522
                rn = rm;
4523
                rm = rtmp;
4524
            }
4525
            break;
4526
        case NEON_3R_VPADD:
4527
            if (u) {
4528
                return 1;
4529
            }
4530
            /* Fall through */
4531
        case NEON_3R_VPMAX:
4532
        case NEON_3R_VPMIN:
4533
            pairwise = 1;
4534
            break;
4535
        case NEON_3R_FLOAT_ARITH:
4536
            pairwise = (u && size < 2); /* if VPADD (float) */
4537
            break;
4538
        case NEON_3R_FLOAT_MINMAX:
4539
            pairwise = u; /* if VPMIN/VPMAX (float) */
4540
            break;
4541
        case NEON_3R_FLOAT_CMP:
4542
            if (!u && size) {
4543
                /* no encoding for U=0 C=1x */
4544
                return 1;
4545
            }
4546
            break;
4547
        case NEON_3R_FLOAT_ACMP:
4548
            if (!u) {
4549
                return 1;
4550
            }
4551
            break;
4552
        case NEON_3R_VRECPS_VRSQRTS:
4553
            if (u) {
4554
                return 1;
4555
            }
4556
            break;
4557
        case NEON_3R_VMUL:
4558
            if (u && (size != 0)) {
4559
                /* UNDEF on invalid size for polynomial subcase */
4560
                return 1;
4561
            }
4562
            break;
4563
        case NEON_3R_VFM:
4564
            if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4565
                return 1;
4566
            }
4567
            break;
4568
        default:
4569
            break;
4570
        }
4571

    
4572
        if (pairwise && q) {
4573
            /* All the pairwise insns UNDEF if Q is set */
4574
            return 1;
4575
        }
4576

    
4577
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4578

    
4579
        if (pairwise) {
4580
            /* Pairwise.  */
4581
            if (pass < 1) {
4582
                tmp = neon_load_reg(rn, 0);
4583
                tmp2 = neon_load_reg(rn, 1);
4584
            } else {
4585
                tmp = neon_load_reg(rm, 0);
4586
                tmp2 = neon_load_reg(rm, 1);
4587
            }
4588
        } else {
4589
            /* Elementwise.  */
4590
            tmp = neon_load_reg(rn, pass);
4591
            tmp2 = neon_load_reg(rm, pass);
4592
        }
4593
        switch (op) {
4594
        case NEON_3R_VHADD:
4595
            GEN_NEON_INTEGER_OP(hadd);
4596
            break;
4597
        case NEON_3R_VQADD:
4598
            GEN_NEON_INTEGER_OP_ENV(qadd);
4599
            break;
4600
        case NEON_3R_VRHADD:
4601
            GEN_NEON_INTEGER_OP(rhadd);
4602
            break;
4603
        case NEON_3R_LOGIC: /* Logic ops.  */
4604
            switch ((u << 2) | size) {
4605
            case 0: /* VAND */
4606
                tcg_gen_and_i32(tmp, tmp, tmp2);
4607
                break;
4608
            case 1: /* BIC */
4609
                tcg_gen_andc_i32(tmp, tmp, tmp2);
4610
                break;
4611
            case 2: /* VORR */
4612
                tcg_gen_or_i32(tmp, tmp, tmp2);
4613
                break;
4614
            case 3: /* VORN */
4615
                tcg_gen_orc_i32(tmp, tmp, tmp2);
4616
                break;
4617
            case 4: /* VEOR */
4618
                tcg_gen_xor_i32(tmp, tmp, tmp2);
4619
                break;
4620
            case 5: /* VBSL */
4621
                tmp3 = neon_load_reg(rd, pass);
4622
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4623
                tcg_temp_free_i32(tmp3);
4624
                break;
4625
            case 6: /* VBIT */
4626
                tmp3 = neon_load_reg(rd, pass);
4627
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4628
                tcg_temp_free_i32(tmp3);
4629
                break;
4630
            case 7: /* VBIF */
4631
                tmp3 = neon_load_reg(rd, pass);
4632
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4633
                tcg_temp_free_i32(tmp3);
4634
                break;
4635
            }
4636
            break;
4637
        case NEON_3R_VHSUB:
4638
            GEN_NEON_INTEGER_OP(hsub);
4639
            break;
4640
        case NEON_3R_VQSUB:
4641
            GEN_NEON_INTEGER_OP_ENV(qsub);
4642
            break;
4643
        case NEON_3R_VCGT:
4644
            GEN_NEON_INTEGER_OP(cgt);
4645
            break;
4646
        case NEON_3R_VCGE:
4647
            GEN_NEON_INTEGER_OP(cge);
4648
            break;
4649
        case NEON_3R_VSHL:
4650
            GEN_NEON_INTEGER_OP(shl);
4651
            break;
4652
        case NEON_3R_VQSHL:
4653
            GEN_NEON_INTEGER_OP_ENV(qshl);
4654
            break;
4655
        case NEON_3R_VRSHL:
4656
            GEN_NEON_INTEGER_OP(rshl);
4657
            break;
4658
        case NEON_3R_VQRSHL:
4659
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4660
            break;
4661
        case NEON_3R_VMAX:
4662
            GEN_NEON_INTEGER_OP(max);
4663
            break;
4664
        case NEON_3R_VMIN:
4665
            GEN_NEON_INTEGER_OP(min);
4666
            break;
4667
        case NEON_3R_VABD:
4668
            GEN_NEON_INTEGER_OP(abd);
4669
            break;
4670
        case NEON_3R_VABA:
4671
            GEN_NEON_INTEGER_OP(abd);
4672
            tcg_temp_free_i32(tmp2);
4673
            tmp2 = neon_load_reg(rd, pass);
4674
            gen_neon_add(size, tmp, tmp2);
4675
            break;
4676
        case NEON_3R_VADD_VSUB:
4677
            if (!u) { /* VADD */
4678
                gen_neon_add(size, tmp, tmp2);
4679
            } else { /* VSUB */
4680
                switch (size) {
4681
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4682
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4683
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4684
                default: abort();
4685
                }
4686
            }
4687
            break;
4688
        case NEON_3R_VTST_VCEQ:
4689
            if (!u) { /* VTST */
4690
                switch (size) {
4691
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4692
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4693
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4694
                default: abort();
4695
                }
4696
            } else { /* VCEQ */
4697
                switch (size) {
4698
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4699
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4700
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4701
                default: abort();
4702
                }
4703
            }
4704
            break;
4705
        case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4706
            switch (size) {
4707
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4708
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4709
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4710
            default: abort();
4711
            }
4712
            tcg_temp_free_i32(tmp2);
4713
            tmp2 = neon_load_reg(rd, pass);
4714
            if (u) { /* VMLS */
4715
                gen_neon_rsb(size, tmp, tmp2);
4716
            } else { /* VMLA */
4717
                gen_neon_add(size, tmp, tmp2);
4718
            }
4719
            break;
4720
        case NEON_3R_VMUL:
4721
            if (u) { /* polynomial */
4722
                gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4723
            } else { /* Integer */
4724
                switch (size) {
4725
                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4726
                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4727
                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4728
                default: abort();
4729
                }
4730
            }
4731
            break;
4732
        case NEON_3R_VPMAX:
4733
            GEN_NEON_INTEGER_OP(pmax);
4734
            break;
4735
        case NEON_3R_VPMIN:
4736
            GEN_NEON_INTEGER_OP(pmin);
4737
            break;
4738
        case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
4739
            if (!u) { /* VQDMULH */
4740
                switch (size) {
4741
                case 1:
4742
                    gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
4743
                    break;
4744
                case 2:
4745
                    gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
4746
                    break;
4747
                default: abort();
4748
                }
4749
            } else { /* VQRDMULH */
4750
                switch (size) {
4751
                case 1:
4752
                    gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
4753
                    break;
4754
                case 2:
4755
                    gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
4756
                    break;
4757
                default: abort();
4758
                }
4759
            }
4760
            break;
4761
        case NEON_3R_VPADD:
4762
            switch (size) {
4763
            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4764
            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4765
            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4766
            default: abort();
4767
            }
4768
            break;
4769
        case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
4770
        {
4771
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4772
            switch ((u << 2) | size) {
4773
            case 0: /* VADD */
4774
            case 4: /* VPADD */
4775
                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4776
                break;
4777
            case 2: /* VSUB */
4778
                gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
4779
                break;
4780
            case 6: /* VABD */
4781
                gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
4782
                break;
4783
            default:
4784
                abort();
4785
            }
4786
            tcg_temp_free_ptr(fpstatus);
4787
            break;
4788
        }
4789
        case NEON_3R_FLOAT_MULTIPLY:
4790
        {
4791
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4792
            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
4793
            if (!u) {
4794
                tcg_temp_free_i32(tmp2);
4795
                tmp2 = neon_load_reg(rd, pass);
4796
                if (size == 0) {
4797
                    gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4798
                } else {
4799
                    gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
4800
                }
4801
            }
4802
            tcg_temp_free_ptr(fpstatus);
4803
            break;
4804
        }
4805
        case NEON_3R_FLOAT_CMP:
4806
        {
4807
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4808
            if (!u) {
4809
                gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
4810
            } else {
4811
                if (size == 0) {
4812
                    gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
4813
                } else {
4814
                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
4815
                }
4816
            }
4817
            tcg_temp_free_ptr(fpstatus);
4818
            break;
4819
        }
4820
        case NEON_3R_FLOAT_ACMP:
4821
        {
4822
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4823
            if (size == 0) {
4824
                gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
4825
            } else {
4826
                gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
4827
            }
4828
            tcg_temp_free_ptr(fpstatus);
4829
            break;
4830
        }
4831
        case NEON_3R_FLOAT_MINMAX:
4832
        {
4833
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4834
            if (size == 0) {
4835
                gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
4836
            } else {
4837
                gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
4838
            }
4839
            tcg_temp_free_ptr(fpstatus);
4840
            break;
4841
        }
4842
        case NEON_3R_VRECPS_VRSQRTS:
4843
            if (size == 0)
4844
                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4845
            else
4846
                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4847
            break;
4848
        case NEON_3R_VFM:
4849
        {
4850
            /* VFMA, VFMS: fused multiply-add */
4851
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4852
            TCGv_i32 tmp3 = neon_load_reg(rd, pass);
4853
            if (size) {
4854
                /* VFMS */
4855
                gen_helper_vfp_negs(tmp, tmp);
4856
            }
4857
            gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
4858
            tcg_temp_free_i32(tmp3);
4859
            tcg_temp_free_ptr(fpstatus);
4860
            break;
4861
        }
4862
        default:
4863
            abort();
4864
        }
4865
        tcg_temp_free_i32(tmp2);
4866

    
4867
        /* Save the result.  For elementwise operations we can put it
4868
           straight into the destination register.  For pairwise operations
4869
           we have to be careful to avoid clobbering the source operands.  */
4870
        if (pairwise && rd == rm) {
4871
            neon_store_scratch(pass, tmp);
4872
        } else {
4873
            neon_store_reg(rd, pass, tmp);
4874
        }
4875

    
4876
        } /* for pass */
4877
        if (pairwise && rd == rm) {
4878
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4879
                tmp = neon_load_scratch(pass);
4880
                neon_store_reg(rd, pass, tmp);
4881
            }
4882
        }
4883
        /* End of 3 register same size operations.  */
4884
    } else if (insn & (1 << 4)) {
4885
        if ((insn & 0x00380080) != 0) {
4886
            /* Two registers and shift.  */
4887
            op = (insn >> 8) & 0xf;
4888
            if (insn & (1 << 7)) {
4889
                /* 64-bit shift. */
4890
                if (op > 7) {
4891
                    return 1;
4892
                }
4893
                size = 3;
4894
            } else {
4895
                size = 2;
4896
                while ((insn & (1 << (size + 19))) == 0)
4897
                    size--;
4898
            }
4899
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4900
            /* To avoid excessive dumplication of ops we implement shift
4901
               by immediate using the variable shift operations.  */
4902
            if (op < 8) {
4903
                /* Shift by immediate:
4904
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4905
                if (q && ((rd | rm) & 1)) {
4906
                    return 1;
4907
                }
4908
                if (!u && (op == 4 || op == 6)) {
4909
                    return 1;
4910
                }
4911
                /* Right shifts are encoded as N - shift, where N is the
4912
                   element size in bits.  */
4913
                if (op <= 4)
4914
                    shift = shift - (1 << (size + 3));
4915
                if (size == 3) {
4916
                    count = q + 1;
4917
                } else {
4918
                    count = q ? 4: 2;
4919
                }
4920
                switch (size) {
4921
                case 0:
4922
                    imm = (uint8_t) shift;
4923
                    imm |= imm << 8;
4924
                    imm |= imm << 16;
4925
                    break;
4926
                case 1:
4927
                    imm = (uint16_t) shift;
4928
                    imm |= imm << 16;
4929
                    break;
4930
                case 2:
4931
                case 3:
4932
                    imm = shift;
4933
                    break;
4934
                default:
4935
                    abort();
4936
                }
4937

    
4938
                for (pass = 0; pass < count; pass++) {
4939
                    if (size == 3) {
4940
                        neon_load_reg64(cpu_V0, rm + pass);
4941
                        tcg_gen_movi_i64(cpu_V1, imm);
4942
                        switch (op) {
4943
                        case 0:  /* VSHR */
4944
                        case 1:  /* VSRA */
4945
                            if (u)
4946
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4947
                            else
4948
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4949
                            break;
4950
                        case 2: /* VRSHR */
4951
                        case 3: /* VRSRA */
4952
                            if (u)
4953
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4954
                            else
4955
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4956
                            break;
4957
                        case 4: /* VSRI */
4958
                        case 5: /* VSHL, VSLI */
4959
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4960
                            break;
4961
                        case 6: /* VQSHLU */
4962
                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
4963
                                                      cpu_V0, cpu_V1);
4964
                            break;
4965
                        case 7: /* VQSHL */
4966
                            if (u) {
4967
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4968
                                                         cpu_V0, cpu_V1);
4969
                            } else {
4970
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4971
                                                         cpu_V0, cpu_V1);
4972
                            }
4973
                            break;
4974
                        }
4975
                        if (op == 1 || op == 3) {
4976
                            /* Accumulate.  */
4977
                            neon_load_reg64(cpu_V1, rd + pass);
4978
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4979
                        } else if (op == 4 || (op == 5 && u)) {
4980
                            /* Insert */
4981
                            neon_load_reg64(cpu_V1, rd + pass);
4982
                            uint64_t mask;
4983
                            if (shift < -63 || shift > 63) {
4984
                                mask = 0;
4985
                            } else {
4986
                                if (op == 4) {
4987
                                    mask = 0xffffffffffffffffull >> -shift;
4988
                                } else {
4989
                                    mask = 0xffffffffffffffffull << shift;
4990
                                }
4991
                            }
4992
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
4993
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4994
                        }
4995
                        neon_store_reg64(cpu_V0, rd + pass);
4996
                    } else { /* size < 3 */
4997
                        /* Operands in T0 and T1.  */
4998
                        tmp = neon_load_reg(rm, pass);
4999
                        tmp2 = tcg_temp_new_i32();
5000
                        tcg_gen_movi_i32(tmp2, imm);
5001
                        switch (op) {
5002
                        case 0:  /* VSHR */
5003
                        case 1:  /* VSRA */
5004
                            GEN_NEON_INTEGER_OP(shl);
5005
                            break;
5006
                        case 2: /* VRSHR */
5007
                        case 3: /* VRSRA */
5008
                            GEN_NEON_INTEGER_OP(rshl);
5009
                            break;
5010
                        case 4: /* VSRI */
5011
                        case 5: /* VSHL, VSLI */
5012
                            switch (size) {
5013
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5014
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5015
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5016
                            default: abort();
5017
                            }
5018
                            break;
5019
                        case 6: /* VQSHLU */
5020
                            switch (size) {
5021
                            case 0:
5022
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
5023
                                                         tmp, tmp2);
5024
                                break;
5025
                            case 1:
5026
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
5027
                                                          tmp, tmp2);
5028
                                break;
5029
                            case 2:
5030
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
5031
                                                          tmp, tmp2);
5032
                                break;
5033
                            default:
5034
                                abort();
5035
                            }
5036
                            break;
5037
                        case 7: /* VQSHL */
5038
                            GEN_NEON_INTEGER_OP_ENV(qshl);
5039
                            break;
5040
                        }
5041
                        tcg_temp_free_i32(tmp2);
5042

    
5043
                        if (op == 1 || op == 3) {
5044
                            /* Accumulate.  */
5045
                            tmp2 = neon_load_reg(rd, pass);
5046
                            gen_neon_add(size, tmp, tmp2);
5047
                            tcg_temp_free_i32(tmp2);
5048
                        } else if (op == 4 || (op == 5 && u)) {
5049
                            /* Insert */
5050
                            switch (size) {
5051
                            case 0:
5052
                                if (op == 4)
5053
                                    mask = 0xff >> -shift;
5054
                                else
5055
                                    mask = (uint8_t)(0xff << shift);
5056
                                mask |= mask << 8;
5057
                                mask |= mask << 16;
5058
                                break;
5059
                            case 1:
5060
                                if (op == 4)
5061
                                    mask = 0xffff >> -shift;
5062
                                else
5063
                                    mask = (uint16_t)(0xffff << shift);
5064
                                mask |= mask << 16;
5065
                                break;
5066
                            case 2:
5067
                                if (shift < -31 || shift > 31) {
5068
                                    mask = 0;
5069
                                } else {
5070
                                    if (op == 4)
5071
                                        mask = 0xffffffffu >> -shift;
5072
                                    else
5073
                                        mask = 0xffffffffu << shift;
5074
                                }
5075
                                break;
5076
                            default:
5077
                                abort();
5078
                            }
5079
                            tmp2 = neon_load_reg(rd, pass);
5080
                            tcg_gen_andi_i32(tmp, tmp, mask);
5081
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5082
                            tcg_gen_or_i32(tmp, tmp, tmp2);
5083
                            tcg_temp_free_i32(tmp2);
5084
                        }
5085
                        neon_store_reg(rd, pass, tmp);
5086
                    }
5087
                } /* for pass */
5088
            } else if (op < 10) {
5089
                /* Shift by immediate and narrow:
5090
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
5091
                int input_unsigned = (op == 8) ? !u : u;
5092
                if (rm & 1) {
5093
                    return 1;
5094
                }
5095
                shift = shift - (1 << (size + 3));
5096
                size++;
5097
                if (size == 3) {
5098
                    tmp64 = tcg_const_i64(shift);
5099
                    neon_load_reg64(cpu_V0, rm);
5100
                    neon_load_reg64(cpu_V1, rm + 1);
5101
                    for (pass = 0; pass < 2; pass++) {
5102
                        TCGv_i64 in;
5103
                        if (pass == 0) {
5104
                            in = cpu_V0;
5105
                        } else {
5106
                            in = cpu_V1;
5107
                        }
5108
                        if (q) {
5109
                            if (input_unsigned) {
5110
                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5111
                            } else {
5112
                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5113
                            }
5114
                        } else {
5115
                            if (input_unsigned) {
5116
                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5117
                            } else {
5118
                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5119
                            }
5120
                        }
5121
                        tmp = tcg_temp_new_i32();
5122
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5123
                        neon_store_reg(rd, pass, tmp);
5124
                    } /* for pass */
5125
                    tcg_temp_free_i64(tmp64);
5126
                } else {
5127
                    if (size == 1) {
5128
                        imm = (uint16_t)shift;
5129
                        imm |= imm << 16;
5130
                    } else {
5131
                        /* size == 2 */
5132
                        imm = (uint32_t)shift;
5133
                    }
5134
                    tmp2 = tcg_const_i32(imm);
5135
                    tmp4 = neon_load_reg(rm + 1, 0);
5136
                    tmp5 = neon_load_reg(rm + 1, 1);
5137
                    for (pass = 0; pass < 2; pass++) {
5138
                        if (pass == 0) {
5139
                            tmp = neon_load_reg(rm, 0);
5140
                        } else {
5141
                            tmp = tmp4;
5142
                        }
5143
                        gen_neon_shift_narrow(size, tmp, tmp2, q,
5144
                                              input_unsigned);
5145
                        if (pass == 0) {
5146
                            tmp3 = neon_load_reg(rm, 1);
5147
                        } else {
5148
                            tmp3 = tmp5;
5149
                        }
5150
                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
5151
                                              input_unsigned);
5152
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5153
                        tcg_temp_free_i32(tmp);
5154
                        tcg_temp_free_i32(tmp3);
5155
                        tmp = tcg_temp_new_i32();
5156
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5157
                        neon_store_reg(rd, pass, tmp);
5158
                    } /* for pass */
5159
                    tcg_temp_free_i32(tmp2);
5160
                }
5161
            } else if (op == 10) {
5162
                /* VSHLL, VMOVL */
5163
                if (q || (rd & 1)) {
5164
                    return 1;
5165
                }
5166
                tmp = neon_load_reg(rm, 0);
5167
                tmp2 = neon_load_reg(rm, 1);
5168
                for (pass = 0; pass < 2; pass++) {
5169
                    if (pass == 1)
5170
                        tmp = tmp2;
5171

    
5172
                    gen_neon_widen(cpu_V0, tmp, size, u);
5173

    
5174
                    if (shift != 0) {
5175
                        /* The shift is less than the width of the source
5176
                           type, so we can just shift the whole register.  */
5177
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5178
                        /* Widen the result of shift: we need to clear
5179
                         * the potential overflow bits resulting from
5180
                         * left bits of the narrow input appearing as
5181
                         * right bits of left the neighbour narrow
5182
                         * input.  */
5183
                        if (size < 2 || !u) {
5184
                            uint64_t imm64;
5185
                            if (size == 0) {
5186
                                imm = (0xffu >> (8 - shift));
5187
                                imm |= imm << 16;
5188
                            } else if (size == 1) {
5189
                                imm = 0xffff >> (16 - shift);
5190
                            } else {
5191
                                /* size == 2 */
5192
                                imm = 0xffffffff >> (32 - shift);
5193
                            }
5194
                            if (size < 2) {
5195
                                imm64 = imm | (((uint64_t)imm) << 32);
5196
                            } else {
5197
                                imm64 = imm;
5198
                            }
5199
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5200
                        }
5201
                    }
5202
                    neon_store_reg64(cpu_V0, rd + pass);
5203
                }
5204
            } else if (op >= 14) {
5205
                /* VCVT fixed-point.  */
5206
                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5207
                    return 1;
5208
                }
5209
                /* We have already masked out the must-be-1 top bit of imm6,
5210
                 * hence this 32-shift where the ARM ARM has 64-imm6.
5211
                 */
5212
                shift = 32 - shift;
5213
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5214
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5215
                    if (!(op & 1)) {
5216
                        if (u)
5217
                            gen_vfp_ulto(0, shift, 1);
5218
                        else
5219
                            gen_vfp_slto(0, shift, 1);
5220
                    } else {
5221
                        if (u)
5222
                            gen_vfp_toul(0, shift, 1);
5223
                        else
5224
                            gen_vfp_tosl(0, shift, 1);
5225
                    }
5226
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5227
                }
5228
            } else {
5229
                return 1;
5230
            }
5231
        } else { /* (insn & 0x00380080) == 0 */
5232
            int invert;
5233
            if (q && (rd & 1)) {
5234
                return 1;
5235
            }
5236

    
5237
            op = (insn >> 8) & 0xf;
5238
            /* One register and immediate.  */
5239
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5240
            invert = (insn & (1 << 5)) != 0;
5241
            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5242
             * We choose to not special-case this and will behave as if a
5243
             * valid constant encoding of 0 had been given.
5244
             */
5245
            switch (op) {
5246
            case 0: case 1:
5247
                /* no-op */
5248
                break;
5249
            case 2: case 3:
5250
                imm <<= 8;
5251
                break;
5252
            case 4: case 5:
5253
                imm <<= 16;
5254
                break;
5255
            case 6: case 7:
5256
                imm <<= 24;
5257
                break;
5258
            case 8: case 9:
5259
                imm |= imm << 16;
5260
                break;
5261
            case 10: case 11:
5262
                imm = (imm << 8) | (imm << 24);
5263
                break;
5264
            case 12:
5265
                imm = (imm << 8) | 0xff;
5266
                break;
5267
            case 13:
5268
                imm = (imm << 16) | 0xffff;
5269
                break;
5270
            case 14:
5271
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
5272
                if (invert)
5273
                    imm = ~imm;
5274
                break;
5275
            case 15:
5276
                if (invert) {
5277
                    return 1;
5278
                }
5279
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5280
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5281
                break;
5282
            }
5283
            if (invert)
5284
                imm = ~imm;
5285

    
5286
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5287
                if (op & 1 && op < 12) {
5288
                    tmp = neon_load_reg(rd, pass);
5289
                    if (invert) {
5290
                        /* The immediate value has already been inverted, so
5291
                           BIC becomes AND.  */
5292
                        tcg_gen_andi_i32(tmp, tmp, imm);
5293
                    } else {
5294
                        tcg_gen_ori_i32(tmp, tmp, imm);
5295
                    }
5296
                } else {
5297
                    /* VMOV, VMVN.  */
5298
                    tmp = tcg_temp_new_i32();
5299
                    if (op == 14 && invert) {
5300
                        int n;
5301
                        uint32_t val;
5302
                        val = 0;
5303
                        for (n = 0; n < 4; n++) {
5304
                            if (imm & (1 << (n + (pass & 1) * 4)))
5305
                                val |= 0xff << (n * 8);
5306
                        }
5307
                        tcg_gen_movi_i32(tmp, val);
5308
                    } else {
5309
                        tcg_gen_movi_i32(tmp, imm);
5310
                    }
5311
                }
5312
                neon_store_reg(rd, pass, tmp);
5313
            }
5314
        }
5315
    } else { /* (insn & 0x00800010 == 0x00800000) */
5316
        if (size != 3) {
5317
            op = (insn >> 8) & 0xf;
5318
            if ((insn & (1 << 6)) == 0) {
5319
                /* Three registers of different lengths.  */
5320
                int src1_wide;
5321
                int src2_wide;
5322
                int prewiden;
5323
                /* undefreq: bit 0 : UNDEF if size != 0
5324
                 *           bit 1 : UNDEF if size == 0
5325
                 *           bit 2 : UNDEF if U == 1
5326
                 * Note that [1:0] set implies 'always UNDEF'
5327
                 */
5328
                int undefreq;
5329
                /* prewiden, src1_wide, src2_wide, undefreq */
5330
                static const int neon_3reg_wide[16][4] = {
5331
                    {1, 0, 0, 0}, /* VADDL */
5332
                    {1, 1, 0, 0}, /* VADDW */
5333
                    {1, 0, 0, 0}, /* VSUBL */
5334
                    {1, 1, 0, 0}, /* VSUBW */
5335
                    {0, 1, 1, 0}, /* VADDHN */
5336
                    {0, 0, 0, 0}, /* VABAL */
5337
                    {0, 1, 1, 0}, /* VSUBHN */
5338
                    {0, 0, 0, 0}, /* VABDL */
5339
                    {0, 0, 0, 0}, /* VMLAL */
5340
                    {0, 0, 0, 6}, /* VQDMLAL */
5341
                    {0, 0, 0, 0}, /* VMLSL */
5342
                    {0, 0, 0, 6}, /* VQDMLSL */
5343
                    {0, 0, 0, 0}, /* Integer VMULL */
5344
                    {0, 0, 0, 2}, /* VQDMULL */
5345
                    {0, 0, 0, 5}, /* Polynomial VMULL */
5346
                    {0, 0, 0, 3}, /* Reserved: always UNDEF */
5347
                };
5348

    
5349
                prewiden = neon_3reg_wide[op][0];
5350
                src1_wide = neon_3reg_wide[op][1];
5351
                src2_wide = neon_3reg_wide[op][2];
5352
                undefreq = neon_3reg_wide[op][3];
5353

    
5354
                if (((undefreq & 1) && (size != 0)) ||
5355
                    ((undefreq & 2) && (size == 0)) ||
5356
                    ((undefreq & 4) && u)) {
5357
                    return 1;
5358
                }
5359
                if ((src1_wide && (rn & 1)) ||
5360
                    (src2_wide && (rm & 1)) ||
5361
                    (!src2_wide && (rd & 1))) {
5362
                    return 1;
5363
                }
5364

    
5365
                /* Avoid overlapping operands.  Wide source operands are
5366
                   always aligned so will never overlap with wide
5367
                   destinations in problematic ways.  */
5368
                if (rd == rm && !src2_wide) {
5369
                    tmp = neon_load_reg(rm, 1);
5370
                    neon_store_scratch(2, tmp);
5371
                } else if (rd == rn && !src1_wide) {
5372
                    tmp = neon_load_reg(rn, 1);
5373
                    neon_store_scratch(2, tmp);
5374
                }
5375
                TCGV_UNUSED(tmp3);
5376
                for (pass = 0; pass < 2; pass++) {
5377
                    if (src1_wide) {
5378
                        neon_load_reg64(cpu_V0, rn + pass);
5379
                        TCGV_UNUSED(tmp);
5380
                    } else {
5381
                        if (pass == 1 && rd == rn) {
5382
                            tmp = neon_load_scratch(2);
5383
                        } else {
5384
                            tmp = neon_load_reg(rn, pass);
5385
                        }
5386
                        if (prewiden) {
5387
                            gen_neon_widen(cpu_V0, tmp, size, u);
5388
                        }
5389
                    }
5390
                    if (src2_wide) {
5391
                        neon_load_reg64(cpu_V1, rm + pass);
5392
                        TCGV_UNUSED(tmp2);
5393
                    } else {
5394
                        if (pass == 1 && rd == rm) {
5395
                            tmp2 = neon_load_scratch(2);
5396
                        } else {
5397
                            tmp2 = neon_load_reg(rm, pass);
5398
                        }
5399
                        if (prewiden) {
5400
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5401
                        }
5402
                    }
5403
                    switch (op) {
5404
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5405
                        gen_neon_addl(size);
5406
                        break;
5407
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5408
                        gen_neon_subl(size);
5409
                        break;
5410
                    case 5: case 7: /* VABAL, VABDL */
5411
                        switch ((size << 1) | u) {
5412
                        case 0:
5413
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5414
                            break;
5415
                        case 1:
5416
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5417
                            break;
5418
                        case 2:
5419
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5420
                            break;
5421
                        case 3:
5422
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5423
                            break;
5424
                        case 4:
5425
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5426
                            break;
5427
                        case 5:
5428
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5429
                            break;
5430
                        default: abort();
5431
                        }
5432
                        tcg_temp_free_i32(tmp2);
5433
                        tcg_temp_free_i32(tmp);
5434
                        break;
5435
                    case 8: case 9: case 10: case 11: case 12: case 13:
5436
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5437
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5438
                        break;
5439
                    case 14: /* Polynomial VMULL */
5440
                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5441
                        tcg_temp_free_i32(tmp2);
5442
                        tcg_temp_free_i32(tmp);
5443
                        break;
5444
                    default: /* 15 is RESERVED: caught earlier  */
5445
                        abort();
5446
                    }
5447
                    if (op == 13) {
5448
                        /* VQDMULL */
5449
                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5450
                        neon_store_reg64(cpu_V0, rd + pass);
5451
                    } else if (op == 5 || (op >= 8 && op <= 11)) {
5452
                        /* Accumulate.  */
5453
                        neon_load_reg64(cpu_V1, rd + pass);
5454
                        switch (op) {
5455
                        case 10: /* VMLSL */
5456
                            gen_neon_negl(cpu_V0, size);
5457
                            /* Fall through */
5458
                        case 5: case 8: /* VABAL, VMLAL */
5459
                            gen_neon_addl(size);
5460
                            break;
5461
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5462
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5463
                            if (op == 11) {
5464
                                gen_neon_negl(cpu_V0, size);
5465
                            }
5466
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5467
                            break;
5468
                        default:
5469
                            abort();
5470
                        }
5471
                        neon_store_reg64(cpu_V0, rd + pass);
5472
                    } else if (op == 4 || op == 6) {
5473
                        /* Narrowing operation.  */
5474
                        tmp = tcg_temp_new_i32();
5475
                        if (!u) {
5476
                            switch (size) {
5477
                            case 0:
5478
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5479
                                break;
5480
                            case 1:
5481
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5482
                                break;
5483
                            case 2:
5484
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5485
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5486
                                break;
5487
                            default: abort();
5488
                            }
5489
                        } else {
5490
                            switch (size) {
5491
                            case 0:
5492
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5493
                                break;
5494
                            case 1:
5495
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5496
                                break;
5497
                            case 2:
5498
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5499
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5500
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5501
                                break;
5502
                            default: abort();
5503
                            }
5504
                        }
5505
                        if (pass == 0) {
5506
                            tmp3 = tmp;
5507
                        } else {
5508
                            neon_store_reg(rd, 0, tmp3);
5509
                            neon_store_reg(rd, 1, tmp);
5510
                        }
5511
                    } else {
5512
                        /* Write back the result.  */
5513
                        neon_store_reg64(cpu_V0, rd + pass);
5514
                    }
5515
                }
5516
            } else {
5517
                /* Two registers and a scalar. NB that for ops of this form
5518
                 * the ARM ARM labels bit 24 as Q, but it is in our variable
5519
                 * 'u', not 'q'.
5520
                 */
5521
                if (size == 0) {
5522
                    return 1;
5523
                }
5524
                switch (op) {
5525
                case 1: /* Float VMLA scalar */
5526
                case 5: /* Floating point VMLS scalar */
5527
                case 9: /* Floating point VMUL scalar */
5528
                    if (size == 1) {
5529
                        return 1;
5530
                    }
5531
                    /* fall through */
5532
                case 0: /* Integer VMLA scalar */
5533
                case 4: /* Integer VMLS scalar */
5534
                case 8: /* Integer VMUL scalar */
5535
                case 12: /* VQDMULH scalar */
5536
                case 13: /* VQRDMULH scalar */
5537
                    if (u && ((rd | rn) & 1)) {
5538
                        return 1;
5539
                    }
5540
                    tmp = neon_get_scalar(size, rm);
5541
                    neon_store_scratch(0, tmp);
5542
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5543
                        tmp = neon_load_scratch(0);
5544
                        tmp2 = neon_load_reg(rn, pass);
5545
                        if (op == 12) {
5546
                            if (size == 1) {
5547
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5548
                            } else {
5549
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5550
                            }
5551
                        } else if (op == 13) {
5552
                            if (size == 1) {
5553
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5554
                            } else {
5555
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5556
                            }
5557
                        } else if (op & 1) {
5558
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5559
                            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5560
                            tcg_temp_free_ptr(fpstatus);
5561
                        } else {
5562
                            switch (size) {
5563
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5564
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5565
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5566
                            default: abort();
5567
                            }
5568
                        }
5569
                        tcg_temp_free_i32(tmp2);
5570
                        if (op < 8) {
5571
                            /* Accumulate.  */
5572
                            tmp2 = neon_load_reg(rd, pass);
5573
                            switch (op) {
5574
                            case 0:
5575
                                gen_neon_add(size, tmp, tmp2);
5576
                                break;
5577
                            case 1:
5578
                            {
5579
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5580
                                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5581
                                tcg_temp_free_ptr(fpstatus);
5582
                                break;
5583
                            }
5584
                            case 4:
5585
                                gen_neon_rsb(size, tmp, tmp2);
5586
                                break;
5587
                            case 5:
5588
                            {
5589
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5590
                                gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5591
                                tcg_temp_free_ptr(fpstatus);
5592
                                break;
5593
                            }
5594
                            default:
5595
                                abort();
5596
                            }
5597
                            tcg_temp_free_i32(tmp2);
5598
                        }
5599
                        neon_store_reg(rd, pass, tmp);
5600
                    }
5601
                    break;
5602
                case 3: /* VQDMLAL scalar */
5603
                case 7: /* VQDMLSL scalar */
5604
                case 11: /* VQDMULL scalar */
5605
                    if (u == 1) {
5606
                        return 1;
5607
                    }
5608
                    /* fall through */
5609
                case 2: /* VMLAL sclar */
5610
                case 6: /* VMLSL scalar */
5611
                case 10: /* VMULL scalar */
5612
                    if (rd & 1) {
5613
                        return 1;
5614
                    }
5615
                    tmp2 = neon_get_scalar(size, rm);
5616
                    /* We need a copy of tmp2 because gen_neon_mull
5617
                     * deletes it during pass 0.  */
5618
                    tmp4 = tcg_temp_new_i32();
5619
                    tcg_gen_mov_i32(tmp4, tmp2);
5620
                    tmp3 = neon_load_reg(rn, 1);
5621

    
5622
                    for (pass = 0; pass < 2; pass++) {
5623
                        if (pass == 0) {
5624
                            tmp = neon_load_reg(rn, 0);
5625
                        } else {
5626
                            tmp = tmp3;
5627
                            tmp2 = tmp4;
5628
                        }
5629
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5630
                        if (op != 11) {
5631
                            neon_load_reg64(cpu_V1, rd + pass);
5632
                        }
5633
                        switch (op) {
5634
                        case 6:
5635
                            gen_neon_negl(cpu_V0, size);
5636
                            /* Fall through */
5637
                        case 2:
5638
                            gen_neon_addl(size);
5639
                            break;
5640
                        case 3: case 7:
5641
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5642
                            if (op == 7) {
5643
                                gen_neon_negl(cpu_V0, size);
5644
                            }
5645
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5646
                            break;
5647
                        case 10:
5648
                            /* no-op */
5649
                            break;
5650
                        case 11:
5651
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5652
                            break;
5653
                        default:
5654
                            abort();
5655
                        }
5656
                        neon_store_reg64(cpu_V0, rd + pass);
5657
                    }
5658

    
5659

    
5660
                    break;
5661
                default: /* 14 and 15 are RESERVED */
5662
                    return 1;
5663
                }
5664
            }
5665
        } else { /* size == 3 */
5666
            if (!u) {
5667
                /* Extract.  */
5668
                imm = (insn >> 8) & 0xf;
5669

    
5670
                if (imm > 7 && !q)
5671
                    return 1;
5672

    
5673
                if (q && ((rd | rn | rm) & 1)) {
5674
                    return 1;
5675
                }
5676

    
5677
                if (imm == 0) {
5678
                    neon_load_reg64(cpu_V0, rn);
5679
                    if (q) {
5680
                        neon_load_reg64(cpu_V1, rn + 1);
5681
                    }
5682
                } else if (imm == 8) {
5683
                    neon_load_reg64(cpu_V0, rn + 1);
5684
                    if (q) {
5685
                        neon_load_reg64(cpu_V1, rm);
5686
                    }
5687
                } else if (q) {
5688
                    tmp64 = tcg_temp_new_i64();
5689
                    if (imm < 8) {
5690
                        neon_load_reg64(cpu_V0, rn);
5691
                        neon_load_reg64(tmp64, rn + 1);
5692
                    } else {
5693
                        neon_load_reg64(cpu_V0, rn + 1);
5694
                        neon_load_reg64(tmp64, rm);
5695
                    }
5696
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5697
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5698
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5699
                    if (imm < 8) {
5700
                        neon_load_reg64(cpu_V1, rm);
5701
                    } else {
5702
                        neon_load_reg64(cpu_V1, rm + 1);
5703
                        imm -= 8;
5704
                    }
5705
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5706
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5707
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5708
                    tcg_temp_free_i64(tmp64);
5709
                } else {
5710
                    /* BUGFIX */
5711
                    neon_load_reg64(cpu_V0, rn);
5712
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5713
                    neon_load_reg64(cpu_V1, rm);
5714
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5715
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5716
                }
5717
                neon_store_reg64(cpu_V0, rd);
5718
                if (q) {
5719
                    neon_store_reg64(cpu_V1, rd + 1);
5720
                }
5721
            } else if ((insn & (1 << 11)) == 0) {
5722
                /* Two register misc.  */
5723
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5724
                size = (insn >> 18) & 3;
5725
                /* UNDEF for unknown op values and bad op-size combinations */
5726
                if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5727
                    return 1;
5728
                }
5729
                if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5730
                    q && ((rm | rd) & 1)) {
5731
                    return 1;
5732
                }
5733
                switch (op) {
5734
                case NEON_2RM_VREV64:
5735
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
5736
                        tmp = neon_load_reg(rm, pass * 2);
5737
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
5738
                        switch (size) {
5739
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5740
                        case 1: gen_swap_half(tmp); break;
5741
                        case 2: /* no-op */ break;
5742
                        default: abort();
5743
                        }
5744
                        neon_store_reg(rd, pass * 2 + 1, tmp);
5745
                        if (size == 2) {
5746
                            neon_store_reg(rd, pass * 2, tmp2);
5747
                        } else {
5748
                            switch (size) {
5749
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5750
                            case 1: gen_swap_half(tmp2); break;
5751
                            default: abort();
5752
                            }
5753
                            neon_store_reg(rd, pass * 2, tmp2);
5754
                        }
5755
                    }
5756
                    break;
5757
                case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5758
                case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5759
                    for (pass = 0; pass < q + 1; pass++) {
5760
                        tmp = neon_load_reg(rm, pass * 2);
5761
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
5762
                        tmp = neon_load_reg(rm, pass * 2 + 1);
5763
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
5764
                        switch (size) {
5765
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5766
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5767
                        case 2: tcg_gen_add_i64(CPU_V001); break;
5768
                        default: abort();
5769
                        }
5770
                        if (op >= NEON_2RM_VPADAL) {
5771
                            /* Accumulate.  */
5772
                            neon_load_reg64(cpu_V1, rd + pass);
5773
                            gen_neon_addl(size);
5774
                        }
5775
                        neon_store_reg64(cpu_V0, rd + pass);
5776
                    }
5777
                    break;
5778
                case NEON_2RM_VTRN:
5779
                    if (size == 2) {
5780
                        int n;
5781
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
5782
                            tmp = neon_load_reg(rm, n);
5783
                            tmp2 = neon_load_reg(rd, n + 1);
5784
                            neon_store_reg(rm, n, tmp2);
5785
                            neon_store_reg(rd, n + 1, tmp);
5786
                        }
5787
                    } else {
5788
                        goto elementwise;
5789
                    }
5790
                    break;
5791
                case NEON_2RM_VUZP:
5792
                    if (gen_neon_unzip(rd, rm, size, q)) {
5793
                        return 1;
5794
                    }
5795
                    break;
5796
                case NEON_2RM_VZIP:
5797
                    if (gen_neon_zip(rd, rm, size, q)) {
5798
                        return 1;
5799
                    }
5800
                    break;
5801
                case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5802
                    /* also VQMOVUN; op field and mnemonics don't line up */
5803
                    if (rm & 1) {
5804
                        return 1;
5805
                    }
5806
                    TCGV_UNUSED(tmp2);
5807
                    for (pass = 0; pass < 2; pass++) {
5808
                        neon_load_reg64(cpu_V0, rm + pass);
5809
                        tmp = tcg_temp_new_i32();
5810
                        gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5811
                                           tmp, cpu_V0);
5812
                        if (pass == 0) {
5813
                            tmp2 = tmp;
5814
                        } else {
5815
                            neon_store_reg(rd, 0, tmp2);
5816
                            neon_store_reg(rd, 1, tmp);
5817
                        }
5818
                    }
5819
                    break;
5820
                case NEON_2RM_VSHLL:
5821
                    if (q || (rd & 1)) {
5822
                        return 1;
5823
                    }
5824
                    tmp = neon_load_reg(rm, 0);
5825
                    tmp2 = neon_load_reg(rm, 1);
5826
                    for (pass = 0; pass < 2; pass++) {
5827
                        if (pass == 1)
5828
                            tmp = tmp2;
5829
                        gen_neon_widen(cpu_V0, tmp, size, 1);
5830
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5831
                        neon_store_reg64(cpu_V0, rd + pass);
5832
                    }
5833
                    break;
5834
                case NEON_2RM_VCVT_F16_F32:
5835
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5836
                        q || (rm & 1)) {
5837
                        return 1;
5838
                    }
5839
                    tmp = tcg_temp_new_i32();
5840
                    tmp2 = tcg_temp_new_i32();
5841
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5842
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5843
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5844
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5845
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5846
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5847
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5848
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5849
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5850
                    neon_store_reg(rd, 0, tmp2);
5851
                    tmp2 = tcg_temp_new_i32();
5852
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5853
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5854
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5855
                    neon_store_reg(rd, 1, tmp2);
5856
                    tcg_temp_free_i32(tmp);
5857
                    break;
5858
                case NEON_2RM_VCVT_F32_F16:
5859
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5860
                        q || (rd & 1)) {
5861
                        return 1;
5862
                    }
5863
                    tmp3 = tcg_temp_new_i32();
5864
                    tmp = neon_load_reg(rm, 0);
5865
                    tmp2 = neon_load_reg(rm, 1);
5866
                    tcg_gen_ext16u_i32(tmp3, tmp);
5867
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5868
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5869
                    tcg_gen_shri_i32(tmp3, tmp, 16);
5870
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5871
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5872
                    tcg_temp_free_i32(tmp);
5873
                    tcg_gen_ext16u_i32(tmp3, tmp2);
5874
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5875
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5876
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
5877
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5878
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5879
                    tcg_temp_free_i32(tmp2);
5880
                    tcg_temp_free_i32(tmp3);
5881
                    break;
5882
                default:
5883
                elementwise:
5884
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
5885
                        if (neon_2rm_is_float_op(op)) {
5886
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
5887
                                           neon_reg_offset(rm, pass));
5888
                            TCGV_UNUSED(tmp);
5889
                        } else {
5890
                            tmp = neon_load_reg(rm, pass);
5891
                        }
5892
                        switch (op) {
5893
                        case NEON_2RM_VREV32:
5894
                            switch (size) {
5895
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5896
                            case 1: gen_swap_half(tmp); break;
5897
                            default: abort();
5898
                            }
5899
                            break;
5900
                        case NEON_2RM_VREV16:
5901
                            gen_rev16(tmp);
5902
                            break;
5903
                        case NEON_2RM_VCLS:
5904
                            switch (size) {
5905
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5906
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5907
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5908
                            default: abort();
5909
                            }
5910
                            break;
5911
                        case NEON_2RM_VCLZ:
5912
                            switch (size) {
5913
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5914
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5915
                            case 2: gen_helper_clz(tmp, tmp); break;
5916
                            default: abort();
5917
                            }
5918
                            break;
5919
                        case NEON_2RM_VCNT:
5920
                            gen_helper_neon_cnt_u8(tmp, tmp);
5921
                            break;
5922
                        case NEON_2RM_VMVN:
5923
                            tcg_gen_not_i32(tmp, tmp);
5924
                            break;
5925
                        case NEON_2RM_VQABS:
5926
                            switch (size) {
5927
                            case 0:
5928
                                gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
5929
                                break;
5930
                            case 1:
5931
                                gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
5932
                                break;
5933
                            case 2:
5934
                                gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
5935
                                break;
5936
                            default: abort();
5937
                            }
5938
                            break;
5939
                        case NEON_2RM_VQNEG:
5940
                            switch (size) {
5941
                            case 0:
5942
                                gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
5943
                                break;
5944
                            case 1:
5945
                                gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
5946
                                break;
5947
                            case 2:
5948
                                gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
5949
                                break;
5950
                            default: abort();
5951
                            }
5952
                            break;
5953
                        case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
5954
                            tmp2 = tcg_const_i32(0);
5955
                            switch(size) {
5956
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5957
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5958
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5959
                            default: abort();
5960
                            }
5961
                            tcg_temp_free(tmp2);
5962
                            if (op == NEON_2RM_VCLE0) {
5963
                                tcg_gen_not_i32(tmp, tmp);
5964
                            }
5965
                            break;
5966
                        case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
5967
                            tmp2 = tcg_const_i32(0);
5968
                            switch(size) {
5969
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
5970
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
5971
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
5972
                            default: abort();
5973
                            }
5974
                            tcg_temp_free(tmp2);
5975
                            if (op == NEON_2RM_VCLT0) {
5976
                                tcg_gen_not_i32(tmp, tmp);
5977
                            }
5978
                            break;
5979
                        case NEON_2RM_VCEQ0:
5980
                            tmp2 = tcg_const_i32(0);
5981
                            switch(size) {
5982
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5983
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5984
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5985
                            default: abort();
5986
                            }
5987
                            tcg_temp_free(tmp2);
5988
                            break;
5989
                        case NEON_2RM_VABS:
5990
                            switch(size) {
5991
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
5992
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
5993
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
5994
                            default: abort();
5995
                            }
5996
                            break;
5997
                        case NEON_2RM_VNEG:
5998
                            tmp2 = tcg_const_i32(0);
5999
                            gen_neon_rsb(size, tmp, tmp2);
6000
                            tcg_temp_free(tmp2);
6001
                            break;
6002
                        case NEON_2RM_VCGT0_F:
6003
                        {
6004
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6005
                            tmp2 = tcg_const_i32(0);
6006
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6007
                            tcg_temp_free(tmp2);
6008
                            tcg_temp_free_ptr(fpstatus);
6009
                            break;
6010
                        }
6011
                        case NEON_2RM_VCGE0_F:
6012
                        {
6013
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6014
                            tmp2 = tcg_const_i32(0);
6015
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6016
                            tcg_temp_free(tmp2);
6017
                            tcg_temp_free_ptr(fpstatus);
6018
                            break;
6019
                        }
6020
                        case NEON_2RM_VCEQ0_F:
6021
                        {
6022
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6023
                            tmp2 = tcg_const_i32(0);
6024
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6025
                            tcg_temp_free(tmp2);
6026
                            tcg_temp_free_ptr(fpstatus);
6027
                            break;
6028
                        }
6029
                        case NEON_2RM_VCLE0_F:
6030
                        {
6031
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6032
                            tmp2 = tcg_const_i32(0);
6033
                            gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6034
                            tcg_temp_free(tmp2);
6035
                            tcg_temp_free_ptr(fpstatus);
6036
                            break;
6037
                        }
6038
                        case NEON_2RM_VCLT0_F:
6039
                        {
6040
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6041
                            tmp2 = tcg_const_i32(0);
6042
                            gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6043
                            tcg_temp_free(tmp2);
6044
                            tcg_temp_free_ptr(fpstatus);
6045
                            break;
6046
                        }
6047
                        case NEON_2RM_VABS_F:
6048
                            gen_vfp_abs(0);
6049
                            break;
6050
                        case NEON_2RM_VNEG_F:
6051
                            gen_vfp_neg(0);
6052
                            break;
6053
                        case NEON_2RM_VSWP:
6054
                            tmp2 = neon_load_reg(rd, pass);
6055
                            neon_store_reg(rm, pass, tmp2);
6056
                            break;
6057
                        case NEON_2RM_VTRN:
6058
                            tmp2 = neon_load_reg(rd, pass);
6059
                            switch (size) {
6060
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
6061
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
6062
                            default: abort();
6063
                            }
6064
                            neon_store_reg(rm, pass, tmp2);
6065
                            break;
6066
                        case NEON_2RM_VRECPE:
6067
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
6068
                            break;
6069
                        case NEON_2RM_VRSQRTE:
6070
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6071
                            break;
6072
                        case NEON_2RM_VRECPE_F:
6073
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6074
                            break;
6075
                        case NEON_2RM_VRSQRTE_F:
6076
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6077
                            break;
6078
                        case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6079
                            gen_vfp_sito(0, 1);
6080
                            break;
6081
                        case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6082
                            gen_vfp_uito(0, 1);
6083
                            break;
6084
                        case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6085
                            gen_vfp_tosiz(0, 1);
6086
                            break;
6087
                        case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6088
                            gen_vfp_touiz(0, 1);
6089
                            break;
6090
                        default:
6091
                            /* Reserved op values were caught by the
6092
                             * neon_2rm_sizes[] check earlier.
6093
                             */
6094
                            abort();
6095
                        }
6096
                        if (neon_2rm_is_float_op(op)) {
6097
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
6098
                                           neon_reg_offset(rd, pass));
6099
                        } else {
6100
                            neon_store_reg(rd, pass, tmp);
6101
                        }
6102
                    }
6103
                    break;
6104
                }
6105
            } else if ((insn & (1 << 10)) == 0) {
6106
                /* VTBL, VTBX.  */
6107
                int n = ((insn >> 8) & 3) + 1;
6108
                if ((rn + n) > 32) {
6109
                    /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6110
                     * helper function running off the end of the register file.
6111
                     */
6112
                    return 1;
6113
                }
6114
                n <<= 3;
6115
                if (insn & (1 << 6)) {
6116
                    tmp = neon_load_reg(rd, 0);
6117
                } else {
6118
                    tmp = tcg_temp_new_i32();
6119
                    tcg_gen_movi_i32(tmp, 0);
6120
                }
6121
                tmp2 = neon_load_reg(rm, 0);
6122
                tmp4 = tcg_const_i32(rn);
6123
                tmp5 = tcg_const_i32(n);
6124
                gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
6125
                tcg_temp_free_i32(tmp);
6126
                if (insn & (1 << 6)) {
6127
                    tmp = neon_load_reg(rd, 1);
6128
                } else {
6129
                    tmp = tcg_temp_new_i32();
6130
                    tcg_gen_movi_i32(tmp, 0);
6131
                }
6132
                tmp3 = neon_load_reg(rm, 1);
6133
                gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
6134
                tcg_temp_free_i32(tmp5);
6135
                tcg_temp_free_i32(tmp4);
6136
                neon_store_reg(rd, 0, tmp2);
6137
                neon_store_reg(rd, 1, tmp3);
6138
                tcg_temp_free_i32(tmp);
6139
            } else if ((insn & 0x380) == 0) {
6140
                /* VDUP */
6141
                if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6142
                    return 1;
6143
                }
6144
                if (insn & (1 << 19)) {
6145
                    tmp = neon_load_reg(rm, 1);
6146
                } else {
6147
                    tmp = neon_load_reg(rm, 0);
6148
                }
6149
                if (insn & (1 << 16)) {
6150
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6151
                } else if (insn & (1 << 17)) {
6152
                    if ((insn >> 18) & 1)
6153
                        gen_neon_dup_high16(tmp);
6154
                    else
6155
                        gen_neon_dup_low16(tmp);
6156
                }
6157
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
6158
                    tmp2 = tcg_temp_new_i32();
6159
                    tcg_gen_mov_i32(tmp2, tmp);
6160
                    neon_store_reg(rd, pass, tmp2);
6161
                }
6162
                tcg_temp_free_i32(tmp);
6163
            } else {
6164
                return 1;
6165
            }
6166
        }
6167
    }
6168
    return 0;
6169
}
6170

    
6171
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6172
{
6173
    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6174
    const ARMCPRegInfo *ri;
6175
    ARMCPU *cpu = arm_env_get_cpu(env);
6176

    
6177
    cpnum = (insn >> 8) & 0xf;
6178
    if (arm_feature(env, ARM_FEATURE_XSCALE)
6179
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6180
        return 1;
6181

    
6182
    /* First check for coprocessor space used for actual instructions */
6183
    switch (cpnum) {
6184
      case 0:
6185
      case 1:
6186
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6187
            return disas_iwmmxt_insn(env, s, insn);
6188
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6189
            return disas_dsp_insn(env, s, insn);
6190
        }
6191
        return 1;
6192
    case 10:
6193
    case 11:
6194
        return disas_vfp_insn (env, s, insn);
6195
    default:
6196
        break;
6197
    }
6198

    
6199
    /* Otherwise treat as a generic register access */
6200
    is64 = (insn & (1 << 25)) == 0;
6201
    if (!is64 && ((insn & (1 << 4)) == 0)) {
6202
        /* cdp */
6203
        return 1;
6204
    }
6205

    
6206
    crm = insn & 0xf;
6207
    if (is64) {
6208
        crn = 0;
6209
        opc1 = (insn >> 4) & 0xf;
6210
        opc2 = 0;
6211
        rt2 = (insn >> 16) & 0xf;
6212
    } else {
6213
        crn = (insn >> 16) & 0xf;
6214
        opc1 = (insn >> 21) & 7;
6215
        opc2 = (insn >> 5) & 7;
6216
        rt2 = 0;
6217
    }
6218
    isread = (insn >> 20) & 1;
6219
    rt = (insn >> 12) & 0xf;
6220

    
6221
    ri = get_arm_cp_reginfo(cpu,
6222
                            ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6223
    if (ri) {
6224
        /* Check access permissions */
6225
        if (!cp_access_ok(env, ri, isread)) {
6226
            return 1;
6227
        }
6228

    
6229
        /* Handle special cases first */
6230
        switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6231
        case ARM_CP_NOP:
6232
            return 0;
6233
        case ARM_CP_WFI:
6234
            if (isread) {
6235
                return 1;
6236
            }
6237
            gen_set_pc_im(s->pc);
6238
            s->is_jmp = DISAS_WFI;
6239
            return 0;
6240
        default:
6241
            break;
6242
        }
6243

    
6244
        if (isread) {
6245
            /* Read */
6246
            if (is64) {
6247
                TCGv_i64 tmp64;
6248
                TCGv_i32 tmp;
6249
                if (ri->type & ARM_CP_CONST) {
6250
                    tmp64 = tcg_const_i64(ri->resetvalue);
6251
                } else if (ri->readfn) {
6252
                    TCGv_ptr tmpptr;
6253
                    gen_set_pc_im(s->pc);
6254
                    tmp64 = tcg_temp_new_i64();
6255
                    tmpptr = tcg_const_ptr(ri);
6256
                    gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6257
                    tcg_temp_free_ptr(tmpptr);
6258
                } else {
6259
                    tmp64 = tcg_temp_new_i64();
6260
                    tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6261
                }
6262
                tmp = tcg_temp_new_i32();
6263
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6264
                store_reg(s, rt, tmp);
6265
                tcg_gen_shri_i64(tmp64, tmp64, 32);
6266
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6267
                store_reg(s, rt2, tmp);
6268
            } else {
6269
                TCGv tmp;
6270
                if (ri->type & ARM_CP_CONST) {
6271
                    tmp = tcg_const_i32(ri->resetvalue);
6272
                } else if (ri->readfn) {
6273
                    TCGv_ptr tmpptr;
6274
                    gen_set_pc_im(s->pc);
6275
                    tmp = tcg_temp_new_i32();
6276
                    tmpptr = tcg_const_ptr(ri);
6277
                    gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6278
                    tcg_temp_free_ptr(tmpptr);
6279
                } else {
6280
                    tmp = load_cpu_offset(ri->fieldoffset);
6281
                }
6282
                if (rt == 15) {
6283
                    /* Destination register of r15 for 32 bit loads sets
6284
                     * the condition codes from the high 4 bits of the value
6285
                     */
6286
                    gen_set_nzcv(tmp);
6287
                    tcg_temp_free_i32(tmp);
6288
                } else {
6289
                    store_reg(s, rt, tmp);
6290
                }
6291
            }
6292
        } else {
6293
            /* Write */
6294
            if (ri->type & ARM_CP_CONST) {
6295
                /* If not forbidden by access permissions, treat as WI */
6296
                return 0;
6297
            }
6298

    
6299
            if (is64) {
6300
                TCGv tmplo, tmphi;
6301
                TCGv_i64 tmp64 = tcg_temp_new_i64();
6302
                tmplo = load_reg(s, rt);
6303
                tmphi = load_reg(s, rt2);
6304
                tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6305
                tcg_temp_free_i32(tmplo);
6306
                tcg_temp_free_i32(tmphi);
6307
                if (ri->writefn) {
6308
                    TCGv_ptr tmpptr = tcg_const_ptr(ri);
6309
                    gen_set_pc_im(s->pc);
6310
                    gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6311
                    tcg_temp_free_ptr(tmpptr);
6312
                } else {
6313
                    tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6314
                }
6315
                tcg_temp_free_i64(tmp64);
6316
            } else {
6317
                if (ri->writefn) {
6318
                    TCGv tmp;
6319
                    TCGv_ptr tmpptr;
6320
                    gen_set_pc_im(s->pc);
6321
                    tmp = load_reg(s, rt);
6322
                    tmpptr = tcg_const_ptr(ri);
6323
                    gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6324
                    tcg_temp_free_ptr(tmpptr);
6325
                    tcg_temp_free_i32(tmp);
6326
                } else {
6327
                    TCGv tmp = load_reg(s, rt);
6328
                    store_cpu_offset(tmp, ri->fieldoffset);
6329
                }
6330
            }
6331
            /* We default to ending the TB on a coprocessor register write,
6332
             * but allow this to be suppressed by the register definition
6333
             * (usually only necessary to work around guest bugs).
6334
             */
6335
            if (!(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6336
                gen_lookup_tb(s);
6337
            }
6338
        }
6339
        return 0;
6340
    }
6341

    
6342
    return 1;
6343
}
6344

    
6345

    
6346
/* Store a 64-bit value to a register pair.  Clobbers val.  */
6347
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6348
{
6349
    TCGv tmp;
6350
    tmp = tcg_temp_new_i32();
6351
    tcg_gen_trunc_i64_i32(tmp, val);
6352
    store_reg(s, rlow, tmp);
6353
    tmp = tcg_temp_new_i32();
6354
    tcg_gen_shri_i64(val, val, 32);
6355
    tcg_gen_trunc_i64_i32(tmp, val);
6356
    store_reg(s, rhigh, tmp);
6357
}
6358

    
6359
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
6360
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6361
{
6362
    TCGv_i64 tmp;
6363
    TCGv tmp2;
6364

    
6365
    /* Load value and extend to 64 bits.  */
6366
    tmp = tcg_temp_new_i64();
6367
    tmp2 = load_reg(s, rlow);
6368
    tcg_gen_extu_i32_i64(tmp, tmp2);
6369
    tcg_temp_free_i32(tmp2);
6370
    tcg_gen_add_i64(val, val, tmp);
6371
    tcg_temp_free_i64(tmp);
6372
}
6373

    
6374
/* load and add a 64-bit value from a register pair.  */
6375
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6376
{
6377
    TCGv_i64 tmp;
6378
    TCGv tmpl;
6379
    TCGv tmph;
6380

    
6381
    /* Load 64-bit value rd:rn.  */
6382
    tmpl = load_reg(s, rlow);
6383
    tmph = load_reg(s, rhigh);
6384
    tmp = tcg_temp_new_i64();
6385
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6386
    tcg_temp_free_i32(tmpl);
6387
    tcg_temp_free_i32(tmph);
6388
    tcg_gen_add_i64(val, val, tmp);
6389
    tcg_temp_free_i64(tmp);
6390
}
6391

    
6392
/* Set N and Z flags from a 64-bit value.  */
6393
static void gen_logicq_cc(TCGv_i64 val)
6394
{
6395
    TCGv tmp = tcg_temp_new_i32();
6396
    gen_helper_logicq_cc(tmp, val);
6397
    gen_logic_CC(tmp);
6398
    tcg_temp_free_i32(tmp);
6399
}
6400

    
6401
/* Load/Store exclusive instructions are implemented by remembering
6402
   the value/address loaded, and seeing if these are the same
6403
   when the store is performed. This should be is sufficient to implement
6404
   the architecturally mandated semantics, and avoids having to monitor
6405
   regular stores.
6406

6407
   In system emulation mode only one CPU will be running at once, so
6408
   this sequence is effectively atomic.  In user emulation mode we
6409
   throw an exception and handle the atomic operation elsewhere.  */
6410
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6411
                               TCGv addr, int size)
6412
{
6413
    TCGv tmp;
6414

    
6415
    switch (size) {
6416
    case 0:
6417
        tmp = gen_ld8u(addr, IS_USER(s));
6418
        break;
6419
    case 1:
6420
        tmp = gen_ld16u(addr, IS_USER(s));
6421
        break;
6422
    case 2:
6423
    case 3:
6424
        tmp = gen_ld32(addr, IS_USER(s));
6425
        break;
6426
    default:
6427
        abort();
6428
    }
6429
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6430
    store_reg(s, rt, tmp);
6431
    if (size == 3) {
6432
        TCGv tmp2 = tcg_temp_new_i32();
6433
        tcg_gen_addi_i32(tmp2, addr, 4);
6434
        tmp = gen_ld32(tmp2, IS_USER(s));
6435
        tcg_temp_free_i32(tmp2);
6436
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6437
        store_reg(s, rt2, tmp);
6438
    }
6439
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6440
}
6441

    
6442
static void gen_clrex(DisasContext *s)
6443
{
6444
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6445
}
6446

    
6447
#ifdef CONFIG_USER_ONLY
6448
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6449
                                TCGv addr, int size)
6450
{
6451
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
6452
    tcg_gen_movi_i32(cpu_exclusive_info,
6453
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
6454
    gen_exception_insn(s, 4, EXCP_STREX);
6455
}
6456
#else
6457
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6458
                                TCGv addr, int size)
6459
{
6460
    TCGv tmp;
6461
    int done_label;
6462
    int fail_label;
6463

    
6464
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6465
         [addr] = {Rt};
6466
         {Rd} = 0;
6467
       } else {
6468
         {Rd} = 1;
6469
       } */
6470
    fail_label = gen_new_label();
6471
    done_label = gen_new_label();
6472
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6473
    switch (size) {
6474
    case 0:
6475
        tmp = gen_ld8u(addr, IS_USER(s));
6476
        break;
6477
    case 1:
6478
        tmp = gen_ld16u(addr, IS_USER(s));
6479
        break;
6480
    case 2:
6481
    case 3:
6482
        tmp = gen_ld32(addr, IS_USER(s));
6483
        break;
6484
    default:
6485
        abort();
6486
    }
6487
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6488
    tcg_temp_free_i32(tmp);
6489
    if (size == 3) {
6490
        TCGv tmp2 = tcg_temp_new_i32();
6491
        tcg_gen_addi_i32(tmp2, addr, 4);
6492
        tmp = gen_ld32(tmp2, IS_USER(s));
6493
        tcg_temp_free_i32(tmp2);
6494
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6495
        tcg_temp_free_i32(tmp);
6496
    }
6497
    tmp = load_reg(s, rt);
6498
    switch (size) {
6499
    case 0:
6500
        gen_st8(tmp, addr, IS_USER(s));
6501
        break;
6502
    case 1:
6503
        gen_st16(tmp, addr, IS_USER(s));
6504
        break;
6505
    case 2:
6506
    case 3:
6507
        gen_st32(tmp, addr, IS_USER(s));
6508
        break;
6509
    default:
6510
        abort();
6511
    }
6512
    if (size == 3) {
6513
        tcg_gen_addi_i32(addr, addr, 4);
6514
        tmp = load_reg(s, rt2);
6515
        gen_st32(tmp, addr, IS_USER(s));
6516
    }
6517
    tcg_gen_movi_i32(cpu_R[rd], 0);
6518
    tcg_gen_br(done_label);
6519
    gen_set_label(fail_label);
6520
    tcg_gen_movi_i32(cpu_R[rd], 1);
6521
    gen_set_label(done_label);
6522
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6523
}
6524
#endif
6525

    
6526
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6527
{
6528
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6529
    TCGv tmp;
6530
    TCGv tmp2;
6531
    TCGv tmp3;
6532
    TCGv addr;
6533
    TCGv_i64 tmp64;
6534

    
6535
    insn = arm_ldl_code(s->pc, s->bswap_code);
6536
    s->pc += 4;
6537

    
6538
    /* M variants do not implement ARM mode.  */
6539
    if (IS_M(env))
6540
        goto illegal_op;
6541
    cond = insn >> 28;
6542
    if (cond == 0xf){
6543
        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6544
         * choose to UNDEF. In ARMv5 and above the space is used
6545
         * for miscellaneous unconditional instructions.
6546
         */
6547
        ARCH(5);
6548

    
6549
        /* Unconditional instructions.  */
6550
        if (((insn >> 25) & 7) == 1) {
6551
            /* NEON Data processing.  */
6552
            if (!arm_feature(env, ARM_FEATURE_NEON))
6553
                goto illegal_op;
6554

    
6555
            if (disas_neon_data_insn(env, s, insn))
6556
                goto illegal_op;
6557
            return;
6558
        }
6559
        if ((insn & 0x0f100000) == 0x04000000) {
6560
            /* NEON load/store.  */
6561
            if (!arm_feature(env, ARM_FEATURE_NEON))
6562
                goto illegal_op;
6563

    
6564
            if (disas_neon_ls_insn(env, s, insn))
6565
                goto illegal_op;
6566
            return;
6567
        }
6568
        if (((insn & 0x0f30f000) == 0x0510f000) ||
6569
            ((insn & 0x0f30f010) == 0x0710f000)) {
6570
            if ((insn & (1 << 22)) == 0) {
6571
                /* PLDW; v7MP */
6572
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6573
                    goto illegal_op;
6574
                }
6575
            }
6576
            /* Otherwise PLD; v5TE+ */
6577
            ARCH(5TE);
6578
            return;
6579
        }
6580
        if (((insn & 0x0f70f000) == 0x0450f000) ||
6581
            ((insn & 0x0f70f010) == 0x0650f000)) {
6582
            ARCH(7);
6583
            return; /* PLI; V7 */
6584
        }
6585
        if (((insn & 0x0f700000) == 0x04100000) ||
6586
            ((insn & 0x0f700010) == 0x06100000)) {
6587
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6588
                goto illegal_op;
6589
            }
6590
            return; /* v7MP: Unallocated memory hint: must NOP */
6591
        }
6592

    
6593
        if ((insn & 0x0ffffdff) == 0x01010000) {
6594
            ARCH(6);
6595
            /* setend */
6596
            if (((insn >> 9) & 1) != s->bswap_code) {
6597
                /* Dynamic endianness switching not implemented. */
6598
                goto illegal_op;
6599
            }
6600
            return;
6601
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6602
            switch ((insn >> 4) & 0xf) {
6603
            case 1: /* clrex */
6604
                ARCH(6K);
6605
                gen_clrex(s);
6606
                return;
6607
            case 4: /* dsb */
6608
            case 5: /* dmb */
6609
            case 6: /* isb */
6610
                ARCH(7);
6611
                /* We don't emulate caches so these are a no-op.  */
6612
                return;
6613
            default:
6614
                goto illegal_op;
6615
            }
6616
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6617
            /* srs */
6618
            int32_t offset;
6619
            if (IS_USER(s))
6620
                goto illegal_op;
6621
            ARCH(6);
6622
            op1 = (insn & 0x1f);
6623
            addr = tcg_temp_new_i32();
6624
            tmp = tcg_const_i32(op1);
6625
            gen_helper_get_r13_banked(addr, cpu_env, tmp);
6626
            tcg_temp_free_i32(tmp);
6627
            i = (insn >> 23) & 3;
6628
            switch (i) {
6629
            case 0: offset = -4; break; /* DA */
6630
            case 1: offset = 0; break; /* IA */
6631
            case 2: offset = -8; break; /* DB */
6632
            case 3: offset = 4; break; /* IB */
6633
            default: abort();
6634
            }
6635
            if (offset)
6636
                tcg_gen_addi_i32(addr, addr, offset);
6637
            tmp = load_reg(s, 14);
6638
            gen_st32(tmp, addr, 0);
6639
            tmp = load_cpu_field(spsr);
6640
            tcg_gen_addi_i32(addr, addr, 4);
6641
            gen_st32(tmp, addr, 0);
6642
            if (insn & (1 << 21)) {
6643
                /* Base writeback.  */
6644
                switch (i) {
6645
                case 0: offset = -8; break;
6646
                case 1: offset = 4; break;
6647
                case 2: offset = -4; break;
6648
                case 3: offset = 0; break;
6649
                default: abort();
6650
                }
6651
                if (offset)
6652
                    tcg_gen_addi_i32(addr, addr, offset);
6653
                tmp = tcg_const_i32(op1);
6654
                gen_helper_set_r13_banked(cpu_env, tmp, addr);
6655
                tcg_temp_free_i32(tmp);
6656
                tcg_temp_free_i32(addr);
6657
            } else {
6658
                tcg_temp_free_i32(addr);
6659
            }
6660
            return;
6661
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6662
            /* rfe */
6663
            int32_t offset;
6664
            if (IS_USER(s))
6665
                goto illegal_op;
6666
            ARCH(6);
6667
            rn = (insn >> 16) & 0xf;
6668
            addr = load_reg(s, rn);
6669
            i = (insn >> 23) & 3;
6670
            switch (i) {
6671
            case 0: offset = -4; break; /* DA */
6672
            case 1: offset = 0; break; /* IA */
6673
            case 2: offset = -8; break; /* DB */
6674
            case 3: offset = 4; break; /* IB */
6675
            default: abort();
6676
            }
6677
            if (offset)
6678
                tcg_gen_addi_i32(addr, addr, offset);
6679
            /* Load PC into tmp and CPSR into tmp2.  */
6680
            tmp = gen_ld32(addr, 0);
6681
            tcg_gen_addi_i32(addr, addr, 4);
6682
            tmp2 = gen_ld32(addr, 0);
6683
            if (insn & (1 << 21)) {
6684
                /* Base writeback.  */
6685
                switch (i) {
6686
                case 0: offset = -8; break;
6687
                case 1: offset = 4; break;
6688
                case 2: offset = -4; break;
6689
                case 3: offset = 0; break;
6690
                default: abort();
6691
                }
6692
                if (offset)
6693
                    tcg_gen_addi_i32(addr, addr, offset);
6694
                store_reg(s, rn, addr);
6695
            } else {
6696
                tcg_temp_free_i32(addr);
6697
            }
6698
            gen_rfe(s, tmp, tmp2);
6699
            return;
6700
        } else if ((insn & 0x0e000000) == 0x0a000000) {
6701
            /* branch link and change to thumb (blx <offset>) */
6702
            int32_t offset;
6703

    
6704
            val = (uint32_t)s->pc;
6705
            tmp = tcg_temp_new_i32();
6706
            tcg_gen_movi_i32(tmp, val);
6707
            store_reg(s, 14, tmp);
6708
            /* Sign-extend the 24-bit offset */
6709
            offset = (((int32_t)insn) << 8) >> 8;
6710
            /* offset * 4 + bit24 * 2 + (thumb bit) */
6711
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
6712
            /* pipeline offset */
6713
            val += 4;
6714
            /* protected by ARCH(5); above, near the start of uncond block */
6715
            gen_bx_im(s, val);
6716
            return;
6717
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
6718
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6719
                /* iWMMXt register transfer.  */
6720
                if (env->cp15.c15_cpar & (1 << 1))
6721
                    if (!disas_iwmmxt_insn(env, s, insn))
6722
                        return;
6723
            }
6724
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
6725
            /* Coprocessor double register transfer.  */
6726
            ARCH(5TE);
6727
        } else if ((insn & 0x0f000010) == 0x0e000010) {
6728
            /* Additional coprocessor register transfer.  */
6729
        } else if ((insn & 0x0ff10020) == 0x01000000) {
6730
            uint32_t mask;
6731
            uint32_t val;
6732
            /* cps (privileged) */
6733
            if (IS_USER(s))
6734
                return;
6735
            mask = val = 0;
6736
            if (insn & (1 << 19)) {
6737
                if (insn & (1 << 8))
6738
                    mask |= CPSR_A;
6739
                if (insn & (1 << 7))
6740
                    mask |= CPSR_I;
6741
                if (insn & (1 << 6))
6742
                    mask |= CPSR_F;
6743
                if (insn & (1 << 18))
6744
                    val |= mask;
6745
            }
6746
            if (insn & (1 << 17)) {
6747
                mask |= CPSR_M;
6748
                val |= (insn & 0x1f);
6749
            }
6750
            if (mask) {
6751
                gen_set_psr_im(s, mask, 0, val);
6752
            }
6753
            return;
6754
        }
6755
        goto illegal_op;
6756
    }
6757
    if (cond != 0xe) {
6758
        /* if not always execute, we generate a conditional jump to
6759
           next instruction */
6760
        s->condlabel = gen_new_label();
6761
        gen_test_cc(cond ^ 1, s->condlabel);
6762
        s->condjmp = 1;
6763
    }
6764
    if ((insn & 0x0f900000) == 0x03000000) {
6765
        if ((insn & (1 << 21)) == 0) {
6766
            ARCH(6T2);
6767
            rd = (insn >> 12) & 0xf;
6768
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6769
            if ((insn & (1 << 22)) == 0) {
6770
                /* MOVW */
6771
                tmp = tcg_temp_new_i32();
6772
                tcg_gen_movi_i32(tmp, val);
6773
            } else {
6774
                /* MOVT */
6775
                tmp = load_reg(s, rd);
6776
                tcg_gen_ext16u_i32(tmp, tmp);
6777
                tcg_gen_ori_i32(tmp, tmp, val << 16);
6778
            }
6779
            store_reg(s, rd, tmp);
6780
        } else {
6781
            if (((insn >> 12) & 0xf) != 0xf)
6782
                goto illegal_op;
6783
            if (((insn >> 16) & 0xf) == 0) {
6784
                gen_nop_hint(s, insn & 0xff);
6785
            } else {
6786
                /* CPSR = immediate */
6787
                val = insn & 0xff;
6788
                shift = ((insn >> 8) & 0xf) * 2;
6789
                if (shift)
6790
                    val = (val >> shift) | (val << (32 - shift));
6791
                i = ((insn & (1 << 22)) != 0);
6792
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6793
                    goto illegal_op;
6794
            }
6795
        }
6796
    } else if ((insn & 0x0f900000) == 0x01000000
6797
               && (insn & 0x00000090) != 0x00000090) {
6798
        /* miscellaneous instructions */
6799
        op1 = (insn >> 21) & 3;
6800
        sh = (insn >> 4) & 0xf;
6801
        rm = insn & 0xf;
6802
        switch (sh) {
6803
        case 0x0: /* move program status register */
6804
            if (op1 & 1) {
6805
                /* PSR = reg */
6806
                tmp = load_reg(s, rm);
6807
                i = ((op1 & 2) != 0);
6808
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6809
                    goto illegal_op;
6810
            } else {
6811
                /* reg = PSR */
6812
                rd = (insn >> 12) & 0xf;
6813
                if (op1 & 2) {
6814
                    if (IS_USER(s))
6815
                        goto illegal_op;
6816
                    tmp = load_cpu_field(spsr);
6817
                } else {
6818
                    tmp = tcg_temp_new_i32();
6819
                    gen_helper_cpsr_read(tmp);
6820
                }
6821
                store_reg(s, rd, tmp);
6822
            }
6823
            break;
6824
        case 0x1:
6825
            if (op1 == 1) {
6826
                /* branch/exchange thumb (bx).  */
6827
                ARCH(4T);
6828
                tmp = load_reg(s, rm);
6829
                gen_bx(s, tmp);
6830
            } else if (op1 == 3) {
6831
                /* clz */
6832
                ARCH(5);
6833
                rd = (insn >> 12) & 0xf;
6834
                tmp = load_reg(s, rm);
6835
                gen_helper_clz(tmp, tmp);
6836
                store_reg(s, rd, tmp);
6837
            } else {
6838
                goto illegal_op;
6839
            }
6840
            break;
6841
        case 0x2:
6842
            if (op1 == 1) {
6843
                ARCH(5J); /* bxj */
6844
                /* Trivial implementation equivalent to bx.  */
6845
                tmp = load_reg(s, rm);
6846
                gen_bx(s, tmp);
6847
            } else {
6848
                goto illegal_op;
6849
            }
6850
            break;
6851
        case 0x3:
6852
            if (op1 != 1)
6853
              goto illegal_op;
6854

    
6855
            ARCH(5);
6856
            /* branch link/exchange thumb (blx) */
6857
            tmp = load_reg(s, rm);
6858
            tmp2 = tcg_temp_new_i32();
6859
            tcg_gen_movi_i32(tmp2, s->pc);
6860
            store_reg(s, 14, tmp2);
6861
            gen_bx(s, tmp);
6862
            break;
6863
        case 0x5: /* saturating add/subtract */
6864
            ARCH(5TE);
6865
            rd = (insn >> 12) & 0xf;
6866
            rn = (insn >> 16) & 0xf;
6867
            tmp = load_reg(s, rm);
6868
            tmp2 = load_reg(s, rn);
6869
            if (op1 & 2)
6870
                gen_helper_double_saturate(tmp2, tmp2);
6871
            if (op1 & 1)
6872
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6873
            else
6874
                gen_helper_add_saturate(tmp, tmp, tmp2);
6875
            tcg_temp_free_i32(tmp2);
6876
            store_reg(s, rd, tmp);
6877
            break;
6878
        case 7:
6879
            /* SMC instruction (op1 == 3)
6880
               and undefined instructions (op1 == 0 || op1 == 2)
6881
               will trap */
6882
            if (op1 != 1) {
6883
                goto illegal_op;
6884
            }
6885
            /* bkpt */
6886
            ARCH(5);
6887
            gen_exception_insn(s, 4, EXCP_BKPT);
6888
            break;
6889
        case 0x8: /* signed multiply */
6890
        case 0xa:
6891
        case 0xc:
6892
        case 0xe:
6893
            ARCH(5TE);
6894
            rs = (insn >> 8) & 0xf;
6895
            rn = (insn >> 12) & 0xf;
6896
            rd = (insn >> 16) & 0xf;
6897
            if (op1 == 1) {
6898
                /* (32 * 16) >> 16 */
6899
                tmp = load_reg(s, rm);
6900
                tmp2 = load_reg(s, rs);
6901
                if (sh & 4)
6902
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6903
                else
6904
                    gen_sxth(tmp2);
6905
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
6906
                tcg_gen_shri_i64(tmp64, tmp64, 16);
6907
                tmp = tcg_temp_new_i32();
6908
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6909
                tcg_temp_free_i64(tmp64);
6910
                if ((sh & 2) == 0) {
6911
                    tmp2 = load_reg(s, rn);
6912
                    gen_helper_add_setq(tmp, tmp, tmp2);
6913
                    tcg_temp_free_i32(tmp2);
6914
                }
6915
                store_reg(s, rd, tmp);
6916
            } else {
6917
                /* 16 * 16 */
6918
                tmp = load_reg(s, rm);
6919
                tmp2 = load_reg(s, rs);
6920
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6921
                tcg_temp_free_i32(tmp2);
6922
                if (op1 == 2) {
6923
                    tmp64 = tcg_temp_new_i64();
6924
                    tcg_gen_ext_i32_i64(tmp64, tmp);
6925
                    tcg_temp_free_i32(tmp);
6926
                    gen_addq(s, tmp64, rn, rd);
6927
                    gen_storeq_reg(s, rn, rd, tmp64);
6928
                    tcg_temp_free_i64(tmp64);
6929
                } else {
6930
                    if (op1 == 0) {
6931
                        tmp2 = load_reg(s, rn);
6932
                        gen_helper_add_setq(tmp, tmp, tmp2);
6933
                        tcg_temp_free_i32(tmp2);
6934
                    }
6935
                    store_reg(s, rd, tmp);
6936
                }
6937
            }
6938
            break;
6939
        default:
6940
            goto illegal_op;
6941
        }
6942
    } else if (((insn & 0x0e000000) == 0 &&
6943
                (insn & 0x00000090) != 0x90) ||
6944
               ((insn & 0x0e000000) == (1 << 25))) {
6945
        int set_cc, logic_cc, shiftop;
6946

    
6947
        op1 = (insn >> 21) & 0xf;
6948
        set_cc = (insn >> 20) & 1;
6949
        logic_cc = table_logic_cc[op1] & set_cc;
6950

    
6951
        /* data processing instruction */
6952
        if (insn & (1 << 25)) {
6953
            /* immediate operand */
6954
            val = insn & 0xff;
6955
            shift = ((insn >> 8) & 0xf) * 2;
6956
            if (shift) {
6957
                val = (val >> shift) | (val << (32 - shift));
6958
            }
6959
            tmp2 = tcg_temp_new_i32();
6960
            tcg_gen_movi_i32(tmp2, val);
6961
            if (logic_cc && shift) {
6962
                gen_set_CF_bit31(tmp2);
6963
            }
6964
        } else {
6965
            /* register */
6966
            rm = (insn) & 0xf;
6967
            tmp2 = load_reg(s, rm);
6968
            shiftop = (insn >> 5) & 3;
6969
            if (!(insn & (1 << 4))) {
6970
                shift = (insn >> 7) & 0x1f;
6971
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6972
            } else {
6973
                rs = (insn >> 8) & 0xf;
6974
                tmp = load_reg(s, rs);
6975
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6976
            }
6977
        }
6978
        if (op1 != 0x0f && op1 != 0x0d) {
6979
            rn = (insn >> 16) & 0xf;
6980
            tmp = load_reg(s, rn);
6981
        } else {
6982
            TCGV_UNUSED(tmp);
6983
        }
6984
        rd = (insn >> 12) & 0xf;
6985
        switch(op1) {
6986
        case 0x00:
6987
            tcg_gen_and_i32(tmp, tmp, tmp2);
6988
            if (logic_cc) {
6989
                gen_logic_CC(tmp);
6990
            }
6991
            store_reg_bx(env, s, rd, tmp);
6992
            break;
6993
        case 0x01:
6994
            tcg_gen_xor_i32(tmp, tmp, tmp2);
6995
            if (logic_cc) {
6996
                gen_logic_CC(tmp);
6997
            }
6998
            store_reg_bx(env, s, rd, tmp);
6999
            break;
7000
        case 0x02:
7001
            if (set_cc && rd == 15) {
7002
                /* SUBS r15, ... is used for exception return.  */
7003
                if (IS_USER(s)) {
7004
                    goto illegal_op;
7005
                }
7006
                gen_helper_sub_cc(tmp, tmp, tmp2);
7007
                gen_exception_return(s, tmp);
7008
            } else {
7009
                if (set_cc) {
7010
                    gen_helper_sub_cc(tmp, tmp, tmp2);
7011
                } else {
7012
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7013
                }
7014
                store_reg_bx(env, s, rd, tmp);
7015
            }
7016
            break;
7017
        case 0x03:
7018
            if (set_cc) {
7019
                gen_helper_sub_cc(tmp, tmp2, tmp);
7020
            } else {
7021
                tcg_gen_sub_i32(tmp, tmp2, tmp);
7022
            }
7023
            store_reg_bx(env, s, rd, tmp);
7024
            break;
7025
        case 0x04:
7026
            if (set_cc) {
7027
                gen_helper_add_cc(tmp, tmp, tmp2);
7028
            } else {
7029
                tcg_gen_add_i32(tmp, tmp, tmp2);
7030
            }
7031
            store_reg_bx(env, s, rd, tmp);
7032
            break;
7033
        case 0x05:
7034
            if (set_cc) {
7035
                gen_helper_adc_cc(tmp, tmp, tmp2);
7036
            } else {
7037
                gen_add_carry(tmp, tmp, tmp2);
7038
            }
7039
            store_reg_bx(env, s, rd, tmp);
7040
            break;
7041
        case 0x06:
7042
            if (set_cc) {
7043
                gen_helper_sbc_cc(tmp, tmp, tmp2);
7044
            } else {
7045
                gen_sub_carry(tmp, tmp, tmp2);
7046
            }
7047
            store_reg_bx(env, s, rd, tmp);
7048
            break;
7049
        case 0x07:
7050
            if (set_cc) {
7051
                gen_helper_sbc_cc(tmp, tmp2, tmp);
7052
            } else {
7053
                gen_sub_carry(tmp, tmp2, tmp);
7054
            }
7055
            store_reg_bx(env, s, rd, tmp);
7056
            break;
7057
        case 0x08:
7058
            if (set_cc) {
7059
                tcg_gen_and_i32(tmp, tmp, tmp2);
7060
                gen_logic_CC(tmp);
7061
            }
7062
            tcg_temp_free_i32(tmp);
7063
            break;
7064
        case 0x09:
7065
            if (set_cc) {
7066
                tcg_gen_xor_i32(tmp, tmp, tmp2);
7067
                gen_logic_CC(tmp);
7068
            }
7069
            tcg_temp_free_i32(tmp);
7070
            break;
7071
        case 0x0a:
7072
            if (set_cc) {
7073
                gen_helper_sub_cc(tmp, tmp, tmp2);
7074
            }
7075
            tcg_temp_free_i32(tmp);
7076
            break;
7077
        case 0x0b:
7078
            if (set_cc) {
7079
                gen_helper_add_cc(tmp, tmp, tmp2);
7080
            }
7081
            tcg_temp_free_i32(tmp);
7082
            break;
7083
        case 0x0c:
7084
            tcg_gen_or_i32(tmp, tmp, tmp2);
7085
            if (logic_cc) {
7086
                gen_logic_CC(tmp);
7087
            }
7088
            store_reg_bx(env, s, rd, tmp);
7089
            break;
7090
        case 0x0d:
7091
            if (logic_cc && rd == 15) {
7092
                /* MOVS r15, ... is used for exception return.  */
7093
                if (IS_USER(s)) {
7094
                    goto illegal_op;
7095
                }
7096
                gen_exception_return(s, tmp2);
7097
            } else {
7098
                if (logic_cc) {
7099
                    gen_logic_CC(tmp2);
7100
                }
7101
                store_reg_bx(env, s, rd, tmp2);
7102
            }
7103
            break;
7104
        case 0x0e:
7105
            tcg_gen_andc_i32(tmp, tmp, tmp2);
7106
            if (logic_cc) {
7107
                gen_logic_CC(tmp);
7108
            }
7109
            store_reg_bx(env, s, rd, tmp);
7110
            break;
7111
        default:
7112
        case 0x0f:
7113
            tcg_gen_not_i32(tmp2, tmp2);
7114
            if (logic_cc) {
7115
                gen_logic_CC(tmp2);
7116
            }
7117
            store_reg_bx(env, s, rd, tmp2);
7118
            break;
7119
        }
7120
        if (op1 != 0x0f && op1 != 0x0d) {
7121
            tcg_temp_free_i32(tmp2);
7122
        }
7123
    } else {
7124
        /* other instructions */
7125
        op1 = (insn >> 24) & 0xf;
7126
        switch(op1) {
7127
        case 0x0:
7128
        case 0x1:
7129
            /* multiplies, extra load/stores */
7130
            sh = (insn >> 5) & 3;
7131
            if (sh == 0) {
7132
                if (op1 == 0x0) {
7133
                    rd = (insn >> 16) & 0xf;
7134
                    rn = (insn >> 12) & 0xf;
7135
                    rs = (insn >> 8) & 0xf;
7136
                    rm = (insn) & 0xf;
7137
                    op1 = (insn >> 20) & 0xf;
7138
                    switch (op1) {
7139
                    case 0: case 1: case 2: case 3: case 6:
7140
                        /* 32 bit mul */
7141
                        tmp = load_reg(s, rs);
7142
                        tmp2 = load_reg(s, rm);
7143
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
7144
                        tcg_temp_free_i32(tmp2);
7145
                        if (insn & (1 << 22)) {
7146
                            /* Subtract (mls) */
7147
                            ARCH(6T2);
7148
                            tmp2 = load_reg(s, rn);
7149
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
7150
                            tcg_temp_free_i32(tmp2);
7151
                        } else if (insn & (1 << 21)) {
7152
                            /* Add */
7153
                            tmp2 = load_reg(s, rn);
7154
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7155
                            tcg_temp_free_i32(tmp2);
7156
                        }
7157
                        if (insn & (1 << 20))
7158
                            gen_logic_CC(tmp);
7159
                        store_reg(s, rd, tmp);
7160
                        break;
7161
                    case 4:
7162
                        /* 64 bit mul double accumulate (UMAAL) */
7163
                        ARCH(6);
7164
                        tmp = load_reg(s, rs);
7165
                        tmp2 = load_reg(s, rm);
7166
                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7167
                        gen_addq_lo(s, tmp64, rn);
7168
                        gen_addq_lo(s, tmp64, rd);
7169
                        gen_storeq_reg(s, rn, rd, tmp64);
7170
                        tcg_temp_free_i64(tmp64);
7171
                        break;
7172
                    case 8: case 9: case 10: case 11:
7173
                    case 12: case 13: case 14: case 15:
7174
                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7175
                        tmp = load_reg(s, rs);
7176
                        tmp2 = load_reg(s, rm);
7177
                        if (insn & (1 << 22)) {
7178
                            tmp64 = gen_muls_i64_i32(tmp, tmp2);
7179
                        } else {
7180
                            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7181
                        }
7182
                        if (insn & (1 << 21)) { /* mult accumulate */
7183
                            gen_addq(s, tmp64, rn, rd);
7184
                        }
7185
                        if (insn & (1 << 20)) {
7186
                            gen_logicq_cc(tmp64);
7187
                        }
7188
                        gen_storeq_reg(s, rn, rd, tmp64);
7189
                        tcg_temp_free_i64(tmp64);
7190
                        break;
7191
                    default:
7192
                        goto illegal_op;
7193
                    }
7194
                } else {
7195
                    rn = (insn >> 16) & 0xf;
7196
                    rd = (insn >> 12) & 0xf;
7197
                    if (insn & (1 << 23)) {
7198
                        /* load/store exclusive */
7199
                        op1 = (insn >> 21) & 0x3;
7200
                        if (op1)
7201
                            ARCH(6K);
7202
                        else
7203
                            ARCH(6);
7204
                        addr = tcg_temp_local_new_i32();
7205
                        load_reg_var(s, addr, rn);
7206
                        if (insn & (1 << 20)) {
7207
                            switch (op1) {
7208
                            case 0: /* ldrex */
7209
                                gen_load_exclusive(s, rd, 15, addr, 2);
7210
                                break;
7211
                            case 1: /* ldrexd */
7212
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
7213
                                break;
7214
                            case 2: /* ldrexb */
7215
                                gen_load_exclusive(s, rd, 15, addr, 0);
7216
                                break;
7217
                            case 3: /* ldrexh */
7218
                                gen_load_exclusive(s, rd, 15, addr, 1);
7219
                                break;
7220
                            default:
7221
                                abort();
7222
                            }
7223
                        } else {
7224
                            rm = insn & 0xf;
7225
                            switch (op1) {
7226
                            case 0:  /*  strex */
7227
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
7228
                                break;
7229
                            case 1: /*  strexd */
7230
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7231
                                break;
7232
                            case 2: /*  strexb */
7233
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
7234
                                break;
7235
                            case 3: /* strexh */
7236
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
7237
                                break;
7238
                            default:
7239
                                abort();
7240
                            }
7241
                        }
7242
                        tcg_temp_free(addr);
7243
                    } else {
7244
                        /* SWP instruction */
7245
                        rm = (insn) & 0xf;
7246

    
7247
                        /* ??? This is not really atomic.  However we know
7248
                           we never have multiple CPUs running in parallel,
7249
                           so it is good enough.  */
7250
                        addr = load_reg(s, rn);
7251
                        tmp = load_reg(s, rm);
7252
                        if (insn & (1 << 22)) {
7253
                            tmp2 = gen_ld8u(addr, IS_USER(s));
7254
                            gen_st8(tmp, addr, IS_USER(s));
7255
                        } else {
7256
                            tmp2 = gen_ld32(addr, IS_USER(s));
7257
                            gen_st32(tmp, addr, IS_USER(s));
7258
                        }
7259
                        tcg_temp_free_i32(addr);
7260
                        store_reg(s, rd, tmp2);
7261
                    }
7262
                }
7263
            } else {
7264
                int address_offset;
7265
                int load;
7266
                /* Misc load/store */
7267
                rn = (insn >> 16) & 0xf;
7268
                rd = (insn >> 12) & 0xf;
7269
                addr = load_reg(s, rn);
7270
                if (insn & (1 << 24))
7271
                    gen_add_datah_offset(s, insn, 0, addr);
7272
                address_offset = 0;
7273
                if (insn & (1 << 20)) {
7274
                    /* load */
7275
                    switch(sh) {
7276
                    case 1:
7277
                        tmp = gen_ld16u(addr, IS_USER(s));
7278
                        break;
7279
                    case 2:
7280
                        tmp = gen_ld8s(addr, IS_USER(s));
7281
                        break;
7282
                    default:
7283
                    case 3:
7284
                        tmp = gen_ld16s(addr, IS_USER(s));
7285
                        break;
7286
                    }
7287
                    load = 1;
7288
                } else if (sh & 2) {
7289
                    ARCH(5TE);
7290
                    /* doubleword */
7291
                    if (sh & 1) {
7292
                        /* store */
7293
                        tmp = load_reg(s, rd);
7294
                        gen_st32(tmp, addr, IS_USER(s));
7295
                        tcg_gen_addi_i32(addr, addr, 4);
7296
                        tmp = load_reg(s, rd + 1);
7297
                        gen_st32(tmp, addr, IS_USER(s));
7298
                        load = 0;
7299
                    } else {
7300
                        /* load */
7301
                        tmp = gen_ld32(addr, IS_USER(s));
7302
                        store_reg(s, rd, tmp);
7303
                        tcg_gen_addi_i32(addr, addr, 4);
7304
                        tmp = gen_ld32(addr, IS_USER(s));
7305
                        rd++;
7306
                        load = 1;
7307
                    }
7308
                    address_offset = -4;
7309
                } else {
7310
                    /* store */
7311
                    tmp = load_reg(s, rd);
7312
                    gen_st16(tmp, addr, IS_USER(s));
7313
                    load = 0;
7314
                }
7315
                /* Perform base writeback before the loaded value to
7316
                   ensure correct behavior with overlapping index registers.
7317
                   ldrd with base writeback is is undefined if the
7318
                   destination and index registers overlap.  */
7319
                if (!(insn & (1 << 24))) {
7320
                    gen_add_datah_offset(s, insn, address_offset, addr);
7321
                    store_reg(s, rn, addr);
7322
                } else if (insn & (1 << 21)) {
7323
                    if (address_offset)
7324
                        tcg_gen_addi_i32(addr, addr, address_offset);
7325
                    store_reg(s, rn, addr);
7326
                } else {
7327
                    tcg_temp_free_i32(addr);
7328
                }
7329
                if (load) {
7330
                    /* Complete the load.  */
7331
                    store_reg(s, rd, tmp);
7332
                }
7333
            }
7334
            break;
7335
        case 0x4:
7336
        case 0x5:
7337
            goto do_ldst;
7338
        case 0x6:
7339
        case 0x7:
7340
            if (insn & (1 << 4)) {
7341
                ARCH(6);
7342
                /* Armv6 Media instructions.  */
7343
                rm = insn & 0xf;
7344
                rn = (insn >> 16) & 0xf;
7345
                rd = (insn >> 12) & 0xf;
7346
                rs = (insn >> 8) & 0xf;
7347
                switch ((insn >> 23) & 3) {
7348
                case 0: /* Parallel add/subtract.  */
7349
                    op1 = (insn >> 20) & 7;
7350
                    tmp = load_reg(s, rn);
7351
                    tmp2 = load_reg(s, rm);
7352
                    sh = (insn >> 5) & 7;
7353
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7354
                        goto illegal_op;
7355
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7356
                    tcg_temp_free_i32(tmp2);
7357
                    store_reg(s, rd, tmp);
7358
                    break;
7359
                case 1:
7360
                    if ((insn & 0x00700020) == 0) {
7361
                        /* Halfword pack.  */
7362
                        tmp = load_reg(s, rn);
7363
                        tmp2 = load_reg(s, rm);
7364
                        shift = (insn >> 7) & 0x1f;
7365
                        if (insn & (1 << 6)) {
7366
                            /* pkhtb */
7367
                            if (shift == 0)
7368
                                shift = 31;
7369
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
7370
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7371
                            tcg_gen_ext16u_i32(tmp2, tmp2);
7372
                        } else {
7373
                            /* pkhbt */
7374
                            if (shift)
7375
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
7376
                            tcg_gen_ext16u_i32(tmp, tmp);
7377
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7378
                        }
7379
                        tcg_gen_or_i32(tmp, tmp, tmp2);
7380
                        tcg_temp_free_i32(tmp2);
7381
                        store_reg(s, rd, tmp);
7382
                    } else if ((insn & 0x00200020) == 0x00200000) {
7383
                        /* [us]sat */
7384
                        tmp = load_reg(s, rm);
7385
                        shift = (insn >> 7) & 0x1f;
7386
                        if (insn & (1 << 6)) {
7387
                            if (shift == 0)
7388
                                shift = 31;
7389
                            tcg_gen_sari_i32(tmp, tmp, shift);
7390
                        } else {
7391
                            tcg_gen_shli_i32(tmp, tmp, shift);
7392
                        }
7393
                        sh = (insn >> 16) & 0x1f;
7394
                        tmp2 = tcg_const_i32(sh);
7395
                        if (insn & (1 << 22))
7396
                          gen_helper_usat(tmp, tmp, tmp2);
7397
                        else
7398
                          gen_helper_ssat(tmp, tmp, tmp2);
7399
                        tcg_temp_free_i32(tmp2);
7400
                        store_reg(s, rd, tmp);
7401
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
7402
                        /* [us]sat16 */
7403
                        tmp = load_reg(s, rm);
7404
                        sh = (insn >> 16) & 0x1f;
7405
                        tmp2 = tcg_const_i32(sh);
7406
                        if (insn & (1 << 22))
7407
                          gen_helper_usat16(tmp, tmp, tmp2);
7408
                        else
7409
                          gen_helper_ssat16(tmp, tmp, tmp2);
7410
                        tcg_temp_free_i32(tmp2);
7411
                        store_reg(s, rd, tmp);
7412
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7413
                        /* Select bytes.  */
7414
                        tmp = load_reg(s, rn);
7415
                        tmp2 = load_reg(s, rm);
7416
                        tmp3 = tcg_temp_new_i32();
7417
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7418
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7419
                        tcg_temp_free_i32(tmp3);
7420
                        tcg_temp_free_i32(tmp2);
7421
                        store_reg(s, rd, tmp);
7422
                    } else if ((insn & 0x000003e0) == 0x00000060) {
7423
                        tmp = load_reg(s, rm);
7424
                        shift = (insn >> 10) & 3;
7425
                        /* ??? In many cases it's not necessary to do a
7426
                           rotate, a shift is sufficient.  */
7427
                        if (shift != 0)
7428
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7429
                        op1 = (insn >> 20) & 7;
7430
                        switch (op1) {
7431
                        case 0: gen_sxtb16(tmp);  break;
7432
                        case 2: gen_sxtb(tmp);    break;
7433
                        case 3: gen_sxth(tmp);    break;
7434
                        case 4: gen_uxtb16(tmp);  break;
7435
                        case 6: gen_uxtb(tmp);    break;
7436
                        case 7: gen_uxth(tmp);    break;
7437
                        default: goto illegal_op;
7438
                        }
7439
                        if (rn != 15) {
7440
                            tmp2 = load_reg(s, rn);
7441
                            if ((op1 & 3) == 0) {
7442
                                gen_add16(tmp, tmp2);
7443
                            } else {
7444
                                tcg_gen_add_i32(tmp, tmp, tmp2);
7445
                                tcg_temp_free_i32(tmp2);
7446
                            }
7447
                        }
7448
                        store_reg(s, rd, tmp);
7449
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7450
                        /* rev */
7451
                        tmp = load_reg(s, rm);
7452
                        if (insn & (1 << 22)) {
7453
                            if (insn & (1 << 7)) {
7454
                                gen_revsh(tmp);
7455
                            } else {
7456
                                ARCH(6T2);
7457
                                gen_helper_rbit(tmp, tmp);
7458
                            }
7459
                        } else {
7460
                            if (insn & (1 << 7))
7461
                                gen_rev16(tmp);
7462
                            else
7463
                                tcg_gen_bswap32_i32(tmp, tmp);
7464
                        }
7465
                        store_reg(s, rd, tmp);
7466
                    } else {
7467
                        goto illegal_op;
7468
                    }
7469
                    break;
7470
                case 2: /* Multiplies (Type 3).  */
7471
                    switch ((insn >> 20) & 0x7) {
7472
                    case 5:
7473
                        if (((insn >> 6) ^ (insn >> 7)) & 1) {
7474
                            /* op2 not 00x or 11x : UNDEF */
7475
                            goto illegal_op;
7476
                        }
7477
                        /* Signed multiply most significant [accumulate].
7478
                           (SMMUL, SMMLA, SMMLS) */
7479
                        tmp = load_reg(s, rm);
7480
                        tmp2 = load_reg(s, rs);
7481
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7482

    
7483
                        if (rd != 15) {
7484
                            tmp = load_reg(s, rd);
7485
                            if (insn & (1 << 6)) {
7486
                                tmp64 = gen_subq_msw(tmp64, tmp);
7487
                            } else {
7488
                                tmp64 = gen_addq_msw(tmp64, tmp);
7489
                            }
7490
                        }
7491
                        if (insn & (1 << 5)) {
7492
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7493
                        }
7494
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
7495
                        tmp = tcg_temp_new_i32();
7496
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
7497
                        tcg_temp_free_i64(tmp64);
7498
                        store_reg(s, rn, tmp);
7499
                        break;
7500
                    case 0:
7501
                    case 4:
7502
                        /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7503
                        if (insn & (1 << 7)) {
7504
                            goto illegal_op;
7505
                        }
7506
                        tmp = load_reg(s, rm);
7507
                        tmp2 = load_reg(s, rs);
7508
                        if (insn & (1 << 5))
7509
                            gen_swap_half(tmp2);
7510
                        gen_smul_dual(tmp, tmp2);
7511
                        if (insn & (1 << 6)) {
7512
                            /* This subtraction cannot overflow. */
7513
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
7514
                        } else {
7515
                            /* This addition cannot overflow 32 bits;
7516
                             * however it may overflow considered as a signed
7517
                             * operation, in which case we must set the Q flag.
7518
                             */
7519
                            gen_helper_add_setq(tmp, tmp, tmp2);
7520
                        }
7521
                        tcg_temp_free_i32(tmp2);
7522
                        if (insn & (1 << 22)) {
7523
                            /* smlald, smlsld */
7524
                            tmp64 = tcg_temp_new_i64();
7525
                            tcg_gen_ext_i32_i64(tmp64, tmp);
7526
                            tcg_temp_free_i32(tmp);
7527
                            gen_addq(s, tmp64, rd, rn);
7528
                            gen_storeq_reg(s, rd, rn, tmp64);
7529
                            tcg_temp_free_i64(tmp64);
7530
                        } else {
7531
                            /* smuad, smusd, smlad, smlsd */
7532
                            if (rd != 15)
7533
                              {
7534
                                tmp2 = load_reg(s, rd);
7535
                                gen_helper_add_setq(tmp, tmp, tmp2);
7536
                                tcg_temp_free_i32(tmp2);
7537
                              }
7538
                            store_reg(s, rn, tmp);
7539
                        }
7540
                        break;
7541
                    case 1:
7542
                    case 3:
7543
                        /* SDIV, UDIV */
7544
                        if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7545
                            goto illegal_op;
7546
                        }
7547
                        if (((insn >> 5) & 7) || (rd != 15)) {
7548
                            goto illegal_op;
7549
                        }
7550
                        tmp = load_reg(s, rm);
7551
                        tmp2 = load_reg(s, rs);
7552
                        if (insn & (1 << 21)) {
7553
                            gen_helper_udiv(tmp, tmp, tmp2);
7554
                        } else {
7555
                            gen_helper_sdiv(tmp, tmp, tmp2);
7556
                        }
7557
                        tcg_temp_free_i32(tmp2);
7558
                        store_reg(s, rn, tmp);
7559
                        break;
7560
                    default:
7561
                        goto illegal_op;
7562
                    }
7563
                    break;
7564
                case 3:
7565
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7566
                    switch (op1) {
7567
                    case 0: /* Unsigned sum of absolute differences.  */
7568
                        ARCH(6);
7569
                        tmp = load_reg(s, rm);
7570
                        tmp2 = load_reg(s, rs);
7571
                        gen_helper_usad8(tmp, tmp, tmp2);
7572
                        tcg_temp_free_i32(tmp2);
7573
                        if (rd != 15) {
7574
                            tmp2 = load_reg(s, rd);
7575
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7576
                            tcg_temp_free_i32(tmp2);
7577
                        }
7578
                        store_reg(s, rn, tmp);
7579
                        break;
7580
                    case 0x20: case 0x24: case 0x28: case 0x2c:
7581
                        /* Bitfield insert/clear.  */
7582
                        ARCH(6T2);
7583
                        shift = (insn >> 7) & 0x1f;
7584
                        i = (insn >> 16) & 0x1f;
7585
                        i = i + 1 - shift;
7586
                        if (rm == 15) {
7587
                            tmp = tcg_temp_new_i32();
7588
                            tcg_gen_movi_i32(tmp, 0);
7589
                        } else {
7590
                            tmp = load_reg(s, rm);
7591
                        }
7592
                        if (i != 32) {
7593
                            tmp2 = load_reg(s, rd);
7594
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
7595
                            tcg_temp_free_i32(tmp2);
7596
                        }
7597
                        store_reg(s, rd, tmp);
7598
                        break;
7599
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7600
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7601
                        ARCH(6T2);
7602
                        tmp = load_reg(s, rm);
7603
                        shift = (insn >> 7) & 0x1f;
7604
                        i = ((insn >> 16) & 0x1f) + 1;
7605
                        if (shift + i > 32)
7606
                            goto illegal_op;
7607
                        if (i < 32) {
7608
                            if (op1 & 0x20) {
7609
                                gen_ubfx(tmp, shift, (1u << i) - 1);
7610
                            } else {
7611
                                gen_sbfx(tmp, shift, i);
7612
                            }
7613
                        }
7614
                        store_reg(s, rd, tmp);
7615
                        break;
7616
                    default:
7617
                        goto illegal_op;
7618
                    }
7619
                    break;
7620
                }
7621
                break;
7622
            }
7623
        do_ldst:
7624
            /* Check for undefined extension instructions
7625
             * per the ARM Bible IE:
7626
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
7627
             */
7628
            sh = (0xf << 20) | (0xf << 4);
7629
            if (op1 == 0x7 && ((insn & sh) == sh))
7630
            {
7631
                goto illegal_op;
7632
            }
7633
            /* load/store byte/word */
7634
            rn = (insn >> 16) & 0xf;
7635
            rd = (insn >> 12) & 0xf;
7636
            tmp2 = load_reg(s, rn);
7637
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7638
            if (insn & (1 << 24))
7639
                gen_add_data_offset(s, insn, tmp2);
7640
            if (insn & (1 << 20)) {
7641
                /* load */
7642
                if (insn & (1 << 22)) {
7643
                    tmp = gen_ld8u(tmp2, i);
7644
                } else {
7645
                    tmp = gen_ld32(tmp2, i);
7646
                }
7647
            } else {
7648
                /* store */
7649
                tmp = load_reg(s, rd);
7650
                if (insn & (1 << 22))
7651
                    gen_st8(tmp, tmp2, i);
7652
                else
7653
                    gen_st32(tmp, tmp2, i);
7654
            }
7655
            if (!(insn & (1 << 24))) {
7656
                gen_add_data_offset(s, insn, tmp2);
7657
                store_reg(s, rn, tmp2);
7658
            } else if (insn & (1 << 21)) {
7659
                store_reg(s, rn, tmp2);
7660
            } else {
7661
                tcg_temp_free_i32(tmp2);
7662
            }
7663
            if (insn & (1 << 20)) {
7664
                /* Complete the load.  */
7665
                store_reg_from_load(env, s, rd, tmp);
7666
            }
7667
            break;
7668
        case 0x08:
7669
        case 0x09:
7670
            {
7671
                int j, n, user, loaded_base;
7672
                TCGv loaded_var;
7673
                /* load/store multiple words */
7674
                /* XXX: store correct base if write back */
7675
                user = 0;
7676
                if (insn & (1 << 22)) {
7677
                    if (IS_USER(s))
7678
                        goto illegal_op; /* only usable in supervisor mode */
7679

    
7680
                    if ((insn & (1 << 15)) == 0)
7681
                        user = 1;
7682
                }
7683
                rn = (insn >> 16) & 0xf;
7684
                addr = load_reg(s, rn);
7685

    
7686
                /* compute total size */
7687
                loaded_base = 0;
7688
                TCGV_UNUSED(loaded_var);
7689
                n = 0;
7690
                for(i=0;i<16;i++) {
7691
                    if (insn & (1 << i))
7692
                        n++;
7693
                }
7694
                /* XXX: test invalid n == 0 case ? */
7695
                if (insn & (1 << 23)) {
7696
                    if (insn & (1 << 24)) {
7697
                        /* pre increment */
7698
                        tcg_gen_addi_i32(addr, addr, 4);
7699
                    } else {
7700
                        /* post increment */
7701
                    }
7702
                } else {
7703
                    if (insn & (1 << 24)) {
7704
                        /* pre decrement */
7705
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
7706
                    } else {
7707
                        /* post decrement */
7708
                        if (n != 1)
7709
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7710
                    }
7711
                }
7712
                j = 0;
7713
                for(i=0;i<16;i++) {
7714
                    if (insn & (1 << i)) {
7715
                        if (insn & (1 << 20)) {
7716
                            /* load */
7717
                            tmp = gen_ld32(addr, IS_USER(s));
7718
                            if (user) {
7719
                                tmp2 = tcg_const_i32(i);
7720
                                gen_helper_set_user_reg(tmp2, tmp);
7721
                                tcg_temp_free_i32(tmp2);
7722
                                tcg_temp_free_i32(tmp);
7723
                            } else if (i == rn) {
7724
                                loaded_var = tmp;
7725
                                loaded_base = 1;
7726
                            } else {
7727
                                store_reg_from_load(env, s, i, tmp);
7728
                            }
7729
                        } else {
7730
                            /* store */
7731
                            if (i == 15) {
7732
                                /* special case: r15 = PC + 8 */
7733
                                val = (long)s->pc + 4;
7734
                                tmp = tcg_temp_new_i32();
7735
                                tcg_gen_movi_i32(tmp, val);
7736
                            } else if (user) {
7737
                                tmp = tcg_temp_new_i32();
7738
                                tmp2 = tcg_const_i32(i);
7739
                                gen_helper_get_user_reg(tmp, tmp2);
7740
                                tcg_temp_free_i32(tmp2);
7741
                            } else {
7742
                                tmp = load_reg(s, i);
7743
                            }
7744
                            gen_st32(tmp, addr, IS_USER(s));
7745
                        }
7746
                        j++;
7747
                        /* no need to add after the last transfer */
7748
                        if (j != n)
7749
                            tcg_gen_addi_i32(addr, addr, 4);
7750
                    }
7751
                }
7752
                if (insn & (1 << 21)) {
7753
                    /* write back */
7754
                    if (insn & (1 << 23)) {
7755
                        if (insn & (1 << 24)) {
7756
                            /* pre increment */
7757
                        } else {
7758
                            /* post increment */
7759
                            tcg_gen_addi_i32(addr, addr, 4);
7760
                        }
7761
                    } else {
7762
                        if (insn & (1 << 24)) {
7763
                            /* pre decrement */
7764
                            if (n != 1)
7765
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7766
                        } else {
7767
                            /* post decrement */
7768
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
7769
                        }
7770
                    }
7771
                    store_reg(s, rn, addr);
7772
                } else {
7773
                    tcg_temp_free_i32(addr);
7774
                }
7775
                if (loaded_base) {
7776
                    store_reg(s, rn, loaded_var);
7777
                }
7778
                if ((insn & (1 << 22)) && !user) {
7779
                    /* Restore CPSR from SPSR.  */
7780
                    tmp = load_cpu_field(spsr);
7781
                    gen_set_cpsr(tmp, 0xffffffff);
7782
                    tcg_temp_free_i32(tmp);
7783
                    s->is_jmp = DISAS_UPDATE;
7784
                }
7785
            }
7786
            break;
7787
        case 0xa:
7788
        case 0xb:
7789
            {
7790
                int32_t offset;
7791

    
7792
                /* branch (and link) */
7793
                val = (int32_t)s->pc;
7794
                if (insn & (1 << 24)) {
7795
                    tmp = tcg_temp_new_i32();
7796
                    tcg_gen_movi_i32(tmp, val);
7797
                    store_reg(s, 14, tmp);
7798
                }
7799
                offset = (((int32_t)insn << 8) >> 8);
7800
                val += (offset << 2) + 4;
7801
                gen_jmp(s, val);
7802
            }
7803
            break;
7804
        case 0xc:
7805
        case 0xd:
7806
        case 0xe:
7807
            /* Coprocessor.  */
7808
            if (disas_coproc_insn(env, s, insn))
7809
                goto illegal_op;
7810
            break;
7811
        case 0xf:
7812
            /* swi */
7813
            gen_set_pc_im(s->pc);
7814
            s->is_jmp = DISAS_SWI;
7815
            break;
7816
        default:
7817
        illegal_op:
7818
            gen_exception_insn(s, 4, EXCP_UDEF);
7819
            break;
7820
        }
7821
    }
7822
}
7823

    
7824
/* Return true if this is a Thumb-2 logical op.  */
7825
static int
7826
thumb2_logic_op(int op)
7827
{
7828
    return (op < 8);
7829
}
7830

    
7831
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7832
   then set condition code flags based on the result of the operation.
7833
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7834
   to the high bit of T1.
7835
   Returns zero if the opcode is valid.  */
7836

    
7837
static int
7838
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7839
{
7840
    int logic_cc;
7841

    
7842
    logic_cc = 0;
7843
    switch (op) {
7844
    case 0: /* and */
7845
        tcg_gen_and_i32(t0, t0, t1);
7846
        logic_cc = conds;
7847
        break;
7848
    case 1: /* bic */
7849
        tcg_gen_andc_i32(t0, t0, t1);
7850
        logic_cc = conds;
7851
        break;
7852
    case 2: /* orr */
7853
        tcg_gen_or_i32(t0, t0, t1);
7854
        logic_cc = conds;
7855
        break;
7856
    case 3: /* orn */
7857
        tcg_gen_orc_i32(t0, t0, t1);
7858
        logic_cc = conds;
7859
        break;
7860
    case 4: /* eor */
7861
        tcg_gen_xor_i32(t0, t0, t1);
7862
        logic_cc = conds;
7863
        break;
7864
    case 8: /* add */
7865
        if (conds)
7866
            gen_helper_add_cc(t0, t0, t1);
7867
        else
7868
            tcg_gen_add_i32(t0, t0, t1);
7869
        break;
7870
    case 10: /* adc */
7871
        if (conds)
7872
            gen_helper_adc_cc(t0, t0, t1);
7873
        else
7874
            gen_adc(t0, t1);
7875
        break;
7876
    case 11: /* sbc */
7877
        if (conds)
7878
            gen_helper_sbc_cc(t0, t0, t1);
7879
        else
7880
            gen_sub_carry(t0, t0, t1);
7881
        break;
7882
    case 13: /* sub */
7883
        if (conds)
7884
            gen_helper_sub_cc(t0, t0, t1);
7885
        else
7886
            tcg_gen_sub_i32(t0, t0, t1);
7887
        break;
7888
    case 14: /* rsb */
7889
        if (conds)
7890
            gen_helper_sub_cc(t0, t1, t0);
7891
        else
7892
            tcg_gen_sub_i32(t0, t1, t0);
7893
        break;
7894
    default: /* 5, 6, 7, 9, 12, 15. */
7895
        return 1;
7896
    }
7897
    if (logic_cc) {
7898
        gen_logic_CC(t0);
7899
        if (shifter_out)
7900
            gen_set_CF_bit31(t1);
7901
    }
7902
    return 0;
7903
}
7904

    
7905
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7906
   is not legal.  */
7907
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
7908
{
7909
    uint32_t insn, imm, shift, offset;
7910
    uint32_t rd, rn, rm, rs;
7911
    TCGv tmp;
7912
    TCGv tmp2;
7913
    TCGv tmp3;
7914
    TCGv addr;
7915
    TCGv_i64 tmp64;
7916
    int op;
7917
    int shiftop;
7918
    int conds;
7919
    int logic_cc;
7920

    
7921
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7922
          || arm_feature (env, ARM_FEATURE_M))) {
7923
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7924
           16-bit instructions to get correct prefetch abort behavior.  */
7925
        insn = insn_hw1;
7926
        if ((insn & (1 << 12)) == 0) {
7927
            ARCH(5);
7928
            /* Second half of blx.  */
7929
            offset = ((insn & 0x7ff) << 1);
7930
            tmp = load_reg(s, 14);
7931
            tcg_gen_addi_i32(tmp, tmp, offset);
7932
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7933

    
7934
            tmp2 = tcg_temp_new_i32();
7935
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7936
            store_reg(s, 14, tmp2);
7937
            gen_bx(s, tmp);
7938
            return 0;
7939
        }
7940
        if (insn & (1 << 11)) {
7941
            /* Second half of bl.  */
7942
            offset = ((insn & 0x7ff) << 1) | 1;
7943
            tmp = load_reg(s, 14);
7944
            tcg_gen_addi_i32(tmp, tmp, offset);
7945

    
7946
            tmp2 = tcg_temp_new_i32();
7947
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7948
            store_reg(s, 14, tmp2);
7949
            gen_bx(s, tmp);
7950
            return 0;
7951
        }
7952
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7953
            /* Instruction spans a page boundary.  Implement it as two
7954
               16-bit instructions in case the second half causes an
7955
               prefetch abort.  */
7956
            offset = ((int32_t)insn << 21) >> 9;
7957
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7958
            return 0;
7959
        }
7960
        /* Fall through to 32-bit decode.  */
7961
    }
7962

    
7963
    insn = arm_lduw_code(s->pc, s->bswap_code);
7964
    s->pc += 2;
7965
    insn |= (uint32_t)insn_hw1 << 16;
7966

    
7967
    if ((insn & 0xf800e800) != 0xf000e800) {
7968
        ARCH(6T2);
7969
    }
7970

    
7971
    rn = (insn >> 16) & 0xf;
7972
    rs = (insn >> 12) & 0xf;
7973
    rd = (insn >> 8) & 0xf;
7974
    rm = insn & 0xf;
7975
    switch ((insn >> 25) & 0xf) {
7976
    case 0: case 1: case 2: case 3:
7977
        /* 16-bit instructions.  Should never happen.  */
7978
        abort();
7979
    case 4:
7980
        if (insn & (1 << 22)) {
7981
            /* Other load/store, table branch.  */
7982
            if (insn & 0x01200000) {
7983
                /* Load/store doubleword.  */
7984
                if (rn == 15) {
7985
                    addr = tcg_temp_new_i32();
7986
                    tcg_gen_movi_i32(addr, s->pc & ~3);
7987
                } else {
7988
                    addr = load_reg(s, rn);
7989
                }
7990
                offset = (insn & 0xff) * 4;
7991
                if ((insn & (1 << 23)) == 0)
7992
                    offset = -offset;
7993
                if (insn & (1 << 24)) {
7994
                    tcg_gen_addi_i32(addr, addr, offset);
7995
                    offset = 0;
7996
                }
7997
                if (insn & (1 << 20)) {
7998
                    /* ldrd */
7999
                    tmp = gen_ld32(addr, IS_USER(s));
8000
                    store_reg(s, rs, tmp);
8001
                    tcg_gen_addi_i32(addr, addr, 4);
8002
                    tmp = gen_ld32(addr, IS_USER(s));
8003
                    store_reg(s, rd, tmp);
8004
                } else {
8005
                    /* strd */
8006
                    tmp = load_reg(s, rs);
8007
                    gen_st32(tmp, addr, IS_USER(s));
8008
                    tcg_gen_addi_i32(addr, addr, 4);
8009
                    tmp = load_reg(s, rd);
8010
                    gen_st32(tmp, addr, IS_USER(s));
8011
                }
8012
                if (insn & (1 << 21)) {
8013
                    /* Base writeback.  */
8014
                    if (rn == 15)
8015
                        goto illegal_op;
8016
                    tcg_gen_addi_i32(addr, addr, offset - 4);
8017
                    store_reg(s, rn, addr);
8018
                } else {
8019
                    tcg_temp_free_i32(addr);
8020
                }
8021
            } else if ((insn & (1 << 23)) == 0) {
8022
                /* Load/store exclusive word.  */
8023
                addr = tcg_temp_local_new();
8024
                load_reg_var(s, addr, rn);
8025
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8026
                if (insn & (1 << 20)) {
8027
                    gen_load_exclusive(s, rs, 15, addr, 2);
8028
                } else {
8029
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
8030
                }
8031
                tcg_temp_free(addr);
8032
            } else if ((insn & (1 << 6)) == 0) {
8033
                /* Table Branch.  */
8034
                if (rn == 15) {
8035
                    addr = tcg_temp_new_i32();
8036
                    tcg_gen_movi_i32(addr, s->pc);
8037
                } else {
8038
                    addr = load_reg(s, rn);
8039
                }
8040
                tmp = load_reg(s, rm);
8041
                tcg_gen_add_i32(addr, addr, tmp);
8042
                if (insn & (1 << 4)) {
8043
                    /* tbh */
8044
                    tcg_gen_add_i32(addr, addr, tmp);
8045
                    tcg_temp_free_i32(tmp);
8046
                    tmp = gen_ld16u(addr, IS_USER(s));
8047
                } else { /* tbb */
8048
                    tcg_temp_free_i32(tmp);
8049
                    tmp = gen_ld8u(addr, IS_USER(s));
8050
                }
8051
                tcg_temp_free_i32(addr);
8052
                tcg_gen_shli_i32(tmp, tmp, 1);
8053
                tcg_gen_addi_i32(tmp, tmp, s->pc);
8054
                store_reg(s, 15, tmp);
8055
            } else {
8056
                /* Load/store exclusive byte/halfword/doubleword.  */
8057
                ARCH(7);
8058
                op = (insn >> 4) & 0x3;
8059
                if (op == 2) {
8060
                    goto illegal_op;
8061
                }
8062
                addr = tcg_temp_local_new();
8063
                load_reg_var(s, addr, rn);
8064
                if (insn & (1 << 20)) {
8065
                    gen_load_exclusive(s, rs, rd, addr, op);
8066
                } else {
8067
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
8068
                }
8069
                tcg_temp_free(addr);
8070
            }
8071
        } else {
8072
            /* Load/store multiple, RFE, SRS.  */
8073
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8074
                /* Not available in user mode.  */
8075
                if (IS_USER(s))
8076
                    goto illegal_op;
8077
                if (insn & (1 << 20)) {
8078
                    /* rfe */
8079
                    addr = load_reg(s, rn);
8080
                    if ((insn & (1 << 24)) == 0)
8081
                        tcg_gen_addi_i32(addr, addr, -8);
8082
                    /* Load PC into tmp and CPSR into tmp2.  */
8083
                    tmp = gen_ld32(addr, 0);
8084
                    tcg_gen_addi_i32(addr, addr, 4);
8085
                    tmp2 = gen_ld32(addr, 0);
8086
                    if (insn & (1 << 21)) {
8087
                        /* Base writeback.  */
8088
                        if (insn & (1 << 24)) {
8089
                            tcg_gen_addi_i32(addr, addr, 4);
8090
                        } else {
8091
                            tcg_gen_addi_i32(addr, addr, -4);
8092
                        }
8093
                        store_reg(s, rn, addr);
8094
                    } else {
8095
                        tcg_temp_free_i32(addr);
8096
                    }
8097
                    gen_rfe(s, tmp, tmp2);
8098
                } else {
8099
                    /* srs */
8100
                    op = (insn & 0x1f);
8101
                    addr = tcg_temp_new_i32();
8102
                    tmp = tcg_const_i32(op);
8103
                    gen_helper_get_r13_banked(addr, cpu_env, tmp);
8104
                    tcg_temp_free_i32(tmp);
8105
                    if ((insn & (1 << 24)) == 0) {
8106
                        tcg_gen_addi_i32(addr, addr, -8);
8107
                    }
8108
                    tmp = load_reg(s, 14);
8109
                    gen_st32(tmp, addr, 0);
8110
                    tcg_gen_addi_i32(addr, addr, 4);
8111
                    tmp = tcg_temp_new_i32();
8112
                    gen_helper_cpsr_read(tmp);
8113
                    gen_st32(tmp, addr, 0);
8114
                    if (insn & (1 << 21)) {
8115
                        if ((insn & (1 << 24)) == 0) {
8116
                            tcg_gen_addi_i32(addr, addr, -4);
8117
                        } else {
8118
                            tcg_gen_addi_i32(addr, addr, 4);
8119
                        }
8120
                        tmp = tcg_const_i32(op);
8121
                        gen_helper_set_r13_banked(cpu_env, tmp, addr);
8122
                        tcg_temp_free_i32(tmp);
8123
                    } else {
8124
                        tcg_temp_free_i32(addr);
8125
                    }
8126
                }
8127
            } else {
8128
                int i, loaded_base = 0;
8129
                TCGv loaded_var;
8130
                /* Load/store multiple.  */
8131
                addr = load_reg(s, rn);
8132
                offset = 0;
8133
                for (i = 0; i < 16; i++) {
8134
                    if (insn & (1 << i))
8135
                        offset += 4;
8136
                }
8137
                if (insn & (1 << 24)) {
8138
                    tcg_gen_addi_i32(addr, addr, -offset);
8139
                }
8140

    
8141
                TCGV_UNUSED(loaded_var);
8142
                for (i = 0; i < 16; i++) {
8143
                    if ((insn & (1 << i)) == 0)
8144
                        continue;
8145
                    if (insn & (1 << 20)) {
8146
                        /* Load.  */
8147
                        tmp = gen_ld32(addr, IS_USER(s));
8148
                        if (i == 15) {
8149
                            gen_bx(s, tmp);
8150
                        } else if (i == rn) {
8151
                            loaded_var = tmp;
8152
                            loaded_base = 1;
8153
                        } else {
8154
                            store_reg(s, i, tmp);
8155
                        }
8156
                    } else {
8157
                        /* Store.  */
8158
                        tmp = load_reg(s, i);
8159
                        gen_st32(tmp, addr, IS_USER(s));
8160
                    }
8161
                    tcg_gen_addi_i32(addr, addr, 4);
8162
                }
8163
                if (loaded_base) {
8164
                    store_reg(s, rn, loaded_var);
8165
                }
8166
                if (insn & (1 << 21)) {
8167
                    /* Base register writeback.  */
8168
                    if (insn & (1 << 24)) {
8169
                        tcg_gen_addi_i32(addr, addr, -offset);
8170
                    }
8171
                    /* Fault if writeback register is in register list.  */
8172
                    if (insn & (1 << rn))
8173
                        goto illegal_op;
8174
                    store_reg(s, rn, addr);
8175
                } else {
8176
                    tcg_temp_free_i32(addr);
8177
                }
8178
            }
8179
        }
8180
        break;
8181
    case 5:
8182

    
8183
        op = (insn >> 21) & 0xf;
8184
        if (op == 6) {
8185
            /* Halfword pack.  */
8186
            tmp = load_reg(s, rn);
8187
            tmp2 = load_reg(s, rm);
8188
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8189
            if (insn & (1 << 5)) {
8190
                /* pkhtb */
8191
                if (shift == 0)
8192
                    shift = 31;
8193
                tcg_gen_sari_i32(tmp2, tmp2, shift);
8194
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8195
                tcg_gen_ext16u_i32(tmp2, tmp2);
8196
            } else {
8197
                /* pkhbt */
8198
                if (shift)
8199
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
8200
                tcg_gen_ext16u_i32(tmp, tmp);
8201
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8202
            }
8203
            tcg_gen_or_i32(tmp, tmp, tmp2);
8204
            tcg_temp_free_i32(tmp2);
8205
            store_reg(s, rd, tmp);
8206
        } else {
8207
            /* Data processing register constant shift.  */
8208
            if (rn == 15) {
8209
                tmp = tcg_temp_new_i32();
8210
                tcg_gen_movi_i32(tmp, 0);
8211
            } else {
8212
                tmp = load_reg(s, rn);
8213
            }
8214
            tmp2 = load_reg(s, rm);
8215

    
8216
            shiftop = (insn >> 4) & 3;
8217
            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8218
            conds = (insn & (1 << 20)) != 0;
8219
            logic_cc = (conds && thumb2_logic_op(op));
8220
            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8221
            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8222
                goto illegal_op;
8223
            tcg_temp_free_i32(tmp2);
8224
            if (rd != 15) {
8225
                store_reg(s, rd, tmp);
8226
            } else {
8227
                tcg_temp_free_i32(tmp);
8228
            }
8229
        }
8230
        break;
8231
    case 13: /* Misc data processing.  */
8232
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8233
        if (op < 4 && (insn & 0xf000) != 0xf000)
8234
            goto illegal_op;
8235
        switch (op) {
8236
        case 0: /* Register controlled shift.  */
8237
            tmp = load_reg(s, rn);
8238
            tmp2 = load_reg(s, rm);
8239
            if ((insn & 0x70) != 0)
8240
                goto illegal_op;
8241
            op = (insn >> 21) & 3;
8242
            logic_cc = (insn & (1 << 20)) != 0;
8243
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8244
            if (logic_cc)
8245
                gen_logic_CC(tmp);
8246
            store_reg_bx(env, s, rd, tmp);
8247
            break;
8248
        case 1: /* Sign/zero extend.  */
8249
            tmp = load_reg(s, rm);
8250
            shift = (insn >> 4) & 3;
8251
            /* ??? In many cases it's not necessary to do a
8252
               rotate, a shift is sufficient.  */
8253
            if (shift != 0)
8254
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8255
            op = (insn >> 20) & 7;
8256
            switch (op) {
8257
            case 0: gen_sxth(tmp);   break;
8258
            case 1: gen_uxth(tmp);   break;
8259
            case 2: gen_sxtb16(tmp); break;
8260
            case 3: gen_uxtb16(tmp); break;
8261
            case 4: gen_sxtb(tmp);   break;
8262
            case 5: gen_uxtb(tmp);   break;
8263
            default: goto illegal_op;
8264
            }
8265
            if (rn != 15) {
8266
                tmp2 = load_reg(s, rn);
8267
                if ((op >> 1) == 1) {
8268
                    gen_add16(tmp, tmp2);
8269
                } else {
8270
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8271
                    tcg_temp_free_i32(tmp2);
8272
                }
8273
            }
8274
            store_reg(s, rd, tmp);
8275
            break;
8276
        case 2: /* SIMD add/subtract.  */
8277
            op = (insn >> 20) & 7;
8278
            shift = (insn >> 4) & 7;
8279
            if ((op & 3) == 3 || (shift & 3) == 3)
8280
                goto illegal_op;
8281
            tmp = load_reg(s, rn);
8282
            tmp2 = load_reg(s, rm);
8283
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8284
            tcg_temp_free_i32(tmp2);
8285
            store_reg(s, rd, tmp);
8286
            break;
8287
        case 3: /* Other data processing.  */
8288
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8289
            if (op < 4) {
8290
                /* Saturating add/subtract.  */
8291
                tmp = load_reg(s, rn);
8292
                tmp2 = load_reg(s, rm);
8293
                if (op & 1)
8294
                    gen_helper_double_saturate(tmp, tmp);
8295
                if (op & 2)
8296
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
8297
                else
8298
                    gen_helper_add_saturate(tmp, tmp, tmp2);
8299
                tcg_temp_free_i32(tmp2);
8300
            } else {
8301
                tmp = load_reg(s, rn);
8302
                switch (op) {
8303
                case 0x0a: /* rbit */
8304
                    gen_helper_rbit(tmp, tmp);
8305
                    break;
8306
                case 0x08: /* rev */
8307
                    tcg_gen_bswap32_i32(tmp, tmp);
8308
                    break;
8309
                case 0x09: /* rev16 */
8310
                    gen_rev16(tmp);
8311
                    break;
8312
                case 0x0b: /* revsh */
8313
                    gen_revsh(tmp);
8314
                    break;
8315
                case 0x10: /* sel */
8316
                    tmp2 = load_reg(s, rm);
8317
                    tmp3 = tcg_temp_new_i32();
8318
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8319
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8320
                    tcg_temp_free_i32(tmp3);
8321
                    tcg_temp_free_i32(tmp2);
8322
                    break;
8323
                case 0x18: /* clz */
8324
                    gen_helper_clz(tmp, tmp);
8325
                    break;
8326
                default:
8327
                    goto illegal_op;
8328
                }
8329
            }
8330
            store_reg(s, rd, tmp);
8331
            break;
8332
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
8333
            op = (insn >> 4) & 0xf;
8334
            tmp = load_reg(s, rn);
8335
            tmp2 = load_reg(s, rm);
8336
            switch ((insn >> 20) & 7) {
8337
            case 0: /* 32 x 32 -> 32 */
8338
                tcg_gen_mul_i32(tmp, tmp, tmp2);
8339
                tcg_temp_free_i32(tmp2);
8340
                if (rs != 15) {
8341
                    tmp2 = load_reg(s, rs);
8342
                    if (op)
8343
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
8344
                    else
8345
                        tcg_gen_add_i32(tmp, tmp, tmp2);
8346
                    tcg_temp_free_i32(tmp2);
8347
                }
8348
                break;
8349
            case 1: /* 16 x 16 -> 32 */
8350
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
8351
                tcg_temp_free_i32(tmp2);
8352
                if (rs != 15) {
8353
                    tmp2 = load_reg(s, rs);
8354
                    gen_helper_add_setq(tmp, tmp, tmp2);
8355
                    tcg_temp_free_i32(tmp2);
8356
                }
8357
                break;
8358
            case 2: /* Dual multiply add.  */
8359
            case 4: /* Dual multiply subtract.  */
8360
                if (op)
8361
                    gen_swap_half(tmp2);
8362
                gen_smul_dual(tmp, tmp2);
8363
                if (insn & (1 << 22)) {
8364
                    /* This subtraction cannot overflow. */
8365
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8366
                } else {
8367
                    /* This addition cannot overflow 32 bits;
8368
                     * however it may overflow considered as a signed
8369
                     * operation, in which case we must set the Q flag.
8370
                     */
8371
                    gen_helper_add_setq(tmp, tmp, tmp2);
8372
                }
8373
                tcg_temp_free_i32(tmp2);
8374
                if (rs != 15)
8375
                  {
8376
                    tmp2 = load_reg(s, rs);
8377
                    gen_helper_add_setq(tmp, tmp, tmp2);
8378
                    tcg_temp_free_i32(tmp2);
8379
                  }
8380
                break;
8381
            case 3: /* 32 * 16 -> 32msb */
8382
                if (op)
8383
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
8384
                else
8385
                    gen_sxth(tmp2);
8386
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
8387
                tcg_gen_shri_i64(tmp64, tmp64, 16);
8388
                tmp = tcg_temp_new_i32();
8389
                tcg_gen_trunc_i64_i32(tmp, tmp64);
8390
                tcg_temp_free_i64(tmp64);
8391
                if (rs != 15)
8392
                  {
8393
                    tmp2 = load_reg(s, rs);
8394
                    gen_helper_add_setq(tmp, tmp, tmp2);
8395
                    tcg_temp_free_i32(tmp2);
8396
                  }
8397
                break;
8398
            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8399
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
8400
                if (rs != 15) {
8401
                    tmp = load_reg(s, rs);
8402
                    if (insn & (1 << 20)) {
8403
                        tmp64 = gen_addq_msw(tmp64, tmp);
8404
                    } else {
8405
                        tmp64 = gen_subq_msw(tmp64, tmp);
8406
                    }
8407
                }
8408
                if (insn & (1 << 4)) {
8409
                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8410
                }
8411
                tcg_gen_shri_i64(tmp64, tmp64, 32);
8412
                tmp = tcg_temp_new_i32();
8413
                tcg_gen_trunc_i64_i32(tmp, tmp64);
8414
                tcg_temp_free_i64(tmp64);
8415
                break;
8416
            case 7: /* Unsigned sum of absolute differences.  */
8417
                gen_helper_usad8(tmp, tmp, tmp2);
8418
                tcg_temp_free_i32(tmp2);
8419
                if (rs != 15) {
8420
                    tmp2 = load_reg(s, rs);
8421
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8422
                    tcg_temp_free_i32(tmp2);
8423
                }
8424
                break;
8425
            }
8426
            store_reg(s, rd, tmp);
8427
            break;
8428
        case 6: case 7: /* 64-bit multiply, Divide.  */
8429
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8430
            tmp = load_reg(s, rn);
8431
            tmp2 = load_reg(s, rm);
8432
            if ((op & 0x50) == 0x10) {
8433
                /* sdiv, udiv */
8434
                if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8435
                    goto illegal_op;
8436
                }
8437
                if (op & 0x20)
8438
                    gen_helper_udiv(tmp, tmp, tmp2);
8439
                else
8440
                    gen_helper_sdiv(tmp, tmp, tmp2);
8441
                tcg_temp_free_i32(tmp2);
8442
                store_reg(s, rd, tmp);
8443
            } else if ((op & 0xe) == 0xc) {
8444
                /* Dual multiply accumulate long.  */
8445
                if (op & 1)
8446
                    gen_swap_half(tmp2);
8447
                gen_smul_dual(tmp, tmp2);
8448
                if (op & 0x10) {
8449
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8450
                } else {
8451
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8452
                }
8453
                tcg_temp_free_i32(tmp2);
8454
                /* BUGFIX */
8455
                tmp64 = tcg_temp_new_i64();
8456
                tcg_gen_ext_i32_i64(tmp64, tmp);
8457
                tcg_temp_free_i32(tmp);
8458
                gen_addq(s, tmp64, rs, rd);
8459
                gen_storeq_reg(s, rs, rd, tmp64);
8460
                tcg_temp_free_i64(tmp64);
8461
            } else {
8462
                if (op & 0x20) {
8463
                    /* Unsigned 64-bit multiply  */
8464
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8465
                } else {
8466
                    if (op & 8) {
8467
                        /* smlalxy */
8468
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
8469
                        tcg_temp_free_i32(tmp2);
8470
                        tmp64 = tcg_temp_new_i64();
8471
                        tcg_gen_ext_i32_i64(tmp64, tmp);
8472
                        tcg_temp_free_i32(tmp);
8473
                    } else {
8474
                        /* Signed 64-bit multiply  */
8475
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
8476
                    }
8477
                }
8478
                if (op & 4) {
8479
                    /* umaal */
8480
                    gen_addq_lo(s, tmp64, rs);
8481
                    gen_addq_lo(s, tmp64, rd);
8482
                } else if (op & 0x40) {
8483
                    /* 64-bit accumulate.  */
8484
                    gen_addq(s, tmp64, rs, rd);
8485
                }
8486
                gen_storeq_reg(s, rs, rd, tmp64);
8487
                tcg_temp_free_i64(tmp64);
8488
            }
8489
            break;
8490
        }
8491
        break;
8492
    case 6: case 7: case 14: case 15:
8493
        /* Coprocessor.  */
8494
        if (((insn >> 24) & 3) == 3) {
8495
            /* Translate into the equivalent ARM encoding.  */
8496
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8497
            if (disas_neon_data_insn(env, s, insn))
8498
                goto illegal_op;
8499
        } else {
8500
            if (insn & (1 << 28))
8501
                goto illegal_op;
8502
            if (disas_coproc_insn (env, s, insn))
8503
                goto illegal_op;
8504
        }
8505
        break;
8506
    case 8: case 9: case 10: case 11:
8507
        if (insn & (1 << 15)) {
8508
            /* Branches, misc control.  */
8509
            if (insn & 0x5000) {
8510
                /* Unconditional branch.  */
8511
                /* signextend(hw1[10:0]) -> offset[:12].  */
8512
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8513
                /* hw1[10:0] -> offset[11:1].  */
8514
                offset |= (insn & 0x7ff) << 1;
8515
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8516
                   offset[24:22] already have the same value because of the
8517
                   sign extension above.  */
8518
                offset ^= ((~insn) & (1 << 13)) << 10;
8519
                offset ^= ((~insn) & (1 << 11)) << 11;
8520

    
8521
                if (insn & (1 << 14)) {
8522
                    /* Branch and link.  */
8523
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8524
                }
8525

    
8526
                offset += s->pc;
8527
                if (insn & (1 << 12)) {
8528
                    /* b/bl */
8529
                    gen_jmp(s, offset);
8530
                } else {
8531
                    /* blx */
8532
                    offset &= ~(uint32_t)2;
8533
                    /* thumb2 bx, no need to check */
8534
                    gen_bx_im(s, offset);
8535
                }
8536
            } else if (((insn >> 23) & 7) == 7) {
8537
                /* Misc control */
8538
                if (insn & (1 << 13))
8539
                    goto illegal_op;
8540

    
8541
                if (insn & (1 << 26)) {
8542
                    /* Secure monitor call (v6Z) */
8543
                    goto illegal_op; /* not implemented.  */
8544
                } else {
8545
                    op = (insn >> 20) & 7;
8546
                    switch (op) {
8547
                    case 0: /* msr cpsr.  */
8548
                        if (IS_M(env)) {
8549
                            tmp = load_reg(s, rn);
8550
                            addr = tcg_const_i32(insn & 0xff);
8551
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
8552
                            tcg_temp_free_i32(addr);
8553
                            tcg_temp_free_i32(tmp);
8554
                            gen_lookup_tb(s);
8555
                            break;
8556
                        }
8557
                        /* fall through */
8558
                    case 1: /* msr spsr.  */
8559
                        if (IS_M(env))
8560
                            goto illegal_op;
8561
                        tmp = load_reg(s, rn);
8562
                        if (gen_set_psr(s,
8563
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8564
                              op == 1, tmp))
8565
                            goto illegal_op;
8566
                        break;
8567
                    case 2: /* cps, nop-hint.  */
8568
                        if (((insn >> 8) & 7) == 0) {
8569
                            gen_nop_hint(s, insn & 0xff);
8570
                        }
8571
                        /* Implemented as NOP in user mode.  */
8572
                        if (IS_USER(s))
8573
                            break;
8574
                        offset = 0;
8575
                        imm = 0;
8576
                        if (insn & (1 << 10)) {
8577
                            if (insn & (1 << 7))
8578
                                offset |= CPSR_A;
8579
                            if (insn & (1 << 6))
8580
                                offset |= CPSR_I;
8581
                            if (insn & (1 << 5))
8582
                                offset |= CPSR_F;
8583
                            if (insn & (1 << 9))
8584
                                imm = CPSR_A | CPSR_I | CPSR_F;
8585
                        }
8586
                        if (insn & (1 << 8)) {
8587
                            offset |= 0x1f;
8588
                            imm |= (insn & 0x1f);
8589
                        }
8590
                        if (offset) {
8591
                            gen_set_psr_im(s, offset, 0, imm);
8592
                        }
8593
                        break;
8594
                    case 3: /* Special control operations.  */
8595
                        ARCH(7);
8596
                        op = (insn >> 4) & 0xf;
8597
                        switch (op) {
8598
                        case 2: /* clrex */
8599
                            gen_clrex(s);
8600
                            break;
8601
                        case 4: /* dsb */
8602
                        case 5: /* dmb */
8603
                        case 6: /* isb */
8604
                            /* These execute as NOPs.  */
8605
                            break;
8606
                        default:
8607
                            goto illegal_op;
8608
                        }
8609
                        break;
8610
                    case 4: /* bxj */
8611
                        /* Trivial implementation equivalent to bx.  */
8612
                        tmp = load_reg(s, rn);
8613
                        gen_bx(s, tmp);
8614
                        break;
8615
                    case 5: /* Exception return.  */
8616
                        if (IS_USER(s)) {
8617
                            goto illegal_op;
8618
                        }
8619
                        if (rn != 14 || rd != 15) {
8620
                            goto illegal_op;
8621
                        }
8622
                        tmp = load_reg(s, rn);
8623
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8624
                        gen_exception_return(s, tmp);
8625
                        break;
8626
                    case 6: /* mrs cpsr.  */
8627
                        tmp = tcg_temp_new_i32();
8628
                        if (IS_M(env)) {
8629
                            addr = tcg_const_i32(insn & 0xff);
8630
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
8631
                            tcg_temp_free_i32(addr);
8632
                        } else {
8633
                            gen_helper_cpsr_read(tmp);
8634
                        }
8635
                        store_reg(s, rd, tmp);
8636
                        break;
8637
                    case 7: /* mrs spsr.  */
8638
                        /* Not accessible in user mode.  */
8639
                        if (IS_USER(s) || IS_M(env))
8640
                            goto illegal_op;
8641
                        tmp = load_cpu_field(spsr);
8642
                        store_reg(s, rd, tmp);
8643
                        break;
8644
                    }
8645
                }
8646
            } else {
8647
                /* Conditional branch.  */
8648
                op = (insn >> 22) & 0xf;
8649
                /* Generate a conditional jump to next instruction.  */
8650
                s->condlabel = gen_new_label();
8651
                gen_test_cc(op ^ 1, s->condlabel);
8652
                s->condjmp = 1;
8653

    
8654
                /* offset[11:1] = insn[10:0] */
8655
                offset = (insn & 0x7ff) << 1;
8656
                /* offset[17:12] = insn[21:16].  */
8657
                offset |= (insn & 0x003f0000) >> 4;
8658
                /* offset[31:20] = insn[26].  */
8659
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8660
                /* offset[18] = insn[13].  */
8661
                offset |= (insn & (1 << 13)) << 5;
8662
                /* offset[19] = insn[11].  */
8663
                offset |= (insn & (1 << 11)) << 8;
8664

    
8665
                /* jump to the offset */
8666
                gen_jmp(s, s->pc + offset);
8667
            }
8668
        } else {
8669
            /* Data processing immediate.  */
8670
            if (insn & (1 << 25)) {
8671
                if (insn & (1 << 24)) {
8672
                    if (insn & (1 << 20))
8673
                        goto illegal_op;
8674
                    /* Bitfield/Saturate.  */
8675
                    op = (insn >> 21) & 7;
8676
                    imm = insn & 0x1f;
8677
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8678
                    if (rn == 15) {
8679
                        tmp = tcg_temp_new_i32();
8680
                        tcg_gen_movi_i32(tmp, 0);
8681
                    } else {
8682
                        tmp = load_reg(s, rn);
8683
                    }
8684
                    switch (op) {
8685
                    case 2: /* Signed bitfield extract.  */
8686
                        imm++;
8687
                        if (shift + imm > 32)
8688
                            goto illegal_op;
8689
                        if (imm < 32)
8690
                            gen_sbfx(tmp, shift, imm);
8691
                        break;
8692
                    case 6: /* Unsigned bitfield extract.  */
8693
                        imm++;
8694
                        if (shift + imm > 32)
8695
                            goto illegal_op;
8696
                        if (imm < 32)
8697
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
8698
                        break;
8699
                    case 3: /* Bitfield insert/clear.  */
8700
                        if (imm < shift)
8701
                            goto illegal_op;
8702
                        imm = imm + 1 - shift;
8703
                        if (imm != 32) {
8704
                            tmp2 = load_reg(s, rd);
8705
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
8706
                            tcg_temp_free_i32(tmp2);
8707
                        }
8708
                        break;
8709
                    case 7:
8710
                        goto illegal_op;
8711
                    default: /* Saturate.  */
8712
                        if (shift) {
8713
                            if (op & 1)
8714
                                tcg_gen_sari_i32(tmp, tmp, shift);
8715
                            else
8716
                                tcg_gen_shli_i32(tmp, tmp, shift);
8717
                        }
8718
                        tmp2 = tcg_const_i32(imm);
8719
                        if (op & 4) {
8720
                            /* Unsigned.  */
8721
                            if ((op & 1) && shift == 0)
8722
                                gen_helper_usat16(tmp, tmp, tmp2);
8723
                            else
8724
                                gen_helper_usat(tmp, tmp, tmp2);
8725
                        } else {
8726
                            /* Signed.  */
8727
                            if ((op & 1) && shift == 0)
8728
                                gen_helper_ssat16(tmp, tmp, tmp2);
8729
                            else
8730
                                gen_helper_ssat(tmp, tmp, tmp2);
8731
                        }
8732
                        tcg_temp_free_i32(tmp2);
8733
                        break;
8734
                    }
8735
                    store_reg(s, rd, tmp);
8736
                } else {
8737
                    imm = ((insn & 0x04000000) >> 15)
8738
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
8739
                    if (insn & (1 << 22)) {
8740
                        /* 16-bit immediate.  */
8741
                        imm |= (insn >> 4) & 0xf000;
8742
                        if (insn & (1 << 23)) {
8743
                            /* movt */
8744
                            tmp = load_reg(s, rd);
8745
                            tcg_gen_ext16u_i32(tmp, tmp);
8746
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
8747
                        } else {
8748
                            /* movw */
8749
                            tmp = tcg_temp_new_i32();
8750
                            tcg_gen_movi_i32(tmp, imm);
8751
                        }
8752
                    } else {
8753
                        /* Add/sub 12-bit immediate.  */
8754
                        if (rn == 15) {
8755
                            offset = s->pc & ~(uint32_t)3;
8756
                            if (insn & (1 << 23))
8757
                                offset -= imm;
8758
                            else
8759
                                offset += imm;
8760
                            tmp = tcg_temp_new_i32();
8761
                            tcg_gen_movi_i32(tmp, offset);
8762
                        } else {
8763
                            tmp = load_reg(s, rn);
8764
                            if (insn & (1 << 23))
8765
                                tcg_gen_subi_i32(tmp, tmp, imm);
8766
                            else
8767
                                tcg_gen_addi_i32(tmp, tmp, imm);
8768
                        }
8769
                    }
8770
                    store_reg(s, rd, tmp);
8771
                }
8772
            } else {
8773
                int shifter_out = 0;
8774
                /* modified 12-bit immediate.  */
8775
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8776
                imm = (insn & 0xff);
8777
                switch (shift) {
8778
                case 0: /* XY */
8779
                    /* Nothing to do.  */
8780
                    break;
8781
                case 1: /* 00XY00XY */
8782
                    imm |= imm << 16;
8783
                    break;
8784
                case 2: /* XY00XY00 */
8785
                    imm |= imm << 16;
8786
                    imm <<= 8;
8787
                    break;
8788
                case 3: /* XYXYXYXY */
8789
                    imm |= imm << 16;
8790
                    imm |= imm << 8;
8791
                    break;
8792
                default: /* Rotated constant.  */
8793
                    shift = (shift << 1) | (imm >> 7);
8794
                    imm |= 0x80;
8795
                    imm = imm << (32 - shift);
8796
                    shifter_out = 1;
8797
                    break;
8798
                }
8799
                tmp2 = tcg_temp_new_i32();
8800
                tcg_gen_movi_i32(tmp2, imm);
8801
                rn = (insn >> 16) & 0xf;
8802
                if (rn == 15) {
8803
                    tmp = tcg_temp_new_i32();
8804
                    tcg_gen_movi_i32(tmp, 0);
8805
                } else {
8806
                    tmp = load_reg(s, rn);
8807
                }
8808
                op = (insn >> 21) & 0xf;
8809
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
8810
                                       shifter_out, tmp, tmp2))
8811
                    goto illegal_op;
8812
                tcg_temp_free_i32(tmp2);
8813
                rd = (insn >> 8) & 0xf;
8814
                if (rd != 15) {
8815
                    store_reg(s, rd, tmp);
8816
                } else {
8817
                    tcg_temp_free_i32(tmp);
8818
                }
8819
            }
8820
        }
8821
        break;
8822
    case 12: /* Load/store single data item.  */
8823
        {
8824
        int postinc = 0;
8825
        int writeback = 0;
8826
        int user;
8827
        if ((insn & 0x01100000) == 0x01000000) {
8828
            if (disas_neon_ls_insn(env, s, insn))
8829
                goto illegal_op;
8830
            break;
8831
        }
8832
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8833
        if (rs == 15) {
8834
            if (!(insn & (1 << 20))) {
8835
                goto illegal_op;
8836
            }
8837
            if (op != 2) {
8838
                /* Byte or halfword load space with dest == r15 : memory hints.
8839
                 * Catch them early so we don't emit pointless addressing code.
8840
                 * This space is a mix of:
8841
                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
8842
                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8843
                 *     cores)
8844
                 *  unallocated hints, which must be treated as NOPs
8845
                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
8846
                 *     which is easiest for the decoding logic
8847
                 *  Some space which must UNDEF
8848
                 */
8849
                int op1 = (insn >> 23) & 3;
8850
                int op2 = (insn >> 6) & 0x3f;
8851
                if (op & 2) {
8852
                    goto illegal_op;
8853
                }
8854
                if (rn == 15) {
8855
                    /* UNPREDICTABLE, unallocated hint or
8856
                     * PLD/PLDW/PLI (literal)
8857
                     */
8858
                    return 0;
8859
                }
8860
                if (op1 & 1) {
8861
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
8862
                }
8863
                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
8864
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
8865
                }
8866
                /* UNDEF space, or an UNPREDICTABLE */
8867
                return 1;
8868
            }
8869
        }
8870
        user = IS_USER(s);
8871
        if (rn == 15) {
8872
            addr = tcg_temp_new_i32();
8873
            /* PC relative.  */
8874
            /* s->pc has already been incremented by 4.  */
8875
            imm = s->pc & 0xfffffffc;
8876
            if (insn & (1 << 23))
8877
                imm += insn & 0xfff;
8878
            else
8879
                imm -= insn & 0xfff;
8880
            tcg_gen_movi_i32(addr, imm);
8881
        } else {
8882
            addr = load_reg(s, rn);
8883
            if (insn & (1 << 23)) {
8884
                /* Positive offset.  */
8885
                imm = insn & 0xfff;
8886
                tcg_gen_addi_i32(addr, addr, imm);
8887
            } else {
8888
                imm = insn & 0xff;
8889
                switch ((insn >> 8) & 0xf) {
8890
                case 0x0: /* Shifted Register.  */
8891
                    shift = (insn >> 4) & 0xf;
8892
                    if (shift > 3) {
8893
                        tcg_temp_free_i32(addr);
8894
                        goto illegal_op;
8895
                    }
8896
                    tmp = load_reg(s, rm);
8897
                    if (shift)
8898
                        tcg_gen_shli_i32(tmp, tmp, shift);
8899
                    tcg_gen_add_i32(addr, addr, tmp);
8900
                    tcg_temp_free_i32(tmp);
8901
                    break;
8902
                case 0xc: /* Negative offset.  */
8903
                    tcg_gen_addi_i32(addr, addr, -imm);
8904
                    break;
8905
                case 0xe: /* User privilege.  */
8906
                    tcg_gen_addi_i32(addr, addr, imm);
8907
                    user = 1;
8908
                    break;
8909
                case 0x9: /* Post-decrement.  */
8910
                    imm = -imm;
8911
                    /* Fall through.  */
8912
                case 0xb: /* Post-increment.  */
8913
                    postinc = 1;
8914
                    writeback = 1;
8915
                    break;
8916
                case 0xd: /* Pre-decrement.  */
8917
                    imm = -imm;
8918
                    /* Fall through.  */
8919
                case 0xf: /* Pre-increment.  */
8920
                    tcg_gen_addi_i32(addr, addr, imm);
8921
                    writeback = 1;
8922
                    break;
8923
                default:
8924
                    tcg_temp_free_i32(addr);
8925
                    goto illegal_op;
8926
                }
8927
            }
8928
        }
8929
        if (insn & (1 << 20)) {
8930
            /* Load.  */
8931
            switch (op) {
8932
            case 0: tmp = gen_ld8u(addr, user); break;
8933
            case 4: tmp = gen_ld8s(addr, user); break;
8934
            case 1: tmp = gen_ld16u(addr, user); break;
8935
            case 5: tmp = gen_ld16s(addr, user); break;
8936
            case 2: tmp = gen_ld32(addr, user); break;
8937
            default:
8938
                tcg_temp_free_i32(addr);
8939
                goto illegal_op;
8940
            }
8941
            if (rs == 15) {
8942
                gen_bx(s, tmp);
8943
            } else {
8944
                store_reg(s, rs, tmp);
8945
            }
8946
        } else {
8947
            /* Store.  */
8948
            tmp = load_reg(s, rs);
8949
            switch (op) {
8950
            case 0: gen_st8(tmp, addr, user); break;
8951
            case 1: gen_st16(tmp, addr, user); break;
8952
            case 2: gen_st32(tmp, addr, user); break;
8953
            default:
8954
                tcg_temp_free_i32(addr);
8955
                goto illegal_op;
8956
            }
8957
        }
8958
        if (postinc)
8959
            tcg_gen_addi_i32(addr, addr, imm);
8960
        if (writeback) {
8961
            store_reg(s, rn, addr);
8962
        } else {
8963
            tcg_temp_free_i32(addr);
8964
        }
8965
        }
8966
        break;
8967
    default:
8968
        goto illegal_op;
8969
    }
8970
    return 0;
8971
illegal_op:
8972
    return 1;
8973
}
8974

    
8975
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
8976
{
8977
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8978
    int32_t offset;
8979
    int i;
8980
    TCGv tmp;
8981
    TCGv tmp2;
8982
    TCGv addr;
8983

    
8984
    if (s->condexec_mask) {
8985
        cond = s->condexec_cond;
8986
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
8987
          s->condlabel = gen_new_label();
8988
          gen_test_cc(cond ^ 1, s->condlabel);
8989
          s->condjmp = 1;
8990
        }
8991
    }
8992

    
8993
    insn = arm_lduw_code(s->pc, s->bswap_code);
8994
    s->pc += 2;
8995

    
8996
    switch (insn >> 12) {
8997
    case 0: case 1:
8998

    
8999
        rd = insn & 7;
9000
        op = (insn >> 11) & 3;
9001
        if (op == 3) {
9002
            /* add/subtract */
9003
            rn = (insn >> 3) & 7;
9004
            tmp = load_reg(s, rn);
9005
            if (insn & (1 << 10)) {
9006
                /* immediate */
9007
                tmp2 = tcg_temp_new_i32();
9008
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9009
            } else {
9010
                /* reg */
9011
                rm = (insn >> 6) & 7;
9012
                tmp2 = load_reg(s, rm);
9013
            }
9014
            if (insn & (1 << 9)) {
9015
                if (s->condexec_mask)
9016
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9017
                else
9018
                    gen_helper_sub_cc(tmp, tmp, tmp2);
9019
            } else {
9020
                if (s->condexec_mask)
9021
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9022
                else
9023
                    gen_helper_add_cc(tmp, tmp, tmp2);
9024
            }
9025
            tcg_temp_free_i32(tmp2);
9026
            store_reg(s, rd, tmp);
9027
        } else {
9028
            /* shift immediate */
9029
            rm = (insn >> 3) & 7;
9030
            shift = (insn >> 6) & 0x1f;
9031
            tmp = load_reg(s, rm);
9032
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9033
            if (!s->condexec_mask)
9034
                gen_logic_CC(tmp);
9035
            store_reg(s, rd, tmp);
9036
        }
9037
        break;
9038
    case 2: case 3:
9039
        /* arithmetic large immediate */
9040
        op = (insn >> 11) & 3;
9041
        rd = (insn >> 8) & 0x7;
9042
        if (op == 0) { /* mov */
9043
            tmp = tcg_temp_new_i32();
9044
            tcg_gen_movi_i32(tmp, insn & 0xff);
9045
            if (!s->condexec_mask)
9046
                gen_logic_CC(tmp);
9047
            store_reg(s, rd, tmp);
9048
        } else {
9049
            tmp = load_reg(s, rd);
9050
            tmp2 = tcg_temp_new_i32();
9051
            tcg_gen_movi_i32(tmp2, insn & 0xff);
9052
            switch (op) {
9053
            case 1: /* cmp */
9054
                gen_helper_sub_cc(tmp, tmp, tmp2);
9055
                tcg_temp_free_i32(tmp);
9056
                tcg_temp_free_i32(tmp2);
9057
                break;
9058
            case 2: /* add */
9059
                if (s->condexec_mask)
9060
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9061
                else
9062
                    gen_helper_add_cc(tmp, tmp, tmp2);
9063
                tcg_temp_free_i32(tmp2);
9064
                store_reg(s, rd, tmp);
9065
                break;
9066
            case 3: /* sub */
9067
                if (s->condexec_mask)
9068
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9069
                else
9070
                    gen_helper_sub_cc(tmp, tmp, tmp2);
9071
                tcg_temp_free_i32(tmp2);
9072
                store_reg(s, rd, tmp);
9073
                break;
9074
            }
9075
        }
9076
        break;
9077
    case 4:
9078
        if (insn & (1 << 11)) {
9079
            rd = (insn >> 8) & 7;
9080
            /* load pc-relative.  Bit 1 of PC is ignored.  */
9081
            val = s->pc + 2 + ((insn & 0xff) * 4);
9082
            val &= ~(uint32_t)2;
9083
            addr = tcg_temp_new_i32();
9084
            tcg_gen_movi_i32(addr, val);
9085
            tmp = gen_ld32(addr, IS_USER(s));
9086
            tcg_temp_free_i32(addr);
9087
            store_reg(s, rd, tmp);
9088
            break;
9089
        }
9090
        if (insn & (1 << 10)) {
9091
            /* data processing extended or blx */
9092
            rd = (insn & 7) | ((insn >> 4) & 8);
9093
            rm = (insn >> 3) & 0xf;
9094
            op = (insn >> 8) & 3;
9095
            switch (op) {
9096
            case 0: /* add */
9097
                tmp = load_reg(s, rd);
9098
                tmp2 = load_reg(s, rm);
9099
                tcg_gen_add_i32(tmp, tmp, tmp2);
9100
                tcg_temp_free_i32(tmp2);
9101
                store_reg(s, rd, tmp);
9102
                break;
9103
            case 1: /* cmp */
9104
                tmp = load_reg(s, rd);
9105
                tmp2 = load_reg(s, rm);
9106
                gen_helper_sub_cc(tmp, tmp, tmp2);
9107
                tcg_temp_free_i32(tmp2);
9108
                tcg_temp_free_i32(tmp);
9109
                break;
9110
            case 2: /* mov/cpy */
9111
                tmp = load_reg(s, rm);
9112
                store_reg(s, rd, tmp);
9113
                break;
9114
            case 3:/* branch [and link] exchange thumb register */
9115
                tmp = load_reg(s, rm);
9116
                if (insn & (1 << 7)) {
9117
                    ARCH(5);
9118
                    val = (uint32_t)s->pc | 1;
9119
                    tmp2 = tcg_temp_new_i32();
9120
                    tcg_gen_movi_i32(tmp2, val);
9121
                    store_reg(s, 14, tmp2);
9122
                }
9123
                /* already thumb, no need to check */
9124
                gen_bx(s, tmp);
9125
                break;
9126
            }
9127
            break;
9128
        }
9129

    
9130
        /* data processing register */
9131
        rd = insn & 7;
9132
        rm = (insn >> 3) & 7;
9133
        op = (insn >> 6) & 0xf;
9134
        if (op == 2 || op == 3 || op == 4 || op == 7) {
9135
            /* the shift/rotate ops want the operands backwards */
9136
            val = rm;
9137
            rm = rd;
9138
            rd = val;
9139
            val = 1;
9140
        } else {
9141
            val = 0;
9142
        }
9143

    
9144
        if (op == 9) { /* neg */
9145
            tmp = tcg_temp_new_i32();
9146
            tcg_gen_movi_i32(tmp, 0);
9147
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
9148
            tmp = load_reg(s, rd);
9149
        } else {
9150
            TCGV_UNUSED(tmp);
9151
        }
9152

    
9153
        tmp2 = load_reg(s, rm);
9154
        switch (op) {
9155
        case 0x0: /* and */
9156
            tcg_gen_and_i32(tmp, tmp, tmp2);
9157
            if (!s->condexec_mask)
9158
                gen_logic_CC(tmp);
9159
            break;
9160
        case 0x1: /* eor */
9161
            tcg_gen_xor_i32(tmp, tmp, tmp2);
9162
            if (!s->condexec_mask)
9163
                gen_logic_CC(tmp);
9164
            break;
9165
        case 0x2: /* lsl */
9166
            if (s->condexec_mask) {
9167
                gen_helper_shl(tmp2, tmp2, tmp);
9168
            } else {
9169
                gen_helper_shl_cc(tmp2, tmp2, tmp);
9170
                gen_logic_CC(tmp2);
9171
            }
9172
            break;
9173
        case 0x3: /* lsr */
9174
            if (s->condexec_mask) {
9175
                gen_helper_shr(tmp2, tmp2, tmp);
9176
            } else {
9177
                gen_helper_shr_cc(tmp2, tmp2, tmp);
9178
                gen_logic_CC(tmp2);
9179
            }
9180
            break;
9181
        case 0x4: /* asr */
9182
            if (s->condexec_mask) {
9183
                gen_helper_sar(tmp2, tmp2, tmp);
9184
            } else {
9185
                gen_helper_sar_cc(tmp2, tmp2, tmp);
9186
                gen_logic_CC(tmp2);
9187
            }
9188
            break;
9189
        case 0x5: /* adc */
9190
            if (s->condexec_mask)
9191
                gen_adc(tmp, tmp2);
9192
            else
9193
                gen_helper_adc_cc(tmp, tmp, tmp2);
9194
            break;
9195
        case 0x6: /* sbc */
9196
            if (s->condexec_mask)
9197
                gen_sub_carry(tmp, tmp, tmp2);
9198
            else
9199
                gen_helper_sbc_cc(tmp, tmp, tmp2);
9200
            break;
9201
        case 0x7: /* ror */
9202
            if (s->condexec_mask) {
9203
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
9204
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9205
            } else {
9206
                gen_helper_ror_cc(tmp2, tmp2, tmp);
9207
                gen_logic_CC(tmp2);
9208
            }
9209
            break;
9210
        case 0x8: /* tst */
9211
            tcg_gen_and_i32(tmp, tmp, tmp2);
9212
            gen_logic_CC(tmp);
9213
            rd = 16;
9214
            break;
9215
        case 0x9: /* neg */
9216
            if (s->condexec_mask)
9217
                tcg_gen_neg_i32(tmp, tmp2);
9218
            else
9219
                gen_helper_sub_cc(tmp, tmp, tmp2);
9220
            break;
9221
        case 0xa: /* cmp */
9222
            gen_helper_sub_cc(tmp, tmp, tmp2);
9223
            rd = 16;
9224
            break;
9225
        case 0xb: /* cmn */
9226
            gen_helper_add_cc(tmp, tmp, tmp2);
9227
            rd = 16;
9228
            break;
9229
        case 0xc: /* orr */
9230
            tcg_gen_or_i32(tmp, tmp, tmp2);
9231
            if (!s->condexec_mask)
9232
                gen_logic_CC(tmp);
9233
            break;
9234
        case 0xd: /* mul */
9235
            tcg_gen_mul_i32(tmp, tmp, tmp2);
9236
            if (!s->condexec_mask)
9237
                gen_logic_CC(tmp);
9238
            break;
9239
        case 0xe: /* bic */
9240
            tcg_gen_andc_i32(tmp, tmp, tmp2);
9241
            if (!s->condexec_mask)
9242
                gen_logic_CC(tmp);
9243
            break;
9244
        case 0xf: /* mvn */
9245
            tcg_gen_not_i32(tmp2, tmp2);
9246
            if (!s->condexec_mask)
9247
                gen_logic_CC(tmp2);
9248
            val = 1;
9249
            rm = rd;
9250
            break;
9251
        }
9252
        if (rd != 16) {
9253
            if (val) {
9254
                store_reg(s, rm, tmp2);
9255
                if (op != 0xf)
9256
                    tcg_temp_free_i32(tmp);
9257
            } else {
9258
                store_reg(s, rd, tmp);
9259
                tcg_temp_free_i32(tmp2);
9260
            }
9261
        } else {
9262
            tcg_temp_free_i32(tmp);
9263
            tcg_temp_free_i32(tmp2);
9264
        }
9265
        break;
9266

    
9267
    case 5:
9268
        /* load/store register offset.  */
9269
        rd = insn & 7;
9270
        rn = (insn >> 3) & 7;
9271
        rm = (insn >> 6) & 7;
9272
        op = (insn >> 9) & 7;
9273
        addr = load_reg(s, rn);
9274
        tmp = load_reg(s, rm);
9275
        tcg_gen_add_i32(addr, addr, tmp);
9276
        tcg_temp_free_i32(tmp);
9277

    
9278
        if (op < 3) /* store */
9279
            tmp = load_reg(s, rd);
9280

    
9281
        switch (op) {
9282
        case 0: /* str */
9283
            gen_st32(tmp, addr, IS_USER(s));
9284
            break;
9285
        case 1: /* strh */
9286
            gen_st16(tmp, addr, IS_USER(s));
9287
            break;
9288
        case 2: /* strb */
9289
            gen_st8(tmp, addr, IS_USER(s));
9290
            break;
9291
        case 3: /* ldrsb */
9292
            tmp = gen_ld8s(addr, IS_USER(s));
9293
            break;
9294
        case 4: /* ldr */
9295
            tmp = gen_ld32(addr, IS_USER(s));
9296
            break;
9297
        case 5: /* ldrh */
9298
            tmp = gen_ld16u(addr, IS_USER(s));
9299
            break;
9300
        case 6: /* ldrb */
9301
            tmp = gen_ld8u(addr, IS_USER(s));
9302
            break;
9303
        case 7: /* ldrsh */
9304
            tmp = gen_ld16s(addr, IS_USER(s));
9305
            break;
9306
        }
9307
        if (op >= 3) /* load */
9308
            store_reg(s, rd, tmp);
9309
        tcg_temp_free_i32(addr);
9310
        break;
9311

    
9312
    case 6:
9313
        /* load/store word immediate offset */
9314
        rd = insn & 7;
9315
        rn = (insn >> 3) & 7;
9316
        addr = load_reg(s, rn);
9317
        val = (insn >> 4) & 0x7c;
9318
        tcg_gen_addi_i32(addr, addr, val);
9319

    
9320
        if (insn & (1 << 11)) {
9321
            /* load */
9322
            tmp = gen_ld32(addr, IS_USER(s));
9323
            store_reg(s, rd, tmp);
9324
        } else {
9325
            /* store */
9326
            tmp = load_reg(s, rd);
9327
            gen_st32(tmp, addr, IS_USER(s));
9328
        }
9329
        tcg_temp_free_i32(addr);
9330
        break;
9331

    
9332
    case 7:
9333
        /* load/store byte immediate offset */
9334
        rd = insn & 7;
9335
        rn = (insn >> 3) & 7;
9336
        addr = load_reg(s, rn);
9337
        val = (insn >> 6) & 0x1f;
9338
        tcg_gen_addi_i32(addr, addr, val);
9339

    
9340
        if (insn & (1 << 11)) {
9341
            /* load */
9342
            tmp = gen_ld8u(addr, IS_USER(s));
9343
            store_reg(s, rd, tmp);
9344
        } else {
9345
            /* store */
9346
            tmp = load_reg(s, rd);
9347
            gen_st8(tmp, addr, IS_USER(s));
9348
        }
9349
        tcg_temp_free_i32(addr);
9350
        break;
9351

    
9352
    case 8:
9353
        /* load/store halfword immediate offset */
9354
        rd = insn & 7;
9355
        rn = (insn >> 3) & 7;
9356
        addr = load_reg(s, rn);
9357
        val = (insn >> 5) & 0x3e;
9358
        tcg_gen_addi_i32(addr, addr, val);
9359

    
9360
        if (insn & (1 << 11)) {
9361
            /* load */
9362
            tmp = gen_ld16u(addr, IS_USER(s));
9363
            store_reg(s, rd, tmp);
9364
        } else {
9365
            /* store */
9366
            tmp = load_reg(s, rd);
9367
            gen_st16(tmp, addr, IS_USER(s));
9368
        }
9369
        tcg_temp_free_i32(addr);
9370
        break;
9371

    
9372
    case 9:
9373
        /* load/store from stack */
9374
        rd = (insn >> 8) & 7;
9375
        addr = load_reg(s, 13);
9376
        val = (insn & 0xff) * 4;
9377
        tcg_gen_addi_i32(addr, addr, val);
9378

    
9379
        if (insn & (1 << 11)) {
9380
            /* load */
9381
            tmp = gen_ld32(addr, IS_USER(s));
9382
            store_reg(s, rd, tmp);
9383
        } else {
9384
            /* store */
9385
            tmp = load_reg(s, rd);
9386
            gen_st32(tmp, addr, IS_USER(s));
9387
        }
9388
        tcg_temp_free_i32(addr);
9389
        break;
9390

    
9391
    case 10:
9392
        /* add to high reg */
9393
        rd = (insn >> 8) & 7;
9394
        if (insn & (1 << 11)) {
9395
            /* SP */
9396
            tmp = load_reg(s, 13);
9397
        } else {
9398
            /* PC. bit 1 is ignored.  */
9399
            tmp = tcg_temp_new_i32();
9400
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9401
        }
9402
        val = (insn & 0xff) * 4;
9403
        tcg_gen_addi_i32(tmp, tmp, val);
9404
        store_reg(s, rd, tmp);
9405
        break;
9406

    
9407
    case 11:
9408
        /* misc */
9409
        op = (insn >> 8) & 0xf;
9410
        switch (op) {
9411
        case 0:
9412
            /* adjust stack pointer */
9413
            tmp = load_reg(s, 13);
9414
            val = (insn & 0x7f) * 4;
9415
            if (insn & (1 << 7))
9416
                val = -(int32_t)val;
9417
            tcg_gen_addi_i32(tmp, tmp, val);
9418
            store_reg(s, 13, tmp);
9419
            break;
9420

    
9421
        case 2: /* sign/zero extend.  */
9422
            ARCH(6);
9423
            rd = insn & 7;
9424
            rm = (insn >> 3) & 7;
9425
            tmp = load_reg(s, rm);
9426
            switch ((insn >> 6) & 3) {
9427
            case 0: gen_sxth(tmp); break;
9428
            case 1: gen_sxtb(tmp); break;
9429
            case 2: gen_uxth(tmp); break;
9430
            case 3: gen_uxtb(tmp); break;
9431
            }
9432
            store_reg(s, rd, tmp);
9433
            break;
9434
        case 4: case 5: case 0xc: case 0xd:
9435
            /* push/pop */
9436
            addr = load_reg(s, 13);
9437
            if (insn & (1 << 8))
9438
                offset = 4;
9439
            else
9440
                offset = 0;
9441
            for (i = 0; i < 8; i++) {
9442
                if (insn & (1 << i))
9443
                    offset += 4;
9444
            }
9445
            if ((insn & (1 << 11)) == 0) {
9446
                tcg_gen_addi_i32(addr, addr, -offset);
9447
            }
9448
            for (i = 0; i < 8; i++) {
9449
                if (insn & (1 << i)) {
9450
                    if (insn & (1 << 11)) {
9451
                        /* pop */
9452
                        tmp = gen_ld32(addr, IS_USER(s));
9453
                        store_reg(s, i, tmp);
9454
                    } else {
9455
                        /* push */
9456
                        tmp = load_reg(s, i);
9457
                        gen_st32(tmp, addr, IS_USER(s));
9458
                    }
9459
                    /* advance to the next address.  */
9460
                    tcg_gen_addi_i32(addr, addr, 4);
9461
                }
9462
            }
9463
            TCGV_UNUSED(tmp);
9464
            if (insn & (1 << 8)) {
9465
                if (insn & (1 << 11)) {
9466
                    /* pop pc */
9467
                    tmp = gen_ld32(addr, IS_USER(s));
9468
                    /* don't set the pc until the rest of the instruction
9469
                       has completed */
9470
                } else {
9471
                    /* push lr */
9472
                    tmp = load_reg(s, 14);
9473
                    gen_st32(tmp, addr, IS_USER(s));
9474
                }
9475
                tcg_gen_addi_i32(addr, addr, 4);
9476
            }
9477
            if ((insn & (1 << 11)) == 0) {
9478
                tcg_gen_addi_i32(addr, addr, -offset);
9479
            }
9480
            /* write back the new stack pointer */
9481
            store_reg(s, 13, addr);
9482
            /* set the new PC value */
9483
            if ((insn & 0x0900) == 0x0900) {
9484
                store_reg_from_load(env, s, 15, tmp);
9485
            }
9486
            break;
9487

    
9488
        case 1: case 3: case 9: case 11: /* czb */
9489
            rm = insn & 7;
9490
            tmp = load_reg(s, rm);
9491
            s->condlabel = gen_new_label();
9492
            s->condjmp = 1;
9493
            if (insn & (1 << 11))
9494
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9495
            else
9496
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9497
            tcg_temp_free_i32(tmp);
9498
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9499
            val = (uint32_t)s->pc + 2;
9500
            val += offset;
9501
            gen_jmp(s, val);
9502
            break;
9503

    
9504
        case 15: /* IT, nop-hint.  */
9505
            if ((insn & 0xf) == 0) {
9506
                gen_nop_hint(s, (insn >> 4) & 0xf);
9507
                break;
9508
            }
9509
            /* If Then.  */
9510
            s->condexec_cond = (insn >> 4) & 0xe;
9511
            s->condexec_mask = insn & 0x1f;
9512
            /* No actual code generated for this insn, just setup state.  */
9513
            break;
9514

    
9515
        case 0xe: /* bkpt */
9516
            ARCH(5);
9517
            gen_exception_insn(s, 2, EXCP_BKPT);
9518
            break;
9519

    
9520
        case 0xa: /* rev */
9521
            ARCH(6);
9522
            rn = (insn >> 3) & 0x7;
9523
            rd = insn & 0x7;
9524
            tmp = load_reg(s, rn);
9525
            switch ((insn >> 6) & 3) {
9526
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9527
            case 1: gen_rev16(tmp); break;
9528
            case 3: gen_revsh(tmp); break;
9529
            default: goto illegal_op;
9530
            }
9531
            store_reg(s, rd, tmp);
9532
            break;
9533

    
9534
        case 6:
9535
            switch ((insn >> 5) & 7) {
9536
            case 2:
9537
                /* setend */
9538
                ARCH(6);
9539
                if (((insn >> 3) & 1) != s->bswap_code) {
9540
                    /* Dynamic endianness switching not implemented. */
9541
                    goto illegal_op;
9542
                }
9543
                break;
9544
            case 3:
9545
                /* cps */
9546
                ARCH(6);
9547
                if (IS_USER(s)) {
9548
                    break;
9549
                }
9550
                if (IS_M(env)) {
9551
                    tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9552
                    /* FAULTMASK */
9553
                    if (insn & 1) {
9554
                        addr = tcg_const_i32(19);
9555
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
9556
                        tcg_temp_free_i32(addr);
9557
                    }
9558
                    /* PRIMASK */
9559
                    if (insn & 2) {
9560
                        addr = tcg_const_i32(16);
9561
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
9562
                        tcg_temp_free_i32(addr);
9563
                    }
9564
                    tcg_temp_free_i32(tmp);
9565
                    gen_lookup_tb(s);
9566
                } else {
9567
                    if (insn & (1 << 4)) {
9568
                        shift = CPSR_A | CPSR_I | CPSR_F;
9569
                    } else {
9570
                        shift = 0;
9571
                    }
9572
                    gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9573
                }
9574
                break;
9575
            default:
9576
                goto undef;
9577
            }
9578
            break;
9579

    
9580
        default:
9581
            goto undef;
9582
        }
9583
        break;
9584

    
9585
    case 12:
9586
    {
9587
        /* load/store multiple */
9588
        TCGv loaded_var;
9589
        TCGV_UNUSED(loaded_var);
9590
        rn = (insn >> 8) & 0x7;
9591
        addr = load_reg(s, rn);
9592
        for (i = 0; i < 8; i++) {
9593
            if (insn & (1 << i)) {
9594
                if (insn & (1 << 11)) {
9595
                    /* load */
9596
                    tmp = gen_ld32(addr, IS_USER(s));
9597
                    if (i == rn) {
9598
                        loaded_var = tmp;
9599
                    } else {
9600
                        store_reg(s, i, tmp);
9601
                    }
9602
                } else {
9603
                    /* store */
9604
                    tmp = load_reg(s, i);
9605
                    gen_st32(tmp, addr, IS_USER(s));
9606
                }
9607
                /* advance to the next address */
9608
                tcg_gen_addi_i32(addr, addr, 4);
9609
            }
9610
        }
9611
        if ((insn & (1 << rn)) == 0) {
9612
            /* base reg not in list: base register writeback */
9613
            store_reg(s, rn, addr);
9614
        } else {
9615
            /* base reg in list: if load, complete it now */
9616
            if (insn & (1 << 11)) {
9617
                store_reg(s, rn, loaded_var);
9618
            }
9619
            tcg_temp_free_i32(addr);
9620
        }
9621
        break;
9622
    }
9623
    case 13:
9624
        /* conditional branch or swi */
9625
        cond = (insn >> 8) & 0xf;
9626
        if (cond == 0xe)
9627
            goto undef;
9628

    
9629
        if (cond == 0xf) {
9630
            /* swi */
9631
            gen_set_pc_im(s->pc);
9632
            s->is_jmp = DISAS_SWI;
9633
            break;
9634
        }
9635
        /* generate a conditional jump to next instruction */
9636
        s->condlabel = gen_new_label();
9637
        gen_test_cc(cond ^ 1, s->condlabel);
9638
        s->condjmp = 1;
9639

    
9640
        /* jump to the offset */
9641
        val = (uint32_t)s->pc + 2;
9642
        offset = ((int32_t)insn << 24) >> 24;
9643
        val += offset << 1;
9644
        gen_jmp(s, val);
9645
        break;
9646

    
9647
    case 14:
9648
        if (insn & (1 << 11)) {
9649
            if (disas_thumb2_insn(env, s, insn))
9650
              goto undef32;
9651
            break;
9652
        }
9653
        /* unconditional branch */
9654
        val = (uint32_t)s->pc;
9655
        offset = ((int32_t)insn << 21) >> 21;
9656
        val += (offset << 1) + 2;
9657
        gen_jmp(s, val);
9658
        break;
9659

    
9660
    case 15:
9661
        if (disas_thumb2_insn(env, s, insn))
9662
            goto undef32;
9663
        break;
9664
    }
9665
    return;
9666
undef32:
9667
    gen_exception_insn(s, 4, EXCP_UDEF);
9668
    return;
9669
illegal_op:
9670
undef:
9671
    gen_exception_insn(s, 2, EXCP_UDEF);
9672
}
9673

    
9674
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9675
   basic block 'tb'. If search_pc is TRUE, also generate PC
9676
   information for each intermediate instruction. */
9677
static inline void gen_intermediate_code_internal(CPUARMState *env,
9678
                                                  TranslationBlock *tb,
9679
                                                  int search_pc)
9680
{
9681
    DisasContext dc1, *dc = &dc1;
9682
    CPUBreakpoint *bp;
9683
    uint16_t *gen_opc_end;
9684
    int j, lj;
9685
    target_ulong pc_start;
9686
    uint32_t next_page_start;
9687
    int num_insns;
9688
    int max_insns;
9689

    
9690
    /* generate intermediate code */
9691
    pc_start = tb->pc;
9692

    
9693
    dc->tb = tb;
9694

    
9695
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9696

    
9697
    dc->is_jmp = DISAS_NEXT;
9698
    dc->pc = pc_start;
9699
    dc->singlestep_enabled = env->singlestep_enabled;
9700
    dc->condjmp = 0;
9701
    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9702
    dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
9703
    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9704
    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9705
#if !defined(CONFIG_USER_ONLY)
9706
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9707
#endif
9708
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9709
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9710
    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9711
    cpu_F0s = tcg_temp_new_i32();
9712
    cpu_F1s = tcg_temp_new_i32();
9713
    cpu_F0d = tcg_temp_new_i64();
9714
    cpu_F1d = tcg_temp_new_i64();
9715
    cpu_V0 = cpu_F0d;
9716
    cpu_V1 = cpu_F1d;
9717
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
9718
    cpu_M0 = tcg_temp_new_i64();
9719
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9720
    lj = -1;
9721
    num_insns = 0;
9722
    max_insns = tb->cflags & CF_COUNT_MASK;
9723
    if (max_insns == 0)
9724
        max_insns = CF_COUNT_MASK;
9725

    
9726
    gen_icount_start();
9727

    
9728
    tcg_clear_temp_count();
9729

    
9730
    /* A note on handling of the condexec (IT) bits:
9731
     *
9732
     * We want to avoid the overhead of having to write the updated condexec
9733
     * bits back to the CPUARMState for every instruction in an IT block. So:
9734
     * (1) if the condexec bits are not already zero then we write
9735
     * zero back into the CPUARMState now. This avoids complications trying
9736
     * to do it at the end of the block. (For example if we don't do this
9737
     * it's hard to identify whether we can safely skip writing condexec
9738
     * at the end of the TB, which we definitely want to do for the case
9739
     * where a TB doesn't do anything with the IT state at all.)
9740
     * (2) if we are going to leave the TB then we call gen_set_condexec()
9741
     * which will write the correct value into CPUARMState if zero is wrong.
9742
     * This is done both for leaving the TB at the end, and for leaving
9743
     * it because of an exception we know will happen, which is done in
9744
     * gen_exception_insn(). The latter is necessary because we need to
9745
     * leave the TB with the PC/IT state just prior to execution of the
9746
     * instruction which caused the exception.
9747
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9748
     * then the CPUARMState will be wrong and we need to reset it.
9749
     * This is handled in the same way as restoration of the
9750
     * PC in these situations: we will be called again with search_pc=1
9751
     * and generate a mapping of the condexec bits for each PC in
9752
     * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9753
     * this to restore the condexec bits.
9754
     *
9755
     * Note that there are no instructions which can read the condexec
9756
     * bits, and none which can write non-static values to them, so
9757
     * we don't need to care about whether CPUARMState is correct in the
9758
     * middle of a TB.
9759
     */
9760

    
9761
    /* Reset the conditional execution bits immediately. This avoids
9762
       complications trying to do it at the end of the block.  */
9763
    if (dc->condexec_mask || dc->condexec_cond)
9764
      {
9765
        TCGv tmp = tcg_temp_new_i32();
9766
        tcg_gen_movi_i32(tmp, 0);
9767
        store_cpu_field(tmp, condexec_bits);
9768
      }
9769
    do {
9770
#ifdef CONFIG_USER_ONLY
9771
        /* Intercept jump to the magic kernel page.  */
9772
        if (dc->pc >= 0xffff0000) {
9773
            /* We always get here via a jump, so know we are not in a
9774
               conditional execution block.  */
9775
            gen_exception(EXCP_KERNEL_TRAP);
9776
            dc->is_jmp = DISAS_UPDATE;
9777
            break;
9778
        }
9779
#else
9780
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9781
            /* We always get here via a jump, so know we are not in a
9782
               conditional execution block.  */
9783
            gen_exception(EXCP_EXCEPTION_EXIT);
9784
            dc->is_jmp = DISAS_UPDATE;
9785
            break;
9786
        }
9787
#endif
9788

    
9789
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9790
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9791
                if (bp->pc == dc->pc) {
9792
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
9793
                    /* Advance PC so that clearing the breakpoint will
9794
                       invalidate this TB.  */
9795
                    dc->pc += 2;
9796
                    goto done_generating;
9797
                    break;
9798
                }
9799
            }
9800
        }
9801
        if (search_pc) {
9802
            j = gen_opc_ptr - gen_opc_buf;
9803
            if (lj < j) {
9804
                lj++;
9805
                while (lj < j)
9806
                    gen_opc_instr_start[lj++] = 0;
9807
            }
9808
            gen_opc_pc[lj] = dc->pc;
9809
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9810
            gen_opc_instr_start[lj] = 1;
9811
            gen_opc_icount[lj] = num_insns;
9812
        }
9813

    
9814
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9815
            gen_io_start();
9816

    
9817
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
9818
            tcg_gen_debug_insn_start(dc->pc);
9819
        }
9820

    
9821
        if (dc->thumb) {
9822
            disas_thumb_insn(env, dc);
9823
            if (dc->condexec_mask) {
9824
                dc->condexec_cond = (dc->condexec_cond & 0xe)
9825
                                   | ((dc->condexec_mask >> 4) & 1);
9826
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9827
                if (dc->condexec_mask == 0) {
9828
                    dc->condexec_cond = 0;
9829
                }
9830
            }
9831
        } else {
9832
            disas_arm_insn(env, dc);
9833
        }
9834

    
9835
        if (dc->condjmp && !dc->is_jmp) {
9836
            gen_set_label(dc->condlabel);
9837
            dc->condjmp = 0;
9838
        }
9839

    
9840
        if (tcg_check_temp_count()) {
9841
            fprintf(stderr, "TCG temporary leak before %08x\n", dc->pc);
9842
        }
9843

    
9844
        /* Translation stops when a conditional branch is encountered.
9845
         * Otherwise the subsequent code could get translated several times.
9846
         * Also stop translation when a page boundary is reached.  This
9847
         * ensures prefetch aborts occur at the right place.  */
9848
        num_insns ++;
9849
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9850
             !env->singlestep_enabled &&
9851
             !singlestep &&
9852
             dc->pc < next_page_start &&
9853
             num_insns < max_insns);
9854

    
9855
    if (tb->cflags & CF_LAST_IO) {
9856
        if (dc->condjmp) {
9857
            /* FIXME:  This can theoretically happen with self-modifying
9858
               code.  */
9859
            cpu_abort(env, "IO on conditional branch instruction");
9860
        }
9861
        gen_io_end();
9862
    }
9863

    
9864
    /* At this stage dc->condjmp will only be set when the skipped
9865
       instruction was a conditional branch or trap, and the PC has
9866
       already been written.  */
9867
    if (unlikely(env->singlestep_enabled)) {
9868
        /* Make sure the pc is updated, and raise a debug exception.  */
9869
        if (dc->condjmp) {
9870
            gen_set_condexec(dc);
9871
            if (dc->is_jmp == DISAS_SWI) {
9872
                gen_exception(EXCP_SWI);
9873
            } else {
9874
                gen_exception(EXCP_DEBUG);
9875
            }
9876
            gen_set_label(dc->condlabel);
9877
        }
9878
        if (dc->condjmp || !dc->is_jmp) {
9879
            gen_set_pc_im(dc->pc);
9880
            dc->condjmp = 0;
9881
        }
9882
        gen_set_condexec(dc);
9883
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9884
            gen_exception(EXCP_SWI);
9885
        } else {
9886
            /* FIXME: Single stepping a WFI insn will not halt
9887
               the CPU.  */
9888
            gen_exception(EXCP_DEBUG);
9889
        }
9890
    } else {
9891
        /* While branches must always occur at the end of an IT block,
9892
           there are a few other things that can cause us to terminate
9893
           the TB in the middel of an IT block:
9894
            - Exception generating instructions (bkpt, swi, undefined).
9895
            - Page boundaries.
9896
            - Hardware watchpoints.
9897
           Hardware breakpoints have already been handled and skip this code.
9898
         */
9899
        gen_set_condexec(dc);
9900
        switch(dc->is_jmp) {
9901
        case DISAS_NEXT:
9902
            gen_goto_tb(dc, 1, dc->pc);
9903
            break;
9904
        default:
9905
        case DISAS_JUMP:
9906
        case DISAS_UPDATE:
9907
            /* indicate that the hash table must be used to find the next TB */
9908
            tcg_gen_exit_tb(0);
9909
            break;
9910
        case DISAS_TB_JUMP:
9911
            /* nothing more to generate */
9912
            break;
9913
        case DISAS_WFI:
9914
            gen_helper_wfi();
9915
            break;
9916
        case DISAS_SWI:
9917
            gen_exception(EXCP_SWI);
9918
            break;
9919
        }
9920
        if (dc->condjmp) {
9921
            gen_set_label(dc->condlabel);
9922
            gen_set_condexec(dc);
9923
            gen_goto_tb(dc, 1, dc->pc);
9924
            dc->condjmp = 0;
9925
        }
9926
    }
9927

    
9928
done_generating:
9929
    gen_icount_end(tb, num_insns);
9930
    *gen_opc_ptr = INDEX_op_end;
9931

    
9932
#ifdef DEBUG_DISAS
9933
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9934
        qemu_log("----------------\n");
9935
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9936
        log_target_disas(pc_start, dc->pc - pc_start,
9937
                         dc->thumb | (dc->bswap_code << 1));
9938
        qemu_log("\n");
9939
    }
9940
#endif
9941
    if (search_pc) {
9942
        j = gen_opc_ptr - gen_opc_buf;
9943
        lj++;
9944
        while (lj <= j)
9945
            gen_opc_instr_start[lj++] = 0;
9946
    } else {
9947
        tb->size = dc->pc - pc_start;
9948
        tb->icount = num_insns;
9949
    }
9950
}
9951

    
9952
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
9953
{
9954
    gen_intermediate_code_internal(env, tb, 0);
9955
}
9956

    
9957
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
9958
{
9959
    gen_intermediate_code_internal(env, tb, 1);
9960
}
9961

    
9962
static const char *cpu_mode_names[16] = {
9963
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9964
  "???", "???", "???", "und", "???", "???", "???", "sys"
9965
};
9966

    
9967
void cpu_dump_state(CPUARMState *env, FILE *f, fprintf_function cpu_fprintf,
9968
                    int flags)
9969
{
9970
    int i;
9971
#if 0
9972
    union {
9973
        uint32_t i;
9974
        float s;
9975
    } s0, s1;
9976
    CPU_DoubleU d;
9977
    /* ??? This assumes float64 and double have the same layout.
9978
       Oh well, it's only debug dumps.  */
9979
    union {
9980
        float64 f64;
9981
        double d;
9982
    } d0;
9983
#endif
9984
    uint32_t psr;
9985

    
9986
    for(i=0;i<16;i++) {
9987
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9988
        if ((i % 4) == 3)
9989
            cpu_fprintf(f, "\n");
9990
        else
9991
            cpu_fprintf(f, " ");
9992
    }
9993
    psr = cpsr_read(env);
9994
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9995
                psr,
9996
                psr & (1 << 31) ? 'N' : '-',
9997
                psr & (1 << 30) ? 'Z' : '-',
9998
                psr & (1 << 29) ? 'C' : '-',
9999
                psr & (1 << 28) ? 'V' : '-',
10000
                psr & CPSR_T ? 'T' : 'A',
10001
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10002

    
10003
#if 0
10004
    for (i = 0; i < 16; i++) {
10005
        d.d = env->vfp.regs[i];
10006
        s0.i = d.l.lower;
10007
        s1.i = d.l.upper;
10008
        d0.f64 = d.d;
10009
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
10010
                    i * 2, (int)s0.i, s0.s,
10011
                    i * 2 + 1, (int)s1.i, s1.s,
10012
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
10013
                    d0.d);
10014
    }
10015
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10016
#endif
10017
}
10018

    
10019
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10020
{
10021
    env->regs[15] = gen_opc_pc[pc_pos];
10022
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
10023
}