Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 72cf2d4f

History | View | Annotate | Download (300.6 kB)

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

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

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

    
37
#define ENABLE_ARCH_5J    0
38
#define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
39
#define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
40
#define ENABLE_ARCH_6T2   arm_feature(env, ARM_FEATURE_THUMB2)
41
#define ENABLE_ARCH_7     arm_feature(env, ARM_FEATURE_V7)
42

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

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

    
64
#if defined(CONFIG_USER_ONLY)
65
#define IS_USER(s) 1
66
#else
67
#define IS_USER(s) (s->user)
68
#endif
69

    
70
/* These instructions trap after executing, so defer them until after the
71
   conditional executions state has been updated.  */
72
#define DISAS_WFI 4
73
#define DISAS_SWI 5
74

    
75
static TCGv_ptr cpu_env;
76
/* We reuse the same 64-bit temporaries for efficiency.  */
77
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
78

    
79
/* FIXME:  These should be removed.  */
80
static TCGv cpu_T[2];
81
static TCGv cpu_F0s, cpu_F1s;
82
static TCGv_i64 cpu_F0d, cpu_F1d;
83

    
84
#define ICOUNT_TEMP cpu_T[0]
85
#include "gen-icount.h"
86

    
87
/* initialize TCG globals.  */
88
void arm_translate_init(void)
89
{
90
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
91

    
92
    cpu_T[0] = tcg_global_reg_new_i32(TCG_AREG1, "T0");
93
    cpu_T[1] = tcg_global_reg_new_i32(TCG_AREG2, "T1");
94

    
95
#define GEN_HELPER 2
96
#include "helpers.h"
97
}
98

    
99
/* The code generator doesn't like lots of temporaries, so maintain our own
100
   cache for reuse within a function.  */
101
#define MAX_TEMPS 8
102
static int num_temps;
103
static TCGv temps[MAX_TEMPS];
104

    
105
/* Allocate a temporary variable.  */
106
static TCGv_i32 new_tmp(void)
107
{
108
    TCGv tmp;
109
    if (num_temps == MAX_TEMPS)
110
        abort();
111

    
112
    if (GET_TCGV_I32(temps[num_temps]))
113
      return temps[num_temps++];
114

    
115
    tmp = tcg_temp_new_i32();
116
    temps[num_temps++] = tmp;
117
    return tmp;
118
}
119

    
120
/* Release a temporary variable.  */
121
static void dead_tmp(TCGv tmp)
122
{
123
    int i;
124
    num_temps--;
125
    i = num_temps;
126
    if (TCGV_EQUAL(temps[i], tmp))
127
        return;
128

    
129
    /* Shuffle this temp to the last slot.  */
130
    while (!TCGV_EQUAL(temps[i], tmp))
131
        i--;
132
    while (i < num_temps) {
133
        temps[i] = temps[i + 1];
134
        i++;
135
    }
136
    temps[i] = tmp;
137
}
138

    
139
static inline TCGv load_cpu_offset(int offset)
140
{
141
    TCGv tmp = new_tmp();
142
    tcg_gen_ld_i32(tmp, cpu_env, offset);
143
    return tmp;
144
}
145

    
146
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
147

    
148
static inline void store_cpu_offset(TCGv var, int offset)
149
{
150
    tcg_gen_st_i32(var, cpu_env, offset);
151
    dead_tmp(var);
152
}
153

    
154
#define store_cpu_field(var, name) \
155
    store_cpu_offset(var, offsetof(CPUState, name))
156

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

    
173
/* Create a new temporary and set it to the value of a CPU register.  */
174
static inline TCGv load_reg(DisasContext *s, int reg)
175
{
176
    TCGv tmp = new_tmp();
177
    load_reg_var(s, tmp, reg);
178
    return tmp;
179
}
180

    
181
/* Set a CPU register.  The source must be a temporary and will be
182
   marked as dead.  */
183
static void store_reg(DisasContext *s, int reg, TCGv var)
184
{
185
    if (reg == 15) {
186
        tcg_gen_andi_i32(var, var, ~1);
187
        s->is_jmp = DISAS_JUMP;
188
    }
189
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
190
    dead_tmp(var);
191
}
192

    
193

    
194
/* Basic operations.  */
195
#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
196
#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
197
#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
198

    
199
#define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
200
#define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
201
#define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
202
#define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
203

    
204
#define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
205
#define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
206
#define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
207
#define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
208
#define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
209

    
210
#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
211
#define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
212
#define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
213
#define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
214
#define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
215
#define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
216
#define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
217

    
218
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
219
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
220

    
221
/* Value extensions.  */
222
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
223
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
224
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
225
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
226

    
227
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
228
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
229

    
230
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
231

    
232
#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
233
/* Set NZCV flags from the high 4 bits of var.  */
234
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
235

    
236
static void gen_exception(int excp)
237
{
238
    TCGv tmp = new_tmp();
239
    tcg_gen_movi_i32(tmp, excp);
240
    gen_helper_exception(tmp);
241
    dead_tmp(tmp);
242
}
243

    
244
static void gen_smul_dual(TCGv a, TCGv b)
245
{
246
    TCGv tmp1 = new_tmp();
247
    TCGv tmp2 = new_tmp();
248
    tcg_gen_ext16s_i32(tmp1, a);
249
    tcg_gen_ext16s_i32(tmp2, b);
250
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
251
    dead_tmp(tmp2);
252
    tcg_gen_sari_i32(a, a, 16);
253
    tcg_gen_sari_i32(b, b, 16);
254
    tcg_gen_mul_i32(b, b, a);
255
    tcg_gen_mov_i32(a, tmp1);
256
    dead_tmp(tmp1);
257
}
258

    
259
/* Byteswap each halfword.  */
260
static void gen_rev16(TCGv var)
261
{
262
    TCGv tmp = new_tmp();
263
    tcg_gen_shri_i32(tmp, var, 8);
264
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
265
    tcg_gen_shli_i32(var, var, 8);
266
    tcg_gen_andi_i32(var, var, 0xff00ff00);
267
    tcg_gen_or_i32(var, var, tmp);
268
    dead_tmp(tmp);
269
}
270

    
271
/* Byteswap low halfword and sign extend.  */
272
static void gen_revsh(TCGv var)
273
{
274
    TCGv tmp = new_tmp();
275
    tcg_gen_shri_i32(tmp, var, 8);
276
    tcg_gen_andi_i32(tmp, tmp, 0x00ff);
277
    tcg_gen_shli_i32(var, var, 8);
278
    tcg_gen_ext8s_i32(var, var);
279
    tcg_gen_or_i32(var, var, tmp);
280
    dead_tmp(tmp);
281
}
282

    
283
/* Unsigned bitfield extract.  */
284
static void gen_ubfx(TCGv var, int shift, uint32_t mask)
285
{
286
    if (shift)
287
        tcg_gen_shri_i32(var, var, shift);
288
    tcg_gen_andi_i32(var, var, mask);
289
}
290

    
291
/* Signed bitfield extract.  */
292
static void gen_sbfx(TCGv var, int shift, int width)
293
{
294
    uint32_t signbit;
295

    
296
    if (shift)
297
        tcg_gen_sari_i32(var, var, shift);
298
    if (shift + width < 32) {
299
        signbit = 1u << (width - 1);
300
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
301
        tcg_gen_xori_i32(var, var, signbit);
302
        tcg_gen_subi_i32(var, var, signbit);
303
    }
304
}
305

    
306
/* Bitfield insertion.  Insert val into base.  Clobbers base and val.  */
307
static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
308
{
309
    tcg_gen_andi_i32(val, val, mask);
310
    tcg_gen_shli_i32(val, val, shift);
311
    tcg_gen_andi_i32(base, base, ~(mask << shift));
312
    tcg_gen_or_i32(dest, base, val);
313
}
314

    
315
/* Round the top 32 bits of a 64-bit value.  */
316
static void gen_roundqd(TCGv a, TCGv b)
317
{
318
    tcg_gen_shri_i32(a, a, 31);
319
    tcg_gen_add_i32(a, a, b);
320
}
321

    
322
/* FIXME: Most targets have native widening multiplication.
323
   It would be good to use that instead of a full wide multiply.  */
324
/* 32x32->64 multiply.  Marks inputs as dead.  */
325
static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
326
{
327
    TCGv_i64 tmp1 = tcg_temp_new_i64();
328
    TCGv_i64 tmp2 = tcg_temp_new_i64();
329

    
330
    tcg_gen_extu_i32_i64(tmp1, a);
331
    dead_tmp(a);
332
    tcg_gen_extu_i32_i64(tmp2, b);
333
    dead_tmp(b);
334
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
335
    return tmp1;
336
}
337

    
338
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
339
{
340
    TCGv_i64 tmp1 = tcg_temp_new_i64();
341
    TCGv_i64 tmp2 = tcg_temp_new_i64();
342

    
343
    tcg_gen_ext_i32_i64(tmp1, a);
344
    dead_tmp(a);
345
    tcg_gen_ext_i32_i64(tmp2, b);
346
    dead_tmp(b);
347
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
348
    return tmp1;
349
}
350

    
351
/* Unsigned 32x32->64 multiply.  */
352
static void gen_op_mull_T0_T1(void)
353
{
354
    TCGv_i64 tmp1 = tcg_temp_new_i64();
355
    TCGv_i64 tmp2 = tcg_temp_new_i64();
356

    
357
    tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
358
    tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
359
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
360
    tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
361
    tcg_gen_shri_i64(tmp1, tmp1, 32);
362
    tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
363
}
364

    
365
/* Signed 32x32->64 multiply.  */
366
static void gen_imull(TCGv a, TCGv b)
367
{
368
    TCGv_i64 tmp1 = tcg_temp_new_i64();
369
    TCGv_i64 tmp2 = tcg_temp_new_i64();
370

    
371
    tcg_gen_ext_i32_i64(tmp1, a);
372
    tcg_gen_ext_i32_i64(tmp2, b);
373
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
374
    tcg_gen_trunc_i64_i32(a, tmp1);
375
    tcg_gen_shri_i64(tmp1, tmp1, 32);
376
    tcg_gen_trunc_i64_i32(b, tmp1);
377
}
378

    
379
/* Swap low and high halfwords.  */
380
static void gen_swap_half(TCGv var)
381
{
382
    TCGv tmp = new_tmp();
383
    tcg_gen_shri_i32(tmp, var, 16);
384
    tcg_gen_shli_i32(var, var, 16);
385
    tcg_gen_or_i32(var, var, tmp);
386
    dead_tmp(tmp);
387
}
388

    
389
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
390
    tmp = (t0 ^ t1) & 0x8000;
391
    t0 &= ~0x8000;
392
    t1 &= ~0x8000;
393
    t0 = (t0 + t1) ^ tmp;
394
 */
395

    
396
static void gen_add16(TCGv t0, TCGv t1)
397
{
398
    TCGv tmp = new_tmp();
399
    tcg_gen_xor_i32(tmp, t0, t1);
400
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
401
    tcg_gen_andi_i32(t0, t0, ~0x8000);
402
    tcg_gen_andi_i32(t1, t1, ~0x8000);
403
    tcg_gen_add_i32(t0, t0, t1);
404
    tcg_gen_xor_i32(t0, t0, tmp);
405
    dead_tmp(tmp);
406
    dead_tmp(t1);
407
}
408

    
409
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
410

    
411
/* Set CF to the top bit of var.  */
412
static void gen_set_CF_bit31(TCGv var)
413
{
414
    TCGv tmp = new_tmp();
415
    tcg_gen_shri_i32(tmp, var, 31);
416
    gen_set_CF(tmp);
417
    dead_tmp(tmp);
418
}
419

    
420
/* Set N and Z flags from var.  */
421
static inline void gen_logic_CC(TCGv var)
422
{
423
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
424
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
425
}
426

    
427
/* T0 += T1 + CF.  */
428
static void gen_adc_T0_T1(void)
429
{
430
    TCGv tmp;
431
    gen_op_addl_T0_T1();
432
    tmp = load_cpu_field(CF);
433
    tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
434
    dead_tmp(tmp);
435
}
436

    
437
/* dest = T0 + T1 + CF. */
438
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
439
{
440
    TCGv tmp;
441
    tcg_gen_add_i32(dest, t0, t1);
442
    tmp = load_cpu_field(CF);
443
    tcg_gen_add_i32(dest, dest, tmp);
444
    dead_tmp(tmp);
445
}
446

    
447
/* dest = T0 - T1 + CF - 1.  */
448
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
449
{
450
    TCGv tmp;
451
    tcg_gen_sub_i32(dest, t0, t1);
452
    tmp = load_cpu_field(CF);
453
    tcg_gen_add_i32(dest, dest, tmp);
454
    tcg_gen_subi_i32(dest, dest, 1);
455
    dead_tmp(tmp);
456
}
457

    
458
#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
459
#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
460

    
461
/* T0 &= ~T1.  Clobbers T1.  */
462
/* FIXME: Implement bic natively.  */
463
static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
464
{
465
    TCGv tmp = new_tmp();
466
    tcg_gen_not_i32(tmp, t1);
467
    tcg_gen_and_i32(dest, t0, tmp);
468
    dead_tmp(tmp);
469
}
470
static inline void gen_op_bicl_T0_T1(void)
471
{
472
    gen_op_notl_T1();
473
    gen_op_andl_T0_T1();
474
}
475

    
476
/* FIXME:  Implement this natively.  */
477
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
478

    
479
/* FIXME:  Implement this natively.  */
480
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
481
{
482
    TCGv tmp;
483

    
484
    if (i == 0)
485
        return;
486

    
487
    tmp = new_tmp();
488
    tcg_gen_shri_i32(tmp, t1, i);
489
    tcg_gen_shli_i32(t1, t1, 32 - i);
490
    tcg_gen_or_i32(t0, t1, tmp);
491
    dead_tmp(tmp);
492
}
493

    
494
static void shifter_out_im(TCGv var, int shift)
495
{
496
    TCGv tmp = new_tmp();
497
    if (shift == 0) {
498
        tcg_gen_andi_i32(tmp, var, 1);
499
    } else {
500
        tcg_gen_shri_i32(tmp, var, shift);
501
        if (shift != 31)
502
            tcg_gen_andi_i32(tmp, tmp, 1);
503
    }
504
    gen_set_CF(tmp);
505
    dead_tmp(tmp);
506
}
507

    
508
/* Shift by immediate.  Includes special handling for shift == 0.  */
509
static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
510
{
511
    switch (shiftop) {
512
    case 0: /* LSL */
513
        if (shift != 0) {
514
            if (flags)
515
                shifter_out_im(var, 32 - shift);
516
            tcg_gen_shli_i32(var, var, shift);
517
        }
518
        break;
519
    case 1: /* LSR */
520
        if (shift == 0) {
521
            if (flags) {
522
                tcg_gen_shri_i32(var, var, 31);
523
                gen_set_CF(var);
524
            }
525
            tcg_gen_movi_i32(var, 0);
526
        } else {
527
            if (flags)
528
                shifter_out_im(var, shift - 1);
529
            tcg_gen_shri_i32(var, var, shift);
530
        }
531
        break;
532
    case 2: /* ASR */
533
        if (shift == 0)
534
            shift = 32;
535
        if (flags)
536
            shifter_out_im(var, shift - 1);
537
        if (shift == 32)
538
          shift = 31;
539
        tcg_gen_sari_i32(var, var, shift);
540
        break;
541
    case 3: /* ROR/RRX */
542
        if (shift != 0) {
543
            if (flags)
544
                shifter_out_im(var, shift - 1);
545
            tcg_gen_rori_i32(var, var, shift); break;
546
        } else {
547
            TCGv tmp = load_cpu_field(CF);
548
            if (flags)
549
                shifter_out_im(var, 0);
550
            tcg_gen_shri_i32(var, var, 1);
551
            tcg_gen_shli_i32(tmp, tmp, 31);
552
            tcg_gen_or_i32(var, var, tmp);
553
            dead_tmp(tmp);
554
        }
555
    }
556
};
557

    
558
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
559
                                     TCGv shift, int flags)
560
{
561
    if (flags) {
562
        switch (shiftop) {
563
        case 0: gen_helper_shl_cc(var, var, shift); break;
564
        case 1: gen_helper_shr_cc(var, var, shift); break;
565
        case 2: gen_helper_sar_cc(var, var, shift); break;
566
        case 3: gen_helper_ror_cc(var, var, shift); break;
567
        }
568
    } else {
569
        switch (shiftop) {
570
        case 0: gen_helper_shl(var, var, shift); break;
571
        case 1: gen_helper_shr(var, var, shift); break;
572
        case 2: gen_helper_sar(var, var, shift); break;
573
        case 3: gen_helper_ror(var, var, shift); break;
574
        }
575
    }
576
    dead_tmp(shift);
577
}
578

    
579
#define PAS_OP(pfx) \
580
    switch (op2) {  \
581
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
582
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
583
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
584
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
585
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
586
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
587
    }
588
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
589
{
590
    TCGv_ptr tmp;
591

    
592
    switch (op1) {
593
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
594
    case 1:
595
        tmp = tcg_temp_new_ptr();
596
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
597
        PAS_OP(s)
598
        break;
599
    case 5:
600
        tmp = tcg_temp_new_ptr();
601
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
602
        PAS_OP(u)
603
        break;
604
#undef gen_pas_helper
605
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
606
    case 2:
607
        PAS_OP(q);
608
        break;
609
    case 3:
610
        PAS_OP(sh);
611
        break;
612
    case 6:
613
        PAS_OP(uq);
614
        break;
615
    case 7:
616
        PAS_OP(uh);
617
        break;
618
#undef gen_pas_helper
619
    }
620
}
621
#undef PAS_OP
622

    
623
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
624
#define PAS_OP(pfx) \
625
    switch (op2) {  \
626
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
627
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
628
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
629
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
630
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
631
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
632
    }
633
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
634
{
635
    TCGv_ptr tmp;
636

    
637
    switch (op1) {
638
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
639
    case 0:
640
        tmp = tcg_temp_new_ptr();
641
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
642
        PAS_OP(s)
643
        break;
644
    case 4:
645
        tmp = tcg_temp_new_ptr();
646
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
647
        PAS_OP(u)
648
        break;
649
#undef gen_pas_helper
650
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
651
    case 1:
652
        PAS_OP(q);
653
        break;
654
    case 2:
655
        PAS_OP(sh);
656
        break;
657
    case 5:
658
        PAS_OP(uq);
659
        break;
660
    case 6:
661
        PAS_OP(uh);
662
        break;
663
#undef gen_pas_helper
664
    }
665
}
666
#undef PAS_OP
667

    
668
static void gen_test_cc(int cc, int label)
669
{
670
    TCGv tmp;
671
    TCGv tmp2;
672
    int inv;
673

    
674
    switch (cc) {
675
    case 0: /* eq: Z */
676
        tmp = load_cpu_field(ZF);
677
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
678
        break;
679
    case 1: /* ne: !Z */
680
        tmp = load_cpu_field(ZF);
681
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
682
        break;
683
    case 2: /* cs: C */
684
        tmp = load_cpu_field(CF);
685
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
686
        break;
687
    case 3: /* cc: !C */
688
        tmp = load_cpu_field(CF);
689
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
690
        break;
691
    case 4: /* mi: N */
692
        tmp = load_cpu_field(NF);
693
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
694
        break;
695
    case 5: /* pl: !N */
696
        tmp = load_cpu_field(NF);
697
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
698
        break;
699
    case 6: /* vs: V */
700
        tmp = load_cpu_field(VF);
701
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
702
        break;
703
    case 7: /* vc: !V */
704
        tmp = load_cpu_field(VF);
705
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
706
        break;
707
    case 8: /* hi: C && !Z */
708
        inv = gen_new_label();
709
        tmp = load_cpu_field(CF);
710
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
711
        dead_tmp(tmp);
712
        tmp = load_cpu_field(ZF);
713
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
714
        gen_set_label(inv);
715
        break;
716
    case 9: /* ls: !C || Z */
717
        tmp = load_cpu_field(CF);
718
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
719
        dead_tmp(tmp);
720
        tmp = load_cpu_field(ZF);
721
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
722
        break;
723
    case 10: /* ge: N == V -> N ^ V == 0 */
724
        tmp = load_cpu_field(VF);
725
        tmp2 = load_cpu_field(NF);
726
        tcg_gen_xor_i32(tmp, tmp, tmp2);
727
        dead_tmp(tmp2);
728
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
729
        break;
730
    case 11: /* lt: N != V -> N ^ V != 0 */
731
        tmp = load_cpu_field(VF);
732
        tmp2 = load_cpu_field(NF);
733
        tcg_gen_xor_i32(tmp, tmp, tmp2);
734
        dead_tmp(tmp2);
735
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
736
        break;
737
    case 12: /* gt: !Z && N == V */
738
        inv = gen_new_label();
739
        tmp = load_cpu_field(ZF);
740
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
741
        dead_tmp(tmp);
742
        tmp = load_cpu_field(VF);
743
        tmp2 = load_cpu_field(NF);
744
        tcg_gen_xor_i32(tmp, tmp, tmp2);
745
        dead_tmp(tmp2);
746
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
747
        gen_set_label(inv);
748
        break;
749
    case 13: /* le: Z || N != V */
750
        tmp = load_cpu_field(ZF);
751
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
752
        dead_tmp(tmp);
753
        tmp = load_cpu_field(VF);
754
        tmp2 = load_cpu_field(NF);
755
        tcg_gen_xor_i32(tmp, tmp, tmp2);
756
        dead_tmp(tmp2);
757
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
758
        break;
759
    default:
760
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
761
        abort();
762
    }
763
    dead_tmp(tmp);
764
}
765

    
766
static const uint8_t table_logic_cc[16] = {
767
    1, /* and */
768
    1, /* xor */
769
    0, /* sub */
770
    0, /* rsb */
771
    0, /* add */
772
    0, /* adc */
773
    0, /* sbc */
774
    0, /* rsc */
775
    1, /* andl */
776
    1, /* xorl */
777
    0, /* cmp */
778
    0, /* cmn */
779
    1, /* orr */
780
    1, /* mov */
781
    1, /* bic */
782
    1, /* mvn */
783
};
784

    
785
/* Set PC and Thumb state from an immediate address.  */
786
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
787
{
788
    TCGv tmp;
789

    
790
    s->is_jmp = DISAS_UPDATE;
791
    tmp = new_tmp();
792
    if (s->thumb != (addr & 1)) {
793
        tcg_gen_movi_i32(tmp, addr & 1);
794
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
795
    }
796
    tcg_gen_movi_i32(tmp, addr & ~1);
797
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
798
    dead_tmp(tmp);
799
}
800

    
801
/* Set PC and Thumb state from var.  var is marked as dead.  */
802
static inline void gen_bx(DisasContext *s, TCGv var)
803
{
804
    TCGv tmp;
805

    
806
    s->is_jmp = DISAS_UPDATE;
807
    tmp = new_tmp();
808
    tcg_gen_andi_i32(tmp, var, 1);
809
    store_cpu_field(tmp, thumb);
810
    tcg_gen_andi_i32(var, var, ~1);
811
    store_cpu_field(var, regs[15]);
812
}
813

    
814
/* Variant of store_reg which uses branch&exchange logic when storing
815
   to r15 in ARM architecture v7 and above. The source must be a temporary
816
   and will be marked as dead. */
817
static inline void store_reg_bx(CPUState *env, DisasContext *s,
818
                                int reg, TCGv var)
819
{
820
    if (reg == 15 && ENABLE_ARCH_7) {
821
        gen_bx(s, var);
822
    } else {
823
        store_reg(s, reg, var);
824
    }
825
}
826

    
827
static inline TCGv gen_ld8s(TCGv addr, int index)
828
{
829
    TCGv tmp = new_tmp();
830
    tcg_gen_qemu_ld8s(tmp, addr, index);
831
    return tmp;
832
}
833
static inline TCGv gen_ld8u(TCGv addr, int index)
834
{
835
    TCGv tmp = new_tmp();
836
    tcg_gen_qemu_ld8u(tmp, addr, index);
837
    return tmp;
838
}
839
static inline TCGv gen_ld16s(TCGv addr, int index)
840
{
841
    TCGv tmp = new_tmp();
842
    tcg_gen_qemu_ld16s(tmp, addr, index);
843
    return tmp;
844
}
845
static inline TCGv gen_ld16u(TCGv addr, int index)
846
{
847
    TCGv tmp = new_tmp();
848
    tcg_gen_qemu_ld16u(tmp, addr, index);
849
    return tmp;
850
}
851
static inline TCGv gen_ld32(TCGv addr, int index)
852
{
853
    TCGv tmp = new_tmp();
854
    tcg_gen_qemu_ld32u(tmp, addr, index);
855
    return tmp;
856
}
857
static inline void gen_st8(TCGv val, TCGv addr, int index)
858
{
859
    tcg_gen_qemu_st8(val, addr, index);
860
    dead_tmp(val);
861
}
862
static inline void gen_st16(TCGv val, TCGv addr, int index)
863
{
864
    tcg_gen_qemu_st16(val, addr, index);
865
    dead_tmp(val);
866
}
867
static inline void gen_st32(TCGv val, TCGv addr, int index)
868
{
869
    tcg_gen_qemu_st32(val, addr, index);
870
    dead_tmp(val);
871
}
872

    
873
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
874
{
875
    load_reg_var(s, cpu_T[0], reg);
876
}
877

    
878
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
879
{
880
    load_reg_var(s, cpu_T[1], reg);
881
}
882

    
883
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
884
{
885
    load_reg_var(s, cpu_T[2], reg);
886
}
887

    
888
static inline void gen_set_pc_im(uint32_t val)
889
{
890
    TCGv tmp = new_tmp();
891
    tcg_gen_movi_i32(tmp, val);
892
    store_cpu_field(tmp, regs[15]);
893
}
894

    
895
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
896
{
897
    TCGv tmp;
898
    if (reg == 15) {
899
        tmp = new_tmp();
900
        tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
901
    } else {
902
        tmp = cpu_T[t];
903
    }
904
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
905
    if (reg == 15) {
906
        dead_tmp(tmp);
907
        s->is_jmp = DISAS_JUMP;
908
    }
909
}
910

    
911
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
912
{
913
    gen_movl_reg_TN(s, reg, 0);
914
}
915

    
916
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
917
{
918
    gen_movl_reg_TN(s, reg, 1);
919
}
920

    
921
/* Force a TB lookup after an instruction that changes the CPU state.  */
922
static inline void gen_lookup_tb(DisasContext *s)
923
{
924
    gen_op_movl_T0_im(s->pc);
925
    gen_movl_reg_T0(s, 15);
926
    s->is_jmp = DISAS_UPDATE;
927
}
928

    
929
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
930
                                       TCGv var)
931
{
932
    int val, rm, shift, shiftop;
933
    TCGv offset;
934

    
935
    if (!(insn & (1 << 25))) {
936
        /* immediate */
937
        val = insn & 0xfff;
938
        if (!(insn & (1 << 23)))
939
            val = -val;
940
        if (val != 0)
941
            tcg_gen_addi_i32(var, var, val);
942
    } else {
943
        /* shift/register */
944
        rm = (insn) & 0xf;
945
        shift = (insn >> 7) & 0x1f;
946
        shiftop = (insn >> 5) & 3;
947
        offset = load_reg(s, rm);
948
        gen_arm_shift_im(offset, shiftop, shift, 0);
949
        if (!(insn & (1 << 23)))
950
            tcg_gen_sub_i32(var, var, offset);
951
        else
952
            tcg_gen_add_i32(var, var, offset);
953
        dead_tmp(offset);
954
    }
955
}
956

    
957
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
958
                                        int extra, TCGv var)
959
{
960
    int val, rm;
961
    TCGv offset;
962

    
963
    if (insn & (1 << 22)) {
964
        /* immediate */
965
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
966
        if (!(insn & (1 << 23)))
967
            val = -val;
968
        val += extra;
969
        if (val != 0)
970
            tcg_gen_addi_i32(var, var, val);
971
    } else {
972
        /* register */
973
        if (extra)
974
            tcg_gen_addi_i32(var, var, extra);
975
        rm = (insn) & 0xf;
976
        offset = load_reg(s, rm);
977
        if (!(insn & (1 << 23)))
978
            tcg_gen_sub_i32(var, var, offset);
979
        else
980
            tcg_gen_add_i32(var, var, offset);
981
        dead_tmp(offset);
982
    }
983
}
984

    
985
#define VFP_OP2(name)                                                 \
986
static inline void gen_vfp_##name(int dp)                             \
987
{                                                                     \
988
    if (dp)                                                           \
989
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
990
    else                                                              \
991
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
992
}
993

    
994
VFP_OP2(add)
995
VFP_OP2(sub)
996
VFP_OP2(mul)
997
VFP_OP2(div)
998

    
999
#undef VFP_OP2
1000

    
1001
static inline void gen_vfp_abs(int dp)
1002
{
1003
    if (dp)
1004
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1005
    else
1006
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1007
}
1008

    
1009
static inline void gen_vfp_neg(int dp)
1010
{
1011
    if (dp)
1012
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1013
    else
1014
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1015
}
1016

    
1017
static inline void gen_vfp_sqrt(int dp)
1018
{
1019
    if (dp)
1020
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1021
    else
1022
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1023
}
1024

    
1025
static inline void gen_vfp_cmp(int dp)
1026
{
1027
    if (dp)
1028
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1029
    else
1030
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1031
}
1032

    
1033
static inline void gen_vfp_cmpe(int dp)
1034
{
1035
    if (dp)
1036
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1037
    else
1038
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1039
}
1040

    
1041
static inline void gen_vfp_F1_ld0(int dp)
1042
{
1043
    if (dp)
1044
        tcg_gen_movi_i64(cpu_F1d, 0);
1045
    else
1046
        tcg_gen_movi_i32(cpu_F1s, 0);
1047
}
1048

    
1049
static inline void gen_vfp_uito(int dp)
1050
{
1051
    if (dp)
1052
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1053
    else
1054
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1055
}
1056

    
1057
static inline void gen_vfp_sito(int dp)
1058
{
1059
    if (dp)
1060
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1061
    else
1062
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1063
}
1064

    
1065
static inline void gen_vfp_toui(int dp)
1066
{
1067
    if (dp)
1068
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1069
    else
1070
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1071
}
1072

    
1073
static inline void gen_vfp_touiz(int dp)
1074
{
1075
    if (dp)
1076
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1077
    else
1078
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1079
}
1080

    
1081
static inline void gen_vfp_tosi(int dp)
1082
{
1083
    if (dp)
1084
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1085
    else
1086
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1087
}
1088

    
1089
static inline void gen_vfp_tosiz(int dp)
1090
{
1091
    if (dp)
1092
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1093
    else
1094
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1095
}
1096

    
1097
#define VFP_GEN_FIX(name) \
1098
static inline void gen_vfp_##name(int dp, int shift) \
1099
{ \
1100
    if (dp) \
1101
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1102
    else \
1103
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1104
}
1105
VFP_GEN_FIX(tosh)
1106
VFP_GEN_FIX(tosl)
1107
VFP_GEN_FIX(touh)
1108
VFP_GEN_FIX(toul)
1109
VFP_GEN_FIX(shto)
1110
VFP_GEN_FIX(slto)
1111
VFP_GEN_FIX(uhto)
1112
VFP_GEN_FIX(ulto)
1113
#undef VFP_GEN_FIX
1114

    
1115
static inline void gen_vfp_ld(DisasContext *s, int dp)
1116
{
1117
    if (dp)
1118
        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1119
    else
1120
        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1121
}
1122

    
1123
static inline void gen_vfp_st(DisasContext *s, int dp)
1124
{
1125
    if (dp)
1126
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1127
    else
1128
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1129
}
1130

    
1131
static inline long
1132
vfp_reg_offset (int dp, int reg)
1133
{
1134
    if (dp)
1135
        return offsetof(CPUARMState, vfp.regs[reg]);
1136
    else if (reg & 1) {
1137
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1138
          + offsetof(CPU_DoubleU, l.upper);
1139
    } else {
1140
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1141
          + offsetof(CPU_DoubleU, l.lower);
1142
    }
1143
}
1144

    
1145
/* Return the offset of a 32-bit piece of a NEON register.
1146
   zero is the least significant end of the register.  */
1147
static inline long
1148
neon_reg_offset (int reg, int n)
1149
{
1150
    int sreg;
1151
    sreg = reg * 2 + n;
1152
    return vfp_reg_offset(0, sreg);
1153
}
1154

    
1155
/* FIXME: Remove these.  */
1156
#define neon_T0 cpu_T[0]
1157
#define neon_T1 cpu_T[1]
1158
#define NEON_GET_REG(T, reg, n) \
1159
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1160
#define NEON_SET_REG(T, reg, n) \
1161
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1162

    
1163
static TCGv neon_load_reg(int reg, int pass)
1164
{
1165
    TCGv tmp = new_tmp();
1166
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1167
    return tmp;
1168
}
1169

    
1170
static void neon_store_reg(int reg, int pass, TCGv var)
1171
{
1172
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1173
    dead_tmp(var);
1174
}
1175

    
1176
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1177
{
1178
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1179
}
1180

    
1181
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1182
{
1183
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1184
}
1185

    
1186
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1187
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1188
#define tcg_gen_st_f32 tcg_gen_st_i32
1189
#define tcg_gen_st_f64 tcg_gen_st_i64
1190

    
1191
static inline void gen_mov_F0_vreg(int dp, int reg)
1192
{
1193
    if (dp)
1194
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1195
    else
1196
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1197
}
1198

    
1199
static inline void gen_mov_F1_vreg(int dp, int reg)
1200
{
1201
    if (dp)
1202
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1203
    else
1204
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1205
}
1206

    
1207
static inline void gen_mov_vreg_F0(int dp, int reg)
1208
{
1209
    if (dp)
1210
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1211
    else
1212
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1213
}
1214

    
1215
#define ARM_CP_RW_BIT        (1 << 20)
1216

    
1217
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1218
{
1219
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1220
}
1221

    
1222
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1223
{
1224
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1225
}
1226

    
1227
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1228
{
1229
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1230
}
1231

    
1232
static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1233
{
1234
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1235
}
1236

    
1237
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1238
{
1239
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1240
}
1241

    
1242
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1243
{
1244
    iwmmxt_store_reg(cpu_M0, rn);
1245
}
1246

    
1247
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1248
{
1249
    iwmmxt_load_reg(cpu_M0, rn);
1250
}
1251

    
1252
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1253
{
1254
    iwmmxt_load_reg(cpu_V1, rn);
1255
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1256
}
1257

    
1258
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1259
{
1260
    iwmmxt_load_reg(cpu_V1, rn);
1261
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1262
}
1263

    
1264
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1265
{
1266
    iwmmxt_load_reg(cpu_V1, rn);
1267
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1268
}
1269

    
1270
#define IWMMXT_OP(name) \
1271
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1272
{ \
1273
    iwmmxt_load_reg(cpu_V1, rn); \
1274
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1275
}
1276

    
1277
#define IWMMXT_OP_ENV(name) \
1278
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1279
{ \
1280
    iwmmxt_load_reg(cpu_V1, rn); \
1281
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1282
}
1283

    
1284
#define IWMMXT_OP_ENV_SIZE(name) \
1285
IWMMXT_OP_ENV(name##b) \
1286
IWMMXT_OP_ENV(name##w) \
1287
IWMMXT_OP_ENV(name##l)
1288

    
1289
#define IWMMXT_OP_ENV1(name) \
1290
static inline void gen_op_iwmmxt_##name##_M0(void) \
1291
{ \
1292
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1293
}
1294

    
1295
IWMMXT_OP(maddsq)
1296
IWMMXT_OP(madduq)
1297
IWMMXT_OP(sadb)
1298
IWMMXT_OP(sadw)
1299
IWMMXT_OP(mulslw)
1300
IWMMXT_OP(mulshw)
1301
IWMMXT_OP(mululw)
1302
IWMMXT_OP(muluhw)
1303
IWMMXT_OP(macsw)
1304
IWMMXT_OP(macuw)
1305

    
1306
IWMMXT_OP_ENV_SIZE(unpackl)
1307
IWMMXT_OP_ENV_SIZE(unpackh)
1308

    
1309
IWMMXT_OP_ENV1(unpacklub)
1310
IWMMXT_OP_ENV1(unpackluw)
1311
IWMMXT_OP_ENV1(unpacklul)
1312
IWMMXT_OP_ENV1(unpackhub)
1313
IWMMXT_OP_ENV1(unpackhuw)
1314
IWMMXT_OP_ENV1(unpackhul)
1315
IWMMXT_OP_ENV1(unpacklsb)
1316
IWMMXT_OP_ENV1(unpacklsw)
1317
IWMMXT_OP_ENV1(unpacklsl)
1318
IWMMXT_OP_ENV1(unpackhsb)
1319
IWMMXT_OP_ENV1(unpackhsw)
1320
IWMMXT_OP_ENV1(unpackhsl)
1321

    
1322
IWMMXT_OP_ENV_SIZE(cmpeq)
1323
IWMMXT_OP_ENV_SIZE(cmpgtu)
1324
IWMMXT_OP_ENV_SIZE(cmpgts)
1325

    
1326
IWMMXT_OP_ENV_SIZE(mins)
1327
IWMMXT_OP_ENV_SIZE(minu)
1328
IWMMXT_OP_ENV_SIZE(maxs)
1329
IWMMXT_OP_ENV_SIZE(maxu)
1330

    
1331
IWMMXT_OP_ENV_SIZE(subn)
1332
IWMMXT_OP_ENV_SIZE(addn)
1333
IWMMXT_OP_ENV_SIZE(subu)
1334
IWMMXT_OP_ENV_SIZE(addu)
1335
IWMMXT_OP_ENV_SIZE(subs)
1336
IWMMXT_OP_ENV_SIZE(adds)
1337

    
1338
IWMMXT_OP_ENV(avgb0)
1339
IWMMXT_OP_ENV(avgb1)
1340
IWMMXT_OP_ENV(avgw0)
1341
IWMMXT_OP_ENV(avgw1)
1342

    
1343
IWMMXT_OP(msadb)
1344

    
1345
IWMMXT_OP_ENV(packuw)
1346
IWMMXT_OP_ENV(packul)
1347
IWMMXT_OP_ENV(packuq)
1348
IWMMXT_OP_ENV(packsw)
1349
IWMMXT_OP_ENV(packsl)
1350
IWMMXT_OP_ENV(packsq)
1351

    
1352
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1353
{
1354
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1355
}
1356

    
1357
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1358
{
1359
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1360
}
1361

    
1362
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1363
{
1364
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1365
}
1366

    
1367
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1368
{
1369
    iwmmxt_load_reg(cpu_V1, rn);
1370
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1371
}
1372

    
1373
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1374
{
1375
    TCGv tmp = tcg_const_i32(shift);
1376
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1377
}
1378

    
1379
static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1380
{
1381
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1382
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1383
    tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1384
}
1385

    
1386
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1387
{
1388
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1389
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1390
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1391
}
1392

    
1393
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1394
{
1395
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1396
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1397
    if (mask != ~0u)
1398
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1399
}
1400

    
1401
static void gen_op_iwmmxt_set_mup(void)
1402
{
1403
    TCGv tmp;
1404
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1405
    tcg_gen_ori_i32(tmp, tmp, 2);
1406
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1407
}
1408

    
1409
static void gen_op_iwmmxt_set_cup(void)
1410
{
1411
    TCGv tmp;
1412
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1413
    tcg_gen_ori_i32(tmp, tmp, 1);
1414
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1415
}
1416

    
1417
static void gen_op_iwmmxt_setpsr_nz(void)
1418
{
1419
    TCGv tmp = new_tmp();
1420
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1421
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1422
}
1423

    
1424
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1425
{
1426
    iwmmxt_load_reg(cpu_V1, rn);
1427
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1428
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1429
}
1430

    
1431

    
1432
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1433
{
1434
    iwmmxt_load_reg(cpu_V0, rn);
1435
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1436
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1437
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1438
}
1439

    
1440
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1441
{
1442
    tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
1443
    iwmmxt_store_reg(cpu_V0, rn);
1444
}
1445

    
1446
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1447
{
1448
    int rd;
1449
    uint32_t offset;
1450

    
1451
    rd = (insn >> 16) & 0xf;
1452
    gen_movl_T1_reg(s, rd);
1453

    
1454
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1455
    if (insn & (1 << 24)) {
1456
        /* Pre indexed */
1457
        if (insn & (1 << 23))
1458
            gen_op_addl_T1_im(offset);
1459
        else
1460
            gen_op_addl_T1_im(-offset);
1461

    
1462
        if (insn & (1 << 21))
1463
            gen_movl_reg_T1(s, rd);
1464
    } else if (insn & (1 << 21)) {
1465
        /* Post indexed */
1466
        if (insn & (1 << 23))
1467
            gen_op_movl_T0_im(offset);
1468
        else
1469
            gen_op_movl_T0_im(- offset);
1470
        gen_op_addl_T0_T1();
1471
        gen_movl_reg_T0(s, rd);
1472
    } else if (!(insn & (1 << 23)))
1473
        return 1;
1474
    return 0;
1475
}
1476

    
1477
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1478
{
1479
    int rd = (insn >> 0) & 0xf;
1480

    
1481
    if (insn & (1 << 8))
1482
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1483
            return 1;
1484
        else
1485
            gen_op_iwmmxt_movl_T0_wCx(rd);
1486
    else
1487
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1488

    
1489
    gen_op_movl_T1_im(mask);
1490
    gen_op_andl_T0_T1();
1491
    return 0;
1492
}
1493

    
1494
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1495
   (ie. an undefined instruction).  */
1496
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1497
{
1498
    int rd, wrd;
1499
    int rdhi, rdlo, rd0, rd1, i;
1500
    TCGv tmp;
1501

    
1502
    if ((insn & 0x0e000e00) == 0x0c000000) {
1503
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1504
            wrd = insn & 0xf;
1505
            rdlo = (insn >> 12) & 0xf;
1506
            rdhi = (insn >> 16) & 0xf;
1507
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1508
                gen_iwmmxt_movl_T0_T1_wRn(wrd);
1509
                gen_movl_reg_T0(s, rdlo);
1510
                gen_movl_reg_T1(s, rdhi);
1511
            } else {                                        /* TMCRR */
1512
                gen_movl_T0_reg(s, rdlo);
1513
                gen_movl_T1_reg(s, rdhi);
1514
                gen_iwmmxt_movl_wRn_T0_T1(wrd);
1515
                gen_op_iwmmxt_set_mup();
1516
            }
1517
            return 0;
1518
        }
1519

    
1520
        wrd = (insn >> 12) & 0xf;
1521
        if (gen_iwmmxt_address(s, insn))
1522
            return 1;
1523
        if (insn & ARM_CP_RW_BIT) {
1524
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1525
                tmp = gen_ld32(cpu_T[1], IS_USER(s));
1526
                tcg_gen_mov_i32(cpu_T[0], tmp);
1527
                dead_tmp(tmp);
1528
                gen_op_iwmmxt_movl_wCx_T0(wrd);
1529
            } else {
1530
                i = 1;
1531
                if (insn & (1 << 8)) {
1532
                    if (insn & (1 << 22)) {                /* WLDRD */
1533
                        tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1534
                        i = 0;
1535
                    } else {                                /* WLDRW wRd */
1536
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
1537
                    }
1538
                } else {
1539
                    if (insn & (1 << 22)) {                /* WLDRH */
1540
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1541
                    } else {                                /* WLDRB */
1542
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1543
                    }
1544
                }
1545
                if (i) {
1546
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
1547
                    dead_tmp(tmp);
1548
                }
1549
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1550
            }
1551
        } else {
1552
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1553
                gen_op_iwmmxt_movl_T0_wCx(wrd);
1554
                tmp = new_tmp();
1555
                tcg_gen_mov_i32(tmp, cpu_T[0]);
1556
                gen_st32(tmp, cpu_T[1], IS_USER(s));
1557
            } else {
1558
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1559
                tmp = new_tmp();
1560
                if (insn & (1 << 8)) {
1561
                    if (insn & (1 << 22)) {                /* WSTRD */
1562
                        dead_tmp(tmp);
1563
                        tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1564
                    } else {                                /* WSTRW wRd */
1565
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1566
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
1567
                    }
1568
                } else {
1569
                    if (insn & (1 << 22)) {                /* WSTRH */
1570
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1571
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
1572
                    } else {                                /* WSTRB */
1573
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1574
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
1575
                    }
1576
                }
1577
            }
1578
        }
1579
        return 0;
1580
    }
1581

    
1582
    if ((insn & 0x0f000000) != 0x0e000000)
1583
        return 1;
1584

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

    
2457
    return 0;
2458
}
2459

    
2460
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2461
   (ie. an undefined instruction).  */
2462
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2463
{
2464
    int acc, rd0, rd1, rdhi, rdlo;
2465

    
2466
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2467
        /* Multiply with Internal Accumulate Format */
2468
        rd0 = (insn >> 12) & 0xf;
2469
        rd1 = insn & 0xf;
2470
        acc = (insn >> 5) & 7;
2471

    
2472
        if (acc != 0)
2473
            return 1;
2474

    
2475
        switch ((insn >> 16) & 0xf) {
2476
        case 0x0:                                        /* MIA */
2477
            gen_movl_T0_reg(s, rd0);
2478
            gen_movl_T1_reg(s, rd1);
2479
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2480
            break;
2481
        case 0x8:                                        /* MIAPH */
2482
            gen_movl_T0_reg(s, rd0);
2483
            gen_movl_T1_reg(s, rd1);
2484
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2485
            break;
2486
        case 0xc:                                        /* MIABB */
2487
        case 0xd:                                        /* MIABT */
2488
        case 0xe:                                        /* MIATB */
2489
        case 0xf:                                        /* MIATT */
2490
            gen_movl_T1_reg(s, rd0);
2491
            if (insn & (1 << 16))
2492
                gen_op_shrl_T1_im(16);
2493
            gen_op_movl_T0_T1();
2494
            gen_movl_T1_reg(s, rd1);
2495
            if (insn & (1 << 17))
2496
                gen_op_shrl_T1_im(16);
2497
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2498
            break;
2499
        default:
2500
            return 1;
2501
        }
2502

    
2503
        gen_op_iwmmxt_movq_wRn_M0(acc);
2504
        return 0;
2505
    }
2506

    
2507
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2508
        /* Internal Accumulator Access Format */
2509
        rdhi = (insn >> 16) & 0xf;
2510
        rdlo = (insn >> 12) & 0xf;
2511
        acc = insn & 7;
2512

    
2513
        if (acc != 0)
2514
            return 1;
2515

    
2516
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2517
            gen_iwmmxt_movl_T0_T1_wRn(acc);
2518
            gen_movl_reg_T0(s, rdlo);
2519
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2520
            gen_op_andl_T0_T1();
2521
            gen_movl_reg_T0(s, rdhi);
2522
        } else {                                        /* MAR */
2523
            gen_movl_T0_reg(s, rdlo);
2524
            gen_movl_T1_reg(s, rdhi);
2525
            gen_iwmmxt_movl_wRn_T0_T1(acc);
2526
        }
2527
        return 0;
2528
    }
2529

    
2530
    return 1;
2531
}
2532

    
2533
/* Disassemble system coprocessor instruction.  Return nonzero if
2534
   instruction is not defined.  */
2535
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2536
{
2537
    TCGv tmp;
2538
    uint32_t rd = (insn >> 12) & 0xf;
2539
    uint32_t cp = (insn >> 8) & 0xf;
2540
    if (IS_USER(s)) {
2541
        return 1;
2542
    }
2543

    
2544
    if (insn & ARM_CP_RW_BIT) {
2545
        if (!env->cp[cp].cp_read)
2546
            return 1;
2547
        gen_set_pc_im(s->pc);
2548
        tmp = new_tmp();
2549
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2550
        store_reg(s, rd, tmp);
2551
    } else {
2552
        if (!env->cp[cp].cp_write)
2553
            return 1;
2554
        gen_set_pc_im(s->pc);
2555
        tmp = load_reg(s, rd);
2556
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2557
        dead_tmp(tmp);
2558
    }
2559
    return 0;
2560
}
2561

    
2562
static int cp15_user_ok(uint32_t insn)
2563
{
2564
    int cpn = (insn >> 16) & 0xf;
2565
    int cpm = insn & 0xf;
2566
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2567

    
2568
    if (cpn == 13 && cpm == 0) {
2569
        /* TLS register.  */
2570
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2571
            return 1;
2572
    }
2573
    if (cpn == 7) {
2574
        /* ISB, DSB, DMB.  */
2575
        if ((cpm == 5 && op == 4)
2576
                || (cpm == 10 && (op == 4 || op == 5)))
2577
            return 1;
2578
    }
2579
    return 0;
2580
}
2581

    
2582
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2583
   instruction is not defined.  */
2584
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2585
{
2586
    uint32_t rd;
2587
    TCGv tmp;
2588

    
2589
    /* M profile cores use memory mapped registers instead of cp15.  */
2590
    if (arm_feature(env, ARM_FEATURE_M))
2591
        return 1;
2592

    
2593
    if ((insn & (1 << 25)) == 0) {
2594
        if (insn & (1 << 20)) {
2595
            /* mrrc */
2596
            return 1;
2597
        }
2598
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2599
        return 0;
2600
    }
2601
    if ((insn & (1 << 4)) == 0) {
2602
        /* cdp */
2603
        return 1;
2604
    }
2605
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2606
        return 1;
2607
    }
2608
    if ((insn & 0x0fff0fff) == 0x0e070f90
2609
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2610
        /* Wait for interrupt.  */
2611
        gen_set_pc_im(s->pc);
2612
        s->is_jmp = DISAS_WFI;
2613
        return 0;
2614
    }
2615
    rd = (insn >> 12) & 0xf;
2616
    if (insn & ARM_CP_RW_BIT) {
2617
        tmp = new_tmp();
2618
        gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2619
        /* If the destination register is r15 then sets condition codes.  */
2620
        if (rd != 15)
2621
            store_reg(s, rd, tmp);
2622
        else
2623
            dead_tmp(tmp);
2624
    } else {
2625
        tmp = load_reg(s, rd);
2626
        gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2627
        dead_tmp(tmp);
2628
        /* Normally we would always end the TB here, but Linux
2629
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2630
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2631
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2632
                (insn & 0x0fff0fff) != 0x0e010f10)
2633
            gen_lookup_tb(s);
2634
    }
2635
    return 0;
2636
}
2637

    
2638
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2639
#define VFP_SREG(insn, bigbit, smallbit) \
2640
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2641
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2642
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2643
        reg = (((insn) >> (bigbit)) & 0x0f) \
2644
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2645
    } else { \
2646
        if (insn & (1 << (smallbit))) \
2647
            return 1; \
2648
        reg = ((insn) >> (bigbit)) & 0x0f; \
2649
    }} while (0)
2650

    
2651
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2652
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2653
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2654
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2655
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2656
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2657

    
2658
/* Move between integer and VFP cores.  */
2659
static TCGv gen_vfp_mrs(void)
2660
{
2661
    TCGv tmp = new_tmp();
2662
    tcg_gen_mov_i32(tmp, cpu_F0s);
2663
    return tmp;
2664
}
2665

    
2666
static void gen_vfp_msr(TCGv tmp)
2667
{
2668
    tcg_gen_mov_i32(cpu_F0s, tmp);
2669
    dead_tmp(tmp);
2670
}
2671

    
2672
static inline int
2673
vfp_enabled(CPUState * env)
2674
{
2675
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2676
}
2677

    
2678
static void gen_neon_dup_u8(TCGv var, int shift)
2679
{
2680
    TCGv tmp = new_tmp();
2681
    if (shift)
2682
        tcg_gen_shri_i32(var, var, shift);
2683
    tcg_gen_ext8u_i32(var, var);
2684
    tcg_gen_shli_i32(tmp, var, 8);
2685
    tcg_gen_or_i32(var, var, tmp);
2686
    tcg_gen_shli_i32(tmp, var, 16);
2687
    tcg_gen_or_i32(var, var, tmp);
2688
    dead_tmp(tmp);
2689
}
2690

    
2691
static void gen_neon_dup_low16(TCGv var)
2692
{
2693
    TCGv tmp = new_tmp();
2694
    tcg_gen_ext16u_i32(var, var);
2695
    tcg_gen_shli_i32(tmp, var, 16);
2696
    tcg_gen_or_i32(var, var, tmp);
2697
    dead_tmp(tmp);
2698
}
2699

    
2700
static void gen_neon_dup_high16(TCGv var)
2701
{
2702
    TCGv tmp = new_tmp();
2703
    tcg_gen_andi_i32(var, var, 0xffff0000);
2704
    tcg_gen_shri_i32(tmp, var, 16);
2705
    tcg_gen_or_i32(var, var, tmp);
2706
    dead_tmp(tmp);
2707
}
2708

    
2709
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2710
   (ie. an undefined instruction).  */
2711
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2712
{
2713
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2714
    int dp, veclen;
2715
    TCGv tmp;
2716
    TCGv tmp2;
2717

    
2718
    if (!arm_feature(env, ARM_FEATURE_VFP))
2719
        return 1;
2720

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

    
2740
                VFP_DREG_N(rn, insn);
2741
                if (insn & 0xf)
2742
                    return 1;
2743
                if (insn & 0x00c00060
2744
                    && !arm_feature(env, ARM_FEATURE_NEON))
2745
                    return 1;
2746

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

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

    
2936
                if (op == 15 && (rn == 15 || rn > 17)) {
2937
                    /* Integer or single precision destination.  */
2938
                    rd = VFP_SREG_D(insn);
2939
                } else {
2940
                    VFP_DREG_D(rd, insn);
2941
                }
2942

    
2943
                if (op == 15 && (rn == 16 || rn == 17)) {
2944
                    /* Integer source.  */
2945
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2946
                } else {
2947
                    VFP_DREG_M(rm, insn);
2948
                }
2949
            } else {
2950
                rn = VFP_SREG_N(insn);
2951
                if (op == 15 && rn == 15) {
2952
                    /* Double precision destination.  */
2953
                    VFP_DREG_D(rd, insn);
2954
                } else {
2955
                    rd = VFP_SREG_D(insn);
2956
                }
2957
                rm = VFP_SREG_M(insn);
2958
            }
2959

    
2960
            veclen = env->vfp.vec_len;
2961
            if (op == 15 && rn > 3)
2962
                veclen = 0;
2963

    
2964
            /* Shut up compiler warnings.  */
2965
            delta_m = 0;
2966
            delta_d = 0;
2967
            bank_mask = 0;
2968

    
2969
            if (veclen > 0) {
2970
                if (dp)
2971
                    bank_mask = 0xc;
2972
                else
2973
                    bank_mask = 0x18;
2974

    
2975
                /* Figure out what type of vector operation this is.  */
2976
                if ((rd & bank_mask) == 0) {
2977
                    /* scalar */
2978
                    veclen = 0;
2979
                } else {
2980
                    if (dp)
2981
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2982
                    else
2983
                        delta_d = env->vfp.vec_stride + 1;
2984

    
2985
                    if ((rm & bank_mask) == 0) {
2986
                        /* mixed scalar/vector */
2987
                        delta_m = 0;
2988
                    } else {
2989
                        /* vector */
2990
                        delta_m = delta_d;
2991
                    }
2992
                }
2993
            }
2994

    
2995
            /* Load the initial operands.  */
2996
            if (op == 15) {
2997
                switch (rn) {
2998
                case 16:
2999
                case 17:
3000
                    /* Integer source */
3001
                    gen_mov_F0_vreg(0, rm);
3002
                    break;
3003
                case 8:
3004
                case 9:
3005
                    /* Compare */
3006
                    gen_mov_F0_vreg(dp, rd);
3007
                    gen_mov_F1_vreg(dp, rm);
3008
                    break;
3009
                case 10:
3010
                case 11:
3011
                    /* Compare with zero */
3012
                    gen_mov_F0_vreg(dp, rd);
3013
                    gen_vfp_F1_ld0(dp);
3014
                    break;
3015
                case 20:
3016
                case 21:
3017
                case 22:
3018
                case 23:
3019
                case 28:
3020
                case 29:
3021
                case 30:
3022
                case 31:
3023
                    /* Source and destination the same.  */
3024
                    gen_mov_F0_vreg(dp, rd);
3025
                    break;
3026
                default:
3027
                    /* One source operand.  */
3028
                    gen_mov_F0_vreg(dp, rm);
3029
                    break;
3030
                }
3031
            } else {
3032
                /* Two source operands.  */
3033
                gen_mov_F0_vreg(dp, rn);
3034
                gen_mov_F1_vreg(dp, rm);
3035
            }
3036

    
3037
            for (;;) {
3038
                /* Perform the calculation.  */
3039
                switch (op) {
3040
                case 0: /* mac: fd + (fn * fm) */
3041
                    gen_vfp_mul(dp);
3042
                    gen_mov_F1_vreg(dp, rd);
3043
                    gen_vfp_add(dp);
3044
                    break;
3045
                case 1: /* nmac: fd - (fn * fm) */
3046
                    gen_vfp_mul(dp);
3047
                    gen_vfp_neg(dp);
3048
                    gen_mov_F1_vreg(dp, rd);
3049
                    gen_vfp_add(dp);
3050
                    break;
3051
                case 2: /* msc: -fd + (fn * fm) */
3052
                    gen_vfp_mul(dp);
3053
                    gen_mov_F1_vreg(dp, rd);
3054
                    gen_vfp_sub(dp);
3055
                    break;
3056
                case 3: /* nmsc: -fd - (fn * fm)  */
3057
                    gen_vfp_mul(dp);
3058
                    gen_vfp_neg(dp);
3059
                    gen_mov_F1_vreg(dp, rd);
3060
                    gen_vfp_sub(dp);
3061
                    break;
3062
                case 4: /* mul: fn * fm */
3063
                    gen_vfp_mul(dp);
3064
                    break;
3065
                case 5: /* nmul: -(fn * fm) */
3066
                    gen_vfp_mul(dp);
3067
                    gen_vfp_neg(dp);
3068
                    break;
3069
                case 6: /* add: fn + fm */
3070
                    gen_vfp_add(dp);
3071
                    break;
3072
                case 7: /* sub: fn - fm */
3073
                    gen_vfp_sub(dp);
3074
                    break;
3075
                case 8: /* div: fn / fm */
3076
                    gen_vfp_div(dp);
3077
                    break;
3078
                case 14: /* fconst */
3079
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3080
                      return 1;
3081

    
3082
                    n = (insn << 12) & 0x80000000;
3083
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3084
                    if (dp) {
3085
                        if (i & 0x40)
3086
                            i |= 0x3f80;
3087
                        else
3088
                            i |= 0x4000;
3089
                        n |= i << 16;
3090
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3091
                    } else {
3092
                        if (i & 0x40)
3093
                            i |= 0x780;
3094
                        else
3095
                            i |= 0x800;
3096
                        n |= i << 19;
3097
                        tcg_gen_movi_i32(cpu_F0s, n);
3098
                    }
3099
                    break;
3100
                case 15: /* extension space */
3101
                    switch (rn) {
3102
                    case 0: /* cpy */
3103
                        /* no-op */
3104
                        break;
3105
                    case 1: /* abs */
3106
                        gen_vfp_abs(dp);
3107
                        break;
3108
                    case 2: /* neg */
3109
                        gen_vfp_neg(dp);
3110
                        break;
3111
                    case 3: /* sqrt */
3112
                        gen_vfp_sqrt(dp);
3113
                        break;
3114
                    case 8: /* cmp */
3115
                        gen_vfp_cmp(dp);
3116
                        break;
3117
                    case 9: /* cmpe */
3118
                        gen_vfp_cmpe(dp);
3119
                        break;
3120
                    case 10: /* cmpz */
3121
                        gen_vfp_cmp(dp);
3122
                        break;
3123
                    case 11: /* cmpez */
3124
                        gen_vfp_F1_ld0(dp);
3125
                        gen_vfp_cmpe(dp);
3126
                        break;
3127
                    case 15: /* single<->double conversion */
3128
                        if (dp)
3129
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3130
                        else
3131
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3132
                        break;
3133
                    case 16: /* fuito */
3134
                        gen_vfp_uito(dp);
3135
                        break;
3136
                    case 17: /* fsito */
3137
                        gen_vfp_sito(dp);
3138
                        break;
3139
                    case 20: /* fshto */
3140
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3141
                          return 1;
3142
                        gen_vfp_shto(dp, 16 - rm);
3143
                        break;
3144
                    case 21: /* fslto */
3145
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3146
                          return 1;
3147
                        gen_vfp_slto(dp, 32 - rm);
3148
                        break;
3149
                    case 22: /* fuhto */
3150
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3151
                          return 1;
3152
                        gen_vfp_uhto(dp, 16 - rm);
3153
                        break;
3154
                    case 23: /* fulto */
3155
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3156
                          return 1;
3157
                        gen_vfp_ulto(dp, 32 - rm);
3158
                        break;
3159
                    case 24: /* ftoui */
3160
                        gen_vfp_toui(dp);
3161
                        break;
3162
                    case 25: /* ftouiz */
3163
                        gen_vfp_touiz(dp);
3164
                        break;
3165
                    case 26: /* ftosi */
3166
                        gen_vfp_tosi(dp);
3167
                        break;
3168
                    case 27: /* ftosiz */
3169
                        gen_vfp_tosiz(dp);
3170
                        break;
3171
                    case 28: /* ftosh */
3172
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3173
                          return 1;
3174
                        gen_vfp_tosh(dp, 16 - rm);
3175
                        break;
3176
                    case 29: /* ftosl */
3177
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3178
                          return 1;
3179
                        gen_vfp_tosl(dp, 32 - rm);
3180
                        break;
3181
                    case 30: /* ftouh */
3182
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3183
                          return 1;
3184
                        gen_vfp_touh(dp, 16 - rm);
3185
                        break;
3186
                    case 31: /* ftoul */
3187
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3188
                          return 1;
3189
                        gen_vfp_toul(dp, 32 - rm);
3190
                        break;
3191
                    default: /* undefined */
3192
                        printf ("rn:%d\n", rn);
3193
                        return 1;
3194
                    }
3195
                    break;
3196
                default: /* undefined */
3197
                    printf ("op:%d\n", op);
3198
                    return 1;
3199
                }
3200

    
3201
                /* Write back the result.  */
3202
                if (op == 15 && (rn >= 8 && rn <= 11))
3203
                    ; /* Comparison, do nothing.  */
3204
                else if (op == 15 && rn > 17)
3205
                    /* Integer result.  */
3206
                    gen_mov_vreg_F0(0, rd);
3207
                else if (op == 15 && rn == 15)
3208
                    /* conversion */
3209
                    gen_mov_vreg_F0(!dp, rd);
3210
                else
3211
                    gen_mov_vreg_F0(dp, rd);
3212

    
3213
                /* break out of the loop if we have finished  */
3214
                if (veclen == 0)
3215
                    break;
3216

    
3217
                if (op == 15 && delta_m == 0) {
3218
                    /* single source one-many */
3219
                    while (veclen--) {
3220
                        rd = ((rd + delta_d) & (bank_mask - 1))
3221
                             | (rd & bank_mask);
3222
                        gen_mov_vreg_F0(dp, rd);
3223
                    }
3224
                    break;
3225
                }
3226
                /* Setup the next operands.  */
3227
                veclen--;
3228
                rd = ((rd + delta_d) & (bank_mask - 1))
3229
                     | (rd & bank_mask);
3230

    
3231
                if (op == 15) {
3232
                    /* One source operand.  */
3233
                    rm = ((rm + delta_m) & (bank_mask - 1))
3234
                         | (rm & bank_mask);
3235
                    gen_mov_F0_vreg(dp, rm);
3236
                } else {
3237
                    /* Two source operands.  */
3238
                    rn = ((rn + delta_d) & (bank_mask - 1))
3239
                         | (rn & bank_mask);
3240
                    gen_mov_F0_vreg(dp, rn);
3241
                    if (delta_m) {
3242
                        rm = ((rm + delta_m) & (bank_mask - 1))
3243
                             | (rm & bank_mask);
3244
                        gen_mov_F1_vreg(dp, rm);
3245
                    }
3246
                }
3247
            }
3248
        }
3249
        break;
3250
    case 0xc:
3251
    case 0xd:
3252
        if (dp && (insn & 0x03e00000) == 0x00400000) {
3253
            /* two-register transfer */
3254
            rn = (insn >> 16) & 0xf;
3255
            rd = (insn >> 12) & 0xf;
3256
            if (dp) {
3257
                VFP_DREG_M(rm, insn);
3258
            } else {
3259
                rm = VFP_SREG_M(insn);
3260
            }
3261

    
3262
            if (insn & ARM_CP_RW_BIT) {
3263
                /* vfp->arm */
3264
                if (dp) {
3265
                    gen_mov_F0_vreg(0, rm * 2);
3266
                    tmp = gen_vfp_mrs();
3267
                    store_reg(s, rd, tmp);
3268
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3269
                    tmp = gen_vfp_mrs();
3270
                    store_reg(s, rn, tmp);
3271
                } else {
3272
                    gen_mov_F0_vreg(0, rm);
3273
                    tmp = gen_vfp_mrs();
3274
                    store_reg(s, rn, tmp);
3275
                    gen_mov_F0_vreg(0, rm + 1);
3276
                    tmp = gen_vfp_mrs();
3277
                    store_reg(s, rd, tmp);
3278
                }
3279
            } else {
3280
                /* arm->vfp */
3281
                if (dp) {
3282
                    tmp = load_reg(s, rd);
3283
                    gen_vfp_msr(tmp);
3284
                    gen_mov_vreg_F0(0, rm * 2);
3285
                    tmp = load_reg(s, rn);
3286
                    gen_vfp_msr(tmp);
3287
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3288
                } else {
3289
                    tmp = load_reg(s, rn);
3290
                    gen_vfp_msr(tmp);
3291
                    gen_mov_vreg_F0(0, rm);
3292
                    tmp = load_reg(s, rd);
3293
                    gen_vfp_msr(tmp);
3294
                    gen_mov_vreg_F0(0, rm + 1);
3295
                }
3296
            }
3297
        } else {
3298
            /* Load/store */
3299
            rn = (insn >> 16) & 0xf;
3300
            if (dp)
3301
                VFP_DREG_D(rd, insn);
3302
            else
3303
                rd = VFP_SREG_D(insn);
3304
            if (s->thumb && rn == 15) {
3305
                gen_op_movl_T1_im(s->pc & ~2);
3306
            } else {
3307
                gen_movl_T1_reg(s, rn);
3308
            }
3309
            if ((insn & 0x01200000) == 0x01000000) {
3310
                /* Single load/store */
3311
                offset = (insn & 0xff) << 2;
3312
                if ((insn & (1 << 23)) == 0)
3313
                    offset = -offset;
3314
                gen_op_addl_T1_im(offset);
3315
                if (insn & (1 << 20)) {
3316
                    gen_vfp_ld(s, dp);
3317
                    gen_mov_vreg_F0(dp, rd);
3318
                } else {
3319
                    gen_mov_F0_vreg(dp, rd);
3320
                    gen_vfp_st(s, dp);
3321
                }
3322
            } else {
3323
                /* load/store multiple */
3324
                if (dp)
3325
                    n = (insn >> 1) & 0x7f;
3326
                else
3327
                    n = insn & 0xff;
3328

    
3329
                if (insn & (1 << 24)) /* pre-decrement */
3330
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3331

    
3332
                if (dp)
3333
                    offset = 8;
3334
                else
3335
                    offset = 4;
3336
                for (i = 0; i < n; i++) {
3337
                    if (insn & ARM_CP_RW_BIT) {
3338
                        /* load */
3339
                        gen_vfp_ld(s, dp);
3340
                        gen_mov_vreg_F0(dp, rd + i);
3341
                    } else {
3342
                        /* store */
3343
                        gen_mov_F0_vreg(dp, rd + i);
3344
                        gen_vfp_st(s, dp);
3345
                    }
3346
                    gen_op_addl_T1_im(offset);
3347
                }
3348
                if (insn & (1 << 21)) {
3349
                    /* writeback */
3350
                    if (insn & (1 << 24))
3351
                        offset = -offset * n;
3352
                    else if (dp && (insn & 1))
3353
                        offset = 4;
3354
                    else
3355
                        offset = 0;
3356

    
3357
                    if (offset != 0)
3358
                        gen_op_addl_T1_im(offset);
3359
                    gen_movl_reg_T1(s, rn);
3360
                }
3361
            }
3362
        }
3363
        break;
3364
    default:
3365
        /* Should never happen.  */
3366
        return 1;
3367
    }
3368
    return 0;
3369
}
3370

    
3371
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3372
{
3373
    TranslationBlock *tb;
3374

    
3375
    tb = s->tb;
3376
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3377
        tcg_gen_goto_tb(n);
3378
        gen_set_pc_im(dest);
3379
        tcg_gen_exit_tb((long)tb + n);
3380
    } else {
3381
        gen_set_pc_im(dest);
3382
        tcg_gen_exit_tb(0);
3383
    }
3384
}
3385

    
3386
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3387
{
3388
    if (unlikely(s->singlestep_enabled)) {
3389
        /* An indirect jump so that we still trigger the debug exception.  */
3390
        if (s->thumb)
3391
            dest |= 1;
3392
        gen_bx_im(s, dest);
3393
    } else {
3394
        gen_goto_tb(s, 0, dest);
3395
        s->is_jmp = DISAS_TB_JUMP;
3396
    }
3397
}
3398

    
3399
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3400
{
3401
    if (x)
3402
        tcg_gen_sari_i32(t0, t0, 16);
3403
    else
3404
        gen_sxth(t0);
3405
    if (y)
3406
        tcg_gen_sari_i32(t1, t1, 16);
3407
    else
3408
        gen_sxth(t1);
3409
    tcg_gen_mul_i32(t0, t0, t1);
3410
}
3411

    
3412
/* Return the mask of PSR bits set by a MSR instruction.  */
3413
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3414
    uint32_t mask;
3415

    
3416
    mask = 0;
3417
    if (flags & (1 << 0))
3418
        mask |= 0xff;
3419
    if (flags & (1 << 1))
3420
        mask |= 0xff00;
3421
    if (flags & (1 << 2))
3422
        mask |= 0xff0000;
3423
    if (flags & (1 << 3))
3424
        mask |= 0xff000000;
3425

    
3426
    /* Mask out undefined bits.  */
3427
    mask &= ~CPSR_RESERVED;
3428
    if (!arm_feature(env, ARM_FEATURE_V6))
3429
        mask &= ~(CPSR_E | CPSR_GE);
3430
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3431
        mask &= ~CPSR_IT;
3432
    /* Mask out execution state bits.  */
3433
    if (!spsr)
3434
        mask &= ~CPSR_EXEC;
3435
    /* Mask out privileged bits.  */
3436
    if (IS_USER(s))
3437
        mask &= CPSR_USER;
3438
    return mask;
3439
}
3440

    
3441
/* Returns nonzero if access to the PSR is not permitted.  */
3442
static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3443
{
3444
    TCGv tmp;
3445
    if (spsr) {
3446
        /* ??? This is also undefined in system mode.  */
3447
        if (IS_USER(s))
3448
            return 1;
3449

    
3450
        tmp = load_cpu_field(spsr);
3451
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3452
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3453
        tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3454
        store_cpu_field(tmp, spsr);
3455
    } else {
3456
        gen_set_cpsr(cpu_T[0], mask);
3457
    }
3458
    gen_lookup_tb(s);
3459
    return 0;
3460
}
3461

    
3462
/* Generate an old-style exception return. Marks pc as dead. */
3463
static void gen_exception_return(DisasContext *s, TCGv pc)
3464
{
3465
    TCGv tmp;
3466
    store_reg(s, 15, pc);
3467
    tmp = load_cpu_field(spsr);
3468
    gen_set_cpsr(tmp, 0xffffffff);
3469
    dead_tmp(tmp);
3470
    s->is_jmp = DISAS_UPDATE;
3471
}
3472

    
3473
/* Generate a v6 exception return.  Marks both values as dead.  */
3474
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3475
{
3476
    gen_set_cpsr(cpsr, 0xffffffff);
3477
    dead_tmp(cpsr);
3478
    store_reg(s, 15, pc);
3479
    s->is_jmp = DISAS_UPDATE;
3480
}
3481

    
3482
static inline void
3483
gen_set_condexec (DisasContext *s)
3484
{
3485
    if (s->condexec_mask) {
3486
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3487
        TCGv tmp = new_tmp();
3488
        tcg_gen_movi_i32(tmp, val);
3489
        store_cpu_field(tmp, condexec_bits);
3490
    }
3491
}
3492

    
3493
static void gen_nop_hint(DisasContext *s, int val)
3494
{
3495
    switch (val) {
3496
    case 3: /* wfi */
3497
        gen_set_pc_im(s->pc);
3498
        s->is_jmp = DISAS_WFI;
3499
        break;
3500
    case 2: /* wfe */
3501
    case 4: /* sev */
3502
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3503
    default: /* nop */
3504
        break;
3505
    }
3506
}
3507

    
3508
/* These macros help make the code more readable when migrating from the
3509
   old dyngen helpers.  They should probably be removed when
3510
   T0/T1 are removed.  */
3511
#define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3512
#define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3513

    
3514
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3515

    
3516
static inline int gen_neon_add(int size)
3517
{
3518
    switch (size) {
3519
    case 0: gen_helper_neon_add_u8(CPU_T001); break;
3520
    case 1: gen_helper_neon_add_u16(CPU_T001); break;
3521
    case 2: gen_op_addl_T0_T1(); break;
3522
    default: return 1;
3523
    }
3524
    return 0;
3525
}
3526

    
3527
static inline void gen_neon_rsb(int size)
3528
{
3529
    switch (size) {
3530
    case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3531
    case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3532
    case 2: gen_op_rsbl_T0_T1(); break;
3533
    default: return;
3534
    }
3535
}
3536

    
3537
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3538
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3539
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3540
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3541
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3542

    
3543
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3544
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3545
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3546
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3547
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3548

    
3549
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3550
    switch ((size << 1) | u) { \
3551
    case 0: \
3552
        gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3553
        break; \
3554
    case 1: \
3555
        gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3556
        break; \
3557
    case 2: \
3558
        gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3559
        break; \
3560
    case 3: \
3561
        gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3562
        break; \
3563
    case 4: \
3564
        gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3565
        break; \
3566
    case 5: \
3567
        gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3568
        break; \
3569
    default: return 1; \
3570
    }} while (0)
3571

    
3572
#define GEN_NEON_INTEGER_OP(name) do { \
3573
    switch ((size << 1) | u) { \
3574
    case 0: \
3575
        gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3576
        break; \
3577
    case 1: \
3578
        gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3579
        break; \
3580
    case 2: \
3581
        gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3582
        break; \
3583
    case 3: \
3584
        gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3585
        break; \
3586
    case 4: \
3587
        gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3588
        break; \
3589
    case 5: \
3590
        gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3591
        break; \
3592
    default: return 1; \
3593
    }} while (0)
3594

    
3595
static inline void
3596
gen_neon_movl_scratch_T0(int scratch)
3597
{
3598
  uint32_t offset;
3599

    
3600
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3601
  tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3602
}
3603

    
3604
static inline void
3605
gen_neon_movl_scratch_T1(int scratch)
3606
{
3607
  uint32_t offset;
3608

    
3609
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3610
  tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3611
}
3612

    
3613
static inline void
3614
gen_neon_movl_T0_scratch(int scratch)
3615
{
3616
  uint32_t offset;
3617

    
3618
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3619
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3620
}
3621

    
3622
static inline void
3623
gen_neon_movl_T1_scratch(int scratch)
3624
{
3625
  uint32_t offset;
3626

    
3627
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3628
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3629
}
3630

    
3631
static inline void gen_neon_get_scalar(int size, int reg)
3632
{
3633
    if (size == 1) {
3634
        NEON_GET_REG(T0, reg >> 1, reg & 1);
3635
    } else {
3636
        NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3637
        if (reg & 1)
3638
            gen_neon_dup_low16(cpu_T[0]);
3639
        else
3640
            gen_neon_dup_high16(cpu_T[0]);
3641
    }
3642
}
3643

    
3644
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3645
{
3646
    int n;
3647

    
3648
    for (n = 0; n < q + 1; n += 2) {
3649
        NEON_GET_REG(T0, reg, n);
3650
        NEON_GET_REG(T0, reg, n + n);
3651
        switch (size) {
3652
        case 0: gen_helper_neon_unzip_u8(); break;
3653
        case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same.  */
3654
        case 2: /* no-op */; break;
3655
        default: abort();
3656
        }
3657
        gen_neon_movl_scratch_T0(tmp + n);
3658
        gen_neon_movl_scratch_T1(tmp + n + 1);
3659
    }
3660
}
3661

    
3662
static struct {
3663
    int nregs;
3664
    int interleave;
3665
    int spacing;
3666
} neon_ls_element_type[11] = {
3667
    {4, 4, 1},
3668
    {4, 4, 2},
3669
    {4, 1, 1},
3670
    {4, 2, 1},
3671
    {3, 3, 1},
3672
    {3, 3, 2},
3673
    {3, 1, 1},
3674
    {1, 1, 1},
3675
    {2, 2, 1},
3676
    {2, 2, 2},
3677
    {2, 1, 1}
3678
};
3679

    
3680
/* Translate a NEON load/store element instruction.  Return nonzero if the
3681
   instruction is invalid.  */
3682
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3683
{
3684
    int rd, rn, rm;
3685
    int op;
3686
    int nregs;
3687
    int interleave;
3688
    int stride;
3689
    int size;
3690
    int reg;
3691
    int pass;
3692
    int load;
3693
    int shift;
3694
    int n;
3695
    TCGv tmp;
3696
    TCGv tmp2;
3697

    
3698
    if (!vfp_enabled(env))
3699
      return 1;
3700
    VFP_DREG_D(rd, insn);
3701
    rn = (insn >> 16) & 0xf;
3702
    rm = insn & 0xf;
3703
    load = (insn & (1 << 21)) != 0;
3704
    if ((insn & (1 << 23)) == 0) {
3705
        /* Load store all elements.  */
3706
        op = (insn >> 8) & 0xf;
3707
        size = (insn >> 6) & 3;
3708
        if (op > 10 || size == 3)
3709
            return 1;
3710
        nregs = neon_ls_element_type[op].nregs;
3711
        interleave = neon_ls_element_type[op].interleave;
3712
        gen_movl_T1_reg(s, rn);
3713
        stride = (1 << size) * interleave;
3714
        for (reg = 0; reg < nregs; reg++) {
3715
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3716
                gen_movl_T1_reg(s, rn);
3717
                gen_op_addl_T1_im((1 << size) * reg);
3718
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3719
                gen_movl_T1_reg(s, rn);
3720
                gen_op_addl_T1_im(1 << size);
3721
            }
3722
            for (pass = 0; pass < 2; pass++) {
3723
                if (size == 2) {
3724
                    if (load) {
3725
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3726
                        neon_store_reg(rd, pass, tmp);
3727
                    } else {
3728
                        tmp = neon_load_reg(rd, pass);
3729
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3730
                    }
3731
                    gen_op_addl_T1_im(stride);
3732
                } else if (size == 1) {
3733
                    if (load) {
3734
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3735
                        gen_op_addl_T1_im(stride);
3736
                        tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
3737
                        gen_op_addl_T1_im(stride);
3738
                        gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3739
                        dead_tmp(tmp2);
3740
                        neon_store_reg(rd, pass, tmp);
3741
                    } else {
3742
                        tmp = neon_load_reg(rd, pass);
3743
                        tmp2 = new_tmp();
3744
                        tcg_gen_shri_i32(tmp2, tmp, 16);
3745
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3746
                        gen_op_addl_T1_im(stride);
3747
                        gen_st16(tmp2, cpu_T[1], IS_USER(s));
3748
                        gen_op_addl_T1_im(stride);
3749
                    }
3750
                } else /* size == 0 */ {
3751
                    if (load) {
3752
                        TCGV_UNUSED(tmp2);
3753
                        for (n = 0; n < 4; n++) {
3754
                            tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3755
                            gen_op_addl_T1_im(stride);
3756
                            if (n == 0) {
3757
                                tmp2 = tmp;
3758
                            } else {
3759
                                gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3760
                                dead_tmp(tmp);
3761
                            }
3762
                        }
3763
                        neon_store_reg(rd, pass, tmp2);
3764
                    } else {
3765
                        tmp2 = neon_load_reg(rd, pass);
3766
                        for (n = 0; n < 4; n++) {
3767
                            tmp = new_tmp();
3768
                            if (n == 0) {
3769
                                tcg_gen_mov_i32(tmp, tmp2);
3770
                            } else {
3771
                                tcg_gen_shri_i32(tmp, tmp2, n * 8);
3772
                            }
3773
                            gen_st8(tmp, cpu_T[1], IS_USER(s));
3774
                            gen_op_addl_T1_im(stride);
3775
                        }
3776
                        dead_tmp(tmp2);
3777
                    }
3778
                }
3779
            }
3780
            rd += neon_ls_element_type[op].spacing;
3781
        }
3782
        stride = nregs * 8;
3783
    } else {
3784
        size = (insn >> 10) & 3;
3785
        if (size == 3) {
3786
            /* Load single element to all lanes.  */
3787
            if (!load)
3788
                return 1;
3789
            size = (insn >> 6) & 3;
3790
            nregs = ((insn >> 8) & 3) + 1;
3791
            stride = (insn & (1 << 5)) ? 2 : 1;
3792
            gen_movl_T1_reg(s, rn);
3793
            for (reg = 0; reg < nregs; reg++) {
3794
                switch (size) {
3795
                case 0:
3796
                    tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3797
                    gen_neon_dup_u8(tmp, 0);
3798
                    break;
3799
                case 1:
3800
                    tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3801
                    gen_neon_dup_low16(tmp);
3802
                    break;
3803
                case 2:
3804
                    tmp = gen_ld32(cpu_T[0], IS_USER(s));
3805
                    break;
3806
                case 3:
3807
                    return 1;
3808
                default: /* Avoid compiler warnings.  */
3809
                    abort();
3810
                }
3811
                gen_op_addl_T1_im(1 << size);
3812
                tmp2 = new_tmp();
3813
                tcg_gen_mov_i32(tmp2, tmp);
3814
                neon_store_reg(rd, 0, tmp2);
3815
                neon_store_reg(rd, 1, tmp);
3816
                rd += stride;
3817
            }
3818
            stride = (1 << size) * nregs;
3819
        } else {
3820
            /* Single element.  */
3821
            pass = (insn >> 7) & 1;
3822
            switch (size) {
3823
            case 0:
3824
                shift = ((insn >> 5) & 3) * 8;
3825
                stride = 1;
3826
                break;
3827
            case 1:
3828
                shift = ((insn >> 6) & 1) * 16;
3829
                stride = (insn & (1 << 5)) ? 2 : 1;
3830
                break;
3831
            case 2:
3832
                shift = 0;
3833
                stride = (insn & (1 << 6)) ? 2 : 1;
3834
                break;
3835
            default:
3836
                abort();
3837
            }
3838
            nregs = ((insn >> 8) & 3) + 1;
3839
            gen_movl_T1_reg(s, rn);
3840
            for (reg = 0; reg < nregs; reg++) {
3841
                if (load) {
3842
                    switch (size) {
3843
                    case 0:
3844
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3845
                        break;
3846
                    case 1:
3847
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3848
                        break;
3849
                    case 2:
3850
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3851
                        break;
3852
                    default: /* Avoid compiler warnings.  */
3853
                        abort();
3854
                    }
3855
                    if (size != 2) {
3856
                        tmp2 = neon_load_reg(rd, pass);
3857
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3858
                        dead_tmp(tmp2);
3859
                    }
3860
                    neon_store_reg(rd, pass, tmp);
3861
                } else { /* Store */
3862
                    tmp = neon_load_reg(rd, pass);
3863
                    if (shift)
3864
                        tcg_gen_shri_i32(tmp, tmp, shift);
3865
                    switch (size) {
3866
                    case 0:
3867
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
3868
                        break;
3869
                    case 1:
3870
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3871
                        break;
3872
                    case 2:
3873
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3874
                        break;
3875
                    }
3876
                }
3877
                rd += stride;
3878
                gen_op_addl_T1_im(1 << size);
3879
            }
3880
            stride = nregs * (1 << size);
3881
        }
3882
    }
3883
    if (rm != 15) {
3884
        TCGv base;
3885

    
3886
        base = load_reg(s, rn);
3887
        if (rm == 13) {
3888
            tcg_gen_addi_i32(base, base, stride);
3889
        } else {
3890
            TCGv index;
3891
            index = load_reg(s, rm);
3892
            tcg_gen_add_i32(base, base, index);
3893
            dead_tmp(index);
3894
        }
3895
        store_reg(s, rn, base);
3896
    }
3897
    return 0;
3898
}
3899

    
3900
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3901
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3902
{
3903
    tcg_gen_and_i32(t, t, c);
3904
    tcg_gen_bic_i32(f, f, c);
3905
    tcg_gen_or_i32(dest, t, f);
3906
}
3907

    
3908
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
3909
{
3910
    switch (size) {
3911
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
3912
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
3913
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3914
    default: abort();
3915
    }
3916
}
3917

    
3918
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
3919
{
3920
    switch (size) {
3921
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3922
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3923
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3924
    default: abort();
3925
    }
3926
}
3927

    
3928
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
3929
{
3930
    switch (size) {
3931
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3932
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3933
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3934
    default: abort();
3935
    }
3936
}
3937

    
3938
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3939
                                         int q, int u)
3940
{
3941
    if (q) {
3942
        if (u) {
3943
            switch (size) {
3944
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3945
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3946
            default: abort();
3947
            }
3948
        } else {
3949
            switch (size) {
3950
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3951
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3952
            default: abort();
3953
            }
3954
        }
3955
    } else {
3956
        if (u) {
3957
            switch (size) {
3958
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3959
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3960
            default: abort();
3961
            }
3962
        } else {
3963
            switch (size) {
3964
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3965
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3966
            default: abort();
3967
            }
3968
        }
3969
    }
3970
}
3971

    
3972
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
3973
{
3974
    if (u) {
3975
        switch (size) {
3976
        case 0: gen_helper_neon_widen_u8(dest, src); break;
3977
        case 1: gen_helper_neon_widen_u16(dest, src); break;
3978
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
3979
        default: abort();
3980
        }
3981
    } else {
3982
        switch (size) {
3983
        case 0: gen_helper_neon_widen_s8(dest, src); break;
3984
        case 1: gen_helper_neon_widen_s16(dest, src); break;
3985
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
3986
        default: abort();
3987
        }
3988
    }
3989
    dead_tmp(src);
3990
}
3991

    
3992
static inline void gen_neon_addl(int size)
3993
{
3994
    switch (size) {
3995
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3996
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3997
    case 2: tcg_gen_add_i64(CPU_V001); break;
3998
    default: abort();
3999
    }
4000
}
4001

    
4002
static inline void gen_neon_subl(int size)
4003
{
4004
    switch (size) {
4005
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4006
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4007
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4008
    default: abort();
4009
    }
4010
}
4011

    
4012
static inline void gen_neon_negl(TCGv_i64 var, int size)
4013
{
4014
    switch (size) {
4015
    case 0: gen_helper_neon_negl_u16(var, var); break;
4016
    case 1: gen_helper_neon_negl_u32(var, var); break;
4017
    case 2: gen_helper_neon_negl_u64(var, var); break;
4018
    default: abort();
4019
    }
4020
}
4021

    
4022
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4023
{
4024
    switch (size) {
4025
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4026
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4027
    default: abort();
4028
    }
4029
}
4030

    
4031
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4032
{
4033
    TCGv_i64 tmp;
4034

    
4035
    switch ((size << 1) | u) {
4036
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4037
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4038
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4039
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4040
    case 4:
4041
        tmp = gen_muls_i64_i32(a, b);
4042
        tcg_gen_mov_i64(dest, tmp);
4043
        break;
4044
    case 5:
4045
        tmp = gen_mulu_i64_i32(a, b);
4046
        tcg_gen_mov_i64(dest, tmp);
4047
        break;
4048
    default: abort();
4049
    }
4050
    if (size < 2) {
4051
        dead_tmp(b);
4052
        dead_tmp(a);
4053
    }
4054
}
4055

    
4056
/* Translate a NEON data processing instruction.  Return nonzero if the
4057
   instruction is invalid.
4058
   We process data in a mixture of 32-bit and 64-bit chunks.
4059
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4060

    
4061
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4062
{
4063
    int op;
4064
    int q;
4065
    int rd, rn, rm;
4066
    int size;
4067
    int shift;
4068
    int pass;
4069
    int count;
4070
    int pairwise;
4071
    int u;
4072
    int n;
4073
    uint32_t imm;
4074
    TCGv tmp;
4075
    TCGv tmp2;
4076
    TCGv tmp3;
4077
    TCGv_i64 tmp64;
4078

    
4079
    if (!vfp_enabled(env))
4080
      return 1;
4081
    q = (insn & (1 << 6)) != 0;
4082
    u = (insn >> 24) & 1;
4083
    VFP_DREG_D(rd, insn);
4084
    VFP_DREG_N(rn, insn);
4085
    VFP_DREG_M(rm, insn);
4086
    size = (insn >> 20) & 3;
4087
    if ((insn & (1 << 23)) == 0) {
4088
        /* Three register same length.  */
4089
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4090
        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4091
                          || op == 10 || op  == 11 || op == 16)) {
4092
            /* 64-bit element instructions.  */
4093
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4094
                neon_load_reg64(cpu_V0, rn + pass);
4095
                neon_load_reg64(cpu_V1, rm + pass);
4096
                switch (op) {
4097
                case 1: /* VQADD */
4098
                    if (u) {
4099
                        gen_helper_neon_add_saturate_u64(CPU_V001);
4100
                    } else {
4101
                        gen_helper_neon_add_saturate_s64(CPU_V001);
4102
                    }
4103
                    break;
4104
                case 5: /* VQSUB */
4105
                    if (u) {
4106
                        gen_helper_neon_sub_saturate_u64(CPU_V001);
4107
                    } else {
4108
                        gen_helper_neon_sub_saturate_s64(CPU_V001);
4109
                    }
4110
                    break;
4111
                case 8: /* VSHL */
4112
                    if (u) {
4113
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4114
                    } else {
4115
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4116
                    }
4117
                    break;
4118
                case 9: /* VQSHL */
4119
                    if (u) {
4120
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4121
                                                 cpu_V0, cpu_V0);
4122
                    } else {
4123
                        gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4124
                                                 cpu_V1, cpu_V0);
4125
                    }
4126
                    break;
4127
                case 10: /* VRSHL */
4128
                    if (u) {
4129
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4130
                    } else {
4131
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4132
                    }
4133
                    break;
4134
                case 11: /* VQRSHL */
4135
                    if (u) {
4136
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4137
                                                  cpu_V1, cpu_V0);
4138
                    } else {
4139
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4140
                                                  cpu_V1, cpu_V0);
4141
                    }
4142
                    break;
4143
                case 16:
4144
                    if (u) {
4145
                        tcg_gen_sub_i64(CPU_V001);
4146
                    } else {
4147
                        tcg_gen_add_i64(CPU_V001);
4148
                    }
4149
                    break;
4150
                default:
4151
                    abort();
4152
                }
4153
                neon_store_reg64(cpu_V0, rd + pass);
4154
            }
4155
            return 0;
4156
        }
4157
        switch (op) {
4158
        case 8: /* VSHL */
4159
        case 9: /* VQSHL */
4160
        case 10: /* VRSHL */
4161
        case 11: /* VQRSHL */
4162
            {
4163
                int rtmp;
4164
                /* Shift instruction operands are reversed.  */
4165
                rtmp = rn;
4166
                rn = rm;
4167
                rm = rtmp;
4168
                pairwise = 0;
4169
            }
4170
            break;
4171
        case 20: /* VPMAX */
4172
        case 21: /* VPMIN */
4173
        case 23: /* VPADD */
4174
            pairwise = 1;
4175
            break;
4176
        case 26: /* VPADD (float) */
4177
            pairwise = (u && size < 2);
4178
            break;
4179
        case 30: /* VPMIN/VPMAX (float) */
4180
            pairwise = u;
4181
            break;
4182
        default:
4183
            pairwise = 0;
4184
            break;
4185
        }
4186
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4187

    
4188
        if (pairwise) {
4189
            /* Pairwise.  */
4190
            if (q)
4191
                n = (pass & 1) * 2;
4192
            else
4193
                n = 0;
4194
            if (pass < q + 1) {
4195
                NEON_GET_REG(T0, rn, n);
4196
                NEON_GET_REG(T1, rn, n + 1);
4197
            } else {
4198
                NEON_GET_REG(T0, rm, n);
4199
                NEON_GET_REG(T1, rm, n + 1);
4200
            }
4201
        } else {
4202
            /* Elementwise.  */
4203
            NEON_GET_REG(T0, rn, pass);
4204
            NEON_GET_REG(T1, rm, pass);
4205
        }
4206
        switch (op) {
4207
        case 0: /* VHADD */
4208
            GEN_NEON_INTEGER_OP(hadd);
4209
            break;
4210
        case 1: /* VQADD */
4211
            GEN_NEON_INTEGER_OP_ENV(qadd);
4212
            break;
4213
        case 2: /* VRHADD */
4214
            GEN_NEON_INTEGER_OP(rhadd);
4215
            break;
4216
        case 3: /* Logic ops.  */
4217
            switch ((u << 2) | size) {
4218
            case 0: /* VAND */
4219
                gen_op_andl_T0_T1();
4220
                break;
4221
            case 1: /* BIC */
4222
                gen_op_bicl_T0_T1();
4223
                break;
4224
            case 2: /* VORR */
4225
                gen_op_orl_T0_T1();
4226
                break;
4227
            case 3: /* VORN */
4228
                gen_op_notl_T1();
4229
                gen_op_orl_T0_T1();
4230
                break;
4231
            case 4: /* VEOR */
4232
                gen_op_xorl_T0_T1();
4233
                break;
4234
            case 5: /* VBSL */
4235
                tmp = neon_load_reg(rd, pass);
4236
                gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
4237
                dead_tmp(tmp);
4238
                break;
4239
            case 6: /* VBIT */
4240
                tmp = neon_load_reg(rd, pass);
4241
                gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
4242
                dead_tmp(tmp);
4243
                break;
4244
            case 7: /* VBIF */
4245
                tmp = neon_load_reg(rd, pass);
4246
                gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
4247
                dead_tmp(tmp);
4248
                break;
4249
            }
4250
            break;
4251
        case 4: /* VHSUB */
4252
            GEN_NEON_INTEGER_OP(hsub);
4253
            break;
4254
        case 5: /* VQSUB */
4255
            GEN_NEON_INTEGER_OP_ENV(qsub);
4256
            break;
4257
        case 6: /* VCGT */
4258
            GEN_NEON_INTEGER_OP(cgt);
4259
            break;
4260
        case 7: /* VCGE */
4261
            GEN_NEON_INTEGER_OP(cge);
4262
            break;
4263
        case 8: /* VSHL */
4264
            GEN_NEON_INTEGER_OP(shl);
4265
            break;
4266
        case 9: /* VQSHL */
4267
            GEN_NEON_INTEGER_OP_ENV(qshl);
4268
            break;
4269
        case 10: /* VRSHL */
4270
            GEN_NEON_INTEGER_OP(rshl);
4271
            break;
4272
        case 11: /* VQRSHL */
4273
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4274
            break;
4275
        case 12: /* VMAX */
4276
            GEN_NEON_INTEGER_OP(max);
4277
            break;
4278
        case 13: /* VMIN */
4279
            GEN_NEON_INTEGER_OP(min);
4280
            break;
4281
        case 14: /* VABD */
4282
            GEN_NEON_INTEGER_OP(abd);
4283
            break;
4284
        case 15: /* VABA */
4285
            GEN_NEON_INTEGER_OP(abd);
4286
            NEON_GET_REG(T1, rd, pass);
4287
            gen_neon_add(size);
4288
            break;
4289
        case 16:
4290
            if (!u) { /* VADD */
4291
                if (gen_neon_add(size))
4292
                    return 1;
4293
            } else { /* VSUB */
4294
                switch (size) {
4295
                case 0: gen_helper_neon_sub_u8(CPU_T001); break;
4296
                case 1: gen_helper_neon_sub_u16(CPU_T001); break;
4297
                case 2: gen_op_subl_T0_T1(); break;
4298
                default: return 1;
4299
                }
4300
            }
4301
            break;
4302
        case 17:
4303
            if (!u) { /* VTST */
4304
                switch (size) {
4305
                case 0: gen_helper_neon_tst_u8(CPU_T001); break;
4306
                case 1: gen_helper_neon_tst_u16(CPU_T001); break;
4307
                case 2: gen_helper_neon_tst_u32(CPU_T001); break;
4308
                default: return 1;
4309
                }
4310
            } else { /* VCEQ */
4311
                switch (size) {
4312
                case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
4313
                case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
4314
                case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
4315
                default: return 1;
4316
                }
4317
            }
4318
            break;
4319
        case 18: /* Multiply.  */
4320
            switch (size) {
4321
            case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4322
            case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4323
            case 2: gen_op_mul_T0_T1(); break;
4324
            default: return 1;
4325
            }
4326
            NEON_GET_REG(T1, rd, pass);
4327
            if (u) { /* VMLS */
4328
                gen_neon_rsb(size);
4329
            } else { /* VMLA */
4330
                gen_neon_add(size);
4331
            }
4332
            break;
4333
        case 19: /* VMUL */
4334
            if (u) { /* polynomial */
4335
                gen_helper_neon_mul_p8(CPU_T001);
4336
            } else { /* Integer */
4337
                switch (size) {
4338
                case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4339
                case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4340
                case 2: gen_op_mul_T0_T1(); break;
4341
                default: return 1;
4342
                }
4343
            }
4344
            break;
4345
        case 20: /* VPMAX */
4346
            GEN_NEON_INTEGER_OP(pmax);
4347
            break;
4348
        case 21: /* VPMIN */
4349
            GEN_NEON_INTEGER_OP(pmin);
4350
            break;
4351
        case 22: /* Hultiply high.  */
4352
            if (!u) { /* VQDMULH */
4353
                switch (size) {
4354
                case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
4355
                case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
4356
                default: return 1;
4357
                }
4358
            } else { /* VQRDHMUL */
4359
                switch (size) {
4360
                case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
4361
                case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
4362
                default: return 1;
4363
                }
4364
            }
4365
            break;
4366
        case 23: /* VPADD */
4367
            if (u)
4368
                return 1;
4369
            switch (size) {
4370
            case 0: gen_helper_neon_padd_u8(CPU_T001); break;
4371
            case 1: gen_helper_neon_padd_u16(CPU_T001); break;
4372
            case 2: gen_op_addl_T0_T1(); break;
4373
            default: return 1;
4374
            }
4375
            break;
4376
        case 26: /* Floating point arithnetic.  */
4377
            switch ((u << 2) | size) {
4378
            case 0: /* VADD */
4379
                gen_helper_neon_add_f32(CPU_T001);
4380
                break;
4381
            case 2: /* VSUB */
4382
                gen_helper_neon_sub_f32(CPU_T001);
4383
                break;
4384
            case 4: /* VPADD */
4385
                gen_helper_neon_add_f32(CPU_T001);
4386
                break;
4387
            case 6: /* VABD */
4388
                gen_helper_neon_abd_f32(CPU_T001);
4389
                break;
4390
            default:
4391
                return 1;
4392
            }
4393
            break;
4394
        case 27: /* Float multiply.  */
4395
            gen_helper_neon_mul_f32(CPU_T001);
4396
            if (!u) {
4397
                NEON_GET_REG(T1, rd, pass);
4398
                if (size == 0) {
4399
                    gen_helper_neon_add_f32(CPU_T001);
4400
                } else {
4401
                    gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
4402
                }
4403
            }
4404
            break;
4405
        case 28: /* Float compare.  */
4406
            if (!u) {
4407
                gen_helper_neon_ceq_f32(CPU_T001);
4408
            } else {
4409
                if (size == 0)
4410
                    gen_helper_neon_cge_f32(CPU_T001);
4411
                else
4412
                    gen_helper_neon_cgt_f32(CPU_T001);
4413
            }
4414
            break;
4415
        case 29: /* Float compare absolute.  */
4416
            if (!u)
4417
                return 1;
4418
            if (size == 0)
4419
                gen_helper_neon_acge_f32(CPU_T001);
4420
            else
4421
                gen_helper_neon_acgt_f32(CPU_T001);
4422
            break;
4423
        case 30: /* Float min/max.  */
4424
            if (size == 0)
4425
                gen_helper_neon_max_f32(CPU_T001);
4426
            else
4427
                gen_helper_neon_min_f32(CPU_T001);
4428
            break;
4429
        case 31:
4430
            if (size == 0)
4431
                gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4432
            else
4433
                gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4434
            break;
4435
        default:
4436
            abort();
4437
        }
4438
        /* Save the result.  For elementwise operations we can put it
4439
           straight into the destination register.  For pairwise operations
4440
           we have to be careful to avoid clobbering the source operands.  */
4441
        if (pairwise && rd == rm) {
4442
            gen_neon_movl_scratch_T0(pass);
4443
        } else {
4444
            NEON_SET_REG(T0, rd, pass);
4445
        }
4446

    
4447
        } /* for pass */
4448
        if (pairwise && rd == rm) {
4449
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4450
                gen_neon_movl_T0_scratch(pass);
4451
                NEON_SET_REG(T0, rd, pass);
4452
            }
4453
        }
4454
        /* End of 3 register same size operations.  */
4455
    } else if (insn & (1 << 4)) {
4456
        if ((insn & 0x00380080) != 0) {
4457
            /* Two registers and shift.  */
4458
            op = (insn >> 8) & 0xf;
4459
            if (insn & (1 << 7)) {
4460
                /* 64-bit shift.   */
4461
                size = 3;
4462
            } else {
4463
                size = 2;
4464
                while ((insn & (1 << (size + 19))) == 0)
4465
                    size--;
4466
            }
4467
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4468
            /* To avoid excessive dumplication of ops we implement shift
4469
               by immediate using the variable shift operations.  */
4470
            if (op < 8) {
4471
                /* Shift by immediate:
4472
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4473
                /* Right shifts are encoded as N - shift, where N is the
4474
                   element size in bits.  */
4475
                if (op <= 4)
4476
                    shift = shift - (1 << (size + 3));
4477
                if (size == 3) {
4478
                    count = q + 1;
4479
                } else {
4480
                    count = q ? 4: 2;
4481
                }
4482
                switch (size) {
4483
                case 0:
4484
                    imm = (uint8_t) shift;
4485
                    imm |= imm << 8;
4486
                    imm |= imm << 16;
4487
                    break;
4488
                case 1:
4489
                    imm = (uint16_t) shift;
4490
                    imm |= imm << 16;
4491
                    break;
4492
                case 2:
4493
                case 3:
4494
                    imm = shift;
4495
                    break;
4496
                default:
4497
                    abort();
4498
                }
4499

    
4500
                for (pass = 0; pass < count; pass++) {
4501
                    if (size == 3) {
4502
                        neon_load_reg64(cpu_V0, rm + pass);
4503
                        tcg_gen_movi_i64(cpu_V1, imm);
4504
                        switch (op) {
4505
                        case 0:  /* VSHR */
4506
                        case 1:  /* VSRA */
4507
                            if (u)
4508
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4509
                            else
4510
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4511
                            break;
4512
                        case 2: /* VRSHR */
4513
                        case 3: /* VRSRA */
4514
                            if (u)
4515
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4516
                            else
4517
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4518
                            break;
4519
                        case 4: /* VSRI */
4520
                            if (!u)
4521
                                return 1;
4522
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4523
                            break;
4524
                        case 5: /* VSHL, VSLI */
4525
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4526
                            break;
4527
                        case 6: /* VQSHL */
4528
                            if (u)
4529
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4530
                            else
4531
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4532
                            break;
4533
                        case 7: /* VQSHLU */
4534
                            gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4535
                            break;
4536
                        }
4537
                        if (op == 1 || op == 3) {
4538
                            /* Accumulate.  */
4539
                            neon_load_reg64(cpu_V0, rd + pass);
4540
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4541
                        } else if (op == 4 || (op == 5 && u)) {
4542
                            /* Insert */
4543
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4544
                        }
4545
                        neon_store_reg64(cpu_V0, rd + pass);
4546
                    } else { /* size < 3 */
4547
                        /* Operands in T0 and T1.  */
4548
                        gen_op_movl_T1_im(imm);
4549
                        NEON_GET_REG(T0, rm, pass);
4550
                        switch (op) {
4551
                        case 0:  /* VSHR */
4552
                        case 1:  /* VSRA */
4553
                            GEN_NEON_INTEGER_OP(shl);
4554
                            break;
4555
                        case 2: /* VRSHR */
4556
                        case 3: /* VRSRA */
4557
                            GEN_NEON_INTEGER_OP(rshl);
4558
                            break;
4559
                        case 4: /* VSRI */
4560
                            if (!u)
4561
                                return 1;
4562
                            GEN_NEON_INTEGER_OP(shl);
4563
                            break;
4564
                        case 5: /* VSHL, VSLI */
4565
                            switch (size) {
4566
                            case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4567
                            case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4568
                            case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4569
                            default: return 1;
4570
                            }
4571
                            break;
4572
                        case 6: /* VQSHL */
4573
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4574
                            break;
4575
                        case 7: /* VQSHLU */
4576
                            switch (size) {
4577
                            case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4578
                            case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4579
                            case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4580
                            default: return 1;
4581
                            }
4582
                            break;
4583
                        }
4584

    
4585
                        if (op == 1 || op == 3) {
4586
                            /* Accumulate.  */
4587
                            NEON_GET_REG(T1, rd, pass);
4588
                            gen_neon_add(size);
4589
                        } else if (op == 4 || (op == 5 && u)) {
4590
                            /* Insert */
4591
                            switch (size) {
4592
                            case 0:
4593
                                if (op == 4)
4594
                                    imm = 0xff >> -shift;
4595
                                else
4596
                                    imm = (uint8_t)(0xff << shift);
4597
                                imm |= imm << 8;
4598
                                imm |= imm << 16;
4599
                                break;
4600
                            case 1:
4601
                                if (op == 4)
4602
                                    imm = 0xffff >> -shift;
4603
                                else
4604
                                    imm = (uint16_t)(0xffff << shift);
4605
                                imm |= imm << 16;
4606
                                break;
4607
                            case 2:
4608
                                if (op == 4)
4609
                                    imm = 0xffffffffu >> -shift;
4610
                                else
4611
                                    imm = 0xffffffffu << shift;
4612
                                break;
4613
                            default:
4614
                                abort();
4615
                            }
4616
                            tmp = neon_load_reg(rd, pass);
4617
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4618
                            tcg_gen_andi_i32(tmp, tmp, ~imm);
4619
                            tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4620
                        }
4621
                        NEON_SET_REG(T0, rd, pass);
4622
                    }
4623
                } /* for pass */
4624
            } else if (op < 10) {
4625
                /* Shift by immediate and narrow:
4626
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4627
                shift = shift - (1 << (size + 3));
4628
                size++;
4629
                switch (size) {
4630
                case 1:
4631
                    imm = (uint16_t)shift;
4632
                    imm |= imm << 16;
4633
                    tmp2 = tcg_const_i32(imm);
4634
                    TCGV_UNUSED_I64(tmp64);
4635
                    break;
4636
                case 2:
4637
                    imm = (uint32_t)shift;
4638
                    tmp2 = tcg_const_i32(imm);
4639
                    TCGV_UNUSED_I64(tmp64);
4640
                    break;
4641
                case 3:
4642
                    tmp64 = tcg_const_i64(shift);
4643
                    TCGV_UNUSED(tmp2);
4644
                    break;
4645
                default:
4646
                    abort();
4647
                }
4648

    
4649
                for (pass = 0; pass < 2; pass++) {
4650
                    if (size == 3) {
4651
                        neon_load_reg64(cpu_V0, rm + pass);
4652
                        if (q) {
4653
                          if (u)
4654
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4655
                          else
4656
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4657
                        } else {
4658
                          if (u)
4659
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4660
                          else
4661
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4662
                        }
4663
                    } else {
4664
                        tmp = neon_load_reg(rm + pass, 0);
4665
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4666
                        tmp3 = neon_load_reg(rm + pass, 1);
4667
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4668
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4669
                        dead_tmp(tmp);
4670
                        dead_tmp(tmp3);
4671
                    }
4672
                    tmp = new_tmp();
4673
                    if (op == 8 && !u) {
4674
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4675
                    } else {
4676
                        if (op == 8)
4677
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4678
                        else
4679
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4680
                    }
4681
                    if (pass == 0) {
4682
                        tmp2 = tmp;
4683
                    } else {
4684
                        neon_store_reg(rd, 0, tmp2);
4685
                        neon_store_reg(rd, 1, tmp);
4686
                    }
4687
                } /* for pass */
4688
            } else if (op == 10) {
4689
                /* VSHLL */
4690
                if (q || size == 3)
4691
                    return 1;
4692
                tmp = neon_load_reg(rm, 0);
4693
                tmp2 = neon_load_reg(rm, 1);
4694
                for (pass = 0; pass < 2; pass++) {
4695
                    if (pass == 1)
4696
                        tmp = tmp2;
4697

    
4698
                    gen_neon_widen(cpu_V0, tmp, size, u);
4699

    
4700
                    if (shift != 0) {
4701
                        /* The shift is less than the width of the source
4702
                           type, so we can just shift the whole register.  */
4703
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4704
                        if (size < 2 || !u) {
4705
                            uint64_t imm64;
4706
                            if (size == 0) {
4707
                                imm = (0xffu >> (8 - shift));
4708
                                imm |= imm << 16;
4709
                            } else {
4710
                                imm = 0xffff >> (16 - shift);
4711
                            }
4712
                            imm64 = imm | (((uint64_t)imm) << 32);
4713
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4714
                        }
4715
                    }
4716
                    neon_store_reg64(cpu_V0, rd + pass);
4717
                }
4718
            } else if (op == 15 || op == 16) {
4719
                /* VCVT fixed-point.  */
4720
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4721
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4722
                    if (op & 1) {
4723
                        if (u)
4724
                            gen_vfp_ulto(0, shift);
4725
                        else
4726
                            gen_vfp_slto(0, shift);
4727
                    } else {
4728
                        if (u)
4729
                            gen_vfp_toul(0, shift);
4730
                        else
4731
                            gen_vfp_tosl(0, shift);
4732
                    }
4733
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4734
                }
4735
            } else {
4736
                return 1;
4737
            }
4738
        } else { /* (insn & 0x00380080) == 0 */
4739
            int invert;
4740

    
4741
            op = (insn >> 8) & 0xf;
4742
            /* One register and immediate.  */
4743
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4744
            invert = (insn & (1 << 5)) != 0;
4745
            switch (op) {
4746
            case 0: case 1:
4747
                /* no-op */
4748
                break;
4749
            case 2: case 3:
4750
                imm <<= 8;
4751
                break;
4752
            case 4: case 5:
4753
                imm <<= 16;
4754
                break;
4755
            case 6: case 7:
4756
                imm <<= 24;
4757
                break;
4758
            case 8: case 9:
4759
                imm |= imm << 16;
4760
                break;
4761
            case 10: case 11:
4762
                imm = (imm << 8) | (imm << 24);
4763
                break;
4764
            case 12:
4765
                imm = (imm < 8) | 0xff;
4766
                break;
4767
            case 13:
4768
                imm = (imm << 16) | 0xffff;
4769
                break;
4770
            case 14: