Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 3a554c0f

History | View | Annotate | Download (303.4 kB)

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

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

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

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

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

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

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

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

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

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

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

    
88
static const char *regnames[] =
89
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
90
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
91

    
92
/* initialize TCG globals.  */
93
void arm_translate_init(void)
94
{
95
    int i;
96

    
97
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
98

    
99
    cpu_T[0] = tcg_global_reg_new_i32(TCG_AREG1, "T0");
100
    cpu_T[1] = tcg_global_reg_new_i32(TCG_AREG2, "T1");
101

    
102
    for (i = 0; i < 16; i++) {
103
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
104
                                          offsetof(CPUState, regs[i]),
105
                                          regnames[i]);
106
    }
107

    
108
#define GEN_HELPER 2
109
#include "helpers.h"
110
}
111

    
112
static int num_temps;
113

    
114
/* Allocate a temporary variable.  */
115
static TCGv_i32 new_tmp(void)
116
{
117
    num_temps++;
118
    return tcg_temp_new_i32();
119
}
120

    
121
/* Release a temporary variable.  */
122
static void dead_tmp(TCGv tmp)
123
{
124
    tcg_temp_free(tmp);
125
    num_temps--;
126
}
127

    
128
static inline TCGv load_cpu_offset(int offset)
129
{
130
    TCGv tmp = new_tmp();
131
    tcg_gen_ld_i32(tmp, cpu_env, offset);
132
    return tmp;
133
}
134

    
135
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
136

    
137
static inline void store_cpu_offset(TCGv var, int offset)
138
{
139
    tcg_gen_st_i32(var, cpu_env, offset);
140
    dead_tmp(var);
141
}
142

    
143
#define store_cpu_field(var, name) \
144
    store_cpu_offset(var, offsetof(CPUState, name))
145

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

    
162
/* Create a new temporary and set it to the value of a CPU register.  */
163
static inline TCGv load_reg(DisasContext *s, int reg)
164
{
165
    TCGv tmp = new_tmp();
166
    load_reg_var(s, tmp, reg);
167
    return tmp;
168
}
169

    
170
/* Set a CPU register.  The source must be a temporary and will be
171
   marked as dead.  */
172
static void store_reg(DisasContext *s, int reg, TCGv var)
173
{
174
    if (reg == 15) {
175
        tcg_gen_andi_i32(var, var, ~1);
176
        s->is_jmp = DISAS_JUMP;
177
    }
178
    tcg_gen_mov_i32(cpu_R[reg], var);
179
    dead_tmp(var);
180
}
181

    
182

    
183
/* Basic operations.  */
184
#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
185
#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
186
#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
187

    
188
#define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
189
#define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
190

    
191
#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
192
#define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
193
#define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
194

    
195
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
196
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
197

    
198
/* Value extensions.  */
199
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
200
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
201
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
202
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
203

    
204
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
205
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
206

    
207

    
208
#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
209
/* Set NZCV flags from the high 4 bits of var.  */
210
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
211

    
212
static void gen_exception(int excp)
213
{
214
    TCGv tmp = new_tmp();
215
    tcg_gen_movi_i32(tmp, excp);
216
    gen_helper_exception(tmp);
217
    dead_tmp(tmp);
218
}
219

    
220
static void gen_smul_dual(TCGv a, TCGv b)
221
{
222
    TCGv tmp1 = new_tmp();
223
    TCGv tmp2 = new_tmp();
224
    tcg_gen_ext16s_i32(tmp1, a);
225
    tcg_gen_ext16s_i32(tmp2, b);
226
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
227
    dead_tmp(tmp2);
228
    tcg_gen_sari_i32(a, a, 16);
229
    tcg_gen_sari_i32(b, b, 16);
230
    tcg_gen_mul_i32(b, b, a);
231
    tcg_gen_mov_i32(a, tmp1);
232
    dead_tmp(tmp1);
233
}
234

    
235
/* Byteswap each halfword.  */
236
static void gen_rev16(TCGv var)
237
{
238
    TCGv tmp = new_tmp();
239
    tcg_gen_shri_i32(tmp, var, 8);
240
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
241
    tcg_gen_shli_i32(var, var, 8);
242
    tcg_gen_andi_i32(var, var, 0xff00ff00);
243
    tcg_gen_or_i32(var, var, tmp);
244
    dead_tmp(tmp);
245
}
246

    
247
/* Byteswap low halfword and sign extend.  */
248
static void gen_revsh(TCGv var)
249
{
250
    TCGv tmp = new_tmp();
251
    tcg_gen_shri_i32(tmp, var, 8);
252
    tcg_gen_andi_i32(tmp, tmp, 0x00ff);
253
    tcg_gen_shli_i32(var, var, 8);
254
    tcg_gen_ext8s_i32(var, var);
255
    tcg_gen_or_i32(var, var, tmp);
256
    dead_tmp(tmp);
257
}
258

    
259
/* Unsigned bitfield extract.  */
260
static void gen_ubfx(TCGv var, int shift, uint32_t mask)
261
{
262
    if (shift)
263
        tcg_gen_shri_i32(var, var, shift);
264
    tcg_gen_andi_i32(var, var, mask);
265
}
266

    
267
/* Signed bitfield extract.  */
268
static void gen_sbfx(TCGv var, int shift, int width)
269
{
270
    uint32_t signbit;
271

    
272
    if (shift)
273
        tcg_gen_sari_i32(var, var, shift);
274
    if (shift + width < 32) {
275
        signbit = 1u << (width - 1);
276
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
277
        tcg_gen_xori_i32(var, var, signbit);
278
        tcg_gen_subi_i32(var, var, signbit);
279
    }
280
}
281

    
282
/* Bitfield insertion.  Insert val into base.  Clobbers base and val.  */
283
static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
284
{
285
    tcg_gen_andi_i32(val, val, mask);
286
    tcg_gen_shli_i32(val, val, shift);
287
    tcg_gen_andi_i32(base, base, ~(mask << shift));
288
    tcg_gen_or_i32(dest, base, val);
289
}
290

    
291
/* Round the top 32 bits of a 64-bit value.  */
292
static void gen_roundqd(TCGv a, TCGv b)
293
{
294
    tcg_gen_shri_i32(a, a, 31);
295
    tcg_gen_add_i32(a, a, b);
296
}
297

    
298
/* FIXME: Most targets have native widening multiplication.
299
   It would be good to use that instead of a full wide multiply.  */
300
/* 32x32->64 multiply.  Marks inputs as dead.  */
301
static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
302
{
303
    TCGv_i64 tmp1 = tcg_temp_new_i64();
304
    TCGv_i64 tmp2 = tcg_temp_new_i64();
305

    
306
    tcg_gen_extu_i32_i64(tmp1, a);
307
    dead_tmp(a);
308
    tcg_gen_extu_i32_i64(tmp2, b);
309
    dead_tmp(b);
310
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
311
    return tmp1;
312
}
313

    
314
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
315
{
316
    TCGv_i64 tmp1 = tcg_temp_new_i64();
317
    TCGv_i64 tmp2 = tcg_temp_new_i64();
318

    
319
    tcg_gen_ext_i32_i64(tmp1, a);
320
    dead_tmp(a);
321
    tcg_gen_ext_i32_i64(tmp2, b);
322
    dead_tmp(b);
323
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
324
    return tmp1;
325
}
326

    
327
/* Unsigned 32x32->64 multiply.  */
328
static void gen_mull(TCGv a, TCGv b)
329
{
330
    TCGv_i64 tmp1 = tcg_temp_new_i64();
331
    TCGv_i64 tmp2 = tcg_temp_new_i64();
332

    
333
    tcg_gen_extu_i32_i64(tmp1, a);
334
    tcg_gen_extu_i32_i64(tmp2, b);
335
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
336
    tcg_gen_trunc_i64_i32(a, tmp1);
337
    tcg_gen_shri_i64(tmp1, tmp1, 32);
338
    tcg_gen_trunc_i64_i32(b, tmp1);
339
}
340

    
341
/* Signed 32x32->64 multiply.  */
342
static void gen_imull(TCGv a, TCGv b)
343
{
344
    TCGv_i64 tmp1 = tcg_temp_new_i64();
345
    TCGv_i64 tmp2 = tcg_temp_new_i64();
346

    
347
    tcg_gen_ext_i32_i64(tmp1, a);
348
    tcg_gen_ext_i32_i64(tmp2, b);
349
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
350
    tcg_gen_trunc_i64_i32(a, tmp1);
351
    tcg_gen_shri_i64(tmp1, tmp1, 32);
352
    tcg_gen_trunc_i64_i32(b, tmp1);
353
}
354

    
355
/* Swap low and high halfwords.  */
356
static void gen_swap_half(TCGv var)
357
{
358
    TCGv tmp = new_tmp();
359
    tcg_gen_shri_i32(tmp, var, 16);
360
    tcg_gen_shli_i32(var, var, 16);
361
    tcg_gen_or_i32(var, var, tmp);
362
    dead_tmp(tmp);
363
}
364

    
365
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
366
    tmp = (t0 ^ t1) & 0x8000;
367
    t0 &= ~0x8000;
368
    t1 &= ~0x8000;
369
    t0 = (t0 + t1) ^ tmp;
370
 */
371

    
372
static void gen_add16(TCGv t0, TCGv t1)
373
{
374
    TCGv tmp = new_tmp();
375
    tcg_gen_xor_i32(tmp, t0, t1);
376
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
377
    tcg_gen_andi_i32(t0, t0, ~0x8000);
378
    tcg_gen_andi_i32(t1, t1, ~0x8000);
379
    tcg_gen_add_i32(t0, t0, t1);
380
    tcg_gen_xor_i32(t0, t0, tmp);
381
    dead_tmp(tmp);
382
    dead_tmp(t1);
383
}
384

    
385
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
386

    
387
/* Set CF to the top bit of var.  */
388
static void gen_set_CF_bit31(TCGv var)
389
{
390
    TCGv tmp = new_tmp();
391
    tcg_gen_shri_i32(tmp, var, 31);
392
    gen_set_CF(tmp);
393
    dead_tmp(tmp);
394
}
395

    
396
/* Set N and Z flags from var.  */
397
static inline void gen_logic_CC(TCGv var)
398
{
399
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
400
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
401
}
402

    
403
/* T0 += T1 + CF.  */
404
static void gen_adc(TCGv t0, TCGv t1)
405
{
406
    TCGv tmp;
407
    tcg_gen_add_i32(t0, t0, t1);
408
    tmp = load_cpu_field(CF);
409
    tcg_gen_add_i32(t0, t0, tmp);
410
    dead_tmp(tmp);
411
}
412

    
413
/* dest = T0 + T1 + CF. */
414
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
415
{
416
    TCGv tmp;
417
    tcg_gen_add_i32(dest, t0, t1);
418
    tmp = load_cpu_field(CF);
419
    tcg_gen_add_i32(dest, dest, tmp);
420
    dead_tmp(tmp);
421
}
422

    
423
/* dest = T0 - T1 + CF - 1.  */
424
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
425
{
426
    TCGv tmp;
427
    tcg_gen_sub_i32(dest, t0, t1);
428
    tmp = load_cpu_field(CF);
429
    tcg_gen_add_i32(dest, dest, tmp);
430
    tcg_gen_subi_i32(dest, dest, 1);
431
    dead_tmp(tmp);
432
}
433

    
434
/* T0 &= ~T1.  Clobbers T1.  */
435
/* FIXME: Implement bic natively.  */
436
static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
437
{
438
    TCGv tmp = new_tmp();
439
    tcg_gen_not_i32(tmp, t1);
440
    tcg_gen_and_i32(dest, t0, tmp);
441
    dead_tmp(tmp);
442
}
443
static inline void gen_op_bicl_T0_T1(void)
444
{
445
    gen_op_notl_T1();
446
    gen_op_andl_T0_T1();
447
}
448

    
449
/* FIXME:  Implement this natively.  */
450
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
451

    
452
/* FIXME:  Implement this natively.  */
453
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
454
{
455
    TCGv tmp;
456

    
457
    if (i == 0)
458
        return;
459

    
460
    tmp = new_tmp();
461
    tcg_gen_shri_i32(tmp, t1, i);
462
    tcg_gen_shli_i32(t1, t1, 32 - i);
463
    tcg_gen_or_i32(t0, t1, tmp);
464
    dead_tmp(tmp);
465
}
466

    
467
static void shifter_out_im(TCGv var, int shift)
468
{
469
    TCGv tmp = new_tmp();
470
    if (shift == 0) {
471
        tcg_gen_andi_i32(tmp, var, 1);
472
    } else {
473
        tcg_gen_shri_i32(tmp, var, shift);
474
        if (shift != 31)
475
            tcg_gen_andi_i32(tmp, tmp, 1);
476
    }
477
    gen_set_CF(tmp);
478
    dead_tmp(tmp);
479
}
480

    
481
/* Shift by immediate.  Includes special handling for shift == 0.  */
482
static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
483
{
484
    switch (shiftop) {
485
    case 0: /* LSL */
486
        if (shift != 0) {
487
            if (flags)
488
                shifter_out_im(var, 32 - shift);
489
            tcg_gen_shli_i32(var, var, shift);
490
        }
491
        break;
492
    case 1: /* LSR */
493
        if (shift == 0) {
494
            if (flags) {
495
                tcg_gen_shri_i32(var, var, 31);
496
                gen_set_CF(var);
497
            }
498
            tcg_gen_movi_i32(var, 0);
499
        } else {
500
            if (flags)
501
                shifter_out_im(var, shift - 1);
502
            tcg_gen_shri_i32(var, var, shift);
503
        }
504
        break;
505
    case 2: /* ASR */
506
        if (shift == 0)
507
            shift = 32;
508
        if (flags)
509
            shifter_out_im(var, shift - 1);
510
        if (shift == 32)
511
          shift = 31;
512
        tcg_gen_sari_i32(var, var, shift);
513
        break;
514
    case 3: /* ROR/RRX */
515
        if (shift != 0) {
516
            if (flags)
517
                shifter_out_im(var, shift - 1);
518
            tcg_gen_rori_i32(var, var, shift); break;
519
        } else {
520
            TCGv tmp = load_cpu_field(CF);
521
            if (flags)
522
                shifter_out_im(var, 0);
523
            tcg_gen_shri_i32(var, var, 1);
524
            tcg_gen_shli_i32(tmp, tmp, 31);
525
            tcg_gen_or_i32(var, var, tmp);
526
            dead_tmp(tmp);
527
        }
528
    }
529
};
530

    
531
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
532
                                     TCGv shift, int flags)
533
{
534
    if (flags) {
535
        switch (shiftop) {
536
        case 0: gen_helper_shl_cc(var, var, shift); break;
537
        case 1: gen_helper_shr_cc(var, var, shift); break;
538
        case 2: gen_helper_sar_cc(var, var, shift); break;
539
        case 3: gen_helper_ror_cc(var, var, shift); break;
540
        }
541
    } else {
542
        switch (shiftop) {
543
        case 0: gen_helper_shl(var, var, shift); break;
544
        case 1: gen_helper_shr(var, var, shift); break;
545
        case 2: gen_helper_sar(var, var, shift); break;
546
        case 3: gen_helper_ror(var, var, shift); break;
547
        }
548
    }
549
    dead_tmp(shift);
550
}
551

    
552
#define PAS_OP(pfx) \
553
    switch (op2) {  \
554
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
555
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
556
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
557
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
558
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
559
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
560
    }
561
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
562
{
563
    TCGv_ptr tmp;
564

    
565
    switch (op1) {
566
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
567
    case 1:
568
        tmp = tcg_temp_new_ptr();
569
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
570
        PAS_OP(s)
571
        break;
572
    case 5:
573
        tmp = tcg_temp_new_ptr();
574
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
575
        PAS_OP(u)
576
        break;
577
#undef gen_pas_helper
578
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
579
    case 2:
580
        PAS_OP(q);
581
        break;
582
    case 3:
583
        PAS_OP(sh);
584
        break;
585
    case 6:
586
        PAS_OP(uq);
587
        break;
588
    case 7:
589
        PAS_OP(uh);
590
        break;
591
#undef gen_pas_helper
592
    }
593
}
594
#undef PAS_OP
595

    
596
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
597
#define PAS_OP(pfx) \
598
    switch (op2) {  \
599
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
600
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
601
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
602
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
603
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
604
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
605
    }
606
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
607
{
608
    TCGv_ptr tmp;
609

    
610
    switch (op1) {
611
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
612
    case 0:
613
        tmp = tcg_temp_new_ptr();
614
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
615
        PAS_OP(s)
616
        break;
617
    case 4:
618
        tmp = tcg_temp_new_ptr();
619
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
620
        PAS_OP(u)
621
        break;
622
#undef gen_pas_helper
623
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
624
    case 1:
625
        PAS_OP(q);
626
        break;
627
    case 2:
628
        PAS_OP(sh);
629
        break;
630
    case 5:
631
        PAS_OP(uq);
632
        break;
633
    case 6:
634
        PAS_OP(uh);
635
        break;
636
#undef gen_pas_helper
637
    }
638
}
639
#undef PAS_OP
640

    
641
static void gen_test_cc(int cc, int label)
642
{
643
    TCGv tmp;
644
    TCGv tmp2;
645
    int inv;
646

    
647
    switch (cc) {
648
    case 0: /* eq: Z */
649
        tmp = load_cpu_field(ZF);
650
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
651
        break;
652
    case 1: /* ne: !Z */
653
        tmp = load_cpu_field(ZF);
654
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
655
        break;
656
    case 2: /* cs: C */
657
        tmp = load_cpu_field(CF);
658
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
659
        break;
660
    case 3: /* cc: !C */
661
        tmp = load_cpu_field(CF);
662
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
663
        break;
664
    case 4: /* mi: N */
665
        tmp = load_cpu_field(NF);
666
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
667
        break;
668
    case 5: /* pl: !N */
669
        tmp = load_cpu_field(NF);
670
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
671
        break;
672
    case 6: /* vs: V */
673
        tmp = load_cpu_field(VF);
674
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
675
        break;
676
    case 7: /* vc: !V */
677
        tmp = load_cpu_field(VF);
678
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
679
        break;
680
    case 8: /* hi: C && !Z */
681
        inv = gen_new_label();
682
        tmp = load_cpu_field(CF);
683
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
684
        dead_tmp(tmp);
685
        tmp = load_cpu_field(ZF);
686
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
687
        gen_set_label(inv);
688
        break;
689
    case 9: /* ls: !C || Z */
690
        tmp = load_cpu_field(CF);
691
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
692
        dead_tmp(tmp);
693
        tmp = load_cpu_field(ZF);
694
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
695
        break;
696
    case 10: /* ge: N == V -> N ^ V == 0 */
697
        tmp = load_cpu_field(VF);
698
        tmp2 = load_cpu_field(NF);
699
        tcg_gen_xor_i32(tmp, tmp, tmp2);
700
        dead_tmp(tmp2);
701
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
702
        break;
703
    case 11: /* lt: N != V -> N ^ V != 0 */
704
        tmp = load_cpu_field(VF);
705
        tmp2 = load_cpu_field(NF);
706
        tcg_gen_xor_i32(tmp, tmp, tmp2);
707
        dead_tmp(tmp2);
708
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
709
        break;
710
    case 12: /* gt: !Z && N == V */
711
        inv = gen_new_label();
712
        tmp = load_cpu_field(ZF);
713
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
714
        dead_tmp(tmp);
715
        tmp = load_cpu_field(VF);
716
        tmp2 = load_cpu_field(NF);
717
        tcg_gen_xor_i32(tmp, tmp, tmp2);
718
        dead_tmp(tmp2);
719
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
720
        gen_set_label(inv);
721
        break;
722
    case 13: /* le: Z || N != V */
723
        tmp = load_cpu_field(ZF);
724
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
725
        dead_tmp(tmp);
726
        tmp = load_cpu_field(VF);
727
        tmp2 = load_cpu_field(NF);
728
        tcg_gen_xor_i32(tmp, tmp, tmp2);
729
        dead_tmp(tmp2);
730
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
731
        break;
732
    default:
733
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
734
        abort();
735
    }
736
    dead_tmp(tmp);
737
}
738

    
739
static const uint8_t table_logic_cc[16] = {
740
    1, /* and */
741
    1, /* xor */
742
    0, /* sub */
743
    0, /* rsb */
744
    0, /* add */
745
    0, /* adc */
746
    0, /* sbc */
747
    0, /* rsc */
748
    1, /* andl */
749
    1, /* xorl */
750
    0, /* cmp */
751
    0, /* cmn */
752
    1, /* orr */
753
    1, /* mov */
754
    1, /* bic */
755
    1, /* mvn */
756
};
757

    
758
/* Set PC and Thumb state from an immediate address.  */
759
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
760
{
761
    TCGv tmp;
762

    
763
    s->is_jmp = DISAS_UPDATE;
764
    if (s->thumb != (addr & 1)) {
765
        tmp = new_tmp();
766
        tcg_gen_movi_i32(tmp, addr & 1);
767
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
768
        dead_tmp(tmp);
769
    }
770
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
771
}
772

    
773
/* Set PC and Thumb state from var.  var is marked as dead.  */
774
static inline void gen_bx(DisasContext *s, TCGv var)
775
{
776
    s->is_jmp = DISAS_UPDATE;
777
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
778
    tcg_gen_andi_i32(var, var, 1);
779
    store_cpu_field(var, thumb);
780
}
781

    
782
/* Variant of store_reg which uses branch&exchange logic when storing
783
   to r15 in ARM architecture v7 and above. The source must be a temporary
784
   and will be marked as dead. */
785
static inline void store_reg_bx(CPUState *env, DisasContext *s,
786
                                int reg, TCGv var)
787
{
788
    if (reg == 15 && ENABLE_ARCH_7) {
789
        gen_bx(s, var);
790
    } else {
791
        store_reg(s, reg, var);
792
    }
793
}
794

    
795
static inline TCGv gen_ld8s(TCGv addr, int index)
796
{
797
    TCGv tmp = new_tmp();
798
    tcg_gen_qemu_ld8s(tmp, addr, index);
799
    return tmp;
800
}
801
static inline TCGv gen_ld8u(TCGv addr, int index)
802
{
803
    TCGv tmp = new_tmp();
804
    tcg_gen_qemu_ld8u(tmp, addr, index);
805
    return tmp;
806
}
807
static inline TCGv gen_ld16s(TCGv addr, int index)
808
{
809
    TCGv tmp = new_tmp();
810
    tcg_gen_qemu_ld16s(tmp, addr, index);
811
    return tmp;
812
}
813
static inline TCGv gen_ld16u(TCGv addr, int index)
814
{
815
    TCGv tmp = new_tmp();
816
    tcg_gen_qemu_ld16u(tmp, addr, index);
817
    return tmp;
818
}
819
static inline TCGv gen_ld32(TCGv addr, int index)
820
{
821
    TCGv tmp = new_tmp();
822
    tcg_gen_qemu_ld32u(tmp, addr, index);
823
    return tmp;
824
}
825
static inline void gen_st8(TCGv val, TCGv addr, int index)
826
{
827
    tcg_gen_qemu_st8(val, addr, index);
828
    dead_tmp(val);
829
}
830
static inline void gen_st16(TCGv val, TCGv addr, int index)
831
{
832
    tcg_gen_qemu_st16(val, addr, index);
833
    dead_tmp(val);
834
}
835
static inline void gen_st32(TCGv val, TCGv addr, int index)
836
{
837
    tcg_gen_qemu_st32(val, addr, index);
838
    dead_tmp(val);
839
}
840

    
841
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
842
{
843
    load_reg_var(s, cpu_T[0], reg);
844
}
845

    
846
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
847
{
848
    load_reg_var(s, cpu_T[1], reg);
849
}
850

    
851
static inline void gen_set_pc_im(uint32_t val)
852
{
853
    tcg_gen_movi_i32(cpu_R[15], val);
854
}
855

    
856
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
857
{
858
    TCGv tmp;
859
    if (reg == 15) {
860
        tmp = new_tmp();
861
        tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
862
    } else {
863
        tmp = cpu_T[t];
864
    }
865
    tcg_gen_mov_i32(cpu_R[reg], tmp);
866
    if (reg == 15) {
867
        dead_tmp(tmp);
868
        s->is_jmp = DISAS_JUMP;
869
    }
870
}
871

    
872
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
873
{
874
    gen_movl_reg_TN(s, reg, 0);
875
}
876

    
877
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
878
{
879
    gen_movl_reg_TN(s, reg, 1);
880
}
881

    
882
/* Force a TB lookup after an instruction that changes the CPU state.  */
883
static inline void gen_lookup_tb(DisasContext *s)
884
{
885
    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
886
    s->is_jmp = DISAS_UPDATE;
887
}
888

    
889
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
890
                                       TCGv var)
891
{
892
    int val, rm, shift, shiftop;
893
    TCGv offset;
894

    
895
    if (!(insn & (1 << 25))) {
896
        /* immediate */
897
        val = insn & 0xfff;
898
        if (!(insn & (1 << 23)))
899
            val = -val;
900
        if (val != 0)
901
            tcg_gen_addi_i32(var, var, val);
902
    } else {
903
        /* shift/register */
904
        rm = (insn) & 0xf;
905
        shift = (insn >> 7) & 0x1f;
906
        shiftop = (insn >> 5) & 3;
907
        offset = load_reg(s, rm);
908
        gen_arm_shift_im(offset, shiftop, shift, 0);
909
        if (!(insn & (1 << 23)))
910
            tcg_gen_sub_i32(var, var, offset);
911
        else
912
            tcg_gen_add_i32(var, var, offset);
913
        dead_tmp(offset);
914
    }
915
}
916

    
917
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
918
                                        int extra, TCGv var)
919
{
920
    int val, rm;
921
    TCGv offset;
922

    
923
    if (insn & (1 << 22)) {
924
        /* immediate */
925
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
926
        if (!(insn & (1 << 23)))
927
            val = -val;
928
        val += extra;
929
        if (val != 0)
930
            tcg_gen_addi_i32(var, var, val);
931
    } else {
932
        /* register */
933
        if (extra)
934
            tcg_gen_addi_i32(var, var, extra);
935
        rm = (insn) & 0xf;
936
        offset = load_reg(s, rm);
937
        if (!(insn & (1 << 23)))
938
            tcg_gen_sub_i32(var, var, offset);
939
        else
940
            tcg_gen_add_i32(var, var, offset);
941
        dead_tmp(offset);
942
    }
943
}
944

    
945
#define VFP_OP2(name)                                                 \
946
static inline void gen_vfp_##name(int dp)                             \
947
{                                                                     \
948
    if (dp)                                                           \
949
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
950
    else                                                              \
951
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
952
}
953

    
954
VFP_OP2(add)
955
VFP_OP2(sub)
956
VFP_OP2(mul)
957
VFP_OP2(div)
958

    
959
#undef VFP_OP2
960

    
961
static inline void gen_vfp_abs(int dp)
962
{
963
    if (dp)
964
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
965
    else
966
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
967
}
968

    
969
static inline void gen_vfp_neg(int dp)
970
{
971
    if (dp)
972
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
973
    else
974
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
975
}
976

    
977
static inline void gen_vfp_sqrt(int dp)
978
{
979
    if (dp)
980
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
981
    else
982
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
983
}
984

    
985
static inline void gen_vfp_cmp(int dp)
986
{
987
    if (dp)
988
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
989
    else
990
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
991
}
992

    
993
static inline void gen_vfp_cmpe(int dp)
994
{
995
    if (dp)
996
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
997
    else
998
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
999
}
1000

    
1001
static inline void gen_vfp_F1_ld0(int dp)
1002
{
1003
    if (dp)
1004
        tcg_gen_movi_i64(cpu_F1d, 0);
1005
    else
1006
        tcg_gen_movi_i32(cpu_F1s, 0);
1007
}
1008

    
1009
static inline void gen_vfp_uito(int dp)
1010
{
1011
    if (dp)
1012
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1013
    else
1014
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1015
}
1016

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

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

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

    
1041
static inline void gen_vfp_tosi(int dp)
1042
{
1043
    if (dp)
1044
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1045
    else
1046
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1047
}
1048

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

    
1057
#define VFP_GEN_FIX(name) \
1058
static inline void gen_vfp_##name(int dp, int shift) \
1059
{ \
1060
    if (dp) \
1061
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1062
    else \
1063
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1064
}
1065
VFP_GEN_FIX(tosh)
1066
VFP_GEN_FIX(tosl)
1067
VFP_GEN_FIX(touh)
1068
VFP_GEN_FIX(toul)
1069
VFP_GEN_FIX(shto)
1070
VFP_GEN_FIX(slto)
1071
VFP_GEN_FIX(uhto)
1072
VFP_GEN_FIX(ulto)
1073
#undef VFP_GEN_FIX
1074

    
1075
static inline void gen_vfp_ld(DisasContext *s, int dp)
1076
{
1077
    if (dp)
1078
        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1079
    else
1080
        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1081
}
1082

    
1083
static inline void gen_vfp_st(DisasContext *s, int dp)
1084
{
1085
    if (dp)
1086
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1087
    else
1088
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1089
}
1090

    
1091
static inline long
1092
vfp_reg_offset (int dp, int reg)
1093
{
1094
    if (dp)
1095
        return offsetof(CPUARMState, vfp.regs[reg]);
1096
    else if (reg & 1) {
1097
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1098
          + offsetof(CPU_DoubleU, l.upper);
1099
    } else {
1100
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1101
          + offsetof(CPU_DoubleU, l.lower);
1102
    }
1103
}
1104

    
1105
/* Return the offset of a 32-bit piece of a NEON register.
1106
   zero is the least significant end of the register.  */
1107
static inline long
1108
neon_reg_offset (int reg, int n)
1109
{
1110
    int sreg;
1111
    sreg = reg * 2 + n;
1112
    return vfp_reg_offset(0, sreg);
1113
}
1114

    
1115
static TCGv neon_load_reg(int reg, int pass)
1116
{
1117
    TCGv tmp = new_tmp();
1118
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1119
    return tmp;
1120
}
1121

    
1122
static void neon_store_reg(int reg, int pass, TCGv var)
1123
{
1124
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1125
    dead_tmp(var);
1126
}
1127

    
1128
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1129
{
1130
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1131
}
1132

    
1133
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1134
{
1135
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1136
}
1137

    
1138
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1139
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1140
#define tcg_gen_st_f32 tcg_gen_st_i32
1141
#define tcg_gen_st_f64 tcg_gen_st_i64
1142

    
1143
static inline void gen_mov_F0_vreg(int dp, int reg)
1144
{
1145
    if (dp)
1146
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1147
    else
1148
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1149
}
1150

    
1151
static inline void gen_mov_F1_vreg(int dp, int reg)
1152
{
1153
    if (dp)
1154
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1155
    else
1156
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1157
}
1158

    
1159
static inline void gen_mov_vreg_F0(int dp, int reg)
1160
{
1161
    if (dp)
1162
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1163
    else
1164
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1165
}
1166

    
1167
#define ARM_CP_RW_BIT        (1 << 20)
1168

    
1169
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1170
{
1171
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1172
}
1173

    
1174
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1175
{
1176
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1177
}
1178

    
1179
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1180
{
1181
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1182
}
1183

    
1184
static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1185
{
1186
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1187
}
1188

    
1189
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1190
{
1191
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1192
}
1193

    
1194
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1195
{
1196
    iwmmxt_store_reg(cpu_M0, rn);
1197
}
1198

    
1199
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1200
{
1201
    iwmmxt_load_reg(cpu_M0, rn);
1202
}
1203

    
1204
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1205
{
1206
    iwmmxt_load_reg(cpu_V1, rn);
1207
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1208
}
1209

    
1210
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1211
{
1212
    iwmmxt_load_reg(cpu_V1, rn);
1213
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1214
}
1215

    
1216
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1217
{
1218
    iwmmxt_load_reg(cpu_V1, rn);
1219
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1220
}
1221

    
1222
#define IWMMXT_OP(name) \
1223
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1224
{ \
1225
    iwmmxt_load_reg(cpu_V1, rn); \
1226
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1227
}
1228

    
1229
#define IWMMXT_OP_ENV(name) \
1230
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1231
{ \
1232
    iwmmxt_load_reg(cpu_V1, rn); \
1233
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1234
}
1235

    
1236
#define IWMMXT_OP_ENV_SIZE(name) \
1237
IWMMXT_OP_ENV(name##b) \
1238
IWMMXT_OP_ENV(name##w) \
1239
IWMMXT_OP_ENV(name##l)
1240

    
1241
#define IWMMXT_OP_ENV1(name) \
1242
static inline void gen_op_iwmmxt_##name##_M0(void) \
1243
{ \
1244
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1245
}
1246

    
1247
IWMMXT_OP(maddsq)
1248
IWMMXT_OP(madduq)
1249
IWMMXT_OP(sadb)
1250
IWMMXT_OP(sadw)
1251
IWMMXT_OP(mulslw)
1252
IWMMXT_OP(mulshw)
1253
IWMMXT_OP(mululw)
1254
IWMMXT_OP(muluhw)
1255
IWMMXT_OP(macsw)
1256
IWMMXT_OP(macuw)
1257

    
1258
IWMMXT_OP_ENV_SIZE(unpackl)
1259
IWMMXT_OP_ENV_SIZE(unpackh)
1260

    
1261
IWMMXT_OP_ENV1(unpacklub)
1262
IWMMXT_OP_ENV1(unpackluw)
1263
IWMMXT_OP_ENV1(unpacklul)
1264
IWMMXT_OP_ENV1(unpackhub)
1265
IWMMXT_OP_ENV1(unpackhuw)
1266
IWMMXT_OP_ENV1(unpackhul)
1267
IWMMXT_OP_ENV1(unpacklsb)
1268
IWMMXT_OP_ENV1(unpacklsw)
1269
IWMMXT_OP_ENV1(unpacklsl)
1270
IWMMXT_OP_ENV1(unpackhsb)
1271
IWMMXT_OP_ENV1(unpackhsw)
1272
IWMMXT_OP_ENV1(unpackhsl)
1273

    
1274
IWMMXT_OP_ENV_SIZE(cmpeq)
1275
IWMMXT_OP_ENV_SIZE(cmpgtu)
1276
IWMMXT_OP_ENV_SIZE(cmpgts)
1277

    
1278
IWMMXT_OP_ENV_SIZE(mins)
1279
IWMMXT_OP_ENV_SIZE(minu)
1280
IWMMXT_OP_ENV_SIZE(maxs)
1281
IWMMXT_OP_ENV_SIZE(maxu)
1282

    
1283
IWMMXT_OP_ENV_SIZE(subn)
1284
IWMMXT_OP_ENV_SIZE(addn)
1285
IWMMXT_OP_ENV_SIZE(subu)
1286
IWMMXT_OP_ENV_SIZE(addu)
1287
IWMMXT_OP_ENV_SIZE(subs)
1288
IWMMXT_OP_ENV_SIZE(adds)
1289

    
1290
IWMMXT_OP_ENV(avgb0)
1291
IWMMXT_OP_ENV(avgb1)
1292
IWMMXT_OP_ENV(avgw0)
1293
IWMMXT_OP_ENV(avgw1)
1294

    
1295
IWMMXT_OP(msadb)
1296

    
1297
IWMMXT_OP_ENV(packuw)
1298
IWMMXT_OP_ENV(packul)
1299
IWMMXT_OP_ENV(packuq)
1300
IWMMXT_OP_ENV(packsw)
1301
IWMMXT_OP_ENV(packsl)
1302
IWMMXT_OP_ENV(packsq)
1303

    
1304
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1305
{
1306
    iwmmxt_load_reg(cpu_V1, rn);
1307
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1308
}
1309

    
1310
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1311
{
1312
    TCGv tmp = tcg_const_i32(shift);
1313
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1314
}
1315

    
1316
static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1317
{
1318
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1319
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1320
    tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1321
}
1322

    
1323
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1324
{
1325
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1326
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1327
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1328
}
1329

    
1330
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1331
{
1332
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1333
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1334
    if (mask != ~0u)
1335
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1336
}
1337

    
1338
static void gen_op_iwmmxt_set_mup(void)
1339
{
1340
    TCGv tmp;
1341
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1342
    tcg_gen_ori_i32(tmp, tmp, 2);
1343
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1344
}
1345

    
1346
static void gen_op_iwmmxt_set_cup(void)
1347
{
1348
    TCGv tmp;
1349
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1350
    tcg_gen_ori_i32(tmp, tmp, 1);
1351
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1352
}
1353

    
1354
static void gen_op_iwmmxt_setpsr_nz(void)
1355
{
1356
    TCGv tmp = new_tmp();
1357
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1358
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1359
}
1360

    
1361
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1362
{
1363
    iwmmxt_load_reg(cpu_V1, rn);
1364
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1365
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1366
}
1367

    
1368
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1369
{
1370
    iwmmxt_load_reg(cpu_V0, rn);
1371
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1372
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1373
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1374
}
1375

    
1376
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1377
{
1378
    tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
1379
    iwmmxt_store_reg(cpu_V0, rn);
1380
}
1381

    
1382
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1383
{
1384
    int rd;
1385
    uint32_t offset;
1386

    
1387
    rd = (insn >> 16) & 0xf;
1388
    gen_movl_T1_reg(s, rd);
1389

    
1390
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1391
    if (insn & (1 << 24)) {
1392
        /* Pre indexed */
1393
        if (insn & (1 << 23))
1394
            gen_op_addl_T1_im(offset);
1395
        else
1396
            gen_op_addl_T1_im(-offset);
1397

    
1398
        if (insn & (1 << 21))
1399
            gen_movl_reg_T1(s, rd);
1400
    } else if (insn & (1 << 21)) {
1401
        /* Post indexed */
1402
        if (insn & (1 << 23))
1403
            gen_op_movl_T0_im(offset);
1404
        else
1405
            gen_op_movl_T0_im(- offset);
1406
        gen_op_addl_T0_T1();
1407
        gen_movl_reg_T0(s, rd);
1408
    } else if (!(insn & (1 << 23)))
1409
        return 1;
1410
    return 0;
1411
}
1412

    
1413
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1414
{
1415
    int rd = (insn >> 0) & 0xf;
1416

    
1417
    if (insn & (1 << 8))
1418
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1419
            return 1;
1420
        else
1421
            gen_op_iwmmxt_movl_T0_wCx(rd);
1422
    else
1423
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1424

    
1425
    gen_op_movl_T1_im(mask);
1426
    gen_op_andl_T0_T1();
1427
    return 0;
1428
}
1429

    
1430
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1431
   (ie. an undefined instruction).  */
1432
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1433
{
1434
    int rd, wrd;
1435
    int rdhi, rdlo, rd0, rd1, i;
1436
    TCGv tmp;
1437

    
1438
    if ((insn & 0x0e000e00) == 0x0c000000) {
1439
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1440
            wrd = insn & 0xf;
1441
            rdlo = (insn >> 12) & 0xf;
1442
            rdhi = (insn >> 16) & 0xf;
1443
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1444
                gen_iwmmxt_movl_T0_T1_wRn(wrd);
1445
                gen_movl_reg_T0(s, rdlo);
1446
                gen_movl_reg_T1(s, rdhi);
1447
            } else {                                        /* TMCRR */
1448
                gen_movl_T0_reg(s, rdlo);
1449
                gen_movl_T1_reg(s, rdhi);
1450
                gen_iwmmxt_movl_wRn_T0_T1(wrd);
1451
                gen_op_iwmmxt_set_mup();
1452
            }
1453
            return 0;
1454
        }
1455

    
1456
        wrd = (insn >> 12) & 0xf;
1457
        if (gen_iwmmxt_address(s, insn))
1458
            return 1;
1459
        if (insn & ARM_CP_RW_BIT) {
1460
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1461
                tmp = gen_ld32(cpu_T[1], IS_USER(s));
1462
                tcg_gen_mov_i32(cpu_T[0], tmp);
1463
                dead_tmp(tmp);
1464
                gen_op_iwmmxt_movl_wCx_T0(wrd);
1465
            } else {
1466
                i = 1;
1467
                if (insn & (1 << 8)) {
1468
                    if (insn & (1 << 22)) {                /* WLDRD */
1469
                        tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1470
                        i = 0;
1471
                    } else {                                /* WLDRW wRd */
1472
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
1473
                    }
1474
                } else {
1475
                    if (insn & (1 << 22)) {                /* WLDRH */
1476
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1477
                    } else {                                /* WLDRB */
1478
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1479
                    }
1480
                }
1481
                if (i) {
1482
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
1483
                    dead_tmp(tmp);
1484
                }
1485
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1486
            }
1487
        } else {
1488
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1489
                gen_op_iwmmxt_movl_T0_wCx(wrd);
1490
                tmp = new_tmp();
1491
                tcg_gen_mov_i32(tmp, cpu_T[0]);
1492
                gen_st32(tmp, cpu_T[1], IS_USER(s));
1493
            } else {
1494
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1495
                tmp = new_tmp();
1496
                if (insn & (1 << 8)) {
1497
                    if (insn & (1 << 22)) {                /* WSTRD */
1498
                        dead_tmp(tmp);
1499
                        tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1500
                    } else {                                /* WSTRW wRd */
1501
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1502
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
1503
                    }
1504
                } else {
1505
                    if (insn & (1 << 22)) {                /* WSTRH */
1506
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1507
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
1508
                    } else {                                /* WSTRB */
1509
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1510
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
1511
                    }
1512
                }
1513
            }
1514
        }
1515
        return 0;
1516
    }
1517

    
1518
    if ((insn & 0x0f000000) != 0x0e000000)
1519
        return 1;
1520

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

    
2395
    return 0;
2396
}
2397

    
2398
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2399
   (ie. an undefined instruction).  */
2400
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2401
{
2402
    int acc, rd0, rd1, rdhi, rdlo;
2403
    TCGv tmp, tmp2;
2404

    
2405
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2406
        /* Multiply with Internal Accumulate Format */
2407
        rd0 = (insn >> 12) & 0xf;
2408
        rd1 = insn & 0xf;
2409
        acc = (insn >> 5) & 7;
2410

    
2411
        if (acc != 0)
2412
            return 1;
2413

    
2414
        tmp = load_reg(s, rd0);
2415
        tmp2 = load_reg(s, rd1);
2416
        switch ((insn >> 16) & 0xf) {
2417
        case 0x0:                                        /* MIA */
2418
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2419
            break;
2420
        case 0x8:                                        /* MIAPH */
2421
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2422
            break;
2423
        case 0xc:                                        /* MIABB */
2424
        case 0xd:                                        /* MIABT */
2425
        case 0xe:                                        /* MIATB */
2426
        case 0xf:                                        /* MIATT */
2427
            if (insn & (1 << 16))
2428
                tcg_gen_shri_i32(tmp, tmp, 16);
2429
            if (insn & (1 << 17))
2430
                tcg_gen_shri_i32(tmp2, tmp2, 16);
2431
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2432
            break;
2433
        default:
2434
            return 1;
2435
        }
2436
        dead_tmp(tmp2);
2437
        dead_tmp(tmp);
2438

    
2439
        gen_op_iwmmxt_movq_wRn_M0(acc);
2440
        return 0;
2441
    }
2442

    
2443
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2444
        /* Internal Accumulator Access Format */
2445
        rdhi = (insn >> 16) & 0xf;
2446
        rdlo = (insn >> 12) & 0xf;
2447
        acc = insn & 7;
2448

    
2449
        if (acc != 0)
2450
            return 1;
2451

    
2452
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2453
            iwmmxt_load_reg(cpu_V0, acc);
2454
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2455
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2456
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2457
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2458
        } else {                                        /* MAR */
2459
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2460
            iwmmxt_store_reg(cpu_V0, acc);
2461
        }
2462
        return 0;
2463
    }
2464

    
2465
    return 1;
2466
}
2467

    
2468
/* Disassemble system coprocessor instruction.  Return nonzero if
2469
   instruction is not defined.  */
2470
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2471
{
2472
    TCGv tmp;
2473
    uint32_t rd = (insn >> 12) & 0xf;
2474
    uint32_t cp = (insn >> 8) & 0xf;
2475
    if (IS_USER(s)) {
2476
        return 1;
2477
    }
2478

    
2479
    if (insn & ARM_CP_RW_BIT) {
2480
        if (!env->cp[cp].cp_read)
2481
            return 1;
2482
        gen_set_pc_im(s->pc);
2483
        tmp = new_tmp();
2484
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2485
        store_reg(s, rd, tmp);
2486
    } else {
2487
        if (!env->cp[cp].cp_write)
2488
            return 1;
2489
        gen_set_pc_im(s->pc);
2490
        tmp = load_reg(s, rd);
2491
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2492
        dead_tmp(tmp);
2493
    }
2494
    return 0;
2495
}
2496

    
2497
static int cp15_user_ok(uint32_t insn)
2498
{
2499
    int cpn = (insn >> 16) & 0xf;
2500
    int cpm = insn & 0xf;
2501
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2502

    
2503
    if (cpn == 13 && cpm == 0) {
2504
        /* TLS register.  */
2505
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2506
            return 1;
2507
    }
2508
    if (cpn == 7) {
2509
        /* ISB, DSB, DMB.  */
2510
        if ((cpm == 5 && op == 4)
2511
                || (cpm == 10 && (op == 4 || op == 5)))
2512
            return 1;
2513
    }
2514
    return 0;
2515
}
2516

    
2517
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2518
   instruction is not defined.  */
2519
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2520
{
2521
    uint32_t rd;
2522
    TCGv tmp;
2523

    
2524
    /* M profile cores use memory mapped registers instead of cp15.  */
2525
    if (arm_feature(env, ARM_FEATURE_M))
2526
        return 1;
2527

    
2528
    if ((insn & (1 << 25)) == 0) {
2529
        if (insn & (1 << 20)) {
2530
            /* mrrc */
2531
            return 1;
2532
        }
2533
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2534
        return 0;
2535
    }
2536
    if ((insn & (1 << 4)) == 0) {
2537
        /* cdp */
2538
        return 1;
2539
    }
2540
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2541
        return 1;
2542
    }
2543
    if ((insn & 0x0fff0fff) == 0x0e070f90
2544
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2545
        /* Wait for interrupt.  */
2546
        gen_set_pc_im(s->pc);
2547
        s->is_jmp = DISAS_WFI;
2548
        return 0;
2549
    }
2550
    rd = (insn >> 12) & 0xf;
2551
    if (insn & ARM_CP_RW_BIT) {
2552
        tmp = new_tmp();
2553
        gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2554
        /* If the destination register is r15 then sets condition codes.  */
2555
        if (rd != 15)
2556
            store_reg(s, rd, tmp);
2557
        else
2558
            dead_tmp(tmp);
2559
    } else {
2560
        tmp = load_reg(s, rd);
2561
        gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2562
        dead_tmp(tmp);
2563
        /* Normally we would always end the TB here, but Linux
2564
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2565
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2566
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2567
                (insn & 0x0fff0fff) != 0x0e010f10)
2568
            gen_lookup_tb(s);
2569
    }
2570
    return 0;
2571
}
2572

    
2573
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2574
#define VFP_SREG(insn, bigbit, smallbit) \
2575
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2576
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2577
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2578
        reg = (((insn) >> (bigbit)) & 0x0f) \
2579
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2580
    } else { \
2581
        if (insn & (1 << (smallbit))) \
2582
            return 1; \
2583
        reg = ((insn) >> (bigbit)) & 0x0f; \
2584
    }} while (0)
2585

    
2586
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2587
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2588
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2589
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2590
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2591
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2592

    
2593
/* Move between integer and VFP cores.  */
2594
static TCGv gen_vfp_mrs(void)
2595
{
2596
    TCGv tmp = new_tmp();
2597
    tcg_gen_mov_i32(tmp, cpu_F0s);
2598
    return tmp;
2599
}
2600

    
2601
static void gen_vfp_msr(TCGv tmp)
2602
{
2603
    tcg_gen_mov_i32(cpu_F0s, tmp);
2604
    dead_tmp(tmp);
2605
}
2606

    
2607
static inline int
2608
vfp_enabled(CPUState * env)
2609
{
2610
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2611
}
2612

    
2613
static void gen_neon_dup_u8(TCGv var, int shift)
2614
{
2615
    TCGv tmp = new_tmp();
2616
    if (shift)
2617
        tcg_gen_shri_i32(var, var, shift);
2618
    tcg_gen_ext8u_i32(var, var);
2619
    tcg_gen_shli_i32(tmp, var, 8);
2620
    tcg_gen_or_i32(var, var, tmp);
2621
    tcg_gen_shli_i32(tmp, var, 16);
2622
    tcg_gen_or_i32(var, var, tmp);
2623
    dead_tmp(tmp);
2624
}
2625

    
2626
static void gen_neon_dup_low16(TCGv var)
2627
{
2628
    TCGv tmp = new_tmp();
2629
    tcg_gen_ext16u_i32(var, var);
2630
    tcg_gen_shli_i32(tmp, var, 16);
2631
    tcg_gen_or_i32(var, var, tmp);
2632
    dead_tmp(tmp);
2633
}
2634

    
2635
static void gen_neon_dup_high16(TCGv var)
2636
{
2637
    TCGv tmp = new_tmp();
2638
    tcg_gen_andi_i32(var, var, 0xffff0000);
2639
    tcg_gen_shri_i32(tmp, var, 16);
2640
    tcg_gen_or_i32(var, var, tmp);
2641
    dead_tmp(tmp);
2642
}
2643

    
2644
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2645
   (ie. an undefined instruction).  */
2646
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2647
{
2648
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2649
    int dp, veclen;
2650
    TCGv tmp;
2651
    TCGv tmp2;
2652

    
2653
    if (!arm_feature(env, ARM_FEATURE_VFP))
2654
        return 1;
2655

    
2656
    if (!vfp_enabled(env)) {
2657
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2658
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2659
            return 1;
2660
        rn = (insn >> 16) & 0xf;
2661
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2662
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2663
            return 1;
2664
    }
2665
    dp = ((insn & 0xf00) == 0xb00);
2666
    switch ((insn >> 24) & 0xf) {
2667
    case 0xe:
2668
        if (insn & (1 << 4)) {
2669
            /* single register transfer */
2670
            rd = (insn >> 12) & 0xf;
2671
            if (dp) {
2672
                int size;
2673
                int pass;
2674

    
2675
                VFP_DREG_N(rn, insn);
2676
                if (insn & 0xf)
2677
                    return 1;
2678
                if (insn & 0x00c00060
2679
                    && !arm_feature(env, ARM_FEATURE_NEON))
2680
                    return 1;
2681

    
2682
                pass = (insn >> 21) & 1;
2683
                if (insn & (1 << 22)) {
2684
                    size = 0;
2685
                    offset = ((insn >> 5) & 3) * 8;
2686
                } else if (insn & (1 << 5)) {
2687
                    size = 1;
2688
                    offset = (insn & (1 << 6)) ? 16 : 0;
2689
                } else {
2690
                    size = 2;
2691
                    offset = 0;
2692
                }
2693
                if (insn & ARM_CP_RW_BIT) {
2694
                    /* vfp->arm */
2695
                    tmp = neon_load_reg(rn, pass);
2696
                    switch (size) {
2697
                    case 0:
2698
                        if (offset)
2699
                            tcg_gen_shri_i32(tmp, tmp, offset);
2700
                        if (insn & (1 << 23))
2701
                            gen_uxtb(tmp);
2702
                        else
2703
                            gen_sxtb(tmp);
2704
                        break;
2705
                    case 1:
2706
                        if (insn & (1 << 23)) {
2707
                            if (offset) {
2708
                                tcg_gen_shri_i32(tmp, tmp, 16);
2709
                            } else {
2710
                                gen_uxth(tmp);
2711
                            }
2712
                        } else {
2713
                            if (offset) {
2714
                                tcg_gen_sari_i32(tmp, tmp, 16);
2715
                            } else {
2716
                                gen_sxth(tmp);
2717
                            }
2718
                        }
2719
                        break;
2720
                    case 2:
2721
                        break;
2722
                    }
2723
                    store_reg(s, rd, tmp);
2724
                } else {
2725
                    /* arm->vfp */
2726
                    tmp = load_reg(s, rd);
2727
                    if (insn & (1 << 23)) {
2728
                        /* VDUP */
2729
                        if (size == 0) {
2730
                            gen_neon_dup_u8(tmp, 0);
2731
                        } else if (size == 1) {
2732
                            gen_neon_dup_low16(tmp);
2733
                        }
2734
                        for (n = 0; n <= pass * 2; n++) {
2735
                            tmp2 = new_tmp();
2736
                            tcg_gen_mov_i32(tmp2, tmp);
2737
                            neon_store_reg(rn, n, tmp2);
2738
                        }
2739
                        neon_store_reg(rn, n, tmp);
2740
                    } else {
2741
                        /* VMOV */
2742
                        switch (size) {
2743
                        case 0:
2744
                            tmp2 = neon_load_reg(rn, pass);
2745
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2746
                            dead_tmp(tmp2);
2747
                            break;
2748
                        case 1:
2749
                            tmp2 = neon_load_reg(rn, pass);
2750
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2751
                            dead_tmp(tmp2);
2752
                            break;
2753
                        case 2:
2754
                            break;
2755
                        }
2756
                        neon_store_reg(rn, pass, tmp);
2757
                    }
2758
                }
2759
            } else { /* !dp */
2760
                if ((insn & 0x6f) != 0x00)
2761
                    return 1;
2762
                rn = VFP_SREG_N(insn);
2763
                if (insn & ARM_CP_RW_BIT) {
2764
                    /* vfp->arm */
2765
                    if (insn & (1 << 21)) {
2766
                        /* system register */
2767
                        rn >>= 1;
2768

    
2769
                        switch (rn) {
2770
                        case ARM_VFP_FPSID:
2771
                            /* VFP2 allows access to FSID from userspace.
2772
                               VFP3 restricts all id registers to privileged
2773
                               accesses.  */
2774
                            if (IS_USER(s)
2775
                                && arm_feature(env, ARM_FEATURE_VFP3))
2776
                                return 1;
2777
                            tmp = load_cpu_field(vfp.xregs[rn]);
2778
                            break;
2779
                        case ARM_VFP_FPEXC:
2780
                            if (IS_USER(s))
2781
                                return 1;
2782
                            tmp = load_cpu_field(vfp.xregs[rn]);
2783
                            break;
2784
                        case ARM_VFP_FPINST:
2785
                        case ARM_VFP_FPINST2:
2786
                            /* Not present in VFP3.  */
2787
                            if (IS_USER(s)
2788
                                || arm_feature(env, ARM_FEATURE_VFP3))
2789
                                return 1;
2790
                            tmp = load_cpu_field(vfp.xregs[rn]);
2791
                            break;
2792
                        case ARM_VFP_FPSCR:
2793
                            if (rd == 15) {
2794
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2795
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2796
                            } else {
2797
                                tmp = new_tmp();
2798
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2799
                            }
2800
                            break;
2801
                        case ARM_VFP_MVFR0:
2802
                        case ARM_VFP_MVFR1:
2803
                            if (IS_USER(s)
2804
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2805
                                return 1;
2806
                            tmp = load_cpu_field(vfp.xregs[rn]);
2807
                            break;
2808
                        default:
2809
                            return 1;
2810
                        }
2811
                    } else {
2812
                        gen_mov_F0_vreg(0, rn);
2813
                        tmp = gen_vfp_mrs();
2814
                    }
2815
                    if (rd == 15) {
2816
                        /* Set the 4 flag bits in the CPSR.  */
2817
                        gen_set_nzcv(tmp);
2818
                        dead_tmp(tmp);
2819
                    } else {
2820
                        store_reg(s, rd, tmp);
2821
                    }
2822
                } else {
2823
                    /* arm->vfp */
2824
                    tmp = load_reg(s, rd);
2825
                    if (insn & (1 << 21)) {
2826
                        rn >>= 1;
2827
                        /* system register */
2828
                        switch (rn) {
2829
                        case ARM_VFP_FPSID:
2830
                        case ARM_VFP_MVFR0:
2831
                        case ARM_VFP_MVFR1:
2832
                            /* Writes are ignored.  */
2833
                            break;
2834
                        case ARM_VFP_FPSCR:
2835
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2836
                            dead_tmp(tmp);
2837
                            gen_lookup_tb(s);
2838
                            break;
2839
                        case ARM_VFP_FPEXC:
2840
                            if (IS_USER(s))
2841
                                return 1;
2842
                            store_cpu_field(tmp, vfp.xregs[rn]);
2843
                            gen_lookup_tb(s);
2844
                            break;
2845
                        case ARM_VFP_FPINST:
2846
                        case ARM_VFP_FPINST2:
2847
                            store_cpu_field(tmp, vfp.xregs[rn]);
2848
                            break;
2849
                        default:
2850
                            return 1;
2851
                        }
2852
                    } else {
2853
                        gen_vfp_msr(tmp);
2854
                        gen_mov_vreg_F0(0, rn);
2855
                    }
2856
                }
2857
            }
2858
        } else {
2859
            /* data processing */
2860
            /* The opcode is in bits 23, 21, 20 and 6.  */
2861
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2862
            if (dp) {
2863
                if (op == 15) {
2864
                    /* rn is opcode */
2865
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2866
                } else {
2867
                    /* rn is register number */
2868
                    VFP_DREG_N(rn, insn);
2869
                }
2870

    
2871
                if (op == 15 && (rn == 15 || rn > 17)) {
2872
                    /* Integer or single precision destination.  */
2873
                    rd = VFP_SREG_D(insn);
2874
                } else {
2875
                    VFP_DREG_D(rd, insn);
2876
                }
2877

    
2878
                if (op == 15 && (rn == 16 || rn == 17)) {
2879
                    /* Integer source.  */
2880
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2881
                } else {
2882
                    VFP_DREG_M(rm, insn);
2883
                }
2884
            } else {
2885
                rn = VFP_SREG_N(insn);
2886
                if (op == 15 && rn == 15) {
2887
                    /* Double precision destination.  */
2888
                    VFP_DREG_D(rd, insn);
2889
                } else {
2890
                    rd = VFP_SREG_D(insn);
2891
                }
2892
                rm = VFP_SREG_M(insn);
2893
            }
2894

    
2895
            veclen = env->vfp.vec_len;
2896
            if (op == 15 && rn > 3)
2897
                veclen = 0;
2898

    
2899
            /* Shut up compiler warnings.  */
2900
            delta_m = 0;
2901
            delta_d = 0;
2902
            bank_mask = 0;
2903

    
2904
            if (veclen > 0) {
2905
                if (dp)
2906
                    bank_mask = 0xc;
2907
                else
2908
                    bank_mask = 0x18;
2909

    
2910
                /* Figure out what type of vector operation this is.  */
2911
                if ((rd & bank_mask) == 0) {
2912
                    /* scalar */
2913
                    veclen = 0;
2914
                } else {
2915
                    if (dp)
2916
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2917
                    else
2918
                        delta_d = env->vfp.vec_stride + 1;
2919

    
2920
                    if ((rm & bank_mask) == 0) {
2921
                        /* mixed scalar/vector */
2922
                        delta_m = 0;
2923
                    } else {
2924
                        /* vector */
2925
                        delta_m = delta_d;
2926
                    }
2927
                }
2928
            }
2929

    
2930
            /* Load the initial operands.  */
2931
            if (op == 15) {
2932
                switch (rn) {
2933
                case 16:
2934
                case 17:
2935
                    /* Integer source */
2936
                    gen_mov_F0_vreg(0, rm);
2937
                    break;
2938
                case 8:
2939
                case 9:
2940
                    /* Compare */
2941
                    gen_mov_F0_vreg(dp, rd);
2942
                    gen_mov_F1_vreg(dp, rm);
2943
                    break;
2944
                case 10:
2945
                case 11:
2946
                    /* Compare with zero */
2947
                    gen_mov_F0_vreg(dp, rd);
2948
                    gen_vfp_F1_ld0(dp);
2949
                    break;
2950
                case 20:
2951
                case 21:
2952
                case 22:
2953
                case 23:
2954
                case 28:
2955
                case 29:
2956
                case 30:
2957
                case 31:
2958
                    /* Source and destination the same.  */
2959
                    gen_mov_F0_vreg(dp, rd);
2960
                    break;
2961
                default:
2962
                    /* One source operand.  */
2963
                    gen_mov_F0_vreg(dp, rm);
2964
                    break;
2965
                }
2966
            } else {
2967
                /* Two source operands.  */
2968
                gen_mov_F0_vreg(dp, rn);
2969
                gen_mov_F1_vreg(dp, rm);
2970
            }
2971

    
2972
            for (;;) {
2973
                /* Perform the calculation.  */
2974
                switch (op) {
2975
                case 0: /* mac: fd + (fn * fm) */
2976
                    gen_vfp_mul(dp);
2977
                    gen_mov_F1_vreg(dp, rd);
2978
                    gen_vfp_add(dp);
2979
                    break;
2980
                case 1: /* nmac: fd - (fn * fm) */
2981
                    gen_vfp_mul(dp);
2982
                    gen_vfp_neg(dp);
2983
                    gen_mov_F1_vreg(dp, rd);
2984
                    gen_vfp_add(dp);
2985
                    break;
2986
                case 2: /* msc: -fd + (fn * fm) */
2987
                    gen_vfp_mul(dp);
2988
                    gen_mov_F1_vreg(dp, rd);
2989
                    gen_vfp_sub(dp);
2990
                    break;
2991
                case 3: /* nmsc: -fd - (fn * fm)  */
2992
                    gen_vfp_mul(dp);
2993
                    gen_vfp_neg(dp);
2994
                    gen_mov_F1_vreg(dp, rd);
2995
                    gen_vfp_sub(dp);
2996
                    break;
2997
                case 4: /* mul: fn * fm */
2998
                    gen_vfp_mul(dp);
2999
                    break;
3000
                case 5: /* nmul: -(fn * fm) */
3001
                    gen_vfp_mul(dp);
3002
                    gen_vfp_neg(dp);
3003
                    break;
3004
                case 6: /* add: fn + fm */
3005
                    gen_vfp_add(dp);
3006
                    break;
3007
                case 7: /* sub: fn - fm */
3008
                    gen_vfp_sub(dp);
3009
                    break;
3010
                case 8: /* div: fn / fm */
3011
                    gen_vfp_div(dp);
3012
                    break;
3013
                case 14: /* fconst */
3014
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3015
                      return 1;
3016

    
3017
                    n = (insn << 12) & 0x80000000;
3018
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3019
                    if (dp) {
3020
                        if (i & 0x40)
3021
                            i |= 0x3f80;
3022
                        else
3023
                            i |= 0x4000;
3024
                        n |= i << 16;
3025
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3026
                    } else {
3027
                        if (i & 0x40)
3028
                            i |= 0x780;
3029
                        else
3030
                            i |= 0x800;
3031
                        n |= i << 19;
3032
                        tcg_gen_movi_i32(cpu_F0s, n);
3033
                    }
3034
                    break;
3035
                case 15: /* extension space */
3036
                    switch (rn) {
3037
                    case 0: /* cpy */
3038
                        /* no-op */
3039
                        break;
3040
                    case 1: /* abs */
3041
                        gen_vfp_abs(dp);
3042
                        break;
3043
                    case 2: /* neg */
3044
                        gen_vfp_neg(dp);
3045
                        break;
3046
                    case 3: /* sqrt */
3047
                        gen_vfp_sqrt(dp);
3048
                        break;
3049
                    case 8: /* cmp */
3050
                        gen_vfp_cmp(dp);
3051
                        break;
3052
                    case 9: /* cmpe */
3053
                        gen_vfp_cmpe(dp);
3054
                        break;
3055
                    case 10: /* cmpz */
3056
                        gen_vfp_cmp(dp);
3057
                        break;
3058
                    case 11: /* cmpez */
3059
                        gen_vfp_F1_ld0(dp);
3060
                        gen_vfp_cmpe(dp);
3061
                        break;
3062
                    case 15: /* single<->double conversion */
3063
                        if (dp)
3064
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3065
                        else
3066
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3067
                        break;
3068
                    case 16: /* fuito */
3069
                        gen_vfp_uito(dp);
3070
                        break;
3071
                    case 17: /* fsito */
3072
                        gen_vfp_sito(dp);
3073
                        break;
3074
                    case 20: /* fshto */
3075
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3076
                          return 1;
3077
                        gen_vfp_shto(dp, 16 - rm);
3078
                        break;
3079
                    case 21: /* fslto */
3080
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3081
                          return 1;
3082
                        gen_vfp_slto(dp, 32 - rm);
3083
                        break;
3084
                    case 22: /* fuhto */
3085
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3086
                          return 1;
3087
                        gen_vfp_uhto(dp, 16 - rm);
3088
                        break;
3089
                    case 23: /* fulto */
3090
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3091
                          return 1;
3092
                        gen_vfp_ulto(dp, 32 - rm);
3093
                        break;
3094
                    case 24: /* ftoui */
3095
                        gen_vfp_toui(dp);
3096
                        break;
3097
                    case 25: /* ftouiz */
3098
                        gen_vfp_touiz(dp);
3099
                        break;
3100
                    case 26: /* ftosi */
3101
                        gen_vfp_tosi(dp);
3102
                        break;
3103
                    case 27: /* ftosiz */
3104
                        gen_vfp_tosiz(dp);
3105
                        break;
3106
                    case 28: /* ftosh */
3107
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3108
                          return 1;
3109
                        gen_vfp_tosh(dp, 16 - rm);
3110
                        break;
3111
                    case 29: /* ftosl */
3112
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3113
                          return 1;
3114
                        gen_vfp_tosl(dp, 32 - rm);
3115
                        break;
3116
                    case 30: /* ftouh */
3117
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3118
                          return 1;
3119
                        gen_vfp_touh(dp, 16 - rm);
3120
                        break;
3121
                    case 31: /* ftoul */
3122
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3123
                          return 1;
3124
                        gen_vfp_toul(dp, 32 - rm);
3125
                        break;
3126
                    default: /* undefined */
3127
                        printf ("rn:%d\n", rn);
3128
                        return 1;
3129
                    }
3130
                    break;
3131
                default: /* undefined */
3132
                    printf ("op:%d\n", op);
3133
                    return 1;
3134
                }
3135

    
3136
                /* Write back the result.  */
3137
                if (op == 15 && (rn >= 8 && rn <= 11))
3138
                    ; /* Comparison, do nothing.  */
3139
                else if (op == 15 && rn > 17)
3140
                    /* Integer result.  */
3141
                    gen_mov_vreg_F0(0, rd);
3142
                else if (op == 15 && rn == 15)
3143
                    /* conversion */
3144
                    gen_mov_vreg_F0(!dp, rd);
3145
                else
3146
                    gen_mov_vreg_F0(dp, rd);
3147

    
3148
                /* break out of the loop if we have finished  */
3149
                if (veclen == 0)
3150
                    break;
3151

    
3152
                if (op == 15 && delta_m == 0) {
3153
                    /* single source one-many */
3154
                    while (veclen--) {
3155
                        rd = ((rd + delta_d) & (bank_mask - 1))
3156
                             | (rd & bank_mask);
3157
                        gen_mov_vreg_F0(dp, rd);
3158
                    }
3159
                    break;
3160
                }
3161
                /* Setup the next operands.  */
3162
                veclen--;
3163
                rd = ((rd + delta_d) & (bank_mask - 1))
3164
                     | (rd & bank_mask);
3165

    
3166
                if (op == 15) {
3167
                    /* One source operand.  */
3168
                    rm = ((rm + delta_m) & (bank_mask - 1))
3169
                         | (rm & bank_mask);
3170
                    gen_mov_F0_vreg(dp, rm);
3171
                } else {
3172
                    /* Two source operands.  */
3173
                    rn = ((rn + delta_d) & (bank_mask - 1))
3174
                         | (rn & bank_mask);
3175
                    gen_mov_F0_vreg(dp, rn);
3176
                    if (delta_m) {
3177
                        rm = ((rm + delta_m) & (bank_mask - 1))
3178
                             | (rm & bank_mask);
3179
                        gen_mov_F1_vreg(dp, rm);
3180
                    }
3181
                }
3182
            }
3183
        }
3184
        break;
3185
    case 0xc:
3186
    case 0xd:
3187
        if (dp && (insn & 0x03e00000) == 0x00400000) {
3188
            /* two-register transfer */
3189
            rn = (insn >> 16) & 0xf;
3190
            rd = (insn >> 12) & 0xf;
3191
            if (dp) {
3192
                VFP_DREG_M(rm, insn);
3193
            } else {
3194
                rm = VFP_SREG_M(insn);
3195
            }
3196

    
3197
            if (insn & ARM_CP_RW_BIT) {
3198
                /* vfp->arm */
3199
                if (dp) {
3200
                    gen_mov_F0_vreg(0, rm * 2);
3201
                    tmp = gen_vfp_mrs();
3202
                    store_reg(s, rd, tmp);
3203
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3204
                    tmp = gen_vfp_mrs();
3205
                    store_reg(s, rn, tmp);
3206
                } else {
3207
                    gen_mov_F0_vreg(0, rm);
3208
                    tmp = gen_vfp_mrs();
3209
                    store_reg(s, rn, tmp);
3210
                    gen_mov_F0_vreg(0, rm + 1);
3211
                    tmp = gen_vfp_mrs();
3212
                    store_reg(s, rd, tmp);
3213
                }
3214
            } else {
3215
                /* arm->vfp */
3216
                if (dp) {
3217
                    tmp = load_reg(s, rd);
3218
                    gen_vfp_msr(tmp);
3219
                    gen_mov_vreg_F0(0, rm * 2);
3220
                    tmp = load_reg(s, rn);
3221
                    gen_vfp_msr(tmp);
3222
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3223
                } else {
3224
                    tmp = load_reg(s, rn);
3225
                    gen_vfp_msr(tmp);
3226
                    gen_mov_vreg_F0(0, rm);
3227
                    tmp = load_reg(s, rd);
3228
                    gen_vfp_msr(tmp);
3229
                    gen_mov_vreg_F0(0, rm + 1);
3230
                }
3231
            }
3232
        } else {
3233
            /* Load/store */
3234
            rn = (insn >> 16) & 0xf;
3235
            if (dp)
3236
                VFP_DREG_D(rd, insn);
3237
            else
3238
                rd = VFP_SREG_D(insn);
3239
            if (s->thumb && rn == 15) {
3240
                gen_op_movl_T1_im(s->pc & ~2);
3241
            } else {
3242
                gen_movl_T1_reg(s, rn);
3243
            }
3244
            if ((insn & 0x01200000) == 0x01000000) {
3245
                /* Single load/store */
3246
                offset = (insn & 0xff) << 2;
3247
                if ((insn & (1 << 23)) == 0)
3248
                    offset = -offset;
3249
                gen_op_addl_T1_im(offset);
3250
                if (insn & (1 << 20)) {
3251
                    gen_vfp_ld(s, dp);
3252
                    gen_mov_vreg_F0(dp, rd);
3253
                } else {
3254
                    gen_mov_F0_vreg(dp, rd);
3255
                    gen_vfp_st(s, dp);
3256
                }
3257
            } else {
3258
                /* load/store multiple */
3259
                if (dp)
3260
                    n = (insn >> 1) & 0x7f;
3261
                else
3262
                    n = insn & 0xff;
3263

    
3264
                if (insn & (1 << 24)) /* pre-decrement */
3265
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3266

    
3267
                if (dp)
3268
                    offset = 8;
3269
                else
3270
                    offset = 4;
3271
                for (i = 0; i < n; i++) {
3272
                    if (insn & ARM_CP_RW_BIT) {
3273
                        /* load */
3274
                        gen_vfp_ld(s, dp);
3275
                        gen_mov_vreg_F0(dp, rd + i);
3276
                    } else {
3277
                        /* store */
3278
                        gen_mov_F0_vreg(dp, rd + i);
3279
                        gen_vfp_st(s, dp);
3280
                    }
3281
                    gen_op_addl_T1_im(offset);
3282
                }
3283
                if (insn & (1 << 21)) {
3284
                    /* writeback */
3285
                    if (insn & (1 << 24))
3286
                        offset = -offset * n;
3287
                    else if (dp && (insn & 1))
3288
                        offset = 4;
3289
                    else
3290
                        offset = 0;
3291

    
3292
                    if (offset != 0)
3293
                        gen_op_addl_T1_im(offset);
3294
                    gen_movl_reg_T1(s, rn);
3295
                }
3296
            }
3297
        }
3298
        break;
3299
    default:
3300
        /* Should never happen.  */
3301
        return 1;
3302
    }
3303
    return 0;
3304
}
3305

    
3306
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3307
{
3308
    TranslationBlock *tb;
3309

    
3310
    tb = s->tb;
3311
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3312
        tcg_gen_goto_tb(n);
3313
        gen_set_pc_im(dest);
3314
        tcg_gen_exit_tb((long)tb + n);
3315
    } else {
3316
        gen_set_pc_im(dest);
3317
        tcg_gen_exit_tb(0);
3318
    }
3319
}
3320

    
3321
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3322
{
3323
    if (unlikely(s->singlestep_enabled)) {
3324
        /* An indirect jump so that we still trigger the debug exception.  */
3325
        if (s->thumb)
3326
            dest |= 1;
3327
        gen_bx_im(s, dest);
3328
    } else {
3329
        gen_goto_tb(s, 0, dest);
3330
        s->is_jmp = DISAS_TB_JUMP;
3331
    }
3332
}
3333

    
3334
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3335
{
3336
    if (x)
3337
        tcg_gen_sari_i32(t0, t0, 16);
3338
    else
3339
        gen_sxth(t0);
3340
    if (y)
3341
        tcg_gen_sari_i32(t1, t1, 16);
3342
    else
3343
        gen_sxth(t1);
3344
    tcg_gen_mul_i32(t0, t0, t1);
3345
}
3346

    
3347
/* Return the mask of PSR bits set by a MSR instruction.  */
3348
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3349
    uint32_t mask;
3350

    
3351
    mask = 0;
3352
    if (flags & (1 << 0))
3353
        mask |= 0xff;
3354
    if (flags & (1 << 1))
3355
        mask |= 0xff00;
3356
    if (flags & (1 << 2))
3357
        mask |= 0xff0000;
3358
    if (flags & (1 << 3))
3359
        mask |= 0xff000000;
3360

    
3361
    /* Mask out undefined bits.  */
3362
    mask &= ~CPSR_RESERVED;
3363
    if (!arm_feature(env, ARM_FEATURE_V6))
3364
        mask &= ~(CPSR_E | CPSR_GE);
3365
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3366
        mask &= ~CPSR_IT;
3367
    /* Mask out execution state bits.  */
3368
    if (!spsr)
3369
        mask &= ~CPSR_EXEC;
3370
    /* Mask out privileged bits.  */
3371
    if (IS_USER(s))
3372
        mask &= CPSR_USER;
3373
    return mask;
3374
}
3375

    
3376
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3377
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3378
{
3379
    TCGv tmp;
3380
    if (spsr) {
3381
        /* ??? This is also undefined in system mode.  */
3382
        if (IS_USER(s))
3383
            return 1;
3384

    
3385
        tmp = load_cpu_field(spsr);
3386
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3387
        tcg_gen_andi_i32(t0, t0, mask);
3388
        tcg_gen_or_i32(tmp, tmp, t0);
3389
        store_cpu_field(tmp, spsr);
3390
    } else {
3391
        gen_set_cpsr(t0, mask);
3392
    }
3393
    dead_tmp(t0);
3394
    gen_lookup_tb(s);
3395
    return 0;
3396
}
3397

    
3398
/* Returns nonzero if access to the PSR is not permitted.  */
3399
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3400
{
3401
    TCGv tmp;
3402
    tmp = new_tmp();
3403
    tcg_gen_movi_i32(tmp, val);
3404
    return gen_set_psr(s, mask, spsr, tmp);
3405
}
3406

    
3407
/* Generate an old-style exception return. Marks pc as dead. */
3408
static void gen_exception_return(DisasContext *s, TCGv pc)
3409
{
3410
    TCGv tmp;
3411
    store_reg(s, 15, pc);
3412
    tmp = load_cpu_field(spsr);
3413
    gen_set_cpsr(tmp, 0xffffffff);
3414
    dead_tmp(tmp);
3415
    s->is_jmp = DISAS_UPDATE;
3416
}
3417

    
3418
/* Generate a v6 exception return.  Marks both values as dead.  */
3419
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3420
{
3421
    gen_set_cpsr(cpsr, 0xffffffff);
3422
    dead_tmp(cpsr);
3423
    store_reg(s, 15, pc);
3424
    s->is_jmp = DISAS_UPDATE;
3425
}
3426

    
3427
static inline void
3428
gen_set_condexec (DisasContext *s)
3429
{
3430
    if (s->condexec_mask) {
3431
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3432
        TCGv tmp = new_tmp();
3433
        tcg_gen_movi_i32(tmp, val);
3434
        store_cpu_field(tmp, condexec_bits);
3435
    }
3436
}
3437

    
3438
static void gen_nop_hint(DisasContext *s, int val)
3439
{
3440
    switch (val) {
3441
    case 3: /* wfi */
3442
        gen_set_pc_im(s->pc);
3443
        s->is_jmp = DISAS_WFI;
3444
        break;
3445
    case 2: /* wfe */
3446
    case 4: /* sev */
3447
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3448
    default: /* nop */
3449
        break;
3450
    }
3451
}
3452

    
3453
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3454

    
3455
static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3456
{
3457
    switch (size) {
3458
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3459
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3460
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3461
    default: return 1;
3462
    }
3463
    return 0;
3464
}
3465

    
3466
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3467
{
3468
    switch (size) {
3469
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3470
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3471
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3472
    default: return;
3473
    }
3474
}
3475

    
3476
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3477
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3478
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3479
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3480
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3481

    
3482
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3483
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3484
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3485
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3486
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3487

    
3488
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3489
    switch ((size << 1) | u) { \
3490
    case 0: \
3491
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3492
        break; \
3493
    case 1: \
3494
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3495
        break; \
3496
    case 2: \
3497
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3498
        break; \
3499
    case 3: \
3500
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3501
        break; \
3502
    case 4: \
3503
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3504
        break; \
3505
    case 5: \
3506
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3507
        break; \
3508
    default: return 1; \
3509
    }} while (0)
3510

    
3511
#define GEN_NEON_INTEGER_OP(name) do { \
3512
    switch ((size << 1) | u) { \
3513
    case 0: \
3514
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3515
        break; \
3516
    case 1: \
3517
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3518
        break; \
3519
    case 2: \
3520
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3521
        break; \
3522
    case 3: \
3523
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3524
        break; \
3525
    case 4: \
3526
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3527
        break; \
3528
    case 5: \
3529
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3530
        break; \
3531
    default: return 1; \
3532
    }} while (0)
3533

    
3534
static TCGv neon_load_scratch(int scratch)
3535
{
3536
    TCGv tmp = new_tmp();
3537
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3538
    return tmp;
3539
}
3540

    
3541
static void neon_store_scratch(int scratch, TCGv var)
3542
{
3543
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3544
    dead_tmp(var);
3545
}
3546

    
3547
static inline TCGv neon_get_scalar(int size, int reg)
3548
{
3549
    TCGv tmp;
3550
    if (size == 1) {
3551
        tmp = neon_load_reg(reg >> 1, reg & 1);
3552
    } else {
3553
        tmp = neon_load_reg(reg >> 2, (reg >> 1) & 1);
3554
        if (reg & 1) {
3555
            gen_neon_dup_low16(tmp);
3556
        } else {
3557
            gen_neon_dup_high16(tmp);
3558
        }
3559
    }
3560
    return tmp;
3561
}
3562

    
3563
static void gen_neon_unzip_u8(TCGv t0, TCGv t1)
3564
{
3565
    TCGv rd, rm, tmp;
3566

    
3567
    rd = new_tmp();
3568
    rm = new_tmp();
3569
    tmp = new_tmp();
3570

    
3571
    tcg_gen_andi_i32(rd, t0, 0xff);
3572
    tcg_gen_shri_i32(tmp, t0, 8);
3573
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3574
    tcg_gen_or_i32(rd, rd, tmp);
3575
    tcg_gen_shli_i32(tmp, t1, 16);
3576
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3577
    tcg_gen_or_i32(rd, rd, tmp);
3578
    tcg_gen_shli_i32(tmp, t1, 8);
3579
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3580
    tcg_gen_or_i32(rd, rd, tmp);
3581

    
3582
    tcg_gen_shri_i32(rm, t0, 8);
3583
    tcg_gen_andi_i32(rm, rm, 0xff);
3584
    tcg_gen_shri_i32(tmp, t0, 16);
3585
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3586
    tcg_gen_or_i32(rm, rm, tmp);
3587
    tcg_gen_shli_i32(tmp, t1, 8);
3588
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3589
    tcg_gen_or_i32(rm, rm, tmp);
3590
    tcg_gen_andi_i32(tmp, t1, 0xff000000);
3591
    tcg_gen_or_i32(t1, rm, tmp);
3592
    tcg_gen_mov_i32(t0, rd);
3593

    
3594
    dead_tmp(tmp);
3595
    dead_tmp(rm);
3596
    dead_tmp(rd);
3597
}
3598

    
3599
static void gen_neon_zip_u8(TCGv t0, TCGv t1)
3600
{
3601
    TCGv rd, rm, tmp;
3602

    
3603
    rd = new_tmp();
3604
    rm = new_tmp();
3605
    tmp = new_tmp();
3606

    
3607
    tcg_gen_andi_i32(rd, t0, 0xff);
3608
    tcg_gen_shli_i32(tmp, t1, 8);
3609
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3610
    tcg_gen_or_i32(rd, rd, tmp);
3611
    tcg_gen_shli_i32(tmp, t0, 16);
3612
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3613
    tcg_gen_or_i32(rd, rd, tmp);
3614
    tcg_gen_shli_i32(tmp, t1, 24);
3615
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3616
    tcg_gen_or_i32(rd, rd, tmp);
3617

    
3618
    tcg_gen_andi_i32(rm, t1, 0xff000000);
3619
    tcg_gen_shri_i32(tmp, t0, 8);
3620
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3621
    tcg_gen_or_i32(rm, rm, tmp);
3622
    tcg_gen_shri_i32(tmp, t1, 8);
3623
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3624
    tcg_gen_or_i32(rm, rm, tmp);
3625
    tcg_gen_shri_i32(tmp, t0, 16);
3626
    tcg_gen_andi_i32(tmp, tmp, 0xff);
3627
    tcg_gen_or_i32(t1, rm, tmp);
3628
    tcg_gen_mov_i32(t0, rd);
3629

    
3630
    dead_tmp(tmp);
3631
    dead_tmp(rm);
3632
    dead_tmp(rd);
3633
}
3634

    
3635
static void gen_neon_zip_u16(TCGv t0, TCGv t1)
3636
{
3637
    TCGv tmp, tmp2;
3638

    
3639
    tmp = new_tmp();
3640
    tmp2 = new_tmp();
3641

    
3642
    tcg_gen_andi_i32(tmp, t0, 0xffff);
3643
    tcg_gen_shli_i32(tmp2, t1, 16);
3644
    tcg_gen_or_i32(tmp, tmp, tmp2);
3645
    tcg_gen_andi_i32(t1, t1, 0xffff0000);
3646
    tcg_gen_shri_i32(tmp2, t0, 16);
3647
    tcg_gen_or_i32(t1, t1, tmp2);
3648
    tcg_gen_mov_i32(t0, tmp);
3649

    
3650
    dead_tmp(tmp2);
3651
    dead_tmp(tmp);
3652
}
3653

    
3654
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3655
{
3656
    int n;
3657
    TCGv t0, t1;
3658

    
3659
    for (n = 0; n < q + 1; n += 2) {
3660
        t0 = neon_load_reg(reg, n);
3661
        t1 = neon_load_reg(reg, n + 1);
3662
        switch (size) {
3663
        case 0: gen_neon_unzip_u8(t0, t1); break;
3664
        case 1: gen_neon_zip_u16(t0, t1); break; /* zip and unzip are the same.  */
3665
        case 2: /* no-op */; break;
3666
        default: abort();
3667
        }
3668
        neon_store_scratch(tmp + n, t0);
3669
        neon_store_scratch(tmp + n + 1, t1);
3670
    }
3671
}
3672

    
3673
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3674
{
3675
    TCGv rd, tmp;
3676

    
3677
    rd = new_tmp();
3678
    tmp = new_tmp();
3679

    
3680
    tcg_gen_shli_i32(rd, t0, 8);
3681
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3682
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3683
    tcg_gen_or_i32(rd, rd, tmp);
3684

    
3685
    tcg_gen_shri_i32(t1, t1, 8);
3686
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3687
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3688
    tcg_gen_or_i32(t1, t1, tmp);
3689
    tcg_gen_mov_i32(t0, rd);
3690

    
3691
    dead_tmp(tmp);
3692
    dead_tmp(rd);
3693
}
3694

    
3695
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3696
{
3697
    TCGv rd, tmp;
3698

    
3699
    rd = new_tmp();
3700
    tmp = new_tmp();
3701

    
3702
    tcg_gen_shli_i32(rd, t0, 16);
3703
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3704
    tcg_gen_or_i32(rd, rd, tmp);
3705
    tcg_gen_shri_i32(t1, t1, 16);
3706
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3707
    tcg_gen_or_i32(t1, t1, tmp);
3708
    tcg_gen_mov_i32(t0, rd);
3709

    
3710
    dead_tmp(tmp);
3711
    dead_tmp(rd);
3712
}
3713

    
3714

    
3715
static struct {
3716
    int nregs;
3717
    int interleave;
3718
    int spacing;
3719
} neon_ls_element_type[11] = {
3720
    {4, 4, 1},
3721
    {4, 4, 2},
3722
    {4, 1, 1},
3723
    {4, 2, 1},
3724
    {3, 3, 1},
3725
    {3, 3, 2},
3726
    {3, 1, 1},
3727
    {1, 1, 1},
3728
    {2, 2, 1},
3729
    {2, 2, 2},
3730
    {2, 1, 1}
3731
};
3732

    
3733
/* Translate a NEON load/store element instruction.  Return nonzero if the
3734
   instruction is invalid.  */
3735
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3736
{
3737
    int rd, rn, rm;
3738
    int op;
3739
    int nregs;
3740
    int interleave;
3741
    int stride;
3742
    int size;
3743
    int reg;
3744
    int pass;
3745
    int load;
3746
    int shift;
3747
    int n;
3748
    TCGv addr;
3749
    TCGv tmp;
3750
    TCGv tmp2;
3751

    
3752
    if (!vfp_enabled(env))
3753
      return 1;
3754
    VFP_DREG_D(rd, insn);
3755
    rn = (insn >> 16) & 0xf;
3756
    rm = insn & 0xf;
3757
    load = (insn & (1 << 21)) != 0;
3758
    addr = new_tmp();
3759
    if ((insn & (1 << 23)) == 0) {
3760
        /* Load store all elements.  */
3761
        op = (insn >> 8) & 0xf;
3762
        size = (insn >> 6) & 3;
3763
        if (op > 10 || size == 3)
3764
            return 1;
3765
        nregs = neon_ls_element_type[op].nregs;
3766
        interleave = neon_ls_element_type[op].interleave;
3767
        tcg_gen_mov_i32(addr, cpu_R[rn]);
3768
        stride = (1 << size) * interleave;
3769
        for (reg = 0; reg < nregs; reg++) {
3770
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3771
                tcg_gen_addi_i32(addr, cpu_R[rn], (1 << size) * reg);
3772
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3773
                tcg_gen_addi_i32(addr, cpu_R[rn], 1 << size);
3774
            }
3775
            for (pass = 0; pass < 2; pass++) {
3776
                if (size == 2) {
3777
                    if (load) {
3778
                        tmp = gen_ld32(addr, IS_USER(s));
3779
                        neon_store_reg(rd, pass, tmp);
3780
                    } else {
3781
                        tmp = neon_load_reg(rd, pass);
3782
                        gen_st32(tmp, addr, IS_USER(s));
3783
                    }
3784
                    tcg_gen_addi_i32(addr, addr, stride);
3785
                } else if (size == 1) {
3786
                    if (load) {
3787
                        tmp = gen_ld16u(addr, IS_USER(s));
3788
                        tcg_gen_addi_i32(addr, addr, stride);
3789
                        tmp2 = gen_ld16u(addr, IS_USER(s));
3790
                        tcg_gen_addi_i32(addr, addr, stride);
3791
                        gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3792
                        dead_tmp(tmp2);
3793
                        neon_store_reg(rd, pass, tmp);
3794
                    } else {
3795
                        tmp = neon_load_reg(rd, pass);
3796
                        tmp2 = new_tmp();
3797
                        tcg_gen_shri_i32(tmp2, tmp, 16);
3798
                        gen_st16(tmp, addr, IS_USER(s));
3799
                        tcg_gen_addi_i32(addr, addr, stride);
3800
                        gen_st16(tmp2, addr, IS_USER(s));
3801
                        tcg_gen_addi_i32(addr, addr, stride);
3802
                    }
3803
                } else /* size == 0 */ {
3804
                    if (load) {
3805
                        TCGV_UNUSED(tmp2);
3806
                        for (n = 0; n < 4; n++) {
3807
                            tmp = gen_ld8u(addr, IS_USER(s));
3808
                            tcg_gen_addi_i32(addr, addr, stride);
3809
                            if (n == 0) {
3810
                                tmp2 = tmp;
3811
                            } else {
3812
                                gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3813
                                dead_tmp(tmp);
3814
                            }
3815
                        }
3816
                        neon_store_reg(rd, pass, tmp2);
3817
                    } else {
3818
                        tmp2 = neon_load_reg(rd, pass);
3819
                        for (n = 0; n < 4; n++) {
3820
                            tmp = new_tmp();
3821
                            if (n == 0) {
3822
                                tcg_gen_mov_i32(tmp, tmp2);
3823
                            } else {
3824
                                tcg_gen_shri_i32(tmp, tmp2, n * 8);
3825
                            }
3826
                            gen_st8(tmp, addr, IS_USER(s));
3827
                            tcg_gen_addi_i32(addr, addr, stride);
3828
                        }
3829
                        dead_tmp(tmp2);
3830
                    }
3831
                }
3832
            }
3833
            rd += neon_ls_element_type[op].spacing;
3834
        }
3835
        stride = nregs * 8;
3836
    } else {
3837
        size = (insn >> 10) & 3;
3838
        if (size == 3) {
3839
            /* Load single element to all lanes.  */
3840
            if (!load)
3841
                return 1;
3842
            size = (insn >> 6) & 3;
3843
            nregs = ((insn >> 8) & 3) + 1;
3844
            stride = (insn & (1 << 5)) ? 2 : 1;
3845
            tcg_gen_mov_i32(addr, cpu_R[rn]);
3846
            for (reg = 0; reg < nregs; reg++) {
3847
                switch (size) {
3848
                case 0:
3849
                    tmp = gen_ld8u(addr, IS_USER(s));
3850
                    gen_neon_dup_u8(tmp, 0);
3851
                    break;
3852
                case 1:
3853
                    tmp = gen_ld16u(addr, IS_USER(s));
3854
                    gen_neon_dup_low16(tmp);
3855
                    break;
3856
                case 2:
3857
                    tmp = gen_ld32(addr, IS_USER(s));
3858
                    break;
3859
                case 3:
3860
                    return 1;
3861
                default: /* Avoid compiler warnings.  */
3862
                    abort();
3863
                }
3864
                tcg_gen_addi_i32(addr, addr, 1 << size);
3865
                tmp2 = new_tmp();
3866
                tcg_gen_mov_i32(tmp2, tmp);
3867
                neon_store_reg(rd, 0, tmp2);
3868
                neon_store_reg(rd, 1, tmp);
3869
                rd += stride;
3870
            }
3871
            stride = (1 << size) * nregs;
3872
        } else {
3873
            /* Single element.  */
3874
            pass = (insn >> 7) & 1;
3875
            switch (size) {
3876
            case 0:
3877
                shift = ((insn >> 5) & 3) * 8;
3878
                stride = 1;
3879
                break;
3880
            case 1:
3881
                shift = ((insn >> 6) & 1) * 16;
3882
                stride = (insn & (1 << 5)) ? 2 : 1;
3883
                break;
3884
            case 2:
3885
                shift = 0;
3886
                stride = (insn & (1 << 6)) ? 2 : 1;
3887
                break;
3888
            default:
3889
                abort();
3890
            }
3891
            nregs = ((insn >> 8) & 3) + 1;
3892
            tcg_gen_mov_i32(addr, cpu_R[rn]);
3893
            for (reg = 0; reg < nregs; reg++) {
3894
                if (load) {
3895
                    switch (size) {
3896
                    case 0:
3897
                        tmp = gen_ld8u(addr, IS_USER(s));
3898
                        break;
3899
                    case 1:
3900
                        tmp = gen_ld16u(addr, IS_USER(s));
3901
                        break;
3902
                    case 2:
3903
                        tmp = gen_ld32(addr, IS_USER(s));
3904
                        break;
3905
                    default: /* Avoid compiler warnings.  */
3906
                        abort();
3907
                    }
3908
                    if (size != 2) {
3909
                        tmp2 = neon_load_reg(rd, pass);
3910
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3911
                        dead_tmp(tmp2);
3912
                    }
3913
                    neon_store_reg(rd, pass, tmp);
3914
                } else { /* Store */
3915
                    tmp = neon_load_reg(rd, pass);
3916
                    if (shift)
3917
                        tcg_gen_shri_i32(tmp, tmp, shift);
3918
                    switch (size) {
3919
                    case 0:
3920
                        gen_st8(tmp, addr, IS_USER(s));
3921
                        break;
3922
                    case 1:
3923
                        gen_st16(tmp, addr, IS_USER(s));
3924
                        break;
3925
                    case 2:
3926
                        gen_st32(tmp, addr, IS_USER(s));
3927
                        break;
3928
                    }
3929
                }
3930
                rd += stride;
3931
                tcg_gen_addi_i32(addr, addr, 1 << size);
3932
            }
3933
            stride = nregs * (1 << size);
3934
        }
3935
    }
3936
    dead_tmp(addr);
3937
    if (rm != 15) {
3938
        TCGv base;
3939

    
3940
        base = load_reg(s, rn);
3941
        if (rm == 13) {
3942
            tcg_gen_addi_i32(base, base, stride);
3943
        } else {
3944
            TCGv index;
3945
            index = load_reg(s, rm);
3946
            tcg_gen_add_i32(base, base, index);
3947
            dead_tmp(index);
3948
        }
3949
        store_reg(s, rn, base);
3950
    }
3951
    return 0;
3952
}
3953

    
3954
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3955
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3956
{
3957
    tcg_gen_and_i32(t, t, c);
3958
    tcg_gen_bic_i32(f, f, c);
3959
    tcg_gen_or_i32(dest, t, f);
3960
}
3961

    
3962
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
3963
{
3964
    switch (size) {
3965
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
3966
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
3967
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3968
    default: abort();
3969
    }
3970
}
3971

    
3972
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
3973
{
3974
    switch (size) {
3975
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3976
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3977
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3978
    default: abort();
3979
    }
3980
}
3981

    
3982
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
3983
{
3984
    switch (size) {
3985
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3986
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3987
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3988
    default: abort();
3989
    }
3990
}
3991

    
3992
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3993
                                         int q, int u)
3994
{
3995
    if (q) {
3996
        if (u) {
3997
            switch (size) {
3998
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3999
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4000
            default: abort();
4001
            }
4002
        } else {
4003
            switch (size) {
4004
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4005
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4006
            default: abort();
4007
            }
4008
        }
4009
    } else {
4010
        if (u) {
4011
            switch (size) {
4012
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4013
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4014
            default: abort();
4015
            }
4016
        } else {
4017
            switch (size) {
4018
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4019
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4020
            default: abort();
4021
            }
4022
        }
4023
    }
4024
}
4025

    
4026
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4027
{
4028
    if (u) {
4029
        switch (size) {
4030
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4031
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4032
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4033
        default: abort();
4034
        }
4035
    } else {
4036
        switch (size) {
4037
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4038
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4039
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4040
        default: abort();
4041
        }
4042
    }
4043
    dead_tmp(src);
4044
}
4045

    
4046
static inline void gen_neon_addl(int size)
4047
{
4048
    switch (size) {
4049
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4050
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4051
    case 2: tcg_gen_add_i64(CPU_V001); break;
4052
    default: abort();
4053
    }
4054
}
4055

    
4056
static inline void gen_neon_subl(int size)
4057
{
4058
    switch (size) {
4059
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4060
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4061
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4062
    default: abort();
4063
    }
4064
}
4065

    
4066
static inline void gen_neon_negl(TCGv_i64 var, int size)
4067
{
4068
    switch (size) {
4069
    case 0: gen_helper_neon_negl_u16(var, var); break;
4070
    case 1: gen_helper_neon_negl_u32(var, var); break;
4071
    case 2: gen_helper_neon_negl_u64(var, var); break;
4072
    default: abort();
4073
    }
4074
}
4075

    
4076
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4077
{
4078
    switch (size) {
4079
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4080
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4081
    default: abort();
4082
    }
4083
}
4084

    
4085
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4086
{
4087
    TCGv_i64 tmp;
4088

    
4089
    switch ((size << 1) | u) {
4090
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4091
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4092
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4093
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4094
    case 4:
4095
        tmp = gen_muls_i64_i32(a, b);
4096
        tcg_gen_mov_i64(dest, tmp);
4097
        break;
4098
    case 5:
4099
        tmp = gen_mulu_i64_i32(a, b);
4100
        tcg_gen_mov_i64(dest, tmp);
4101
        break;
4102
    default: abort();
4103
    }
4104
}
4105

    
4106
/* Translate a NEON data processing instruction.  Return nonzero if the
4107
   instruction is invalid.
4108
   We process data in a mixture of 32-bit and 64-bit chunks.
4109
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4110

    
4111
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4112
{
4113
    int op;
4114
    int q;
4115
    int rd, rn, rm;
4116
    int size;
4117
    int shift;
4118
    int pass;
4119
    int count;
4120
    int pairwise;
4121
    int u;
4122
    int n;
4123
    uint32_t imm;
4124
    TCGv tmp;
4125
    TCGv tmp2;
4126
    TCGv tmp3;
4127
    TCGv_i64 tmp64;
4128

    
4129
    if (!vfp_enabled(env))
4130
      return 1;
4131
    q = (insn & (1 << 6)) != 0;
4132
    u = (insn >> 24) & 1;
4133
    VFP_DREG_D(rd, insn);
4134
    VFP_DREG_N(rn, insn);
4135
    VFP_DREG_M(rm, insn);
4136
    size = (insn >> 20) & 3;
4137
    if ((insn & (1 << 23)) == 0) {
4138
        /* Three register same length.  */
4139
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4140
        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4141
                          || op == 10 || op  == 11 || op == 16)) {
4142
            /* 64-bit element instructions.  */
4143
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4144
                neon_load_reg64(cpu_V0, rn + pass);
4145
                neon_load_reg64(cpu_V1, rm + pass);
4146
                switch (op) {
4147
                case 1: /* VQADD */
4148
                    if (u) {
4149
                        gen_helper_neon_add_saturate_u64(CPU_V001);
4150
                    } else {
4151
                        gen_helper_neon_add_saturate_s64(CPU_V001);
4152
                    }
4153
                    break;
4154
                case 5: /* VQSUB */
4155
                    if (u) {
4156
                        gen_helper_neon_sub_saturate_u64(CPU_V001);
4157
                    } else {
4158
                        gen_helper_neon_sub_saturate_s64(CPU_V001);
4159
                    }
4160
                    break;
4161
                case 8: /* VSHL */
4162
                    if (u) {
4163
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4164
                    } else {
4165
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4166
                    }
4167
                    break;
4168
                case 9: /* VQSHL */
4169
                    if (u) {
4170
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4171
                                                 cpu_V0, cpu_V0);
4172
                    } else {
4173
                        gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4174
                                                 cpu_V1, cpu_V0);
4175
                    }
4176
                    break;
4177
                case 10: /* VRSHL */
4178
                    if (u) {
4179
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4180
                    } else {
4181
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4182
                    }
4183
                    break;
4184
                case 11: /* VQRSHL */
4185
                    if (u) {
4186
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4187
                                                  cpu_V1, cpu_V0);
4188
                    } else {
4189
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4190
                                                  cpu_V1, cpu_V0);
4191
                    }
4192
                    break;
4193
                case 16:
4194
                    if (u) {
4195
                        tcg_gen_sub_i64(CPU_V001);
4196
                    } else {
4197
                        tcg_gen_add_i64(CPU_V001);
4198
                    }
4199
                    break;
4200
                default:
4201
                    abort();
4202
                }
4203
                neon_store_reg64(cpu_V0, rd + pass);
4204
            }
4205
            return 0;
4206
        }
4207
        switch (op) {
4208
        case 8: /* VSHL */
4209
        case 9: /* VQSHL */
4210
        case 10: /* VRSHL */
4211
        case 11: /* VQRSHL */
4212
            {
4213
                int rtmp;
4214
                /* Shift instruction operands are reversed.  */
4215
                rtmp = rn;
4216
                rn = rm;
4217
                rm = rtmp;
4218
                pairwise = 0;
4219
            }
4220
            break;
4221
        case 20: /* VPMAX */
4222
        case 21: /* VPMIN */
4223
        case 23: /* VPADD */
4224
            pairwise = 1;
4225
            break;
4226
        case 26: /* VPADD (float) */
4227
            pairwise = (u && size < 2);
4228
            break;
4229
        case 30: /* VPMIN/VPMAX (float) */
4230
            pairwise = u;
4231
            break;
4232
        default:
4233
            pairwise = 0;
4234
            break;
4235
        }
4236

    
4237
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4238

    
4239
        if (pairwise) {
4240
            /* Pairwise.  */
4241
            if (q)
4242
                n = (pass & 1) * 2;
4243
            else
4244
                n = 0;
4245
            if (pass < q + 1) {
4246
                tmp = neon_load_reg(rn, n);
4247
                tmp2 = neon_load_reg(rn, n + 1);
4248
            } else {
4249
                tmp = neon_load_reg(rm, n);
4250
                tmp2 = neon_load_reg(rm, n + 1);
4251
            }
4252
        } else {
4253
            /* Elementwise.  */
4254
            tmp = neon_load_reg(rn, pass);
4255
            tmp2 = neon_load_reg(rm, pass);
4256
        }
4257
        switch (op) {
4258
        case 0: /* VHADD */
4259
            GEN_NEON_INTEGER_OP(hadd);
4260
            break;
4261
        case 1: /* VQADD */
4262
            GEN_NEON_INTEGER_OP_ENV(qadd);
4263
            break;
4264
        case 2: /* VRHADD */
4265
            GEN_NEON_INTEGER_OP(rhadd);
4266
            break;
4267
        case 3: /* Logic ops.  */
4268
            switch ((u << 2) | size) {
4269
            case 0: /* VAND */
4270
                tcg_gen_and_i32(tmp, tmp, tmp2);
4271
                break;
4272
            case 1: /* BIC */
4273
                tcg_gen_bic_i32(tmp, tmp, tmp2);
4274
                break;
4275
            case 2: /* VORR */
4276
                tcg_gen_or_i32(tmp, tmp, tmp2);
4277
                break;
4278
            case 3: /* VORN */
4279
                tcg_gen_not_i32(tmp2, tmp2);
4280
                tcg_gen_or_i32(tmp, tmp, tmp2);
4281
                break;
4282
            case 4: /* VEOR */
4283
                tcg_gen_xor_i32(tmp, tmp, tmp2);
4284
                break;
4285
            case 5: /* VBSL */
4286
                tmp3 = neon_load_reg(rd, pass);
4287
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4288
                dead_tmp(tmp3);
4289
                break;
4290
            case 6: /* VBIT */
4291
                tmp3 = neon_load_reg(rd, pass);
4292
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4293
                dead_tmp(tmp3);
4294
                break;
4295
            case 7: /* VBIF */
4296
                tmp3 = neon_load_reg(rd, pass);
4297
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4298
                dead_tmp(tmp3);
4299
                break;
4300
            }
4301
            break;
4302
        case 4: /* VHSUB */
4303
            GEN_NEON_INTEGER_OP(hsub);
4304
            break;
4305
        case 5: /* VQSUB */
4306
            GEN_NEON_INTEGER_OP_ENV(qsub);
4307
            break;
4308
        case 6: /* VCGT */
4309
            GEN_NEON_INTEGER_OP(cgt);
4310
            break;
4311
        case 7: /* VCGE */
4312
            GEN_NEON_INTEGER_OP(cge);
4313
            break;
4314
        case 8: /* VSHL */
4315
            GEN_NEON_INTEGER_OP(shl);
4316
            break;
4317
        case 9: /* VQSHL */
4318
            GEN_NEON_INTEGER_OP_ENV(qshl);
4319
            break;
4320
        case 10: /* VRSHL */
4321
            GEN_NEON_INTEGER_OP(rshl);
4322
            break;
4323
        case 11: /* VQRSHL */
4324
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4325
            break;
4326
        case 12: /* VMAX */
4327
            GEN_NEON_INTEGER_OP(max);
4328
            break;
4329
        case 13: /* VMIN */
4330
            GEN_NEON_INTEGER_OP(min);
4331
            break;
4332
        case 14: /* VABD */
4333
            GEN_NEON_INTEGER_OP(abd);
4334
            break;
4335
        case 15: /* VABA */
4336
            GEN_NEON_INTEGER_OP(abd);
4337
            dead_tmp(tmp2);
4338
            tmp2 = neon_load_reg(rd, pass);
4339
            gen_neon_add(size, tmp, tmp2);
4340
            break;
4341
        case 16:
4342
            if (!u) { /* VADD */
4343
                if (gen_neon_add(size, tmp, tmp2))
4344
                    return 1;
4345
            } else { /* VSUB */
4346
                switch (size) {
4347
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4348
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4349
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4350
                default: return 1;
4351
                }
4352
            }
4353
            break;
4354
        case 17:
4355
            if (!u) { /* VTST */
4356
                switch (size) {
4357
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4358
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4359
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4360
                default: return 1;
4361
                }
4362
            } else { /* VCEQ */
4363
                switch (size) {
4364
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4365
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4366
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4367
                default: return 1;
4368
                }
4369
            }
4370
            break;
4371
        case 18: /* Multiply.  */
4372
            switch (size) {
4373
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4374
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4375
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4376
            default: return 1;
4377
            }
4378
            dead_tmp(tmp2);
4379
            tmp2 = neon_load_reg(rd, pass);
4380
            if (u) { /* VMLS */
4381
                gen_neon_rsb(size, tmp, tmp2);
4382
            } else { /* VMLA */
4383
                gen_neon_add(size, tmp, tmp2);
4384
            }
4385
            break;
4386
        case 19: /* VMUL */
4387
            if (u) { /* polynomial */
4388
                gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4389
            } else { /* Integer */
4390
                switch (size) {
4391
                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4392
                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4393
                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4394
                default: return 1;
4395
                }
4396
            }
4397
            break;
4398
        case 20: /* VPMAX */
4399
            GEN_NEON_INTEGER_OP(pmax);
4400
            break;
4401
        case 21: /* VPMIN */
4402
            GEN_NEON_INTEGER_OP(pmin);
4403
            break;
4404
        case 22: /* Hultiply high.  */
4405
            if (!u) { /* VQDMULH */
4406
                switch (size) {
4407
                case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4408
                case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4409
                default: return 1;
4410
                }
4411
            } else { /* VQRDHMUL */
4412
                switch (size) {
4413
                case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4414
                case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4415
                default: return 1;
4416
                }
4417
            }
4418
            break;
4419
        case 23: /* VPADD */
4420
            if (u)
4421
                return 1;
4422
            switch (size) {
4423
            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4424
            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4425
            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4426
            default: return 1;
4427
            }
4428
            break;
4429
        case 26: /* Floating point arithnetic.  */
4430
            switch ((u << 2) | size) {
4431
            case 0: /* VADD */
4432
                gen_helper_neon_add_f32(tmp, tmp, tmp2);
4433
                break;
4434
            case 2: /* VSUB */
4435
                gen_helper_neon_sub_f32(tmp, tmp, tmp2);
4436
                break;
4437
            case 4: /* VPADD */
4438
                gen_helper_neon_add_f32(tmp, tmp, tmp2);
4439
                break;
4440
            case 6: /* VABD */
4441
                gen_helper_neon_abd_f32(tmp, tmp, tmp2);
4442
                break;
4443
            default:
4444
                return 1;
4445
            }
4446
            break;
4447
        case 27: /* Float multiply.  */
4448
            gen_helper_neon_mul_f32(tmp, tmp, tmp2);
4449
            if (!u) {
4450
                dead_tmp(tmp2);
4451
                tmp2 = neon_load_reg(rd, pass);
4452
                if (size == 0) {
4453
                    gen_helper_neon_add_f32(tmp, tmp, tmp2);
4454
                } else {
4455
                    gen_helper_neon_sub_f32(tmp, tmp2, tmp);
4456
                }
4457
            }
4458
            break;
4459
        case 28: /* Float compare.  */
4460
            if (!u) {
4461
                gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
4462
            } else {
4463
                if (size == 0)
4464
                    gen_helper_neon_cge_f32(tmp, tmp, tmp2);
4465
                else
4466
                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
4467
            }
4468
            break;
4469
        case 29: /* Float compare absolute.  */
4470
            if (!u)
4471
                return 1;
4472
            if (size == 0)
4473
                gen_helper_neon_acge_f32(tmp, tmp, tmp2);
4474
            else
4475
                gen_helper_neon_acgt_f32(tmp, tmp, tmp2);
4476
            break;
4477
        case 30: /* Float min/max.  */
4478
            if (size == 0)
4479
                gen_helper_neon_max_f32(tmp, tmp, tmp2);
4480
            else
4481
                gen_helper_neon_min_f32(tmp, tmp, tmp2);
4482
            break;
4483
        case 31:
4484
            if (size == 0)
4485
                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4486
            else
4487
                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4488
            break;
4489
        default:
4490
            abort();
4491
        }
4492
        dead_tmp(tmp2);
4493

    
4494
        /* Save the result.  For elementwise operations we can put it
4495
           straight into the destination register.  For pairwise operations
4496
           we have to be careful to avoid clobbering the source operands.  */
4497
        if (pairwise && rd == rm) {
4498
            neon_store_scratch(pass, tmp);
4499
        } else {
4500
            neon_store_reg(rd, pass, tmp);
4501
        }
4502

    
4503
        } /* for pass */
4504
        if (pairwise && rd == rm) {
4505
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4506
                tmp = neon_load_scratch(pass);
4507
                neon_store_reg(rd, pass, tmp);
4508
            }
4509
        }
4510
        /* End of 3 register same size operations.  */
4511
    } else if (insn & (1 << 4)) {
4512
        if ((insn & 0x00380080) != 0) {
4513
            /* Two registers and shift.  */
4514
            op = (insn >> 8) & 0xf;
4515
            if (insn & (1 << 7)) {
4516
                /* 64-bit shift.   */
4517
                size = 3;
4518
            } else {
4519
                size = 2;
4520
                while ((insn & (1 << (size + 19))) == 0)
4521
                    size--;
4522
            }
4523
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4524
            /* To avoid excessive dumplication of ops we implement shift
4525
               by immediate using the variable shift operations.  */
4526
            if (op < 8) {
4527
                /* Shift by immediate:
4528
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4529
                /* Right shifts are encoded as N - shift, where N is the
4530
                   element size in bits.  */
4531
                if (op <= 4)
4532
                    shift = shift - (1 << (size + 3));
4533
                if (size == 3) {
4534
                    count = q + 1;
4535
                } else {
4536
                    count = q ? 4: 2;
4537
                }
4538
                switch (size) {
4539
                case 0:
4540
                    imm = (uint8_t) shift;
4541
                    imm |= imm << 8;
4542
                    imm |= imm << 16;
4543
                    break;
4544
                case 1:
4545
                    imm = (uint16_t) shift;
4546
                    imm |= imm << 16;
4547
                    break;
4548
                case 2:
4549
                case 3:
4550
                    imm = shift;
4551
                    break;
4552
                default:
4553
                    abort();
4554
                }
4555

    
4556
                for (pass = 0; pass < count; pass++) {
4557
                    if (size == 3) {
4558
                        neon_load_reg64(cpu_V0, rm + pass);
4559
                        tcg_gen_movi_i64(cpu_V1, imm);
4560
                        switch (op) {
4561
                        case 0:  /* VSHR */
4562
                        case 1:  /* VSRA */
4563
                            if (u)
4564
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4565
                            else
4566
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4567
                            break;
4568
                        case 2: /* VRSHR */
4569
                        case 3: /* VRSRA */
4570
                            if (u)
4571
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4572
                            else
4573
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4574
                            break;
4575
                        case 4: /* VSRI */
4576
                            if (!u)
4577
                                return 1;
4578
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4579
                            break;
4580
                        case 5: /* VSHL, VSLI */
4581
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4582
                            break;
4583
                        case 6: /* VQSHL */
4584
                            if (u)
4585
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4586
                            else
4587
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4588
                            break;
4589
                        case 7: /* VQSHLU */
4590
                            gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4591
                            break;
4592
                        }
4593
                        if (op == 1 || op == 3) {
4594
                            /* Accumulate.  */
4595
                            neon_load_reg64(cpu_V0, rd + pass);
4596
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4597
                        } else if (op == 4 || (op == 5 && u)) {
4598
                            /* Insert */
4599
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4600
                        }
4601
                        neon_store_reg64(cpu_V0, rd + pass);
4602
                    } else { /* size < 3 */
4603
                        /* Operands in T0 and T1.  */
4604
                        tmp = neon_load_reg(rm, pass);
4605
                        tmp2 = new_tmp();
4606
                        tcg_gen_movi_i32(tmp2, imm);
4607
                        switch (op) {
4608
                        case 0:  /* VSHR */
4609
                        case 1:  /* VSRA */
4610
                            GEN_NEON_INTEGER_OP(shl);
4611
                            break;
4612
                        case 2: /* VRSHR */
4613
                        case 3: /* VRSRA */
4614
                            GEN_NEON_INTEGER_OP(rshl);
4615
                            break;
4616
                        case 4: /* VSRI */
4617
                            if (!u)
4618
                                return 1;
4619
                            GEN_NEON_INTEGER_OP(shl);
4620
                            break;
4621
                        case 5: /* VSHL, VSLI */
4622
                            switch (size) {
4623
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4624
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4625
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4626
                            default: return 1;
4627
                            }
4628
                            break;
4629
                        case 6: /* VQSHL */
4630
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4631
                            break;
4632
                        case 7: /* VQSHLU */
4633
                            switch (size) {
4634
                            case 0: gen_helper_neon_qshl_u8(tmp, cpu_env, tmp, tmp2); break;
4635
                            case 1: gen_helper_neon_qshl_u16(tmp, cpu_env, tmp, tmp2); break;
4636
                            case 2: gen_helper_neon_qshl_u32(tmp, cpu_env, tmp, tmp2); break;
4637
                            default: return 1;
4638
                            }
4639
                            break;
4640
                        }
4641
                        dead_tmp(tmp2);
4642

    
4643
                        if (op == 1 || op == 3) {
4644
                            /* Accumulate.  */
4645
                            tmp2 = neon_load_reg(rd, pass);
4646
                            gen_neon_add(size, tmp2, tmp);
4647
                            dead_tmp(tmp2);
4648
                        } else if (op == 4 || (op == 5 && u)) {
4649
                            /* Insert */
4650
                            switch (size) {
4651
                            case 0:
4652
                                if (op == 4)
4653
                                    imm = 0xff >> -shift;
4654
                                else
4655
                                    imm = (uint8_t)(0xff << shift);
4656
                                imm |= imm << 8;
4657
                                imm |= imm << 16;
4658
                                break;
4659
                            case 1:
4660
                                if (op == 4)
4661
                                    imm = 0xffff >> -shift;
4662
                                else
4663
                                    imm = (uint16_t)(0xffff << shift);
4664
                                imm |= imm << 16;
4665
                                break;
4666
                            case 2:
4667
                                if (op == 4)
4668
                                    imm = 0xffffffffu >> -shift;
4669
                                else
4670
                                    imm = 0xffffffffu << shift;
4671
                                break;
4672
                            default:
4673
                                abort();
4674
                            }
4675
                            tmp2 = neon_load_reg(rd, pass);
4676
                            tcg_gen_andi_i32(tmp, tmp, imm);
4677
                            tcg_gen_andi_i32(tmp2, tmp2, ~imm);
4678
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4679
                            dead_tmp(tmp2);
4680
                        }
4681
                        neon_store_reg(rd, pass, tmp);
4682
                    }
4683
                } /* for pass */
4684
            } else if (op < 10) {
4685
                /* Shift by immediate and narrow:
4686
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4687
                shift = shift - (1 << (size + 3));
4688
                size++;
4689
                switch (size) {
4690
                case 1:
4691
                    imm = (uint16_t)shift;
4692
                    imm |= imm << 16;
4693
                    tmp2 = tcg_const_i32(imm);
4694
                    TCGV_UNUSED_I64(tmp64);
4695
                    break;
4696
                case 2:
4697
                    imm = (uint32_t)shift;
4698
                    tmp2 = tcg_const_i32(imm);
4699
                    TCGV_UNUSED_I64(tmp64);
4700
                    break;
4701
                case 3:
4702
                    tmp64 = tcg_const_i64(shift);
4703
                    TCGV_UNUSED(tmp2);
4704
                    break;
4705
                default:
4706
                    abort();
4707
                }
4708

    
4709
                for (pass = 0; pass < 2; pass++) {
4710
                    if (size == 3) {
4711
                        neon_load_reg64(cpu_V0, rm + pass);
4712
                        if (q) {
4713
                          if (u)
4714
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4715
                          else
4716
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4717
                        } else {
4718
                          if (u)
4719
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4720
                          else
4721
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4722
                        }
4723
                    } else {
4724
                        tmp = neon_load_reg(rm + pass, 0);
4725
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4726
                        tmp3 = neon_load_reg(rm + pass, 1);
4727
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4728
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4729
                        dead_tmp(tmp);
4730
                        dead_tmp(tmp3);
4731
                    }
4732
                    tmp = new_tmp();
4733
                    if (op == 8 && !u) {
4734
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4735
                    } else {
4736
                        if (op == 8)
4737
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4738
                        else
4739
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4740
                    }
4741
                    if (pass == 0) {
4742
                        tmp2 = tmp;
4743
                    } else {
4744
                        neon_store_reg(rd, 0, tmp2);
4745
                        neon_store_reg(rd, 1, tmp);
4746
                    }
4747
                } /* for pass */
4748
            } else if (op == 10) {
4749
                /* VSHLL */
4750
                if (q || size == 3)
4751
                    return 1;
4752
                tmp = neon_load_reg(rm, 0);
4753
                tmp2 = neon_load_reg(rm, 1);
4754
                for (pass = 0; pass < 2; pass++) {
4755
                    if (pass == 1)
4756
                        tmp = tmp2;
4757

    
4758
                    gen_neon_widen(cpu_V0, tmp, size, u);
4759

    
4760
                    if (shift != 0) {
4761
                        /* The shift is less than the width of the source
4762
                           type, so we can just shift the whole register.  */
4763
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4764
                        if (size < 2 || !u) {
4765
                            uint64_t imm64;
4766
                            if (size == 0) {
4767
                                imm = (0xffu >> (8 - shift));
4768
                                imm |= imm << 16;
4769
                            } else {
4770
                                imm = 0xffff >> (16 - shift);
4771
                            }
4772
                            imm64 = imm | (((uint64_t)imm) << 32);
4773
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4774
                        }
4775
                    }
4776
                    neon_store_reg64(cpu_V0, rd + pass);
4777
                }
4778
            } else if (op == 15 || op == 16) {
4779
                /* VCVT fixed-point.  */
4780
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4781
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4782
                    if (op & 1) {
4783
                        if (u)
4784
                            gen_vfp_ulto(0, shift);
4785
                        else
4786
                            gen_vfp_slto(0, shift);
4787
                    } else {
4788
                        if (u)
4789
                            gen_vfp_toul(0, shift);
4790
                        else
4791
                            gen_vfp_tosl(0, shift);
4792
                    }
4793
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4794
                }
4795
            } else {
4796
                return 1;
4797
            }
4798
        } else { /* (insn & 0x00380080) == 0 */
4799
            int invert;
4800

    
4801
            op = (insn >> 8) & 0xf;
4802
            /* One register and immediate.  */
4803
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4804
            invert = (insn & (1 << 5)) != 0;
4805
            switch (op) {
4806
            case 0: case 1:
4807
                /* no-op */
4808
                break;
4809
            case 2: case 3:
4810
                imm <<= 8;
4811
                break;
4812
            case 4: case 5:
4813
                imm <<= 16;
4814
                break;
4815
            case 6: case 7:
4816
                imm <<= 24;
4817
                break;
4818
            case 8: case 9:
4819
                imm |= imm << 16;
4820
                break;
4821
            case 10: case 11:
4822
                imm = (imm << 8) | (imm << 24);
4823
                break;
4824
            case 12:
4825
                imm = (imm < 8) | 0xff;
4826
                break;
4827
            case 13:
4828
                imm = (imm << 16) | 0xffff;
4829
                break;
4830
            case 14:
4831
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4832
                if (invert)
4833
                    imm = ~imm;
4834
                break;
4835
            case 15:
4836
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4837
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4838
                break;
4839
            }
4840
            if (invert)
4841
                imm = ~imm;
4842

    
4843
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4844
                if (op & 1 && op < 12) {
4845
                    tmp = neon_load_reg(rd, pass);
4846
                    if (invert) {
4847
                        /* The immediate value has already been inverted, so
4848
                           BIC becomes AND.  */
4849
                        tcg_gen_andi_i32(tmp, tmp, imm);
4850
                    } else {
4851
                        tcg_gen_ori_i32(tmp, tmp, imm);
4852
                    }
4853
                } else {
4854
                    /* VMOV, VMVN.  */
4855
                    tmp = new_tmp();
4856
                    if (op == 14 && invert) {
4857
                        uint32_t val;
4858
                        val = 0;
4859
                        for (n = 0; n < 4; n++) {
4860
                            if (imm & (1 << (n + (pass & 1) * 4)))
4861
                                val |= 0xff << (n * 8);
4862
                        }
4863
                        tcg_gen_movi_i32(tmp, val);
4864
                    } else {
4865
                        tcg_gen_movi_i32(tmp, imm);
4866
                    }
4867
                }
4868
                neon_store_reg(rd, pass, tmp);
4869
            }
4870
        }
4871
    } else { /* (insn & 0x00800010 == 0x00800000) */
4872
        if (size != 3) {
4873
            op = (insn >> 8) & 0xf;
4874
            if ((insn & (1 << 6)) == 0) {
4875
                /* Three registers of different lengths.  */
4876
                int src1_wide;
4877
                int src2_wide;
4878
                int prewiden;
4879
                /* prewiden, src1_wide, src2_wide */
4880
                static const int neon_3reg_wide[16][3] = {
4881
                    {1, 0, 0}, /* VADDL */
4882
                    {1, 1, 0}, /* VADDW */
4883
                    {1, 0, 0}, /* VSUBL */
4884
                    {1, 1, 0}, /* VSUBW */
4885
                    {0, 1, 1}, /* VADDHN */
4886
                    {0, 0, 0}, /* VABAL */
4887
                    {0, 1, 1}, /* VSUBHN */
4888
                    {0, 0, 0}, /* VABDL */
4889
                    {0, 0, 0}, /* VMLAL */
4890
                    {0, 0, 0}, /* VQDMLAL */
4891
                    {0, 0, 0}, /* VMLSL */
4892
                    {0, 0, 0}, /* VQDMLSL */
4893
                    {0, 0, 0}, /* Integer VMULL */
4894
                    {0, 0, 0}, /* VQDMULL */
4895
                    {0, 0, 0}  /* Polynomial VMULL */
4896
                };
4897

    
4898
                prewiden = neon_3reg_wide[op][0];
4899
                src1_wide = neon_3reg_wide[op][1];
4900
                src2_wide = neon_3reg_wide[op][2];
4901

    
4902
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4903
                    return 1;
4904

    
4905
                /* Avoid overlapping operands.  Wide source operands are
4906
                   always aligned so will never overlap with wide
4907
                   destinations in problematic ways.  */
4908
                if (rd == rm && !src2_wide) {
4909
                    tmp = neon_load_reg(rm, 1);
4910
                    neon_store_scratch(2, tmp);
4911
                } else if (rd == rn && !src1_wide) {
4912
                    tmp = neon_load_reg(rn, 1);
4913
                    neon_store_scratch(2, tmp);
4914
                }
4915
                TCGV_UNUSED(tmp3);
4916
                for (pass = 0; pass < 2; pass++) {
4917
                    if (src1_wide) {
4918
                        neon_load_reg64(cpu_V0, rn + pass);
4919
                        TCGV_UNUSED(tmp);
4920
                    } else {
4921
                        if (pass == 1 && rd == rn) {
4922
                            tmp = neon_load_scratch(2);
4923
                        } else {
4924
                            tmp = neon_load_reg(rn, pass);
4925
                        }
4926
                        if (prewiden) {
4927
                            gen_neon_widen(cpu_V0, tmp, size, u);
4928
                        }
4929
                    }
4930
                    if (src2_wide) {
4931
                        neon_load_reg64(cpu_V1, rm + pass);
4932
                        TCGV_UNUSED(tmp2);
4933
                    } else {
4934
                        if (pass == 1 && rd == rm) {
4935
                            tmp2 = neon_load_scratch(2);
4936
                        } else {
4937
                            tmp2 = neon_load_reg(rm, pass);
4938
                        }
4939
                        if (prewiden) {
4940
                            gen_neon_widen(cpu_V1, tmp2, size, u);
4941
                        }
4942
                    }
4943
                    switch (op) {
4944
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4945
                        gen_neon_addl(size);
4946
                        break;
4947
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4948
                        gen_neon_subl(size);
4949
                        break;
4950
                    case 5: case 7: /* VABAL, VABDL */
4951
                        switch ((size << 1) | u) {
4952
                        case 0:
4953
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4954
                            break;
4955
                        case 1:
4956
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4957
                            break;
4958
                        case 2:
4959
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4960
                            break;
4961
                        case 3:
4962
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4963
                            break;
4964
                        case 4:
4965
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4966
                            break;
4967
                        case 5:
4968
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4969
                            break;
4970
                        default: abort();
4971
                        }
4972
                        dead_tmp(tmp2);
4973
                        dead_tmp(tmp);
4974
                        break;
4975
                    case 8: case 9: case 10: case 11: case 12: case 13:
4976
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4977
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4978
                        dead_tmp(tmp2);
4979
                        dead_tmp(tmp);
4980
                        break;
4981
                    case 14: /* Polynomial VMULL */
4982
                        cpu_abort(env, "Polynomial VMULL not implemented");
4983

    
4984
                    default: /* 15 is RESERVED.  */
4985
                        return 1;
4986
                    }
4987
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4988
                        /* Accumulate.  */
4989
                        if (op == 10 || op == 11) {
4990
                            gen_neon_negl(cpu_V0, size);
4991
                        }
4992

    
4993
                        if (op != 13) {
4994
                            neon_load_reg64(cpu_V1, rd + pass);
4995
                        }
4996

    
4997
                        switch (op) {
4998
                        case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4999
                            gen_neon_addl(size);
5000
                            break;
5001
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5002
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5003
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5004
                            break;
5005
                            /* Fall through.  */
5006
                        case 13: /* VQDMULL */
5007
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5008
                            break;
5009
                        default:
5010
                            abort();
5011
                        }
5012
                        neon_store_reg64(cpu_V0, rd + pass);
5013
                    } else if (op == 4 || op == 6) {
5014
                        /* Narrowing operation.  */
5015
                        tmp = new_tmp();
5016
                        if (u) {
5017
                            switch (size) {
5018
                            case 0:
5019
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5020
                                break;
5021
                            case 1:
5022
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5023
                                break;
5024
                            case 2:
5025
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5026
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5027
                                break;
5028
                            default: abort();
5029
                            }
5030
                        } else {
5031
                            switch (size) {
5032
                            case 0:
5033
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5034
                                break;
5035
                            case 1:
5036
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5037
                                break;
5038
                            case 2:
5039
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5040
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5041
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5042
                                break;
5043
                            default: abort();
5044
                            }
5045
                        }
5046
                        if (pass == 0) {
5047
                            tmp3 = tmp;
5048
                        } else {
5049
                            neon_store_reg(rd, 0, tmp3);
5050
                            neon_store_reg(rd, 1, tmp);
5051
                        }
5052
                    } else {
5053
                        /* Write back the result.  */
5054
                        neon_store_reg64(cpu_V0, rd + pass);
5055
                    }
5056
                }
5057
            } else {
5058
                /* Two registers and a scalar.  */
5059
                switch (op) {
5060
                case 0: /* Integer VMLA scalar */
5061
                case 1: /* Float VMLA scalar */
5062
                case 4: /* Integer VMLS scalar */
5063
                case 5: /* Floating point VMLS scalar */
5064
                case 8: /* Integer VMUL scalar */
5065
                case 9: /* Floating point VMUL scalar */
5066
                case 12: /* VQDMULH scalar */
5067
                case 13: /* VQRDMULH scalar */
5068
                    tmp = neon_get_scalar(size, rm);
5069
                    neon_store_scratch(0, tmp);
5070
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5071
                        tmp = neon_load_scratch(0);
5072
                        tmp2 = neon_load_reg(rn, pass);
5073
                        if (op == 12) {
5074
                            if (size == 1) {
5075
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5076
                            } else {
5077
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5078
                            }
5079
                        } else if (op == 13) {
5080
                            if (size == 1) {
5081
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5082
                            } else {
5083
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5084
                            }
5085
                        } else if (op & 1) {
5086
                            gen_helper_neon_mul_f32(tmp, tmp, tmp2);
5087
                        } else {
5088
                            switch (size) {
5089
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5090
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5091
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5092
                            default: return 1;
5093
                            }
5094
                        }
5095
                        dead_tmp(tmp2);
5096
                        if (op < 8) {
5097
                            /* Accumulate.  */
5098
                            tmp2 = neon_load_reg(rd, pass);
5099
                            switch (op) {
5100
                            case 0:
5101
                                gen_neon_add(size, tmp, tmp2);
5102
                                break;
5103
                            case 1:
5104
                                gen_helper_neon_add_f32(tmp, tmp, tmp2);
5105
                                break;
5106
                            case 4:
5107
                                gen_neon_rsb(size, tmp, tmp2);
5108
                                break;
5109
                            case 5:
5110
                                gen_helper_neon_sub_f32(tmp, tmp2, tmp);
5111
                                break;
5112
                            default:
5113
                                abort();
5114
                            }
5115
                            dead_tmp(tmp2);
5116
                        }
5117
                        neon_store_reg(rd, pass, tmp);
5118
                    }
5119
                    break;
5120
                case 2: /* VMLAL sclar */
5121
                case 3: /* VQDMLAL scalar */
5122
                case 6: /* VMLSL scalar */
5123
                case 7: /* VQDMLSL scalar */
5124
                case 10: /* VMULL scalar */
5125
                case 11: /* VQDMULL scalar */
5126
                    if (size == 0 && (op == 3 || op == 7 || op == 11))
5127
                        return 1;
5128

    
5129
                    tmp2 = neon_get_scalar(size, rm);
5130
                    tmp3 = neon_load_reg(rn, 1);
5131

    
5132
                    for (pass = 0; pass < 2; pass++) {
5133
                        if (pass == 0) {
5134
                            tmp = neon_load_reg(rn, 0);
5135
                        } else {
5136
                            tmp = tmp3;
5137
                        }
5138
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5139
                        dead_tmp(tmp);
5140
                        if (op == 6 || op == 7) {
5141
                            gen_neon_negl(cpu_V0, size);
5142
                        }
5143
                        if (op != 11) {
5144
                            neon_load_reg64(cpu_V1, rd + pass);
5145
                        }
5146
                        switch (op) {
5147
                        case 2: case 6:
5148
                            gen_neon_addl(size);
5149
                            break;
5150
                        case 3: case 7:
5151
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5152
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5153
                            break;
5154
                        case 10:
5155
                            /* no-op */
5156
                            break;
5157
                        case 11:
5158
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5159
                            break;
5160
                        default:
5161
                            abort();
5162
                        }
5163
                        neon_store_reg64(cpu_V0, rd + pass);
5164
                    }
5165

    
5166
                    dead_tmp(tmp2);
5167

    
5168
                    break;
5169
                default: /* 14 and 15 are RESERVED */
5170
                    return 1;
5171
                }
5172
            }
5173
        } else { /* size == 3 */
5174
            if (!u) {
5175
                /* Extract.  */
5176
                imm = (insn >> 8) & 0xf;
5177
                count = q + 1;
5178

    
5179
                if (imm > 7 && !q)
5180
                    return 1;
5181

    
5182
                if (imm == 0) {
5183
                    neon_load_reg64(cpu_V0, rn);
5184
                    if (q) {
5185
                        neon_load_reg64(cpu_V1, rn + 1);
5186
                    }
5187
                } else if (imm == 8) {
5188
                    neon_load_reg64(cpu_V0, rn + 1);
5189
                    if (q) {
5190
                        neon_load_reg64(cpu_V1, rm);
5191
                    }
5192
                } else if (q) {
5193
                    tmp64 = tcg_temp_new_i64();
5194
                    if (imm < 8) {
5195
                        neon_load_reg64(cpu_V0, rn);
5196
                        neon_load_reg64(tmp64, rn + 1);
5197
                    } else {
5198
                        neon_load_reg64(cpu_V0, rn + 1);
5199
                        neon_load_reg64(tmp64, rm);
5200
                    }
5201
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5202
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5203
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5204
                    if (imm < 8) {
5205
                        neon_load_reg64(cpu_V1, rm);
5206
                    } else {
5207
                        neon_load_reg64(cpu_V1, rm + 1);
5208
                        imm -= 8;
5209
                    }
5210
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5211
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5212
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5213
                } else {
5214
                    /* BUGFIX */
5215
                    neon_load_reg64(cpu_V0, rn);
5216
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5217
                    neon_load_reg64(cpu_V1, rm);
5218
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5219
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5220
                }
5221
                neon_store_reg64(cpu_V0, rd);
5222
                if (q) {
5223
                    neon_store_reg64(cpu_V1, rd + 1);
5224
                }
5225
            } else if ((insn & (1 << 11)) == 0) {
5226
                /* Two register misc.  */
5227
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5228
                size = (insn >> 18) & 3;
5229
                switch (op) {
5230
                case 0: /* VREV64 */
5231
                    if (size == 3)
5232
                        return 1;
5233
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
5234
                        tmp = neon_load_reg(rm, pass * 2);
5235
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
5236
                        switch (size) {
5237
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5238
                        case 1: gen_swap_half(tmp); break;
5239
                        case 2: /* no-op */ break;
5240
                        default: abort();
5241
                        }
5242
                        neon_store_reg(rd, pass * 2 + 1, tmp);
5243
                        if (size == 2) {
5244
                            neon_store_reg(rd, pass * 2, tmp2);
5245
                        } else {
5246
                            switch (size) {
5247
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5248
                            case 1: gen_swap_half(tmp2); break;
5249
                            default: abort();
5250
                            }
5251
                            neon_store_reg(rd, pass * 2, tmp2);
5252
                        }
5253
                    }
5254
                    break;
5255
                case 4: case 5: /* VPADDL */
5256
                case 12: case 13: /* VPADAL */
5257
                    if (size == 3)
5258
                        return 1;
5259
                    for (pass = 0; pass < q + 1; pass++) {
5260
                        tmp = neon_load_reg(rm, pass * 2);
5261
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
5262
                        tmp = neon_load_reg(rm, pass * 2 + 1);
5263
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
5264
                        switch (size) {
5265
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5266
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5267
                        case 2: tcg_gen_add_i64(CPU_V001); break;
5268
                        default: abort();
5269
                        }
5270
                        if (op >= 12) {
5271
                            /* Accumulate.  */
5272
                            neon_load_reg64(cpu_V1, rd + pass);
5273
                            gen_neon_addl(size);
5274
                        }
5275
                        neon_store_reg64(cpu_V0, rd + pass);
5276
                    }
5277
                    break;
5278
                case 33: /* VTRN */
5279
                    if (size == 2) {
5280
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
5281
                            tmp = neon_load_reg(rm, n);
5282
                            tmp2 = neon_load_reg(rd, n + 1);
5283
                            neon_store_reg(rm, n, tmp2);
5284
                            neon_store_reg(rd, n + 1, tmp);
5285
                        }
5286
                    } else {
5287
                        goto elementwise;
5288
                    }
5289
                    break;
5290
                case 34: /* VUZP */
5291
                    /* Reg  Before       After
5292
                       Rd   A3 A2 A1 A0  B2 B0 A2 A0
5293
                       Rm   B3 B2 B1 B0  B3 B1 A3 A1
5294
                     */
5295
                    if (size == 3)
5296
                        return 1;
5297
                    gen_neon_unzip(rd, q, 0, size);
5298
                    gen_neon_unzip(rm, q, 4, size);
5299
                    if (q) {
5300
                        static int unzip_order_q[8] =
5301
                            {0, 2, 4, 6, 1, 3, 5, 7};
5302
                        for (n = 0; n < 8; n++) {
5303
                            int reg = (n < 4) ? rd : rm;
5304
                            tmp = neon_load_scratch(unzip_order_q[n]);
5305
                            neon_store_reg(reg, n % 4, tmp);
5306
                        }
5307
                    } else {
5308
                        static int unzip_order[4] =
5309
                            {0, 4, 1, 5};
5310
                        for (n = 0; n < 4; n++) {
5311
                            int reg = (n < 2) ? rd : rm;
5312
                            tmp = neon_load_scratch(unzip_order[n]);
5313
                            neon_store_reg(reg, n % 2, tmp);
5314
                        }
5315
                    }
5316
                    break;
5317
                case 35: /* VZIP */
5318
                    /* Reg  Before       After
5319
                       Rd   A3 A2 A1 A0  B1 A1 B0 A0
5320
                       Rm   B3 B2 B1 B0  B3 A3 B2 A2
5321
                     */
5322
                    if (size == 3)
5323
                        return 1;
5324
                    count = (q ? 4 : 2);
5325
                    for (n = 0; n < count; n++) {
5326
                        tmp = neon_load_reg(rd, n);
5327
                        tmp2 = neon_load_reg(rd, n);
5328
                        switch (size) {
5329
                        case 0: gen_neon_zip_u8(tmp, tmp2); break;
5330
                        case 1: gen_neon_zip_u16(tmp, tmp2); break;
5331
                        case 2: /* no-op */; break;
5332
                        default: abort();
5333
                        }
5334
                        neon_store_scratch(n * 2, tmp);
5335
                        neon_store_scratch(n * 2 + 1, tmp2);
5336
                    }
5337
                    for (n = 0; n < count * 2; n++) {
5338
                        int reg = (n < count) ? rd : rm;
5339
                        tmp = neon_load_scratch(n);
5340
                        neon_store_reg(reg, n % count, tmp);
5341
                    }
5342
                    break;
5343
                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5344
                    if (size == 3)
5345
                        return 1;
5346
                    TCGV_UNUSED(tmp2);
5347
                    for (pass = 0; pass < 2; pass++) {
5348
                        neon_load_reg64(cpu_V0, rm + pass);
5349
                        tmp = new_tmp();
5350
                        if (op == 36 && q == 0) {
5351
                            gen_neon_narrow(size, tmp, cpu_V0);
5352
                        } else if (q) {
5353
                            gen_neon_narrow_satu(size, tmp, cpu_V0);
5354
                        } else {
5355
                            gen_neon_narrow_sats(size, tmp, cpu_V0);
5356
                        }
5357
                        if (pass == 0) {
5358
                            tmp2 = tmp;
5359
                        } else {
5360
                            neon_store_reg(rd, 0, tmp2);
5361
                            neon_store_reg(rd, 1, tmp);
5362
                        }
5363
                    }
5364
                    break;
5365
                case 38: /* VSHLL */
5366
                    if (q || size == 3)
5367
                        return 1;
5368
                    tmp = neon_load_reg(rm, 0);
5369
                    tmp2 = neon_load_reg(rm, 1);
5370
                    for (pass = 0; pass < 2; pass++) {
5371
                        if (pass == 1)
5372
                            tmp = tmp2;
5373
                        gen_neon_widen(cpu_V0, tmp, size, 1);
5374
                        neon_store_reg64(cpu_V0, rd + pass);
5375
                    }
5376
                    break;
5377
                default:
5378
                elementwise:
5379
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
5380
                        if (op == 30 || op == 31 || op >= 58) {
5381
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
5382
                                           neon_reg_offset(rm, pass));
5383
                            TCGV_UNUSED(tmp);
5384
                        } else {
5385
                            tmp = neon_load_reg(rm, pass);
5386
                        }
5387
                        switch (op) {
5388
                        case 1: /* VREV32 */
5389
                            switch (size) {
5390
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5391
                            case 1: gen_swap_half(tmp); break;
5392
                            default: return 1;
5393
                            }
5394
                            break;
5395
                        case 2: /* VREV16 */
5396
                            if (size != 0)
5397
                                return 1;
5398
                            gen_rev16(tmp);
5399
                            break;
5400
                        case 8: /* CLS */
5401
                            switch (size) {
5402
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5403
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5404
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5405
                            default: return 1;
5406
                            }
5407
                            break;
5408
                        case 9: /* CLZ */
5409
                            switch (size) {
5410
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5411
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5412
                            case 2: gen_helper_clz(tmp, tmp); break;
5413
                            default: return 1;
5414
                            }
5415
                            break;
5416
                        case 10: /* CNT */
5417
                            if (size != 0)
5418
                                return 1;
5419
                            gen_helper_neon_cnt_u8(tmp, tmp);
5420
                            break;
5421
                        case 11: /* VNOT */
5422
                            if (size != 0)
5423
                                return 1;
5424
                            tcg_gen_not_i32(tmp, tmp);
5425
                            break;
5426
                        case 14: /* VQABS */
5427
                            switch (size) {
5428
                            case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
5429
                            case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
5430
                            case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
5431
                            default: return 1;
5432
                            }
5433
                            break;
5434
                        case 15: /* VQNEG */
5435
                            switch (size) {
5436
                            case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
5437
                            case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
5438
                            case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
5439
                            default: return 1;
5440
                            }
5441
                            break;
5442
                        case 16: case 19: /* VCGT #0, VCLE #0 */
5443
                            tmp2 = tcg_const_i32(0);
5444
                            switch(size) {
5445
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5446
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5447
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5448
                            default: return 1;
5449
                            }
5450
                            tcg_temp_free(tmp2);
5451
                            if (op == 19)
5452
                                tcg_gen_not_i32(tmp, tmp);
5453
                            break;
5454
                        case 17: case 20: /* VCGE #0, VCLT #0 */
5455
                            tmp2 = tcg_const_i32(0);
5456
                            switch(size) {
5457
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
5458
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
5459
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
5460
                            default: return 1;
5461
                            }
5462
                            tcg_temp_free(tmp2);
5463
                            if (op == 20)
5464
                                tcg_gen_not_i32(tmp, tmp);
5465
                            break;
5466
                        case 18: /* VCEQ #0 */
5467
                            tmp2 = tcg_const_i32(0);
5468
                            switch(size) {
5469
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5470
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5471
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5472
                            default: return 1;
5473
                            }
5474
                            tcg_temp_free(tmp2);
5475
                            break;
5476
                        case 22: /* VABS */
5477
                            switch(size) {
5478
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
5479
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
5480
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
5481
                            default: return 1;
5482
                            }
5483
                            break;
5484
                        case 23: /* VNEG */
5485
                            if (size == 3)
5486
                                return 1;
5487
                            tmp2 = tcg_const_i32(0);
5488
                            gen_neon_rsb(size, tmp, tmp2);
5489
                            tcg_temp_free(tmp2);
5490
                            break;
5491
                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5492
                            tmp2 = tcg_const_i32(0);
5493
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
5494
                            tcg_temp_free(tmp2);
5495
                            if (op == 27)
5496
                                tcg_gen_not_i32(tmp, tmp);
5497
                            break;
5498
                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5499
                            tmp2 = tcg_const_i32(0);
5500
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2);
5501
                            tcg_temp_free(tmp2);
5502
                            if (op == 28)
5503
                                tcg_gen_not_i32(tmp, tmp);
5504
                            break;
5505
                        case 26: /* Float VCEQ #0 */
5506
                            tmp2 = tcg_const_i32(0);
5507
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
5508
                            tcg_temp_free(tmp2);
5509
                            break;
5510
                        case 30: /* Float VABS */
5511
                            gen_vfp_abs(0);
5512
                            break;
5513
                        case 31: /* Float VNEG */
5514
                            gen_vfp_neg(0);
5515
                            break;
5516
                        case 32: /* VSWP */
5517
                            tmp2 = neon_load_reg(rd, pass);
5518
                            neon_store_reg(rm, pass, tmp2);
5519
                            break;
5520
                        case 33: /* VTRN */
5521
                            tmp2 = neon_load_reg(rd, pass);
5522
                            switch (size) {
5523
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
5524
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
5525
                            case 2: abort();
5526
                            default: return 1;
5527
                            }
5528
                            neon_store_reg(rm, pass, tmp2);
5529
                            break;
5530
                        case 56: /* Integer VRECPE */
5531
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
5532
                            break;
5533
                        case 57: /* Integer VRSQRTE */
5534
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
5535
                            break;
5536
                        case 58: /* Float VRECPE */
5537
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5538
                            break;
5539
                        case 59: /* Float VRSQRTE */
5540
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5541
                            break;
5542
                        case 60: /* VCVT.F32.S32 */
5543
                            gen_vfp_tosiz(0);
5544
                            break;
5545
                        case 61: /* VCVT.F32.U32 */
5546
                            gen_vfp_touiz(0);
5547
                            break;
5548
                        case 62: /* VCVT.S32.F32 */
5549
                            gen_vfp_sito(0);
5550
                            break;
5551
                        case 63: /* VCVT.U32.F32 */
5552
                            gen_vfp_uito(0);
5553
                            break;
5554
                        default:
5555
                            /* Reserved: 21, 29, 39-56 */
5556
                            return 1;
5557
                        }
5558
                        if (op == 30 || op == 31 || op >= 58) {
5559
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
5560
                                           neon_reg_offset(rd, pass));
5561
                        } else {
5562
                            neon_store_reg(rd, pass, tmp);
5563
                        }
5564
                    }
5565
                    break;
5566
                }
5567
            } else if ((insn & (1 << 10)) == 0) {
5568
                /* VTBL, VTBX.  */
5569
                n = ((insn >> 5) & 0x18) + 8;
5570
                if (insn & (1 << 6)) {
5571
                    tmp = neon_load_reg(rd, 0);
5572
                } else {
5573
                    tmp = new_tmp();
5574
                    tcg_gen_movi_i32(tmp, 0);
5575
                }
5576
                tmp2 = neon_load_reg(rm, 0);
5577
                gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
5578
                                    tcg_const_i32(n));
5579
                dead_tmp(tmp);
5580
                if (insn & (1 << 6)) {
5581
                    tmp = neon_load_reg(rd, 1);
5582
                } else {
5583
                    tmp = new_tmp();
5584
                    tcg_gen_movi_i32(tmp, 0);
5585
                }
5586
                tmp3 = neon_load_reg(rm, 1);
5587
                gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
5588
                                    tcg_const_i32(n));
5589
                neon_store_reg(rd, 0, tmp2);
5590
                neon_store_reg(rd, 1, tmp3);
5591
                dead_tmp(tmp);
5592
            } else if ((insn & 0x380) == 0) {
5593
                /* VDUP */
5594
                if (insn & (1 << 19)) {
5595
                    tmp = neon_load_reg(rm, 1);
5596
                } else {
5597
                    tmp = neon_load_reg(rm, 0);
5598
                }
5599
                if (insn & (1 << 16)) {
5600
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
5601
                } else if (insn & (1 << 17)) {
5602
                    if ((insn >> 18) & 1)
5603
                        gen_neon_dup_high16(tmp);
5604
                    else
5605
                        gen_neon_dup_low16(tmp);
5606
                }
5607
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5608
                    tmp2 = new_tmp();
5609
                    tcg_gen_mov_i32(tmp2, tmp);
5610
                    neon_store_reg(rd, pass, tmp2);
5611
                }
5612
                dead_tmp(tmp);
5613
            } else {
5614
                return 1;
5615
            }
5616
        }
5617
    }
5618
    return 0;
5619
}
5620

    
5621
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5622
{
5623
    int crn = (insn >> 16) & 0xf;
5624
    int crm = insn & 0xf;
5625
    int op1 = (insn >> 21) & 7;
5626
    int op2 = (insn >> 5) & 7;
5627
    int rt = (insn >> 12) & 0xf;
5628
    TCGv tmp;
5629

    
5630
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5631
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5632
            /* TEECR */
5633
            if (IS_USER(s))
5634
                return 1;
5635
            tmp = load_cpu_field(teecr);
5636
            store_reg(s, rt, tmp);
5637
            return 0;
5638
        }
5639
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5640
            /* TEEHBR */
5641
            if (IS_USER(s) && (env->teecr & 1))
5642
                return 1;
5643
            tmp = load_cpu_field(teehbr);
5644
            store_reg(s, rt, tmp);
5645
            return 0;
5646
        }
5647
    }
5648
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5649
            op1, crn, crm, op2);
5650
    return 1;
5651
}
5652

    
5653
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5654
{
5655
    int crn = (insn >> 16) & 0xf;
5656
    int crm = insn & 0xf;
5657
    int op1 = (insn >> 21) & 7;
5658
    int op2 = (insn >> 5) & 7;
5659
    int rt = (insn >> 12) & 0xf;
5660
    TCGv tmp;
5661

    
5662
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5663
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5664
            /* TEECR */
5665
            if (IS_USER(s))
5666
                return 1;
5667
            tmp = load_reg(s, rt);
5668
            gen_helper_set_teecr(cpu_env, tmp);
5669
            dead_tmp(tmp);
5670
            return 0;
5671
        }
5672
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5673
            /* TEEHBR */
5674
            if (IS_USER(s) && (env->teecr & 1))
5675
                return 1;
5676
            tmp = load_reg(s, rt);
5677
            store_cpu_field(tmp, teehbr);
5678
            return 0;
5679
        }
5680
    }
5681
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5682
            op1, crn, crm, op2);
5683
    return 1;
5684
}
5685

    
5686
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5687
{
5688
    int cpnum;
5689

    
5690
    cpnum = (insn >> 8) & 0xf;
5691
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5692
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5693
        return 1;
5694

    
5695
    switch (cpnum) {
5696
      case 0:
5697
      case 1:
5698
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5699
            return disas_iwmmxt_insn(env, s, insn);
5700
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5701
            return disas_dsp_insn(env, s, insn);
5702
        }
5703
        return 1;
5704
    case 10:
5705
    case 11:
5706
        return disas_vfp_insn (env, s, insn);
5707
    case 14:
5708
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5709
           Unfortunately Intel decided to ignore this.  */
5710
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5711
            goto board;
5712
        if (insn & (1 << 20))
5713
            return disas_cp14_read(env, s, insn);
5714
        else
5715
            return disas_cp14_write(env, s, insn);
5716
    case 15:
5717
        return disas_cp15_insn (env, s, insn);
5718
    default:
5719
    board:
5720
        /* Unknown coprocessor.  See if the board has hooked it.  */
5721
        return disas_cp_insn (env, s, insn);
5722
    }
5723
}
5724

    
5725

    
5726
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5727
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5728
{
5729
    TCGv tmp;
5730
    tmp = new_tmp();
5731
    tcg_gen_trunc_i64_i32(tmp, val);
5732
    store_reg(s, rlow, tmp);
5733
    tmp = new_tmp();
5734
    tcg_gen_shri_i64(val, val, 32);
5735
    tcg_gen_trunc_i64_i32(tmp, val);
5736
    store_reg(s, rhigh, tmp);
5737
}
5738

    
5739
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5740
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5741
{
5742
    TCGv_i64 tmp;
5743
    TCGv tmp2;
5744

    
5745
    /* Load value and extend to 64 bits.  */
5746
    tmp = tcg_temp_new_i64();
5747
    tmp2 = load_reg(s, rlow);
5748
    tcg_gen_extu_i32_i64(tmp, tmp2);
5749
    dead_tmp(tmp2);
5750
    tcg_gen_add_i64(val, val, tmp);
5751
}
5752

    
5753
/* load and add a 64-bit value from a register pair.  */
5754
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5755
{
5756
    TCGv_i64 tmp;
5757
    TCGv tmpl;
5758
    TCGv tmph;
5759

    
5760
    /* Load 64-bit value rd:rn.  */
5761
    tmpl = load_reg(s, rlow);
5762
    tmph = load_reg(s, rhigh);
5763
    tmp = tcg_temp_new_i64();
5764
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5765
    dead_tmp(tmpl);
5766
    dead_tmp(tmph);
5767
    tcg_gen_add_i64(val, val, tmp);
5768
}
5769

    
5770
/* Set N and Z flags from a 64-bit value.  */
5771
static void gen_logicq_cc(TCGv_i64 val)
5772
{
5773
    TCGv tmp = new_tmp();
5774
    gen_helper_logicq_cc(tmp, val);
5775
    gen_logic_CC(tmp);
5776
    dead_tmp(tmp);
5777
}
5778

    
5779
static void disas_arm_insn(CPUState * env, DisasContext *s)
5780
{
5781
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5782
    TCGv tmp;
5783
    TCGv tmp2;
5784
    TCGv tmp3;
5785
    TCGv addr;
5786
    TCGv_i64 tmp64;
5787

    
5788
    insn = ldl_code(s->pc);
5789
    s->pc += 4;
5790

    
5791
    /* M variants do not implement ARM mode.  */
5792
    if (IS_M(env))
5793
        goto illegal_op;
5794
    cond = insn >> 28;
5795
    if (cond == 0xf){
5796
        /* Unconditional instructions.  */
5797
        if (((insn >> 25) & 7) == 1) {
5798
            /* NEON Data processing.  */
5799
            if (!arm_feature(env, ARM_FEATURE_NEON))
5800
                goto illegal_op;
5801

    
5802
            if (disas_neon_data_insn(env, s, insn))
5803
                goto illegal_op;
5804
            return;
5805
        }
5806
        if ((insn & 0x0f100000) == 0x04000000) {
5807
            /* NEON load/store.  */
5808
            if (!arm_feature(env, ARM_FEATURE_NEON))
5809
                goto illegal_op;
5810

    
5811
            if (disas_neon_ls_insn(env, s, insn))
5812
                goto illegal_op;
5813
            return;
5814
        }
5815
        if ((insn & 0x0d70f000) == 0x0550f000)
5816
            return; /* PLD */
5817
        else if ((insn & 0x0ffffdff) == 0x01010000) {
5818
            ARCH(6);
5819
            /* setend */
5820
            if (insn & (1 << 9)) {
5821
                /* BE8 mode not implemented.  */
5822
                goto illegal_op;
5823
            }
5824
            return;
5825
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
5826
            switch ((insn >> 4) & 0xf) {
5827
            case 1: /* clrex */
5828
                ARCH(6K);
5829
                gen_helper_clrex(cpu_env);
5830
                return;
5831
            case 4: /* dsb */
5832
            case 5: /* dmb */
5833
            case 6: /* isb */
5834
                ARCH(7);
5835
                /* We don't emulate caches so these are a no-op.  */
5836
                return;
5837
            default:
5838
                goto illegal_op;
5839
            }
5840
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5841
            /* srs */
5842
            int32_t offset;
5843
            if (IS_USER(s))
5844
                goto illegal_op;
5845
            ARCH(6);
5846
            op1 = (insn & 0x1f);
5847
            if (op1 == (env->uncached_cpsr & CPSR_M)) {
5848
                addr = load_reg(s, 13);
5849
            } else {
5850
                addr = new_tmp();
5851
                gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5852
            }
5853
            i = (insn >> 23) & 3;
5854
            switch (i) {
5855
            case 0: offset = -4; break; /* DA */
5856
            case 1: offset = 0; break; /* IA */
5857
            case 2: offset = -8; break; /* DB */
5858
            case 3: offset = 4; break; /* IB */
5859
            default: abort();
5860
            }
5861
            if (offset)
5862
                tcg_gen_addi_i32(addr, addr, offset);
5863
            tmp = load_reg(s, 14);
5864
            gen_st32(tmp, addr, 0);
5865
            tmp = load_cpu_field(spsr);
5866
            tcg_gen_addi_i32(addr, addr, 4);
5867
            gen_st32(tmp, addr, 0);
5868
            if (insn & (1 << 21)) {
5869
                /* Base writeback.  */
5870
                switch (i) {
5871
                case 0: offset = -8; break;
5872
                case 1: offset = 4; break;
5873
                case 2: offset = -4; break;
5874
                case 3: offset = 0; break;
5875
                default: abort();
5876
                }
5877
                if (offset)
5878
                    tcg_gen_addi_i32(addr, addr, offset);
5879
                if (op1 == (env->uncached_cpsr & CPSR_M)) {
5880
                    store_reg(s, 13, addr);
5881
                } else {
5882
                    gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), addr);
5883
                    dead_tmp(addr);
5884
                }
5885
            } else {
5886
                dead_tmp(addr);
5887
            }
5888
        } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5889
            /* rfe */
5890
            int32_t offset;
5891
            if (IS_USER(s))
5892
                goto illegal_op;
5893
            ARCH(6);
5894
            rn = (insn >> 16) & 0xf;
5895
            addr = load_reg(s, rn);
5896
            i = (insn >> 23) & 3;
5897
            switch (i) {
5898
            case 0: offset = -4; break; /* DA */
5899
            case 1: offset = 0; break; /* IA */
5900
            case 2: offset = -8; break; /* DB */
5901
            case 3: offset = 4; break; /* IB */
5902
            default: abort();
5903
            }
5904
            if (offset)
5905
                tcg_gen_addi_i32(addr, addr, offset);
5906
            /* Load PC into tmp and CPSR into tmp2.  */
5907
            tmp = gen_ld32(addr, 0);
5908
            tcg_gen_addi_i32(addr, addr, 4);
5909
            tmp2 = gen_ld32(addr, 0);
5910
            if (insn & (1 << 21)) {
5911
                /* Base writeback.  */
5912
                switch (i) {
5913
                case 0: offset = -8; break;
5914
                case 1: offset = 4; break;
5915
                case 2: offset = -4; break;
5916
                case 3: offset = 0; break;
5917
                default: abort();
5918
                }
5919
                if (offset)
5920
                    tcg_gen_addi_i32(addr, addr, offset);
5921
                store_reg(s, rn, addr);
5922
            } else {
5923
                dead_tmp(addr);
5924
            }
5925
            gen_rfe(s, tmp, tmp2);
5926
            return;
5927
        } else if ((insn & 0x0e000000) == 0x0a000000) {
5928
            /* branch link and change to thumb (blx <offset>) */
5929
            int32_t offset;
5930

    
5931
            val = (uint32_t)s->pc;
5932
            tmp = new_tmp();
5933
            tcg_gen_movi_i32(tmp, val);
5934
            store_reg(s, 14, tmp);
5935
            /* Sign-extend the 24-bit offset */
5936
            offset = (((int32_t)insn) << 8) >> 8;
5937
            /* offset * 4 + bit24 * 2 + (thumb bit) */
5938
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
5939
            /* pipeline offset */
5940
            val += 4;
5941
            gen_bx_im(s, val);
5942
            return;
5943
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
5944
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5945
                /* iWMMXt register transfer.  */
5946
                if (env->cp15.c15_cpar & (1 << 1))
5947
                    if (!disas_iwmmxt_insn(env, s, insn))
5948
                        return;
5949
            }
5950
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
5951
            /* Coprocessor double register transfer.  */
5952
        } else if ((insn & 0x0f000010) == 0x0e000010) {
5953
            /* Additional coprocessor register transfer.  */
5954
        } else if ((insn & 0x0ff10020) == 0x01000000) {
5955
            uint32_t mask;
5956
            uint32_t val;
5957
            /* cps (privileged) */
5958
            if (IS_USER(s))
5959
                return;
5960
            mask = val = 0;
5961
            if (insn & (1 << 19)) {
5962
                if (insn & (1 << 8))
5963
                    mask |= CPSR_A;
5964
                if (insn & (1 << 7))
5965
                    mask |= CPSR_I;
5966
                if (insn & (1 << 6))
5967
                    mask |= CPSR_F;
5968
                if (insn & (1 << 18))
5969
                    val |= mask;
5970
            }
5971
            if (insn & (1 << 17)) {
5972
                mask |= CPSR_M;
5973
                val |= (insn & 0x1f);
5974
            }
5975
            if (mask) {
5976
                gen_set_psr_im(s, mask, 0, val);
5977
            }
5978
            return;
5979
        }
5980
        goto illegal_op;
5981
    }
5982
    if (cond != 0xe) {
5983
        /* if not always execute, we generate a conditional jump to
5984
           next instruction */
5985
        s->condlabel = gen_new_label();
5986
        gen_test_cc(cond ^ 1, s->condlabel);
5987
        s->condjmp = 1;
5988
    }
5989
    if ((insn & 0x0f900000) == 0x03000000) {
5990
        if ((insn & (1 << 21)) == 0) {
5991
            ARCH(6T2);
5992
            rd = (insn >> 12) & 0xf;
5993
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5994
            if ((insn & (1 << 22)) == 0) {
5995
                /* MOVW */
5996
                tmp = new_tmp();
5997
                tcg_gen_movi_i32(tmp, val);
5998
            } else {
5999
                /* MOVT */
6000
                tmp = load_reg(s, rd);
6001
                tcg_gen_ext16u_i32(tmp, tmp);
6002
                tcg_gen_ori_i32(tmp, tmp, val << 16);
6003
            }
6004
            store_reg(s, rd, tmp);
6005
        } else {
6006
            if (((insn >> 12) & 0xf) != 0xf)
6007
                goto illegal_op;
6008
            if (((insn >> 16) & 0xf) == 0) {
6009
                gen_nop_hint(s, insn & 0xff);
6010
            } else {
6011
                /* CPSR = immediate */
6012
                val = insn & 0xff;
6013
                shift = ((insn >> 8) & 0xf) * 2;
6014
                if (shift)
6015
                    val = (val >> shift) | (val << (32 - shift));
6016
                i = ((insn & (1 << 22)) != 0);
6017
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6018
                    goto illegal_op;
6019
            }
6020
        }
6021
    } else if ((insn & 0x0f900000) == 0x01000000
6022
               && (insn & 0x00000090) != 0x00000090) {
6023
        /* miscellaneous instructions */
6024
        op1 = (insn >> 21) & 3;
6025
        sh = (insn >> 4) & 0xf;
6026
        rm = insn & 0xf;
6027
        switch (sh) {
6028
        case 0x0: /* move program status register */
6029
            if (op1 & 1) {
6030
                /* PSR = reg */
6031
                tmp = load_reg(s, rm);
6032
                i = ((op1 & 2) != 0);
6033
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6034
                    goto illegal_op;
6035
            } else {
6036
                /* reg = PSR */
6037
                rd = (insn >> 12) & 0xf;
6038
                if (op1 & 2) {
6039
                    if (IS_USER(s))
6040
                        goto illegal_op;
6041
                    tmp = load_cpu_field(spsr);
6042
                } else {
6043
                    tmp = new_tmp();
6044
                    gen_helper_cpsr_read(tmp);
6045
                }
6046
                store_reg(s, rd, tmp);
6047
            }
6048
            break;
6049
        case 0x1:
6050
            if (op1 == 1) {
6051
                /* branch/exchange thumb (bx).  */
6052
                tmp = load_reg(s, rm);
6053
                gen_bx(s, tmp);
6054
            } else if (op1 == 3) {
6055
                /* clz */
6056
                rd = (insn >> 12) & 0xf;
6057
                tmp = load_reg(s, rm);
6058
                gen_helper_clz(tmp, tmp);
6059
                store_reg(s, rd, tmp);
6060
            } else {
6061
                goto illegal_op;
6062
            }
6063
            break;
6064
        case 0x2:
6065
            if (op1 == 1) {
6066
                ARCH(5J); /* bxj */
6067
                /* Trivial implementation equivalent to bx.  */
6068
                tmp = load_reg(s, rm);
6069
                gen_bx(s, tmp);
6070
            } else {
6071
                goto illegal_op;
6072
            }
6073
            break;
6074
        case 0x3:
6075
            if (op1 != 1)
6076
              goto illegal_op;
6077

    
6078
            /* branch link/exchange thumb (blx) */
6079
            tmp = load_reg(s, rm);
6080
            tmp2 = new_tmp();
6081
            tcg_gen_movi_i32(tmp2, s->pc);
6082
            store_reg(s, 14, tmp2);
6083
            gen_bx(s, tmp);
6084
            break;
6085
        case 0x5: /* saturating add/subtract */
6086
            rd = (insn >> 12) & 0xf;
6087
            rn = (insn >> 16) & 0xf;
6088
            tmp = load_reg(s, rm);
6089
            tmp2 = load_reg(s, rn);
6090
            if (op1 & 2)
6091
                gen_helper_double_saturate(tmp2, tmp2);
6092
            if (op1 & 1)
6093
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6094
            else
6095
                gen_helper_add_saturate(tmp, tmp, tmp2);
6096
            dead_tmp(tmp2);
6097
            store_reg(s, rd, tmp);
6098
            break;
6099
        case 7: /* bkpt */
6100
            gen_set_condexec(s);
6101
            gen_set_pc_im(s->pc - 4);
6102
            gen_exception(EXCP_BKPT);
6103
            s->is_jmp = DISAS_JUMP;
6104
            break;
6105
        case 0x8: /* signed multiply */
6106
        case 0xa:
6107
        case 0xc:
6108
        case 0xe:
6109
            rs = (insn >> 8) & 0xf;
6110
            rn = (insn >> 12) & 0xf;
6111
            rd = (insn >> 16) & 0xf;
6112
            if (op1 == 1) {
6113
                /* (32 * 16) >> 16 */
6114
                tmp = load_reg(s, rm);
6115
                tmp2 = load_reg(s, rs);
6116
                if (sh & 4)
6117
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6118
                else
6119
                    gen_sxth(tmp2);
6120
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
6121
                tcg_gen_shri_i64(tmp64, tmp64, 16);
6122
                tmp = new_tmp();
6123
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6124
                if ((sh & 2) == 0) {
6125
                    tmp2 = load_reg(s, rn);
6126
                    gen_helper_add_setq(tmp, tmp, tmp2);
6127
                    dead_tmp(tmp2);
6128
                }
6129
                store_reg(s, rd, tmp);
6130
            } else {
6131
                /* 16 * 16 */
6132
                tmp = load_reg(s, rm);
6133
                tmp2 = load_reg(s, rs);
6134
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6135
                dead_tmp(tmp2);
6136
                if (op1 == 2) {
6137
                    tmp64 = tcg_temp_new_i64();
6138
                    tcg_gen_ext_i32_i64(tmp64, tmp);
6139
                    dead_tmp(tmp);
6140
                    gen_addq(s, tmp64, rn, rd);
6141
                    gen_storeq_reg(s, rn, rd, tmp64);
6142
                } else {
6143
                    if (op1 == 0) {
6144
                        tmp2 = load_reg(s, rn);
6145
                        gen_helper_add_setq(tmp, tmp, tmp2);
6146
                        dead_tmp(tmp2);
6147
                    }
6148
                    store_reg(s, rd, tmp);
6149
                }
6150
            }
6151
            break;
6152
        default:
6153
            goto illegal_op;
6154
        }
6155
    } else if (((insn & 0x0e000000) == 0 &&
6156
                (insn & 0x00000090) != 0x90) ||
6157
               ((insn & 0x0e000000) == (1 << 25))) {
6158
        int set_cc, logic_cc, shiftop;
6159

    
6160
        op1 = (insn >> 21) & 0xf;
6161
        set_cc = (insn >> 20) & 1;
6162
        logic_cc = table_logic_cc[op1] & set_cc;
6163

    
6164
        /* data processing instruction */
6165
        if (insn & (1 << 25)) {
6166
            /* immediate operand */
6167
            val = insn & 0xff;
6168
            shift = ((insn >> 8) & 0xf) * 2;
6169
            if (shift) {
6170
                val = (val >> shift) | (val << (32 - shift));
6171
            }
6172
            tmp2 = new_tmp();
6173
            tcg_gen_movi_i32(tmp2, val);
6174
            if (logic_cc && shift) {
6175
                gen_set_CF_bit31(tmp2);
6176
            }
6177
        } else {
6178
            /* register */
6179
            rm = (insn) & 0xf;
6180
            tmp2 = load_reg(s, rm);
6181
            shiftop = (insn >> 5) & 3;
6182
            if (!(insn & (1 << 4))) {
6183
                shift = (insn >> 7) & 0x1f;
6184
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6185
            } else {
6186
                rs = (insn >> 8) & 0xf;
6187
                tmp = load_reg(s, rs);
6188
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6189
            }
6190
        }
6191
        if (op1 != 0x0f && op1 != 0x0d) {
6192
            rn = (insn >> 16) & 0xf;
6193
            tmp = load_reg(s, rn);
6194
        } else {
6195
            TCGV_UNUSED(tmp);
6196
        }
6197
        rd = (insn >> 12) & 0xf;
6198
        switch(op1) {
6199
        case 0x00:
6200
            tcg_gen_and_i32(tmp, tmp, tmp2);
6201
            if (logic_cc) {
6202
                gen_logic_CC(tmp);
6203
            }
6204
            store_reg_bx(env, s, rd, tmp);
6205
            break;
6206
        case 0x01:
6207
            tcg_gen_xor_i32(tmp, tmp, tmp2);
6208
            if (logic_cc) {
6209
                gen_logic_CC(tmp);
6210
            }
6211
            store_reg_bx(env, s, rd, tmp);
6212
            break;
6213
        case 0x02:
6214
            if (set_cc && rd == 15) {
6215
                /* SUBS r15, ... is used for exception return.  */
6216
                if (IS_USER(s)) {
6217
                    goto illegal_op;
6218
                }
6219
                gen_helper_sub_cc(tmp, tmp, tmp2);
6220
                gen_exception_return(s, tmp);
6221
            } else {
6222
                if (set_cc) {
6223
                    gen_helper_sub_cc(tmp, tmp, tmp2);
6224
                } else {
6225
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
6226
                }
6227
                store_reg_bx(env, s, rd, tmp);
6228
            }
6229
            break;
6230
        case 0x03:
6231
            if (set_cc) {
6232
                gen_helper_sub_cc(tmp, tmp2, tmp);
6233
            } else {
6234
                tcg_gen_sub_i32(tmp, tmp2, tmp);
6235
            }
6236
            store_reg_bx(env, s, rd, tmp);
6237
            break;
6238
        case 0x04:
6239
            if (set_cc) {
6240
                gen_helper_add_cc(tmp, tmp, tmp2);
6241
            } else {
6242
                tcg_gen_add_i32(tmp, tmp, tmp2);
6243
            }
6244
            store_reg_bx(env, s, rd, tmp);
6245
            break;
6246
        case 0x05:
6247
            if (set_cc) {
6248
                gen_helper_adc_cc(tmp, tmp, tmp2);
6249
            } else {
6250
                gen_add_carry(tmp, tmp, tmp2);
6251
            }
6252
            store_reg_bx(env, s, rd, tmp);
6253
            break;
6254
        case 0x06:
6255
            if (set_cc) {
6256
                gen_helper_sbc_cc(tmp, tmp, tmp2);
6257
            } else {
6258
                gen_sub_carry(tmp, tmp, tmp2);
6259
            }
6260
            store_reg_bx(env, s, rd, tmp);
6261
            break;
6262
        case 0x07:
6263
            if (set_cc) {
6264
                gen_helper_sbc_cc(tmp, tmp2, tmp);
6265
            } else {
6266
                gen_sub_carry(tmp, tmp2, tmp);
6267
            }
6268
            store_reg_bx(env, s, rd, tmp);
6269
            break;
6270
        case 0x08:
6271
            if (set_cc) {
6272
                tcg_gen_and_i32(tmp, tmp, tmp2);
6273
                gen_logic_CC(tmp);
6274
            }
6275
            dead_tmp(tmp);
6276
            break;
6277
        case 0x09:
6278
            if (set_cc) {
6279
                tcg_gen_xor_i32(tmp, tmp, tmp2);
6280
                gen_logic_CC(tmp);
6281
            }
6282
            dead_tmp(tmp);
6283
            break;
6284
        case 0x0a:
6285
            if (set_cc) {
6286
                gen_helper_sub_cc(tmp, tmp, tmp2);
6287
            }
6288
            dead_tmp(tmp);
6289
            break;
6290
        case 0x0b:
6291
            if (set_cc) {
6292
                gen_helper_add_cc(tmp, tmp, tmp2);
6293
            }
6294
            dead_tmp(tmp);
6295
            break;
6296
        case 0x0c:
6297
            tcg_gen_or_i32(tmp, tmp, tmp2);
6298
            if (logic_cc) {
6299
                gen_logic_CC(tmp);
6300
            }
6301
            store_reg_bx(env, s, rd, tmp);
6302
            break;
6303
        case 0x0d:
6304
            if (logic_cc && rd == 15) {
6305
                /* MOVS r15, ... is used for exception return.  */
6306
                if (IS_USER(s)) {
6307
                    goto illegal_op;
6308
                }
6309
                gen_exception_return(s, tmp2);
6310
            } else {
6311
                if (logic_cc) {
6312
                    gen_logic_CC(tmp2);
6313
                }
6314
                store_reg_bx(env, s, rd, tmp2);
6315
            }
6316
            break;
6317
        case 0x0e:
6318
            tcg_gen_bic_i32(tmp, tmp, tmp2);
6319
            if (logic_cc) {
6320
                gen_logic_CC(tmp);
6321
            }
6322
            store_reg_bx(env, s, rd, tmp);
6323
            break;
6324
        default:
6325
        case 0x0f:
6326
            tcg_gen_not_i32(tmp2, tmp2);
6327
            if (logic_cc) {
6328
                gen_logic_CC(tmp2);
6329
            }
6330
            store_reg_bx(env, s, rd, tmp2);
6331
            break;
6332
        }
6333
        if (op1 != 0x0f && op1 != 0x0d) {
6334
            dead_tmp(tmp2);
6335
        }
6336
    } else {
6337
        /* other instructions */
6338
        op1 = (insn >> 24) & 0xf;
6339
        switch(op1) {
6340
        case 0x0:
6341
        case 0x1:
6342
            /* multiplies, extra load/stores */
6343
            sh = (insn >> 5) & 3;
6344
            if (sh == 0) {
6345
                if (op1 == 0x0) {
6346
                    rd = (insn >> 16) & 0xf;
6347
                    rn = (insn >> 12) & 0xf;
6348
                    rs = (insn >> 8) & 0xf;
6349
                    rm = (insn) & 0xf;
6350
                    op1 = (insn >> 20) & 0xf;
6351
                    switch (op1) {
6352
                    case 0: case 1: case 2: case 3: case 6:
6353
                        /* 32 bit mul */
6354
                        tmp = load_reg(s, rs);
6355
                        tmp2 = load_reg(s, rm);
6356
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
6357
                        dead_tmp(tmp2);
6358
                        if (insn & (1 << 22)) {
6359
                            /* Subtract (mls) */
6360
                            ARCH(6T2);
6361
                            tmp2 = load_reg(s, rn);
6362
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
6363
                            dead_tmp(tmp2);
6364
                        } else if (insn & (1 << 21)) {
6365
                            /* Add */
6366
                            tmp2 = load_reg(s, rn);
6367
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6368
                            dead_tmp(tmp2);
6369
                        }
6370
                        if (insn & (1 << 20))
6371
                            gen_logic_CC(tmp);
6372
                        store_reg(s, rd, tmp);
6373
                        break;
6374
                    default:
6375
                        /* 64 bit mul */
6376
                        tmp = load_reg(s, rs);
6377
                        tmp2 = load_reg(s, rm);
6378
                        if (insn & (1 << 22))
6379
                            tmp64 = gen_muls_i64_i32(tmp, tmp2);
6380
                        else
6381
                            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6382
                        if (insn & (1 << 21)) /* mult accumulate */
6383
                            gen_addq(s, tmp64, rn, rd);
6384
                        if (!(insn & (1 << 23))) { /* double accumulate */
6385
                            ARCH(6);
6386
                            gen_addq_lo(s, tmp64, rn);
6387
                            gen_addq_lo(s, tmp64, rd);
6388
                        }
6389
                        if (insn & (1 << 20))
6390
                            gen_logicq_cc(tmp64);
6391
                        gen_storeq_reg(s, rn, rd, tmp64);
6392
                        break;
6393
                    }
6394
                } else {
6395
                    rn = (insn >> 16) & 0xf;
6396
                    rd = (insn >> 12) & 0xf;
6397
                    if (insn & (1 << 23)) {
6398
                        /* load/store exclusive */
6399
                        op1 = (insn >> 21) & 0x3;
6400
                        if (op1)
6401
                            ARCH(6K);
6402
                        else
6403
                            ARCH(6);
6404
                        addr = tcg_temp_local_new_i32();
6405
                        tcg_gen_mov_i32(addr, cpu_R[rn]);
6406
                        if (insn & (1 << 20)) {
6407
                            gen_helper_mark_exclusive(cpu_env, addr);
6408
                            switch (op1) {
6409
                            case 0: /* ldrex */
6410
                                tmp = gen_ld32(addr, IS_USER(s));
6411
                                break;
6412
                            case 1: /* ldrexd */
6413
                                tmp = gen_ld32(addr, IS_USER(s));
6414
                                store_reg(s, rd, tmp);
6415
                                tcg_gen_addi_i32(addr, addr, 4);
6416
                                tmp = gen_ld32(addr, IS_USER(s));
6417
                                rd++;
6418
                                break;
6419
                            case 2: /* ldrexb */
6420
                                tmp = gen_ld8u(addr, IS_USER(s));
6421
                                break;
6422
                            case 3: /* ldrexh */
6423
                                tmp = gen_ld16u(addr, IS_USER(s));
6424
                                break;
6425
                            default:
6426
                                abort();
6427
                            }
6428
                            store_reg(s, rd, tmp);
6429
                        } else {
6430
                            int label = gen_new_label();
6431
                            rm = insn & 0xf;
6432
                            tmp2 = tcg_temp_local_new_i32();
6433
                            gen_helper_test_exclusive(tmp2, cpu_env, addr);
6434
                            tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
6435
                            tmp = load_reg(s,rm);
6436
                            switch (op1) {
6437
                            case 0:  /*  strex */
6438
                                gen_st32(tmp, addr, IS_USER(s));
6439
                                break;
6440
                            case 1: /*  strexd */
6441
                                gen_st32(tmp, addr, IS_USER(s));
6442
                                tcg_gen_addi_i32(addr, addr, 4);
6443
                                tmp = load_reg(s, rm + 1);
6444
                                gen_st32(tmp, addr, IS_USER(s));
6445
                                break;
6446
                            case 2: /*  strexb */
6447
                                gen_st8(tmp, addr, IS_USER(s));
6448
                                break;
6449
                            case 3: /* strexh */
6450
                                gen_st16(tmp, addr, IS_USER(s));
6451
                                break;
6452
                            default:
6453
                                abort();
6454
                            }
6455
                            gen_set_label(label);
6456
                            tcg_gen_mov_i32(cpu_R[rd], tmp2);
6457
                            tcg_temp_free(tmp2);
6458
                        }
6459
                        tcg_temp_free(addr);
6460
                    } else {
6461
                        /* SWP instruction */
6462
                        rm = (insn) & 0xf;
6463

    
6464
                        /* ??? This is not really atomic.  However we know
6465
                           we never have multiple CPUs running in parallel,
6466
                           so it is good enough.  */
6467
                        addr = load_reg(s, rn);
6468
                        tmp = load_reg(s, rm);
6469
                        if (insn & (1 << 22)) {
6470
                            tmp2 = gen_ld8u(addr, IS_USER(s));
6471
                            gen_st8(tmp, addr, IS_USER(s));
6472
                        } else {
6473
                            tmp2 = gen_ld32(addr, IS_USER(s));
6474
                            gen_st32(tmp, addr, IS_USER(s));
6475
                        }
6476
                        dead_tmp(addr);
6477
                        store_reg(s, rd, tmp2);
6478
                    }
6479
                }
6480
            } else {
6481
                int address_offset;
6482
                int load;
6483
                /* Misc load/store */
6484
                rn = (insn >> 16) & 0xf;
6485
                rd = (insn >> 12) & 0xf;
6486
                addr = load_reg(s, rn);
6487
                if (insn & (1 << 24))
6488
                    gen_add_datah_offset(s, insn, 0, addr);
6489
                address_offset = 0;
6490
                if (insn & (1 << 20)) {
6491
                    /* load */
6492
                    switch(sh) {
6493
                    case 1:
6494
                        tmp = gen_ld16u(addr, IS_USER(s));
6495
                        break;
6496
                    case 2:
6497
                        tmp = gen_ld8s(addr, IS_USER(s));
6498
                        break;
6499
                    default:
6500
                    case 3:
6501
                        tmp = gen_ld16s(addr, IS_USER(s));
6502
                        break;
6503
                    }
6504
                    load = 1;
6505
                } else if (sh & 2) {
6506
                    /* doubleword */
6507
                    if (sh & 1) {
6508
                        /* store */
6509
                        tmp = load_reg(s, rd);
6510
                        gen_st32(tmp, addr, IS_USER(s));
6511
                        tcg_gen_addi_i32(addr, addr, 4);
6512
                        tmp = load_reg(s, rd + 1);
6513
                        gen_st32(tmp, addr, IS_USER(s));
6514
                        load = 0;
6515
                    } else {
6516
                        /* load */
6517
                        tmp = gen_ld32(addr, IS_USER(s));
6518
                        store_reg(s, rd, tmp);
6519
                        tcg_gen_addi_i32(addr, addr, 4);
6520
                        tmp = gen_ld32(addr, IS_USER(s));
6521
                        rd++;
6522
                        load = 1;
6523
                    }
6524
                    address_offset = -4;
6525
                } else {
6526
                    /* store */
6527
                    tmp = load_reg(s, rd);
6528
                    gen_st16(tmp, addr, IS_USER(s));
6529
                    load = 0;
6530
                }
6531
                /* Perform base writeback before the loaded value to
6532
                   ensure correct behavior with overlapping index registers.
6533
                   ldrd with base writeback is is undefined if the
6534
                   destination and index registers overlap.  */
6535
                if (!(insn & (1 << 24))) {
6536
                    gen_add_datah_offset(s, insn, address_offset, addr);
6537
                    store_reg(s, rn, addr);
6538
                } else if (insn & (1 << 21)) {
6539
                    if (address_offset)
6540
                        tcg_gen_addi_i32(addr, addr, address_offset);
6541
                    store_reg(s, rn, addr);
6542
                } else {
6543
                    dead_tmp(addr);
6544
                }
6545
                if (load) {
6546
                    /* Complete the load.  */
6547
                    store_reg(s, rd, tmp);
6548
                }
6549
            }
6550
            break;
6551
        case 0x4:
6552
        case 0x5:
6553
            goto do_ldst;
6554
        case 0x6:
6555
        case 0x7:
6556
            if (insn & (1 << 4)) {
6557
                ARCH(6);
6558
                /* Armv6 Media instructions.  */
6559
                rm = insn & 0xf;
6560
                rn = (insn >> 16) & 0xf;
6561
                rd = (insn >> 12) & 0xf;
6562
                rs = (insn >> 8) & 0xf;
6563
                switch ((insn >> 23) & 3) {
6564
                case 0: /* Parallel add/subtract.  */
6565
                    op1 = (insn >> 20) & 7;
6566
                    tmp = load_reg(s, rn);
6567
                    tmp2 = load_reg(s, rm);
6568
                    sh = (insn >> 5) & 7;
6569
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6570
                        goto illegal_op;
6571
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6572
                    dead_tmp(tmp2);
6573
                    store_reg(s, rd, tmp);
6574
                    break;
6575
                case 1:
6576
                    if ((insn & 0x00700020) == 0) {
6577
                        /* Halfword pack.  */
6578
                        tmp = load_reg(s, rn);
6579
                        tmp2 = load_reg(s, rm);
6580
                        shift = (insn >> 7) & 0x1f;
6581
                        if (insn & (1 << 6)) {
6582
                            /* pkhtb */
6583
                            if (shift == 0)
6584
                                shift = 31;
6585
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
6586
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6587
                            tcg_gen_ext16u_i32(tmp2, tmp2);
6588
                        } else {
6589
                            /* pkhbt */
6590
                            if (shift)
6591
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
6592
                            tcg_gen_ext16u_i32(tmp, tmp);
6593
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6594
                        }
6595
                        tcg_gen_or_i32(tmp, tmp, tmp2);
6596
                        dead_tmp(tmp2);
6597
                        store_reg(s, rd, tmp);
6598
                    } else if ((insn & 0x00200020) == 0x00200000) {
6599
                        /* [us]sat */
6600
                        tmp = load_reg(s, rm);
6601
                        shift = (insn >> 7) & 0x1f;
6602
                        if (insn & (1 << 6)) {
6603
                            if (shift == 0)
6604
                                shift = 31;
6605
                            tcg_gen_sari_i32(tmp, tmp, shift);
6606
                        } else {
6607
                            tcg_gen_shli_i32(tmp, tmp, shift);
6608
                        }
6609
                        sh = (insn >> 16) & 0x1f;
6610
                        if (sh != 0) {
6611
                            if (insn & (1 << 22))
6612
                                gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6613
                            else
6614
                                gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6615
                        }
6616
                        store_reg(s, rd, tmp);
6617
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
6618
                        /* [us]sat16 */
6619
                        tmp = load_reg(s, rm);
6620
                        sh = (insn >> 16) & 0x1f;
6621
                        if (sh != 0) {
6622
                            if (insn & (1 << 22))
6623
                                gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6624
                            else
6625
                                gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6626
                        }
6627
                        store_reg(s, rd, tmp);
6628
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6629
                        /* Select bytes.  */
6630
                        tmp = load_reg(s, rn);
6631
                        tmp2 = load_reg(s, rm);
6632
                        tmp3 = new_tmp();
6633
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6634
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6635
                        dead_tmp(tmp3);
6636
                        dead_tmp(tmp2);
6637
                        store_reg(s, rd, tmp);
6638
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6639
                        tmp = load_reg(s, rm);
6640
                        shift = (insn >> 10) & 3;
6641
                        /* ??? In many cases it's not neccessary to do a
6642
                           rotate, a shift is sufficient.  */
6643
                        if (shift != 0)
6644
                            tcg_gen_rori_i32(tmp, tmp, shift * 8);
6645
                        op1 = (insn >> 20) & 7;
6646
                        switch (op1) {
6647
                        case 0: gen_sxtb16(tmp);  break;
6648
                        case 2: gen_sxtb(tmp);    break;
6649
                        case 3: gen_sxth(tmp);    break;
6650
                        case 4: gen_uxtb16(tmp);  break;
6651
                        case 6: gen_uxtb(tmp);    break;
6652
                        case 7: gen_uxth(tmp);    break;
6653
                        default: goto illegal_op;
6654
                        }
6655
                        if (rn != 15) {
6656
                            tmp2 = load_reg(s, rn);
6657
                            if ((op1 & 3) == 0) {
6658
                                gen_add16(tmp, tmp2);
6659
                            } else {
6660
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6661
                                dead_tmp(tmp2);
6662
                            }
6663
                        }
6664
                        store_reg(s, rd, tmp);
6665
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6666
                        /* rev */
6667
                        tmp = load_reg(s, rm);
6668
                        if (insn & (1 << 22)) {
6669
                            if (insn & (1 << 7)) {
6670
                                gen_revsh(tmp);
6671
                            } else {
6672
                                ARCH(6T2);
6673
                                gen_helper_rbit(tmp, tmp);
6674
                            }
6675
                        } else {
6676
                            if (insn & (1 << 7))
6677
                                gen_rev16(tmp);
6678
                            else
6679
                                tcg_gen_bswap32_i32(tmp, tmp);
6680
                        }
6681
                        store_reg(s, rd, tmp);
6682
                    } else {
6683
                        goto illegal_op;
6684
                    }
6685
                    break;
6686
                case 2: /* Multiplies (Type 3).  */
6687
                    tmp = load_reg(s, rm);
6688
                    tmp2 = load_reg(s, rs);
6689
                    if (insn & (1 << 20)) {
6690
                        /* Signed multiply most significant [accumulate].  */
6691
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
6692
                        if (insn & (1 << 5))
6693
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
6694
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
6695
                        tmp = new_tmp();
6696
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
6697
                        if (rd != 15) {
6698
                            tmp2 = load_reg(s, rd);
6699
                            if (insn & (1 << 6)) {
6700
                                tcg_gen_sub_i32(tmp, tmp, tmp2);
6701
                            } else {
6702
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6703
                            }
6704
                            dead_tmp(tmp2);
6705
                        }
6706
                        store_reg(s, rn, tmp);
6707
                    } else {
6708
                        if (insn & (1 << 5))
6709
                            gen_swap_half(tmp2);
6710
                        gen_smul_dual(tmp, tmp2);
6711
                        /* This addition cannot overflow.  */
6712
                        if (insn & (1 << 6)) {
6713
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
6714
                        } else {
6715
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6716
                        }
6717
                        dead_tmp(tmp2);
6718
                        if (insn & (1 << 22)) {
6719
                            /* smlald, smlsld */
6720
                            tmp64 = tcg_temp_new_i64();
6721
                            tcg_gen_ext_i32_i64(tmp64, tmp);
6722
                            dead_tmp(tmp);
6723
                            gen_addq(s, tmp64, rd, rn);
6724
                            gen_storeq_reg(s, rd, rn, tmp64);
6725
                        } else {
6726
                            /* smuad, smusd, smlad, smlsd */
6727
                            if (rd != 15)
6728
                              {
6729
                                tmp2 = load_reg(s, rd);
6730
                                gen_helper_add_setq(tmp, tmp, tmp2);
6731
                                dead_tmp(tmp2);
6732
                              }
6733
                            store_reg(s, rn, tmp);
6734
                        }
6735
                    }
6736
                    break;
6737
                case 3:
6738
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6739
                    switch (op1) {
6740
                    case 0: /* Unsigned sum of absolute differences.  */
6741
                        ARCH(6);
6742
                        tmp = load_reg(s, rm);
6743
                        tmp2 = load_reg(s, rs);
6744
                        gen_helper_usad8(tmp, tmp, tmp2);
6745
                        dead_tmp(tmp2);
6746
                        if (rd != 15) {
6747
                            tmp2 = load_reg(s, rd);
6748
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6749
                            dead_tmp(tmp2);
6750
                        }
6751
                        store_reg(s, rn, tmp);
6752
                        break;
6753
                    case 0x20: case 0x24: case 0x28: case 0x2c:
6754
                        /* Bitfield insert/clear.  */
6755
                        ARCH(6T2);
6756
                        shift = (insn >> 7) & 0x1f;
6757
                        i = (insn >> 16) & 0x1f;
6758
                        i = i + 1 - shift;
6759
                        if (rm == 15) {
6760
                            tmp = new_tmp();
6761
                            tcg_gen_movi_i32(tmp, 0);
6762
                        } else {
6763
                            tmp = load_reg(s, rm);
6764
                        }
6765
                        if (i != 32) {
6766
                            tmp2 = load_reg(s, rd);
6767
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6768
                            dead_tmp(tmp2);
6769
                        }
6770
                        store_reg(s, rd, tmp);
6771
                        break;
6772
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6773
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6774
                        ARCH(6T2);
6775
                        tmp = load_reg(s, rm);
6776
                        shift = (insn >> 7) & 0x1f;
6777
                        i = ((insn >> 16) & 0x1f) + 1;
6778
                        if (shift + i > 32)
6779
                            goto illegal_op;
6780
                        if (i < 32) {
6781
                            if (op1 & 0x20) {
6782
                                gen_ubfx(tmp, shift, (1u << i) - 1);
6783
                            } else {
6784
                                gen_sbfx(tmp, shift, i);
6785
                            }
6786
                        }
6787
                        store_reg(s, rd, tmp);
6788
                        break;
6789
                    default:
6790
                        goto illegal_op;
6791
                    }
6792
                    break;
6793
                }
6794
                break;
6795
            }
6796
        do_ldst:
6797
            /* Check for undefined extension instructions
6798
             * per the ARM Bible IE:
6799
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
6800
             */
6801
            sh = (0xf << 20) | (0xf << 4);
6802
            if (op1 == 0x7 && ((insn & sh) == sh))
6803
            {
6804
                goto illegal_op;
6805
            }
6806
            /* load/store byte/word */
6807
            rn = (insn >> 16) & 0xf;
6808
            rd = (insn >> 12) & 0xf;
6809
            tmp2 = load_reg(s, rn);
6810
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6811
            if (insn & (1 << 24))
6812
                gen_add_data_offset(s, insn, tmp2);
6813
            if (insn & (1 << 20)) {
6814
                /* load */
6815
                if (insn & (1 << 22)) {
6816
                    tmp = gen_ld8u(tmp2, i);
6817
                } else {
6818
                    tmp = gen_ld32(tmp2, i);
6819
                }
6820
            } else {
6821
                /* store */
6822
                tmp = load_reg(s, rd);
6823
                if (insn & (1 << 22))
6824
                    gen_st8(tmp, tmp2, i);
6825
                else
6826
                    gen_st32(tmp, tmp2, i);
6827
            }
6828
            if (!(insn & (1 << 24))) {
6829
                gen_add_data_offset(s, insn, tmp2);
6830
                store_reg(s, rn, tmp2);
6831
            } else if (insn & (1 << 21)) {
6832
                store_reg(s, rn, tmp2);
6833
            } else {
6834
                dead_tmp(tmp2);
6835
            }
6836
            if (insn & (1 << 20)) {
6837
                /* Complete the load.  */
6838
                if (rd == 15)
6839
                    gen_bx(s, tmp);
6840
                else
6841
                    store_reg(s, rd, tmp);
6842
            }
6843
            break;
6844
        case 0x08:
6845
        case 0x09:
6846
            {
6847
                int j, n, user, loaded_base;
6848
                TCGv loaded_var;
6849
                /* load/store multiple words */
6850
                /* XXX: store correct base if write back */
6851
                user = 0;
6852
                if (insn & (1 << 22)) {
6853
                    if (IS_USER(s))
6854
                        goto illegal_op; /* only usable in supervisor mode */
6855

    
6856
                    if ((insn & (1 << 15)) == 0)
6857
                        user = 1;
6858
                }
6859
                rn = (insn >> 16) & 0xf;
6860
                addr = load_reg(s, rn);
6861

    
6862
                /* compute total size */
6863
                loaded_base = 0;
6864
                TCGV_UNUSED(loaded_var);
6865
                n = 0;
6866
                for(i=0;i<16;i++) {
6867
                    if (insn & (1 << i))
6868
                        n++;
6869
                }
6870
                /* XXX: test invalid n == 0 case ? */
6871
                if (insn & (1 << 23)) {
6872
                    if (insn & (1 << 24)) {
6873
                        /* pre increment */
6874
                        tcg_gen_addi_i32(addr, addr, 4);
6875
                    } else {
6876
                        /* post increment */
6877
                    }
6878
                } else {
6879
                    if (insn & (1 << 24)) {
6880
                        /* pre decrement */
6881
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
6882
                    } else {
6883
                        /* post decrement */
6884
                        if (n != 1)
6885
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6886
                    }
6887
                }
6888
                j = 0;
6889
                for(i=0;i<16;i++) {
6890
                    if (insn & (1 << i)) {
6891
                        if (insn & (1 << 20)) {
6892
                            /* load */
6893
                            tmp = gen_ld32(addr, IS_USER(s));
6894
                            if (i == 15) {
6895
                                gen_bx(s, tmp);
6896
                            } else if (user) {
6897
                                gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6898
                                dead_tmp(tmp);
6899
                            } else if (i == rn) {
6900
                                loaded_var = tmp;
6901
                                loaded_base = 1;
6902
                            } else {
6903
                                store_reg(s, i, tmp);
6904
                            }
6905
                        } else {
6906
                            /* store */
6907
                            if (i == 15) {
6908
                                /* special case: r15 = PC + 8 */
6909
                                val = (long)s->pc + 4;
6910
                                tmp = new_tmp();
6911
                                tcg_gen_movi_i32(tmp, val);
6912
                            } else if (user) {
6913
                                tmp = new_tmp();
6914
                                gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6915
                            } else {
6916
                                tmp = load_reg(s, i);
6917
                            }
6918
                            gen_st32(tmp, addr, IS_USER(s));
6919
                        }
6920
                        j++;
6921
                        /* no need to add after the last transfer */
6922
                        if (j != n)
6923
                            tcg_gen_addi_i32(addr, addr, 4);
6924
                    }
6925
                }
6926
                if (insn & (1 << 21)) {
6927
                    /* write back */
6928
                    if (insn & (1 << 23)) {
6929
                        if (insn & (1 << 24)) {
6930
                            /* pre increment */
6931
                        } else {
6932
                            /* post increment */
6933
                            tcg_gen_addi_i32(addr, addr, 4);
6934
                        }
6935
                    } else {
6936
                        if (insn & (1 << 24)) {
6937
                            /* pre decrement */
6938
                            if (n != 1)
6939
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6940
                        } else {
6941
                            /* post decrement */
6942
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
6943
                        }
6944
                    }
6945
                    store_reg(s, rn, addr);
6946
                } else {
6947
                    dead_tmp(addr);
6948
                }
6949
                if (loaded_base) {
6950
                    store_reg(s, rn, loaded_var);
6951
                }
6952
                if ((insn & (1 << 22)) && !user) {
6953
                    /* Restore CPSR from SPSR.  */
6954
                    tmp = load_cpu_field(spsr);
6955
                    gen_set_cpsr(tmp, 0xffffffff);
6956
                    dead_tmp(tmp);
6957
                    s->is_jmp = DISAS_UPDATE;
6958
                }
6959
            }
6960
            break;
6961
        case 0xa:
6962
        case 0xb:
6963
            {
6964
                int32_t offset;
6965

    
6966
                /* branch (and link) */
6967
                val = (int32_t)s->pc;
6968
                if (insn & (1 << 24)) {
6969
                    tmp = new_tmp();
6970
                    tcg_gen_movi_i32(tmp, val);
6971
                    store_reg(s, 14, tmp);
6972
                }
6973
                offset = (((int32_t)insn << 8) >> 8);
6974
                val += (offset << 2) + 4;
6975
                gen_jmp(s, val);
6976
            }
6977
            break;
6978
        case 0xc:
6979
        case 0xd:
6980
        case 0xe:
6981
            /* Coprocessor.  */
6982
            if (disas_coproc_insn(env, s, insn))
6983
                goto illegal_op;
6984
            break;
6985
        case 0xf:
6986
            /* swi */
6987
            gen_set_pc_im(s->pc);
6988
            s->is_jmp = DISAS_SWI;
6989
            break;
6990
        default:
6991
        illegal_op:
6992
            gen_set_condexec(s);
6993
            gen_set_pc_im(s->pc - 4);
6994
            gen_exception(EXCP_UDEF);
6995
            s->is_jmp = DISAS_JUMP;
6996
            break;
6997
        }
6998
    }
6999
}
7000

    
7001
/* Return true if this is a Thumb-2 logical op.  */
7002
static int
7003
thumb2_logic_op(int op)
7004
{
7005
    return (op < 8);
7006
}
7007

    
7008
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7009
   then set condition code flags based on the result of the operation.
7010
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7011
   to the high bit of T1.
7012
   Returns zero if the opcode is valid.  */
7013

    
7014
static int
7015
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7016
{
7017
    int logic_cc;
7018

    
7019
    logic_cc = 0;
7020
    switch (op) {
7021
    case 0: /* and */
7022
        tcg_gen_and_i32(t0, t0, t1);
7023
        logic_cc = conds;
7024
        break;
7025
    case 1: /* bic */
7026
        tcg_gen_bic_i32(t0, t0, t1);
7027
        logic_cc = conds;
7028
        break;
7029
    case 2: /* orr */
7030
        tcg_gen_or_i32(t0, t0, t1);
7031
        logic_cc = conds;
7032
        break;
7033
    case 3: /* orn */
7034
        tcg_gen_not_i32(t1, t1);
7035
        tcg_gen_or_i32(t0, t0, t1);
7036
        logic_cc = conds;
7037
        break;
7038
    case 4: /* eor */
7039
        tcg_gen_xor_i32(t0, t0, t1);
7040
        logic_cc = conds;
7041
        break;
7042
    case 8: /* add */
7043
        if (conds)
7044
            gen_helper_add_cc(t0, t0, t1);
7045
        else
7046
            tcg_gen_add_i32(t0, t0, t1);
7047
        break;
7048
    case 10: /* adc */
7049
        if (conds)
7050
            gen_helper_adc_cc(t0, t0, t1);
7051
        else
7052
            gen_adc(t0, t1);
7053
        break;
7054
    case 11: /* sbc */
7055
        if (conds)
7056
            gen_helper_sbc_cc(t0, t0, t1);
7057
        else
7058
            gen_sub_carry(t0, t0, t1);
7059
        break;
7060
    case 13: /* sub */
7061
        if (conds)
7062
            gen_helper_sub_cc(t0, t0, t1);
7063
        else
7064
            tcg_gen_sub_i32(t0, t0, t1);
7065
        break;
7066
    case 14: /* rsb */
7067
        if (conds)
7068
            gen_helper_sub_cc(t0, t1, t0);
7069
        else
7070
            tcg_gen_sub_i32(t0, t1, t0);
7071
        break;
7072
    default: /* 5, 6, 7, 9, 12, 15. */
7073
        return 1;
7074
    }
7075
    if (logic_cc) {
7076
        gen_logic_CC(t0);
7077
        if (shifter_out)
7078
            gen_set_CF_bit31(t1);
7079
    }
7080
    return 0;
7081
}
7082

    
7083
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7084
   is not legal.  */
7085
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7086
{
7087
    uint32_t insn, imm, shift, offset;
7088
    uint32_t rd, rn, rm, rs;
7089
    TCGv tmp;
7090
    TCGv tmp2;
7091
    TCGv tmp3;
7092
    TCGv addr;
7093
    TCGv_i64 tmp64;
7094
    int op;
7095
    int shiftop;
7096
    int conds;
7097
    int logic_cc;
7098

    
7099
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7100
          || arm_feature (env, ARM_FEATURE_M))) {
7101
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7102
           16-bit instructions to get correct prefetch abort behavior.  */
7103
        insn = insn_hw1;
7104
        if ((insn & (1 << 12)) == 0) {
7105
            /* Second half of blx.  */
7106
            offset = ((insn & 0x7ff) << 1);
7107
            tmp = load_reg(s, 14);
7108
            tcg_gen_addi_i32(tmp, tmp, offset);
7109
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7110

    
7111
            tmp2 = new_tmp();
7112
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7113
            store_reg(s, 14, tmp2);
7114
            gen_bx(s, tmp);
7115
            return 0;
7116
        }
7117
        if (insn & (1 << 11)) {
7118
            /* Second half of bl.  */
7119
            offset = ((insn & 0x7ff) << 1) | 1;
7120
            tmp = load_reg(s, 14);
7121
            tcg_gen_addi_i32(tmp, tmp, offset);
7122

    
7123
            tmp2 = new_tmp();
7124
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7125
            store_reg(s, 14, tmp2);
7126
            gen_bx(s, tmp);
7127
            return 0;
7128
        }
7129
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7130
            /* Instruction spans a page boundary.  Implement it as two
7131
               16-bit instructions in case the second half causes an
7132
               prefetch abort.  */
7133
            offset = ((int32_t)insn << 21) >> 9;
7134
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7135
            return 0;
7136
        }
7137
        /* Fall through to 32-bit decode.  */
7138
    }
7139

    
7140
    insn = lduw_code(s->pc);
7141
    s->pc += 2;
7142
    insn |= (uint32_t)insn_hw1 << 16;
7143

    
7144
    if ((insn & 0xf800e800) != 0xf000e800) {
7145
        ARCH(6T2);
7146
    }
7147

    
7148
    rn = (insn >> 16) & 0xf;
7149
    rs = (insn >> 12) & 0xf;
7150
    rd = (insn >> 8) & 0xf;
7151
    rm = insn & 0xf;
7152
    switch ((insn >> 25) & 0xf) {
7153
    case 0: case 1: case 2: case 3:
7154
        /* 16-bit instructions.  Should never happen.  */
7155
        abort();
7156
    case 4:
7157
        if (insn & (1 << 22)) {
7158
            /* Other load/store, table branch.  */
7159
            if (insn & 0x01200000) {
7160
                /* Load/store doubleword.  */
7161
                if (rn == 15) {
7162
                    addr = new_tmp();
7163
                    tcg_gen_movi_i32(addr, s->pc & ~3);
7164
                } else {
7165
                    addr = load_reg(s, rn);
7166
                }
7167
                offset = (insn & 0xff) * 4;
7168
                if ((insn & (1 << 23)) == 0)
7169
                    offset = -offset;
7170
                if (insn & (1 << 24)) {
7171
                    tcg_gen_addi_i32(addr, addr, offset);
7172
                    offset = 0;
7173
                }
7174
                if (insn & (1 << 20)) {
7175
                    /* ldrd */
7176
                    tmp = gen_ld32(addr, IS_USER(s));
7177
                    store_reg(s, rs, tmp);
7178
                    tcg_gen_addi_i32(addr, addr, 4);
7179
                    tmp = gen_ld32(addr, IS_USER(s));
7180
                    store_reg(s, rd, tmp);
7181
                } else {
7182
                    /* strd */
7183
                    tmp = load_reg(s, rs);
7184
                    gen_st32(tmp, addr, IS_USER(s));
7185
                    tcg_gen_addi_i32(addr, addr, 4);
7186
                    tmp = load_reg(s, rd);
7187
                    gen_st32(tmp, addr, IS_USER(s));
7188
                }
7189
                if (insn & (1 << 21)) {
7190
                    /* Base writeback.  */
7191
                    if (rn == 15)
7192
                        goto illegal_op;
7193
                    tcg_gen_addi_i32(addr, addr, offset - 4);
7194
                    store_reg(s, rn, addr);
7195
                } else {
7196
                    dead_tmp(addr);
7197
                }
7198
            } else if ((insn & (1 << 23)) == 0) {
7199
                /* Load/store exclusive word.  */
7200
                addr = tcg_temp_local_new();
7201
                tcg_gen_mov_i32(addr, cpu_R[rn]);
7202
                if (insn & (1 << 20)) {
7203
                    gen_helper_mark_exclusive(cpu_env, addr);
7204
                    tmp = gen_ld32(addr, IS_USER(s));
7205
                    store_reg(s, rd, tmp);
7206
                } else {
7207
                    int label = gen_new_label();
7208
                    tmp2 = tcg_temp_local_new();
7209
                    gen_helper_test_exclusive(tmp2, cpu_env, addr);
7210
                    tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
7211
                    tmp = load_reg(s, rs);
7212
                    gen_st32(tmp, addr, IS_USER(s));
7213
                    gen_set_label(label);
7214
                    tcg_gen_mov_i32(cpu_R[rd], tmp2);
7215
                    tcg_temp_free(tmp2);
7216
                }
7217
                tcg_temp_free(addr);
7218
            } else if ((insn & (1 << 6)) == 0) {
7219
                /* Table Branch.  */
7220
                if (rn == 15) {
7221
                    addr = new_tmp();
7222
                    tcg_gen_movi_i32(addr, s->pc);
7223
                } else {
7224
                    addr = load_reg(s, rn);
7225
                }
7226
                tmp = load_reg(s, rm);
7227
                tcg_gen_add_i32(addr, addr, tmp);
7228
                if (insn & (1 << 4)) {
7229
                    /* tbh */
7230
                    tcg_gen_add_i32(addr, addr, tmp);
7231
                    dead_tmp(tmp);
7232
                    tmp = gen_ld16u(addr, IS_USER(s));
7233
                } else { /* tbb */
7234
                    dead_tmp(tmp);
7235
                    tmp = gen_ld8u(addr, IS_USER(s));
7236
                }
7237
                dead_tmp(addr);
7238
                tcg_gen_shli_i32(tmp, tmp, 1);
7239
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7240
                store_reg(s, 15, tmp);
7241
            } else {
7242
                /* Load/store exclusive byte/halfword/doubleword.  */
7243
                /* ??? These are not really atomic.  However we know
7244
                   we never have multiple CPUs running in parallel,
7245
                   so it is good enough.  */
7246
                op = (insn >> 4) & 0x3;
7247
                addr = tcg_temp_local_new();
7248
                tcg_gen_mov_i32(addr, cpu_R[rn]);
7249
                if (insn & (1 << 20)) {
7250
                    gen_helper_mark_exclusive(cpu_env, addr);
7251
                    switch (op) {
7252
                    case 0:
7253
                        tmp = gen_ld8u(addr, IS_USER(s));
7254
                        break;
7255
                    case 1:
7256
                        tmp = gen_ld16u(addr, IS_USER(s));
7257
                        break;
7258
                    case 3:
7259
                        tmp = gen_ld32(addr, IS_USER(s));
7260
                        tcg_gen_addi_i32(addr, addr, 4);
7261
                        tmp2 = gen_ld32(addr, IS_USER(s));
7262
                        store_reg(s, rd, tmp2);
7263
                        break;
7264
                    default:
7265
                        goto illegal_op;
7266
                    }
7267
                    store_reg(s, rs, tmp);
7268
                } else {
7269
                    int label = gen_new_label();
7270
                    tmp2 = tcg_temp_local_new();
7271
                    gen_helper_test_exclusive(tmp2, cpu_env, addr);
7272
                    tcg_gen_brcondi_i32(TCG_COND_NE, tmp2, 0, label);
7273
                    tmp = load_reg(s, rs);
7274
                    switch (op) {
7275
                    case 0:
7276
                        gen_st8(tmp, addr, IS_USER(s));
7277
                        break;
7278
                    case 1:
7279
                        gen_st16(tmp, addr, IS_USER(s));
7280
                        break;
7281
                    case 3:
7282
                        gen_st32(tmp, addr, IS_USER(s));
7283
                        tcg_gen_addi_i32(addr, addr, 4);
7284
                        tmp = load_reg(s, rd);
7285
                        gen_st32(tmp, addr, IS_USER(s));
7286
                        break;
7287
                    default:
7288
                        goto illegal_op;
7289
                    }
7290
                    gen_set_label(label);
7291
                    tcg_gen_mov_i32(cpu_R[rm], tmp2);
7292
                    tcg_temp_free(tmp2);
7293
                }
7294
                tcg_temp_free(addr);
7295
            }
7296
        } else {
7297
            /* Load/store multiple, RFE, SRS.  */
7298
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7299
                /* Not available in user mode.  */
7300
                if (IS_USER(s))
7301
                    goto illegal_op;
7302
                if (insn & (1 << 20)) {
7303
                    /* rfe */
7304
                    addr = load_reg(s, rn);
7305
                    if ((insn & (1 << 24)) == 0)
7306
                        tcg_gen_addi_i32(addr, addr, -8);
7307
                    /* Load PC into tmp and CPSR into tmp2.  */
7308
                    tmp = gen_ld32(addr, 0);
7309
                    tcg_gen_addi_i32(addr, addr, 4);
7310
                    tmp2 = gen_ld32(addr, 0);
7311
                    if (insn & (1 << 21)) {
7312
                        /* Base writeback.  */
7313
                        if (insn & (1 << 24)) {
7314
                            tcg_gen_addi_i32(addr, addr, 4);
7315
                        } else {
7316
                            tcg_gen_addi_i32(addr, addr, -4);
7317
                        }
7318
                        store_reg(s, rn, addr);
7319
                    } else {
7320
                        dead_tmp(addr);
7321
                    }
7322
                    gen_rfe(s, tmp, tmp2);
7323
                } else {
7324
                    /* srs */
7325
                    op = (insn & 0x1f);
7326
                    if (op == (env->uncached_cpsr & CPSR_M)) {
7327
                        addr = load_reg(s, 13);
7328
                    } else {
7329
                        addr = new_tmp();
7330
                        gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7331
                    }
7332
                    if ((insn & (1 << 24)) == 0) {
7333
                        tcg_gen_addi_i32(addr, addr, -8);
7334
                    }
7335
                    tmp = load_reg(s, 14);
7336
                    gen_st32(tmp, addr, 0);
7337
                    tcg_gen_addi_i32(addr, addr, 4);
7338
                    tmp = new_tmp();
7339
                    gen_helper_cpsr_read(tmp);
7340
                    gen_st32(tmp, addr, 0);
7341
                    if (insn & (1 << 21)) {
7342
                        if ((insn & (1 << 24)) == 0) {
7343
                            tcg_gen_addi_i32(addr, addr, -4);
7344
                        } else {
7345
                            tcg_gen_addi_i32(addr, addr, 4);
7346
                        }
7347
                        if (op == (env->uncached_cpsr & CPSR_M)) {
7348
                            store_reg(s, 13, addr);
7349
                        } else {
7350
                            gen_helper_set_r13_banked(cpu_env,
7351
                                tcg_const_i32(op), addr);
7352
                        }
7353
                    } else {
7354
                        dead_tmp(addr);
7355
                    }
7356
                }
7357
            } else {
7358
                int i;
7359
                /* Load/store multiple.  */
7360
                addr = load_reg(s, rn);
7361
                offset = 0;
7362
                for (i = 0; i < 16; i++) {
7363
                    if (insn & (1 << i))
7364
                        offset += 4;
7365
                }
7366
                if (insn & (1 << 24)) {
7367
                    tcg_gen_addi_i32(addr, addr, -offset);
7368
                }
7369

    
7370
                for (i = 0; i < 16; i++) {
7371
                    if ((insn & (1 << i)) == 0)
7372
                        continue;
7373
                    if (insn & (1 << 20)) {
7374
                        /* Load.  */
7375
                        tmp = gen_ld32(addr, IS_USER(s));
7376
                        if (i == 15) {
7377
                            gen_bx(s, tmp);
7378
                        } else {
7379
                            store_reg(s, i, tmp);
7380
                        }
7381
                    } else {
7382
                        /* Store.  */
7383
                        tmp = load_reg(s, i);
7384
                        gen_st32(tmp, addr, IS_USER(s));
7385
                    }
7386
                    tcg_gen_addi_i32(addr, addr, 4);
7387
                }
7388
                if (insn & (1 << 21)) {
7389
                    /* Base register writeback.  */
7390
                    if (insn & (1 << 24)) {
7391
                        tcg_gen_addi_i32(addr, addr, -offset);
7392
                    }
7393
                    /* Fault if writeback register is in register list.  */
7394
                    if (insn & (1 << rn))
7395
                        goto illegal_op;
7396
                    store_reg(s, rn, addr);
7397
                } else {
7398
                    dead_tmp(addr);
7399
                }
7400
            }
7401
        }
7402
        break;
7403
    case 5: /* Data processing register constant shift.  */
7404
        if (rn == 15) {
7405
            tmp = new_tmp();
7406
            tcg_gen_movi_i32(tmp, 0);
7407
        } else {
7408
            tmp = load_reg(s, rn);
7409
        }
7410
        tmp2 = load_reg(s, rm);
7411
        op = (insn >> 21) & 0xf;
7412
        shiftop = (insn >> 4) & 3;
7413
        shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7414
        conds = (insn & (1 << 20)) != 0;
7415
        logic_cc = (conds && thumb2_logic_op(op));
7416
        gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7417
        if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
7418
            goto illegal_op;
7419
        dead_tmp(tmp2);
7420
        if (rd != 15) {
7421
            store_reg(s, rd, tmp);
7422
        } else {
7423
            dead_tmp(tmp);
7424
        }
7425
        break;
7426
    case 13: /* Misc data processing.  */
7427
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7428
        if (op < 4 && (insn & 0xf000) != 0xf000)
7429
            goto illegal_op;
7430
        switch (op) {
7431
        case 0: /* Register controlled shift.  */
7432
            tmp = load_reg(s, rn);
7433
            tmp2 = load_reg(s, rm);
7434
            if ((insn & 0x70) != 0)
7435
                goto illegal_op;
7436
            op = (insn >> 21) & 3;
7437
            logic_cc = (insn & (1 << 20)) != 0;
7438
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7439
            if (logic_cc)
7440
                gen_logic_CC(tmp);
7441
            store_reg_bx(env, s, rd, tmp);
7442
            break;
7443
        case 1: /* Sign/zero extend.  */
7444
            tmp = load_reg(s, rm);
7445
            shift = (insn >> 4) & 3;
7446
            /* ??? In many cases it's not neccessary to do a
7447
               rotate, a shift is sufficient.  */
7448
            if (shift != 0)
7449
                tcg_gen_rori_i32(tmp, tmp, shift * 8);
7450
            op = (insn >> 20) & 7;
7451
            switch (op) {
7452
            case 0: gen_sxth(tmp);   break;
7453
            case 1: gen_uxth(tmp);   break;
7454
            case 2: gen_sxtb16(tmp); break;
7455
            case 3: gen_uxtb16(tmp); break;
7456
            case 4: gen_sxtb(tmp);   break;
7457
            case 5: gen_uxtb(tmp);   break;
7458
            default: goto illegal_op;
7459
            }
7460
            if (rn != 15) {
7461
                tmp2 = load_reg(s, rn);
7462
                if ((op >> 1) == 1) {
7463
                    gen_add16(tmp, tmp2);
7464
                } else {
7465
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7466
                    dead_tmp(tmp2);
7467
                }
7468
            }
7469
            store_reg(s, rd, tmp);
7470
            break;
7471
        case 2: /* SIMD add/subtract.  */
7472
            op = (insn >> 20) & 7;
7473
            shift = (insn >> 4) & 7;
7474
            if ((op & 3) == 3 || (shift & 3) == 3)
7475
                goto illegal_op;
7476
            tmp = load_reg(s, rn);
7477
            tmp2 = load_reg(s, rm);
7478
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7479
            dead_tmp(tmp2);
7480
            store_reg(s, rd, tmp);
7481
            break;
7482
        case 3: /* Other data processing.  */
7483
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7484
            if (op < 4) {
7485
                /* Saturating add/subtract.  */
7486
                tmp = load_reg(s, rn);
7487
                tmp2 = load_reg(s, rm);
7488
                if (op & 2)
7489
                    gen_helper_double_saturate(tmp, tmp);
7490
                if (op & 1)
7491
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7492
                else
7493
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7494
                dead_tmp(tmp2);
7495
            } else {
7496
                tmp = load_reg(s, rn);
7497
                switch (op) {
7498
                case 0x0a: /* rbit */
7499
                    gen_helper_rbit(tmp, tmp);
7500
                    break;
7501
                case 0x08: /* rev */
7502
                    tcg_gen_bswap32_i32(tmp, tmp);
7503
                    break;
7504
                case 0x09: /* rev16 */
7505
                    gen_rev16(tmp);
7506
                    break;
7507
                case 0x0b: /* revsh */
7508
                    gen_revsh(tmp);
7509
                    break;
7510
                case 0x10: /* sel */
7511
                    tmp2 = load_reg(s, rm);
7512
                    tmp3 = new_tmp();
7513
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7514
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7515
                    dead_tmp(tmp3);
7516
                    dead_tmp(tmp2);
7517
                    break;
7518
                case 0x18: /* clz */
7519
                    gen_helper_clz(tmp, tmp);
7520
                    break;
7521
                default:
7522
                    goto illegal_op;
7523
                }
7524
            }
7525
            store_reg(s, rd, tmp);
7526
            break;
7527
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7528
            op = (insn >> 4) & 0xf;
7529
            tmp = load_reg(s, rn);
7530
            tmp2 = load_reg(s, rm);
7531
            switch ((insn >> 20) & 7) {
7532
            case 0: /* 32 x 32 -> 32 */
7533
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7534
                dead_tmp(tmp2);
7535
                if (rs != 15) {
7536
                    tmp2 = load_reg(s, rs);
7537
                    if (op)
7538
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7539
                    else
7540
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7541
                    dead_tmp(tmp2);
7542
                }
7543
                break;
7544
            case 1: /* 16 x 16 -> 32 */
7545
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7546
                dead_tmp(tmp2);
7547
                if (rs != 15) {
7548
                    tmp2 = load_reg(s, rs);
7549
                    gen_helper_add_setq(tmp, tmp, tmp2);
7550
                    dead_tmp(tmp2);
7551
                }
7552
                break;
7553
            case 2: /* Dual multiply add.  */
7554
            case 4: /* Dual multiply subtract.  */
7555
                if (op)
7556
                    gen_swap_half(tmp2);
7557
                gen_smul_dual(tmp, tmp2);
7558
                /* This addition cannot overflow.  */
7559
                if (insn & (1 << 22)) {
7560
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7561
                } else {
7562
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7563
                }
7564
                dead_tmp(tmp2);
7565
                if (rs != 15)
7566
                  {
7567
                    tmp2 = load_reg(s, rs);
7568
                    gen_helper_add_setq(tmp, tmp, tmp2);
7569
                    dead_tmp(tmp2);
7570
                  }
7571
                break;
7572
            case 3: /* 32 * 16 -> 32msb */
7573
                if (op)
7574
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7575
                else
7576
                    gen_sxth(tmp2);
7577
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7578
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7579
                tmp = new_tmp();
7580
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7581
                if (rs != 15)
7582
                  {
7583
                    tmp2 = load_reg(s, rs);
7584
                    gen_helper_add_setq(tmp, tmp, tmp2);
7585
                    dead_tmp(tmp2);
7586
                  }
7587
                break;
7588
            case 5: case 6: /* 32 * 32 -> 32msb */
7589
                gen_imull(tmp, tmp2);
7590
                if (insn & (1 << 5)) {
7591
                    gen_roundqd(tmp, tmp2);
7592
                    dead_tmp(tmp2);
7593
                } else {
7594
                    dead_tmp(tmp);
7595
                    tmp = tmp2;
7596
                }
7597
                if (rs != 15) {
7598
                    tmp2 = load_reg(s, rs);
7599
                    if (insn & (1 << 21)) {
7600
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7601
                    } else {
7602
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7603
                    }
7604
                    dead_tmp(tmp2);
7605
                }
7606
                break;
7607
            case 7: /* Unsigned sum of absolute differences.  */
7608
                gen_helper_usad8(tmp, tmp, tmp2);
7609
                dead_tmp(tmp2);
7610
                if (rs != 15) {
7611
                    tmp2 = load_reg(s, rs);
7612
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7613
                    dead_tmp(tmp2);
7614
                }
7615
                break;
7616
            }
7617
            store_reg(s, rd, tmp);
7618
            break;
7619
        case 6: case 7: /* 64-bit multiply, Divide.  */
7620
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7621
            tmp = load_reg(s, rn);
7622
            tmp2 = load_reg(s, rm);
7623
            if ((op & 0x50) == 0x10) {
7624
                /* sdiv, udiv */
7625
                if (!arm_feature(env, ARM_FEATURE_DIV))
7626
                    goto illegal_op;
7627
                if (op & 0x20)
7628
                    gen_helper_udiv(tmp, tmp, tmp2);
7629
                else
7630
                    gen_helper_sdiv(tmp, tmp, tmp2);
7631
                dead_tmp(tmp2);
7632
                store_reg(s, rd, tmp);
7633
            } else if ((op & 0xe) == 0xc) {
7634
                /* Dual multiply accumulate long.  */
7635
                if (op & 1)
7636
                    gen_swap_half(tmp2);
7637
                gen_smul_dual(tmp, tmp2);
7638
                if (op & 0x10) {
7639
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7640
                } else {
7641
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7642
                }
7643
                dead_tmp(tmp2);
7644
                /* BUGFIX */
7645
                tmp64 = tcg_temp_new_i64();
7646
                tcg_gen_ext_i32_i64(tmp64, tmp);
7647
                dead_tmp(tmp);
7648
                gen_addq(s, tmp64, rs, rd);
7649
                gen_storeq_reg(s, rs, rd, tmp64);
7650
            } else {
7651
                if (op & 0x20) {
7652
                    /* Unsigned 64-bit multiply  */
7653
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7654
                } else {
7655
                    if (op & 8) {
7656
                        /* smlalxy */
7657
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7658
                        dead_tmp(tmp2);
7659
                        tmp64 = tcg_temp_new_i64();
7660
                        tcg_gen_ext_i32_i64(tmp64, tmp);
7661
                        dead_tmp(tmp);
7662
                    } else {
7663
                        /* Signed 64-bit multiply  */
7664
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7665
                    }
7666
                }
7667
                if (op & 4) {
7668
                    /* umaal */
7669
                    gen_addq_lo(s, tmp64, rs);
7670
                    gen_addq_lo(s, tmp64, rd);
7671
                } else if (op & 0x40) {
7672
                    /* 64-bit accumulate.  */
7673
                    gen_addq(s, tmp64, rs, rd);
7674
                }
7675
                gen_storeq_reg(s, rs, rd, tmp64);
7676
            }
7677
            break;
7678
        }
7679
        break;
7680
    case 6: case 7: case 14: case 15:
7681
        /* Coprocessor.  */
7682
        if (((insn >> 24) & 3) == 3) {
7683
            /* Translate into the equivalent ARM encoding.  */
7684
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7685
            if (disas_neon_data_insn(env, s, insn))
7686
                goto illegal_op;
7687
        } else {
7688
            if (insn & (1 << 28))
7689
                goto illegal_op;
7690
            if (disas_coproc_insn (env, s, insn))
7691
                goto illegal_op;
7692
        }
7693
        break;
7694
    case 8: case 9: case 10: case 11:
7695
        if (insn & (1 << 15)) {
7696
            /* Branches, misc control.  */
7697
            if (insn & 0x5000) {
7698
                /* Unconditional branch.  */
7699
                /* signextend(hw1[10:0]) -> offset[:12].  */
7700
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7701
                /* hw1[10:0] -> offset[11:1].  */
7702
                offset |= (insn & 0x7ff) << 1;
7703
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7704
                   offset[24:22] already have the same value because of the
7705
                   sign extension above.  */
7706
                offset ^= ((~insn) & (1 << 13)) << 10;
7707
                offset ^= ((~insn) & (1 << 11)) << 11;
7708

    
7709
                if (insn & (1 << 14)) {
7710
                    /* Branch and link.  */
7711
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
7712
                }
7713

    
7714
                offset += s->pc;
7715
                if (insn & (1 << 12)) {
7716
                    /* b/bl */
7717
                    gen_jmp(s, offset);
7718
                } else {
7719
                    /* blx */
7720
                    offset &= ~(uint32_t)2;
7721
                    gen_bx_im(s, offset);
7722
                }
7723
            } else if (((insn >> 23) & 7) == 7) {
7724
                /* Misc control */
7725
                if (insn & (1 << 13))
7726
                    goto illegal_op;
7727

    
7728
                if (insn & (1 << 26)) {
7729
                    /* Secure monitor call (v6Z) */
7730
                    goto illegal_op; /* not implemented.  */
7731
                } else {
7732
                    op = (insn >> 20) & 7;
7733
                    switch (op) {
7734
                    case 0: /* msr cpsr.  */
7735
                        if (IS_M(env)) {
7736
                            tmp = load_reg(s, rn);
7737
                            addr = tcg_const_i32(insn & 0xff);
7738
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7739
                            gen_lookup_tb(s);
7740
                            break;
7741
                        }
7742
                        /* fall through */
7743
                    case 1: /* msr spsr.  */
7744
                        if (IS_M(env))
7745
                            goto illegal_op;
7746
                        tmp = load_reg(s, rn);
7747
                        if (gen_set_psr(s,
7748
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7749
                              op == 1, tmp))
7750
                            goto illegal_op;
7751
                        break;
7752
                    case 2: /* cps, nop-hint.  */
7753
                        if (((insn >> 8) & 7) == 0) {
7754
                            gen_nop_hint(s, insn & 0xff);
7755
                        }
7756
                        /* Implemented as NOP in user mode.  */
7757
                        if (IS_USER(s))
7758
                            break;
7759
                        offset = 0;
7760
                        imm = 0;
7761
                        if (insn & (1 << 10)) {
7762
                            if (insn & (1 << 7))
7763
                                offset |= CPSR_A;
7764
                            if (insn & (1 << 6))
7765
                                offset |= CPSR_I;
7766
                            if (insn & (1 << 5))
7767
                                offset |= CPSR_F;
7768
                            if (insn & (1 << 9))
7769
                                imm = CPSR_A | CPSR_I | CPSR_F;
7770
                        }
7771
                        if (insn & (1 << 8)) {
7772
                            offset |= 0x1f;
7773
                            imm |= (insn & 0x1f);
7774
                        }
7775
                        if (offset) {
7776
                            gen_set_psr_im(s, offset, 0, imm);
7777
                        }
7778
                        break;
7779
                    case 3: /* Special control operations.  */
7780
                        op = (insn >> 4) & 0xf;
7781
                        switch (op) {
7782
                        case 2: /* clrex */
7783
                            gen_helper_clrex(cpu_env);
7784
                            break;
7785
                        case 4: /* dsb */
7786
                        case 5: /* dmb */
7787
                        case 6: /* isb */
7788
                            /* These execute as NOPs.  */
7789
                            ARCH(7);
7790
                            break;
7791
                        default:
7792
                            goto illegal_op;
7793
                        }
7794
                        break;
7795
                    case 4: /* bxj */
7796
                        /* Trivial implementation equivalent to bx.  */
7797
                        tmp = load_reg(s, rn);
7798
                        gen_bx(s, tmp);
7799
                        break;
7800
                    case 5: /* Exception return.  */
7801
                        /* Unpredictable in user mode.  */
7802
                        goto illegal_op;
7803
                    case 6: /* mrs cpsr.  */
7804
                        tmp = new_tmp();
7805
                        if (IS_M(env)) {
7806
                            addr = tcg_const_i32(insn & 0xff);
7807
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
7808
                        } else {
7809
                            gen_helper_cpsr_read(tmp);
7810
                        }
7811
                        store_reg(s, rd, tmp);
7812
                        break;
7813
                    case 7: /* mrs spsr.  */
7814
                        /* Not accessible in user mode.  */
7815
                        if (IS_USER(s) || IS_M(env))
7816
                            goto illegal_op;
7817
                        tmp = load_cpu_field(spsr);
7818
                        store_reg(s, rd, tmp);
7819
                        break;
7820
                    }
7821
                }
7822
            } else {
7823
                /* Conditional branch.  */
7824
                op = (insn >> 22) & 0xf;
7825
                /* Generate a conditional jump to next instruction.  */
7826
                s->condlabel = gen_new_label();
7827
                gen_test_cc(op ^ 1, s->condlabel);
7828
                s->condjmp = 1;
7829

    
7830
                /* offset[11:1] = insn[10:0] */
7831
                offset = (insn & 0x7ff) << 1;
7832
                /* offset[17:12] = insn[21:16].  */
7833
                offset |= (insn & 0x003f0000) >> 4;
7834
                /* offset[31:20] = insn[26].  */
7835
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7836
                /* offset[18] = insn[13].  */
7837
                offset |= (insn & (1 << 13)) << 5;
7838
                /* offset[19] = insn[11].  */
7839
                offset |= (insn & (1 << 11)) << 8;
7840

    
7841
                /* jump to the offset */
7842
                gen_jmp(s, s->pc + offset);
7843
            }
7844
        } else {
7845
            /* Data processing immediate.  */
7846
            if (insn & (1 << 25)) {
7847
                if (insn & (1 << 24)) {
7848
                    if (insn & (1 << 20))
7849
                        goto illegal_op;
7850
                    /* Bitfield/Saturate.  */
7851
                    op = (insn >> 21) & 7;
7852
                    imm = insn & 0x1f;
7853
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7854
                    if (rn == 15) {
7855
                        tmp = new_tmp();
7856
                        tcg_gen_movi_i32(tmp, 0);
7857
                    } else {
7858
                        tmp = load_reg(s, rn);
7859
                    }
7860
                    switch (op) {
7861
                    case 2: /* Signed bitfield extract.  */
7862
                        imm++;
7863
                        if (shift + imm > 32)
7864
                            goto illegal_op;
7865
                        if (imm < 32)
7866
                            gen_sbfx(tmp, shift, imm);
7867
                        break;
7868
                    case 6: /* Unsigned bitfield extract.  */
7869
                        imm++;
7870
                        if (shift + imm > 32)
7871
                            goto illegal_op;
7872
                        if (imm < 32)
7873
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
7874
                        break;
7875
                    case 3: /* Bitfield insert/clear.  */
7876
                        if (imm < shift)
7877
                            goto illegal_op;
7878
                        imm = imm + 1 - shift;
7879
                        if (imm != 32) {
7880
                            tmp2 = load_reg(s, rd);
7881
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7882
                            dead_tmp(tmp2);
7883
                        }
7884
                        break;
7885
                    case 7:
7886
                        goto illegal_op;
7887
                    default: /* Saturate.  */
7888
                        if (shift) {
7889
                            if (op & 1)
7890
                                tcg_gen_sari_i32(tmp, tmp, shift);
7891
                            else
7892
                                tcg_gen_shli_i32(tmp, tmp, shift);
7893
                        }
7894
                        tmp2 = tcg_const_i32(imm);
7895
                        if (op & 4) {
7896
                            /* Unsigned.  */
7897
                            if ((op & 1) && shift == 0)
7898
                                gen_helper_usat16(tmp, tmp, tmp2);
7899
                            else
7900
                                gen_helper_usat(tmp, tmp, tmp2);
7901
                        } else {
7902
                            /* Signed.  */
7903
                            if ((op & 1) && shift == 0)
7904
                                gen_helper_ssat16(tmp, tmp, tmp2);
7905
                            else
7906
                                gen_helper_ssat(tmp, tmp, tmp2);
7907
                        }
7908
                        break;
7909
                    }
7910
                    store_reg(s, rd, tmp);
7911
                } else {
7912
                    imm = ((insn & 0x04000000) >> 15)
7913
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
7914
                    if (insn & (1 << 22)) {
7915
                        /* 16-bit immediate.  */
7916
                        imm |= (insn >> 4) & 0xf000;
7917
                        if (insn & (1 << 23)) {
7918
                            /* movt */
7919
                            tmp = load_reg(s, rd);
7920
                            tcg_gen_ext16u_i32(tmp, tmp);
7921
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
7922
                        } else {
7923
                            /* movw */
7924
                            tmp = new_tmp();
7925
                            tcg_gen_movi_i32(tmp, imm);
7926
                        }
7927
                    } else {
7928
                        /* Add/sub 12-bit immediate.  */
7929
                        if (rn == 15) {
7930
                            offset = s->pc & ~(uint32_t)3;
7931
                            if (insn & (1 << 23))
7932
                                offset -= imm;
7933
                            else
7934
                                offset += imm;
7935
                            tmp = new_tmp();
7936
                            tcg_gen_movi_i32(tmp, offset);
7937
                        } else {
7938
                            tmp = load_reg(s, rn);
7939
                            if (insn & (1 << 23))
7940
                                tcg_gen_subi_i32(tmp, tmp, imm);
7941
                            else
7942
                                tcg_gen_addi_i32(tmp, tmp, imm);
7943
                        }
7944
                    }
7945
                    store_reg(s, rd, tmp);
7946
                }
7947
            } else {
7948
                int shifter_out = 0;
7949
                /* modified 12-bit immediate.  */
7950
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7951
                imm = (insn & 0xff);
7952
                switch (shift) {
7953
                case 0: /* XY */
7954
                    /* Nothing to do.  */
7955
                    break;
7956
                case 1: /* 00XY00XY */
7957
                    imm |= imm << 16;
7958
                    break;
7959
                case 2: /* XY00XY00 */
7960
                    imm |= imm << 16;
7961
                    imm <<= 8;
7962
                    break;
7963
                case 3: /* XYXYXYXY */
7964
                    imm |= imm << 16;
7965
                    imm |= imm << 8;
7966
                    break;
7967
                default: /* Rotated constant.  */
7968
                    shift = (shift << 1) | (imm >> 7);
7969
                    imm |= 0x80;
7970
                    imm = imm << (32 - shift);
7971
                    shifter_out = 1;
7972
                    break;
7973
                }
7974
                tmp2 = new_tmp();
7975
                tcg_gen_movi_i32(tmp2, imm);
7976
                rn = (insn >> 16) & 0xf;
7977
                if (rn == 15) {
7978
                    tmp = new_tmp();
7979
                    tcg_gen_movi_i32(tmp, 0);
7980
                } else {
7981
                    tmp = load_reg(s, rn);
7982
                }
7983
                op = (insn >> 21) & 0xf;
7984
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7985
                                       shifter_out, tmp, tmp2))
7986
                    goto illegal_op;
7987
                dead_tmp(tmp2);
7988
                rd = (insn >> 8) & 0xf;
7989
                if (rd != 15) {
7990
                    store_reg(s, rd, tmp);
7991
                } else {
7992
                    dead_tmp(tmp);
7993
                }
7994
            }
7995
        }
7996
        break;
7997
    case 12: /* Load/store single data item.  */
7998
        {
7999
        int postinc = 0;
8000
        int writeback = 0;
8001
        int user;
8002
        if ((insn & 0x01100000) == 0x01000000) {
8003
            if (disas_neon_ls_insn(env, s, insn))
8004
                goto illegal_op;
8005
            break;
8006
        }
8007
        user = IS_USER(s);
8008
        if (rn == 15) {
8009
            addr = new_tmp();
8010
            /* PC relative.  */
8011
            /* s->pc has already been incremented by 4.  */
8012
            imm = s->pc & 0xfffffffc;
8013
            if (insn & (1 << 23))
8014
                imm += insn & 0xfff;
8015
            else
8016
                imm -= insn & 0xfff;
8017
            tcg_gen_movi_i32(addr, imm);
8018
        } else {
8019
            addr = load_reg(s, rn);
8020
            if (insn & (1 << 23)) {
8021
                /* Positive offset.  */
8022
                imm = insn & 0xfff;
8023
                tcg_gen_addi_i32(addr, addr, imm);
8024
            } else {
8025
                op = (insn >> 8) & 7;
8026
                imm = insn & 0xff;
8027
                switch (op) {
8028
                case 0: case 8: /* Shifted Register.  */
8029
                    shift = (insn >> 4) & 0xf;
8030
                    if (shift > 3)
8031
                        goto illegal_op;
8032
                    tmp = load_reg(s, rm);
8033
                    if (shift)
8034
                        tcg_gen_shli_i32(tmp, tmp, shift);
8035
                    tcg_gen_add_i32(addr, addr, tmp);
8036
                    dead_tmp(tmp);
8037
                    break;
8038
                case 4: /* Negative offset.  */
8039
                    tcg_gen_addi_i32(addr, addr, -imm);
8040
                    break;
8041
                case 6: /* User privilege.  */
8042
                    tcg_gen_addi_i32(addr, addr, imm);
8043
                    user = 1;
8044
                    break;
8045
                case 1: /* Post-decrement.  */
8046
                    imm = -imm;
8047
                    /* Fall through.  */
8048
                case 3: /* Post-increment.  */
8049
                    postinc = 1;
8050
                    writeback = 1;
8051
                    break;
8052
                case 5: /* Pre-decrement.  */
8053
                    imm = -imm;
8054
                    /* Fall through.  */
8055
                case 7: /* Pre-increment.  */
8056
                    tcg_gen_addi_i32(addr, addr, imm);
8057
                    writeback = 1;
8058
                    break;
8059
                default:
8060
                    goto illegal_op;
8061
                }
8062
            }
8063
        }
8064
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8065
        if (insn & (1 << 20)) {
8066
            /* Load.  */
8067
            if (rs == 15 && op != 2) {
8068
                if (op & 2)
8069
                    goto illegal_op;
8070
                /* Memory hint.  Implemented as NOP.  */
8071
            } else {
8072
                switch (op) {
8073
                case 0: tmp = gen_ld8u(addr, user); break;
8074
                case 4: tmp = gen_ld8s(addr, user); break;
8075
                case 1: tmp = gen_ld16u(addr, user); break;
8076
                case 5: tmp = gen_ld16s(addr, user); break;
8077
                case 2: tmp = gen_ld32(addr, user); break;
8078
                default: goto illegal_op;
8079
                }
8080
                if (rs == 15) {
8081
                    gen_bx(s, tmp);
8082
                } else {
8083
                    store_reg(s, rs, tmp);
8084
                }
8085
            }
8086
        } else {
8087
            /* Store.  */
8088
            if (rs == 15)
8089
                goto illegal_op;
8090
            tmp = load_reg(s, rs);
8091
            switch (op) {
8092
            case 0: gen_st8(tmp, addr, user); break;
8093
            case 1: gen_st16(tmp, addr, user); break;
8094
            case 2: gen_st32(tmp, addr, user); break;
8095
            default: goto illegal_op;
8096
            }
8097
        }
8098
        if (postinc)
8099
            tcg_gen_addi_i32(addr, addr, imm);
8100
        if (writeback) {
8101
            store_reg(s, rn, addr);
8102
        } else {
8103
            dead_tmp(addr);
8104
        }
8105
        }
8106
        break;
8107
    default:
8108
        goto illegal_op;
8109
    }
8110
    return 0;
8111
illegal_op:
8112
    return 1;
8113
}
8114

    
8115
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8116
{
8117
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8118
    int32_t offset;
8119
    int i;
8120
    TCGv tmp;
8121
    TCGv tmp2;
8122
    TCGv addr;
8123

    
8124
    if (s->condexec_mask) {
8125
        cond = s->condexec_cond;
8126
        s->condlabel = gen_new_label();
8127
        gen_test_cc(cond ^ 1, s->condlabel);
8128
        s->condjmp = 1;
8129
    }
8130

    
8131
    insn = lduw_code(s->pc);
8132
    s->pc += 2;
8133

    
8134
    switch (insn >> 12) {
8135
    case 0: case 1:
8136

    
8137
        rd = insn & 7;
8138
        op = (insn >> 11) & 3;
8139
        if (op == 3) {
8140
            /* add/subtract */
8141
            rn = (insn >> 3) & 7;
8142
            tmp = load_reg(s, rn);
8143
            if (insn & (1 << 10)) {
8144
                /* immediate */
8145
                tmp2 = new_tmp();
8146
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8147
            } else {
8148
                /* reg */
8149
                rm = (insn >> 6) & 7;
8150
                tmp2 = load_reg(s, rm);
8151
            }
8152
            if (insn & (1 << 9)) {
8153
                if (s->condexec_mask)
8154
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8155
                else
8156
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8157
            } else {
8158
                if (s->condexec_mask)
8159
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8160
                else
8161
                    gen_helper_add_cc(tmp, tmp, tmp2);
8162
            }
8163
            dead_tmp(tmp2);
8164
            store_reg(s, rd, tmp);
8165
        } else {
8166
            /* shift immediate */
8167
            rm = (insn >> 3) & 7;
8168
            shift = (insn >> 6) & 0x1f;
8169
            tmp = load_reg(s, rm);
8170
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8171
            if (!s->condexec_mask)
8172
                gen_logic_CC(tmp);
8173
            store_reg(s, rd, tmp);
8174
        }
8175
        break;
8176
    case 2: case 3:
8177
        /* arithmetic large immediate */
8178
        op = (insn >> 11) & 3;
8179
        rd = (insn >> 8) & 0x7;
8180
        if (op == 0) { /* mov */
8181
            tmp = new_tmp();
8182
            tcg_gen_movi_i32(tmp, insn & 0xff);
8183
            if (!s->condexec_mask)
8184
                gen_logic_CC(tmp);
8185
            store_reg(s, rd, tmp);
8186
        } else {
8187
            tmp = load_reg(s, rd);
8188
            tmp2 = new_tmp();
8189
            tcg_gen_movi_i32(tmp2, insn & 0xff);
8190
            switch (op) {
8191
            case 1: /* cmp */
8192
                gen_helper_sub_cc(tmp, tmp, tmp2);
8193
                dead_tmp(tmp);
8194
                dead_tmp(tmp2);
8195
                break;
8196
            case 2: /* add */
8197
                if (s->condexec_mask)
8198
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8199
                else
8200
                    gen_helper_add_cc(tmp, tmp, tmp2);
8201
                dead_tmp(tmp2);
8202
                store_reg(s, rd, tmp);
8203
                break;
8204
            case 3: /* sub */
8205
                if (s->condexec_mask)
8206
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8207
                else
8208
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8209
                dead_tmp(tmp2);
8210
                store_reg(s, rd, tmp);
8211
                break;
8212
            }
8213
        }
8214
        break;
8215
    case 4:
8216
        if (insn & (1 << 11)) {
8217
            rd = (insn >> 8) & 7;
8218
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8219
            val = s->pc + 2 + ((insn & 0xff) * 4);
8220
            val &= ~(uint32_t)2;
8221
            addr = new_tmp();
8222
            tcg_gen_movi_i32(addr, val);
8223
            tmp = gen_ld32(addr, IS_USER(s));
8224
            dead_tmp(addr);
8225
            store_reg(s, rd, tmp);
8226
            break;
8227
        }
8228
        if (insn & (1 << 10)) {
8229
            /* data processing extended or blx */
8230
            rd = (insn & 7) | ((insn >> 4) & 8);
8231
            rm = (insn >> 3) & 0xf;
8232
            op = (insn >> 8) & 3;
8233
            switch (op) {
8234
            case 0: /* add */
8235
                tmp = load_reg(s, rd);
8236
                tmp2 = load_reg(s, rm);
8237
                tcg_gen_add_i32(tmp, tmp, tmp2);
8238
                dead_tmp(tmp2);
8239
                store_reg(s, rd, tmp);
8240
                break;
8241
            case 1: /* cmp */
8242
                tmp = load_reg(s, rd);
8243
                tmp2 = load_reg(s, rm);
8244
                gen_helper_sub_cc(tmp, tmp, tmp2);
8245
                dead_tmp(tmp2);
8246
                dead_tmp(tmp);
8247
                break;
8248
            case 2: /* mov/cpy */
8249
                tmp = load_reg(s, rm);
8250
                store_reg(s, rd, tmp);
8251
                break;
8252
            case 3:/* branch [and link] exchange thumb register */
8253
                tmp = load_reg(s, rm);
8254
                if (insn & (1 << 7)) {
8255
                    val = (uint32_t)s->pc | 1;
8256
                    tmp2 = new_tmp();
8257
                    tcg_gen_movi_i32(tmp2, val);
8258
                    store_reg(s, 14, tmp2);
8259
                }
8260
                gen_bx(s, tmp);
8261
                break;
8262
            }
8263
            break;
8264
        }
8265

    
8266
        /* data processing register */
8267
        rd = insn & 7;
8268
        rm = (insn >> 3) & 7;
8269
        op = (insn >> 6) & 0xf;
8270
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8271
            /* the shift/rotate ops want the operands backwards */
8272
            val = rm;
8273
            rm = rd;
8274
            rd = val;
8275
            val = 1;
8276
        } else {
8277
            val = 0;
8278
        }
8279

    
8280
        if (op == 9) { /* neg */
8281
            tmp = new_tmp();
8282
            tcg_gen_movi_i32(tmp, 0);
8283
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
8284
            tmp = load_reg(s, rd);
8285
        } else {
8286
            TCGV_UNUSED(tmp);
8287
        }
8288

    
8289
        tmp2 = load_reg(s, rm);
8290
        switch (op) {
8291
        case 0x0: /* and */
8292
            tcg_gen_and_i32(tmp, tmp, tmp2);
8293
            if (!s->condexec_mask)
8294
                gen_logic_CC(tmp);
8295
            break;
8296
        case 0x1: /* eor */
8297
            tcg_gen_xor_i32(tmp, tmp, tmp2);
8298
            if (!s->condexec_mask)
8299
                gen_logic_CC(tmp);
8300
            break;
8301
        case 0x2: /* lsl */
8302
            if (s->condexec_mask) {
8303
                gen_helper_shl(tmp2, tmp2, tmp);
8304
            } else {
8305
                gen_helper_shl_cc(tmp2, tmp2, tmp);
8306
                gen_logic_CC(tmp2);
8307
            }
8308
            break;
8309
        case 0x3: /* lsr */
8310
            if (s->condexec_mask) {
8311
                gen_helper_shr(tmp2, tmp2, tmp);
8312
            } else {
8313
                gen_helper_shr_cc(tmp2, tmp2, tmp);
8314
                gen_logic_CC(tmp2);
8315
            }
8316
            break;
8317
        case 0x4: /* asr */
8318
            if (s->condexec_mask) {
8319
                gen_helper_sar(tmp2, tmp2, tmp);
8320
            } else {
8321
                gen_helper_sar_cc(tmp2, tmp2, tmp);
8322
                gen_logic_CC(tmp2);
8323
            }
8324
            break;
8325
        case 0x5: /* adc */
8326
            if (s->condexec_mask)
8327
                gen_adc(tmp, tmp2);
8328
            else
8329
                gen_helper_adc_cc(tmp, tmp, tmp2);
8330
            break;
8331
        case 0x6: /* sbc */
8332
            if (s->condexec_mask)
8333
                gen_sub_carry(tmp, tmp, tmp2);
8334
            else
8335
                gen_helper_sbc_cc(tmp, tmp, tmp2);
8336
            break;
8337
        case 0x7: /* ror */
8338
            if (s->condexec_mask) {
8339
                gen_helper_ror(tmp2, tmp2, tmp);
8340
            } else {
8341
                gen_helper_ror_cc(tmp2, tmp2, tmp);
8342
                gen_logic_CC(tmp2);
8343
            }
8344
            break;
8345
        case 0x8: /* tst */
8346
            tcg_gen_and_i32(tmp, tmp, tmp2);
8347
            gen_logic_CC(tmp);
8348
            rd = 16;
8349
            break;
8350
        case 0x9: /* neg */
8351
            if (s->condexec_mask)
8352
                tcg_gen_neg_i32(tmp, tmp2);
8353
            else
8354
                gen_helper_sub_cc(tmp, tmp, tmp2);
8355
            break;
8356
        case 0xa: /* cmp */
8357
            gen_helper_sub_cc(tmp, tmp, tmp2);
8358
            rd = 16;
8359
            break;
8360
        case 0xb: /* cmn */
8361
            gen_helper_add_cc(tmp, tmp, tmp2);
8362
            rd = 16;
8363
            break;
8364
        case 0xc: /* orr */
8365
            tcg_gen_or_i32(tmp, tmp, tmp2);
8366
            if (!s->condexec_mask)
8367
                gen_logic_CC(tmp);
8368
            break;
8369
        case 0xd: /* mul */
8370
            gen_mull(tmp, tmp2);
8371
            if (!s->condexec_mask)
8372
                gen_logic_CC(tmp);
8373
            break;
8374
        case 0xe: /* bic */
8375
            tcg_gen_bic_i32(tmp, tmp, tmp2);
8376
            if (!s->condexec_mask)
8377
                gen_logic_CC(tmp);
8378
            break;
8379
        case 0xf: /* mvn */
8380
            tcg_gen_not_i32(tmp2, tmp2);
8381
            if (!s->condexec_mask)
8382
                gen_logic_CC(tmp2);
8383
            val = 1;
8384
            rm = rd;
8385
            break;
8386
        }
8387
        if (rd != 16) {
8388
            if (val) {
8389
                store_reg(s, rm, tmp2);
8390
                if (op != 0xf)
8391
                    dead_tmp(tmp);
8392
            } else {
8393
                store_reg(s, rd, tmp);
8394
                dead_tmp(tmp2);
8395
            }
8396
        } else {
8397
            dead_tmp(tmp);
8398
            dead_tmp(tmp2);
8399
        }
8400
        break;
8401

    
8402
    case 5:
8403
        /* load/store register offset.  */
8404
        rd = insn & 7;
8405
        rn = (insn >> 3) & 7;
8406
        rm = (insn >> 6) & 7;
8407
        op = (insn >> 9) & 7;
8408
        addr = load_reg(s, rn);
8409
        tmp = load_reg(s, rm);
8410
        tcg_gen_add_i32(addr, addr, tmp);
8411
        dead_tmp(tmp);
8412

    
8413
        if (op < 3) /* store */
8414
            tmp = load_reg(s, rd);
8415

    
8416
        switch (op) {
8417
        case 0: /* str */
8418
            gen_st32(tmp, addr, IS_USER(s));
8419
            break;
8420
        case 1: /* strh */
8421
            gen_st16(tmp, addr, IS_USER(s));
8422
            break;
8423
        case 2: /* strb */
8424
            gen_st8(tmp, addr, IS_USER(s));
8425
            break;
8426
        case 3: /* ldrsb */
8427
            tmp = gen_ld8s(addr, IS_USER(s));
8428
            break;
8429
        case 4: /* ldr */
8430
            tmp = gen_ld32(addr, IS_USER(s));
8431
            break;
8432
        case 5: /* ldrh */
8433
            tmp = gen_ld16u(addr, IS_USER(s));
8434
            break;
8435
        case 6: /* ldrb */
8436
            tmp = gen_ld8u(addr, IS_USER(s));
8437
            break;
8438
        case 7: /* ldrsh */
8439
            tmp = gen_ld16s(addr, IS_USER(s));
8440
            break;
8441
        }
8442
        if (op >= 3) /* load */
8443
            store_reg(s, rd, tmp);
8444
        dead_tmp(addr);
8445
        break;
8446

    
8447
    case 6:
8448
        /* load/store word immediate offset */
8449
        rd = insn & 7;
8450
        rn = (insn >> 3) & 7;
8451
        addr = load_reg(s, rn);
8452
        val = (insn >> 4) & 0x7c;
8453
        tcg_gen_addi_i32(addr, addr, val);
8454

    
8455
        if (insn & (1 << 11)) {
8456
            /* load */
8457
            tmp = gen_ld32(addr, IS_USER(s));
8458
            store_reg(s, rd, tmp);
8459
        } else {
8460
            /* store */
8461
            tmp = load_reg(s, rd);
8462
            gen_st32(tmp, addr, IS_USER(s));
8463
        }
8464
        dead_tmp(addr);
8465
        break;
8466

    
8467
    case 7:
8468
        /* load/store byte immediate offset */
8469
        rd = insn & 7;
8470
        rn = (insn >> 3) & 7;
8471
        addr = load_reg(s, rn);
8472
        val = (insn >> 6) & 0x1f;
8473
        tcg_gen_addi_i32(addr, addr, val);
8474

    
8475
        if (insn & (1 << 11)) {
8476
            /* load */
8477
            tmp = gen_ld8u(addr, IS_USER(s));
8478
            store_reg(s, rd, tmp);
8479
        } else {
8480
            /* store */
8481
            tmp = load_reg(s, rd);
8482
            gen_st8(tmp, addr, IS_USER(s));
8483
        }
8484
        dead_tmp(addr);
8485
        break;
8486

    
8487
    case 8:
8488
        /* load/store halfword immediate offset */
8489
        rd = insn & 7;
8490
        rn = (insn >> 3) & 7;
8491
        addr = load_reg(s, rn);
8492
        val = (insn >> 5) & 0x3e;
8493
        tcg_gen_addi_i32(addr, addr, val);
8494

    
8495
        if (insn & (1 << 11)) {
8496
            /* load */
8497
            tmp = gen_ld16u(addr, IS_USER(s));
8498
            store_reg(s, rd, tmp);
8499
        } else {
8500
            /* store */
8501
            tmp = load_reg(s, rd);
8502
            gen_st16(tmp, addr, IS_USER(s));
8503
        }
8504
        dead_tmp(addr);
8505
        break;
8506

    
8507
    case 9:
8508
        /* load/store from stack */
8509
        rd = (insn >> 8) & 7;
8510
        addr = load_reg(s, 13);
8511
        val = (insn & 0xff) * 4;
8512
        tcg_gen_addi_i32(addr, addr, val);
8513

    
8514
        if (insn & (1 << 11)) {
8515
            /* load */
8516
            tmp = gen_ld32(addr, IS_USER(s));
8517
            store_reg(s, rd, tmp);
8518
        } else {
8519
            /* store */
8520
            tmp = load_reg(s, rd);
8521
            gen_st32(tmp, addr, IS_USER(s));
8522
        }
8523
        dead_tmp(addr);
8524
        break;
8525

    
8526
    case 10:
8527
        /* add to high reg */
8528
        rd = (insn >> 8) & 7;
8529
        if (insn & (1 << 11)) {
8530
            /* SP */
8531
            tmp = load_reg(s, 13);
8532
        } else {
8533
            /* PC. bit 1 is ignored.  */
8534
            tmp = new_tmp();
8535
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8536
        }
8537
        val = (insn & 0xff) * 4;
8538
        tcg_gen_addi_i32(tmp, tmp, val);
8539
        store_reg(s, rd, tmp);
8540
        break;
8541

    
8542
    case 11:
8543
        /* misc */
8544
        op = (insn >> 8) & 0xf;
8545
        switch (op) {
8546
        case 0:
8547
            /* adjust stack pointer */
8548
            tmp = load_reg(s, 13);
8549
            val = (insn & 0x7f) * 4;
8550
            if (insn & (1 << 7))
8551
                val = -(int32_t)val;
8552
            tcg_gen_addi_i32(tmp, tmp, val);
8553
            store_reg(s, 13, tmp);
8554
            break;
8555

    
8556
        case 2: /* sign/zero extend.  */
8557
            ARCH(6);
8558
            rd = insn & 7;
8559
            rm = (insn >> 3) & 7;
8560
            tmp = load_reg(s, rm);
8561
            switch ((insn >> 6) & 3) {
8562
            case 0: gen_sxth(tmp); break;
8563
            case 1: gen_sxtb(tmp); break;
8564
            case 2: gen_uxth(tmp); break;
8565
            case 3: gen_uxtb(tmp); break;
8566
            }
8567
            store_reg(s, rd, tmp);
8568
            break;
8569
        case 4: case 5: case 0xc: case 0xd:
8570
            /* push/pop */
8571
            addr = load_reg(s, 13);
8572
            if (insn & (1 << 8))
8573
                offset = 4;
8574
            else
8575
                offset = 0;
8576
            for (i = 0; i < 8; i++) {
8577
                if (insn & (1 << i))
8578
                    offset += 4;
8579
            }
8580
            if ((insn & (1 << 11)) == 0) {
8581
                tcg_gen_addi_i32(addr, addr, -offset);
8582
            }
8583
            for (i = 0; i < 8; i++) {
8584
                if (insn & (1 << i)) {
8585
                    if (insn & (1 << 11)) {
8586
                        /* pop */
8587
                        tmp = gen_ld32(addr, IS_USER(s));
8588
                        store_reg(s, i, tmp);
8589
                    } else {
8590
                        /* push */
8591
                        tmp = load_reg(s, i);
8592
                        gen_st32(tmp, addr, IS_USER(s));
8593
                    }
8594
                    /* advance to the next address.  */
8595
                    tcg_gen_addi_i32(addr, addr, 4);
8596
                }
8597
            }
8598
            TCGV_UNUSED(tmp);
8599
            if (insn & (1 << 8)) {
8600
                if (insn & (1 << 11)) {
8601
                    /* pop pc */
8602
                    tmp = gen_ld32(addr, IS_USER(s));
8603
                    /* don't set the pc until the rest of the instruction
8604
                       has completed */
8605
                } else {
8606
                    /* push lr */
8607
                    tmp = load_reg(s, 14);
8608
                    gen_st32(tmp, addr, IS_USER(s));
8609
                }
8610
                tcg_gen_addi_i32(addr, addr, 4);
8611
            }
8612
            if ((insn & (1 << 11)) == 0) {
8613
                tcg_gen_addi_i32(addr, addr, -offset);
8614
            }
8615
            /* write back the new stack pointer */
8616
            store_reg(s, 13, addr);
8617
            /* set the new PC value */
8618
            if ((insn & 0x0900) == 0x0900)
8619
                gen_bx(s, tmp);
8620
            break;
8621

    
8622
        case 1: case 3: case 9: case 11: /* czb */
8623
            rm = insn & 7;
8624
            tmp = load_reg(s, rm);
8625
            s->condlabel = gen_new_label();
8626
            s->condjmp = 1;
8627
            if (insn & (1 << 11))
8628
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8629
            else
8630
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8631
            dead_tmp(tmp);
8632
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8633
            val = (uint32_t)s->pc + 2;
8634
            val += offset;
8635
            gen_jmp(s, val);
8636
            break;
8637

    
8638
        case 15: /* IT, nop-hint.  */
8639
            if ((insn & 0xf) == 0) {
8640
                gen_nop_hint(s, (insn >> 4) & 0xf);
8641
                break;
8642
            }
8643
            /* If Then.  */
8644
            s->condexec_cond = (insn >> 4) & 0xe;
8645
            s->condexec_mask = insn & 0x1f;
8646
            /* No actual code generated for this insn, just setup state.  */
8647
            break;
8648

    
8649
        case 0xe: /* bkpt */
8650
            gen_set_condexec(s);
8651
            gen_set_pc_im(s->pc - 2);
8652
            gen_exception(EXCP_BKPT);
8653
            s->is_jmp = DISAS_JUMP;
8654
            break;
8655

    
8656
        case 0xa: /* rev */
8657
            ARCH(6);
8658
            rn = (insn >> 3) & 0x7;
8659
            rd = insn & 0x7;
8660
            tmp = load_reg(s, rn);
8661
            switch ((insn >> 6) & 3) {
8662
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8663
            case 1: gen_rev16(tmp); break;
8664
            case 3: gen_revsh(tmp); break;
8665
            default: goto illegal_op;
8666
            }
8667
            store_reg(s, rd, tmp);
8668
            break;
8669

    
8670
        case 6: /* cps */
8671
            ARCH(6);
8672
            if (IS_USER(s))
8673
                break;
8674
            if (IS_M(env)) {
8675
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8676
                /* PRIMASK */
8677
                if (insn & 1) {
8678
                    addr = tcg_const_i32(16);
8679
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8680
                }
8681
                /* FAULTMASK */
8682
                if (insn & 2) {
8683
                    addr = tcg_const_i32(17);
8684
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8685
                }
8686
                gen_lookup_tb(s);
8687
            } else {
8688
                if (insn & (1 << 4))
8689
                    shift = CPSR_A | CPSR_I | CPSR_F;
8690
                else
8691
                    shift = 0;
8692
                gen_set_psr_im(s, shift, 0, ((insn & 7) << 6) & shift);
8693
            }
8694
            break;
8695

    
8696
        default:
8697
            goto undef;
8698
        }
8699
        break;
8700

    
8701
    case 12:
8702
        /* load/store multiple */
8703
        rn = (insn >> 8) & 0x7;
8704
        addr = load_reg(s, rn);
8705
        for (i = 0; i < 8; i++) {
8706
            if (insn & (1 << i)) {
8707
                if (insn & (1 << 11)) {
8708
                    /* load */
8709
                    tmp = gen_ld32(addr, IS_USER(s));
8710
                    store_reg(s, i, tmp);
8711
                } else {
8712
                    /* store */
8713
                    tmp = load_reg(s, i);
8714
                    gen_st32(tmp, addr, IS_USER(s));
8715
                }
8716
                /* advance to the next address */
8717
                tcg_gen_addi_i32(addr, addr, 4);
8718
            }
8719
        }
8720
        /* Base register writeback.  */
8721
        if ((insn & (1 << rn)) == 0) {
8722
            store_reg(s, rn, addr);
8723
        } else {
8724
            dead_tmp(addr);
8725
        }
8726
        break;
8727

    
8728
    case 13:
8729
        /* conditional branch or swi */
8730
        cond = (insn >> 8) & 0xf;
8731
        if (cond == 0xe)
8732
            goto undef;
8733

    
8734
        if (cond == 0xf) {
8735
            /* swi */
8736
            gen_set_condexec(s);
8737
            gen_set_pc_im(s->pc);
8738
            s->is_jmp = DISAS_SWI;
8739
            break;
8740
        }
8741
        /* generate a conditional jump to next instruction */
8742
        s->condlabel = gen_new_label();
8743
        gen_test_cc(cond ^ 1, s->condlabel);
8744
        s->condjmp = 1;
8745

    
8746
        /* jump to the offset */
8747
        val = (uint32_t)s->pc + 2;
8748
        offset = ((int32_t)insn << 24) >> 24;
8749
        val += offset << 1;
8750
        gen_jmp(s, val);
8751
        break;
8752

    
8753
    case 14:
8754
        if (insn & (1 << 11)) {
8755
            if (disas_thumb2_insn(env, s, insn))
8756
              goto undef32;
8757
            break;
8758
        }
8759
        /* unconditional branch */
8760
        val = (uint32_t)s->pc;
8761
        offset = ((int32_t)insn << 21) >> 21;
8762
        val += (offset << 1) + 2;
8763
        gen_jmp(s, val);
8764
        break;
8765

    
8766
    case 15:
8767
        if (disas_thumb2_insn(env, s, insn))
8768
            goto undef32;
8769
        break;
8770
    }
8771
    return;
8772
undef32:
8773
    gen_set_condexec(s);
8774
    gen_set_pc_im(s->pc - 4);
8775
    gen_exception(EXCP_UDEF);
8776
    s->is_jmp = DISAS_JUMP;
8777
    return;
8778
illegal_op:
8779
undef:
8780
    gen_set_condexec(s);
8781
    gen_set_pc_im(s->pc - 2);
8782
    gen_exception(EXCP_UDEF);
8783
    s->is_jmp = DISAS_JUMP;
8784
}
8785

    
8786
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8787
   basic block 'tb'. If search_pc is TRUE, also generate PC
8788
   information for each intermediate instruction. */
8789
static inline void gen_intermediate_code_internal(CPUState *env,
8790
                                                  TranslationBlock *tb,
8791
                                                  int search_pc)
8792
{
8793
    DisasContext dc1, *dc = &dc1;
8794
    CPUBreakpoint *bp;
8795
    uint16_t *gen_opc_end;
8796
    int j, lj;
8797
    target_ulong pc_start;
8798
    uint32_t next_page_start;
8799
    int num_insns;
8800
    int max_insns;
8801

    
8802
    /* generate intermediate code */
8803
    num_temps = 0;
8804

    
8805
    pc_start = tb->pc;
8806

    
8807
    dc->tb = tb;
8808

    
8809
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8810

    
8811
    dc->is_jmp = DISAS_NEXT;
8812
    dc->pc = pc_start;
8813
    dc->singlestep_enabled = env->singlestep_enabled;
8814
    dc->condjmp = 0;
8815
    dc->thumb = env->thumb;
8816
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8817
    dc->condexec_cond = env->condexec_bits >> 4;
8818
#if !defined(CONFIG_USER_ONLY)
8819
    if (IS_M(env)) {
8820
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8821
    } else {
8822
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8823
    }
8824
#endif
8825
    cpu_F0s = tcg_temp_new_i32();
8826
    cpu_F1s = tcg_temp_new_i32();
8827
    cpu_F0d = tcg_temp_new_i64();
8828
    cpu_F1d = tcg_temp_new_i64();
8829
    cpu_V0 = cpu_F0d;
8830
    cpu_V1 = cpu_F1d;
8831
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
8832
    cpu_M0 = tcg_temp_new_i64();
8833
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8834
    lj = -1;
8835
    num_insns = 0;
8836
    max_insns = tb->cflags & CF_COUNT_MASK;
8837
    if (max_insns == 0)
8838
        max_insns = CF_COUNT_MASK;
8839

    
8840
    gen_icount_start();
8841
    /* Reset the conditional execution bits immediately. This avoids
8842
       complications trying to do it at the end of the block.  */
8843
    if (env->condexec_bits)
8844
      {
8845
        TCGv tmp = new_tmp();
8846
        tcg_gen_movi_i32(tmp, 0);
8847
        store_cpu_field(tmp, condexec_bits);
8848
      }
8849
    do {
8850
#ifdef CONFIG_USER_ONLY
8851
        /* Intercept jump to the magic kernel page.  */
8852
        if (dc->pc >= 0xffff0000) {
8853
            /* We always get here via a jump, so know we are not in a
8854
               conditional execution block.  */
8855
            gen_exception(EXCP_KERNEL_TRAP);
8856
            dc->is_jmp = DISAS_UPDATE;
8857
            break;
8858
        }
8859
#else
8860
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8861
            /* We always get here via a jump, so know we are not in a
8862
               conditional execution block.  */
8863
            gen_exception(EXCP_EXCEPTION_EXIT);
8864
            dc->is_jmp = DISAS_UPDATE;
8865
            break;
8866
        }
8867
#endif
8868

    
8869
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
8870
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
8871
                if (bp->pc == dc->pc) {
8872
                    gen_set_condexec(dc);
8873
                    gen_set_pc_im(dc->pc);
8874
                    gen_exception(EXCP_DEBUG);
8875
                    dc->is_jmp = DISAS_JUMP;
8876
                    /* Advance PC so that clearing the breakpoint will
8877
                       invalidate this TB.  */
8878
                    dc->pc += 2;
8879
                    goto done_generating;
8880
                    break;
8881
                }
8882
            }
8883
        }
8884
        if (search_pc) {
8885
            j = gen_opc_ptr - gen_opc_buf;
8886
            if (lj < j) {
8887
                lj++;
8888
                while (lj < j)
8889
                    gen_opc_instr_start[lj++] = 0;
8890
            }
8891
            gen_opc_pc[lj] = dc->pc;
8892
            gen_opc_instr_start[lj] = 1;
8893
            gen_opc_icount[lj] = num_insns;
8894
        }
8895

    
8896
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8897
            gen_io_start();
8898

    
8899
        if (env->thumb) {
8900
            disas_thumb_insn(env, dc);
8901
            if (dc->condexec_mask) {
8902
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8903
                                   | ((dc->condexec_mask >> 4) & 1);
8904
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8905
                if (dc->condexec_mask == 0) {
8906
                    dc->condexec_cond = 0;
8907
                }
8908
            }
8909
        } else {
8910
            disas_arm_insn(env, dc);
8911
        }
8912
        if (num_temps) {
8913
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8914
            num_temps = 0;
8915
        }
8916

    
8917
        if (dc->condjmp && !dc->is_jmp) {
8918
            gen_set_label(dc->condlabel);
8919
            dc->condjmp = 0;
8920
        }
8921
        /* Translation stops when a conditional branch is encountered.
8922
         * Otherwise the subsequent code could get translated several times.
8923
         * Also stop translation when a page boundary is reached.  This
8924
         * ensures prefetch aborts occur at the right place.  */
8925
        num_insns ++;
8926
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8927
             !env->singlestep_enabled &&
8928
             !singlestep &&
8929
             dc->pc < next_page_start &&
8930
             num_insns < max_insns);
8931

    
8932
    if (tb->cflags & CF_LAST_IO) {
8933
        if (dc->condjmp) {
8934
            /* FIXME:  This can theoretically happen with self-modifying
8935
               code.  */
8936
            cpu_abort(env, "IO on conditional branch instruction");
8937
        }
8938
        gen_io_end();
8939
    }
8940

    
8941
    /* At this stage dc->condjmp will only be set when the skipped
8942
       instruction was a conditional branch or trap, and the PC has
8943
       already been written.  */
8944
    if (unlikely(env->singlestep_enabled)) {
8945
        /* Make sure the pc is updated, and raise a debug exception.  */
8946
        if (dc->condjmp) {
8947
            gen_set_condexec(dc);
8948
            if (dc->is_jmp == DISAS_SWI) {
8949
                gen_exception(EXCP_SWI);
8950
            } else {
8951
                gen_exception(EXCP_DEBUG);
8952
            }
8953
            gen_set_label(dc->condlabel);
8954
        }
8955
        if (dc->condjmp || !dc->is_jmp) {
8956
            gen_set_pc_im(dc->pc);
8957
            dc->condjmp = 0;
8958
        }
8959
        gen_set_condexec(dc);
8960
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8961
            gen_exception(EXCP_SWI);
8962
        } else {
8963
            /* FIXME: Single stepping a WFI insn will not halt
8964
               the CPU.  */
8965
            gen_exception(EXCP_DEBUG);
8966
        }
8967
    } else {
8968
        /* While branches must always occur at the end of an IT block,
8969
           there are a few other things that can cause us to terminate
8970
           the TB in the middel of an IT block:
8971
            - Exception generating instructions (bkpt, swi, undefined).
8972
            - Page boundaries.
8973
            - Hardware watchpoints.
8974
           Hardware breakpoints have already been handled and skip this code.
8975
         */
8976
        gen_set_condexec(dc);
8977
        switch(dc->is_jmp) {
8978
        case DISAS_NEXT:
8979
            gen_goto_tb(dc, 1, dc->pc);
8980
            break;
8981
        default:
8982
        case DISAS_JUMP:
8983
        case DISAS_UPDATE:
8984
            /* indicate that the hash table must be used to find the next TB */
8985
            tcg_gen_exit_tb(0);
8986
            break;
8987
        case DISAS_TB_JUMP:
8988
            /* nothing more to generate */
8989
            break;
8990
        case DISAS_WFI:
8991
            gen_helper_wfi();
8992
            break;
8993
        case DISAS_SWI:
8994
            gen_exception(EXCP_SWI);
8995
            break;
8996
        }
8997
        if (dc->condjmp) {
8998
            gen_set_label(dc->condlabel);
8999
            gen_set_condexec(dc);
9000
            gen_goto_tb(dc, 1, dc->pc);
9001
            dc->condjmp = 0;
9002
        }
9003
    }
9004

    
9005
done_generating:
9006
    gen_icount_end(tb, num_insns);
9007
    *gen_opc_ptr = INDEX_op_end;
9008

    
9009
#ifdef DEBUG_DISAS
9010
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9011
        qemu_log("----------------\n");
9012
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9013
        log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
9014
        qemu_log("\n");
9015
    }
9016
#endif
9017
    if (search_pc) {
9018
        j = gen_opc_ptr - gen_opc_buf;
9019
        lj++;
9020
        while (lj <= j)
9021
            gen_opc_instr_start[lj++] = 0;
9022
    } else {
9023
        tb->size = dc->pc - pc_start;
9024
        tb->icount = num_insns;
9025
    }
9026
}
9027

    
9028
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9029
{
9030
    gen_intermediate_code_internal(env, tb, 0);
9031
}
9032

    
9033
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9034
{
9035
    gen_intermediate_code_internal(env, tb, 1);
9036
}
9037

    
9038
static const char *cpu_mode_names[16] = {
9039
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9040
  "???", "???", "???", "und", "???", "???", "???", "sys"
9041
};
9042

    
9043
void cpu_dump_state(CPUState *env, FILE *f,
9044
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9045
                    int flags)
9046
{
9047
    int i;
9048
#if 0
9049
    union {
9050
        uint32_t i;
9051
        float s;
9052
    } s0, s1;
9053
    CPU_DoubleU d;
9054
    /* ??? This assumes float64 and double have the same layout.
9055
       Oh well, it's only debug dumps.  */
9056
    union {
9057
        float64 f64;
9058
        double d;
9059
    } d0;
9060
#endif
9061
    uint32_t psr;
9062

    
9063
    for(i=0;i<16;i++) {
9064
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9065
        if ((i % 4) == 3)
9066
            cpu_fprintf(f, "\n");
9067
        else
9068
            cpu_fprintf(f, " ");
9069
    }
9070
    psr = cpsr_read(env);
9071
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9072
                psr,
9073
                psr & (1 << 31) ? 'N' : '-',
9074
                psr & (1 << 30) ? 'Z' : '-',
9075
                psr & (1 << 29) ? 'C' : '-',
9076
                psr & (1 << 28) ? 'V' : '-',
9077
                psr & CPSR_T ? 'T' : 'A',
9078
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9079

    
9080
#if 0
9081
    for (i = 0; i < 16; i++) {
9082
        d.d = env->vfp.regs[i];
9083
        s0.i = d.l.lower;
9084
        s1.i = d.l.upper;
9085
        d0.f64 = d.d;
9086
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9087
                    i * 2, (int)s0.i, s0.s,
9088
                    i * 2 + 1, (int)s1.i, s1.s,
9089
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9090
                    d0.d);
9091
    }
9092
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9093
#endif
9094
}
9095

    
9096
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9097
                unsigned long searched_pc, int pc_pos, void *puc)
9098
{
9099
    env->regs[15] = gen_opc_pc[pc_pos];
9100
}