Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 390efc54

History | View | Annotate | Download (294.7 kB)

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

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

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

    
42
#define ARCH(x) if (!ENABLE_ARCH_##x) goto illegal_op;
43

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

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

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

    
75
/* XXX: move that elsewhere */
76
extern FILE *logfile;
77
extern int loglevel;
78

    
79
static TCGv cpu_env;
80
/* We reuse the same 64-bit temporaries for efficiency.  */
81
static TCGv cpu_V0, cpu_V1, cpu_M0;
82

    
83
/* FIXME:  These should be removed.  */
84
static TCGv cpu_T[2];
85
static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
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_ext8s_i32(tmp1, a);
251
    tcg_gen_ext8s_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
/* FIXME:  Implement this natively.  */
455
static inline void tcg_gen_not_i32(TCGv t0, TCGv t1)
456
{
457
    tcg_gen_xori_i32(t0, t1, ~0);
458
}
459

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
815
/* TODO: This should be removed.  Use gen_bx instead.  */
816
static inline void gen_bx_T0(DisasContext *s)
817
{
818
    TCGv tmp = new_tmp();
819
    tcg_gen_mov_i32(tmp, cpu_T[0]);
820
    gen_bx(s, tmp);
821
}
822

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

    
880
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
881
{
882
    load_reg_var(s, cpu_T[0], reg);
883
}
884

    
885
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
886
{
887
    load_reg_var(s, cpu_T[1], reg);
888
}
889

    
890
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
891
{
892
    load_reg_var(s, cpu_T[2], reg);
893
}
894

    
895
static inline void gen_set_pc_im(uint32_t val)
896
{
897
    TCGv tmp = new_tmp();
898
    tcg_gen_movi_i32(tmp, val);
899
    store_cpu_field(tmp, regs[15]);
900
}
901

    
902
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
903
{
904
    TCGv tmp;
905
    if (reg == 15) {
906
        tmp = new_tmp();
907
        tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
908
    } else {
909
        tmp = cpu_T[t];
910
    }
911
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
912
    if (reg == 15) {
913
        dead_tmp(tmp);
914
        s->is_jmp = DISAS_JUMP;
915
    }
916
}
917

    
918
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
919
{
920
    gen_movl_reg_TN(s, reg, 0);
921
}
922

    
923
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
924
{
925
    gen_movl_reg_TN(s, reg, 1);
926
}
927

    
928
/* Force a TB lookup after an instruction that changes the CPU state.  */
929
static inline void gen_lookup_tb(DisasContext *s)
930
{
931
    gen_op_movl_T0_im(s->pc);
932
    gen_movl_reg_T0(s, 15);
933
    s->is_jmp = DISAS_UPDATE;
934
}
935

    
936
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
937
                                       TCGv var)
938
{
939
    int val, rm, shift, shiftop;
940
    TCGv offset;
941

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

    
964
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
965
                                        int extra, TCGv var)
966
{
967
    int val, rm;
968
    TCGv offset;
969

    
970
    if (insn & (1 << 22)) {
971
        /* immediate */
972
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
973
        if (!(insn & (1 << 23)))
974
            val = -val;
975
        val += extra;
976
        if (val != 0)
977
            tcg_gen_addi_i32(var, var, val);
978
    } else {
979
        /* register */
980
        if (extra)
981
            tcg_gen_addi_i32(var, var, extra);
982
        rm = (insn) & 0xf;
983
        offset = load_reg(s, rm);
984
        if (!(insn & (1 << 23)))
985
            tcg_gen_sub_i32(var, var, offset);
986
        else
987
            tcg_gen_add_i32(var, var, offset);
988
        dead_tmp(offset);
989
    }
990
}
991

    
992
#define VFP_OP2(name)                                                 \
993
static inline void gen_vfp_##name(int dp)                             \
994
{                                                                     \
995
    if (dp)                                                           \
996
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
997
    else                                                              \
998
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
999
}
1000

    
1001
#define VFP_OP1(name)                               \
1002
static inline void gen_vfp_##name(int dp, int arg)  \
1003
{                                                   \
1004
    if (dp)                                         \
1005
        gen_op_vfp_##name##d(arg);                  \
1006
    else                                            \
1007
        gen_op_vfp_##name##s(arg);                  \
1008
}
1009

    
1010
VFP_OP2(add)
1011
VFP_OP2(sub)
1012
VFP_OP2(mul)
1013
VFP_OP2(div)
1014

    
1015
#undef VFP_OP2
1016

    
1017
static inline void gen_vfp_abs(int dp)
1018
{
1019
    if (dp)
1020
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1021
    else
1022
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1023
}
1024

    
1025
static inline void gen_vfp_neg(int dp)
1026
{
1027
    if (dp)
1028
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1029
    else
1030
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1031
}
1032

    
1033
static inline void gen_vfp_sqrt(int dp)
1034
{
1035
    if (dp)
1036
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1037
    else
1038
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1039
}
1040

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

    
1049
static inline void gen_vfp_cmpe(int dp)
1050
{
1051
    if (dp)
1052
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1053
    else
1054
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1055
}
1056

    
1057
static inline void gen_vfp_F1_ld0(int dp)
1058
{
1059
    if (dp)
1060
        tcg_gen_movi_i64(cpu_F1d, 0);
1061
    else
1062
        tcg_gen_movi_i32(cpu_F1s, 0);
1063
}
1064

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

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

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

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

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

    
1105
static inline void gen_vfp_tosiz(int dp)
1106
{
1107
    if (dp)
1108
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1109
    else
1110
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1111
}
1112

    
1113
#define VFP_GEN_FIX(name) \
1114
static inline void gen_vfp_##name(int dp, int shift) \
1115
{ \
1116
    if (dp) \
1117
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1118
    else \
1119
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1120
}
1121
VFP_GEN_FIX(tosh)
1122
VFP_GEN_FIX(tosl)
1123
VFP_GEN_FIX(touh)
1124
VFP_GEN_FIX(toul)
1125
VFP_GEN_FIX(shto)
1126
VFP_GEN_FIX(slto)
1127
VFP_GEN_FIX(uhto)
1128
VFP_GEN_FIX(ulto)
1129
#undef VFP_GEN_FIX
1130

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

    
1139
static inline void gen_vfp_st(DisasContext *s, int dp)
1140
{
1141
    if (dp)
1142
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1143
    else
1144
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1145
}
1146

    
1147
static inline long
1148
vfp_reg_offset (int dp, int reg)
1149
{
1150
    if (dp)
1151
        return offsetof(CPUARMState, vfp.regs[reg]);
1152
    else if (reg & 1) {
1153
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1154
          + offsetof(CPU_DoubleU, l.upper);
1155
    } else {
1156
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1157
          + offsetof(CPU_DoubleU, l.lower);
1158
    }
1159
}
1160

    
1161
/* Return the offset of a 32-bit piece of a NEON register.
1162
   zero is the least significant end of the register.  */
1163
static inline long
1164
neon_reg_offset (int reg, int n)
1165
{
1166
    int sreg;
1167
    sreg = reg * 2 + n;
1168
    return vfp_reg_offset(0, sreg);
1169
}
1170

    
1171
/* FIXME: Remove these.  */
1172
#define neon_T0 cpu_T[0]
1173
#define neon_T1 cpu_T[1]
1174
#define NEON_GET_REG(T, reg, n) \
1175
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1176
#define NEON_SET_REG(T, reg, n) \
1177
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1178

    
1179
static TCGv neon_load_reg(int reg, int pass)
1180
{
1181
    TCGv tmp = new_tmp();
1182
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1183
    return tmp;
1184
}
1185

    
1186
static void neon_store_reg(int reg, int pass, TCGv var)
1187
{
1188
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1189
    dead_tmp(var);
1190
}
1191

    
1192
static inline void neon_load_reg64(TCGv var, int reg)
1193
{
1194
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1195
}
1196

    
1197
static inline void neon_store_reg64(TCGv var, int reg)
1198
{
1199
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1200
}
1201

    
1202
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1203
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1204
#define tcg_gen_st_f32 tcg_gen_st_i32
1205
#define tcg_gen_st_f64 tcg_gen_st_i64
1206

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

    
1215
static inline void gen_mov_F1_vreg(int dp, int reg)
1216
{
1217
    if (dp)
1218
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1219
    else
1220
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1221
}
1222

    
1223
static inline void gen_mov_vreg_F0(int dp, int reg)
1224
{
1225
    if (dp)
1226
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1227
    else
1228
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1229
}
1230

    
1231
#define ARM_CP_RW_BIT        (1 << 20)
1232

    
1233
static inline void iwmmxt_load_reg(TCGv var, int reg)
1234
{
1235
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1236
}
1237

    
1238
static inline void iwmmxt_store_reg(TCGv var, int reg)
1239
{
1240
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1241
}
1242

    
1243
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1244
{
1245
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1246
}
1247

    
1248
static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1249
{
1250
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1251
}
1252

    
1253
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1254
{
1255
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1256
}
1257

    
1258
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1259
{
1260
    iwmmxt_store_reg(cpu_M0, rn);
1261
}
1262

    
1263
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1264
{
1265
    iwmmxt_load_reg(cpu_M0, rn);
1266
}
1267

    
1268
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1269
{
1270
    iwmmxt_load_reg(cpu_V1, rn);
1271
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1272
}
1273

    
1274
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1275
{
1276
    iwmmxt_load_reg(cpu_V1, rn);
1277
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1278
}
1279

    
1280
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1281
{
1282
    iwmmxt_load_reg(cpu_V1, rn);
1283
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1284
}
1285

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

    
1293
#define IWMMXT_OP_ENV(name) \
1294
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1295
{ \
1296
    iwmmxt_load_reg(cpu_V1, rn); \
1297
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1298
}
1299

    
1300
#define IWMMXT_OP_ENV_SIZE(name) \
1301
IWMMXT_OP_ENV(name##b) \
1302
IWMMXT_OP_ENV(name##w) \
1303
IWMMXT_OP_ENV(name##l)
1304

    
1305
#define IWMMXT_OP_ENV1(name) \
1306
static inline void gen_op_iwmmxt_##name##_M0(void) \
1307
{ \
1308
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1309
}
1310

    
1311
IWMMXT_OP(maddsq)
1312
IWMMXT_OP(madduq)
1313
IWMMXT_OP(sadb)
1314
IWMMXT_OP(sadw)
1315
IWMMXT_OP(mulslw)
1316
IWMMXT_OP(mulshw)
1317
IWMMXT_OP(mululw)
1318
IWMMXT_OP(muluhw)
1319
IWMMXT_OP(macsw)
1320
IWMMXT_OP(macuw)
1321

    
1322
IWMMXT_OP_ENV_SIZE(unpackl)
1323
IWMMXT_OP_ENV_SIZE(unpackh)
1324

    
1325
IWMMXT_OP_ENV1(unpacklub)
1326
IWMMXT_OP_ENV1(unpackluw)
1327
IWMMXT_OP_ENV1(unpacklul)
1328
IWMMXT_OP_ENV1(unpackhub)
1329
IWMMXT_OP_ENV1(unpackhuw)
1330
IWMMXT_OP_ENV1(unpackhul)
1331
IWMMXT_OP_ENV1(unpacklsb)
1332
IWMMXT_OP_ENV1(unpacklsw)
1333
IWMMXT_OP_ENV1(unpacklsl)
1334
IWMMXT_OP_ENV1(unpackhsb)
1335
IWMMXT_OP_ENV1(unpackhsw)
1336
IWMMXT_OP_ENV1(unpackhsl)
1337

    
1338
IWMMXT_OP_ENV_SIZE(cmpeq)
1339
IWMMXT_OP_ENV_SIZE(cmpgtu)
1340
IWMMXT_OP_ENV_SIZE(cmpgts)
1341

    
1342
IWMMXT_OP_ENV_SIZE(mins)
1343
IWMMXT_OP_ENV_SIZE(minu)
1344
IWMMXT_OP_ENV_SIZE(maxs)
1345
IWMMXT_OP_ENV_SIZE(maxu)
1346

    
1347
IWMMXT_OP_ENV_SIZE(subn)
1348
IWMMXT_OP_ENV_SIZE(addn)
1349
IWMMXT_OP_ENV_SIZE(subu)
1350
IWMMXT_OP_ENV_SIZE(addu)
1351
IWMMXT_OP_ENV_SIZE(subs)
1352
IWMMXT_OP_ENV_SIZE(adds)
1353

    
1354
IWMMXT_OP_ENV(avgb0)
1355
IWMMXT_OP_ENV(avgb1)
1356
IWMMXT_OP_ENV(avgw0)
1357
IWMMXT_OP_ENV(avgw1)
1358

    
1359
IWMMXT_OP(msadb)
1360

    
1361
IWMMXT_OP_ENV(packuw)
1362
IWMMXT_OP_ENV(packul)
1363
IWMMXT_OP_ENV(packuq)
1364
IWMMXT_OP_ENV(packsw)
1365
IWMMXT_OP_ENV(packsl)
1366
IWMMXT_OP_ENV(packsq)
1367

    
1368
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1369
{
1370
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1371
}
1372

    
1373
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1374
{
1375
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1376
}
1377

    
1378
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1379
{
1380
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1381
}
1382

    
1383
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1384
{
1385
    iwmmxt_load_reg(cpu_V1, rn);
1386
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1387
}
1388

    
1389
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1390
{
1391
    TCGv tmp = tcg_const_i32(shift);
1392
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1393
}
1394

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

    
1402
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1403
{
1404
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1405
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1406
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1407
}
1408

    
1409
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1410
{
1411
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1412
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1413
    if (mask != ~0u)
1414
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1415
}
1416

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

    
1425
static void gen_op_iwmmxt_set_cup(void)
1426
{
1427
    TCGv tmp;
1428
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1429
    tcg_gen_ori_i32(tmp, tmp, 1);
1430
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1431
}
1432

    
1433
static void gen_op_iwmmxt_setpsr_nz(void)
1434
{
1435
    TCGv tmp = new_tmp();
1436
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1437
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1438
}
1439

    
1440
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1441
{
1442
    iwmmxt_load_reg(cpu_V1, rn);
1443
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1444
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1445
}
1446

    
1447

    
1448
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1449
{
1450
    iwmmxt_load_reg(cpu_V0, rn);
1451
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1452
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1453
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1454
}
1455

    
1456
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1457
{
1458
    tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1459
    tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1460
    tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1461
    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1462
    iwmmxt_store_reg(cpu_V0, rn);
1463
}
1464

    
1465
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1466
{
1467
    int rd;
1468
    uint32_t offset;
1469

    
1470
    rd = (insn >> 16) & 0xf;
1471
    gen_movl_T1_reg(s, rd);
1472

    
1473
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1474
    if (insn & (1 << 24)) {
1475
        /* Pre indexed */
1476
        if (insn & (1 << 23))
1477
            gen_op_addl_T1_im(offset);
1478
        else
1479
            gen_op_addl_T1_im(-offset);
1480

    
1481
        if (insn & (1 << 21))
1482
            gen_movl_reg_T1(s, rd);
1483
    } else if (insn & (1 << 21)) {
1484
        /* Post indexed */
1485
        if (insn & (1 << 23))
1486
            gen_op_movl_T0_im(offset);
1487
        else
1488
            gen_op_movl_T0_im(- offset);
1489
        gen_op_addl_T0_T1();
1490
        gen_movl_reg_T0(s, rd);
1491
    } else if (!(insn & (1 << 23)))
1492
        return 1;
1493
    return 0;
1494
}
1495

    
1496
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1497
{
1498
    int rd = (insn >> 0) & 0xf;
1499

    
1500
    if (insn & (1 << 8))
1501
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1502
            return 1;
1503
        else
1504
            gen_op_iwmmxt_movl_T0_wCx(rd);
1505
    else
1506
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1507

    
1508
    gen_op_movl_T1_im(mask);
1509
    gen_op_andl_T0_T1();
1510
    return 0;
1511
}
1512

    
1513
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1514
   (ie. an undefined instruction).  */
1515
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1516
{
1517
    int rd, wrd;
1518
    int rdhi, rdlo, rd0, rd1, i;
1519
    TCGv tmp;
1520

    
1521
    if ((insn & 0x0e000e00) == 0x0c000000) {
1522
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1523
            wrd = insn & 0xf;
1524
            rdlo = (insn >> 12) & 0xf;
1525
            rdhi = (insn >> 16) & 0xf;
1526
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1527
                gen_iwmmxt_movl_T0_T1_wRn(wrd);
1528
                gen_movl_reg_T0(s, rdlo);
1529
                gen_movl_reg_T1(s, rdhi);
1530
            } else {                                        /* TMCRR */
1531
                gen_movl_T0_reg(s, rdlo);
1532
                gen_movl_T1_reg(s, rdhi);
1533
                gen_iwmmxt_movl_wRn_T0_T1(wrd);
1534
                gen_op_iwmmxt_set_mup();
1535
            }
1536
            return 0;
1537
        }
1538

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

    
1601
    if ((insn & 0x0f000000) != 0x0e000000)
1602
        return 1;
1603

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

    
2476
    return 0;
2477
}
2478

    
2479
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2480
   (ie. an undefined instruction).  */
2481
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2482
{
2483
    int acc, rd0, rd1, rdhi, rdlo;
2484

    
2485
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2486
        /* Multiply with Internal Accumulate Format */
2487
        rd0 = (insn >> 12) & 0xf;
2488
        rd1 = insn & 0xf;
2489
        acc = (insn >> 5) & 7;
2490

    
2491
        if (acc != 0)
2492
            return 1;
2493

    
2494
        switch ((insn >> 16) & 0xf) {
2495
        case 0x0:                                        /* MIA */
2496
            gen_movl_T0_reg(s, rd0);
2497
            gen_movl_T1_reg(s, rd1);
2498
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2499
            break;
2500
        case 0x8:                                        /* MIAPH */
2501
            gen_movl_T0_reg(s, rd0);
2502
            gen_movl_T1_reg(s, rd1);
2503
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2504
            break;
2505
        case 0xc:                                        /* MIABB */
2506
        case 0xd:                                        /* MIABT */
2507
        case 0xe:                                        /* MIATB */
2508
        case 0xf:                                        /* MIATT */
2509
            gen_movl_T1_reg(s, rd0);
2510
            if (insn & (1 << 16))
2511
                gen_op_shrl_T1_im(16);
2512
            gen_op_movl_T0_T1();
2513
            gen_movl_T1_reg(s, rd1);
2514
            if (insn & (1 << 17))
2515
                gen_op_shrl_T1_im(16);
2516
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2517
            break;
2518
        default:
2519
            return 1;
2520
        }
2521

    
2522
        gen_op_iwmmxt_movq_wRn_M0(acc);
2523
        return 0;
2524
    }
2525

    
2526
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2527
        /* Internal Accumulator Access Format */
2528
        rdhi = (insn >> 16) & 0xf;
2529
        rdlo = (insn >> 12) & 0xf;
2530
        acc = insn & 7;
2531

    
2532
        if (acc != 0)
2533
            return 1;
2534

    
2535
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2536
            gen_iwmmxt_movl_T0_T1_wRn(acc);
2537
            gen_movl_reg_T0(s, rdlo);
2538
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2539
            gen_op_andl_T0_T1();
2540
            gen_movl_reg_T0(s, rdhi);
2541
        } else {                                        /* MAR */
2542
            gen_movl_T0_reg(s, rdlo);
2543
            gen_movl_T1_reg(s, rdhi);
2544
            gen_iwmmxt_movl_wRn_T0_T1(acc);
2545
        }
2546
        return 0;
2547
    }
2548

    
2549
    return 1;
2550
}
2551

    
2552
/* Disassemble system coprocessor instruction.  Return nonzero if
2553
   instruction is not defined.  */
2554
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2555
{
2556
    TCGv tmp;
2557
    uint32_t rd = (insn >> 12) & 0xf;
2558
    uint32_t cp = (insn >> 8) & 0xf;
2559
    if (IS_USER(s)) {
2560
        return 1;
2561
    }
2562

    
2563
    if (insn & ARM_CP_RW_BIT) {
2564
        if (!env->cp[cp].cp_read)
2565
            return 1;
2566
        gen_set_pc_im(s->pc);
2567
        tmp = new_tmp();
2568
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2569
        store_reg(s, rd, tmp);
2570
    } else {
2571
        if (!env->cp[cp].cp_write)
2572
            return 1;
2573
        gen_set_pc_im(s->pc);
2574
        tmp = load_reg(s, rd);
2575
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2576
    }
2577
    return 0;
2578
}
2579

    
2580
static int cp15_user_ok(uint32_t insn)
2581
{
2582
    int cpn = (insn >> 16) & 0xf;
2583
    int cpm = insn & 0xf;
2584
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2585

    
2586
    if (cpn == 13 && cpm == 0) {
2587
        /* TLS register.  */
2588
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2589
            return 1;
2590
    }
2591
    if (cpn == 7) {
2592
        /* ISB, DSB, DMB.  */
2593
        if ((cpm == 5 && op == 4)
2594
                || (cpm == 10 && (op == 4 || op == 5)))
2595
            return 1;
2596
    }
2597
    return 0;
2598
}
2599

    
2600
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2601
   instruction is not defined.  */
2602
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2603
{
2604
    uint32_t rd;
2605
    TCGv tmp;
2606

    
2607
    /* M profile cores use memory mapped registers instead of cp15.  */
2608
    if (arm_feature(env, ARM_FEATURE_M))
2609
        return 1;
2610

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

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

    
2669
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2670
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2671
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2672
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2673
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2674
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2675

    
2676
/* Move between integer and VFP cores.  */
2677
static TCGv gen_vfp_mrs(void)
2678
{
2679
    TCGv tmp = new_tmp();
2680
    tcg_gen_mov_i32(tmp, cpu_F0s);
2681
    return tmp;
2682
}
2683

    
2684
static void gen_vfp_msr(TCGv tmp)
2685
{
2686
    tcg_gen_mov_i32(cpu_F0s, tmp);
2687
    dead_tmp(tmp);
2688
}
2689

    
2690
static inline int
2691
vfp_enabled(CPUState * env)
2692
{
2693
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2694
}
2695

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

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

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

    
2727
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2728
   (ie. an undefined instruction).  */
2729
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2730
{
2731
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2732
    int dp, veclen;
2733
    TCGv tmp;
2734
    TCGv tmp2;
2735

    
2736
    if (!arm_feature(env, ARM_FEATURE_VFP))
2737
        return 1;
2738

    
2739
    if (!vfp_enabled(env)) {
2740
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2741
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2742
            return 1;
2743
        rn = (insn >> 16) & 0xf;
2744
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2745
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2746
            return 1;
2747
    }
2748
    dp = ((insn & 0xf00) == 0xb00);
2749
    switch ((insn >> 24) & 0xf) {
2750
    case 0xe:
2751
        if (insn & (1 << 4)) {
2752
            /* single register transfer */
2753
            rd = (insn >> 12) & 0xf;
2754
            if (dp) {
2755
                int size;
2756
                int pass;
2757

    
2758
                VFP_DREG_N(rn, insn);
2759
                if (insn & 0xf)
2760
                    return 1;
2761
                if (insn & 0x00c00060
2762
                    && !arm_feature(env, ARM_FEATURE_NEON))
2763
                    return 1;
2764

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

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

    
2952
                if (op == 15 && (rn == 15 || rn > 17)) {
2953
                    /* Integer or single precision destination.  */
2954
                    rd = VFP_SREG_D(insn);
2955
                } else {
2956
                    VFP_DREG_D(rd, insn);
2957
                }
2958

    
2959
                if (op == 15 && (rn == 16 || rn == 17)) {
2960
                    /* Integer source.  */
2961
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2962
                } else {
2963
                    VFP_DREG_M(rm, insn);
2964
                }
2965
            } else {
2966
                rn = VFP_SREG_N(insn);
2967
                if (op == 15 && rn == 15) {
2968
                    /* Double precision destination.  */
2969
                    VFP_DREG_D(rd, insn);
2970
                } else {
2971
                    rd = VFP_SREG_D(insn);
2972
                }
2973
                rm = VFP_SREG_M(insn);
2974
            }
2975

    
2976
            veclen = env->vfp.vec_len;
2977
            if (op == 15 && rn > 3)
2978
                veclen = 0;
2979

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

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

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

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

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

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

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

    
3213
                /* Write back the result.  */
3214
                if (op == 15 && (rn >= 8 && rn <= 11))
3215
                    ; /* Comparison, do nothing.  */
3216
                else if (op == 15 && rn > 17)
3217
                    /* Integer result.  */
3218
                    gen_mov_vreg_F0(0, rd);
3219
                else if (op == 15 && rn == 15)
3220
                    /* conversion */
3221
                    gen_mov_vreg_F0(!dp, rd);
3222
                else
3223
                    gen_mov_vreg_F0(dp, rd);
3224

    
3225
                /* break out of the loop if we have finished  */
3226
                if (veclen == 0)
3227
                    break;
3228

    
3229
                if (op == 15 && delta_m == 0) {
3230
                    /* single source one-many */
3231
                    while (veclen--) {
3232
                        rd = ((rd + delta_d) & (bank_mask - 1))
3233
                             | (rd & bank_mask);
3234
                        gen_mov_vreg_F0(dp, rd);
3235
                    }
3236
                    break;
3237
                }
3238
                /* Setup the next operands.  */
3239
                veclen--;
3240
                rd = ((rd + delta_d) & (bank_mask - 1))
3241
                     | (rd & bank_mask);
3242

    
3243
                if (op == 15) {
3244
                    /* One source operand.  */
3245
                    rm = ((rm + delta_m) & (bank_mask - 1))
3246
                         | (rm & bank_mask);
3247
                    gen_mov_F0_vreg(dp, rm);
3248
                } else {
3249
                    /* Two source operands.  */
3250
                    rn = ((rn + delta_d) & (bank_mask - 1))
3251
                         | (rn & bank_mask);
3252
                    gen_mov_F0_vreg(dp, rn);
3253
                    if (delta_m) {
3254
                        rm = ((rm + delta_m) & (bank_mask - 1))
3255
                             | (rm & bank_mask);
3256
                        gen_mov_F1_vreg(dp, rm);
3257
                    }
3258
                }
3259
            }
3260
        }
3261
        break;
3262
    case 0xc:
3263
    case 0xd:
3264
        if (dp && (insn & 0x03e00000) == 0x00400000) {
3265
            /* two-register transfer */
3266
            rn = (insn >> 16) & 0xf;
3267
            rd = (insn >> 12) & 0xf;
3268
            if (dp) {
3269
                VFP_DREG_M(rm, insn);
3270
            } else {
3271
                rm = VFP_SREG_M(insn);
3272
            }
3273

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

    
3341
                if (insn & (1 << 24)) /* pre-decrement */
3342
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3343

    
3344
                if (dp)
3345
                    offset = 8;
3346
                else
3347
                    offset = 4;
3348
                for (i = 0; i < n; i++) {
3349
                    if (insn & ARM_CP_RW_BIT) {
3350
                        /* load */
3351
                        gen_vfp_ld(s, dp);
3352
                        gen_mov_vreg_F0(dp, rd + i);
3353
                    } else {
3354
                        /* store */
3355
                        gen_mov_F0_vreg(dp, rd + i);
3356
                        gen_vfp_st(s, dp);
3357
                    }
3358
                    gen_op_addl_T1_im(offset);
3359
                }
3360
                if (insn & (1 << 21)) {
3361
                    /* writeback */
3362
                    if (insn & (1 << 24))
3363
                        offset = -offset * n;
3364
                    else if (dp && (insn & 1))
3365
                        offset = 4;
3366
                    else
3367
                        offset = 0;
3368

    
3369
                    if (offset != 0)
3370
                        gen_op_addl_T1_im(offset);
3371
                    gen_movl_reg_T1(s, rn);
3372
                }
3373
            }
3374
        }
3375
        break;
3376
    default:
3377
        /* Should never happen.  */
3378
        return 1;
3379
    }
3380
    return 0;
3381
}
3382

    
3383
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3384
{
3385
    TranslationBlock *tb;
3386

    
3387
    tb = s->tb;
3388
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3389
        tcg_gen_goto_tb(n);
3390
        gen_set_pc_im(dest);
3391
        tcg_gen_exit_tb((long)tb + n);
3392
    } else {
3393
        gen_set_pc_im(dest);
3394
        tcg_gen_exit_tb(0);
3395
    }
3396
}
3397

    
3398
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3399
{
3400
    if (__builtin_expect(s->singlestep_enabled, 0)) {
3401
        /* An indirect jump so that we still trigger the debug exception.  */
3402
        if (s->thumb)
3403
            dest |= 1;
3404
        gen_bx_im(s, dest);
3405
    } else {
3406
        gen_goto_tb(s, 0, dest);
3407
        s->is_jmp = DISAS_TB_JUMP;
3408
    }
3409
}
3410

    
3411
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3412
{
3413
    if (x)
3414
        tcg_gen_sari_i32(t0, t0, 16);
3415
    else
3416
        gen_sxth(t0);
3417
    if (y)
3418
        tcg_gen_sari_i32(t1, t1, 16);
3419
    else
3420
        gen_sxth(t1);
3421
    tcg_gen_mul_i32(t0, t0, t1);
3422
}
3423

    
3424
/* Return the mask of PSR bits set by a MSR instruction.  */
3425
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3426
    uint32_t mask;
3427

    
3428
    mask = 0;
3429
    if (flags & (1 << 0))
3430
        mask |= 0xff;
3431
    if (flags & (1 << 1))
3432
        mask |= 0xff00;
3433
    if (flags & (1 << 2))
3434
        mask |= 0xff0000;
3435
    if (flags & (1 << 3))
3436
        mask |= 0xff000000;
3437

    
3438
    /* Mask out undefined bits.  */
3439
    mask &= ~CPSR_RESERVED;
3440
    if (!arm_feature(env, ARM_FEATURE_V6))
3441
        mask &= ~(CPSR_E | CPSR_GE);
3442
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3443
        mask &= ~CPSR_IT;
3444
    /* Mask out execution state bits.  */
3445
    if (!spsr)
3446
        mask &= ~CPSR_EXEC;
3447
    /* Mask out privileged bits.  */
3448
    if (IS_USER(s))
3449
        mask &= CPSR_USER;
3450
    return mask;
3451
}
3452

    
3453
/* Returns nonzero if access to the PSR is not permitted.  */
3454
static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3455
{
3456
    TCGv tmp;
3457
    if (spsr) {
3458
        /* ??? This is also undefined in system mode.  */
3459
        if (IS_USER(s))
3460
            return 1;
3461

    
3462
        tmp = load_cpu_field(spsr);
3463
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3464
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3465
        tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3466
        store_cpu_field(tmp, spsr);
3467
    } else {
3468
        gen_set_cpsr(cpu_T[0], mask);
3469
    }
3470
    gen_lookup_tb(s);
3471
    return 0;
3472
}
3473

    
3474
/* Generate an old-style exception return.  */
3475
static void gen_exception_return(DisasContext *s)
3476
{
3477
    TCGv tmp;
3478
    gen_movl_reg_T0(s, 15);
3479
    tmp = load_cpu_field(spsr);
3480
    gen_set_cpsr(tmp, 0xffffffff);
3481
    dead_tmp(tmp);
3482
    s->is_jmp = DISAS_UPDATE;
3483
}
3484

    
3485
/* Generate a v6 exception return.  Marks both values as dead.  */
3486
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3487
{
3488
    gen_set_cpsr(cpsr, 0xffffffff);
3489
    dead_tmp(cpsr);
3490
    store_reg(s, 15, pc);
3491
    s->is_jmp = DISAS_UPDATE;
3492
}
3493

    
3494
static inline void
3495
gen_set_condexec (DisasContext *s)
3496
{
3497
    if (s->condexec_mask) {
3498
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3499
        TCGv tmp = new_tmp();
3500
        tcg_gen_movi_i32(tmp, val);
3501
        store_cpu_field(tmp, condexec_bits);
3502
    }
3503
}
3504

    
3505
static void gen_nop_hint(DisasContext *s, int val)
3506
{
3507
    switch (val) {
3508
    case 3: /* wfi */
3509
        gen_set_pc_im(s->pc);
3510
        s->is_jmp = DISAS_WFI;
3511
        break;
3512
    case 2: /* wfe */
3513
    case 4: /* sev */
3514
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3515
    default: /* nop */
3516
        break;
3517
    }
3518
}
3519

    
3520
/* These macros help make the code more readable when migrating from the
3521
   old dyngen helpers.  They should probably be removed when
3522
   T0/T1 are removed.  */
3523
#define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3524
#define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3525

    
3526
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3527

    
3528
static inline int gen_neon_add(int size)
3529
{
3530
    switch (size) {
3531
    case 0: gen_helper_neon_add_u8(CPU_T001); break;
3532
    case 1: gen_helper_neon_add_u16(CPU_T001); break;
3533
    case 2: gen_op_addl_T0_T1(); break;
3534
    default: return 1;
3535
    }
3536
    return 0;
3537
}
3538

    
3539
static inline void gen_neon_rsb(int size)
3540
{
3541
    switch (size) {
3542
    case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3543
    case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3544
    case 2: gen_op_rsbl_T0_T1(); break;
3545
    default: return;
3546
    }
3547
}
3548

    
3549
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3550
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3551
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3552
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3553
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3554

    
3555
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3556
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3557
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3558
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3559
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3560

    
3561
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3562
    switch ((size << 1) | u) { \
3563
    case 0: \
3564
        gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3565
        break; \
3566
    case 1: \
3567
        gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3568
        break; \
3569
    case 2: \
3570
        gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3571
        break; \
3572
    case 3: \
3573
        gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3574
        break; \
3575
    case 4: \
3576
        gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3577
        break; \
3578
    case 5: \
3579
        gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3580
        break; \
3581
    default: return 1; \
3582
    }} while (0)
3583

    
3584
#define GEN_NEON_INTEGER_OP(name) do { \
3585
    switch ((size << 1) | u) { \
3586
    case 0: \
3587
        gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3588
        break; \
3589
    case 1: \
3590
        gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3591
        break; \
3592
    case 2: \
3593
        gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3594
        break; \
3595
    case 3: \
3596
        gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3597
        break; \
3598
    case 4: \
3599
        gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3600
        break; \
3601
    case 5: \
3602
        gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3603
        break; \
3604
    default: return 1; \
3605
    }} while (0)
3606

    
3607
static inline void
3608
gen_neon_movl_scratch_T0(int scratch)
3609
{
3610
  uint32_t offset;
3611

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

    
3616
static inline void
3617
gen_neon_movl_scratch_T1(int scratch)
3618
{
3619
  uint32_t offset;
3620

    
3621
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3622
  tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3623
}
3624

    
3625
static inline void
3626
gen_neon_movl_T0_scratch(int scratch)
3627
{
3628
  uint32_t offset;
3629

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

    
3634
static inline void
3635
gen_neon_movl_T1_scratch(int scratch)
3636
{
3637
  uint32_t offset;
3638

    
3639
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3640
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3641
}
3642

    
3643
static inline void gen_neon_get_scalar(int size, int reg)
3644
{
3645
    if (size == 1) {
3646
        NEON_GET_REG(T0, reg >> 1, reg & 1);
3647
    } else {
3648
        NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3649
        if (reg & 1)
3650
            gen_neon_dup_low16(cpu_T[0]);
3651
        else
3652
            gen_neon_dup_high16(cpu_T[0]);
3653
    }
3654
}
3655

    
3656
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3657
{
3658
    int n;
3659

    
3660
    for (n = 0; n < q + 1; n += 2) {
3661
        NEON_GET_REG(T0, reg, n);
3662
        NEON_GET_REG(T0, reg, n + n);
3663
        switch (size) {
3664
        case 0: gen_helper_neon_unzip_u8(); break;
3665
        case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same.  */
3666
        case 2: /* no-op */; break;
3667
        default: abort();
3668
        }
3669
        gen_neon_movl_scratch_T0(tmp + n);
3670
        gen_neon_movl_scratch_T1(tmp + n + 1);
3671
    }
3672
}
3673

    
3674
static struct {
3675
    int nregs;
3676
    int interleave;
3677
    int spacing;
3678
} neon_ls_element_type[11] = {
3679
    {4, 4, 1},
3680
    {4, 4, 2},
3681
    {4, 1, 1},
3682
    {4, 2, 1},
3683
    {3, 3, 1},
3684
    {3, 3, 2},
3685
    {3, 1, 1},
3686
    {1, 1, 1},
3687
    {2, 2, 1},
3688
    {2, 2, 2},
3689
    {2, 1, 1}
3690
};
3691

    
3692
/* Translate a NEON load/store element instruction.  Return nonzero if the
3693
   instruction is invalid.  */
3694
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3695
{
3696
    int rd, rn, rm;
3697
    int op;
3698
    int nregs;
3699
    int interleave;
3700
    int stride;
3701
    int size;
3702
    int reg;
3703
    int pass;
3704
    int load;
3705
    int shift;
3706
    int n;
3707
    TCGv tmp;
3708
    TCGv tmp2;
3709

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

    
3893
        base = load_reg(s, rn);
3894
        if (rm == 13) {
3895
            tcg_gen_addi_i32(base, base, stride);
3896
        } else {
3897
            TCGv index;
3898
            index = load_reg(s, rm);
3899
            tcg_gen_add_i32(base, base, index);
3900
            dead_tmp(index);
3901
        }
3902
        store_reg(s, rn, base);
3903
    }
3904
    return 0;
3905
}
3906

    
3907
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3908
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3909
{
3910
    tcg_gen_and_i32(t, t, c);
3911
    tcg_gen_bic_i32(f, f, c);
3912
    tcg_gen_or_i32(dest, t, f);
3913
}
3914

    
3915
static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
3916
{
3917
    switch (size) {
3918
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
3919
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
3920
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3921
    default: abort();
3922
    }
3923
}
3924

    
3925
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
3926
{
3927
    switch (size) {
3928
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3929
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3930
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3931
    default: abort();
3932
    }
3933
}
3934

    
3935
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
3936
{
3937
    switch (size) {
3938
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3939
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3940
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3941
    default: abort();
3942
    }
3943
}
3944

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

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

    
3999
static inline void gen_neon_addl(int size)
4000
{
4001
    switch (size) {
4002
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4003
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4004
    case 2: tcg_gen_add_i64(CPU_V001); break;
4005
    default: abort();
4006
    }
4007
}
4008

    
4009
static inline void gen_neon_subl(int size)
4010
{
4011
    switch (size) {
4012
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4013
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4014
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4015
    default: abort();
4016
    }
4017
}
4018

    
4019
static inline void gen_neon_negl(TCGv var, int size)
4020
{
4021
    switch (size) {
4022
    case 0: gen_helper_neon_negl_u16(var, var); break;
4023
    case 1: gen_helper_neon_negl_u32(var, var); break;
4024
    case 2: gen_helper_neon_negl_u64(var, var); break;
4025
    default: abort();
4026
    }
4027
}
4028

    
4029
static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4030
{
4031
    switch (size) {
4032
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4033
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4034
    default: abort();
4035
    }
4036
}
4037

    
4038
static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4039
{
4040
    TCGv tmp;
4041

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

    
4063
/* Translate a NEON data processing instruction.  Return nonzero if the
4064
   instruction is invalid.
4065
   We process data in a mixture of 32-bit and 64-bit chunks.
4066
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4067

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

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

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

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

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

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

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

    
4703
                    gen_neon_widen(cpu_V0, tmp, size, u);
4704

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

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