Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 30d11a2a

History | View | Annotate | Download (312.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
static TCGv_i32 cpu_exclusive_addr;
80
static TCGv_i32 cpu_exclusive_val;
81
static TCGv_i32 cpu_exclusive_high;
82
#ifdef CONFIG_USER_ONLY
83
static TCGv_i32 cpu_exclusive_test;
84
static TCGv_i32 cpu_exclusive_info;
85
#endif
86

    
87
/* FIXME:  These should be removed.  */
88
static TCGv cpu_F0s, cpu_F1s;
89
static TCGv_i64 cpu_F0d, cpu_F1d;
90

    
91
#include "gen-icount.h"
92

    
93
static const char *regnames[] =
94
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
95
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
96

    
97
/* initialize TCG globals.  */
98
void arm_translate_init(void)
99
{
100
    int i;
101

    
102
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
103

    
104
    for (i = 0; i < 16; i++) {
105
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
106
                                          offsetof(CPUState, regs[i]),
107
                                          regnames[i]);
108
    }
109
    cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
110
        offsetof(CPUState, exclusive_addr), "exclusive_addr");
111
    cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
112
        offsetof(CPUState, exclusive_val), "exclusive_val");
113
    cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
114
        offsetof(CPUState, exclusive_high), "exclusive_high");
115
#ifdef CONFIG_USER_ONLY
116
    cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
117
        offsetof(CPUState, exclusive_test), "exclusive_test");
118
    cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
119
        offsetof(CPUState, exclusive_info), "exclusive_info");
120
#endif
121

    
122
#define GEN_HELPER 2
123
#include "helpers.h"
124
}
125

    
126
static int num_temps;
127

    
128
/* Allocate a temporary variable.  */
129
static TCGv_i32 new_tmp(void)
130
{
131
    num_temps++;
132
    return tcg_temp_new_i32();
133
}
134

    
135
/* Release a temporary variable.  */
136
static void dead_tmp(TCGv tmp)
137
{
138
    tcg_temp_free(tmp);
139
    num_temps--;
140
}
141

    
142
static inline TCGv load_cpu_offset(int offset)
143
{
144
    TCGv tmp = new_tmp();
145
    tcg_gen_ld_i32(tmp, cpu_env, offset);
146
    return tmp;
147
}
148

    
149
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
150

    
151
static inline void store_cpu_offset(TCGv var, int offset)
152
{
153
    tcg_gen_st_i32(var, cpu_env, offset);
154
    dead_tmp(var);
155
}
156

    
157
#define store_cpu_field(var, name) \
158
    store_cpu_offset(var, offsetof(CPUState, name))
159

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

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

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

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

    
202
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
203
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
204

    
205

    
206
static inline void gen_set_cpsr(TCGv var, uint32_t mask)
207
{
208
    TCGv tmp_mask = tcg_const_i32(mask);
209
    gen_helper_cpsr_write(var, tmp_mask);
210
    tcg_temp_free_i32(tmp_mask);
211
}
212
/* Set NZCV flags from the high 4 bits of var.  */
213
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
214

    
215
static void gen_exception(int excp)
216
{
217
    TCGv tmp = new_tmp();
218
    tcg_gen_movi_i32(tmp, excp);
219
    gen_helper_exception(tmp);
220
    dead_tmp(tmp);
221
}
222

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

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

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

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

    
270
/* Signed bitfield extract.  */
271
static void gen_sbfx(TCGv var, int shift, int width)
272
{
273
    uint32_t signbit;
274

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

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

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

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

    
309
    tcg_gen_extu_i32_i64(tmp1, a);
310
    dead_tmp(a);
311
    tcg_gen_extu_i32_i64(tmp2, b);
312
    dead_tmp(b);
313
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
314
    tcg_temp_free_i64(tmp2);
315
    return tmp1;
316
}
317

    
318
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
319
{
320
    TCGv_i64 tmp1 = tcg_temp_new_i64();
321
    TCGv_i64 tmp2 = tcg_temp_new_i64();
322

    
323
    tcg_gen_ext_i32_i64(tmp1, a);
324
    dead_tmp(a);
325
    tcg_gen_ext_i32_i64(tmp2, b);
326
    dead_tmp(b);
327
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
328
    tcg_temp_free_i64(tmp2);
329
    return tmp1;
330
}
331

    
332
/* Signed 32x32->64 multiply.  */
333
static void gen_imull(TCGv a, TCGv b)
334
{
335
    TCGv_i64 tmp1 = tcg_temp_new_i64();
336
    TCGv_i64 tmp2 = tcg_temp_new_i64();
337

    
338
    tcg_gen_ext_i32_i64(tmp1, a);
339
    tcg_gen_ext_i32_i64(tmp2, b);
340
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
341
    tcg_temp_free_i64(tmp2);
342
    tcg_gen_trunc_i64_i32(a, tmp1);
343
    tcg_gen_shri_i64(tmp1, tmp1, 32);
344
    tcg_gen_trunc_i64_i32(b, tmp1);
345
    tcg_temp_free_i64(tmp1);
346
}
347

    
348
/* Swap low and high halfwords.  */
349
static void gen_swap_half(TCGv var)
350
{
351
    TCGv tmp = new_tmp();
352
    tcg_gen_shri_i32(tmp, var, 16);
353
    tcg_gen_shli_i32(var, var, 16);
354
    tcg_gen_or_i32(var, var, tmp);
355
    dead_tmp(tmp);
356
}
357

    
358
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
359
    tmp = (t0 ^ t1) & 0x8000;
360
    t0 &= ~0x8000;
361
    t1 &= ~0x8000;
362
    t0 = (t0 + t1) ^ tmp;
363
 */
364

    
365
static void gen_add16(TCGv t0, TCGv t1)
366
{
367
    TCGv tmp = new_tmp();
368
    tcg_gen_xor_i32(tmp, t0, t1);
369
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
370
    tcg_gen_andi_i32(t0, t0, ~0x8000);
371
    tcg_gen_andi_i32(t1, t1, ~0x8000);
372
    tcg_gen_add_i32(t0, t0, t1);
373
    tcg_gen_xor_i32(t0, t0, tmp);
374
    dead_tmp(tmp);
375
    dead_tmp(t1);
376
}
377

    
378
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
379

    
380
/* Set CF to the top bit of var.  */
381
static void gen_set_CF_bit31(TCGv var)
382
{
383
    TCGv tmp = new_tmp();
384
    tcg_gen_shri_i32(tmp, var, 31);
385
    gen_set_CF(tmp);
386
    dead_tmp(tmp);
387
}
388

    
389
/* Set N and Z flags from var.  */
390
static inline void gen_logic_CC(TCGv var)
391
{
392
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
393
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
394
}
395

    
396
/* T0 += T1 + CF.  */
397
static void gen_adc(TCGv t0, TCGv t1)
398
{
399
    TCGv tmp;
400
    tcg_gen_add_i32(t0, t0, t1);
401
    tmp = load_cpu_field(CF);
402
    tcg_gen_add_i32(t0, t0, tmp);
403
    dead_tmp(tmp);
404
}
405

    
406
/* dest = T0 + T1 + CF. */
407
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
408
{
409
    TCGv tmp;
410
    tcg_gen_add_i32(dest, t0, t1);
411
    tmp = load_cpu_field(CF);
412
    tcg_gen_add_i32(dest, dest, tmp);
413
    dead_tmp(tmp);
414
}
415

    
416
/* dest = T0 - T1 + CF - 1.  */
417
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
418
{
419
    TCGv tmp;
420
    tcg_gen_sub_i32(dest, t0, t1);
421
    tmp = load_cpu_field(CF);
422
    tcg_gen_add_i32(dest, dest, tmp);
423
    tcg_gen_subi_i32(dest, dest, 1);
424
    dead_tmp(tmp);
425
}
426

    
427
/* FIXME:  Implement this natively.  */
428
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
429

    
430
static void shifter_out_im(TCGv var, int shift)
431
{
432
    TCGv tmp = new_tmp();
433
    if (shift == 0) {
434
        tcg_gen_andi_i32(tmp, var, 1);
435
    } else {
436
        tcg_gen_shri_i32(tmp, var, shift);
437
        if (shift != 31)
438
            tcg_gen_andi_i32(tmp, tmp, 1);
439
    }
440
    gen_set_CF(tmp);
441
    dead_tmp(tmp);
442
}
443

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

    
494
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
495
                                     TCGv shift, int flags)
496
{
497
    if (flags) {
498
        switch (shiftop) {
499
        case 0: gen_helper_shl_cc(var, var, shift); break;
500
        case 1: gen_helper_shr_cc(var, var, shift); break;
501
        case 2: gen_helper_sar_cc(var, var, shift); break;
502
        case 3: gen_helper_ror_cc(var, var, shift); break;
503
        }
504
    } else {
505
        switch (shiftop) {
506
        case 0: gen_helper_shl(var, var, shift); break;
507
        case 1: gen_helper_shr(var, var, shift); break;
508
        case 2: gen_helper_sar(var, var, shift); break;
509
        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
510
                tcg_gen_rotr_i32(var, var, shift); break;
511
        }
512
    }
513
    dead_tmp(shift);
514
}
515

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

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

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

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

    
609
static void gen_test_cc(int cc, int label)
610
{
611
    TCGv tmp;
612
    TCGv tmp2;
613
    int inv;
614

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

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

    
726
/* Set PC and Thumb state from an immediate address.  */
727
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
728
{
729
    TCGv tmp;
730

    
731
    s->is_jmp = DISAS_UPDATE;
732
    if (s->thumb != (addr & 1)) {
733
        tmp = new_tmp();
734
        tcg_gen_movi_i32(tmp, addr & 1);
735
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
736
        dead_tmp(tmp);
737
    }
738
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
739
}
740

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

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

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

    
820
static inline void gen_set_pc_im(uint32_t val)
821
{
822
    tcg_gen_movi_i32(cpu_R[15], val);
823
}
824

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

    
832
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
833
                                       TCGv var)
834
{
835
    int val, rm, shift, shiftop;
836
    TCGv offset;
837

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

    
860
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
861
                                        int extra, TCGv var)
862
{
863
    int val, rm;
864
    TCGv offset;
865

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

    
888
#define VFP_OP2(name)                                                 \
889
static inline void gen_vfp_##name(int dp)                             \
890
{                                                                     \
891
    if (dp)                                                           \
892
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
893
    else                                                              \
894
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
895
}
896

    
897
VFP_OP2(add)
898
VFP_OP2(sub)
899
VFP_OP2(mul)
900
VFP_OP2(div)
901

    
902
#undef VFP_OP2
903

    
904
static inline void gen_vfp_abs(int dp)
905
{
906
    if (dp)
907
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
908
    else
909
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
910
}
911

    
912
static inline void gen_vfp_neg(int dp)
913
{
914
    if (dp)
915
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
916
    else
917
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
918
}
919

    
920
static inline void gen_vfp_sqrt(int dp)
921
{
922
    if (dp)
923
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
924
    else
925
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
926
}
927

    
928
static inline void gen_vfp_cmp(int dp)
929
{
930
    if (dp)
931
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
932
    else
933
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
934
}
935

    
936
static inline void gen_vfp_cmpe(int dp)
937
{
938
    if (dp)
939
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
940
    else
941
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
942
}
943

    
944
static inline void gen_vfp_F1_ld0(int dp)
945
{
946
    if (dp)
947
        tcg_gen_movi_i64(cpu_F1d, 0);
948
    else
949
        tcg_gen_movi_i32(cpu_F1s, 0);
950
}
951

    
952
static inline void gen_vfp_uito(int dp)
953
{
954
    if (dp)
955
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
956
    else
957
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
958
}
959

    
960
static inline void gen_vfp_sito(int dp)
961
{
962
    if (dp)
963
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
964
    else
965
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
966
}
967

    
968
static inline void gen_vfp_toui(int dp)
969
{
970
    if (dp)
971
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
972
    else
973
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
974
}
975

    
976
static inline void gen_vfp_touiz(int dp)
977
{
978
    if (dp)
979
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
980
    else
981
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
982
}
983

    
984
static inline void gen_vfp_tosi(int dp)
985
{
986
    if (dp)
987
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
988
    else
989
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
990
}
991

    
992
static inline void gen_vfp_tosiz(int dp)
993
{
994
    if (dp)
995
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
996
    else
997
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
998
}
999

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

    
1020
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
1021
{
1022
    if (dp)
1023
        tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1024
    else
1025
        tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1026
}
1027

    
1028
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
1029
{
1030
    if (dp)
1031
        tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1032
    else
1033
        tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1034
}
1035

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

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

    
1060
static TCGv neon_load_reg(int reg, int pass)
1061
{
1062
    TCGv tmp = new_tmp();
1063
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1064
    return tmp;
1065
}
1066

    
1067
static void neon_store_reg(int reg, int pass, TCGv var)
1068
{
1069
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1070
    dead_tmp(var);
1071
}
1072

    
1073
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1074
{
1075
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1076
}
1077

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

    
1083
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1084
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1085
#define tcg_gen_st_f32 tcg_gen_st_i32
1086
#define tcg_gen_st_f64 tcg_gen_st_i64
1087

    
1088
static inline void gen_mov_F0_vreg(int dp, int reg)
1089
{
1090
    if (dp)
1091
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1092
    else
1093
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1094
}
1095

    
1096
static inline void gen_mov_F1_vreg(int dp, int reg)
1097
{
1098
    if (dp)
1099
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1100
    else
1101
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1102
}
1103

    
1104
static inline void gen_mov_vreg_F0(int dp, int reg)
1105
{
1106
    if (dp)
1107
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1108
    else
1109
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1110
}
1111

    
1112
#define ARM_CP_RW_BIT        (1 << 20)
1113

    
1114
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1115
{
1116
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1117
}
1118

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

    
1124
static inline TCGv iwmmxt_load_creg(int reg)
1125
{
1126
    TCGv var = new_tmp();
1127
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1128
    return var;
1129
}
1130

    
1131
static inline void iwmmxt_store_creg(int reg, TCGv var)
1132
{
1133
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1134
}
1135

    
1136
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1137
{
1138
    iwmmxt_store_reg(cpu_M0, rn);
1139
}
1140

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

    
1146
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1147
{
1148
    iwmmxt_load_reg(cpu_V1, rn);
1149
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1150
}
1151

    
1152
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1153
{
1154
    iwmmxt_load_reg(cpu_V1, rn);
1155
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1156
}
1157

    
1158
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1159
{
1160
    iwmmxt_load_reg(cpu_V1, rn);
1161
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1162
}
1163

    
1164
#define IWMMXT_OP(name) \
1165
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1166
{ \
1167
    iwmmxt_load_reg(cpu_V1, rn); \
1168
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1169
}
1170

    
1171
#define IWMMXT_OP_ENV(name) \
1172
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1173
{ \
1174
    iwmmxt_load_reg(cpu_V1, rn); \
1175
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1176
}
1177

    
1178
#define IWMMXT_OP_ENV_SIZE(name) \
1179
IWMMXT_OP_ENV(name##b) \
1180
IWMMXT_OP_ENV(name##w) \
1181
IWMMXT_OP_ENV(name##l)
1182

    
1183
#define IWMMXT_OP_ENV1(name) \
1184
static inline void gen_op_iwmmxt_##name##_M0(void) \
1185
{ \
1186
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1187
}
1188

    
1189
IWMMXT_OP(maddsq)
1190
IWMMXT_OP(madduq)
1191
IWMMXT_OP(sadb)
1192
IWMMXT_OP(sadw)
1193
IWMMXT_OP(mulslw)
1194
IWMMXT_OP(mulshw)
1195
IWMMXT_OP(mululw)
1196
IWMMXT_OP(muluhw)
1197
IWMMXT_OP(macsw)
1198
IWMMXT_OP(macuw)
1199

    
1200
IWMMXT_OP_ENV_SIZE(unpackl)
1201
IWMMXT_OP_ENV_SIZE(unpackh)
1202

    
1203
IWMMXT_OP_ENV1(unpacklub)
1204
IWMMXT_OP_ENV1(unpackluw)
1205
IWMMXT_OP_ENV1(unpacklul)
1206
IWMMXT_OP_ENV1(unpackhub)
1207
IWMMXT_OP_ENV1(unpackhuw)
1208
IWMMXT_OP_ENV1(unpackhul)
1209
IWMMXT_OP_ENV1(unpacklsb)
1210
IWMMXT_OP_ENV1(unpacklsw)
1211
IWMMXT_OP_ENV1(unpacklsl)
1212
IWMMXT_OP_ENV1(unpackhsb)
1213
IWMMXT_OP_ENV1(unpackhsw)
1214
IWMMXT_OP_ENV1(unpackhsl)
1215

    
1216
IWMMXT_OP_ENV_SIZE(cmpeq)
1217
IWMMXT_OP_ENV_SIZE(cmpgtu)
1218
IWMMXT_OP_ENV_SIZE(cmpgts)
1219

    
1220
IWMMXT_OP_ENV_SIZE(mins)
1221
IWMMXT_OP_ENV_SIZE(minu)
1222
IWMMXT_OP_ENV_SIZE(maxs)
1223
IWMMXT_OP_ENV_SIZE(maxu)
1224

    
1225
IWMMXT_OP_ENV_SIZE(subn)
1226
IWMMXT_OP_ENV_SIZE(addn)
1227
IWMMXT_OP_ENV_SIZE(subu)
1228
IWMMXT_OP_ENV_SIZE(addu)
1229
IWMMXT_OP_ENV_SIZE(subs)
1230
IWMMXT_OP_ENV_SIZE(adds)
1231

    
1232
IWMMXT_OP_ENV(avgb0)
1233
IWMMXT_OP_ENV(avgb1)
1234
IWMMXT_OP_ENV(avgw0)
1235
IWMMXT_OP_ENV(avgw1)
1236

    
1237
IWMMXT_OP(msadb)
1238

    
1239
IWMMXT_OP_ENV(packuw)
1240
IWMMXT_OP_ENV(packul)
1241
IWMMXT_OP_ENV(packuq)
1242
IWMMXT_OP_ENV(packsw)
1243
IWMMXT_OP_ENV(packsl)
1244
IWMMXT_OP_ENV(packsq)
1245

    
1246
static void gen_op_iwmmxt_set_mup(void)
1247
{
1248
    TCGv tmp;
1249
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1250
    tcg_gen_ori_i32(tmp, tmp, 2);
1251
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1252
}
1253

    
1254
static void gen_op_iwmmxt_set_cup(void)
1255
{
1256
    TCGv tmp;
1257
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1258
    tcg_gen_ori_i32(tmp, tmp, 1);
1259
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1260
}
1261

    
1262
static void gen_op_iwmmxt_setpsr_nz(void)
1263
{
1264
    TCGv tmp = new_tmp();
1265
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1266
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1267
}
1268

    
1269
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1270
{
1271
    iwmmxt_load_reg(cpu_V1, rn);
1272
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1273
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1274
}
1275

    
1276
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1277
{
1278
    int rd;
1279
    uint32_t offset;
1280
    TCGv tmp;
1281

    
1282
    rd = (insn >> 16) & 0xf;
1283
    tmp = load_reg(s, rd);
1284

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

    
1310
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1311
{
1312
    int rd = (insn >> 0) & 0xf;
1313
    TCGv tmp;
1314

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

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

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

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

    
1421
    if ((insn & 0x0f000000) != 0x0e000000)
1422
        return 1;
1423

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

    
2332
    return 0;
2333
}
2334

    
2335
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2336
   (ie. an undefined instruction).  */
2337
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2338
{
2339
    int acc, rd0, rd1, rdhi, rdlo;
2340
    TCGv tmp, tmp2;
2341

    
2342
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2343
        /* Multiply with Internal Accumulate Format */
2344
        rd0 = (insn >> 12) & 0xf;
2345
        rd1 = insn & 0xf;
2346
        acc = (insn >> 5) & 7;
2347

    
2348
        if (acc != 0)
2349
            return 1;
2350

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

    
2376
        gen_op_iwmmxt_movq_wRn_M0(acc);
2377
        return 0;
2378
    }
2379

    
2380
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2381
        /* Internal Accumulator Access Format */
2382
        rdhi = (insn >> 16) & 0xf;
2383
        rdlo = (insn >> 12) & 0xf;
2384
        acc = insn & 7;
2385

    
2386
        if (acc != 0)
2387
            return 1;
2388

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

    
2402
    return 1;
2403
}
2404

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

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

    
2438
static int cp15_user_ok(uint32_t insn)
2439
{
2440
    int cpn = (insn >> 16) & 0xf;
2441
    int cpm = insn & 0xf;
2442
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2443

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

    
2458
static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd)
2459
{
2460
    TCGv tmp;
2461
    int cpn = (insn >> 16) & 0xf;
2462
    int cpm = insn & 0xf;
2463
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2464

    
2465
    if (!arm_feature(env, ARM_FEATURE_V6K))
2466
        return 0;
2467

    
2468
    if (!(cpn == 13 && cpm == 0))
2469
        return 0;
2470

    
2471
    if (insn & ARM_CP_RW_BIT) {
2472
        switch (op) {
2473
        case 2:
2474
            tmp = load_cpu_field(cp15.c13_tls1);
2475
            break;
2476
        case 3:
2477
            tmp = load_cpu_field(cp15.c13_tls2);
2478
            break;
2479
        case 4:
2480
            tmp = load_cpu_field(cp15.c13_tls3);
2481
            break;
2482
        default:
2483
            return 0;
2484
        }
2485
        store_reg(s, rd, tmp);
2486

    
2487
    } else {
2488
        tmp = load_reg(s, rd);
2489
        switch (op) {
2490
        case 2:
2491
            store_cpu_field(tmp, cp15.c13_tls1);
2492
            break;
2493
        case 3:
2494
            store_cpu_field(tmp, cp15.c13_tls2);
2495
            break;
2496
        case 4:
2497
            store_cpu_field(tmp, cp15.c13_tls3);
2498
            break;
2499
        default:
2500
            dead_tmp(tmp);
2501
            return 0;
2502
        }
2503
    }
2504
    return 1;
2505
}
2506

    
2507
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2508
   instruction is not defined.  */
2509
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2510
{
2511
    uint32_t rd;
2512
    TCGv tmp, tmp2;
2513

    
2514
    /* M profile cores use memory mapped registers instead of cp15.  */
2515
    if (arm_feature(env, ARM_FEATURE_M))
2516
        return 1;
2517

    
2518
    if ((insn & (1 << 25)) == 0) {
2519
        if (insn & (1 << 20)) {
2520
            /* mrrc */
2521
            return 1;
2522
        }
2523
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2524
        return 0;
2525
    }
2526
    if ((insn & (1 << 4)) == 0) {
2527
        /* cdp */
2528
        return 1;
2529
    }
2530
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2531
        return 1;
2532
    }
2533
    if ((insn & 0x0fff0fff) == 0x0e070f90
2534
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2535
        /* Wait for interrupt.  */
2536
        gen_set_pc_im(s->pc);
2537
        s->is_jmp = DISAS_WFI;
2538
        return 0;
2539
    }
2540
    rd = (insn >> 12) & 0xf;
2541

    
2542
    if (cp15_tls_load_store(env, s, insn, rd))
2543
        return 0;
2544

    
2545
    tmp2 = tcg_const_i32(insn);
2546
    if (insn & ARM_CP_RW_BIT) {
2547
        tmp = new_tmp();
2548
        gen_helper_get_cp15(tmp, cpu_env, tmp2);
2549
        /* If the destination register is r15 then sets condition codes.  */
2550
        if (rd != 15)
2551
            store_reg(s, rd, tmp);
2552
        else
2553
            dead_tmp(tmp);
2554
    } else {
2555
        tmp = load_reg(s, rd);
2556
        gen_helper_set_cp15(cpu_env, tmp2, tmp);
2557
        dead_tmp(tmp);
2558
        /* Normally we would always end the TB here, but Linux
2559
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2560
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2561
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2562
                (insn & 0x0fff0fff) != 0x0e010f10)
2563
            gen_lookup_tb(s);
2564
    }
2565
    tcg_temp_free_i32(tmp2);
2566
    return 0;
2567
}
2568

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

    
2582
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2583
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2584
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2585
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2586
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2587
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2588

    
2589
/* Move between integer and VFP cores.  */
2590
static TCGv gen_vfp_mrs(void)
2591
{
2592
    TCGv tmp = new_tmp();
2593
    tcg_gen_mov_i32(tmp, cpu_F0s);
2594
    return tmp;
2595
}
2596

    
2597
static void gen_vfp_msr(TCGv tmp)
2598
{
2599
    tcg_gen_mov_i32(cpu_F0s, tmp);
2600
    dead_tmp(tmp);
2601
}
2602

    
2603
static inline int
2604
vfp_enabled(CPUState * env)
2605
{
2606
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2607
}
2608

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

    
2622
static void gen_neon_dup_low16(TCGv var)
2623
{
2624
    TCGv tmp = new_tmp();
2625
    tcg_gen_ext16u_i32(var, var);
2626
    tcg_gen_shli_i32(tmp, var, 16);
2627
    tcg_gen_or_i32(var, var, tmp);
2628
    dead_tmp(tmp);
2629
}
2630

    
2631
static void gen_neon_dup_high16(TCGv var)
2632
{
2633
    TCGv tmp = new_tmp();
2634
    tcg_gen_andi_i32(var, var, 0xffff0000);
2635
    tcg_gen_shri_i32(tmp, var, 16);
2636
    tcg_gen_or_i32(var, var, tmp);
2637
    dead_tmp(tmp);
2638
}
2639

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

    
2650
    if (!arm_feature(env, ARM_FEATURE_VFP))
2651
        return 1;
2652

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

    
2672
                VFP_DREG_N(rn, insn);
2673
                if (insn & 0xf)
2674
                    return 1;
2675
                if (insn & 0x00c00060
2676
                    && !arm_feature(env, ARM_FEATURE_NEON))
2677
                    return 1;
2678

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

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

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

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

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

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

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

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

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

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

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

    
3017
                    n = (insn << 12) & 0x80000000;
3018
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3019
                    if (dp) {
3020
                        if (i & 0x40)
3021
                            i |= 0x3f80;
3022
                        else
3023
                            i |= 0x4000;
3024
                        n |= i << 16;
3025
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3026
                    } else {
3027
                        if (i & 0x40)
3028
                            i |= 0x780;
3029
                        else
3030
                            i |= 0x800;
3031
                        n |= i << 19;
3032
                        tcg_gen_movi_i32(cpu_F0s, n);
3033
                    }
3034
                    break;
3035
                case 15: /* extension space */
3036
                    switch (rn) {
3037
                    case 0: /* cpy */
3038
                        /* no-op */
3039
                        break;
3040
                    case 1: /* abs */
3041
                        gen_vfp_abs(dp);
3042
                        break;
3043
                    case 2: /* neg */
3044
                        gen_vfp_neg(dp);
3045
                        break;
3046
                    case 3: /* sqrt */
3047
                        gen_vfp_sqrt(dp);
3048
                        break;
3049
                    case 4: /* vcvtb.f32.f16 */
3050
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3051
                          return 1;
3052
                        tmp = gen_vfp_mrs();
3053
                        tcg_gen_ext16u_i32(tmp, tmp);
3054
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3055
                        dead_tmp(tmp);
3056
                        break;
3057
                    case 5: /* vcvtt.f32.f16 */
3058
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3059
                          return 1;
3060
                        tmp = gen_vfp_mrs();
3061
                        tcg_gen_shri_i32(tmp, tmp, 16);
3062
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3063
                        dead_tmp(tmp);
3064
                        break;
3065
                    case 6: /* vcvtb.f16.f32 */
3066
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3067
                          return 1;
3068
                        tmp = new_tmp();
3069
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3070
                        gen_mov_F0_vreg(0, rd);
3071
                        tmp2 = gen_vfp_mrs();
3072
                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3073
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3074
                        dead_tmp(tmp2);
3075
                        gen_vfp_msr(tmp);
3076
                        break;
3077
                    case 7: /* vcvtt.f16.f32 */
3078
                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
3079
                          return 1;
3080
                        tmp = new_tmp();
3081
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3082
                        tcg_gen_shli_i32(tmp, tmp, 16);
3083
                        gen_mov_F0_vreg(0, rd);
3084
                        tmp2 = gen_vfp_mrs();
3085
                        tcg_gen_ext16u_i32(tmp2, tmp2);
3086
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3087
                        dead_tmp(tmp2);
3088
                        gen_vfp_msr(tmp);
3089
                        break;
3090
                    case 8: /* cmp */
3091
                        gen_vfp_cmp(dp);
3092
                        break;
3093
                    case 9: /* cmpe */
3094
                        gen_vfp_cmpe(dp);
3095
                        break;
3096
                    case 10: /* cmpz */
3097
                        gen_vfp_cmp(dp);
3098
                        break;
3099
                    case 11: /* cmpez */
3100
                        gen_vfp_F1_ld0(dp);
3101
                        gen_vfp_cmpe(dp);
3102
                        break;
3103
                    case 15: /* single<->double conversion */
3104
                        if (dp)
3105
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3106
                        else
3107
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3108
                        break;
3109
                    case 16: /* fuito */
3110
                        gen_vfp_uito(dp);
3111
                        break;
3112
                    case 17: /* fsito */
3113
                        gen_vfp_sito(dp);
3114
                        break;
3115
                    case 20: /* fshto */
3116
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3117
                          return 1;
3118
                        gen_vfp_shto(dp, 16 - rm);
3119
                        break;
3120
                    case 21: /* fslto */
3121
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3122
                          return 1;
3123
                        gen_vfp_slto(dp, 32 - rm);
3124
                        break;
3125
                    case 22: /* fuhto */
3126
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3127
                          return 1;
3128
                        gen_vfp_uhto(dp, 16 - rm);
3129
                        break;
3130
                    case 23: /* fulto */
3131
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3132
                          return 1;
3133
                        gen_vfp_ulto(dp, 32 - rm);
3134
                        break;
3135
                    case 24: /* ftoui */
3136
                        gen_vfp_toui(dp);
3137
                        break;
3138
                    case 25: /* ftouiz */
3139
                        gen_vfp_touiz(dp);
3140
                        break;
3141
                    case 26: /* ftosi */
3142
                        gen_vfp_tosi(dp);
3143
                        break;
3144
                    case 27: /* ftosiz */
3145
                        gen_vfp_tosiz(dp);
3146
                        break;
3147
                    case 28: /* ftosh */
3148
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3149
                          return 1;
3150
                        gen_vfp_tosh(dp, 16 - rm);
3151
                        break;
3152
                    case 29: /* ftosl */
3153
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3154
                          return 1;
3155
                        gen_vfp_tosl(dp, 32 - rm);
3156
                        break;
3157
                    case 30: /* ftouh */
3158
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3159
                          return 1;
3160
                        gen_vfp_touh(dp, 16 - rm);
3161
                        break;
3162
                    case 31: /* ftoul */
3163
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3164
                          return 1;
3165
                        gen_vfp_toul(dp, 32 - rm);
3166
                        break;
3167
                    default: /* undefined */
3168
                        printf ("rn:%d\n", rn);
3169
                        return 1;
3170
                    }
3171
                    break;
3172
                default: /* undefined */
3173
                    printf ("op:%d\n", op);
3174
                    return 1;
3175
                }
3176

    
3177
                /* Write back the result.  */
3178
                if (op == 15 && (rn >= 8 && rn <= 11))
3179
                    ; /* Comparison, do nothing.  */
3180
                else if (op == 15 && rn > 17)
3181
                    /* Integer result.  */
3182
                    gen_mov_vreg_F0(0, rd);
3183
                else if (op == 15 && rn == 15)
3184
                    /* conversion */
3185
                    gen_mov_vreg_F0(!dp, rd);
3186
                else
3187
                    gen_mov_vreg_F0(dp, rd);
3188

    
3189
                /* break out of the loop if we have finished  */
3190
                if (veclen == 0)
3191
                    break;
3192

    
3193
                if (op == 15 && delta_m == 0) {
3194
                    /* single source one-many */
3195
                    while (veclen--) {
3196
                        rd = ((rd + delta_d) & (bank_mask - 1))
3197
                             | (rd & bank_mask);
3198
                        gen_mov_vreg_F0(dp, rd);
3199
                    }
3200
                    break;
3201
                }
3202
                /* Setup the next operands.  */
3203
                veclen--;
3204
                rd = ((rd + delta_d) & (bank_mask - 1))
3205
                     | (rd & bank_mask);
3206

    
3207
                if (op == 15) {
3208
                    /* One source operand.  */
3209
                    rm = ((rm + delta_m) & (bank_mask - 1))
3210
                         | (rm & bank_mask);
3211
                    gen_mov_F0_vreg(dp, rm);
3212
                } else {
3213
                    /* Two source operands.  */
3214
                    rn = ((rn + delta_d) & (bank_mask - 1))
3215
                         | (rn & bank_mask);
3216
                    gen_mov_F0_vreg(dp, rn);
3217
                    if (delta_m) {
3218
                        rm = ((rm + delta_m) & (bank_mask - 1))
3219
                             | (rm & bank_mask);
3220
                        gen_mov_F1_vreg(dp, rm);
3221
                    }
3222
                }
3223
            }
3224
        }
3225
        break;
3226
    case 0xc:
3227
    case 0xd:
3228
        if (dp && (insn & 0x03e00000) == 0x00400000) {
3229
            /* two-register transfer */
3230
            rn = (insn >> 16) & 0xf;
3231
            rd = (insn >> 12) & 0xf;
3232
            if (dp) {
3233
                VFP_DREG_M(rm, insn);
3234
            } else {
3235
                rm = VFP_SREG_M(insn);
3236
            }
3237

    
3238
            if (insn & ARM_CP_RW_BIT) {
3239
                /* vfp->arm */
3240
                if (dp) {
3241
                    gen_mov_F0_vreg(0, rm * 2);
3242
                    tmp = gen_vfp_mrs();
3243
                    store_reg(s, rd, tmp);
3244
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3245
                    tmp = gen_vfp_mrs();
3246
                    store_reg(s, rn, tmp);
3247
                } else {
3248
                    gen_mov_F0_vreg(0, rm);
3249
                    tmp = gen_vfp_mrs();
3250
                    store_reg(s, rn, tmp);
3251
                    gen_mov_F0_vreg(0, rm + 1);
3252
                    tmp = gen_vfp_mrs();
3253
                    store_reg(s, rd, tmp);
3254
                }
3255
            } else {
3256
                /* arm->vfp */
3257
                if (dp) {
3258
                    tmp = load_reg(s, rd);
3259
                    gen_vfp_msr(tmp);
3260
                    gen_mov_vreg_F0(0, rm * 2);
3261
                    tmp = load_reg(s, rn);
3262
                    gen_vfp_msr(tmp);
3263
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3264
                } else {
3265
                    tmp = load_reg(s, rn);
3266
                    gen_vfp_msr(tmp);
3267
                    gen_mov_vreg_F0(0, rm);
3268
                    tmp = load_reg(s, rd);
3269
                    gen_vfp_msr(tmp);
3270
                    gen_mov_vreg_F0(0, rm + 1);
3271
                }
3272
            }
3273
        } else {
3274
            /* Load/store */
3275
            rn = (insn >> 16) & 0xf;
3276
            if (dp)
3277
                VFP_DREG_D(rd, insn);
3278
            else
3279
                rd = VFP_SREG_D(insn);
3280
            if (s->thumb && rn == 15) {
3281
                addr = new_tmp();
3282
                tcg_gen_movi_i32(addr, s->pc & ~2);
3283
            } else {
3284
                addr = load_reg(s, rn);
3285
            }
3286
            if ((insn & 0x01200000) == 0x01000000) {
3287
                /* Single load/store */
3288
                offset = (insn & 0xff) << 2;
3289
                if ((insn & (1 << 23)) == 0)
3290
                    offset = -offset;
3291
                tcg_gen_addi_i32(addr, addr, offset);
3292
                if (insn & (1 << 20)) {
3293
                    gen_vfp_ld(s, dp, addr);
3294
                    gen_mov_vreg_F0(dp, rd);
3295
                } else {
3296
                    gen_mov_F0_vreg(dp, rd);
3297
                    gen_vfp_st(s, dp, addr);
3298
                }
3299
                dead_tmp(addr);
3300
            } else {
3301
                /* load/store multiple */
3302
                if (dp)
3303
                    n = (insn >> 1) & 0x7f;
3304
                else
3305
                    n = insn & 0xff;
3306

    
3307
                if (insn & (1 << 24)) /* pre-decrement */
3308
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3309

    
3310
                if (dp)
3311
                    offset = 8;
3312
                else
3313
                    offset = 4;
3314
                for (i = 0; i < n; i++) {
3315
                    if (insn & ARM_CP_RW_BIT) {
3316
                        /* load */
3317
                        gen_vfp_ld(s, dp, addr);
3318
                        gen_mov_vreg_F0(dp, rd + i);
3319
                    } else {
3320
                        /* store */
3321
                        gen_mov_F0_vreg(dp, rd + i);
3322
                        gen_vfp_st(s, dp, addr);
3323
                    }
3324
                    tcg_gen_addi_i32(addr, addr, offset);
3325
                }
3326
                if (insn & (1 << 21)) {
3327
                    /* writeback */
3328
                    if (insn & (1 << 24))
3329
                        offset = -offset * n;
3330
                    else if (dp && (insn & 1))
3331
                        offset = 4;
3332
                    else
3333
                        offset = 0;
3334

    
3335
                    if (offset != 0)
3336
                        tcg_gen_addi_i32(addr, addr, offset);
3337
                    store_reg(s, rn, addr);
3338
                } else {
3339
                    dead_tmp(addr);
3340
                }
3341
            }
3342
        }
3343
        break;
3344
    default:
3345
        /* Should never happen.  */
3346
        return 1;
3347
    }
3348
    return 0;
3349
}
3350

    
3351
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3352
{
3353
    TranslationBlock *tb;
3354

    
3355
    tb = s->tb;
3356
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3357
        tcg_gen_goto_tb(n);
3358
        gen_set_pc_im(dest);
3359
        tcg_gen_exit_tb((long)tb + n);
3360
    } else {
3361
        gen_set_pc_im(dest);
3362
        tcg_gen_exit_tb(0);
3363
    }
3364
}
3365

    
3366
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3367
{
3368
    if (unlikely(s->singlestep_enabled)) {
3369
        /* An indirect jump so that we still trigger the debug exception.  */
3370
        if (s->thumb)
3371
            dest |= 1;
3372
        gen_bx_im(s, dest);
3373
    } else {
3374
        gen_goto_tb(s, 0, dest);
3375
        s->is_jmp = DISAS_TB_JUMP;
3376
    }
3377
}
3378

    
3379
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3380
{
3381
    if (x)
3382
        tcg_gen_sari_i32(t0, t0, 16);
3383
    else
3384
        gen_sxth(t0);
3385
    if (y)
3386
        tcg_gen_sari_i32(t1, t1, 16);
3387
    else
3388
        gen_sxth(t1);
3389
    tcg_gen_mul_i32(t0, t0, t1);
3390
}
3391

    
3392
/* Return the mask of PSR bits set by a MSR instruction.  */
3393
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3394
    uint32_t mask;
3395

    
3396
    mask = 0;
3397
    if (flags & (1 << 0))
3398
        mask |= 0xff;
3399
    if (flags & (1 << 1))
3400
        mask |= 0xff00;
3401
    if (flags & (1 << 2))
3402
        mask |= 0xff0000;
3403
    if (flags & (1 << 3))
3404
        mask |= 0xff000000;
3405

    
3406
    /* Mask out undefined bits.  */
3407
    mask &= ~CPSR_RESERVED;
3408
    if (!arm_feature(env, ARM_FEATURE_V6))
3409
        mask &= ~(CPSR_E | CPSR_GE);
3410
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3411
        mask &= ~CPSR_IT;
3412
    /* Mask out execution state bits.  */
3413
    if (!spsr)
3414
        mask &= ~CPSR_EXEC;
3415
    /* Mask out privileged bits.  */
3416
    if (IS_USER(s))
3417
        mask &= CPSR_USER;
3418
    return mask;
3419
}
3420

    
3421
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3422
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3423
{
3424
    TCGv tmp;
3425
    if (spsr) {
3426
        /* ??? This is also undefined in system mode.  */
3427
        if (IS_USER(s))
3428
            return 1;
3429

    
3430
        tmp = load_cpu_field(spsr);
3431
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3432
        tcg_gen_andi_i32(t0, t0, mask);
3433
        tcg_gen_or_i32(tmp, tmp, t0);
3434
        store_cpu_field(tmp, spsr);
3435
    } else {
3436
        gen_set_cpsr(t0, mask);
3437
    }
3438
    dead_tmp(t0);
3439
    gen_lookup_tb(s);
3440
    return 0;
3441
}
3442

    
3443
/* Returns nonzero if access to the PSR is not permitted.  */
3444
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3445
{
3446
    TCGv tmp;
3447
    tmp = new_tmp();
3448
    tcg_gen_movi_i32(tmp, val);
3449
    return gen_set_psr(s, mask, spsr, tmp);
3450
}
3451

    
3452
/* Generate an old-style exception return. Marks pc as dead. */
3453
static void gen_exception_return(DisasContext *s, TCGv pc)
3454
{
3455
    TCGv tmp;
3456
    store_reg(s, 15, pc);
3457
    tmp = load_cpu_field(spsr);
3458
    gen_set_cpsr(tmp, 0xffffffff);
3459
    dead_tmp(tmp);
3460
    s->is_jmp = DISAS_UPDATE;
3461
}
3462

    
3463
/* Generate a v6 exception return.  Marks both values as dead.  */
3464
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3465
{
3466
    gen_set_cpsr(cpsr, 0xffffffff);
3467
    dead_tmp(cpsr);
3468
    store_reg(s, 15, pc);
3469
    s->is_jmp = DISAS_UPDATE;
3470
}
3471

    
3472
static inline void
3473
gen_set_condexec (DisasContext *s)
3474
{
3475
    if (s->condexec_mask) {
3476
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3477
        TCGv tmp = new_tmp();
3478
        tcg_gen_movi_i32(tmp, val);
3479
        store_cpu_field(tmp, condexec_bits);
3480
    }
3481
}
3482

    
3483
static void gen_nop_hint(DisasContext *s, int val)
3484
{
3485
    switch (val) {
3486
    case 3: /* wfi */
3487
        gen_set_pc_im(s->pc);
3488
        s->is_jmp = DISAS_WFI;
3489
        break;
3490
    case 2: /* wfe */
3491
    case 4: /* sev */
3492
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3493
    default: /* nop */
3494
        break;
3495
    }
3496
}
3497

    
3498
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3499

    
3500
static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3501
{
3502
    switch (size) {
3503
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3504
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3505
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3506
    default: return 1;
3507
    }
3508
    return 0;
3509
}
3510

    
3511
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3512
{
3513
    switch (size) {
3514
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3515
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3516
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3517
    default: return;
3518
    }
3519
}
3520

    
3521
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3522
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3523
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3524
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3525
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3526

    
3527
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3528
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3529
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3530
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3531
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3532

    
3533
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3534
    switch ((size << 1) | u) { \
3535
    case 0: \
3536
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3537
        break; \
3538
    case 1: \
3539
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3540
        break; \
3541
    case 2: \
3542
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3543
        break; \
3544
    case 3: \
3545
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3546
        break; \
3547
    case 4: \
3548
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3549
        break; \
3550
    case 5: \
3551
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3552
        break; \
3553
    default: return 1; \
3554
    }} while (0)
3555

    
3556
#define GEN_NEON_INTEGER_OP(name) do { \
3557
    switch ((size << 1) | u) { \
3558
    case 0: \
3559
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3560
        break; \
3561
    case 1: \
3562
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3563
        break; \
3564
    case 2: \
3565
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3566
        break; \
3567
    case 3: \
3568
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3569
        break; \
3570
    case 4: \
3571
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3572
        break; \
3573
    case 5: \
3574
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3575
        break; \
3576
    default: return 1; \
3577
    }} while (0)
3578

    
3579
static TCGv neon_load_scratch(int scratch)
3580
{
3581
    TCGv tmp = new_tmp();
3582
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3583
    return tmp;
3584
}
3585

    
3586
static void neon_store_scratch(int scratch, TCGv var)
3587
{
3588
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3589
    dead_tmp(var);
3590
}
3591

    
3592
static inline TCGv neon_get_scalar(int size, int reg)
3593
{
3594
    TCGv tmp;
3595
    if (size == 1) {
3596
        tmp = neon_load_reg(reg >> 1, reg & 1);
3597
    } else {
3598
        tmp = neon_load_reg(reg >> 2, (reg >> 1) & 1);
3599
        if (reg & 1) {
3600
            gen_neon_dup_low16(tmp);
3601
        } else {
3602
            gen_neon_dup_high16(tmp);
3603
        }
3604
    }
3605
    return tmp;
3606
}
3607

    
3608
static void gen_neon_unzip_u8(TCGv t0, TCGv t1)
3609
{
3610
    TCGv rd, rm, tmp;
3611

    
3612
    rd = new_tmp();
3613
    rm = new_tmp();
3614
    tmp = new_tmp();
3615

    
3616
    tcg_gen_andi_i32(rd, t0, 0xff);
3617
    tcg_gen_shri_i32(tmp, t0, 8);
3618
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3619
    tcg_gen_or_i32(rd, rd, tmp);
3620
    tcg_gen_shli_i32(tmp, t1, 16);
3621
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3622
    tcg_gen_or_i32(rd, rd, tmp);
3623
    tcg_gen_shli_i32(tmp, t1, 8);
3624
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3625
    tcg_gen_or_i32(rd, rd, tmp);
3626

    
3627
    tcg_gen_shri_i32(rm, t0, 8);
3628
    tcg_gen_andi_i32(rm, rm, 0xff);
3629
    tcg_gen_shri_i32(tmp, t0, 16);
3630
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3631
    tcg_gen_or_i32(rm, rm, tmp);
3632
    tcg_gen_shli_i32(tmp, t1, 8);
3633
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3634
    tcg_gen_or_i32(rm, rm, tmp);
3635
    tcg_gen_andi_i32(tmp, t1, 0xff000000);
3636
    tcg_gen_or_i32(t1, rm, tmp);
3637
    tcg_gen_mov_i32(t0, rd);
3638

    
3639
    dead_tmp(tmp);
3640
    dead_tmp(rm);
3641
    dead_tmp(rd);
3642
}
3643

    
3644
static void gen_neon_zip_u8(TCGv t0, TCGv t1)
3645
{
3646
    TCGv rd, rm, tmp;
3647

    
3648
    rd = new_tmp();
3649
    rm = new_tmp();
3650
    tmp = new_tmp();
3651

    
3652
    tcg_gen_andi_i32(rd, t0, 0xff);
3653
    tcg_gen_shli_i32(tmp, t1, 8);
3654
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3655
    tcg_gen_or_i32(rd, rd, tmp);
3656
    tcg_gen_shli_i32(tmp, t0, 16);
3657
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3658
    tcg_gen_or_i32(rd, rd, tmp);
3659
    tcg_gen_shli_i32(tmp, t1, 24);
3660
    tcg_gen_andi_i32(tmp, tmp, 0xff000000);
3661
    tcg_gen_or_i32(rd, rd, tmp);
3662

    
3663
    tcg_gen_andi_i32(rm, t1, 0xff000000);
3664
    tcg_gen_shri_i32(tmp, t0, 8);
3665
    tcg_gen_andi_i32(tmp, tmp, 0xff0000);
3666
    tcg_gen_or_i32(rm, rm, tmp);
3667
    tcg_gen_shri_i32(tmp, t1, 8);
3668
    tcg_gen_andi_i32(tmp, tmp, 0xff00);
3669
    tcg_gen_or_i32(rm, rm, tmp);
3670
    tcg_gen_shri_i32(tmp, t0, 16);
3671
    tcg_gen_andi_i32(tmp, tmp, 0xff);
3672
    tcg_gen_or_i32(t1, rm, tmp);
3673
    tcg_gen_mov_i32(t0, rd);
3674

    
3675
    dead_tmp(tmp);
3676
    dead_tmp(rm);
3677
    dead_tmp(rd);
3678
}
3679

    
3680
static void gen_neon_zip_u16(TCGv t0, TCGv t1)
3681
{
3682
    TCGv tmp, tmp2;
3683

    
3684
    tmp = new_tmp();
3685
    tmp2 = new_tmp();
3686

    
3687
    tcg_gen_andi_i32(tmp, t0, 0xffff);
3688
    tcg_gen_shli_i32(tmp2, t1, 16);
3689
    tcg_gen_or_i32(tmp, tmp, tmp2);
3690
    tcg_gen_andi_i32(t1, t1, 0xffff0000);
3691
    tcg_gen_shri_i32(tmp2, t0, 16);
3692
    tcg_gen_or_i32(t1, t1, tmp2);
3693
    tcg_gen_mov_i32(t0, tmp);
3694

    
3695
    dead_tmp(tmp2);
3696
    dead_tmp(tmp);
3697
}
3698

    
3699
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3700
{
3701
    int n;
3702
    TCGv t0, t1;
3703

    
3704
    for (n = 0; n < q + 1; n += 2) {
3705
        t0 = neon_load_reg(reg, n);
3706
        t1 = neon_load_reg(reg, n + 1);
3707
        switch (size) {
3708
        case 0: gen_neon_unzip_u8(t0, t1); break;
3709
        case 1: gen_neon_zip_u16(t0, t1); break; /* zip and unzip are the same.  */
3710
        case 2: /* no-op */; break;
3711
        default: abort();
3712
        }
3713
        neon_store_scratch(tmp + n, t0);
3714
        neon_store_scratch(tmp + n + 1, t1);
3715
    }
3716
}
3717

    
3718
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3719
{
3720
    TCGv rd, tmp;
3721

    
3722
    rd = new_tmp();
3723
    tmp = new_tmp();
3724

    
3725
    tcg_gen_shli_i32(rd, t0, 8);
3726
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3727
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3728
    tcg_gen_or_i32(rd, rd, tmp);
3729

    
3730
    tcg_gen_shri_i32(t1, t1, 8);
3731
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3732
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3733
    tcg_gen_or_i32(t1, t1, tmp);
3734
    tcg_gen_mov_i32(t0, rd);
3735

    
3736
    dead_tmp(tmp);
3737
    dead_tmp(rd);
3738
}
3739

    
3740
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3741
{
3742
    TCGv rd, tmp;
3743

    
3744
    rd = new_tmp();
3745
    tmp = new_tmp();
3746

    
3747
    tcg_gen_shli_i32(rd, t0, 16);
3748
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3749
    tcg_gen_or_i32(rd, rd, tmp);
3750
    tcg_gen_shri_i32(t1, t1, 16);
3751
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3752
    tcg_gen_or_i32(t1, t1, tmp);
3753
    tcg_gen_mov_i32(t0, rd);
3754

    
3755
    dead_tmp(tmp);
3756
    dead_tmp(rd);
3757
}
3758

    
3759

    
3760
static struct {
3761
    int nregs;
3762
    int interleave;
3763
    int spacing;
3764
} neon_ls_element_type[11] = {
3765
    {4, 4, 1},
3766
    {4, 4, 2},
3767
    {4, 1, 1},
3768
    {4, 2, 1},
3769
    {3, 3, 1},
3770
    {3, 3, 2},
3771
    {3, 1, 1},
3772
    {1, 1, 1},
3773
    {2, 2, 1},
3774
    {2, 2, 2},
3775
    {2, 1, 1}
3776
};
3777

    
3778
/* Translate a NEON load/store element instruction.  Return nonzero if the
3779
   instruction is invalid.  */
3780
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3781
{
3782
    int rd, rn, rm;
3783
    int op;
3784
    int nregs;
3785
    int interleave;
3786
    int spacing;
3787
    int stride;
3788
    int size;
3789
    int reg;
3790
    int pass;
3791
    int load;
3792
    int shift;
3793
    int n;
3794
    TCGv addr;
3795
    TCGv tmp;
3796
    TCGv tmp2;
3797
    TCGv_i64 tmp64;
3798

    
3799
    if (!vfp_enabled(env))
3800
      return 1;
3801
    VFP_DREG_D(rd, insn);
3802
    rn = (insn >> 16) & 0xf;
3803
    rm = insn & 0xf;
3804
    load = (insn & (1 << 21)) != 0;
3805
    addr = new_tmp();
3806
    if ((insn & (1 << 23)) == 0) {
3807
        /* Load store all elements.  */
3808
        op = (insn >> 8) & 0xf;
3809
        size = (insn >> 6) & 3;
3810
        if (op > 10)
3811
            return 1;
3812
        nregs = neon_ls_element_type[op].nregs;
3813
        interleave = neon_ls_element_type[op].interleave;
3814
        spacing = neon_ls_element_type[op].spacing;
3815
        if (size == 3 && (interleave | spacing) != 1)
3816
            return 1;
3817
        load_reg_var(s, addr, rn);
3818
        stride = (1 << size) * interleave;
3819
        for (reg = 0; reg < nregs; reg++) {
3820
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3821
                load_reg_var(s, addr, rn);
3822
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3823
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3824
                load_reg_var(s, addr, rn);
3825
                tcg_gen_addi_i32(addr, addr, 1 << size);
3826
            }
3827
            if (size == 3) {
3828
                if (load) {
3829
                    tmp64 = gen_ld64(addr, IS_USER(s));
3830
                    neon_store_reg64(tmp64, rd);
3831
                    tcg_temp_free_i64(tmp64);
3832
                } else {
3833
                    tmp64 = tcg_temp_new_i64();
3834
                    neon_load_reg64(tmp64, rd);
3835
                    gen_st64(tmp64, addr, IS_USER(s));
3836
                }
3837
                tcg_gen_addi_i32(addr, addr, stride);
3838
            } else {
3839
                for (pass = 0; pass < 2; pass++) {
3840
                    if (size == 2) {
3841
                        if (load) {
3842
                            tmp = gen_ld32(addr, IS_USER(s));
3843
                            neon_store_reg(rd, pass, tmp);
3844
                        } else {
3845
                            tmp = neon_load_reg(rd, pass);
3846
                            gen_st32(tmp, addr, IS_USER(s));
3847
                        }
3848
                        tcg_gen_addi_i32(addr, addr, stride);
3849
                    } else if (size == 1) {
3850
                        if (load) {
3851
                            tmp = gen_ld16u(addr, IS_USER(s));
3852
                            tcg_gen_addi_i32(addr, addr, stride);
3853
                            tmp2 = gen_ld16u(addr, IS_USER(s));
3854
                            tcg_gen_addi_i32(addr, addr, stride);
3855
                            gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3856
                            dead_tmp(tmp2);
3857
                            neon_store_reg(rd, pass, tmp);
3858
                        } else {
3859
                            tmp = neon_load_reg(rd, pass);
3860
                            tmp2 = new_tmp();
3861
                            tcg_gen_shri_i32(tmp2, tmp, 16);
3862
                            gen_st16(tmp, addr, IS_USER(s));
3863
                            tcg_gen_addi_i32(addr, addr, stride);
3864
                            gen_st16(tmp2, addr, IS_USER(s));
3865
                            tcg_gen_addi_i32(addr, addr, stride);
3866
                        }
3867
                    } else /* size == 0 */ {
3868
                        if (load) {
3869
                            TCGV_UNUSED(tmp2);
3870
                            for (n = 0; n < 4; n++) {
3871
                                tmp = gen_ld8u(addr, IS_USER(s));
3872
                                tcg_gen_addi_i32(addr, addr, stride);
3873
                                if (n == 0) {
3874
                                    tmp2 = tmp;
3875
                                } else {
3876
                                    gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3877
                                    dead_tmp(tmp);
3878
                                }
3879
                            }
3880
                            neon_store_reg(rd, pass, tmp2);
3881
                        } else {
3882
                            tmp2 = neon_load_reg(rd, pass);
3883
                            for (n = 0; n < 4; n++) {
3884
                                tmp = new_tmp();
3885
                                if (n == 0) {
3886
                                    tcg_gen_mov_i32(tmp, tmp2);
3887
                                } else {
3888
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
3889
                                }
3890
                                gen_st8(tmp, addr, IS_USER(s));
3891
                                tcg_gen_addi_i32(addr, addr, stride);
3892
                            }
3893
                            dead_tmp(tmp2);
3894
                        }
3895
                    }
3896
                }
3897
            }
3898
            rd += spacing;
3899
        }
3900
        stride = nregs * 8;
3901
    } else {
3902
        size = (insn >> 10) & 3;
3903
        if (size == 3) {
3904
            /* Load single element to all lanes.  */
3905
            if (!load)
3906
                return 1;
3907
            size = (insn >> 6) & 3;
3908
            nregs = ((insn >> 8) & 3) + 1;
3909
            stride = (insn & (1 << 5)) ? 2 : 1;
3910
            load_reg_var(s, addr, rn);
3911
            for (reg = 0; reg < nregs; reg++) {
3912
                switch (size) {
3913
                case 0:
3914
                    tmp = gen_ld8u(addr, IS_USER(s));
3915
                    gen_neon_dup_u8(tmp, 0);
3916
                    break;
3917
                case 1:
3918
                    tmp = gen_ld16u(addr, IS_USER(s));
3919
                    gen_neon_dup_low16(tmp);
3920
                    break;
3921
                case 2:
3922
                    tmp = gen_ld32(addr, IS_USER(s));
3923
                    break;
3924
                case 3:
3925
                    return 1;
3926
                default: /* Avoid compiler warnings.  */
3927
                    abort();
3928
                }
3929
                tcg_gen_addi_i32(addr, addr, 1 << size);
3930
                tmp2 = new_tmp();
3931
                tcg_gen_mov_i32(tmp2, tmp);
3932
                neon_store_reg(rd, 0, tmp2);
3933
                neon_store_reg(rd, 1, tmp);
3934
                rd += stride;
3935
            }
3936
            stride = (1 << size) * nregs;
3937
        } else {
3938
            /* Single element.  */
3939
            pass = (insn >> 7) & 1;
3940
            switch (size) {
3941
            case 0:
3942
                shift = ((insn >> 5) & 3) * 8;
3943
                stride = 1;
3944
                break;
3945
            case 1:
3946
                shift = ((insn >> 6) & 1) * 16;
3947
                stride = (insn & (1 << 5)) ? 2 : 1;
3948
                break;
3949
            case 2:
3950
                shift = 0;
3951
                stride = (insn & (1 << 6)) ? 2 : 1;
3952
                break;
3953
            default:
3954
                abort();
3955
            }
3956
            nregs = ((insn >> 8) & 3) + 1;
3957
            load_reg_var(s, addr, rn);
3958
            for (reg = 0; reg < nregs; reg++) {
3959
                if (load) {
3960
                    switch (size) {
3961
                    case 0:
3962
                        tmp = gen_ld8u(addr, IS_USER(s));
3963
                        break;
3964
                    case 1:
3965
                        tmp = gen_ld16u(addr, IS_USER(s));
3966
                        break;
3967
                    case 2:
3968
                        tmp = gen_ld32(addr, IS_USER(s));
3969
                        break;
3970
                    default: /* Avoid compiler warnings.  */
3971
                        abort();
3972
                    }
3973
                    if (size != 2) {
3974
                        tmp2 = neon_load_reg(rd, pass);
3975
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3976
                        dead_tmp(tmp2);
3977
                    }
3978
                    neon_store_reg(rd, pass, tmp);
3979
                } else { /* Store */
3980
                    tmp = neon_load_reg(rd, pass);
3981
                    if (shift)
3982
                        tcg_gen_shri_i32(tmp, tmp, shift);
3983
                    switch (size) {
3984
                    case 0:
3985
                        gen_st8(tmp, addr, IS_USER(s));
3986
                        break;
3987
                    case 1:
3988
                        gen_st16(tmp, addr, IS_USER(s));
3989
                        break;
3990
                    case 2:
3991
                        gen_st32(tmp, addr, IS_USER(s));
3992
                        break;
3993
                    }
3994
                }
3995
                rd += stride;
3996
                tcg_gen_addi_i32(addr, addr, 1 << size);
3997
            }
3998
            stride = nregs * (1 << size);
3999
        }
4000
    }
4001
    dead_tmp(addr);
4002
    if (rm != 15) {
4003
        TCGv base;
4004

    
4005
        base = load_reg(s, rn);
4006
        if (rm == 13) {
4007
            tcg_gen_addi_i32(base, base, stride);
4008
        } else {
4009
            TCGv index;
4010
            index = load_reg(s, rm);
4011
            tcg_gen_add_i32(base, base, index);
4012
            dead_tmp(index);
4013
        }
4014
        store_reg(s, rn, base);
4015
    }
4016
    return 0;
4017
}
4018

    
4019
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4020
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4021
{
4022
    tcg_gen_and_i32(t, t, c);
4023
    tcg_gen_andc_i32(f, f, c);
4024
    tcg_gen_or_i32(dest, t, f);
4025
}
4026

    
4027
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4028
{
4029
    switch (size) {
4030
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4031
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4032
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4033
    default: abort();
4034
    }
4035
}
4036

    
4037
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4038
{
4039
    switch (size) {
4040
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4041
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4042
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4043
    default: abort();
4044
    }
4045
}
4046

    
4047
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4048
{
4049
    switch (size) {
4050
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4051
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4052
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4053
    default: abort();
4054
    }
4055
}
4056

    
4057
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4058
                                         int q, int u)
4059
{
4060
    if (q) {
4061
        if (u) {
4062
            switch (size) {
4063
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4064
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4065
            default: abort();
4066
            }
4067
        } else {
4068
            switch (size) {
4069
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4070
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4071
            default: abort();
4072
            }
4073
        }
4074
    } else {
4075
        if (u) {
4076
            switch (size) {
4077
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4078
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4079
            default: abort();
4080
            }
4081
        } else {
4082
            switch (size) {
4083
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4084
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4085
            default: abort();
4086
            }
4087
        }
4088
    }
4089
}
4090

    
4091
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4092
{
4093
    if (u) {
4094
        switch (size) {
4095
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4096
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4097
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4098
        default: abort();
4099
        }
4100
    } else {
4101
        switch (size) {
4102
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4103
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4104
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4105
        default: abort();
4106
        }
4107
    }
4108
    dead_tmp(src);
4109
}
4110

    
4111
static inline void gen_neon_addl(int size)
4112
{
4113
    switch (size) {
4114
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4115
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4116
    case 2: tcg_gen_add_i64(CPU_V001); break;
4117
    default: abort();
4118
    }
4119
}
4120

    
4121
static inline void gen_neon_subl(int size)
4122
{
4123
    switch (size) {
4124
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4125
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4126
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4127
    default: abort();
4128
    }
4129
}
4130

    
4131
static inline void gen_neon_negl(TCGv_i64 var, int size)
4132
{
4133
    switch (size) {
4134
    case 0: gen_helper_neon_negl_u16(var, var); break;
4135
    case 1: gen_helper_neon_negl_u32(var, var); break;
4136
    case 2: gen_helper_neon_negl_u64(var, var); break;
4137
    default: abort();
4138
    }
4139
}
4140

    
4141
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4142
{
4143
    switch (size) {
4144
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4145
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4146
    default: abort();
4147
    }
4148
}
4149

    
4150
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4151
{
4152
    TCGv_i64 tmp;
4153

    
4154
    switch ((size << 1) | u) {
4155
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4156
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4157
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4158
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4159
    case 4:
4160
        tmp = gen_muls_i64_i32(a, b);
4161
        tcg_gen_mov_i64(dest, tmp);
4162
        break;
4163
    case 5:
4164
        tmp = gen_mulu_i64_i32(a, b);
4165
        tcg_gen_mov_i64(dest, tmp);
4166
        break;
4167
    default: abort();
4168
    }
4169
}
4170

    
4171
/* Translate a NEON data processing instruction.  Return nonzero if the
4172
   instruction is invalid.
4173
   We process data in a mixture of 32-bit and 64-bit chunks.
4174
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4175

    
4176
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4177
{
4178
    int op;
4179
    int q;
4180
    int rd, rn, rm;
4181
    int size;
4182
    int shift;
4183
    int pass;
4184
    int count;
4185
    int pairwise;
4186
    int u;
4187
    int n;
4188
    uint32_t imm, mask;
4189
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4190
    TCGv_i64 tmp64;
4191

    
4192
    if (!vfp_enabled(env))
4193
      return 1;
4194
    q = (insn & (1 << 6)) != 0;
4195
    u = (insn >> 24) & 1;
4196
    VFP_DREG_D(rd, insn);
4197
    VFP_DREG_N(rn, insn);
4198
    VFP_DREG_M(rm, insn);
4199
    size = (insn >> 20) & 3;
4200
    if ((insn & (1 << 23)) == 0) {
4201
        /* Three register same length.  */
4202
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4203
        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4204
                          || op == 10 || op  == 11 || op == 16)) {
4205
            /* 64-bit element instructions.  */
4206
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4207
                neon_load_reg64(cpu_V0, rn + pass);
4208
                neon_load_reg64(cpu_V1, rm + pass);
4209
                switch (op) {
4210
                case 1: /* VQADD */
4211
                    if (u) {
4212
                        gen_helper_neon_add_saturate_u64(CPU_V001);
4213
                    } else {
4214
                        gen_helper_neon_add_saturate_s64(CPU_V001);
4215
                    }
4216
                    break;
4217
                case 5: /* VQSUB */
4218
                    if (u) {
4219
                        gen_helper_neon_sub_saturate_u64(CPU_V001);
4220
                    } else {
4221
                        gen_helper_neon_sub_saturate_s64(CPU_V001);
4222
                    }
4223
                    break;
4224
                case 8: /* VSHL */
4225
                    if (u) {
4226
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4227
                    } else {
4228
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4229
                    }
4230
                    break;
4231
                case 9: /* VQSHL */
4232
                    if (u) {
4233
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4234
                                                 cpu_V0, cpu_V0);
4235
                    } else {
4236
                        gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4237
                                                 cpu_V1, cpu_V0);
4238
                    }
4239
                    break;
4240
                case 10: /* VRSHL */
4241
                    if (u) {
4242
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4243
                    } else {
4244
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4245
                    }
4246
                    break;
4247
                case 11: /* VQRSHL */
4248
                    if (u) {
4249
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4250
                                                  cpu_V1, cpu_V0);
4251
                    } else {
4252
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4253
                                                  cpu_V1, cpu_V0);
4254
                    }
4255
                    break;
4256
                case 16:
4257
                    if (u) {
4258
                        tcg_gen_sub_i64(CPU_V001);
4259
                    } else {
4260
                        tcg_gen_add_i64(CPU_V001);
4261
                    }
4262
                    break;
4263
                default:
4264
                    abort();
4265
                }
4266
                neon_store_reg64(cpu_V0, rd + pass);
4267
            }
4268
            return 0;
4269
        }
4270
        switch (op) {
4271
        case 8: /* VSHL */
4272
        case 9: /* VQSHL */
4273
        case 10: /* VRSHL */
4274
        case 11: /* VQRSHL */
4275
            {
4276
                int rtmp;
4277
                /* Shift instruction operands are reversed.  */
4278
                rtmp = rn;
4279
                rn = rm;
4280
                rm = rtmp;
4281
                pairwise = 0;
4282
            }
4283
            break;
4284
        case 20: /* VPMAX */
4285
        case 21: /* VPMIN */
4286
        case 23: /* VPADD */
4287
            pairwise = 1;
4288
            break;
4289
        case 26: /* VPADD (float) */
4290
            pairwise = (u && size < 2);
4291
            break;
4292
        case 30: /* VPMIN/VPMAX (float) */
4293
            pairwise = u;
4294
            break;
4295
        default:
4296
            pairwise = 0;
4297
            break;
4298
        }
4299

    
4300
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4301

    
4302
        if (pairwise) {
4303
            /* Pairwise.  */
4304
            if (q)
4305
                n = (pass & 1) * 2;
4306
            else
4307
                n = 0;
4308
            if (pass < q + 1) {
4309
                tmp = neon_load_reg(rn, n);
4310
                tmp2 = neon_load_reg(rn, n + 1);
4311
            } else {
4312
                tmp = neon_load_reg(rm, n);
4313
                tmp2 = neon_load_reg(rm, n + 1);
4314
            }
4315
        } else {
4316
            /* Elementwise.  */
4317
            tmp = neon_load_reg(rn, pass);
4318
            tmp2 = neon_load_reg(rm, pass);
4319
        }
4320
        switch (op) {
4321
        case 0: /* VHADD */
4322
            GEN_NEON_INTEGER_OP(hadd);
4323
            break;
4324
        case 1: /* VQADD */
4325
            GEN_NEON_INTEGER_OP_ENV(qadd);
4326
            break;
4327
        case 2: /* VRHADD */
4328
            GEN_NEON_INTEGER_OP(rhadd);
4329
            break;
4330
        case 3: /* Logic ops.  */
4331
            switch ((u << 2) | size) {
4332
            case 0: /* VAND */
4333
                tcg_gen_and_i32(tmp, tmp, tmp2);
4334
                break;
4335
            case 1: /* BIC */
4336
                tcg_gen_andc_i32(tmp, tmp, tmp2);
4337
                break;
4338
            case 2: /* VORR */
4339
                tcg_gen_or_i32(tmp, tmp, tmp2);
4340
                break;
4341
            case 3: /* VORN */
4342
                tcg_gen_orc_i32(tmp, tmp, tmp2);
4343
                break;
4344
            case 4: /* VEOR */
4345
                tcg_gen_xor_i32(tmp, tmp, tmp2);
4346
                break;
4347
            case 5: /* VBSL */
4348
                tmp3 = neon_load_reg(rd, pass);
4349
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4350
                dead_tmp(tmp3);
4351
                break;
4352
            case 6: /* VBIT */
4353
                tmp3 = neon_load_reg(rd, pass);
4354
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4355
                dead_tmp(tmp3);
4356
                break;
4357
            case 7: /* VBIF */
4358
                tmp3 = neon_load_reg(rd, pass);
4359
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4360
                dead_tmp(tmp3);
4361
                break;
4362
            }
4363
            break;
4364
        case 4: /* VHSUB */
4365
            GEN_NEON_INTEGER_OP(hsub);
4366
            break;
4367
        case 5: /* VQSUB */
4368
            GEN_NEON_INTEGER_OP_ENV(qsub);
4369
            break;
4370
        case 6: /* VCGT */
4371
            GEN_NEON_INTEGER_OP(cgt);
4372
            break;
4373
        case 7: /* VCGE */
4374
            GEN_NEON_INTEGER_OP(cge);
4375
            break;
4376
        case 8: /* VSHL */
4377
            GEN_NEON_INTEGER_OP(shl);
4378
            break;
4379
        case 9: /* VQSHL */
4380
            GEN_NEON_INTEGER_OP_ENV(qshl);
4381
            break;
4382
        case 10: /* VRSHL */
4383
            GEN_NEON_INTEGER_OP(rshl);
4384
            break;
4385
        case 11: /* VQRSHL */
4386
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4387
            break;
4388
        case 12: /* VMAX */
4389
            GEN_NEON_INTEGER_OP(max);
4390
            break;
4391
        case 13: /* VMIN */
4392
            GEN_NEON_INTEGER_OP(min);
4393
            break;
4394
        case 14: /* VABD */
4395
            GEN_NEON_INTEGER_OP(abd);
4396
            break;
4397
        case 15: /* VABA */
4398
            GEN_NEON_INTEGER_OP(abd);
4399
            dead_tmp(tmp2);
4400
            tmp2 = neon_load_reg(rd, pass);
4401
            gen_neon_add(size, tmp, tmp2);
4402
            break;
4403
        case 16:
4404
            if (!u) { /* VADD */
4405
                if (gen_neon_add(size, tmp, tmp2))
4406
                    return 1;
4407
            } else { /* VSUB */
4408
                switch (size) {
4409
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4410
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4411
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4412
                default: return 1;
4413
                }
4414
            }
4415
            break;
4416
        case 17:
4417
            if (!u) { /* VTST */
4418
                switch (size) {
4419
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4420
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4421
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4422
                default: return 1;
4423
                }
4424
            } else { /* VCEQ */
4425
                switch (size) {
4426
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4427
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4428
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4429
                default: return 1;
4430
                }
4431
            }
4432
            break;
4433
        case 18: /* Multiply.  */
4434
            switch (size) {
4435
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4436
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4437
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4438
            default: return 1;
4439
            }
4440
            dead_tmp(tmp2);
4441
            tmp2 = neon_load_reg(rd, pass);
4442
            if (u) { /* VMLS */
4443
                gen_neon_rsb(size, tmp, tmp2);
4444
            } else { /* VMLA */
4445
                gen_neon_add(size, tmp, tmp2);
4446
            }
4447
            break;
4448
        case 19: /* VMUL */
4449
            if (u) { /* polynomial */
4450
                gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4451
            } else { /* Integer */
4452
                switch (size) {
4453
                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4454
                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4455
                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4456
                default: return 1;
4457
                }
4458
            }
4459
            break;
4460
        case 20: /* VPMAX */
4461
            GEN_NEON_INTEGER_OP(pmax);
4462
            break;
4463
        case 21: /* VPMIN */
4464
            GEN_NEON_INTEGER_OP(pmin);
4465
            break;
4466
        case 22: /* Hultiply high.  */
4467
            if (!u) { /* VQDMULH */
4468
                switch (size) {
4469
                case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4470
                case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4471
                default: return 1;
4472
                }
4473
            } else { /* VQRDHMUL */
4474
                switch (size) {
4475
                case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
4476
                case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
4477
                default: return 1;
4478
                }
4479
            }
4480
            break;
4481
        case 23: /* VPADD */
4482
            if (u)
4483
                return 1;
4484
            switch (size) {
4485
            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4486
            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4487
            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4488
            default: return 1;
4489
            }
4490
            break;
4491
        case 26: /* Floating point arithnetic.  */
4492
            switch ((u << 2) | size) {
4493
            case 0: /* VADD */
4494
                gen_helper_neon_add_f32(tmp, tmp, tmp2);
4495
                break;
4496
            case 2: /* VSUB */
4497
                gen_helper_neon_sub_f32(tmp, tmp, tmp2);
4498
                break;
4499
            case 4: /* VPADD */
4500
                gen_helper_neon_add_f32(tmp, tmp, tmp2);
4501
                break;
4502
            case 6: /* VABD */
4503
                gen_helper_neon_abd_f32(tmp, tmp, tmp2);
4504
                break;
4505
            default:
4506
                return 1;
4507
            }
4508
            break;
4509
        case 27: /* Float multiply.  */
4510
            gen_helper_neon_mul_f32(tmp, tmp, tmp2);
4511
            if (!u) {
4512
                dead_tmp(tmp2);
4513
                tmp2 = neon_load_reg(rd, pass);
4514
                if (size == 0) {
4515
                    gen_helper_neon_add_f32(tmp, tmp, tmp2);
4516
                } else {
4517
                    gen_helper_neon_sub_f32(tmp, tmp2, tmp);
4518
                }
4519
            }
4520
            break;
4521
        case 28: /* Float compare.  */
4522
            if (!u) {
4523
                gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
4524
            } else {
4525
                if (size == 0)
4526
                    gen_helper_neon_cge_f32(tmp, tmp, tmp2);
4527
                else
4528
                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
4529
            }
4530
            break;
4531
        case 29: /* Float compare absolute.  */
4532
            if (!u)
4533
                return 1;
4534
            if (size == 0)
4535
                gen_helper_neon_acge_f32(tmp, tmp, tmp2);
4536
            else
4537
                gen_helper_neon_acgt_f32(tmp, tmp, tmp2);
4538
            break;
4539
        case 30: /* Float min/max.  */
4540
            if (size == 0)
4541
                gen_helper_neon_max_f32(tmp, tmp, tmp2);
4542
            else
4543
                gen_helper_neon_min_f32(tmp, tmp, tmp2);
4544
            break;
4545
        case 31:
4546
            if (size == 0)
4547
                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4548
            else
4549
                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4550
            break;
4551
        default:
4552
            abort();
4553
        }
4554
        dead_tmp(tmp2);
4555

    
4556
        /* Save the result.  For elementwise operations we can put it
4557
           straight into the destination register.  For pairwise operations
4558
           we have to be careful to avoid clobbering the source operands.  */
4559
        if (pairwise && rd == rm) {
4560
            neon_store_scratch(pass, tmp);
4561
        } else {
4562
            neon_store_reg(rd, pass, tmp);
4563
        }
4564

    
4565
        } /* for pass */
4566
        if (pairwise && rd == rm) {
4567
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4568
                tmp = neon_load_scratch(pass);
4569
                neon_store_reg(rd, pass, tmp);
4570
            }
4571
        }
4572
        /* End of 3 register same size operations.  */
4573
    } else if (insn & (1 << 4)) {
4574
        if ((insn & 0x00380080) != 0) {
4575
            /* Two registers and shift.  */
4576
            op = (insn >> 8) & 0xf;
4577
            if (insn & (1 << 7)) {
4578
                /* 64-bit shift.   */
4579
                size = 3;
4580
            } else {
4581
                size = 2;
4582
                while ((insn & (1 << (size + 19))) == 0)
4583
                    size--;
4584
            }
4585
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4586
            /* To avoid excessive dumplication of ops we implement shift
4587
               by immediate using the variable shift operations.  */
4588
            if (op < 8) {
4589
                /* Shift by immediate:
4590
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4591
                /* Right shifts are encoded as N - shift, where N is the
4592
                   element size in bits.  */
4593
                if (op <= 4)
4594
                    shift = shift - (1 << (size + 3));
4595
                if (size == 3) {
4596
                    count = q + 1;
4597
                } else {
4598
                    count = q ? 4: 2;
4599
                }
4600
                switch (size) {
4601
                case 0:
4602
                    imm = (uint8_t) shift;
4603
                    imm |= imm << 8;
4604
                    imm |= imm << 16;
4605
                    break;
4606
                case 1:
4607
                    imm = (uint16_t) shift;
4608
                    imm |= imm << 16;
4609
                    break;
4610
                case 2:
4611
                case 3:
4612
                    imm = shift;
4613
                    break;
4614
                default:
4615
                    abort();
4616
                }
4617

    
4618
                for (pass = 0; pass < count; pass++) {
4619
                    if (size == 3) {
4620
                        neon_load_reg64(cpu_V0, rm + pass);
4621
                        tcg_gen_movi_i64(cpu_V1, imm);
4622
                        switch (op) {
4623
                        case 0:  /* VSHR */
4624
                        case 1:  /* VSRA */
4625
                            if (u)
4626
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4627
                            else
4628
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4629
                            break;
4630
                        case 2: /* VRSHR */
4631
                        case 3: /* VRSRA */
4632
                            if (u)
4633
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4634
                            else
4635
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4636
                            break;
4637
                        case 4: /* VSRI */
4638
                            if (!u)
4639
                                return 1;
4640
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4641
                            break;
4642
                        case 5: /* VSHL, VSLI */
4643
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4644
                            break;
4645
                        case 6: /* VQSHL */
4646
                            if (u)
4647
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4648
                            else
4649
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4650
                            break;
4651
                        case 7: /* VQSHLU */
4652
                            gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4653
                            break;
4654
                        }
4655
                        if (op == 1 || op == 3) {
4656
                            /* Accumulate.  */
4657
                            neon_load_reg64(cpu_V0, rd + pass);
4658
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4659
                        } else if (op == 4 || (op == 5 && u)) {
4660
                            /* Insert */
4661
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4662
                        }
4663
                        neon_store_reg64(cpu_V0, rd + pass);
4664
                    } else { /* size < 3 */
4665
                        /* Operands in T0 and T1.  */
4666
                        tmp = neon_load_reg(rm, pass);
4667
                        tmp2 = new_tmp();
4668
                        tcg_gen_movi_i32(tmp2, imm);
4669
                        switch (op) {
4670
                        case 0:  /* VSHR */
4671
                        case 1:  /* VSRA */
4672
                            GEN_NEON_INTEGER_OP(shl);
4673
                            break;
4674
                        case 2: /* VRSHR */
4675
                        case 3: /* VRSRA */
4676
                            GEN_NEON_INTEGER_OP(rshl);
4677
                            break;
4678
                        case 4: /* VSRI */
4679
                            if (!u)
4680
                                return 1;
4681
                            GEN_NEON_INTEGER_OP(shl);
4682
                            break;
4683
                        case 5: /* VSHL, VSLI */
4684
                            switch (size) {
4685
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4686
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4687
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4688
                            default: return 1;
4689
                            }
4690
                            break;
4691
                        case 6: /* VQSHL */
4692
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4693
                            break;
4694
                        case 7: /* VQSHLU */
4695
                            switch (size) {
4696
                            case 0: gen_helper_neon_qshl_u8(tmp, cpu_env, tmp, tmp2); break;
4697
                            case 1: gen_helper_neon_qshl_u16(tmp, cpu_env, tmp, tmp2); break;
4698
                            case 2: gen_helper_neon_qshl_u32(tmp, cpu_env, tmp, tmp2); break;
4699
                            default: return 1;
4700
                            }
4701
                            break;
4702
                        }
4703
                        dead_tmp(tmp2);
4704

    
4705
                        if (op == 1 || op == 3) {
4706
                            /* Accumulate.  */
4707
                            tmp2 = neon_load_reg(rd, pass);
4708
                            gen_neon_add(size, tmp2, tmp);
4709
                            dead_tmp(tmp2);
4710
                        } else if (op == 4 || (op == 5 && u)) {
4711
                            /* Insert */
4712
                            switch (size) {
4713
                            case 0:
4714
                                if (op == 4)
4715
                                    mask = 0xff >> -shift;
4716
                                else
4717
                                    mask = (uint8_t)(0xff << shift);
4718
                                mask |= mask << 8;
4719
                                mask |= mask << 16;
4720
                                break;
4721
                            case 1:
4722
                                if (op == 4)
4723
                                    mask = 0xffff >> -shift;
4724
                                else
4725
                                    mask = (uint16_t)(0xffff << shift);
4726
                                mask |= mask << 16;
4727
                                break;
4728
                            case 2:
4729
                                if (shift < -31 || shift > 31) {
4730
                                    mask = 0;
4731
                                } else {
4732
                                    if (op == 4)
4733
                                        mask = 0xffffffffu >> -shift;
4734
                                    else
4735
                                        mask = 0xffffffffu << shift;
4736
                                }
4737
                                break;
4738
                            default:
4739
                                abort();
4740
                            }
4741
                            tmp2 = neon_load_reg(rd, pass);
4742
                            tcg_gen_andi_i32(tmp, tmp, mask);
4743
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
4744
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4745
                            dead_tmp(tmp2);
4746
                        }
4747
                        neon_store_reg(rd, pass, tmp);
4748
                    }
4749
                } /* for pass */
4750
            } else if (op < 10) {
4751
                /* Shift by immediate and narrow:
4752
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4753
                shift = shift - (1 << (size + 3));
4754
                size++;
4755
                switch (size) {
4756
                case 1:
4757
                    imm = (uint16_t)shift;
4758
                    imm |= imm << 16;
4759
                    tmp2 = tcg_const_i32(imm);
4760
                    TCGV_UNUSED_I64(tmp64);
4761
                    break;
4762
                case 2:
4763
                    imm = (uint32_t)shift;
4764
                    tmp2 = tcg_const_i32(imm);
4765
                    TCGV_UNUSED_I64(tmp64);
4766
                    break;
4767
                case 3:
4768
                    tmp64 = tcg_const_i64(shift);
4769
                    TCGV_UNUSED(tmp2);
4770
                    break;
4771
                default:
4772
                    abort();
4773
                }
4774

    
4775
                for (pass = 0; pass < 2; pass++) {
4776
                    if (size == 3) {
4777
                        neon_load_reg64(cpu_V0, rm + pass);
4778
                        if (q) {
4779
                          if (u)
4780
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4781
                          else
4782
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4783
                        } else {
4784
                          if (u)
4785
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4786
                          else
4787
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4788
                        }
4789
                    } else {
4790
                        tmp = neon_load_reg(rm + pass, 0);
4791
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4792
                        tmp3 = neon_load_reg(rm + pass, 1);
4793
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4794
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4795
                        dead_tmp(tmp);
4796
                        dead_tmp(tmp3);
4797
                    }
4798
                    tmp = new_tmp();
4799
                    if (op == 8 && !u) {
4800
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4801
                    } else {
4802
                        if (op == 8)
4803
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4804
                        else
4805
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4806
                    }
4807
                    neon_store_reg(rd, pass, tmp);
4808
                } /* for pass */
4809
                if (size == 3) {
4810
                    tcg_temp_free_i64(tmp64);
4811
                } else {
4812
                    dead_tmp(tmp2);
4813
                }
4814
            } else if (op == 10) {
4815
                /* VSHLL */
4816
                if (q || size == 3)
4817
                    return 1;
4818
                tmp = neon_load_reg(rm, 0);
4819
                tmp2 = neon_load_reg(rm, 1);
4820
                for (pass = 0; pass < 2; pass++) {
4821
                    if (pass == 1)
4822
                        tmp = tmp2;
4823

    
4824
                    gen_neon_widen(cpu_V0, tmp, size, u);
4825

    
4826
                    if (shift != 0) {
4827
                        /* The shift is less than the width of the source
4828
                           type, so we can just shift the whole register.  */
4829
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4830
                        if (size < 2 || !u) {
4831
                            uint64_t imm64;
4832
                            if (size == 0) {
4833
                                imm = (0xffu >> (8 - shift));
4834
                                imm |= imm << 16;
4835
                            } else {
4836
                                imm = 0xffff >> (16 - shift);
4837
                            }
4838
                            imm64 = imm | (((uint64_t)imm) << 32);
4839
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4840
                        }
4841
                    }
4842
                    neon_store_reg64(cpu_V0, rd + pass);
4843
                }
4844
            } else if (op == 15 || op == 16) {
4845
                /* VCVT fixed-point.  */
4846
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4847
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4848
                    if (op & 1) {
4849
                        if (u)
4850
                            gen_vfp_ulto(0, shift);
4851
                        else
4852
                            gen_vfp_slto(0, shift);
4853
                    } else {
4854
                        if (u)
4855
                            gen_vfp_toul(0, shift);
4856
                        else
4857
                            gen_vfp_tosl(0, shift);
4858
                    }
4859
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4860
                }
4861
            } else {
4862
                return 1;
4863
            }
4864
        } else { /* (insn & 0x00380080) == 0 */
4865
            int invert;
4866

    
4867
            op = (insn >> 8) & 0xf;
4868
            /* One register and immediate.  */
4869
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4870
            invert = (insn & (1 << 5)) != 0;
4871
            switch (op) {
4872
            case 0: case 1:
4873
                /* no-op */
4874
                break;
4875
            case 2: case 3:
4876
                imm <<= 8;
4877
                break;
4878
            case 4: case 5:
4879
                imm <<= 16;
4880
                break;
4881
            case 6: case 7:
4882
                imm <<= 24;
4883
                break;
4884
            case 8: case 9:
4885
                imm |= imm << 16;
4886
                break;
4887
            case 10: case 11:
4888
                imm = (imm << 8) | (imm << 24);
4889
                break;
4890
            case 12:
4891
                imm = (imm < 8) | 0xff;
4892
                break;
4893
            case 13:
4894
                imm = (imm << 16) | 0xffff;
4895
                break;
4896
            case 14:
4897
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4898
                if (invert)
4899
                    imm = ~imm;
4900
                break;
4901
            case 15:
4902
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4903
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4904
                break;
4905
            }
4906
            if (invert)
4907
                imm = ~imm;
4908

    
4909
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4910
                if (op & 1 && op < 12) {
4911
                    tmp = neon_load_reg(rd, pass);
4912
                    if (invert) {
4913
                        /* The immediate value has already been inverted, so
4914
                           BIC becomes AND.  */
4915
                        tcg_gen_andi_i32(tmp, tmp, imm);
4916
                    } else {
4917
                        tcg_gen_ori_i32(tmp, tmp, imm);
4918
                    }
4919
                } else {
4920
                    /* VMOV, VMVN.  */
4921
                    tmp = new_tmp();
4922
                    if (op == 14 && invert) {
4923
                        uint32_t val;
4924
                        val = 0;
4925
                        for (n = 0; n < 4; n++) {
4926
                            if (imm & (1 << (n + (pass & 1) * 4)))
4927
                                val |= 0xff << (n * 8);
4928
                        }
4929
                        tcg_gen_movi_i32(tmp, val);
4930
                    } else {
4931
                        tcg_gen_movi_i32(tmp, imm);
4932
                    }
4933
                }
4934
                neon_store_reg(rd, pass, tmp);
4935
            }
4936
        }
4937
    } else { /* (insn & 0x00800010 == 0x00800000) */
4938
        if (size != 3) {
4939
            op = (insn >> 8) & 0xf;
4940
            if ((insn & (1 << 6)) == 0) {
4941
                /* Three registers of different lengths.  */
4942
                int src1_wide;
4943
                int src2_wide;
4944
                int prewiden;
4945
                /* prewiden, src1_wide, src2_wide */
4946
                static const int neon_3reg_wide[16][3] = {
4947
                    {1, 0, 0}, /* VADDL */
4948
                    {1, 1, 0}, /* VADDW */
4949
                    {1, 0, 0}, /* VSUBL */
4950
                    {1, 1, 0}, /* VSUBW */
4951
                    {0, 1, 1}, /* VADDHN */
4952
                    {0, 0, 0}, /* VABAL */
4953
                    {0, 1, 1}, /* VSUBHN */
4954
                    {0, 0, 0}, /* VABDL */
4955
                    {0, 0, 0}, /* VMLAL */
4956
                    {0, 0, 0}, /* VQDMLAL */
4957
                    {0, 0, 0}, /* VMLSL */
4958
                    {0, 0, 0}, /* VQDMLSL */
4959
                    {0, 0, 0}, /* Integer VMULL */
4960
                    {0, 0, 0}, /* VQDMULL */
4961
                    {0, 0, 0}  /* Polynomial VMULL */
4962
                };
4963

    
4964
                prewiden = neon_3reg_wide[op][0];
4965
                src1_wide = neon_3reg_wide[op][1];
4966
                src2_wide = neon_3reg_wide[op][2];
4967

    
4968
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4969
                    return 1;
4970

    
4971
                /* Avoid overlapping operands.  Wide source operands are
4972
                   always aligned so will never overlap with wide
4973
                   destinations in problematic ways.  */
4974
                if (rd == rm && !src2_wide) {
4975
                    tmp = neon_load_reg(rm, 1);
4976
                    neon_store_scratch(2, tmp);
4977
                } else if (rd == rn && !src1_wide) {
4978
                    tmp = neon_load_reg(rn, 1);
4979
                    neon_store_scratch(2, tmp);
4980
                }
4981
                TCGV_UNUSED(tmp3);
4982
                for (pass = 0; pass < 2; pass++) {
4983
                    if (src1_wide) {
4984
                        neon_load_reg64(cpu_V0, rn + pass);
4985
                        TCGV_UNUSED(tmp);
4986
                    } else {
4987
                        if (pass == 1 && rd == rn) {
4988
                            tmp = neon_load_scratch(2);
4989
                        } else {
4990
                            tmp = neon_load_reg(rn, pass);
4991
                        }
4992
                        if (prewiden) {
4993
                            gen_neon_widen(cpu_V0, tmp, size, u);
4994
                        }
4995
                    }
4996
                    if (src2_wide) {
4997
                        neon_load_reg64(cpu_V1, rm + pass);
4998
                        TCGV_UNUSED(tmp2);
4999
                    } else {
5000
                        if (pass == 1 && rd == rm) {
5001
                            tmp2 = neon_load_scratch(2);
5002
                        } else {
5003
                            tmp2 = neon_load_reg(rm, pass);
5004
                        }
5005
                        if (prewiden) {
5006
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5007
                        }
5008
                    }
5009
                    switch (op) {
5010
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5011
                        gen_neon_addl(size);
5012
                        break;
5013
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5014
                        gen_neon_subl(size);
5015
                        break;
5016
                    case 5: case 7: /* VABAL, VABDL */
5017
                        switch ((size << 1) | u) {
5018
                        case 0:
5019
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5020
                            break;
5021
                        case 1:
5022
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5023
                            break;
5024
                        case 2:
5025
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5026
                            break;
5027
                        case 3:
5028
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5029
                            break;
5030
                        case 4:
5031
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5032
                            break;
5033
                        case 5:
5034
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5035
                            break;
5036
                        default: abort();
5037
                        }
5038
                        dead_tmp(tmp2);
5039
                        dead_tmp(tmp);
5040
                        break;
5041
                    case 8: case 9: case 10: case 11: case 12: case 13:
5042
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5043
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5044
                        dead_tmp(tmp2);
5045
                        dead_tmp(tmp);
5046
                        break;
5047
                    case 14: /* Polynomial VMULL */
5048
                        cpu_abort(env, "Polynomial VMULL not implemented");
5049

    
5050
                    default: /* 15 is RESERVED.  */
5051
                        return 1;
5052
                    }
5053
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
5054
                        /* Accumulate.  */
5055
                        if (op == 10 || op == 11) {
5056
                            gen_neon_negl(cpu_V0, size);
5057
                        }
5058

    
5059
                        if (op != 13) {
5060
                            neon_load_reg64(cpu_V1, rd + pass);
5061
                        }
5062

    
5063
                        switch (op) {
5064
                        case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
5065
                            gen_neon_addl(size);
5066
                            break;
5067
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5068
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5069
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5070
                            break;
5071
                            /* Fall through.  */
5072
                        case 13: /* VQDMULL */
5073
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5074
                            break;
5075
                        default:
5076
                            abort();
5077
                        }
5078
                        neon_store_reg64(cpu_V0, rd + pass);
5079
                    } else if (op == 4 || op == 6) {
5080
                        /* Narrowing operation.  */
5081
                        tmp = new_tmp();
5082
                        if (!u) {
5083
                            switch (size) {
5084
                            case 0:
5085
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5086
                                break;
5087
                            case 1:
5088
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5089
                                break;
5090
                            case 2:
5091
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5092
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5093
                                break;
5094
                            default: abort();
5095
                            }
5096
                        } else {
5097
                            switch (size) {
5098
                            case 0:
5099
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5100
                                break;
5101
                            case 1:
5102
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5103
                                break;
5104
                            case 2:
5105
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5106
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5107
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5108
                                break;
5109
                            default: abort();
5110
                            }
5111
                        }
5112
                        if (pass == 0) {
5113
                            tmp3 = tmp;
5114
                        } else {
5115
                            neon_store_reg(rd, 0, tmp3);
5116
                            neon_store_reg(rd, 1, tmp);
5117
                        }
5118
                    } else {
5119
                        /* Write back the result.  */
5120
                        neon_store_reg64(cpu_V0, rd + pass);
5121
                    }
5122
                }
5123
            } else {
5124
                /* Two registers and a scalar.  */
5125
                switch (op) {
5126
                case 0: /* Integer VMLA scalar */
5127
                case 1: /* Float VMLA scalar */
5128
                case 4: /* Integer VMLS scalar */
5129
                case 5: /* Floating point VMLS scalar */
5130
                case 8: /* Integer VMUL scalar */
5131
                case 9: /* Floating point VMUL scalar */
5132
                case 12: /* VQDMULH scalar */
5133
                case 13: /* VQRDMULH scalar */
5134
                    tmp = neon_get_scalar(size, rm);
5135
                    neon_store_scratch(0, tmp);
5136
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5137
                        tmp = neon_load_scratch(0);
5138
                        tmp2 = neon_load_reg(rn, pass);
5139
                        if (op == 12) {
5140
                            if (size == 1) {
5141
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5142
                            } else {
5143
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5144
                            }
5145
                        } else if (op == 13) {
5146
                            if (size == 1) {
5147
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5148
                            } else {
5149
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5150
                            }
5151
                        } else if (op & 1) {
5152
                            gen_helper_neon_mul_f32(tmp, tmp, tmp2);
5153
                        } else {
5154
                            switch (size) {
5155
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5156
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5157
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5158
                            default: return 1;
5159
                            }
5160
                        }
5161
                        dead_tmp(tmp2);
5162
                        if (op < 8) {
5163
                            /* Accumulate.  */
5164
                            tmp2 = neon_load_reg(rd, pass);
5165
                            switch (op) {
5166
                            case 0:
5167
                                gen_neon_add(size, tmp, tmp2);
5168
                                break;
5169
                            case 1:
5170
                                gen_helper_neon_add_f32(tmp, tmp, tmp2);
5171
                                break;
5172
                            case 4:
5173
                                gen_neon_rsb(size, tmp, tmp2);
5174
                                break;
5175
                            case 5:
5176
                                gen_helper_neon_sub_f32(tmp, tmp2, tmp);
5177
                                break;
5178
                            default:
5179
                                abort();
5180
                            }
5181
                            dead_tmp(tmp2);
5182
                        }
5183
                        neon_store_reg(rd, pass, tmp);
5184
                    }
5185
                    break;
5186
                case 2: /* VMLAL sclar */
5187
                case 3: /* VQDMLAL scalar */
5188
                case 6: /* VMLSL scalar */
5189
                case 7: /* VQDMLSL scalar */
5190
                case 10: /* VMULL scalar */
5191
                case 11: /* VQDMULL scalar */
5192
                    if (size == 0 && (op == 3 || op == 7 || op == 11))
5193
                        return 1;
5194

    
5195
                    tmp2 = neon_get_scalar(size, rm);
5196
                    tmp3 = neon_load_reg(rn, 1);
5197

    
5198
                    for (pass = 0; pass < 2; pass++) {
5199
                        if (pass == 0) {
5200
                            tmp = neon_load_reg(rn, 0);
5201
                        } else {
5202
                            tmp = tmp3;
5203
                        }
5204
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5205
                        dead_tmp(tmp);
5206
                        if (op == 6 || op == 7) {
5207
                            gen_neon_negl(cpu_V0, size);
5208
                        }
5209
                        if (op != 11) {
5210
                            neon_load_reg64(cpu_V1, rd + pass);
5211
                        }
5212
                        switch (op) {
5213
                        case 2: case 6:
5214
                            gen_neon_addl(size);
5215
                            break;
5216
                        case 3: case 7:
5217
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5218
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5219
                            break;
5220
                        case 10:
5221
                            /* no-op */
5222
                            break;
5223
                        case 11:
5224
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5225
                            break;
5226
                        default:
5227
                            abort();
5228
                        }
5229
                        neon_store_reg64(cpu_V0, rd + pass);
5230
                    }
5231

    
5232
                    dead_tmp(tmp2);
5233

    
5234
                    break;
5235
                default: /* 14 and 15 are RESERVED */
5236
                    return 1;
5237
                }
5238
            }
5239
        } else { /* size == 3 */
5240
            if (!u) {
5241
                /* Extract.  */
5242
                imm = (insn >> 8) & 0xf;
5243
                count = q + 1;
5244

    
5245
                if (imm > 7 && !q)
5246
                    return 1;
5247

    
5248
                if (imm == 0) {
5249
                    neon_load_reg64(cpu_V0, rn);
5250
                    if (q) {
5251
                        neon_load_reg64(cpu_V1, rn + 1);
5252
                    }
5253
                } else if (imm == 8) {
5254
                    neon_load_reg64(cpu_V0, rn + 1);
5255
                    if (q) {
5256
                        neon_load_reg64(cpu_V1, rm);
5257
                    }
5258
                } else if (q) {
5259
                    tmp64 = tcg_temp_new_i64();
5260
                    if (imm < 8) {
5261
                        neon_load_reg64(cpu_V0, rn);
5262
                        neon_load_reg64(tmp64, rn + 1);
5263
                    } else {
5264
                        neon_load_reg64(cpu_V0, rn + 1);
5265
                        neon_load_reg64(tmp64, rm);
5266
                    }
5267
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5268
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5269
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5270
                    if (imm < 8) {
5271
                        neon_load_reg64(cpu_V1, rm);
5272
                    } else {
5273
                        neon_load_reg64(cpu_V1, rm + 1);
5274
                        imm -= 8;
5275
                    }
5276
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5277
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5278
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5279
                    tcg_temp_free_i64(tmp64);
5280
                } else {
5281
                    /* BUGFIX */
5282
                    neon_load_reg64(cpu_V0, rn);
5283
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5284
                    neon_load_reg64(cpu_V1, rm);
5285
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5286
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5287
                }
5288
                neon_store_reg64(cpu_V0, rd);
5289
                if (q) {
5290
                    neon_store_reg64(cpu_V1, rd + 1);
5291
                }
5292
            } else if ((insn & (1 << 11)) == 0) {
5293
                /* Two register misc.  */
5294
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5295
                size = (insn >> 18) & 3;
5296
                switch (op) {
5297
                case 0: /* VREV64 */
5298
                    if (size == 3)
5299
                        return 1;
5300
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
5301
                        tmp = neon_load_reg(rm, pass * 2);
5302
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
5303
                        switch (size) {
5304
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5305
                        case 1: gen_swap_half(tmp); break;
5306
                        case 2: /* no-op */ break;
5307
                        default: abort();
5308
                        }
5309
                        neon_store_reg(rd, pass * 2 + 1, tmp);
5310
                        if (size == 2) {
5311
                            neon_store_reg(rd, pass * 2, tmp2);
5312
                        } else {
5313
                            switch (size) {
5314
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5315
                            case 1: gen_swap_half(tmp2); break;
5316
                            default: abort();
5317
                            }
5318
                            neon_store_reg(rd, pass * 2, tmp2);
5319
                        }
5320
                    }
5321
                    break;
5322
                case 4: case 5: /* VPADDL */
5323
                case 12: case 13: /* VPADAL */
5324
                    if (size == 3)
5325
                        return 1;
5326
                    for (pass = 0; pass < q + 1; pass++) {
5327
                        tmp = neon_load_reg(rm, pass * 2);
5328
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
5329
                        tmp = neon_load_reg(rm, pass * 2 + 1);
5330
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
5331
                        switch (size) {
5332
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5333
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5334
                        case 2: tcg_gen_add_i64(CPU_V001); break;
5335
                        default: abort();
5336
                        }
5337
                        if (op >= 12) {
5338
                            /* Accumulate.  */
5339
                            neon_load_reg64(cpu_V1, rd + pass);
5340
                            gen_neon_addl(size);
5341
                        }
5342
                        neon_store_reg64(cpu_V0, rd + pass);
5343
                    }
5344
                    break;
5345
                case 33: /* VTRN */
5346
                    if (size == 2) {
5347
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
5348
                            tmp = neon_load_reg(rm, n);
5349
                            tmp2 = neon_load_reg(rd, n + 1);
5350
                            neon_store_reg(rm, n, tmp2);
5351
                            neon_store_reg(rd, n + 1, tmp);
5352
                        }
5353
                    } else {
5354
                        goto elementwise;
5355
                    }
5356
                    break;
5357
                case 34: /* VUZP */
5358
                    /* Reg  Before       After
5359
                       Rd   A3 A2 A1 A0  B2 B0 A2 A0
5360
                       Rm   B3 B2 B1 B0  B3 B1 A3 A1
5361
                     */
5362
                    if (size == 3)
5363
                        return 1;
5364
                    gen_neon_unzip(rd, q, 0, size);
5365
                    gen_neon_unzip(rm, q, 4, size);
5366
                    if (q) {
5367
                        static int unzip_order_q[8] =
5368
                            {0, 2, 4, 6, 1, 3, 5, 7};
5369
                        for (n = 0; n < 8; n++) {
5370
                            int reg = (n < 4) ? rd : rm;
5371
                            tmp = neon_load_scratch(unzip_order_q[n]);
5372
                            neon_store_reg(reg, n % 4, tmp);
5373
                        }
5374
                    } else {
5375
                        static int unzip_order[4] =
5376
                            {0, 4, 1, 5};
5377
                        for (n = 0; n < 4; n++) {
5378
                            int reg = (n < 2) ? rd : rm;
5379
                            tmp = neon_load_scratch(unzip_order[n]);
5380
                            neon_store_reg(reg, n % 2, tmp);
5381
                        }
5382
                    }
5383
                    break;
5384
                case 35: /* VZIP */
5385
                    /* Reg  Before       After
5386
                       Rd   A3 A2 A1 A0  B1 A1 B0 A0
5387
                       Rm   B3 B2 B1 B0  B3 A3 B2 A2
5388
                     */
5389
                    if (size == 3)
5390
                        return 1;
5391
                    count = (q ? 4 : 2);
5392
                    for (n = 0; n < count; n++) {
5393
                        tmp = neon_load_reg(rd, n);
5394
                        tmp2 = neon_load_reg(rd, n);
5395
                        switch (size) {
5396
                        case 0: gen_neon_zip_u8(tmp, tmp2); break;
5397
                        case 1: gen_neon_zip_u16(tmp, tmp2); break;
5398
                        case 2: /* no-op */; break;
5399
                        default: abort();
5400
                        }
5401
                        neon_store_scratch(n * 2, tmp);
5402
                        neon_store_scratch(n * 2 + 1, tmp2);
5403
                    }
5404
                    for (n = 0; n < count * 2; n++) {
5405
                        int reg = (n < count) ? rd : rm;
5406
                        tmp = neon_load_scratch(n);
5407
                        neon_store_reg(reg, n % count, tmp);
5408
                    }
5409
                    break;
5410
                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5411
                    if (size == 3)
5412
                        return 1;
5413
                    TCGV_UNUSED(tmp2);
5414
                    for (pass = 0; pass < 2; pass++) {
5415
                        neon_load_reg64(cpu_V0, rm + pass);
5416
                        tmp = new_tmp();
5417
                        if (op == 36 && q == 0) {
5418
                            gen_neon_narrow(size, tmp, cpu_V0);
5419
                        } else if (q) {
5420
                            gen_neon_narrow_satu(size, tmp, cpu_V0);
5421
                        } else {
5422
                            gen_neon_narrow_sats(size, tmp, cpu_V0);
5423
                        }
5424
                        if (pass == 0) {
5425
                            tmp2 = tmp;
5426
                        } else {
5427
                            neon_store_reg(rd, 0, tmp2);
5428
                            neon_store_reg(rd, 1, tmp);
5429
                        }
5430
                    }
5431
                    break;
5432
                case 38: /* VSHLL */
5433
                    if (q || size == 3)
5434
                        return 1;
5435
                    tmp = neon_load_reg(rm, 0);
5436
                    tmp2 = neon_load_reg(rm, 1);
5437
                    for (pass = 0; pass < 2; pass++) {
5438
                        if (pass == 1)
5439
                            tmp = tmp2;
5440
                        gen_neon_widen(cpu_V0, tmp, size, 1);
5441
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5442
                        neon_store_reg64(cpu_V0, rd + pass);
5443
                    }
5444
                    break;
5445
                case 44: /* VCVT.F16.F32 */
5446
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5447
                      return 1;
5448
                    tmp = new_tmp();
5449
                    tmp2 = new_tmp();
5450
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5451
                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5452
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5453
                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5454
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5455
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5456
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5457
                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5458
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5459
                    neon_store_reg(rd, 0, tmp2);
5460
                    tmp2 = new_tmp();
5461
                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5462
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5463
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5464
                    neon_store_reg(rd, 1, tmp2);
5465
                    dead_tmp(tmp);
5466
                    break;
5467
                case 46: /* VCVT.F32.F16 */
5468
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5469
                      return 1;
5470
                    tmp3 = new_tmp();
5471
                    tmp = neon_load_reg(rm, 0);
5472
                    tmp2 = neon_load_reg(rm, 1);
5473
                    tcg_gen_ext16u_i32(tmp3, tmp);
5474
                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5475
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5476
                    tcg_gen_shri_i32(tmp3, tmp, 16);
5477
                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5478
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5479
                    dead_tmp(tmp);
5480
                    tcg_gen_ext16u_i32(tmp3, tmp2);
5481
                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5482
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5483
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
5484
                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5485
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5486
                    dead_tmp(tmp2);
5487
                    dead_tmp(tmp3);
5488
                    break;
5489
                default:
5490
                elementwise:
5491
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
5492
                        if (op == 30 || op == 31 || op >= 58) {
5493
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
5494
                                           neon_reg_offset(rm, pass));
5495
                            TCGV_UNUSED(tmp);
5496
                        } else {
5497
                            tmp = neon_load_reg(rm, pass);
5498
                        }
5499
                        switch (op) {
5500
                        case 1: /* VREV32 */
5501
                            switch (size) {
5502
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5503
                            case 1: gen_swap_half(tmp); break;
5504
                            default: return 1;
5505
                            }
5506
                            break;
5507
                        case 2: /* VREV16 */
5508
                            if (size != 0)
5509
                                return 1;
5510
                            gen_rev16(tmp);
5511
                            break;
5512
                        case 8: /* CLS */
5513
                            switch (size) {
5514
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5515
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5516
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5517
                            default: return 1;
5518
                            }
5519
                            break;
5520
                        case 9: /* CLZ */
5521
                            switch (size) {
5522
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5523
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5524
                            case 2: gen_helper_clz(tmp, tmp); break;
5525
                            default: return 1;
5526
                            }
5527
                            break;
5528
                        case 10: /* CNT */
5529
                            if (size != 0)
5530
                                return 1;
5531
                            gen_helper_neon_cnt_u8(tmp, tmp);
5532
                            break;
5533
                        case 11: /* VNOT */
5534
                            if (size != 0)
5535
                                return 1;
5536
                            tcg_gen_not_i32(tmp, tmp);
5537
                            break;
5538
                        case 14: /* VQABS */
5539
                            switch (size) {
5540
                            case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
5541
                            case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
5542
                            case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
5543
                            default: return 1;
5544
                            }
5545
                            break;
5546
                        case 15: /* VQNEG */
5547
                            switch (size) {
5548
                            case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
5549
                            case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
5550
                            case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
5551
                            default: return 1;
5552
                            }
5553
                            break;
5554
                        case 16: case 19: /* VCGT #0, VCLE #0 */
5555
                            tmp2 = tcg_const_i32(0);
5556
                            switch(size) {
5557
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5558
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5559
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5560
                            default: return 1;
5561
                            }
5562
                            tcg_temp_free(tmp2);
5563
                            if (op == 19)
5564
                                tcg_gen_not_i32(tmp, tmp);
5565
                            break;
5566
                        case 17: case 20: /* VCGE #0, VCLT #0 */
5567
                            tmp2 = tcg_const_i32(0);
5568
                            switch(size) {
5569
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
5570
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
5571
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
5572
                            default: return 1;
5573
                            }
5574
                            tcg_temp_free(tmp2);
5575
                            if (op == 20)
5576
                                tcg_gen_not_i32(tmp, tmp);
5577
                            break;
5578
                        case 18: /* VCEQ #0 */
5579
                            tmp2 = tcg_const_i32(0);
5580
                            switch(size) {
5581
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5582
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5583
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5584
                            default: return 1;
5585
                            }
5586
                            tcg_temp_free(tmp2);
5587
                            break;
5588
                        case 22: /* VABS */
5589
                            switch(size) {
5590
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
5591
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
5592
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
5593
                            default: return 1;
5594
                            }
5595
                            break;
5596
                        case 23: /* VNEG */
5597
                            if (size == 3)
5598
                                return 1;
5599
                            tmp2 = tcg_const_i32(0);
5600
                            gen_neon_rsb(size, tmp, tmp2);
5601
                            tcg_temp_free(tmp2);
5602
                            break;
5603
                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5604
                            tmp2 = tcg_const_i32(0);
5605
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
5606
                            tcg_temp_free(tmp2);
5607
                            if (op == 27)
5608
                                tcg_gen_not_i32(tmp, tmp);
5609
                            break;
5610
                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5611
                            tmp2 = tcg_const_i32(0);
5612
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2);
5613
                            tcg_temp_free(tmp2);
5614
                            if (op == 28)
5615
                                tcg_gen_not_i32(tmp, tmp);
5616
                            break;
5617
                        case 26: /* Float VCEQ #0 */
5618
                            tmp2 = tcg_const_i32(0);
5619
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
5620
                            tcg_temp_free(tmp2);
5621
                            break;
5622
                        case 30: /* Float VABS */
5623
                            gen_vfp_abs(0);
5624
                            break;
5625
                        case 31: /* Float VNEG */
5626
                            gen_vfp_neg(0);
5627
                            break;
5628
                        case 32: /* VSWP */
5629
                            tmp2 = neon_load_reg(rd, pass);
5630
                            neon_store_reg(rm, pass, tmp2);
5631
                            break;
5632
                        case 33: /* VTRN */
5633
                            tmp2 = neon_load_reg(rd, pass);
5634
                            switch (size) {
5635
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
5636
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
5637
                            case 2: abort();
5638
                            default: return 1;
5639
                            }
5640
                            neon_store_reg(rm, pass, tmp2);
5641
                            break;
5642
                        case 56: /* Integer VRECPE */
5643
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
5644
                            break;
5645
                        case 57: /* Integer VRSQRTE */
5646
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
5647
                            break;
5648
                        case 58: /* Float VRECPE */
5649
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5650
                            break;
5651
                        case 59: /* Float VRSQRTE */
5652
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5653
                            break;
5654
                        case 60: /* VCVT.F32.S32 */
5655
                            gen_vfp_tosiz(0);
5656
                            break;
5657
                        case 61: /* VCVT.F32.U32 */
5658
                            gen_vfp_touiz(0);
5659
                            break;
5660
                        case 62: /* VCVT.S32.F32 */
5661
                            gen_vfp_sito(0);
5662
                            break;
5663
                        case 63: /* VCVT.U32.F32 */
5664
                            gen_vfp_uito(0);
5665
                            break;
5666
                        default:
5667
                            /* Reserved: 21, 29, 39-56 */
5668
                            return 1;
5669
                        }
5670
                        if (op == 30 || op == 31 || op >= 58) {
5671
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
5672
                                           neon_reg_offset(rd, pass));
5673
                        } else {
5674
                            neon_store_reg(rd, pass, tmp);
5675
                        }
5676
                    }
5677
                    break;
5678
                }
5679
            } else if ((insn & (1 << 10)) == 0) {
5680
                /* VTBL, VTBX.  */
5681
                n = ((insn >> 5) & 0x18) + 8;
5682
                if (insn & (1 << 6)) {
5683
                    tmp = neon_load_reg(rd, 0);
5684
                } else {
5685
                    tmp = new_tmp();
5686
                    tcg_gen_movi_i32(tmp, 0);
5687
                }
5688
                tmp2 = neon_load_reg(rm, 0);
5689
                tmp4 = tcg_const_i32(rn);
5690
                tmp5 = tcg_const_i32(n);
5691
                gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
5692
                dead_tmp(tmp);
5693
                if (insn & (1 << 6)) {
5694
                    tmp = neon_load_reg(rd, 1);
5695
                } else {
5696
                    tmp = new_tmp();
5697
                    tcg_gen_movi_i32(tmp, 0);
5698
                }
5699
                tmp3 = neon_load_reg(rm, 1);
5700
                gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
5701
                tcg_temp_free_i32(tmp5);
5702
                tcg_temp_free_i32(tmp4);
5703
                neon_store_reg(rd, 0, tmp2);
5704
                neon_store_reg(rd, 1, tmp3);
5705
                dead_tmp(tmp);
5706
            } else if ((insn & 0x380) == 0) {
5707
                /* VDUP */
5708
                if (insn & (1 << 19)) {
5709
                    tmp = neon_load_reg(rm, 1);
5710
                } else {
5711
                    tmp = neon_load_reg(rm, 0);
5712
                }
5713
                if (insn & (1 << 16)) {
5714
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
5715
                } else if (insn & (1 << 17)) {
5716
                    if ((insn >> 18) & 1)
5717
                        gen_neon_dup_high16(tmp);
5718
                    else
5719
                        gen_neon_dup_low16(tmp);
5720
                }
5721
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5722
                    tmp2 = new_tmp();
5723
                    tcg_gen_mov_i32(tmp2, tmp);
5724
                    neon_store_reg(rd, pass, tmp2);
5725
                }
5726
                dead_tmp(tmp);
5727
            } else {
5728
                return 1;
5729
            }
5730
        }
5731
    }
5732
    return 0;
5733
}
5734

    
5735
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5736
{
5737
    int crn = (insn >> 16) & 0xf;
5738
    int crm = insn & 0xf;
5739
    int op1 = (insn >> 21) & 7;
5740
    int op2 = (insn >> 5) & 7;
5741
    int rt = (insn >> 12) & 0xf;
5742
    TCGv tmp;
5743

    
5744
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5745
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5746
            /* TEECR */
5747
            if (IS_USER(s))
5748
                return 1;
5749
            tmp = load_cpu_field(teecr);
5750
            store_reg(s, rt, tmp);
5751
            return 0;
5752
        }
5753
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5754
            /* TEEHBR */
5755
            if (IS_USER(s) && (env->teecr & 1))
5756
                return 1;
5757
            tmp = load_cpu_field(teehbr);
5758
            store_reg(s, rt, tmp);
5759
            return 0;
5760
        }
5761
    }
5762
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5763
            op1, crn, crm, op2);
5764
    return 1;
5765
}
5766

    
5767
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5768
{
5769
    int crn = (insn >> 16) & 0xf;
5770
    int crm = insn & 0xf;
5771
    int op1 = (insn >> 21) & 7;
5772
    int op2 = (insn >> 5) & 7;
5773
    int rt = (insn >> 12) & 0xf;
5774
    TCGv tmp;
5775

    
5776
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5777
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5778
            /* TEECR */
5779
            if (IS_USER(s))
5780
                return 1;
5781
            tmp = load_reg(s, rt);
5782
            gen_helper_set_teecr(cpu_env, tmp);
5783
            dead_tmp(tmp);
5784
            return 0;
5785
        }
5786
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5787
            /* TEEHBR */
5788
            if (IS_USER(s) && (env->teecr & 1))
5789
                return 1;
5790
            tmp = load_reg(s, rt);
5791
            store_cpu_field(tmp, teehbr);
5792
            return 0;
5793
        }
5794
    }
5795
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5796
            op1, crn, crm, op2);
5797
    return 1;
5798
}
5799

    
5800
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5801
{
5802
    int cpnum;
5803

    
5804
    cpnum = (insn >> 8) & 0xf;
5805
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5806
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5807
        return 1;
5808

    
5809
    switch (cpnum) {
5810
      case 0:
5811
      case 1:
5812
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5813
            return disas_iwmmxt_insn(env, s, insn);
5814
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5815
            return disas_dsp_insn(env, s, insn);
5816
        }
5817
        return 1;
5818
    case 10:
5819
    case 11:
5820
        return disas_vfp_insn (env, s, insn);
5821
    case 14:
5822
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5823
           Unfortunately Intel decided to ignore this.  */
5824
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5825
            goto board;
5826
        if (insn & (1 << 20))
5827
            return disas_cp14_read(env, s, insn);
5828
        else
5829
            return disas_cp14_write(env, s, insn);
5830
    case 15:
5831
        return disas_cp15_insn (env, s, insn);
5832
    default:
5833
    board:
5834
        /* Unknown coprocessor.  See if the board has hooked it.  */
5835
        return disas_cp_insn (env, s, insn);
5836
    }
5837
}
5838

    
5839

    
5840
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5841
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5842
{
5843
    TCGv tmp;
5844
    tmp = new_tmp();
5845
    tcg_gen_trunc_i64_i32(tmp, val);
5846
    store_reg(s, rlow, tmp);
5847
    tmp = new_tmp();
5848
    tcg_gen_shri_i64(val, val, 32);
5849
    tcg_gen_trunc_i64_i32(tmp, val);
5850
    store_reg(s, rhigh, tmp);
5851
}
5852

    
5853
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5854
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5855
{
5856
    TCGv_i64 tmp;
5857
    TCGv tmp2;
5858

    
5859
    /* Load value and extend to 64 bits.  */
5860
    tmp = tcg_temp_new_i64();
5861
    tmp2 = load_reg(s, rlow);
5862
    tcg_gen_extu_i32_i64(tmp, tmp2);
5863
    dead_tmp(tmp2);
5864
    tcg_gen_add_i64(val, val, tmp);
5865
    tcg_temp_free_i64(tmp);
5866
}
5867

    
5868
/* load and add a 64-bit value from a register pair.  */
5869
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5870
{
5871
    TCGv_i64 tmp;
5872
    TCGv tmpl;
5873
    TCGv tmph;
5874

    
5875
    /* Load 64-bit value rd:rn.  */
5876
    tmpl = load_reg(s, rlow);
5877
    tmph = load_reg(s, rhigh);
5878
    tmp = tcg_temp_new_i64();
5879
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5880
    dead_tmp(tmpl);
5881
    dead_tmp(tmph);
5882
    tcg_gen_add_i64(val, val, tmp);
5883
    tcg_temp_free_i64(tmp);
5884
}
5885

    
5886
/* Set N and Z flags from a 64-bit value.  */
5887
static void gen_logicq_cc(TCGv_i64 val)
5888
{
5889
    TCGv tmp = new_tmp();
5890
    gen_helper_logicq_cc(tmp, val);
5891
    gen_logic_CC(tmp);
5892
    dead_tmp(tmp);
5893
}
5894

    
5895
/* Load/Store exclusive instructions are implemented by remembering
5896
   the value/address loaded, and seeing if these are the same
5897
   when the store is performed. This should be is sufficient to implement
5898
   the architecturally mandated semantics, and avoids having to monitor
5899
   regular stores.
5900

5901
   In system emulation mode only one CPU will be running at once, so
5902
   this sequence is effectively atomic.  In user emulation mode we
5903
   throw an exception and handle the atomic operation elsewhere.  */
5904
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
5905
                               TCGv addr, int size)
5906
{
5907
    TCGv tmp;
5908

    
5909
    switch (size) {
5910
    case 0:
5911
        tmp = gen_ld8u(addr, IS_USER(s));
5912
        break;
5913
    case 1:
5914
        tmp = gen_ld16u(addr, IS_USER(s));
5915
        break;
5916
    case 2:
5917
    case 3:
5918
        tmp = gen_ld32(addr, IS_USER(s));
5919
        break;
5920
    default:
5921
        abort();
5922
    }
5923
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
5924
    store_reg(s, rt, tmp);
5925
    if (size == 3) {
5926
        tcg_gen_addi_i32(addr, addr, 4);
5927
        tmp = gen_ld32(addr, IS_USER(s));
5928
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
5929
        store_reg(s, rt2, tmp);
5930
    }
5931
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
5932
}
5933

    
5934
static void gen_clrex(DisasContext *s)
5935
{
5936
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
5937
}
5938

    
5939
#ifdef CONFIG_USER_ONLY
5940
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
5941
                                TCGv addr, int size)
5942
{
5943
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
5944
    tcg_gen_movi_i32(cpu_exclusive_info,
5945
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
5946
    gen_set_condexec(s);
5947
    gen_set_pc_im(s->pc - 4);
5948
    gen_exception(EXCP_STREX);
5949
    s->is_jmp = DISAS_JUMP;
5950
}
5951
#else
5952
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
5953
                                TCGv addr, int size)
5954
{
5955
    TCGv tmp;
5956
    int done_label;
5957
    int fail_label;
5958

    
5959
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
5960
         [addr] = {Rt};
5961
         {Rd} = 0;
5962
       } else {
5963
         {Rd} = 1;
5964
       } */
5965
    fail_label = gen_new_label();
5966
    done_label = gen_new_label();
5967
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
5968
    switch (size) {
5969
    case 0:
5970
        tmp = gen_ld8u(addr, IS_USER(s));
5971
        break;
5972
    case 1:
5973
        tmp = gen_ld16u(addr, IS_USER(s));
5974
        break;
5975
    case 2:
5976
    case 3:
5977
        tmp = gen_ld32(addr, IS_USER(s));
5978
        break;
5979
    default:
5980
        abort();
5981
    }
5982
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
5983
    dead_tmp(tmp);
5984
    if (size == 3) {
5985
        TCGv tmp2 = new_tmp();
5986
        tcg_gen_addi_i32(tmp2, addr, 4);
5987
        tmp = gen_ld32(addr, IS_USER(s));
5988
        dead_tmp(tmp2);
5989
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
5990
        dead_tmp(tmp);
5991
    }
5992
    tmp = load_reg(s, rt);
5993
    switch (size) {
5994
    case 0:
5995
        gen_st8(tmp, addr, IS_USER(s));
5996
        break;
5997
    case 1:
5998
        gen_st16(tmp, addr, IS_USER(s));
5999
        break;
6000
    case 2:
6001
    case 3:
6002
        gen_st32(tmp, addr, IS_USER(s));
6003
        break;
6004
    default:
6005
        abort();
6006
    }
6007
    if (size == 3) {
6008
        tcg_gen_addi_i32(addr, addr, 4);
6009
        tmp = load_reg(s, rt2);
6010
        gen_st32(tmp, addr, IS_USER(s));
6011
    }
6012
    tcg_gen_movi_i32(cpu_R[rd], 0);
6013
    tcg_gen_br(done_label);
6014
    gen_set_label(fail_label);
6015
    tcg_gen_movi_i32(cpu_R[rd], 1);
6016
    gen_set_label(done_label);
6017
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6018
}
6019
#endif
6020

    
6021
static void disas_arm_insn(CPUState * env, DisasContext *s)
6022
{
6023
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6024
    TCGv tmp;
6025
    TCGv tmp2;
6026
    TCGv tmp3;
6027
    TCGv addr;
6028
    TCGv_i64 tmp64;
6029

    
6030
    insn = ldl_code(s->pc);
6031
    s->pc += 4;
6032

    
6033
    /* M variants do not implement ARM mode.  */
6034
    if (IS_M(env))
6035
        goto illegal_op;
6036
    cond = insn >> 28;
6037
    if (cond == 0xf){
6038
        /* Unconditional instructions.  */
6039
        if (((insn >> 25) & 7) == 1) {
6040
            /* NEON Data processing.  */
6041
            if (!arm_feature(env, ARM_FEATURE_NEON))
6042
                goto illegal_op;
6043

    
6044
            if (disas_neon_data_insn(env, s, insn))
6045
                goto illegal_op;
6046
            return;
6047
        }
6048
        if ((insn & 0x0f100000) == 0x04000000) {
6049
            /* NEON load/store.  */
6050
            if (!arm_feature(env, ARM_FEATURE_NEON))
6051
                goto illegal_op;
6052

    
6053
            if (disas_neon_ls_insn(env, s, insn))
6054
                goto illegal_op;
6055
            return;
6056
        }
6057
        if ((insn & 0x0d70f000) == 0x0550f000)
6058
            return; /* PLD */
6059
        else if ((insn & 0x0ffffdff) == 0x01010000) {
6060
            ARCH(6);
6061
            /* setend */
6062
            if (insn & (1 << 9)) {
6063
                /* BE8 mode not implemented.  */
6064
                goto illegal_op;
6065
            }
6066
            return;
6067
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6068
            switch ((insn >> 4) & 0xf) {
6069
            case 1: /* clrex */
6070
                ARCH(6K);
6071
                gen_clrex(s);
6072
                return;
6073
            case 4: /* dsb */
6074
            case 5: /* dmb */
6075
            case 6: /* isb */
6076
                ARCH(7);
6077
                /* We don't emulate caches so these are a no-op.  */
6078
                return;
6079
            default:
6080
                goto illegal_op;
6081
            }
6082
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6083
            /* srs */
6084
            int32_t offset;
6085
            if (IS_USER(s))
6086
                goto illegal_op;
6087
            ARCH(6);
6088
            op1 = (insn & 0x1f);
6089
            if (op1 == (env->uncached_cpsr & CPSR_M)) {
6090
                addr = load_reg(s, 13);
6091
            } else {
6092
                addr = new_tmp();
6093
                tmp = tcg_const_i32(op1);
6094
                gen_helper_get_r13_banked(addr, cpu_env, tmp);
6095
                tcg_temp_free_i32(tmp);
6096
            }
6097
            i = (insn >> 23) & 3;
6098
            switch (i) {
6099
            case 0: offset = -4; break; /* DA */
6100
            case 1: offset = 0; break; /* IA */
6101
            case 2: offset = -8; break; /* DB */
6102
            case 3: offset = 4; break; /* IB */
6103
            default: abort();
6104
            }
6105
            if (offset)
6106
                tcg_gen_addi_i32(addr, addr, offset);
6107
            tmp = load_reg(s, 14);
6108
            gen_st32(tmp, addr, 0);
6109
            tmp = load_cpu_field(spsr);
6110
            tcg_gen_addi_i32(addr, addr, 4);
6111
            gen_st32(tmp, addr, 0);
6112
            if (insn & (1 << 21)) {
6113
                /* Base writeback.  */
6114
                switch (i) {
6115
                case 0: offset = -8; break;
6116
                case 1: offset = 4; break;
6117
                case 2: offset = -4; break;
6118
                case 3: offset = 0; break;
6119
                default: abort();
6120
                }
6121
                if (offset)
6122
                    tcg_gen_addi_i32(addr, addr, offset);
6123
                if (op1 == (env->uncached_cpsr & CPSR_M)) {
6124
                    store_reg(s, 13, addr);
6125
                } else {
6126
                    tmp = tcg_const_i32(op1);
6127
                    gen_helper_set_r13_banked(cpu_env, tmp, addr);
6128
                    tcg_temp_free_i32(tmp);
6129
                    dead_tmp(addr);
6130
                }
6131
            } else {
6132
                dead_tmp(addr);
6133
            }
6134
        } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
6135
            /* rfe */
6136
            int32_t offset;
6137
            if (IS_USER(s))
6138
                goto illegal_op;
6139
            ARCH(6);
6140
            rn = (insn >> 16) & 0xf;
6141
            addr = load_reg(s, rn);
6142
            i = (insn >> 23) & 3;
6143
            switch (i) {
6144
            case 0: offset = -4; break; /* DA */
6145
            case 1: offset = 0; break; /* IA */
6146
            case 2: offset = -8; break; /* DB */
6147
            case 3: offset = 4; break; /* IB */
6148
            default: abort();
6149
            }
6150
            if (offset)
6151
                tcg_gen_addi_i32(addr, addr, offset);
6152
            /* Load PC into tmp and CPSR into tmp2.  */
6153
            tmp = gen_ld32(addr, 0);
6154
            tcg_gen_addi_i32(addr, addr, 4);
6155
            tmp2 = gen_ld32(addr, 0);
6156
            if (insn & (1 << 21)) {
6157
                /* Base writeback.  */
6158
                switch (i) {
6159
                case 0: offset = -8; break;
6160
                case 1: offset = 4; break;
6161
                case 2: offset = -4; break;
6162
                case 3: offset = 0; break;
6163
                default: abort();
6164
                }
6165
                if (offset)
6166
                    tcg_gen_addi_i32(addr, addr, offset);
6167
                store_reg(s, rn, addr);
6168
            } else {
6169
                dead_tmp(addr);
6170
            }
6171
            gen_rfe(s, tmp, tmp2);
6172
            return;
6173
        } else if ((insn & 0x0e000000) == 0x0a000000) {
6174
            /* branch link and change to thumb (blx <offset>) */
6175
            int32_t offset;
6176

    
6177
            val = (uint32_t)s->pc;
6178
            tmp = new_tmp();
6179
            tcg_gen_movi_i32(tmp, val);
6180
            store_reg(s, 14, tmp);
6181
            /* Sign-extend the 24-bit offset */
6182
            offset = (((int32_t)insn) << 8) >> 8;
6183
            /* offset * 4 + bit24 * 2 + (thumb bit) */
6184
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
6185
            /* pipeline offset */
6186
            val += 4;
6187
            gen_bx_im(s, val);
6188
            return;
6189
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
6190
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6191
                /* iWMMXt register transfer.  */
6192
                if (env->cp15.c15_cpar & (1 << 1))
6193
                    if (!disas_iwmmxt_insn(env, s, insn))
6194
                        return;
6195
            }
6196
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
6197
            /* Coprocessor double register transfer.  */
6198
        } else if ((insn & 0x0f000010) == 0x0e000010) {
6199
            /* Additional coprocessor register transfer.  */
6200
        } else if ((insn & 0x0ff10020) == 0x01000000) {
6201
            uint32_t mask;
6202
            uint32_t val;
6203
            /* cps (privileged) */
6204
            if (IS_USER(s))
6205
                return;
6206
            mask = val = 0;
6207
            if (insn & (1 << 19)) {
6208
                if (insn & (1 << 8))
6209
                    mask |= CPSR_A;
6210
                if (insn & (1 << 7))
6211
                    mask |= CPSR_I;
6212
                if (insn & (1 << 6))
6213
                    mask |= CPSR_F;
6214
                if (insn & (1 << 18))
6215
                    val |= mask;
6216
            }
6217
            if (insn & (1 << 17)) {
6218
                mask |= CPSR_M;
6219
                val |= (insn & 0x1f);
6220
            }
6221
            if (mask) {
6222
                gen_set_psr_im(s, mask, 0, val);
6223
            }
6224
            return;
6225
        }
6226
        goto illegal_op;
6227
    }
6228
    if (cond != 0xe) {
6229
        /* if not always execute, we generate a conditional jump to
6230
           next instruction */
6231
        s->condlabel = gen_new_label();
6232
        gen_test_cc(cond ^ 1, s->condlabel);
6233
        s->condjmp = 1;
6234
    }
6235
    if ((insn & 0x0f900000) == 0x03000000) {
6236
        if ((insn & (1 << 21)) == 0) {
6237
            ARCH(6T2);
6238
            rd = (insn >> 12) & 0xf;
6239
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6240
            if ((insn & (1 << 22)) == 0) {
6241
                /* MOVW */
6242
                tmp = new_tmp();
6243
                tcg_gen_movi_i32(tmp, val);
6244
            } else {
6245
                /* MOVT */
6246
                tmp = load_reg(s, rd);
6247
                tcg_gen_ext16u_i32(tmp, tmp);
6248
                tcg_gen_ori_i32(tmp, tmp, val << 16);
6249
            }
6250
            store_reg(s, rd, tmp);
6251
        } else {
6252
            if (((insn >> 12) & 0xf) != 0xf)
6253
                goto illegal_op;
6254
            if (((insn >> 16) & 0xf) == 0) {
6255
                gen_nop_hint(s, insn & 0xff);
6256
            } else {
6257
                /* CPSR = immediate */
6258
                val = insn & 0xff;
6259
                shift = ((insn >> 8) & 0xf) * 2;
6260
                if (shift)
6261
                    val = (val >> shift) | (val << (32 - shift));
6262
                i = ((insn & (1 << 22)) != 0);
6263
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6264
                    goto illegal_op;
6265
            }
6266
        }
6267
    } else if ((insn & 0x0f900000) == 0x01000000
6268
               && (insn & 0x00000090) != 0x00000090) {
6269
        /* miscellaneous instructions */
6270
        op1 = (insn >> 21) & 3;
6271
        sh = (insn >> 4) & 0xf;
6272
        rm = insn & 0xf;
6273
        switch (sh) {
6274
        case 0x0: /* move program status register */
6275
            if (op1 & 1) {
6276
                /* PSR = reg */
6277
                tmp = load_reg(s, rm);
6278
                i = ((op1 & 2) != 0);
6279
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6280
                    goto illegal_op;
6281
            } else {
6282
                /* reg = PSR */
6283
                rd = (insn >> 12) & 0xf;
6284
                if (op1 & 2) {
6285
                    if (IS_USER(s))
6286
                        goto illegal_op;
6287
                    tmp = load_cpu_field(spsr);
6288
                } else {
6289
                    tmp = new_tmp();
6290
                    gen_helper_cpsr_read(tmp);
6291
                }
6292
                store_reg(s, rd, tmp);
6293
            }
6294
            break;
6295
        case 0x1:
6296
            if (op1 == 1) {
6297
                /* branch/exchange thumb (bx).  */
6298
                tmp = load_reg(s, rm);
6299
                gen_bx(s, tmp);
6300
            } else if (op1 == 3) {
6301
                /* clz */
6302
                rd = (insn >> 12) & 0xf;
6303
                tmp = load_reg(s, rm);
6304
                gen_helper_clz(tmp, tmp);
6305
                store_reg(s, rd, tmp);
6306
            } else {
6307
                goto illegal_op;
6308
            }
6309
            break;
6310
        case 0x2:
6311
            if (op1 == 1) {
6312
                ARCH(5J); /* bxj */
6313
                /* Trivial implementation equivalent to bx.  */
6314
                tmp = load_reg(s, rm);
6315
                gen_bx(s, tmp);
6316
            } else {
6317
                goto illegal_op;
6318
            }
6319
            break;
6320
        case 0x3:
6321
            if (op1 != 1)
6322
              goto illegal_op;
6323

    
6324
            /* branch link/exchange thumb (blx) */
6325
            tmp = load_reg(s, rm);
6326
            tmp2 = new_tmp();
6327
            tcg_gen_movi_i32(tmp2, s->pc);
6328
            store_reg(s, 14, tmp2);
6329
            gen_bx(s, tmp);
6330
            break;
6331
        case 0x5: /* saturating add/subtract */
6332
            rd = (insn >> 12) & 0xf;
6333
            rn = (insn >> 16) & 0xf;
6334
            tmp = load_reg(s, rm);
6335
            tmp2 = load_reg(s, rn);
6336
            if (op1 & 2)
6337
                gen_helper_double_saturate(tmp2, tmp2);
6338
            if (op1 & 1)
6339
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6340
            else
6341
                gen_helper_add_saturate(tmp, tmp, tmp2);
6342
            dead_tmp(tmp2);
6343
            store_reg(s, rd, tmp);
6344
            break;
6345
        case 7: /* bkpt */
6346
            gen_set_condexec(s);
6347
            gen_set_pc_im(s->pc - 4);
6348
            gen_exception(EXCP_BKPT);
6349
            s->is_jmp = DISAS_JUMP;
6350
            break;
6351
        case 0x8: /* signed multiply */
6352
        case 0xa:
6353
        case 0xc:
6354
        case 0xe:
6355
            rs = (insn >> 8) & 0xf;
6356
            rn = (insn >> 12) & 0xf;
6357
            rd = (insn >> 16) & 0xf;
6358
            if (op1 == 1) {
6359
                /* (32 * 16) >> 16 */
6360
                tmp = load_reg(s, rm);
6361
                tmp2 = load_reg(s, rs);
6362
                if (sh & 4)
6363
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6364
                else
6365
                    gen_sxth(tmp2);
6366
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
6367
                tcg_gen_shri_i64(tmp64, tmp64, 16);
6368
                tmp = new_tmp();
6369
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6370
                tcg_temp_free_i64(tmp64);
6371
                if ((sh & 2) == 0) {
6372
                    tmp2 = load_reg(s, rn);
6373
                    gen_helper_add_setq(tmp, tmp, tmp2);
6374
                    dead_tmp(tmp2);
6375
                }
6376
                store_reg(s, rd, tmp);
6377
            } else {
6378
                /* 16 * 16 */
6379
                tmp = load_reg(s, rm);
6380
                tmp2 = load_reg(s, rs);
6381
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6382
                dead_tmp(tmp2);
6383
                if (op1 == 2) {
6384
                    tmp64 = tcg_temp_new_i64();
6385
                    tcg_gen_ext_i32_i64(tmp64, tmp);
6386
                    dead_tmp(tmp);
6387
                    gen_addq(s, tmp64, rn, rd);
6388
                    gen_storeq_reg(s, rn, rd, tmp64);
6389
                    tcg_temp_free_i64(tmp64);
6390
                } else {
6391
                    if (op1 == 0) {
6392
                        tmp2 = load_reg(s, rn);
6393
                        gen_helper_add_setq(tmp, tmp, tmp2);
6394
                        dead_tmp(tmp2);
6395
                    }
6396
                    store_reg(s, rd, tmp);
6397
                }
6398
            }
6399
            break;
6400
        default:
6401
            goto illegal_op;
6402
        }
6403
    } else if (((insn & 0x0e000000) == 0 &&
6404
                (insn & 0x00000090) != 0x90) ||
6405
               ((insn & 0x0e000000) == (1 << 25))) {
6406
        int set_cc, logic_cc, shiftop;
6407

    
6408
        op1 = (insn >> 21) & 0xf;
6409
        set_cc = (insn >> 20) & 1;
6410
        logic_cc = table_logic_cc[op1] & set_cc;
6411

    
6412
        /* data processing instruction */
6413
        if (insn & (1 << 25)) {
6414
            /* immediate operand */
6415
            val = insn & 0xff;
6416
            shift = ((insn >> 8) & 0xf) * 2;
6417
            if (shift) {
6418
                val = (val >> shift) | (val << (32 - shift));
6419
            }
6420
            tmp2 = new_tmp();
6421
            tcg_gen_movi_i32(tmp2, val);
6422
            if (logic_cc && shift) {
6423
                gen_set_CF_bit31(tmp2);
6424
            }
6425
        } else {
6426
            /* register */
6427
            rm = (insn) & 0xf;
6428
            tmp2 = load_reg(s, rm);
6429
            shiftop = (insn >> 5) & 3;
6430
            if (!(insn & (1 << 4))) {
6431
                shift = (insn >> 7) & 0x1f;
6432
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6433
            } else {
6434
                rs = (insn >> 8) & 0xf;
6435
                tmp = load_reg(s, rs);
6436
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6437
            }
6438
        }
6439
        if (op1 != 0x0f && op1 != 0x0d) {
6440
            rn = (insn >> 16) & 0xf;
6441
            tmp = load_reg(s, rn);
6442
        } else {
6443
            TCGV_UNUSED(tmp);
6444
        }
6445
        rd = (insn >> 12) & 0xf;
6446
        switch(op1) {
6447
        case 0x00:
6448
            tcg_gen_and_i32(tmp, tmp, tmp2);
6449
            if (logic_cc) {
6450
                gen_logic_CC(tmp);
6451
            }
6452
            store_reg_bx(env, s, rd, tmp);
6453
            break;
6454
        case 0x01:
6455
            tcg_gen_xor_i32(tmp, tmp, tmp2);
6456
            if (logic_cc) {
6457
                gen_logic_CC(tmp);
6458
            }
6459
            store_reg_bx(env, s, rd, tmp);
6460
            break;
6461
        case 0x02:
6462
            if (set_cc && rd == 15) {
6463
                /* SUBS r15, ... is used for exception return.  */
6464
                if (IS_USER(s)) {
6465
                    goto illegal_op;
6466
                }
6467
                gen_helper_sub_cc(tmp, tmp, tmp2);
6468
                gen_exception_return(s, tmp);
6469
            } else {
6470
                if (set_cc) {
6471
                    gen_helper_sub_cc(tmp, tmp, tmp2);
6472
                } else {
6473
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
6474
                }
6475
                store_reg_bx(env, s, rd, tmp);
6476
            }
6477
            break;
6478
        case 0x03:
6479
            if (set_cc) {
6480
                gen_helper_sub_cc(tmp, tmp2, tmp);
6481
            } else {
6482
                tcg_gen_sub_i32(tmp, tmp2, tmp);
6483
            }
6484
            store_reg_bx(env, s, rd, tmp);
6485
            break;
6486
        case 0x04:
6487
            if (set_cc) {
6488
                gen_helper_add_cc(tmp, tmp, tmp2);
6489
            } else {
6490
                tcg_gen_add_i32(tmp, tmp, tmp2);
6491
            }
6492
            store_reg_bx(env, s, rd, tmp);
6493
            break;
6494
        case 0x05:
6495
            if (set_cc) {
6496
                gen_helper_adc_cc(tmp, tmp, tmp2);
6497
            } else {
6498
                gen_add_carry(tmp, tmp, tmp2);
6499
            }
6500
            store_reg_bx(env, s, rd, tmp);
6501
            break;
6502
        case 0x06:
6503
            if (set_cc) {
6504
                gen_helper_sbc_cc(tmp, tmp, tmp2);
6505
            } else {
6506
                gen_sub_carry(tmp, tmp, tmp2);
6507
            }
6508
            store_reg_bx(env, s, rd, tmp);
6509
            break;
6510
        case 0x07:
6511
            if (set_cc) {
6512
                gen_helper_sbc_cc(tmp, tmp2, tmp);
6513
            } else {
6514
                gen_sub_carry(tmp, tmp2, tmp);
6515
            }
6516
            store_reg_bx(env, s, rd, tmp);
6517
            break;
6518
        case 0x08:
6519
            if (set_cc) {
6520
                tcg_gen_and_i32(tmp, tmp, tmp2);
6521
                gen_logic_CC(tmp);
6522
            }
6523
            dead_tmp(tmp);
6524
            break;
6525
        case 0x09:
6526
            if (set_cc) {
6527
                tcg_gen_xor_i32(tmp, tmp, tmp2);
6528
                gen_logic_CC(tmp);
6529
            }
6530
            dead_tmp(tmp);
6531
            break;
6532
        case 0x0a:
6533
            if (set_cc) {
6534
                gen_helper_sub_cc(tmp, tmp, tmp2);
6535
            }
6536
            dead_tmp(tmp);
6537
            break;
6538
        case 0x0b:
6539
            if (set_cc) {
6540
                gen_helper_add_cc(tmp, tmp, tmp2);
6541
            }
6542
            dead_tmp(tmp);
6543
            break;
6544
        case 0x0c:
6545
            tcg_gen_or_i32(tmp, tmp, tmp2);
6546
            if (logic_cc) {
6547
                gen_logic_CC(tmp);
6548
            }
6549
            store_reg_bx(env, s, rd, tmp);
6550
            break;
6551
        case 0x0d:
6552
            if (logic_cc && rd == 15) {
6553
                /* MOVS r15, ... is used for exception return.  */
6554
                if (IS_USER(s)) {
6555
                    goto illegal_op;
6556
                }
6557
                gen_exception_return(s, tmp2);
6558
            } else {
6559
                if (logic_cc) {
6560
                    gen_logic_CC(tmp2);
6561
                }
6562
                store_reg_bx(env, s, rd, tmp2);
6563
            }
6564
            break;
6565
        case 0x0e:
6566
            tcg_gen_andc_i32(tmp, tmp, tmp2);
6567
            if (logic_cc) {
6568
                gen_logic_CC(tmp);
6569
            }
6570
            store_reg_bx(env, s, rd, tmp);
6571
            break;
6572
        default:
6573
        case 0x0f:
6574
            tcg_gen_not_i32(tmp2, tmp2);
6575
            if (logic_cc) {
6576
                gen_logic_CC(tmp2);
6577
            }
6578
            store_reg_bx(env, s, rd, tmp2);
6579
            break;
6580
        }
6581
        if (op1 != 0x0f && op1 != 0x0d) {
6582
            dead_tmp(tmp2);
6583
        }
6584
    } else {
6585
        /* other instructions */
6586
        op1 = (insn >> 24) & 0xf;
6587
        switch(op1) {
6588
        case 0x0:
6589
        case 0x1:
6590
            /* multiplies, extra load/stores */
6591
            sh = (insn >> 5) & 3;
6592
            if (sh == 0) {
6593
                if (op1 == 0x0) {
6594
                    rd = (insn >> 16) & 0xf;
6595
                    rn = (insn >> 12) & 0xf;
6596
                    rs = (insn >> 8) & 0xf;
6597
                    rm = (insn) & 0xf;
6598
                    op1 = (insn >> 20) & 0xf;
6599
                    switch (op1) {
6600
                    case 0: case 1: case 2: case 3: case 6:
6601
                        /* 32 bit mul */
6602
                        tmp = load_reg(s, rs);
6603
                        tmp2 = load_reg(s, rm);
6604
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
6605
                        dead_tmp(tmp2);
6606
                        if (insn & (1 << 22)) {
6607
                            /* Subtract (mls) */
6608
                            ARCH(6T2);
6609
                            tmp2 = load_reg(s, rn);
6610
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
6611
                            dead_tmp(tmp2);
6612
                        } else if (insn & (1 << 21)) {
6613
                            /* Add */
6614
                            tmp2 = load_reg(s, rn);
6615
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6616
                            dead_tmp(tmp2);
6617
                        }
6618
                        if (insn & (1 << 20))
6619
                            gen_logic_CC(tmp);
6620
                        store_reg(s, rd, tmp);
6621
                        break;
6622
                    default:
6623
                        /* 64 bit mul */
6624
                        tmp = load_reg(s, rs);
6625
                        tmp2 = load_reg(s, rm);
6626
                        if (insn & (1 << 22))
6627
                            tmp64 = gen_muls_i64_i32(tmp, tmp2);
6628
                        else
6629
                            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6630
                        if (insn & (1 << 21)) /* mult accumulate */
6631
                            gen_addq(s, tmp64, rn, rd);
6632
                        if (!(insn & (1 << 23))) { /* double accumulate */
6633
                            ARCH(6);
6634
                            gen_addq_lo(s, tmp64, rn);
6635
                            gen_addq_lo(s, tmp64, rd);
6636
                        }
6637
                        if (insn & (1 << 20))
6638
                            gen_logicq_cc(tmp64);
6639
                        gen_storeq_reg(s, rn, rd, tmp64);
6640
                        tcg_temp_free_i64(tmp64);
6641
                        break;
6642
                    }
6643
                } else {
6644
                    rn = (insn >> 16) & 0xf;
6645
                    rd = (insn >> 12) & 0xf;
6646
                    if (insn & (1 << 23)) {
6647
                        /* load/store exclusive */
6648
                        op1 = (insn >> 21) & 0x3;
6649
                        if (op1)
6650
                            ARCH(6K);
6651
                        else
6652
                            ARCH(6);
6653
                        addr = tcg_temp_local_new_i32();
6654
                        load_reg_var(s, addr, rn);
6655
                        if (insn & (1 << 20)) {
6656
                            switch (op1) {
6657
                            case 0: /* ldrex */
6658
                                gen_load_exclusive(s, rd, 15, addr, 2);
6659
                                break;
6660
                            case 1: /* ldrexd */
6661
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
6662
                                break;
6663
                            case 2: /* ldrexb */
6664
                                gen_load_exclusive(s, rd, 15, addr, 0);
6665
                                break;
6666
                            case 3: /* ldrexh */
6667
                                gen_load_exclusive(s, rd, 15, addr, 1);
6668
                                break;
6669
                            default:
6670
                                abort();
6671
                            }
6672
                        } else {
6673
                            rm = insn & 0xf;
6674
                            switch (op1) {
6675
                            case 0:  /*  strex */
6676
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
6677
                                break;
6678
                            case 1: /*  strexd */
6679
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
6680
                                break;
6681
                            case 2: /*  strexb */
6682
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
6683
                                break;
6684
                            case 3: /* strexh */
6685
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
6686
                                break;
6687
                            default:
6688
                                abort();
6689
                            }
6690
                        }
6691
                        tcg_temp_free(addr);
6692
                    } else {
6693
                        /* SWP instruction */
6694
                        rm = (insn) & 0xf;
6695

    
6696
                        /* ??? This is not really atomic.  However we know
6697
                           we never have multiple CPUs running in parallel,
6698
                           so it is good enough.  */
6699
                        addr = load_reg(s, rn);
6700
                        tmp = load_reg(s, rm);
6701
                        if (insn & (1 << 22)) {
6702
                            tmp2 = gen_ld8u(addr, IS_USER(s));
6703
                            gen_st8(tmp, addr, IS_USER(s));
6704
                        } else {
6705
                            tmp2 = gen_ld32(addr, IS_USER(s));
6706
                            gen_st32(tmp, addr, IS_USER(s));
6707
                        }
6708
                        dead_tmp(addr);
6709
                        store_reg(s, rd, tmp2);
6710
                    }
6711
                }
6712
            } else {
6713
                int address_offset;
6714
                int load;
6715
                /* Misc load/store */
6716
                rn = (insn >> 16) & 0xf;
6717
                rd = (insn >> 12) & 0xf;
6718
                addr = load_reg(s, rn);
6719
                if (insn & (1 << 24))
6720
                    gen_add_datah_offset(s, insn, 0, addr);
6721
                address_offset = 0;
6722
                if (insn & (1 << 20)) {
6723
                    /* load */
6724
                    switch(sh) {
6725
                    case 1:
6726
                        tmp = gen_ld16u(addr, IS_USER(s));
6727
                        break;
6728
                    case 2:
6729
                        tmp = gen_ld8s(addr, IS_USER(s));
6730
                        break;
6731
                    default:
6732
                    case 3:
6733
                        tmp = gen_ld16s(addr, IS_USER(s));
6734
                        break;
6735
                    }
6736
                    load = 1;
6737
                } else if (sh & 2) {
6738
                    /* doubleword */
6739
                    if (sh & 1) {
6740
                        /* store */
6741
                        tmp = load_reg(s, rd);
6742
                        gen_st32(tmp, addr, IS_USER(s));
6743
                        tcg_gen_addi_i32(addr, addr, 4);
6744
                        tmp = load_reg(s, rd + 1);
6745
                        gen_st32(tmp, addr, IS_USER(s));
6746
                        load = 0;
6747
                    } else {
6748
                        /* load */
6749
                        tmp = gen_ld32(addr, IS_USER(s));
6750
                        store_reg(s, rd, tmp);
6751
                        tcg_gen_addi_i32(addr, addr, 4);
6752
                        tmp = gen_ld32(addr, IS_USER(s));
6753
                        rd++;
6754
                        load = 1;
6755
                    }
6756
                    address_offset = -4;
6757
                } else {
6758
                    /* store */
6759
                    tmp = load_reg(s, rd);
6760
                    gen_st16(tmp, addr, IS_USER(s));
6761
                    load = 0;
6762
                }
6763
                /* Perform base writeback before the loaded value to
6764
                   ensure correct behavior with overlapping index registers.
6765
                   ldrd with base writeback is is undefined if the
6766
                   destination and index registers overlap.  */
6767
                if (!(insn & (1 << 24))) {
6768
                    gen_add_datah_offset(s, insn, address_offset, addr);
6769
                    store_reg(s, rn, addr);
6770
                } else if (insn & (1 << 21)) {
6771
                    if (address_offset)
6772
                        tcg_gen_addi_i32(addr, addr, address_offset);
6773
                    store_reg(s, rn, addr);
6774
                } else {
6775
                    dead_tmp(addr);
6776
                }
6777
                if (load) {
6778
                    /* Complete the load.  */
6779
                    store_reg(s, rd, tmp);
6780
                }
6781
            }
6782
            break;
6783
        case 0x4:
6784
        case 0x5:
6785
            goto do_ldst;
6786
        case 0x6:
6787
        case 0x7:
6788
            if (insn & (1 << 4)) {
6789
                ARCH(6);
6790
                /* Armv6 Media instructions.  */
6791
                rm = insn & 0xf;
6792
                rn = (insn >> 16) & 0xf;
6793
                rd = (insn >> 12) & 0xf;
6794
                rs = (insn >> 8) & 0xf;
6795
                switch ((insn >> 23) & 3) {
6796
                case 0: /* Parallel add/subtract.  */
6797
                    op1 = (insn >> 20) & 7;
6798
                    tmp = load_reg(s, rn);
6799
                    tmp2 = load_reg(s, rm);
6800
                    sh = (insn >> 5) & 7;
6801
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6802
                        goto illegal_op;
6803
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6804
                    dead_tmp(tmp2);
6805
                    store_reg(s, rd, tmp);
6806
                    break;
6807
                case 1:
6808
                    if ((insn & 0x00700020) == 0) {
6809
                        /* Halfword pack.  */
6810
                        tmp = load_reg(s, rn);
6811
                        tmp2 = load_reg(s, rm);
6812
                        shift = (insn >> 7) & 0x1f;
6813
                        if (insn & (1 << 6)) {
6814
                            /* pkhtb */
6815
                            if (shift == 0)
6816
                                shift = 31;
6817
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
6818
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6819
                            tcg_gen_ext16u_i32(tmp2, tmp2);
6820
                        } else {
6821
                            /* pkhbt */
6822
                            if (shift)
6823
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
6824
                            tcg_gen_ext16u_i32(tmp, tmp);
6825
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6826
                        }
6827
                        tcg_gen_or_i32(tmp, tmp, tmp2);
6828
                        dead_tmp(tmp2);
6829
                        store_reg(s, rd, tmp);
6830
                    } else if ((insn & 0x00200020) == 0x00200000) {
6831
                        /* [us]sat */
6832
                        tmp = load_reg(s, rm);
6833
                        shift = (insn >> 7) & 0x1f;
6834
                        if (insn & (1 << 6)) {
6835
                            if (shift == 0)
6836
                                shift = 31;
6837
                            tcg_gen_sari_i32(tmp, tmp, shift);
6838
                        } else {
6839
                            tcg_gen_shli_i32(tmp, tmp, shift);
6840
                        }
6841
                        sh = (insn >> 16) & 0x1f;
6842
                        if (sh != 0) {
6843
                            tmp2 = tcg_const_i32(sh);
6844
                            if (insn & (1 << 22))
6845
                                gen_helper_usat(tmp, tmp, tmp2);
6846
                            else
6847
                                gen_helper_ssat(tmp, tmp, tmp2);
6848
                            tcg_temp_free_i32(tmp2);
6849
                        }
6850
                        store_reg(s, rd, tmp);
6851
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
6852
                        /* [us]sat16 */
6853
                        tmp = load_reg(s, rm);
6854
                        sh = (insn >> 16) & 0x1f;
6855
                        if (sh != 0) {
6856
                            tmp2 = tcg_const_i32(sh);
6857
                            if (insn & (1 << 22))
6858
                                gen_helper_usat16(tmp, tmp, tmp2);
6859
                            else
6860
                                gen_helper_ssat16(tmp, tmp, tmp2);
6861
                            tcg_temp_free_i32(tmp2);
6862
                        }
6863
                        store_reg(s, rd, tmp);
6864
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6865
                        /* Select bytes.  */
6866
                        tmp = load_reg(s, rn);
6867
                        tmp2 = load_reg(s, rm);
6868
                        tmp3 = new_tmp();
6869
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6870
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6871
                        dead_tmp(tmp3);
6872
                        dead_tmp(tmp2);
6873
                        store_reg(s, rd, tmp);
6874
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6875
                        tmp = load_reg(s, rm);
6876
                        shift = (insn >> 10) & 3;
6877
                        /* ??? In many cases it's not neccessary to do a
6878
                           rotate, a shift is sufficient.  */
6879
                        if (shift != 0)
6880
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
6881
                        op1 = (insn >> 20) & 7;
6882
                        switch (op1) {
6883
                        case 0: gen_sxtb16(tmp);  break;
6884
                        case 2: gen_sxtb(tmp);    break;
6885
                        case 3: gen_sxth(tmp);    break;
6886
                        case 4: gen_uxtb16(tmp);  break;
6887
                        case 6: gen_uxtb(tmp);    break;
6888
                        case 7: gen_uxth(tmp);    break;
6889
                        default: goto illegal_op;
6890
                        }
6891
                        if (rn != 15) {
6892
                            tmp2 = load_reg(s, rn);
6893
                            if ((op1 & 3) == 0) {
6894
                                gen_add16(tmp, tmp2);
6895
                            } else {
6896
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6897
                                dead_tmp(tmp2);
6898
                            }
6899
                        }
6900
                        store_reg(s, rd, tmp);
6901
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6902
                        /* rev */
6903
                        tmp = load_reg(s, rm);
6904
                        if (insn & (1 << 22)) {
6905
                            if (insn & (1 << 7)) {
6906
                                gen_revsh(tmp);
6907
                            } else {
6908
                                ARCH(6T2);
6909
                                gen_helper_rbit(tmp, tmp);
6910
                            }
6911
                        } else {
6912
                            if (insn & (1 << 7))
6913
                                gen_rev16(tmp);
6914
                            else
6915
                                tcg_gen_bswap32_i32(tmp, tmp);
6916
                        }
6917
                        store_reg(s, rd, tmp);
6918
                    } else {
6919
                        goto illegal_op;
6920
                    }
6921
                    break;
6922
                case 2: /* Multiplies (Type 3).  */
6923
                    tmp = load_reg(s, rm);
6924
                    tmp2 = load_reg(s, rs);
6925
                    if (insn & (1 << 20)) {
6926
                        /* Signed multiply most significant [accumulate].  */
6927
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
6928
                        if (insn & (1 << 5))
6929
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
6930
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
6931
                        tmp = new_tmp();
6932
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
6933
                        tcg_temp_free_i64(tmp64);
6934
                        if (rd != 15) {
6935
                            tmp2 = load_reg(s, rd);
6936
                            if (insn & (1 << 6)) {
6937
                                tcg_gen_sub_i32(tmp, tmp, tmp2);
6938
                            } else {
6939
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6940
                            }
6941
                            dead_tmp(tmp2);
6942
                        }
6943
                        store_reg(s, rn, tmp);
6944
                    } else {
6945
                        if (insn & (1 << 5))
6946
                            gen_swap_half(tmp2);
6947
                        gen_smul_dual(tmp, tmp2);
6948
                        /* This addition cannot overflow.  */
6949
                        if (insn & (1 << 6)) {
6950
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
6951
                        } else {
6952
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6953
                        }
6954
                        dead_tmp(tmp2);
6955
                        if (insn & (1 << 22)) {
6956
                            /* smlald, smlsld */
6957
                            tmp64 = tcg_temp_new_i64();
6958
                            tcg_gen_ext_i32_i64(tmp64, tmp);
6959
                            dead_tmp(tmp);
6960
                            gen_addq(s, tmp64, rd, rn);
6961
                            gen_storeq_reg(s, rd, rn, tmp64);
6962
                            tcg_temp_free_i64(tmp64);
6963
                        } else {
6964
                            /* smuad, smusd, smlad, smlsd */
6965
                            if (rd != 15)
6966
                              {
6967
                                tmp2 = load_reg(s, rd);
6968
                                gen_helper_add_setq(tmp, tmp, tmp2);
6969
                                dead_tmp(tmp2);
6970
                              }
6971
                            store_reg(s, rn, tmp);
6972
                        }
6973
                    }
6974
                    break;
6975
                case 3:
6976
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6977
                    switch (op1) {
6978
                    case 0: /* Unsigned sum of absolute differences.  */
6979
                        ARCH(6);
6980
                        tmp = load_reg(s, rm);
6981
                        tmp2 = load_reg(s, rs);
6982
                        gen_helper_usad8(tmp, tmp, tmp2);
6983
                        dead_tmp(tmp2);
6984
                        if (rd != 15) {
6985
                            tmp2 = load_reg(s, rd);
6986
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6987
                            dead_tmp(tmp2);
6988
                        }
6989
                        store_reg(s, rn, tmp);
6990
                        break;
6991
                    case 0x20: case 0x24: case 0x28: case 0x2c:
6992
                        /* Bitfield insert/clear.  */
6993
                        ARCH(6T2);
6994
                        shift = (insn >> 7) & 0x1f;
6995
                        i = (insn >> 16) & 0x1f;
6996
                        i = i + 1 - shift;
6997
                        if (rm == 15) {
6998
                            tmp = new_tmp();
6999
                            tcg_gen_movi_i32(tmp, 0);
7000
                        } else {
7001
                            tmp = load_reg(s, rm);
7002
                        }
7003
                        if (i != 32) {
7004
                            tmp2 = load_reg(s, rd);
7005
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
7006
                            dead_tmp(tmp2);
7007
                        }
7008
                        store_reg(s, rd, tmp);
7009
                        break;
7010
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7011
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7012
                        ARCH(6T2);
7013
                        tmp = load_reg(s, rm);
7014
                        shift = (insn >> 7) & 0x1f;
7015
                        i = ((insn >> 16) & 0x1f) + 1;
7016
                        if (shift + i > 32)
7017
                            goto illegal_op;
7018
                        if (i < 32) {
7019
                            if (op1 & 0x20) {
7020
                                gen_ubfx(tmp, shift, (1u << i) - 1);
7021
                            } else {
7022
                                gen_sbfx(tmp, shift, i);
7023
                            }
7024
                        }
7025
                        store_reg(s, rd, tmp);
7026
                        break;
7027
                    default:
7028
                        goto illegal_op;
7029
                    }
7030
                    break;
7031
                }
7032
                break;
7033
            }
7034
        do_ldst:
7035
            /* Check for undefined extension instructions
7036
             * per the ARM Bible IE:
7037
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
7038
             */
7039
            sh = (0xf << 20) | (0xf << 4);
7040
            if (op1 == 0x7 && ((insn & sh) == sh))
7041
            {
7042
                goto illegal_op;
7043
            }
7044
            /* load/store byte/word */
7045
            rn = (insn >> 16) & 0xf;
7046
            rd = (insn >> 12) & 0xf;
7047
            tmp2 = load_reg(s, rn);
7048
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7049
            if (insn & (1 << 24))
7050
                gen_add_data_offset(s, insn, tmp2);
7051
            if (insn & (1 << 20)) {
7052
                /* load */
7053
                if (insn & (1 << 22)) {
7054
                    tmp = gen_ld8u(tmp2, i);
7055
                } else {
7056
                    tmp = gen_ld32(tmp2, i);
7057
                }
7058
            } else {
7059
                /* store */
7060
                tmp = load_reg(s, rd);
7061
                if (insn & (1 << 22))
7062
                    gen_st8(tmp, tmp2, i);
7063
                else
7064
                    gen_st32(tmp, tmp2, i);
7065
            }
7066
            if (!(insn & (1 << 24))) {
7067
                gen_add_data_offset(s, insn, tmp2);
7068
                store_reg(s, rn, tmp2);
7069
            } else if (insn & (1 << 21)) {
7070
                store_reg(s, rn, tmp2);
7071
            } else {
7072
                dead_tmp(tmp2);
7073
            }
7074
            if (insn & (1 << 20)) {
7075
                /* Complete the load.  */
7076
                if (rd == 15)
7077
                    gen_bx(s, tmp);
7078
                else
7079
                    store_reg(s, rd, tmp);
7080
            }
7081
            break;
7082
        case 0x08:
7083
        case 0x09:
7084
            {
7085
                int j, n, user, loaded_base;
7086
                TCGv loaded_var;
7087
                /* load/store multiple words */
7088
                /* XXX: store correct base if write back */
7089
                user = 0;
7090
                if (insn & (1 << 22)) {
7091
                    if (IS_USER(s))
7092
                        goto illegal_op; /* only usable in supervisor mode */
7093

    
7094
                    if ((insn & (1 << 15)) == 0)
7095
                        user = 1;
7096
                }
7097
                rn = (insn >> 16) & 0xf;
7098
                addr = load_reg(s, rn);
7099

    
7100
                /* compute total size */
7101
                loaded_base = 0;
7102
                TCGV_UNUSED(loaded_var);
7103
                n = 0;
7104
                for(i=0;i<16;i++) {
7105
                    if (insn & (1 << i))
7106
                        n++;
7107
                }
7108
                /* XXX: test invalid n == 0 case ? */
7109
                if (insn & (1 << 23)) {
7110
                    if (insn & (1 << 24)) {
7111
                        /* pre increment */
7112
                        tcg_gen_addi_i32(addr, addr, 4);
7113
                    } else {
7114
                        /* post increment */
7115
                    }
7116
                } else {
7117
                    if (insn & (1 << 24)) {
7118
                        /* pre decrement */
7119
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
7120
                    } else {
7121
                        /* post decrement */
7122
                        if (n != 1)
7123
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7124
                    }
7125
                }
7126
                j = 0;
7127
                for(i=0;i<16;i++) {
7128
                    if (insn & (1 << i)) {
7129
                        if (insn & (1 << 20)) {
7130
                            /* load */
7131
                            tmp = gen_ld32(addr, IS_USER(s));
7132
                            if (i == 15) {
7133
                                gen_bx(s, tmp);
7134
                            } else if (user) {
7135
                                tmp2 = tcg_const_i32(i);
7136
                                gen_helper_set_user_reg(tmp2, tmp);
7137
                                tcg_temp_free_i32(tmp2);
7138
                                dead_tmp(tmp);
7139
                            } else if (i == rn) {
7140
                                loaded_var = tmp;
7141
                                loaded_base = 1;
7142
                            } else {
7143
                                store_reg(s, i, tmp);
7144
                            }
7145
                        } else {
7146
                            /* store */
7147
                            if (i == 15) {
7148
                                /* special case: r15 = PC + 8 */
7149
                                val = (long)s->pc + 4;
7150
                                tmp = new_tmp();
7151
                                tcg_gen_movi_i32(tmp, val);
7152
                            } else if (user) {
7153
                                tmp = new_tmp();
7154
                                tmp2 = tcg_const_i32(i);
7155
                                gen_helper_get_user_reg(tmp, tmp2);
7156
                                tcg_temp_free_i32(tmp2);
7157
                            } else {
7158
                                tmp = load_reg(s, i);
7159
                            }
7160
                            gen_st32(tmp, addr, IS_USER(s));
7161
                        }
7162
                        j++;
7163
                        /* no need to add after the last transfer */
7164
                        if (j != n)
7165
                            tcg_gen_addi_i32(addr, addr, 4);
7166
                    }
7167
                }
7168
                if (insn & (1 << 21)) {
7169
                    /* write back */
7170
                    if (insn & (1 << 23)) {
7171
                        if (insn & (1 << 24)) {
7172
                            /* pre increment */
7173
                        } else {
7174
                            /* post increment */
7175
                            tcg_gen_addi_i32(addr, addr, 4);
7176
                        }
7177
                    } else {
7178
                        if (insn & (1 << 24)) {
7179
                            /* pre decrement */
7180
                            if (n != 1)
7181
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7182
                        } else {
7183
                            /* post decrement */
7184
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
7185
                        }
7186
                    }
7187
                    store_reg(s, rn, addr);
7188
                } else {
7189
                    dead_tmp(addr);
7190
                }
7191
                if (loaded_base) {
7192
                    store_reg(s, rn, loaded_var);
7193
                }
7194
                if ((insn & (1 << 22)) && !user) {
7195
                    /* Restore CPSR from SPSR.  */
7196
                    tmp = load_cpu_field(spsr);
7197
                    gen_set_cpsr(tmp, 0xffffffff);
7198
                    dead_tmp(tmp);
7199
                    s->is_jmp = DISAS_UPDATE;
7200
                }
7201
            }
7202
            break;
7203
        case 0xa:
7204
        case 0xb:
7205
            {
7206
                int32_t offset;
7207

    
7208
                /* branch (and link) */
7209
                val = (int32_t)s->pc;
7210
                if (insn & (1 << 24)) {
7211
                    tmp = new_tmp();
7212
                    tcg_gen_movi_i32(tmp, val);
7213
                    store_reg(s, 14, tmp);
7214
                }
7215
                offset = (((int32_t)insn << 8) >> 8);
7216
                val += (offset << 2) + 4;
7217
                gen_jmp(s, val);
7218
            }
7219
            break;
7220
        case 0xc:
7221
        case 0xd:
7222
        case 0xe:
7223
            /* Coprocessor.  */
7224
            if (disas_coproc_insn(env, s, insn))
7225
                goto illegal_op;
7226
            break;
7227
        case 0xf:
7228
            /* swi */
7229
            gen_set_pc_im(s->pc);
7230
            s->is_jmp = DISAS_SWI;
7231
            break;
7232
        default:
7233
        illegal_op:
7234
            gen_set_condexec(s);
7235
            gen_set_pc_im(s->pc - 4);
7236
            gen_exception(EXCP_UDEF);
7237
            s->is_jmp = DISAS_JUMP;
7238
            break;
7239
        }
7240
    }
7241
}
7242

    
7243
/* Return true if this is a Thumb-2 logical op.  */
7244
static int
7245
thumb2_logic_op(int op)
7246
{
7247
    return (op < 8);
7248
}
7249

    
7250
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7251
   then set condition code flags based on the result of the operation.
7252
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7253
   to the high bit of T1.
7254
   Returns zero if the opcode is valid.  */
7255

    
7256
static int
7257
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7258
{
7259
    int logic_cc;
7260

    
7261
    logic_cc = 0;
7262
    switch (op) {
7263
    case 0: /* and */
7264
        tcg_gen_and_i32(t0, t0, t1);
7265
        logic_cc = conds;
7266
        break;
7267
    case 1: /* bic */
7268
        tcg_gen_andc_i32(t0, t0, t1);
7269
        logic_cc = conds;
7270
        break;
7271
    case 2: /* orr */
7272
        tcg_gen_or_i32(t0, t0, t1);
7273
        logic_cc = conds;
7274
        break;
7275
    case 3: /* orn */
7276
        tcg_gen_not_i32(t1, t1);
7277
        tcg_gen_or_i32(t0, t0, t1);
7278
        logic_cc = conds;
7279
        break;
7280
    case 4: /* eor */
7281
        tcg_gen_xor_i32(t0, t0, t1);
7282
        logic_cc = conds;
7283
        break;
7284
    case 8: /* add */
7285
        if (conds)
7286
            gen_helper_add_cc(t0, t0, t1);
7287
        else
7288
            tcg_gen_add_i32(t0, t0, t1);
7289
        break;
7290
    case 10: /* adc */
7291
        if (conds)
7292
            gen_helper_adc_cc(t0, t0, t1);
7293
        else
7294
            gen_adc(t0, t1);
7295
        break;
7296
    case 11: /* sbc */
7297
        if (conds)
7298
            gen_helper_sbc_cc(t0, t0, t1);
7299
        else
7300
            gen_sub_carry(t0, t0, t1);
7301
        break;
7302
    case 13: /* sub */
7303
        if (conds)
7304
            gen_helper_sub_cc(t0, t0, t1);
7305
        else
7306
            tcg_gen_sub_i32(t0, t0, t1);
7307
        break;
7308
    case 14: /* rsb */
7309
        if (conds)
7310
            gen_helper_sub_cc(t0, t1, t0);
7311
        else
7312
            tcg_gen_sub_i32(t0, t1, t0);
7313
        break;
7314
    default: /* 5, 6, 7, 9, 12, 15. */
7315
        return 1;
7316
    }
7317
    if (logic_cc) {
7318
        gen_logic_CC(t0);
7319
        if (shifter_out)
7320
            gen_set_CF_bit31(t1);
7321
    }
7322
    return 0;
7323
}
7324

    
7325
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7326
   is not legal.  */
7327
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7328
{
7329
    uint32_t insn, imm, shift, offset;
7330
    uint32_t rd, rn, rm, rs;
7331
    TCGv tmp;
7332
    TCGv tmp2;
7333
    TCGv tmp3;
7334
    TCGv addr;
7335
    TCGv_i64 tmp64;
7336
    int op;
7337
    int shiftop;
7338
    int conds;
7339
    int logic_cc;
7340

    
7341
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7342
          || arm_feature (env, ARM_FEATURE_M))) {
7343
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7344
           16-bit instructions to get correct prefetch abort behavior.  */
7345
        insn = insn_hw1;
7346
        if ((insn & (1 << 12)) == 0) {
7347
            /* Second half of blx.  */
7348
            offset = ((insn & 0x7ff) << 1);
7349
            tmp = load_reg(s, 14);
7350
            tcg_gen_addi_i32(tmp, tmp, offset);
7351
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7352

    
7353
            tmp2 = new_tmp();
7354
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7355
            store_reg(s, 14, tmp2);
7356
            gen_bx(s, tmp);
7357
            return 0;
7358
        }
7359
        if (insn & (1 << 11)) {
7360
            /* Second half of bl.  */
7361
            offset = ((insn & 0x7ff) << 1) | 1;
7362
            tmp = load_reg(s, 14);
7363
            tcg_gen_addi_i32(tmp, tmp, offset);
7364

    
7365
            tmp2 = new_tmp();
7366
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7367
            store_reg(s, 14, tmp2);
7368
            gen_bx(s, tmp);
7369
            return 0;
7370
        }
7371
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7372
            /* Instruction spans a page boundary.  Implement it as two
7373
               16-bit instructions in case the second half causes an
7374
               prefetch abort.  */
7375
            offset = ((int32_t)insn << 21) >> 9;
7376
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7377
            return 0;
7378
        }
7379
        /* Fall through to 32-bit decode.  */
7380
    }
7381

    
7382
    insn = lduw_code(s->pc);
7383
    s->pc += 2;
7384
    insn |= (uint32_t)insn_hw1 << 16;
7385

    
7386
    if ((insn & 0xf800e800) != 0xf000e800) {
7387
        ARCH(6T2);
7388
    }
7389

    
7390
    rn = (insn >> 16) & 0xf;
7391
    rs = (insn >> 12) & 0xf;
7392
    rd = (insn >> 8) & 0xf;
7393
    rm = insn & 0xf;
7394
    switch ((insn >> 25) & 0xf) {
7395
    case 0: case 1: case 2: case 3:
7396
        /* 16-bit instructions.  Should never happen.  */
7397
        abort();
7398
    case 4:
7399
        if (insn & (1 << 22)) {
7400
            /* Other load/store, table branch.  */
7401
            if (insn & 0x01200000) {
7402
                /* Load/store doubleword.  */
7403
                if (rn == 15) {
7404
                    addr = new_tmp();
7405
                    tcg_gen_movi_i32(addr, s->pc & ~3);
7406
                } else {
7407
                    addr = load_reg(s, rn);
7408
                }
7409
                offset = (insn & 0xff) * 4;
7410
                if ((insn & (1 << 23)) == 0)
7411
                    offset = -offset;
7412
                if (insn & (1 << 24)) {
7413
                    tcg_gen_addi_i32(addr, addr, offset);
7414
                    offset = 0;
7415
                }
7416
                if (insn & (1 << 20)) {
7417
                    /* ldrd */
7418
                    tmp = gen_ld32(addr, IS_USER(s));
7419
                    store_reg(s, rs, tmp);
7420
                    tcg_gen_addi_i32(addr, addr, 4);
7421
                    tmp = gen_ld32(addr, IS_USER(s));
7422
                    store_reg(s, rd, tmp);
7423
                } else {
7424
                    /* strd */
7425
                    tmp = load_reg(s, rs);
7426
                    gen_st32(tmp, addr, IS_USER(s));
7427
                    tcg_gen_addi_i32(addr, addr, 4);
7428
                    tmp = load_reg(s, rd);
7429
                    gen_st32(tmp, addr, IS_USER(s));
7430
                }
7431
                if (insn & (1 << 21)) {
7432
                    /* Base writeback.  */
7433
                    if (rn == 15)
7434
                        goto illegal_op;
7435
                    tcg_gen_addi_i32(addr, addr, offset - 4);
7436
                    store_reg(s, rn, addr);
7437
                } else {
7438
                    dead_tmp(addr);
7439
                }
7440
            } else if ((insn & (1 << 23)) == 0) {
7441
                /* Load/store exclusive word.  */
7442
                addr = tcg_temp_local_new();
7443
                load_reg_var(s, addr, rn);
7444
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
7445
                if (insn & (1 << 20)) {
7446
                    gen_load_exclusive(s, rs, 15, addr, 2);
7447
                } else {
7448
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
7449
                }
7450
                tcg_temp_free(addr);
7451
            } else if ((insn & (1 << 6)) == 0) {
7452
                /* Table Branch.  */
7453
                if (rn == 15) {
7454
                    addr = new_tmp();
7455
                    tcg_gen_movi_i32(addr, s->pc);
7456
                } else {
7457
                    addr = load_reg(s, rn);
7458
                }
7459
                tmp = load_reg(s, rm);
7460
                tcg_gen_add_i32(addr, addr, tmp);
7461
                if (insn & (1 << 4)) {
7462
                    /* tbh */
7463
                    tcg_gen_add_i32(addr, addr, tmp);
7464
                    dead_tmp(tmp);
7465
                    tmp = gen_ld16u(addr, IS_USER(s));
7466
                } else { /* tbb */
7467
                    dead_tmp(tmp);
7468
                    tmp = gen_ld8u(addr, IS_USER(s));
7469
                }
7470
                dead_tmp(addr);
7471
                tcg_gen_shli_i32(tmp, tmp, 1);
7472
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7473
                store_reg(s, 15, tmp);
7474
            } else {
7475
                /* Load/store exclusive byte/halfword/doubleword.  */
7476
                ARCH(7);
7477
                op = (insn >> 4) & 0x3;
7478
                if (op == 2) {
7479
                    goto illegal_op;
7480
                }
7481
                addr = tcg_temp_local_new();
7482
                load_reg_var(s, addr, rn);
7483
                if (insn & (1 << 20)) {
7484
                    gen_load_exclusive(s, rs, rd, addr, op);
7485
                } else {
7486
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
7487
                }
7488
                tcg_temp_free(addr);
7489
            }
7490
        } else {
7491
            /* Load/store multiple, RFE, SRS.  */
7492
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7493
                /* Not available in user mode.  */
7494
                if (IS_USER(s))
7495
                    goto illegal_op;
7496
                if (insn & (1 << 20)) {
7497
                    /* rfe */
7498
                    addr = load_reg(s, rn);
7499
                    if ((insn & (1 << 24)) == 0)
7500
                        tcg_gen_addi_i32(addr, addr, -8);
7501
                    /* Load PC into tmp and CPSR into tmp2.  */
7502
                    tmp = gen_ld32(addr, 0);
7503
                    tcg_gen_addi_i32(addr, addr, 4);
7504
                    tmp2 = gen_ld32(addr, 0);
7505
                    if (insn & (1 << 21)) {
7506
                        /* Base writeback.  */
7507
                        if (insn & (1 << 24)) {
7508
                            tcg_gen_addi_i32(addr, addr, 4);
7509
                        } else {
7510
                            tcg_gen_addi_i32(addr, addr, -4);
7511
                        }
7512
                        store_reg(s, rn, addr);
7513
                    } else {
7514
                        dead_tmp(addr);
7515
                    }
7516
                    gen_rfe(s, tmp, tmp2);
7517
                } else {
7518
                    /* srs */
7519
                    op = (insn & 0x1f);
7520
                    if (op == (env->uncached_cpsr & CPSR_M)) {
7521
                        addr = load_reg(s, 13);
7522
                    } else {
7523
                        addr = new_tmp();
7524
                        tmp = tcg_const_i32(op);
7525
                        gen_helper_get_r13_banked(addr, cpu_env, tmp);
7526
                        tcg_temp_free_i32(tmp);
7527
                    }
7528
                    if ((insn & (1 << 24)) == 0) {
7529
                        tcg_gen_addi_i32(addr, addr, -8);
7530
                    }
7531
                    tmp = load_reg(s, 14);
7532
                    gen_st32(tmp, addr, 0);
7533
                    tcg_gen_addi_i32(addr, addr, 4);
7534
                    tmp = new_tmp();
7535
                    gen_helper_cpsr_read(tmp);
7536
                    gen_st32(tmp, addr, 0);
7537
                    if (insn & (1 << 21)) {
7538
                        if ((insn & (1 << 24)) == 0) {
7539
                            tcg_gen_addi_i32(addr, addr, -4);
7540
                        } else {
7541
                            tcg_gen_addi_i32(addr, addr, 4);
7542
                        }
7543
                        if (op == (env->uncached_cpsr & CPSR_M)) {
7544
                            store_reg(s, 13, addr);
7545
                        } else {
7546
                            tmp = tcg_const_i32(op);
7547
                            gen_helper_set_r13_banked(cpu_env, tmp, addr);
7548
                            tcg_temp_free_i32(tmp);
7549
                        }
7550
                    } else {
7551
                        dead_tmp(addr);
7552
                    }
7553
                }
7554
            } else {
7555
                int i;
7556
                /* Load/store multiple.  */
7557
                addr = load_reg(s, rn);
7558
                offset = 0;
7559
                for (i = 0; i < 16; i++) {
7560
                    if (insn & (1 << i))
7561
                        offset += 4;
7562
                }
7563
                if (insn & (1 << 24)) {
7564
                    tcg_gen_addi_i32(addr, addr, -offset);
7565
                }
7566

    
7567
                for (i = 0; i < 16; i++) {
7568
                    if ((insn & (1 << i)) == 0)
7569
                        continue;
7570
                    if (insn & (1 << 20)) {
7571
                        /* Load.  */
7572
                        tmp = gen_ld32(addr, IS_USER(s));
7573
                        if (i == 15) {
7574
                            gen_bx(s, tmp);
7575
                        } else {
7576
                            store_reg(s, i, tmp);
7577
                        }
7578
                    } else {
7579
                        /* Store.  */
7580
                        tmp = load_reg(s, i);
7581
                        gen_st32(tmp, addr, IS_USER(s));
7582
                    }
7583
                    tcg_gen_addi_i32(addr, addr, 4);
7584
                }
7585
                if (insn & (1 << 21)) {
7586
                    /* Base register writeback.  */
7587
                    if (insn & (1 << 24)) {
7588
                        tcg_gen_addi_i32(addr, addr, -offset);
7589
                    }
7590
                    /* Fault if writeback register is in register list.  */
7591
                    if (insn & (1 << rn))
7592
                        goto illegal_op;
7593
                    store_reg(s, rn, addr);
7594
                } else {
7595
                    dead_tmp(addr);
7596
                }
7597
            }
7598
        }
7599
        break;
7600
    case 5: /* Data processing register constant shift.  */
7601
        if (rn == 15) {
7602
            tmp = new_tmp();
7603
            tcg_gen_movi_i32(tmp, 0);
7604
        } else {
7605
            tmp = load_reg(s, rn);
7606
        }
7607
        tmp2 = load_reg(s, rm);
7608
        op = (insn >> 21) & 0xf;
7609
        shiftop = (insn >> 4) & 3;
7610
        shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7611
        conds = (insn & (1 << 20)) != 0;
7612
        logic_cc = (conds && thumb2_logic_op(op));
7613
        gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7614
        if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
7615
            goto illegal_op;
7616
        dead_tmp(tmp2);
7617
        if (rd != 15) {
7618
            store_reg(s, rd, tmp);
7619
        } else {
7620
            dead_tmp(tmp);
7621
        }
7622
        break;
7623
    case 13: /* Misc data processing.  */
7624
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7625
        if (op < 4 && (insn & 0xf000) != 0xf000)
7626
            goto illegal_op;
7627
        switch (op) {
7628
        case 0: /* Register controlled shift.  */
7629
            tmp = load_reg(s, rn);
7630
            tmp2 = load_reg(s, rm);
7631
            if ((insn & 0x70) != 0)
7632
                goto illegal_op;
7633
            op = (insn >> 21) & 3;
7634
            logic_cc = (insn & (1 << 20)) != 0;
7635
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7636
            if (logic_cc)
7637
                gen_logic_CC(tmp);
7638
            store_reg_bx(env, s, rd, tmp);
7639
            break;
7640
        case 1: /* Sign/zero extend.  */
7641
            tmp = load_reg(s, rm);
7642
            shift = (insn >> 4) & 3;
7643
            /* ??? In many cases it's not neccessary to do a
7644
               rotate, a shift is sufficient.  */
7645
            if (shift != 0)
7646
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7647
            op = (insn >> 20) & 7;
7648
            switch (op) {
7649
            case 0: gen_sxth(tmp);   break;
7650
            case 1: gen_uxth(tmp);   break;
7651
            case 2: gen_sxtb16(tmp); break;
7652
            case 3: gen_uxtb16(tmp); break;
7653
            case 4: gen_sxtb(tmp);   break;
7654
            case 5: gen_uxtb(tmp);   break;
7655
            default: goto illegal_op;
7656
            }
7657
            if (rn != 15) {
7658
                tmp2 = load_reg(s, rn);
7659
                if ((op >> 1) == 1) {
7660
                    gen_add16(tmp, tmp2);
7661
                } else {
7662
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7663
                    dead_tmp(tmp2);
7664
                }
7665
            }
7666
            store_reg(s, rd, tmp);
7667
            break;
7668
        case 2: /* SIMD add/subtract.  */
7669
            op = (insn >> 20) & 7;
7670
            shift = (insn >> 4) & 7;
7671
            if ((op & 3) == 3 || (shift & 3) == 3)
7672
                goto illegal_op;
7673
            tmp = load_reg(s, rn);
7674
            tmp2 = load_reg(s, rm);
7675
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7676
            dead_tmp(tmp2);
7677
            store_reg(s, rd, tmp);
7678
            break;
7679
        case 3: /* Other data processing.  */
7680
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7681
            if (op < 4) {
7682
                /* Saturating add/subtract.  */
7683
                tmp = load_reg(s, rn);
7684
                tmp2 = load_reg(s, rm);
7685
                if (op & 2)
7686
                    gen_helper_double_saturate(tmp, tmp);
7687
                if (op & 1)
7688
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7689
                else
7690
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7691
                dead_tmp(tmp2);
7692
            } else {
7693
                tmp = load_reg(s, rn);
7694
                switch (op) {
7695
                case 0x0a: /* rbit */
7696
                    gen_helper_rbit(tmp, tmp);
7697
                    break;
7698
                case 0x08: /* rev */
7699
                    tcg_gen_bswap32_i32(tmp, tmp);
7700
                    break;
7701
                case 0x09: /* rev16 */
7702
                    gen_rev16(tmp);
7703
                    break;
7704
                case 0x0b: /* revsh */
7705
                    gen_revsh(tmp);
7706
                    break;
7707
                case 0x10: /* sel */
7708
                    tmp2 = load_reg(s, rm);
7709
                    tmp3 = new_tmp();
7710
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7711
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7712
                    dead_tmp(tmp3);
7713
                    dead_tmp(tmp2);
7714
                    break;
7715
                case 0x18: /* clz */
7716
                    gen_helper_clz(tmp, tmp);
7717
                    break;
7718
                default:
7719
                    goto illegal_op;
7720
                }
7721
            }
7722
            store_reg(s, rd, tmp);
7723
            break;
7724
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7725
            op = (insn >> 4) & 0xf;
7726
            tmp = load_reg(s, rn);
7727
            tmp2 = load_reg(s, rm);
7728
            switch ((insn >> 20) & 7) {
7729
            case 0: /* 32 x 32 -> 32 */
7730
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7731
                dead_tmp(tmp2);
7732
                if (rs != 15) {
7733
                    tmp2 = load_reg(s, rs);
7734
                    if (op)
7735
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7736
                    else
7737
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7738
                    dead_tmp(tmp2);
7739
                }
7740
                break;
7741
            case 1: /* 16 x 16 -> 32 */
7742
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7743
                dead_tmp(tmp2);
7744
                if (rs != 15) {
7745
                    tmp2 = load_reg(s, rs);
7746
                    gen_helper_add_setq(tmp, tmp, tmp2);
7747
                    dead_tmp(tmp2);
7748
                }
7749
                break;
7750
            case 2: /* Dual multiply add.  */
7751
            case 4: /* Dual multiply subtract.  */
7752
                if (op)
7753
                    gen_swap_half(tmp2);
7754
                gen_smul_dual(tmp, tmp2);
7755
                /* This addition cannot overflow.  */
7756
                if (insn & (1 << 22)) {
7757
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7758
                } else {
7759
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7760
                }
7761
                dead_tmp(tmp2);
7762
                if (rs != 15)
7763
                  {
7764
                    tmp2 = load_reg(s, rs);
7765
                    gen_helper_add_setq(tmp, tmp, tmp2);
7766
                    dead_tmp(tmp2);
7767
                  }
7768
                break;
7769
            case 3: /* 32 * 16 -> 32msb */
7770
                if (op)
7771
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7772
                else
7773
                    gen_sxth(tmp2);
7774
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7775
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7776
                tmp = new_tmp();
7777
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7778
                tcg_temp_free_i64(tmp64);
7779
                if (rs != 15)
7780
                  {
7781
                    tmp2 = load_reg(s, rs);
7782
                    gen_helper_add_setq(tmp, tmp, tmp2);
7783
                    dead_tmp(tmp2);
7784
                  }
7785
                break;
7786
            case 5: case 6: /* 32 * 32 -> 32msb */
7787
                gen_imull(tmp, tmp2);
7788
                if (insn & (1 << 5)) {
7789
                    gen_roundqd(tmp, tmp2);
7790
                    dead_tmp(tmp2);
7791
                } else {
7792
                    dead_tmp(tmp);
7793
                    tmp = tmp2;
7794
                }
7795
                if (rs != 15) {
7796
                    tmp2 = load_reg(s, rs);
7797
                    if (insn & (1 << 21)) {
7798
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7799
                    } else {
7800
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7801
                    }
7802
                    dead_tmp(tmp2);
7803
                }
7804
                break;
7805
            case 7: /* Unsigned sum of absolute differences.  */
7806
                gen_helper_usad8(tmp, tmp, tmp2);
7807
                dead_tmp(tmp2);
7808
                if (rs != 15) {
7809
                    tmp2 = load_reg(s, rs);
7810
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7811
                    dead_tmp(tmp2);
7812
                }
7813
                break;
7814
            }
7815
            store_reg(s, rd, tmp);
7816
            break;
7817
        case 6: case 7: /* 64-bit multiply, Divide.  */
7818
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7819
            tmp = load_reg(s, rn);
7820
            tmp2 = load_reg(s, rm);
7821
            if ((op & 0x50) == 0x10) {
7822
                /* sdiv, udiv */
7823
                if (!arm_feature(env, ARM_FEATURE_DIV))
7824
                    goto illegal_op;
7825
                if (op & 0x20)
7826
                    gen_helper_udiv(tmp, tmp, tmp2);
7827
                else
7828
                    gen_helper_sdiv(tmp, tmp, tmp2);
7829
                dead_tmp(tmp2);
7830
                store_reg(s, rd, tmp);
7831
            } else if ((op & 0xe) == 0xc) {
7832
                /* Dual multiply accumulate long.  */
7833
                if (op & 1)
7834
                    gen_swap_half(tmp2);
7835
                gen_smul_dual(tmp, tmp2);
7836
                if (op & 0x10) {
7837
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7838
                } else {
7839
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7840
                }
7841
                dead_tmp(tmp2);
7842
                /* BUGFIX */
7843
                tmp64 = tcg_temp_new_i64();
7844
                tcg_gen_ext_i32_i64(tmp64, tmp);
7845
                dead_tmp(tmp);
7846
                gen_addq(s, tmp64, rs, rd);
7847
                gen_storeq_reg(s, rs, rd, tmp64);
7848
                tcg_temp_free_i64(tmp64);
7849
            } else {
7850
                if (op & 0x20) {
7851
                    /* Unsigned 64-bit multiply  */
7852
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7853
                } else {
7854
                    if (op & 8) {
7855
                        /* smlalxy */
7856
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7857
                        dead_tmp(tmp2);
7858
                        tmp64 = tcg_temp_new_i64();
7859
                        tcg_gen_ext_i32_i64(tmp64, tmp);
7860
                        dead_tmp(tmp);
7861
                    } else {
7862
                        /* Signed 64-bit multiply  */
7863
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7864
                    }
7865
                }
7866
                if (op & 4) {
7867
                    /* umaal */
7868
                    gen_addq_lo(s, tmp64, rs);
7869
                    gen_addq_lo(s, tmp64, rd);
7870
                } else if (op & 0x40) {
7871
                    /* 64-bit accumulate.  */
7872
                    gen_addq(s, tmp64, rs, rd);
7873
                }
7874
                gen_storeq_reg(s, rs, rd, tmp64);
7875
                tcg_temp_free_i64(tmp64);
7876
            }
7877
            break;
7878
        }
7879
        break;
7880
    case 6: case 7: case 14: case 15:
7881
        /* Coprocessor.  */
7882
        if (((insn >> 24) & 3) == 3) {
7883
            /* Translate into the equivalent ARM encoding.  */
7884
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7885
            if (disas_neon_data_insn(env, s, insn))
7886
                goto illegal_op;
7887
        } else {
7888
            if (insn & (1 << 28))
7889
                goto illegal_op;
7890
            if (disas_coproc_insn (env, s, insn))
7891
                goto illegal_op;
7892
        }
7893
        break;
7894
    case 8: case 9: case 10: case 11:
7895
        if (insn & (1 << 15)) {
7896
            /* Branches, misc control.  */
7897
            if (insn & 0x5000) {
7898
                /* Unconditional branch.  */
7899
                /* signextend(hw1[10:0]) -> offset[:12].  */
7900
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7901
                /* hw1[10:0] -> offset[11:1].  */
7902
                offset |= (insn & 0x7ff) << 1;
7903
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7904
                   offset[24:22] already have the same value because of the
7905
                   sign extension above.  */
7906
                offset ^= ((~insn) & (1 << 13)) << 10;
7907
                offset ^= ((~insn) & (1 << 11)) << 11;
7908

    
7909
                if (insn & (1 << 14)) {
7910
                    /* Branch and link.  */
7911
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
7912
                }
7913

    
7914
                offset += s->pc;
7915
                if (insn & (1 << 12)) {
7916
                    /* b/bl */
7917
                    gen_jmp(s, offset);
7918
                } else {
7919
                    /* blx */
7920
                    offset &= ~(uint32_t)2;
7921
                    gen_bx_im(s, offset);
7922
                }
7923
            } else if (((insn >> 23) & 7) == 7) {
7924
                /* Misc control */
7925
                if (insn & (1 << 13))
7926
                    goto illegal_op;
7927

    
7928
                if (insn & (1 << 26)) {
7929
                    /* Secure monitor call (v6Z) */
7930
                    goto illegal_op; /* not implemented.  */
7931
                } else {
7932
                    op = (insn >> 20) & 7;
7933
                    switch (op) {
7934
                    case 0: /* msr cpsr.  */
7935
                        if (IS_M(env)) {
7936
                            tmp = load_reg(s, rn);
7937
                            addr = tcg_const_i32(insn & 0xff);
7938
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7939
                            tcg_temp_free_i32(addr);
7940
                            dead_tmp(tmp);
7941
                            gen_lookup_tb(s);
7942
                            break;
7943
                        }
7944
                        /* fall through */
7945
                    case 1: /* msr spsr.  */
7946
                        if (IS_M(env))
7947
                            goto illegal_op;
7948
                        tmp = load_reg(s, rn);
7949
                        if (gen_set_psr(s,
7950
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7951
                              op == 1, tmp))
7952
                            goto illegal_op;
7953
                        break;
7954
                    case 2: /* cps, nop-hint.  */
7955
                        if (((insn >> 8) & 7) == 0) {
7956
                            gen_nop_hint(s, insn & 0xff);
7957
                        }
7958
                        /* Implemented as NOP in user mode.  */
7959
                        if (IS_USER(s))
7960
                            break;
7961
                        offset = 0;
7962
                        imm = 0;
7963
                        if (insn & (1 << 10)) {
7964
                            if (insn & (1 << 7))
7965
                                offset |= CPSR_A;
7966
                            if (insn & (1 << 6))
7967
                                offset |= CPSR_I;
7968
                            if (insn & (1 << 5))
7969
                                offset |= CPSR_F;
7970
                            if (insn & (1 << 9))
7971
                                imm = CPSR_A | CPSR_I | CPSR_F;
7972
                        }
7973
                        if (insn & (1 << 8)) {
7974
                            offset |= 0x1f;
7975
                            imm |= (insn & 0x1f);
7976
                        }
7977
                        if (offset) {
7978
                            gen_set_psr_im(s, offset, 0, imm);
7979
                        }
7980
                        break;
7981
                    case 3: /* Special control operations.  */
7982
                        ARCH(7);
7983
                        op = (insn >> 4) & 0xf;
7984
                        switch (op) {
7985
                        case 2: /* clrex */
7986
                            gen_clrex(s);
7987
                            break;
7988
                        case 4: /* dsb */
7989
                        case 5: /* dmb */
7990
                        case 6: /* isb */
7991
                            /* These execute as NOPs.  */
7992
                            break;
7993
                        default:
7994
                            goto illegal_op;
7995
                        }
7996
                        break;
7997
                    case 4: /* bxj */
7998
                        /* Trivial implementation equivalent to bx.  */
7999
                        tmp = load_reg(s, rn);
8000
                        gen_bx(s, tmp);
8001
                        break;
8002
                    case 5: /* Exception return.  */
8003
                        if (IS_USER(s)) {
8004
                            goto illegal_op;
8005
                        }
8006
                        if (rn != 14 || rd != 15) {
8007
                            goto illegal_op;
8008
                        }
8009
                        tmp = load_reg(s, rn);
8010
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8011
                        gen_exception_return(s, tmp);
8012
                        break;
8013
                    case 6: /* mrs cpsr.  */
8014
                        tmp = new_tmp();
8015
                        if (IS_M(env)) {
8016
                            addr = tcg_const_i32(insn & 0xff);
8017
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
8018
                            tcg_temp_free_i32(addr);
8019
                        } else {
8020
                            gen_helper_cpsr_read(tmp);
8021
                        }
8022
                        store_reg(s, rd, tmp);
8023
                        break;
8024
                    case 7: /* mrs spsr.  */
8025
                        /* Not accessible in user mode.  */
8026
                        if (IS_USER(s) || IS_M(env))
8027
                            goto illegal_op;
8028
                        tmp = load_cpu_field(spsr);
8029
                        store_reg(s, rd, tmp);
8030
                        break;
8031
                    }
8032
                }
8033
            } else {
8034
                /* Conditional branch.  */
8035
                op = (insn >> 22) & 0xf;
8036
                /* Generate a conditional jump to next instruction.  */
8037
                s->condlabel = gen_new_label();
8038
                gen_test_cc(op ^ 1, s->condlabel);
8039
                s->condjmp = 1;
8040

    
8041
                /* offset[11:1] = insn[10:0] */
8042
                offset = (insn & 0x7ff) << 1;
8043
                /* offset[17:12] = insn[21:16].  */
8044
                offset |= (insn & 0x003f0000) >> 4;
8045
                /* offset[31:20] = insn[26].  */
8046
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8047
                /* offset[18] = insn[13].  */
8048
                offset |= (insn & (1 << 13)) << 5;
8049
                /* offset[19] = insn[11].  */
8050
                offset |= (insn & (1 << 11)) << 8;
8051

    
8052
                /* jump to the offset */
8053
                gen_jmp(s, s->pc + offset);
8054
            }
8055
        } else {
8056
            /* Data processing immediate.  */
8057
            if (insn & (1 << 25)) {
8058
                if (insn & (1 << 24)) {
8059
                    if (insn & (1 << 20))
8060
                        goto illegal_op;
8061
                    /* Bitfield/Saturate.  */
8062
                    op = (insn >> 21) & 7;
8063
                    imm = insn & 0x1f;
8064
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8065
                    if (rn == 15) {
8066
                        tmp = new_tmp();
8067
                        tcg_gen_movi_i32(tmp, 0);
8068
                    } else {
8069
                        tmp = load_reg(s, rn);
8070
                    }
8071
                    switch (op) {
8072
                    case 2: /* Signed bitfield extract.  */
8073
                        imm++;
8074
                        if (shift + imm > 32)
8075
                            goto illegal_op;
8076
                        if (imm < 32)
8077
                            gen_sbfx(tmp, shift, imm);
8078
                        break;
8079
                    case 6: /* Unsigned bitfield extract.  */
8080
                        imm++;
8081
                        if (shift + imm > 32)
8082
                            goto illegal_op;
8083
                        if (imm < 32)
8084
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
8085
                        break;
8086
                    case 3: /* Bitfield insert/clear.  */
8087
                        if (imm < shift)
8088
                            goto illegal_op;
8089
                        imm = imm + 1 - shift;
8090
                        if (imm != 32) {
8091
                            tmp2 = load_reg(s, rd);
8092
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
8093
                            dead_tmp(tmp2);
8094
                        }
8095
                        break;
8096
                    case 7:
8097
                        goto illegal_op;
8098
                    default: /* Saturate.  */
8099
                        if (shift) {
8100
                            if (op & 1)
8101
                                tcg_gen_sari_i32(tmp, tmp, shift);
8102
                            else
8103
                                tcg_gen_shli_i32(tmp, tmp, shift);
8104
                        }
8105
                        tmp2 = tcg_const_i32(imm);
8106
                        if (op & 4) {
8107
                            /* Unsigned.  */
8108
                            if ((op & 1) && shift == 0)
8109
                                gen_helper_usat16(tmp, tmp, tmp2);
8110
                            else
8111
                                gen_helper_usat(tmp, tmp, tmp2);
8112
                        } else {
8113
                            /* Signed.  */
8114
                            if ((op & 1) && shift == 0)
8115
                                gen_helper_ssat16(tmp, tmp, tmp2);
8116
                            else
8117
                                gen_helper_ssat(tmp, tmp, tmp2);
8118
                        }
8119
                        tcg_temp_free_i32(tmp2);
8120
                        break;
8121
                    }
8122
                    store_reg(s, rd, tmp);
8123
                } else {
8124
                    imm = ((insn & 0x04000000) >> 15)
8125
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
8126
                    if (insn & (1 << 22)) {
8127
                        /* 16-bit immediate.  */
8128
                        imm |= (insn >> 4) & 0xf000;
8129
                        if (insn & (1 << 23)) {
8130
                            /* movt */
8131
                            tmp = load_reg(s, rd);
8132
                            tcg_gen_ext16u_i32(tmp, tmp);
8133
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
8134
                        } else {
8135
                            /* movw */
8136
                            tmp = new_tmp();
8137
                            tcg_gen_movi_i32(tmp, imm);
8138
                        }
8139
                    } else {
8140
                        /* Add/sub 12-bit immediate.  */
8141
                        if (rn == 15) {
8142
                            offset = s->pc & ~(uint32_t)3;
8143
                            if (insn & (1 << 23))
8144
                                offset -= imm;
8145
                            else
8146
                                offset += imm;
8147
                            tmp = new_tmp();
8148
                            tcg_gen_movi_i32(tmp, offset);
8149
                        } else {
8150
                            tmp = load_reg(s, rn);
8151
                            if (insn & (1 << 23))
8152
                                tcg_gen_subi_i32(tmp, tmp, imm);
8153
                            else
8154
                                tcg_gen_addi_i32(tmp, tmp, imm);
8155
                        }
8156
                    }
8157
                    store_reg(s, rd, tmp);
8158
                }
8159
            } else {
8160
                int shifter_out = 0;
8161
                /* modified 12-bit immediate.  */
8162
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8163
                imm = (insn & 0xff);
8164
                switch (shift) {
8165
                case 0: /* XY */
8166
                    /* Nothing to do.  */
8167
                    break;
8168
                case 1: /* 00XY00XY */
8169
                    imm |= imm << 16;
8170
                    break;
8171
                case 2: /* XY00XY00 */
8172
                    imm |= imm << 16;
8173
                    imm <<= 8;
8174
                    break;
8175
                case 3: /* XYXYXYXY */
8176
                    imm |= imm << 16;
8177
                    imm |= imm << 8;
8178
                    break;
8179
                default: /* Rotated constant.  */
8180
                    shift = (shift << 1) | (imm >> 7);
8181
                    imm |= 0x80;
8182
                    imm = imm << (32 - shift);
8183
                    shifter_out = 1;
8184
                    break;
8185
                }
8186
                tmp2 = new_tmp();
8187
                tcg_gen_movi_i32(tmp2, imm);
8188
                rn = (insn >> 16) & 0xf;
8189
                if (rn == 15) {
8190
                    tmp = new_tmp();
8191
                    tcg_gen_movi_i32(tmp, 0);
8192
                } else {
8193
                    tmp = load_reg(s, rn);
8194
                }
8195
                op = (insn >> 21) & 0xf;
8196
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
8197
                                       shifter_out, tmp, tmp2))
8198
                    goto illegal_op;
8199
                dead_tmp(tmp2);
8200
                rd = (insn >> 8) & 0xf;
8201
                if (rd != 15) {
8202
                    store_reg(s, rd, tmp);
8203
                } else {
8204
                    dead_tmp(tmp);
8205
                }
8206
            }
8207
        }
8208
        break;
8209
    case 12: /* Load/store single data item.  */
8210
        {
8211
        int postinc = 0;
8212
        int writeback = 0;
8213
        int user;
8214
        if ((insn & 0x01100000) == 0x01000000) {
8215
            if (disas_neon_ls_insn(env, s, insn))
8216
                goto illegal_op;
8217
            break;
8218
        }
8219
        user = IS_USER(s);
8220
        if (rn == 15) {
8221
            addr = new_tmp();
8222
            /* PC relative.  */
8223
            /* s->pc has already been incremented by 4.  */
8224
            imm = s->pc & 0xfffffffc;
8225
            if (insn & (1 << 23))
8226
                imm += insn & 0xfff;
8227
            else
8228
                imm -= insn & 0xfff;
8229
            tcg_gen_movi_i32(addr, imm);
8230
        } else {
8231
            addr = load_reg(s, rn);
8232
            if (insn & (1 << 23)) {
8233
                /* Positive offset.  */
8234
                imm = insn & 0xfff;
8235
                tcg_gen_addi_i32(addr, addr, imm);
8236
            } else {
8237
                op = (insn >> 8) & 7;
8238
                imm = insn & 0xff;
8239
                switch (op) {
8240
                case 0: case 8: /* Shifted Register.  */
8241
                    shift = (insn >> 4) & 0xf;
8242
                    if (shift > 3)
8243
                        goto illegal_op;
8244
                    tmp = load_reg(s, rm);
8245
                    if (shift)
8246
                        tcg_gen_shli_i32(tmp, tmp, shift);
8247
                    tcg_gen_add_i32(addr, addr, tmp);
8248
                    dead_tmp(tmp);
8249
                    break;
8250
                case 4: /* Negative offset.  */
8251
                    tcg_gen_addi_i32(addr, addr, -imm);
8252
                    break;
8253
                case 6: /* User privilege.  */
8254
                    tcg_gen_addi_i32(addr, addr, imm);
8255
                    user = 1;
8256
                    break;
8257
                case 1: /* Post-decrement.  */
8258
                    imm = -imm;
8259
                    /* Fall through.  */
8260
                case 3: /* Post-increment.  */
8261
                    postinc = 1;
8262
                    writeback = 1;
8263
                    break;
8264
                case 5: /* Pre-decrement.  */
8265
                    imm = -imm;
8266
                    /* Fall through.  */
8267
                case 7: /* Pre-increment.  */
8268
                    tcg_gen_addi_i32(addr, addr, imm);
8269
                    writeback = 1;
8270
                    break;
8271
                default:
8272
                    goto illegal_op;
8273
                }
8274
            }
8275
        }
8276
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8277
        if (insn & (1 << 20)) {
8278
            /* Load.  */
8279
            if (rs == 15 && op != 2) {
8280
                if (op & 2)
8281
                    goto illegal_op;
8282
                /* Memory hint.  Implemented as NOP.  */
8283
            } else {
8284
                switch (op) {
8285
                case 0: tmp = gen_ld8u(addr, user); break;
8286
                case 4: tmp = gen_ld8s(addr, user); break;
8287
                case 1: tmp = gen_ld16u(addr, user); break;
8288
                case 5: tmp = gen_ld16s(addr, user); break;
8289
                case 2: tmp = gen_ld32(addr, user); break;
8290
                default: goto illegal_op;
8291
                }
8292
                if (rs == 15) {
8293
                    gen_bx(s, tmp);
8294
                } else {
8295
                    store_reg(s, rs, tmp);
8296
                }
8297
            }
8298
        } else {
8299
            /* Store.  */
8300
            if (rs == 15)
8301
                goto illegal_op;
8302
            tmp = load_reg(s, rs);
8303
            switch (op) {
8304
            case 0: gen_st8(tmp, addr, user); break;
8305
            case 1: gen_st16(tmp, addr, user); break;
8306
            case 2: gen_st32(tmp, addr, user); break;
8307
            default: goto illegal_op;
8308
            }
8309
        }
8310
        if (postinc)
8311
            tcg_gen_addi_i32(addr, addr, imm);
8312
        if (writeback) {
8313
            store_reg(s, rn, addr);
8314
        } else {
8315
            dead_tmp(addr);
8316
        }
8317
        }
8318
        break;
8319
    default:
8320
        goto illegal_op;
8321
    }
8322
    return 0;
8323
illegal_op:
8324
    return 1;
8325
}
8326

    
8327
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8328
{
8329
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8330
    int32_t offset;
8331
    int i;
8332
    TCGv tmp;
8333
    TCGv tmp2;
8334
    TCGv addr;
8335

    
8336
    if (s->condexec_mask) {
8337
        cond = s->condexec_cond;
8338
        s->condlabel = gen_new_label();
8339
        gen_test_cc(cond ^ 1, s->condlabel);
8340
        s->condjmp = 1;
8341
    }
8342

    
8343
    insn = lduw_code(s->pc);
8344
    s->pc += 2;
8345

    
8346
    switch (insn >> 12) {
8347
    case 0: case 1:
8348

    
8349
        rd = insn & 7;
8350
        op = (insn >> 11) & 3;
8351
        if (op == 3) {
8352
            /* add/subtract */
8353
            rn = (insn >> 3) & 7;
8354
            tmp = load_reg(s, rn);
8355
            if (insn & (1 << 10)) {
8356
                /* immediate */
8357
                tmp2 = new_tmp();
8358
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8359
            } else {
8360
                /* reg */
8361
                rm = (insn >> 6) & 7;
8362
                tmp2 = load_reg(s, rm);
8363
            }
8364
            if (insn & (1 << 9)) {
8365
                if (s->condexec_mask)
8366
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8367
                else
8368
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8369
            } else {
8370
                if (s->condexec_mask)
8371
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8372
                else
8373
                    gen_helper_add_cc(tmp, tmp, tmp2);
8374
            }
8375
            dead_tmp(tmp2);
8376
            store_reg(s, rd, tmp);
8377
        } else {
8378
            /* shift immediate */
8379
            rm = (insn >> 3) & 7;
8380
            shift = (insn >> 6) & 0x1f;
8381
            tmp = load_reg(s, rm);
8382
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8383
            if (!s->condexec_mask)
8384
                gen_logic_CC(tmp);
8385
            store_reg(s, rd, tmp);
8386
        }
8387
        break;
8388
    case 2: case 3:
8389
        /* arithmetic large immediate */
8390
        op = (insn >> 11) & 3;
8391
        rd = (insn >> 8) & 0x7;
8392
        if (op == 0) { /* mov */
8393
            tmp = new_tmp();
8394
            tcg_gen_movi_i32(tmp, insn & 0xff);
8395
            if (!s->condexec_mask)
8396
                gen_logic_CC(tmp);
8397
            store_reg(s, rd, tmp);
8398
        } else {
8399
            tmp = load_reg(s, rd);
8400
            tmp2 = new_tmp();
8401
            tcg_gen_movi_i32(tmp2, insn & 0xff);
8402
            switch (op) {
8403
            case 1: /* cmp */
8404
                gen_helper_sub_cc(tmp, tmp, tmp2);
8405
                dead_tmp(tmp);
8406
                dead_tmp(tmp2);
8407
                break;
8408
            case 2: /* add */
8409
                if (s->condexec_mask)
8410
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8411
                else
8412
                    gen_helper_add_cc(tmp, tmp, tmp2);
8413
                dead_tmp(tmp2);
8414
                store_reg(s, rd, tmp);
8415
                break;
8416
            case 3: /* sub */
8417
                if (s->condexec_mask)
8418
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8419
                else
8420
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8421
                dead_tmp(tmp2);
8422
                store_reg(s, rd, tmp);
8423
                break;
8424
            }
8425
        }
8426
        break;
8427
    case 4:
8428
        if (insn & (1 << 11)) {
8429
            rd = (insn >> 8) & 7;
8430
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8431
            val = s->pc + 2 + ((insn & 0xff) * 4);
8432
            val &= ~(uint32_t)2;
8433
            addr = new_tmp();
8434
            tcg_gen_movi_i32(addr, val);
8435
            tmp = gen_ld32(addr, IS_USER(s));
8436
            dead_tmp(addr);
8437
            store_reg(s, rd, tmp);
8438
            break;
8439
        }
8440
        if (insn & (1 << 10)) {
8441
            /* data processing extended or blx */
8442
            rd = (insn & 7) | ((insn >> 4) & 8);
8443
            rm = (insn >> 3) & 0xf;
8444
            op = (insn >> 8) & 3;
8445
            switch (op) {
8446
            case 0: /* add */
8447
                tmp = load_reg(s, rd);
8448
                tmp2 = load_reg(s, rm);
8449
                tcg_gen_add_i32(tmp, tmp, tmp2);
8450
                dead_tmp(tmp2);
8451
                store_reg(s, rd, tmp);
8452
                break;
8453
            case 1: /* cmp */
8454
                tmp = load_reg(s, rd);
8455
                tmp2 = load_reg(s, rm);
8456
                gen_helper_sub_cc(tmp, tmp, tmp2);
8457
                dead_tmp(tmp2);
8458
                dead_tmp(tmp);
8459
                break;
8460
            case 2: /* mov/cpy */
8461
                tmp = load_reg(s, rm);
8462
                store_reg(s, rd, tmp);
8463
                break;
8464
            case 3:/* branch [and link] exchange thumb register */
8465
                tmp = load_reg(s, rm);
8466
                if (insn & (1 << 7)) {
8467
                    val = (uint32_t)s->pc | 1;
8468
                    tmp2 = new_tmp();
8469
                    tcg_gen_movi_i32(tmp2, val);
8470
                    store_reg(s, 14, tmp2);
8471
                }
8472
                gen_bx(s, tmp);
8473
                break;
8474
            }
8475
            break;
8476
        }
8477

    
8478
        /* data processing register */
8479
        rd = insn & 7;
8480
        rm = (insn >> 3) & 7;
8481
        op = (insn >> 6) & 0xf;
8482
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8483
            /* the shift/rotate ops want the operands backwards */
8484
            val = rm;
8485
            rm = rd;
8486
            rd = val;
8487
            val = 1;
8488
        } else {
8489
            val = 0;
8490
        }
8491

    
8492
        if (op == 9) { /* neg */
8493
            tmp = new_tmp();
8494
            tcg_gen_movi_i32(tmp, 0);
8495
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
8496
            tmp = load_reg(s, rd);
8497
        } else {
8498
            TCGV_UNUSED(tmp);
8499
        }
8500

    
8501
        tmp2 = load_reg(s, rm);
8502
        switch (op) {
8503
        case 0x0: /* and */
8504
            tcg_gen_and_i32(tmp, tmp, tmp2);
8505
            if (!s->condexec_mask)
8506
                gen_logic_CC(tmp);
8507
            break;
8508
        case 0x1: /* eor */
8509
            tcg_gen_xor_i32(tmp, tmp, tmp2);
8510
            if (!s->condexec_mask)
8511
                gen_logic_CC(tmp);
8512
            break;
8513
        case 0x2: /* lsl */
8514
            if (s->condexec_mask) {
8515
                gen_helper_shl(tmp2, tmp2, tmp);
8516
            } else {
8517
                gen_helper_shl_cc(tmp2, tmp2, tmp);
8518
                gen_logic_CC(tmp2);
8519
            }
8520
            break;
8521
        case 0x3: /* lsr */
8522
            if (s->condexec_mask) {
8523
                gen_helper_shr(tmp2, tmp2, tmp);
8524
            } else {
8525
                gen_helper_shr_cc(tmp2, tmp2, tmp);
8526
                gen_logic_CC(tmp2);
8527
            }
8528
            break;
8529
        case 0x4: /* asr */
8530
            if (s->condexec_mask) {
8531
                gen_helper_sar(tmp2, tmp2, tmp);
8532
            } else {
8533
                gen_helper_sar_cc(tmp2, tmp2, tmp);
8534
                gen_logic_CC(tmp2);
8535
            }
8536
            break;
8537
        case 0x5: /* adc */
8538
            if (s->condexec_mask)
8539
                gen_adc(tmp, tmp2);
8540
            else
8541
                gen_helper_adc_cc(tmp, tmp, tmp2);
8542
            break;
8543
        case 0x6: /* sbc */
8544
            if (s->condexec_mask)
8545
                gen_sub_carry(tmp, tmp, tmp2);
8546
            else
8547
                gen_helper_sbc_cc(tmp, tmp, tmp2);
8548
            break;
8549
        case 0x7: /* ror */
8550
            if (s->condexec_mask) {
8551
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
8552
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
8553
            } else {
8554
                gen_helper_ror_cc(tmp2, tmp2, tmp);
8555
                gen_logic_CC(tmp2);
8556
            }
8557
            break;
8558
        case 0x8: /* tst */
8559
            tcg_gen_and_i32(tmp, tmp, tmp2);
8560
            gen_logic_CC(tmp);
8561
            rd = 16;
8562
            break;
8563
        case 0x9: /* neg */
8564
            if (s->condexec_mask)
8565
                tcg_gen_neg_i32(tmp, tmp2);
8566
            else
8567
                gen_helper_sub_cc(tmp, tmp, tmp2);
8568
            break;
8569
        case 0xa: /* cmp */
8570
            gen_helper_sub_cc(tmp, tmp, tmp2);
8571
            rd = 16;
8572
            break;
8573
        case 0xb: /* cmn */
8574
            gen_helper_add_cc(tmp, tmp, tmp2);
8575
            rd = 16;
8576
            break;
8577
        case 0xc: /* orr */
8578
            tcg_gen_or_i32(tmp, tmp, tmp2);
8579
            if (!s->condexec_mask)
8580
                gen_logic_CC(tmp);
8581
            break;
8582
        case 0xd: /* mul */
8583
            tcg_gen_mul_i32(tmp, tmp, tmp2);
8584
            if (!s->condexec_mask)
8585
                gen_logic_CC(tmp);
8586
            break;
8587
        case 0xe: /* bic */
8588
            tcg_gen_andc_i32(tmp, tmp, tmp2);
8589
            if (!s->condexec_mask)
8590
                gen_logic_CC(tmp);
8591
            break;
8592
        case 0xf: /* mvn */
8593
            tcg_gen_not_i32(tmp2, tmp2);
8594
            if (!s->condexec_mask)
8595
                gen_logic_CC(tmp2);
8596
            val = 1;
8597
            rm = rd;
8598
            break;
8599
        }
8600
        if (rd != 16) {
8601
            if (val) {
8602
                store_reg(s, rm, tmp2);
8603
                if (op != 0xf)
8604
                    dead_tmp(tmp);
8605
            } else {
8606
                store_reg(s, rd, tmp);
8607
                dead_tmp(tmp2);
8608
            }
8609
        } else {
8610
            dead_tmp(tmp);
8611
            dead_tmp(tmp2);
8612
        }
8613
        break;
8614

    
8615
    case 5:
8616
        /* load/store register offset.  */
8617
        rd = insn & 7;
8618
        rn = (insn >> 3) & 7;
8619
        rm = (insn >> 6) & 7;
8620
        op = (insn >> 9) & 7;
8621
        addr = load_reg(s, rn);
8622
        tmp = load_reg(s, rm);
8623
        tcg_gen_add_i32(addr, addr, tmp);
8624
        dead_tmp(tmp);
8625

    
8626
        if (op < 3) /* store */
8627
            tmp = load_reg(s, rd);
8628

    
8629
        switch (op) {
8630
        case 0: /* str */
8631
            gen_st32(tmp, addr, IS_USER(s));
8632
            break;
8633
        case 1: /* strh */
8634
            gen_st16(tmp, addr, IS_USER(s));
8635
            break;
8636
        case 2: /* strb */
8637
            gen_st8(tmp, addr, IS_USER(s));
8638
            break;
8639
        case 3: /* ldrsb */
8640
            tmp = gen_ld8s(addr, IS_USER(s));
8641
            break;
8642
        case 4: /* ldr */
8643
            tmp = gen_ld32(addr, IS_USER(s));
8644
            break;
8645
        case 5: /* ldrh */
8646
            tmp = gen_ld16u(addr, IS_USER(s));
8647
            break;
8648
        case 6: /* ldrb */
8649
            tmp = gen_ld8u(addr, IS_USER(s));
8650
            break;
8651
        case 7: /* ldrsh */
8652
            tmp = gen_ld16s(addr, IS_USER(s));
8653
            break;
8654
        }
8655
        if (op >= 3) /* load */
8656
            store_reg(s, rd, tmp);
8657
        dead_tmp(addr);
8658
        break;
8659

    
8660
    case 6:
8661
        /* load/store word immediate offset */
8662
        rd = insn & 7;
8663
        rn = (insn >> 3) & 7;
8664
        addr = load_reg(s, rn);
8665
        val = (insn >> 4) & 0x7c;
8666
        tcg_gen_addi_i32(addr, addr, val);
8667

    
8668
        if (insn & (1 << 11)) {
8669
            /* load */
8670
            tmp = gen_ld32(addr, IS_USER(s));
8671
            store_reg(s, rd, tmp);
8672
        } else {
8673
            /* store */
8674
            tmp = load_reg(s, rd);
8675
            gen_st32(tmp, addr, IS_USER(s));
8676
        }
8677
        dead_tmp(addr);
8678
        break;
8679

    
8680
    case 7:
8681
        /* load/store byte immediate offset */
8682
        rd = insn & 7;
8683
        rn = (insn >> 3) & 7;
8684
        addr = load_reg(s, rn);
8685
        val = (insn >> 6) & 0x1f;
8686
        tcg_gen_addi_i32(addr, addr, val);
8687

    
8688
        if (insn & (1 << 11)) {
8689
            /* load */
8690
            tmp = gen_ld8u(addr, IS_USER(s));
8691
            store_reg(s, rd, tmp);
8692
        } else {
8693
            /* store */
8694
            tmp = load_reg(s, rd);
8695
            gen_st8(tmp, addr, IS_USER(s));
8696
        }
8697
        dead_tmp(addr);
8698
        break;
8699

    
8700
    case 8:
8701
        /* load/store halfword immediate offset */
8702
        rd = insn & 7;
8703
        rn = (insn >> 3) & 7;
8704
        addr = load_reg(s, rn);
8705
        val = (insn >> 5) & 0x3e;
8706
        tcg_gen_addi_i32(addr, addr, val);
8707

    
8708
        if (insn & (1 << 11)) {
8709
            /* load */
8710
            tmp = gen_ld16u(addr, IS_USER(s));
8711
            store_reg(s, rd, tmp);
8712
        } else {
8713
            /* store */
8714
            tmp = load_reg(s, rd);
8715
            gen_st16(tmp, addr, IS_USER(s));
8716
        }
8717
        dead_tmp(addr);
8718
        break;
8719

    
8720
    case 9:
8721
        /* load/store from stack */
8722
        rd = (insn >> 8) & 7;
8723
        addr = load_reg(s, 13);
8724
        val = (insn & 0xff) * 4;
8725
        tcg_gen_addi_i32(addr, addr, val);
8726

    
8727
        if (insn & (1 << 11)) {
8728
            /* load */
8729
            tmp = gen_ld32(addr, IS_USER(s));
8730
            store_reg(s, rd, tmp);
8731
        } else {
8732
            /* store */
8733
            tmp = load_reg(s, rd);
8734
            gen_st32(tmp, addr, IS_USER(s));
8735
        }
8736
        dead_tmp(addr);
8737
        break;
8738

    
8739
    case 10:
8740
        /* add to high reg */
8741
        rd = (insn >> 8) & 7;
8742
        if (insn & (1 << 11)) {
8743
            /* SP */
8744
            tmp = load_reg(s, 13);
8745
        } else {
8746
            /* PC. bit 1 is ignored.  */
8747
            tmp = new_tmp();
8748
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8749
        }
8750
        val = (insn & 0xff) * 4;
8751
        tcg_gen_addi_i32(tmp, tmp, val);
8752
        store_reg(s, rd, tmp);
8753
        break;
8754

    
8755
    case 11:
8756
        /* misc */
8757
        op = (insn >> 8) & 0xf;
8758
        switch (op) {
8759
        case 0:
8760
            /* adjust stack pointer */
8761
            tmp = load_reg(s, 13);
8762
            val = (insn & 0x7f) * 4;
8763
            if (insn & (1 << 7))
8764
                val = -(int32_t)val;
8765
            tcg_gen_addi_i32(tmp, tmp, val);
8766
            store_reg(s, 13, tmp);
8767
            break;
8768

    
8769
        case 2: /* sign/zero extend.  */
8770
            ARCH(6);
8771
            rd = insn & 7;
8772
            rm = (insn >> 3) & 7;
8773
            tmp = load_reg(s, rm);
8774
            switch ((insn >> 6) & 3) {
8775
            case 0: gen_sxth(tmp); break;
8776
            case 1: gen_sxtb(tmp); break;
8777
            case 2: gen_uxth(tmp); break;
8778
            case 3: gen_uxtb(tmp); break;
8779
            }
8780
            store_reg(s, rd, tmp);
8781
            break;
8782
        case 4: case 5: case 0xc: case 0xd:
8783
            /* push/pop */
8784
            addr = load_reg(s, 13);
8785
            if (insn & (1 << 8))
8786
                offset = 4;
8787
            else
8788
                offset = 0;
8789
            for (i = 0; i < 8; i++) {
8790
                if (insn & (1 << i))
8791
                    offset += 4;
8792
            }
8793
            if ((insn & (1 << 11)) == 0) {
8794
                tcg_gen_addi_i32(addr, addr, -offset);
8795
            }
8796
            for (i = 0; i < 8; i++) {
8797
                if (insn & (1 << i)) {
8798
                    if (insn & (1 << 11)) {
8799
                        /* pop */
8800
                        tmp = gen_ld32(addr, IS_USER(s));
8801
                        store_reg(s, i, tmp);
8802
                    } else {
8803
                        /* push */
8804
                        tmp = load_reg(s, i);
8805
                        gen_st32(tmp, addr, IS_USER(s));
8806
                    }
8807
                    /* advance to the next address.  */
8808
                    tcg_gen_addi_i32(addr, addr, 4);
8809
                }
8810
            }
8811
            TCGV_UNUSED(tmp);
8812
            if (insn & (1 << 8)) {
8813
                if (insn & (1 << 11)) {
8814
                    /* pop pc */
8815
                    tmp = gen_ld32(addr, IS_USER(s));
8816
                    /* don't set the pc until the rest of the instruction
8817
                       has completed */
8818
                } else {
8819
                    /* push lr */
8820
                    tmp = load_reg(s, 14);
8821
                    gen_st32(tmp, addr, IS_USER(s));
8822
                }
8823
                tcg_gen_addi_i32(addr, addr, 4);
8824
            }
8825
            if ((insn & (1 << 11)) == 0) {
8826
                tcg_gen_addi_i32(addr, addr, -offset);
8827
            }
8828
            /* write back the new stack pointer */
8829
            store_reg(s, 13, addr);
8830
            /* set the new PC value */
8831
            if ((insn & 0x0900) == 0x0900)
8832
                gen_bx(s, tmp);
8833
            break;
8834

    
8835
        case 1: case 3: case 9: case 11: /* czb */
8836
            rm = insn & 7;
8837
            tmp = load_reg(s, rm);
8838
            s->condlabel = gen_new_label();
8839
            s->condjmp = 1;
8840
            if (insn & (1 << 11))
8841
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8842
            else
8843
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8844
            dead_tmp(tmp);
8845
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8846
            val = (uint32_t)s->pc + 2;
8847
            val += offset;
8848
            gen_jmp(s, val);
8849
            break;
8850

    
8851
        case 15: /* IT, nop-hint.  */
8852
            if ((insn & 0xf) == 0) {
8853
                gen_nop_hint(s, (insn >> 4) & 0xf);
8854
                break;
8855
            }
8856
            /* If Then.  */
8857
            s->condexec_cond = (insn >> 4) & 0xe;
8858
            s->condexec_mask = insn & 0x1f;
8859
            /* No actual code generated for this insn, just setup state.  */
8860
            break;
8861

    
8862
        case 0xe: /* bkpt */
8863
            gen_set_condexec(s);
8864
            gen_set_pc_im(s->pc - 2);
8865
            gen_exception(EXCP_BKPT);
8866
            s->is_jmp = DISAS_JUMP;
8867
            break;
8868

    
8869
        case 0xa: /* rev */
8870
            ARCH(6);
8871
            rn = (insn >> 3) & 0x7;
8872
            rd = insn & 0x7;
8873
            tmp = load_reg(s, rn);
8874
            switch ((insn >> 6) & 3) {
8875
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8876
            case 1: gen_rev16(tmp); break;
8877
            case 3: gen_revsh(tmp); break;
8878
            default: goto illegal_op;
8879
            }
8880
            store_reg(s, rd, tmp);
8881
            break;
8882

    
8883
        case 6: /* cps */
8884
            ARCH(6);
8885
            if (IS_USER(s))
8886
                break;
8887
            if (IS_M(env)) {
8888
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8889
                /* PRIMASK */
8890
                if (insn & 1) {
8891
                    addr = tcg_const_i32(16);
8892
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8893
                    tcg_temp_free_i32(addr);
8894
                }
8895
                /* FAULTMASK */
8896
                if (insn & 2) {
8897
                    addr = tcg_const_i32(17);
8898
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8899
                    tcg_temp_free_i32(addr);
8900
                }
8901
                tcg_temp_free_i32(tmp);
8902
                gen_lookup_tb(s);
8903
            } else {
8904
                if (insn & (1 << 4))
8905
                    shift = CPSR_A | CPSR_I | CPSR_F;
8906
                else
8907
                    shift = 0;
8908
                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
8909
            }
8910
            break;
8911

    
8912
        default:
8913
            goto undef;
8914
        }
8915
        break;
8916

    
8917
    case 12:
8918
        /* load/store multiple */
8919
        rn = (insn >> 8) & 0x7;
8920
        addr = load_reg(s, rn);
8921
        for (i = 0; i < 8; i++) {
8922
            if (insn & (1 << i)) {
8923
                if (insn & (1 << 11)) {
8924
                    /* load */
8925
                    tmp = gen_ld32(addr, IS_USER(s));
8926
                    store_reg(s, i, tmp);
8927
                } else {
8928
                    /* store */
8929
                    tmp = load_reg(s, i);
8930
                    gen_st32(tmp, addr, IS_USER(s));
8931
                }
8932
                /* advance to the next address */
8933
                tcg_gen_addi_i32(addr, addr, 4);
8934
            }
8935
        }
8936
        /* Base register writeback.  */
8937
        if ((insn & (1 << rn)) == 0) {
8938
            store_reg(s, rn, addr);
8939
        } else {
8940
            dead_tmp(addr);
8941
        }
8942
        break;
8943

    
8944
    case 13:
8945
        /* conditional branch or swi */
8946
        cond = (insn >> 8) & 0xf;
8947
        if (cond == 0xe)
8948
            goto undef;
8949

    
8950
        if (cond == 0xf) {
8951
            /* swi */
8952
            gen_set_condexec(s);
8953
            gen_set_pc_im(s->pc);
8954
            s->is_jmp = DISAS_SWI;
8955
            break;
8956
        }
8957
        /* generate a conditional jump to next instruction */
8958
        s->condlabel = gen_new_label();
8959
        gen_test_cc(cond ^ 1, s->condlabel);
8960
        s->condjmp = 1;
8961

    
8962
        /* jump to the offset */
8963
        val = (uint32_t)s->pc + 2;
8964
        offset = ((int32_t)insn << 24) >> 24;
8965
        val += offset << 1;
8966
        gen_jmp(s, val);
8967
        break;
8968

    
8969
    case 14:
8970
        if (insn & (1 << 11)) {
8971
            if (disas_thumb2_insn(env, s, insn))
8972
              goto undef32;
8973
            break;
8974
        }
8975
        /* unconditional branch */
8976
        val = (uint32_t)s->pc;
8977
        offset = ((int32_t)insn << 21) >> 21;
8978
        val += (offset << 1) + 2;
8979
        gen_jmp(s, val);
8980
        break;
8981

    
8982
    case 15:
8983
        if (disas_thumb2_insn(env, s, insn))
8984
            goto undef32;
8985
        break;
8986
    }
8987
    return;
8988
undef32:
8989
    gen_set_condexec(s);
8990
    gen_set_pc_im(s->pc - 4);
8991
    gen_exception(EXCP_UDEF);
8992
    s->is_jmp = DISAS_JUMP;
8993
    return;
8994
illegal_op:
8995
undef:
8996
    gen_set_condexec(s);
8997
    gen_set_pc_im(s->pc - 2);
8998
    gen_exception(EXCP_UDEF);
8999
    s->is_jmp = DISAS_JUMP;
9000
}
9001

    
9002
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9003
   basic block 'tb'. If search_pc is TRUE, also generate PC
9004
   information for each intermediate instruction. */
9005
static inline void gen_intermediate_code_internal(CPUState *env,
9006
                                                  TranslationBlock *tb,
9007
                                                  int search_pc)
9008
{
9009
    DisasContext dc1, *dc = &dc1;
9010
    CPUBreakpoint *bp;
9011
    uint16_t *gen_opc_end;
9012
    int j, lj;
9013
    target_ulong pc_start;
9014
    uint32_t next_page_start;
9015
    int num_insns;
9016
    int max_insns;
9017

    
9018
    /* generate intermediate code */
9019
    num_temps = 0;
9020

    
9021
    pc_start = tb->pc;
9022

    
9023
    dc->tb = tb;
9024

    
9025
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9026

    
9027
    dc->is_jmp = DISAS_NEXT;
9028
    dc->pc = pc_start;
9029
    dc->singlestep_enabled = env->singlestep_enabled;
9030
    dc->condjmp = 0;
9031
    dc->thumb = env->thumb;
9032
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
9033
    dc->condexec_cond = env->condexec_bits >> 4;
9034
#if !defined(CONFIG_USER_ONLY)
9035
    if (IS_M(env)) {
9036
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
9037
    } else {
9038
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
9039
    }
9040
#endif
9041
    cpu_F0s = tcg_temp_new_i32();
9042
    cpu_F1s = tcg_temp_new_i32();
9043
    cpu_F0d = tcg_temp_new_i64();
9044
    cpu_F1d = tcg_temp_new_i64();
9045
    cpu_V0 = cpu_F0d;
9046
    cpu_V1 = cpu_F1d;
9047
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
9048
    cpu_M0 = tcg_temp_new_i64();
9049
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9050
    lj = -1;
9051
    num_insns = 0;
9052
    max_insns = tb->cflags & CF_COUNT_MASK;
9053
    if (max_insns == 0)
9054
        max_insns = CF_COUNT_MASK;
9055

    
9056
    gen_icount_start();
9057
    /* Reset the conditional execution bits immediately. This avoids
9058
       complications trying to do it at the end of the block.  */
9059
    if (env->condexec_bits)
9060
      {
9061
        TCGv tmp = new_tmp();
9062
        tcg_gen_movi_i32(tmp, 0);
9063
        store_cpu_field(tmp, condexec_bits);
9064
      }
9065
    do {
9066
#ifdef CONFIG_USER_ONLY
9067
        /* Intercept jump to the magic kernel page.  */
9068
        if (dc->pc >= 0xffff0000) {
9069
            /* We always get here via a jump, so know we are not in a
9070
               conditional execution block.  */
9071
            gen_exception(EXCP_KERNEL_TRAP);
9072
            dc->is_jmp = DISAS_UPDATE;
9073
            break;
9074
        }
9075
#else
9076
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9077
            /* We always get here via a jump, so know we are not in a
9078
               conditional execution block.  */
9079
            gen_exception(EXCP_EXCEPTION_EXIT);
9080
            dc->is_jmp = DISAS_UPDATE;
9081
            break;
9082
        }
9083
#endif
9084

    
9085
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9086
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9087
                if (bp->pc == dc->pc) {
9088
                    gen_set_condexec(dc);
9089
                    gen_set_pc_im(dc->pc);
9090
                    gen_exception(EXCP_DEBUG);
9091
                    dc->is_jmp = DISAS_JUMP;
9092
                    /* Advance PC so that clearing the breakpoint will
9093
                       invalidate this TB.  */
9094
                    dc->pc += 2;
9095
                    goto done_generating;
9096
                    break;
9097
                }
9098
            }
9099
        }
9100
        if (search_pc) {
9101
            j = gen_opc_ptr - gen_opc_buf;
9102
            if (lj < j) {
9103
                lj++;
9104
                while (lj < j)
9105
                    gen_opc_instr_start[lj++] = 0;
9106
            }
9107
            gen_opc_pc[lj] = dc->pc;
9108
            gen_opc_instr_start[lj] = 1;
9109
            gen_opc_icount[lj] = num_insns;
9110
        }
9111

    
9112
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9113
            gen_io_start();
9114

    
9115
        if (env->thumb) {
9116
            disas_thumb_insn(env, dc);
9117
            if (dc->condexec_mask) {
9118
                dc->condexec_cond = (dc->condexec_cond & 0xe)
9119
                                   | ((dc->condexec_mask >> 4) & 1);
9120
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9121
                if (dc->condexec_mask == 0) {
9122
                    dc->condexec_cond = 0;
9123
                }
9124
            }
9125
        } else {
9126
            disas_arm_insn(env, dc);
9127
        }
9128
        if (num_temps) {
9129
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
9130
            num_temps = 0;
9131
        }
9132

    
9133
        if (dc->condjmp && !dc->is_jmp) {
9134
            gen_set_label(dc->condlabel);
9135
            dc->condjmp = 0;
9136
        }
9137
        /* Translation stops when a conditional branch is encountered.
9138
         * Otherwise the subsequent code could get translated several times.
9139
         * Also stop translation when a page boundary is reached.  This
9140
         * ensures prefetch aborts occur at the right place.  */
9141
        num_insns ++;
9142
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9143
             !env->singlestep_enabled &&
9144
             !singlestep &&
9145
             dc->pc < next_page_start &&
9146
             num_insns < max_insns);
9147

    
9148
    if (tb->cflags & CF_LAST_IO) {
9149
        if (dc->condjmp) {
9150
            /* FIXME:  This can theoretically happen with self-modifying
9151
               code.  */
9152
            cpu_abort(env, "IO on conditional branch instruction");
9153
        }
9154
        gen_io_end();
9155
    }
9156

    
9157
    /* At this stage dc->condjmp will only be set when the skipped
9158
       instruction was a conditional branch or trap, and the PC has
9159
       already been written.  */
9160
    if (unlikely(env->singlestep_enabled)) {
9161
        /* Make sure the pc is updated, and raise a debug exception.  */
9162
        if (dc->condjmp) {
9163
            gen_set_condexec(dc);
9164
            if (dc->is_jmp == DISAS_SWI) {
9165
                gen_exception(EXCP_SWI);
9166
            } else {
9167
                gen_exception(EXCP_DEBUG);
9168
            }
9169
            gen_set_label(dc->condlabel);
9170
        }
9171
        if (dc->condjmp || !dc->is_jmp) {
9172
            gen_set_pc_im(dc->pc);
9173
            dc->condjmp = 0;
9174
        }
9175
        gen_set_condexec(dc);
9176
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9177
            gen_exception(EXCP_SWI);
9178
        } else {
9179
            /* FIXME: Single stepping a WFI insn will not halt
9180
               the CPU.  */
9181
            gen_exception(EXCP_DEBUG);
9182
        }
9183
    } else {
9184
        /* While branches must always occur at the end of an IT block,
9185
           there are a few other things that can cause us to terminate
9186
           the TB in the middel of an IT block:
9187
            - Exception generating instructions (bkpt, swi, undefined).
9188
            - Page boundaries.
9189
            - Hardware watchpoints.
9190
           Hardware breakpoints have already been handled and skip this code.
9191
         */
9192
        gen_set_condexec(dc);
9193
        switch(dc->is_jmp) {
9194
        case DISAS_NEXT:
9195
            gen_goto_tb(dc, 1, dc->pc);
9196
            break;
9197
        default:
9198
        case DISAS_JUMP:
9199
        case DISAS_UPDATE:
9200
            /* indicate that the hash table must be used to find the next TB */
9201
            tcg_gen_exit_tb(0);
9202
            break;
9203
        case DISAS_TB_JUMP:
9204
            /* nothing more to generate */
9205
            break;
9206
        case DISAS_WFI:
9207
            gen_helper_wfi();
9208
            break;
9209
        case DISAS_SWI:
9210
            gen_exception(EXCP_SWI);
9211
            break;
9212
        }
9213
        if (dc->condjmp) {
9214
            gen_set_label(dc->condlabel);
9215
            gen_set_condexec(dc);
9216
            gen_goto_tb(dc, 1, dc->pc);
9217
            dc->condjmp = 0;
9218
        }
9219
    }
9220

    
9221
done_generating:
9222
    gen_icount_end(tb, num_insns);
9223
    *gen_opc_ptr = INDEX_op_end;
9224

    
9225
#ifdef DEBUG_DISAS
9226
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9227
        qemu_log("----------------\n");
9228
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9229
        log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
9230
        qemu_log("\n");
9231
    }
9232
#endif
9233
    if (search_pc) {
9234
        j = gen_opc_ptr - gen_opc_buf;
9235
        lj++;
9236
        while (lj <= j)
9237
            gen_opc_instr_start[lj++] = 0;
9238
    } else {
9239
        tb->size = dc->pc - pc_start;
9240
        tb->icount = num_insns;
9241
    }
9242
}
9243

    
9244
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9245
{
9246
    gen_intermediate_code_internal(env, tb, 0);
9247
}
9248

    
9249
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9250
{
9251
    gen_intermediate_code_internal(env, tb, 1);
9252
}
9253

    
9254
static const char *cpu_mode_names[16] = {
9255
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9256
  "???", "???", "???", "und", "???", "???", "???", "sys"
9257
};
9258

    
9259
void cpu_dump_state(CPUState *env, FILE *f,
9260
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9261
                    int flags)
9262
{
9263
    int i;
9264
#if 0
9265
    union {
9266
        uint32_t i;
9267
        float s;
9268
    } s0, s1;
9269
    CPU_DoubleU d;
9270
    /* ??? This assumes float64 and double have the same layout.
9271
       Oh well, it's only debug dumps.  */
9272
    union {
9273
        float64 f64;
9274
        double d;
9275
    } d0;
9276
#endif
9277
    uint32_t psr;
9278

    
9279
    for(i=0;i<16;i++) {
9280
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9281
        if ((i % 4) == 3)
9282
            cpu_fprintf(f, "\n");
9283
        else
9284
            cpu_fprintf(f, " ");
9285
    }
9286
    psr = cpsr_read(env);
9287
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9288
                psr,
9289
                psr & (1 << 31) ? 'N' : '-',
9290
                psr & (1 << 30) ? 'Z' : '-',
9291
                psr & (1 << 29) ? 'C' : '-',
9292
                psr & (1 << 28) ? 'V' : '-',
9293
                psr & CPSR_T ? 'T' : 'A',
9294
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9295

    
9296
#if 0
9297
    for (i = 0; i < 16; i++) {
9298
        d.d = env->vfp.regs[i];
9299
        s0.i = d.l.lower;
9300
        s1.i = d.l.upper;
9301
        d0.f64 = d.d;
9302
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9303
                    i * 2, (int)s0.i, s0.s,
9304
                    i * 2 + 1, (int)s1.i, s1.s,
9305
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9306
                    d0.d);
9307
    }
9308
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9309
#endif
9310
}
9311

    
9312
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9313
                unsigned long searched_pc, int pc_pos, void *puc)
9314
{
9315
    env->regs[15] = gen_opc_pc[pc_pos];
9316
}