Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 934814f1

History | View | Annotate | Download (342.9 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
#if !defined(CONFIG_USER_ONLY)
63
    int user;
64
#endif
65
    int vfp_enabled;
66
    int vec_len;
67
    int vec_stride;
68
} DisasContext;
69

    
70
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
71

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

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

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

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

    
99
#include "gen-icount.h"
100

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

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

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

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

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

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

    
141
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
142

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

    
149
#define store_cpu_field(var, name) \
150
    store_cpu_offset(var, offsetof(CPUState, name))
151

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

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

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

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

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

    
197

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
371
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
372

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
925
#undef VFP_OP2
926

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1146
#define ARM_CP_RW_BIT        (1 << 20)
1147

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1235
IWMMXT_OP_ENV_SIZE(unpackl)
1236
IWMMXT_OP_ENV_SIZE(unpackh)
1237

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

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

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

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

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

    
1272
IWMMXT_OP(msadb)
1273

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2368
    return 0;
2369
}
2370

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

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

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

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

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

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

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

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

    
2438
    return 1;
2439
}
2440

    
2441
/* Disassemble system coprocessor instruction.  Return nonzero if
2442
   instruction is not defined.  */
2443
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2444
{
2445
    TCGv tmp, tmp2;
2446
    uint32_t rd = (insn >> 12) & 0xf;
2447
    uint32_t cp = (insn >> 8) & 0xf;
2448
    if (IS_USER(s)) {
2449
        return 1;
2450
    }
2451

    
2452
    if (insn & ARM_CP_RW_BIT) {
2453
        if (!env->cp[cp].cp_read)
2454
            return 1;
2455
        gen_set_pc_im(s->pc);
2456
        tmp = tcg_temp_new_i32();
2457
        tmp2 = tcg_const_i32(insn);
2458
        gen_helper_get_cp(tmp, cpu_env, tmp2);
2459
        tcg_temp_free(tmp2);
2460
        store_reg(s, rd, tmp);
2461
    } else {
2462
        if (!env->cp[cp].cp_write)
2463
            return 1;
2464
        gen_set_pc_im(s->pc);
2465
        tmp = load_reg(s, rd);
2466
        tmp2 = tcg_const_i32(insn);
2467
        gen_helper_set_cp(cpu_env, tmp2, tmp);
2468
        tcg_temp_free(tmp2);
2469
        tcg_temp_free_i32(tmp);
2470
    }
2471
    return 0;
2472
}
2473

    
2474
static int cp15_user_ok(CPUState *env, uint32_t insn)
2475
{
2476
    int cpn = (insn >> 16) & 0xf;
2477
    int cpm = insn & 0xf;
2478
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2479

    
2480
    if (arm_feature(env, ARM_FEATURE_V7) && cpn == 9) {
2481
        /* Performance monitor registers fall into three categories:
2482
         *  (a) always UNDEF in usermode
2483
         *  (b) UNDEF only if PMUSERENR.EN is 0
2484
         *  (c) always read OK and UNDEF on write (PMUSERENR only)
2485
         */
2486
        if ((cpm == 12 && (op < 6)) ||
2487
            (cpm == 13 && (op < 3))) {
2488
            return env->cp15.c9_pmuserenr;
2489
        } else if (cpm == 14 && op == 0 && (insn & ARM_CP_RW_BIT)) {
2490
            /* PMUSERENR, read only */
2491
            return 1;
2492
        }
2493
        return 0;
2494
    }
2495

    
2496
    if (cpn == 13 && cpm == 0) {
2497
        /* TLS register.  */
2498
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2499
            return 1;
2500
    }
2501
    return 0;
2502
}
2503

    
2504
static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd)
2505
{
2506
    TCGv tmp;
2507
    int cpn = (insn >> 16) & 0xf;
2508
    int cpm = insn & 0xf;
2509
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2510

    
2511
    if (!arm_feature(env, ARM_FEATURE_V6K))
2512
        return 0;
2513

    
2514
    if (!(cpn == 13 && cpm == 0))
2515
        return 0;
2516

    
2517
    if (insn & ARM_CP_RW_BIT) {
2518
        switch (op) {
2519
        case 2:
2520
            tmp = load_cpu_field(cp15.c13_tls1);
2521
            break;
2522
        case 3:
2523
            tmp = load_cpu_field(cp15.c13_tls2);
2524
            break;
2525
        case 4:
2526
            tmp = load_cpu_field(cp15.c13_tls3);
2527
            break;
2528
        default:
2529
            return 0;
2530
        }
2531
        store_reg(s, rd, tmp);
2532

    
2533
    } else {
2534
        tmp = load_reg(s, rd);
2535
        switch (op) {
2536
        case 2:
2537
            store_cpu_field(tmp, cp15.c13_tls1);
2538
            break;
2539
        case 3:
2540
            store_cpu_field(tmp, cp15.c13_tls2);
2541
            break;
2542
        case 4:
2543
            store_cpu_field(tmp, cp15.c13_tls3);
2544
            break;
2545
        default:
2546
            tcg_temp_free_i32(tmp);
2547
            return 0;
2548
        }
2549
    }
2550
    return 1;
2551
}
2552

    
2553
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2554
   instruction is not defined.  */
2555
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2556
{
2557
    uint32_t rd;
2558
    TCGv tmp, tmp2;
2559

    
2560
    /* M profile cores use memory mapped registers instead of cp15.  */
2561
    if (arm_feature(env, ARM_FEATURE_M))
2562
        return 1;
2563

    
2564
    if ((insn & (1 << 25)) == 0) {
2565
        if (insn & (1 << 20)) {
2566
            /* mrrc */
2567
            return 1;
2568
        }
2569
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2570
        return 0;
2571
    }
2572
    if ((insn & (1 << 4)) == 0) {
2573
        /* cdp */
2574
        return 1;
2575
    }
2576
    /* We special case a number of cp15 instructions which were used
2577
     * for things which are real instructions in ARMv7. This allows
2578
     * them to work in linux-user mode which doesn't provide functional
2579
     * get_cp15/set_cp15 helpers, and is more efficient anyway.
2580
     */
2581
    switch ((insn & 0x0fff0fff)) {
2582
    case 0x0e070f90:
2583
        /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
2584
         * In v7, this must NOP.
2585
         */
2586
        if (IS_USER(s)) {
2587
            return 1;
2588
        }
2589
        if (!arm_feature(env, ARM_FEATURE_V7)) {
2590
            /* Wait for interrupt.  */
2591
            gen_set_pc_im(s->pc);
2592
            s->is_jmp = DISAS_WFI;
2593
        }
2594
        return 0;
2595
    case 0x0e070f58:
2596
        /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
2597
         * so this is slightly over-broad.
2598
         */
2599
        if (!IS_USER(s) && !arm_feature(env, ARM_FEATURE_V6)) {
2600
            /* Wait for interrupt.  */
2601
            gen_set_pc_im(s->pc);
2602
            s->is_jmp = DISAS_WFI;
2603
            return 0;
2604
        }
2605
        /* Otherwise continue to handle via helper function.
2606
         * In particular, on v7 and some v6 cores this is one of
2607
         * the VA-PA registers.
2608
         */
2609
        break;
2610
    case 0x0e070f3d:
2611
        /* 0,c7,c13,1: prefetch-by-MVA in v6, NOP in v7 */
2612
        if (arm_feature(env, ARM_FEATURE_V6)) {
2613
            return IS_USER(s) ? 1 : 0;
2614
        }
2615
        break;
2616
    case 0x0e070f95: /* 0,c7,c5,4 : ISB */
2617
    case 0x0e070f9a: /* 0,c7,c10,4: DSB */
2618
    case 0x0e070fba: /* 0,c7,c10,5: DMB */
2619
        /* Barriers in both v6 and v7 */
2620
        if (arm_feature(env, ARM_FEATURE_V6)) {
2621
            return 0;
2622
        }
2623
        break;
2624
    default:
2625
        break;
2626
    }
2627

    
2628
    if (IS_USER(s) && !cp15_user_ok(env, insn)) {
2629
        return 1;
2630
    }
2631

    
2632
    rd = (insn >> 12) & 0xf;
2633

    
2634
    if (cp15_tls_load_store(env, s, insn, rd))
2635
        return 0;
2636

    
2637
    tmp2 = tcg_const_i32(insn);
2638
    if (insn & ARM_CP_RW_BIT) {
2639
        tmp = tcg_temp_new_i32();
2640
        gen_helper_get_cp15(tmp, cpu_env, tmp2);
2641
        /* If the destination register is r15 then sets condition codes.  */
2642
        if (rd != 15)
2643
            store_reg(s, rd, tmp);
2644
        else
2645
            tcg_temp_free_i32(tmp);
2646
    } else {
2647
        tmp = load_reg(s, rd);
2648
        gen_helper_set_cp15(cpu_env, tmp2, tmp);
2649
        tcg_temp_free_i32(tmp);
2650
        /* Normally we would always end the TB here, but Linux
2651
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2652
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2653
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2654
                (insn & 0x0fff0fff) != 0x0e010f10)
2655
            gen_lookup_tb(s);
2656
    }
2657
    tcg_temp_free_i32(tmp2);
2658
    return 0;
2659
}
2660

    
2661
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2662
#define VFP_SREG(insn, bigbit, smallbit) \
2663
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2664
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2665
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2666
        reg = (((insn) >> (bigbit)) & 0x0f) \
2667
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2668
    } else { \
2669
        if (insn & (1 << (smallbit))) \
2670
            return 1; \
2671
        reg = ((insn) >> (bigbit)) & 0x0f; \
2672
    }} while (0)
2673

    
2674
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2675
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2676
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2677
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2678
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2679
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2680

    
2681
/* Move between integer and VFP cores.  */
2682
static TCGv gen_vfp_mrs(void)
2683
{
2684
    TCGv tmp = tcg_temp_new_i32();
2685
    tcg_gen_mov_i32(tmp, cpu_F0s);
2686
    return tmp;
2687
}
2688

    
2689
static void gen_vfp_msr(TCGv tmp)
2690
{
2691
    tcg_gen_mov_i32(cpu_F0s, tmp);
2692
    tcg_temp_free_i32(tmp);
2693
}
2694

    
2695
static void gen_neon_dup_u8(TCGv var, int shift)
2696
{
2697
    TCGv tmp = tcg_temp_new_i32();
2698
    if (shift)
2699
        tcg_gen_shri_i32(var, var, shift);
2700
    tcg_gen_ext8u_i32(var, var);
2701
    tcg_gen_shli_i32(tmp, var, 8);
2702
    tcg_gen_or_i32(var, var, tmp);
2703
    tcg_gen_shli_i32(tmp, var, 16);
2704
    tcg_gen_or_i32(var, var, tmp);
2705
    tcg_temp_free_i32(tmp);
2706
}
2707

    
2708
static void gen_neon_dup_low16(TCGv var)
2709
{
2710
    TCGv tmp = tcg_temp_new_i32();
2711
    tcg_gen_ext16u_i32(var, var);
2712
    tcg_gen_shli_i32(tmp, var, 16);
2713
    tcg_gen_or_i32(var, var, tmp);
2714
    tcg_temp_free_i32(tmp);
2715
}
2716

    
2717
static void gen_neon_dup_high16(TCGv var)
2718
{
2719
    TCGv tmp = tcg_temp_new_i32();
2720
    tcg_gen_andi_i32(var, var, 0xffff0000);
2721
    tcg_gen_shri_i32(tmp, var, 16);
2722
    tcg_gen_or_i32(var, var, tmp);
2723
    tcg_temp_free_i32(tmp);
2724
}
2725

    
2726
static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size)
2727
{
2728
    /* Load a single Neon element and replicate into a 32 bit TCG reg */
2729
    TCGv tmp;
2730
    switch (size) {
2731
    case 0:
2732
        tmp = gen_ld8u(addr, IS_USER(s));
2733
        gen_neon_dup_u8(tmp, 0);
2734
        break;
2735
    case 1:
2736
        tmp = gen_ld16u(addr, IS_USER(s));
2737
        gen_neon_dup_low16(tmp);
2738
        break;
2739
    case 2:
2740
        tmp = gen_ld32(addr, IS_USER(s));
2741
        break;
2742
    default: /* Avoid compiler warnings.  */
2743
        abort();
2744
    }
2745
    return tmp;
2746
}
2747

    
2748
/* Disassemble a VFP instruction.  Returns nonzero if an error occurred
2749
   (ie. an undefined instruction).  */
2750
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2751
{
2752
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2753
    int dp, veclen;
2754
    TCGv addr;
2755
    TCGv tmp;
2756
    TCGv tmp2;
2757

    
2758
    if (!arm_feature(env, ARM_FEATURE_VFP))
2759
        return 1;
2760

    
2761
    if (!s->vfp_enabled) {
2762
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2763
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2764
            return 1;
2765
        rn = (insn >> 16) & 0xf;
2766
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2767
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2768
            return 1;
2769
    }
2770
    dp = ((insn & 0xf00) == 0xb00);
2771
    switch ((insn >> 24) & 0xf) {
2772
    case 0xe:
2773
        if (insn & (1 << 4)) {
2774
            /* single register transfer */
2775
            rd = (insn >> 12) & 0xf;
2776
            if (dp) {
2777
                int size;
2778
                int pass;
2779

    
2780
                VFP_DREG_N(rn, insn);
2781
                if (insn & 0xf)
2782
                    return 1;
2783
                if (insn & 0x00c00060
2784
                    && !arm_feature(env, ARM_FEATURE_NEON))
2785
                    return 1;
2786

    
2787
                pass = (insn >> 21) & 1;
2788
                if (insn & (1 << 22)) {
2789
                    size = 0;
2790
                    offset = ((insn >> 5) & 3) * 8;
2791
                } else if (insn & (1 << 5)) {
2792
                    size = 1;
2793
                    offset = (insn & (1 << 6)) ? 16 : 0;
2794
                } else {
2795
                    size = 2;
2796
                    offset = 0;
2797
                }
2798
                if (insn & ARM_CP_RW_BIT) {
2799
                    /* vfp->arm */
2800
                    tmp = neon_load_reg(rn, pass);
2801
                    switch (size) {
2802
                    case 0:
2803
                        if (offset)
2804
                            tcg_gen_shri_i32(tmp, tmp, offset);
2805
                        if (insn & (1 << 23))
2806
                            gen_uxtb(tmp);
2807
                        else
2808
                            gen_sxtb(tmp);
2809
                        break;
2810
                    case 1:
2811
                        if (insn & (1 << 23)) {
2812
                            if (offset) {
2813
                                tcg_gen_shri_i32(tmp, tmp, 16);
2814
                            } else {
2815
                                gen_uxth(tmp);
2816
                            }
2817
                        } else {
2818
                            if (offset) {
2819
                                tcg_gen_sari_i32(tmp, tmp, 16);
2820
                            } else {
2821
                                gen_sxth(tmp);
2822
                            }
2823
                        }
2824
                        break;
2825
                    case 2:
2826
                        break;
2827
                    }
2828
                    store_reg(s, rd, tmp);
2829
                } else {
2830
                    /* arm->vfp */
2831
                    tmp = load_reg(s, rd);
2832
                    if (insn & (1 << 23)) {
2833
                        /* VDUP */
2834
                        if (size == 0) {
2835
                            gen_neon_dup_u8(tmp, 0);
2836
                        } else if (size == 1) {
2837
                            gen_neon_dup_low16(tmp);
2838
                        }
2839
                        for (n = 0; n <= pass * 2; n++) {
2840
                            tmp2 = tcg_temp_new_i32();
2841
                            tcg_gen_mov_i32(tmp2, tmp);
2842
                            neon_store_reg(rn, n, tmp2);
2843
                        }
2844
                        neon_store_reg(rn, n, tmp);
2845
                    } else {
2846
                        /* VMOV */
2847
                        switch (size) {
2848
                        case 0:
2849
                            tmp2 = neon_load_reg(rn, pass);
2850
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2851
                            tcg_temp_free_i32(tmp2);
2852
                            break;
2853
                        case 1:
2854
                            tmp2 = neon_load_reg(rn, pass);
2855
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2856
                            tcg_temp_free_i32(tmp2);
2857
                            break;
2858
                        case 2:
2859
                            break;
2860
                        }
2861
                        neon_store_reg(rn, pass, tmp);
2862
                    }
2863
                }
2864
            } else { /* !dp */
2865
                if ((insn & 0x6f) != 0x00)
2866
                    return 1;
2867
                rn = VFP_SREG_N(insn);
2868
                if (insn & ARM_CP_RW_BIT) {
2869
                    /* vfp->arm */
2870
                    if (insn & (1 << 21)) {
2871
                        /* system register */
2872
                        rn >>= 1;
2873

    
2874
                        switch (rn) {
2875
                        case ARM_VFP_FPSID:
2876
                            /* VFP2 allows access to FSID from userspace.
2877
                               VFP3 restricts all id registers to privileged
2878
                               accesses.  */
2879
                            if (IS_USER(s)
2880
                                && arm_feature(env, ARM_FEATURE_VFP3))
2881
                                return 1;
2882
                            tmp = load_cpu_field(vfp.xregs[rn]);
2883
                            break;
2884
                        case ARM_VFP_FPEXC:
2885
                            if (IS_USER(s))
2886
                                return 1;
2887
                            tmp = load_cpu_field(vfp.xregs[rn]);
2888
                            break;
2889
                        case ARM_VFP_FPINST:
2890
                        case ARM_VFP_FPINST2:
2891
                            /* Not present in VFP3.  */
2892
                            if (IS_USER(s)
2893
                                || arm_feature(env, ARM_FEATURE_VFP3))
2894
                                return 1;
2895
                            tmp = load_cpu_field(vfp.xregs[rn]);
2896
                            break;
2897
                        case ARM_VFP_FPSCR:
2898
                            if (rd == 15) {
2899
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2900
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2901
                            } else {
2902
                                tmp = tcg_temp_new_i32();
2903
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2904
                            }
2905
                            break;
2906
                        case ARM_VFP_MVFR0:
2907
                        case ARM_VFP_MVFR1:
2908
                            if (IS_USER(s)
2909
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2910
                                return 1;
2911
                            tmp = load_cpu_field(vfp.xregs[rn]);
2912
                            break;
2913
                        default:
2914
                            return 1;
2915
                        }
2916
                    } else {
2917
                        gen_mov_F0_vreg(0, rn);
2918
                        tmp = gen_vfp_mrs();
2919
                    }
2920
                    if (rd == 15) {
2921
                        /* Set the 4 flag bits in the CPSR.  */
2922
                        gen_set_nzcv(tmp);
2923
                        tcg_temp_free_i32(tmp);
2924
                    } else {
2925
                        store_reg(s, rd, tmp);
2926
                    }
2927
                } else {
2928
                    /* arm->vfp */
2929
                    tmp = load_reg(s, rd);
2930
                    if (insn & (1 << 21)) {
2931
                        rn >>= 1;
2932
                        /* system register */
2933
                        switch (rn) {
2934
                        case ARM_VFP_FPSID:
2935
                        case ARM_VFP_MVFR0:
2936
                        case ARM_VFP_MVFR1:
2937
                            /* Writes are ignored.  */
2938
                            break;
2939
                        case ARM_VFP_FPSCR:
2940
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2941
                            tcg_temp_free_i32(tmp);
2942
                            gen_lookup_tb(s);
2943
                            break;
2944
                        case ARM_VFP_FPEXC:
2945
                            if (IS_USER(s))
2946
                                return 1;
2947
                            /* TODO: VFP subarchitecture support.
2948
                             * For now, keep the EN bit only */
2949
                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2950
                            store_cpu_field(tmp, vfp.xregs[rn]);
2951
                            gen_lookup_tb(s);
2952
                            break;
2953
                        case ARM_VFP_FPINST:
2954
                        case ARM_VFP_FPINST2:
2955
                            store_cpu_field(tmp, vfp.xregs[rn]);
2956
                            break;
2957
                        default:
2958
                            return 1;
2959
                        }
2960
                    } else {
2961
                        gen_vfp_msr(tmp);
2962
                        gen_mov_vreg_F0(0, rn);
2963
                    }
2964
                }
2965
            }
2966
        } else {
2967
            /* data processing */
2968
            /* The opcode is in bits 23, 21, 20 and 6.  */
2969
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2970
            if (dp) {
2971
                if (op == 15) {
2972
                    /* rn is opcode */
2973
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2974
                } else {
2975
                    /* rn is register number */
2976
                    VFP_DREG_N(rn, insn);
2977
                }
2978

    
2979
                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2980
                    /* Integer or single precision destination.  */
2981
                    rd = VFP_SREG_D(insn);
2982
                } else {
2983
                    VFP_DREG_D(rd, insn);
2984
                }
2985
                if (op == 15 &&
2986
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2987
                    /* VCVT from int is always from S reg regardless of dp bit.
2988
                     * VCVT with immediate frac_bits has same format as SREG_M
2989
                     */
2990
                    rm = VFP_SREG_M(insn);
2991
                } else {
2992
                    VFP_DREG_M(rm, insn);
2993
                }
2994
            } else {
2995
                rn = VFP_SREG_N(insn);
2996
                if (op == 15 && rn == 15) {
2997
                    /* Double precision destination.  */
2998
                    VFP_DREG_D(rd, insn);
2999
                } else {
3000
                    rd = VFP_SREG_D(insn);
3001
                }
3002
                /* NB that we implicitly rely on the encoding for the frac_bits
3003
                 * in VCVT of fixed to float being the same as that of an SREG_M
3004
                 */
3005
                rm = VFP_SREG_M(insn);
3006
            }
3007

    
3008
            veclen = s->vec_len;
3009
            if (op == 15 && rn > 3)
3010
                veclen = 0;
3011

    
3012
            /* Shut up compiler warnings.  */
3013
            delta_m = 0;
3014
            delta_d = 0;
3015
            bank_mask = 0;
3016

    
3017
            if (veclen > 0) {
3018
                if (dp)
3019
                    bank_mask = 0xc;
3020
                else
3021
                    bank_mask = 0x18;
3022

    
3023
                /* Figure out what type of vector operation this is.  */
3024
                if ((rd & bank_mask) == 0) {
3025
                    /* scalar */
3026
                    veclen = 0;
3027
                } else {
3028
                    if (dp)
3029
                        delta_d = (s->vec_stride >> 1) + 1;
3030
                    else
3031
                        delta_d = s->vec_stride + 1;
3032

    
3033
                    if ((rm & bank_mask) == 0) {
3034
                        /* mixed scalar/vector */
3035
                        delta_m = 0;
3036
                    } else {
3037
                        /* vector */
3038
                        delta_m = delta_d;
3039
                    }
3040
                }
3041
            }
3042

    
3043
            /* Load the initial operands.  */
3044
            if (op == 15) {
3045
                switch (rn) {
3046
                case 16:
3047
                case 17:
3048
                    /* Integer source */
3049
                    gen_mov_F0_vreg(0, rm);
3050
                    break;
3051
                case 8:
3052
                case 9:
3053
                    /* Compare */
3054
                    gen_mov_F0_vreg(dp, rd);
3055
                    gen_mov_F1_vreg(dp, rm);
3056
                    break;
3057
                case 10:
3058
                case 11:
3059
                    /* Compare with zero */
3060
                    gen_mov_F0_vreg(dp, rd);
3061
                    gen_vfp_F1_ld0(dp);
3062
                    break;
3063
                case 20:
3064
                case 21:
3065
                case 22:
3066
                case 23:
3067
                case 28:
3068
                case 29:
3069
                case 30:
3070
                case 31:
3071
                    /* Source and destination the same.  */
3072
                    gen_mov_F0_vreg(dp, rd);
3073
                    break;
3074
                default:
3075
                    /* One source operand.  */
3076
                    gen_mov_F0_vreg(dp, rm);
3077
                    break;
3078
                }
3079
            } else {
3080
                /* Two source operands.  */
3081
                gen_mov_F0_vreg(dp, rn);
3082
                gen_mov_F1_vreg(dp, rm);
3083
            }
3084

    
3085
            for (;;) {
3086
                /* Perform the calculation.  */
3087
                switch (op) {
3088
                case 0: /* VMLA: fd + (fn * fm) */
3089
                    /* Note that order of inputs to the add matters for NaNs */
3090
                    gen_vfp_F1_mul(dp);
3091
                    gen_mov_F0_vreg(dp, rd);
3092
                    gen_vfp_add(dp);
3093
                    break;
3094
                case 1: /* VMLS: fd + -(fn * fm) */
3095
                    gen_vfp_mul(dp);
3096
                    gen_vfp_F1_neg(dp);
3097
                    gen_mov_F0_vreg(dp, rd);
3098
                    gen_vfp_add(dp);
3099
                    break;
3100
                case 2: /* VNMLS: -fd + (fn * fm) */
3101
                    /* Note that it isn't valid to replace (-A + B) with (B - A)
3102
                     * or similar plausible looking simplifications
3103
                     * because this will give wrong results for NaNs.
3104
                     */
3105
                    gen_vfp_F1_mul(dp);
3106
                    gen_mov_F0_vreg(dp, rd);
3107
                    gen_vfp_neg(dp);
3108
                    gen_vfp_add(dp);
3109
                    break;
3110
                case 3: /* VNMLA: -fd + -(fn * fm) */
3111
                    gen_vfp_mul(dp);
3112
                    gen_vfp_F1_neg(dp);
3113
                    gen_mov_F0_vreg(dp, rd);
3114
                    gen_vfp_neg(dp);
3115
                    gen_vfp_add(dp);
3116
                    break;
3117
                case 4: /* mul: fn * fm */
3118
                    gen_vfp_mul(dp);
3119
                    break;
3120
                case 5: /* nmul: -(fn * fm) */
3121
                    gen_vfp_mul(dp);
3122
                    gen_vfp_neg(dp);
3123
                    break;
3124
                case 6: /* add: fn + fm */
3125
                    gen_vfp_add(dp);
3126
                    break;
3127
                case 7: /* sub: fn - fm */
3128
                    gen_vfp_sub(dp);
3129
                    break;
3130
                case 8: /* div: fn / fm */
3131
                    gen_vfp_div(dp);
3132
                    break;
3133
                case 14: /* fconst */
3134
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3135
                      return 1;
3136

    
3137
                    n = (insn << 12) & 0x80000000;
3138
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3139
                    if (dp) {
3140
                        if (i & 0x40)
3141
                            i |= 0x3f80;
3142
                        else
3143
                            i |= 0x4000;
3144
                        n |= i << 16;
3145
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3146
                    } else {
3147
                        if (i & 0x40)
3148
                            i |= 0x780;
3149
                        else
3150
                            i |= 0x800;
3151
                        n |= i << 19;
3152
                        tcg_gen_movi_i32(cpu_F0s, n);
3153
                    }
3154
                    break;
3155
                case 15: /* extension space */
3156
                    switch (rn) {
3157
                    case 0: /* cpy */
3158
                        /* no-op */
3159
                        break;
3160
                    case 1: /* abs */
3161
                        gen_vfp_abs(dp);
3162
                        break;
3163
                    case 2: /* neg */
3164
                        gen_vfp_neg(dp);
3165
                        break;
3166
                    case 3: /* sqrt */
3167
                        gen_vfp_sqrt(dp);
3168
                        break;
3169
                    case 4: /* vcvtb.f32.f16 */
3170
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3171
                          return 1;
3172
                        tmp = gen_vfp_mrs();
3173
                        tcg_gen_ext16u_i32(tmp, tmp);
3174
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3175
                        tcg_temp_free_i32(tmp);
3176
                        break;
3177
                    case 5: /* vcvtt.f32.f16 */
3178
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3179
                          return 1;
3180
                        tmp = gen_vfp_mrs();
3181
                        tcg_gen_shri_i32(tmp, tmp, 16);
3182
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3183
                        tcg_temp_free_i32(tmp);
3184
                        break;
3185
                    case 6: /* vcvtb.f16.f32 */
3186
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3187
                          return 1;
3188
                        tmp = tcg_temp_new_i32();
3189
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3190
                        gen_mov_F0_vreg(0, rd);
3191
                        tmp2 = gen_vfp_mrs();
3192
                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3193
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3194
                        tcg_temp_free_i32(tmp2);
3195
                        gen_vfp_msr(tmp);
3196
                        break;
3197
                    case 7: /* vcvtt.f16.f32 */
3198
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3199
                          return 1;
3200
                        tmp = tcg_temp_new_i32();
3201
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3202
                        tcg_gen_shli_i32(tmp, tmp, 16);
3203
                        gen_mov_F0_vreg(0, rd);
3204
                        tmp2 = gen_vfp_mrs();
3205
                        tcg_gen_ext16u_i32(tmp2, tmp2);
3206
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3207
                        tcg_temp_free_i32(tmp2);
3208
                        gen_vfp_msr(tmp);
3209
                        break;
3210
                    case 8: /* cmp */
3211
                        gen_vfp_cmp(dp);
3212
                        break;
3213
                    case 9: /* cmpe */
3214
                        gen_vfp_cmpe(dp);
3215
                        break;
3216
                    case 10: /* cmpz */
3217
                        gen_vfp_cmp(dp);
3218
                        break;
3219
                    case 11: /* cmpez */
3220
                        gen_vfp_F1_ld0(dp);
3221
                        gen_vfp_cmpe(dp);
3222
                        break;
3223
                    case 15: /* single<->double conversion */
3224
                        if (dp)
3225
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3226
                        else
3227
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3228
                        break;
3229
                    case 16: /* fuito */
3230
                        gen_vfp_uito(dp, 0);
3231
                        break;
3232
                    case 17: /* fsito */
3233
                        gen_vfp_sito(dp, 0);
3234
                        break;
3235
                    case 20: /* fshto */
3236
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3237
                          return 1;
3238
                        gen_vfp_shto(dp, 16 - rm, 0);
3239
                        break;
3240
                    case 21: /* fslto */
3241
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3242
                          return 1;
3243
                        gen_vfp_slto(dp, 32 - rm, 0);
3244
                        break;
3245
                    case 22: /* fuhto */
3246
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3247
                          return 1;
3248
                        gen_vfp_uhto(dp, 16 - rm, 0);
3249
                        break;
3250
                    case 23: /* fulto */
3251
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3252
                          return 1;
3253
                        gen_vfp_ulto(dp, 32 - rm, 0);
3254
                        break;
3255
                    case 24: /* ftoui */
3256
                        gen_vfp_toui(dp, 0);
3257
                        break;
3258
                    case 25: /* ftouiz */
3259
                        gen_vfp_touiz(dp, 0);
3260
                        break;
3261
                    case 26: /* ftosi */
3262
                        gen_vfp_tosi(dp, 0);
3263
                        break;
3264
                    case 27: /* ftosiz */
3265
                        gen_vfp_tosiz(dp, 0);
3266
                        break;
3267
                    case 28: /* ftosh */
3268
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3269
                          return 1;
3270
                        gen_vfp_tosh(dp, 16 - rm, 0);
3271
                        break;
3272
                    case 29: /* ftosl */
3273
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3274
                          return 1;
3275
                        gen_vfp_tosl(dp, 32 - rm, 0);
3276
                        break;
3277
                    case 30: /* ftouh */
3278
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3279
                          return 1;
3280
                        gen_vfp_touh(dp, 16 - rm, 0);
3281
                        break;
3282
                    case 31: /* ftoul */
3283
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3284
                          return 1;
3285
                        gen_vfp_toul(dp, 32 - rm, 0);
3286
                        break;
3287
                    default: /* undefined */
3288
                        printf ("rn:%d\n", rn);
3289
                        return 1;
3290
                    }
3291
                    break;
3292
                default: /* undefined */
3293
                    printf ("op:%d\n", op);
3294
                    return 1;
3295
                }
3296

    
3297
                /* Write back the result.  */
3298
                if (op == 15 && (rn >= 8 && rn <= 11))
3299
                    ; /* Comparison, do nothing.  */
3300
                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3301
                    /* VCVT double to int: always integer result. */
3302
                    gen_mov_vreg_F0(0, rd);
3303
                else if (op == 15 && rn == 15)
3304
                    /* conversion */
3305
                    gen_mov_vreg_F0(!dp, rd);
3306
                else
3307
                    gen_mov_vreg_F0(dp, rd);
3308

    
3309
                /* break out of the loop if we have finished  */
3310
                if (veclen == 0)
3311
                    break;
3312

    
3313
                if (op == 15 && delta_m == 0) {
3314
                    /* single source one-many */
3315
                    while (veclen--) {
3316
                        rd = ((rd + delta_d) & (bank_mask - 1))
3317
                             | (rd & bank_mask);
3318
                        gen_mov_vreg_F0(dp, rd);
3319
                    }
3320
                    break;
3321
                }
3322
                /* Setup the next operands.  */
3323
                veclen--;
3324
                rd = ((rd + delta_d) & (bank_mask - 1))
3325
                     | (rd & bank_mask);
3326

    
3327
                if (op == 15) {
3328
                    /* One source operand.  */
3329
                    rm = ((rm + delta_m) & (bank_mask - 1))
3330
                         | (rm & bank_mask);
3331
                    gen_mov_F0_vreg(dp, rm);
3332
                } else {
3333
                    /* Two source operands.  */
3334
                    rn = ((rn + delta_d) & (bank_mask - 1))
3335
                         | (rn & bank_mask);
3336
                    gen_mov_F0_vreg(dp, rn);
3337
                    if (delta_m) {
3338
                        rm = ((rm + delta_m) & (bank_mask - 1))
3339
                             | (rm & bank_mask);
3340
                        gen_mov_F1_vreg(dp, rm);
3341
                    }
3342
                }
3343
            }
3344
        }
3345
        break;
3346
    case 0xc:
3347
    case 0xd:
3348
        if ((insn & 0x03e00000) == 0x00400000) {
3349
            /* two-register transfer */
3350
            rn = (insn >> 16) & 0xf;
3351
            rd = (insn >> 12) & 0xf;
3352
            if (dp) {
3353
                VFP_DREG_M(rm, insn);
3354
            } else {
3355
                rm = VFP_SREG_M(insn);
3356
            }
3357

    
3358
            if (insn & ARM_CP_RW_BIT) {
3359
                /* vfp->arm */
3360
                if (dp) {
3361
                    gen_mov_F0_vreg(0, rm * 2);
3362
                    tmp = gen_vfp_mrs();
3363
                    store_reg(s, rd, tmp);
3364
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3365
                    tmp = gen_vfp_mrs();
3366
                    store_reg(s, rn, tmp);
3367
                } else {
3368
                    gen_mov_F0_vreg(0, rm);
3369
                    tmp = gen_vfp_mrs();
3370
                    store_reg(s, rd, tmp);
3371
                    gen_mov_F0_vreg(0, rm + 1);
3372
                    tmp = gen_vfp_mrs();
3373
                    store_reg(s, rn, tmp);
3374
                }
3375
            } else {
3376
                /* arm->vfp */
3377
                if (dp) {
3378
                    tmp = load_reg(s, rd);
3379
                    gen_vfp_msr(tmp);
3380
                    gen_mov_vreg_F0(0, rm * 2);
3381
                    tmp = load_reg(s, rn);
3382
                    gen_vfp_msr(tmp);
3383
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3384
                } else {
3385
                    tmp = load_reg(s, rd);
3386
                    gen_vfp_msr(tmp);
3387
                    gen_mov_vreg_F0(0, rm);
3388
                    tmp = load_reg(s, rn);
3389
                    gen_vfp_msr(tmp);
3390
                    gen_mov_vreg_F0(0, rm + 1);
3391
                }
3392
            }
3393
        } else {
3394
            /* Load/store */
3395
            rn = (insn >> 16) & 0xf;
3396
            if (dp)
3397
                VFP_DREG_D(rd, insn);
3398
            else
3399
                rd = VFP_SREG_D(insn);
3400
            if ((insn & 0x01200000) == 0x01000000) {
3401
                /* Single load/store */
3402
                offset = (insn & 0xff) << 2;
3403
                if ((insn & (1 << 23)) == 0)
3404
                    offset = -offset;
3405
                if (s->thumb && rn == 15) {
3406
                    /* This is actually UNPREDICTABLE */
3407
                    addr = tcg_temp_new_i32();
3408
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3409
                } else {
3410
                    addr = load_reg(s, rn);
3411
                }
3412
                tcg_gen_addi_i32(addr, addr, offset);
3413
                if (insn & (1 << 20)) {
3414
                    gen_vfp_ld(s, dp, addr);
3415
                    gen_mov_vreg_F0(dp, rd);
3416
                } else {
3417
                    gen_mov_F0_vreg(dp, rd);
3418
                    gen_vfp_st(s, dp, addr);
3419
                }
3420
                tcg_temp_free_i32(addr);
3421
            } else {
3422
                /* load/store multiple */
3423
                int w = insn & (1 << 21);
3424
                if (dp)
3425
                    n = (insn >> 1) & 0x7f;
3426
                else
3427
                    n = insn & 0xff;
3428

    
3429
                if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3430
                    /* P == U , W == 1  => UNDEF */
3431
                    return 1;
3432
                }
3433
                if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3434
                    /* UNPREDICTABLE cases for bad immediates: we choose to
3435
                     * UNDEF to avoid generating huge numbers of TCG ops
3436
                     */
3437
                    return 1;
3438
                }
3439
                if (rn == 15 && w) {
3440
                    /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3441
                    return 1;
3442
                }
3443

    
3444
                if (s->thumb && rn == 15) {
3445
                    /* This is actually UNPREDICTABLE */
3446
                    addr = tcg_temp_new_i32();
3447
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3448
                } else {
3449
                    addr = load_reg(s, rn);
3450
                }
3451
                if (insn & (1 << 24)) /* pre-decrement */
3452
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3453

    
3454
                if (dp)
3455
                    offset = 8;
3456
                else
3457
                    offset = 4;
3458
                for (i = 0; i < n; i++) {
3459
                    if (insn & ARM_CP_RW_BIT) {
3460
                        /* load */
3461
                        gen_vfp_ld(s, dp, addr);
3462
                        gen_mov_vreg_F0(dp, rd + i);
3463
                    } else {
3464
                        /* store */
3465
                        gen_mov_F0_vreg(dp, rd + i);
3466
                        gen_vfp_st(s, dp, addr);
3467
                    }
3468
                    tcg_gen_addi_i32(addr, addr, offset);
3469
                }
3470
                if (w) {
3471
                    /* writeback */
3472
                    if (insn & (1 << 24))
3473
                        offset = -offset * n;
3474
                    else if (dp && (insn & 1))
3475
                        offset = 4;
3476
                    else
3477
                        offset = 0;
3478

    
3479
                    if (offset != 0)
3480
                        tcg_gen_addi_i32(addr, addr, offset);
3481
                    store_reg(s, rn, addr);
3482
                } else {
3483
                    tcg_temp_free_i32(addr);
3484
                }
3485
            }
3486
        }
3487
        break;
3488
    default:
3489
        /* Should never happen.  */
3490
        return 1;
3491
    }
3492
    return 0;
3493
}
3494

    
3495
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3496
{
3497
    TranslationBlock *tb;
3498

    
3499
    tb = s->tb;
3500
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3501
        tcg_gen_goto_tb(n);
3502
        gen_set_pc_im(dest);
3503
        tcg_gen_exit_tb((tcg_target_long)tb + n);
3504
    } else {
3505
        gen_set_pc_im(dest);
3506
        tcg_gen_exit_tb(0);
3507
    }
3508
}
3509

    
3510
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3511
{
3512
    if (unlikely(s->singlestep_enabled)) {
3513
        /* An indirect jump so that we still trigger the debug exception.  */
3514
        if (s->thumb)
3515
            dest |= 1;
3516
        gen_bx_im(s, dest);
3517
    } else {
3518
        gen_goto_tb(s, 0, dest);
3519
        s->is_jmp = DISAS_TB_JUMP;
3520
    }
3521
}
3522

    
3523
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3524
{
3525
    if (x)
3526
        tcg_gen_sari_i32(t0, t0, 16);
3527
    else
3528
        gen_sxth(t0);
3529
    if (y)
3530
        tcg_gen_sari_i32(t1, t1, 16);
3531
    else
3532
        gen_sxth(t1);
3533
    tcg_gen_mul_i32(t0, t0, t1);
3534
}
3535

    
3536
/* Return the mask of PSR bits set by a MSR instruction.  */
3537
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3538
    uint32_t mask;
3539

    
3540
    mask = 0;
3541
    if (flags & (1 << 0))
3542
        mask |= 0xff;
3543
    if (flags & (1 << 1))
3544
        mask |= 0xff00;
3545
    if (flags & (1 << 2))
3546
        mask |= 0xff0000;
3547
    if (flags & (1 << 3))
3548
        mask |= 0xff000000;
3549

    
3550
    /* Mask out undefined bits.  */
3551
    mask &= ~CPSR_RESERVED;
3552
    if (!arm_feature(env, ARM_FEATURE_V4T))
3553
        mask &= ~CPSR_T;
3554
    if (!arm_feature(env, ARM_FEATURE_V5))
3555
        mask &= ~CPSR_Q; /* V5TE in reality*/
3556
    if (!arm_feature(env, ARM_FEATURE_V6))
3557
        mask &= ~(CPSR_E | CPSR_GE);
3558
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3559
        mask &= ~CPSR_IT;
3560
    /* Mask out execution state bits.  */
3561
    if (!spsr)
3562
        mask &= ~CPSR_EXEC;
3563
    /* Mask out privileged bits.  */
3564
    if (IS_USER(s))
3565
        mask &= CPSR_USER;
3566
    return mask;
3567
}
3568

    
3569
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3570
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3571
{
3572
    TCGv tmp;
3573
    if (spsr) {
3574
        /* ??? This is also undefined in system mode.  */
3575
        if (IS_USER(s))
3576
            return 1;
3577

    
3578
        tmp = load_cpu_field(spsr);
3579
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3580
        tcg_gen_andi_i32(t0, t0, mask);
3581
        tcg_gen_or_i32(tmp, tmp, t0);
3582
        store_cpu_field(tmp, spsr);
3583
    } else {
3584
        gen_set_cpsr(t0, mask);
3585
    }
3586
    tcg_temp_free_i32(t0);
3587
    gen_lookup_tb(s);
3588
    return 0;
3589
}
3590

    
3591
/* Returns nonzero if access to the PSR is not permitted.  */
3592
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3593
{
3594
    TCGv tmp;
3595
    tmp = tcg_temp_new_i32();
3596
    tcg_gen_movi_i32(tmp, val);
3597
    return gen_set_psr(s, mask, spsr, tmp);
3598
}
3599

    
3600
/* Generate an old-style exception return. Marks pc as dead. */
3601
static void gen_exception_return(DisasContext *s, TCGv pc)
3602
{
3603
    TCGv tmp;
3604
    store_reg(s, 15, pc);
3605
    tmp = load_cpu_field(spsr);
3606
    gen_set_cpsr(tmp, 0xffffffff);
3607
    tcg_temp_free_i32(tmp);
3608
    s->is_jmp = DISAS_UPDATE;
3609
}
3610

    
3611
/* Generate a v6 exception return.  Marks both values as dead.  */
3612
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3613
{
3614
    gen_set_cpsr(cpsr, 0xffffffff);
3615
    tcg_temp_free_i32(cpsr);
3616
    store_reg(s, 15, pc);
3617
    s->is_jmp = DISAS_UPDATE;
3618
}
3619

    
3620
static inline void
3621
gen_set_condexec (DisasContext *s)
3622
{
3623
    if (s->condexec_mask) {
3624
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3625
        TCGv tmp = tcg_temp_new_i32();
3626
        tcg_gen_movi_i32(tmp, val);
3627
        store_cpu_field(tmp, condexec_bits);
3628
    }
3629
}
3630

    
3631
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3632
{
3633
    gen_set_condexec(s);
3634
    gen_set_pc_im(s->pc - offset);
3635
    gen_exception(excp);
3636
    s->is_jmp = DISAS_JUMP;
3637
}
3638

    
3639
static void gen_nop_hint(DisasContext *s, int val)
3640
{
3641
    switch (val) {
3642
    case 3: /* wfi */
3643
        gen_set_pc_im(s->pc);
3644
        s->is_jmp = DISAS_WFI;
3645
        break;
3646
    case 2: /* wfe */
3647
    case 4: /* sev */
3648
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3649
    default: /* nop */
3650
        break;
3651
    }
3652
}
3653

    
3654
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3655

    
3656
static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
3657
{
3658
    switch (size) {
3659
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3660
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3661
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3662
    default: abort();
3663
    }
3664
}
3665

    
3666
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3667
{
3668
    switch (size) {
3669
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3670
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3671
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3672
    default: return;
3673
    }
3674
}
3675

    
3676
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3677
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3678
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3679
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3680
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3681

    
3682
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3683
    switch ((size << 1) | u) { \
3684
    case 0: \
3685
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3686
        break; \
3687
    case 1: \
3688
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3689
        break; \
3690
    case 2: \
3691
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3692
        break; \
3693
    case 3: \
3694
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3695
        break; \
3696
    case 4: \
3697
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3698
        break; \
3699
    case 5: \
3700
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3701
        break; \
3702
    default: return 1; \
3703
    }} while (0)
3704

    
3705
#define GEN_NEON_INTEGER_OP(name) do { \
3706
    switch ((size << 1) | u) { \
3707
    case 0: \
3708
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3709
        break; \
3710
    case 1: \
3711
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3712
        break; \
3713
    case 2: \
3714
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3715
        break; \
3716
    case 3: \
3717
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3718
        break; \
3719
    case 4: \
3720
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3721
        break; \
3722
    case 5: \
3723
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3724
        break; \
3725
    default: return 1; \
3726
    }} while (0)
3727

    
3728
static TCGv neon_load_scratch(int scratch)
3729
{
3730
    TCGv tmp = tcg_temp_new_i32();
3731
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3732
    return tmp;
3733
}
3734

    
3735
static void neon_store_scratch(int scratch, TCGv var)
3736
{
3737
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3738
    tcg_temp_free_i32(var);
3739
}
3740

    
3741
static inline TCGv neon_get_scalar(int size, int reg)
3742
{
3743
    TCGv tmp;
3744
    if (size == 1) {
3745
        tmp = neon_load_reg(reg & 7, reg >> 4);
3746
        if (reg & 8) {
3747
            gen_neon_dup_high16(tmp);
3748
        } else {
3749
            gen_neon_dup_low16(tmp);
3750
        }
3751
    } else {
3752
        tmp = neon_load_reg(reg & 15, reg >> 4);
3753
    }
3754
    return tmp;
3755
}
3756

    
3757
static int gen_neon_unzip(int rd, int rm, int size, int q)
3758
{
3759
    TCGv tmp, tmp2;
3760
    if (!q && size == 2) {
3761
        return 1;
3762
    }
3763
    tmp = tcg_const_i32(rd);
3764
    tmp2 = tcg_const_i32(rm);
3765
    if (q) {
3766
        switch (size) {
3767
        case 0:
3768
            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3769
            break;
3770
        case 1:
3771
            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3772
            break;
3773
        case 2:
3774
            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3775
            break;
3776
        default:
3777
            abort();
3778
        }
3779
    } else {
3780
        switch (size) {
3781
        case 0:
3782
            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3783
            break;
3784
        case 1:
3785
            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3786
            break;
3787
        default:
3788
            abort();
3789
        }
3790
    }
3791
    tcg_temp_free_i32(tmp);
3792
    tcg_temp_free_i32(tmp2);
3793
    return 0;
3794
}
3795

    
3796
static int gen_neon_zip(int rd, int rm, int size, int q)
3797
{
3798
    TCGv tmp, tmp2;
3799
    if (!q && size == 2) {
3800
        return 1;
3801
    }
3802
    tmp = tcg_const_i32(rd);
3803
    tmp2 = tcg_const_i32(rm);
3804
    if (q) {
3805
        switch (size) {
3806
        case 0:
3807
            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3808
            break;
3809
        case 1:
3810
            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3811
            break;
3812
        case 2:
3813
            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3814
            break;
3815
        default:
3816
            abort();
3817
        }
3818
    } else {
3819
        switch (size) {
3820
        case 0:
3821
            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3822
            break;
3823
        case 1:
3824
            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3825
            break;
3826
        default:
3827
            abort();
3828
        }
3829
    }
3830
    tcg_temp_free_i32(tmp);
3831
    tcg_temp_free_i32(tmp2);
3832
    return 0;
3833
}
3834

    
3835
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3836
{
3837
    TCGv rd, tmp;
3838

    
3839
    rd = tcg_temp_new_i32();
3840
    tmp = tcg_temp_new_i32();
3841

    
3842
    tcg_gen_shli_i32(rd, t0, 8);
3843
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3844
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3845
    tcg_gen_or_i32(rd, rd, tmp);
3846

    
3847
    tcg_gen_shri_i32(t1, t1, 8);
3848
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3849
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3850
    tcg_gen_or_i32(t1, t1, tmp);
3851
    tcg_gen_mov_i32(t0, rd);
3852

    
3853
    tcg_temp_free_i32(tmp);
3854
    tcg_temp_free_i32(rd);
3855
}
3856

    
3857
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3858
{
3859
    TCGv rd, tmp;
3860

    
3861
    rd = tcg_temp_new_i32();
3862
    tmp = tcg_temp_new_i32();
3863

    
3864
    tcg_gen_shli_i32(rd, t0, 16);
3865
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3866
    tcg_gen_or_i32(rd, rd, tmp);
3867
    tcg_gen_shri_i32(t1, t1, 16);
3868
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3869
    tcg_gen_or_i32(t1, t1, tmp);
3870
    tcg_gen_mov_i32(t0, rd);
3871

    
3872
    tcg_temp_free_i32(tmp);
3873
    tcg_temp_free_i32(rd);
3874
}
3875

    
3876

    
3877
static struct {
3878
    int nregs;
3879
    int interleave;
3880
    int spacing;
3881
} neon_ls_element_type[11] = {
3882
    {4, 4, 1},
3883
    {4, 4, 2},
3884
    {4, 1, 1},
3885
    {4, 2, 1},
3886
    {3, 3, 1},
3887
    {3, 3, 2},
3888
    {3, 1, 1},
3889
    {1, 1, 1},
3890
    {2, 2, 1},
3891
    {2, 2, 2},
3892
    {2, 1, 1}
3893
};
3894

    
3895
/* Translate a NEON load/store element instruction.  Return nonzero if the
3896
   instruction is invalid.  */
3897
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3898
{
3899
    int rd, rn, rm;
3900
    int op;
3901
    int nregs;
3902
    int interleave;
3903
    int spacing;
3904
    int stride;
3905
    int size;
3906
    int reg;
3907
    int pass;
3908
    int load;
3909
    int shift;
3910
    int n;
3911
    TCGv addr;
3912
    TCGv tmp;
3913
    TCGv tmp2;
3914
    TCGv_i64 tmp64;
3915

    
3916
    if (!s->vfp_enabled)
3917
      return 1;
3918
    VFP_DREG_D(rd, insn);
3919
    rn = (insn >> 16) & 0xf;
3920
    rm = insn & 0xf;
3921
    load = (insn & (1 << 21)) != 0;
3922
    if ((insn & (1 << 23)) == 0) {
3923
        /* Load store all elements.  */
3924
        op = (insn >> 8) & 0xf;
3925
        size = (insn >> 6) & 3;
3926
        if (op > 10)
3927
            return 1;
3928
        /* Catch UNDEF cases for bad values of align field */
3929
        switch (op & 0xc) {
3930
        case 4:
3931
            if (((insn >> 5) & 1) == 1) {
3932
                return 1;
3933
            }
3934
            break;
3935
        case 8:
3936
            if (((insn >> 4) & 3) == 3) {
3937
                return 1;
3938
            }
3939
            break;
3940
        default:
3941
            break;
3942
        }
3943
        nregs = neon_ls_element_type[op].nregs;
3944
        interleave = neon_ls_element_type[op].interleave;
3945
        spacing = neon_ls_element_type[op].spacing;
3946
        if (size == 3 && (interleave | spacing) != 1)
3947
            return 1;
3948
        addr = tcg_temp_new_i32();
3949
        load_reg_var(s, addr, rn);
3950
        stride = (1 << size) * interleave;
3951
        for (reg = 0; reg < nregs; reg++) {
3952
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3953
                load_reg_var(s, addr, rn);
3954
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3955
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3956
                load_reg_var(s, addr, rn);
3957
                tcg_gen_addi_i32(addr, addr, 1 << size);
3958
            }
3959
            if (size == 3) {
3960
                if (load) {
3961
                    tmp64 = gen_ld64(addr, IS_USER(s));
3962
                    neon_store_reg64(tmp64, rd);
3963
                    tcg_temp_free_i64(tmp64);
3964
                } else {
3965
                    tmp64 = tcg_temp_new_i64();
3966
                    neon_load_reg64(tmp64, rd);
3967
                    gen_st64(tmp64, addr, IS_USER(s));
3968
                }
3969
                tcg_gen_addi_i32(addr, addr, stride);
3970
            } else {
3971
                for (pass = 0; pass < 2; pass++) {
3972
                    if (size == 2) {
3973
                        if (load) {
3974
                            tmp = gen_ld32(addr, IS_USER(s));
3975
                            neon_store_reg(rd, pass, tmp);
3976
                        } else {
3977
                            tmp = neon_load_reg(rd, pass);
3978
                            gen_st32(tmp, addr, IS_USER(s));
3979
                        }
3980
                        tcg_gen_addi_i32(addr, addr, stride);
3981
                    } else if (size == 1) {
3982
                        if (load) {
3983
                            tmp = gen_ld16u(addr, IS_USER(s));
3984
                            tcg_gen_addi_i32(addr, addr, stride);
3985
                            tmp2 = gen_ld16u(addr, IS_USER(s));
3986
                            tcg_gen_addi_i32(addr, addr, stride);
3987
                            tcg_gen_shli_i32(tmp2, tmp2, 16);
3988
                            tcg_gen_or_i32(tmp, tmp, tmp2);
3989
                            tcg_temp_free_i32(tmp2);
3990
                            neon_store_reg(rd, pass, tmp);
3991
                        } else {
3992
                            tmp = neon_load_reg(rd, pass);
3993
                            tmp2 = tcg_temp_new_i32();
3994
                            tcg_gen_shri_i32(tmp2, tmp, 16);
3995
                            gen_st16(tmp, addr, IS_USER(s));
3996
                            tcg_gen_addi_i32(addr, addr, stride);
3997
                            gen_st16(tmp2, addr, IS_USER(s));
3998
                            tcg_gen_addi_i32(addr, addr, stride);
3999
                        }
4000
                    } else /* size == 0 */ {
4001
                        if (load) {
4002
                            TCGV_UNUSED(tmp2);
4003
                            for (n = 0; n < 4; n++) {
4004
                                tmp = gen_ld8u(addr, IS_USER(s));
4005
                                tcg_gen_addi_i32(addr, addr, stride);
4006
                                if (n == 0) {
4007
                                    tmp2 = tmp;
4008
                                } else {
4009
                                    tcg_gen_shli_i32(tmp, tmp, n * 8);
4010
                                    tcg_gen_or_i32(tmp2, tmp2, tmp);
4011
                                    tcg_temp_free_i32(tmp);
4012
                                }
4013
                            }
4014
                            neon_store_reg(rd, pass, tmp2);
4015
                        } else {
4016
                            tmp2 = neon_load_reg(rd, pass);
4017
                            for (n = 0; n < 4; n++) {
4018
                                tmp = tcg_temp_new_i32();
4019
                                if (n == 0) {
4020
                                    tcg_gen_mov_i32(tmp, tmp2);
4021
                                } else {
4022
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
4023
                                }
4024
                                gen_st8(tmp, addr, IS_USER(s));
4025
                                tcg_gen_addi_i32(addr, addr, stride);
4026
                            }
4027
                            tcg_temp_free_i32(tmp2);
4028
                        }
4029
                    }
4030
                }
4031
            }
4032
            rd += spacing;
4033
        }
4034
        tcg_temp_free_i32(addr);
4035
        stride = nregs * 8;
4036
    } else {
4037
        size = (insn >> 10) & 3;
4038
        if (size == 3) {
4039
            /* Load single element to all lanes.  */
4040
            int a = (insn >> 4) & 1;
4041
            if (!load) {
4042
                return 1;
4043
            }
4044
            size = (insn >> 6) & 3;
4045
            nregs = ((insn >> 8) & 3) + 1;
4046

    
4047
            if (size == 3) {
4048
                if (nregs != 4 || a == 0) {
4049
                    return 1;
4050
                }
4051
                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4052
                size = 2;
4053
            }
4054
            if (nregs == 1 && a == 1 && size == 0) {
4055
                return 1;
4056
            }
4057
            if (nregs == 3 && a == 1) {
4058
                return 1;
4059
            }
4060
            addr = tcg_temp_new_i32();
4061
            load_reg_var(s, addr, rn);
4062
            if (nregs == 1) {
4063
                /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4064
                tmp = gen_load_and_replicate(s, addr, size);
4065
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4066
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4067
                if (insn & (1 << 5)) {
4068
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4069
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4070
                }
4071
                tcg_temp_free_i32(tmp);
4072
            } else {
4073
                /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4074
                stride = (insn & (1 << 5)) ? 2 : 1;
4075
                for (reg = 0; reg < nregs; reg++) {
4076
                    tmp = gen_load_and_replicate(s, addr, size);
4077
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4078
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4079
                    tcg_temp_free_i32(tmp);
4080
                    tcg_gen_addi_i32(addr, addr, 1 << size);
4081
                    rd += stride;
4082
                }
4083
            }
4084
            tcg_temp_free_i32(addr);
4085
            stride = (1 << size) * nregs;
4086
        } else {
4087
            /* Single element.  */
4088
            int idx = (insn >> 4) & 0xf;
4089
            pass = (insn >> 7) & 1;
4090
            switch (size) {
4091
            case 0:
4092
                shift = ((insn >> 5) & 3) * 8;
4093
                stride = 1;
4094
                break;
4095
            case 1:
4096
                shift = ((insn >> 6) & 1) * 16;
4097
                stride = (insn & (1 << 5)) ? 2 : 1;
4098
                break;
4099
            case 2:
4100
                shift = 0;
4101
                stride = (insn & (1 << 6)) ? 2 : 1;
4102
                break;
4103
            default:
4104
                abort();
4105
            }
4106
            nregs = ((insn >> 8) & 3) + 1;
4107
            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4108
            switch (nregs) {
4109
            case 1:
4110
                if (((idx & (1 << size)) != 0) ||
4111
                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4112
                    return 1;
4113
                }
4114
                break;
4115
            case 3:
4116
                if ((idx & 1) != 0) {
4117
                    return 1;
4118
                }
4119
                /* fall through */
4120
            case 2:
4121
                if (size == 2 && (idx & 2) != 0) {
4122
                    return 1;
4123
                }
4124
                break;
4125
            case 4:
4126
                if ((size == 2) && ((idx & 3) == 3)) {
4127
                    return 1;
4128
                }
4129
                break;
4130
            default:
4131
                abort();
4132
            }
4133
            if ((rd + stride * (nregs - 1)) > 31) {
4134
                /* Attempts to write off the end of the register file
4135
                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4136
                 * the neon_load_reg() would write off the end of the array.
4137
                 */
4138
                return 1;
4139
            }
4140
            addr = tcg_temp_new_i32();
4141
            load_reg_var(s, addr, rn);
4142
            for (reg = 0; reg < nregs; reg++) {
4143
                if (load) {
4144
                    switch (size) {
4145
                    case 0:
4146
                        tmp = gen_ld8u(addr, IS_USER(s));
4147
                        break;
4148
                    case 1:
4149
                        tmp = gen_ld16u(addr, IS_USER(s));
4150
                        break;
4151
                    case 2:
4152
                        tmp = gen_ld32(addr, IS_USER(s));
4153
                        break;
4154
                    default: /* Avoid compiler warnings.  */
4155
                        abort();
4156
                    }
4157
                    if (size != 2) {
4158
                        tmp2 = neon_load_reg(rd, pass);
4159
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
4160
                        tcg_temp_free_i32(tmp2);
4161
                    }
4162
                    neon_store_reg(rd, pass, tmp);
4163
                } else { /* Store */
4164
                    tmp = neon_load_reg(rd, pass);
4165
                    if (shift)
4166
                        tcg_gen_shri_i32(tmp, tmp, shift);
4167
                    switch (size) {
4168
                    case 0:
4169
                        gen_st8(tmp, addr, IS_USER(s));
4170
                        break;
4171
                    case 1:
4172
                        gen_st16(tmp, addr, IS_USER(s));
4173
                        break;
4174
                    case 2:
4175
                        gen_st32(tmp, addr, IS_USER(s));
4176
                        break;
4177
                    }
4178
                }
4179
                rd += stride;
4180
                tcg_gen_addi_i32(addr, addr, 1 << size);
4181
            }
4182
            tcg_temp_free_i32(addr);
4183
            stride = nregs * (1 << size);
4184
        }
4185
    }
4186
    if (rm != 15) {
4187
        TCGv base;
4188

    
4189
        base = load_reg(s, rn);
4190
        if (rm == 13) {
4191
            tcg_gen_addi_i32(base, base, stride);
4192
        } else {
4193
            TCGv index;
4194
            index = load_reg(s, rm);
4195
            tcg_gen_add_i32(base, base, index);
4196
            tcg_temp_free_i32(index);
4197
        }
4198
        store_reg(s, rn, base);
4199
    }
4200
    return 0;
4201
}
4202

    
4203
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4204
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4205
{
4206
    tcg_gen_and_i32(t, t, c);
4207
    tcg_gen_andc_i32(f, f, c);
4208
    tcg_gen_or_i32(dest, t, f);
4209
}
4210

    
4211
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4212
{
4213
    switch (size) {
4214
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4215
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4216
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4217
    default: abort();
4218
    }
4219
}
4220

    
4221
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4222
{
4223
    switch (size) {
4224
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4225
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4226
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4227
    default: abort();
4228
    }
4229
}
4230

    
4231
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4232
{
4233
    switch (size) {
4234
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4235
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4236
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4237
    default: abort();
4238
    }
4239
}
4240

    
4241
static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4242
{
4243
    switch (size) {
4244
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4245
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4246
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4247
    default: abort();
4248
    }
4249
}
4250

    
4251
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4252
                                         int q, int u)
4253
{
4254
    if (q) {
4255
        if (u) {
4256
            switch (size) {
4257
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4258
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4259
            default: abort();
4260
            }
4261
        } else {
4262
            switch (size) {
4263
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4264
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4265
            default: abort();
4266
            }
4267
        }
4268
    } else {
4269
        if (u) {
4270
            switch (size) {
4271
            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4272
            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4273
            default: abort();
4274
            }
4275
        } else {
4276
            switch (size) {
4277
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4278
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4279
            default: abort();
4280
            }
4281
        }
4282
    }
4283
}
4284

    
4285
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4286
{
4287
    if (u) {
4288
        switch (size) {
4289
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4290
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4291
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4292
        default: abort();
4293
        }
4294
    } else {
4295
        switch (size) {
4296
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4297
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4298
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4299
        default: abort();
4300
        }
4301
    }
4302
    tcg_temp_free_i32(src);
4303
}
4304

    
4305
static inline void gen_neon_addl(int size)
4306
{
4307
    switch (size) {
4308
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4309
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4310
    case 2: tcg_gen_add_i64(CPU_V001); break;
4311
    default: abort();
4312
    }
4313
}
4314

    
4315
static inline void gen_neon_subl(int size)
4316
{
4317
    switch (size) {
4318
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4319
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4320
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4321
    default: abort();
4322
    }
4323
}
4324

    
4325
static inline void gen_neon_negl(TCGv_i64 var, int size)
4326
{
4327
    switch (size) {
4328
    case 0: gen_helper_neon_negl_u16(var, var); break;
4329
    case 1: gen_helper_neon_negl_u32(var, var); break;
4330
    case 2: gen_helper_neon_negl_u64(var, var); break;
4331
    default: abort();
4332
    }
4333
}
4334

    
4335
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4336
{
4337
    switch (size) {
4338
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4339
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4340
    default: abort();
4341
    }
4342
}
4343

    
4344
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4345
{
4346
    TCGv_i64 tmp;
4347

    
4348
    switch ((size << 1) | u) {
4349
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4350
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4351
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4352
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4353
    case 4:
4354
        tmp = gen_muls_i64_i32(a, b);
4355
        tcg_gen_mov_i64(dest, tmp);
4356
        tcg_temp_free_i64(tmp);
4357
        break;
4358
    case 5:
4359
        tmp = gen_mulu_i64_i32(a, b);
4360
        tcg_gen_mov_i64(dest, tmp);
4361
        tcg_temp_free_i64(tmp);
4362
        break;
4363
    default: abort();
4364
    }
4365

    
4366
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4367
       Don't forget to clean them now.  */
4368
    if (size < 2) {
4369
        tcg_temp_free_i32(a);
4370
        tcg_temp_free_i32(b);
4371
    }
4372
}
4373

    
4374
static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
4375
{
4376
    if (op) {
4377
        if (u) {
4378
            gen_neon_unarrow_sats(size, dest, src);
4379
        } else {
4380
            gen_neon_narrow(size, dest, src);
4381
        }
4382
    } else {
4383
        if (u) {
4384
            gen_neon_narrow_satu(size, dest, src);
4385
        } else {
4386
            gen_neon_narrow_sats(size, dest, src);
4387
        }
4388
    }
4389
}
4390

    
4391
/* Symbolic constants for op fields for Neon 3-register same-length.
4392
 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4393
 * table A7-9.
4394
 */
4395
#define NEON_3R_VHADD 0
4396
#define NEON_3R_VQADD 1
4397
#define NEON_3R_VRHADD 2
4398
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4399
#define NEON_3R_VHSUB 4
4400
#define NEON_3R_VQSUB 5
4401
#define NEON_3R_VCGT 6
4402
#define NEON_3R_VCGE 7
4403
#define NEON_3R_VSHL 8
4404
#define NEON_3R_VQSHL 9
4405
#define NEON_3R_VRSHL 10
4406
#define NEON_3R_VQRSHL 11
4407
#define NEON_3R_VMAX 12
4408
#define NEON_3R_VMIN 13
4409
#define NEON_3R_VABD 14
4410
#define NEON_3R_VABA 15
4411
#define NEON_3R_VADD_VSUB 16
4412
#define NEON_3R_VTST_VCEQ 17
4413
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4414
#define NEON_3R_VMUL 19
4415
#define NEON_3R_VPMAX 20
4416
#define NEON_3R_VPMIN 21
4417
#define NEON_3R_VQDMULH_VQRDMULH 22
4418
#define NEON_3R_VPADD 23
4419
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4420
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4421
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4422
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4423
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4424
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4425

    
4426
static const uint8_t neon_3r_sizes[] = {
4427
    [NEON_3R_VHADD] = 0x7,
4428
    [NEON_3R_VQADD] = 0xf,
4429
    [NEON_3R_VRHADD] = 0x7,
4430
    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4431
    [NEON_3R_VHSUB] = 0x7,
4432
    [NEON_3R_VQSUB] = 0xf,
4433
    [NEON_3R_VCGT] = 0x7,
4434
    [NEON_3R_VCGE] = 0x7,
4435
    [NEON_3R_VSHL] = 0xf,
4436
    [NEON_3R_VQSHL] = 0xf,
4437
    [NEON_3R_VRSHL] = 0xf,
4438
    [NEON_3R_VQRSHL] = 0xf,
4439
    [NEON_3R_VMAX] = 0x7,
4440
    [NEON_3R_VMIN] = 0x7,
4441
    [NEON_3R_VABD] = 0x7,
4442
    [NEON_3R_VABA] = 0x7,
4443
    [NEON_3R_VADD_VSUB] = 0xf,
4444
    [NEON_3R_VTST_VCEQ] = 0x7,
4445
    [NEON_3R_VML] = 0x7,
4446
    [NEON_3R_VMUL] = 0x7,
4447
    [NEON_3R_VPMAX] = 0x7,
4448
    [NEON_3R_VPMIN] = 0x7,
4449
    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4450
    [NEON_3R_VPADD] = 0x7,
4451
    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4452
    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4453
    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4454
    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4455
    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4456
    [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4457
};
4458

    
4459
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4460
 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4461
 * table A7-13.
4462
 */
4463
#define NEON_2RM_VREV64 0
4464
#define NEON_2RM_VREV32 1
4465
#define NEON_2RM_VREV16 2
4466
#define NEON_2RM_VPADDL 4
4467
#define NEON_2RM_VPADDL_U 5
4468
#define NEON_2RM_VCLS 8
4469
#define NEON_2RM_VCLZ 9
4470
#define NEON_2RM_VCNT 10
4471
#define NEON_2RM_VMVN 11
4472
#define NEON_2RM_VPADAL 12
4473
#define NEON_2RM_VPADAL_U 13
4474
#define NEON_2RM_VQABS 14
4475
#define NEON_2RM_VQNEG 15
4476
#define NEON_2RM_VCGT0 16
4477
#define NEON_2RM_VCGE0 17
4478
#define NEON_2RM_VCEQ0 18
4479
#define NEON_2RM_VCLE0 19
4480
#define NEON_2RM_VCLT0 20
4481
#define NEON_2RM_VABS 22
4482
#define NEON_2RM_VNEG 23
4483
#define NEON_2RM_VCGT0_F 24
4484
#define NEON_2RM_VCGE0_F 25
4485
#define NEON_2RM_VCEQ0_F 26
4486
#define NEON_2RM_VCLE0_F 27
4487
#define NEON_2RM_VCLT0_F 28
4488
#define NEON_2RM_VABS_F 30
4489
#define NEON_2RM_VNEG_F 31
4490
#define NEON_2RM_VSWP 32
4491
#define NEON_2RM_VTRN 33
4492
#define NEON_2RM_VUZP 34
4493
#define NEON_2RM_VZIP 35
4494
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4495
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4496
#define NEON_2RM_VSHLL 38
4497
#define NEON_2RM_VCVT_F16_F32 44
4498
#define NEON_2RM_VCVT_F32_F16 46
4499
#define NEON_2RM_VRECPE 56
4500
#define NEON_2RM_VRSQRTE 57
4501
#define NEON_2RM_VRECPE_F 58
4502
#define NEON_2RM_VRSQRTE_F 59
4503
#define NEON_2RM_VCVT_FS 60
4504
#define NEON_2RM_VCVT_FU 61
4505
#define NEON_2RM_VCVT_SF 62
4506
#define NEON_2RM_VCVT_UF 63
4507

    
4508
static int neon_2rm_is_float_op(int op)
4509
{
4510
    /* Return true if this neon 2reg-misc op is float-to-float */
4511
    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4512
            op >= NEON_2RM_VRECPE_F);
4513
}
4514

    
4515
/* Each entry in this array has bit n set if the insn allows
4516
 * size value n (otherwise it will UNDEF). Since unallocated
4517
 * op values will have no bits set they always UNDEF.
4518
 */
4519
static const uint8_t neon_2rm_sizes[] = {
4520
    [NEON_2RM_VREV64] = 0x7,
4521
    [NEON_2RM_VREV32] = 0x3,
4522
    [NEON_2RM_VREV16] = 0x1,
4523
    [NEON_2RM_VPADDL] = 0x7,
4524
    [NEON_2RM_VPADDL_U] = 0x7,
4525
    [NEON_2RM_VCLS] = 0x7,
4526
    [NEON_2RM_VCLZ] = 0x7,
4527
    [NEON_2RM_VCNT] = 0x1,
4528
    [NEON_2RM_VMVN] = 0x1,
4529
    [NEON_2RM_VPADAL] = 0x7,
4530
    [NEON_2RM_VPADAL_U] = 0x7,
4531
    [NEON_2RM_VQABS] = 0x7,
4532
    [NEON_2RM_VQNEG] = 0x7,
4533
    [NEON_2RM_VCGT0] = 0x7,
4534
    [NEON_2RM_VCGE0] = 0x7,
4535
    [NEON_2RM_VCEQ0] = 0x7,
4536
    [NEON_2RM_VCLE0] = 0x7,
4537
    [NEON_2RM_VCLT0] = 0x7,
4538
    [NEON_2RM_VABS] = 0x7,
4539
    [NEON_2RM_VNEG] = 0x7,
4540
    [NEON_2RM_VCGT0_F] = 0x4,
4541
    [NEON_2RM_VCGE0_F] = 0x4,
4542
    [NEON_2RM_VCEQ0_F] = 0x4,
4543
    [NEON_2RM_VCLE0_F] = 0x4,
4544
    [NEON_2RM_VCLT0_F] = 0x4,
4545
    [NEON_2RM_VABS_F] = 0x4,
4546
    [NEON_2RM_VNEG_F] = 0x4,
4547
    [NEON_2RM_VSWP] = 0x1,
4548
    [NEON_2RM_VTRN] = 0x7,
4549
    [NEON_2RM_VUZP] = 0x7,
4550
    [NEON_2RM_VZIP] = 0x7,
4551
    [NEON_2RM_VMOVN] = 0x7,
4552
    [NEON_2RM_VQMOVN] = 0x7,
4553
    [NEON_2RM_VSHLL] = 0x7,
4554
    [NEON_2RM_VCVT_F16_F32] = 0x2,
4555
    [NEON_2RM_VCVT_F32_F16] = 0x2,
4556
    [NEON_2RM_VRECPE] = 0x4,
4557
    [NEON_2RM_VRSQRTE] = 0x4,
4558
    [NEON_2RM_VRECPE_F] = 0x4,
4559
    [NEON_2RM_VRSQRTE_F] = 0x4,
4560
    [NEON_2RM_VCVT_FS] = 0x4,
4561
    [NEON_2RM_VCVT_FU] = 0x4,
4562
    [NEON_2RM_VCVT_SF] = 0x4,
4563
    [NEON_2RM_VCVT_UF] = 0x4,
4564
};
4565

    
4566
/* Translate a NEON data processing instruction.  Return nonzero if the
4567
   instruction is invalid.
4568
   We process data in a mixture of 32-bit and 64-bit chunks.
4569
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4570

    
4571
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4572
{
4573
    int op;
4574
    int q;
4575
    int rd, rn, rm;
4576
    int size;
4577
    int shift;
4578
    int pass;
4579
    int count;
4580
    int pairwise;
4581
    int u;
4582
    uint32_t imm, mask;
4583
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4584
    TCGv_i64 tmp64;
4585

    
4586
    if (!s->vfp_enabled)
4587
      return 1;
4588
    q = (insn & (1 << 6)) != 0;
4589
    u = (insn >> 24) & 1;
4590
    VFP_DREG_D(rd, insn);
4591
    VFP_DREG_N(rn, insn);
4592
    VFP_DREG_M(rm, insn);
4593
    size = (insn >> 20) & 3;
4594
    if ((insn & (1 << 23)) == 0) {
4595
        /* Three register same length.  */
4596
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4597
        /* Catch invalid op and bad size combinations: UNDEF */
4598
        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4599
            return 1;
4600
        }
4601
        /* All insns of this form UNDEF for either this condition or the
4602
         * superset of cases "Q==1"; we catch the latter later.
4603
         */
4604
        if (q && ((rd | rn | rm) & 1)) {
4605
            return 1;
4606
        }
4607
        if (size == 3 && op != NEON_3R_LOGIC) {
4608
            /* 64-bit element instructions. */
4609
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4610
                neon_load_reg64(cpu_V0, rn + pass);
4611
                neon_load_reg64(cpu_V1, rm + pass);
4612
                switch (op) {
4613
                case NEON_3R_VQADD:
4614
                    if (u) {
4615
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4616
                                                 cpu_V0, cpu_V1);
4617
                    } else {
4618
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4619
                                                 cpu_V0, cpu_V1);
4620
                    }
4621
                    break;
4622
                case NEON_3R_VQSUB:
4623
                    if (u) {
4624
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4625
                                                 cpu_V0, cpu_V1);
4626
                    } else {
4627
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4628
                                                 cpu_V0, cpu_V1);
4629
                    }
4630
                    break;
4631
                case NEON_3R_VSHL:
4632
                    if (u) {
4633
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4634
                    } else {
4635
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4636
                    }
4637
                    break;
4638
                case NEON_3R_VQSHL:
4639
                    if (u) {
4640
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4641
                                                 cpu_V1, cpu_V0);
4642
                    } else {
4643
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4644
                                                 cpu_V1, cpu_V0);
4645
                    }
4646
                    break;
4647
                case NEON_3R_VRSHL:
4648
                    if (u) {
4649
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4650
                    } else {
4651
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4652
                    }
4653
                    break;
4654
                case NEON_3R_VQRSHL:
4655
                    if (u) {
4656
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4657
                                                  cpu_V1, cpu_V0);
4658
                    } else {
4659
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4660
                                                  cpu_V1, cpu_V0);
4661
                    }
4662
                    break;
4663
                case NEON_3R_VADD_VSUB:
4664
                    if (u) {
4665
                        tcg_gen_sub_i64(CPU_V001);
4666
                    } else {
4667
                        tcg_gen_add_i64(CPU_V001);
4668
                    }
4669
                    break;
4670
                default:
4671
                    abort();
4672
                }
4673
                neon_store_reg64(cpu_V0, rd + pass);
4674
            }
4675
            return 0;
4676
        }
4677
        pairwise = 0;
4678
        switch (op) {
4679
        case NEON_3R_VSHL:
4680
        case NEON_3R_VQSHL:
4681
        case NEON_3R_VRSHL:
4682
        case NEON_3R_VQRSHL:
4683
            {
4684
                int rtmp;
4685
                /* Shift instruction operands are reversed.  */
4686
                rtmp = rn;
4687
                rn = rm;
4688
                rm = rtmp;
4689
            }
4690
            break;
4691
        case NEON_3R_VPADD:
4692
            if (u) {
4693
                return 1;
4694
            }
4695
            /* Fall through */
4696
        case NEON_3R_VPMAX:
4697
        case NEON_3R_VPMIN:
4698
            pairwise = 1;
4699
            break;
4700
        case NEON_3R_FLOAT_ARITH:
4701
            pairwise = (u && size < 2); /* if VPADD (float) */
4702
            break;
4703
        case NEON_3R_FLOAT_MINMAX:
4704
            pairwise = u; /* if VPMIN/VPMAX (float) */
4705
            break;
4706
        case NEON_3R_FLOAT_CMP:
4707
            if (!u && size) {
4708
                /* no encoding for U=0 C=1x */
4709
                return 1;
4710
            }
4711
            break;
4712
        case NEON_3R_FLOAT_ACMP:
4713
            if (!u) {
4714
                return 1;
4715
            }
4716
            break;
4717
        case NEON_3R_VRECPS_VRSQRTS:
4718
            if (u) {
4719
                return 1;
4720
            }
4721
            break;
4722
        case NEON_3R_VMUL:
4723
            if (u && (size != 0)) {
4724
                /* UNDEF on invalid size for polynomial subcase */
4725
                return 1;
4726
            }
4727
            break;
4728
        default:
4729
            break;
4730
        }
4731

    
4732
        if (pairwise && q) {
4733
            /* All the pairwise insns UNDEF if Q is set */
4734
            return 1;
4735
        }
4736

    
4737
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4738

    
4739
        if (pairwise) {
4740
            /* Pairwise.  */
4741
            if (pass < 1) {
4742
                tmp = neon_load_reg(rn, 0);
4743
                tmp2 = neon_load_reg(rn, 1);
4744
            } else {
4745
                tmp = neon_load_reg(rm, 0);
4746
                tmp2 = neon_load_reg(rm, 1);
4747
            }
4748
        } else {
4749
            /* Elementwise.  */
4750
            tmp = neon_load_reg(rn, pass);
4751
            tmp2 = neon_load_reg(rm, pass);
4752
        }
4753
        switch (op) {
4754
        case NEON_3R_VHADD:
4755
            GEN_NEON_INTEGER_OP(hadd);
4756
            break;
4757
        case NEON_3R_VQADD:
4758
            GEN_NEON_INTEGER_OP_ENV(qadd);
4759
            break;
4760
        case NEON_3R_VRHADD:
4761
            GEN_NEON_INTEGER_OP(rhadd);
4762
            break;
4763
        case NEON_3R_LOGIC: /* Logic ops.  */
4764
            switch ((u << 2) | size) {
4765
            case 0: /* VAND */
4766
                tcg_gen_and_i32(tmp, tmp, tmp2);
4767
                break;
4768
            case 1: /* BIC */
4769
                tcg_gen_andc_i32(tmp, tmp, tmp2);
4770
                break;
4771
            case 2: /* VORR */
4772
                tcg_gen_or_i32(tmp, tmp, tmp2);
4773
                break;
4774
            case 3: /* VORN */
4775
                tcg_gen_orc_i32(tmp, tmp, tmp2);
4776
                break;
4777
            case 4: /* VEOR */
4778
                tcg_gen_xor_i32(tmp, tmp, tmp2);
4779
                break;
4780
            case 5: /* VBSL */
4781
                tmp3 = neon_load_reg(rd, pass);
4782
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4783
                tcg_temp_free_i32(tmp3);
4784
                break;
4785
            case 6: /* VBIT */
4786
                tmp3 = neon_load_reg(rd, pass);
4787
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4788
                tcg_temp_free_i32(tmp3);
4789
                break;
4790
            case 7: /* VBIF */
4791
                tmp3 = neon_load_reg(rd, pass);
4792
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4793
                tcg_temp_free_i32(tmp3);
4794
                break;
4795
            }
4796
            break;
4797
        case NEON_3R_VHSUB:
4798
            GEN_NEON_INTEGER_OP(hsub);
4799
            break;
4800
        case NEON_3R_VQSUB:
4801
            GEN_NEON_INTEGER_OP_ENV(qsub);
4802
            break;
4803
        case NEON_3R_VCGT:
4804
            GEN_NEON_INTEGER_OP(cgt);
4805
            break;
4806
        case NEON_3R_VCGE:
4807
            GEN_NEON_INTEGER_OP(cge);
4808
            break;
4809
        case NEON_3R_VSHL:
4810
            GEN_NEON_INTEGER_OP(shl);
4811
            break;
4812
        case NEON_3R_VQSHL:
4813
            GEN_NEON_INTEGER_OP_ENV(qshl);
4814
            break;
4815
        case NEON_3R_VRSHL:
4816
            GEN_NEON_INTEGER_OP(rshl);
4817
            break;
4818
        case NEON_3R_VQRSHL:
4819
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4820
            break;
4821
        case NEON_3R_VMAX:
4822
            GEN_NEON_INTEGER_OP(max);
4823
            break;
4824
        case NEON_3R_VMIN:
4825
            GEN_NEON_INTEGER_OP(min);
4826
            break;
4827
        case NEON_3R_VABD:
4828
            GEN_NEON_INTEGER_OP(abd);
4829
            break;
4830
        case NEON_3R_VABA:
4831
            GEN_NEON_INTEGER_OP(abd);
4832
            tcg_temp_free_i32(tmp2);
4833
            tmp2 = neon_load_reg(rd, pass);
4834
            gen_neon_add(size, tmp, tmp2);
4835
            break;
4836
        case NEON_3R_VADD_VSUB:
4837
            if (!u) { /* VADD */
4838
                gen_neon_add(size, tmp, tmp2);
4839
            } else { /* VSUB */
4840
                switch (size) {
4841
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4842
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4843
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4844
                default: abort();
4845
                }
4846
            }
4847
            break;
4848
        case NEON_3R_VTST_VCEQ:
4849
            if (!u) { /* VTST */
4850
                switch (size) {
4851
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4852
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4853
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4854
                default: abort();
4855
                }
4856
            } else { /* VCEQ */
4857
                switch (size) {
4858
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4859
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4860
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4861
                default: abort();
4862
                }
4863
            }
4864
            break;
4865
        case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4866
            switch (size) {
4867
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4868
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4869
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4870
            default: abort();
4871
            }
4872
            tcg_temp_free_i32(tmp2);
4873
            tmp2 = neon_load_reg(rd, pass);
4874
            if (u) { /* VMLS */
4875
                gen_neon_rsb(size, tmp, tmp2);
4876
            } else { /* VMLA */
4877
                gen_neon_add(size, tmp, tmp2);
4878
            }
4879
            break;
4880
        case NEON_3R_VMUL:
4881
            if (u) { /* polynomial */
4882
                gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4883
            } else { /* Integer */
4884
                switch (size) {
4885
                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4886
                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4887
                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4888
                default: abort();
4889
                }
4890
            }
4891
            break;
4892
        case NEON_3R_VPMAX:
4893
            GEN_NEON_INTEGER_OP(pmax);
4894
            break;
4895
        case NEON_3R_VPMIN:
4896
            GEN_NEON_INTEGER_OP(pmin);
4897
            break;
4898
        case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
4899
            if (!u) { /* VQDMULH */
4900
                switch (size) {
4901
                case 1:
4902
                    gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
4903
                    break;
4904
                case 2:
4905
                    gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
4906
                    break;
4907
                default: abort();
4908
                }
4909
            } else { /* VQRDMULH */
4910
                switch (size) {
4911
                case 1:
4912
                    gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
4913
                    break;
4914
                case 2:
4915
                    gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
4916
                    break;
4917
                default: abort();
4918
                }
4919
            }
4920
            break;
4921
        case NEON_3R_VPADD:
4922
            switch (size) {
4923
            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4924
            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4925
            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4926
            default: abort();
4927
            }
4928
            break;
4929
        case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
4930
        {
4931
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4932
            switch ((u << 2) | size) {
4933
            case 0: /* VADD */
4934
            case 4: /* VPADD */
4935
                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4936
                break;
4937
            case 2: /* VSUB */
4938
                gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
4939
                break;
4940
            case 6: /* VABD */
4941
                gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
4942
                break;
4943
            default:
4944
                abort();
4945
            }
4946
            tcg_temp_free_ptr(fpstatus);
4947
            break;
4948
        }
4949
        case NEON_3R_FLOAT_MULTIPLY:
4950
        {
4951
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4952
            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
4953
            if (!u) {
4954
                tcg_temp_free_i32(tmp2);
4955
                tmp2 = neon_load_reg(rd, pass);
4956
                if (size == 0) {
4957
                    gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4958
                } else {
4959
                    gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
4960
                }
4961
            }
4962
            tcg_temp_free_ptr(fpstatus);
4963
            break;
4964
        }
4965
        case NEON_3R_FLOAT_CMP:
4966
        {
4967
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4968
            if (!u) {
4969
                gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
4970
            } else {
4971
                if (size == 0) {
4972
                    gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
4973
                } else {
4974
                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
4975
                }
4976
            }
4977
            tcg_temp_free_ptr(fpstatus);
4978
            break;
4979
        }
4980
        case NEON_3R_FLOAT_ACMP:
4981
        {
4982
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4983
            if (size == 0) {
4984
                gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
4985
            } else {
4986
                gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
4987
            }
4988
            tcg_temp_free_ptr(fpstatus);
4989
            break;
4990
        }
4991
        case NEON_3R_FLOAT_MINMAX:
4992
        {
4993
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4994
            if (size == 0) {
4995
                gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
4996
            } else {
4997
                gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
4998
            }
4999
            tcg_temp_free_ptr(fpstatus);
5000
            break;
5001
        }
5002
        case NEON_3R_VRECPS_VRSQRTS:
5003
            if (size == 0)
5004
                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5005
            else
5006
                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5007
            break;
5008
        default:
5009
            abort();
5010
        }
5011
        tcg_temp_free_i32(tmp2);
5012

    
5013
        /* Save the result.  For elementwise operations we can put it
5014
           straight into the destination register.  For pairwise operations
5015
           we have to be careful to avoid clobbering the source operands.  */
5016
        if (pairwise && rd == rm) {
5017
            neon_store_scratch(pass, tmp);
5018
        } else {
5019
            neon_store_reg(rd, pass, tmp);
5020
        }
5021

    
5022
        } /* for pass */
5023
        if (pairwise && rd == rm) {
5024
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5025
                tmp = neon_load_scratch(pass);
5026
                neon_store_reg(rd, pass, tmp);
5027
            }
5028
        }
5029
        /* End of 3 register same size operations.  */
5030
    } else if (insn & (1 << 4)) {
5031
        if ((insn & 0x00380080) != 0) {
5032
            /* Two registers and shift.  */
5033
            op = (insn >> 8) & 0xf;
5034
            if (insn & (1 << 7)) {
5035
                /* 64-bit shift. */
5036
                if (op > 7) {
5037
                    return 1;
5038
                }
5039
                size = 3;
5040
            } else {
5041
                size = 2;
5042
                while ((insn & (1 << (size + 19))) == 0)
5043
                    size--;
5044
            }
5045
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5046
            /* To avoid excessive dumplication of ops we implement shift
5047
               by immediate using the variable shift operations.  */
5048
            if (op < 8) {
5049
                /* Shift by immediate:
5050
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
5051
                if (q && ((rd | rm) & 1)) {
5052
                    return 1;
5053
                }
5054
                if (!u && (op == 4 || op == 6)) {
5055
                    return 1;
5056
                }
5057
                /* Right shifts are encoded as N - shift, where N is the
5058
                   element size in bits.  */
5059
                if (op <= 4)
5060
                    shift = shift - (1 << (size + 3));
5061
                if (size == 3) {
5062
                    count = q + 1;
5063
                } else {
5064
                    count = q ? 4: 2;
5065
                }
5066
                switch (size) {
5067
                case 0:
5068
                    imm = (uint8_t) shift;
5069
                    imm |= imm << 8;
5070
                    imm |= imm << 16;
5071
                    break;
5072
                case 1:
5073
                    imm = (uint16_t) shift;
5074
                    imm |= imm << 16;
5075
                    break;
5076
                case 2:
5077
                case 3:
5078
                    imm = shift;
5079
                    break;
5080
                default:
5081
                    abort();
5082
                }
5083

    
5084
                for (pass = 0; pass < count; pass++) {
5085
                    if (size == 3) {
5086
                        neon_load_reg64(cpu_V0, rm + pass);
5087
                        tcg_gen_movi_i64(cpu_V1, imm);
5088
                        switch (op) {
5089
                        case 0:  /* VSHR */
5090
                        case 1:  /* VSRA */
5091
                            if (u)
5092
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5093
                            else
5094
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5095
                            break;
5096
                        case 2: /* VRSHR */
5097
                        case 3: /* VRSRA */
5098
                            if (u)
5099
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5100
                            else
5101
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5102
                            break;
5103
                        case 4: /* VSRI */
5104
                        case 5: /* VSHL, VSLI */
5105
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5106
                            break;
5107
                        case 6: /* VQSHLU */
5108
                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5109
                                                      cpu_V0, cpu_V1);
5110
                            break;
5111
                        case 7: /* VQSHL */
5112
                            if (u) {
5113
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5114
                                                         cpu_V0, cpu_V1);
5115
                            } else {
5116
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5117
                                                         cpu_V0, cpu_V1);
5118
                            }
5119
                            break;
5120
                        }
5121
                        if (op == 1 || op == 3) {
5122
                            /* Accumulate.  */
5123
                            neon_load_reg64(cpu_V1, rd + pass);
5124
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5125
                        } else if (op == 4 || (op == 5 && u)) {
5126
                            /* Insert */
5127
                            neon_load_reg64(cpu_V1, rd + pass);
5128
                            uint64_t mask;
5129
                            if (shift < -63 || shift > 63) {
5130
                                mask = 0;
5131
                            } else {
5132
                                if (op == 4) {
5133
                                    mask = 0xffffffffffffffffull >> -shift;
5134
                                } else {
5135
                                    mask = 0xffffffffffffffffull << shift;
5136
                                }
5137
                            }
5138
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5139
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5140
                        }
5141
                        neon_store_reg64(cpu_V0, rd + pass);
5142
                    } else { /* size < 3 */
5143
                        /* Operands in T0 and T1.  */
5144
                        tmp = neon_load_reg(rm, pass);
5145
                        tmp2 = tcg_temp_new_i32();
5146
                        tcg_gen_movi_i32(tmp2, imm);
5147
                        switch (op) {
5148
                        case 0:  /* VSHR */
5149
                        case 1:  /* VSRA */
5150
                            GEN_NEON_INTEGER_OP(shl);
5151
                            break;
5152
                        case 2: /* VRSHR */
5153
                        case 3: /* VRSRA */
5154
                            GEN_NEON_INTEGER_OP(rshl);
5155
                            break;
5156
                        case 4: /* VSRI */
5157
                        case 5: /* VSHL, VSLI */
5158
                            switch (size) {
5159
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5160
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5161
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5162
                            default: abort();
5163
                            }
5164
                            break;
5165
                        case 6: /* VQSHLU */
5166
                            switch (size) {
5167
                            case 0:
5168
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
5169
                                                         tmp, tmp2);
5170
                                break;
5171
                            case 1:
5172
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
5173
                                                          tmp, tmp2);
5174
                                break;
5175
                            case 2:
5176
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
5177
                                                          tmp, tmp2);
5178
                                break;
5179
                            default:
5180
                                abort();
5181
                            }
5182
                            break;
5183
                        case 7: /* VQSHL */
5184
                            GEN_NEON_INTEGER_OP_ENV(qshl);
5185
                            break;
5186
                        }
5187
                        tcg_temp_free_i32(tmp2);
5188

    
5189
                        if (op == 1 || op == 3) {
5190
                            /* Accumulate.  */
5191
                            tmp2 = neon_load_reg(rd, pass);
5192
                            gen_neon_add(size, tmp, tmp2);
5193
                            tcg_temp_free_i32(tmp2);
5194
                        } else if (op == 4 || (op == 5 && u)) {
5195
                            /* Insert */
5196
                            switch (size) {
5197
                            case 0:
5198
                                if (op == 4)
5199
                                    mask = 0xff >> -shift;
5200
                                else
5201
                                    mask = (uint8_t)(0xff << shift);
5202
                                mask |= mask << 8;
5203
                                mask |= mask << 16;
5204
                                break;
5205
                            case 1:
5206
                                if (op == 4)
5207
                                    mask = 0xffff >> -shift;
5208
                                else
5209
                                    mask = (uint16_t)(0xffff << shift);
5210
                                mask |= mask << 16;
5211
                                break;
5212
                            case 2:
5213
                                if (shift < -31 || shift > 31) {
5214
                                    mask = 0;
5215
                                } else {
5216
                                    if (op == 4)
5217
                                        mask = 0xffffffffu >> -shift;
5218
                                    else
5219
                                        mask = 0xffffffffu << shift;
5220
                                }
5221
                                break;
5222
                            default:
5223
                                abort();
5224
                            }
5225
                            tmp2 = neon_load_reg(rd, pass);
5226
                            tcg_gen_andi_i32(tmp, tmp, mask);
5227
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5228
                            tcg_gen_or_i32(tmp, tmp, tmp2);
5229
                            tcg_temp_free_i32(tmp2);
5230
                        }
5231
                        neon_store_reg(rd, pass, tmp);
5232
                    }
5233
                } /* for pass */
5234
            } else if (op < 10) {
5235
                /* Shift by immediate and narrow:
5236
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
5237
                int input_unsigned = (op == 8) ? !u : u;
5238
                if (rm & 1) {
5239
                    return 1;
5240
                }
5241
                shift = shift - (1 << (size + 3));
5242
                size++;
5243
                if (size == 3) {
5244
                    tmp64 = tcg_const_i64(shift);
5245
                    neon_load_reg64(cpu_V0, rm);
5246
                    neon_load_reg64(cpu_V1, rm + 1);
5247
                    for (pass = 0; pass < 2; pass++) {
5248
                        TCGv_i64 in;
5249
                        if (pass == 0) {
5250
                            in = cpu_V0;
5251
                        } else {
5252
                            in = cpu_V1;
5253
                        }
5254
                        if (q) {
5255
                            if (input_unsigned) {
5256
                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5257
                            } else {
5258
                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5259
                            }
5260
                        } else {
5261
                            if (input_unsigned) {
5262
                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5263
                            } else {
5264
                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5265
                            }
5266
                        }
5267
                        tmp = tcg_temp_new_i32();
5268
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5269
                        neon_store_reg(rd, pass, tmp);
5270
                    } /* for pass */
5271
                    tcg_temp_free_i64(tmp64);
5272
                } else {
5273
                    if (size == 1) {
5274
                        imm = (uint16_t)shift;
5275
                        imm |= imm << 16;
5276
                    } else {
5277
                        /* size == 2 */
5278
                        imm = (uint32_t)shift;
5279
                    }
5280
                    tmp2 = tcg_const_i32(imm);
5281
                    tmp4 = neon_load_reg(rm + 1, 0);
5282
                    tmp5 = neon_load_reg(rm + 1, 1);
5283
                    for (pass = 0; pass < 2; pass++) {
5284
                        if (pass == 0) {
5285
                            tmp = neon_load_reg(rm, 0);
5286
                        } else {
5287
                            tmp = tmp4;
5288
                        }
5289
                        gen_neon_shift_narrow(size, tmp, tmp2, q,
5290
                                              input_unsigned);
5291
                        if (pass == 0) {
5292
                            tmp3 = neon_load_reg(rm, 1);
5293
                        } else {
5294
                            tmp3 = tmp5;
5295
                        }
5296
                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
5297
                                              input_unsigned);
5298
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5299
                        tcg_temp_free_i32(tmp);
5300
                        tcg_temp_free_i32(tmp3);
5301
                        tmp = tcg_temp_new_i32();
5302
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5303
                        neon_store_reg(rd, pass, tmp);
5304
                    } /* for pass */
5305
                    tcg_temp_free_i32(tmp2);
5306
                }
5307
            } else if (op == 10) {
5308
                /* VSHLL, VMOVL */
5309
                if (q || (rd & 1)) {
5310
                    return 1;
5311
                }
5312
                tmp = neon_load_reg(rm, 0);
5313
                tmp2 = neon_load_reg(rm, 1);
5314
                for (pass = 0; pass < 2; pass++) {
5315
                    if (pass == 1)
5316
                        tmp = tmp2;
5317

    
5318
                    gen_neon_widen(cpu_V0, tmp, size, u);
5319

    
5320
                    if (shift != 0) {
5321
                        /* The shift is less than the width of the source
5322
                           type, so we can just shift the whole register.  */
5323
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5324
                        /* Widen the result of shift: we need to clear
5325
                         * the potential overflow bits resulting from
5326
                         * left bits of the narrow input appearing as
5327
                         * right bits of left the neighbour narrow
5328
                         * input.  */
5329
                        if (size < 2 || !u) {
5330
                            uint64_t imm64;
5331
                            if (size == 0) {
5332
                                imm = (0xffu >> (8 - shift));
5333
                                imm |= imm << 16;
5334
                            } else if (size == 1) {
5335
                                imm = 0xffff >> (16 - shift);
5336
                            } else {
5337
                                /* size == 2 */
5338
                                imm = 0xffffffff >> (32 - shift);
5339
                            }
5340
                            if (size < 2) {
5341
                                imm64 = imm | (((uint64_t)imm) << 32);
5342
                            } else {
5343
                                imm64 = imm;
5344
                            }
5345
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5346
                        }
5347
                    }
5348
                    neon_store_reg64(cpu_V0, rd + pass);
5349
                }
5350
            } else if (op >= 14) {
5351
                /* VCVT fixed-point.  */
5352
                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5353
                    return 1;
5354
                }
5355
                /* We have already masked out the must-be-1 top bit of imm6,
5356
                 * hence this 32-shift where the ARM ARM has 64-imm6.
5357
                 */
5358
                shift = 32 - shift;
5359
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5360
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5361
                    if (!(op & 1)) {
5362
                        if (u)
5363
                            gen_vfp_ulto(0, shift, 1);
5364
                        else
5365
                            gen_vfp_slto(0, shift, 1);
5366
                    } else {
5367
                        if (u)
5368
                            gen_vfp_toul(0, shift, 1);
5369
                        else
5370
                            gen_vfp_tosl(0, shift, 1);
5371
                    }
5372
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5373
                }
5374
            } else {
5375
                return 1;
5376
            }
5377
        } else { /* (insn & 0x00380080) == 0 */
5378
            int invert;
5379
            if (q && (rd & 1)) {
5380
                return 1;
5381
            }
5382

    
5383
            op = (insn >> 8) & 0xf;
5384
            /* One register and immediate.  */
5385
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5386
            invert = (insn & (1 << 5)) != 0;
5387
            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5388
             * We choose to not special-case this and will behave as if a
5389
             * valid constant encoding of 0 had been given.
5390
             */
5391
            switch (op) {
5392
            case 0: case 1:
5393
                /* no-op */
5394
                break;
5395
            case 2: case 3:
5396
                imm <<= 8;
5397
                break;
5398
            case 4: case 5:
5399
                imm <<= 16;
5400
                break;
5401
            case 6: case 7:
5402
                imm <<= 24;
5403
                break;
5404
            case 8: case 9:
5405
                imm |= imm << 16;
5406
                break;
5407
            case 10: case 11:
5408
                imm = (imm << 8) | (imm << 24);
5409
                break;
5410
            case 12:
5411
                imm = (imm << 8) | 0xff;
5412
                break;
5413
            case 13:
5414
                imm = (imm << 16) | 0xffff;
5415
                break;
5416
            case 14:
5417
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
5418
                if (invert)
5419
                    imm = ~imm;
5420
                break;
5421
            case 15:
5422
                if (invert) {
5423
                    return 1;
5424
                }
5425
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5426
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5427
                break;
5428
            }
5429
            if (invert)
5430
                imm = ~imm;
5431

    
5432
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5433
                if (op & 1 && op < 12) {
5434
                    tmp = neon_load_reg(rd, pass);
5435
                    if (invert) {
5436
                        /* The immediate value has already been inverted, so
5437
                           BIC becomes AND.  */
5438
                        tcg_gen_andi_i32(tmp, tmp, imm);
5439
                    } else {
5440
                        tcg_gen_ori_i32(tmp, tmp, imm);
5441
                    }
5442
                } else {
5443
                    /* VMOV, VMVN.  */
5444
                    tmp = tcg_temp_new_i32();
5445
                    if (op == 14 && invert) {
5446
                        int n;
5447
                        uint32_t val;
5448
                        val = 0;
5449
                        for (n = 0; n < 4; n++) {
5450
                            if (imm & (1 << (n + (pass & 1) * 4)))
5451
                                val |= 0xff << (n * 8);
5452
                        }
5453
                        tcg_gen_movi_i32(tmp, val);
5454
                    } else {
5455
                        tcg_gen_movi_i32(tmp, imm);
5456
                    }
5457
                }
5458
                neon_store_reg(rd, pass, tmp);
5459
            }
5460
        }
5461
    } else { /* (insn & 0x00800010 == 0x00800000) */
5462
        if (size != 3) {
5463
            op = (insn >> 8) & 0xf;
5464
            if ((insn & (1 << 6)) == 0) {
5465
                /* Three registers of different lengths.  */
5466
                int src1_wide;
5467
                int src2_wide;
5468
                int prewiden;
5469
                /* undefreq: bit 0 : UNDEF if size != 0
5470
                 *           bit 1 : UNDEF if size == 0
5471
                 *           bit 2 : UNDEF if U == 1
5472
                 * Note that [1:0] set implies 'always UNDEF'
5473
                 */
5474
                int undefreq;
5475
                /* prewiden, src1_wide, src2_wide, undefreq */
5476
                static const int neon_3reg_wide[16][4] = {
5477
                    {1, 0, 0, 0}, /* VADDL */
5478
                    {1, 1, 0, 0}, /* VADDW */
5479
                    {1, 0, 0, 0}, /* VSUBL */
5480
                    {1, 1, 0, 0}, /* VSUBW */
5481
                    {0, 1, 1, 0}, /* VADDHN */
5482
                    {0, 0, 0, 0}, /* VABAL */
5483
                    {0, 1, 1, 0}, /* VSUBHN */
5484
                    {0, 0, 0, 0}, /* VABDL */
5485
                    {0, 0, 0, 0}, /* VMLAL */
5486
                    {0, 0, 0, 6}, /* VQDMLAL */
5487
                    {0, 0, 0, 0}, /* VMLSL */
5488
                    {0, 0, 0, 6}, /* VQDMLSL */
5489
                    {0, 0, 0, 0}, /* Integer VMULL */
5490
                    {0, 0, 0, 2}, /* VQDMULL */
5491
                    {0, 0, 0, 5}, /* Polynomial VMULL */
5492
                    {0, 0, 0, 3}, /* Reserved: always UNDEF */
5493
                };
5494

    
5495
                prewiden = neon_3reg_wide[op][0];
5496
                src1_wide = neon_3reg_wide[op][1];
5497
                src2_wide = neon_3reg_wide[op][2];
5498
                undefreq = neon_3reg_wide[op][3];
5499

    
5500
                if (((undefreq & 1) && (size != 0)) ||
5501
                    ((undefreq & 2) && (size == 0)) ||
5502
                    ((undefreq & 4) && u)) {
5503
                    return 1;
5504
                }
5505
                if ((src1_wide && (rn & 1)) ||
5506
                    (src2_wide && (rm & 1)) ||
5507
                    (!src2_wide && (rd & 1))) {
5508
                    return 1;
5509
                }
5510

    
5511
                /* Avoid overlapping operands.  Wide source operands are
5512
                   always aligned so will never overlap with wide
5513
                   destinations in problematic ways.  */
5514
                if (rd == rm && !src2_wide) {
5515
                    tmp = neon_load_reg(rm, 1);
5516
                    neon_store_scratch(2, tmp);
5517
                } else if (rd == rn && !src1_wide) {
5518
                    tmp = neon_load_reg(rn, 1);
5519
                    neon_store_scratch(2, tmp);
5520
                }
5521
                TCGV_UNUSED(tmp3);
5522
                for (pass = 0; pass < 2; pass++) {
5523
                    if (src1_wide) {
5524
                        neon_load_reg64(cpu_V0, rn + pass);
5525
                        TCGV_UNUSED(tmp);
5526
                    } else {
5527
                        if (pass == 1 && rd == rn) {
5528
                            tmp = neon_load_scratch(2);
5529
                        } else {
5530
                            tmp = neon_load_reg(rn, pass);
5531
                        }
5532
                        if (prewiden) {
5533
                            gen_neon_widen(cpu_V0, tmp, size, u);
5534
                        }
5535
                    }
5536
                    if (src2_wide) {
5537
                        neon_load_reg64(cpu_V1, rm + pass);
5538
                        TCGV_UNUSED(tmp2);
5539
                    } else {
5540
                        if (pass == 1 && rd == rm) {
5541
                            tmp2 = neon_load_scratch(2);
5542
                        } else {
5543
                            tmp2 = neon_load_reg(rm, pass);
5544
                        }
5545
                        if (prewiden) {
5546
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5547
                        }
5548
                    }
5549
                    switch (op) {
5550
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5551
                        gen_neon_addl(size);
5552
                        break;
5553
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5554
                        gen_neon_subl(size);
5555
                        break;
5556
                    case 5: case 7: /* VABAL, VABDL */
5557
                        switch ((size << 1) | u) {
5558
                        case 0:
5559
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5560
                            break;
5561
                        case 1:
5562
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5563
                            break;
5564
                        case 2:
5565
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5566
                            break;
5567
                        case 3:
5568
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5569
                            break;
5570
                        case 4:
5571
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5572
                            break;
5573
                        case 5:
5574
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5575
                            break;
5576
                        default: abort();
5577
                        }
5578
                        tcg_temp_free_i32(tmp2);
5579
                        tcg_temp_free_i32(tmp);
5580
                        break;
5581
                    case 8: case 9: case 10: case 11: case 12: case 13:
5582
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5583
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5584
                        break;
5585
                    case 14: /* Polynomial VMULL */
5586
                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5587
                        tcg_temp_free_i32(tmp2);
5588
                        tcg_temp_free_i32(tmp);
5589
                        break;
5590
                    default: /* 15 is RESERVED: caught earlier  */
5591
                        abort();
5592
                    }
5593
                    if (op == 13) {
5594
                        /* VQDMULL */
5595
                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5596
                        neon_store_reg64(cpu_V0, rd + pass);
5597
                    } else if (op == 5 || (op >= 8 && op <= 11)) {
5598
                        /* Accumulate.  */
5599
                        neon_load_reg64(cpu_V1, rd + pass);
5600
                        switch (op) {
5601
                        case 10: /* VMLSL */
5602
                            gen_neon_negl(cpu_V0, size);
5603
                            /* Fall through */
5604
                        case 5: case 8: /* VABAL, VMLAL */
5605
                            gen_neon_addl(size);
5606
                            break;
5607
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5608
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5609
                            if (op == 11) {
5610
                                gen_neon_negl(cpu_V0, size);
5611
                            }
5612
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5613
                            break;
5614
                        default:
5615
                            abort();
5616
                        }
5617
                        neon_store_reg64(cpu_V0, rd + pass);
5618
                    } else if (op == 4 || op == 6) {
5619
                        /* Narrowing operation.  */
5620
                        tmp = tcg_temp_new_i32();
5621
                        if (!u) {
5622
                            switch (size) {
5623
                            case 0:
5624
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5625
                                break;
5626
                            case 1:
5627
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5628
                                break;
5629
                            case 2:
5630
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5631
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5632
                                break;
5633
                            default: abort();
5634
                            }
5635
                        } else {
5636
                            switch (size) {
5637
                            case 0:
5638
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5639
                                break;
5640
                            case 1:
5641
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5642
                                break;
5643
                            case 2:
5644
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5645
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5646
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5647
                                break;
5648
                            default: abort();
5649
                            }
5650
                        }
5651
                        if (pass == 0) {
5652
                            tmp3 = tmp;
5653
                        } else {
5654
                            neon_store_reg(rd, 0, tmp3);
5655
                            neon_store_reg(rd, 1, tmp);
5656
                        }
5657
                    } else {
5658
                        /* Write back the result.  */
5659
                        neon_store_reg64(cpu_V0, rd + pass);
5660
                    }
5661
                }
5662
            } else {
5663
                /* Two registers and a scalar. NB that for ops of this form
5664
                 * the ARM ARM labels bit 24 as Q, but it is in our variable
5665
                 * 'u', not 'q'.
5666
                 */
5667
                if (size == 0) {
5668
                    return 1;
5669
                }
5670
                switch (op) {
5671
                case 1: /* Float VMLA scalar */
5672
                case 5: /* Floating point VMLS scalar */
5673
                case 9: /* Floating point VMUL scalar */
5674
                    if (size == 1) {
5675
                        return 1;
5676
                    }
5677
                    /* fall through */
5678
                case 0: /* Integer VMLA scalar */
5679
                case 4: /* Integer VMLS scalar */
5680
                case 8: /* Integer VMUL scalar */
5681
                case 12: /* VQDMULH scalar */
5682
                case 13: /* VQRDMULH scalar */
5683
                    if (u && ((rd | rn) & 1)) {
5684
                        return 1;
5685
                    }
5686
                    tmp = neon_get_scalar(size, rm);
5687
                    neon_store_scratch(0, tmp);
5688
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5689
                        tmp = neon_load_scratch(0);
5690
                        tmp2 = neon_load_reg(rn, pass);
5691
                        if (op == 12) {
5692
                            if (size == 1) {
5693
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5694
                            } else {
5695
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5696
                            }
5697
                        } else if (op == 13) {
5698
                            if (size == 1) {
5699
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5700
                            } else {
5701
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5702
                            }
5703
                        } else if (op & 1) {
5704
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5705
                            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5706
                            tcg_temp_free_ptr(fpstatus);
5707
                        } else {
5708
                            switch (size) {
5709
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5710
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5711
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5712
                            default: abort();
5713
                            }
5714
                        }
5715
                        tcg_temp_free_i32(tmp2);
5716
                        if (op < 8) {
5717
                            /* Accumulate.  */
5718
                            tmp2 = neon_load_reg(rd, pass);
5719
                            switch (op) {
5720
                            case 0:
5721
                                gen_neon_add(size, tmp, tmp2);
5722
                                break;
5723
                            case 1:
5724
                            {
5725
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5726
                                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5727
                                tcg_temp_free_ptr(fpstatus);
5728
                                break;
5729
                            }
5730
                            case 4:
5731
                                gen_neon_rsb(size, tmp, tmp2);
5732
                                break;
5733
                            case 5:
5734
                            {
5735
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5736
                                gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5737
                                tcg_temp_free_ptr(fpstatus);
5738
                                break;
5739
                            }
5740
                            default:
5741
                                abort();
5742
                            }
5743
                            tcg_temp_free_i32(tmp2);
5744
                        }
5745
                        neon_store_reg(rd, pass, tmp);
5746
                    }
5747
                    break;
5748
                case 3: /* VQDMLAL scalar */
5749
                case 7: /* VQDMLSL scalar */
5750
                case 11: /* VQDMULL scalar */
5751
                    if (u == 1) {
5752
                        return 1;
5753
                    }
5754
                    /* fall through */
5755
                case 2: /* VMLAL sclar */
5756
                case 6: /* VMLSL scalar */
5757
                case 10: /* VMULL scalar */
5758
                    if (rd & 1) {
5759
                        return 1;
5760
                    }
5761
                    tmp2 = neon_get_scalar(size, rm);
5762
                    /* We need a copy of tmp2 because gen_neon_mull
5763
                     * deletes it during pass 0.  */
5764
                    tmp4 = tcg_temp_new_i32();
5765
                    tcg_gen_mov_i32(tmp4, tmp2);
5766
                    tmp3 = neon_load_reg(rn, 1);
5767

    
5768
                    for (pass = 0; pass < 2; pass++) {
5769
                        if (pass == 0) {
5770
                            tmp = neon_load_reg(rn, 0);
5771
                        } else {
5772
                            tmp = tmp3;
5773
                            tmp2 = tmp4;
5774
                        }
5775
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5776
                        if (op != 11) {
5777
                            neon_load_reg64(cpu_V1, rd + pass);
5778
                        }
5779
                        switch (op) {
5780
                        case 6:
5781
                            gen_neon_negl(cpu_V0, size);
5782
                            /* Fall through */
5783
                        case 2:
5784
                            gen_neon_addl(size);
5785
                            break;
5786
                        case 3: case 7:
5787
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5788
                            if (op == 7) {
5789
                                gen_neon_negl(cpu_V0, size);
5790
                            }
5791
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5792
                            break;
5793
                        case 10:
5794
                            /* no-op */
5795
                            break;
5796
                        case 11:
5797
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5798
                            break;
5799
                        default:
5800
                            abort();
5801
                        }
5802
                        neon_store_reg64(cpu_V0, rd + pass);
5803
                    }
5804

    
5805

    
5806
                    break;
5807
                default: /* 14 and 15 are RESERVED */
5808
                    return 1;
5809
                }
5810
            }
5811
        } else { /* size == 3 */
5812
            if (!u) {
5813
                /* Extract.  */
5814
                imm = (insn >> 8) & 0xf;
5815

    
5816
                if (imm > 7 && !q)
5817
                    return 1;
5818

    
5819
                if (q && ((rd | rn | rm) & 1)) {
5820
                    return 1;
5821
                }
5822

    
5823
                if (imm == 0) {
5824
                    neon_load_reg64(cpu_V0, rn);
5825
                    if (q) {
5826
                        neon_load_reg64(cpu_V1, rn + 1);
5827
                    }
5828
                } else if (imm == 8) {
5829
                    neon_load_reg64(cpu_V0, rn + 1);
5830
                    if (q) {
5831
                        neon_load_reg64(cpu_V1, rm);
5832
                    }
5833
                } else if (q) {
5834
                    tmp64 = tcg_temp_new_i64();
5835
                    if (imm < 8) {
5836
                        neon_load_reg64(cpu_V0, rn);
5837
                        neon_load_reg64(tmp64, rn + 1);
5838
                    } else {
5839
                        neon_load_reg64(cpu_V0, rn + 1);
5840
                        neon_load_reg64(tmp64, rm);
5841
                    }
5842
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5843
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5844
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5845
                    if (imm < 8) {
5846
                        neon_load_reg64(cpu_V1, rm);
5847
                    } else {
5848
                        neon_load_reg64(cpu_V1, rm + 1);
5849
                        imm -= 8;
5850
                    }
5851
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5852
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5853
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5854
                    tcg_temp_free_i64(tmp64);
5855
                } else {
5856
                    /* BUGFIX */
5857
                    neon_load_reg64(cpu_V0, rn);
5858
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5859
                    neon_load_reg64(cpu_V1, rm);
5860
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5861
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5862
                }
5863
                neon_store_reg64(cpu_V0, rd);
5864
                if (q) {
5865
                    neon_store_reg64(cpu_V1, rd + 1);
5866
                }
5867
            } else if ((insn & (1 << 11)) == 0) {
5868
                /* Two register misc.  */
5869
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5870
                size = (insn >> 18) & 3;
5871
                /* UNDEF for unknown op values and bad op-size combinations */
5872
                if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5873
                    return 1;
5874
                }
5875
                if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5876
                    q && ((rm | rd) & 1)) {
5877
                    return 1;
5878
                }
5879
                switch (op) {
5880
                case NEON_2RM_VREV64:
5881
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
5882
                        tmp = neon_load_reg(rm, pass * 2);
5883
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
5884
                        switch (size) {
5885
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5886
                        case 1: gen_swap_half(tmp); break;
5887
                        case 2: /* no-op */ break;
5888
                        default: abort();
5889
                        }
5890
                        neon_store_reg(rd, pass * 2 + 1, tmp);
5891
                        if (size == 2) {
5892
                            neon_store_reg(rd, pass * 2, tmp2);
5893
                        } else {
5894
                            switch (size) {
5895
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5896
                            case 1: gen_swap_half(tmp2); break;
5897
                            default: abort();
5898
                            }
5899
                            neon_store_reg(rd, pass * 2, tmp2);
5900
                        }
5901
                    }
5902
                    break;
5903
                case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5904
                case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5905
                    for (pass = 0; pass < q + 1; pass++) {
5906
                        tmp = neon_load_reg(rm, pass * 2);
5907
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
5908
                        tmp = neon_load_reg(rm, pass * 2 + 1);
5909
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
5910
                        switch (size) {
5911
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5912
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5913
                        case 2: tcg_gen_add_i64(CPU_V001); break;
5914
                        default: abort();
5915
                        }
5916
                        if (op >= NEON_2RM_VPADAL) {
5917
                            /* Accumulate.  */
5918
                            neon_load_reg64(cpu_V1, rd + pass);
5919
                            gen_neon_addl(size);
5920
                        }
5921
                        neon_store_reg64(cpu_V0, rd + pass);
5922
                    }
5923
                    break;
5924
                case NEON_2RM_VTRN:
5925
                    if (size == 2) {
5926
                        int n;
5927
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
5928
                            tmp = neon_load_reg(rm, n);
5929
                            tmp2 = neon_load_reg(rd, n + 1);
5930
                            neon_store_reg(rm, n, tmp2);
5931
                            neon_store_reg(rd, n + 1, tmp);
5932
                        }
5933
                    } else {
5934
                        goto elementwise;
5935
                    }
5936
                    break;
5937
                case NEON_2RM_VUZP:
5938
                    if (gen_neon_unzip(rd, rm, size, q)) {
5939
                        return 1;
5940
                    }
5941
                    break;
5942
                case NEON_2RM_VZIP:
5943
                    if (gen_neon_zip(rd, rm, size, q)) {
5944
                        return 1;
5945
                    }
5946
                    break;
5947
                case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5948
                    /* also VQMOVUN; op field and mnemonics don't line up */
5949
                    if (rm & 1) {
5950
                        return 1;
5951
                    }
5952
                    TCGV_UNUSED(tmp2);
5953
                    for (pass = 0; pass < 2; pass++) {
5954
                        neon_load_reg64(cpu_V0, rm + pass);
5955
                        tmp = tcg_temp_new_i32();
5956
                        gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5957
                                           tmp, cpu_V0);
5958
                        if (pass == 0) {
5959
                            tmp2 = tmp;
5960
                        } else {
5961
                            neon_store_reg(rd, 0, tmp2);
5962
                            neon_store_reg(rd, 1, tmp);
5963
                        }
5964
                    }
5965
                    break;
5966
                case NEON_2RM_VSHLL:
5967
                    if (q || (rd & 1)) {
5968
                        return 1;
5969
                    }
5970
                    tmp = neon_load_reg(rm, 0);
5971
                    tmp2 = neon_load_reg(rm, 1);
5972
                    for (pass = 0; pass < 2; pass++) {
5973
                        if (pass == 1)
5974
                            tmp = tmp2;
5975
                        gen_neon_widen(cpu_V0, tmp, size, 1);
5976
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5977
                        neon_store_reg64(cpu_V0, rd + pass);
5978
                    }
5979
                    break;
5980
                case NEON_2RM_VCVT_F16_F32:
5981
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5982
                        q || (rm & 1)) {
5983
                        return 1;
5984
                    }
5985
                    tmp = tcg_temp_new_i32();
5986
                    tmp2 = tcg_temp_new_i32();
5987
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5988
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5989
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5990
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5991
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5992
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5993
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5994
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5995
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5996
                    neon_store_reg(rd, 0, tmp2);
5997
                    tmp2 = tcg_temp_new_i32();
5998
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5999
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
6000
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
6001
                    neon_store_reg(rd, 1, tmp2);
6002
                    tcg_temp_free_i32(tmp);
6003
                    break;
6004
                case NEON_2RM_VCVT_F32_F16:
6005
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6006
                        q || (rd & 1)) {
6007
                        return 1;
6008
                    }
6009
                    tmp3 = tcg_temp_new_i32();
6010
                    tmp = neon_load_reg(rm, 0);
6011
                    tmp2 = neon_load_reg(rm, 1);
6012
                    tcg_gen_ext16u_i32(tmp3, tmp);
6013
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6014
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6015
                    tcg_gen_shri_i32(tmp3, tmp, 16);
6016
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6017
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6018
                    tcg_temp_free_i32(tmp);
6019
                    tcg_gen_ext16u_i32(tmp3, tmp2);
6020
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6021
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6022
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
6023
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6024
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6025
                    tcg_temp_free_i32(tmp2);
6026
                    tcg_temp_free_i32(tmp3);
6027
                    break;
6028
                default:
6029
                elementwise:
6030
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
6031
                        if (neon_2rm_is_float_op(op)) {
6032
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
6033
                                           neon_reg_offset(rm, pass));
6034
                            TCGV_UNUSED(tmp);
6035
                        } else {
6036
                            tmp = neon_load_reg(rm, pass);
6037
                        }
6038
                        switch (op) {
6039
                        case NEON_2RM_VREV32:
6040
                            switch (size) {
6041
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6042
                            case 1: gen_swap_half(tmp); break;
6043
                            default: abort();
6044
                            }
6045
                            break;
6046
                        case NEON_2RM_VREV16:
6047
                            gen_rev16(tmp);
6048
                            break;
6049
                        case NEON_2RM_VCLS:
6050
                            switch (size) {
6051
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6052
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6053
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6054
                            default: abort();
6055
                            }
6056
                            break;
6057
                        case NEON_2RM_VCLZ:
6058
                            switch (size) {
6059
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6060
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6061
                            case 2: gen_helper_clz(tmp, tmp); break;
6062
                            default: abort();
6063
                            }
6064
                            break;
6065
                        case NEON_2RM_VCNT:
6066
                            gen_helper_neon_cnt_u8(tmp, tmp);
6067
                            break;
6068
                        case NEON_2RM_VMVN:
6069
                            tcg_gen_not_i32(tmp, tmp);
6070
                            break;
6071
                        case NEON_2RM_VQABS:
6072
                            switch (size) {
6073
                            case 0:
6074
                                gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6075
                                break;
6076
                            case 1:
6077
                                gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6078
                                break;
6079
                            case 2:
6080
                                gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6081
                                break;
6082
                            default: abort();
6083
                            }
6084
                            break;
6085
                        case NEON_2RM_VQNEG:
6086
                            switch (size) {
6087
                            case 0:
6088
                                gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6089
                                break;
6090
                            case 1:
6091
                                gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6092
                                break;
6093
                            case 2:
6094
                                gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6095
                                break;
6096
                            default: abort();
6097
                            }
6098
                            break;
6099
                        case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6100
                            tmp2 = tcg_const_i32(0);
6101
                            switch(size) {
6102
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6103
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6104
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6105
                            default: abort();
6106
                            }
6107
                            tcg_temp_free(tmp2);
6108
                            if (op == NEON_2RM_VCLE0) {
6109
                                tcg_gen_not_i32(tmp, tmp);
6110
                            }
6111
                            break;
6112
                        case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6113
                            tmp2 = tcg_const_i32(0);
6114
                            switch(size) {
6115
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6116
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6117
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6118
                            default: abort();
6119
                            }
6120
                            tcg_temp_free(tmp2);
6121
                            if (op == NEON_2RM_VCLT0) {
6122
                                tcg_gen_not_i32(tmp, tmp);
6123
                            }
6124
                            break;
6125
                        case NEON_2RM_VCEQ0:
6126
                            tmp2 = tcg_const_i32(0);
6127
                            switch(size) {
6128
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6129
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6130
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6131
                            default: abort();
6132
                            }
6133
                            tcg_temp_free(tmp2);
6134
                            break;
6135
                        case NEON_2RM_VABS:
6136
                            switch(size) {
6137
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6138
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6139
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
6140
                            default: abort();
6141
                            }
6142
                            break;
6143
                        case NEON_2RM_VNEG:
6144
                            tmp2 = tcg_const_i32(0);
6145
                            gen_neon_rsb(size, tmp, tmp2);
6146
                            tcg_temp_free(tmp2);
6147
                            break;
6148
                        case NEON_2RM_VCGT0_F:
6149
                        {
6150
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6151
                            tmp2 = tcg_const_i32(0);
6152
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6153
                            tcg_temp_free(tmp2);
6154
                            tcg_temp_free_ptr(fpstatus);
6155
                            break;
6156
                        }
6157
                        case NEON_2RM_VCGE0_F:
6158
                        {
6159
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6160
                            tmp2 = tcg_const_i32(0);
6161
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6162
                            tcg_temp_free(tmp2);
6163
                            tcg_temp_free_ptr(fpstatus);
6164
                            break;
6165
                        }
6166
                        case NEON_2RM_VCEQ0_F:
6167
                        {
6168
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6169
                            tmp2 = tcg_const_i32(0);
6170
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6171
                            tcg_temp_free(tmp2);
6172
                            tcg_temp_free_ptr(fpstatus);
6173
                            break;
6174
                        }
6175
                        case NEON_2RM_VCLE0_F:
6176
                        {
6177
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6178
                            tmp2 = tcg_const_i32(0);
6179
                            gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6180
                            tcg_temp_free(tmp2);
6181
                            tcg_temp_free_ptr(fpstatus);
6182
                            break;
6183
                        }
6184
                        case NEON_2RM_VCLT0_F:
6185
                        {
6186
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6187
                            tmp2 = tcg_const_i32(0);
6188
                            gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6189
                            tcg_temp_free(tmp2);
6190
                            tcg_temp_free_ptr(fpstatus);
6191
                            break;
6192
                        }
6193
                        case NEON_2RM_VABS_F:
6194
                            gen_vfp_abs(0);
6195
                            break;
6196
                        case NEON_2RM_VNEG_F:
6197
                            gen_vfp_neg(0);
6198
                            break;
6199
                        case NEON_2RM_VSWP:
6200
                            tmp2 = neon_load_reg(rd, pass);
6201
                            neon_store_reg(rm, pass, tmp2);
6202
                            break;
6203
                        case NEON_2RM_VTRN:
6204
                            tmp2 = neon_load_reg(rd, pass);
6205
                            switch (size) {
6206
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
6207
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
6208
                            default: abort();
6209
                            }
6210
                            neon_store_reg(rm, pass, tmp2);
6211
                            break;
6212
                        case NEON_2RM_VRECPE:
6213
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
6214
                            break;
6215
                        case NEON_2RM_VRSQRTE:
6216
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6217
                            break;
6218
                        case NEON_2RM_VRECPE_F:
6219
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6220
                            break;
6221
                        case NEON_2RM_VRSQRTE_F:
6222
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6223
                            break;
6224
                        case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6225
                            gen_vfp_sito(0, 1);
6226
                            break;
6227
                        case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6228
                            gen_vfp_uito(0, 1);
6229
                            break;
6230
                        case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6231
                            gen_vfp_tosiz(0, 1);
6232
                            break;
6233
                        case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6234
                            gen_vfp_touiz(0, 1);
6235
                            break;
6236
                        default:
6237
                            /* Reserved op values were caught by the
6238
                             * neon_2rm_sizes[] check earlier.
6239
                             */
6240
                            abort();
6241
                        }
6242
                        if (neon_2rm_is_float_op(op)) {
6243
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
6244
                                           neon_reg_offset(rd, pass));
6245
                        } else {
6246
                            neon_store_reg(rd, pass, tmp);
6247
                        }
6248
                    }
6249
                    break;
6250
                }
6251
            } else if ((insn & (1 << 10)) == 0) {
6252
                /* VTBL, VTBX.  */
6253
                int n = ((insn >> 8) & 3) + 1;
6254
                if ((rn + n) > 32) {
6255
                    /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6256
                     * helper function running off the end of the register file.
6257
                     */
6258
                    return 1;
6259
                }
6260
                n <<= 3;
6261
                if (insn & (1 << 6)) {
6262
                    tmp = neon_load_reg(rd, 0);
6263
                } else {
6264
                    tmp = tcg_temp_new_i32();
6265
                    tcg_gen_movi_i32(tmp, 0);
6266
                }
6267
                tmp2 = neon_load_reg(rm, 0);
6268
                tmp4 = tcg_const_i32(rn);
6269
                tmp5 = tcg_const_i32(n);
6270
                gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
6271
                tcg_temp_free_i32(tmp);
6272
                if (insn & (1 << 6)) {
6273
                    tmp = neon_load_reg(rd, 1);
6274
                } else {
6275
                    tmp = tcg_temp_new_i32();
6276
                    tcg_gen_movi_i32(tmp, 0);
6277
                }
6278
                tmp3 = neon_load_reg(rm, 1);
6279
                gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
6280
                tcg_temp_free_i32(tmp5);
6281
                tcg_temp_free_i32(tmp4);
6282
                neon_store_reg(rd, 0, tmp2);
6283
                neon_store_reg(rd, 1, tmp3);
6284
                tcg_temp_free_i32(tmp);
6285
            } else if ((insn & 0x380) == 0) {
6286
                /* VDUP */
6287
                if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6288
                    return 1;
6289
                }
6290
                if (insn & (1 << 19)) {
6291
                    tmp = neon_load_reg(rm, 1);
6292
                } else {
6293
                    tmp = neon_load_reg(rm, 0);
6294
                }
6295
                if (insn & (1 << 16)) {
6296
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6297
                } else if (insn & (1 << 17)) {
6298
                    if ((insn >> 18) & 1)
6299
                        gen_neon_dup_high16(tmp);
6300
                    else
6301
                        gen_neon_dup_low16(tmp);
6302
                }
6303
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
6304
                    tmp2 = tcg_temp_new_i32();
6305
                    tcg_gen_mov_i32(tmp2, tmp);
6306
                    neon_store_reg(rd, pass, tmp2);
6307
                }
6308
                tcg_temp_free_i32(tmp);
6309
            } else {
6310
                return 1;
6311
            }
6312
        }
6313
    }
6314
    return 0;
6315
}
6316

    
6317
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
6318
{
6319
    int crn = (insn >> 16) & 0xf;
6320
    int crm = insn & 0xf;
6321
    int op1 = (insn >> 21) & 7;
6322
    int op2 = (insn >> 5) & 7;
6323
    int rt = (insn >> 12) & 0xf;
6324
    TCGv tmp;
6325

    
6326
    /* Minimal set of debug registers, since we don't support debug */
6327
    if (op1 == 0 && crn == 0 && op2 == 0) {
6328
        switch (crm) {
6329
        case 0:
6330
            /* DBGDIDR: just RAZ. In particular this means the
6331
             * "debug architecture version" bits will read as
6332
             * a reserved value, which should cause Linux to
6333
             * not try to use the debug hardware.
6334
             */
6335
            tmp = tcg_const_i32(0);
6336
            store_reg(s, rt, tmp);
6337
            return 0;
6338
        case 1:
6339
        case 2:
6340
            /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
6341
             * don't implement memory mapped debug components
6342
             */
6343
            if (ENABLE_ARCH_7) {
6344
                tmp = tcg_const_i32(0);
6345
                store_reg(s, rt, tmp);
6346
                return 0;
6347
            }
6348
            break;
6349
        default:
6350
            break;
6351
        }
6352
    }
6353

    
6354
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
6355
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
6356
            /* TEECR */
6357
            if (IS_USER(s))
6358
                return 1;
6359
            tmp = load_cpu_field(teecr);
6360
            store_reg(s, rt, tmp);
6361
            return 0;
6362
        }
6363
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
6364
            /* TEEHBR */
6365
            if (IS_USER(s) && (env->teecr & 1))
6366
                return 1;
6367
            tmp = load_cpu_field(teehbr);
6368
            store_reg(s, rt, tmp);
6369
            return 0;
6370
        }
6371
    }
6372
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
6373
            op1, crn, crm, op2);
6374
    return 1;
6375
}
6376

    
6377
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
6378
{
6379
    int crn = (insn >> 16) & 0xf;
6380
    int crm = insn & 0xf;
6381
    int op1 = (insn >> 21) & 7;
6382
    int op2 = (insn >> 5) & 7;
6383
    int rt = (insn >> 12) & 0xf;
6384
    TCGv tmp;
6385

    
6386
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
6387
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
6388
            /* TEECR */
6389
            if (IS_USER(s))
6390
                return 1;
6391
            tmp = load_reg(s, rt);
6392
            gen_helper_set_teecr(cpu_env, tmp);
6393
            tcg_temp_free_i32(tmp);
6394
            return 0;
6395
        }
6396
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
6397
            /* TEEHBR */
6398
            if (IS_USER(s) && (env->teecr & 1))
6399
                return 1;
6400
            tmp = load_reg(s, rt);
6401
            store_cpu_field(tmp, teehbr);
6402
            return 0;
6403
        }
6404
    }
6405
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
6406
            op1, crn, crm, op2);
6407
    return 1;
6408
}
6409

    
6410
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
6411
{
6412
    int cpnum;
6413

    
6414
    cpnum = (insn >> 8) & 0xf;
6415
    if (arm_feature(env, ARM_FEATURE_XSCALE)
6416
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6417
        return 1;
6418

    
6419
    switch (cpnum) {
6420
      case 0:
6421
      case 1:
6422
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6423
            return disas_iwmmxt_insn(env, s, insn);
6424
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6425
            return disas_dsp_insn(env, s, insn);
6426
        }
6427
        return 1;
6428
    case 10:
6429
    case 11:
6430
        return disas_vfp_insn (env, s, insn);
6431
    case 14:
6432
        /* Coprocessors 7-15 are architecturally reserved by ARM.
6433
           Unfortunately Intel decided to ignore this.  */
6434
        if (arm_feature(env, ARM_FEATURE_XSCALE))
6435
            goto board;
6436
        if (insn & (1 << 20))
6437
            return disas_cp14_read(env, s, insn);
6438
        else
6439
            return disas_cp14_write(env, s, insn);
6440
    case 15:
6441
        return disas_cp15_insn (env, s, insn);
6442
    default:
6443
    board:
6444
        /* Unknown coprocessor.  See if the board has hooked it.  */
6445
        return disas_cp_insn (env, s, insn);
6446
    }
6447
}
6448

    
6449

    
6450
/* Store a 64-bit value to a register pair.  Clobbers val.  */
6451
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6452
{
6453
    TCGv tmp;
6454
    tmp = tcg_temp_new_i32();
6455
    tcg_gen_trunc_i64_i32(tmp, val);
6456
    store_reg(s, rlow, tmp);
6457
    tmp = tcg_temp_new_i32();
6458
    tcg_gen_shri_i64(val, val, 32);
6459
    tcg_gen_trunc_i64_i32(tmp, val);
6460
    store_reg(s, rhigh, tmp);
6461
}
6462

    
6463
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
6464
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6465
{
6466
    TCGv_i64 tmp;
6467
    TCGv tmp2;
6468

    
6469
    /* Load value and extend to 64 bits.  */
6470
    tmp = tcg_temp_new_i64();
6471
    tmp2 = load_reg(s, rlow);
6472
    tcg_gen_extu_i32_i64(tmp, tmp2);
6473
    tcg_temp_free_i32(tmp2);
6474
    tcg_gen_add_i64(val, val, tmp);
6475
    tcg_temp_free_i64(tmp);
6476
}
6477

    
6478
/* load and add a 64-bit value from a register pair.  */
6479
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6480
{
6481
    TCGv_i64 tmp;
6482
    TCGv tmpl;
6483
    TCGv tmph;
6484

    
6485
    /* Load 64-bit value rd:rn.  */
6486
    tmpl = load_reg(s, rlow);
6487
    tmph = load_reg(s, rhigh);
6488
    tmp = tcg_temp_new_i64();
6489
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6490
    tcg_temp_free_i32(tmpl);
6491
    tcg_temp_free_i32(tmph);
6492
    tcg_gen_add_i64(val, val, tmp);
6493
    tcg_temp_free_i64(tmp);
6494
}
6495

    
6496
/* Set N and Z flags from a 64-bit value.  */
6497
static void gen_logicq_cc(TCGv_i64 val)
6498
{
6499
    TCGv tmp = tcg_temp_new_i32();
6500
    gen_helper_logicq_cc(tmp, val);
6501
    gen_logic_CC(tmp);
6502
    tcg_temp_free_i32(tmp);
6503
}
6504

    
6505
/* Load/Store exclusive instructions are implemented by remembering
6506
   the value/address loaded, and seeing if these are the same
6507
   when the store is performed. This should be is sufficient to implement
6508
   the architecturally mandated semantics, and avoids having to monitor
6509
   regular stores.
6510

6511
   In system emulation mode only one CPU will be running at once, so
6512
   this sequence is effectively atomic.  In user emulation mode we
6513
   throw an exception and handle the atomic operation elsewhere.  */
6514
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6515
                               TCGv addr, int size)
6516
{
6517
    TCGv tmp;
6518

    
6519
    switch (size) {
6520
    case 0:
6521
        tmp = gen_ld8u(addr, IS_USER(s));
6522
        break;
6523
    case 1:
6524
        tmp = gen_ld16u(addr, IS_USER(s));
6525
        break;
6526
    case 2:
6527
    case 3:
6528
        tmp = gen_ld32(addr, IS_USER(s));
6529
        break;
6530
    default:
6531
        abort();
6532
    }
6533
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6534
    store_reg(s, rt, tmp);
6535
    if (size == 3) {
6536
        TCGv tmp2 = tcg_temp_new_i32();
6537
        tcg_gen_addi_i32(tmp2, addr, 4);
6538
        tmp = gen_ld32(tmp2, IS_USER(s));
6539
        tcg_temp_free_i32(tmp2);
6540
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6541
        store_reg(s, rt2, tmp);
6542
    }
6543
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6544
}
6545

    
6546
static void gen_clrex(DisasContext *s)
6547
{
6548
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6549
}
6550

    
6551
#ifdef CONFIG_USER_ONLY
6552
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6553
                                TCGv addr, int size)
6554
{
6555
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
6556
    tcg_gen_movi_i32(cpu_exclusive_info,
6557
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
6558
    gen_exception_insn(s, 4, EXCP_STREX);
6559
}
6560
#else
6561
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6562
                                TCGv addr, int size)
6563
{
6564
    TCGv tmp;
6565
    int done_label;
6566
    int fail_label;
6567

    
6568
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6569
         [addr] = {Rt};
6570
         {Rd} = 0;
6571
       } else {
6572
         {Rd} = 1;
6573
       } */
6574
    fail_label = gen_new_label();
6575
    done_label = gen_new_label();
6576
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6577
    switch (size) {
6578
    case 0:
6579
        tmp = gen_ld8u(addr, IS_USER(s));
6580
        break;
6581
    case 1:
6582
        tmp = gen_ld16u(addr, IS_USER(s));
6583
        break;
6584
    case 2:
6585
    case 3:
6586
        tmp = gen_ld32(addr, IS_USER(s));
6587
        break;
6588
    default:
6589
        abort();
6590
    }
6591
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6592
    tcg_temp_free_i32(tmp);
6593
    if (size == 3) {
6594
        TCGv tmp2 = tcg_temp_new_i32();
6595
        tcg_gen_addi_i32(tmp2, addr, 4);
6596
        tmp = gen_ld32(tmp2, IS_USER(s));
6597
        tcg_temp_free_i32(tmp2);
6598
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6599
        tcg_temp_free_i32(tmp);
6600
    }
6601
    tmp = load_reg(s, rt);
6602
    switch (size) {
6603
    case 0:
6604
        gen_st8(tmp, addr, IS_USER(s));
6605
        break;
6606
    case 1:
6607
        gen_st16(tmp, addr, IS_USER(s));
6608
        break;
6609
    case 2:
6610
    case 3:
6611
        gen_st32(tmp, addr, IS_USER(s));
6612
        break;
6613
    default:
6614
        abort();
6615
    }
6616
    if (size == 3) {
6617
        tcg_gen_addi_i32(addr, addr, 4);
6618
        tmp = load_reg(s, rt2);
6619
        gen_st32(tmp, addr, IS_USER(s));
6620
    }
6621
    tcg_gen_movi_i32(cpu_R[rd], 0);
6622
    tcg_gen_br(done_label);
6623
    gen_set_label(fail_label);
6624
    tcg_gen_movi_i32(cpu_R[rd], 1);
6625
    gen_set_label(done_label);
6626
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6627
}
6628
#endif
6629

    
6630
static void disas_arm_insn(CPUState * env, DisasContext *s)
6631
{
6632
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6633
    TCGv tmp;
6634
    TCGv tmp2;
6635
    TCGv tmp3;
6636
    TCGv addr;
6637
    TCGv_i64 tmp64;
6638

    
6639
    insn = ldl_code(s->pc);
6640
    s->pc += 4;
6641

    
6642
    /* M variants do not implement ARM mode.  */
6643
    if (IS_M(env))
6644
        goto illegal_op;
6645
    cond = insn >> 28;
6646
    if (cond == 0xf){
6647
        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6648
         * choose to UNDEF. In ARMv5 and above the space is used
6649
         * for miscellaneous unconditional instructions.
6650
         */
6651
        ARCH(5);
6652

    
6653
        /* Unconditional instructions.  */
6654
        if (((insn >> 25) & 7) == 1) {
6655
            /* NEON Data processing.  */
6656
            if (!arm_feature(env, ARM_FEATURE_NEON))
6657
                goto illegal_op;
6658

    
6659
            if (disas_neon_data_insn(env, s, insn))
6660
                goto illegal_op;
6661
            return;
6662
        }
6663
        if ((insn & 0x0f100000) == 0x04000000) {
6664
            /* NEON load/store.  */
6665
            if (!arm_feature(env, ARM_FEATURE_NEON))
6666
                goto illegal_op;
6667

    
6668
            if (disas_neon_ls_insn(env, s, insn))
6669
                goto illegal_op;
6670
            return;
6671
        }
6672
        if (((insn & 0x0f30f000) == 0x0510f000) ||
6673
            ((insn & 0x0f30f010) == 0x0710f000)) {
6674
            if ((insn & (1 << 22)) == 0) {
6675
                /* PLDW; v7MP */
6676
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6677
                    goto illegal_op;
6678
                }
6679
            }
6680
            /* Otherwise PLD; v5TE+ */
6681
            ARCH(5TE);
6682
            return;
6683
        }
6684
        if (((insn & 0x0f70f000) == 0x0450f000) ||
6685
            ((insn & 0x0f70f010) == 0x0650f000)) {
6686
            ARCH(7);
6687
            return; /* PLI; V7 */
6688
        }
6689
        if (((insn & 0x0f700000) == 0x04100000) ||
6690
            ((insn & 0x0f700010) == 0x06100000)) {
6691
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6692
                goto illegal_op;
6693
            }
6694
            return; /* v7MP: Unallocated memory hint: must NOP */
6695
        }
6696

    
6697
        if ((insn & 0x0ffffdff) == 0x01010000) {
6698
            ARCH(6);
6699
            /* setend */
6700
            if (insn & (1 << 9)) {
6701
                /* BE8 mode not implemented.  */
6702
                goto illegal_op;
6703
            }
6704
            return;
6705
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6706
            switch ((insn >> 4) & 0xf) {
6707
            case 1: /* clrex */
6708
                ARCH(6K);
6709
                gen_clrex(s);
6710
                return;
6711
            case 4: /* dsb */
6712
            case 5: /* dmb */
6713
            case 6: /* isb */
6714
                ARCH(7);
6715
                /* We don't emulate caches so these are a no-op.  */
6716
                return;
6717
            default:
6718
                goto illegal_op;
6719
            }
6720
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6721
            /* srs */
6722
            int32_t offset;
6723
            if (IS_USER(s))
6724
                goto illegal_op;
6725
            ARCH(6);
6726
            op1 = (insn & 0x1f);
6727
            addr = tcg_temp_new_i32();
6728
            tmp = tcg_const_i32(op1);
6729
            gen_helper_get_r13_banked(addr, cpu_env, tmp);
6730
            tcg_temp_free_i32(tmp);
6731
            i = (insn >> 23) & 3;
6732
            switch (i) {
6733
            case 0: offset = -4; break; /* DA */
6734
            case 1: offset = 0; break; /* IA */
6735
            case 2: offset = -8; break; /* DB */
6736
            case 3: offset = 4; break; /* IB */
6737
            default: abort();
6738
            }
6739
            if (offset)
6740
                tcg_gen_addi_i32(addr, addr, offset);
6741
            tmp = load_reg(s, 14);
6742
            gen_st32(tmp, addr, 0);
6743
            tmp = load_cpu_field(spsr);
6744
            tcg_gen_addi_i32(addr, addr, 4);
6745
            gen_st32(tmp, addr, 0);
6746
            if (insn & (1 << 21)) {
6747
                /* Base writeback.  */
6748
                switch (i) {
6749
                case 0: offset = -8; break;
6750
                case 1: offset = 4; break;
6751
                case 2: offset = -4; break;
6752
                case 3: offset = 0; break;
6753
                default: abort();
6754
                }
6755
                if (offset)
6756
                    tcg_gen_addi_i32(addr, addr, offset);
6757
                tmp = tcg_const_i32(op1);
6758
                gen_helper_set_r13_banked(cpu_env, tmp, addr);
6759
                tcg_temp_free_i32(tmp);
6760
                tcg_temp_free_i32(addr);
6761
            } else {
6762
                tcg_temp_free_i32(addr);
6763
            }
6764
            return;
6765
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6766
            /* rfe */
6767
            int32_t offset;
6768
            if (IS_USER(s))
6769
                goto illegal_op;
6770
            ARCH(6);
6771
            rn = (insn >> 16) & 0xf;
6772
            addr = load_reg(s, rn);
6773
            i = (insn >> 23) & 3;
6774
            switch (i) {
6775
            case 0: offset = -4; break; /* DA */
6776
            case 1: offset = 0; break; /* IA */
6777
            case 2: offset = -8; break; /* DB */
6778
            case 3: offset = 4; break; /* IB */
6779
            default: abort();
6780
            }
6781
            if (offset)
6782
                tcg_gen_addi_i32(addr, addr, offset);
6783
            /* Load PC into tmp and CPSR into tmp2.  */
6784
            tmp = gen_ld32(addr, 0);
6785
            tcg_gen_addi_i32(addr, addr, 4);
6786
            tmp2 = gen_ld32(addr, 0);
6787
            if (insn & (1 << 21)) {
6788
                /* Base writeback.  */
6789
                switch (i) {
6790
                case 0: offset = -8; break;
6791
                case 1: offset = 4; break;
6792
                case 2: offset = -4; break;
6793
                case 3: offset = 0; break;
6794
                default: abort();
6795
                }
6796
                if (offset)
6797
                    tcg_gen_addi_i32(addr, addr, offset);
6798
                store_reg(s, rn, addr);
6799
            } else {
6800
                tcg_temp_free_i32(addr);
6801
            }
6802
            gen_rfe(s, tmp, tmp2);
6803
            return;
6804
        } else if ((insn & 0x0e000000) == 0x0a000000) {
6805
            /* branch link and change to thumb (blx <offset>) */
6806
            int32_t offset;
6807

    
6808
            val = (uint32_t)s->pc;
6809
            tmp = tcg_temp_new_i32();
6810
            tcg_gen_movi_i32(tmp, val);
6811
            store_reg(s, 14, tmp);
6812
            /* Sign-extend the 24-bit offset */
6813
            offset = (((int32_t)insn) << 8) >> 8;
6814
            /* offset * 4 + bit24 * 2 + (thumb bit) */
6815
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
6816
            /* pipeline offset */
6817
            val += 4;
6818
            /* protected by ARCH(5); above, near the start of uncond block */
6819
            gen_bx_im(s, val);
6820
            return;
6821
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
6822
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6823
                /* iWMMXt register transfer.  */
6824
                if (env->cp15.c15_cpar & (1 << 1))
6825
                    if (!disas_iwmmxt_insn(env, s, insn))
6826
                        return;
6827
            }
6828
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
6829
            /* Coprocessor double register transfer.  */
6830
            ARCH(5TE);
6831
        } else if ((insn & 0x0f000010) == 0x0e000010) {
6832
            /* Additional coprocessor register transfer.  */
6833
        } else if ((insn & 0x0ff10020) == 0x01000000) {
6834
            uint32_t mask;
6835
            uint32_t val;
6836
            /* cps (privileged) */
6837
            if (IS_USER(s))
6838
                return;
6839
            mask = val = 0;
6840
            if (insn & (1 << 19)) {
6841
                if (insn & (1 << 8))
6842
                    mask |= CPSR_A;
6843
                if (insn & (1 << 7))
6844
                    mask |= CPSR_I;
6845
                if (insn & (1 << 6))
6846
                    mask |= CPSR_F;
6847
                if (insn & (1 << 18))
6848
                    val |= mask;
6849
            }
6850
            if (insn & (1 << 17)) {
6851
                mask |= CPSR_M;
6852
                val |= (insn & 0x1f);
6853
            }
6854
            if (mask) {
6855
                gen_set_psr_im(s, mask, 0, val);
6856
            }
6857
            return;
6858
        }
6859
        goto illegal_op;
6860
    }
6861
    if (cond != 0xe) {
6862
        /* if not always execute, we generate a conditional jump to
6863
           next instruction */
6864
        s->condlabel = gen_new_label();
6865
        gen_test_cc(cond ^ 1, s->condlabel);
6866
        s->condjmp = 1;
6867
    }
6868
    if ((insn & 0x0f900000) == 0x03000000) {
6869
        if ((insn & (1 << 21)) == 0) {
6870
            ARCH(6T2);
6871
            rd = (insn >> 12) & 0xf;
6872
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6873
            if ((insn & (1 << 22)) == 0) {
6874
                /* MOVW */
6875
                tmp = tcg_temp_new_i32();
6876
                tcg_gen_movi_i32(tmp, val);
6877
            } else {
6878
                /* MOVT */
6879
                tmp = load_reg(s, rd);
6880
                tcg_gen_ext16u_i32(tmp, tmp);
6881
                tcg_gen_ori_i32(tmp, tmp, val << 16);
6882
            }
6883
            store_reg(s, rd, tmp);
6884
        } else {
6885
            if (((insn >> 12) & 0xf) != 0xf)
6886
                goto illegal_op;
6887
            if (((insn >> 16) & 0xf) == 0) {
6888
                gen_nop_hint(s, insn & 0xff);
6889
            } else {
6890
                /* CPSR = immediate */
6891
                val = insn & 0xff;
6892
                shift = ((insn >> 8) & 0xf) * 2;
6893
                if (shift)
6894
                    val = (val >> shift) | (val << (32 - shift));
6895
                i = ((insn & (1 << 22)) != 0);
6896
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6897
                    goto illegal_op;
6898
            }
6899
        }
6900
    } else if ((insn & 0x0f900000) == 0x01000000
6901
               && (insn & 0x00000090) != 0x00000090) {
6902
        /* miscellaneous instructions */
6903
        op1 = (insn >> 21) & 3;
6904
        sh = (insn >> 4) & 0xf;
6905
        rm = insn & 0xf;
6906
        switch (sh) {
6907
        case 0x0: /* move program status register */
6908
            if (op1 & 1) {
6909
                /* PSR = reg */
6910
                tmp = load_reg(s, rm);
6911
                i = ((op1 & 2) != 0);
6912
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6913
                    goto illegal_op;
6914
            } else {
6915
                /* reg = PSR */
6916
                rd = (insn >> 12) & 0xf;
6917
                if (op1 & 2) {
6918
                    if (IS_USER(s))
6919
                        goto illegal_op;
6920
                    tmp = load_cpu_field(spsr);
6921
                } else {
6922
                    tmp = tcg_temp_new_i32();
6923
                    gen_helper_cpsr_read(tmp);
6924
                }
6925
                store_reg(s, rd, tmp);
6926
            }
6927
            break;
6928
        case 0x1:
6929
            if (op1 == 1) {
6930
                /* branch/exchange thumb (bx).  */
6931
                ARCH(4T);
6932
                tmp = load_reg(s, rm);
6933
                gen_bx(s, tmp);
6934
            } else if (op1 == 3) {
6935
                /* clz */
6936
                ARCH(5);
6937
                rd = (insn >> 12) & 0xf;
6938
                tmp = load_reg(s, rm);
6939
                gen_helper_clz(tmp, tmp);
6940
                store_reg(s, rd, tmp);
6941
            } else {
6942
                goto illegal_op;
6943
            }
6944
            break;
6945
        case 0x2:
6946
            if (op1 == 1) {
6947
                ARCH(5J); /* bxj */
6948
                /* Trivial implementation equivalent to bx.  */
6949
                tmp = load_reg(s, rm);
6950
                gen_bx(s, tmp);
6951
            } else {
6952
                goto illegal_op;
6953
            }
6954
            break;
6955
        case 0x3:
6956
            if (op1 != 1)
6957
              goto illegal_op;
6958

    
6959
            ARCH(5);
6960
            /* branch link/exchange thumb (blx) */
6961
            tmp = load_reg(s, rm);
6962
            tmp2 = tcg_temp_new_i32();
6963
            tcg_gen_movi_i32(tmp2, s->pc);
6964
            store_reg(s, 14, tmp2);
6965
            gen_bx(s, tmp);
6966
            break;
6967
        case 0x5: /* saturating add/subtract */
6968
            ARCH(5TE);
6969
            rd = (insn >> 12) & 0xf;
6970
            rn = (insn >> 16) & 0xf;
6971
            tmp = load_reg(s, rm);
6972
            tmp2 = load_reg(s, rn);
6973
            if (op1 & 2)
6974
                gen_helper_double_saturate(tmp2, tmp2);
6975
            if (op1 & 1)
6976
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6977
            else
6978
                gen_helper_add_saturate(tmp, tmp, tmp2);
6979
            tcg_temp_free_i32(tmp2);
6980
            store_reg(s, rd, tmp);
6981
            break;
6982
        case 7:
6983
            /* SMC instruction (op1 == 3)
6984
               and undefined instructions (op1 == 0 || op1 == 2)
6985
               will trap */
6986
            if (op1 != 1) {
6987
                goto illegal_op;
6988
            }
6989
            /* bkpt */
6990
            ARCH(5);
6991
            gen_exception_insn(s, 4, EXCP_BKPT);
6992
            break;
6993
        case 0x8: /* signed multiply */
6994
        case 0xa:
6995
        case 0xc:
6996
        case 0xe:
6997
            ARCH(5TE);
6998
            rs = (insn >> 8) & 0xf;
6999
            rn = (insn >> 12) & 0xf;
7000
            rd = (insn >> 16) & 0xf;
7001
            if (op1 == 1) {
7002
                /* (32 * 16) >> 16 */
7003
                tmp = load_reg(s, rm);
7004
                tmp2 = load_reg(s, rs);
7005
                if (sh & 4)
7006
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7007
                else
7008
                    gen_sxth(tmp2);
7009
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7010
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7011
                tmp = tcg_temp_new_i32();
7012
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7013
                tcg_temp_free_i64(tmp64);
7014
                if ((sh & 2) == 0) {
7015
                    tmp2 = load_reg(s, rn);
7016
                    gen_helper_add_setq(tmp, tmp, tmp2);
7017
                    tcg_temp_free_i32(tmp2);
7018
                }
7019
                store_reg(s, rd, tmp);
7020
            } else {
7021
                /* 16 * 16 */
7022
                tmp = load_reg(s, rm);
7023
                tmp2 = load_reg(s, rs);
7024
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7025
                tcg_temp_free_i32(tmp2);
7026
                if (op1 == 2) {
7027
                    tmp64 = tcg_temp_new_i64();
7028
                    tcg_gen_ext_i32_i64(tmp64, tmp);
7029
                    tcg_temp_free_i32(tmp);
7030
                    gen_addq(s, tmp64, rn, rd);
7031
                    gen_storeq_reg(s, rn, rd, tmp64);
7032
                    tcg_temp_free_i64(tmp64);
7033
                } else {
7034
                    if (op1 == 0) {
7035
                        tmp2 = load_reg(s, rn);
7036
                        gen_helper_add_setq(tmp, tmp, tmp2);
7037
                        tcg_temp_free_i32(tmp2);
7038
                    }
7039
                    store_reg(s, rd, tmp);
7040
                }
7041
            }
7042
            break;
7043
        default:
7044
            goto illegal_op;
7045
        }
7046
    } else if (((insn & 0x0e000000) == 0 &&
7047
                (insn & 0x00000090) != 0x90) ||
7048
               ((insn & 0x0e000000) == (1 << 25))) {
7049
        int set_cc, logic_cc, shiftop;
7050

    
7051
        op1 = (insn >> 21) & 0xf;
7052
        set_cc = (insn >> 20) & 1;
7053
        logic_cc = table_logic_cc[op1] & set_cc;
7054

    
7055
        /* data processing instruction */
7056
        if (insn & (1 << 25)) {
7057
            /* immediate operand */
7058
            val = insn & 0xff;
7059
            shift = ((insn >> 8) & 0xf) * 2;
7060
            if (shift) {
7061
                val = (val >> shift) | (val << (32 - shift));
7062
            }
7063
            tmp2 = tcg_temp_new_i32();
7064
            tcg_gen_movi_i32(tmp2, val);
7065
            if (logic_cc && shift) {
7066
                gen_set_CF_bit31(tmp2);
7067
            }
7068
        } else {
7069
            /* register */
7070
            rm = (insn) & 0xf;
7071
            tmp2 = load_reg(s, rm);
7072
            shiftop = (insn >> 5) & 3;
7073
            if (!(insn & (1 << 4))) {
7074
                shift = (insn >> 7) & 0x1f;
7075
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7076
            } else {
7077
                rs = (insn >> 8) & 0xf;
7078
                tmp = load_reg(s, rs);
7079
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7080
            }
7081
        }
7082
        if (op1 != 0x0f && op1 != 0x0d) {
7083
            rn = (insn >> 16) & 0xf;
7084
            tmp = load_reg(s, rn);
7085
        } else {
7086
            TCGV_UNUSED(tmp);
7087
        }
7088
        rd = (insn >> 12) & 0xf;
7089
        switch(op1) {
7090
        case 0x00:
7091
            tcg_gen_and_i32(tmp, tmp, tmp2);
7092
            if (logic_cc) {
7093
                gen_logic_CC(tmp);
7094
            }
7095
            store_reg_bx(env, s, rd, tmp);
7096
            break;
7097
        case 0x01:
7098
            tcg_gen_xor_i32(tmp, tmp, tmp2);
7099
            if (logic_cc) {
7100
                gen_logic_CC(tmp);
7101
            }
7102
            store_reg_bx(env, s, rd, tmp);
7103
            break;
7104
        case 0x02:
7105
            if (set_cc && rd == 15) {
7106
                /* SUBS r15, ... is used for exception return.  */
7107
                if (IS_USER(s)) {
7108
                    goto illegal_op;
7109
                }
7110
                gen_helper_sub_cc(tmp, tmp, tmp2);
7111
                gen_exception_return(s, tmp);
7112
            } else {
7113
                if (set_cc) {
7114
                    gen_helper_sub_cc(tmp, tmp, tmp2);
7115
                } else {
7116
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7117
                }
7118
                store_reg_bx(env, s, rd, tmp);
7119
            }
7120
            break;
7121
        case 0x03:
7122
            if (set_cc) {
7123
                gen_helper_sub_cc(tmp, tmp2, tmp);
7124
            } else {
7125
                tcg_gen_sub_i32(tmp, tmp2, tmp);
7126
            }
7127
            store_reg_bx(env, s, rd, tmp);
7128
            break;
7129
        case 0x04:
7130
            if (set_cc) {
7131
                gen_helper_add_cc(tmp, tmp, tmp2);
7132
            } else {
7133
                tcg_gen_add_i32(tmp, tmp, tmp2);
7134
            }
7135
            store_reg_bx(env, s, rd, tmp);
7136
            break;
7137
        case 0x05:
7138
            if (set_cc) {
7139
                gen_helper_adc_cc(tmp, tmp, tmp2);
7140
            } else {
7141
                gen_add_carry(tmp, tmp, tmp2);
7142
            }
7143
            store_reg_bx(env, s, rd, tmp);
7144
            break;
7145
        case 0x06:
7146
            if (set_cc) {
7147
                gen_helper_sbc_cc(tmp, tmp, tmp2);
7148
            } else {
7149
                gen_sub_carry(tmp, tmp, tmp2);
7150
            }
7151
            store_reg_bx(env, s, rd, tmp);
7152
            break;
7153
        case 0x07:
7154
            if (set_cc) {
7155
                gen_helper_sbc_cc(tmp, tmp2, tmp);
7156
            } else {
7157
                gen_sub_carry(tmp, tmp2, tmp);
7158
            }
7159
            store_reg_bx(env, s, rd, tmp);
7160
            break;
7161
        case 0x08:
7162
            if (set_cc) {
7163
                tcg_gen_and_i32(tmp, tmp, tmp2);
7164
                gen_logic_CC(tmp);
7165
            }
7166
            tcg_temp_free_i32(tmp);
7167
            break;
7168
        case 0x09:
7169
            if (set_cc) {
7170
                tcg_gen_xor_i32(tmp, tmp, tmp2);
7171
                gen_logic_CC(tmp);
7172
            }
7173
            tcg_temp_free_i32(tmp);
7174
            break;
7175
        case 0x0a:
7176
            if (set_cc) {
7177
                gen_helper_sub_cc(tmp, tmp, tmp2);
7178
            }
7179
            tcg_temp_free_i32(tmp);
7180
            break;
7181
        case 0x0b:
7182
            if (set_cc) {
7183
                gen_helper_add_cc(tmp, tmp, tmp2);
7184
            }
7185
            tcg_temp_free_i32(tmp);
7186
            break;
7187
        case 0x0c:
7188
            tcg_gen_or_i32(tmp, tmp, tmp2);
7189
            if (logic_cc) {
7190
                gen_logic_CC(tmp);
7191
            }
7192
            store_reg_bx(env, s, rd, tmp);
7193
            break;
7194
        case 0x0d:
7195
            if (logic_cc && rd == 15) {
7196
                /* MOVS r15, ... is used for exception return.  */
7197
                if (IS_USER(s)) {
7198
                    goto illegal_op;
7199
                }
7200
                gen_exception_return(s, tmp2);
7201
            } else {
7202
                if (logic_cc) {
7203
                    gen_logic_CC(tmp2);
7204
                }
7205
                store_reg_bx(env, s, rd, tmp2);
7206
            }
7207
            break;
7208
        case 0x0e:
7209
            tcg_gen_andc_i32(tmp, tmp, tmp2);
7210
            if (logic_cc) {
7211
                gen_logic_CC(tmp);
7212
            }
7213
            store_reg_bx(env, s, rd, tmp);
7214
            break;
7215
        default:
7216
        case 0x0f:
7217
            tcg_gen_not_i32(tmp2, tmp2);
7218
            if (logic_cc) {
7219
                gen_logic_CC(tmp2);
7220
            }
7221
            store_reg_bx(env, s, rd, tmp2);
7222
            break;
7223
        }
7224
        if (op1 != 0x0f && op1 != 0x0d) {
7225
            tcg_temp_free_i32(tmp2);
7226
        }
7227
    } else {
7228
        /* other instructions */
7229
        op1 = (insn >> 24) & 0xf;
7230
        switch(op1) {
7231
        case 0x0:
7232
        case 0x1:
7233
            /* multiplies, extra load/stores */
7234
            sh = (insn >> 5) & 3;
7235
            if (sh == 0) {
7236
                if (op1 == 0x0) {
7237
                    rd = (insn >> 16) & 0xf;
7238
                    rn = (insn >> 12) & 0xf;
7239
                    rs = (insn >> 8) & 0xf;
7240
                    rm = (insn) & 0xf;
7241
                    op1 = (insn >> 20) & 0xf;
7242
                    switch (op1) {
7243
                    case 0: case 1: case 2: case 3: case 6:
7244
                        /* 32 bit mul */
7245
                        tmp = load_reg(s, rs);
7246
                        tmp2 = load_reg(s, rm);
7247
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
7248
                        tcg_temp_free_i32(tmp2);
7249
                        if (insn & (1 << 22)) {
7250
                            /* Subtract (mls) */
7251
                            ARCH(6T2);
7252
                            tmp2 = load_reg(s, rn);
7253
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
7254
                            tcg_temp_free_i32(tmp2);
7255
                        } else if (insn & (1 << 21)) {
7256
                            /* Add */
7257
                            tmp2 = load_reg(s, rn);
7258
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7259
                            tcg_temp_free_i32(tmp2);
7260
                        }
7261
                        if (insn & (1 << 20))
7262
                            gen_logic_CC(tmp);
7263
                        store_reg(s, rd, tmp);
7264
                        break;
7265
                    case 4:
7266
                        /* 64 bit mul double accumulate (UMAAL) */
7267
                        ARCH(6);
7268
                        tmp = load_reg(s, rs);
7269
                        tmp2 = load_reg(s, rm);
7270
                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7271
                        gen_addq_lo(s, tmp64, rn);
7272
                        gen_addq_lo(s, tmp64, rd);
7273
                        gen_storeq_reg(s, rn, rd, tmp64);
7274
                        tcg_temp_free_i64(tmp64);
7275
                        break;
7276
                    case 8: case 9: case 10: case 11:
7277
                    case 12: case 13: case 14: case 15:
7278
                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7279
                        tmp = load_reg(s, rs);
7280
                        tmp2 = load_reg(s, rm);
7281
                        if (insn & (1 << 22)) {
7282
                            tmp64 = gen_muls_i64_i32(tmp, tmp2);
7283
                        } else {
7284
                            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7285
                        }
7286
                        if (insn & (1 << 21)) { /* mult accumulate */
7287
                            gen_addq(s, tmp64, rn, rd);
7288
                        }
7289
                        if (insn & (1 << 20)) {
7290
                            gen_logicq_cc(tmp64);
7291
                        }
7292
                        gen_storeq_reg(s, rn, rd, tmp64);
7293
                        tcg_temp_free_i64(tmp64);
7294
                        break;
7295
                    default:
7296
                        goto illegal_op;
7297
                    }
7298
                } else {
7299
                    rn = (insn >> 16) & 0xf;
7300
                    rd = (insn >> 12) & 0xf;
7301
                    if (insn & (1 << 23)) {
7302
                        /* load/store exclusive */
7303
                        op1 = (insn >> 21) & 0x3;
7304
                        if (op1)
7305
                            ARCH(6K);
7306
                        else
7307
                            ARCH(6);
7308
                        addr = tcg_temp_local_new_i32();
7309
                        load_reg_var(s, addr, rn);
7310
                        if (insn & (1 << 20)) {
7311
                            switch (op1) {
7312
                            case 0: /* ldrex */
7313
                                gen_load_exclusive(s, rd, 15, addr, 2);
7314
                                break;
7315
                            case 1: /* ldrexd */
7316
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
7317
                                break;
7318
                            case 2: /* ldrexb */
7319
                                gen_load_exclusive(s, rd, 15, addr, 0);
7320
                                break;
7321
                            case 3: /* ldrexh */
7322
                                gen_load_exclusive(s, rd, 15, addr, 1);
7323
                                break;
7324
                            default:
7325
                                abort();
7326
                            }
7327
                        } else {
7328
                            rm = insn & 0xf;
7329
                            switch (op1) {
7330
                            case 0:  /*  strex */
7331
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
7332
                                break;
7333
                            case 1: /*  strexd */
7334
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7335
                                break;
7336
                            case 2: /*  strexb */
7337
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
7338
                                break;
7339
                            case 3: /* strexh */
7340
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
7341
                                break;
7342
                            default:
7343
                                abort();
7344
                            }
7345
                        }
7346
                        tcg_temp_free(addr);
7347
                    } else {
7348
                        /* SWP instruction */
7349
                        rm = (insn) & 0xf;
7350

    
7351
                        /* ??? This is not really atomic.  However we know
7352
                           we never have multiple CPUs running in parallel,
7353
                           so it is good enough.  */
7354
                        addr = load_reg(s, rn);
7355
                        tmp = load_reg(s, rm);
7356
                        if (insn & (1 << 22)) {
7357
                            tmp2 = gen_ld8u(addr, IS_USER(s));
7358
                            gen_st8(tmp, addr, IS_USER(s));
7359
                        } else {
7360
                            tmp2 = gen_ld32(addr, IS_USER(s));
7361
                            gen_st32(tmp, addr, IS_USER(s));
7362
                        }
7363
                        tcg_temp_free_i32(addr);
7364
                        store_reg(s, rd, tmp2);
7365
                    }
7366
                }
7367
            } else {
7368
                int address_offset;
7369
                int load;
7370
                /* Misc load/store */
7371
                rn = (insn >> 16) & 0xf;
7372
                rd = (insn >> 12) & 0xf;
7373
                addr = load_reg(s, rn);
7374
                if (insn & (1 << 24))
7375
                    gen_add_datah_offset(s, insn, 0, addr);
7376
                address_offset = 0;
7377
                if (insn & (1 << 20)) {
7378
                    /* load */
7379
                    switch(sh) {
7380
                    case 1:
7381
                        tmp = gen_ld16u(addr, IS_USER(s));
7382
                        break;
7383
                    case 2:
7384
                        tmp = gen_ld8s(addr, IS_USER(s));
7385
                        break;
7386
                    default:
7387
                    case 3:
7388
                        tmp = gen_ld16s(addr, IS_USER(s));
7389
                        break;
7390
                    }
7391
                    load = 1;
7392
                } else if (sh & 2) {
7393
                    ARCH(5TE);
7394
                    /* doubleword */
7395
                    if (sh & 1) {
7396
                        /* store */
7397
                        tmp = load_reg(s, rd);
7398
                        gen_st32(tmp, addr, IS_USER(s));
7399
                        tcg_gen_addi_i32(addr, addr, 4);
7400
                        tmp = load_reg(s, rd + 1);
7401
                        gen_st32(tmp, addr, IS_USER(s));
7402
                        load = 0;
7403
                    } else {
7404
                        /* load */
7405
                        tmp = gen_ld32(addr, IS_USER(s));
7406
                        store_reg(s, rd, tmp);
7407
                        tcg_gen_addi_i32(addr, addr, 4);
7408
                        tmp = gen_ld32(addr, IS_USER(s));
7409
                        rd++;
7410
                        load = 1;
7411
                    }
7412
                    address_offset = -4;
7413
                } else {
7414
                    /* store */
7415
                    tmp = load_reg(s, rd);
7416
                    gen_st16(tmp, addr, IS_USER(s));
7417
                    load = 0;
7418
                }
7419
                /* Perform base writeback before the loaded value to
7420
                   ensure correct behavior with overlapping index registers.
7421
                   ldrd with base writeback is is undefined if the
7422
                   destination and index registers overlap.  */
7423
                if (!(insn & (1 << 24))) {
7424
                    gen_add_datah_offset(s, insn, address_offset, addr);
7425
                    store_reg(s, rn, addr);
7426
                } else if (insn & (1 << 21)) {
7427
                    if (address_offset)
7428
                        tcg_gen_addi_i32(addr, addr, address_offset);
7429
                    store_reg(s, rn, addr);
7430
                } else {
7431
                    tcg_temp_free_i32(addr);
7432
                }
7433
                if (load) {
7434
                    /* Complete the load.  */
7435
                    store_reg(s, rd, tmp);
7436
                }
7437
            }
7438
            break;
7439
        case 0x4:
7440
        case 0x5:
7441
            goto do_ldst;
7442
        case 0x6:
7443
        case 0x7:
7444
            if (insn & (1 << 4)) {
7445
                ARCH(6);
7446
                /* Armv6 Media instructions.  */
7447
                rm = insn & 0xf;
7448
                rn = (insn >> 16) & 0xf;
7449
                rd = (insn >> 12) & 0xf;
7450
                rs = (insn >> 8) & 0xf;
7451
                switch ((insn >> 23) & 3) {
7452
                case 0: /* Parallel add/subtract.  */
7453
                    op1 = (insn >> 20) & 7;
7454
                    tmp = load_reg(s, rn);
7455
                    tmp2 = load_reg(s, rm);
7456
                    sh = (insn >> 5) & 7;
7457
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7458
                        goto illegal_op;
7459
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7460
                    tcg_temp_free_i32(tmp2);
7461
                    store_reg(s, rd, tmp);
7462
                    break;
7463
                case 1:
7464
                    if ((insn & 0x00700020) == 0) {
7465
                        /* Halfword pack.  */
7466
                        tmp = load_reg(s, rn);
7467
                        tmp2 = load_reg(s, rm);
7468
                        shift = (insn >> 7) & 0x1f;
7469
                        if (insn & (1 << 6)) {
7470
                            /* pkhtb */
7471
                            if (shift == 0)
7472
                                shift = 31;
7473
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
7474
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7475
                            tcg_gen_ext16u_i32(tmp2, tmp2);
7476
                        } else {
7477
                            /* pkhbt */
7478
                            if (shift)
7479
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
7480
                            tcg_gen_ext16u_i32(tmp, tmp);
7481
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7482
                        }
7483
                        tcg_gen_or_i32(tmp, tmp, tmp2);
7484
                        tcg_temp_free_i32(tmp2);
7485
                        store_reg(s, rd, tmp);
7486
                    } else if ((insn & 0x00200020) == 0x00200000) {
7487
                        /* [us]sat */
7488
                        tmp = load_reg(s, rm);
7489
                        shift = (insn >> 7) & 0x1f;
7490
                        if (insn & (1 << 6)) {
7491
                            if (shift == 0)
7492
                                shift = 31;
7493
                            tcg_gen_sari_i32(tmp, tmp, shift);
7494
                        } else {
7495
                            tcg_gen_shli_i32(tmp, tmp, shift);
7496
                        }
7497
                        sh = (insn >> 16) & 0x1f;
7498
                        tmp2 = tcg_const_i32(sh);
7499
                        if (insn & (1 << 22))
7500
                          gen_helper_usat(tmp, tmp, tmp2);
7501
                        else
7502
                          gen_helper_ssat(tmp, tmp, tmp2);
7503
                        tcg_temp_free_i32(tmp2);
7504
                        store_reg(s, rd, tmp);
7505
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
7506
                        /* [us]sat16 */
7507
                        tmp = load_reg(s, rm);
7508
                        sh = (insn >> 16) & 0x1f;
7509
                        tmp2 = tcg_const_i32(sh);
7510
                        if (insn & (1 << 22))
7511
                          gen_helper_usat16(tmp, tmp, tmp2);
7512
                        else
7513
                          gen_helper_ssat16(tmp, tmp, tmp2);
7514
                        tcg_temp_free_i32(tmp2);
7515
                        store_reg(s, rd, tmp);
7516
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7517
                        /* Select bytes.  */
7518
                        tmp = load_reg(s, rn);
7519
                        tmp2 = load_reg(s, rm);
7520
                        tmp3 = tcg_temp_new_i32();
7521
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7522
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7523
                        tcg_temp_free_i32(tmp3);
7524
                        tcg_temp_free_i32(tmp2);
7525
                        store_reg(s, rd, tmp);
7526
                    } else if ((insn & 0x000003e0) == 0x00000060) {
7527
                        tmp = load_reg(s, rm);
7528
                        shift = (insn >> 10) & 3;
7529
                        /* ??? In many cases it's not necessary to do a
7530
                           rotate, a shift is sufficient.  */
7531
                        if (shift != 0)
7532
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7533
                        op1 = (insn >> 20) & 7;
7534
                        switch (op1) {
7535
                        case 0: gen_sxtb16(tmp);  break;
7536
                        case 2: gen_sxtb(tmp);    break;
7537
                        case 3: gen_sxth(tmp);    break;
7538
                        case 4: gen_uxtb16(tmp);  break;
7539
                        case 6: gen_uxtb(tmp);    break;
7540
                        case 7: gen_uxth(tmp);    break;
7541
                        default: goto illegal_op;
7542
                        }
7543
                        if (rn != 15) {
7544
                            tmp2 = load_reg(s, rn);
7545
                            if ((op1 & 3) == 0) {
7546
                                gen_add16(tmp, tmp2);
7547
                            } else {
7548
                                tcg_gen_add_i32(tmp, tmp, tmp2);
7549
                                tcg_temp_free_i32(tmp2);
7550
                            }
7551
                        }
7552
                        store_reg(s, rd, tmp);
7553
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7554
                        /* rev */
7555
                        tmp = load_reg(s, rm);
7556
                        if (insn & (1 << 22)) {
7557
                            if (insn & (1 << 7)) {
7558
                                gen_revsh(tmp);
7559
                            } else {
7560
                                ARCH(6T2);
7561
                                gen_helper_rbit(tmp, tmp);
7562
                            }
7563
                        } else {
7564
                            if (insn & (1 << 7))
7565
                                gen_rev16(tmp);
7566
                            else
7567
                                tcg_gen_bswap32_i32(tmp, tmp);
7568
                        }
7569
                        store_reg(s, rd, tmp);
7570
                    } else {
7571
                        goto illegal_op;
7572
                    }
7573
                    break;
7574
                case 2: /* Multiplies (Type 3).  */
7575
                    tmp = load_reg(s, rm);
7576
                    tmp2 = load_reg(s, rs);
7577
                    if (insn & (1 << 20)) {
7578
                        /* Signed multiply most significant [accumulate].
7579
                           (SMMUL, SMMLA, SMMLS) */
7580
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7581

    
7582
                        if (rd != 15) {
7583
                            tmp = load_reg(s, rd);
7584
                            if (insn & (1 << 6)) {
7585
                                tmp64 = gen_subq_msw(tmp64, tmp);
7586
                            } else {
7587
                                tmp64 = gen_addq_msw(tmp64, tmp);
7588
                            }
7589
                        }
7590
                        if (insn & (1 << 5)) {
7591
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7592
                        }
7593
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
7594
                        tmp = tcg_temp_new_i32();
7595
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
7596
                        tcg_temp_free_i64(tmp64);
7597
                        store_reg(s, rn, tmp);
7598
                    } else {
7599
                        if (insn & (1 << 5))
7600
                            gen_swap_half(tmp2);
7601
                        gen_smul_dual(tmp, tmp2);
7602
                        if (insn & (1 << 6)) {
7603
                            /* This subtraction cannot overflow. */
7604
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
7605
                        } else {
7606
                            /* This addition cannot overflow 32 bits;
7607
                             * however it may overflow considered as a signed
7608
                             * operation, in which case we must set the Q flag.
7609
                             */
7610
                            gen_helper_add_setq(tmp, tmp, tmp2);
7611
                        }
7612
                        tcg_temp_free_i32(tmp2);
7613
                        if (insn & (1 << 22)) {
7614
                            /* smlald, smlsld */
7615
                            tmp64 = tcg_temp_new_i64();
7616
                            tcg_gen_ext_i32_i64(tmp64, tmp);
7617
                            tcg_temp_free_i32(tmp);
7618
                            gen_addq(s, tmp64, rd, rn);
7619
                            gen_storeq_reg(s, rd, rn, tmp64);
7620
                            tcg_temp_free_i64(tmp64);
7621
                        } else {
7622
                            /* smuad, smusd, smlad, smlsd */
7623
                            if (rd != 15)
7624
                              {
7625
                                tmp2 = load_reg(s, rd);
7626
                                gen_helper_add_setq(tmp, tmp, tmp2);
7627
                                tcg_temp_free_i32(tmp2);
7628
                              }
7629
                            store_reg(s, rn, tmp);
7630
                        }
7631
                    }
7632
                    break;
7633
                case 3:
7634
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7635
                    switch (op1) {
7636
                    case 0: /* Unsigned sum of absolute differences.  */
7637
                        ARCH(6);
7638
                        tmp = load_reg(s, rm);
7639
                        tmp2 = load_reg(s, rs);
7640
                        gen_helper_usad8(tmp, tmp, tmp2);
7641
                        tcg_temp_free_i32(tmp2);
7642
                        if (rd != 15) {
7643
                            tmp2 = load_reg(s, rd);
7644
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7645
                            tcg_temp_free_i32(tmp2);
7646
                        }
7647
                        store_reg(s, rn, tmp);
7648
                        break;
7649
                    case 0x20: case 0x24: case 0x28: case 0x2c:
7650
                        /* Bitfield insert/clear.  */
7651
                        ARCH(6T2);
7652
                        shift = (insn >> 7) & 0x1f;
7653
                        i = (insn >> 16) & 0x1f;
7654
                        i = i + 1 - shift;
7655
                        if (rm == 15) {
7656
                            tmp = tcg_temp_new_i32();
7657
                            tcg_gen_movi_i32(tmp, 0);
7658
                        } else {
7659
                            tmp = load_reg(s, rm);
7660
                        }
7661
                        if (i != 32) {
7662
                            tmp2 = load_reg(s, rd);
7663
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
7664
                            tcg_temp_free_i32(tmp2);
7665
                        }
7666
                        store_reg(s, rd, tmp);
7667
                        break;
7668
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7669
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7670
                        ARCH(6T2);
7671
                        tmp = load_reg(s, rm);
7672
                        shift = (insn >> 7) & 0x1f;
7673
                        i = ((insn >> 16) & 0x1f) + 1;
7674
                        if (shift + i > 32)
7675
                            goto illegal_op;
7676
                        if (i < 32) {
7677
                            if (op1 & 0x20) {
7678
                                gen_ubfx(tmp, shift, (1u << i) - 1);
7679
                            } else {
7680
                                gen_sbfx(tmp, shift, i);
7681
                            }
7682
                        }
7683
                        store_reg(s, rd, tmp);
7684
                        break;
7685
                    default:
7686
                        goto illegal_op;
7687
                    }
7688
                    break;
7689
                }
7690
                break;
7691
            }
7692
        do_ldst:
7693
            /* Check for undefined extension instructions
7694
             * per the ARM Bible IE:
7695
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
7696
             */
7697
            sh = (0xf << 20) | (0xf << 4);
7698
            if (op1 == 0x7 && ((insn & sh) == sh))
7699
            {
7700
                goto illegal_op;
7701
            }
7702
            /* load/store byte/word */
7703
            rn = (insn >> 16) & 0xf;
7704
            rd = (insn >> 12) & 0xf;
7705
            tmp2 = load_reg(s, rn);
7706
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7707
            if (insn & (1 << 24))
7708
                gen_add_data_offset(s, insn, tmp2);
7709
            if (insn & (1 << 20)) {
7710
                /* load */
7711
                if (insn & (1 << 22)) {
7712
                    tmp = gen_ld8u(tmp2, i);
7713
                } else {
7714
                    tmp = gen_ld32(tmp2, i);
7715
                }
7716
            } else {
7717
                /* store */
7718
                tmp = load_reg(s, rd);
7719
                if (insn & (1 << 22))
7720
                    gen_st8(tmp, tmp2, i);
7721
                else
7722
                    gen_st32(tmp, tmp2, i);
7723
            }
7724
            if (!(insn & (1 << 24))) {
7725
                gen_add_data_offset(s, insn, tmp2);
7726
                store_reg(s, rn, tmp2);
7727
            } else if (insn & (1 << 21)) {
7728
                store_reg(s, rn, tmp2);
7729
            } else {
7730
                tcg_temp_free_i32(tmp2);
7731
            }
7732
            if (insn & (1 << 20)) {
7733
                /* Complete the load.  */
7734
                store_reg_from_load(env, s, rd, tmp);
7735
            }
7736
            break;
7737
        case 0x08:
7738
        case 0x09:
7739
            {
7740
                int j, n, user, loaded_base;
7741
                TCGv loaded_var;
7742
                /* load/store multiple words */
7743
                /* XXX: store correct base if write back */
7744
                user = 0;
7745
                if (insn & (1 << 22)) {
7746
                    if (IS_USER(s))
7747
                        goto illegal_op; /* only usable in supervisor mode */
7748

    
7749
                    if ((insn & (1 << 15)) == 0)
7750
                        user = 1;
7751
                }
7752
                rn = (insn >> 16) & 0xf;
7753
                addr = load_reg(s, rn);
7754

    
7755
                /* compute total size */
7756
                loaded_base = 0;
7757
                TCGV_UNUSED(loaded_var);
7758
                n = 0;
7759
                for(i=0;i<16;i++) {
7760
                    if (insn & (1 << i))
7761
                        n++;
7762
                }
7763
                /* XXX: test invalid n == 0 case ? */
7764
                if (insn & (1 << 23)) {
7765
                    if (insn & (1 << 24)) {
7766
                        /* pre increment */
7767
                        tcg_gen_addi_i32(addr, addr, 4);
7768
                    } else {
7769
                        /* post increment */
7770
                    }
7771
                } else {
7772
                    if (insn & (1 << 24)) {
7773
                        /* pre decrement */
7774
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
7775
                    } else {
7776
                        /* post decrement */
7777
                        if (n != 1)
7778
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7779
                    }
7780
                }
7781
                j = 0;
7782
                for(i=0;i<16;i++) {
7783
                    if (insn & (1 << i)) {
7784
                        if (insn & (1 << 20)) {
7785
                            /* load */
7786
                            tmp = gen_ld32(addr, IS_USER(s));
7787
                            if (user) {
7788
                                tmp2 = tcg_const_i32(i);
7789
                                gen_helper_set_user_reg(tmp2, tmp);
7790
                                tcg_temp_free_i32(tmp2);
7791
                                tcg_temp_free_i32(tmp);
7792
                            } else if (i == rn) {
7793
                                loaded_var = tmp;
7794
                                loaded_base = 1;
7795
                            } else {
7796
                                store_reg_from_load(env, s, i, tmp);
7797
                            }
7798
                        } else {
7799
                            /* store */
7800
                            if (i == 15) {
7801
                                /* special case: r15 = PC + 8 */
7802
                                val = (long)s->pc + 4;
7803
                                tmp = tcg_temp_new_i32();
7804
                                tcg_gen_movi_i32(tmp, val);
7805
                            } else if (user) {
7806
                                tmp = tcg_temp_new_i32();
7807
                                tmp2 = tcg_const_i32(i);
7808
                                gen_helper_get_user_reg(tmp, tmp2);
7809
                                tcg_temp_free_i32(tmp2);
7810
                            } else {
7811
                                tmp = load_reg(s, i);
7812
                            }
7813
                            gen_st32(tmp, addr, IS_USER(s));
7814
                        }
7815
                        j++;
7816
                        /* no need to add after the last transfer */
7817
                        if (j != n)
7818
                            tcg_gen_addi_i32(addr, addr, 4);
7819
                    }
7820
                }
7821
                if (insn & (1 << 21)) {
7822
                    /* write back */
7823
                    if (insn & (1 << 23)) {
7824
                        if (insn & (1 << 24)) {
7825
                            /* pre increment */
7826
                        } else {
7827
                            /* post increment */
7828
                            tcg_gen_addi_i32(addr, addr, 4);
7829
                        }
7830
                    } else {
7831
                        if (insn & (1 << 24)) {
7832
                            /* pre decrement */
7833
                            if (n != 1)
7834
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7835
                        } else {
7836
                            /* post decrement */
7837
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
7838
                        }
7839
                    }
7840
                    store_reg(s, rn, addr);
7841
                } else {
7842
                    tcg_temp_free_i32(addr);
7843
                }
7844
                if (loaded_base) {
7845
                    store_reg(s, rn, loaded_var);
7846
                }
7847
                if ((insn & (1 << 22)) && !user) {
7848
                    /* Restore CPSR from SPSR.  */
7849
                    tmp = load_cpu_field(spsr);
7850
                    gen_set_cpsr(tmp, 0xffffffff);
7851
                    tcg_temp_free_i32(tmp);
7852
                    s->is_jmp = DISAS_UPDATE;
7853
                }
7854
            }
7855
            break;
7856
        case 0xa:
7857
        case 0xb:
7858
            {
7859
                int32_t offset;
7860

    
7861
                /* branch (and link) */
7862
                val = (int32_t)s->pc;
7863
                if (insn & (1 << 24)) {
7864
                    tmp = tcg_temp_new_i32();
7865
                    tcg_gen_movi_i32(tmp, val);
7866
                    store_reg(s, 14, tmp);
7867
                }
7868
                offset = (((int32_t)insn << 8) >> 8);
7869
                val += (offset << 2) + 4;
7870
                gen_jmp(s, val);
7871
            }
7872
            break;
7873
        case 0xc:
7874
        case 0xd:
7875
        case 0xe:
7876
            /* Coprocessor.  */
7877
            if (disas_coproc_insn(env, s, insn))
7878
                goto illegal_op;
7879
            break;
7880
        case 0xf:
7881
            /* swi */
7882
            gen_set_pc_im(s->pc);
7883
            s->is_jmp = DISAS_SWI;
7884
            break;
7885
        default:
7886
        illegal_op:
7887
            gen_exception_insn(s, 4, EXCP_UDEF);
7888
            break;
7889
        }
7890
    }
7891
}
7892

    
7893
/* Return true if this is a Thumb-2 logical op.  */
7894
static int
7895
thumb2_logic_op(int op)
7896
{
7897
    return (op < 8);
7898
}
7899

    
7900
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7901
   then set condition code flags based on the result of the operation.
7902
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7903
   to the high bit of T1.
7904
   Returns zero if the opcode is valid.  */
7905

    
7906
static int
7907
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7908
{
7909
    int logic_cc;
7910

    
7911
    logic_cc = 0;
7912
    switch (op) {
7913
    case 0: /* and */
7914
        tcg_gen_and_i32(t0, t0, t1);
7915
        logic_cc = conds;
7916
        break;
7917
    case 1: /* bic */
7918
        tcg_gen_andc_i32(t0, t0, t1);
7919
        logic_cc = conds;
7920
        break;
7921
    case 2: /* orr */
7922
        tcg_gen_or_i32(t0, t0, t1);
7923
        logic_cc = conds;
7924
        break;
7925
    case 3: /* orn */
7926
        tcg_gen_orc_i32(t0, t0, t1);
7927
        logic_cc = conds;
7928
        break;
7929
    case 4: /* eor */
7930
        tcg_gen_xor_i32(t0, t0, t1);
7931
        logic_cc = conds;
7932
        break;
7933
    case 8: /* add */
7934
        if (conds)
7935
            gen_helper_add_cc(t0, t0, t1);
7936
        else
7937
            tcg_gen_add_i32(t0, t0, t1);
7938
        break;
7939
    case 10: /* adc */
7940
        if (conds)
7941
            gen_helper_adc_cc(t0, t0, t1);
7942
        else
7943
            gen_adc(t0, t1);
7944
        break;
7945
    case 11: /* sbc */
7946
        if (conds)
7947
            gen_helper_sbc_cc(t0, t0, t1);
7948
        else
7949
            gen_sub_carry(t0, t0, t1);
7950
        break;
7951
    case 13: /* sub */
7952
        if (conds)
7953
            gen_helper_sub_cc(t0, t0, t1);
7954
        else
7955
            tcg_gen_sub_i32(t0, t0, t1);
7956
        break;
7957
    case 14: /* rsb */
7958
        if (conds)
7959
            gen_helper_sub_cc(t0, t1, t0);
7960
        else
7961
            tcg_gen_sub_i32(t0, t1, t0);
7962
        break;
7963
    default: /* 5, 6, 7, 9, 12, 15. */
7964
        return 1;
7965
    }
7966
    if (logic_cc) {
7967
        gen_logic_CC(t0);
7968
        if (shifter_out)
7969
            gen_set_CF_bit31(t1);
7970
    }
7971
    return 0;
7972
}
7973

    
7974
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7975
   is not legal.  */
7976
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7977
{
7978
    uint32_t insn, imm, shift, offset;
7979
    uint32_t rd, rn, rm, rs;
7980
    TCGv tmp;
7981
    TCGv tmp2;
7982
    TCGv tmp3;
7983
    TCGv addr;
7984
    TCGv_i64 tmp64;
7985
    int op;
7986
    int shiftop;
7987
    int conds;
7988
    int logic_cc;
7989

    
7990
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7991
          || arm_feature (env, ARM_FEATURE_M))) {
7992
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7993
           16-bit instructions to get correct prefetch abort behavior.  */
7994
        insn = insn_hw1;
7995
        if ((insn & (1 << 12)) == 0) {
7996
            ARCH(5);
7997
            /* Second half of blx.  */
7998
            offset = ((insn & 0x7ff) << 1);
7999
            tmp = load_reg(s, 14);
8000
            tcg_gen_addi_i32(tmp, tmp, offset);
8001
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8002

    
8003
            tmp2 = tcg_temp_new_i32();
8004
            tcg_gen_movi_i32(tmp2, s->pc | 1);
8005
            store_reg(s, 14, tmp2);
8006
            gen_bx(s, tmp);
8007
            return 0;
8008
        }
8009
        if (insn & (1 << 11)) {
8010
            /* Second half of bl.  */
8011
            offset = ((insn & 0x7ff) << 1) | 1;
8012
            tmp = load_reg(s, 14);
8013
            tcg_gen_addi_i32(tmp, tmp, offset);
8014

    
8015
            tmp2 = tcg_temp_new_i32();
8016
            tcg_gen_movi_i32(tmp2, s->pc | 1);
8017
            store_reg(s, 14, tmp2);
8018
            gen_bx(s, tmp);
8019
            return 0;
8020
        }
8021
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8022
            /* Instruction spans a page boundary.  Implement it as two
8023
               16-bit instructions in case the second half causes an
8024
               prefetch abort.  */
8025
            offset = ((int32_t)insn << 21) >> 9;
8026
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8027
            return 0;
8028
        }
8029
        /* Fall through to 32-bit decode.  */
8030
    }
8031

    
8032
    insn = lduw_code(s->pc);
8033
    s->pc += 2;
8034
    insn |= (uint32_t)insn_hw1 << 16;
8035

    
8036
    if ((insn & 0xf800e800) != 0xf000e800) {
8037
        ARCH(6T2);
8038
    }
8039

    
8040
    rn = (insn >> 16) & 0xf;
8041
    rs = (insn >> 12) & 0xf;
8042
    rd = (insn >> 8) & 0xf;
8043
    rm = insn & 0xf;
8044
    switch ((insn >> 25) & 0xf) {
8045
    case 0: case 1: case 2: case 3:
8046
        /* 16-bit instructions.  Should never happen.  */
8047
        abort();
8048
    case 4:
8049
        if (insn & (1 << 22)) {
8050
            /* Other load/store, table branch.  */
8051
            if (insn & 0x01200000) {
8052
                /* Load/store doubleword.  */
8053
                if (rn == 15) {
8054
                    addr = tcg_temp_new_i32();
8055
                    tcg_gen_movi_i32(addr, s->pc & ~3);
8056
                } else {
8057
                    addr = load_reg(s, rn);
8058
                }
8059
                offset = (insn & 0xff) * 4;
8060
                if ((insn & (1 << 23)) == 0)
8061
                    offset = -offset;
8062
                if (insn & (1 << 24)) {
8063
                    tcg_gen_addi_i32(addr, addr, offset);
8064
                    offset = 0;
8065
                }
8066
                if (insn & (1 << 20)) {
8067
                    /* ldrd */
8068
                    tmp = gen_ld32(addr, IS_USER(s));
8069
                    store_reg(s, rs, tmp);
8070
                    tcg_gen_addi_i32(addr, addr, 4);
8071
                    tmp = gen_ld32(addr, IS_USER(s));
8072
                    store_reg(s, rd, tmp);
8073
                } else {
8074
                    /* strd */
8075
                    tmp = load_reg(s, rs);
8076
                    gen_st32(tmp, addr, IS_USER(s));
8077
                    tcg_gen_addi_i32(addr, addr, 4);
8078
                    tmp = load_reg(s, rd);
8079
                    gen_st32(tmp, addr, IS_USER(s));
8080
                }
8081
                if (insn & (1 << 21)) {
8082
                    /* Base writeback.  */
8083
                    if (rn == 15)
8084
                        goto illegal_op;
8085
                    tcg_gen_addi_i32(addr, addr, offset - 4);
8086
                    store_reg(s, rn, addr);
8087
                } else {
8088
                    tcg_temp_free_i32(addr);
8089
                }
8090
            } else if ((insn & (1 << 23)) == 0) {
8091
                /* Load/store exclusive word.  */
8092
                addr = tcg_temp_local_new();
8093
                load_reg_var(s, addr, rn);
8094
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8095
                if (insn & (1 << 20)) {
8096
                    gen_load_exclusive(s, rs, 15, addr, 2);
8097
                } else {
8098
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
8099
                }
8100
                tcg_temp_free(addr);
8101
            } else if ((insn & (1 << 6)) == 0) {
8102
                /* Table Branch.  */
8103
                if (rn == 15) {
8104
                    addr = tcg_temp_new_i32();
8105
                    tcg_gen_movi_i32(addr, s->pc);
8106
                } else {
8107
                    addr = load_reg(s, rn);
8108
                }
8109
                tmp = load_reg(s, rm);
8110
                tcg_gen_add_i32(addr, addr, tmp);
8111
                if (insn & (1 << 4)) {
8112
                    /* tbh */
8113
                    tcg_gen_add_i32(addr, addr, tmp);
8114
                    tcg_temp_free_i32(tmp);
8115
                    tmp = gen_ld16u(addr, IS_USER(s));
8116
                } else { /* tbb */
8117
                    tcg_temp_free_i32(tmp);
8118
                    tmp = gen_ld8u(addr, IS_USER(s));
8119
                }
8120
                tcg_temp_free_i32(addr);
8121
                tcg_gen_shli_i32(tmp, tmp, 1);
8122
                tcg_gen_addi_i32(tmp, tmp, s->pc);
8123
                store_reg(s, 15, tmp);
8124
            } else {
8125
                /* Load/store exclusive byte/halfword/doubleword.  */
8126
                ARCH(7);
8127
                op = (insn >> 4) & 0x3;
8128
                if (op == 2) {
8129
                    goto illegal_op;
8130
                }
8131
                addr = tcg_temp_local_new();
8132
                load_reg_var(s, addr, rn);
8133
                if (insn & (1 << 20)) {
8134
                    gen_load_exclusive(s, rs, rd, addr, op);
8135
                } else {
8136
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
8137
                }
8138
                tcg_temp_free(addr);
8139
            }
8140
        } else {
8141
            /* Load/store multiple, RFE, SRS.  */
8142
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8143
                /* Not available in user mode.  */
8144
                if (IS_USER(s))
8145
                    goto illegal_op;
8146
                if (insn & (1 << 20)) {
8147
                    /* rfe */
8148
                    addr = load_reg(s, rn);
8149
                    if ((insn & (1 << 24)) == 0)
8150
                        tcg_gen_addi_i32(addr, addr, -8);
8151
                    /* Load PC into tmp and CPSR into tmp2.  */
8152
                    tmp = gen_ld32(addr, 0);
8153
                    tcg_gen_addi_i32(addr, addr, 4);
8154
                    tmp2 = gen_ld32(addr, 0);
8155
                    if (insn & (1 << 21)) {
8156
                        /* Base writeback.  */
8157
                        if (insn & (1 << 24)) {
8158
                            tcg_gen_addi_i32(addr, addr, 4);
8159
                        } else {
8160
                            tcg_gen_addi_i32(addr, addr, -4);
8161
                        }
8162
                        store_reg(s, rn, addr);
8163
                    } else {
8164
                        tcg_temp_free_i32(addr);
8165
                    }
8166
                    gen_rfe(s, tmp, tmp2);
8167
                } else {
8168
                    /* srs */
8169
                    op = (insn & 0x1f);
8170
                    addr = tcg_temp_new_i32();
8171
                    tmp = tcg_const_i32(op);
8172
                    gen_helper_get_r13_banked(addr, cpu_env, tmp);
8173
                    tcg_temp_free_i32(tmp);
8174
                    if ((insn & (1 << 24)) == 0) {
8175
                        tcg_gen_addi_i32(addr, addr, -8);
8176
                    }
8177
                    tmp = load_reg(s, 14);
8178
                    gen_st32(tmp, addr, 0);
8179
                    tcg_gen_addi_i32(addr, addr, 4);
8180
                    tmp = tcg_temp_new_i32();
8181
                    gen_helper_cpsr_read(tmp);
8182
                    gen_st32(tmp, addr, 0);
8183
                    if (insn & (1 << 21)) {
8184
                        if ((insn & (1 << 24)) == 0) {
8185
                            tcg_gen_addi_i32(addr, addr, -4);
8186
                        } else {
8187
                            tcg_gen_addi_i32(addr, addr, 4);
8188
                        }
8189
                        tmp = tcg_const_i32(op);
8190
                        gen_helper_set_r13_banked(cpu_env, tmp, addr);
8191
                        tcg_temp_free_i32(tmp);
8192
                    } else {
8193
                        tcg_temp_free_i32(addr);
8194
                    }
8195
                }
8196
            } else {
8197
                int i, loaded_base = 0;
8198
                TCGv loaded_var;
8199
                /* Load/store multiple.  */
8200
                addr = load_reg(s, rn);
8201
                offset = 0;
8202
                for (i = 0; i < 16; i++) {
8203
                    if (insn & (1 << i))
8204
                        offset += 4;
8205
                }
8206
                if (insn & (1 << 24)) {
8207
                    tcg_gen_addi_i32(addr, addr, -offset);
8208
                }
8209

    
8210
                TCGV_UNUSED(loaded_var);
8211
                for (i = 0; i < 16; i++) {
8212
                    if ((insn & (1 << i)) == 0)
8213
                        continue;
8214
                    if (insn & (1 << 20)) {
8215
                        /* Load.  */
8216
                        tmp = gen_ld32(addr, IS_USER(s));
8217
                        if (i == 15) {
8218
                            gen_bx(s, tmp);
8219
                        } else if (i == rn) {
8220
                            loaded_var = tmp;
8221
                            loaded_base = 1;
8222
                        } else {
8223
                            store_reg(s, i, tmp);
8224
                        }
8225
                    } else {
8226
                        /* Store.  */
8227
                        tmp = load_reg(s, i);
8228
                        gen_st32(tmp, addr, IS_USER(s));
8229
                    }
8230
                    tcg_gen_addi_i32(addr, addr, 4);
8231
                }
8232
                if (loaded_base) {
8233
                    store_reg(s, rn, loaded_var);
8234
                }
8235
                if (insn & (1 << 21)) {
8236
                    /* Base register writeback.  */
8237
                    if (insn & (1 << 24)) {
8238
                        tcg_gen_addi_i32(addr, addr, -offset);
8239
                    }
8240
                    /* Fault if writeback register is in register list.  */
8241
                    if (insn & (1 << rn))
8242
                        goto illegal_op;
8243
                    store_reg(s, rn, addr);
8244
                } else {
8245
                    tcg_temp_free_i32(addr);
8246
                }
8247
            }
8248
        }
8249
        break;
8250
    case 5:
8251

    
8252
        op = (insn >> 21) & 0xf;
8253
        if (op == 6) {
8254
            /* Halfword pack.  */
8255
            tmp = load_reg(s, rn);
8256
            tmp2 = load_reg(s, rm);
8257
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8258
            if (insn & (1 << 5)) {
8259
                /* pkhtb */
8260
                if (shift == 0)
8261
                    shift = 31;
8262
                tcg_gen_sari_i32(tmp2, tmp2, shift);
8263
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8264
                tcg_gen_ext16u_i32(tmp2, tmp2);
8265
            } else {
8266
                /* pkhbt */
8267
                if (shift)
8268
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
8269
                tcg_gen_ext16u_i32(tmp, tmp);
8270
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8271
            }
8272
            tcg_gen_or_i32(tmp, tmp, tmp2);
8273
            tcg_temp_free_i32(tmp2);
8274
            store_reg(s, rd, tmp);
8275
        } else {
8276
            /* Data processing register constant shift.  */
8277
            if (rn == 15) {
8278
                tmp = tcg_temp_new_i32();
8279
                tcg_gen_movi_i32(tmp, 0);
8280
            } else {
8281
                tmp = load_reg(s, rn);
8282
            }
8283
            tmp2 = load_reg(s, rm);
8284

    
8285
            shiftop = (insn >> 4) & 3;
8286
            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8287
            conds = (insn & (1 << 20)) != 0;
8288
            logic_cc = (conds && thumb2_logic_op(op));
8289
            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8290
            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8291
                goto illegal_op;
8292
            tcg_temp_free_i32(tmp2);
8293
            if (rd != 15) {
8294
                store_reg(s, rd, tmp);
8295
            } else {
8296
                tcg_temp_free_i32(tmp);
8297
            }
8298
        }
8299
        break;
8300
    case 13: /* Misc data processing.  */
8301
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8302
        if (op < 4 && (insn & 0xf000) != 0xf000)
8303
            goto illegal_op;
8304
        switch (op) {
8305
        case 0: /* Register controlled shift.  */
8306
            tmp = load_reg(s, rn);
8307
            tmp2 = load_reg(s, rm);
8308
            if ((insn & 0x70) != 0)
8309
                goto illegal_op;
8310
            op = (insn >> 21) & 3;
8311
            logic_cc = (insn & (1 << 20)) != 0;
8312
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8313
            if (logic_cc)
8314
                gen_logic_CC(tmp);
8315
            store_reg_bx(env, s, rd, tmp);
8316
            break;
8317
        case 1: /* Sign/zero extend.  */
8318
            tmp = load_reg(s, rm);
8319
            shift = (insn >> 4) & 3;
8320
            /* ??? In many cases it's not necessary to do a
8321
               rotate, a shift is sufficient.  */
8322
            if (shift != 0)
8323
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8324
            op = (insn >> 20) & 7;
8325
            switch (op) {
8326
            case 0: gen_sxth(tmp);   break;
8327
            case 1: gen_uxth(tmp);   break;
8328
            case 2: gen_sxtb16(tmp); break;
8329
            case 3: gen_uxtb16(tmp); break;
8330
            case 4: gen_sxtb(tmp);   break;
8331
            case 5: gen_uxtb(tmp);   break;
8332
            default: goto illegal_op;
8333
            }
8334
            if (rn != 15) {
8335
                tmp2 = load_reg(s, rn);
8336
                if ((op >> 1) == 1) {
8337
                    gen_add16(tmp, tmp2);
8338
                } else {
8339
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8340
                    tcg_temp_free_i32(tmp2);
8341
                }
8342
            }
8343
            store_reg(s, rd, tmp);
8344
            break;
8345
        case 2: /* SIMD add/subtract.  */
8346
            op = (insn >> 20) & 7;
8347
            shift = (insn >> 4) & 7;
8348
            if ((op & 3) == 3 || (shift & 3) == 3)
8349
                goto illegal_op;
8350
            tmp = load_reg(s, rn);
8351
            tmp2 = load_reg(s, rm);
8352
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8353
            tcg_temp_free_i32(tmp2);
8354
            store_reg(s, rd, tmp);
8355
            break;
8356
        case 3: /* Other data processing.  */
8357
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8358
            if (op < 4) {
8359
                /* Saturating add/subtract.  */
8360
                tmp = load_reg(s, rn);
8361
                tmp2 = load_reg(s, rm);
8362
                if (op & 1)
8363
                    gen_helper_double_saturate(tmp, tmp);
8364
                if (op & 2)
8365
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
8366
                else
8367
                    gen_helper_add_saturate(tmp, tmp, tmp2);
8368
                tcg_temp_free_i32(tmp2);
8369
            } else {
8370
                tmp = load_reg(s, rn);
8371
                switch (op) {
8372
                case 0x0a: /* rbit */
8373
                    gen_helper_rbit(tmp, tmp);
8374
                    break;
8375
                case 0x08: /* rev */
8376
                    tcg_gen_bswap32_i32(tmp, tmp);
8377
                    break;
8378
                case 0x09: /* rev16 */
8379
                    gen_rev16(tmp);
8380
                    break;
8381
                case 0x0b: /* revsh */
8382
                    gen_revsh(tmp);
8383
                    break;
8384
                case 0x10: /* sel */
8385
                    tmp2 = load_reg(s, rm);
8386
                    tmp3 = tcg_temp_new_i32();
8387
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
8388
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8389
                    tcg_temp_free_i32(tmp3);
8390
                    tcg_temp_free_i32(tmp2);
8391
                    break;
8392
                case 0x18: /* clz */
8393
                    gen_helper_clz(tmp, tmp);
8394
                    break;
8395
                default:
8396
                    goto illegal_op;
8397
                }
8398
            }
8399
            store_reg(s, rd, tmp);
8400
            break;
8401
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
8402
            op = (insn >> 4) & 0xf;
8403
            tmp = load_reg(s, rn);
8404
            tmp2 = load_reg(s, rm);
8405
            switch ((insn >> 20) & 7) {
8406
            case 0: /* 32 x 32 -> 32 */
8407
                tcg_gen_mul_i32(tmp, tmp, tmp2);
8408
                tcg_temp_free_i32(tmp2);
8409
                if (rs != 15) {
8410
                    tmp2 = load_reg(s, rs);
8411
                    if (op)
8412
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
8413
                    else
8414
                        tcg_gen_add_i32(tmp, tmp, tmp2);
8415
                    tcg_temp_free_i32(tmp2);
8416
                }
8417
                break;
8418
            case 1: /* 16 x 16 -> 32 */
8419
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
8420
                tcg_temp_free_i32(tmp2);
8421
                if (rs != 15) {
8422
                    tmp2 = load_reg(s, rs);
8423
                    gen_helper_add_setq(tmp, tmp, tmp2);
8424
                    tcg_temp_free_i32(tmp2);
8425
                }
8426
                break;
8427
            case 2: /* Dual multiply add.  */
8428
            case 4: /* Dual multiply subtract.  */
8429
                if (op)
8430
                    gen_swap_half(tmp2);
8431
                gen_smul_dual(tmp, tmp2);
8432
                if (insn & (1 << 22)) {
8433
                    /* This subtraction cannot overflow. */
8434
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8435
                } else {
8436
                    /* This addition cannot overflow 32 bits;
8437
                     * however it may overflow considered as a signed
8438
                     * operation, in which case we must set the Q flag.
8439
                     */
8440
                    gen_helper_add_setq(tmp, tmp, tmp2);
8441
                }
8442
                tcg_temp_free_i32(tmp2);
8443
                if (rs != 15)
8444
                  {
8445
                    tmp2 = load_reg(s, rs);
8446
                    gen_helper_add_setq(tmp, tmp, tmp2);
8447
                    tcg_temp_free_i32(tmp2);
8448
                  }
8449
                break;
8450
            case 3: /* 32 * 16 -> 32msb */
8451
                if (op)
8452
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
8453
                else
8454
                    gen_sxth(tmp2);
8455
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
8456
                tcg_gen_shri_i64(tmp64, tmp64, 16);
8457
                tmp = tcg_temp_new_i32();
8458
                tcg_gen_trunc_i64_i32(tmp, tmp64);
8459
                tcg_temp_free_i64(tmp64);
8460
                if (rs != 15)
8461
                  {
8462
                    tmp2 = load_reg(s, rs);
8463
                    gen_helper_add_setq(tmp, tmp, tmp2);
8464
                    tcg_temp_free_i32(tmp2);
8465
                  }
8466
                break;
8467
            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8468
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
8469
                if (rs != 15) {
8470
                    tmp = load_reg(s, rs);
8471
                    if (insn & (1 << 20)) {
8472
                        tmp64 = gen_addq_msw(tmp64, tmp);
8473
                    } else {
8474
                        tmp64 = gen_subq_msw(tmp64, tmp);
8475
                    }
8476
                }
8477
                if (insn & (1 << 4)) {
8478
                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8479
                }
8480
                tcg_gen_shri_i64(tmp64, tmp64, 32);
8481
                tmp = tcg_temp_new_i32();
8482
                tcg_gen_trunc_i64_i32(tmp, tmp64);
8483
                tcg_temp_free_i64(tmp64);
8484
                break;
8485
            case 7: /* Unsigned sum of absolute differences.  */
8486
                gen_helper_usad8(tmp, tmp, tmp2);
8487
                tcg_temp_free_i32(tmp2);
8488
                if (rs != 15) {
8489
                    tmp2 = load_reg(s, rs);
8490
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8491
                    tcg_temp_free_i32(tmp2);
8492
                }
8493
                break;
8494
            }
8495
            store_reg(s, rd, tmp);
8496
            break;
8497
        case 6: case 7: /* 64-bit multiply, Divide.  */
8498
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8499
            tmp = load_reg(s, rn);
8500
            tmp2 = load_reg(s, rm);
8501
            if ((op & 0x50) == 0x10) {
8502
                /* sdiv, udiv */
8503
                if (!arm_feature(env, ARM_FEATURE_DIV))
8504
                    goto illegal_op;
8505
                if (op & 0x20)
8506
                    gen_helper_udiv(tmp, tmp, tmp2);
8507
                else
8508
                    gen_helper_sdiv(tmp, tmp, tmp2);
8509
                tcg_temp_free_i32(tmp2);
8510
                store_reg(s, rd, tmp);
8511
            } else if ((op & 0xe) == 0xc) {
8512
                /* Dual multiply accumulate long.  */
8513
                if (op & 1)
8514
                    gen_swap_half(tmp2);
8515
                gen_smul_dual(tmp, tmp2);
8516
                if (op & 0x10) {
8517
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8518
                } else {
8519
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8520
                }
8521
                tcg_temp_free_i32(tmp2);
8522
                /* BUGFIX */
8523
                tmp64 = tcg_temp_new_i64();
8524
                tcg_gen_ext_i32_i64(tmp64, tmp);
8525
                tcg_temp_free_i32(tmp);
8526
                gen_addq(s, tmp64, rs, rd);
8527
                gen_storeq_reg(s, rs, rd, tmp64);
8528
                tcg_temp_free_i64(tmp64);
8529
            } else {
8530
                if (op & 0x20) {
8531
                    /* Unsigned 64-bit multiply  */
8532
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8533
                } else {
8534
                    if (op & 8) {
8535
                        /* smlalxy */
8536
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
8537
                        tcg_temp_free_i32(tmp2);
8538
                        tmp64 = tcg_temp_new_i64();
8539
                        tcg_gen_ext_i32_i64(tmp64, tmp);
8540
                        tcg_temp_free_i32(tmp);
8541
                    } else {
8542
                        /* Signed 64-bit multiply  */
8543
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
8544
                    }
8545
                }
8546
                if (op & 4) {
8547
                    /* umaal */
8548
                    gen_addq_lo(s, tmp64, rs);
8549
                    gen_addq_lo(s, tmp64, rd);
8550
                } else if (op & 0x40) {
8551
                    /* 64-bit accumulate.  */
8552
                    gen_addq(s, tmp64, rs, rd);
8553
                }
8554
                gen_storeq_reg(s, rs, rd, tmp64);
8555
                tcg_temp_free_i64(tmp64);
8556
            }
8557
            break;
8558
        }
8559
        break;
8560
    case 6: case 7: case 14: case 15:
8561
        /* Coprocessor.  */
8562
        if (((insn >> 24) & 3) == 3) {
8563
            /* Translate into the equivalent ARM encoding.  */
8564
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8565
            if (disas_neon_data_insn(env, s, insn))
8566
                goto illegal_op;
8567
        } else {
8568
            if (insn & (1 << 28))
8569
                goto illegal_op;
8570
            if (disas_coproc_insn (env, s, insn))
8571
                goto illegal_op;
8572
        }
8573
        break;
8574
    case 8: case 9: case 10: case 11:
8575
        if (insn & (1 << 15)) {
8576
            /* Branches, misc control.  */
8577
            if (insn & 0x5000) {
8578
                /* Unconditional branch.  */
8579
                /* signextend(hw1[10:0]) -> offset[:12].  */
8580
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8581
                /* hw1[10:0] -> offset[11:1].  */
8582
                offset |= (insn & 0x7ff) << 1;
8583
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8584
                   offset[24:22] already have the same value because of the
8585
                   sign extension above.  */
8586
                offset ^= ((~insn) & (1 << 13)) << 10;
8587
                offset ^= ((~insn) & (1 << 11)) << 11;
8588

    
8589
                if (insn & (1 << 14)) {
8590
                    /* Branch and link.  */
8591
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8592
                }
8593

    
8594
                offset += s->pc;
8595
                if (insn & (1 << 12)) {
8596
                    /* b/bl */
8597
                    gen_jmp(s, offset);
8598
                } else {
8599
                    /* blx */
8600
                    offset &= ~(uint32_t)2;
8601
                    /* thumb2 bx, no need to check */
8602
                    gen_bx_im(s, offset);
8603
                }
8604
            } else if (((insn >> 23) & 7) == 7) {
8605
                /* Misc control */
8606
                if (insn & (1 << 13))
8607
                    goto illegal_op;
8608

    
8609
                if (insn & (1 << 26)) {
8610
                    /* Secure monitor call (v6Z) */
8611
                    goto illegal_op; /* not implemented.  */
8612
                } else {
8613
                    op = (insn >> 20) & 7;
8614
                    switch (op) {
8615
                    case 0: /* msr cpsr.  */
8616
                        if (IS_M(env)) {
8617
                            tmp = load_reg(s, rn);
8618
                            addr = tcg_const_i32(insn & 0xff);
8619
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
8620
                            tcg_temp_free_i32(addr);
8621
                            tcg_temp_free_i32(tmp);
8622
                            gen_lookup_tb(s);
8623
                            break;
8624
                        }
8625
                        /* fall through */
8626
                    case 1: /* msr spsr.  */
8627
                        if (IS_M(env))
8628
                            goto illegal_op;
8629
                        tmp = load_reg(s, rn);
8630
                        if (gen_set_psr(s,
8631
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8632
                              op == 1, tmp))
8633
                            goto illegal_op;
8634
                        break;
8635
                    case 2: /* cps, nop-hint.  */
8636
                        if (((insn >> 8) & 7) == 0) {
8637
                            gen_nop_hint(s, insn & 0xff);
8638
                        }
8639
                        /* Implemented as NOP in user mode.  */
8640
                        if (IS_USER(s))
8641
                            break;
8642
                        offset = 0;
8643
                        imm = 0;
8644
                        if (insn & (1 << 10)) {
8645
                            if (insn & (1 << 7))
8646
                                offset |= CPSR_A;
8647
                            if (insn & (1 << 6))
8648
                                offset |= CPSR_I;
8649
                            if (insn & (1 << 5))
8650
                                offset |= CPSR_F;
8651
                            if (insn & (1 << 9))
8652
                                imm = CPSR_A | CPSR_I | CPSR_F;
8653
                        }
8654
                        if (insn & (1 << 8)) {
8655
                            offset |= 0x1f;
8656
                            imm |= (insn & 0x1f);
8657
                        }
8658
                        if (offset) {
8659
                            gen_set_psr_im(s, offset, 0, imm);
8660
                        }
8661
                        break;
8662
                    case 3: /* Special control operations.  */
8663
                        ARCH(7);
8664
                        op = (insn >> 4) & 0xf;
8665
                        switch (op) {
8666
                        case 2: /* clrex */
8667
                            gen_clrex(s);
8668
                            break;
8669
                        case 4: /* dsb */
8670
                        case 5: /* dmb */
8671
                        case 6: /* isb */
8672
                            /* These execute as NOPs.  */
8673
                            break;
8674
                        default:
8675
                            goto illegal_op;
8676
                        }
8677
                        break;
8678
                    case 4: /* bxj */
8679
                        /* Trivial implementation equivalent to bx.  */
8680
                        tmp = load_reg(s, rn);
8681
                        gen_bx(s, tmp);
8682
                        break;
8683
                    case 5: /* Exception return.  */
8684
                        if (IS_USER(s)) {
8685
                            goto illegal_op;
8686
                        }
8687
                        if (rn != 14 || rd != 15) {
8688
                            goto illegal_op;
8689
                        }
8690
                        tmp = load_reg(s, rn);
8691
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8692
                        gen_exception_return(s, tmp);
8693
                        break;
8694
                    case 6: /* mrs cpsr.  */
8695
                        tmp = tcg_temp_new_i32();
8696
                        if (IS_M(env)) {
8697
                            addr = tcg_const_i32(insn & 0xff);
8698
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
8699
                            tcg_temp_free_i32(addr);
8700
                        } else {
8701
                            gen_helper_cpsr_read(tmp);
8702
                        }
8703
                        store_reg(s, rd, tmp);
8704
                        break;
8705
                    case 7: /* mrs spsr.  */
8706
                        /* Not accessible in user mode.  */
8707
                        if (IS_USER(s) || IS_M(env))
8708
                            goto illegal_op;
8709
                        tmp = load_cpu_field(spsr);
8710
                        store_reg(s, rd, tmp);
8711
                        break;
8712
                    }
8713
                }
8714
            } else {
8715
                /* Conditional branch.  */
8716
                op = (insn >> 22) & 0xf;
8717
                /* Generate a conditional jump to next instruction.  */
8718
                s->condlabel = gen_new_label();
8719
                gen_test_cc(op ^ 1, s->condlabel);
8720
                s->condjmp = 1;
8721

    
8722
                /* offset[11:1] = insn[10:0] */
8723
                offset = (insn & 0x7ff) << 1;
8724
                /* offset[17:12] = insn[21:16].  */
8725
                offset |= (insn & 0x003f0000) >> 4;
8726
                /* offset[31:20] = insn[26].  */
8727
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8728
                /* offset[18] = insn[13].  */
8729
                offset |= (insn & (1 << 13)) << 5;
8730
                /* offset[19] = insn[11].  */
8731
                offset |= (insn & (1 << 11)) << 8;
8732

    
8733
                /* jump to the offset */
8734
                gen_jmp(s, s->pc + offset);
8735
            }
8736
        } else {
8737
            /* Data processing immediate.  */
8738
            if (insn & (1 << 25)) {
8739
                if (insn & (1 << 24)) {
8740
                    if (insn & (1 << 20))
8741
                        goto illegal_op;
8742
                    /* Bitfield/Saturate.  */
8743
                    op = (insn >> 21) & 7;
8744
                    imm = insn & 0x1f;
8745
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8746
                    if (rn == 15) {
8747
                        tmp = tcg_temp_new_i32();
8748
                        tcg_gen_movi_i32(tmp, 0);
8749
                    } else {
8750
                        tmp = load_reg(s, rn);
8751
                    }
8752
                    switch (op) {
8753
                    case 2: /* Signed bitfield extract.  */
8754
                        imm++;
8755
                        if (shift + imm > 32)
8756
                            goto illegal_op;
8757
                        if (imm < 32)
8758
                            gen_sbfx(tmp, shift, imm);
8759
                        break;
8760
                    case 6: /* Unsigned bitfield extract.  */
8761
                        imm++;
8762
                        if (shift + imm > 32)
8763
                            goto illegal_op;
8764
                        if (imm < 32)
8765
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
8766
                        break;
8767
                    case 3: /* Bitfield insert/clear.  */
8768
                        if (imm < shift)
8769
                            goto illegal_op;
8770
                        imm = imm + 1 - shift;
8771
                        if (imm != 32) {
8772
                            tmp2 = load_reg(s, rd);
8773
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
8774
                            tcg_temp_free_i32(tmp2);
8775
                        }
8776
                        break;
8777
                    case 7:
8778
                        goto illegal_op;
8779
                    default: /* Saturate.  */
8780
                        if (shift) {
8781
                            if (op & 1)
8782
                                tcg_gen_sari_i32(tmp, tmp, shift);
8783
                            else
8784
                                tcg_gen_shli_i32(tmp, tmp, shift);
8785
                        }
8786
                        tmp2 = tcg_const_i32(imm);
8787
                        if (op & 4) {
8788
                            /* Unsigned.  */
8789
                            if ((op & 1) && shift == 0)
8790
                                gen_helper_usat16(tmp, tmp, tmp2);
8791
                            else
8792
                                gen_helper_usat(tmp, tmp, tmp2);
8793
                        } else {
8794
                            /* Signed.  */
8795
                            if ((op & 1) && shift == 0)
8796
                                gen_helper_ssat16(tmp, tmp, tmp2);
8797
                            else
8798
                                gen_helper_ssat(tmp, tmp, tmp2);
8799
                        }
8800
                        tcg_temp_free_i32(tmp2);
8801
                        break;
8802
                    }
8803
                    store_reg(s, rd, tmp);
8804
                } else {
8805
                    imm = ((insn & 0x04000000) >> 15)
8806
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
8807
                    if (insn & (1 << 22)) {
8808
                        /* 16-bit immediate.  */
8809
                        imm |= (insn >> 4) & 0xf000;
8810
                        if (insn & (1 << 23)) {
8811
                            /* movt */
8812
                            tmp = load_reg(s, rd);
8813
                            tcg_gen_ext16u_i32(tmp, tmp);
8814
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
8815
                        } else {
8816
                            /* movw */
8817
                            tmp = tcg_temp_new_i32();
8818
                            tcg_gen_movi_i32(tmp, imm);
8819
                        }
8820
                    } else {
8821
                        /* Add/sub 12-bit immediate.  */
8822
                        if (rn == 15) {
8823
                            offset = s->pc & ~(uint32_t)3;
8824
                            if (insn & (1 << 23))
8825
                                offset -= imm;
8826
                            else
8827
                                offset += imm;
8828
                            tmp = tcg_temp_new_i32();
8829
                            tcg_gen_movi_i32(tmp, offset);
8830
                        } else {
8831
                            tmp = load_reg(s, rn);
8832
                            if (insn & (1 << 23))
8833
                                tcg_gen_subi_i32(tmp, tmp, imm);
8834
                            else
8835
                                tcg_gen_addi_i32(tmp, tmp, imm);
8836
                        }
8837
                    }
8838
                    store_reg(s, rd, tmp);
8839
                }
8840
            } else {
8841
                int shifter_out = 0;
8842
                /* modified 12-bit immediate.  */
8843
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8844
                imm = (insn & 0xff);
8845
                switch (shift) {
8846
                case 0: /* XY */
8847
                    /* Nothing to do.  */
8848
                    break;
8849
                case 1: /* 00XY00XY */
8850
                    imm |= imm << 16;
8851
                    break;
8852
                case 2: /* XY00XY00 */
8853
                    imm |= imm << 16;
8854
                    imm <<= 8;
8855
                    break;
8856
                case 3: /* XYXYXYXY */
8857
                    imm |= imm << 16;
8858
                    imm |= imm << 8;
8859
                    break;
8860
                default: /* Rotated constant.  */
8861
                    shift = (shift << 1) | (imm >> 7);
8862
                    imm |= 0x80;
8863
                    imm = imm << (32 - shift);
8864
                    shifter_out = 1;
8865
                    break;
8866
                }
8867
                tmp2 = tcg_temp_new_i32();
8868
                tcg_gen_movi_i32(tmp2, imm);
8869
                rn = (insn >> 16) & 0xf;
8870
                if (rn == 15) {
8871
                    tmp = tcg_temp_new_i32();
8872
                    tcg_gen_movi_i32(tmp, 0);
8873
                } else {
8874
                    tmp = load_reg(s, rn);
8875
                }
8876
                op = (insn >> 21) & 0xf;
8877
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
8878
                                       shifter_out, tmp, tmp2))
8879
                    goto illegal_op;
8880
                tcg_temp_free_i32(tmp2);
8881
                rd = (insn >> 8) & 0xf;
8882
                if (rd != 15) {
8883
                    store_reg(s, rd, tmp);
8884
                } else {
8885
                    tcg_temp_free_i32(tmp);
8886
                }
8887
            }
8888
        }
8889
        break;
8890
    case 12: /* Load/store single data item.  */
8891
        {
8892
        int postinc = 0;
8893
        int writeback = 0;
8894
        int user;
8895
        if ((insn & 0x01100000) == 0x01000000) {
8896
            if (disas_neon_ls_insn(env, s, insn))
8897
                goto illegal_op;
8898
            break;
8899
        }
8900
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8901
        if (rs == 15) {
8902
            if (!(insn & (1 << 20))) {
8903
                goto illegal_op;
8904
            }
8905
            if (op != 2) {
8906
                /* Byte or halfword load space with dest == r15 : memory hints.
8907
                 * Catch them early so we don't emit pointless addressing code.
8908
                 * This space is a mix of:
8909
                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
8910
                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8911
                 *     cores)
8912
                 *  unallocated hints, which must be treated as NOPs
8913
                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
8914
                 *     which is easiest for the decoding logic
8915
                 *  Some space which must UNDEF
8916
                 */
8917
                int op1 = (insn >> 23) & 3;
8918
                int op2 = (insn >> 6) & 0x3f;
8919
                if (op & 2) {
8920
                    goto illegal_op;
8921
                }
8922
                if (rn == 15) {
8923
                    /* UNPREDICTABLE or unallocated hint */
8924
                    return 0;
8925
                }
8926
                if (op1 & 1) {
8927
                    return 0; /* PLD* or unallocated hint */
8928
                }
8929
                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
8930
                    return 0; /* PLD* or unallocated hint */
8931
                }
8932
                /* UNDEF space, or an UNPREDICTABLE */
8933
                return 1;
8934
            }
8935
        }
8936
        user = IS_USER(s);
8937
        if (rn == 15) {
8938
            addr = tcg_temp_new_i32();
8939
            /* PC relative.  */
8940
            /* s->pc has already been incremented by 4.  */
8941
            imm = s->pc & 0xfffffffc;
8942
            if (insn & (1 << 23))
8943
                imm += insn & 0xfff;
8944
            else
8945
                imm -= insn & 0xfff;
8946
            tcg_gen_movi_i32(addr, imm);
8947
        } else {
8948
            addr = load_reg(s, rn);
8949
            if (insn & (1 << 23)) {
8950
                /* Positive offset.  */
8951
                imm = insn & 0xfff;
8952
                tcg_gen_addi_i32(addr, addr, imm);
8953
            } else {
8954
                imm = insn & 0xff;
8955
                switch ((insn >> 8) & 0xf) {
8956
                case 0x0: /* Shifted Register.  */
8957
                    shift = (insn >> 4) & 0xf;
8958
                    if (shift > 3) {
8959
                        tcg_temp_free_i32(addr);
8960
                        goto illegal_op;
8961
                    }
8962
                    tmp = load_reg(s, rm);
8963
                    if (shift)
8964
                        tcg_gen_shli_i32(tmp, tmp, shift);
8965
                    tcg_gen_add_i32(addr, addr, tmp);
8966
                    tcg_temp_free_i32(tmp);
8967
                    break;
8968
                case 0xc: /* Negative offset.  */
8969
                    tcg_gen_addi_i32(addr, addr, -imm);
8970
                    break;
8971
                case 0xe: /* User privilege.  */
8972
                    tcg_gen_addi_i32(addr, addr, imm);
8973
                    user = 1;
8974
                    break;
8975
                case 0x9: /* Post-decrement.  */
8976
                    imm = -imm;
8977
                    /* Fall through.  */
8978
                case 0xb: /* Post-increment.  */
8979
                    postinc = 1;
8980
                    writeback = 1;
8981
                    break;
8982
                case 0xd: /* Pre-decrement.  */
8983
                    imm = -imm;
8984
                    /* Fall through.  */
8985
                case 0xf: /* Pre-increment.  */
8986
                    tcg_gen_addi_i32(addr, addr, imm);
8987
                    writeback = 1;
8988
                    break;
8989
                default:
8990
                    tcg_temp_free_i32(addr);
8991
                    goto illegal_op;
8992
                }
8993
            }
8994
        }
8995
        if (insn & (1 << 20)) {
8996
            /* Load.  */
8997
            switch (op) {
8998
            case 0: tmp = gen_ld8u(addr, user); break;
8999
            case 4: tmp = gen_ld8s(addr, user); break;
9000
            case 1: tmp = gen_ld16u(addr, user); break;
9001
            case 5: tmp = gen_ld16s(addr, user); break;
9002
            case 2: tmp = gen_ld32(addr, user); break;
9003
            default:
9004
                tcg_temp_free_i32(addr);
9005
                goto illegal_op;
9006
            }
9007
            if (rs == 15) {
9008
                gen_bx(s, tmp);
9009
            } else {
9010
                store_reg(s, rs, tmp);
9011
            }
9012
        } else {
9013
            /* Store.  */
9014
            tmp = load_reg(s, rs);
9015
            switch (op) {
9016
            case 0: gen_st8(tmp, addr, user); break;
9017
            case 1: gen_st16(tmp, addr, user); break;
9018
            case 2: gen_st32(tmp, addr, user); break;
9019
            default:
9020
                tcg_temp_free_i32(addr);
9021
                goto illegal_op;
9022
            }
9023
        }
9024
        if (postinc)
9025
            tcg_gen_addi_i32(addr, addr, imm);
9026
        if (writeback) {
9027
            store_reg(s, rn, addr);
9028
        } else {
9029
            tcg_temp_free_i32(addr);
9030
        }
9031
        }
9032
        break;
9033
    default:
9034
        goto illegal_op;
9035
    }
9036
    return 0;
9037
illegal_op:
9038
    return 1;
9039
}
9040

    
9041
static void disas_thumb_insn(CPUState *env, DisasContext *s)
9042
{
9043
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
9044
    int32_t offset;
9045
    int i;
9046
    TCGv tmp;
9047
    TCGv tmp2;
9048
    TCGv addr;
9049

    
9050
    if (s->condexec_mask) {
9051
        cond = s->condexec_cond;
9052
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
9053
          s->condlabel = gen_new_label();
9054
          gen_test_cc(cond ^ 1, s->condlabel);
9055
          s->condjmp = 1;
9056
        }
9057
    }
9058

    
9059
    insn = lduw_code(s->pc);
9060
    s->pc += 2;
9061

    
9062
    switch (insn >> 12) {
9063
    case 0: case 1:
9064

    
9065
        rd = insn & 7;
9066
        op = (insn >> 11) & 3;
9067
        if (op == 3) {
9068
            /* add/subtract */
9069
            rn = (insn >> 3) & 7;
9070
            tmp = load_reg(s, rn);
9071
            if (insn & (1 << 10)) {
9072
                /* immediate */
9073
                tmp2 = tcg_temp_new_i32();
9074
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9075
            } else {
9076
                /* reg */
9077
                rm = (insn >> 6) & 7;
9078
                tmp2 = load_reg(s, rm);
9079
            }
9080
            if (insn & (1 << 9)) {
9081
                if (s->condexec_mask)
9082
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9083
                else
9084
                    gen_helper_sub_cc(tmp, tmp, tmp2);
9085
            } else {
9086
                if (s->condexec_mask)
9087
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9088
                else
9089
                    gen_helper_add_cc(tmp, tmp, tmp2);
9090
            }
9091
            tcg_temp_free_i32(tmp2);
9092
            store_reg(s, rd, tmp);
9093
        } else {
9094
            /* shift immediate */
9095
            rm = (insn >> 3) & 7;
9096
            shift = (insn >> 6) & 0x1f;
9097
            tmp = load_reg(s, rm);
9098
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9099
            if (!s->condexec_mask)
9100
                gen_logic_CC(tmp);
9101
            store_reg(s, rd, tmp);
9102
        }
9103
        break;
9104
    case 2: case 3:
9105
        /* arithmetic large immediate */
9106
        op = (insn >> 11) & 3;
9107
        rd = (insn >> 8) & 0x7;
9108
        if (op == 0) { /* mov */
9109
            tmp = tcg_temp_new_i32();
9110
            tcg_gen_movi_i32(tmp, insn & 0xff);
9111
            if (!s->condexec_mask)
9112
                gen_logic_CC(tmp);
9113
            store_reg(s, rd, tmp);
9114
        } else {
9115
            tmp = load_reg(s, rd);
9116
            tmp2 = tcg_temp_new_i32();
9117
            tcg_gen_movi_i32(tmp2, insn & 0xff);
9118
            switch (op) {
9119
            case 1: /* cmp */
9120
                gen_helper_sub_cc(tmp, tmp, tmp2);
9121
                tcg_temp_free_i32(tmp);
9122
                tcg_temp_free_i32(tmp2);
9123
                break;
9124
            case 2: /* add */
9125
                if (s->condexec_mask)
9126
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9127
                else
9128
                    gen_helper_add_cc(tmp, tmp, tmp2);
9129
                tcg_temp_free_i32(tmp2);
9130
                store_reg(s, rd, tmp);
9131
                break;
9132
            case 3: /* sub */
9133
                if (s->condexec_mask)
9134
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9135
                else
9136
                    gen_helper_sub_cc(tmp, tmp, tmp2);
9137
                tcg_temp_free_i32(tmp2);
9138
                store_reg(s, rd, tmp);
9139
                break;
9140
            }
9141
        }
9142
        break;
9143
    case 4:
9144
        if (insn & (1 << 11)) {
9145
            rd = (insn >> 8) & 7;
9146
            /* load pc-relative.  Bit 1 of PC is ignored.  */
9147
            val = s->pc + 2 + ((insn & 0xff) * 4);
9148
            val &= ~(uint32_t)2;
9149
            addr = tcg_temp_new_i32();
9150
            tcg_gen_movi_i32(addr, val);
9151
            tmp = gen_ld32(addr, IS_USER(s));
9152
            tcg_temp_free_i32(addr);
9153
            store_reg(s, rd, tmp);
9154
            break;
9155
        }
9156
        if (insn & (1 << 10)) {
9157
            /* data processing extended or blx */
9158
            rd = (insn & 7) | ((insn >> 4) & 8);
9159
            rm = (insn >> 3) & 0xf;
9160
            op = (insn >> 8) & 3;
9161
            switch (op) {
9162
            case 0: /* add */
9163
                tmp = load_reg(s, rd);
9164
                tmp2 = load_reg(s, rm);
9165
                tcg_gen_add_i32(tmp, tmp, tmp2);
9166
                tcg_temp_free_i32(tmp2);
9167
                store_reg(s, rd, tmp);
9168
                break;
9169
            case 1: /* cmp */
9170
                tmp = load_reg(s, rd);
9171
                tmp2 = load_reg(s, rm);
9172
                gen_helper_sub_cc(tmp, tmp, tmp2);
9173
                tcg_temp_free_i32(tmp2);
9174
                tcg_temp_free_i32(tmp);
9175
                break;
9176
            case 2: /* mov/cpy */
9177
                tmp = load_reg(s, rm);
9178
                store_reg(s, rd, tmp);
9179
                break;
9180
            case 3:/* branch [and link] exchange thumb register */
9181
                tmp = load_reg(s, rm);
9182
                if (insn & (1 << 7)) {
9183
                    ARCH(5);
9184
                    val = (uint32_t)s->pc | 1;
9185
                    tmp2 = tcg_temp_new_i32();
9186
                    tcg_gen_movi_i32(tmp2, val);
9187
                    store_reg(s, 14, tmp2);
9188
                }
9189
                /* already thumb, no need to check */
9190
                gen_bx(s, tmp);
9191
                break;
9192
            }
9193
            break;
9194
        }
9195

    
9196
        /* data processing register */
9197
        rd = insn & 7;
9198
        rm = (insn >> 3) & 7;
9199
        op = (insn >> 6) & 0xf;
9200
        if (op == 2 || op == 3 || op == 4 || op == 7) {
9201
            /* the shift/rotate ops want the operands backwards */
9202
            val = rm;
9203
            rm = rd;
9204
            rd = val;
9205
            val = 1;
9206
        } else {
9207
            val = 0;
9208
        }
9209

    
9210
        if (op == 9) { /* neg */
9211
            tmp = tcg_temp_new_i32();
9212
            tcg_gen_movi_i32(tmp, 0);
9213
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
9214
            tmp = load_reg(s, rd);
9215
        } else {
9216
            TCGV_UNUSED(tmp);
9217
        }
9218

    
9219
        tmp2 = load_reg(s, rm);
9220
        switch (op) {
9221
        case 0x0: /* and */
9222
            tcg_gen_and_i32(tmp, tmp, tmp2);
9223
            if (!s->condexec_mask)
9224
                gen_logic_CC(tmp);
9225
            break;
9226
        case 0x1: /* eor */
9227
            tcg_gen_xor_i32(tmp, tmp, tmp2);
9228
            if (!s->condexec_mask)
9229
                gen_logic_CC(tmp);
9230
            break;
9231
        case 0x2: /* lsl */
9232
            if (s->condexec_mask) {
9233
                gen_helper_shl(tmp2, tmp2, tmp);
9234
            } else {
9235
                gen_helper_shl_cc(tmp2, tmp2, tmp);
9236
                gen_logic_CC(tmp2);
9237
            }
9238
            break;
9239
        case 0x3: /* lsr */
9240
            if (s->condexec_mask) {
9241
                gen_helper_shr(tmp2, tmp2, tmp);
9242
            } else {
9243
                gen_helper_shr_cc(tmp2, tmp2, tmp);
9244
                gen_logic_CC(tmp2);
9245
            }
9246
            break;
9247
        case 0x4: /* asr */
9248
            if (s->condexec_mask) {
9249
                gen_helper_sar(tmp2, tmp2, tmp);
9250
            } else {
9251
                gen_helper_sar_cc(tmp2, tmp2, tmp);
9252
                gen_logic_CC(tmp2);
9253
            }
9254
            break;
9255
        case 0x5: /* adc */
9256
            if (s->condexec_mask)
9257
                gen_adc(tmp, tmp2);
9258
            else
9259
                gen_helper_adc_cc(tmp, tmp, tmp2);
9260
            break;
9261
        case 0x6: /* sbc */
9262
            if (s->condexec_mask)
9263
                gen_sub_carry(tmp, tmp, tmp2);
9264
            else
9265
                gen_helper_sbc_cc(tmp, tmp, tmp2);
9266
            break;
9267
        case 0x7: /* ror */
9268
            if (s->condexec_mask) {
9269
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
9270
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9271
            } else {
9272
                gen_helper_ror_cc(tmp2, tmp2, tmp);
9273
                gen_logic_CC(tmp2);
9274
            }
9275
            break;
9276
        case 0x8: /* tst */
9277
            tcg_gen_and_i32(tmp, tmp, tmp2);
9278
            gen_logic_CC(tmp);
9279
            rd = 16;
9280
            break;
9281
        case 0x9: /* neg */
9282
            if (s->condexec_mask)
9283
                tcg_gen_neg_i32(tmp, tmp2);
9284
            else
9285
                gen_helper_sub_cc(tmp, tmp, tmp2);
9286
            break;
9287
        case 0xa: /* cmp */
9288
            gen_helper_sub_cc(tmp, tmp, tmp2);
9289
            rd = 16;
9290
            break;
9291
        case 0xb: /* cmn */
9292
            gen_helper_add_cc(tmp, tmp, tmp2);
9293
            rd = 16;
9294
            break;
9295
        case 0xc: /* orr */
9296
            tcg_gen_or_i32(tmp, tmp, tmp2);
9297
            if (!s->condexec_mask)
9298
                gen_logic_CC(tmp);
9299
            break;
9300
        case 0xd: /* mul */
9301
            tcg_gen_mul_i32(tmp, tmp, tmp2);
9302
            if (!s->condexec_mask)
9303
                gen_logic_CC(tmp);
9304
            break;
9305
        case 0xe: /* bic */
9306
            tcg_gen_andc_i32(tmp, tmp, tmp2);
9307
            if (!s->condexec_mask)
9308
                gen_logic_CC(tmp);
9309
            break;
9310
        case 0xf: /* mvn */
9311
            tcg_gen_not_i32(tmp2, tmp2);
9312
            if (!s->condexec_mask)
9313
                gen_logic_CC(tmp2);
9314
            val = 1;
9315
            rm = rd;
9316
            break;
9317
        }
9318
        if (rd != 16) {
9319
            if (val) {
9320
                store_reg(s, rm, tmp2);
9321
                if (op != 0xf)
9322
                    tcg_temp_free_i32(tmp);
9323
            } else {
9324
                store_reg(s, rd, tmp);
9325
                tcg_temp_free_i32(tmp2);
9326
            }
9327
        } else {
9328
            tcg_temp_free_i32(tmp);
9329
            tcg_temp_free_i32(tmp2);
9330
        }
9331
        break;
9332

    
9333
    case 5:
9334
        /* load/store register offset.  */
9335
        rd = insn & 7;
9336
        rn = (insn >> 3) & 7;
9337
        rm = (insn >> 6) & 7;
9338
        op = (insn >> 9) & 7;
9339
        addr = load_reg(s, rn);
9340
        tmp = load_reg(s, rm);
9341
        tcg_gen_add_i32(addr, addr, tmp);
9342
        tcg_temp_free_i32(tmp);
9343

    
9344
        if (op < 3) /* store */
9345
            tmp = load_reg(s, rd);
9346

    
9347
        switch (op) {
9348
        case 0: /* str */
9349
            gen_st32(tmp, addr, IS_USER(s));
9350
            break;
9351
        case 1: /* strh */
9352
            gen_st16(tmp, addr, IS_USER(s));
9353
            break;
9354
        case 2: /* strb */
9355
            gen_st8(tmp, addr, IS_USER(s));
9356
            break;
9357
        case 3: /* ldrsb */
9358
            tmp = gen_ld8s(addr, IS_USER(s));
9359
            break;
9360
        case 4: /* ldr */
9361
            tmp = gen_ld32(addr, IS_USER(s));
9362
            break;
9363
        case 5: /* ldrh */
9364
            tmp = gen_ld16u(addr, IS_USER(s));
9365
            break;
9366
        case 6: /* ldrb */
9367
            tmp = gen_ld8u(addr, IS_USER(s));
9368
            break;
9369
        case 7: /* ldrsh */
9370
            tmp = gen_ld16s(addr, IS_USER(s));
9371
            break;
9372
        }
9373
        if (op >= 3) /* load */
9374
            store_reg(s, rd, tmp);
9375
        tcg_temp_free_i32(addr);
9376
        break;
9377

    
9378
    case 6:
9379
        /* load/store word immediate offset */
9380
        rd = insn & 7;
9381
        rn = (insn >> 3) & 7;
9382
        addr = load_reg(s, rn);
9383
        val = (insn >> 4) & 0x7c;
9384
        tcg_gen_addi_i32(addr, addr, val);
9385

    
9386
        if (insn & (1 << 11)) {
9387
            /* load */
9388
            tmp = gen_ld32(addr, IS_USER(s));
9389
            store_reg(s, rd, tmp);
9390
        } else {
9391
            /* store */
9392
            tmp = load_reg(s, rd);
9393
            gen_st32(tmp, addr, IS_USER(s));
9394
        }
9395
        tcg_temp_free_i32(addr);
9396
        break;
9397

    
9398
    case 7:
9399
        /* load/store byte immediate offset */
9400
        rd = insn & 7;
9401
        rn = (insn >> 3) & 7;
9402
        addr = load_reg(s, rn);
9403
        val = (insn >> 6) & 0x1f;
9404
        tcg_gen_addi_i32(addr, addr, val);
9405

    
9406
        if (insn & (1 << 11)) {
9407
            /* load */
9408
            tmp = gen_ld8u(addr, IS_USER(s));
9409
            store_reg(s, rd, tmp);
9410
        } else {
9411
            /* store */
9412
            tmp = load_reg(s, rd);
9413
            gen_st8(tmp, addr, IS_USER(s));
9414
        }
9415
        tcg_temp_free_i32(addr);
9416
        break;
9417

    
9418
    case 8:
9419
        /* load/store halfword immediate offset */
9420
        rd = insn & 7;
9421
        rn = (insn >> 3) & 7;
9422
        addr = load_reg(s, rn);
9423
        val = (insn >> 5) & 0x3e;
9424
        tcg_gen_addi_i32(addr, addr, val);
9425

    
9426
        if (insn & (1 << 11)) {
9427
            /* load */
9428
            tmp = gen_ld16u(addr, IS_USER(s));
9429
            store_reg(s, rd, tmp);
9430
        } else {
9431
            /* store */
9432
            tmp = load_reg(s, rd);
9433
            gen_st16(tmp, addr, IS_USER(s));
9434
        }
9435
        tcg_temp_free_i32(addr);
9436
        break;
9437

    
9438
    case 9:
9439
        /* load/store from stack */
9440
        rd = (insn >> 8) & 7;
9441
        addr = load_reg(s, 13);
9442
        val = (insn & 0xff) * 4;
9443
        tcg_gen_addi_i32(addr, addr, val);
9444

    
9445
        if (insn & (1 << 11)) {
9446
            /* load */
9447
            tmp = gen_ld32(addr, IS_USER(s));
9448
            store_reg(s, rd, tmp);
9449
        } else {
9450
            /* store */
9451
            tmp = load_reg(s, rd);
9452
            gen_st32(tmp, addr, IS_USER(s));
9453
        }
9454
        tcg_temp_free_i32(addr);
9455
        break;
9456

    
9457
    case 10:
9458
        /* add to high reg */
9459
        rd = (insn >> 8) & 7;
9460
        if (insn & (1 << 11)) {
9461
            /* SP */
9462
            tmp = load_reg(s, 13);
9463
        } else {
9464
            /* PC. bit 1 is ignored.  */
9465
            tmp = tcg_temp_new_i32();
9466
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9467
        }
9468
        val = (insn & 0xff) * 4;
9469
        tcg_gen_addi_i32(tmp, tmp, val);
9470
        store_reg(s, rd, tmp);
9471
        break;
9472

    
9473
    case 11:
9474
        /* misc */
9475
        op = (insn >> 8) & 0xf;
9476
        switch (op) {
9477
        case 0:
9478
            /* adjust stack pointer */
9479
            tmp = load_reg(s, 13);
9480
            val = (insn & 0x7f) * 4;
9481
            if (insn & (1 << 7))
9482
                val = -(int32_t)val;
9483
            tcg_gen_addi_i32(tmp, tmp, val);
9484
            store_reg(s, 13, tmp);
9485
            break;
9486

    
9487
        case 2: /* sign/zero extend.  */
9488
            ARCH(6);
9489
            rd = insn & 7;
9490
            rm = (insn >> 3) & 7;
9491
            tmp = load_reg(s, rm);
9492
            switch ((insn >> 6) & 3) {
9493
            case 0: gen_sxth(tmp); break;
9494
            case 1: gen_sxtb(tmp); break;
9495
            case 2: gen_uxth(tmp); break;
9496
            case 3: gen_uxtb(tmp); break;
9497
            }
9498
            store_reg(s, rd, tmp);
9499
            break;
9500
        case 4: case 5: case 0xc: case 0xd:
9501
            /* push/pop */
9502
            addr = load_reg(s, 13);
9503
            if (insn & (1 << 8))
9504
                offset = 4;
9505
            else
9506
                offset = 0;
9507
            for (i = 0; i < 8; i++) {
9508
                if (insn & (1 << i))
9509
                    offset += 4;
9510
            }
9511
            if ((insn & (1 << 11)) == 0) {
9512
                tcg_gen_addi_i32(addr, addr, -offset);
9513
            }
9514
            for (i = 0; i < 8; i++) {
9515
                if (insn & (1 << i)) {
9516
                    if (insn & (1 << 11)) {
9517
                        /* pop */
9518
                        tmp = gen_ld32(addr, IS_USER(s));
9519
                        store_reg(s, i, tmp);
9520
                    } else {
9521
                        /* push */
9522
                        tmp = load_reg(s, i);
9523
                        gen_st32(tmp, addr, IS_USER(s));
9524
                    }
9525
                    /* advance to the next address.  */
9526
                    tcg_gen_addi_i32(addr, addr, 4);
9527
                }
9528
            }
9529
            TCGV_UNUSED(tmp);
9530
            if (insn & (1 << 8)) {
9531
                if (insn & (1 << 11)) {
9532
                    /* pop pc */
9533
                    tmp = gen_ld32(addr, IS_USER(s));
9534
                    /* don't set the pc until the rest of the instruction
9535
                       has completed */
9536
                } else {
9537
                    /* push lr */
9538
                    tmp = load_reg(s, 14);
9539
                    gen_st32(tmp, addr, IS_USER(s));
9540
                }
9541
                tcg_gen_addi_i32(addr, addr, 4);
9542
            }
9543
            if ((insn & (1 << 11)) == 0) {
9544
                tcg_gen_addi_i32(addr, addr, -offset);
9545
            }
9546
            /* write back the new stack pointer */
9547
            store_reg(s, 13, addr);
9548
            /* set the new PC value */
9549
            if ((insn & 0x0900) == 0x0900) {
9550
                store_reg_from_load(env, s, 15, tmp);
9551
            }
9552
            break;
9553

    
9554
        case 1: case 3: case 9: case 11: /* czb */
9555
            rm = insn & 7;
9556
            tmp = load_reg(s, rm);
9557
            s->condlabel = gen_new_label();
9558
            s->condjmp = 1;
9559
            if (insn & (1 << 11))
9560
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9561
            else
9562
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9563
            tcg_temp_free_i32(tmp);
9564
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9565
            val = (uint32_t)s->pc + 2;
9566
            val += offset;
9567
            gen_jmp(s, val);
9568
            break;
9569

    
9570
        case 15: /* IT, nop-hint.  */
9571
            if ((insn & 0xf) == 0) {
9572
                gen_nop_hint(s, (insn >> 4) & 0xf);
9573
                break;
9574
            }
9575
            /* If Then.  */
9576
            s->condexec_cond = (insn >> 4) & 0xe;
9577
            s->condexec_mask = insn & 0x1f;
9578
            /* No actual code generated for this insn, just setup state.  */
9579
            break;
9580

    
9581
        case 0xe: /* bkpt */
9582
            ARCH(5);
9583
            gen_exception_insn(s, 2, EXCP_BKPT);
9584
            break;
9585

    
9586
        case 0xa: /* rev */
9587
            ARCH(6);
9588
            rn = (insn >> 3) & 0x7;
9589
            rd = insn & 0x7;
9590
            tmp = load_reg(s, rn);
9591
            switch ((insn >> 6) & 3) {
9592
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9593
            case 1: gen_rev16(tmp); break;
9594
            case 3: gen_revsh(tmp); break;
9595
            default: goto illegal_op;
9596
            }
9597
            store_reg(s, rd, tmp);
9598
            break;
9599

    
9600
        case 6: /* cps */
9601
            ARCH(6);
9602
            if (IS_USER(s))
9603
                break;
9604
            if (IS_M(env)) {
9605
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9606
                /* PRIMASK */
9607
                if (insn & 1) {
9608
                    addr = tcg_const_i32(16);
9609
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9610
                    tcg_temp_free_i32(addr);
9611
                }
9612
                /* FAULTMASK */
9613
                if (insn & 2) {
9614
                    addr = tcg_const_i32(17);
9615
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9616
                    tcg_temp_free_i32(addr);
9617
                }
9618
                tcg_temp_free_i32(tmp);
9619
                gen_lookup_tb(s);
9620
            } else {
9621
                if (insn & (1 << 4))
9622
                    shift = CPSR_A | CPSR_I | CPSR_F;
9623
                else
9624
                    shift = 0;
9625
                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9626
            }
9627
            break;
9628

    
9629
        default:
9630
            goto undef;
9631
        }
9632
        break;
9633

    
9634
    case 12:
9635
    {
9636
        /* load/store multiple */
9637
        TCGv loaded_var;
9638
        TCGV_UNUSED(loaded_var);
9639
        rn = (insn >> 8) & 0x7;
9640
        addr = load_reg(s, rn);
9641
        for (i = 0; i < 8; i++) {
9642
            if (insn & (1 << i)) {
9643
                if (insn & (1 << 11)) {
9644
                    /* load */
9645
                    tmp = gen_ld32(addr, IS_USER(s));
9646
                    if (i == rn) {
9647
                        loaded_var = tmp;
9648
                    } else {
9649
                        store_reg(s, i, tmp);
9650
                    }
9651
                } else {
9652
                    /* store */
9653
                    tmp = load_reg(s, i);
9654
                    gen_st32(tmp, addr, IS_USER(s));
9655
                }
9656
                /* advance to the next address */
9657
                tcg_gen_addi_i32(addr, addr, 4);
9658
            }
9659
        }
9660
        if ((insn & (1 << rn)) == 0) {
9661
            /* base reg not in list: base register writeback */
9662
            store_reg(s, rn, addr);
9663
        } else {
9664
            /* base reg in list: if load, complete it now */
9665
            if (insn & (1 << 11)) {
9666
                store_reg(s, rn, loaded_var);
9667
            }
9668
            tcg_temp_free_i32(addr);
9669
        }
9670
        break;
9671
    }
9672
    case 13:
9673
        /* conditional branch or swi */
9674
        cond = (insn >> 8) & 0xf;
9675
        if (cond == 0xe)
9676
            goto undef;
9677

    
9678
        if (cond == 0xf) {
9679
            /* swi */
9680
            gen_set_pc_im(s->pc);
9681
            s->is_jmp = DISAS_SWI;
9682
            break;
9683
        }
9684
        /* generate a conditional jump to next instruction */
9685
        s->condlabel = gen_new_label();
9686
        gen_test_cc(cond ^ 1, s->condlabel);
9687
        s->condjmp = 1;
9688

    
9689
        /* jump to the offset */
9690
        val = (uint32_t)s->pc + 2;
9691
        offset = ((int32_t)insn << 24) >> 24;
9692
        val += offset << 1;
9693
        gen_jmp(s, val);
9694
        break;
9695

    
9696
    case 14:
9697
        if (insn & (1 << 11)) {
9698
            if (disas_thumb2_insn(env, s, insn))
9699
              goto undef32;
9700
            break;
9701
        }
9702
        /* unconditional branch */
9703
        val = (uint32_t)s->pc;
9704
        offset = ((int32_t)insn << 21) >> 21;
9705
        val += (offset << 1) + 2;
9706
        gen_jmp(s, val);
9707
        break;
9708

    
9709
    case 15:
9710
        if (disas_thumb2_insn(env, s, insn))
9711
            goto undef32;
9712
        break;
9713
    }
9714
    return;
9715
undef32:
9716
    gen_exception_insn(s, 4, EXCP_UDEF);
9717
    return;
9718
illegal_op:
9719
undef:
9720
    gen_exception_insn(s, 2, EXCP_UDEF);
9721
}
9722

    
9723
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9724
   basic block 'tb'. If search_pc is TRUE, also generate PC
9725
   information for each intermediate instruction. */
9726
static inline void gen_intermediate_code_internal(CPUState *env,
9727
                                                  TranslationBlock *tb,
9728
                                                  int search_pc)
9729
{
9730
    DisasContext dc1, *dc = &dc1;
9731
    CPUBreakpoint *bp;
9732
    uint16_t *gen_opc_end;
9733
    int j, lj;
9734
    target_ulong pc_start;
9735
    uint32_t next_page_start;
9736
    int num_insns;
9737
    int max_insns;
9738

    
9739
    /* generate intermediate code */
9740
    pc_start = tb->pc;
9741

    
9742
    dc->tb = tb;
9743

    
9744
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9745

    
9746
    dc->is_jmp = DISAS_NEXT;
9747
    dc->pc = pc_start;
9748
    dc->singlestep_enabled = env->singlestep_enabled;
9749
    dc->condjmp = 0;
9750
    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9751
    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9752
    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9753
#if !defined(CONFIG_USER_ONLY)
9754
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9755
#endif
9756
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9757
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9758
    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9759
    cpu_F0s = tcg_temp_new_i32();
9760
    cpu_F1s = tcg_temp_new_i32();
9761
    cpu_F0d = tcg_temp_new_i64();
9762
    cpu_F1d = tcg_temp_new_i64();
9763
    cpu_V0 = cpu_F0d;
9764
    cpu_V1 = cpu_F1d;
9765
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
9766
    cpu_M0 = tcg_temp_new_i64();
9767
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9768
    lj = -1;
9769
    num_insns = 0;
9770
    max_insns = tb->cflags & CF_COUNT_MASK;
9771
    if (max_insns == 0)
9772
        max_insns = CF_COUNT_MASK;
9773

    
9774
    gen_icount_start();
9775

    
9776
    tcg_clear_temp_count();
9777

    
9778
    /* A note on handling of the condexec (IT) bits:
9779
     *
9780
     * We want to avoid the overhead of having to write the updated condexec
9781
     * bits back to the CPUState for every instruction in an IT block. So:
9782
     * (1) if the condexec bits are not already zero then we write
9783
     * zero back into the CPUState now. This avoids complications trying
9784
     * to do it at the end of the block. (For example if we don't do this
9785
     * it's hard to identify whether we can safely skip writing condexec
9786
     * at the end of the TB, which we definitely want to do for the case
9787
     * where a TB doesn't do anything with the IT state at all.)
9788
     * (2) if we are going to leave the TB then we call gen_set_condexec()
9789
     * which will write the correct value into CPUState if zero is wrong.
9790
     * This is done both for leaving the TB at the end, and for leaving
9791
     * it because of an exception we know will happen, which is done in
9792
     * gen_exception_insn(). The latter is necessary because we need to
9793
     * leave the TB with the PC/IT state just prior to execution of the
9794
     * instruction which caused the exception.
9795
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9796
     * then the CPUState will be wrong and we need to reset it.
9797
     * This is handled in the same way as restoration of the
9798
     * PC in these situations: we will be called again with search_pc=1
9799
     * and generate a mapping of the condexec bits for each PC in
9800
     * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9801
     * this to restore the condexec bits.
9802
     *
9803
     * Note that there are no instructions which can read the condexec
9804
     * bits, and none which can write non-static values to them, so
9805
     * we don't need to care about whether CPUState is correct in the
9806
     * middle of a TB.
9807
     */
9808

    
9809
    /* Reset the conditional execution bits immediately. This avoids
9810
       complications trying to do it at the end of the block.  */
9811
    if (dc->condexec_mask || dc->condexec_cond)
9812
      {
9813
        TCGv tmp = tcg_temp_new_i32();
9814
        tcg_gen_movi_i32(tmp, 0);
9815
        store_cpu_field(tmp, condexec_bits);
9816
      }
9817
    do {
9818
#ifdef CONFIG_USER_ONLY
9819
        /* Intercept jump to the magic kernel page.  */
9820
        if (dc->pc >= 0xffff0000) {
9821
            /* We always get here via a jump, so know we are not in a
9822
               conditional execution block.  */
9823
            gen_exception(EXCP_KERNEL_TRAP);
9824
            dc->is_jmp = DISAS_UPDATE;
9825
            break;
9826
        }
9827
#else
9828
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9829
            /* We always get here via a jump, so know we are not in a
9830
               conditional execution block.  */
9831
            gen_exception(EXCP_EXCEPTION_EXIT);
9832
            dc->is_jmp = DISAS_UPDATE;
9833
            break;
9834
        }
9835
#endif
9836

    
9837
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9838
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9839
                if (bp->pc == dc->pc) {
9840
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
9841
                    /* Advance PC so that clearing the breakpoint will
9842
                       invalidate this TB.  */
9843
                    dc->pc += 2;
9844
                    goto done_generating;
9845
                    break;
9846
                }
9847
            }
9848
        }
9849
        if (search_pc) {
9850
            j = gen_opc_ptr - gen_opc_buf;
9851
            if (lj < j) {
9852
                lj++;
9853
                while (lj < j)
9854
                    gen_opc_instr_start[lj++] = 0;
9855
            }
9856
            gen_opc_pc[lj] = dc->pc;
9857
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9858
            gen_opc_instr_start[lj] = 1;
9859
            gen_opc_icount[lj] = num_insns;
9860
        }
9861

    
9862
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9863
            gen_io_start();
9864

    
9865
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
9866
            tcg_gen_debug_insn_start(dc->pc);
9867
        }
9868

    
9869
        if (dc->thumb) {
9870
            disas_thumb_insn(env, dc);
9871
            if (dc->condexec_mask) {
9872
                dc->condexec_cond = (dc->condexec_cond & 0xe)
9873
                                   | ((dc->condexec_mask >> 4) & 1);
9874
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9875
                if (dc->condexec_mask == 0) {
9876
                    dc->condexec_cond = 0;
9877
                }
9878
            }
9879
        } else {
9880
            disas_arm_insn(env, dc);
9881
        }
9882

    
9883
        if (dc->condjmp && !dc->is_jmp) {
9884
            gen_set_label(dc->condlabel);
9885
            dc->condjmp = 0;
9886
        }
9887

    
9888
        if (tcg_check_temp_count()) {
9889
            fprintf(stderr, "TCG temporary leak before %08x\n", dc->pc);
9890
        }
9891

    
9892
        /* Translation stops when a conditional branch is encountered.
9893
         * Otherwise the subsequent code could get translated several times.
9894
         * Also stop translation when a page boundary is reached.  This
9895
         * ensures prefetch aborts occur at the right place.  */
9896
        num_insns ++;
9897
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9898
             !env->singlestep_enabled &&
9899
             !singlestep &&
9900
             dc->pc < next_page_start &&
9901
             num_insns < max_insns);
9902

    
9903
    if (tb->cflags & CF_LAST_IO) {
9904
        if (dc->condjmp) {
9905
            /* FIXME:  This can theoretically happen with self-modifying
9906
               code.  */
9907
            cpu_abort(env, "IO on conditional branch instruction");
9908
        }
9909
        gen_io_end();
9910
    }
9911

    
9912
    /* At this stage dc->condjmp will only be set when the skipped
9913
       instruction was a conditional branch or trap, and the PC has
9914
       already been written.  */
9915
    if (unlikely(env->singlestep_enabled)) {
9916
        /* Make sure the pc is updated, and raise a debug exception.  */
9917
        if (dc->condjmp) {
9918
            gen_set_condexec(dc);
9919
            if (dc->is_jmp == DISAS_SWI) {
9920
                gen_exception(EXCP_SWI);
9921
            } else {
9922
                gen_exception(EXCP_DEBUG);
9923
            }
9924
            gen_set_label(dc->condlabel);
9925
        }
9926
        if (dc->condjmp || !dc->is_jmp) {
9927
            gen_set_pc_im(dc->pc);
9928
            dc->condjmp = 0;
9929
        }
9930
        gen_set_condexec(dc);
9931
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9932
            gen_exception(EXCP_SWI);
9933
        } else {
9934
            /* FIXME: Single stepping a WFI insn will not halt
9935
               the CPU.  */
9936
            gen_exception(EXCP_DEBUG);
9937
        }
9938
    } else {
9939
        /* While branches must always occur at the end of an IT block,
9940
           there are a few other things that can cause us to terminate
9941
           the TB in the middel of an IT block:
9942
            - Exception generating instructions (bkpt, swi, undefined).
9943
            - Page boundaries.
9944
            - Hardware watchpoints.
9945
           Hardware breakpoints have already been handled and skip this code.
9946
         */
9947
        gen_set_condexec(dc);
9948
        switch(dc->is_jmp) {
9949
        case DISAS_NEXT:
9950
            gen_goto_tb(dc, 1, dc->pc);
9951
            break;
9952
        default:
9953
        case DISAS_JUMP:
9954
        case DISAS_UPDATE:
9955
            /* indicate that the hash table must be used to find the next TB */
9956
            tcg_gen_exit_tb(0);
9957
            break;
9958
        case DISAS_TB_JUMP:
9959
            /* nothing more to generate */
9960
            break;
9961
        case DISAS_WFI:
9962
            gen_helper_wfi();
9963
            break;
9964
        case DISAS_SWI:
9965
            gen_exception(EXCP_SWI);
9966
            break;
9967
        }
9968
        if (dc->condjmp) {
9969
            gen_set_label(dc->condlabel);
9970
            gen_set_condexec(dc);
9971
            gen_goto_tb(dc, 1, dc->pc);
9972
            dc->condjmp = 0;
9973
        }
9974
    }
9975

    
9976
done_generating:
9977
    gen_icount_end(tb, num_insns);
9978
    *gen_opc_ptr = INDEX_op_end;
9979

    
9980
#ifdef DEBUG_DISAS
9981
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9982
        qemu_log("----------------\n");
9983
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9984
        log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);
9985
        qemu_log("\n");
9986
    }
9987
#endif
9988
    if (search_pc) {
9989
        j = gen_opc_ptr - gen_opc_buf;
9990
        lj++;
9991
        while (lj <= j)
9992
            gen_opc_instr_start[lj++] = 0;
9993
    } else {
9994
        tb->size = dc->pc - pc_start;
9995
        tb->icount = num_insns;
9996
    }
9997
}
9998

    
9999
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
10000
{
10001
    gen_intermediate_code_internal(env, tb, 0);
10002
}
10003

    
10004
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
10005
{
10006
    gen_intermediate_code_internal(env, tb, 1);
10007
}
10008

    
10009
static const char *cpu_mode_names[16] = {
10010
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10011
  "???", "???", "???", "und", "???", "???", "???", "sys"
10012
};
10013

    
10014
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
10015
                    int flags)
10016
{
10017
    int i;
10018
#if 0
10019
    union {
10020
        uint32_t i;
10021
        float s;
10022
    } s0, s1;
10023
    CPU_DoubleU d;
10024
    /* ??? This assumes float64 and double have the same layout.
10025
       Oh well, it's only debug dumps.  */
10026
    union {
10027
        float64 f64;
10028
        double d;
10029
    } d0;
10030
#endif
10031
    uint32_t psr;
10032

    
10033
    for(i=0;i<16;i++) {
10034
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10035
        if ((i % 4) == 3)
10036
            cpu_fprintf(f, "\n");
10037
        else
10038
            cpu_fprintf(f, " ");
10039
    }
10040
    psr = cpsr_read(env);
10041
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10042
                psr,
10043
                psr & (1 << 31) ? 'N' : '-',
10044
                psr & (1 << 30) ? 'Z' : '-',
10045
                psr & (1 << 29) ? 'C' : '-',
10046
                psr & (1 << 28) ? 'V' : '-',
10047
                psr & CPSR_T ? 'T' : 'A',
10048
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10049

    
10050
#if 0
10051
    for (i = 0; i < 16; i++) {
10052
        d.d = env->vfp.regs[i];
10053
        s0.i = d.l.lower;
10054
        s1.i = d.l.upper;
10055
        d0.f64 = d.d;
10056
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
10057
                    i * 2, (int)s0.i, s0.s,
10058
                    i * 2 + 1, (int)s1.i, s1.s,
10059
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
10060
                    d0.d);
10061
    }
10062
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10063
#endif
10064
}
10065

    
10066
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
10067
{
10068
    env->regs[15] = gen_opc_pc[pc_pos];
10069
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
10070
}