Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 71b3c3de

History | View | Annotate | Download (305.1 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_F0s, cpu_F1s;
82
static TCGv_i64 cpu_F0d, cpu_F1d;
83

    
84
#include "gen-icount.h"
85

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

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

    
95
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
96

    
97
    for (i = 0; i < 16; i++) {
98
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
99
                                          offsetof(CPUState, regs[i]),
100
                                          regnames[i]);
101
    }
102

    
103
#define GEN_HELPER 2
104
#include "helpers.h"
105
}
106

    
107
static int num_temps;
108

    
109
/* Allocate a temporary variable.  */
110
static TCGv_i32 new_tmp(void)
111
{
112
    num_temps++;
113
    return tcg_temp_new_i32();
114
}
115

    
116
/* Release a temporary variable.  */
117
static void dead_tmp(TCGv tmp)
118
{
119
    tcg_temp_free(tmp);
120
    num_temps--;
121
}
122

    
123
static inline TCGv load_cpu_offset(int offset)
124
{
125
    TCGv tmp = new_tmp();
126
    tcg_gen_ld_i32(tmp, cpu_env, offset);
127
    return tmp;
128
}
129

    
130
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
131

    
132
static inline void store_cpu_offset(TCGv var, int offset)
133
{
134
    tcg_gen_st_i32(var, cpu_env, offset);
135
    dead_tmp(var);
136
}
137

    
138
#define store_cpu_field(var, name) \
139
    store_cpu_offset(var, offsetof(CPUState, name))
140

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

    
157
/* Create a new temporary and set it to the value of a CPU register.  */
158
static inline TCGv load_reg(DisasContext *s, int reg)
159
{
160
    TCGv tmp = new_tmp();
161
    load_reg_var(s, tmp, reg);
162
    return tmp;
163
}
164

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

    
177
/* Value extensions.  */
178
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
179
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
180
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
181
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
182

    
183
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
184
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
185

    
186

    
187
static inline void gen_set_cpsr(TCGv var, uint32_t mask)
188
{
189
    TCGv tmp_mask = tcg_const_i32(mask);
190
    gen_helper_cpsr_write(var, tmp_mask);
191
    tcg_temp_free_i32(tmp_mask);
192
}
193
/* Set NZCV flags from the high 4 bits of var.  */
194
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
195

    
196
static void gen_exception(int excp)
197
{
198
    TCGv tmp = new_tmp();
199
    tcg_gen_movi_i32(tmp, excp);
200
    gen_helper_exception(tmp);
201
    dead_tmp(tmp);
202
}
203

    
204
static void gen_smul_dual(TCGv a, TCGv b)
205
{
206
    TCGv tmp1 = new_tmp();
207
    TCGv tmp2 = new_tmp();
208
    tcg_gen_ext16s_i32(tmp1, a);
209
    tcg_gen_ext16s_i32(tmp2, b);
210
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
211
    dead_tmp(tmp2);
212
    tcg_gen_sari_i32(a, a, 16);
213
    tcg_gen_sari_i32(b, b, 16);
214
    tcg_gen_mul_i32(b, b, a);
215
    tcg_gen_mov_i32(a, tmp1);
216
    dead_tmp(tmp1);
217
}
218

    
219
/* Byteswap each halfword.  */
220
static void gen_rev16(TCGv var)
221
{
222
    TCGv tmp = new_tmp();
223
    tcg_gen_shri_i32(tmp, var, 8);
224
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
225
    tcg_gen_shli_i32(var, var, 8);
226
    tcg_gen_andi_i32(var, var, 0xff00ff00);
227
    tcg_gen_or_i32(var, var, tmp);
228
    dead_tmp(tmp);
229
}
230

    
231
/* Byteswap low halfword and sign extend.  */
232
static void gen_revsh(TCGv var)
233
{
234
    TCGv tmp = new_tmp();
235
    tcg_gen_shri_i32(tmp, var, 8);
236
    tcg_gen_andi_i32(tmp, tmp, 0x00ff);
237
    tcg_gen_shli_i32(var, var, 8);
238
    tcg_gen_ext8s_i32(var, var);
239
    tcg_gen_or_i32(var, var, tmp);
240
    dead_tmp(tmp);
241
}
242

    
243
/* Unsigned bitfield extract.  */
244
static void gen_ubfx(TCGv var, int shift, uint32_t mask)
245
{
246
    if (shift)
247
        tcg_gen_shri_i32(var, var, shift);
248
    tcg_gen_andi_i32(var, var, mask);
249
}
250

    
251
/* Signed bitfield extract.  */
252
static void gen_sbfx(TCGv var, int shift, int width)
253
{
254
    uint32_t signbit;
255

    
256
    if (shift)
257
        tcg_gen_sari_i32(var, var, shift);
258
    if (shift + width < 32) {
259
        signbit = 1u << (width - 1);
260
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
261
        tcg_gen_xori_i32(var, var, signbit);
262
        tcg_gen_subi_i32(var, var, signbit);
263
    }
264
}
265

    
266
/* Bitfield insertion.  Insert val into base.  Clobbers base and val.  */
267
static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
268
{
269
    tcg_gen_andi_i32(val, val, mask);
270
    tcg_gen_shli_i32(val, val, shift);
271
    tcg_gen_andi_i32(base, base, ~(mask << shift));
272
    tcg_gen_or_i32(dest, base, val);
273
}
274

    
275
/* Round the top 32 bits of a 64-bit value.  */
276
static void gen_roundqd(TCGv a, TCGv b)
277
{
278
    tcg_gen_shri_i32(a, a, 31);
279
    tcg_gen_add_i32(a, a, b);
280
}
281

    
282
/* FIXME: Most targets have native widening multiplication.
283
   It would be good to use that instead of a full wide multiply.  */
284
/* 32x32->64 multiply.  Marks inputs as dead.  */
285
static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
286
{
287
    TCGv_i64 tmp1 = tcg_temp_new_i64();
288
    TCGv_i64 tmp2 = tcg_temp_new_i64();
289

    
290
    tcg_gen_extu_i32_i64(tmp1, a);
291
    dead_tmp(a);
292
    tcg_gen_extu_i32_i64(tmp2, b);
293
    dead_tmp(b);
294
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
295
    tcg_temp_free_i64(tmp2);
296
    return tmp1;
297
}
298

    
299
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
300
{
301
    TCGv_i64 tmp1 = tcg_temp_new_i64();
302
    TCGv_i64 tmp2 = tcg_temp_new_i64();
303

    
304
    tcg_gen_ext_i32_i64(tmp1, a);
305
    dead_tmp(a);
306
    tcg_gen_ext_i32_i64(tmp2, b);
307
    dead_tmp(b);
308
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
309
    tcg_temp_free_i64(tmp2);
310
    return tmp1;
311
}
312

    
313
/* Signed 32x32->64 multiply.  */
314
static void gen_imull(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
    tcg_gen_ext_i32_i64(tmp2, b);
321
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
322
    tcg_temp_free_i64(tmp2);
323
    tcg_gen_trunc_i64_i32(a, tmp1);
324
    tcg_gen_shri_i64(tmp1, tmp1, 32);
325
    tcg_gen_trunc_i64_i32(b, tmp1);
326
    tcg_temp_free_i64(tmp1);
327
}
328

    
329
/* Swap low and high halfwords.  */
330
static void gen_swap_half(TCGv var)
331
{
332
    TCGv tmp = new_tmp();
333
    tcg_gen_shri_i32(tmp, var, 16);
334
    tcg_gen_shli_i32(var, var, 16);
335
    tcg_gen_or_i32(var, var, tmp);
336
    dead_tmp(tmp);
337
}
338

    
339
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
340
    tmp = (t0 ^ t1) & 0x8000;
341
    t0 &= ~0x8000;
342
    t1 &= ~0x8000;
343
    t0 = (t0 + t1) ^ tmp;
344
 */
345

    
346
static void gen_add16(TCGv t0, TCGv t1)
347
{
348
    TCGv tmp = new_tmp();
349
    tcg_gen_xor_i32(tmp, t0, t1);
350
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
351
    tcg_gen_andi_i32(t0, t0, ~0x8000);
352
    tcg_gen_andi_i32(t1, t1, ~0x8000);
353
    tcg_gen_add_i32(t0, t0, t1);
354
    tcg_gen_xor_i32(t0, t0, tmp);
355
    dead_tmp(tmp);
356
    dead_tmp(t1);
357
}
358

    
359
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
360

    
361
/* Set CF to the top bit of var.  */
362
static void gen_set_CF_bit31(TCGv var)
363
{
364
    TCGv tmp = new_tmp();
365
    tcg_gen_shri_i32(tmp, var, 31);
366
    gen_set_CF(tmp);
367
    dead_tmp(tmp);
368
}
369

    
370
/* Set N and Z flags from var.  */
371
static inline void gen_logic_CC(TCGv var)
372
{
373
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
374
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
375
}
376

    
377
/* T0 += T1 + CF.  */
378
static void gen_adc(TCGv t0, TCGv t1)
379
{
380
    TCGv tmp;
381
    tcg_gen_add_i32(t0, t0, t1);
382
    tmp = load_cpu_field(CF);
383
    tcg_gen_add_i32(t0, t0, tmp);
384
    dead_tmp(tmp);
385
}
386

    
387
/* dest = T0 + T1 + CF. */
388
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
389
{
390
    TCGv tmp;
391
    tcg_gen_add_i32(dest, t0, t1);
392
    tmp = load_cpu_field(CF);
393
    tcg_gen_add_i32(dest, dest, tmp);
394
    dead_tmp(tmp);
395
}
396

    
397
/* dest = T0 - T1 + CF - 1.  */
398
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
399
{
400
    TCGv tmp;
401
    tcg_gen_sub_i32(dest, t0, t1);
402
    tmp = load_cpu_field(CF);
403
    tcg_gen_add_i32(dest, dest, tmp);
404
    tcg_gen_subi_i32(dest, dest, 1);
405
    dead_tmp(tmp);
406
}
407

    
408
/* T0 &= ~T1.  Clobbers T1.  */
409
/* FIXME: Implement bic natively.  */
410
static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
411
{
412
    TCGv tmp = new_tmp();
413
    tcg_gen_not_i32(tmp, t1);
414
    tcg_gen_and_i32(dest, t0, tmp);
415
    dead_tmp(tmp);
416
}
417

    
418
/* FIXME:  Implement this natively.  */
419
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
420

    
421
/* FIXME:  Implement this natively.  */
422
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
423
{
424
    TCGv tmp;
425

    
426
    if (i == 0)
427
        return;
428

    
429
    tmp = new_tmp();
430
    tcg_gen_shri_i32(tmp, t1, i);
431
    tcg_gen_shli_i32(t1, t1, 32 - i);
432
    tcg_gen_or_i32(t0, t1, tmp);
433
    dead_tmp(tmp);
434
}
435

    
436
static void shifter_out_im(TCGv var, int shift)
437
{
438
    TCGv tmp = new_tmp();
439
    if (shift == 0) {
440
        tcg_gen_andi_i32(tmp, var, 1);
441
    } else {
442
        tcg_gen_shri_i32(tmp, var, shift);
443
        if (shift != 31)
444
            tcg_gen_andi_i32(tmp, tmp, 1);
445
    }
446
    gen_set_CF(tmp);
447
    dead_tmp(tmp);
448
}
449

    
450
/* Shift by immediate.  Includes special handling for shift == 0.  */
451
static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
452
{
453
    switch (shiftop) {
454
    case 0: /* LSL */
455
        if (shift != 0) {
456
            if (flags)
457
                shifter_out_im(var, 32 - shift);
458
            tcg_gen_shli_i32(var, var, shift);
459
        }
460
        break;
461
    case 1: /* LSR */
462
        if (shift == 0) {
463
            if (flags) {
464
                tcg_gen_shri_i32(var, var, 31);
465
                gen_set_CF(var);
466
            }
467
            tcg_gen_movi_i32(var, 0);
468
        } else {
469
            if (flags)
470
                shifter_out_im(var, shift - 1);
471
            tcg_gen_shri_i32(var, var, shift);
472
        }
473
        break;
474
    case 2: /* ASR */
475
        if (shift == 0)
476
            shift = 32;
477
        if (flags)
478
            shifter_out_im(var, shift - 1);
479
        if (shift == 32)
480
          shift = 31;
481
        tcg_gen_sari_i32(var, var, shift);
482
        break;
483
    case 3: /* ROR/RRX */
484
        if (shift != 0) {
485
            if (flags)
486
                shifter_out_im(var, shift - 1);
487
            tcg_gen_rori_i32(var, var, shift); break;
488
        } else {
489
            TCGv tmp = load_cpu_field(CF);
490
            if (flags)
491
                shifter_out_im(var, 0);
492
            tcg_gen_shri_i32(var, var, 1);
493
            tcg_gen_shli_i32(tmp, tmp, 31);
494
            tcg_gen_or_i32(var, var, tmp);
495
            dead_tmp(tmp);
496
        }
497
    }
498
};
499

    
500
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
501
                                     TCGv shift, int flags)
502
{
503
    if (flags) {
504
        switch (shiftop) {
505
        case 0: gen_helper_shl_cc(var, var, shift); break;
506
        case 1: gen_helper_shr_cc(var, var, shift); break;
507
        case 2: gen_helper_sar_cc(var, var, shift); break;
508
        case 3: gen_helper_ror_cc(var, var, shift); break;
509
        }
510
    } else {
511
        switch (shiftop) {
512
        case 0: gen_helper_shl(var, var, shift); break;
513
        case 1: gen_helper_shr(var, var, shift); break;
514
        case 2: gen_helper_sar(var, var, shift); break;
515
        case 3: gen_helper_ror(var, var, shift); break;
516
        }
517
    }
518
    dead_tmp(shift);
519
}
520

    
521
#define PAS_OP(pfx) \
522
    switch (op2) {  \
523
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
524
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
525
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
526
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
527
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
528
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
529
    }
530
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
531
{
532
    TCGv_ptr tmp;
533

    
534
    switch (op1) {
535
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
536
    case 1:
537
        tmp = tcg_temp_new_ptr();
538
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
539
        PAS_OP(s)
540
        tcg_temp_free_ptr(tmp);
541
        break;
542
    case 5:
543
        tmp = tcg_temp_new_ptr();
544
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
545
        PAS_OP(u)
546
        tcg_temp_free_ptr(tmp);
547
        break;
548
#undef gen_pas_helper
549
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
550
    case 2:
551
        PAS_OP(q);
552
        break;
553
    case 3:
554
        PAS_OP(sh);
555
        break;
556
    case 6:
557
        PAS_OP(uq);
558
        break;
559
    case 7:
560
        PAS_OP(uh);
561
        break;
562
#undef gen_pas_helper
563
    }
564
}
565
#undef PAS_OP
566

    
567
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
568
#define PAS_OP(pfx) \
569
    switch (op2) {  \
570
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
571
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
572
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
573
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
574
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
575
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
576
    }
577
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
578
{
579
    TCGv_ptr tmp;
580

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

    
614
static void gen_test_cc(int cc, int label)
615
{
616
    TCGv tmp;
617
    TCGv tmp2;
618
    int inv;
619

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

    
712
static const uint8_t table_logic_cc[16] = {
713
    1, /* and */
714
    1, /* xor */
715
    0, /* sub */
716
    0, /* rsb */
717
    0, /* add */
718
    0, /* adc */
719
    0, /* sbc */
720
    0, /* rsc */
721
    1, /* andl */
722
    1, /* xorl */
723
    0, /* cmp */
724
    0, /* cmn */
725
    1, /* orr */
726
    1, /* mov */
727
    1, /* bic */
728
    1, /* mvn */
729
};
730

    
731
/* Set PC and Thumb state from an immediate address.  */
732
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
733
{
734
    TCGv tmp;
735

    
736
    s->is_jmp = DISAS_UPDATE;
737
    if (s->thumb != (addr & 1)) {
738
        tmp = new_tmp();
739
        tcg_gen_movi_i32(tmp, addr & 1);
740
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
741
        dead_tmp(tmp);
742
    }
743
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
744
}
745

    
746
/* Set PC and Thumb state from var.  var is marked as dead.  */
747
static inline void gen_bx(DisasContext *s, TCGv var)
748
{
749
    s->is_jmp = DISAS_UPDATE;
750
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
751
    tcg_gen_andi_i32(var, var, 1);
752
    store_cpu_field(var, thumb);
753
}
754

    
755
/* Variant of store_reg which uses branch&exchange logic when storing
756
   to r15 in ARM architecture v7 and above. The source must be a temporary
757
   and will be marked as dead. */
758
static inline void store_reg_bx(CPUState *env, DisasContext *s,
759
                                int reg, TCGv var)
760
{
761
    if (reg == 15 && ENABLE_ARCH_7) {
762
        gen_bx(s, var);
763
    } else {
764
        store_reg(s, reg, var);
765
    }
766
}
767

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

    
825
static inline void gen_set_pc_im(uint32_t val)
826
{
827
    tcg_gen_movi_i32(cpu_R[15], val);
828
}
829

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

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

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

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

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

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

    
902
VFP_OP2(add)
903
VFP_OP2(sub)
904
VFP_OP2(mul)
905
VFP_OP2(div)
906

    
907
#undef VFP_OP2
908

    
909
static inline void gen_vfp_abs(int dp)
910
{
911
    if (dp)
912
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
913
    else
914
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
915
}
916

    
917
static inline void gen_vfp_neg(int dp)
918
{
919
    if (dp)
920
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
921
    else
922
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
923
}
924

    
925
static inline void gen_vfp_sqrt(int dp)
926
{
927
    if (dp)
928
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
929
    else
930
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
931
}
932

    
933
static inline void gen_vfp_cmp(int dp)
934
{
935
    if (dp)
936
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
937
    else
938
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
939
}
940

    
941
static inline void gen_vfp_cmpe(int dp)
942
{
943
    if (dp)
944
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
945
    else
946
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
947
}
948

    
949
static inline void gen_vfp_F1_ld0(int dp)
950
{
951
    if (dp)
952
        tcg_gen_movi_i64(cpu_F1d, 0);
953
    else
954
        tcg_gen_movi_i32(cpu_F1s, 0);
955
}
956

    
957
static inline void gen_vfp_uito(int dp)
958
{
959
    if (dp)
960
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
961
    else
962
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
963
}
964

    
965
static inline void gen_vfp_sito(int dp)
966
{
967
    if (dp)
968
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
969
    else
970
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
971
}
972

    
973
static inline void gen_vfp_toui(int dp)
974
{
975
    if (dp)
976
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
977
    else
978
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
979
}
980

    
981
static inline void gen_vfp_touiz(int dp)
982
{
983
    if (dp)
984
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
985
    else
986
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
987
}
988

    
989
static inline void gen_vfp_tosi(int dp)
990
{
991
    if (dp)
992
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
993
    else
994
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
995
}
996

    
997
static inline void gen_vfp_tosiz(int dp)
998
{
999
    if (dp)
1000
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1001
    else
1002
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1003
}
1004

    
1005
#define VFP_GEN_FIX(name) \
1006
static inline void gen_vfp_##name(int dp, int shift) \
1007
{ \
1008
    TCGv tmp_shift = tcg_const_i32(shift); \
1009
    if (dp) \
1010
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, cpu_env);\
1011
    else \
1012
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, cpu_env);\
1013
    tcg_temp_free_i32(tmp_shift); \
1014
}
1015
VFP_GEN_FIX(tosh)
1016
VFP_GEN_FIX(tosl)
1017
VFP_GEN_FIX(touh)
1018
VFP_GEN_FIX(toul)
1019
VFP_GEN_FIX(shto)
1020
VFP_GEN_FIX(slto)
1021
VFP_GEN_FIX(uhto)
1022
VFP_GEN_FIX(ulto)
1023
#undef VFP_GEN_FIX
1024

    
1025
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
1026
{
1027
    if (dp)
1028
        tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1029
    else
1030
        tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1031
}
1032

    
1033
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
1034
{
1035
    if (dp)
1036
        tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1037
    else
1038
        tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1039
}
1040

    
1041
static inline long
1042
vfp_reg_offset (int dp, int reg)
1043
{
1044
    if (dp)
1045
        return offsetof(CPUARMState, vfp.regs[reg]);
1046
    else if (reg & 1) {
1047
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1048
          + offsetof(CPU_DoubleU, l.upper);
1049
    } else {
1050
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1051
          + offsetof(CPU_DoubleU, l.lower);
1052
    }
1053
}
1054

    
1055
/* Return the offset of a 32-bit piece of a NEON register.
1056
   zero is the least significant end of the register.  */
1057
static inline long
1058
neon_reg_offset (int reg, int n)
1059
{
1060
    int sreg;
1061
    sreg = reg * 2 + n;
1062
    return vfp_reg_offset(0, sreg);
1063
}
1064

    
1065
static TCGv neon_load_reg(int reg, int pass)
1066
{
1067
    TCGv tmp = new_tmp();
1068
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1069
    return tmp;
1070
}
1071

    
1072
static void neon_store_reg(int reg, int pass, TCGv var)
1073
{
1074
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1075
    dead_tmp(var);
1076
}
1077

    
1078
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1079
{
1080
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1081
}
1082

    
1083
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1084
{
1085
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1086
}
1087

    
1088
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1089
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1090
#define tcg_gen_st_f32 tcg_gen_st_i32
1091
#define tcg_gen_st_f64 tcg_gen_st_i64
1092

    
1093
static inline void gen_mov_F0_vreg(int dp, int reg)
1094
{
1095
    if (dp)
1096
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1097
    else
1098
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1099
}
1100

    
1101
static inline void gen_mov_F1_vreg(int dp, int reg)
1102
{
1103
    if (dp)
1104
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1105
    else
1106
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1107
}
1108

    
1109
static inline void gen_mov_vreg_F0(int dp, int reg)
1110
{
1111
    if (dp)
1112
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1113
    else
1114
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1115
}
1116

    
1117
#define ARM_CP_RW_BIT        (1 << 20)
1118

    
1119
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1120
{
1121
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1122
}
1123

    
1124
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1125
{
1126
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1127
}
1128

    
1129
static inline TCGv iwmmxt_load_creg(int reg)
1130
{
1131
    TCGv var = new_tmp();
1132
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1133
    return var;
1134
}
1135

    
1136
static inline void iwmmxt_store_creg(int reg, TCGv var)
1137
{
1138
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1139
}
1140

    
1141
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1142
{
1143
    iwmmxt_store_reg(cpu_M0, rn);
1144
}
1145

    
1146
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1147
{
1148
    iwmmxt_load_reg(cpu_M0, rn);
1149
}
1150

    
1151
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1152
{
1153
    iwmmxt_load_reg(cpu_V1, rn);
1154
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1155
}
1156

    
1157
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1158
{
1159
    iwmmxt_load_reg(cpu_V1, rn);
1160
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1161
}
1162

    
1163
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1164
{
1165
    iwmmxt_load_reg(cpu_V1, rn);
1166
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1167
}
1168

    
1169
#define IWMMXT_OP(name) \
1170
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1171
{ \
1172
    iwmmxt_load_reg(cpu_V1, rn); \
1173
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1174
}
1175

    
1176
#define IWMMXT_OP_ENV(name) \
1177
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1178
{ \
1179
    iwmmxt_load_reg(cpu_V1, rn); \
1180
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1181
}
1182

    
1183
#define IWMMXT_OP_ENV_SIZE(name) \
1184
IWMMXT_OP_ENV(name##b) \
1185
IWMMXT_OP_ENV(name##w) \
1186
IWMMXT_OP_ENV(name##l)
1187

    
1188
#define IWMMXT_OP_ENV1(name) \
1189
static inline void gen_op_iwmmxt_##name##_M0(void) \
1190
{ \
1191
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1192
}
1193

    
1194
IWMMXT_OP(maddsq)
1195
IWMMXT_OP(madduq)
1196
IWMMXT_OP(sadb)
1197
IWMMXT_OP(sadw)
1198
IWMMXT_OP(mulslw)
1199
IWMMXT_OP(mulshw)
1200
IWMMXT_OP(mululw)
1201
IWMMXT_OP(muluhw)
1202
IWMMXT_OP(macsw)
1203
IWMMXT_OP(macuw)
1204

    
1205
IWMMXT_OP_ENV_SIZE(unpackl)
1206
IWMMXT_OP_ENV_SIZE(unpackh)
1207

    
1208
IWMMXT_OP_ENV1(unpacklub)
1209
IWMMXT_OP_ENV1(unpackluw)
1210
IWMMXT_OP_ENV1(unpacklul)
1211
IWMMXT_OP_ENV1(unpackhub)
1212
IWMMXT_OP_ENV1(unpackhuw)
1213
IWMMXT_OP_ENV1(unpackhul)
1214
IWMMXT_OP_ENV1(unpacklsb)
1215
IWMMXT_OP_ENV1(unpacklsw)
1216
IWMMXT_OP_ENV1(unpacklsl)
1217
IWMMXT_OP_ENV1(unpackhsb)
1218
IWMMXT_OP_ENV1(unpackhsw)
1219
IWMMXT_OP_ENV1(unpackhsl)
1220

    
1221
IWMMXT_OP_ENV_SIZE(cmpeq)
1222
IWMMXT_OP_ENV_SIZE(cmpgtu)
1223
IWMMXT_OP_ENV_SIZE(cmpgts)
1224

    
1225
IWMMXT_OP_ENV_SIZE(mins)
1226
IWMMXT_OP_ENV_SIZE(minu)
1227
IWMMXT_OP_ENV_SIZE(maxs)
1228
IWMMXT_OP_ENV_SIZE(maxu)
1229

    
1230
IWMMXT_OP_ENV_SIZE(subn)
1231
IWMMXT_OP_ENV_SIZE(addn)
1232
IWMMXT_OP_ENV_SIZE(subu)
1233
IWMMXT_OP_ENV_SIZE(addu)
1234
IWMMXT_OP_ENV_SIZE(subs)
1235
IWMMXT_OP_ENV_SIZE(adds)
1236

    
1237
IWMMXT_OP_ENV(avgb0)
1238
IWMMXT_OP_ENV(avgb1)
1239
IWMMXT_OP_ENV(avgw0)
1240
IWMMXT_OP_ENV(avgw1)
1241

    
1242
IWMMXT_OP(msadb)
1243

    
1244
IWMMXT_OP_ENV(packuw)
1245
IWMMXT_OP_ENV(packul)
1246
IWMMXT_OP_ENV(packuq)
1247
IWMMXT_OP_ENV(packsw)
1248
IWMMXT_OP_ENV(packsl)
1249
IWMMXT_OP_ENV(packsq)
1250

    
1251
static void gen_op_iwmmxt_set_mup(void)
1252
{
1253
    TCGv tmp;
1254
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1255
    tcg_gen_ori_i32(tmp, tmp, 2);
1256
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1257
}
1258

    
1259
static void gen_op_iwmmxt_set_cup(void)
1260
{
1261
    TCGv tmp;
1262
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1263
    tcg_gen_ori_i32(tmp, tmp, 1);
1264
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1265
}
1266

    
1267
static void gen_op_iwmmxt_setpsr_nz(void)
1268
{
1269
    TCGv tmp = new_tmp();
1270
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1271
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1272
}
1273

    
1274
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1275
{
1276
    iwmmxt_load_reg(cpu_V1, rn);
1277
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1278
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1279
}
1280

    
1281
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1282
{
1283
    int rd;
1284
    uint32_t offset;
1285
    TCGv tmp;
1286

    
1287
    rd = (insn >> 16) & 0xf;
1288
    tmp = load_reg(s, rd);
1289

    
1290
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1291
    if (insn & (1 << 24)) {
1292
        /* Pre indexed */
1293
        if (insn & (1 << 23))
1294
            tcg_gen_addi_i32(tmp, tmp, offset);
1295
        else
1296
            tcg_gen_addi_i32(tmp, tmp, -offset);
1297
        tcg_gen_mov_i32(dest, tmp);
1298
        if (insn & (1 << 21))
1299
            store_reg(s, rd, tmp);
1300
        else
1301
            dead_tmp(tmp);
1302
    } else if (insn & (1 << 21)) {
1303
        /* Post indexed */
1304
        tcg_gen_mov_i32(dest, tmp);
1305
        if (insn & (1 << 23))
1306
            tcg_gen_addi_i32(tmp, tmp, offset);
1307
        else
1308
            tcg_gen_addi_i32(tmp, tmp, -offset);
1309
        store_reg(s, rd, tmp);
1310
    } else if (!(insn & (1 << 23)))
1311
        return 1;
1312
    return 0;
1313
}
1314

    
1315
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1316
{
1317
    int rd = (insn >> 0) & 0xf;
1318
    TCGv tmp;
1319

    
1320
    if (insn & (1 << 8)) {
1321
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1322
            return 1;
1323
        } else {
1324
            tmp = iwmmxt_load_creg(rd);
1325
        }
1326
    } else {
1327
        tmp = new_tmp();
1328
        iwmmxt_load_reg(cpu_V0, rd);
1329
        tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1330
    }
1331
    tcg_gen_andi_i32(tmp, tmp, mask);
1332
    tcg_gen_mov_i32(dest, tmp);
1333
    dead_tmp(tmp);
1334
    return 0;
1335
}
1336

    
1337
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1338
   (ie. an undefined instruction).  */
1339
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1340
{
1341
    int rd, wrd;
1342
    int rdhi, rdlo, rd0, rd1, i;
1343
    TCGv addr;
1344
    TCGv tmp, tmp2, tmp3;
1345

    
1346
    if ((insn & 0x0e000e00) == 0x0c000000) {
1347
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1348
            wrd = insn & 0xf;
1349
            rdlo = (insn >> 12) & 0xf;
1350
            rdhi = (insn >> 16) & 0xf;
1351
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1352
                iwmmxt_load_reg(cpu_V0, wrd);
1353
                tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1354
                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1355
                tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1356
            } else {                                        /* TMCRR */
1357
                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1358
                iwmmxt_store_reg(cpu_V0, wrd);
1359
                gen_op_iwmmxt_set_mup();
1360
            }
1361
            return 0;
1362
        }
1363

    
1364
        wrd = (insn >> 12) & 0xf;
1365
        addr = new_tmp();
1366
        if (gen_iwmmxt_address(s, insn, addr)) {
1367
            dead_tmp(addr);
1368
            return 1;
1369
        }
1370
        if (insn & ARM_CP_RW_BIT) {
1371
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1372
                tmp = new_tmp();
1373
                tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
1374
                iwmmxt_store_creg(wrd, tmp);
1375
            } else {
1376
                i = 1;
1377
                if (insn & (1 << 8)) {
1378
                    if (insn & (1 << 22)) {                /* WLDRD */
1379
                        tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s));
1380
                        i = 0;
1381
                    } else {                                /* WLDRW wRd */
1382
                        tmp = gen_ld32(addr, IS_USER(s));
1383
                    }
1384
                } else {
1385
                    if (insn & (1 << 22)) {                /* WLDRH */
1386
                        tmp = gen_ld16u(addr, IS_USER(s));
1387
                    } else {                                /* WLDRB */
1388
                        tmp = gen_ld8u(addr, IS_USER(s));
1389
                    }
1390
                }
1391
                if (i) {
1392
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
1393
                    dead_tmp(tmp);
1394
                }
1395
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1396
            }
1397
        } else {
1398
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1399
                tmp = iwmmxt_load_creg(wrd);
1400
                gen_st32(tmp, addr, IS_USER(s));
1401
            } else {
1402
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1403
                tmp = new_tmp();
1404
                if (insn & (1 << 8)) {
1405
                    if (insn & (1 << 22)) {                /* WSTRD */
1406
                        dead_tmp(tmp);
1407
                        tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s));
1408
                    } else {                                /* WSTRW wRd */
1409
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1410
                        gen_st32(tmp, addr, IS_USER(s));
1411
                    }
1412
                } else {
1413
                    if (insn & (1 << 22)) {                /* WSTRH */
1414
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1415
                        gen_st16(tmp, addr, IS_USER(s));
1416
                    } else {                                /* WSTRB */
1417
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1418
                        gen_st8(tmp, addr, IS_USER(s));
1419
                    }
1420
                }
1421
            }
1422
        }
1423
        return 0;
1424
    }
1425

    
1426
    if ((insn & 0x0f000000) != 0x0e000000)
1427
        return 1;
1428

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

    
2337
    return 0;
2338
}
2339

    
2340
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2341
   (ie. an undefined instruction).  */
2342
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2343
{
2344
    int acc, rd0, rd1, rdhi, rdlo;
2345
    TCGv tmp, tmp2;
2346

    
2347
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2348
        /* Multiply with Internal Accumulate Format */
2349
        rd0 = (insn >> 12) & 0xf;
2350
        rd1 = insn & 0xf;
2351
        acc = (insn >> 5) & 7;
2352

    
2353
        if (acc != 0)
2354
            return 1;
2355

    
2356
        tmp = load_reg(s, rd0);
2357
        tmp2 = load_reg(s, rd1);
2358
        switch ((insn >> 16) & 0xf) {
2359
        case 0x0:                                        /* MIA */
2360
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2361
            break;
2362
        case 0x8:                                        /* MIAPH */
2363
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2364
            break;
2365
        case 0xc:                                        /* MIABB */
2366
        case 0xd:                                        /* MIABT */
2367
        case 0xe:                                        /* MIATB */
2368
        case 0xf:                                        /* MIATT */
2369
            if (insn & (1 << 16))
2370
                tcg_gen_shri_i32(tmp, tmp, 16);
2371
            if (insn & (1 << 17))
2372
                tcg_gen_shri_i32(tmp2, tmp2, 16);
2373
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2374
            break;
2375
        default:
2376
            return 1;
2377
        }
2378
        dead_tmp(tmp2);
2379
        dead_tmp(tmp);
2380

    
2381
        gen_op_iwmmxt_movq_wRn_M0(acc);
2382
        return 0;
2383
    }
2384

    
2385
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2386
        /* Internal Accumulator Access Format */
2387
        rdhi = (insn >> 16) & 0xf;
2388
        rdlo = (insn >> 12) & 0xf;
2389
        acc = insn & 7;
2390

    
2391
        if (acc != 0)
2392
            return 1;
2393

    
2394
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2395
            iwmmxt_load_reg(cpu_V0, acc);
2396
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2397
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2398
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2399
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2400
        } else {                                        /* MAR */
2401
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2402
            iwmmxt_store_reg(cpu_V0, acc);
2403
        }
2404
        return 0;
2405
    }
2406

    
2407
    return 1;
2408
}
2409

    
2410
/* Disassemble system coprocessor instruction.  Return nonzero if
2411
   instruction is not defined.  */
2412
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2413
{
2414
    TCGv tmp, tmp2;
2415
    uint32_t rd = (insn >> 12) & 0xf;
2416
    uint32_t cp = (insn >> 8) & 0xf;
2417
    if (IS_USER(s)) {
2418
        return 1;
2419
    }
2420

    
2421
    if (insn & ARM_CP_RW_BIT) {
2422
        if (!env->cp[cp].cp_read)
2423
            return 1;
2424
        gen_set_pc_im(s->pc);
2425
        tmp = new_tmp();
2426
        tmp2 = tcg_const_i32(insn);
2427
        gen_helper_get_cp(tmp, cpu_env, tmp2);
2428
        tcg_temp_free(tmp2);
2429
        store_reg(s, rd, tmp);
2430
    } else {
2431
        if (!env->cp[cp].cp_write)
2432
            return 1;
2433
        gen_set_pc_im(s->pc);
2434
        tmp = load_reg(s, rd);
2435
        tmp2 = tcg_const_i32(insn);
2436
        gen_helper_set_cp(cpu_env, tmp2, tmp);
2437
        tcg_temp_free(tmp2);
2438
        dead_tmp(tmp);
2439
    }
2440
    return 0;
2441
}
2442

    
2443
static int cp15_user_ok(uint32_t insn)
2444
{
2445
    int cpn = (insn >> 16) & 0xf;
2446
    int cpm = insn & 0xf;
2447
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2448

    
2449
    if (cpn == 13 && cpm == 0) {
2450
        /* TLS register.  */
2451
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2452
            return 1;
2453
    }
2454
    if (cpn == 7) {
2455
        /* ISB, DSB, DMB.  */
2456
        if ((cpm == 5 && op == 4)
2457
                || (cpm == 10 && (op == 4 || op == 5)))
2458
            return 1;
2459
    }
2460
    return 0;
2461
}
2462

    
2463
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2464
   instruction is not defined.  */
2465
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2466
{
2467
    uint32_t rd;
2468
    TCGv tmp, tmp2;
2469

    
2470
    /* M profile cores use memory mapped registers instead of cp15.  */
2471
    if (arm_feature(env, ARM_FEATURE_M))
2472
        return 1;
2473

    
2474
    if ((insn & (1 << 25)) == 0) {
2475
        if (insn & (1 << 20)) {
2476
            /* mrrc */
2477
            return 1;
2478
        }
2479
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2480
        return 0;
2481
    }
2482
    if ((insn & (1 << 4)) == 0) {
2483
        /* cdp */
2484
        return 1;
2485
    }
2486
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2487
        return 1;
2488
    }
2489
    if ((insn & 0x0fff0fff) == 0x0e070f90
2490
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2491
        /* Wait for interrupt.  */
2492
        gen_set_pc_im(s->pc);
2493
        s->is_jmp = DISAS_WFI;
2494
        return 0;
2495
    }
2496
    rd = (insn >> 12) & 0xf;
2497
    tmp2 = tcg_const_i32(insn);
2498
    if (insn & ARM_CP_RW_BIT) {
2499
        tmp = new_tmp();
2500
        gen_helper_get_cp15(tmp, cpu_env, tmp2);
2501
        /* If the destination register is r15 then sets condition codes.  */
2502
        if (rd != 15)
2503
            store_reg(s, rd, tmp);
2504
        else
2505
            dead_tmp(tmp);
2506
    } else {
2507
        tmp = load_reg(s, rd);
2508
        gen_helper_set_cp15(cpu_env, tmp2, tmp);
2509
        dead_tmp(tmp);
2510
        /* Normally we would always end the TB here, but Linux
2511
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2512
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2513
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2514
                (insn & 0x0fff0fff) != 0x0e010f10)
2515
            gen_lookup_tb(s);
2516
    }
2517
    tcg_temp_free_i32(tmp2);
2518
    return 0;
2519
}
2520

    
2521
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2522
#define VFP_SREG(insn, bigbit, smallbit) \
2523
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2524
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2525
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2526
        reg = (((insn) >> (bigbit)) & 0x0f) \
2527
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2528
    } else { \
2529
        if (insn & (1 << (smallbit))) \
2530
            return 1; \
2531
        reg = ((insn) >> (bigbit)) & 0x0f; \
2532
    }} while (0)
2533

    
2534
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2535
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2536
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2537
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2538
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2539
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2540

    
2541
/* Move between integer and VFP cores.  */
2542
static TCGv gen_vfp_mrs(void)
2543
{
2544
    TCGv tmp = new_tmp();
2545
    tcg_gen_mov_i32(tmp, cpu_F0s);
2546
    return tmp;
2547
}
2548

    
2549
static void gen_vfp_msr(TCGv tmp)
2550
{
2551
    tcg_gen_mov_i32(cpu_F0s, tmp);
2552
    dead_tmp(tmp);
2553
}
2554

    
2555
static inline int
2556
vfp_enabled(CPUState * env)
2557
{
2558
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2559
}
2560

    
2561
static void gen_neon_dup_u8(TCGv var, int shift)
2562
{
2563
    TCGv tmp = new_tmp();
2564
    if (shift)
2565
        tcg_gen_shri_i32(var, var, shift);
2566
    tcg_gen_ext8u_i32(var, var);
2567
    tcg_gen_shli_i32(tmp, var, 8);
2568
    tcg_gen_or_i32(var, var, tmp);
2569
    tcg_gen_shli_i32(tmp, var, 16);
2570
    tcg_gen_or_i32(var, var, tmp);
2571
    dead_tmp(tmp);
2572
}
2573

    
2574
static void gen_neon_dup_low16(TCGv var)
2575
{
2576
    TCGv tmp = new_tmp();
2577
    tcg_gen_ext16u_i32(var, var);
2578
    tcg_gen_shli_i32(tmp, var, 16);
2579
    tcg_gen_or_i32(var, var, tmp);
2580
    dead_tmp(tmp);
2581
}
2582

    
2583
static void gen_neon_dup_high16(TCGv var)
2584
{
2585
    TCGv tmp = new_tmp();
2586
    tcg_gen_andi_i32(var, var, 0xffff0000);
2587
    tcg_gen_shri_i32(tmp, var, 16);
2588
    tcg_gen_or_i32(var, var, tmp);
2589
    dead_tmp(tmp);
2590
}
2591

    
2592
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2593
   (ie. an undefined instruction).  */
2594
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2595
{
2596
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2597
    int dp, veclen;
2598
    TCGv addr;
2599
    TCGv tmp;
2600
    TCGv tmp2;
2601

    
2602
    if (!arm_feature(env, ARM_FEATURE_VFP))
2603
        return 1;
2604

    
2605
    if (!vfp_enabled(env)) {
2606
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2607
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2608
            return 1;
2609
        rn = (insn >> 16) & 0xf;
2610
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2611
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2612
            return 1;
2613
    }
2614
    dp = ((insn & 0xf00) == 0xb00);
2615
    switch ((insn >> 24) & 0xf) {
2616
    case 0xe:
2617
        if (insn & (1 << 4)) {
2618
            /* single register transfer */
2619
            rd = (insn >> 12) & 0xf;
2620
            if (dp) {
2621
                int size;
2622
                int pass;
2623

    
2624
                VFP_DREG_N(rn, insn);
2625
                if (insn & 0xf)
2626
                    return 1;
2627
                if (insn & 0x00c00060
2628
                    && !arm_feature(env, ARM_FEATURE_NEON))
2629
                    return 1;
2630

    
2631
                pass = (insn >> 21) & 1;
2632
                if (insn & (1 << 22)) {
2633
                    size = 0;
2634
                    offset = ((insn >> 5) & 3) * 8;
2635
                } else if (insn & (1 << 5)) {
2636
                    size = 1;
2637
                    offset = (insn & (1 << 6)) ? 16 : 0;
2638
                } else {
2639
                    size = 2;
2640
                    offset = 0;
2641
                }
2642
                if (insn & ARM_CP_RW_BIT) {
2643
                    /* vfp->arm */
2644
                    tmp = neon_load_reg(rn, pass);
2645
                    switch (size) {
2646
                    case 0:
2647
                        if (offset)
2648
                            tcg_gen_shri_i32(tmp, tmp, offset);
2649
                        if (insn & (1 << 23))
2650
                            gen_uxtb(tmp);
2651
                        else
2652
                            gen_sxtb(tmp);
2653
                        break;
2654
                    case 1:
2655
                        if (insn & (1 << 23)) {
2656
                            if (offset) {
2657
                                tcg_gen_shri_i32(tmp, tmp, 16);
2658
                            } else {
2659
                                gen_uxth(tmp);
2660
                            }
2661
                        } else {
2662
                            if (offset) {
2663
                                tcg_gen_sari_i32(tmp, tmp, 16);
2664
                            } else {
2665
                                gen_sxth(tmp);
2666
                            }
2667
                        }
2668
                        break;
2669
                    case 2:
2670
                        break;
2671
                    }
2672
                    store_reg(s, rd, tmp);
2673
                } else {
2674
                    /* arm->vfp */
2675
                    tmp = load_reg(s, rd);
2676
                    if (insn & (1 << 23)) {
2677
                        /* VDUP */
2678
                        if (size == 0) {
2679
                            gen_neon_dup_u8(tmp, 0);
2680
                        } else if (size == 1) {
2681
                            gen_neon_dup_low16(tmp);
2682
                        }
2683
                        for (n = 0; n <= pass * 2; n++) {
2684
                            tmp2 = new_tmp();
2685
                            tcg_gen_mov_i32(tmp2, tmp);
2686
                            neon_store_reg(rn, n, tmp2);
2687
                        }
2688
                        neon_store_reg(rn, n, tmp);
2689
                    } else {
2690
                        /* VMOV */
2691
                        switch (size) {
2692
                        case 0:
2693
                            tmp2 = neon_load_reg(rn, pass);
2694
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2695
                            dead_tmp(tmp2);
2696
                            break;
2697
                        case 1:
2698
                            tmp2 = neon_load_reg(rn, pass);
2699
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2700
                            dead_tmp(tmp2);
2701
                            break;
2702
                        case 2:
2703
                            break;
2704
                        }
2705
                        neon_store_reg(rn, pass, tmp);
2706
                    }
2707
                }
2708
            } else { /* !dp */
2709
                if ((insn & 0x6f) != 0x00)
2710
                    return 1;
2711
                rn = VFP_SREG_N(insn);
2712
                if (insn & ARM_CP_RW_BIT) {
2713
                    /* vfp->arm */
2714
                    if (insn & (1 << 21)) {
2715
                        /* system register */
2716
                        rn >>= 1;
2717

    
2718
                        switch (rn) {
2719
                        case ARM_VFP_FPSID:
2720
                            /* VFP2 allows access to FSID from userspace.
2721
                               VFP3 restricts all id registers to privileged
2722
                               accesses.  */
2723
                            if (IS_USER(s)
2724
                                && arm_feature(env, ARM_FEATURE_VFP3))
2725
                                return 1;
2726
                            tmp = load_cpu_field(vfp.xregs[rn]);
2727
                            break;
2728
                        case ARM_VFP_FPEXC:
2729
                            if (IS_USER(s))
2730
                                return 1;
2731
                            tmp = load_cpu_field(vfp.xregs[rn]);
2732
                            break;
2733
                        case ARM_VFP_FPINST:
2734
                        case ARM_VFP_FPINST2:
2735
                            /* Not present in VFP3.  */
2736
                            if (IS_USER(s)
2737
                                || arm_feature(env, ARM_FEATURE_VFP3))
2738
                                return 1;
2739
                            tmp = load_cpu_field(vfp.xregs[rn]);
2740
                            break;
2741
                        case ARM_VFP_FPSCR:
2742
                            if (rd == 15) {
2743
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2744
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2745
                            } else {
2746
                                tmp = new_tmp();
2747
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2748
                            }
2749
                            break;
2750
                        case ARM_VFP_MVFR0:
2751
                        case ARM_VFP_MVFR1:
2752
                            if (IS_USER(s)
2753
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2754
                                return 1;
2755
                            tmp = load_cpu_field(vfp.xregs[rn]);
2756
                            break;
2757
                        default:
2758
                            return 1;
2759
                        }
2760
                    } else {
2761
                        gen_mov_F0_vreg(0, rn);
2762
                        tmp = gen_vfp_mrs();
2763
                    }
2764
                    if (rd == 15) {
2765
                        /* Set the 4 flag bits in the CPSR.  */
2766
                        gen_set_nzcv(tmp);
2767
                        dead_tmp(tmp);
2768
                    } else {
2769
                        store_reg(s, rd, tmp);
2770
                    }
2771
                } else {
2772
                    /* arm->vfp */
2773
                    tmp = load_reg(s, rd);
2774
                    if (insn & (1 << 21)) {
2775
                        rn >>= 1;
2776
                        /* system register */
2777
                        switch (rn) {
2778
                        case ARM_VFP_FPSID:
2779
                        case ARM_VFP_MVFR0:
2780
                        case ARM_VFP_MVFR1:
2781
                            /* Writes are ignored.  */
2782
                            break;
2783
                        case ARM_VFP_FPSCR:
2784
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2785
                            dead_tmp(tmp);
2786
                            gen_lookup_tb(s);
2787
                            break;
2788
                        case ARM_VFP_FPEXC:
2789
                            if (IS_USER(s))
2790
                                return 1;
2791
                            /* TODO: VFP subarchitecture support.
2792
                             * For now, keep the EN bit only */
2793
                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2794
                            store_cpu_field(tmp, vfp.xregs[rn]);
2795
                            gen_lookup_tb(s);
2796
                            break;
2797
                        case ARM_VFP_FPINST:
2798
                        case ARM_VFP_FPINST2:
2799
                            store_cpu_field(tmp, vfp.xregs[rn]);
2800
                            break;
2801
                        default:
2802
                            return 1;
2803
                        }
2804
                    } else {
2805
                        gen_vfp_msr(tmp);
2806
                        gen_mov_vreg_F0(0, rn);
2807
                    }
2808
                }
2809
            }
2810
        } else {
2811
            /* data processing */
2812
            /* The opcode is in bits 23, 21, 20 and 6.  */
2813
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2814
            if (dp) {
2815
                if (op == 15) {
2816
                    /* rn is opcode */
2817
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2818
                } else {
2819
                    /* rn is register number */
2820
                    VFP_DREG_N(rn, insn);
2821
                }
2822

    
2823
                if (op == 15 && (rn == 15 || rn > 17)) {
2824
                    /* Integer or single precision destination.  */
2825
                    rd = VFP_SREG_D(insn);
2826
                } else {
2827
                    VFP_DREG_D(rd, insn);
2828
                }
2829

    
2830
                if (op == 15 && (rn == 16 || rn == 17)) {
2831
                    /* Integer source.  */
2832
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2833
                } else {
2834
                    VFP_DREG_M(rm, insn);
2835
                }
2836
            } else {
2837
                rn = VFP_SREG_N(insn);
2838
                if (op == 15 && rn == 15) {
2839
                    /* Double precision destination.  */
2840
                    VFP_DREG_D(rd, insn);
2841
                } else {
2842
                    rd = VFP_SREG_D(insn);
2843
                }
2844
                rm = VFP_SREG_M(insn);
2845
            }
2846

    
2847
            veclen = env->vfp.vec_len;
2848
            if (op == 15 && rn > 3)
2849
                veclen = 0;
2850

    
2851
            /* Shut up compiler warnings.  */
2852
            delta_m = 0;
2853
            delta_d = 0;
2854
            bank_mask = 0;
2855

    
2856
            if (veclen > 0) {
2857
                if (dp)
2858
                    bank_mask = 0xc;
2859
                else
2860
                    bank_mask = 0x18;
2861

    
2862
                /* Figure out what type of vector operation this is.  */
2863
                if ((rd & bank_mask) == 0) {
2864
                    /* scalar */
2865
                    veclen = 0;
2866
                } else {
2867
                    if (dp)
2868
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2869
                    else
2870
                        delta_d = env->vfp.vec_stride + 1;
2871

    
2872
                    if ((rm & bank_mask) == 0) {
2873
                        /* mixed scalar/vector */
2874
                        delta_m = 0;
2875
                    } else {
2876
                        /* vector */
2877
                        delta_m = delta_d;
2878
                    }
2879
                }
2880
            }
2881

    
2882
            /* Load the initial operands.  */
2883
            if (op == 15) {
2884
                switch (rn) {
2885
                case 16:
2886
                case 17:
2887
                    /* Integer source */
2888
                    gen_mov_F0_vreg(0, rm);
2889
                    break;
2890
                case 8:
2891
                case 9:
2892
                    /* Compare */
2893
                    gen_mov_F0_vreg(dp, rd);
2894
                    gen_mov_F1_vreg(dp, rm);
2895
                    break;
2896
                case 10:
2897
                case 11:
2898
                    /* Compare with zero */
2899
                    gen_mov_F0_vreg(dp, rd);
2900
                    gen_vfp_F1_ld0(dp);
2901
                    break;
2902
                case 20:
2903
                case 21:
2904
                case 22:
2905
                case 23:
2906
                case 28:
2907
                case 29:
2908
                case 30:
2909
                case 31:
2910
                    /* Source and destination the same.  */
2911
                    gen_mov_F0_vreg(dp, rd);
2912
                    break;
2913
                default:
2914
                    /* One source operand.  */
2915
                    gen_mov_F0_vreg(dp, rm);
2916
                    break;
2917
                }
2918
            } else {
2919
                /* Two source operands.  */
2920
                gen_mov_F0_vreg(dp, rn);
2921
                gen_mov_F1_vreg(dp, rm);
2922
            }
2923

    
2924
            for (;;) {
2925
                /* Perform the calculation.  */
2926
                switch (op) {
2927
                case 0: /* mac: fd + (fn * fm) */
2928
                    gen_vfp_mul(dp);
2929
                    gen_mov_F1_vreg(dp, rd);
2930
                    gen_vfp_add(dp);
2931
                    break;
2932
                case 1: /* nmac: fd - (fn * fm) */
2933
                    gen_vfp_mul(dp);
2934
                    gen_vfp_neg(dp);
2935
                    gen_mov_F1_vreg(dp, rd);
2936
                    gen_vfp_add(dp);
2937
                    break;
2938
                case 2: /* msc: -fd + (fn * fm) */
2939
                    gen_vfp_mul(dp);
2940
                    gen_mov_F1_vreg(dp, rd);
2941
                    gen_vfp_sub(dp);
2942
                    break;
2943
                case 3: /* nmsc: -fd - (fn * fm)  */
2944
                    gen_vfp_mul(dp);
2945
                    gen_vfp_neg(dp);
2946
                    gen_mov_F1_vreg(dp, rd);
2947
                    gen_vfp_sub(dp);
2948
                    break;
2949
                case 4: /* mul: fn * fm */
2950
                    gen_vfp_mul(dp);
2951
                    break;
2952
                case 5: /* nmul: -(fn * fm) */
2953
                    gen_vfp_mul(dp);
2954
                    gen_vfp_neg(dp);
2955
                    break;
2956
                case 6: /* add: fn + fm */
2957
                    gen_vfp_add(dp);
2958
                    break;
2959
                case 7: /* sub: fn - fm */
2960
                    gen_vfp_sub(dp);
2961
                    break;
2962
                case 8: /* div: fn / fm */
2963
                    gen_vfp_div(dp);
2964
                    break;
2965
                case 14: /* fconst */
2966
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
2967
                      return 1;
2968

    
2969
                    n = (insn << 12) & 0x80000000;
2970
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
2971
                    if (dp) {
2972
                        if (i & 0x40)
2973
                            i |= 0x3f80;
2974
                        else
2975
                            i |= 0x4000;
2976
                        n |= i << 16;
2977
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
2978
                    } else {
2979
                        if (i & 0x40)
2980
                            i |= 0x780;
2981
                        else
2982
                            i |= 0x800;
2983
                        n |= i << 19;
2984
                        tcg_gen_movi_i32(cpu_F0s, n);
2985
                    }
2986
                    break;
2987
                case 15: /* extension space */
2988
                    switch (rn) {
2989
                    case 0: /* cpy */
2990
                        /* no-op */
2991
                        break;
2992
                    case 1: /* abs */
2993
                        gen_vfp_abs(dp);
2994
                        break;
2995
                    case 2: /* neg */
2996
                        gen_vfp_neg(dp);
2997
                        break;
2998
                    case 3: /* sqrt */
2999
                        gen_vfp_sqrt(dp);
3000
                        break;
3001
                    case 8: /* cmp */
3002
                        gen_vfp_cmp(dp);
3003
                        break;
3004
                    case 9: /* cmpe */
3005
                        gen_vfp_cmpe(dp);
3006
                        break;
3007
                    case 10: /* cmpz */
3008
                        gen_vfp_cmp(dp);
3009
                        break;
3010
                    case 11: /* cmpez */
3011
                        gen_vfp_F1_ld0(dp);
3012
                        gen_vfp_cmpe(dp);
3013
                        break;
3014
                    case 15: /* single<->double conversion */
3015
                        if (dp)
3016
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3017
                        else
3018
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3019
                        break;
3020
                    case 16: /* fuito */
3021
                        gen_vfp_uito(dp);
3022
                        break;
3023
                    case 17: /* fsito */
3024
                        gen_vfp_sito(dp);
3025
                        break;
3026
                    case 20: /* fshto */
3027
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3028
                          return 1;
3029
                        gen_vfp_shto(dp, 16 - rm);
3030
                        break;
3031
                    case 21: /* fslto */
3032
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3033
                          return 1;
3034
                        gen_vfp_slto(dp, 32 - rm);
3035
                        break;
3036
                    case 22: /* fuhto */
3037
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3038
                          return 1;
3039
                        gen_vfp_uhto(dp, 16 - rm);
3040
                        break;
3041
                    case 23: /* fulto */
3042
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3043
                          return 1;
3044
                        gen_vfp_ulto(dp, 32 - rm);
3045
                        break;
3046
                    case 24: /* ftoui */
3047
                        gen_vfp_toui(dp);
3048
                        break;
3049
                    case 25: /* ftouiz */
3050
                        gen_vfp_touiz(dp);
3051
                        break;
3052
                    case 26: /* ftosi */
3053
                        gen_vfp_tosi(dp);
3054
                        break;
3055
                    case 27: /* ftosiz */
3056
                        gen_vfp_tosiz(dp);
3057
                        break;
3058
                    case 28: /* ftosh */
3059
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3060
                          return 1;
3061
                        gen_vfp_tosh(dp, 16 - rm);
3062
                        break;
3063
                    case 29: /* ftosl */
3064
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3065
                          return 1;
3066
                        gen_vfp_tosl(dp, 32 - rm);
3067
                        break;
3068
                    case 30: /* ftouh */
3069
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3070
                          return 1;
3071
                        gen_vfp_touh(dp, 16 - rm);
3072
                        break;
3073
                    case 31: /* ftoul */
3074
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3075
                          return 1;
3076
                        gen_vfp_toul(dp, 32 - rm);
3077
                        break;
3078
                    default: /* undefined */
3079
                        printf ("rn:%d\n", rn);
3080
                        return 1;
3081
                    }
3082
                    break;
3083
                default: /* undefined */
3084
                    printf ("op:%d\n", op);
3085
                    return 1;
3086
                }
3087

    
3088
                /* Write back the result.  */
3089
                if (op == 15 && (rn >= 8 && rn <= 11))
3090
                    ; /* Comparison, do nothing.  */
3091
                else if (op == 15 && rn > 17)
3092
                    /* Integer result.  */
3093
                    gen_mov_vreg_F0(0, rd);
3094
                else if (op == 15 && rn == 15)
3095
                    /* conversion */
3096
                    gen_mov_vreg_F0(!dp, rd);
3097
                else
3098
                    gen_mov_vreg_F0(dp, rd);
3099

    
3100
                /* break out of the loop if we have finished  */
3101
                if (veclen == 0)
3102
                    break;
3103

    
3104
                if (op == 15 && delta_m == 0) {
3105
                    /* single source one-many */
3106
                    while (veclen--) {
3107
                        rd = ((rd + delta_d) & (bank_mask - 1))
3108
                             | (rd & bank_mask);
3109
                        gen_mov_vreg_F0(dp, rd);
3110
                    }
3111
                    break;
3112
                }
3113
                /* Setup the next operands.  */
3114
                veclen--;
3115
                rd = ((rd + delta_d) & (bank_mask - 1))
3116
                     | (rd & bank_mask);
3117

    
3118
                if (op == 15) {
3119
                    /* One source operand.  */
3120
                    rm = ((rm + delta_m) & (bank_mask - 1))
3121
                         | (rm & bank_mask);
3122
                    gen_mov_F0_vreg(dp, rm);
3123
                } else {
3124
                    /* Two source operands.  */
3125
                    rn = ((rn + delta_d) & (bank_mask - 1))
3126
                         | (rn & bank_mask);
3127
                    gen_mov_F0_vreg(dp, rn);
3128
                    if (delta_m) {
3129
                        rm = ((rm + delta_m) & (bank_mask - 1))
3130
                             | (rm & bank_mask);
3131
                        gen_mov_F1_vreg(dp, rm);
3132
                    }
3133
                }
3134
            }
3135
        }
3136
        break;
3137
    case 0xc:
3138
    case 0xd:
3139
        if (dp && (insn & 0x03e00000) == 0x00400000) {
3140
            /* two-register transfer */
3141
            rn = (insn >> 16) & 0xf;
3142
            rd = (insn >> 12) & 0xf;
3143
            if (dp) {
3144
                VFP_DREG_M(rm, insn);
3145
            } else {
3146
                rm = VFP_SREG_M(insn);
3147
            }
3148

    
3149
            if (insn & ARM_CP_RW_BIT) {
3150
                /* vfp->arm */
3151
                if (dp) {
3152
                    gen_mov_F0_vreg(0, rm * 2);
3153
                    tmp = gen_vfp_mrs();
3154
                    store_reg(s, rd, tmp);
3155
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3156
                    tmp = gen_vfp_mrs();
3157
                    store_reg(s, rn, tmp);
3158
                } else {
3159
                    gen_mov_F0_vreg(0, rm);
3160
                    tmp = gen_vfp_mrs();
3161
                    store_reg(s, rn, tmp);
3162
                    gen_mov_F0_vreg(0, rm + 1);
3163
                    tmp = gen_vfp_mrs();
3164
                    store_reg(s, rd, tmp);
3165
                }
3166
            } else {
3167
                /* arm->vfp */
3168
                if (dp) {
3169
                    tmp = load_reg(s, rd);
3170
                    gen_vfp_msr(tmp);
3171
                    gen_mov_vreg_F0(0, rm * 2);
3172
                    tmp = load_reg(s, rn);
3173
                    gen_vfp_msr(tmp);
3174
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3175
                } else {
3176
                    tmp = load_reg(s, rn);
3177
                    gen_vfp_msr(tmp);
3178
                    gen_mov_vreg_F0(0, rm);
3179
                    tmp = load_reg(s, rd);
3180
                    gen_vfp_msr(tmp);
3181
                    gen_mov_vreg_F0(0, rm + 1);
3182
                }
3183
            }
3184
        } else {
3185
            /* Load/store */
3186
            rn = (insn >> 16) & 0xf;
3187
            if (dp)
3188
                VFP_DREG_D(rd, insn);
3189
            else
3190
                rd = VFP_SREG_D(insn);
3191
            if (s->thumb && rn == 15) {
3192
                addr = new_tmp();
3193
                tcg_gen_movi_i32(addr, s->pc & ~2);
3194
            } else {
3195
                addr = load_reg(s, rn);
3196
            }
3197
            if ((insn & 0x01200000) == 0x01000000) {
3198
                /* Single load/store */
3199
                offset = (insn & 0xff) << 2;
3200
                if ((insn & (1 << 23)) == 0)
3201
                    offset = -offset;
3202
                tcg_gen_addi_i32(addr, addr, offset);
3203
                if (insn & (1 << 20)) {
3204
                    gen_vfp_ld(s, dp, addr);
3205
                    gen_mov_vreg_F0(dp, rd);
3206
                } else {
3207
                    gen_mov_F0_vreg(dp, rd);
3208
                    gen_vfp_st(s, dp, addr);
3209
                }
3210
                dead_tmp(addr);
3211
            } else {
3212
                /* load/store multiple */
3213
                if (dp)
3214
                    n = (insn >> 1) & 0x7f;
3215
                else
3216
                    n = insn & 0xff;
3217

    
3218
                if (insn & (1 << 24)) /* pre-decrement */
3219
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3220

    
3221
                if (dp)
3222
                    offset = 8;
3223
                else
3224
                    offset = 4;
3225
                for (i = 0; i < n; i++) {
3226
                    if (insn & ARM_CP_RW_BIT) {
3227
                        /* load */
3228
                        gen_vfp_ld(s, dp, addr);
3229
                        gen_mov_vreg_F0(dp, rd + i);
3230
                    } else {
3231
                        /* store */
3232
                        gen_mov_F0_vreg(dp, rd + i);
3233
                        gen_vfp_st(s, dp, addr);
3234
                    }
3235
                    tcg_gen_addi_i32(addr, addr, offset);
3236
                }
3237
                if (insn & (1 << 21)) {
3238
                    /* writeback */
3239
                    if (insn & (1 << 24))
3240
                        offset = -offset * n;
3241
                    else if (dp && (insn & 1))
3242
                        offset = 4;
3243
                    else
3244
                        offset = 0;
3245

    
3246
                    if (offset != 0)
3247
                        tcg_gen_addi_i32(addr, addr, offset);
3248
                    store_reg(s, rn, addr);
3249
                } else {
3250
                    dead_tmp(addr);
3251
                }
3252
            }
3253
        }
3254
        break;
3255
    default:
3256
        /* Should never happen.  */
3257
        return 1;
3258
    }
3259
    return 0;
3260
}
3261

    
3262
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3263
{
3264
    TranslationBlock *tb;
3265

    
3266
    tb = s->tb;
3267
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3268
        tcg_gen_goto_tb(n);
3269
        gen_set_pc_im(dest);
3270
        tcg_gen_exit_tb((long)tb + n);
3271
    } else {
3272
        gen_set_pc_im(dest);
3273
        tcg_gen_exit_tb(0);
3274
    }
3275
}
3276

    
3277
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3278
{
3279
    if (unlikely(s->singlestep_enabled)) {
3280
        /* An indirect jump so that we still trigger the debug exception.  */
3281
        if (s->thumb)
3282
            dest |= 1;
3283
        gen_bx_im(s, dest);
3284
    } else {
3285
        gen_goto_tb(s, 0, dest);
3286
        s->is_jmp = DISAS_TB_JUMP;
3287
    }
3288
}
3289

    
3290
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3291
{
3292
    if (x)
3293
        tcg_gen_sari_i32(t0, t0, 16);
3294
    else
3295
        gen_sxth(t0);
3296
    if (y)
3297
        tcg_gen_sari_i32(t1, t1, 16);
3298
    else
3299
        gen_sxth(t1);
3300
    tcg_gen_mul_i32(t0, t0, t1);
3301
}
3302

    
3303
/* Return the mask of PSR bits set by a MSR instruction.  */
3304
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3305
    uint32_t mask;
3306

    
3307
    mask = 0;
3308
    if (flags & (1 << 0))
3309
        mask |= 0xff;
3310
    if (flags & (1 << 1))
3311
        mask |= 0xff00;
3312
    if (flags & (1 << 2))
3313
        mask |= 0xff0000;
3314
    if (flags & (1 << 3))
3315
        mask |= 0xff000000;
3316

    
3317
    /* Mask out undefined bits.  */
3318
    mask &= ~CPSR_RESERVED;
3319
    if (!arm_feature(env, ARM_FEATURE_V6))
3320
        mask &= ~(CPSR_E | CPSR_GE);
3321
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3322
        mask &= ~CPSR_IT;
3323
    /* Mask out execution state bits.  */
3324
    if (!spsr)
3325
        mask &= ~CPSR_EXEC;
3326
    /* Mask out privileged bits.  */
3327
    if (IS_USER(s))
3328
        mask &= CPSR_USER;
3329
    return mask;
3330
}
3331

    
3332
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3333
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3334
{
3335
    TCGv tmp;
3336
    if (spsr) {
3337
        /* ??? This is also undefined in system mode.  */
3338
        if (IS_USER(s))
3339
            return 1;
3340

    
3341
        tmp = load_cpu_field(spsr);
3342
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3343
        tcg_gen_andi_i32(t0, t0, mask);
3344
        tcg_gen_or_i32(tmp, tmp, t0);
3345
        store_cpu_field(tmp, spsr);
3346
    } else {
3347
        gen_set_cpsr(t0, mask);
3348
    }
3349
    dead_tmp(t0);
3350
    gen_lookup_tb(s);
3351
    return 0;
3352
}
3353

    
3354
/* Returns nonzero if access to the PSR is not permitted.  */
3355
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3356
{
3357
    TCGv tmp;
3358
    tmp = new_tmp();
3359
    tcg_gen_movi_i32(tmp, val);
3360
    return gen_set_psr(s, mask, spsr, tmp);
3361
}
3362

    
3363
/* Generate an old-style exception return. Marks pc as dead. */
3364
static void gen_exception_return(DisasContext *s, TCGv pc)
3365
{
3366
    TCGv tmp;
3367
    store_reg(s, 15, pc);
3368
    tmp = load_cpu_field(spsr);
3369
    gen_set_cpsr(tmp, 0xffffffff);
3370
    dead_tmp(tmp);
3371
    s->is_jmp = DISAS_UPDATE;
3372
}
3373

    
3374
/* Generate a v6 exception return.  Marks both values as dead.  */
3375
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3376
{
3377
    gen_set_cpsr(cpsr, 0xffffffff);
3378
    dead_tmp(cpsr);
3379
    store_reg(s, 15, pc);
3380
    s->is_jmp = DISAS_UPDATE;
3381
}
3382

    
3383
static inline void
3384
gen_set_condexec (DisasContext *s)
3385
{
3386
    if (s->condexec_mask) {
3387
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3388
        TCGv tmp = new_tmp();
3389
        tcg_gen_movi_i32(tmp, val);
3390
        store_cpu_field(tmp, condexec_bits);
3391
    }
3392
}
3393

    
3394
static void gen_nop_hint(DisasContext *s, int val)
3395
{
3396
    switch (val) {
3397
    case 3: /* wfi */
3398
        gen_set_pc_im(s->pc);
3399
        s->is_jmp = DISAS_WFI;
3400
        break;
3401
    case 2: /* wfe */
3402
    case 4: /* sev */
3403
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3404
    default: /* nop */
3405
        break;
3406
    }
3407
}
3408

    
3409
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3410

    
3411
static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3412
{
3413
    switch (size) {
3414
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3415
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3416
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3417
    default: return 1;
3418
    }
3419
    return 0;
3420
}
3421

    
3422
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3423
{
3424
    switch (size) {
3425
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3426
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3427
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3428
    default: return;
3429
    }
3430
}
3431

    
3432
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3433
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3434
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3435
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3436
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3437

    
3438
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3439
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3440
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3441
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3442
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3443

    
3444
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3445
    switch ((size << 1) | u) { \
3446
    case 0: \
3447
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3448
        break; \
3449
    case 1: \
3450
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3451
        break; \
3452
    case 2: \
3453
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3454
        break; \
3455
    case 3: \
3456
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3457
        break; \
3458
    case 4: \
3459
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3460
        break; \
3461
    case 5: \
3462
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3463
        break; \
3464
    default: return 1; \
3465
    }} while (0)
3466

    
3467
#define GEN_NEON_INTEGER_OP(name) do { \
3468
    switch ((size << 1) | u) { \
3469
    case 0: \
3470
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3471
        break; \
3472
    case 1: \
3473
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3474
        break; \
3475
    case 2: \
3476
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3477
        break; \
3478
    case 3: \
3479
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3480
        break; \
3481
    case 4: \
3482
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3483
        break; \
3484
    case 5: \
3485
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3486
        break; \
3487
    default: return 1; \
3488
    }} while (0)
3489

    
3490
static TCGv neon_load_scratch(int scratch)
3491
{
3492
    TCGv tmp = new_tmp();
3493
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3494
    return tmp;
3495
}
3496

    
3497
static void neon_store_scratch(int scratch, TCGv var)
3498
{
3499
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3500
    dead_tmp(var);
3501
}
3502

    
3503
static inline TCGv neon_get_scalar(int size, int reg)
3504
{
3505
    TCGv tmp;
3506
    if (size == 1) {
3507
        tmp = neon_load_reg(reg >> 1, reg & 1);
3508
    } else {
3509
        tmp = neon_load_reg(reg >> 2, (reg >> 1) & 1);
3510
        if (reg & 1) {
3511
            gen_neon_dup_low16(tmp);
3512
        } else {
3513
            gen_neon_dup_high16(tmp);
3514
        }
3515
    }
3516
    return tmp;
3517
}
3518

    
3519
static void gen_neon_unzip_u8(TCGv t0, TCGv t1)
3520
{
3521
    TCGv rd, rm, tmp;
3522

    
3523
    rd = new_tmp();
3524
    rm = new_tmp();
3525
    tmp = new_tmp();
3526

    
3527
    tcg_gen_andi_i32(rd, t0, 0xff);
3528
    tcg_gen_shri_i32(tmp, t0, 8);
3529
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3530
    tcg_gen_or_i32(rd, rd, tmp);
3531
    tcg_gen_shli_i32(tmp, t1, 16);
3532
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3533
    tcg_gen_or_i32(rd, rd, tmp);
3534
    tcg_gen_shli_i32(tmp, t1, 8);
3535
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3536
    tcg_gen_or_i32(rd, rd, tmp);
3537

    
3538
    tcg_gen_shri_i32(rm, t0, 8);
3539
    tcg_gen_andi_i32(rm, rm, 0xff);
3540
    tcg_gen_shri_i32(tmp, t0, 16);
3541
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3542
    tcg_gen_or_i32(rm, rm, tmp);
3543
    tcg_gen_shli_i32(tmp, t1, 8);
3544
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3545
    tcg_gen_or_i32(rm, rm, tmp);
3546
    tcg_gen_andi_i32(tmp, t1, 0xff000000);
3547
    tcg_gen_or_i32(t1, rm, tmp);
3548
    tcg_gen_mov_i32(t0, rd);
3549

    
3550
    dead_tmp(tmp);
3551
    dead_tmp(rm);
3552
    dead_tmp(rd);
3553
}
3554

    
3555
static void gen_neon_zip_u8(TCGv t0, TCGv t1)
3556
{
3557
    TCGv rd, rm, tmp;
3558

    
3559
    rd = new_tmp();
3560
    rm = new_tmp();
3561
    tmp = new_tmp();
3562

    
3563
    tcg_gen_andi_i32(rd, t0, 0xff);
3564
    tcg_gen_shli_i32(tmp, t1, 8);
3565
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3566
    tcg_gen_or_i32(rd, rd, tmp);
3567
    tcg_gen_shli_i32(tmp, t0, 16);
3568
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3569
    tcg_gen_or_i32(rd, rd, tmp);
3570
    tcg_gen_shli_i32(tmp, t1, 24);
3571
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3572
    tcg_gen_or_i32(rd, rd, tmp);
3573

    
3574
    tcg_gen_andi_i32(rm, t1, 0xff000000);
3575
    tcg_gen_shri_i32(tmp, t0, 8);
3576
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3577
    tcg_gen_or_i32(rm, rm, tmp);
3578
    tcg_gen_shri_i32(tmp, t1, 8);
3579
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3580
    tcg_gen_or_i32(rm, rm, tmp);
3581
    tcg_gen_shri_i32(tmp, t0, 16);
3582
    tcg_gen_andi_i32(tmp, tmp, 0xff);
3583
    tcg_gen_or_i32(t1, rm, tmp);
3584
    tcg_gen_mov_i32(t0, rd);
3585

    
3586
    dead_tmp(tmp);
3587
    dead_tmp(rm);
3588
    dead_tmp(rd);
3589
}
3590

    
3591
static void gen_neon_zip_u16(TCGv t0, TCGv t1)
3592
{
3593
    TCGv tmp, tmp2;
3594

    
3595
    tmp = new_tmp();
3596
    tmp2 = new_tmp();
3597

    
3598
    tcg_gen_andi_i32(tmp, t0, 0xffff);
3599
    tcg_gen_shli_i32(tmp2, t1, 16);
3600
    tcg_gen_or_i32(tmp, tmp, tmp2);
3601
    tcg_gen_andi_i32(t1, t1, 0xffff0000);
3602
    tcg_gen_shri_i32(tmp2, t0, 16);
3603
    tcg_gen_or_i32(t1, t1, tmp2);
3604
    tcg_gen_mov_i32(t0, tmp);
3605

    
3606
    dead_tmp(tmp2);
3607
    dead_tmp(tmp);
3608
}
3609

    
3610
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3611
{
3612
    int n;
3613
    TCGv t0, t1;
3614

    
3615
    for (n = 0; n < q + 1; n += 2) {
3616
        t0 = neon_load_reg(reg, n);
3617
        t1 = neon_load_reg(reg, n + 1);
3618
        switch (size) {
3619
        case 0: gen_neon_unzip_u8(t0, t1); break;
3620
        case 1: gen_neon_zip_u16(t0, t1); break; /* zip and unzip are the same.  */
3621
        case 2: /* no-op */; break;
3622
        default: abort();
3623
        }
3624
        neon_store_scratch(tmp + n, t0);
3625
        neon_store_scratch(tmp + n + 1, t1);
3626
    }
3627
}
3628

    
3629
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3630
{
3631
    TCGv rd, tmp;
3632

    
3633
    rd = new_tmp();
3634
    tmp = new_tmp();
3635

    
3636
    tcg_gen_shli_i32(rd, t0, 8);
3637
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3638
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3639
    tcg_gen_or_i32(rd, rd, tmp);
3640

    
3641
    tcg_gen_shri_i32(t1, t1, 8);
3642
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3643
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3644
    tcg_gen_or_i32(t1, t1, tmp);
3645
    tcg_gen_mov_i32(t0, rd);
3646

    
3647
    dead_tmp(tmp);
3648
    dead_tmp(rd);
3649
}
3650

    
3651
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3652
{
3653
    TCGv rd, tmp;
3654

    
3655
    rd = new_tmp();
3656
    tmp = new_tmp();
3657

    
3658
    tcg_gen_shli_i32(rd, t0, 16);
3659
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3660
    tcg_gen_or_i32(rd, rd, tmp);
3661
    tcg_gen_shri_i32(t1, t1, 16);
3662
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3663
    tcg_gen_or_i32(t1, t1, tmp);
3664
    tcg_gen_mov_i32(t0, rd);
3665

    
3666
    dead_tmp(tmp);
3667
    dead_tmp(rd);
3668
}
3669

    
3670

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

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

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

    
3916
        base = load_reg(s, rn);
3917
        if (rm == 13) {
3918
            tcg_gen_addi_i32(base, base, stride);
3919
        } else {
3920
            TCGv index;
3921
            index = load_reg(s, rm);
3922
            tcg_gen_add_i32(base, base, index);
3923
            dead_tmp(index);
3924
        }
3925
        store_reg(s, rn, base);
3926
    }
3927
    return 0;
3928
}
3929

    
3930
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3931
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3932
{
3933
    tcg_gen_and_i32(t, t, c);
3934
    tcg_gen_bic_i32(f, f, c);
3935
    tcg_gen_or_i32(dest, t, f);
3936
}
3937

    
3938
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
3939
{
3940
    switch (size) {
3941
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
3942
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
3943
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3944
    default: abort();
3945
    }
3946
}
3947

    
3948
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
3949
{
3950
    switch (size) {
3951
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3952
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3953
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3954
    default: abort();
3955
    }
3956
}
3957

    
3958
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
3959
{
3960
    switch (size) {
3961
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3962
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3963
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3964
    default: abort();
3965
    }
3966
}
3967

    
3968
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3969
                                         int q, int u)
3970
{
3971
    if (q) {
3972
        if (u) {
3973
            switch (size) {
3974
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3975
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3976
            default: abort();
3977
            }
3978
        } else {
3979
            switch (size) {
3980
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3981
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3982
            default: abort();
3983
            }
3984
        }
3985
    } else {
3986
        if (u) {
3987
            switch (size) {
3988
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3989
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3990
            default: abort();
3991
            }
3992
        } else {
3993
            switch (size) {
3994
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3995
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3996
            default: abort();
3997
            }
3998
        }
3999
    }
4000
}
4001

    
4002
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4003
{
4004
    if (u) {
4005
        switch (size) {
4006
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4007
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4008
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4009
        default: abort();
4010
        }
4011
    } else {
4012
        switch (size) {
4013
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4014
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4015
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4016
        default: abort();
4017
        }
4018
    }
4019
    dead_tmp(src);
4020
}
4021

    
4022
static inline void gen_neon_addl(int size)
4023
{
4024
    switch (size) {
4025
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4026
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4027
    case 2: tcg_gen_add_i64(CPU_V001); break;
4028
    default: abort();
4029
    }
4030
}
4031

    
4032
static inline void gen_neon_subl(int size)
4033
{
4034
    switch (size) {
4035
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4036
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4037
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4038
    default: abort();
4039
    }
4040
}
4041

    
4042
static inline void gen_neon_negl(TCGv_i64 var, int size)
4043
{
4044
    switch (size) {
4045
    case 0: gen_helper_neon_negl_u16(var, var); break;
4046
    case 1: gen_helper_neon_negl_u32(var, var); break;
4047
    case 2: gen_helper_neon_negl_u64(var, var); break;
4048
    default: abort();
4049
    }
4050
}
4051

    
4052
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4053
{
4054
    switch (size) {
4055
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4056
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4057
    default: abort();
4058
    }
4059
}
4060

    
4061
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4062
{
4063
    TCGv_i64 tmp;
4064

    
4065
    switch ((size << 1) | u) {
4066
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4067
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4068
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4069
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4070
    case 4:
4071
        tmp = gen_muls_i64_i32(a, b);
4072
        tcg_gen_mov_i64(dest, tmp);
4073
        break;
4074
    case 5:
4075
        tmp = gen_mulu_i64_i32(a, b);
4076
        tcg_gen_mov_i64(dest, tmp);
4077
        break;
4078
    default: abort();
4079
    }
4080
}
4081

    
4082
/* Translate a NEON data processing instruction.  Return nonzero if the
4083
   instruction is invalid.
4084
   We process data in a mixture of 32-bit and 64-bit chunks.
4085
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4086

    
4087
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4088
{
4089
    int op;
4090
    int q;
4091
    int rd, rn, rm;
4092
    int size;
4093
    int shift;
4094
    int pass;
4095
    int count;
4096
    int pairwise;
4097
    int u;
4098
    int n;
4099
    uint32_t imm;
4100
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4101
    TCGv_i64 tmp64;
4102

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

    
4211
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4212

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

    
4468
        /* Save the result.  For elementwise operations we can put it
4469
           straight into the destination register.  For pairwise operations
4470
           we have to be careful to avoid clobbering the source operands.  */
4471
        if (pairwise && rd == rm) {
4472
            neon_store_scratch(pass, tmp);
4473
        } else {
4474
            neon_store_reg(rd, pass, tmp);
4475
        }
4476

    
4477
        } /* for pass */
4478
        if (pairwise && rd == rm) {
4479
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4480
                tmp = neon_load_scratch(pass);
4481
                neon_store_reg(rd, pass, tmp);
4482
            }
4483
        }
4484
        /* End of 3 register same size operations.  */
4485
    } else if (insn & (1 << 4)) {
4486
        if ((insn & 0x00380080) != 0) {
4487
            /* Two registers and shift.  */
4488
            op = (insn >> 8) & 0xf;
4489
            if (insn & (1 << 7)) {
4490
                /* 64-bit shift.   */
4491
                size = 3;
4492
            } else {
4493
                size = 2;
4494
                while ((insn & (1 << (size + 19))) == 0)
4495
                    size--;
4496
            }
4497
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4498
            /* To avoid excessive dumplication of ops we implement shift
4499
               by immediate using the variable shift operations.  */
4500
            if (op < 8) {
4501
                /* Shift by immediate:
4502
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4503
                /* Right shifts are encoded as N - shift, where N is the
4504
                   element size in bits.  */
4505
                if (op <= 4)
4506
                    shift = shift - (1 << (size + 3));
4507
                if (size == 3) {
4508
                    count = q + 1;
4509
                } else {
4510
                    count = q ? 4: 2;
4511
                }
4512
                switch (size) {
4513
                case 0:
4514
                    imm = (uint8_t) shift;
4515
                    imm |= imm << 8;
4516
                    imm |= imm << 16;
4517
                    break;
4518
                case 1:
4519
                    imm = (uint16_t) shift;
4520
                    imm |= imm << 16;
4521
                    break;
4522
                case 2:
4523
                case 3:
4524
                    imm = shift;
4525
                    break;
4526
                default:
4527
                    abort();
4528
                }
4529

    
4530
                for (pass = 0; pass < count; pass++) {
4531
                    if (size == 3) {
4532
                        neon_load_reg64(cpu_V0, rm + pass);
4533
                        tcg_gen_movi_i64(cpu_V1, imm);
4534
                        switch (op) {
4535
                        case 0:  /* VSHR */
4536
                        case 1:  /* VSRA */
4537
                            if (u)
4538
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4539
                            else
4540
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4541
                            break;
4542
                        case 2: /* VRSHR */
4543
                        case 3: /* VRSRA */
4544
                            if (u)
4545
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4546
                            else
4547
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4548
                            break;
4549
                        case 4: /* VSRI */
4550
                            if (!u)
4551
                                return 1;
4552
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4553
                            break;
4554
                        case 5: /* VSHL, VSLI */
4555
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4556
                            break;
4557
                        case 6: /* VQSHL */
4558
                            if (u)
4559
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4560
                            else
4561
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4562
                            break;
4563
                        case 7: /* VQSHLU */
4564
                            gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4565
                            break;
4566
                        }
4567
                        if (op == 1 || op == 3) {
4568
                            /* Accumulate.  */
4569
                            neon_load_reg64(cpu_V0, rd + pass);
4570
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4571
                        } else if (op == 4 || (op == 5 && u)) {
4572
                            /* Insert */
4573
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4574
                        }
4575
                        neon_store_reg64(cpu_V0, rd + pass);
4576
                    } else { /* size < 3 */
4577
                        /* Operands in T0 and T1.  */
4578
                        tmp = neon_load_reg(rm, pass);
4579
                        tmp2 = new_tmp();
4580
                        tcg_gen_movi_i32(tmp2, imm);
4581
                        switch (op) {
4582
                        case 0:  /* VSHR */
4583
                        case 1:  /* VSRA */
4584
                            GEN_NEON_INTEGER_OP(shl);
4585
                            break;
4586
                        case 2: /* VRSHR */
4587
                        case 3: /* VRSRA */
4588
                            GEN_NEON_INTEGER_OP(rshl);
4589
                            break;
4590
                        case 4: /* VSRI */
4591
                            if (!u)
4592
                                return 1;
4593
                            GEN_NEON_INTEGER_OP(shl);
4594
                            break;
4595
                        case 5: /* VSHL, VSLI */
4596
                            switch (size) {
4597
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4598
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4599
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4600
                            default: return 1;
4601
                            }
4602
                            break;
4603
                        case 6: /* VQSHL */
4604
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4605
                            break;
4606
                        case 7: /* VQSHLU */
4607
                            switch (size) {
4608
                            case 0: gen_helper_neon_qshl_u8(tmp, cpu_env, tmp, tmp2); break;
4609
                            case 1: gen_helper_neon_qshl_u16(tmp, cpu_env, tmp, tmp2); break;
4610
                            case 2: gen_helper_neon_qshl_u32(tmp, cpu_env, tmp, tmp2); break;
4611
                            default: return 1;
4612
                            }
4613
                            break;
4614
                        }
4615
                        dead_tmp(tmp2);
4616

    
4617
                        if (op == 1 || op == 3) {
4618
                            /* Accumulate.  */
4619
                            tmp2 = neon_load_reg(rd, pass);
4620
                            gen_neon_add(size, tmp2, tmp);
4621
                            dead_tmp(tmp2);
4622
                        } else if (op == 4 || (op == 5 && u)) {
4623
                            /* Insert */
4624
                            switch (size) {
4625
                            case 0:
4626
                                if (op == 4)
4627
                                    imm = 0xff >> -shift;
4628
                                else
4629
                                    imm = (uint8_t)(0xff << shift);
4630
                                imm |= imm << 8;
4631
                                imm |= imm << 16;
4632
                                break;
4633
                            case 1:
4634
                                if (op == 4)
4635
                                    imm = 0xffff >> -shift;
4636
                                else
4637
                                    imm = (uint16_t)(0xffff << shift);
4638
                                imm |= imm << 16;
4639
                                break;
4640
                            case 2:
4641
                                if (op == 4)
4642
                                    imm = 0xffffffffu >> -shift;
4643
                                else
4644
                                    imm = 0xffffffffu << shift;
4645
                                break;
4646
                            default:
4647
                                abort();
4648
                            }
4649
                            tmp2 = neon_load_reg(rd, pass);
4650
                            tcg_gen_andi_i32(tmp, tmp, imm);
4651
                            tcg_gen_andi_i32(tmp2, tmp2, ~imm);
4652
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4653
                            dead_tmp(tmp2);
4654
                        }
4655
                        neon_store_reg(rd, pass, tmp);
4656
                    }
4657
                } /* for pass */
4658
            } else if (op < 10) {
4659
                /* Shift by immediate and narrow:
4660
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4661
                shift = shift - (1 << (size + 3));
4662
                size++;
4663
                switch (size) {
4664
                case 1:
4665
                    imm = (uint16_t)shift;
4666
                    imm |= imm << 16;
4667
                    tmp2 = tcg_const_i32(imm);
4668
                    TCGV_UNUSED_I64(tmp64);
4669
                    break;
4670
                case 2:
4671
                    imm = (uint32_t)shift;
4672
                    tmp2 = tcg_const_i32(imm);
4673
                    TCGV_UNUSED_I64(tmp64);
4674
                    break;
4675
                case 3:
4676
                    tmp64 = tcg_const_i64(shift);
4677
                    TCGV_UNUSED(tmp2);
4678
                    break;
4679
                default:
4680
                    abort();
4681
                }
4682

    
4683
                for (pass = 0; pass < 2; pass++) {
4684
                    if (size == 3) {
4685
                        neon_load_reg64(cpu_V0, rm + pass);
4686
                        if (q) {
4687
                          if (u)
4688
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4689
                          else
4690
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4691
                        } else {
4692
                          if (u)
4693
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4694
                          else
4695
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4696
                        }
4697
                    } else {
4698
                        tmp = neon_load_reg(rm + pass, 0);
4699
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4700
                        tmp3 = neon_load_reg(rm + pass, 1);
4701
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4702
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4703
                        dead_tmp(tmp);
4704
                        dead_tmp(tmp3);
4705
                    }
4706
                    tmp = new_tmp();
4707
                    if (op == 8 && !u) {
4708
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4709
                    } else {
4710
                        if (op == 8)
4711
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4712
                        else
4713
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4714
                    }
4715
                    neon_store_reg(rd, pass, tmp);
4716
                } /* for pass */
4717
                if (size == 3) {
4718
                    tcg_temp_free_i64(tmp64);
4719
                } else {
4720
                    dead_tmp(tmp2);
4721
                }
4722
            } else if (op == 10) {
4723
                /* VSHLL */
4724
                if (q || size == 3)
4725
                    return 1;
4726
                tmp = neon_load_reg(rm, 0);
4727
                tmp2 = neon_load_reg(rm, 1);
4728
                for (pass = 0; pass < 2; pass++) {
4729
                    if (pass == 1)
4730
                        tmp = tmp2;
4731

    
4732
                    gen_neon_widen(cpu_V0, tmp, size, u);
4733

    
4734
                    if (shift != 0) {
4735
                        /* The shift is less than the width of the source
4736
                           type, so we can just shift the whole register.  */
4737
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4738
                        if (size < 2 || !u) {
4739
                            uint64_t imm64;
4740
                            if (size == 0) {
4741
                                imm = (0xffu >> (8 - shift));
4742
                                imm |= imm << 16;
4743
                            } else {
4744
                                imm = 0xffff >> (16 - shift);
4745
                            }
4746
                            imm64 = imm | (((uint64_t)imm) << 32);
4747
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4748
                        }
4749
                    }
4750
                    neon_store_reg64(cpu_V0, rd + pass);
4751
                }
4752
            } else if (op == 15 || op == 16) {
4753
                /* VCVT fixed-point.  */
4754
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4755
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4756
                    if (op & 1) {
4757
                        if (u)
4758
                            gen_vfp_ulto(0, shift);
4759
                        else
4760
                            gen_vfp_slto(0, shift);
4761
                    } else {
4762
                        if (u)
4763
                            gen_vfp_toul(0, shift);
4764
                        else
4765
                            gen_vfp_tosl(0, shift);
4766
                    }
4767
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4768
                }
4769
            } else {
4770
                return 1;
4771
            }
4772
        } else { /* (insn & 0x00380080) == 0 */
4773
            int invert;
4774

    
4775
            op = (insn >> 8) & 0xf;
4776
            /* One register and immediate.  */
4777
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4778
            invert = (insn & (1 << 5)) != 0;
4779
            switch (op) {
4780
            case 0: case 1:
4781
                /* no-op */
4782
                break;
4783
            case 2: case 3:
4784
                imm <<= 8;
4785
                break;
4786
            case 4: case 5:
4787
                imm <<= 16;
4788
                break;
4789
            case 6: case 7:
4790
                imm <<= 24;
4791
                break;
4792
            case 8: case 9:
4793
                imm |= imm << 16;
4794
                break;
4795
            case 10: case 11:
4796
                imm = (imm << 8) | (imm << 24);
4797
                break;
4798
            case 12:
4799
                imm = (imm < 8) | 0xff;
4800
                break;
4801
            case 13:
4802
                imm = (imm << 16) | 0xffff;
4803
                break;
4804
            case 14:
4805
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4806
                if (invert)
4807
                    imm = ~imm;
4808
                break;
4809
            case 15:
4810
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4811
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4812
                break;
4813
            }
4814
            if (invert)
4815
                imm = ~imm;
4816

    
4817
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4818
                if (op & 1 && op < 12) {
4819
                    tmp = neon_load_reg(rd, pass);
4820
                    if (invert) {
4821
                        /* The immediate value has already been inverted, so
4822
                           BIC becomes AND.  */
4823
                        tcg_gen_andi_i32(tmp, tmp, imm);
4824
                    } else {
4825
                        tcg_gen_ori_i32(tmp, tmp, imm);
4826
                    }
4827
                } else {
4828
                    /* VMOV, VMVN.  */
4829
                    tmp = new_tmp();
4830
                    if (op == 14 && invert) {
4831
                        uint32_t val;
4832
                        val = 0;
4833
                        for (n = 0; n < 4; n++) {
4834
                            if (imm & (1 << (n + (pass & 1) * 4)))
4835
                                val |= 0xff << (n * 8);
4836
                        }
4837
                        tcg_gen_movi_i32(tmp, val);
4838
                    } else {
4839
                        tcg_gen_movi_i32(tmp, imm);
4840
                    }
4841
                }
4842
                neon_store_reg(rd, pass, tmp);
4843
            }
4844
        }
4845
    } else { /* (insn & 0x00800010 == 0x00800000) */
4846
        if (size != 3) {
4847
            op = (insn >> 8) & 0xf;
4848
            if ((insn & (1 << 6)) == 0) {
4849
                /* Three registers of different lengths.  */
4850
                int src1_wide;
4851
                int src2_wide;
4852
                int prewiden;
4853
                /* prewiden, src1_wide, src2_wide */
4854
                static const int neon_3reg_wide[16][3] = {
4855
                    {1, 0, 0}, /* VADDL */
4856
                    {1, 1, 0}, /* VADDW */
4857
                    {1, 0, 0}, /* VSUBL */
4858
                    {1, 1, 0}, /* VSUBW */
4859
                    {0, 1, 1}, /* VADDHN */
4860
                    {0, 0, 0}, /* VABAL */
4861
                    {0, 1, 1}, /* VSUBHN */
4862
                    {0, 0, 0}, /* VABDL */
4863
                    {0, 0, 0}, /* VMLAL */
4864
                    {0, 0, 0}, /* VQDMLAL */
4865
                    {0, 0, 0}, /* VMLSL */
4866
                    {0, 0, 0}, /* VQDMLSL */
4867
                    {0, 0, 0}, /* Integer VMULL */
4868
                    {0, 0, 0}, /* VQDMULL */
4869
                    {0, 0, 0}  /* Polynomial VMULL */
4870
                };
4871

    
4872
                prewiden = neon_3reg_wide[op][0];
4873
                src1_wide = neon_3reg_wide[op][1];
4874
                src2_wide = neon_3reg_wide[op][2];
4875

    
4876
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4877
                    return 1;
4878

    
4879
                /* Avoid overlapping operands.  Wide source operands are
4880
                   always aligned so will never overlap with wide
4881
                   destinations in problematic ways.  */
4882
                if (rd == rm && !src2_wide) {
4883
                    tmp = neon_load_reg(rm, 1);
4884
                    neon_store_scratch(2, tmp);
4885
                } else if (rd == rn && !src1_wide) {
4886
                    tmp = neon_load_reg(rn, 1);
4887
                    neon_store_scratch(2, tmp);
4888
                }
4889
                TCGV_UNUSED(tmp3);
4890
                for (pass = 0; pass < 2; pass++) {
4891
                    if (src1_wide) {
4892
                        neon_load_reg64(cpu_V0, rn + pass);
4893
                        TCGV_UNUSED(tmp);
4894
                    } else {
4895
                        if (pass == 1 && rd == rn) {
4896
                            tmp = neon_load_scratch(2);
4897
                        } else {
4898
                            tmp = neon_load_reg(rn, pass);
4899
                        }
4900
                        if (prewiden) {
4901
                            gen_neon_widen(cpu_V0, tmp, size, u);
4902
                        }
4903
                    }
4904
                    if (src2_wide) {
4905
                        neon_load_reg64(cpu_V1, rm + pass);
4906
                        TCGV_UNUSED(tmp2);
4907
                    } else {
4908
                        if (pass == 1 && rd == rm) {
4909
                            tmp2 = neon_load_scratch(2);
4910
                        } else {
4911
                            tmp2 = neon_load_reg(rm, pass);
4912
                        }
4913
                        if (prewiden) {
4914
                            gen_neon_widen(cpu_V1, tmp2, size, u);
4915
                        }
4916
                    }
4917
                    switch (op) {
4918
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4919
                        gen_neon_addl(size);
4920
                        break;
4921
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4922
                        gen_neon_subl(size);
4923
                        break;
4924
                    case 5: case 7: /* VABAL, VABDL */
4925
                        switch ((size << 1) | u) {
4926
                        case 0:
4927
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4928
                            break;
4929
                        case 1:
4930
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4931
                            break;
4932
                        case 2:
4933
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4934
                            break;
4935
                        case 3:
4936
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4937
                            break;
4938
                        case 4:
4939
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4940
                            break;
4941
                        case 5:
4942
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4943
                            break;
4944
                        default: abort();
4945
                        }
4946
                        dead_tmp(tmp2);
4947
                        dead_tmp(tmp);
4948
                        break;
4949
                    case 8: case 9: case 10: case 11: case 12: case 13:
4950
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4951
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4952
                        dead_tmp(tmp2);
4953
                        dead_tmp(tmp);
4954
                        break;
4955
                    case 14: /* Polynomial VMULL */
4956
                        cpu_abort(env, "Polynomial VMULL not implemented");
4957

    
4958
                    default: /* 15 is RESERVED.  */
4959
                        return 1;
4960
                    }
4961
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4962
                        /* Accumulate.  */
4963
                        if (op == 10 || op == 11) {
4964
                            gen_neon_negl(cpu_V0, size);
4965
                        }
4966

    
4967
                        if (op != 13) {
4968
                            neon_load_reg64(cpu_V1, rd + pass);
4969
                        }
4970

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

    
5103
                    tmp2 = neon_get_scalar(size, rm);
5104
                    tmp3 = neon_load_reg(rn, 1);
5105

    
5106
                    for (pass = 0; pass < 2; pass++) {
5107
                        if (pass == 0) {
5108
                            tmp = neon_load_reg(rn, 0);
5109
                        } else {
5110
                            tmp = tmp3;
5111
                        }
5112
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5113
                        dead_tmp(tmp);
5114
                        if (op == 6 || op == 7) {
5115
                            gen_neon_negl(cpu_V0, size);
5116
                        }
5117
                        if (op != 11) {
5118
                            neon_load_reg64(cpu_V1, rd + pass);
5119
                        }
5120
                        switch (op) {
5121
                        case 2: case 6:
5122
                            gen_neon_addl(size);
5123
                            break;
5124
                        case 3: case 7:
5125
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5126
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5127
                            break;
5128
                        case 10:
5129
                            /* no-op */
5130
                            break;
5131
                        case 11:
5132
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5133
                            break;
5134
                        default:
5135
                            abort();
5136
                        }
5137
                        neon_store_reg64(cpu_V0, rd + pass);
5138
                    }
5139

    
5140
                    dead_tmp(tmp2);
5141

    
5142
                    break;
5143
                default: /* 14 and 15 are RESERVED */
5144
                    return 1;
5145
                }
5146
            }
5147
        } else { /* size == 3 */
5148
            if (!u) {
5149
                /* Extract.  */
5150
                imm = (insn >> 8) & 0xf;
5151
                count = q + 1;
5152

    
5153
                if (imm > 7 && !q)
5154
                    return 1;
5155

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

    
5598
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5599
{
5600
    int crn = (insn >> 16) & 0xf;
5601
    int crm = insn & 0xf;
5602
    int op1 = (insn >> 21) & 7;
5603
    int op2 = (insn >> 5) & 7;
5604
    int rt = (insn >> 12) & 0xf;
5605
    TCGv tmp;
5606

    
5607
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5608
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5609
            /* TEECR */
5610
            if (IS_USER(s))
5611
                return 1;
5612
            tmp = load_cpu_field(teecr);
5613
            store_reg(s, rt, tmp);
5614
            return 0;
5615
        }
5616
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5617
            /* TEEHBR */
5618
            if (IS_USER(s) && (env->teecr & 1))
5619
                return 1;
5620
            tmp = load_cpu_field(teehbr);
5621
            store_reg(s, rt, tmp);
5622
            return 0;
5623
        }
5624
    }
5625
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5626
            op1, crn, crm, op2);
5627
    return 1;
5628
}
5629

    
5630
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5631
{
5632
    int crn = (insn >> 16) & 0xf;
5633
    int crm = insn & 0xf;
5634
    int op1 = (insn >> 21) & 7;
5635
    int op2 = (insn >> 5) & 7;
5636
    int rt = (insn >> 12) & 0xf;
5637
    TCGv tmp;
5638

    
5639
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5640
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5641
            /* TEECR */
5642
            if (IS_USER(s))
5643
                return 1;
5644
            tmp = load_reg(s, rt);
5645
            gen_helper_set_teecr(cpu_env, tmp);
5646
            dead_tmp(tmp);
5647
            return 0;
5648
        }
5649
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5650
            /* TEEHBR */
5651
            if (IS_USER(s) && (env->teecr & 1))
5652
                return 1;
5653
            tmp = load_reg(s, rt);
5654
            store_cpu_field(tmp, teehbr);
5655
            return 0;
5656
        }
5657
    }
5658
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5659
            op1, crn, crm, op2);
5660
    return 1;
5661
}
5662

    
5663
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5664
{
5665
    int cpnum;
5666

    
5667
    cpnum = (insn >> 8) & 0xf;
5668
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5669
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5670
        return 1;
5671

    
5672
    switch (cpnum) {
5673
      case 0:
5674
      case 1:
5675
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5676
            return disas_iwmmxt_insn(env, s, insn);
5677
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5678
            return disas_dsp_insn(env, s, insn);
5679
        }
5680
        return 1;
5681
    case 10:
5682
    case 11:
5683
        return disas_vfp_insn (env, s, insn);
5684
    case 14:
5685
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5686
           Unfortunately Intel decided to ignore this.  */
5687
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5688
            goto board;
5689
        if (insn & (1 << 20))
5690
            return disas_cp14_read(env, s, insn);
5691
        else
5692
            return disas_cp14_write(env, s, insn);
5693
    case 15:
5694
        return disas_cp15_insn (env, s, insn);
5695
    default:
5696
    board:
5697
        /* Unknown coprocessor.  See if the board has hooked it.  */
5698
        return disas_cp_insn (env, s, insn);
5699
    }
5700
}
5701

    
5702

    
5703
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5704
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5705
{
5706
    TCGv tmp;
5707
    tmp = new_tmp();
5708
    tcg_gen_trunc_i64_i32(tmp, val);
5709
    store_reg(s, rlow, tmp);
5710
    tmp = new_tmp();
5711
    tcg_gen_shri_i64(val, val, 32);
5712
    tcg_gen_trunc_i64_i32(tmp, val);
5713
    store_reg(s, rhigh, tmp);
5714
}
5715

    
5716
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5717
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5718
{
5719
    TCGv_i64 tmp;
5720
    TCGv tmp2;
5721

    
5722
    /* Load value and extend to 64 bits.  */
5723
    tmp = tcg_temp_new_i64();
5724
    tmp2 = load_reg(s, rlow);
5725
    tcg_gen_extu_i32_i64(tmp, tmp2);
5726
    dead_tmp(tmp2);
5727
    tcg_gen_add_i64(val, val, tmp);
5728
    tcg_temp_free_i64(tmp);
5729
}
5730

    
5731
/* load and add a 64-bit value from a register pair.  */
5732
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5733
{
5734
    TCGv_i64 tmp;
5735
    TCGv tmpl;
5736
    TCGv tmph;
5737

    
5738
    /* Load 64-bit value rd:rn.  */
5739
    tmpl = load_reg(s, rlow);
5740
    tmph = load_reg(s, rhigh);
5741
    tmp = tcg_temp_new_i64();
5742
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5743
    dead_tmp(tmpl);
5744
    dead_tmp(tmph);
5745
    tcg_gen_add_i64(val, val, tmp);
5746
    tcg_temp_free_i64(tmp);
5747
}
5748

    
5749
/* Set N and Z flags from a 64-bit value.  */
5750
static void gen_logicq_cc(TCGv_i64 val)
5751
{
5752
    TCGv tmp = new_tmp();
5753
    gen_helper_logicq_cc(tmp, val);
5754
    gen_logic_CC(tmp);
5755
    dead_tmp(tmp);
5756
}
5757

    
5758
static void disas_arm_insn(CPUState * env, DisasContext *s)
5759
{
5760
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5761
    TCGv tmp;
5762
    TCGv tmp2;
5763
    TCGv tmp3;
5764
    TCGv addr;
5765
    TCGv_i64 tmp64;
5766

    
5767
    insn = ldl_code(s->pc);
5768
    s->pc += 4;
5769

    
5770
    /* M variants do not implement ARM mode.  */
5771
    if (IS_M(env))
5772
        goto illegal_op;
5773
    cond = insn >> 28;
5774
    if (cond == 0xf){
5775
        /* Unconditional instructions.  */
5776
        if (((insn >> 25) & 7) == 1) {
5777
            /* NEON Data processing.  */
5778
            if (!arm_feature(env, ARM_FEATURE_NEON))
5779
                goto illegal_op;
5780

    
5781
            if (disas_neon_data_insn(env, s, insn))
5782
                goto illegal_op;
5783
            return;
5784
        }
5785
        if ((insn & 0x0f100000) == 0x04000000) {
5786
            /* NEON load/store.  */
5787
            if (!arm_feature(env, ARM_FEATURE_NEON))
5788
                goto illegal_op;
5789

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

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

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

    
6145
        op1 = (insn >> 21) & 0xf;
6146
        set_cc = (insn >> 20) & 1;
6147
        logic_cc = table_logic_cc[op1] & set_cc;
6148

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

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

    
6848
                    if ((insn & (1 << 15)) == 0)
6849
                        user = 1;
6850
                }
6851
                rn = (insn >> 16) & 0xf;
6852
                addr = load_reg(s, rn);
6853

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

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

    
6997
/* Return true if this is a Thumb-2 logical op.  */
6998
static int
6999
thumb2_logic_op(int op)
7000
{
7001
    return (op < 8);
7002
}
7003

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

    
7010
static int
7011
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7012
{
7013
    int logic_cc;
7014

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

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

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

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

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

    
7136
    insn = lduw_code(s->pc);
7137
    s->pc += 2;
7138
    insn |= (uint32_t)insn_hw1 << 16;
7139

    
7140
    if ((insn & 0xf800e800) != 0xf000e800) {
7141
        ARCH(6T2);
7142
    }
7143

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

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

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

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

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

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

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

    
8121
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8122
{
8123
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8124
    int32_t offset;
8125
    int i;
8126
    TCGv tmp;
8127
    TCGv tmp2;
8128
    TCGv addr;
8129

    
8130
    if (s->condexec_mask) {
8131
        cond = s->condexec_cond;
8132
        s->condlabel = gen_new_label();
8133
        gen_test_cc(cond ^ 1, s->condlabel);
8134
        s->condjmp = 1;
8135
    }
8136

    
8137
    insn = lduw_code(s->pc);
8138
    s->pc += 2;
8139

    
8140
    switch (insn >> 12) {
8141
    case 0: case 1:
8142

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

    
8272
        /* data processing register */
8273
        rd = insn & 7;
8274
        rm = (insn >> 3) & 7;
8275
        op = (insn >> 6) & 0xf;
8276
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8277
            /* the shift/rotate ops want the operands backwards */
8278
            val = rm;
8279
            rm = rd;
8280
            rd = val;
8281
            val = 1;
8282
        } else {
8283
            val = 0;
8284
        }
8285

    
8286
        if (op == 9) { /* neg */
8287
            tmp = new_tmp();
8288
            tcg_gen_movi_i32(tmp, 0);
8289
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
8290
            tmp = load_reg(s, rd);
8291
        } else {
8292
            TCGV_UNUSED(tmp);
8293
        }
8294

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

    
8408
    case 5:
8409
        /* load/store register offset.  */
8410
        rd = insn & 7;
8411
        rn = (insn >> 3) & 7;
8412
        rm = (insn >> 6) & 7;
8413
        op = (insn >> 9) & 7;
8414
        addr = load_reg(s, rn);
8415
        tmp = load_reg(s, rm);
8416
        tcg_gen_add_i32(addr, addr, tmp);
8417
        dead_tmp(tmp);
8418

    
8419
        if (op < 3) /* store */
8420
            tmp = load_reg(s, rd);
8421

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

    
8453
    case 6:
8454
        /* load/store word immediate offset */
8455
        rd = insn & 7;
8456
        rn = (insn >> 3) & 7;
8457
        addr = load_reg(s, rn);
8458
        val = (insn >> 4) & 0x7c;
8459
        tcg_gen_addi_i32(addr, addr, val);
8460

    
8461
        if (insn & (1 << 11)) {
8462
            /* load */
8463
            tmp = gen_ld32(addr, IS_USER(s));
8464
            store_reg(s, rd, tmp);
8465
        } else {
8466
            /* store */
8467
            tmp = load_reg(s, rd);
8468
            gen_st32(tmp, addr, IS_USER(s));
8469
        }
8470
        dead_tmp(addr);
8471
        break;
8472

    
8473
    case 7:
8474
        /* load/store byte immediate offset */
8475
        rd = insn & 7;
8476
        rn = (insn >> 3) & 7;
8477
        addr = load_reg(s, rn);
8478
        val = (insn >> 6) & 0x1f;
8479
        tcg_gen_addi_i32(addr, addr, val);
8480

    
8481
        if (insn & (1 << 11)) {
8482
            /* load */
8483
            tmp = gen_ld8u(addr, IS_USER(s));
8484
            store_reg(s, rd, tmp);
8485
        } else {
8486
            /* store */
8487
            tmp = load_reg(s, rd);
8488
            gen_st8(tmp, addr, IS_USER(s));
8489
        }
8490
        dead_tmp(addr);
8491
        break;
8492

    
8493
    case 8:
8494
        /* load/store halfword immediate offset */
8495
        rd = insn & 7;
8496
        rn = (insn >> 3) & 7;
8497
        addr = load_reg(s, rn);
8498
        val = (insn >> 5) & 0x3e;
8499
        tcg_gen_addi_i32(addr, addr, val);
8500

    
8501
        if (insn & (1 << 11)) {
8502
            /* load */
8503
            tmp = gen_ld16u(addr, IS_USER(s));
8504
            store_reg(s, rd, tmp);
8505
        } else {
8506
            /* store */
8507
            tmp = load_reg(s, rd);
8508
            gen_st16(tmp, addr, IS_USER(s));
8509
        }
8510
        dead_tmp(addr);
8511
        break;
8512

    
8513
    case 9:
8514
        /* load/store from stack */
8515
        rd = (insn >> 8) & 7;
8516
        addr = load_reg(s, 13);
8517
        val = (insn & 0xff) * 4;
8518
        tcg_gen_addi_i32(addr, addr, val);
8519

    
8520
        if (insn & (1 << 11)) {
8521
            /* load */
8522
            tmp = gen_ld32(addr, IS_USER(s));
8523
            store_reg(s, rd, tmp);
8524
        } else {
8525
            /* store */
8526
            tmp = load_reg(s, rd);
8527
            gen_st32(tmp, addr, IS_USER(s));
8528
        }
8529
        dead_tmp(addr);
8530
        break;
8531

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

    
8548
    case 11:
8549
        /* misc */
8550
        op = (insn >> 8) & 0xf;
8551
        switch (op) {
8552
        case 0:
8553
            /* adjust stack pointer */
8554
            tmp = load_reg(s, 13);
8555
            val = (insn & 0x7f) * 4;
8556
            if (insn & (1 << 7))
8557
                val = -(int32_t)val;
8558
            tcg_gen_addi_i32(tmp, tmp, val);
8559
            store_reg(s, 13, tmp);
8560
            break;
8561

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

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

    
8644
        case 15: /* IT, nop-hint.  */
8645
            if ((insn & 0xf) == 0) {
8646
                gen_nop_hint(s, (insn >> 4) & 0xf);
8647
                break;
8648
            }
8649
            /* If Then.  */
8650
            s->condexec_cond = (insn >> 4) & 0xe;
8651
            s->condexec_mask = insn & 0x1f;
8652
            /* No actual code generated for this insn, just setup state.  */
8653
            break;
8654

    
8655
        case 0xe: /* bkpt */
8656
            gen_set_condexec(s);
8657
            gen_set_pc_im(s->pc - 2);
8658
            gen_exception(EXCP_BKPT);
8659
            s->is_jmp = DISAS_JUMP;
8660
            break;
8661

    
8662
        case 0xa: /* rev */
8663
            ARCH(6);
8664
            rn = (insn >> 3) & 0x7;
8665
            rd = insn & 0x7;
8666
            tmp = load_reg(s, rn);
8667
            switch ((insn >> 6) & 3) {
8668
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8669
            case 1: gen_rev16(tmp); break;
8670
            case 3: gen_revsh(tmp); break;
8671
            default: goto illegal_op;
8672
            }
8673
            store_reg(s, rd, tmp);
8674
            break;
8675

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

    
8705
        default:
8706
            goto undef;
8707
        }
8708
        break;
8709

    
8710
    case 12:
8711
        /* load/store multiple */
8712
        rn = (insn >> 8) & 0x7;
8713
        addr = load_reg(s, rn);
8714
        for (i = 0; i < 8; i++) {
8715
            if (insn & (1 << i)) {
8716
                if (insn & (1 << 11)) {
8717
                    /* load */
8718
                    tmp = gen_ld32(addr, IS_USER(s));
8719
                    store_reg(s, i, tmp);
8720
                } else {
8721
                    /* store */
8722
                    tmp = load_reg(s, i);
8723
                    gen_st32(tmp, addr, IS_USER(s));
8724
                }
8725
                /* advance to the next address */
8726
                tcg_gen_addi_i32(addr, addr, 4);
8727
            }
8728
        }
8729
        /* Base register writeback.  */
8730
        if ((insn & (1 << rn)) == 0) {
8731
            store_reg(s, rn, addr);
8732
        } else {
8733
            dead_tmp(addr);
8734
        }
8735
        break;
8736

    
8737
    case 13:
8738
        /* conditional branch or swi */
8739
        cond = (insn >> 8) & 0xf;
8740
        if (cond == 0xe)
8741
            goto undef;
8742

    
8743
        if (cond == 0xf) {
8744
            /* swi */
8745
            gen_set_condexec(s);
8746
            gen_set_pc_im(s->pc);
8747
            s->is_jmp = DISAS_SWI;
8748
            break;
8749
        }
8750
        /* generate a conditional jump to next instruction */
8751
        s->condlabel = gen_new_label();
8752
        gen_test_cc(cond ^ 1, s->condlabel);
8753
        s->condjmp = 1;
8754

    
8755
        /* jump to the offset */
8756
        val = (uint32_t)s->pc + 2;
8757
        offset = ((int32_t)insn << 24) >> 24;
8758
        val += offset << 1;
8759
        gen_jmp(s, val);
8760
        break;
8761

    
8762
    case 14:
8763
        if (insn & (1 << 11)) {
8764
            if (disas_thumb2_insn(env, s, insn))
8765
              goto undef32;
8766
            break;
8767
        }
8768
        /* unconditional branch */
8769
        val = (uint32_t)s->pc;
8770
        offset = ((int32_t)insn << 21) >> 21;
8771
        val += (offset << 1) + 2;
8772
        gen_jmp(s, val);
8773
        break;
8774

    
8775
    case 15:
8776
        if (disas_thumb2_insn(env, s, insn))
8777
            goto undef32;
8778
        break;
8779
    }
8780
    return;
8781
undef32:
8782
    gen_set_condexec(s);
8783
    gen_set_pc_im(s->pc - 4);
8784
    gen_exception(EXCP_UDEF);
8785
    s->is_jmp = DISAS_JUMP;
8786
    return;
8787
illegal_op:
8788
undef:
8789
    gen_set_condexec(s);
8790
    gen_set_pc_im(s->pc - 2);
8791
    gen_exception(EXCP_UDEF);
8792
    s->is_jmp = DISAS_JUMP;
8793
}
8794

    
8795
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8796
   basic block 'tb'. If search_pc is TRUE, also generate PC
8797
   information for each intermediate instruction. */
8798
static inline void gen_intermediate_code_internal(CPUState *env,
8799
                                                  TranslationBlock *tb,
8800
                                                  int search_pc)
8801
{
8802
    DisasContext dc1, *dc = &dc1;
8803
    CPUBreakpoint *bp;
8804
    uint16_t *gen_opc_end;
8805
    int j, lj;
8806
    target_ulong pc_start;
8807
    uint32_t next_page_start;
8808
    int num_insns;
8809
    int max_insns;
8810

    
8811
    /* generate intermediate code */
8812
    num_temps = 0;
8813

    
8814
    pc_start = tb->pc;
8815

    
8816
    dc->tb = tb;
8817

    
8818
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8819

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

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

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

    
8905
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8906
            gen_io_start();
8907

    
8908
        if (env->thumb) {
8909
            disas_thumb_insn(env, dc);
8910
            if (dc->condexec_mask) {
8911
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8912
                                   | ((dc->condexec_mask >> 4) & 1);
8913
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8914
                if (dc->condexec_mask == 0) {
8915
                    dc->condexec_cond = 0;
8916
                }
8917
            }
8918
        } else {
8919
            disas_arm_insn(env, dc);
8920
        }
8921
        if (num_temps) {
8922
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8923
            num_temps = 0;
8924
        }
8925

    
8926
        if (dc->condjmp && !dc->is_jmp) {
8927
            gen_set_label(dc->condlabel);
8928
            dc->condjmp = 0;
8929
        }
8930
        /* Translation stops when a conditional branch is encountered.
8931
         * Otherwise the subsequent code could get translated several times.
8932
         * Also stop translation when a page boundary is reached.  This
8933
         * ensures prefetch aborts occur at the right place.  */
8934
        num_insns ++;
8935
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8936
             !env->singlestep_enabled &&
8937
             !singlestep &&
8938
             dc->pc < next_page_start &&
8939
             num_insns < max_insns);
8940

    
8941
    if (tb->cflags & CF_LAST_IO) {
8942
        if (dc->condjmp) {
8943
            /* FIXME:  This can theoretically happen with self-modifying
8944
               code.  */
8945
            cpu_abort(env, "IO on conditional branch instruction");
8946
        }
8947
        gen_io_end();
8948
    }
8949

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

    
9014
done_generating:
9015
    gen_icount_end(tb, num_insns);
9016
    *gen_opc_ptr = INDEX_op_end;
9017

    
9018
#ifdef DEBUG_DISAS
9019
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9020
        qemu_log("----------------\n");
9021
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9022
        log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
9023
        qemu_log("\n");
9024
    }
9025
#endif
9026
    if (search_pc) {
9027
        j = gen_opc_ptr - gen_opc_buf;
9028
        lj++;
9029
        while (lj <= j)
9030
            gen_opc_instr_start[lj++] = 0;
9031
    } else {
9032
        tb->size = dc->pc - pc_start;
9033
        tb->icount = num_insns;
9034
    }
9035
}
9036

    
9037
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9038
{
9039
    gen_intermediate_code_internal(env, tb, 0);
9040
}
9041

    
9042
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9043
{
9044
    gen_intermediate_code_internal(env, tb, 1);
9045
}
9046

    
9047
static const char *cpu_mode_names[16] = {
9048
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9049
  "???", "???", "???", "und", "???", "???", "???", "sys"
9050
};
9051

    
9052
void cpu_dump_state(CPUState *env, FILE *f,
9053
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9054
                    int flags)
9055
{
9056
    int i;
9057
#if 0
9058
    union {
9059
        uint32_t i;
9060
        float s;
9061
    } s0, s1;
9062
    CPU_DoubleU d;
9063
    /* ??? This assumes float64 and double have the same layout.
9064
       Oh well, it's only debug dumps.  */
9065
    union {
9066
        float64 f64;
9067
        double d;
9068
    } d0;
9069
#endif
9070
    uint32_t psr;
9071

    
9072
    for(i=0;i<16;i++) {
9073
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9074
        if ((i % 4) == 3)
9075
            cpu_fprintf(f, "\n");
9076
        else
9077
            cpu_fprintf(f, " ");
9078
    }
9079
    psr = cpsr_read(env);
9080
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9081
                psr,
9082
                psr & (1 << 31) ? 'N' : '-',
9083
                psr & (1 << 30) ? 'Z' : '-',
9084
                psr & (1 << 29) ? 'C' : '-',
9085
                psr & (1 << 28) ? 'V' : '-',
9086
                psr & CPSR_T ? 'T' : 'A',
9087
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9088

    
9089
#if 0
9090
    for (i = 0; i < 16; i++) {
9091
        d.d = env->vfp.regs[i];
9092
        s0.i = d.l.lower;
9093
        s1.i = d.l.upper;
9094
        d0.f64 = d.d;
9095
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9096
                    i * 2, (int)s0.i, s0.s,
9097
                    i * 2 + 1, (int)s1.i, s1.s,
9098
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9099
                    d0.d);
9100
    }
9101
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9102
#endif
9103
}
9104

    
9105
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9106
                unsigned long searched_pc, int pc_pos, void *puc)
9107
{
9108
    env->regs[15] = gen_opc_pc[pc_pos];
9109
}