Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 36aa55dc

History | View | Annotate | Download (295.8 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, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
#include <stdarg.h>
23
#include <stdlib.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include <inttypes.h>
27

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

    
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) if (!ENABLE_ARCH_##x) goto illegal_op;
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
    int is_mem;
60
#if !defined(CONFIG_USER_ONLY)
61
    int user;
62
#endif
63
} DisasContext;
64

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

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

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

    
80
/* FIXME:  These should be removed.  */
81
static TCGv cpu_T[2];
82
static TCGv cpu_F0s, cpu_F1s, 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(TCG_TYPE_PTR, TCG_AREG0, "env");
91

    
92
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
93
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
94
}
95

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

    
102
/* Allocate a temporary variable.  */
103
static TCGv new_tmp(void)
104
{
105
    TCGv tmp;
106
    if (num_temps == MAX_TEMPS)
107
        abort();
108

    
109
    if (GET_TCGV(temps[num_temps]))
110
      return temps[num_temps++];
111

    
112
    tmp = tcg_temp_new(TCG_TYPE_I32);
113
    temps[num_temps++] = tmp;
114
    return tmp;
115
}
116

    
117
/* Release a temporary variable.  */
118
static void dead_tmp(TCGv tmp)
119
{
120
    int i;
121
    num_temps--;
122
    i = num_temps;
123
    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
124
        return;
125

    
126
    /* Shuffle this temp to the last slot.  */
127
    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
128
        i--;
129
    while (i < num_temps) {
130
        temps[i] = temps[i + 1];
131
        i++;
132
    }
133
    temps[i] = tmp;
134
}
135

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

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

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

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

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

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

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

    
190

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

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

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

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

    
217
#define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
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
#define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
221
#define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
222

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

    
229
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
230
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
231

    
232
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
233

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

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

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

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

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

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

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

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

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

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

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

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

    
340
static TCGv gen_muls_i64_i32(TCGv a, TCGv b)
341
{
342
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
343
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
344

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

    
353
/* Unsigned 32x32->64 multiply.  */
354
static void gen_op_mull_T0_T1(void)
355
{
356
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
357
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
358

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

    
367
/* Signed 32x32->64 multiply.  */
368
static void gen_imull(TCGv a, TCGv b)
369
{
370
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
371
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
372

    
373
    tcg_gen_ext_i32_i64(tmp1, a);
374
    tcg_gen_ext_i32_i64(tmp2, b);
375
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
376
    tcg_gen_trunc_i64_i32(a, tmp1);
377
    tcg_gen_shri_i64(tmp1, tmp1, 32);
378
    tcg_gen_trunc_i64_i32(b, tmp1);
379
}
380
#define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
381

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

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

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

    
412
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
413

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

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

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

    
440
/* dest = T0 - T1 + CF - 1.  */
441
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
442
{
443
    TCGv tmp;
444
    tcg_gen_sub_i32(dest, t0, t1);
445
    tmp = load_cpu_field(CF);
446
    tcg_gen_add_i32(dest, dest, tmp);
447
    tcg_gen_subi_i32(dest, dest, 1);
448
    dead_tmp(tmp);
449
}
450

    
451
#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
452
#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
453

    
454
/* T0 &= ~T1.  Clobbers T1.  */
455
/* FIXME: Implement bic natively.  */
456
static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
457
{
458
    TCGv tmp = new_tmp();
459
    tcg_gen_not_i32(tmp, t1);
460
    tcg_gen_and_i32(dest, t0, tmp);
461
    dead_tmp(tmp);
462
}
463
static inline void gen_op_bicl_T0_T1(void)
464
{
465
    gen_op_notl_T1();
466
    gen_op_andl_T0_T1();
467
}
468

    
469
/* FIXME:  Implement this natively.  */
470
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
471

    
472
/* FIXME:  Implement this natively.  */
473
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
474
{
475
    TCGv tmp;
476

    
477
    if (i == 0)
478
        return;
479

    
480
    tmp = new_tmp();
481
    tcg_gen_shri_i32(tmp, t1, i);
482
    tcg_gen_shli_i32(t1, t1, 32 - i);
483
    tcg_gen_or_i32(t0, t1, tmp);
484
    dead_tmp(tmp);
485
}
486

    
487
static void shifter_out_im(TCGv var, int shift)
488
{
489
    TCGv tmp = new_tmp();
490
    if (shift == 0) {
491
        tcg_gen_andi_i32(tmp, var, 1);
492
    } else {
493
        tcg_gen_shri_i32(tmp, var, shift);
494
        if (shift != 31);
495
            tcg_gen_andi_i32(tmp, tmp, 1);
496
    }
497
    gen_set_CF(tmp);
498
    dead_tmp(tmp);
499
}
500

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

    
551
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
552
                                     TCGv shift, int flags)
553
{
554
    if (flags) {
555
        switch (shiftop) {
556
        case 0: gen_helper_shl_cc(var, var, shift); break;
557
        case 1: gen_helper_shr_cc(var, var, shift); break;
558
        case 2: gen_helper_sar_cc(var, var, shift); break;
559
        case 3: gen_helper_ror_cc(var, var, shift); break;
560
        }
561
    } else {
562
        switch (shiftop) {
563
        case 0: gen_helper_shl(var, var, shift); break;
564
        case 1: gen_helper_shr(var, var, shift); break;
565
        case 2: gen_helper_sar(var, var, shift); break;
566
        case 3: gen_helper_ror(var, var, shift); break;
567
        }
568
    }
569
    dead_tmp(shift);
570
}
571

    
572
#define PAS_OP(pfx) \
573
    switch (op2) {  \
574
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
575
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
576
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
577
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
578
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
579
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
580
    }
581
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
582
{
583
    TCGv tmp;
584

    
585
    switch (op1) {
586
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
587
    case 1:
588
        tmp = tcg_temp_new(TCG_TYPE_PTR);
589
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
590
        PAS_OP(s)
591
        break;
592
    case 5:
593
        tmp = tcg_temp_new(TCG_TYPE_PTR);
594
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
595
        PAS_OP(u)
596
        break;
597
#undef gen_pas_helper
598
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
599
    case 2:
600
        PAS_OP(q);
601
        break;
602
    case 3:
603
        PAS_OP(sh);
604
        break;
605
    case 6:
606
        PAS_OP(uq);
607
        break;
608
    case 7:
609
        PAS_OP(uh);
610
        break;
611
#undef gen_pas_helper
612
    }
613
}
614
#undef PAS_OP
615

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

    
630
    switch (op1) {
631
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
632
    case 0:
633
        tmp = tcg_temp_new(TCG_TYPE_PTR);
634
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
635
        PAS_OP(s)
636
        break;
637
    case 4:
638
        tmp = tcg_temp_new(TCG_TYPE_PTR);
639
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
640
        PAS_OP(u)
641
        break;
642
#undef gen_pas_helper
643
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
644
    case 1:
645
        PAS_OP(q);
646
        break;
647
    case 2:
648
        PAS_OP(sh);
649
        break;
650
    case 5:
651
        PAS_OP(uq);
652
        break;
653
    case 6:
654
        PAS_OP(uh);
655
        break;
656
#undef gen_pas_helper
657
    }
658
}
659
#undef PAS_OP
660

    
661
static void gen_test_cc(int cc, int label)
662
{
663
    TCGv tmp;
664
    TCGv tmp2;
665
    int inv;
666

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

    
759
const uint8_t table_logic_cc[16] = {
760
    1, /* and */
761
    1, /* xor */
762
    0, /* sub */
763
    0, /* rsb */
764
    0, /* add */
765
    0, /* adc */
766
    0, /* sbc */
767
    0, /* rsc */
768
    1, /* andl */
769
    1, /* xorl */
770
    0, /* cmp */
771
    0, /* cmn */
772
    1, /* orr */
773
    1, /* mov */
774
    1, /* bic */
775
    1, /* mvn */
776
};
777

    
778
/* Set PC and Thumb state from an immediate address.  */
779
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
780
{
781
    TCGv tmp;
782

    
783
    s->is_jmp = DISAS_UPDATE;
784
    tmp = new_tmp();
785
    if (s->thumb != (addr & 1)) {
786
        tcg_gen_movi_i32(tmp, addr & 1);
787
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
788
    }
789
    tcg_gen_movi_i32(tmp, addr & ~1);
790
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
791
    dead_tmp(tmp);
792
}
793

    
794
/* Set PC and Thumb state from var.  var is marked as dead.  */
795
static inline void gen_bx(DisasContext *s, TCGv var)
796
{
797
    TCGv tmp;
798

    
799
    s->is_jmp = DISAS_UPDATE;
800
    tmp = new_tmp();
801
    tcg_gen_andi_i32(tmp, var, 1);
802
    store_cpu_field(tmp, thumb);
803
    tcg_gen_andi_i32(var, var, ~1);
804
    store_cpu_field(var, regs[15]);
805
}
806

    
807
/* TODO: This should be removed.  Use gen_bx instead.  */
808
static inline void gen_bx_T0(DisasContext *s)
809
{
810
    TCGv tmp = new_tmp();
811
    tcg_gen_mov_i32(tmp, cpu_T[0]);
812
    gen_bx(s, tmp);
813
}
814

    
815
#if defined(CONFIG_USER_ONLY)
816
#define gen_ldst(name, s) gen_op_##name##_raw()
817
#else
818
#define gen_ldst(name, s) do { \
819
    s->is_mem = 1; \
820
    if (IS_USER(s)) \
821
        gen_op_##name##_user(); \
822
    else \
823
        gen_op_##name##_kernel(); \
824
    } while (0)
825
#endif
826
static inline TCGv gen_ld8s(TCGv addr, int index)
827
{
828
    TCGv tmp = new_tmp();
829
    tcg_gen_qemu_ld8s(tmp, addr, index);
830
    return tmp;
831
}
832
static inline TCGv gen_ld8u(TCGv addr, int index)
833
{
834
    TCGv tmp = new_tmp();
835
    tcg_gen_qemu_ld8u(tmp, addr, index);
836
    return tmp;
837
}
838
static inline TCGv gen_ld16s(TCGv addr, int index)
839
{
840
    TCGv tmp = new_tmp();
841
    tcg_gen_qemu_ld16s(tmp, addr, index);
842
    return tmp;
843
}
844
static inline TCGv gen_ld16u(TCGv addr, int index)
845
{
846
    TCGv tmp = new_tmp();
847
    tcg_gen_qemu_ld16u(tmp, addr, index);
848
    return tmp;
849
}
850
static inline TCGv gen_ld32(TCGv addr, int index)
851
{
852
    TCGv tmp = new_tmp();
853
    tcg_gen_qemu_ld32u(tmp, addr, index);
854
    return tmp;
855
}
856
static inline void gen_st8(TCGv val, TCGv addr, int index)
857
{
858
    tcg_gen_qemu_st8(val, addr, index);
859
    dead_tmp(val);
860
}
861
static inline void gen_st16(TCGv val, TCGv addr, int index)
862
{
863
    tcg_gen_qemu_st16(val, addr, index);
864
    dead_tmp(val);
865
}
866
static inline void gen_st32(TCGv val, TCGv addr, int index)
867
{
868
    tcg_gen_qemu_st32(val, addr, index);
869
    dead_tmp(val);
870
}
871

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

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

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

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

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

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

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

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

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

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

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

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

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

    
993
#define VFP_OP1(name)                               \
994
static inline void gen_vfp_##name(int dp, int arg)  \
995
{                                                   \
996
    if (dp)                                         \
997
        gen_op_vfp_##name##d(arg);                  \
998
    else                                            \
999
        gen_op_vfp_##name##s(arg);                  \
1000
}
1001

    
1002
VFP_OP2(add)
1003
VFP_OP2(sub)
1004
VFP_OP2(mul)
1005
VFP_OP2(div)
1006

    
1007
#undef VFP_OP2
1008

    
1009
static inline void gen_vfp_abs(int dp)
1010
{
1011
    if (dp)
1012
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1013
    else
1014
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1015
}
1016

    
1017
static inline void gen_vfp_neg(int dp)
1018
{
1019
    if (dp)
1020
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1021
    else
1022
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1023
}
1024

    
1025
static inline void gen_vfp_sqrt(int dp)
1026
{
1027
    if (dp)
1028
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1029
    else
1030
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1031
}
1032

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

    
1041
static inline void gen_vfp_cmpe(int dp)
1042
{
1043
    if (dp)
1044
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1045
    else
1046
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1047
}
1048

    
1049
static inline void gen_vfp_F1_ld0(int dp)
1050
{
1051
    if (dp)
1052
        tcg_gen_movi_i64(cpu_F1d, 0);
1053
    else
1054
        tcg_gen_movi_i32(cpu_F1s, 0);
1055
}
1056

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

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

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

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

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

    
1097
static inline void gen_vfp_tosiz(int dp)
1098
{
1099
    if (dp)
1100
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1101
    else
1102
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1103
}
1104

    
1105
#define VFP_GEN_FIX(name) \
1106
static inline void gen_vfp_##name(int dp, int shift) \
1107
{ \
1108
    if (dp) \
1109
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1110
    else \
1111
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1112
}
1113
VFP_GEN_FIX(tosh)
1114
VFP_GEN_FIX(tosl)
1115
VFP_GEN_FIX(touh)
1116
VFP_GEN_FIX(toul)
1117
VFP_GEN_FIX(shto)
1118
VFP_GEN_FIX(slto)
1119
VFP_GEN_FIX(uhto)
1120
VFP_GEN_FIX(ulto)
1121
#undef VFP_GEN_FIX
1122

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

    
1131
static inline void gen_vfp_st(DisasContext *s, int dp)
1132
{
1133
    if (dp)
1134
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1135
    else
1136
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1137
}
1138

    
1139
static inline long
1140
vfp_reg_offset (int dp, int reg)
1141
{
1142
    if (dp)
1143
        return offsetof(CPUARMState, vfp.regs[reg]);
1144
    else if (reg & 1) {
1145
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1146
          + offsetof(CPU_DoubleU, l.upper);
1147
    } else {
1148
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1149
          + offsetof(CPU_DoubleU, l.lower);
1150
    }
1151
}
1152

    
1153
/* Return the offset of a 32-bit piece of a NEON register.
1154
   zero is the least significant end of the register.  */
1155
static inline long
1156
neon_reg_offset (int reg, int n)
1157
{
1158
    int sreg;
1159
    sreg = reg * 2 + n;
1160
    return vfp_reg_offset(0, sreg);
1161
}
1162

    
1163
/* FIXME: Remove these.  */
1164
#define neon_T0 cpu_T[0]
1165
#define neon_T1 cpu_T[1]
1166
#define NEON_GET_REG(T, reg, n) \
1167
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1168
#define NEON_SET_REG(T, reg, n) \
1169
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1170

    
1171
static TCGv neon_load_reg(int reg, int pass)
1172
{
1173
    TCGv tmp = new_tmp();
1174
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1175
    return tmp;
1176
}
1177

    
1178
static void neon_store_reg(int reg, int pass, TCGv var)
1179
{
1180
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1181
    dead_tmp(var);
1182
}
1183

    
1184
static inline void neon_load_reg64(TCGv var, int reg)
1185
{
1186
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1187
}
1188

    
1189
static inline void neon_store_reg64(TCGv var, int reg)
1190
{
1191
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192
}
1193

    
1194
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1195
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1196
#define tcg_gen_st_f32 tcg_gen_st_i32
1197
#define tcg_gen_st_f64 tcg_gen_st_i64
1198

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

    
1207
static inline void gen_mov_F1_vreg(int dp, int reg)
1208
{
1209
    if (dp)
1210
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1211
    else
1212
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1213
}
1214

    
1215
static inline void gen_mov_vreg_F0(int dp, int reg)
1216
{
1217
    if (dp)
1218
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1219
    else
1220
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1221
}
1222

    
1223
#define ARM_CP_RW_BIT        (1 << 20)
1224

    
1225
static inline void iwmmxt_load_reg(TCGv var, int reg)
1226
{
1227
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1228
}
1229

    
1230
static inline void iwmmxt_store_reg(TCGv var, int reg)
1231
{
1232
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1233
}
1234

    
1235
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1236
{
1237
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1238
}
1239

    
1240
static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1241
{
1242
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1243
}
1244

    
1245
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1246
{
1247
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1248
}
1249

    
1250
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1251
{
1252
    iwmmxt_store_reg(cpu_M0, rn);
1253
}
1254

    
1255
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1256
{
1257
    iwmmxt_load_reg(cpu_M0, rn);
1258
}
1259

    
1260
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1261
{
1262
    iwmmxt_load_reg(cpu_V1, rn);
1263
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1264
}
1265

    
1266
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1267
{
1268
    iwmmxt_load_reg(cpu_V1, rn);
1269
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1270
}
1271

    
1272
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1273
{
1274
    iwmmxt_load_reg(cpu_V1, rn);
1275
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1276
}
1277

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

    
1285
#define IWMMXT_OP_ENV(name) \
1286
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1287
{ \
1288
    iwmmxt_load_reg(cpu_V1, rn); \
1289
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1290
}
1291

    
1292
#define IWMMXT_OP_ENV_SIZE(name) \
1293
IWMMXT_OP_ENV(name##b) \
1294
IWMMXT_OP_ENV(name##w) \
1295
IWMMXT_OP_ENV(name##l)
1296

    
1297
#define IWMMXT_OP_ENV1(name) \
1298
static inline void gen_op_iwmmxt_##name##_M0(void) \
1299
{ \
1300
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1301
}
1302

    
1303
IWMMXT_OP(maddsq)
1304
IWMMXT_OP(madduq)
1305
IWMMXT_OP(sadb)
1306
IWMMXT_OP(sadw)
1307
IWMMXT_OP(mulslw)
1308
IWMMXT_OP(mulshw)
1309
IWMMXT_OP(mululw)
1310
IWMMXT_OP(muluhw)
1311
IWMMXT_OP(macsw)
1312
IWMMXT_OP(macuw)
1313

    
1314
IWMMXT_OP_ENV_SIZE(unpackl)
1315
IWMMXT_OP_ENV_SIZE(unpackh)
1316

    
1317
IWMMXT_OP_ENV1(unpacklub)
1318
IWMMXT_OP_ENV1(unpackluw)
1319
IWMMXT_OP_ENV1(unpacklul)
1320
IWMMXT_OP_ENV1(unpackhub)
1321
IWMMXT_OP_ENV1(unpackhuw)
1322
IWMMXT_OP_ENV1(unpackhul)
1323
IWMMXT_OP_ENV1(unpacklsb)
1324
IWMMXT_OP_ENV1(unpacklsw)
1325
IWMMXT_OP_ENV1(unpacklsl)
1326
IWMMXT_OP_ENV1(unpackhsb)
1327
IWMMXT_OP_ENV1(unpackhsw)
1328
IWMMXT_OP_ENV1(unpackhsl)
1329

    
1330
IWMMXT_OP_ENV_SIZE(cmpeq)
1331
IWMMXT_OP_ENV_SIZE(cmpgtu)
1332
IWMMXT_OP_ENV_SIZE(cmpgts)
1333

    
1334
IWMMXT_OP_ENV_SIZE(mins)
1335
IWMMXT_OP_ENV_SIZE(minu)
1336
IWMMXT_OP_ENV_SIZE(maxs)
1337
IWMMXT_OP_ENV_SIZE(maxu)
1338

    
1339
IWMMXT_OP_ENV_SIZE(subn)
1340
IWMMXT_OP_ENV_SIZE(addn)
1341
IWMMXT_OP_ENV_SIZE(subu)
1342
IWMMXT_OP_ENV_SIZE(addu)
1343
IWMMXT_OP_ENV_SIZE(subs)
1344
IWMMXT_OP_ENV_SIZE(adds)
1345

    
1346
IWMMXT_OP_ENV(avgb0)
1347
IWMMXT_OP_ENV(avgb1)
1348
IWMMXT_OP_ENV(avgw0)
1349
IWMMXT_OP_ENV(avgw1)
1350

    
1351
IWMMXT_OP(msadb)
1352

    
1353
IWMMXT_OP_ENV(packuw)
1354
IWMMXT_OP_ENV(packul)
1355
IWMMXT_OP_ENV(packuq)
1356
IWMMXT_OP_ENV(packsw)
1357
IWMMXT_OP_ENV(packsl)
1358
IWMMXT_OP_ENV(packsq)
1359

    
1360
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1361
{
1362
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1363
}
1364

    
1365
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1366
{
1367
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1368
}
1369

    
1370
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1371
{
1372
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1373
}
1374

    
1375
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1376
{
1377
    iwmmxt_load_reg(cpu_V1, rn);
1378
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1379
}
1380

    
1381
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1382
{
1383
    TCGv tmp = tcg_const_i32(shift);
1384
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1385
}
1386

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

    
1394
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1395
{
1396
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1397
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1398
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1399
}
1400

    
1401
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1402
{
1403
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1404
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1405
    if (mask != ~0u)
1406
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1407
}
1408

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

    
1417
static void gen_op_iwmmxt_set_cup(void)
1418
{
1419
    TCGv tmp;
1420
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1421
    tcg_gen_ori_i32(tmp, tmp, 1);
1422
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1423
}
1424

    
1425
static void gen_op_iwmmxt_setpsr_nz(void)
1426
{
1427
    TCGv tmp = new_tmp();
1428
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1429
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1430
}
1431

    
1432
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1433
{
1434
    iwmmxt_load_reg(cpu_V1, rn);
1435
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1436
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1437
}
1438

    
1439

    
1440
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1441
{
1442
    iwmmxt_load_reg(cpu_V0, rn);
1443
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1444
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1445
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1446
}
1447

    
1448
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1449
{
1450
    tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
1451
    iwmmxt_store_reg(cpu_V0, rn);
1452
}
1453

    
1454
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1455
{
1456
    int rd;
1457
    uint32_t offset;
1458

    
1459
    rd = (insn >> 16) & 0xf;
1460
    gen_movl_T1_reg(s, rd);
1461

    
1462
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1463
    if (insn & (1 << 24)) {
1464
        /* Pre indexed */
1465
        if (insn & (1 << 23))
1466
            gen_op_addl_T1_im(offset);
1467
        else
1468
            gen_op_addl_T1_im(-offset);
1469

    
1470
        if (insn & (1 << 21))
1471
            gen_movl_reg_T1(s, rd);
1472
    } else if (insn & (1 << 21)) {
1473
        /* Post indexed */
1474
        if (insn & (1 << 23))
1475
            gen_op_movl_T0_im(offset);
1476
        else
1477
            gen_op_movl_T0_im(- offset);
1478
        gen_op_addl_T0_T1();
1479
        gen_movl_reg_T0(s, rd);
1480
    } else if (!(insn & (1 << 23)))
1481
        return 1;
1482
    return 0;
1483
}
1484

    
1485
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1486
{
1487
    int rd = (insn >> 0) & 0xf;
1488

    
1489
    if (insn & (1 << 8))
1490
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1491
            return 1;
1492
        else
1493
            gen_op_iwmmxt_movl_T0_wCx(rd);
1494
    else
1495
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1496

    
1497
    gen_op_movl_T1_im(mask);
1498
    gen_op_andl_T0_T1();
1499
    return 0;
1500
}
1501

    
1502
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1503
   (ie. an undefined instruction).  */
1504
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1505
{
1506
    int rd, wrd;
1507
    int rdhi, rdlo, rd0, rd1, i;
1508
    TCGv tmp;
1509

    
1510
    if ((insn & 0x0e000e00) == 0x0c000000) {
1511
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1512
            wrd = insn & 0xf;
1513
            rdlo = (insn >> 12) & 0xf;
1514
            rdhi = (insn >> 16) & 0xf;
1515
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1516
                gen_iwmmxt_movl_T0_T1_wRn(wrd);
1517
                gen_movl_reg_T0(s, rdlo);
1518
                gen_movl_reg_T1(s, rdhi);
1519
            } else {                                        /* TMCRR */
1520
                gen_movl_T0_reg(s, rdlo);
1521
                gen_movl_T1_reg(s, rdhi);
1522
                gen_iwmmxt_movl_wRn_T0_T1(wrd);
1523
                gen_op_iwmmxt_set_mup();
1524
            }
1525
            return 0;
1526
        }
1527

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

    
1590
    if ((insn & 0x0f000000) != 0x0e000000)
1591
        return 1;
1592

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

    
2465
    return 0;
2466
}
2467

    
2468
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2469
   (ie. an undefined instruction).  */
2470
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2471
{
2472
    int acc, rd0, rd1, rdhi, rdlo;
2473

    
2474
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2475
        /* Multiply with Internal Accumulate Format */
2476
        rd0 = (insn >> 12) & 0xf;
2477
        rd1 = insn & 0xf;
2478
        acc = (insn >> 5) & 7;
2479

    
2480
        if (acc != 0)
2481
            return 1;
2482

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

    
2511
        gen_op_iwmmxt_movq_wRn_M0(acc);
2512
        return 0;
2513
    }
2514

    
2515
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2516
        /* Internal Accumulator Access Format */
2517
        rdhi = (insn >> 16) & 0xf;
2518
        rdlo = (insn >> 12) & 0xf;
2519
        acc = insn & 7;
2520

    
2521
        if (acc != 0)
2522
            return 1;
2523

    
2524
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2525
            gen_iwmmxt_movl_T0_T1_wRn(acc);
2526
            gen_movl_reg_T0(s, rdlo);
2527
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2528
            gen_op_andl_T0_T1();
2529
            gen_movl_reg_T0(s, rdhi);
2530
        } else {                                        /* MAR */
2531
            gen_movl_T0_reg(s, rdlo);
2532
            gen_movl_T1_reg(s, rdhi);
2533
            gen_iwmmxt_movl_wRn_T0_T1(acc);
2534
        }
2535
        return 0;
2536
    }
2537

    
2538
    return 1;
2539
}
2540

    
2541
/* Disassemble system coprocessor instruction.  Return nonzero if
2542
   instruction is not defined.  */
2543
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2544
{
2545
    TCGv tmp;
2546
    uint32_t rd = (insn >> 12) & 0xf;
2547
    uint32_t cp = (insn >> 8) & 0xf;
2548
    if (IS_USER(s)) {
2549
        return 1;
2550
    }
2551

    
2552
    if (insn & ARM_CP_RW_BIT) {
2553
        if (!env->cp[cp].cp_read)
2554
            return 1;
2555
        gen_set_pc_im(s->pc);
2556
        tmp = new_tmp();
2557
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2558
        store_reg(s, rd, tmp);
2559
    } else {
2560
        if (!env->cp[cp].cp_write)
2561
            return 1;
2562
        gen_set_pc_im(s->pc);
2563
        tmp = load_reg(s, rd);
2564
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2565
        dead_tmp(tmp);
2566
    }
2567
    return 0;
2568
}
2569

    
2570
static int cp15_user_ok(uint32_t insn)
2571
{
2572
    int cpn = (insn >> 16) & 0xf;
2573
    int cpm = insn & 0xf;
2574
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2575

    
2576
    if (cpn == 13 && cpm == 0) {
2577
        /* TLS register.  */
2578
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2579
            return 1;
2580
    }
2581
    if (cpn == 7) {
2582
        /* ISB, DSB, DMB.  */
2583
        if ((cpm == 5 && op == 4)
2584
                || (cpm == 10 && (op == 4 || op == 5)))
2585
            return 1;
2586
    }
2587
    return 0;
2588
}
2589

    
2590
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2591
   instruction is not defined.  */
2592
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2593
{
2594
    uint32_t rd;
2595
    TCGv tmp;
2596

    
2597
    /* M profile cores use memory mapped registers instead of cp15.  */
2598
    if (arm_feature(env, ARM_FEATURE_M))
2599
        return 1;
2600

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

    
2646
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2647
#define VFP_SREG(insn, bigbit, smallbit) \
2648
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2649
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2650
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2651
        reg = (((insn) >> (bigbit)) & 0x0f) \
2652
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2653
    } else { \
2654
        if (insn & (1 << (smallbit))) \
2655
            return 1; \
2656
        reg = ((insn) >> (bigbit)) & 0x0f; \
2657
    }} while (0)
2658

    
2659
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2660
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2661
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2662
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2663
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2664
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2665

    
2666
/* Move between integer and VFP cores.  */
2667
static TCGv gen_vfp_mrs(void)
2668
{
2669
    TCGv tmp = new_tmp();
2670
    tcg_gen_mov_i32(tmp, cpu_F0s);
2671
    return tmp;
2672
}
2673

    
2674
static void gen_vfp_msr(TCGv tmp)
2675
{
2676
    tcg_gen_mov_i32(cpu_F0s, tmp);
2677
    dead_tmp(tmp);
2678
}
2679

    
2680
static inline int
2681
vfp_enabled(CPUState * env)
2682
{
2683
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2684
}
2685

    
2686
static void gen_neon_dup_u8(TCGv var, int shift)
2687
{
2688
    TCGv tmp = new_tmp();
2689
    if (shift)
2690
        tcg_gen_shri_i32(var, var, shift);
2691
    tcg_gen_ext8u_i32(var, var);
2692
    tcg_gen_shli_i32(tmp, var, 8);
2693
    tcg_gen_or_i32(var, var, tmp);
2694
    tcg_gen_shli_i32(tmp, var, 16);
2695
    tcg_gen_or_i32(var, var, tmp);
2696
    dead_tmp(tmp);
2697
}
2698

    
2699
static void gen_neon_dup_low16(TCGv var)
2700
{
2701
    TCGv tmp = new_tmp();
2702
    tcg_gen_ext16u_i32(var, var);
2703
    tcg_gen_shli_i32(tmp, var, 16);
2704
    tcg_gen_or_i32(var, var, tmp);
2705
    dead_tmp(tmp);
2706
}
2707

    
2708
static void gen_neon_dup_high16(TCGv var)
2709
{
2710
    TCGv tmp = new_tmp();
2711
    tcg_gen_andi_i32(var, var, 0xffff0000);
2712
    tcg_gen_shri_i32(tmp, var, 16);
2713
    tcg_gen_or_i32(var, var, tmp);
2714
    dead_tmp(tmp);
2715
}
2716

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

    
2726
    if (!arm_feature(env, ARM_FEATURE_VFP))
2727
        return 1;
2728

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

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

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

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

    
2942
                if (op == 15 && (rn == 15 || rn > 17)) {
2943
                    /* Integer or single precision destination.  */
2944
                    rd = VFP_SREG_D(insn);
2945
                } else {
2946
                    VFP_DREG_D(rd, insn);
2947
                }
2948

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

    
2966
            veclen = env->vfp.vec_len;
2967
            if (op == 15 && rn > 3)
2968
                veclen = 0;
2969

    
2970
            /* Shut up compiler warnings.  */
2971
            delta_m = 0;
2972
            delta_d = 0;
2973
            bank_mask = 0;
2974

    
2975
            if (veclen > 0) {
2976
                if (dp)
2977
                    bank_mask = 0xc;
2978
                else
2979
                    bank_mask = 0x18;
2980

    
2981
                /* Figure out what type of vector operation this is.  */
2982
                if ((rd & bank_mask) == 0) {
2983
                    /* scalar */
2984
                    veclen = 0;
2985
                } else {
2986
                    if (dp)
2987
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2988
                    else
2989
                        delta_d = env->vfp.vec_stride + 1;
2990

    
2991
                    if ((rm & bank_mask) == 0) {
2992
                        /* mixed scalar/vector */
2993
                        delta_m = 0;
2994
                    } else {
2995
                        /* vector */
2996
                        delta_m = delta_d;
2997
                    }
2998
                }
2999
            }
3000

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3516
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3517

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

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

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

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

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

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

    
3597
static inline void
3598
gen_neon_movl_scratch_T0(int scratch)
3599
{
3600
  uint32_t offset;
3601

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

    
3606
static inline void
3607
gen_neon_movl_scratch_T1(int scratch)
3608
{
3609
  uint32_t offset;
3610

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

    
3615
static inline void
3616
gen_neon_movl_T0_scratch(int scratch)
3617
{
3618
  uint32_t offset;
3619

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

    
3624
static inline void
3625
gen_neon_movl_T1_scratch(int scratch)
3626
{
3627
  uint32_t offset;
3628

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4033
static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4034
{
4035
    TCGv tmp;
4036

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

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

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

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

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

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

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

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

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

    
4695
                    gen_neon_widen(cpu_V0, tmp, size, u);
4696

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

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