Statistics
| Branch: | Revision:

root / target-arm / translate.c @ a492892c

History | View | Annotate | Download (342.6 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
                case 4:
3075
                case 5:
3076
                case 6:
3077
                case 7:
3078
                    /* VCVTB, VCVTT: only present with the halfprec extension,
3079
                     * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3080
                     */
3081
                    if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3082
                        return 1;
3083
                    }
3084
                    /* Otherwise fall through */
3085
                default:
3086
                    /* One source operand.  */
3087
                    gen_mov_F0_vreg(dp, rm);
3088
                    break;
3089
                }
3090
            } else {
3091
                /* Two source operands.  */
3092
                gen_mov_F0_vreg(dp, rn);
3093
                gen_mov_F1_vreg(dp, rm);
3094
            }
3095

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3655
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3656

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3877

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5806

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

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

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

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

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

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

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

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

    
6385
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
6386
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
6387
            /* TEECR */
6388
            if (IS_USER(s))
6389
                return 1;
6390
            tmp = load_reg(s, rt);
6391
            gen_helper_set_teecr(cpu_env, tmp);
6392
            tcg_temp_free_i32(tmp);
6393
            return 0;
6394
        }
6395
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
6396
            /* TEEHBR */
6397
            if (IS_USER(s) && (env->teecr & 1))
6398
                return 1;
6399
            tmp = load_reg(s, rt);
6400
            store_cpu_field(tmp, teehbr);
6401
            return 0;
6402
        }
6403
    }
6404
    return 1;
6405
}
6406

    
6407
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
6408
{
6409
    int cpnum;
6410

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

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

    
6446

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

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

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

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

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

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

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

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

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

    
6543
static void gen_clrex(DisasContext *s)
6544
{
6545
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6546
}
6547

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

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

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

    
6636
    insn = ldl_code(s->pc);
6637
    s->pc += 4;
6638

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

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

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

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

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

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

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

    
7048
        op1 = (insn >> 21) & 0xf;
7049
        set_cc = (insn >> 20) & 1;
7050
        logic_cc = table_logic_cc[op1] & set_cc;
7051

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

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

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

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

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

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

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

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

    
7903
static int
7904
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7905
{
7906
    int logic_cc;
7907

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

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

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

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

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

    
8029
    insn = lduw_code(s->pc);
8030
    s->pc += 2;
8031
    insn |= (uint32_t)insn_hw1 << 16;
8032

    
8033
    if ((insn & 0xf800e800) != 0xf000e800) {
8034
        ARCH(6T2);
8035
    }
8036

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

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

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

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

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

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

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

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

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

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

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

    
9056
    insn = lduw_code(s->pc);
9057
    s->pc += 2;
9058

    
9059
    switch (insn >> 12) {
9060
    case 0: case 1:
9061

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

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

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

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

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

    
9341
        if (op < 3) /* store */
9342
            tmp = load_reg(s, rd);
9343

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
9578
        case 0xe: /* bkpt */
9579
            ARCH(5);
9580
            gen_exception_insn(s, 2, EXCP_BKPT);
9581
            break;
9582

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

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

    
9626
        default:
9627
            goto undef;
9628
        }
9629
        break;
9630

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

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

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

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

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

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

    
9736
    /* generate intermediate code */
9737
    pc_start = tb->pc;
9738

    
9739
    dc->tb = tb;
9740

    
9741
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9742

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

    
9771
    gen_icount_start();
9772

    
9773
    tcg_clear_temp_count();
9774

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

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

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

    
9859
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9860
            gen_io_start();
9861

    
9862
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
9863
            tcg_gen_debug_insn_start(dc->pc);
9864
        }
9865

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

    
9880
        if (dc->condjmp && !dc->is_jmp) {
9881
            gen_set_label(dc->condlabel);
9882
            dc->condjmp = 0;
9883
        }
9884

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

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

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

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

    
9973
done_generating:
9974
    gen_icount_end(tb, num_insns);
9975
    *gen_opc_ptr = INDEX_op_end;
9976

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

    
9996
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9997
{
9998
    gen_intermediate_code_internal(env, tb, 0);
9999
}
10000

    
10001
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
10002
{
10003
    gen_intermediate_code_internal(env, tb, 1);
10004
}
10005

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

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

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

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

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