Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 87f19eb2

History | View | Annotate | Download (341.9 kB)

1
/*
2
 *  ARM translation
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *  Copyright (c) 2005-2007 CodeSourcery
6
 *  Copyright (c) 2007 OpenedHand, Ltd.
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20
 */
21
#include <stdarg.h>
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <string.h>
25
#include <inttypes.h>
26

    
27
#include "cpu.h"
28
#include "disas.h"
29
#include "tcg-op.h"
30
#include "qemu-log.h"
31

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

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

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

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

    
70
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
71

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

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

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

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

    
99
#include "gen-icount.h"
100

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
197

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
925
#undef VFP_OP2
926

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1146
#define ARM_CP_RW_BIT        (1 << 20)
1147

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1235
IWMMXT_OP_ENV_SIZE(unpackl)
1236
IWMMXT_OP_ENV_SIZE(unpackh)
1237

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

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

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

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

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

    
1272
IWMMXT_OP(msadb)
1273

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2368
    return 0;
2369
}
2370

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

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

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

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

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

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

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

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

    
2438
    return 1;
2439
}
2440

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3427
                if (insn & (1 << 24)) /* pre-decrement */
3428
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3429

    
3430
                if (dp)
3431
                    offset = 8;
3432
                else
3433
                    offset = 4;
3434
                for (i = 0; i < n; i++) {
3435
                    if (insn & ARM_CP_RW_BIT) {
3436
                        /* load */
3437
                        gen_vfp_ld(s, dp, addr);
3438
                        gen_mov_vreg_F0(dp, rd + i);
3439
                    } else {
3440
                        /* store */
3441
                        gen_mov_F0_vreg(dp, rd + i);
3442
                        gen_vfp_st(s, dp, addr);
3443
                    }
3444
                    tcg_gen_addi_i32(addr, addr, offset);
3445
                }
3446
                if (insn & (1 << 21)) {
3447
                    /* writeback */
3448
                    if (insn & (1 << 24))
3449
                        offset = -offset * n;
3450
                    else if (dp && (insn & 1))
3451
                        offset = 4;
3452
                    else
3453
                        offset = 0;
3454

    
3455
                    if (offset != 0)
3456
                        tcg_gen_addi_i32(addr, addr, offset);
3457
                    store_reg(s, rn, addr);
3458
                } else {
3459
                    tcg_temp_free_i32(addr);
3460
                }
3461
            }
3462
        }
3463
        break;
3464
    default:
3465
        /* Should never happen.  */
3466
        return 1;
3467
    }
3468
    return 0;
3469
}
3470

    
3471
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3472
{
3473
    TranslationBlock *tb;
3474

    
3475
    tb = s->tb;
3476
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3477
        tcg_gen_goto_tb(n);
3478
        gen_set_pc_im(dest);
3479
        tcg_gen_exit_tb((tcg_target_long)tb + n);
3480
    } else {
3481
        gen_set_pc_im(dest);
3482
        tcg_gen_exit_tb(0);
3483
    }
3484
}
3485

    
3486
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3487
{
3488
    if (unlikely(s->singlestep_enabled)) {
3489
        /* An indirect jump so that we still trigger the debug exception.  */
3490
        if (s->thumb)
3491
            dest |= 1;
3492
        gen_bx_im(s, dest);
3493
    } else {
3494
        gen_goto_tb(s, 0, dest);
3495
        s->is_jmp = DISAS_TB_JUMP;
3496
    }
3497
}
3498

    
3499
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3500
{
3501
    if (x)
3502
        tcg_gen_sari_i32(t0, t0, 16);
3503
    else
3504
        gen_sxth(t0);
3505
    if (y)
3506
        tcg_gen_sari_i32(t1, t1, 16);
3507
    else
3508
        gen_sxth(t1);
3509
    tcg_gen_mul_i32(t0, t0, t1);
3510
}
3511

    
3512
/* Return the mask of PSR bits set by a MSR instruction.  */
3513
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3514
    uint32_t mask;
3515

    
3516
    mask = 0;
3517
    if (flags & (1 << 0))
3518
        mask |= 0xff;
3519
    if (flags & (1 << 1))
3520
        mask |= 0xff00;
3521
    if (flags & (1 << 2))
3522
        mask |= 0xff0000;
3523
    if (flags & (1 << 3))
3524
        mask |= 0xff000000;
3525

    
3526
    /* Mask out undefined bits.  */
3527
    mask &= ~CPSR_RESERVED;
3528
    if (!arm_feature(env, ARM_FEATURE_V4T))
3529
        mask &= ~CPSR_T;
3530
    if (!arm_feature(env, ARM_FEATURE_V5))
3531
        mask &= ~CPSR_Q; /* V5TE in reality*/
3532
    if (!arm_feature(env, ARM_FEATURE_V6))
3533
        mask &= ~(CPSR_E | CPSR_GE);
3534
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3535
        mask &= ~CPSR_IT;
3536
    /* Mask out execution state bits.  */
3537
    if (!spsr)
3538
        mask &= ~CPSR_EXEC;
3539
    /* Mask out privileged bits.  */
3540
    if (IS_USER(s))
3541
        mask &= CPSR_USER;
3542
    return mask;
3543
}
3544

    
3545
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3546
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3547
{
3548
    TCGv tmp;
3549
    if (spsr) {
3550
        /* ??? This is also undefined in system mode.  */
3551
        if (IS_USER(s))
3552
            return 1;
3553

    
3554
        tmp = load_cpu_field(spsr);
3555
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3556
        tcg_gen_andi_i32(t0, t0, mask);
3557
        tcg_gen_or_i32(tmp, tmp, t0);
3558
        store_cpu_field(tmp, spsr);
3559
    } else {
3560
        gen_set_cpsr(t0, mask);
3561
    }
3562
    tcg_temp_free_i32(t0);
3563
    gen_lookup_tb(s);
3564
    return 0;
3565
}
3566

    
3567
/* Returns nonzero if access to the PSR is not permitted.  */
3568
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3569
{
3570
    TCGv tmp;
3571
    tmp = tcg_temp_new_i32();
3572
    tcg_gen_movi_i32(tmp, val);
3573
    return gen_set_psr(s, mask, spsr, tmp);
3574
}
3575

    
3576
/* Generate an old-style exception return. Marks pc as dead. */
3577
static void gen_exception_return(DisasContext *s, TCGv pc)
3578
{
3579
    TCGv tmp;
3580
    store_reg(s, 15, pc);
3581
    tmp = load_cpu_field(spsr);
3582
    gen_set_cpsr(tmp, 0xffffffff);
3583
    tcg_temp_free_i32(tmp);
3584
    s->is_jmp = DISAS_UPDATE;
3585
}
3586

    
3587
/* Generate a v6 exception return.  Marks both values as dead.  */
3588
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3589
{
3590
    gen_set_cpsr(cpsr, 0xffffffff);
3591
    tcg_temp_free_i32(cpsr);
3592
    store_reg(s, 15, pc);
3593
    s->is_jmp = DISAS_UPDATE;
3594
}
3595

    
3596
static inline void
3597
gen_set_condexec (DisasContext *s)
3598
{
3599
    if (s->condexec_mask) {
3600
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3601
        TCGv tmp = tcg_temp_new_i32();
3602
        tcg_gen_movi_i32(tmp, val);
3603
        store_cpu_field(tmp, condexec_bits);
3604
    }
3605
}
3606

    
3607
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3608
{
3609
    gen_set_condexec(s);
3610
    gen_set_pc_im(s->pc - offset);
3611
    gen_exception(excp);
3612
    s->is_jmp = DISAS_JUMP;
3613
}
3614

    
3615
static void gen_nop_hint(DisasContext *s, int val)
3616
{
3617
    switch (val) {
3618
    case 3: /* wfi */
3619
        gen_set_pc_im(s->pc);
3620
        s->is_jmp = DISAS_WFI;
3621
        break;
3622
    case 2: /* wfe */
3623
    case 4: /* sev */
3624
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3625
    default: /* nop */
3626
        break;
3627
    }
3628
}
3629

    
3630
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3631

    
3632
static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
3633
{
3634
    switch (size) {
3635
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3636
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3637
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3638
    default: abort();
3639
    }
3640
}
3641

    
3642
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3643
{
3644
    switch (size) {
3645
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3646
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3647
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3648
    default: return;
3649
    }
3650
}
3651

    
3652
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3653
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3654
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3655
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3656
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3657

    
3658
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3659
    switch ((size << 1) | u) { \
3660
    case 0: \
3661
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3662
        break; \
3663
    case 1: \
3664
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3665
        break; \
3666
    case 2: \
3667
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3668
        break; \
3669
    case 3: \
3670
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3671
        break; \
3672
    case 4: \
3673
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3674
        break; \
3675
    case 5: \
3676
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3677
        break; \
3678
    default: return 1; \
3679
    }} while (0)
3680

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

    
3704
static TCGv neon_load_scratch(int scratch)
3705
{
3706
    TCGv tmp = tcg_temp_new_i32();
3707
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3708
    return tmp;
3709
}
3710

    
3711
static void neon_store_scratch(int scratch, TCGv var)
3712
{
3713
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3714
    tcg_temp_free_i32(var);
3715
}
3716

    
3717
static inline TCGv neon_get_scalar(int size, int reg)
3718
{
3719
    TCGv tmp;
3720
    if (size == 1) {
3721
        tmp = neon_load_reg(reg & 7, reg >> 4);
3722
        if (reg & 8) {
3723
            gen_neon_dup_high16(tmp);
3724
        } else {
3725
            gen_neon_dup_low16(tmp);
3726
        }
3727
    } else {
3728
        tmp = neon_load_reg(reg & 15, reg >> 4);
3729
    }
3730
    return tmp;
3731
}
3732

    
3733
static int gen_neon_unzip(int rd, int rm, int size, int q)
3734
{
3735
    TCGv tmp, tmp2;
3736
    if (!q && size == 2) {
3737
        return 1;
3738
    }
3739
    tmp = tcg_const_i32(rd);
3740
    tmp2 = tcg_const_i32(rm);
3741
    if (q) {
3742
        switch (size) {
3743
        case 0:
3744
            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3745
            break;
3746
        case 1:
3747
            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3748
            break;
3749
        case 2:
3750
            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3751
            break;
3752
        default:
3753
            abort();
3754
        }
3755
    } else {
3756
        switch (size) {
3757
        case 0:
3758
            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3759
            break;
3760
        case 1:
3761
            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3762
            break;
3763
        default:
3764
            abort();
3765
        }
3766
    }
3767
    tcg_temp_free_i32(tmp);
3768
    tcg_temp_free_i32(tmp2);
3769
    return 0;
3770
}
3771

    
3772
static int gen_neon_zip(int rd, int rm, int size, int q)
3773
{
3774
    TCGv tmp, tmp2;
3775
    if (!q && size == 2) {
3776
        return 1;
3777
    }
3778
    tmp = tcg_const_i32(rd);
3779
    tmp2 = tcg_const_i32(rm);
3780
    if (q) {
3781
        switch (size) {
3782
        case 0:
3783
            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3784
            break;
3785
        case 1:
3786
            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3787
            break;
3788
        case 2:
3789
            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3790
            break;
3791
        default:
3792
            abort();
3793
        }
3794
    } else {
3795
        switch (size) {
3796
        case 0:
3797
            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3798
            break;
3799
        case 1:
3800
            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3801
            break;
3802
        default:
3803
            abort();
3804
        }
3805
    }
3806
    tcg_temp_free_i32(tmp);
3807
    tcg_temp_free_i32(tmp2);
3808
    return 0;
3809
}
3810

    
3811
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3812
{
3813
    TCGv rd, tmp;
3814

    
3815
    rd = tcg_temp_new_i32();
3816
    tmp = tcg_temp_new_i32();
3817

    
3818
    tcg_gen_shli_i32(rd, t0, 8);
3819
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3820
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3821
    tcg_gen_or_i32(rd, rd, tmp);
3822

    
3823
    tcg_gen_shri_i32(t1, t1, 8);
3824
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3825
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3826
    tcg_gen_or_i32(t1, t1, tmp);
3827
    tcg_gen_mov_i32(t0, rd);
3828

    
3829
    tcg_temp_free_i32(tmp);
3830
    tcg_temp_free_i32(rd);
3831
}
3832

    
3833
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3834
{
3835
    TCGv rd, tmp;
3836

    
3837
    rd = tcg_temp_new_i32();
3838
    tmp = tcg_temp_new_i32();
3839

    
3840
    tcg_gen_shli_i32(rd, t0, 16);
3841
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3842
    tcg_gen_or_i32(rd, rd, tmp);
3843
    tcg_gen_shri_i32(t1, t1, 16);
3844
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3845
    tcg_gen_or_i32(t1, t1, tmp);
3846
    tcg_gen_mov_i32(t0, rd);
3847

    
3848
    tcg_temp_free_i32(tmp);
3849
    tcg_temp_free_i32(rd);
3850
}
3851

    
3852

    
3853
static struct {
3854
    int nregs;
3855
    int interleave;
3856
    int spacing;
3857
} neon_ls_element_type[11] = {
3858
    {4, 4, 1},
3859
    {4, 4, 2},
3860
    {4, 1, 1},
3861
    {4, 2, 1},
3862
    {3, 3, 1},
3863
    {3, 3, 2},
3864
    {3, 1, 1},
3865
    {1, 1, 1},
3866
    {2, 2, 1},
3867
    {2, 2, 2},
3868
    {2, 1, 1}
3869
};
3870

    
3871
/* Translate a NEON load/store element instruction.  Return nonzero if the
3872
   instruction is invalid.  */
3873
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3874
{
3875
    int rd, rn, rm;
3876
    int op;
3877
    int nregs;
3878
    int interleave;
3879
    int spacing;
3880
    int stride;
3881
    int size;
3882
    int reg;
3883
    int pass;
3884
    int load;
3885
    int shift;
3886
    int n;
3887
    TCGv addr;
3888
    TCGv tmp;
3889
    TCGv tmp2;
3890
    TCGv_i64 tmp64;
3891

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

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

    
4165
        base = load_reg(s, rn);
4166
        if (rm == 13) {
4167
            tcg_gen_addi_i32(base, base, stride);
4168
        } else {
4169
            TCGv index;
4170
            index = load_reg(s, rm);
4171
            tcg_gen_add_i32(base, base, index);
4172
            tcg_temp_free_i32(index);
4173
        }
4174
        store_reg(s, rn, base);
4175
    }
4176
    return 0;
4177
}
4178

    
4179
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4180
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4181
{
4182
    tcg_gen_and_i32(t, t, c);
4183
    tcg_gen_andc_i32(f, f, c);
4184
    tcg_gen_or_i32(dest, t, f);
4185
}
4186

    
4187
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4188
{
4189
    switch (size) {
4190
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4191
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4192
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4193
    default: abort();
4194
    }
4195
}
4196

    
4197
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4198
{
4199
    switch (size) {
4200
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4201
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4202
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4203
    default: abort();
4204
    }
4205
}
4206

    
4207
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4208
{
4209
    switch (size) {
4210
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4211
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4212
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4213
    default: abort();
4214
    }
4215
}
4216

    
4217
static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4218
{
4219
    switch (size) {
4220
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4221
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4222
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4223
    default: abort();
4224
    }
4225
}
4226

    
4227
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4228
                                         int q, int u)
4229
{
4230
    if (q) {
4231
        if (u) {
4232
            switch (size) {
4233
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4234
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4235
            default: abort();
4236
            }
4237
        } else {
4238
            switch (size) {
4239
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4240
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4241
            default: abort();
4242
            }
4243
        }
4244
    } else {
4245
        if (u) {
4246
            switch (size) {
4247
            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4248
            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4249
            default: abort();
4250
            }
4251
        } else {
4252
            switch (size) {
4253
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4254
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4255
            default: abort();
4256
            }
4257
        }
4258
    }
4259
}
4260

    
4261
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4262
{
4263
    if (u) {
4264
        switch (size) {
4265
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4266
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4267
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4268
        default: abort();
4269
        }
4270
    } else {
4271
        switch (size) {
4272
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4273
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4274
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4275
        default: abort();
4276
        }
4277
    }
4278
    tcg_temp_free_i32(src);
4279
}
4280

    
4281
static inline void gen_neon_addl(int size)
4282
{
4283
    switch (size) {
4284
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4285
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4286
    case 2: tcg_gen_add_i64(CPU_V001); break;
4287
    default: abort();
4288
    }
4289
}
4290

    
4291
static inline void gen_neon_subl(int size)
4292
{
4293
    switch (size) {
4294
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4295
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4296
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4297
    default: abort();
4298
    }
4299
}
4300

    
4301
static inline void gen_neon_negl(TCGv_i64 var, int size)
4302
{
4303
    switch (size) {
4304
    case 0: gen_helper_neon_negl_u16(var, var); break;
4305
    case 1: gen_helper_neon_negl_u32(var, var); break;
4306
    case 2: gen_helper_neon_negl_u64(var, var); break;
4307
    default: abort();
4308
    }
4309
}
4310

    
4311
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4312
{
4313
    switch (size) {
4314
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4315
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4316
    default: abort();
4317
    }
4318
}
4319

    
4320
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4321
{
4322
    TCGv_i64 tmp;
4323

    
4324
    switch ((size << 1) | u) {
4325
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4326
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4327
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4328
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4329
    case 4:
4330
        tmp = gen_muls_i64_i32(a, b);
4331
        tcg_gen_mov_i64(dest, tmp);
4332
        tcg_temp_free_i64(tmp);
4333
        break;
4334
    case 5:
4335
        tmp = gen_mulu_i64_i32(a, b);
4336
        tcg_gen_mov_i64(dest, tmp);
4337
        tcg_temp_free_i64(tmp);
4338
        break;
4339
    default: abort();
4340
    }
4341

    
4342
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4343
       Don't forget to clean them now.  */
4344
    if (size < 2) {
4345
        tcg_temp_free_i32(a);
4346
        tcg_temp_free_i32(b);
4347
    }
4348
}
4349

    
4350
static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
4351
{
4352
    if (op) {
4353
        if (u) {
4354
            gen_neon_unarrow_sats(size, dest, src);
4355
        } else {
4356
            gen_neon_narrow(size, dest, src);
4357
        }
4358
    } else {
4359
        if (u) {
4360
            gen_neon_narrow_satu(size, dest, src);
4361
        } else {
4362
            gen_neon_narrow_sats(size, dest, src);
4363
        }
4364
    }
4365
}
4366

    
4367
/* Symbolic constants for op fields for Neon 3-register same-length.
4368
 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4369
 * table A7-9.
4370
 */
4371
#define NEON_3R_VHADD 0
4372
#define NEON_3R_VQADD 1
4373
#define NEON_3R_VRHADD 2
4374
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4375
#define NEON_3R_VHSUB 4
4376
#define NEON_3R_VQSUB 5
4377
#define NEON_3R_VCGT 6
4378
#define NEON_3R_VCGE 7
4379
#define NEON_3R_VSHL 8
4380
#define NEON_3R_VQSHL 9
4381
#define NEON_3R_VRSHL 10
4382
#define NEON_3R_VQRSHL 11
4383
#define NEON_3R_VMAX 12
4384
#define NEON_3R_VMIN 13
4385
#define NEON_3R_VABD 14
4386
#define NEON_3R_VABA 15
4387
#define NEON_3R_VADD_VSUB 16
4388
#define NEON_3R_VTST_VCEQ 17
4389
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4390
#define NEON_3R_VMUL 19
4391
#define NEON_3R_VPMAX 20
4392
#define NEON_3R_VPMIN 21
4393
#define NEON_3R_VQDMULH_VQRDMULH 22
4394
#define NEON_3R_VPADD 23
4395
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4396
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4397
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4398
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4399
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4400
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4401

    
4402
static const uint8_t neon_3r_sizes[] = {
4403
    [NEON_3R_VHADD] = 0x7,
4404
    [NEON_3R_VQADD] = 0xf,
4405
    [NEON_3R_VRHADD] = 0x7,
4406
    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4407
    [NEON_3R_VHSUB] = 0x7,
4408
    [NEON_3R_VQSUB] = 0xf,
4409
    [NEON_3R_VCGT] = 0x7,
4410
    [NEON_3R_VCGE] = 0x7,
4411
    [NEON_3R_VSHL] = 0xf,
4412
    [NEON_3R_VQSHL] = 0xf,
4413
    [NEON_3R_VRSHL] = 0xf,
4414
    [NEON_3R_VQRSHL] = 0xf,
4415
    [NEON_3R_VMAX] = 0x7,
4416
    [NEON_3R_VMIN] = 0x7,
4417
    [NEON_3R_VABD] = 0x7,
4418
    [NEON_3R_VABA] = 0x7,
4419
    [NEON_3R_VADD_VSUB] = 0xf,
4420
    [NEON_3R_VTST_VCEQ] = 0x7,
4421
    [NEON_3R_VML] = 0x7,
4422
    [NEON_3R_VMUL] = 0x7,
4423
    [NEON_3R_VPMAX] = 0x7,
4424
    [NEON_3R_VPMIN] = 0x7,
4425
    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4426
    [NEON_3R_VPADD] = 0x7,
4427
    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4428
    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4429
    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4430
    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4431
    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4432
    [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4433
};
4434

    
4435
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4436
 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4437
 * table A7-13.
4438
 */
4439
#define NEON_2RM_VREV64 0
4440
#define NEON_2RM_VREV32 1
4441
#define NEON_2RM_VREV16 2
4442
#define NEON_2RM_VPADDL 4
4443
#define NEON_2RM_VPADDL_U 5
4444
#define NEON_2RM_VCLS 8
4445
#define NEON_2RM_VCLZ 9
4446
#define NEON_2RM_VCNT 10
4447
#define NEON_2RM_VMVN 11
4448
#define NEON_2RM_VPADAL 12
4449
#define NEON_2RM_VPADAL_U 13
4450
#define NEON_2RM_VQABS 14
4451
#define NEON_2RM_VQNEG 15
4452
#define NEON_2RM_VCGT0 16
4453
#define NEON_2RM_VCGE0 17
4454
#define NEON_2RM_VCEQ0 18
4455
#define NEON_2RM_VCLE0 19
4456
#define NEON_2RM_VCLT0 20
4457
#define NEON_2RM_VABS 22
4458
#define NEON_2RM_VNEG 23
4459
#define NEON_2RM_VCGT0_F 24
4460
#define NEON_2RM_VCGE0_F 25
4461
#define NEON_2RM_VCEQ0_F 26
4462
#define NEON_2RM_VCLE0_F 27
4463
#define NEON_2RM_VCLT0_F 28
4464
#define NEON_2RM_VABS_F 30
4465
#define NEON_2RM_VNEG_F 31
4466
#define NEON_2RM_VSWP 32
4467
#define NEON_2RM_VTRN 33
4468
#define NEON_2RM_VUZP 34
4469
#define NEON_2RM_VZIP 35
4470
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4471
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4472
#define NEON_2RM_VSHLL 38
4473
#define NEON_2RM_VCVT_F16_F32 44
4474
#define NEON_2RM_VCVT_F32_F16 46
4475
#define NEON_2RM_VRECPE 56
4476
#define NEON_2RM_VRSQRTE 57
4477
#define NEON_2RM_VRECPE_F 58
4478
#define NEON_2RM_VRSQRTE_F 59
4479
#define NEON_2RM_VCVT_FS 60
4480
#define NEON_2RM_VCVT_FU 61
4481
#define NEON_2RM_VCVT_SF 62
4482
#define NEON_2RM_VCVT_UF 63
4483

    
4484
static int neon_2rm_is_float_op(int op)
4485
{
4486
    /* Return true if this neon 2reg-misc op is float-to-float */
4487
    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4488
            op >= NEON_2RM_VRECPE_F);
4489
}
4490

    
4491
/* Each entry in this array has bit n set if the insn allows
4492
 * size value n (otherwise it will UNDEF). Since unallocated
4493
 * op values will have no bits set they always UNDEF.
4494
 */
4495
static const uint8_t neon_2rm_sizes[] = {
4496
    [NEON_2RM_VREV64] = 0x7,
4497
    [NEON_2RM_VREV32] = 0x3,
4498
    [NEON_2RM_VREV16] = 0x1,
4499
    [NEON_2RM_VPADDL] = 0x7,
4500
    [NEON_2RM_VPADDL_U] = 0x7,
4501
    [NEON_2RM_VCLS] = 0x7,
4502
    [NEON_2RM_VCLZ] = 0x7,
4503
    [NEON_2RM_VCNT] = 0x1,
4504
    [NEON_2RM_VMVN] = 0x1,
4505
    [NEON_2RM_VPADAL] = 0x7,
4506
    [NEON_2RM_VPADAL_U] = 0x7,
4507
    [NEON_2RM_VQABS] = 0x7,
4508
    [NEON_2RM_VQNEG] = 0x7,
4509
    [NEON_2RM_VCGT0] = 0x7,
4510
    [NEON_2RM_VCGE0] = 0x7,
4511
    [NEON_2RM_VCEQ0] = 0x7,
4512
    [NEON_2RM_VCLE0] = 0x7,
4513
    [NEON_2RM_VCLT0] = 0x7,
4514
    [NEON_2RM_VABS] = 0x7,
4515
    [NEON_2RM_VNEG] = 0x7,
4516
    [NEON_2RM_VCGT0_F] = 0x4,
4517
    [NEON_2RM_VCGE0_F] = 0x4,
4518
    [NEON_2RM_VCEQ0_F] = 0x4,
4519
    [NEON_2RM_VCLE0_F] = 0x4,
4520
    [NEON_2RM_VCLT0_F] = 0x4,
4521
    [NEON_2RM_VABS_F] = 0x4,
4522
    [NEON_2RM_VNEG_F] = 0x4,
4523
    [NEON_2RM_VSWP] = 0x1,
4524
    [NEON_2RM_VTRN] = 0x7,
4525
    [NEON_2RM_VUZP] = 0x7,
4526
    [NEON_2RM_VZIP] = 0x7,
4527
    [NEON_2RM_VMOVN] = 0x7,
4528
    [NEON_2RM_VQMOVN] = 0x7,
4529
    [NEON_2RM_VSHLL] = 0x7,
4530
    [NEON_2RM_VCVT_F16_F32] = 0x2,
4531
    [NEON_2RM_VCVT_F32_F16] = 0x2,
4532
    [NEON_2RM_VRECPE] = 0x4,
4533
    [NEON_2RM_VRSQRTE] = 0x4,
4534
    [NEON_2RM_VRECPE_F] = 0x4,
4535
    [NEON_2RM_VRSQRTE_F] = 0x4,
4536
    [NEON_2RM_VCVT_FS] = 0x4,
4537
    [NEON_2RM_VCVT_FU] = 0x4,
4538
    [NEON_2RM_VCVT_SF] = 0x4,
4539
    [NEON_2RM_VCVT_UF] = 0x4,
4540
};
4541

    
4542
/* Translate a NEON data processing instruction.  Return nonzero if the
4543
   instruction is invalid.
4544
   We process data in a mixture of 32-bit and 64-bit chunks.
4545
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4546

    
4547
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4548
{
4549
    int op;
4550
    int q;
4551
    int rd, rn, rm;
4552
    int size;
4553
    int shift;
4554
    int pass;
4555
    int count;
4556
    int pairwise;
4557
    int u;
4558
    uint32_t imm, mask;
4559
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4560
    TCGv_i64 tmp64;
4561

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

    
4708
        if (pairwise && q) {
4709
            /* All the pairwise insns UNDEF if Q is set */
4710
            return 1;
4711
        }
4712

    
4713
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4714

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

    
4989
        /* Save the result.  For elementwise operations we can put it
4990
           straight into the destination register.  For pairwise operations
4991
           we have to be careful to avoid clobbering the source operands.  */
4992
        if (pairwise && rd == rm) {
4993
            neon_store_scratch(pass, tmp);
4994
        } else {
4995
            neon_store_reg(rd, pass, tmp);
4996
        }
4997

    
4998
        } /* for pass */
4999
        if (pairwise && rd == rm) {
5000
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5001
                tmp = neon_load_scratch(pass);
5002
                neon_store_reg(rd, pass, tmp);
5003
            }
5004
        }
5005
        /* End of 3 register same size operations.  */
5006
    } else if (insn & (1 << 4)) {
5007
        if ((insn & 0x00380080) != 0) {
5008
            /* Two registers and shift.  */
5009
            op = (insn >> 8) & 0xf;
5010
            if (insn & (1 << 7)) {
5011
                /* 64-bit shift. */
5012
                if (op > 7) {
5013
                    return 1;
5014
                }
5015
                size = 3;
5016
            } else {
5017
                size = 2;
5018
                while ((insn & (1 << (size + 19))) == 0)
5019
                    size--;
5020
            }
5021
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5022
            /* To avoid excessive dumplication of ops we implement shift
5023
               by immediate using the variable shift operations.  */
5024
            if (op < 8) {
5025
                /* Shift by immediate:
5026
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
5027
                if (q && ((rd | rm) & 1)) {
5028
                    return 1;
5029
                }
5030
                if (!u && (op == 4 || op == 6)) {
5031
                    return 1;
5032
                }
5033
                /* Right shifts are encoded as N - shift, where N is the
5034
                   element size in bits.  */
5035
                if (op <= 4)
5036
                    shift = shift - (1 << (size + 3));
5037
                if (size == 3) {
5038
                    count = q + 1;
5039
                } else {
5040
                    count = q ? 4: 2;
5041
                }
5042
                switch (size) {
5043
                case 0:
5044
                    imm = (uint8_t) shift;
5045
                    imm |= imm << 8;
5046
                    imm |= imm << 16;
5047
                    break;
5048
                case 1:
5049
                    imm = (uint16_t) shift;
5050
                    imm |= imm << 16;
5051
                    break;
5052
                case 2:
5053
                case 3:
5054
                    imm = shift;
5055
                    break;
5056
                default:
5057
                    abort();
5058
                }
5059

    
5060
                for (pass = 0; pass < count; pass++) {
5061
                    if (size == 3) {
5062
                        neon_load_reg64(cpu_V0, rm + pass);
5063
                        tcg_gen_movi_i64(cpu_V1, imm);
5064
                        switch (op) {
5065
                        case 0:  /* VSHR */
5066
                        case 1:  /* VSRA */
5067
                            if (u)
5068
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5069
                            else
5070
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5071
                            break;
5072
                        case 2: /* VRSHR */
5073
                        case 3: /* VRSRA */
5074
                            if (u)
5075
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5076
                            else
5077
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5078
                            break;
5079
                        case 4: /* VSRI */
5080
                        case 5: /* VSHL, VSLI */
5081
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5082
                            break;
5083
                        case 6: /* VQSHLU */
5084
                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5085
                                                      cpu_V0, cpu_V1);
5086
                            break;
5087
                        case 7: /* VQSHL */
5088
                            if (u) {
5089
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5090
                                                         cpu_V0, cpu_V1);
5091
                            } else {
5092
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5093
                                                         cpu_V0, cpu_V1);
5094
                            }
5095
                            break;
5096
                        }
5097
                        if (op == 1 || op == 3) {
5098
                            /* Accumulate.  */
5099
                            neon_load_reg64(cpu_V1, rd + pass);
5100
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5101
                        } else if (op == 4 || (op == 5 && u)) {
5102
                            /* Insert */
5103
                            neon_load_reg64(cpu_V1, rd + pass);
5104
                            uint64_t mask;
5105
                            if (shift < -63 || shift > 63) {
5106
                                mask = 0;
5107
                            } else {
5108
                                if (op == 4) {
5109
                                    mask = 0xffffffffffffffffull >> -shift;
5110
                                } else {
5111
                                    mask = 0xffffffffffffffffull << shift;
5112
                                }
5113
                            }
5114
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5115
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5116
                        }
5117
                        neon_store_reg64(cpu_V0, rd + pass);
5118
                    } else { /* size < 3 */
5119
                        /* Operands in T0 and T1.  */
5120
                        tmp = neon_load_reg(rm, pass);
5121
                        tmp2 = tcg_temp_new_i32();
5122
                        tcg_gen_movi_i32(tmp2, imm);
5123
                        switch (op) {
5124
                        case 0:  /* VSHR */
5125
                        case 1:  /* VSRA */
5126
                            GEN_NEON_INTEGER_OP(shl);
5127
                            break;
5128
                        case 2: /* VRSHR */
5129
                        case 3: /* VRSRA */
5130
                            GEN_NEON_INTEGER_OP(rshl);
5131
                            break;
5132
                        case 4: /* VSRI */
5133
                        case 5: /* VSHL, VSLI */
5134
                            switch (size) {
5135
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5136
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5137
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5138
                            default: abort();
5139
                            }
5140
                            break;
5141
                        case 6: /* VQSHLU */
5142
                            switch (size) {
5143
                            case 0:
5144
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
5145
                                                         tmp, tmp2);
5146
                                break;
5147
                            case 1:
5148
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
5149
                                                          tmp, tmp2);
5150
                                break;
5151
                            case 2:
5152
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
5153
                                                          tmp, tmp2);
5154
                                break;
5155
                            default:
5156
                                abort();
5157
                            }
5158
                            break;
5159
                        case 7: /* VQSHL */
5160
                            GEN_NEON_INTEGER_OP_ENV(qshl);
5161
                            break;
5162
                        }
5163
                        tcg_temp_free_i32(tmp2);
5164

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

    
5294
                    gen_neon_widen(cpu_V0, tmp, size, u);
5295

    
5296
                    if (shift != 0) {
5297
                        /* The shift is less than the width of the source
5298
                           type, so we can just shift the whole register.  */
5299
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5300
                        /* Widen the result of shift: we need to clear
5301
                         * the potential overflow bits resulting from
5302
                         * left bits of the narrow input appearing as
5303
                         * right bits of left the neighbour narrow
5304
                         * input.  */
5305
                        if (size < 2 || !u) {
5306
                            uint64_t imm64;
5307
                            if (size == 0) {
5308
                                imm = (0xffu >> (8 - shift));
5309
                                imm |= imm << 16;
5310
                            } else if (size == 1) {
5311
                                imm = 0xffff >> (16 - shift);
5312
                            } else {
5313
                                /* size == 2 */
5314
                                imm = 0xffffffff >> (32 - shift);
5315
                            }
5316
                            if (size < 2) {
5317
                                imm64 = imm | (((uint64_t)imm) << 32);
5318
                            } else {
5319
                                imm64 = imm;
5320
                            }
5321
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5322
                        }
5323
                    }
5324
                    neon_store_reg64(cpu_V0, rd + pass);
5325
                }
5326
            } else if (op >= 14) {
5327
                /* VCVT fixed-point.  */
5328
                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5329
                    return 1;
5330
                }
5331
                /* We have already masked out the must-be-1 top bit of imm6,
5332
                 * hence this 32-shift where the ARM ARM has 64-imm6.
5333
                 */
5334
                shift = 32 - shift;
5335
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5336
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5337
                    if (!(op & 1)) {
5338
                        if (u)
5339
                            gen_vfp_ulto(0, shift, 1);
5340
                        else
5341
                            gen_vfp_slto(0, shift, 1);
5342
                    } else {
5343
                        if (u)
5344
                            gen_vfp_toul(0, shift, 1);
5345
                        else
5346
                            gen_vfp_tosl(0, shift, 1);
5347
                    }
5348
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5349
                }
5350
            } else {
5351
                return 1;
5352
            }
5353
        } else { /* (insn & 0x00380080) == 0 */
5354
            int invert;
5355
            if (q && (rd & 1)) {
5356
                return 1;
5357
            }
5358

    
5359
            op = (insn >> 8) & 0xf;
5360
            /* One register and immediate.  */
5361
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5362
            invert = (insn & (1 << 5)) != 0;
5363
            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5364
             * We choose to not special-case this and will behave as if a
5365
             * valid constant encoding of 0 had been given.
5366
             */
5367
            switch (op) {
5368
            case 0: case 1:
5369
                /* no-op */
5370
                break;
5371
            case 2: case 3:
5372
                imm <<= 8;
5373
                break;
5374
            case 4: case 5:
5375
                imm <<= 16;
5376
                break;
5377
            case 6: case 7:
5378
                imm <<= 24;
5379
                break;
5380
            case 8: case 9:
5381
                imm |= imm << 16;
5382
                break;
5383
            case 10: case 11:
5384
                imm = (imm << 8) | (imm << 24);
5385
                break;
5386
            case 12:
5387
                imm = (imm << 8) | 0xff;
5388
                break;
5389
            case 13:
5390
                imm = (imm << 16) | 0xffff;
5391
                break;
5392
            case 14:
5393
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
5394
                if (invert)
5395
                    imm = ~imm;
5396
                break;
5397
            case 15:
5398
                if (invert) {
5399
                    return 1;
5400
                }
5401
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5402
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5403
                break;
5404
            }
5405
            if (invert)
5406
                imm = ~imm;
5407

    
5408
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5409
                if (op & 1 && op < 12) {
5410
                    tmp = neon_load_reg(rd, pass);
5411
                    if (invert) {
5412
                        /* The immediate value has already been inverted, so
5413
                           BIC becomes AND.  */
5414
                        tcg_gen_andi_i32(tmp, tmp, imm);
5415
                    } else {
5416
                        tcg_gen_ori_i32(tmp, tmp, imm);
5417
                    }
5418
                } else {
5419
                    /* VMOV, VMVN.  */
5420
                    tmp = tcg_temp_new_i32();
5421
                    if (op == 14 && invert) {
5422
                        int n;
5423
                        uint32_t val;
5424
                        val = 0;
5425
                        for (n = 0; n < 4; n++) {
5426
                            if (imm & (1 << (n + (pass & 1) * 4)))
5427
                                val |= 0xff << (n * 8);
5428
                        }
5429
                        tcg_gen_movi_i32(tmp, val);
5430
                    } else {
5431
                        tcg_gen_movi_i32(tmp, imm);
5432
                    }
5433
                }
5434
                neon_store_reg(rd, pass, tmp);
5435
            }
5436
        }
5437
    } else { /* (insn & 0x00800010 == 0x00800000) */
5438
        if (size != 3) {
5439
            op = (insn >> 8) & 0xf;
5440
            if ((insn & (1 << 6)) == 0) {
5441
                /* Three registers of different lengths.  */
5442
                int src1_wide;
5443
                int src2_wide;
5444
                int prewiden;
5445
                /* undefreq: bit 0 : UNDEF if size != 0
5446
                 *           bit 1 : UNDEF if size == 0
5447
                 *           bit 2 : UNDEF if U == 1
5448
                 * Note that [1:0] set implies 'always UNDEF'
5449
                 */
5450
                int undefreq;
5451
                /* prewiden, src1_wide, src2_wide, undefreq */
5452
                static const int neon_3reg_wide[16][4] = {
5453
                    {1, 0, 0, 0}, /* VADDL */
5454
                    {1, 1, 0, 0}, /* VADDW */
5455
                    {1, 0, 0, 0}, /* VSUBL */
5456
                    {1, 1, 0, 0}, /* VSUBW */
5457
                    {0, 1, 1, 0}, /* VADDHN */
5458
                    {0, 0, 0, 0}, /* VABAL */
5459
                    {0, 1, 1, 0}, /* VSUBHN */
5460
                    {0, 0, 0, 0}, /* VABDL */
5461
                    {0, 0, 0, 0}, /* VMLAL */
5462
                    {0, 0, 0, 6}, /* VQDMLAL */
5463
                    {0, 0, 0, 0}, /* VMLSL */
5464
                    {0, 0, 0, 6}, /* VQDMLSL */
5465
                    {0, 0, 0, 0}, /* Integer VMULL */
5466
                    {0, 0, 0, 2}, /* VQDMULL */
5467
                    {0, 0, 0, 5}, /* Polynomial VMULL */
5468
                    {0, 0, 0, 3}, /* Reserved: always UNDEF */
5469
                };
5470

    
5471
                prewiden = neon_3reg_wide[op][0];
5472
                src1_wide = neon_3reg_wide[op][1];
5473
                src2_wide = neon_3reg_wide[op][2];
5474
                undefreq = neon_3reg_wide[op][3];
5475

    
5476
                if (((undefreq & 1) && (size != 0)) ||
5477
                    ((undefreq & 2) && (size == 0)) ||
5478
                    ((undefreq & 4) && u)) {
5479
                    return 1;
5480
                }
5481
                if ((src1_wide && (rn & 1)) ||
5482
                    (src2_wide && (rm & 1)) ||
5483
                    (!src2_wide && (rd & 1))) {
5484
                    return 1;
5485
                }
5486

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

    
5744
                    for (pass = 0; pass < 2; pass++) {
5745
                        if (pass == 0) {
5746
                            tmp = neon_load_reg(rn, 0);
5747
                        } else {
5748
                            tmp = tmp3;
5749
                            tmp2 = tmp4;
5750
                        }
5751
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5752
                        if (op != 11) {
5753
                            neon_load_reg64(cpu_V1, rd + pass);
5754
                        }
5755
                        switch (op) {
5756
                        case 6:
5757
                            gen_neon_negl(cpu_V0, size);
5758
                            /* Fall through */
5759
                        case 2:
5760
                            gen_neon_addl(size);
5761
                            break;
5762
                        case 3: case 7:
5763
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5764
                            if (op == 7) {
5765
                                gen_neon_negl(cpu_V0, size);
5766
                            }
5767
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5768
                            break;
5769
                        case 10:
5770
                            /* no-op */
5771
                            break;
5772
                        case 11:
5773
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5774
                            break;
5775
                        default:
5776
                            abort();
5777
                        }
5778
                        neon_store_reg64(cpu_V0, rd + pass);
5779
                    }
5780

    
5781

    
5782
                    break;
5783
                default: /* 14 and 15 are RESERVED */
5784
                    return 1;
5785
                }
5786
            }
5787
        } else { /* size == 3 */
5788
            if (!u) {
5789
                /* Extract.  */
5790
                imm = (insn >> 8) & 0xf;
5791

    
5792
                if (imm > 7 && !q)
5793
                    return 1;
5794

    
5795
                if (q && ((rd | rn | rm) & 1)) {
5796
                    return 1;
5797
                }
5798

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

    
6293
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
6294
{
6295
    int crn = (insn >> 16) & 0xf;
6296
    int crm = insn & 0xf;
6297
    int op1 = (insn >> 21) & 7;
6298
    int op2 = (insn >> 5) & 7;
6299
    int rt = (insn >> 12) & 0xf;
6300
    TCGv tmp;
6301

    
6302
    /* Minimal set of debug registers, since we don't support debug */
6303
    if (op1 == 0 && crn == 0 && op2 == 0) {
6304
        switch (crm) {
6305
        case 0:
6306
            /* DBGDIDR: just RAZ. In particular this means the
6307
             * "debug architecture version" bits will read as
6308
             * a reserved value, which should cause Linux to
6309
             * not try to use the debug hardware.
6310
             */
6311
            tmp = tcg_const_i32(0);
6312
            store_reg(s, rt, tmp);
6313
            return 0;
6314
        case 1:
6315
        case 2:
6316
            /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
6317
             * don't implement memory mapped debug components
6318
             */
6319
            if (ENABLE_ARCH_7) {
6320
                tmp = tcg_const_i32(0);
6321
                store_reg(s, rt, tmp);
6322
                return 0;
6323
            }
6324
            break;
6325
        default:
6326
            break;
6327
        }
6328
    }
6329

    
6330
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
6331
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
6332
            /* TEECR */
6333
            if (IS_USER(s))
6334
                return 1;
6335
            tmp = load_cpu_field(teecr);
6336
            store_reg(s, rt, tmp);
6337
            return 0;
6338
        }
6339
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
6340
            /* TEEHBR */
6341
            if (IS_USER(s) && (env->teecr & 1))
6342
                return 1;
6343
            tmp = load_cpu_field(teehbr);
6344
            store_reg(s, rt, tmp);
6345
            return 0;
6346
        }
6347
    }
6348
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
6349
            op1, crn, crm, op2);
6350
    return 1;
6351
}
6352

    
6353
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
6354
{
6355
    int crn = (insn >> 16) & 0xf;
6356
    int crm = insn & 0xf;
6357
    int op1 = (insn >> 21) & 7;
6358
    int op2 = (insn >> 5) & 7;
6359
    int rt = (insn >> 12) & 0xf;
6360
    TCGv tmp;
6361

    
6362
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
6363
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
6364
            /* TEECR */
6365
            if (IS_USER(s))
6366
                return 1;
6367
            tmp = load_reg(s, rt);
6368
            gen_helper_set_teecr(cpu_env, tmp);
6369
            tcg_temp_free_i32(tmp);
6370
            return 0;
6371
        }
6372
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
6373
            /* TEEHBR */
6374
            if (IS_USER(s) && (env->teecr & 1))
6375
                return 1;
6376
            tmp = load_reg(s, rt);
6377
            store_cpu_field(tmp, teehbr);
6378
            return 0;
6379
        }
6380
    }
6381
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
6382
            op1, crn, crm, op2);
6383
    return 1;
6384
}
6385

    
6386
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
6387
{
6388
    int cpnum;
6389

    
6390
    cpnum = (insn >> 8) & 0xf;
6391
    if (arm_feature(env, ARM_FEATURE_XSCALE)
6392
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6393
        return 1;
6394

    
6395
    switch (cpnum) {
6396
      case 0:
6397
      case 1:
6398
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6399
            return disas_iwmmxt_insn(env, s, insn);
6400
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6401
            return disas_dsp_insn(env, s, insn);
6402
        }
6403
        return 1;
6404
    case 10:
6405
    case 11:
6406
        return disas_vfp_insn (env, s, insn);
6407
    case 14:
6408
        /* Coprocessors 7-15 are architecturally reserved by ARM.
6409
           Unfortunately Intel decided to ignore this.  */
6410
        if (arm_feature(env, ARM_FEATURE_XSCALE))
6411
            goto board;
6412
        if (insn & (1 << 20))
6413
            return disas_cp14_read(env, s, insn);
6414
        else
6415
            return disas_cp14_write(env, s, insn);
6416
    case 15:
6417
        return disas_cp15_insn (env, s, insn);
6418
    default:
6419
    board:
6420
        /* Unknown coprocessor.  See if the board has hooked it.  */
6421
        return disas_cp_insn (env, s, insn);
6422
    }
6423
}
6424

    
6425

    
6426
/* Store a 64-bit value to a register pair.  Clobbers val.  */
6427
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6428
{
6429
    TCGv tmp;
6430
    tmp = tcg_temp_new_i32();
6431
    tcg_gen_trunc_i64_i32(tmp, val);
6432
    store_reg(s, rlow, tmp);
6433
    tmp = tcg_temp_new_i32();
6434
    tcg_gen_shri_i64(val, val, 32);
6435
    tcg_gen_trunc_i64_i32(tmp, val);
6436
    store_reg(s, rhigh, tmp);
6437
}
6438

    
6439
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
6440
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6441
{
6442
    TCGv_i64 tmp;
6443
    TCGv tmp2;
6444

    
6445
    /* Load value and extend to 64 bits.  */
6446
    tmp = tcg_temp_new_i64();
6447
    tmp2 = load_reg(s, rlow);
6448
    tcg_gen_extu_i32_i64(tmp, tmp2);
6449
    tcg_temp_free_i32(tmp2);
6450
    tcg_gen_add_i64(val, val, tmp);
6451
    tcg_temp_free_i64(tmp);
6452
}
6453

    
6454
/* load and add a 64-bit value from a register pair.  */
6455
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6456
{
6457
    TCGv_i64 tmp;
6458
    TCGv tmpl;
6459
    TCGv tmph;
6460

    
6461
    /* Load 64-bit value rd:rn.  */
6462
    tmpl = load_reg(s, rlow);
6463
    tmph = load_reg(s, rhigh);
6464
    tmp = tcg_temp_new_i64();
6465
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6466
    tcg_temp_free_i32(tmpl);
6467
    tcg_temp_free_i32(tmph);
6468
    tcg_gen_add_i64(val, val, tmp);
6469
    tcg_temp_free_i64(tmp);
6470
}
6471

    
6472
/* Set N and Z flags from a 64-bit value.  */
6473
static void gen_logicq_cc(TCGv_i64 val)
6474
{
6475
    TCGv tmp = tcg_temp_new_i32();
6476
    gen_helper_logicq_cc(tmp, val);
6477
    gen_logic_CC(tmp);
6478
    tcg_temp_free_i32(tmp);
6479
}
6480

    
6481
/* Load/Store exclusive instructions are implemented by remembering
6482
   the value/address loaded, and seeing if these are the same
6483
   when the store is performed. This should be is sufficient to implement
6484
   the architecturally mandated semantics, and avoids having to monitor
6485
   regular stores.
6486

6487
   In system emulation mode only one CPU will be running at once, so
6488
   this sequence is effectively atomic.  In user emulation mode we
6489
   throw an exception and handle the atomic operation elsewhere.  */
6490
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6491
                               TCGv addr, int size)
6492
{
6493
    TCGv tmp;
6494

    
6495
    switch (size) {
6496
    case 0:
6497
        tmp = gen_ld8u(addr, IS_USER(s));
6498
        break;
6499
    case 1:
6500
        tmp = gen_ld16u(addr, IS_USER(s));
6501
        break;
6502
    case 2:
6503
    case 3:
6504
        tmp = gen_ld32(addr, IS_USER(s));
6505
        break;
6506
    default:
6507
        abort();
6508
    }
6509
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6510
    store_reg(s, rt, tmp);
6511
    if (size == 3) {
6512
        TCGv tmp2 = tcg_temp_new_i32();
6513
        tcg_gen_addi_i32(tmp2, addr, 4);
6514
        tmp = gen_ld32(tmp2, IS_USER(s));
6515
        tcg_temp_free_i32(tmp2);
6516
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6517
        store_reg(s, rt2, tmp);
6518
    }
6519
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6520
}
6521

    
6522
static void gen_clrex(DisasContext *s)
6523
{
6524
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6525
}
6526

    
6527
#ifdef CONFIG_USER_ONLY
6528
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6529
                                TCGv addr, int size)
6530
{
6531
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
6532
    tcg_gen_movi_i32(cpu_exclusive_info,
6533
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
6534
    gen_exception_insn(s, 4, EXCP_STREX);
6535
}
6536
#else
6537
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6538
                                TCGv addr, int size)
6539
{
6540
    TCGv tmp;
6541
    int done_label;
6542
    int fail_label;
6543

    
6544
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6545
         [addr] = {Rt};
6546
         {Rd} = 0;
6547
       } else {
6548
         {Rd} = 1;
6549
       } */
6550
    fail_label = gen_new_label();
6551
    done_label = gen_new_label();
6552
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6553
    switch (size) {
6554
    case 0:
6555
        tmp = gen_ld8u(addr, IS_USER(s));
6556
        break;
6557
    case 1:
6558
        tmp = gen_ld16u(addr, IS_USER(s));
6559
        break;
6560
    case 2:
6561
    case 3:
6562
        tmp = gen_ld32(addr, IS_USER(s));
6563
        break;
6564
    default:
6565
        abort();
6566
    }
6567
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6568
    tcg_temp_free_i32(tmp);
6569
    if (size == 3) {
6570
        TCGv tmp2 = tcg_temp_new_i32();
6571
        tcg_gen_addi_i32(tmp2, addr, 4);
6572
        tmp = gen_ld32(tmp2, IS_USER(s));
6573
        tcg_temp_free_i32(tmp2);
6574
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6575
        tcg_temp_free_i32(tmp);
6576
    }
6577
    tmp = load_reg(s, rt);
6578
    switch (size) {
6579
    case 0:
6580
        gen_st8(tmp, addr, IS_USER(s));
6581
        break;
6582
    case 1:
6583
        gen_st16(tmp, addr, IS_USER(s));
6584
        break;
6585
    case 2:
6586
    case 3:
6587
        gen_st32(tmp, addr, IS_USER(s));
6588
        break;
6589
    default:
6590
        abort();
6591
    }
6592
    if (size == 3) {
6593
        tcg_gen_addi_i32(addr, addr, 4);
6594
        tmp = load_reg(s, rt2);
6595
        gen_st32(tmp, addr, IS_USER(s));
6596
    }
6597
    tcg_gen_movi_i32(cpu_R[rd], 0);
6598
    tcg_gen_br(done_label);
6599
    gen_set_label(fail_label);
6600
    tcg_gen_movi_i32(cpu_R[rd], 1);
6601
    gen_set_label(done_label);
6602
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6603
}
6604
#endif
6605

    
6606
static void disas_arm_insn(CPUState * env, DisasContext *s)
6607
{
6608
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6609
    TCGv tmp;
6610
    TCGv tmp2;
6611
    TCGv tmp3;
6612
    TCGv addr;
6613
    TCGv_i64 tmp64;
6614

    
6615
    insn = ldl_code(s->pc);
6616
    s->pc += 4;
6617

    
6618
    /* M variants do not implement ARM mode.  */
6619
    if (IS_M(env))
6620
        goto illegal_op;
6621
    cond = insn >> 28;
6622
    if (cond == 0xf){
6623
        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6624
         * choose to UNDEF. In ARMv5 and above the space is used
6625
         * for miscellaneous unconditional instructions.
6626
         */
6627
        ARCH(5);
6628

    
6629
        /* Unconditional instructions.  */
6630
        if (((insn >> 25) & 7) == 1) {
6631
            /* NEON Data processing.  */
6632
            if (!arm_feature(env, ARM_FEATURE_NEON))
6633
                goto illegal_op;
6634

    
6635
            if (disas_neon_data_insn(env, s, insn))
6636
                goto illegal_op;
6637
            return;
6638
        }
6639
        if ((insn & 0x0f100000) == 0x04000000) {
6640
            /* NEON load/store.  */
6641
            if (!arm_feature(env, ARM_FEATURE_NEON))
6642
                goto illegal_op;
6643

    
6644
            if (disas_neon_ls_insn(env, s, insn))
6645
                goto illegal_op;
6646
            return;
6647
        }
6648
        if (((insn & 0x0f30f000) == 0x0510f000) ||
6649
            ((insn & 0x0f30f010) == 0x0710f000)) {
6650
            if ((insn & (1 << 22)) == 0) {
6651
                /* PLDW; v7MP */
6652
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6653
                    goto illegal_op;
6654
                }
6655
            }
6656
            /* Otherwise PLD; v5TE+ */
6657
            ARCH(5TE);
6658
            return;
6659
        }
6660
        if (((insn & 0x0f70f000) == 0x0450f000) ||
6661
            ((insn & 0x0f70f010) == 0x0650f000)) {
6662
            ARCH(7);
6663
            return; /* PLI; V7 */
6664
        }
6665
        if (((insn & 0x0f700000) == 0x04100000) ||
6666
            ((insn & 0x0f700010) == 0x06100000)) {
6667
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6668
                goto illegal_op;
6669
            }
6670
            return; /* v7MP: Unallocated memory hint: must NOP */
6671
        }
6672

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

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

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

    
7027
        op1 = (insn >> 21) & 0xf;
7028
        set_cc = (insn >> 20) & 1;
7029
        logic_cc = table_logic_cc[op1] & set_cc;
7030

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

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

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

    
7725
                    if ((insn & (1 << 15)) == 0)
7726
                        user = 1;
7727
                }
7728
                rn = (insn >> 16) & 0xf;
7729
                addr = load_reg(s, rn);
7730

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

    
7837
                /* branch (and link) */
7838
                val = (int32_t)s->pc;
7839
                if (insn & (1 << 24)) {
7840
                    tmp = tcg_temp_new_i32();
7841
                    tcg_gen_movi_i32(tmp, val);
7842
                    store_reg(s, 14, tmp);
7843
                }
7844
                offset = (((int32_t)insn << 8) >> 8);
7845
                val += (offset << 2) + 4;
7846
                gen_jmp(s, val);
7847
            }
7848
            break;
7849
        case 0xc:
7850
        case 0xd:
7851
        case 0xe:
7852
            /* Coprocessor.  */
7853
            if (disas_coproc_insn(env, s, insn))
7854
                goto illegal_op;
7855
            break;
7856
        case 0xf:
7857
            /* swi */
7858
            gen_set_pc_im(s->pc);
7859
            s->is_jmp = DISAS_SWI;
7860
            break;
7861
        default:
7862
        illegal_op:
7863
            gen_exception_insn(s, 4, EXCP_UDEF);
7864
            break;
7865
        }
7866
    }
7867
}
7868

    
7869
/* Return true if this is a Thumb-2 logical op.  */
7870
static int
7871
thumb2_logic_op(int op)
7872
{
7873
    return (op < 8);
7874
}
7875

    
7876
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7877
   then set condition code flags based on the result of the operation.
7878
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7879
   to the high bit of T1.
7880
   Returns zero if the opcode is valid.  */
7881

    
7882
static int
7883
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7884
{
7885
    int logic_cc;
7886

    
7887
    logic_cc = 0;
7888
    switch (op) {
7889
    case 0: /* and */
7890
        tcg_gen_and_i32(t0, t0, t1);
7891
        logic_cc = conds;
7892
        break;
7893
    case 1: /* bic */
7894
        tcg_gen_andc_i32(t0, t0, t1);
7895
        logic_cc = conds;
7896
        break;
7897
    case 2: /* orr */
7898
        tcg_gen_or_i32(t0, t0, t1);
7899
        logic_cc = conds;
7900
        break;
7901
    case 3: /* orn */
7902
        tcg_gen_orc_i32(t0, t0, t1);
7903
        logic_cc = conds;
7904
        break;
7905
    case 4: /* eor */
7906
        tcg_gen_xor_i32(t0, t0, t1);
7907
        logic_cc = conds;
7908
        break;
7909
    case 8: /* add */
7910
        if (conds)
7911
            gen_helper_add_cc(t0, t0, t1);
7912
        else
7913
            tcg_gen_add_i32(t0, t0, t1);
7914
        break;
7915
    case 10: /* adc */
7916
        if (conds)
7917
            gen_helper_adc_cc(t0, t0, t1);
7918
        else
7919
            gen_adc(t0, t1);
7920
        break;
7921
    case 11: /* sbc */
7922
        if (conds)
7923
            gen_helper_sbc_cc(t0, t0, t1);
7924
        else
7925
            gen_sub_carry(t0, t0, t1);
7926
        break;
7927
    case 13: /* sub */
7928
        if (conds)
7929
            gen_helper_sub_cc(t0, t0, t1);
7930
        else
7931
            tcg_gen_sub_i32(t0, t0, t1);
7932
        break;
7933
    case 14: /* rsb */
7934
        if (conds)
7935
            gen_helper_sub_cc(t0, t1, t0);
7936
        else
7937
            tcg_gen_sub_i32(t0, t1, t0);
7938
        break;
7939
    default: /* 5, 6, 7, 9, 12, 15. */
7940
        return 1;
7941
    }
7942
    if (logic_cc) {
7943
        gen_logic_CC(t0);
7944
        if (shifter_out)
7945
            gen_set_CF_bit31(t1);
7946
    }
7947
    return 0;
7948
}
7949

    
7950
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7951
   is not legal.  */
7952
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7953
{
7954
    uint32_t insn, imm, shift, offset;
7955
    uint32_t rd, rn, rm, rs;
7956
    TCGv tmp;
7957
    TCGv tmp2;
7958
    TCGv tmp3;
7959
    TCGv addr;
7960
    TCGv_i64 tmp64;
7961
    int op;
7962
    int shiftop;
7963
    int conds;
7964
    int logic_cc;
7965

    
7966
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7967
          || arm_feature (env, ARM_FEATURE_M))) {
7968
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7969
           16-bit instructions to get correct prefetch abort behavior.  */
7970
        insn = insn_hw1;
7971
        if ((insn & (1 << 12)) == 0) {
7972
            ARCH(5);
7973
            /* Second half of blx.  */
7974
            offset = ((insn & 0x7ff) << 1);
7975
            tmp = load_reg(s, 14);
7976
            tcg_gen_addi_i32(tmp, tmp, offset);
7977
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7978

    
7979
            tmp2 = tcg_temp_new_i32();
7980
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7981
            store_reg(s, 14, tmp2);
7982
            gen_bx(s, tmp);
7983
            return 0;
7984
        }
7985
        if (insn & (1 << 11)) {
7986
            /* Second half of bl.  */
7987
            offset = ((insn & 0x7ff) << 1) | 1;
7988
            tmp = load_reg(s, 14);
7989
            tcg_gen_addi_i32(tmp, tmp, offset);
7990

    
7991
            tmp2 = tcg_temp_new_i32();
7992
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7993
            store_reg(s, 14, tmp2);
7994
            gen_bx(s, tmp);
7995
            return 0;
7996
        }
7997
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7998
            /* Instruction spans a page boundary.  Implement it as two
7999
               16-bit instructions in case the second half causes an
8000
               prefetch abort.  */
8001
            offset = ((int32_t)insn << 21) >> 9;
8002
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8003
            return 0;
8004
        }
8005
        /* Fall through to 32-bit decode.  */
8006
    }
8007

    
8008
    insn = lduw_code(s->pc);
8009
    s->pc += 2;
8010
    insn |= (uint32_t)insn_hw1 << 16;
8011

    
8012
    if ((insn & 0xf800e800) != 0xf000e800) {
8013
        ARCH(6T2);
8014
    }
8015

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

    
8186
                TCGV_UNUSED(loaded_var);
8187
                for (i = 0; i < 16; i++) {
8188
                    if ((insn & (1 << i)) == 0)
8189
                        continue;
8190
                    if (insn & (1 << 20)) {
8191
                        /* Load.  */
8192
                        tmp = gen_ld32(addr, IS_USER(s));
8193
                        if (i == 15) {
8194
                            gen_bx(s, tmp);
8195
                        } else if (i == rn) {
8196
                            loaded_var = tmp;
8197
                            loaded_base = 1;
8198
                        } else {
8199
                            store_reg(s, i, tmp);
8200
                        }
8201
                    } else {
8202
                        /* Store.  */
8203
                        tmp = load_reg(s, i);
8204
                        gen_st32(tmp, addr, IS_USER(s));
8205
                    }
8206
                    tcg_gen_addi_i32(addr, addr, 4);
8207
                }
8208
                if (loaded_base) {
8209
                    store_reg(s, rn, loaded_var);
8210
                }
8211
                if (insn & (1 << 21)) {
8212
                    /* Base register writeback.  */
8213
                    if (insn & (1 << 24)) {
8214
                        tcg_gen_addi_i32(addr, addr, -offset);
8215
                    }
8216
                    /* Fault if writeback register is in register list.  */
8217
                    if (insn & (1 << rn))
8218
                        goto illegal_op;
8219
                    store_reg(s, rn, addr);
8220
                } else {
8221
                    tcg_temp_free_i32(addr);
8222
                }
8223
            }
8224
        }
8225
        break;
8226
    case 5:
8227

    
8228
        op = (insn >> 21) & 0xf;
8229
        if (op == 6) {
8230
            /* Halfword pack.  */
8231
            tmp = load_reg(s, rn);
8232
            tmp2 = load_reg(s, rm);
8233
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8234
            if (insn & (1 << 5)) {
8235
                /* pkhtb */
8236
                if (shift == 0)
8237
                    shift = 31;
8238
                tcg_gen_sari_i32(tmp2, tmp2, shift);
8239
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8240
                tcg_gen_ext16u_i32(tmp2, tmp2);
8241
            } else {
8242
                /* pkhbt */
8243
                if (shift)
8244
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
8245
                tcg_gen_ext16u_i32(tmp, tmp);
8246
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8247
            }
8248
            tcg_gen_or_i32(tmp, tmp, tmp2);
8249
            tcg_temp_free_i32(tmp2);
8250
            store_reg(s, rd, tmp);
8251
        } else {
8252
            /* Data processing register constant shift.  */
8253
            if (rn == 15) {
8254
                tmp = tcg_temp_new_i32();
8255
                tcg_gen_movi_i32(tmp, 0);
8256
            } else {
8257
                tmp = load_reg(s, rn);
8258
            }
8259
            tmp2 = load_reg(s, rm);
8260

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

    
8565
                if (insn & (1 << 14)) {
8566
                    /* Branch and link.  */
8567
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8568
                }
8569

    
8570
                offset += s->pc;
8571
                if (insn & (1 << 12)) {
8572
                    /* b/bl */
8573
                    gen_jmp(s, offset);
8574
                } else {
8575
                    /* blx */
8576
                    offset &= ~(uint32_t)2;
8577
                    /* thumb2 bx, no need to check */
8578
                    gen_bx_im(s, offset);
8579
                }
8580
            } else if (((insn >> 23) & 7) == 7) {
8581
                /* Misc control */
8582
                if (insn & (1 << 13))
8583
                    goto illegal_op;
8584

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

    
8698
                /* offset[11:1] = insn[10:0] */
8699
                offset = (insn & 0x7ff) << 1;
8700
                /* offset[17:12] = insn[21:16].  */
8701
                offset |= (insn & 0x003f0000) >> 4;
8702
                /* offset[31:20] = insn[26].  */
8703
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8704
                /* offset[18] = insn[13].  */
8705
                offset |= (insn & (1 << 13)) << 5;
8706
                /* offset[19] = insn[11].  */
8707
                offset |= (insn & (1 << 11)) << 8;
8708

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

    
9017
static void disas_thumb_insn(CPUState *env, DisasContext *s)
9018
{
9019
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
9020
    int32_t offset;
9021
    int i;
9022
    TCGv tmp;
9023
    TCGv tmp2;
9024
    TCGv addr;
9025

    
9026
    if (s->condexec_mask) {
9027
        cond = s->condexec_cond;
9028
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
9029
          s->condlabel = gen_new_label();
9030
          gen_test_cc(cond ^ 1, s->condlabel);
9031
          s->condjmp = 1;
9032
        }
9033
    }
9034

    
9035
    insn = lduw_code(s->pc);
9036
    s->pc += 2;
9037

    
9038
    switch (insn >> 12) {
9039
    case 0: case 1:
9040

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

    
9172
        /* data processing register */
9173
        rd = insn & 7;
9174
        rm = (insn >> 3) & 7;
9175
        op = (insn >> 6) & 0xf;
9176
        if (op == 2 || op == 3 || op == 4 || op == 7) {
9177
            /* the shift/rotate ops want the operands backwards */
9178
            val = rm;
9179
            rm = rd;
9180
            rd = val;
9181
            val = 1;
9182
        } else {
9183
            val = 0;
9184
        }
9185

    
9186
        if (op == 9) { /* neg */
9187
            tmp = tcg_temp_new_i32();
9188
            tcg_gen_movi_i32(tmp, 0);
9189
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
9190
            tmp = load_reg(s, rd);
9191
        } else {
9192
            TCGV_UNUSED(tmp);
9193
        }
9194

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

    
9309
    case 5:
9310
        /* load/store register offset.  */
9311
        rd = insn & 7;
9312
        rn = (insn >> 3) & 7;
9313
        rm = (insn >> 6) & 7;
9314
        op = (insn >> 9) & 7;
9315
        addr = load_reg(s, rn);
9316
        tmp = load_reg(s, rm);
9317
        tcg_gen_add_i32(addr, addr, tmp);
9318
        tcg_temp_free_i32(tmp);
9319

    
9320
        if (op < 3) /* store */
9321
            tmp = load_reg(s, rd);
9322

    
9323
        switch (op) {
9324
        case 0: /* str */
9325
            gen_st32(tmp, addr, IS_USER(s));
9326
            break;
9327
        case 1: /* strh */
9328
            gen_st16(tmp, addr, IS_USER(s));
9329
            break;
9330
        case 2: /* strb */
9331
            gen_st8(tmp, addr, IS_USER(s));
9332
            break;
9333
        case 3: /* ldrsb */
9334
            tmp = gen_ld8s(addr, IS_USER(s));
9335
            break;
9336
        case 4: /* ldr */
9337
            tmp = gen_ld32(addr, IS_USER(s));
9338
            break;
9339
        case 5: /* ldrh */
9340
            tmp = gen_ld16u(addr, IS_USER(s));
9341
            break;
9342
        case 6: /* ldrb */
9343
            tmp = gen_ld8u(addr, IS_USER(s));
9344
            break;
9345
        case 7: /* ldrsh */
9346
            tmp = gen_ld16s(addr, IS_USER(s));
9347
            break;
9348
        }
9349
        if (op >= 3) /* load */
9350
            store_reg(s, rd, tmp);
9351
        tcg_temp_free_i32(addr);
9352
        break;
9353

    
9354
    case 6:
9355
        /* load/store word immediate offset */
9356
        rd = insn & 7;
9357
        rn = (insn >> 3) & 7;
9358
        addr = load_reg(s, rn);
9359
        val = (insn >> 4) & 0x7c;
9360
        tcg_gen_addi_i32(addr, addr, val);
9361

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

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

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

    
9394
    case 8:
9395
        /* load/store halfword immediate offset */
9396
        rd = insn & 7;
9397
        rn = (insn >> 3) & 7;
9398
        addr = load_reg(s, rn);
9399
        val = (insn >> 5) & 0x3e;
9400
        tcg_gen_addi_i32(addr, addr, val);
9401

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

    
9414
    case 9:
9415
        /* load/store from stack */
9416
        rd = (insn >> 8) & 7;
9417
        addr = load_reg(s, 13);
9418
        val = (insn & 0xff) * 4;
9419
        tcg_gen_addi_i32(addr, addr, val);
9420

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

    
9433
    case 10:
9434
        /* add to high reg */
9435
        rd = (insn >> 8) & 7;
9436
        if (insn & (1 << 11)) {
9437
            /* SP */
9438
            tmp = load_reg(s, 13);
9439
        } else {
9440
            /* PC. bit 1 is ignored.  */
9441
            tmp = tcg_temp_new_i32();
9442
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9443
        }
9444
        val = (insn & 0xff) * 4;
9445
        tcg_gen_addi_i32(tmp, tmp, val);
9446
        store_reg(s, rd, tmp);
9447
        break;
9448

    
9449
    case 11:
9450
        /* misc */
9451
        op = (insn >> 8) & 0xf;
9452
        switch (op) {
9453
        case 0:
9454
            /* adjust stack pointer */
9455
            tmp = load_reg(s, 13);
9456
            val = (insn & 0x7f) * 4;
9457
            if (insn & (1 << 7))
9458
                val = -(int32_t)val;
9459
            tcg_gen_addi_i32(tmp, tmp, val);
9460
            store_reg(s, 13, tmp);
9461
            break;
9462

    
9463
        case 2: /* sign/zero extend.  */
9464
            ARCH(6);
9465
            rd = insn & 7;
9466
            rm = (insn >> 3) & 7;
9467
            tmp = load_reg(s, rm);
9468
            switch ((insn >> 6) & 3) {
9469
            case 0: gen_sxth(tmp); break;
9470
            case 1: gen_sxtb(tmp); break;
9471
            case 2: gen_uxth(tmp); break;
9472
            case 3: gen_uxtb(tmp); break;
9473
            }
9474
            store_reg(s, rd, tmp);
9475
            break;
9476
        case 4: case 5: case 0xc: case 0xd:
9477
            /* push/pop */
9478
            addr = load_reg(s, 13);
9479
            if (insn & (1 << 8))
9480
                offset = 4;
9481
            else
9482
                offset = 0;
9483
            for (i = 0; i < 8; i++) {
9484
                if (insn & (1 << i))
9485
                    offset += 4;
9486
            }
9487
            if ((insn & (1 << 11)) == 0) {
9488
                tcg_gen_addi_i32(addr, addr, -offset);
9489
            }
9490
            for (i = 0; i < 8; i++) {
9491
                if (insn & (1 << i)) {
9492
                    if (insn & (1 << 11)) {
9493
                        /* pop */
9494
                        tmp = gen_ld32(addr, IS_USER(s));
9495
                        store_reg(s, i, tmp);
9496
                    } else {
9497
                        /* push */
9498
                        tmp = load_reg(s, i);
9499
                        gen_st32(tmp, addr, IS_USER(s));
9500
                    }
9501
                    /* advance to the next address.  */
9502
                    tcg_gen_addi_i32(addr, addr, 4);
9503
                }
9504
            }
9505
            TCGV_UNUSED(tmp);
9506
            if (insn & (1 << 8)) {
9507
                if (insn & (1 << 11)) {
9508
                    /* pop pc */
9509
                    tmp = gen_ld32(addr, IS_USER(s));
9510
                    /* don't set the pc until the rest of the instruction
9511
                       has completed */
9512
                } else {
9513
                    /* push lr */
9514
                    tmp = load_reg(s, 14);
9515
                    gen_st32(tmp, addr, IS_USER(s));
9516
                }
9517
                tcg_gen_addi_i32(addr, addr, 4);
9518
            }
9519
            if ((insn & (1 << 11)) == 0) {
9520
                tcg_gen_addi_i32(addr, addr, -offset);
9521
            }
9522
            /* write back the new stack pointer */
9523
            store_reg(s, 13, addr);
9524
            /* set the new PC value */
9525
            if ((insn & 0x0900) == 0x0900) {
9526
                store_reg_from_load(env, s, 15, tmp);
9527
            }
9528
            break;
9529

    
9530
        case 1: case 3: case 9: case 11: /* czb */
9531
            rm = insn & 7;
9532
            tmp = load_reg(s, rm);
9533
            s->condlabel = gen_new_label();
9534
            s->condjmp = 1;
9535
            if (insn & (1 << 11))
9536
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9537
            else
9538
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9539
            tcg_temp_free_i32(tmp);
9540
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9541
            val = (uint32_t)s->pc + 2;
9542
            val += offset;
9543
            gen_jmp(s, val);
9544
            break;
9545

    
9546
        case 15: /* IT, nop-hint.  */
9547
            if ((insn & 0xf) == 0) {
9548
                gen_nop_hint(s, (insn >> 4) & 0xf);
9549
                break;
9550
            }
9551
            /* If Then.  */
9552
            s->condexec_cond = (insn >> 4) & 0xe;
9553
            s->condexec_mask = insn & 0x1f;
9554
            /* No actual code generated for this insn, just setup state.  */
9555
            break;
9556

    
9557
        case 0xe: /* bkpt */
9558
            ARCH(5);
9559
            gen_exception_insn(s, 2, EXCP_BKPT);
9560
            break;
9561

    
9562
        case 0xa: /* rev */
9563
            ARCH(6);
9564
            rn = (insn >> 3) & 0x7;
9565
            rd = insn & 0x7;
9566
            tmp = load_reg(s, rn);
9567
            switch ((insn >> 6) & 3) {
9568
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9569
            case 1: gen_rev16(tmp); break;
9570
            case 3: gen_revsh(tmp); break;
9571
            default: goto illegal_op;
9572
            }
9573
            store_reg(s, rd, tmp);
9574
            break;
9575

    
9576
        case 6: /* cps */
9577
            ARCH(6);
9578
            if (IS_USER(s))
9579
                break;
9580
            if (IS_M(env)) {
9581
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9582
                /* PRIMASK */
9583
                if (insn & 1) {
9584
                    addr = tcg_const_i32(16);
9585
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9586
                    tcg_temp_free_i32(addr);
9587
                }
9588
                /* FAULTMASK */
9589
                if (insn & 2) {
9590
                    addr = tcg_const_i32(17);
9591
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9592
                    tcg_temp_free_i32(addr);
9593
                }
9594
                tcg_temp_free_i32(tmp);
9595
                gen_lookup_tb(s);
9596
            } else {
9597
                if (insn & (1 << 4))
9598
                    shift = CPSR_A | CPSR_I | CPSR_F;
9599
                else
9600
                    shift = 0;
9601
                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9602
            }
9603
            break;
9604

    
9605
        default:
9606
            goto undef;
9607
        }
9608
        break;
9609

    
9610
    case 12:
9611
    {
9612
        /* load/store multiple */
9613
        TCGv loaded_var;
9614
        TCGV_UNUSED(loaded_var);
9615
        rn = (insn >> 8) & 0x7;
9616
        addr = load_reg(s, rn);
9617
        for (i = 0; i < 8; i++) {
9618
            if (insn & (1 << i)) {
9619
                if (insn & (1 << 11)) {
9620
                    /* load */
9621
                    tmp = gen_ld32(addr, IS_USER(s));
9622
                    if (i == rn) {
9623
                        loaded_var = tmp;
9624
                    } else {
9625
                        store_reg(s, i, tmp);
9626
                    }
9627
                } else {
9628
                    /* store */
9629
                    tmp = load_reg(s, i);
9630
                    gen_st32(tmp, addr, IS_USER(s));
9631
                }
9632
                /* advance to the next address */
9633
                tcg_gen_addi_i32(addr, addr, 4);
9634
            }
9635
        }
9636
        if ((insn & (1 << rn)) == 0) {
9637
            /* base reg not in list: base register writeback */
9638
            store_reg(s, rn, addr);
9639
        } else {
9640
            /* base reg in list: if load, complete it now */
9641
            if (insn & (1 << 11)) {
9642
                store_reg(s, rn, loaded_var);
9643
            }
9644
            tcg_temp_free_i32(addr);
9645
        }
9646
        break;
9647
    }
9648
    case 13:
9649
        /* conditional branch or swi */
9650
        cond = (insn >> 8) & 0xf;
9651
        if (cond == 0xe)
9652
            goto undef;
9653

    
9654
        if (cond == 0xf) {
9655
            /* swi */
9656
            gen_set_pc_im(s->pc);
9657
            s->is_jmp = DISAS_SWI;
9658
            break;
9659
        }
9660
        /* generate a conditional jump to next instruction */
9661
        s->condlabel = gen_new_label();
9662
        gen_test_cc(cond ^ 1, s->condlabel);
9663
        s->condjmp = 1;
9664

    
9665
        /* jump to the offset */
9666
        val = (uint32_t)s->pc + 2;
9667
        offset = ((int32_t)insn << 24) >> 24;
9668
        val += offset << 1;
9669
        gen_jmp(s, val);
9670
        break;
9671

    
9672
    case 14:
9673
        if (insn & (1 << 11)) {
9674
            if (disas_thumb2_insn(env, s, insn))
9675
              goto undef32;
9676
            break;
9677
        }
9678
        /* unconditional branch */
9679
        val = (uint32_t)s->pc;
9680
        offset = ((int32_t)insn << 21) >> 21;
9681
        val += (offset << 1) + 2;
9682
        gen_jmp(s, val);
9683
        break;
9684

    
9685
    case 15:
9686
        if (disas_thumb2_insn(env, s, insn))
9687
            goto undef32;
9688
        break;
9689
    }
9690
    return;
9691
undef32:
9692
    gen_exception_insn(s, 4, EXCP_UDEF);
9693
    return;
9694
illegal_op:
9695
undef:
9696
    gen_exception_insn(s, 2, EXCP_UDEF);
9697
}
9698

    
9699
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9700
   basic block 'tb'. If search_pc is TRUE, also generate PC
9701
   information for each intermediate instruction. */
9702
static inline void gen_intermediate_code_internal(CPUState *env,
9703
                                                  TranslationBlock *tb,
9704
                                                  int search_pc)
9705
{
9706
    DisasContext dc1, *dc = &dc1;
9707
    CPUBreakpoint *bp;
9708
    uint16_t *gen_opc_end;
9709
    int j, lj;
9710
    target_ulong pc_start;
9711
    uint32_t next_page_start;
9712
    int num_insns;
9713
    int max_insns;
9714

    
9715
    /* generate intermediate code */
9716
    pc_start = tb->pc;
9717

    
9718
    dc->tb = tb;
9719

    
9720
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9721

    
9722
    dc->is_jmp = DISAS_NEXT;
9723
    dc->pc = pc_start;
9724
    dc->singlestep_enabled = env->singlestep_enabled;
9725
    dc->condjmp = 0;
9726
    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9727
    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9728
    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9729
#if !defined(CONFIG_USER_ONLY)
9730
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9731
#endif
9732
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9733
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9734
    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9735
    cpu_F0s = tcg_temp_new_i32();
9736
    cpu_F1s = tcg_temp_new_i32();
9737
    cpu_F0d = tcg_temp_new_i64();
9738
    cpu_F1d = tcg_temp_new_i64();
9739
    cpu_V0 = cpu_F0d;
9740
    cpu_V1 = cpu_F1d;
9741
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
9742
    cpu_M0 = tcg_temp_new_i64();
9743
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9744
    lj = -1;
9745
    num_insns = 0;
9746
    max_insns = tb->cflags & CF_COUNT_MASK;
9747
    if (max_insns == 0)
9748
        max_insns = CF_COUNT_MASK;
9749

    
9750
    gen_icount_start();
9751

    
9752
    tcg_clear_temp_count();
9753

    
9754
    /* A note on handling of the condexec (IT) bits:
9755
     *
9756
     * We want to avoid the overhead of having to write the updated condexec
9757
     * bits back to the CPUState for every instruction in an IT block. So:
9758
     * (1) if the condexec bits are not already zero then we write
9759
     * zero back into the CPUState now. This avoids complications trying
9760
     * to do it at the end of the block. (For example if we don't do this
9761
     * it's hard to identify whether we can safely skip writing condexec
9762
     * at the end of the TB, which we definitely want to do for the case
9763
     * where a TB doesn't do anything with the IT state at all.)
9764
     * (2) if we are going to leave the TB then we call gen_set_condexec()
9765
     * which will write the correct value into CPUState if zero is wrong.
9766
     * This is done both for leaving the TB at the end, and for leaving
9767
     * it because of an exception we know will happen, which is done in
9768
     * gen_exception_insn(). The latter is necessary because we need to
9769
     * leave the TB with the PC/IT state just prior to execution of the
9770
     * instruction which caused the exception.
9771
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9772
     * then the CPUState will be wrong and we need to reset it.
9773
     * This is handled in the same way as restoration of the
9774
     * PC in these situations: we will be called again with search_pc=1
9775
     * and generate a mapping of the condexec bits for each PC in
9776
     * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9777
     * this to restore the condexec bits.
9778
     *
9779
     * Note that there are no instructions which can read the condexec
9780
     * bits, and none which can write non-static values to them, so
9781
     * we don't need to care about whether CPUState is correct in the
9782
     * middle of a TB.
9783
     */
9784

    
9785
    /* Reset the conditional execution bits immediately. This avoids
9786
       complications trying to do it at the end of the block.  */
9787
    if (dc->condexec_mask || dc->condexec_cond)
9788
      {
9789
        TCGv tmp = tcg_temp_new_i32();
9790
        tcg_gen_movi_i32(tmp, 0);
9791
        store_cpu_field(tmp, condexec_bits);
9792
      }
9793
    do {
9794
#ifdef CONFIG_USER_ONLY
9795
        /* Intercept jump to the magic kernel page.  */
9796
        if (dc->pc >= 0xffff0000) {
9797
            /* We always get here via a jump, so know we are not in a
9798
               conditional execution block.  */
9799
            gen_exception(EXCP_KERNEL_TRAP);
9800
            dc->is_jmp = DISAS_UPDATE;
9801
            break;
9802
        }
9803
#else
9804
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9805
            /* We always get here via a jump, so know we are not in a
9806
               conditional execution block.  */
9807
            gen_exception(EXCP_EXCEPTION_EXIT);
9808
            dc->is_jmp = DISAS_UPDATE;
9809
            break;
9810
        }
9811
#endif
9812

    
9813
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9814
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9815
                if (bp->pc == dc->pc) {
9816
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
9817
                    /* Advance PC so that clearing the breakpoint will
9818
                       invalidate this TB.  */
9819
                    dc->pc += 2;
9820
                    goto done_generating;
9821
                    break;
9822
                }
9823
            }
9824
        }
9825
        if (search_pc) {
9826
            j = gen_opc_ptr - gen_opc_buf;
9827
            if (lj < j) {
9828
                lj++;
9829
                while (lj < j)
9830
                    gen_opc_instr_start[lj++] = 0;
9831
            }
9832
            gen_opc_pc[lj] = dc->pc;
9833
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9834
            gen_opc_instr_start[lj] = 1;
9835
            gen_opc_icount[lj] = num_insns;
9836
        }
9837

    
9838
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9839
            gen_io_start();
9840

    
9841
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
9842
            tcg_gen_debug_insn_start(dc->pc);
9843
        }
9844

    
9845
        if (dc->thumb) {
9846
            disas_thumb_insn(env, dc);
9847
            if (dc->condexec_mask) {
9848
                dc->condexec_cond = (dc->condexec_cond & 0xe)
9849
                                   | ((dc->condexec_mask >> 4) & 1);
9850
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9851
                if (dc->condexec_mask == 0) {
9852
                    dc->condexec_cond = 0;
9853
                }
9854
            }
9855
        } else {
9856
            disas_arm_insn(env, dc);
9857
        }
9858

    
9859
        if (dc->condjmp && !dc->is_jmp) {
9860
            gen_set_label(dc->condlabel);
9861
            dc->condjmp = 0;
9862
        }
9863

    
9864
        if (tcg_check_temp_count()) {
9865
            fprintf(stderr, "TCG temporary leak before %08x\n", dc->pc);
9866
        }
9867

    
9868
        /* Translation stops when a conditional branch is encountered.
9869
         * Otherwise the subsequent code could get translated several times.
9870
         * Also stop translation when a page boundary is reached.  This
9871
         * ensures prefetch aborts occur at the right place.  */
9872
        num_insns ++;
9873
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9874
             !env->singlestep_enabled &&
9875
             !singlestep &&
9876
             dc->pc < next_page_start &&
9877
             num_insns < max_insns);
9878

    
9879
    if (tb->cflags & CF_LAST_IO) {
9880
        if (dc->condjmp) {
9881
            /* FIXME:  This can theoretically happen with self-modifying
9882
               code.  */
9883
            cpu_abort(env, "IO on conditional branch instruction");
9884
        }
9885
        gen_io_end();
9886
    }
9887

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

    
9952
done_generating:
9953
    gen_icount_end(tb, num_insns);
9954
    *gen_opc_ptr = INDEX_op_end;
9955

    
9956
#ifdef DEBUG_DISAS
9957
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9958
        qemu_log("----------------\n");
9959
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9960
        log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);
9961
        qemu_log("\n");
9962
    }
9963
#endif
9964
    if (search_pc) {
9965
        j = gen_opc_ptr - gen_opc_buf;
9966
        lj++;
9967
        while (lj <= j)
9968
            gen_opc_instr_start[lj++] = 0;
9969
    } else {
9970
        tb->size = dc->pc - pc_start;
9971
        tb->icount = num_insns;
9972
    }
9973
}
9974

    
9975
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9976
{
9977
    gen_intermediate_code_internal(env, tb, 0);
9978
}
9979

    
9980
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9981
{
9982
    gen_intermediate_code_internal(env, tb, 1);
9983
}
9984

    
9985
static const char *cpu_mode_names[16] = {
9986
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9987
  "???", "???", "???", "und", "???", "???", "???", "sys"
9988
};
9989

    
9990
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
9991
                    int flags)
9992
{
9993
    int i;
9994
#if 0
9995
    union {
9996
        uint32_t i;
9997
        float s;
9998
    } s0, s1;
9999
    CPU_DoubleU d;
10000
    /* ??? This assumes float64 and double have the same layout.
10001
       Oh well, it's only debug dumps.  */
10002
    union {
10003
        float64 f64;
10004
        double d;
10005
    } d0;
10006
#endif
10007
    uint32_t psr;
10008

    
10009
    for(i=0;i<16;i++) {
10010
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10011
        if ((i % 4) == 3)
10012
            cpu_fprintf(f, "\n");
10013
        else
10014
            cpu_fprintf(f, " ");
10015
    }
10016
    psr = cpsr_read(env);
10017
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10018
                psr,
10019
                psr & (1 << 31) ? 'N' : '-',
10020
                psr & (1 << 30) ? 'Z' : '-',
10021
                psr & (1 << 29) ? 'C' : '-',
10022
                psr & (1 << 28) ? 'V' : '-',
10023
                psr & CPSR_T ? 'T' : 'A',
10024
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10025

    
10026
#if 0
10027
    for (i = 0; i < 16; i++) {
10028
        d.d = env->vfp.regs[i];
10029
        s0.i = d.l.lower;
10030
        s1.i = d.l.upper;
10031
        d0.f64 = d.d;
10032
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
10033
                    i * 2, (int)s0.i, s0.s,
10034
                    i * 2 + 1, (int)s1.i, s1.s,
10035
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
10036
                    d0.d);
10037
    }
10038
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10039
#endif
10040
}
10041

    
10042
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
10043
{
10044
    env->regs[15] = gen_opc_pc[pc_pos];
10045
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
10046
}