Statistics
| Branch: | Revision:

root / target-arm / translate.c @ b7fa9214

History | View | Annotate | Download (336.7 kB)

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

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

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

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

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

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

    
71
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
72

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

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

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

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

    
100
#include "gen-icount.h"
101

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
198

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
896
#define VFP_OP2(name)                                                 \
897
static inline void gen_vfp_##name(int dp)                             \
898
{                                                                     \
899
    if (dp)                                                           \
900
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
901
    else                                                              \
902
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
903
}
904

    
905
VFP_OP2(add)
906
VFP_OP2(sub)
907
VFP_OP2(mul)
908
VFP_OP2(div)
909

    
910
#undef VFP_OP2
911

    
912
static inline void gen_vfp_F1_mul(int dp)
913
{
914
    /* Like gen_vfp_mul() but put result in F1 */
915
    if (dp) {
916
        gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, cpu_env);
917
    } else {
918
        gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, cpu_env);
919
    }
920
}
921

    
922
static inline void gen_vfp_F1_neg(int dp)
923
{
924
    /* Like gen_vfp_neg() but put result in F1 */
925
    if (dp) {
926
        gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
927
    } else {
928
        gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
929
    }
930
}
931

    
932
static inline void gen_vfp_abs(int dp)
933
{
934
    if (dp)
935
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
936
    else
937
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
938
}
939

    
940
static inline void gen_vfp_neg(int dp)
941
{
942
    if (dp)
943
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
944
    else
945
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
946
}
947

    
948
static inline void gen_vfp_sqrt(int dp)
949
{
950
    if (dp)
951
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
952
    else
953
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
954
}
955

    
956
static inline void gen_vfp_cmp(int dp)
957
{
958
    if (dp)
959
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
960
    else
961
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
962
}
963

    
964
static inline void gen_vfp_cmpe(int dp)
965
{
966
    if (dp)
967
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
968
    else
969
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
970
}
971

    
972
static inline void gen_vfp_F1_ld0(int dp)
973
{
974
    if (dp)
975
        tcg_gen_movi_i64(cpu_F1d, 0);
976
    else
977
        tcg_gen_movi_i32(cpu_F1s, 0);
978
}
979

    
980
#define VFP_GEN_ITOF(name) \
981
static inline void gen_vfp_##name(int dp, int neon) \
982
{ \
983
    TCGv_ptr statusptr = tcg_temp_new_ptr(); \
984
    int offset; \
985
    if (neon) { \
986
        offset = offsetof(CPUState, vfp.standard_fp_status); \
987
    } else { \
988
        offset = offsetof(CPUState, vfp.fp_status); \
989
    } \
990
    tcg_gen_addi_ptr(statusptr, cpu_env, offset); \
991
    if (dp) { \
992
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
993
    } else { \
994
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
995
    } \
996
    tcg_temp_free_ptr(statusptr); \
997
}
998

    
999
VFP_GEN_ITOF(uito)
1000
VFP_GEN_ITOF(sito)
1001
#undef VFP_GEN_ITOF
1002

    
1003
#define VFP_GEN_FTOI(name) \
1004
static inline void gen_vfp_##name(int dp, int neon) \
1005
{ \
1006
    TCGv_ptr statusptr = tcg_temp_new_ptr(); \
1007
    int offset; \
1008
    if (neon) { \
1009
        offset = offsetof(CPUState, vfp.standard_fp_status); \
1010
    } else { \
1011
        offset = offsetof(CPUState, vfp.fp_status); \
1012
    } \
1013
    tcg_gen_addi_ptr(statusptr, cpu_env, offset); \
1014
    if (dp) { \
1015
        gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1016
    } else { \
1017
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1018
    } \
1019
    tcg_temp_free_ptr(statusptr); \
1020
}
1021

    
1022
VFP_GEN_FTOI(toui)
1023
VFP_GEN_FTOI(touiz)
1024
VFP_GEN_FTOI(tosi)
1025
VFP_GEN_FTOI(tosiz)
1026
#undef VFP_GEN_FTOI
1027

    
1028
#define VFP_GEN_FIX(name) \
1029
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1030
{ \
1031
    TCGv tmp_shift = tcg_const_i32(shift); \
1032
    TCGv_ptr statusptr = tcg_temp_new_ptr(); \
1033
    int offset; \
1034
    if (neon) { \
1035
        offset = offsetof(CPUState, vfp.standard_fp_status); \
1036
    } else { \
1037
        offset = offsetof(CPUState, vfp.fp_status); \
1038
    } \
1039
    tcg_gen_addi_ptr(statusptr, cpu_env, offset); \
1040
    if (dp) { \
1041
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1042
    } else { \
1043
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1044
    } \
1045
    tcg_temp_free_i32(tmp_shift); \
1046
    tcg_temp_free_ptr(statusptr); \
1047
}
1048
VFP_GEN_FIX(tosh)
1049
VFP_GEN_FIX(tosl)
1050
VFP_GEN_FIX(touh)
1051
VFP_GEN_FIX(toul)
1052
VFP_GEN_FIX(shto)
1053
VFP_GEN_FIX(slto)
1054
VFP_GEN_FIX(uhto)
1055
VFP_GEN_FIX(ulto)
1056
#undef VFP_GEN_FIX
1057

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

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

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

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

    
1098
static TCGv neon_load_reg(int reg, int pass)
1099
{
1100
    TCGv tmp = tcg_temp_new_i32();
1101
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1102
    return tmp;
1103
}
1104

    
1105
static void neon_store_reg(int reg, int pass, TCGv var)
1106
{
1107
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1108
    tcg_temp_free_i32(var);
1109
}
1110

    
1111
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1112
{
1113
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1114
}
1115

    
1116
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1117
{
1118
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1119
}
1120

    
1121
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1122
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1123
#define tcg_gen_st_f32 tcg_gen_st_i32
1124
#define tcg_gen_st_f64 tcg_gen_st_i64
1125

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

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

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

    
1150
#define ARM_CP_RW_BIT        (1 << 20)
1151

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

    
1157
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1158
{
1159
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1160
}
1161

    
1162
static inline TCGv iwmmxt_load_creg(int reg)
1163
{
1164
    TCGv var = tcg_temp_new_i32();
1165
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1166
    return var;
1167
}
1168

    
1169
static inline void iwmmxt_store_creg(int reg, TCGv var)
1170
{
1171
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1172
    tcg_temp_free_i32(var);
1173
}
1174

    
1175
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1176
{
1177
    iwmmxt_store_reg(cpu_M0, rn);
1178
}
1179

    
1180
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1181
{
1182
    iwmmxt_load_reg(cpu_M0, rn);
1183
}
1184

    
1185
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1186
{
1187
    iwmmxt_load_reg(cpu_V1, rn);
1188
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1189
}
1190

    
1191
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1192
{
1193
    iwmmxt_load_reg(cpu_V1, rn);
1194
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1195
}
1196

    
1197
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1198
{
1199
    iwmmxt_load_reg(cpu_V1, rn);
1200
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1201
}
1202

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

    
1210
#define IWMMXT_OP_SIZE(name) \
1211
IWMMXT_OP(name##b) \
1212
IWMMXT_OP(name##w) \
1213
IWMMXT_OP(name##l)
1214

    
1215
#define IWMMXT_OP_1(name) \
1216
static inline void gen_op_iwmmxt_##name##_M0(void) \
1217
{ \
1218
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0); \
1219
}
1220

    
1221
IWMMXT_OP(maddsq)
1222
IWMMXT_OP(madduq)
1223
IWMMXT_OP(sadb)
1224
IWMMXT_OP(sadw)
1225
IWMMXT_OP(mulslw)
1226
IWMMXT_OP(mulshw)
1227
IWMMXT_OP(mululw)
1228
IWMMXT_OP(muluhw)
1229
IWMMXT_OP(macsw)
1230
IWMMXT_OP(macuw)
1231

    
1232
IWMMXT_OP_SIZE(unpackl)
1233
IWMMXT_OP_SIZE(unpackh)
1234

    
1235
IWMMXT_OP_1(unpacklub)
1236
IWMMXT_OP_1(unpackluw)
1237
IWMMXT_OP_1(unpacklul)
1238
IWMMXT_OP_1(unpackhub)
1239
IWMMXT_OP_1(unpackhuw)
1240
IWMMXT_OP_1(unpackhul)
1241
IWMMXT_OP_1(unpacklsb)
1242
IWMMXT_OP_1(unpacklsw)
1243
IWMMXT_OP_1(unpacklsl)
1244
IWMMXT_OP_1(unpackhsb)
1245
IWMMXT_OP_1(unpackhsw)
1246
IWMMXT_OP_1(unpackhsl)
1247

    
1248
IWMMXT_OP_SIZE(cmpeq)
1249
IWMMXT_OP_SIZE(cmpgtu)
1250
IWMMXT_OP_SIZE(cmpgts)
1251

    
1252
IWMMXT_OP_SIZE(mins)
1253
IWMMXT_OP_SIZE(minu)
1254
IWMMXT_OP_SIZE(maxs)
1255
IWMMXT_OP_SIZE(maxu)
1256

    
1257
IWMMXT_OP_SIZE(subn)
1258
IWMMXT_OP_SIZE(addn)
1259
IWMMXT_OP_SIZE(subu)
1260
IWMMXT_OP_SIZE(addu)
1261
IWMMXT_OP_SIZE(subs)
1262
IWMMXT_OP_SIZE(adds)
1263

    
1264
IWMMXT_OP(avgb0)
1265
IWMMXT_OP(avgb1)
1266
IWMMXT_OP(avgw0)
1267
IWMMXT_OP(avgw1)
1268

    
1269
IWMMXT_OP(msadb)
1270

    
1271
IWMMXT_OP(packuw)
1272
IWMMXT_OP(packul)
1273
IWMMXT_OP(packuq)
1274
IWMMXT_OP(packsw)
1275
IWMMXT_OP(packsl)
1276
IWMMXT_OP(packsq)
1277

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

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

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

    
1301
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1302
{
1303
    iwmmxt_load_reg(cpu_V1, rn);
1304
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1305
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1306
}
1307

    
1308
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1309
{
1310
    int rd;
1311
    uint32_t offset;
1312
    TCGv tmp;
1313

    
1314
    rd = (insn >> 16) & 0xf;
1315
    tmp = load_reg(s, rd);
1316

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

    
1342
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1343
{
1344
    int rd = (insn >> 0) & 0xf;
1345
    TCGv tmp;
1346

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

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

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

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

    
1454
    if ((insn & 0x0f000000) != 0x0e000000)
1455
        return 1;
1456

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

    
2365
    return 0;
2366
}
2367

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

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

    
2381
        if (acc != 0)
2382
            return 1;
2383

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

    
2409
        gen_op_iwmmxt_movq_wRn_M0(acc);
2410
        return 0;
2411
    }
2412

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

    
2419
        if (acc != 0)
2420
            return 1;
2421

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

    
2435
    return 1;
2436
}
2437

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

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

    
2471
static int cp15_user_ok(uint32_t insn)
2472
{
2473
    int cpn = (insn >> 16) & 0xf;
2474
    int cpm = insn & 0xf;
2475
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2476

    
2477
    if (cpn == 13 && cpm == 0) {
2478
        /* TLS register.  */
2479
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2480
            return 1;
2481
    }
2482
    if (cpn == 7) {
2483
        /* ISB, DSB, DMB.  */
2484
        if ((cpm == 5 && op == 4)
2485
                || (cpm == 10 && (op == 4 || op == 5)))
2486
            return 1;
2487
    }
2488
    return 0;
2489
}
2490

    
2491
static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd)
2492
{
2493
    TCGv tmp;
2494
    int cpn = (insn >> 16) & 0xf;
2495
    int cpm = insn & 0xf;
2496
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2497

    
2498
    if (!arm_feature(env, ARM_FEATURE_V6K))
2499
        return 0;
2500

    
2501
    if (!(cpn == 13 && cpm == 0))
2502
        return 0;
2503

    
2504
    if (insn & ARM_CP_RW_BIT) {
2505
        switch (op) {
2506
        case 2:
2507
            tmp = load_cpu_field(cp15.c13_tls1);
2508
            break;
2509
        case 3:
2510
            tmp = load_cpu_field(cp15.c13_tls2);
2511
            break;
2512
        case 4:
2513
            tmp = load_cpu_field(cp15.c13_tls3);
2514
            break;
2515
        default:
2516
            return 0;
2517
        }
2518
        store_reg(s, rd, tmp);
2519

    
2520
    } else {
2521
        tmp = load_reg(s, rd);
2522
        switch (op) {
2523
        case 2:
2524
            store_cpu_field(tmp, cp15.c13_tls1);
2525
            break;
2526
        case 3:
2527
            store_cpu_field(tmp, cp15.c13_tls2);
2528
            break;
2529
        case 4:
2530
            store_cpu_field(tmp, cp15.c13_tls3);
2531
            break;
2532
        default:
2533
            tcg_temp_free_i32(tmp);
2534
            return 0;
2535
        }
2536
    }
2537
    return 1;
2538
}
2539

    
2540
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2541
   instruction is not defined.  */
2542
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2543
{
2544
    uint32_t rd;
2545
    TCGv tmp, tmp2;
2546

    
2547
    /* M profile cores use memory mapped registers instead of cp15.  */
2548
    if (arm_feature(env, ARM_FEATURE_M))
2549
        return 1;
2550

    
2551
    if ((insn & (1 << 25)) == 0) {
2552
        if (insn & (1 << 20)) {
2553
            /* mrrc */
2554
            return 1;
2555
        }
2556
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2557
        return 0;
2558
    }
2559
    if ((insn & (1 << 4)) == 0) {
2560
        /* cdp */
2561
        return 1;
2562
    }
2563
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2564
        return 1;
2565
    }
2566

    
2567
    /* Pre-v7 versions of the architecture implemented WFI via coprocessor
2568
     * instructions rather than a separate instruction.
2569
     */
2570
    if ((insn & 0x0fff0fff) == 0x0e070f90) {
2571
        /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
2572
         * In v7, this must NOP.
2573
         */
2574
        if (!arm_feature(env, ARM_FEATURE_V7)) {
2575
            /* Wait for interrupt.  */
2576
            gen_set_pc_im(s->pc);
2577
            s->is_jmp = DISAS_WFI;
2578
        }
2579
        return 0;
2580
    }
2581

    
2582
    if ((insn & 0x0fff0fff) == 0x0e070f58) {
2583
        /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
2584
         * so this is slightly over-broad.
2585
         */
2586
        if (!arm_feature(env, ARM_FEATURE_V6)) {
2587
            /* Wait for interrupt.  */
2588
            gen_set_pc_im(s->pc);
2589
            s->is_jmp = DISAS_WFI;
2590
            return 0;
2591
        }
2592
        /* Otherwise fall through to handle via helper function.
2593
         * In particular, on v7 and some v6 cores this is one of
2594
         * the VA-PA registers.
2595
         */
2596
    }
2597

    
2598
    rd = (insn >> 12) & 0xf;
2599

    
2600
    if (cp15_tls_load_store(env, s, insn, rd))
2601
        return 0;
2602

    
2603
    tmp2 = tcg_const_i32(insn);
2604
    if (insn & ARM_CP_RW_BIT) {
2605
        tmp = tcg_temp_new_i32();
2606
        gen_helper_get_cp15(tmp, cpu_env, tmp2);
2607
        /* If the destination register is r15 then sets condition codes.  */
2608
        if (rd != 15)
2609
            store_reg(s, rd, tmp);
2610
        else
2611
            tcg_temp_free_i32(tmp);
2612
    } else {
2613
        tmp = load_reg(s, rd);
2614
        gen_helper_set_cp15(cpu_env, tmp2, tmp);
2615
        tcg_temp_free_i32(tmp);
2616
        /* Normally we would always end the TB here, but Linux
2617
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2618
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2619
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2620
                (insn & 0x0fff0fff) != 0x0e010f10)
2621
            gen_lookup_tb(s);
2622
    }
2623
    tcg_temp_free_i32(tmp2);
2624
    return 0;
2625
}
2626

    
2627
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2628
#define VFP_SREG(insn, bigbit, smallbit) \
2629
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2630
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2631
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2632
        reg = (((insn) >> (bigbit)) & 0x0f) \
2633
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2634
    } else { \
2635
        if (insn & (1 << (smallbit))) \
2636
            return 1; \
2637
        reg = ((insn) >> (bigbit)) & 0x0f; \
2638
    }} while (0)
2639

    
2640
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2641
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2642
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2643
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2644
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2645
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2646

    
2647
/* Move between integer and VFP cores.  */
2648
static TCGv gen_vfp_mrs(void)
2649
{
2650
    TCGv tmp = tcg_temp_new_i32();
2651
    tcg_gen_mov_i32(tmp, cpu_F0s);
2652
    return tmp;
2653
}
2654

    
2655
static void gen_vfp_msr(TCGv tmp)
2656
{
2657
    tcg_gen_mov_i32(cpu_F0s, tmp);
2658
    tcg_temp_free_i32(tmp);
2659
}
2660

    
2661
static void gen_neon_dup_u8(TCGv var, int shift)
2662
{
2663
    TCGv tmp = tcg_temp_new_i32();
2664
    if (shift)
2665
        tcg_gen_shri_i32(var, var, shift);
2666
    tcg_gen_ext8u_i32(var, var);
2667
    tcg_gen_shli_i32(tmp, var, 8);
2668
    tcg_gen_or_i32(var, var, tmp);
2669
    tcg_gen_shli_i32(tmp, var, 16);
2670
    tcg_gen_or_i32(var, var, tmp);
2671
    tcg_temp_free_i32(tmp);
2672
}
2673

    
2674
static void gen_neon_dup_low16(TCGv var)
2675
{
2676
    TCGv tmp = tcg_temp_new_i32();
2677
    tcg_gen_ext16u_i32(var, var);
2678
    tcg_gen_shli_i32(tmp, var, 16);
2679
    tcg_gen_or_i32(var, var, tmp);
2680
    tcg_temp_free_i32(tmp);
2681
}
2682

    
2683
static void gen_neon_dup_high16(TCGv var)
2684
{
2685
    TCGv tmp = tcg_temp_new_i32();
2686
    tcg_gen_andi_i32(var, var, 0xffff0000);
2687
    tcg_gen_shri_i32(tmp, var, 16);
2688
    tcg_gen_or_i32(var, var, tmp);
2689
    tcg_temp_free_i32(tmp);
2690
}
2691

    
2692
static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size)
2693
{
2694
    /* Load a single Neon element and replicate into a 32 bit TCG reg */
2695
    TCGv tmp;
2696
    switch (size) {
2697
    case 0:
2698
        tmp = gen_ld8u(addr, IS_USER(s));
2699
        gen_neon_dup_u8(tmp, 0);
2700
        break;
2701
    case 1:
2702
        tmp = gen_ld16u(addr, IS_USER(s));
2703
        gen_neon_dup_low16(tmp);
2704
        break;
2705
    case 2:
2706
        tmp = gen_ld32(addr, IS_USER(s));
2707
        break;
2708
    default: /* Avoid compiler warnings.  */
2709
        abort();
2710
    }
2711
    return tmp;
2712
}
2713

    
2714
/* Disassemble a VFP instruction.  Returns nonzero if an error occurred
2715
   (ie. an undefined instruction).  */
2716
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2717
{
2718
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2719
    int dp, veclen;
2720
    TCGv addr;
2721
    TCGv tmp;
2722
    TCGv tmp2;
2723

    
2724
    if (!arm_feature(env, ARM_FEATURE_VFP))
2725
        return 1;
2726

    
2727
    if (!s->vfp_enabled) {
2728
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2729
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2730
            return 1;
2731
        rn = (insn >> 16) & 0xf;
2732
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2733
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2734
            return 1;
2735
    }
2736
    dp = ((insn & 0xf00) == 0xb00);
2737
    switch ((insn >> 24) & 0xf) {
2738
    case 0xe:
2739
        if (insn & (1 << 4)) {
2740
            /* single register transfer */
2741
            rd = (insn >> 12) & 0xf;
2742
            if (dp) {
2743
                int size;
2744
                int pass;
2745

    
2746
                VFP_DREG_N(rn, insn);
2747
                if (insn & 0xf)
2748
                    return 1;
2749
                if (insn & 0x00c00060
2750
                    && !arm_feature(env, ARM_FEATURE_NEON))
2751
                    return 1;
2752

    
2753
                pass = (insn >> 21) & 1;
2754
                if (insn & (1 << 22)) {
2755
                    size = 0;
2756
                    offset = ((insn >> 5) & 3) * 8;
2757
                } else if (insn & (1 << 5)) {
2758
                    size = 1;
2759
                    offset = (insn & (1 << 6)) ? 16 : 0;
2760
                } else {
2761
                    size = 2;
2762
                    offset = 0;
2763
                }
2764
                if (insn & ARM_CP_RW_BIT) {
2765
                    /* vfp->arm */
2766
                    tmp = neon_load_reg(rn, pass);
2767
                    switch (size) {
2768
                    case 0:
2769
                        if (offset)
2770
                            tcg_gen_shri_i32(tmp, tmp, offset);
2771
                        if (insn & (1 << 23))
2772
                            gen_uxtb(tmp);
2773
                        else
2774
                            gen_sxtb(tmp);
2775
                        break;
2776
                    case 1:
2777
                        if (insn & (1 << 23)) {
2778
                            if (offset) {
2779
                                tcg_gen_shri_i32(tmp, tmp, 16);
2780
                            } else {
2781
                                gen_uxth(tmp);
2782
                            }
2783
                        } else {
2784
                            if (offset) {
2785
                                tcg_gen_sari_i32(tmp, tmp, 16);
2786
                            } else {
2787
                                gen_sxth(tmp);
2788
                            }
2789
                        }
2790
                        break;
2791
                    case 2:
2792
                        break;
2793
                    }
2794
                    store_reg(s, rd, tmp);
2795
                } else {
2796
                    /* arm->vfp */
2797
                    tmp = load_reg(s, rd);
2798
                    if (insn & (1 << 23)) {
2799
                        /* VDUP */
2800
                        if (size == 0) {
2801
                            gen_neon_dup_u8(tmp, 0);
2802
                        } else if (size == 1) {
2803
                            gen_neon_dup_low16(tmp);
2804
                        }
2805
                        for (n = 0; n <= pass * 2; n++) {
2806
                            tmp2 = tcg_temp_new_i32();
2807
                            tcg_gen_mov_i32(tmp2, tmp);
2808
                            neon_store_reg(rn, n, tmp2);
2809
                        }
2810
                        neon_store_reg(rn, n, tmp);
2811
                    } else {
2812
                        /* VMOV */
2813
                        switch (size) {
2814
                        case 0:
2815
                            tmp2 = neon_load_reg(rn, pass);
2816
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2817
                            tcg_temp_free_i32(tmp2);
2818
                            break;
2819
                        case 1:
2820
                            tmp2 = neon_load_reg(rn, pass);
2821
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2822
                            tcg_temp_free_i32(tmp2);
2823
                            break;
2824
                        case 2:
2825
                            break;
2826
                        }
2827
                        neon_store_reg(rn, pass, tmp);
2828
                    }
2829
                }
2830
            } else { /* !dp */
2831
                if ((insn & 0x6f) != 0x00)
2832
                    return 1;
2833
                rn = VFP_SREG_N(insn);
2834
                if (insn & ARM_CP_RW_BIT) {
2835
                    /* vfp->arm */
2836
                    if (insn & (1 << 21)) {
2837
                        /* system register */
2838
                        rn >>= 1;
2839

    
2840
                        switch (rn) {
2841
                        case ARM_VFP_FPSID:
2842
                            /* VFP2 allows access to FSID from userspace.
2843
                               VFP3 restricts all id registers to privileged
2844
                               accesses.  */
2845
                            if (IS_USER(s)
2846
                                && arm_feature(env, ARM_FEATURE_VFP3))
2847
                                return 1;
2848
                            tmp = load_cpu_field(vfp.xregs[rn]);
2849
                            break;
2850
                        case ARM_VFP_FPEXC:
2851
                            if (IS_USER(s))
2852
                                return 1;
2853
                            tmp = load_cpu_field(vfp.xregs[rn]);
2854
                            break;
2855
                        case ARM_VFP_FPINST:
2856
                        case ARM_VFP_FPINST2:
2857
                            /* Not present in VFP3.  */
2858
                            if (IS_USER(s)
2859
                                || arm_feature(env, ARM_FEATURE_VFP3))
2860
                                return 1;
2861
                            tmp = load_cpu_field(vfp.xregs[rn]);
2862
                            break;
2863
                        case ARM_VFP_FPSCR:
2864
                            if (rd == 15) {
2865
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2866
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2867
                            } else {
2868
                                tmp = tcg_temp_new_i32();
2869
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2870
                            }
2871
                            break;
2872
                        case ARM_VFP_MVFR0:
2873
                        case ARM_VFP_MVFR1:
2874
                            if (IS_USER(s)
2875
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2876
                                return 1;
2877
                            tmp = load_cpu_field(vfp.xregs[rn]);
2878
                            break;
2879
                        default:
2880
                            return 1;
2881
                        }
2882
                    } else {
2883
                        gen_mov_F0_vreg(0, rn);
2884
                        tmp = gen_vfp_mrs();
2885
                    }
2886
                    if (rd == 15) {
2887
                        /* Set the 4 flag bits in the CPSR.  */
2888
                        gen_set_nzcv(tmp);
2889
                        tcg_temp_free_i32(tmp);
2890
                    } else {
2891
                        store_reg(s, rd, tmp);
2892
                    }
2893
                } else {
2894
                    /* arm->vfp */
2895
                    tmp = load_reg(s, rd);
2896
                    if (insn & (1 << 21)) {
2897
                        rn >>= 1;
2898
                        /* system register */
2899
                        switch (rn) {
2900
                        case ARM_VFP_FPSID:
2901
                        case ARM_VFP_MVFR0:
2902
                        case ARM_VFP_MVFR1:
2903
                            /* Writes are ignored.  */
2904
                            break;
2905
                        case ARM_VFP_FPSCR:
2906
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2907
                            tcg_temp_free_i32(tmp);
2908
                            gen_lookup_tb(s);
2909
                            break;
2910
                        case ARM_VFP_FPEXC:
2911
                            if (IS_USER(s))
2912
                                return 1;
2913
                            /* TODO: VFP subarchitecture support.
2914
                             * For now, keep the EN bit only */
2915
                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2916
                            store_cpu_field(tmp, vfp.xregs[rn]);
2917
                            gen_lookup_tb(s);
2918
                            break;
2919
                        case ARM_VFP_FPINST:
2920
                        case ARM_VFP_FPINST2:
2921
                            store_cpu_field(tmp, vfp.xregs[rn]);
2922
                            break;
2923
                        default:
2924
                            return 1;
2925
                        }
2926
                    } else {
2927
                        gen_vfp_msr(tmp);
2928
                        gen_mov_vreg_F0(0, rn);
2929
                    }
2930
                }
2931
            }
2932
        } else {
2933
            /* data processing */
2934
            /* The opcode is in bits 23, 21, 20 and 6.  */
2935
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2936
            if (dp) {
2937
                if (op == 15) {
2938
                    /* rn is opcode */
2939
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2940
                } else {
2941
                    /* rn is register number */
2942
                    VFP_DREG_N(rn, insn);
2943
                }
2944

    
2945
                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2946
                    /* Integer or single precision destination.  */
2947
                    rd = VFP_SREG_D(insn);
2948
                } else {
2949
                    VFP_DREG_D(rd, insn);
2950
                }
2951
                if (op == 15 &&
2952
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2953
                    /* VCVT from int is always from S reg regardless of dp bit.
2954
                     * VCVT with immediate frac_bits has same format as SREG_M
2955
                     */
2956
                    rm = VFP_SREG_M(insn);
2957
                } else {
2958
                    VFP_DREG_M(rm, insn);
2959
                }
2960
            } else {
2961
                rn = VFP_SREG_N(insn);
2962
                if (op == 15 && rn == 15) {
2963
                    /* Double precision destination.  */
2964
                    VFP_DREG_D(rd, insn);
2965
                } else {
2966
                    rd = VFP_SREG_D(insn);
2967
                }
2968
                /* NB that we implicitly rely on the encoding for the frac_bits
2969
                 * in VCVT of fixed to float being the same as that of an SREG_M
2970
                 */
2971
                rm = VFP_SREG_M(insn);
2972
            }
2973

    
2974
            veclen = s->vec_len;
2975
            if (op == 15 && rn > 3)
2976
                veclen = 0;
2977

    
2978
            /* Shut up compiler warnings.  */
2979
            delta_m = 0;
2980
            delta_d = 0;
2981
            bank_mask = 0;
2982

    
2983
            if (veclen > 0) {
2984
                if (dp)
2985
                    bank_mask = 0xc;
2986
                else
2987
                    bank_mask = 0x18;
2988

    
2989
                /* Figure out what type of vector operation this is.  */
2990
                if ((rd & bank_mask) == 0) {
2991
                    /* scalar */
2992
                    veclen = 0;
2993
                } else {
2994
                    if (dp)
2995
                        delta_d = (s->vec_stride >> 1) + 1;
2996
                    else
2997
                        delta_d = s->vec_stride + 1;
2998

    
2999
                    if ((rm & bank_mask) == 0) {
3000
                        /* mixed scalar/vector */
3001
                        delta_m = 0;
3002
                    } else {
3003
                        /* vector */
3004
                        delta_m = delta_d;
3005
                    }
3006
                }
3007
            }
3008

    
3009
            /* Load the initial operands.  */
3010
            if (op == 15) {
3011
                switch (rn) {
3012
                case 16:
3013
                case 17:
3014
                    /* Integer source */
3015
                    gen_mov_F0_vreg(0, rm);
3016
                    break;
3017
                case 8:
3018
                case 9:
3019
                    /* Compare */
3020
                    gen_mov_F0_vreg(dp, rd);
3021
                    gen_mov_F1_vreg(dp, rm);
3022
                    break;
3023
                case 10:
3024
                case 11:
3025
                    /* Compare with zero */
3026
                    gen_mov_F0_vreg(dp, rd);
3027
                    gen_vfp_F1_ld0(dp);
3028
                    break;
3029
                case 20:
3030
                case 21:
3031
                case 22:
3032
                case 23:
3033
                case 28:
3034
                case 29:
3035
                case 30:
3036
                case 31:
3037
                    /* Source and destination the same.  */
3038
                    gen_mov_F0_vreg(dp, rd);
3039
                    break;
3040
                default:
3041
                    /* One source operand.  */
3042
                    gen_mov_F0_vreg(dp, rm);
3043
                    break;
3044
                }
3045
            } else {
3046
                /* Two source operands.  */
3047
                gen_mov_F0_vreg(dp, rn);
3048
                gen_mov_F1_vreg(dp, rm);
3049
            }
3050

    
3051
            for (;;) {
3052
                /* Perform the calculation.  */
3053
                switch (op) {
3054
                case 0: /* VMLA: fd + (fn * fm) */
3055
                    /* Note that order of inputs to the add matters for NaNs */
3056
                    gen_vfp_F1_mul(dp);
3057
                    gen_mov_F0_vreg(dp, rd);
3058
                    gen_vfp_add(dp);
3059
                    break;
3060
                case 1: /* VMLS: fd + -(fn * fm) */
3061
                    gen_vfp_mul(dp);
3062
                    gen_vfp_F1_neg(dp);
3063
                    gen_mov_F0_vreg(dp, rd);
3064
                    gen_vfp_add(dp);
3065
                    break;
3066
                case 2: /* VNMLS: -fd + (fn * fm) */
3067
                    /* Note that it isn't valid to replace (-A + B) with (B - A)
3068
                     * or similar plausible looking simplifications
3069
                     * because this will give wrong results for NaNs.
3070
                     */
3071
                    gen_vfp_F1_mul(dp);
3072
                    gen_mov_F0_vreg(dp, rd);
3073
                    gen_vfp_neg(dp);
3074
                    gen_vfp_add(dp);
3075
                    break;
3076
                case 3: /* VNMLA: -fd + -(fn * fm) */
3077
                    gen_vfp_mul(dp);
3078
                    gen_vfp_F1_neg(dp);
3079
                    gen_mov_F0_vreg(dp, rd);
3080
                    gen_vfp_neg(dp);
3081
                    gen_vfp_add(dp);
3082
                    break;
3083
                case 4: /* mul: fn * fm */
3084
                    gen_vfp_mul(dp);
3085
                    break;
3086
                case 5: /* nmul: -(fn * fm) */
3087
                    gen_vfp_mul(dp);
3088
                    gen_vfp_neg(dp);
3089
                    break;
3090
                case 6: /* add: fn + fm */
3091
                    gen_vfp_add(dp);
3092
                    break;
3093
                case 7: /* sub: fn - fm */
3094
                    gen_vfp_sub(dp);
3095
                    break;
3096
                case 8: /* div: fn / fm */
3097
                    gen_vfp_div(dp);
3098
                    break;
3099
                case 14: /* fconst */
3100
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3101
                      return 1;
3102

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

    
3263
                /* Write back the result.  */
3264
                if (op == 15 && (rn >= 8 && rn <= 11))
3265
                    ; /* Comparison, do nothing.  */
3266
                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3267
                    /* VCVT double to int: always integer result. */
3268
                    gen_mov_vreg_F0(0, rd);
3269
                else if (op == 15 && rn == 15)
3270
                    /* conversion */
3271
                    gen_mov_vreg_F0(!dp, rd);
3272
                else
3273
                    gen_mov_vreg_F0(dp, rd);
3274

    
3275
                /* break out of the loop if we have finished  */
3276
                if (veclen == 0)
3277
                    break;
3278

    
3279
                if (op == 15 && delta_m == 0) {
3280
                    /* single source one-many */
3281
                    while (veclen--) {
3282
                        rd = ((rd + delta_d) & (bank_mask - 1))
3283
                             | (rd & bank_mask);
3284
                        gen_mov_vreg_F0(dp, rd);
3285
                    }
3286
                    break;
3287
                }
3288
                /* Setup the next operands.  */
3289
                veclen--;
3290
                rd = ((rd + delta_d) & (bank_mask - 1))
3291
                     | (rd & bank_mask);
3292

    
3293
                if (op == 15) {
3294
                    /* One source operand.  */
3295
                    rm = ((rm + delta_m) & (bank_mask - 1))
3296
                         | (rm & bank_mask);
3297
                    gen_mov_F0_vreg(dp, rm);
3298
                } else {
3299
                    /* Two source operands.  */
3300
                    rn = ((rn + delta_d) & (bank_mask - 1))
3301
                         | (rn & bank_mask);
3302
                    gen_mov_F0_vreg(dp, rn);
3303
                    if (delta_m) {
3304
                        rm = ((rm + delta_m) & (bank_mask - 1))
3305
                             | (rm & bank_mask);
3306
                        gen_mov_F1_vreg(dp, rm);
3307
                    }
3308
                }
3309
            }
3310
        }
3311
        break;
3312
    case 0xc:
3313
    case 0xd:
3314
        if ((insn & 0x03e00000) == 0x00400000) {
3315
            /* two-register transfer */
3316
            rn = (insn >> 16) & 0xf;
3317
            rd = (insn >> 12) & 0xf;
3318
            if (dp) {
3319
                VFP_DREG_M(rm, insn);
3320
            } else {
3321
                rm = VFP_SREG_M(insn);
3322
            }
3323

    
3324
            if (insn & ARM_CP_RW_BIT) {
3325
                /* vfp->arm */
3326
                if (dp) {
3327
                    gen_mov_F0_vreg(0, rm * 2);
3328
                    tmp = gen_vfp_mrs();
3329
                    store_reg(s, rd, tmp);
3330
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3331
                    tmp = gen_vfp_mrs();
3332
                    store_reg(s, rn, tmp);
3333
                } else {
3334
                    gen_mov_F0_vreg(0, rm);
3335
                    tmp = gen_vfp_mrs();
3336
                    store_reg(s, rd, tmp);
3337
                    gen_mov_F0_vreg(0, rm + 1);
3338
                    tmp = gen_vfp_mrs();
3339
                    store_reg(s, rn, tmp);
3340
                }
3341
            } else {
3342
                /* arm->vfp */
3343
                if (dp) {
3344
                    tmp = load_reg(s, rd);
3345
                    gen_vfp_msr(tmp);
3346
                    gen_mov_vreg_F0(0, rm * 2);
3347
                    tmp = load_reg(s, rn);
3348
                    gen_vfp_msr(tmp);
3349
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3350
                } else {
3351
                    tmp = load_reg(s, rd);
3352
                    gen_vfp_msr(tmp);
3353
                    gen_mov_vreg_F0(0, rm);
3354
                    tmp = load_reg(s, rn);
3355
                    gen_vfp_msr(tmp);
3356
                    gen_mov_vreg_F0(0, rm + 1);
3357
                }
3358
            }
3359
        } else {
3360
            /* Load/store */
3361
            rn = (insn >> 16) & 0xf;
3362
            if (dp)
3363
                VFP_DREG_D(rd, insn);
3364
            else
3365
                rd = VFP_SREG_D(insn);
3366
            if (s->thumb && rn == 15) {
3367
                addr = tcg_temp_new_i32();
3368
                tcg_gen_movi_i32(addr, s->pc & ~2);
3369
            } else {
3370
                addr = load_reg(s, rn);
3371
            }
3372
            if ((insn & 0x01200000) == 0x01000000) {
3373
                /* Single load/store */
3374
                offset = (insn & 0xff) << 2;
3375
                if ((insn & (1 << 23)) == 0)
3376
                    offset = -offset;
3377
                tcg_gen_addi_i32(addr, addr, offset);
3378
                if (insn & (1 << 20)) {
3379
                    gen_vfp_ld(s, dp, addr);
3380
                    gen_mov_vreg_F0(dp, rd);
3381
                } else {
3382
                    gen_mov_F0_vreg(dp, rd);
3383
                    gen_vfp_st(s, dp, addr);
3384
                }
3385
                tcg_temp_free_i32(addr);
3386
            } else {
3387
                /* load/store multiple */
3388
                if (dp)
3389
                    n = (insn >> 1) & 0x7f;
3390
                else
3391
                    n = insn & 0xff;
3392

    
3393
                if (insn & (1 << 24)) /* pre-decrement */
3394
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3395

    
3396
                if (dp)
3397
                    offset = 8;
3398
                else
3399
                    offset = 4;
3400
                for (i = 0; i < n; i++) {
3401
                    if (insn & ARM_CP_RW_BIT) {
3402
                        /* load */
3403
                        gen_vfp_ld(s, dp, addr);
3404
                        gen_mov_vreg_F0(dp, rd + i);
3405
                    } else {
3406
                        /* store */
3407
                        gen_mov_F0_vreg(dp, rd + i);
3408
                        gen_vfp_st(s, dp, addr);
3409
                    }
3410
                    tcg_gen_addi_i32(addr, addr, offset);
3411
                }
3412
                if (insn & (1 << 21)) {
3413
                    /* writeback */
3414
                    if (insn & (1 << 24))
3415
                        offset = -offset * n;
3416
                    else if (dp && (insn & 1))
3417
                        offset = 4;
3418
                    else
3419
                        offset = 0;
3420

    
3421
                    if (offset != 0)
3422
                        tcg_gen_addi_i32(addr, addr, offset);
3423
                    store_reg(s, rn, addr);
3424
                } else {
3425
                    tcg_temp_free_i32(addr);
3426
                }
3427
            }
3428
        }
3429
        break;
3430
    default:
3431
        /* Should never happen.  */
3432
        return 1;
3433
    }
3434
    return 0;
3435
}
3436

    
3437
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3438
{
3439
    TranslationBlock *tb;
3440

    
3441
    tb = s->tb;
3442
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3443
        tcg_gen_goto_tb(n);
3444
        gen_set_pc_im(dest);
3445
        tcg_gen_exit_tb((tcg_target_long)tb + n);
3446
    } else {
3447
        gen_set_pc_im(dest);
3448
        tcg_gen_exit_tb(0);
3449
    }
3450
}
3451

    
3452
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3453
{
3454
    if (unlikely(s->singlestep_enabled)) {
3455
        /* An indirect jump so that we still trigger the debug exception.  */
3456
        if (s->thumb)
3457
            dest |= 1;
3458
        gen_bx_im(s, dest);
3459
    } else {
3460
        gen_goto_tb(s, 0, dest);
3461
        s->is_jmp = DISAS_TB_JUMP;
3462
    }
3463
}
3464

    
3465
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3466
{
3467
    if (x)
3468
        tcg_gen_sari_i32(t0, t0, 16);
3469
    else
3470
        gen_sxth(t0);
3471
    if (y)
3472
        tcg_gen_sari_i32(t1, t1, 16);
3473
    else
3474
        gen_sxth(t1);
3475
    tcg_gen_mul_i32(t0, t0, t1);
3476
}
3477

    
3478
/* Return the mask of PSR bits set by a MSR instruction.  */
3479
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3480
    uint32_t mask;
3481

    
3482
    mask = 0;
3483
    if (flags & (1 << 0))
3484
        mask |= 0xff;
3485
    if (flags & (1 << 1))
3486
        mask |= 0xff00;
3487
    if (flags & (1 << 2))
3488
        mask |= 0xff0000;
3489
    if (flags & (1 << 3))
3490
        mask |= 0xff000000;
3491

    
3492
    /* Mask out undefined bits.  */
3493
    mask &= ~CPSR_RESERVED;
3494
    if (!arm_feature(env, ARM_FEATURE_V4T))
3495
        mask &= ~CPSR_T;
3496
    if (!arm_feature(env, ARM_FEATURE_V5))
3497
        mask &= ~CPSR_Q; /* V5TE in reality*/
3498
    if (!arm_feature(env, ARM_FEATURE_V6))
3499
        mask &= ~(CPSR_E | CPSR_GE);
3500
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3501
        mask &= ~CPSR_IT;
3502
    /* Mask out execution state bits.  */
3503
    if (!spsr)
3504
        mask &= ~CPSR_EXEC;
3505
    /* Mask out privileged bits.  */
3506
    if (IS_USER(s))
3507
        mask &= CPSR_USER;
3508
    return mask;
3509
}
3510

    
3511
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3512
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3513
{
3514
    TCGv tmp;
3515
    if (spsr) {
3516
        /* ??? This is also undefined in system mode.  */
3517
        if (IS_USER(s))
3518
            return 1;
3519

    
3520
        tmp = load_cpu_field(spsr);
3521
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3522
        tcg_gen_andi_i32(t0, t0, mask);
3523
        tcg_gen_or_i32(tmp, tmp, t0);
3524
        store_cpu_field(tmp, spsr);
3525
    } else {
3526
        gen_set_cpsr(t0, mask);
3527
    }
3528
    tcg_temp_free_i32(t0);
3529
    gen_lookup_tb(s);
3530
    return 0;
3531
}
3532

    
3533
/* Returns nonzero if access to the PSR is not permitted.  */
3534
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3535
{
3536
    TCGv tmp;
3537
    tmp = tcg_temp_new_i32();
3538
    tcg_gen_movi_i32(tmp, val);
3539
    return gen_set_psr(s, mask, spsr, tmp);
3540
}
3541

    
3542
/* Generate an old-style exception return. Marks pc as dead. */
3543
static void gen_exception_return(DisasContext *s, TCGv pc)
3544
{
3545
    TCGv tmp;
3546
    store_reg(s, 15, pc);
3547
    tmp = load_cpu_field(spsr);
3548
    gen_set_cpsr(tmp, 0xffffffff);
3549
    tcg_temp_free_i32(tmp);
3550
    s->is_jmp = DISAS_UPDATE;
3551
}
3552

    
3553
/* Generate a v6 exception return.  Marks both values as dead.  */
3554
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3555
{
3556
    gen_set_cpsr(cpsr, 0xffffffff);
3557
    tcg_temp_free_i32(cpsr);
3558
    store_reg(s, 15, pc);
3559
    s->is_jmp = DISAS_UPDATE;
3560
}
3561

    
3562
static inline void
3563
gen_set_condexec (DisasContext *s)
3564
{
3565
    if (s->condexec_mask) {
3566
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3567
        TCGv tmp = tcg_temp_new_i32();
3568
        tcg_gen_movi_i32(tmp, val);
3569
        store_cpu_field(tmp, condexec_bits);
3570
    }
3571
}
3572

    
3573
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3574
{
3575
    gen_set_condexec(s);
3576
    gen_set_pc_im(s->pc - offset);
3577
    gen_exception(excp);
3578
    s->is_jmp = DISAS_JUMP;
3579
}
3580

    
3581
static void gen_nop_hint(DisasContext *s, int val)
3582
{
3583
    switch (val) {
3584
    case 3: /* wfi */
3585
        gen_set_pc_im(s->pc);
3586
        s->is_jmp = DISAS_WFI;
3587
        break;
3588
    case 2: /* wfe */
3589
    case 4: /* sev */
3590
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3591
    default: /* nop */
3592
        break;
3593
    }
3594
}
3595

    
3596
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3597

    
3598
static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
3599
{
3600
    switch (size) {
3601
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3602
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3603
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3604
    default: abort();
3605
    }
3606
}
3607

    
3608
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3609
{
3610
    switch (size) {
3611
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3612
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3613
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3614
    default: return;
3615
    }
3616
}
3617

    
3618
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3619
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3620
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3621
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3622
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3623

    
3624
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3625
    switch ((size << 1) | u) { \
3626
    case 0: \
3627
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3628
        break; \
3629
    case 1: \
3630
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3631
        break; \
3632
    case 2: \
3633
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3634
        break; \
3635
    case 3: \
3636
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3637
        break; \
3638
    case 4: \
3639
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3640
        break; \
3641
    case 5: \
3642
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3643
        break; \
3644
    default: return 1; \
3645
    }} while (0)
3646

    
3647
#define GEN_NEON_INTEGER_OP(name) do { \
3648
    switch ((size << 1) | u) { \
3649
    case 0: \
3650
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3651
        break; \
3652
    case 1: \
3653
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3654
        break; \
3655
    case 2: \
3656
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3657
        break; \
3658
    case 3: \
3659
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3660
        break; \
3661
    case 4: \
3662
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3663
        break; \
3664
    case 5: \
3665
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3666
        break; \
3667
    default: return 1; \
3668
    }} while (0)
3669

    
3670
static TCGv neon_load_scratch(int scratch)
3671
{
3672
    TCGv tmp = tcg_temp_new_i32();
3673
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3674
    return tmp;
3675
}
3676

    
3677
static void neon_store_scratch(int scratch, TCGv var)
3678
{
3679
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3680
    tcg_temp_free_i32(var);
3681
}
3682

    
3683
static inline TCGv neon_get_scalar(int size, int reg)
3684
{
3685
    TCGv tmp;
3686
    if (size == 1) {
3687
        tmp = neon_load_reg(reg & 7, reg >> 4);
3688
        if (reg & 8) {
3689
            gen_neon_dup_high16(tmp);
3690
        } else {
3691
            gen_neon_dup_low16(tmp);
3692
        }
3693
    } else {
3694
        tmp = neon_load_reg(reg & 15, reg >> 4);
3695
    }
3696
    return tmp;
3697
}
3698

    
3699
static int gen_neon_unzip(int rd, int rm, int size, int q)
3700
{
3701
    TCGv tmp, tmp2;
3702
    if (!q && size == 2) {
3703
        return 1;
3704
    }
3705
    tmp = tcg_const_i32(rd);
3706
    tmp2 = tcg_const_i32(rm);
3707
    if (q) {
3708
        switch (size) {
3709
        case 0:
3710
            gen_helper_neon_qunzip8(tmp, tmp2);
3711
            break;
3712
        case 1:
3713
            gen_helper_neon_qunzip16(tmp, tmp2);
3714
            break;
3715
        case 2:
3716
            gen_helper_neon_qunzip32(tmp, tmp2);
3717
            break;
3718
        default:
3719
            abort();
3720
        }
3721
    } else {
3722
        switch (size) {
3723
        case 0:
3724
            gen_helper_neon_unzip8(tmp, tmp2);
3725
            break;
3726
        case 1:
3727
            gen_helper_neon_unzip16(tmp, tmp2);
3728
            break;
3729
        default:
3730
            abort();
3731
        }
3732
    }
3733
    tcg_temp_free_i32(tmp);
3734
    tcg_temp_free_i32(tmp2);
3735
    return 0;
3736
}
3737

    
3738
static int gen_neon_zip(int rd, int rm, int size, int q)
3739
{
3740
    TCGv tmp, tmp2;
3741
    if (!q && size == 2) {
3742
        return 1;
3743
    }
3744
    tmp = tcg_const_i32(rd);
3745
    tmp2 = tcg_const_i32(rm);
3746
    if (q) {
3747
        switch (size) {
3748
        case 0:
3749
            gen_helper_neon_qzip8(tmp, tmp2);
3750
            break;
3751
        case 1:
3752
            gen_helper_neon_qzip16(tmp, tmp2);
3753
            break;
3754
        case 2:
3755
            gen_helper_neon_qzip32(tmp, tmp2);
3756
            break;
3757
        default:
3758
            abort();
3759
        }
3760
    } else {
3761
        switch (size) {
3762
        case 0:
3763
            gen_helper_neon_zip8(tmp, tmp2);
3764
            break;
3765
        case 1:
3766
            gen_helper_neon_zip16(tmp, tmp2);
3767
            break;
3768
        default:
3769
            abort();
3770
        }
3771
    }
3772
    tcg_temp_free_i32(tmp);
3773
    tcg_temp_free_i32(tmp2);
3774
    return 0;
3775
}
3776

    
3777
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3778
{
3779
    TCGv rd, tmp;
3780

    
3781
    rd = tcg_temp_new_i32();
3782
    tmp = tcg_temp_new_i32();
3783

    
3784
    tcg_gen_shli_i32(rd, t0, 8);
3785
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3786
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3787
    tcg_gen_or_i32(rd, rd, tmp);
3788

    
3789
    tcg_gen_shri_i32(t1, t1, 8);
3790
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3791
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3792
    tcg_gen_or_i32(t1, t1, tmp);
3793
    tcg_gen_mov_i32(t0, rd);
3794

    
3795
    tcg_temp_free_i32(tmp);
3796
    tcg_temp_free_i32(rd);
3797
}
3798

    
3799
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3800
{
3801
    TCGv rd, tmp;
3802

    
3803
    rd = tcg_temp_new_i32();
3804
    tmp = tcg_temp_new_i32();
3805

    
3806
    tcg_gen_shli_i32(rd, t0, 16);
3807
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3808
    tcg_gen_or_i32(rd, rd, tmp);
3809
    tcg_gen_shri_i32(t1, t1, 16);
3810
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3811
    tcg_gen_or_i32(t1, t1, tmp);
3812
    tcg_gen_mov_i32(t0, rd);
3813

    
3814
    tcg_temp_free_i32(tmp);
3815
    tcg_temp_free_i32(rd);
3816
}
3817

    
3818

    
3819
static struct {
3820
    int nregs;
3821
    int interleave;
3822
    int spacing;
3823
} neon_ls_element_type[11] = {
3824
    {4, 4, 1},
3825
    {4, 4, 2},
3826
    {4, 1, 1},
3827
    {4, 2, 1},
3828
    {3, 3, 1},
3829
    {3, 3, 2},
3830
    {3, 1, 1},
3831
    {1, 1, 1},
3832
    {2, 2, 1},
3833
    {2, 2, 2},
3834
    {2, 1, 1}
3835
};
3836

    
3837
/* Translate a NEON load/store element instruction.  Return nonzero if the
3838
   instruction is invalid.  */
3839
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3840
{
3841
    int rd, rn, rm;
3842
    int op;
3843
    int nregs;
3844
    int interleave;
3845
    int spacing;
3846
    int stride;
3847
    int size;
3848
    int reg;
3849
    int pass;
3850
    int load;
3851
    int shift;
3852
    int n;
3853
    TCGv addr;
3854
    TCGv tmp;
3855
    TCGv tmp2;
3856
    TCGv_i64 tmp64;
3857

    
3858
    if (!s->vfp_enabled)
3859
      return 1;
3860
    VFP_DREG_D(rd, insn);
3861
    rn = (insn >> 16) & 0xf;
3862
    rm = insn & 0xf;
3863
    load = (insn & (1 << 21)) != 0;
3864
    if ((insn & (1 << 23)) == 0) {
3865
        /* Load store all elements.  */
3866
        op = (insn >> 8) & 0xf;
3867
        size = (insn >> 6) & 3;
3868
        if (op > 10)
3869
            return 1;
3870
        /* Catch UNDEF cases for bad values of align field */
3871
        switch (op & 0xc) {
3872
        case 4:
3873
            if (((insn >> 5) & 1) == 1) {
3874
                return 1;
3875
            }
3876
            break;
3877
        case 8:
3878
            if (((insn >> 4) & 3) == 3) {
3879
                return 1;
3880
            }
3881
            break;
3882
        default:
3883
            break;
3884
        }
3885
        nregs = neon_ls_element_type[op].nregs;
3886
        interleave = neon_ls_element_type[op].interleave;
3887
        spacing = neon_ls_element_type[op].spacing;
3888
        if (size == 3 && (interleave | spacing) != 1)
3889
            return 1;
3890
        addr = tcg_temp_new_i32();
3891
        load_reg_var(s, addr, rn);
3892
        stride = (1 << size) * interleave;
3893
        for (reg = 0; reg < nregs; reg++) {
3894
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3895
                load_reg_var(s, addr, rn);
3896
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3897
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3898
                load_reg_var(s, addr, rn);
3899
                tcg_gen_addi_i32(addr, addr, 1 << size);
3900
            }
3901
            if (size == 3) {
3902
                if (load) {
3903
                    tmp64 = gen_ld64(addr, IS_USER(s));
3904
                    neon_store_reg64(tmp64, rd);
3905
                    tcg_temp_free_i64(tmp64);
3906
                } else {
3907
                    tmp64 = tcg_temp_new_i64();
3908
                    neon_load_reg64(tmp64, rd);
3909
                    gen_st64(tmp64, addr, IS_USER(s));
3910
                }
3911
                tcg_gen_addi_i32(addr, addr, stride);
3912
            } else {
3913
                for (pass = 0; pass < 2; pass++) {
3914
                    if (size == 2) {
3915
                        if (load) {
3916
                            tmp = gen_ld32(addr, IS_USER(s));
3917
                            neon_store_reg(rd, pass, tmp);
3918
                        } else {
3919
                            tmp = neon_load_reg(rd, pass);
3920
                            gen_st32(tmp, addr, IS_USER(s));
3921
                        }
3922
                        tcg_gen_addi_i32(addr, addr, stride);
3923
                    } else if (size == 1) {
3924
                        if (load) {
3925
                            tmp = gen_ld16u(addr, IS_USER(s));
3926
                            tcg_gen_addi_i32(addr, addr, stride);
3927
                            tmp2 = gen_ld16u(addr, IS_USER(s));
3928
                            tcg_gen_addi_i32(addr, addr, stride);
3929
                            tcg_gen_shli_i32(tmp2, tmp2, 16);
3930
                            tcg_gen_or_i32(tmp, tmp, tmp2);
3931
                            tcg_temp_free_i32(tmp2);
3932
                            neon_store_reg(rd, pass, tmp);
3933
                        } else {
3934
                            tmp = neon_load_reg(rd, pass);
3935
                            tmp2 = tcg_temp_new_i32();
3936
                            tcg_gen_shri_i32(tmp2, tmp, 16);
3937
                            gen_st16(tmp, addr, IS_USER(s));
3938
                            tcg_gen_addi_i32(addr, addr, stride);
3939
                            gen_st16(tmp2, addr, IS_USER(s));
3940
                            tcg_gen_addi_i32(addr, addr, stride);
3941
                        }
3942
                    } else /* size == 0 */ {
3943
                        if (load) {
3944
                            TCGV_UNUSED(tmp2);
3945
                            for (n = 0; n < 4; n++) {
3946
                                tmp = gen_ld8u(addr, IS_USER(s));
3947
                                tcg_gen_addi_i32(addr, addr, stride);
3948
                                if (n == 0) {
3949
                                    tmp2 = tmp;
3950
                                } else {
3951
                                    tcg_gen_shli_i32(tmp, tmp, n * 8);
3952
                                    tcg_gen_or_i32(tmp2, tmp2, tmp);
3953
                                    tcg_temp_free_i32(tmp);
3954
                                }
3955
                            }
3956
                            neon_store_reg(rd, pass, tmp2);
3957
                        } else {
3958
                            tmp2 = neon_load_reg(rd, pass);
3959
                            for (n = 0; n < 4; n++) {
3960
                                tmp = tcg_temp_new_i32();
3961
                                if (n == 0) {
3962
                                    tcg_gen_mov_i32(tmp, tmp2);
3963
                                } else {
3964
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
3965
                                }
3966
                                gen_st8(tmp, addr, IS_USER(s));
3967
                                tcg_gen_addi_i32(addr, addr, stride);
3968
                            }
3969
                            tcg_temp_free_i32(tmp2);
3970
                        }
3971
                    }
3972
                }
3973
            }
3974
            rd += spacing;
3975
        }
3976
        tcg_temp_free_i32(addr);
3977
        stride = nregs * 8;
3978
    } else {
3979
        size = (insn >> 10) & 3;
3980
        if (size == 3) {
3981
            /* Load single element to all lanes.  */
3982
            int a = (insn >> 4) & 1;
3983
            if (!load) {
3984
                return 1;
3985
            }
3986
            size = (insn >> 6) & 3;
3987
            nregs = ((insn >> 8) & 3) + 1;
3988

    
3989
            if (size == 3) {
3990
                if (nregs != 4 || a == 0) {
3991
                    return 1;
3992
                }
3993
                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3994
                size = 2;
3995
            }
3996
            if (nregs == 1 && a == 1 && size == 0) {
3997
                return 1;
3998
            }
3999
            if (nregs == 3 && a == 1) {
4000
                return 1;
4001
            }
4002
            addr = tcg_temp_new_i32();
4003
            load_reg_var(s, addr, rn);
4004
            if (nregs == 1) {
4005
                /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4006
                tmp = gen_load_and_replicate(s, addr, size);
4007
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4008
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4009
                if (insn & (1 << 5)) {
4010
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4011
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4012
                }
4013
                tcg_temp_free_i32(tmp);
4014
            } else {
4015
                /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4016
                stride = (insn & (1 << 5)) ? 2 : 1;
4017
                for (reg = 0; reg < nregs; reg++) {
4018
                    tmp = gen_load_and_replicate(s, addr, size);
4019
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4020
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4021
                    tcg_temp_free_i32(tmp);
4022
                    tcg_gen_addi_i32(addr, addr, 1 << size);
4023
                    rd += stride;
4024
                }
4025
            }
4026
            tcg_temp_free_i32(addr);
4027
            stride = (1 << size) * nregs;
4028
        } else {
4029
            /* Single element.  */
4030
            int idx = (insn >> 4) & 0xf;
4031
            pass = (insn >> 7) & 1;
4032
            switch (size) {
4033
            case 0:
4034
                shift = ((insn >> 5) & 3) * 8;
4035
                stride = 1;
4036
                break;
4037
            case 1:
4038
                shift = ((insn >> 6) & 1) * 16;
4039
                stride = (insn & (1 << 5)) ? 2 : 1;
4040
                break;
4041
            case 2:
4042
                shift = 0;
4043
                stride = (insn & (1 << 6)) ? 2 : 1;
4044
                break;
4045
            default:
4046
                abort();
4047
            }
4048
            nregs = ((insn >> 8) & 3) + 1;
4049
            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4050
            switch (nregs) {
4051
            case 1:
4052
                if (((idx & (1 << size)) != 0) ||
4053
                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4054
                    return 1;
4055
                }
4056
                break;
4057
            case 3:
4058
                if ((idx & 1) != 0) {
4059
                    return 1;
4060
                }
4061
                /* fall through */
4062
            case 2:
4063
                if (size == 2 && (idx & 2) != 0) {
4064
                    return 1;
4065
                }
4066
                break;
4067
            case 4:
4068
                if ((size == 2) && ((idx & 3) == 3)) {
4069
                    return 1;
4070
                }
4071
                break;
4072
            default:
4073
                abort();
4074
            }
4075
            if ((rd + stride * (nregs - 1)) > 31) {
4076
                /* Attempts to write off the end of the register file
4077
                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4078
                 * the neon_load_reg() would write off the end of the array.
4079
                 */
4080
                return 1;
4081
            }
4082
            addr = tcg_temp_new_i32();
4083
            load_reg_var(s, addr, rn);
4084
            for (reg = 0; reg < nregs; reg++) {
4085
                if (load) {
4086
                    switch (size) {
4087
                    case 0:
4088
                        tmp = gen_ld8u(addr, IS_USER(s));
4089
                        break;
4090
                    case 1:
4091
                        tmp = gen_ld16u(addr, IS_USER(s));
4092
                        break;
4093
                    case 2:
4094
                        tmp = gen_ld32(addr, IS_USER(s));
4095
                        break;
4096
                    default: /* Avoid compiler warnings.  */
4097
                        abort();
4098
                    }
4099
                    if (size != 2) {
4100
                        tmp2 = neon_load_reg(rd, pass);
4101
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
4102
                        tcg_temp_free_i32(tmp2);
4103
                    }
4104
                    neon_store_reg(rd, pass, tmp);
4105
                } else { /* Store */
4106
                    tmp = neon_load_reg(rd, pass);
4107
                    if (shift)
4108
                        tcg_gen_shri_i32(tmp, tmp, shift);
4109
                    switch (size) {
4110
                    case 0:
4111
                        gen_st8(tmp, addr, IS_USER(s));
4112
                        break;
4113
                    case 1:
4114
                        gen_st16(tmp, addr, IS_USER(s));
4115
                        break;
4116
                    case 2:
4117
                        gen_st32(tmp, addr, IS_USER(s));
4118
                        break;
4119
                    }
4120
                }
4121
                rd += stride;
4122
                tcg_gen_addi_i32(addr, addr, 1 << size);
4123
            }
4124
            tcg_temp_free_i32(addr);
4125
            stride = nregs * (1 << size);
4126
        }
4127
    }
4128
    if (rm != 15) {
4129
        TCGv base;
4130

    
4131
        base = load_reg(s, rn);
4132
        if (rm == 13) {
4133
            tcg_gen_addi_i32(base, base, stride);
4134
        } else {
4135
            TCGv index;
4136
            index = load_reg(s, rm);
4137
            tcg_gen_add_i32(base, base, index);
4138
            tcg_temp_free_i32(index);
4139
        }
4140
        store_reg(s, rn, base);
4141
    }
4142
    return 0;
4143
}
4144

    
4145
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4146
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4147
{
4148
    tcg_gen_and_i32(t, t, c);
4149
    tcg_gen_andc_i32(f, f, c);
4150
    tcg_gen_or_i32(dest, t, f);
4151
}
4152

    
4153
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4154
{
4155
    switch (size) {
4156
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4157
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4158
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4159
    default: abort();
4160
    }
4161
}
4162

    
4163
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4164
{
4165
    switch (size) {
4166
    case 0: gen_helper_neon_narrow_sat_s8(dest, src); break;
4167
    case 1: gen_helper_neon_narrow_sat_s16(dest, src); break;
4168
    case 2: gen_helper_neon_narrow_sat_s32(dest, src); break;
4169
    default: abort();
4170
    }
4171
}
4172

    
4173
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4174
{
4175
    switch (size) {
4176
    case 0: gen_helper_neon_narrow_sat_u8(dest, src); break;
4177
    case 1: gen_helper_neon_narrow_sat_u16(dest, src); break;
4178
    case 2: gen_helper_neon_narrow_sat_u32(dest, src); break;
4179
    default: abort();
4180
    }
4181
}
4182

    
4183
static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4184
{
4185
    switch (size) {
4186
    case 0: gen_helper_neon_unarrow_sat8(dest, src); break;
4187
    case 1: gen_helper_neon_unarrow_sat16(dest, src); break;
4188
    case 2: gen_helper_neon_unarrow_sat32(dest, src); break;
4189
    default: abort();
4190
    }
4191
}
4192

    
4193
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4194
                                         int q, int u)
4195
{
4196
    if (q) {
4197
        if (u) {
4198
            switch (size) {
4199
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4200
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4201
            default: abort();
4202
            }
4203
        } else {
4204
            switch (size) {
4205
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4206
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4207
            default: abort();
4208
            }
4209
        }
4210
    } else {
4211
        if (u) {
4212
            switch (size) {
4213
            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4214
            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4215
            default: abort();
4216
            }
4217
        } else {
4218
            switch (size) {
4219
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4220
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4221
            default: abort();
4222
            }
4223
        }
4224
    }
4225
}
4226

    
4227
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4228
{
4229
    if (u) {
4230
        switch (size) {
4231
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4232
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4233
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4234
        default: abort();
4235
        }
4236
    } else {
4237
        switch (size) {
4238
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4239
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4240
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4241
        default: abort();
4242
        }
4243
    }
4244
    tcg_temp_free_i32(src);
4245
}
4246

    
4247
static inline void gen_neon_addl(int size)
4248
{
4249
    switch (size) {
4250
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4251
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4252
    case 2: tcg_gen_add_i64(CPU_V001); break;
4253
    default: abort();
4254
    }
4255
}
4256

    
4257
static inline void gen_neon_subl(int size)
4258
{
4259
    switch (size) {
4260
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4261
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4262
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4263
    default: abort();
4264
    }
4265
}
4266

    
4267
static inline void gen_neon_negl(TCGv_i64 var, int size)
4268
{
4269
    switch (size) {
4270
    case 0: gen_helper_neon_negl_u16(var, var); break;
4271
    case 1: gen_helper_neon_negl_u32(var, var); break;
4272
    case 2: gen_helper_neon_negl_u64(var, var); break;
4273
    default: abort();
4274
    }
4275
}
4276

    
4277
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4278
{
4279
    switch (size) {
4280
    case 1: gen_helper_neon_addl_saturate_s32(op0, op0, op1); break;
4281
    case 2: gen_helper_neon_addl_saturate_s64(op0, op0, op1); break;
4282
    default: abort();
4283
    }
4284
}
4285

    
4286
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4287
{
4288
    TCGv_i64 tmp;
4289

    
4290
    switch ((size << 1) | u) {
4291
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4292
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4293
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4294
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4295
    case 4:
4296
        tmp = gen_muls_i64_i32(a, b);
4297
        tcg_gen_mov_i64(dest, tmp);
4298
        tcg_temp_free_i64(tmp);
4299
        break;
4300
    case 5:
4301
        tmp = gen_mulu_i64_i32(a, b);
4302
        tcg_gen_mov_i64(dest, tmp);
4303
        tcg_temp_free_i64(tmp);
4304
        break;
4305
    default: abort();
4306
    }
4307

    
4308
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4309
       Don't forget to clean them now.  */
4310
    if (size < 2) {
4311
        tcg_temp_free_i32(a);
4312
        tcg_temp_free_i32(b);
4313
    }
4314
}
4315

    
4316
static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
4317
{
4318
    if (op) {
4319
        if (u) {
4320
            gen_neon_unarrow_sats(size, dest, src);
4321
        } else {
4322
            gen_neon_narrow(size, dest, src);
4323
        }
4324
    } else {
4325
        if (u) {
4326
            gen_neon_narrow_satu(size, dest, src);
4327
        } else {
4328
            gen_neon_narrow_sats(size, dest, src);
4329
        }
4330
    }
4331
}
4332

    
4333
/* Symbolic constants for op fields for Neon 3-register same-length.
4334
 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4335
 * table A7-9.
4336
 */
4337
#define NEON_3R_VHADD 0
4338
#define NEON_3R_VQADD 1
4339
#define NEON_3R_VRHADD 2
4340
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4341
#define NEON_3R_VHSUB 4
4342
#define NEON_3R_VQSUB 5
4343
#define NEON_3R_VCGT 6
4344
#define NEON_3R_VCGE 7
4345
#define NEON_3R_VSHL 8
4346
#define NEON_3R_VQSHL 9
4347
#define NEON_3R_VRSHL 10
4348
#define NEON_3R_VQRSHL 11
4349
#define NEON_3R_VMAX 12
4350
#define NEON_3R_VMIN 13
4351
#define NEON_3R_VABD 14
4352
#define NEON_3R_VABA 15
4353
#define NEON_3R_VADD_VSUB 16
4354
#define NEON_3R_VTST_VCEQ 17
4355
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4356
#define NEON_3R_VMUL 19
4357
#define NEON_3R_VPMAX 20
4358
#define NEON_3R_VPMIN 21
4359
#define NEON_3R_VQDMULH_VQRDMULH 22
4360
#define NEON_3R_VPADD 23
4361
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4362
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4363
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4364
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4365
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4366
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4367

    
4368
static const uint8_t neon_3r_sizes[] = {
4369
    [NEON_3R_VHADD] = 0x7,
4370
    [NEON_3R_VQADD] = 0xf,
4371
    [NEON_3R_VRHADD] = 0x7,
4372
    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4373
    [NEON_3R_VHSUB] = 0x7,
4374
    [NEON_3R_VQSUB] = 0xf,
4375
    [NEON_3R_VCGT] = 0x7,
4376
    [NEON_3R_VCGE] = 0x7,
4377
    [NEON_3R_VSHL] = 0xf,
4378
    [NEON_3R_VQSHL] = 0xf,
4379
    [NEON_3R_VRSHL] = 0xf,
4380
    [NEON_3R_VQRSHL] = 0xf,
4381
    [NEON_3R_VMAX] = 0x7,
4382
    [NEON_3R_VMIN] = 0x7,
4383
    [NEON_3R_VABD] = 0x7,
4384
    [NEON_3R_VABA] = 0x7,
4385
    [NEON_3R_VADD_VSUB] = 0xf,
4386
    [NEON_3R_VTST_VCEQ] = 0x7,
4387
    [NEON_3R_VML] = 0x7,
4388
    [NEON_3R_VMUL] = 0x7,
4389
    [NEON_3R_VPMAX] = 0x7,
4390
    [NEON_3R_VPMIN] = 0x7,
4391
    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4392
    [NEON_3R_VPADD] = 0x7,
4393
    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4394
    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4395
    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4396
    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4397
    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4398
    [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4399
};
4400

    
4401
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4402
 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4403
 * table A7-13.
4404
 */
4405
#define NEON_2RM_VREV64 0
4406
#define NEON_2RM_VREV32 1
4407
#define NEON_2RM_VREV16 2
4408
#define NEON_2RM_VPADDL 4
4409
#define NEON_2RM_VPADDL_U 5
4410
#define NEON_2RM_VCLS 8
4411
#define NEON_2RM_VCLZ 9
4412
#define NEON_2RM_VCNT 10
4413
#define NEON_2RM_VMVN 11
4414
#define NEON_2RM_VPADAL 12
4415
#define NEON_2RM_VPADAL_U 13
4416
#define NEON_2RM_VQABS 14
4417
#define NEON_2RM_VQNEG 15
4418
#define NEON_2RM_VCGT0 16
4419
#define NEON_2RM_VCGE0 17
4420
#define NEON_2RM_VCEQ0 18
4421
#define NEON_2RM_VCLE0 19
4422
#define NEON_2RM_VCLT0 20
4423
#define NEON_2RM_VABS 22
4424
#define NEON_2RM_VNEG 23
4425
#define NEON_2RM_VCGT0_F 24
4426
#define NEON_2RM_VCGE0_F 25
4427
#define NEON_2RM_VCEQ0_F 26
4428
#define NEON_2RM_VCLE0_F 27
4429
#define NEON_2RM_VCLT0_F 28
4430
#define NEON_2RM_VABS_F 30
4431
#define NEON_2RM_VNEG_F 31
4432
#define NEON_2RM_VSWP 32
4433
#define NEON_2RM_VTRN 33
4434
#define NEON_2RM_VUZP 34
4435
#define NEON_2RM_VZIP 35
4436
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4437
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4438
#define NEON_2RM_VSHLL 38
4439
#define NEON_2RM_VCVT_F16_F32 44
4440
#define NEON_2RM_VCVT_F32_F16 46
4441
#define NEON_2RM_VRECPE 56
4442
#define NEON_2RM_VRSQRTE 57
4443
#define NEON_2RM_VRECPE_F 58
4444
#define NEON_2RM_VRSQRTE_F 59
4445
#define NEON_2RM_VCVT_FS 60
4446
#define NEON_2RM_VCVT_FU 61
4447
#define NEON_2RM_VCVT_SF 62
4448
#define NEON_2RM_VCVT_UF 63
4449

    
4450
static int neon_2rm_is_float_op(int op)
4451
{
4452
    /* Return true if this neon 2reg-misc op is float-to-float */
4453
    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4454
            op >= NEON_2RM_VRECPE_F);
4455
}
4456

    
4457
/* Each entry in this array has bit n set if the insn allows
4458
 * size value n (otherwise it will UNDEF). Since unallocated
4459
 * op values will have no bits set they always UNDEF.
4460
 */
4461
static const uint8_t neon_2rm_sizes[] = {
4462
    [NEON_2RM_VREV64] = 0x7,
4463
    [NEON_2RM_VREV32] = 0x3,
4464
    [NEON_2RM_VREV16] = 0x1,
4465
    [NEON_2RM_VPADDL] = 0x7,
4466
    [NEON_2RM_VPADDL_U] = 0x7,
4467
    [NEON_2RM_VCLS] = 0x7,
4468
    [NEON_2RM_VCLZ] = 0x7,
4469
    [NEON_2RM_VCNT] = 0x1,
4470
    [NEON_2RM_VMVN] = 0x1,
4471
    [NEON_2RM_VPADAL] = 0x7,
4472
    [NEON_2RM_VPADAL_U] = 0x7,
4473
    [NEON_2RM_VQABS] = 0x7,
4474
    [NEON_2RM_VQNEG] = 0x7,
4475
    [NEON_2RM_VCGT0] = 0x7,
4476
    [NEON_2RM_VCGE0] = 0x7,
4477
    [NEON_2RM_VCEQ0] = 0x7,
4478
    [NEON_2RM_VCLE0] = 0x7,
4479
    [NEON_2RM_VCLT0] = 0x7,
4480
    [NEON_2RM_VABS] = 0x7,
4481
    [NEON_2RM_VNEG] = 0x7,
4482
    [NEON_2RM_VCGT0_F] = 0x4,
4483
    [NEON_2RM_VCGE0_F] = 0x4,
4484
    [NEON_2RM_VCEQ0_F] = 0x4,
4485
    [NEON_2RM_VCLE0_F] = 0x4,
4486
    [NEON_2RM_VCLT0_F] = 0x4,
4487
    [NEON_2RM_VABS_F] = 0x4,
4488
    [NEON_2RM_VNEG_F] = 0x4,
4489
    [NEON_2RM_VSWP] = 0x1,
4490
    [NEON_2RM_VTRN] = 0x7,
4491
    [NEON_2RM_VUZP] = 0x7,
4492
    [NEON_2RM_VZIP] = 0x7,
4493
    [NEON_2RM_VMOVN] = 0x7,
4494
    [NEON_2RM_VQMOVN] = 0x7,
4495
    [NEON_2RM_VSHLL] = 0x7,
4496
    [NEON_2RM_VCVT_F16_F32] = 0x2,
4497
    [NEON_2RM_VCVT_F32_F16] = 0x2,
4498
    [NEON_2RM_VRECPE] = 0x4,
4499
    [NEON_2RM_VRSQRTE] = 0x4,
4500
    [NEON_2RM_VRECPE_F] = 0x4,
4501
    [NEON_2RM_VRSQRTE_F] = 0x4,
4502
    [NEON_2RM_VCVT_FS] = 0x4,
4503
    [NEON_2RM_VCVT_FU] = 0x4,
4504
    [NEON_2RM_VCVT_SF] = 0x4,
4505
    [NEON_2RM_VCVT_UF] = 0x4,
4506
};
4507

    
4508
/* Translate a NEON data processing instruction.  Return nonzero if the
4509
   instruction is invalid.
4510
   We process data in a mixture of 32-bit and 64-bit chunks.
4511
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4512

    
4513
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4514
{
4515
    int op;
4516
    int q;
4517
    int rd, rn, rm;
4518
    int size;
4519
    int shift;
4520
    int pass;
4521
    int count;
4522
    int pairwise;
4523
    int u;
4524
    uint32_t imm, mask;
4525
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4526
    TCGv_i64 tmp64;
4527

    
4528
    if (!s->vfp_enabled)
4529
      return 1;
4530
    q = (insn & (1 << 6)) != 0;
4531
    u = (insn >> 24) & 1;
4532
    VFP_DREG_D(rd, insn);
4533
    VFP_DREG_N(rn, insn);
4534
    VFP_DREG_M(rm, insn);
4535
    size = (insn >> 20) & 3;
4536
    if ((insn & (1 << 23)) == 0) {
4537
        /* Three register same length.  */
4538
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4539
        /* Catch invalid op and bad size combinations: UNDEF */
4540
        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4541
            return 1;
4542
        }
4543
        /* All insns of this form UNDEF for either this condition or the
4544
         * superset of cases "Q==1"; we catch the latter later.
4545
         */
4546
        if (q && ((rd | rn | rm) & 1)) {
4547
            return 1;
4548
        }
4549
        if (size == 3 && op != NEON_3R_LOGIC) {
4550
            /* 64-bit element instructions. */
4551
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4552
                neon_load_reg64(cpu_V0, rn + pass);
4553
                neon_load_reg64(cpu_V1, rm + pass);
4554
                switch (op) {
4555
                case NEON_3R_VQADD:
4556
                    if (u) {
4557
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_V0, cpu_V1);
4558
                    } else {
4559
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_V0, cpu_V1);
4560
                    }
4561
                    break;
4562
                case NEON_3R_VQSUB:
4563
                    if (u) {
4564
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_V0, cpu_V1);
4565
                    } else {
4566
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_V0, cpu_V1);
4567
                    }
4568
                    break;
4569
                case NEON_3R_VSHL:
4570
                    if (u) {
4571
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4572
                    } else {
4573
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4574
                    }
4575
                    break;
4576
                case NEON_3R_VQSHL:
4577
                    if (u) {
4578
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_V1, cpu_V0);
4579
                    } else {
4580
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_V1, cpu_V0);
4581
                    }
4582
                    break;
4583
                case NEON_3R_VRSHL:
4584
                    if (u) {
4585
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4586
                    } else {
4587
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4588
                    }
4589
                    break;
4590
                case NEON_3R_VQRSHL:
4591
                    if (u) {
4592
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_V1, cpu_V0);
4593
                    } else {
4594
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_V1, cpu_V0);
4595
                    }
4596
                    break;
4597
                case NEON_3R_VADD_VSUB:
4598
                    if (u) {
4599
                        tcg_gen_sub_i64(CPU_V001);
4600
                    } else {
4601
                        tcg_gen_add_i64(CPU_V001);
4602
                    }
4603
                    break;
4604
                default:
4605
                    abort();
4606
                }
4607
                neon_store_reg64(cpu_V0, rd + pass);
4608
            }
4609
            return 0;
4610
        }
4611
        pairwise = 0;
4612
        switch (op) {
4613
        case NEON_3R_VSHL:
4614
        case NEON_3R_VQSHL:
4615
        case NEON_3R_VRSHL:
4616
        case NEON_3R_VQRSHL:
4617
            {
4618
                int rtmp;
4619
                /* Shift instruction operands are reversed.  */
4620
                rtmp = rn;
4621
                rn = rm;
4622
                rm = rtmp;
4623
            }
4624
            break;
4625
        case NEON_3R_VPADD:
4626
            if (u) {
4627
                return 1;
4628
            }
4629
            /* Fall through */
4630
        case NEON_3R_VPMAX:
4631
        case NEON_3R_VPMIN:
4632
            pairwise = 1;
4633
            break;
4634
        case NEON_3R_FLOAT_ARITH:
4635
            pairwise = (u && size < 2); /* if VPADD (float) */
4636
            break;
4637
        case NEON_3R_FLOAT_MINMAX:
4638
            pairwise = u; /* if VPMIN/VPMAX (float) */
4639
            break;
4640
        case NEON_3R_FLOAT_CMP:
4641
            if (!u && size) {
4642
                /* no encoding for U=0 C=1x */
4643
                return 1;
4644
            }
4645
            break;
4646
        case NEON_3R_FLOAT_ACMP:
4647
            if (!u) {
4648
                return 1;
4649
            }
4650
            break;
4651
        case NEON_3R_VRECPS_VRSQRTS:
4652
            if (u) {
4653
                return 1;
4654
            }
4655
            break;
4656
        case NEON_3R_VMUL:
4657
            if (u && (size != 0)) {
4658
                /* UNDEF on invalid size for polynomial subcase */
4659
                return 1;
4660
            }
4661
            break;
4662
        default:
4663
            break;
4664
        }
4665

    
4666
        if (pairwise && q) {
4667
            /* All the pairwise insns UNDEF if Q is set */
4668
            return 1;
4669
        }
4670

    
4671
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4672

    
4673
        if (pairwise) {
4674
            /* Pairwise.  */
4675
            if (pass < 1) {
4676
                tmp = neon_load_reg(rn, 0);
4677
                tmp2 = neon_load_reg(rn, 1);
4678
            } else {
4679
                tmp = neon_load_reg(rm, 0);
4680
                tmp2 = neon_load_reg(rm, 1);
4681
            }
4682
        } else {
4683
            /* Elementwise.  */
4684
            tmp = neon_load_reg(rn, pass);
4685
            tmp2 = neon_load_reg(rm, pass);
4686
        }
4687
        switch (op) {
4688
        case NEON_3R_VHADD:
4689
            GEN_NEON_INTEGER_OP(hadd);
4690
            break;
4691
        case NEON_3R_VQADD:
4692
            GEN_NEON_INTEGER_OP(qadd);
4693
            break;
4694
        case NEON_3R_VRHADD:
4695
            GEN_NEON_INTEGER_OP(rhadd);
4696
            break;
4697
        case NEON_3R_LOGIC: /* Logic ops.  */
4698
            switch ((u << 2) | size) {
4699
            case 0: /* VAND */
4700
                tcg_gen_and_i32(tmp, tmp, tmp2);
4701
                break;
4702
            case 1: /* BIC */
4703
                tcg_gen_andc_i32(tmp, tmp, tmp2);
4704
                break;
4705
            case 2: /* VORR */
4706
                tcg_gen_or_i32(tmp, tmp, tmp2);
4707
                break;
4708
            case 3: /* VORN */
4709
                tcg_gen_orc_i32(tmp, tmp, tmp2);
4710
                break;
4711
            case 4: /* VEOR */
4712
                tcg_gen_xor_i32(tmp, tmp, tmp2);
4713
                break;
4714
            case 5: /* VBSL */
4715
                tmp3 = neon_load_reg(rd, pass);
4716
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4717
                tcg_temp_free_i32(tmp3);
4718
                break;
4719
            case 6: /* VBIT */
4720
                tmp3 = neon_load_reg(rd, pass);
4721
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4722
                tcg_temp_free_i32(tmp3);
4723
                break;
4724
            case 7: /* VBIF */
4725
                tmp3 = neon_load_reg(rd, pass);
4726
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4727
                tcg_temp_free_i32(tmp3);
4728
                break;
4729
            }
4730
            break;
4731
        case NEON_3R_VHSUB:
4732
            GEN_NEON_INTEGER_OP(hsub);
4733
            break;
4734
        case NEON_3R_VQSUB:
4735
            GEN_NEON_INTEGER_OP(qsub);
4736
            break;
4737
        case NEON_3R_VCGT:
4738
            GEN_NEON_INTEGER_OP(cgt);
4739
            break;
4740
        case NEON_3R_VCGE:
4741
            GEN_NEON_INTEGER_OP(cge);
4742
            break;
4743
        case NEON_3R_VSHL:
4744
            GEN_NEON_INTEGER_OP(shl);
4745
            break;
4746
        case NEON_3R_VQSHL:
4747
            GEN_NEON_INTEGER_OP(qshl);
4748
            break;
4749
        case NEON_3R_VRSHL:
4750
            GEN_NEON_INTEGER_OP(rshl);
4751
            break;
4752
        case NEON_3R_VQRSHL:
4753
            GEN_NEON_INTEGER_OP(qrshl);
4754
            break;
4755
        case NEON_3R_VMAX:
4756
            GEN_NEON_INTEGER_OP(max);
4757
            break;
4758
        case NEON_3R_VMIN:
4759
            GEN_NEON_INTEGER_OP(min);
4760
            break;
4761
        case NEON_3R_VABD:
4762
            GEN_NEON_INTEGER_OP(abd);
4763
            break;
4764
        case NEON_3R_VABA:
4765
            GEN_NEON_INTEGER_OP(abd);
4766
            tcg_temp_free_i32(tmp2);
4767
            tmp2 = neon_load_reg(rd, pass);
4768
            gen_neon_add(size, tmp, tmp2);
4769
            break;
4770
        case NEON_3R_VADD_VSUB:
4771
            if (!u) { /* VADD */
4772
                gen_neon_add(size, tmp, tmp2);
4773
            } else { /* VSUB */
4774
                switch (size) {
4775
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4776
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4777
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4778
                default: abort();
4779
                }
4780
            }
4781
            break;
4782
        case NEON_3R_VTST_VCEQ:
4783
            if (!u) { /* VTST */
4784
                switch (size) {
4785
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4786
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4787
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4788
                default: abort();
4789
                }
4790
            } else { /* VCEQ */
4791
                switch (size) {
4792
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4793
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4794
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4795
                default: abort();
4796
                }
4797
            }
4798
            break;
4799
        case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4800
            switch (size) {
4801
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4802
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4803
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4804
            default: abort();
4805
            }
4806
            tcg_temp_free_i32(tmp2);
4807
            tmp2 = neon_load_reg(rd, pass);
4808
            if (u) { /* VMLS */
4809
                gen_neon_rsb(size, tmp, tmp2);
4810
            } else { /* VMLA */
4811
                gen_neon_add(size, tmp, tmp2);
4812
            }
4813
            break;
4814
        case NEON_3R_VMUL:
4815
            if (u) { /* pol