Statistics
| Branch: | Revision:

root / target-arm / translate.c @ d569956e

History | View | Annotate | Download (322.9 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
    int vfp_enabled;
63
    int vec_len;
64
    int vec_stride;
65
} DisasContext;
66

    
67
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
68

    
69
#if defined(CONFIG_USER_ONLY)
70
#define IS_USER(s) 1
71
#else
72
#define IS_USER(s) (s->user)
73
#endif
74

    
75
/* These instructions trap after executing, so defer them until after the
76
   conditional executions state has been updated.  */
77
#define DISAS_WFI 4
78
#define DISAS_SWI 5
79

    
80
static TCGv_ptr cpu_env;
81
/* We reuse the same 64-bit temporaries for efficiency.  */
82
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
83
static TCGv_i32 cpu_R[16];
84
static TCGv_i32 cpu_exclusive_addr;
85
static TCGv_i32 cpu_exclusive_val;
86
static TCGv_i32 cpu_exclusive_high;
87
#ifdef CONFIG_USER_ONLY
88
static TCGv_i32 cpu_exclusive_test;
89
static TCGv_i32 cpu_exclusive_info;
90
#endif
91

    
92
/* FIXME:  These should be removed.  */
93
static TCGv cpu_F0s, cpu_F1s;
94
static TCGv_i64 cpu_F0d, cpu_F1d;
95

    
96
#include "gen-icount.h"
97

    
98
static const char *regnames[] =
99
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
100
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
101

    
102
/* initialize TCG globals.  */
103
void arm_translate_init(void)
104
{
105
    int i;
106

    
107
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
108

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

    
127
#define GEN_HELPER 2
128
#include "helpers.h"
129
}
130

    
131
static inline TCGv load_cpu_offset(int offset)
132
{
133
    TCGv tmp = tcg_temp_new_i32();
134
    tcg_gen_ld_i32(tmp, cpu_env, offset);
135
    return tmp;
136
}
137

    
138
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
139

    
140
static inline void store_cpu_offset(TCGv var, int offset)
141
{
142
    tcg_gen_st_i32(var, cpu_env, offset);
143
    tcg_temp_free_i32(var);
144
}
145

    
146
#define store_cpu_field(var, name) \
147
    store_cpu_offset(var, offsetof(CPUState, name))
148

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

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

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

    
185
/* Value extensions.  */
186
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
187
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
188
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
189
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
190

    
191
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
192
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
193

    
194

    
195
static inline void gen_set_cpsr(TCGv var, uint32_t mask)
196
{
197
    TCGv tmp_mask = tcg_const_i32(mask);
198
    gen_helper_cpsr_write(var, tmp_mask);
199
    tcg_temp_free_i32(tmp_mask);
200
}
201
/* Set NZCV flags from the high 4 bits of var.  */
202
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
203

    
204
static void gen_exception(int excp)
205
{
206
    TCGv tmp = tcg_temp_new_i32();
207
    tcg_gen_movi_i32(tmp, excp);
208
    gen_helper_exception(tmp);
209
    tcg_temp_free_i32(tmp);
210
}
211

    
212
static void gen_smul_dual(TCGv a, TCGv b)
213
{
214
    TCGv tmp1 = tcg_temp_new_i32();
215
    TCGv tmp2 = tcg_temp_new_i32();
216
    tcg_gen_ext16s_i32(tmp1, a);
217
    tcg_gen_ext16s_i32(tmp2, b);
218
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
219
    tcg_temp_free_i32(tmp2);
220
    tcg_gen_sari_i32(a, a, 16);
221
    tcg_gen_sari_i32(b, b, 16);
222
    tcg_gen_mul_i32(b, b, a);
223
    tcg_gen_mov_i32(a, tmp1);
224
    tcg_temp_free_i32(tmp1);
225
}
226

    
227
/* Byteswap each halfword.  */
228
static void gen_rev16(TCGv var)
229
{
230
    TCGv tmp = tcg_temp_new_i32();
231
    tcg_gen_shri_i32(tmp, var, 8);
232
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
233
    tcg_gen_shli_i32(var, var, 8);
234
    tcg_gen_andi_i32(var, var, 0xff00ff00);
235
    tcg_gen_or_i32(var, var, tmp);
236
    tcg_temp_free_i32(tmp);
237
}
238

    
239
/* Byteswap low halfword and sign extend.  */
240
static void gen_revsh(TCGv var)
241
{
242
    tcg_gen_ext16u_i32(var, var);
243
    tcg_gen_bswap16_i32(var, var);
244
    tcg_gen_ext16s_i32(var, var);
245
}
246

    
247
/* Unsigned bitfield extract.  */
248
static void gen_ubfx(TCGv var, int shift, uint32_t mask)
249
{
250
    if (shift)
251
        tcg_gen_shri_i32(var, var, shift);
252
    tcg_gen_andi_i32(var, var, mask);
253
}
254

    
255
/* Signed bitfield extract.  */
256
static void gen_sbfx(TCGv var, int shift, int width)
257
{
258
    uint32_t signbit;
259

    
260
    if (shift)
261
        tcg_gen_sari_i32(var, var, shift);
262
    if (shift + width < 32) {
263
        signbit = 1u << (width - 1);
264
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
265
        tcg_gen_xori_i32(var, var, signbit);
266
        tcg_gen_subi_i32(var, var, signbit);
267
    }
268
}
269

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

    
279
/* Return (b << 32) + a. Mark inputs as dead */
280
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b)
281
{
282
    TCGv_i64 tmp64 = tcg_temp_new_i64();
283

    
284
    tcg_gen_extu_i32_i64(tmp64, b);
285
    tcg_temp_free_i32(b);
286
    tcg_gen_shli_i64(tmp64, tmp64, 32);
287
    tcg_gen_add_i64(a, tmp64, a);
288

    
289
    tcg_temp_free_i64(tmp64);
290
    return a;
291
}
292

    
293
/* Return (b << 32) - a. Mark inputs as dead. */
294
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
295
{
296
    TCGv_i64 tmp64 = tcg_temp_new_i64();
297

    
298
    tcg_gen_extu_i32_i64(tmp64, b);
299
    tcg_temp_free_i32(b);
300
    tcg_gen_shli_i64(tmp64, tmp64, 32);
301
    tcg_gen_sub_i64(a, tmp64, a);
302

    
303
    tcg_temp_free_i64(tmp64);
304
    return a;
305
}
306

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

    
315
    tcg_gen_extu_i32_i64(tmp1, a);
316
    tcg_temp_free_i32(a);
317
    tcg_gen_extu_i32_i64(tmp2, b);
318
    tcg_temp_free_i32(b);
319
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
320
    tcg_temp_free_i64(tmp2);
321
    return tmp1;
322
}
323

    
324
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
325
{
326
    TCGv_i64 tmp1 = tcg_temp_new_i64();
327
    TCGv_i64 tmp2 = tcg_temp_new_i64();
328

    
329
    tcg_gen_ext_i32_i64(tmp1, a);
330
    tcg_temp_free_i32(a);
331
    tcg_gen_ext_i32_i64(tmp2, b);
332
    tcg_temp_free_i32(b);
333
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
334
    tcg_temp_free_i64(tmp2);
335
    return tmp1;
336
}
337

    
338
/* Swap low and high halfwords.  */
339
static void gen_swap_half(TCGv var)
340
{
341
    TCGv tmp = tcg_temp_new_i32();
342
    tcg_gen_shri_i32(tmp, var, 16);
343
    tcg_gen_shli_i32(var, var, 16);
344
    tcg_gen_or_i32(var, var, tmp);
345
    tcg_temp_free_i32(tmp);
346
}
347

    
348
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
349
    tmp = (t0 ^ t1) & 0x8000;
350
    t0 &= ~0x8000;
351
    t1 &= ~0x8000;
352
    t0 = (t0 + t1) ^ tmp;
353
 */
354

    
355
static void gen_add16(TCGv t0, TCGv t1)
356
{
357
    TCGv tmp = tcg_temp_new_i32();
358
    tcg_gen_xor_i32(tmp, t0, t1);
359
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
360
    tcg_gen_andi_i32(t0, t0, ~0x8000);
361
    tcg_gen_andi_i32(t1, t1, ~0x8000);
362
    tcg_gen_add_i32(t0, t0, t1);
363
    tcg_gen_xor_i32(t0, t0, tmp);
364
    tcg_temp_free_i32(tmp);
365
    tcg_temp_free_i32(t1);
366
}
367

    
368
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
369

    
370
/* Set CF to the top bit of var.  */
371
static void gen_set_CF_bit31(TCGv var)
372
{
373
    TCGv tmp = tcg_temp_new_i32();
374
    tcg_gen_shri_i32(tmp, var, 31);
375
    gen_set_CF(tmp);
376
    tcg_temp_free_i32(tmp);
377
}
378

    
379
/* Set N and Z flags from var.  */
380
static inline void gen_logic_CC(TCGv var)
381
{
382
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
383
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
384
}
385

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

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

    
406
/* dest = T0 - T1 + CF - 1.  */
407
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
408
{
409
    TCGv tmp;
410
    tcg_gen_sub_i32(dest, t0, t1);
411
    tmp = load_cpu_field(CF);
412
    tcg_gen_add_i32(dest, dest, tmp);
413
    tcg_gen_subi_i32(dest, dest, 1);
414
    tcg_temp_free_i32(tmp);
415
}
416

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

    
420
static void shifter_out_im(TCGv var, int shift)
421
{
422
    TCGv tmp = tcg_temp_new_i32();
423
    if (shift == 0) {
424
        tcg_gen_andi_i32(tmp, var, 1);
425
    } else {
426
        tcg_gen_shri_i32(tmp, var, shift);
427
        if (shift != 31)
428
            tcg_gen_andi_i32(tmp, tmp, 1);
429
    }
430
    gen_set_CF(tmp);
431
    tcg_temp_free_i32(tmp);
432
}
433

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

    
484
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
485
                                     TCGv shift, int flags)
486
{
487
    if (flags) {
488
        switch (shiftop) {
489
        case 0: gen_helper_shl_cc(var, var, shift); break;
490
        case 1: gen_helper_shr_cc(var, var, shift); break;
491
        case 2: gen_helper_sar_cc(var, var, shift); break;
492
        case 3: gen_helper_ror_cc(var, var, shift); break;
493
        }
494
    } else {
495
        switch (shiftop) {
496
        case 0: gen_helper_shl(var, var, shift); break;
497
        case 1: gen_helper_shr(var, var, shift); break;
498
        case 2: gen_helper_sar(var, var, shift); break;
499
        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
500
                tcg_gen_rotr_i32(var, var, shift); break;
501
        }
502
    }
503
    tcg_temp_free_i32(shift);
504
}
505

    
506
#define PAS_OP(pfx) \
507
    switch (op2) {  \
508
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
509
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
510
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
511
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
512
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
513
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
514
    }
515
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
516
{
517
    TCGv_ptr tmp;
518

    
519
    switch (op1) {
520
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
521
    case 1:
522
        tmp = tcg_temp_new_ptr();
523
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
524
        PAS_OP(s)
525
        tcg_temp_free_ptr(tmp);
526
        break;
527
    case 5:
528
        tmp = tcg_temp_new_ptr();
529
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
530
        PAS_OP(u)
531
        tcg_temp_free_ptr(tmp);
532
        break;
533
#undef gen_pas_helper
534
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
535
    case 2:
536
        PAS_OP(q);
537
        break;
538
    case 3:
539
        PAS_OP(sh);
540
        break;
541
    case 6:
542
        PAS_OP(uq);
543
        break;
544
    case 7:
545
        PAS_OP(uh);
546
        break;
547
#undef gen_pas_helper
548
    }
549
}
550
#undef PAS_OP
551

    
552
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
553
#define PAS_OP(pfx) \
554
    switch (op1) {  \
555
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
556
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
557
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
558
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
559
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
560
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
561
    }
562
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
563
{
564
    TCGv_ptr tmp;
565

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

    
599
static void gen_test_cc(int cc, int label)
600
{
601
    TCGv tmp;
602
    TCGv tmp2;
603
    int inv;
604

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

    
697
static const uint8_t table_logic_cc[16] = {
698
    1, /* and */
699
    1, /* xor */
700
    0, /* sub */
701
    0, /* rsb */
702
    0, /* add */
703
    0, /* adc */
704
    0, /* sbc */
705
    0, /* rsc */
706
    1, /* andl */
707
    1, /* xorl */
708
    0, /* cmp */
709
    0, /* cmn */
710
    1, /* orr */
711
    1, /* mov */
712
    1, /* bic */
713
    1, /* mvn */
714
};
715

    
716
/* Set PC and Thumb state from an immediate address.  */
717
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
718
{
719
    TCGv tmp;
720

    
721
    s->is_jmp = DISAS_UPDATE;
722
    if (s->thumb != (addr & 1)) {
723
        tmp = tcg_temp_new_i32();
724
        tcg_gen_movi_i32(tmp, addr & 1);
725
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
726
        tcg_temp_free_i32(tmp);
727
    }
728
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
729
}
730

    
731
/* Set PC and Thumb state from var.  var is marked as dead.  */
732
static inline void gen_bx(DisasContext *s, TCGv var)
733
{
734
    s->is_jmp = DISAS_UPDATE;
735
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
736
    tcg_gen_andi_i32(var, var, 1);
737
    store_cpu_field(var, thumb);
738
}
739

    
740
/* Variant of store_reg which uses branch&exchange logic when storing
741
   to r15 in ARM architecture v7 and above. The source must be a temporary
742
   and will be marked as dead. */
743
static inline void store_reg_bx(CPUState *env, DisasContext *s,
744
                                int reg, TCGv var)
745
{
746
    if (reg == 15 && ENABLE_ARCH_7) {
747
        gen_bx(s, var);
748
    } else {
749
        store_reg(s, reg, var);
750
    }
751
}
752

    
753
static inline TCGv gen_ld8s(TCGv addr, int index)
754
{
755
    TCGv tmp = tcg_temp_new_i32();
756
    tcg_gen_qemu_ld8s(tmp, addr, index);
757
    return tmp;
758
}
759
static inline TCGv gen_ld8u(TCGv addr, int index)
760
{
761
    TCGv tmp = tcg_temp_new_i32();
762
    tcg_gen_qemu_ld8u(tmp, addr, index);
763
    return tmp;
764
}
765
static inline TCGv gen_ld16s(TCGv addr, int index)
766
{
767
    TCGv tmp = tcg_temp_new_i32();
768
    tcg_gen_qemu_ld16s(tmp, addr, index);
769
    return tmp;
770
}
771
static inline TCGv gen_ld16u(TCGv addr, int index)
772
{
773
    TCGv tmp = tcg_temp_new_i32();
774
    tcg_gen_qemu_ld16u(tmp, addr, index);
775
    return tmp;
776
}
777
static inline TCGv gen_ld32(TCGv addr, int index)
778
{
779
    TCGv tmp = tcg_temp_new_i32();
780
    tcg_gen_qemu_ld32u(tmp, addr, index);
781
    return tmp;
782
}
783
static inline TCGv_i64 gen_ld64(TCGv addr, int index)
784
{
785
    TCGv_i64 tmp = tcg_temp_new_i64();
786
    tcg_gen_qemu_ld64(tmp, addr, index);
787
    return tmp;
788
}
789
static inline void gen_st8(TCGv val, TCGv addr, int index)
790
{
791
    tcg_gen_qemu_st8(val, addr, index);
792
    tcg_temp_free_i32(val);
793
}
794
static inline void gen_st16(TCGv val, TCGv addr, int index)
795
{
796
    tcg_gen_qemu_st16(val, addr, index);
797
    tcg_temp_free_i32(val);
798
}
799
static inline void gen_st32(TCGv val, TCGv addr, int index)
800
{
801
    tcg_gen_qemu_st32(val, addr, index);
802
    tcg_temp_free_i32(val);
803
}
804
static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
805
{
806
    tcg_gen_qemu_st64(val, addr, index);
807
    tcg_temp_free_i64(val);
808
}
809

    
810
static inline void gen_set_pc_im(uint32_t val)
811
{
812
    tcg_gen_movi_i32(cpu_R[15], val);
813
}
814

    
815
/* Force a TB lookup after an instruction that changes the CPU state.  */
816
static inline void gen_lookup_tb(DisasContext *s)
817
{
818
    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
819
    s->is_jmp = DISAS_UPDATE;
820
}
821

    
822
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
823
                                       TCGv var)
824
{
825
    int val, rm, shift, shiftop;
826
    TCGv offset;
827

    
828
    if (!(insn & (1 << 25))) {
829
        /* immediate */
830
        val = insn & 0xfff;
831
        if (!(insn & (1 << 23)))
832
            val = -val;
833
        if (val != 0)
834
            tcg_gen_addi_i32(var, var, val);
835
    } else {
836
        /* shift/register */
837
        rm = (insn) & 0xf;
838
        shift = (insn >> 7) & 0x1f;
839
        shiftop = (insn >> 5) & 3;
840
        offset = load_reg(s, rm);
841
        gen_arm_shift_im(offset, shiftop, shift, 0);
842
        if (!(insn & (1 << 23)))
843
            tcg_gen_sub_i32(var, var, offset);
844
        else
845
            tcg_gen_add_i32(var, var, offset);
846
        tcg_temp_free_i32(offset);
847
    }
848
}
849

    
850
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
851
                                        int extra, TCGv var)
852
{
853
    int val, rm;
854
    TCGv offset;
855

    
856
    if (insn & (1 << 22)) {
857
        /* immediate */
858
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
859
        if (!(insn & (1 << 23)))
860
            val = -val;
861
        val += extra;
862
        if (val != 0)
863
            tcg_gen_addi_i32(var, var, val);
864
    } else {
865
        /* register */
866
        if (extra)
867
            tcg_gen_addi_i32(var, var, extra);
868
        rm = (insn) & 0xf;
869
        offset = load_reg(s, rm);
870
        if (!(insn & (1 << 23)))
871
            tcg_gen_sub_i32(var, var, offset);
872
        else
873
            tcg_gen_add_i32(var, var, offset);
874
        tcg_temp_free_i32(offset);
875
    }
876
}
877

    
878
#define VFP_OP2(name)                                                 \
879
static inline void gen_vfp_##name(int dp)                             \
880
{                                                                     \
881
    if (dp)                                                           \
882
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
883
    else                                                              \
884
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
885
}
886

    
887
VFP_OP2(add)
888
VFP_OP2(sub)
889
VFP_OP2(mul)
890
VFP_OP2(div)
891

    
892
#undef VFP_OP2
893

    
894
static inline void gen_vfp_abs(int dp)
895
{
896
    if (dp)
897
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
898
    else
899
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
900
}
901

    
902
static inline void gen_vfp_neg(int dp)
903
{
904
    if (dp)
905
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
906
    else
907
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
908
}
909

    
910
static inline void gen_vfp_sqrt(int dp)
911
{
912
    if (dp)
913
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
914
    else
915
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
916
}
917

    
918
static inline void gen_vfp_cmp(int dp)
919
{
920
    if (dp)
921
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
922
    else
923
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
924
}
925

    
926
static inline void gen_vfp_cmpe(int dp)
927
{
928
    if (dp)
929
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
930
    else
931
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
932
}
933

    
934
static inline void gen_vfp_F1_ld0(int dp)
935
{
936
    if (dp)
937
        tcg_gen_movi_i64(cpu_F1d, 0);
938
    else
939
        tcg_gen_movi_i32(cpu_F1s, 0);
940
}
941

    
942
static inline void gen_vfp_uito(int dp)
943
{
944
    if (dp)
945
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
946
    else
947
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
948
}
949

    
950
static inline void gen_vfp_sito(int dp)
951
{
952
    if (dp)
953
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
954
    else
955
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
956
}
957

    
958
static inline void gen_vfp_toui(int dp)
959
{
960
    if (dp)
961
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
962
    else
963
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
964
}
965

    
966
static inline void gen_vfp_touiz(int dp)
967
{
968
    if (dp)
969
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
970
    else
971
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
972
}
973

    
974
static inline void gen_vfp_tosi(int dp)
975
{
976
    if (dp)
977
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
978
    else
979
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
980
}
981

    
982
static inline void gen_vfp_tosiz(int dp)
983
{
984
    if (dp)
985
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
986
    else
987
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
988
}
989

    
990
#define VFP_GEN_FIX(name) \
991
static inline void gen_vfp_##name(int dp, int shift) \
992
{ \
993
    TCGv tmp_shift = tcg_const_i32(shift); \
994
    if (dp) \
995
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, cpu_env);\
996
    else \
997
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, cpu_env);\
998
    tcg_temp_free_i32(tmp_shift); \
999
}
1000
VFP_GEN_FIX(tosh)
1001
VFP_GEN_FIX(tosl)
1002
VFP_GEN_FIX(touh)
1003
VFP_GEN_FIX(toul)
1004
VFP_GEN_FIX(shto)
1005
VFP_GEN_FIX(slto)
1006
VFP_GEN_FIX(uhto)
1007
VFP_GEN_FIX(ulto)
1008
#undef VFP_GEN_FIX
1009

    
1010
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
1011
{
1012
    if (dp)
1013
        tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1014
    else
1015
        tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1016
}
1017

    
1018
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
1019
{
1020
    if (dp)
1021
        tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1022
    else
1023
        tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1024
}
1025

    
1026
static inline long
1027
vfp_reg_offset (int dp, int reg)
1028
{
1029
    if (dp)
1030
        return offsetof(CPUARMState, vfp.regs[reg]);
1031
    else if (reg & 1) {
1032
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1033
          + offsetof(CPU_DoubleU, l.upper);
1034
    } else {
1035
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1036
          + offsetof(CPU_DoubleU, l.lower);
1037
    }
1038
}
1039

    
1040
/* Return the offset of a 32-bit piece of a NEON register.
1041
   zero is the least significant end of the register.  */
1042
static inline long
1043
neon_reg_offset (int reg, int n)
1044
{
1045
    int sreg;
1046
    sreg = reg * 2 + n;
1047
    return vfp_reg_offset(0, sreg);
1048
}
1049

    
1050
static TCGv neon_load_reg(int reg, int pass)
1051
{
1052
    TCGv tmp = tcg_temp_new_i32();
1053
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1054
    return tmp;
1055
}
1056

    
1057
static void neon_store_reg(int reg, int pass, TCGv var)
1058
{
1059
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1060
    tcg_temp_free_i32(var);
1061
}
1062

    
1063
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1064
{
1065
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1066
}
1067

    
1068
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1069
{
1070
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1071
}
1072

    
1073
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1074
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1075
#define tcg_gen_st_f32 tcg_gen_st_i32
1076
#define tcg_gen_st_f64 tcg_gen_st_i64
1077

    
1078
static inline void gen_mov_F0_vreg(int dp, int reg)
1079
{
1080
    if (dp)
1081
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1082
    else
1083
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1084
}
1085

    
1086
static inline void gen_mov_F1_vreg(int dp, int reg)
1087
{
1088
    if (dp)
1089
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1090
    else
1091
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1092
}
1093

    
1094
static inline void gen_mov_vreg_F0(int dp, int reg)
1095
{
1096
    if (dp)
1097
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1098
    else
1099
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1100
}
1101

    
1102
#define ARM_CP_RW_BIT        (1 << 20)
1103

    
1104
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1105
{
1106
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1107
}
1108

    
1109
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1110
{
1111
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1112
}
1113

    
1114
static inline TCGv iwmmxt_load_creg(int reg)
1115
{
1116
    TCGv var = tcg_temp_new_i32();
1117
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1118
    return var;
1119
}
1120

    
1121
static inline void iwmmxt_store_creg(int reg, TCGv var)
1122
{
1123
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1124
    tcg_temp_free_i32(var);
1125
}
1126

    
1127
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1128
{
1129
    iwmmxt_store_reg(cpu_M0, rn);
1130
}
1131

    
1132
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1133
{
1134
    iwmmxt_load_reg(cpu_M0, rn);
1135
}
1136

    
1137
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1138
{
1139
    iwmmxt_load_reg(cpu_V1, rn);
1140
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1141
}
1142

    
1143
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1144
{
1145
    iwmmxt_load_reg(cpu_V1, rn);
1146
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1147
}
1148

    
1149
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1150
{
1151
    iwmmxt_load_reg(cpu_V1, rn);
1152
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1153
}
1154

    
1155
#define IWMMXT_OP(name) \
1156
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1157
{ \
1158
    iwmmxt_load_reg(cpu_V1, rn); \
1159
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1160
}
1161

    
1162
#define IWMMXT_OP_ENV(name) \
1163
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1164
{ \
1165
    iwmmxt_load_reg(cpu_V1, rn); \
1166
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1167
}
1168

    
1169
#define IWMMXT_OP_ENV_SIZE(name) \
1170
IWMMXT_OP_ENV(name##b) \
1171
IWMMXT_OP_ENV(name##w) \
1172
IWMMXT_OP_ENV(name##l)
1173

    
1174
#define IWMMXT_OP_ENV1(name) \
1175
static inline void gen_op_iwmmxt_##name##_M0(void) \
1176
{ \
1177
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1178
}
1179

    
1180
IWMMXT_OP(maddsq)
1181
IWMMXT_OP(madduq)
1182
IWMMXT_OP(sadb)
1183
IWMMXT_OP(sadw)
1184
IWMMXT_OP(mulslw)
1185
IWMMXT_OP(mulshw)
1186
IWMMXT_OP(mululw)
1187
IWMMXT_OP(muluhw)
1188
IWMMXT_OP(macsw)
1189
IWMMXT_OP(macuw)
1190

    
1191
IWMMXT_OP_ENV_SIZE(unpackl)
1192
IWMMXT_OP_ENV_SIZE(unpackh)
1193

    
1194
IWMMXT_OP_ENV1(unpacklub)
1195
IWMMXT_OP_ENV1(unpackluw)
1196
IWMMXT_OP_ENV1(unpacklul)
1197
IWMMXT_OP_ENV1(unpackhub)
1198
IWMMXT_OP_ENV1(unpackhuw)
1199
IWMMXT_OP_ENV1(unpackhul)
1200
IWMMXT_OP_ENV1(unpacklsb)
1201
IWMMXT_OP_ENV1(unpacklsw)
1202
IWMMXT_OP_ENV1(unpacklsl)
1203
IWMMXT_OP_ENV1(unpackhsb)
1204
IWMMXT_OP_ENV1(unpackhsw)
1205
IWMMXT_OP_ENV1(unpackhsl)
1206

    
1207
IWMMXT_OP_ENV_SIZE(cmpeq)
1208
IWMMXT_OP_ENV_SIZE(cmpgtu)
1209
IWMMXT_OP_ENV_SIZE(cmpgts)
1210

    
1211
IWMMXT_OP_ENV_SIZE(mins)
1212
IWMMXT_OP_ENV_SIZE(minu)
1213
IWMMXT_OP_ENV_SIZE(maxs)
1214
IWMMXT_OP_ENV_SIZE(maxu)
1215

    
1216
IWMMXT_OP_ENV_SIZE(subn)
1217
IWMMXT_OP_ENV_SIZE(addn)
1218
IWMMXT_OP_ENV_SIZE(subu)
1219
IWMMXT_OP_ENV_SIZE(addu)
1220
IWMMXT_OP_ENV_SIZE(subs)
1221
IWMMXT_OP_ENV_SIZE(adds)
1222

    
1223
IWMMXT_OP_ENV(avgb0)
1224
IWMMXT_OP_ENV(avgb1)
1225
IWMMXT_OP_ENV(avgw0)
1226
IWMMXT_OP_ENV(avgw1)
1227

    
1228
IWMMXT_OP(msadb)
1229

    
1230
IWMMXT_OP_ENV(packuw)
1231
IWMMXT_OP_ENV(packul)
1232
IWMMXT_OP_ENV(packuq)
1233
IWMMXT_OP_ENV(packsw)
1234
IWMMXT_OP_ENV(packsl)
1235
IWMMXT_OP_ENV(packsq)
1236

    
1237
static void gen_op_iwmmxt_set_mup(void)
1238
{
1239
    TCGv tmp;
1240
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1241
    tcg_gen_ori_i32(tmp, tmp, 2);
1242
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1243
}
1244

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

    
1253
static void gen_op_iwmmxt_setpsr_nz(void)
1254
{
1255
    TCGv tmp = tcg_temp_new_i32();
1256
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1257
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1258
}
1259

    
1260
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1261
{
1262
    iwmmxt_load_reg(cpu_V1, rn);
1263
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1264
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1265
}
1266

    
1267
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1268
{
1269
    int rd;
1270
    uint32_t offset;
1271
    TCGv tmp;
1272

    
1273
    rd = (insn >> 16) & 0xf;
1274
    tmp = load_reg(s, rd);
1275

    
1276
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1277
    if (insn & (1 << 24)) {
1278
        /* Pre indexed */
1279
        if (insn & (1 << 23))
1280
            tcg_gen_addi_i32(tmp, tmp, offset);
1281
        else
1282
            tcg_gen_addi_i32(tmp, tmp, -offset);
1283
        tcg_gen_mov_i32(dest, tmp);
1284
        if (insn & (1 << 21))
1285
            store_reg(s, rd, tmp);
1286
        else
1287
            tcg_temp_free_i32(tmp);
1288
    } else if (insn & (1 << 21)) {
1289
        /* Post indexed */
1290
        tcg_gen_mov_i32(dest, tmp);
1291
        if (insn & (1 << 23))
1292
            tcg_gen_addi_i32(tmp, tmp, offset);
1293
        else
1294
            tcg_gen_addi_i32(tmp, tmp, -offset);
1295
        store_reg(s, rd, tmp);
1296
    } else if (!(insn & (1 << 23)))
1297
        return 1;
1298
    return 0;
1299
}
1300

    
1301
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1302
{
1303
    int rd = (insn >> 0) & 0xf;
1304
    TCGv tmp;
1305

    
1306
    if (insn & (1 << 8)) {
1307
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1308
            return 1;
1309
        } else {
1310
            tmp = iwmmxt_load_creg(rd);
1311
        }
1312
    } else {
1313
        tmp = tcg_temp_new_i32();
1314
        iwmmxt_load_reg(cpu_V0, rd);
1315
        tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1316
    }
1317
    tcg_gen_andi_i32(tmp, tmp, mask);
1318
    tcg_gen_mov_i32(dest, tmp);
1319
    tcg_temp_free_i32(tmp);
1320
    return 0;
1321
}
1322

    
1323
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1324
   (ie. an undefined instruction).  */
1325
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1326
{
1327
    int rd, wrd;
1328
    int rdhi, rdlo, rd0, rd1, i;
1329
    TCGv addr;
1330
    TCGv tmp, tmp2, tmp3;
1331

    
1332
    if ((insn & 0x0e000e00) == 0x0c000000) {
1333
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1334
            wrd = insn & 0xf;
1335
            rdlo = (insn >> 12) & 0xf;
1336
            rdhi = (insn >> 16) & 0xf;
1337
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1338
                iwmmxt_load_reg(cpu_V0, wrd);
1339
                tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1340
                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1341
                tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1342
            } else {                                        /* TMCRR */
1343
                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1344
                iwmmxt_store_reg(cpu_V0, wrd);
1345
                gen_op_iwmmxt_set_mup();
1346
            }
1347
            return 0;
1348
        }
1349

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

    
1413
    if ((insn & 0x0f000000) != 0x0e000000)
1414
        return 1;
1415

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

    
2324
    return 0;
2325
}
2326

    
2327
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2328
   (ie. an undefined instruction).  */
2329
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2330
{
2331
    int acc, rd0, rd1, rdhi, rdlo;
2332
    TCGv tmp, tmp2;
2333

    
2334
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2335
        /* Multiply with Internal Accumulate Format */
2336
        rd0 = (insn >> 12) & 0xf;
2337
        rd1 = insn & 0xf;
2338
        acc = (insn >> 5) & 7;
2339

    
2340
        if (acc != 0)
2341
            return 1;
2342

    
2343
        tmp = load_reg(s, rd0);
2344
        tmp2 = load_reg(s, rd1);
2345
        switch ((insn >> 16) & 0xf) {
2346
        case 0x0:                                        /* MIA */
2347
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2348
            break;
2349
        case 0x8:                                        /* MIAPH */
2350
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2351
            break;
2352
        case 0xc:                                        /* MIABB */
2353
        case 0xd:                                        /* MIABT */
2354
        case 0xe:                                        /* MIATB */
2355
        case 0xf:                                        /* MIATT */
2356
            if (insn & (1 << 16))
2357
                tcg_gen_shri_i32(tmp, tmp, 16);
2358
            if (insn & (1 << 17))
2359
                tcg_gen_shri_i32(tmp2, tmp2, 16);
2360
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2361
            break;
2362
        default:
2363
            return 1;
2364
        }
2365
        tcg_temp_free_i32(tmp2);
2366
        tcg_temp_free_i32(tmp);
2367

    
2368
        gen_op_iwmmxt_movq_wRn_M0(acc);
2369
        return 0;
2370
    }
2371

    
2372
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2373
        /* Internal Accumulator Access Format */
2374
        rdhi = (insn >> 16) & 0xf;
2375
        rdlo = (insn >> 12) & 0xf;
2376
        acc = insn & 7;
2377

    
2378
        if (acc != 0)
2379
            return 1;
2380

    
2381
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2382
            iwmmxt_load_reg(cpu_V0, acc);
2383
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2384
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2385
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2386
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2387
        } else {                                        /* MAR */
2388
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2389
            iwmmxt_store_reg(cpu_V0, acc);
2390
        }
2391
        return 0;
2392
    }
2393

    
2394
    return 1;
2395
}
2396

    
2397
/* Disassemble system coprocessor instruction.  Return nonzero if
2398
   instruction is not defined.  */
2399
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2400
{
2401
    TCGv tmp, tmp2;
2402
    uint32_t rd = (insn >> 12) & 0xf;
2403
    uint32_t cp = (insn >> 8) & 0xf;
2404
    if (IS_USER(s)) {
2405
        return 1;
2406
    }
2407

    
2408
    if (insn & ARM_CP_RW_BIT) {
2409
        if (!env->cp[cp].cp_read)
2410
            return 1;
2411
        gen_set_pc_im(s->pc);
2412
        tmp = tcg_temp_new_i32();
2413
        tmp2 = tcg_const_i32(insn);
2414
        gen_helper_get_cp(tmp, cpu_env, tmp2);
2415
        tcg_temp_free(tmp2);
2416
        store_reg(s, rd, tmp);
2417
    } else {
2418
        if (!env->cp[cp].cp_write)
2419
            return 1;
2420
        gen_set_pc_im(s->pc);
2421
        tmp = load_reg(s, rd);
2422
        tmp2 = tcg_const_i32(insn);
2423
        gen_helper_set_cp(cpu_env, tmp2, tmp);
2424
        tcg_temp_free(tmp2);
2425
        tcg_temp_free_i32(tmp);
2426
    }
2427
    return 0;
2428
}
2429

    
2430
static int cp15_user_ok(uint32_t insn)
2431
{
2432
    int cpn = (insn >> 16) & 0xf;
2433
    int cpm = insn & 0xf;
2434
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2435

    
2436
    if (cpn == 13 && cpm == 0) {
2437
        /* TLS register.  */
2438
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2439
            return 1;
2440
    }
2441
    if (cpn == 7) {
2442
        /* ISB, DSB, DMB.  */
2443
        if ((cpm == 5 && op == 4)
2444
                || (cpm == 10 && (op == 4 || op == 5)))
2445
            return 1;
2446
    }
2447
    return 0;
2448
}
2449

    
2450
static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd)
2451
{
2452
    TCGv tmp;
2453
    int cpn = (insn >> 16) & 0xf;
2454
    int cpm = insn & 0xf;
2455
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2456

    
2457
    if (!arm_feature(env, ARM_FEATURE_V6K))
2458
        return 0;
2459

    
2460
    if (!(cpn == 13 && cpm == 0))
2461
        return 0;
2462

    
2463
    if (insn & ARM_CP_RW_BIT) {
2464
        switch (op) {
2465
        case 2:
2466
            tmp = load_cpu_field(cp15.c13_tls1);
2467
            break;
2468
        case 3:
2469
            tmp = load_cpu_field(cp15.c13_tls2);
2470
            break;
2471
        case 4:
2472
            tmp = load_cpu_field(cp15.c13_tls3);
2473
            break;
2474
        default:
2475
            return 0;
2476
        }
2477
        store_reg(s, rd, tmp);
2478

    
2479
    } else {
2480
        tmp = load_reg(s, rd);
2481
        switch (op) {
2482
        case 2:
2483
            store_cpu_field(tmp, cp15.c13_tls1);
2484
            break;
2485
        case 3:
2486
            store_cpu_field(tmp, cp15.c13_tls2);
2487
            break;
2488
        case 4:
2489
            store_cpu_field(tmp, cp15.c13_tls3);
2490
            break;
2491
        default:
2492
            tcg_temp_free_i32(tmp);
2493
            return 0;
2494
        }
2495
    }
2496
    return 1;
2497
}
2498

    
2499
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2500
   instruction is not defined.  */
2501
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2502
{
2503
    uint32_t rd;
2504
    TCGv tmp, tmp2;
2505

    
2506
    /* M profile cores use memory mapped registers instead of cp15.  */
2507
    if (arm_feature(env, ARM_FEATURE_M))
2508
        return 1;
2509

    
2510
    if ((insn & (1 << 25)) == 0) {
2511
        if (insn & (1 << 20)) {
2512
            /* mrrc */
2513
            return 1;
2514
        }
2515
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2516
        return 0;
2517
    }
2518
    if ((insn & (1 << 4)) == 0) {
2519
        /* cdp */
2520
        return 1;
2521
    }
2522
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2523
        return 1;
2524
    }
2525

    
2526
    /* Pre-v7 versions of the architecture implemented WFI via coprocessor
2527
     * instructions rather than a separate instruction.
2528
     */
2529
    if ((insn & 0x0fff0fff) == 0x0e070f90) {
2530
        /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
2531
         * In v7, this must NOP.
2532
         */
2533
        if (!arm_feature(env, ARM_FEATURE_V7)) {
2534
            /* Wait for interrupt.  */
2535
            gen_set_pc_im(s->pc);
2536
            s->is_jmp = DISAS_WFI;
2537
        }
2538
        return 0;
2539
    }
2540

    
2541
    if ((insn & 0x0fff0fff) == 0x0e070f58) {
2542
        /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
2543
         * so this is slightly over-broad.
2544
         */
2545
        if (!arm_feature(env, ARM_FEATURE_V6)) {
2546
            /* Wait for interrupt.  */
2547
            gen_set_pc_im(s->pc);
2548
            s->is_jmp = DISAS_WFI;
2549
            return 0;
2550
        }
2551
        /* Otherwise fall through to handle via helper function.
2552
         * In particular, on v7 and some v6 cores this is one of
2553
         * the VA-PA registers.
2554
         */
2555
    }
2556

    
2557
    rd = (insn >> 12) & 0xf;
2558

    
2559
    if (cp15_tls_load_store(env, s, insn, rd))
2560
        return 0;
2561

    
2562
    tmp2 = tcg_const_i32(insn);
2563
    if (insn & ARM_CP_RW_BIT) {
2564
        tmp = tcg_temp_new_i32();
2565
        gen_helper_get_cp15(tmp, cpu_env, tmp2);
2566
        /* If the destination register is r15 then sets condition codes.  */
2567
        if (rd != 15)
2568
            store_reg(s, rd, tmp);
2569
        else
2570
            tcg_temp_free_i32(tmp);
2571
    } else {
2572
        tmp = load_reg(s, rd);
2573
        gen_helper_set_cp15(cpu_env, tmp2, tmp);
2574
        tcg_temp_free_i32(tmp);
2575
        /* Normally we would always end the TB here, but Linux
2576
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2577
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2578
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2579
                (insn & 0x0fff0fff) != 0x0e010f10)
2580
            gen_lookup_tb(s);
2581
    }
2582
    tcg_temp_free_i32(tmp2);
2583
    return 0;
2584
}
2585

    
2586
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2587
#define VFP_SREG(insn, bigbit, smallbit) \
2588
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2589
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2590
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2591
        reg = (((insn) >> (bigbit)) & 0x0f) \
2592
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2593
    } else { \
2594
        if (insn & (1 << (smallbit))) \
2595
            return 1; \
2596
        reg = ((insn) >> (bigbit)) & 0x0f; \
2597
    }} while (0)
2598

    
2599
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2600
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2601
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2602
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2603
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2604
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2605

    
2606
/* Move between integer and VFP cores.  */
2607
static TCGv gen_vfp_mrs(void)
2608
{
2609
    TCGv tmp = tcg_temp_new_i32();
2610
    tcg_gen_mov_i32(tmp, cpu_F0s);
2611
    return tmp;
2612
}
2613

    
2614
static void gen_vfp_msr(TCGv tmp)
2615
{
2616
    tcg_gen_mov_i32(cpu_F0s, tmp);
2617
    tcg_temp_free_i32(tmp);
2618
}
2619

    
2620
static void gen_neon_dup_u8(TCGv var, int shift)
2621
{
2622
    TCGv tmp = tcg_temp_new_i32();
2623
    if (shift)
2624
        tcg_gen_shri_i32(var, var, shift);
2625
    tcg_gen_ext8u_i32(var, var);
2626
    tcg_gen_shli_i32(tmp, var, 8);
2627
    tcg_gen_or_i32(var, var, tmp);
2628
    tcg_gen_shli_i32(tmp, var, 16);
2629
    tcg_gen_or_i32(var, var, tmp);
2630
    tcg_temp_free_i32(tmp);
2631
}
2632

    
2633
static void gen_neon_dup_low16(TCGv var)
2634
{
2635
    TCGv tmp = tcg_temp_new_i32();
2636
    tcg_gen_ext16u_i32(var, var);
2637
    tcg_gen_shli_i32(tmp, var, 16);
2638
    tcg_gen_or_i32(var, var, tmp);
2639
    tcg_temp_free_i32(tmp);
2640
}
2641

    
2642
static void gen_neon_dup_high16(TCGv var)
2643
{
2644
    TCGv tmp = tcg_temp_new_i32();
2645
    tcg_gen_andi_i32(var, var, 0xffff0000);
2646
    tcg_gen_shri_i32(tmp, var, 16);
2647
    tcg_gen_or_i32(var, var, tmp);
2648
    tcg_temp_free_i32(tmp);
2649
}
2650

    
2651
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2652
   (ie. an undefined instruction).  */
2653
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2654
{
2655
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2656
    int dp, veclen;
2657
    TCGv addr;
2658
    TCGv tmp;
2659
    TCGv tmp2;
2660

    
2661
    if (!arm_feature(env, ARM_FEATURE_VFP))
2662
        return 1;
2663

    
2664
    if (!s->vfp_enabled) {
2665
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2666
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2667
            return 1;
2668
        rn = (insn >> 16) & 0xf;
2669
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2670
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2671
            return 1;
2672
    }
2673
    dp = ((insn & 0xf00) == 0xb00);
2674
    switch ((insn >> 24) & 0xf) {
2675
    case 0xe:
2676
        if (insn & (1 << 4)) {
2677
            /* single register transfer */
2678
            rd = (insn >> 12) & 0xf;
2679
            if (dp) {
2680
                int size;
2681
                int pass;
2682

    
2683
                VFP_DREG_N(rn, insn);
2684
                if (insn & 0xf)
2685
                    return 1;
2686
                if (insn & 0x00c00060
2687
                    && !arm_feature(env, ARM_FEATURE_NEON))
2688
                    return 1;
2689

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

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

    
2882
                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2883
                    /* Integer or single precision destination.  */
2884
                    rd = VFP_SREG_D(insn);
2885
                } else {
2886
                    VFP_DREG_D(rd, insn);
2887
                }
2888
                if (op == 15 &&
2889
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2890
                    /* VCVT from int is always from S reg regardless of dp bit.
2891
                     * VCVT with immediate frac_bits has same format as SREG_M
2892
                     */
2893
                    rm = VFP_SREG_M(insn);
2894
                } else {
2895
                    VFP_DREG_M(rm, insn);
2896
                }
2897
            } else {
2898
                rn = VFP_SREG_N(insn);
2899
                if (op == 15 && rn == 15) {
2900
                    /* Double precision destination.  */
2901
                    VFP_DREG_D(rd, insn);
2902
                } else {
2903
                    rd = VFP_SREG_D(insn);
2904
                }
2905
                /* NB that we implicitly rely on the encoding for the frac_bits
2906
                 * in VCVT of fixed to float being the same as that of an SREG_M
2907
                 */
2908
                rm = VFP_SREG_M(insn);
2909
            }
2910

    
2911
            veclen = s->vec_len;
2912
            if (op == 15 && rn > 3)
2913
                veclen = 0;
2914

    
2915
            /* Shut up compiler warnings.  */
2916
            delta_m = 0;
2917
            delta_d = 0;
2918
            bank_mask = 0;
2919

    
2920
            if (veclen > 0) {
2921
                if (dp)
2922
                    bank_mask = 0xc;
2923
                else
2924
                    bank_mask = 0x18;
2925

    
2926
                /* Figure out what type of vector operation this is.  */
2927
                if ((rd & bank_mask) == 0) {
2928
                    /* scalar */
2929
                    veclen = 0;
2930
                } else {
2931
                    if (dp)
2932
                        delta_d = (s->vec_stride >> 1) + 1;
2933
                    else
2934
                        delta_d = s->vec_stride + 1;
2935

    
2936
                    if ((rm & bank_mask) == 0) {
2937
                        /* mixed scalar/vector */
2938
                        delta_m = 0;
2939
                    } else {
2940
                        /* vector */
2941
                        delta_m = delta_d;
2942
                    }
2943
                }
2944
            }
2945

    
2946
            /* Load the initial operands.  */
2947
            if (op == 15) {
2948
                switch (rn) {
2949
                case 16:
2950
                case 17:
2951
                    /* Integer source */
2952
                    gen_mov_F0_vreg(0, rm);
2953
                    break;
2954
                case 8:
2955
                case 9:
2956
                    /* Compare */
2957
                    gen_mov_F0_vreg(dp, rd);
2958
                    gen_mov_F1_vreg(dp, rm);
2959
                    break;
2960
                case 10:
2961
                case 11:
2962
                    /* Compare with zero */
2963
                    gen_mov_F0_vreg(dp, rd);
2964
                    gen_vfp_F1_ld0(dp);
2965
                    break;
2966
                case 20:
2967
                case 21:
2968
                case 22:
2969
                case 23:
2970
                case 28:
2971
                case 29:
2972
                case 30:
2973
                case 31:
2974
                    /* Source and destination the same.  */
2975
                    gen_mov_F0_vreg(dp, rd);
2976
                    break;
2977
                default:
2978
                    /* One source operand.  */
2979
                    gen_mov_F0_vreg(dp, rm);
2980
                    break;
2981
                }
2982
            } else {
2983
                /* Two source operands.  */
2984
                gen_mov_F0_vreg(dp, rn);
2985
                gen_mov_F1_vreg(dp, rm);
2986
            }
2987

    
2988
            for (;;) {
2989
                /* Perform the calculation.  */
2990
                switch (op) {
2991
                case 0: /* mac: fd + (fn * fm) */
2992
                    gen_vfp_mul(dp);
2993
                    gen_mov_F1_vreg(dp, rd);
2994
                    gen_vfp_add(dp);
2995
                    break;
2996
                case 1: /* nmac: fd - (fn * fm) */
2997
                    gen_vfp_mul(dp);
2998
                    gen_vfp_neg(dp);
2999
                    gen_mov_F1_vreg(dp, rd);
3000
                    gen_vfp_add(dp);
3001
                    break;
3002
                case 2: /* msc: -fd + (fn * fm) */
3003
                    gen_vfp_mul(dp);
3004
                    gen_mov_F1_vreg(dp, rd);
3005
                    gen_vfp_sub(dp);
3006
                    break;
3007
                case 3: /* nmsc: -fd - (fn * fm)  */
3008
                    gen_vfp_mul(dp);
3009
                    gen_vfp_neg(dp);
3010
                    gen_mov_F1_vreg(dp, rd);
3011
                    gen_vfp_sub(dp);
3012
                    break;
3013
                case 4: /* mul: fn * fm */
3014
                    gen_vfp_mul(dp);
3015
                    break;
3016
                case 5: /* nmul: -(fn * fm) */
3017
                    gen_vfp_mul(dp);
3018
                    gen_vfp_neg(dp);
3019
                    break;
3020
                case 6: /* add: fn + fm */
3021
                    gen_vfp_add(dp);
3022
                    break;
3023
                case 7: /* sub: fn - fm */
3024
                    gen_vfp_sub(dp);
3025
                    break;
3026
                case 8: /* div: fn / fm */
3027
                    gen_vfp_div(dp);
3028
                    break;
3029
                case 14: /* fconst */
3030
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3031
                      return 1;
3032

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

    
3193
                /* Write back the result.  */
3194
                if (op == 15 && (rn >= 8 && rn <= 11))
3195
                    ; /* Comparison, do nothing.  */
3196
                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3197
                    /* VCVT double to int: always integer result. */
3198
                    gen_mov_vreg_F0(0, rd);
3199
                else if (op == 15 && rn == 15)
3200
                    /* conversion */
3201
                    gen_mov_vreg_F0(!dp, rd);
3202
                else
3203
                    gen_mov_vreg_F0(dp, rd);
3204

    
3205
                /* break out of the loop if we have finished  */
3206
                if (veclen == 0)
3207
                    break;
3208

    
3209
                if (op == 15 && delta_m == 0) {
3210
                    /* single source one-many */
3211
                    while (veclen--) {
3212
                        rd = ((rd + delta_d) & (bank_mask - 1))
3213
                             | (rd & bank_mask);
3214
                        gen_mov_vreg_F0(dp, rd);
3215
                    }
3216
                    break;
3217
                }
3218
                /* Setup the next operands.  */
3219
                veclen--;
3220
                rd = ((rd + delta_d) & (bank_mask - 1))
3221
                     | (rd & bank_mask);
3222

    
3223
                if (op == 15) {
3224
                    /* One source operand.  */
3225
                    rm = ((rm + delta_m) & (bank_mask - 1))
3226
                         | (rm & bank_mask);
3227
                    gen_mov_F0_vreg(dp, rm);
3228
                } else {
3229
                    /* Two source operands.  */
3230
                    rn = ((rn + delta_d) & (bank_mask - 1))
3231
                         | (rn & bank_mask);
3232
                    gen_mov_F0_vreg(dp, rn);
3233
                    if (delta_m) {
3234
                        rm = ((rm + delta_m) & (bank_mask - 1))
3235
                             | (rm & bank_mask);
3236
                        gen_mov_F1_vreg(dp, rm);
3237
                    }
3238
                }
3239
            }
3240
        }
3241
        break;
3242
    case 0xc:
3243
    case 0xd:
3244
        if ((insn & 0x03e00000) == 0x00400000) {
3245
            /* two-register transfer */
3246
            rn = (insn >> 16) & 0xf;
3247
            rd = (insn >> 12) & 0xf;
3248
            if (dp) {
3249
                VFP_DREG_M(rm, insn);
3250
            } else {
3251
                rm = VFP_SREG_M(insn);
3252
            }
3253

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

    
3323
                if (insn & (1 << 24)) /* pre-decrement */
3324
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3325

    
3326
                if (dp)
3327
                    offset = 8;
3328
                else
3329
                    offset = 4;
3330
                for (i = 0; i < n; i++) {
3331
                    if (insn & ARM_CP_RW_BIT) {
3332
                        /* load */
3333
                        gen_vfp_ld(s, dp, addr);
3334
                        gen_mov_vreg_F0(dp, rd + i);
3335
                    } else {
3336
                        /* store */
3337
                        gen_mov_F0_vreg(dp, rd + i);
3338
                        gen_vfp_st(s, dp, addr);
3339
                    }
3340
                    tcg_gen_addi_i32(addr, addr, offset);
3341
                }
3342
                if (insn & (1 << 21)) {
3343
                    /* writeback */
3344
                    if (insn & (1 << 24))
3345
                        offset = -offset * n;
3346
                    else if (dp && (insn & 1))
3347
                        offset = 4;
3348
                    else
3349
                        offset = 0;
3350

    
3351
                    if (offset != 0)
3352
                        tcg_gen_addi_i32(addr, addr, offset);
3353
                    store_reg(s, rn, addr);
3354
                } else {
3355
                    tcg_temp_free_i32(addr);
3356
                }
3357
            }
3358
        }
3359
        break;
3360
    default:
3361
        /* Should never happen.  */
3362
        return 1;
3363
    }
3364
    return 0;
3365
}
3366

    
3367
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3368
{
3369
    TranslationBlock *tb;
3370

    
3371
    tb = s->tb;
3372
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3373
        tcg_gen_goto_tb(n);
3374
        gen_set_pc_im(dest);
3375
        tcg_gen_exit_tb((long)tb + n);
3376
    } else {
3377
        gen_set_pc_im(dest);
3378
        tcg_gen_exit_tb(0);
3379
    }
3380
}
3381

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

    
3395
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3396
{
3397
    if (x)
3398
        tcg_gen_sari_i32(t0, t0, 16);
3399
    else
3400
        gen_sxth(t0);
3401
    if (y)
3402
        tcg_gen_sari_i32(t1, t1, 16);
3403
    else
3404
        gen_sxth(t1);
3405
    tcg_gen_mul_i32(t0, t0, t1);
3406
}
3407

    
3408
/* Return the mask of PSR bits set by a MSR instruction.  */
3409
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3410
    uint32_t mask;
3411

    
3412
    mask = 0;
3413
    if (flags & (1 << 0))
3414
        mask |= 0xff;
3415
    if (flags & (1 << 1))
3416
        mask |= 0xff00;
3417
    if (flags & (1 << 2))
3418
        mask |= 0xff0000;
3419
    if (flags & (1 << 3))
3420
        mask |= 0xff000000;
3421

    
3422
    /* Mask out undefined bits.  */
3423
    mask &= ~CPSR_RESERVED;
3424
    if (!arm_feature(env, ARM_FEATURE_V6))
3425
        mask &= ~(CPSR_E | CPSR_GE);
3426
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3427
        mask &= ~CPSR_IT;
3428
    /* Mask out execution state bits.  */
3429
    if (!spsr)
3430
        mask &= ~CPSR_EXEC;
3431
    /* Mask out privileged bits.  */
3432
    if (IS_USER(s))
3433
        mask &= CPSR_USER;
3434
    return mask;
3435
}
3436

    
3437
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3438
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3439
{
3440
    TCGv tmp;
3441
    if (spsr) {
3442
        /* ??? This is also undefined in system mode.  */
3443
        if (IS_USER(s))
3444
            return 1;
3445

    
3446
        tmp = load_cpu_field(spsr);
3447
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3448
        tcg_gen_andi_i32(t0, t0, mask);
3449
        tcg_gen_or_i32(tmp, tmp, t0);
3450
        store_cpu_field(tmp, spsr);
3451
    } else {
3452
        gen_set_cpsr(t0, mask);
3453
    }
3454
    tcg_temp_free_i32(t0);
3455
    gen_lookup_tb(s);
3456
    return 0;
3457
}
3458

    
3459
/* Returns nonzero if access to the PSR is not permitted.  */
3460
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3461
{
3462
    TCGv tmp;
3463
    tmp = tcg_temp_new_i32();
3464
    tcg_gen_movi_i32(tmp, val);
3465
    return gen_set_psr(s, mask, spsr, tmp);
3466
}
3467

    
3468
/* Generate an old-style exception return. Marks pc as dead. */
3469
static void gen_exception_return(DisasContext *s, TCGv pc)
3470
{
3471
    TCGv tmp;
3472
    store_reg(s, 15, pc);
3473
    tmp = load_cpu_field(spsr);
3474
    gen_set_cpsr(tmp, 0xffffffff);
3475
    tcg_temp_free_i32(tmp);
3476
    s->is_jmp = DISAS_UPDATE;
3477
}
3478

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

    
3488
static inline void
3489
gen_set_condexec (DisasContext *s)
3490
{
3491
    if (s->condexec_mask) {
3492
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3493
        TCGv tmp = tcg_temp_new_i32();
3494
        tcg_gen_movi_i32(tmp, val);
3495
        store_cpu_field(tmp, condexec_bits);
3496
    }
3497
}
3498

    
3499
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3500
{
3501
    gen_set_condexec(s);
3502
    gen_set_pc_im(s->pc - offset);
3503
    gen_exception(excp);
3504
    s->is_jmp = DISAS_JUMP;
3505
}
3506

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

    
3522
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3523

    
3524
static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3525
{
3526
    switch (size) {
3527
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3528
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3529
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3530
    default: return 1;
3531
    }
3532
    return 0;
3533
}
3534

    
3535
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3536
{
3537
    switch (size) {
3538
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3539
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3540
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3541
    default: return;
3542
    }
3543
}
3544

    
3545
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3546
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3547
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3548
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3549
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3550

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

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

    
3597
static TCGv neon_load_scratch(int scratch)
3598
{
3599
    TCGv tmp = tcg_temp_new_i32();
3600
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3601
    return tmp;
3602
}
3603

    
3604
static void neon_store_scratch(int scratch, TCGv var)
3605
{
3606
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3607
    tcg_temp_free_i32(var);
3608
}
3609

    
3610
static inline TCGv neon_get_scalar(int size, int reg)
3611
{
3612
    TCGv tmp;
3613
    if (size == 1) {
3614
        tmp = neon_load_reg(reg & 7, reg >> 4);
3615
        if (reg & 8) {
3616
            gen_neon_dup_high16(tmp);
3617
        } else {
3618
            gen_neon_dup_low16(tmp);
3619
        }
3620
    } else {
3621
        tmp = neon_load_reg(reg & 15, reg >> 4);
3622
    }
3623
    return tmp;
3624
}
3625

    
3626
static int gen_neon_unzip(int rd, int rm, int size, int q)
3627
{
3628
    TCGv tmp, tmp2;
3629
    if (size == 3 || (!q && size == 2)) {
3630
        return 1;
3631
    }
3632
    tmp = tcg_const_i32(rd);
3633
    tmp2 = tcg_const_i32(rm);
3634
    if (q) {
3635
        switch (size) {
3636
        case 0:
3637
            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3638
            break;
3639
        case 1:
3640
            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3641
            break;
3642
        case 2:
3643
            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3644
            break;
3645
        default:
3646
            abort();
3647
        }
3648
    } else {
3649
        switch (size) {
3650
        case 0:
3651
            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3652
            break;
3653
        case 1:
3654
            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3655
            break;
3656
        default:
3657
            abort();
3658
        }
3659
    }
3660
    tcg_temp_free_i32(tmp);
3661
    tcg_temp_free_i32(tmp2);
3662
    return 0;
3663
}
3664

    
3665
static int gen_neon_zip(int rd, int rm, int size, int q)
3666
{
3667
    TCGv tmp, tmp2;
3668
    if (size == 3 || (!q && size == 2)) {
3669
        return 1;
3670
    }
3671
    tmp = tcg_const_i32(rd);
3672
    tmp2 = tcg_const_i32(rm);
3673
    if (q) {
3674
        switch (size) {
3675
        case 0:
3676
            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3677
            break;
3678
        case 1:
3679
            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3680
            break;
3681
        case 2:
3682
            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3683
            break;
3684
        default:
3685
            abort();
3686
        }
3687
    } else {
3688
        switch (size) {
3689
        case 0:
3690
            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3691
            break;
3692
        case 1:
3693
            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3694
            break;
3695
        default:
3696
            abort();
3697
        }
3698
    }
3699
    tcg_temp_free_i32(tmp);
3700
    tcg_temp_free_i32(tmp2);
3701
    return 0;
3702
}
3703

    
3704
static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3705
{
3706
    TCGv rd, tmp;
3707

    
3708
    rd = tcg_temp_new_i32();
3709
    tmp = tcg_temp_new_i32();
3710

    
3711
    tcg_gen_shli_i32(rd, t0, 8);
3712
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3713
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3714
    tcg_gen_or_i32(rd, rd, tmp);
3715

    
3716
    tcg_gen_shri_i32(t1, t1, 8);
3717
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3718
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3719
    tcg_gen_or_i32(t1, t1, tmp);
3720
    tcg_gen_mov_i32(t0, rd);
3721

    
3722
    tcg_temp_free_i32(tmp);
3723
    tcg_temp_free_i32(rd);
3724
}
3725

    
3726
static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3727
{
3728
    TCGv rd, tmp;
3729

    
3730
    rd = tcg_temp_new_i32();
3731
    tmp = tcg_temp_new_i32();
3732

    
3733
    tcg_gen_shli_i32(rd, t0, 16);
3734
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3735
    tcg_gen_or_i32(rd, rd, tmp);
3736
    tcg_gen_shri_i32(t1, t1, 16);
3737
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3738
    tcg_gen_or_i32(t1, t1, tmp);
3739
    tcg_gen_mov_i32(t0, rd);
3740

    
3741
    tcg_temp_free_i32(tmp);
3742
    tcg_temp_free_i32(rd);
3743
}
3744

    
3745

    
3746
static struct {
3747
    int nregs;
3748
    int interleave;
3749
    int spacing;
3750
} neon_ls_element_type[11] = {
3751
    {4, 4, 1},
3752
    {4, 4, 2},
3753
    {4, 1, 1},
3754
    {4, 2, 1},
3755
    {3, 3, 1},
3756
    {3, 3, 2},
3757
    {3, 1, 1},
3758
    {1, 1, 1},
3759
    {2, 2, 1},
3760
    {2, 2, 2},
3761
    {2, 1, 1}
3762
};
3763

    
3764
/* Translate a NEON load/store element instruction.  Return nonzero if the
3765
   instruction is invalid.  */
3766
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3767
{
3768
    int rd, rn, rm;
3769
    int op;
3770
    int nregs;
3771
    int interleave;
3772
    int spacing;
3773
    int stride;
3774
    int size;
3775
    int reg;
3776
    int pass;
3777
    int load;
3778
    int shift;
3779
    int n;
3780
    TCGv addr;
3781
    TCGv tmp;
3782
    TCGv tmp2;
3783
    TCGv_i64 tmp64;
3784

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

    
3993
        base = load_reg(s, rn);
3994
        if (rm == 13) {
3995
            tcg_gen_addi_i32(base, base, stride);
3996
        } else {
3997
            TCGv index;
3998
            index = load_reg(s, rm);
3999
            tcg_gen_add_i32(base, base, index);
4000
            tcg_temp_free_i32(index);
4001
        }
4002
        store_reg(s, rn, base);
4003
    }
4004
    return 0;
4005
}
4006

    
4007
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4008
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4009
{
4010
    tcg_gen_and_i32(t, t, c);
4011
    tcg_gen_andc_i32(f, f, c);
4012
    tcg_gen_or_i32(dest, t, f);
4013
}
4014

    
4015
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4016
{
4017
    switch (size) {
4018
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4019
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4020
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4021
    default: abort();
4022
    }
4023
}
4024

    
4025
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4026
{
4027
    switch (size) {
4028
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4029
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4030
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4031
    default: abort();
4032
    }
4033
}
4034

    
4035
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4036
{
4037
    switch (size) {
4038
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4039
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4040
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4041
    default: abort();
4042
    }
4043
}
4044

    
4045
static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4046
{
4047
    switch (size) {
4048
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4049
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4050
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4051
    default: abort();
4052
    }
4053
}
4054

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

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

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

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

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

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

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

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

    
4170
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4171
       Don't forget to clean them now.  */
4172
    if (size < 2) {
4173
        tcg_temp_free_i32(a);
4174
        tcg_temp_free_i32(b);
4175
    }
4176
}
4177

    
4178
static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
4179
{
4180
    if (op) {
4181
        if (u) {
4182
            gen_neon_unarrow_sats(size, dest, src);
4183
        } else {
4184
            gen_neon_narrow(size, dest, src);
4185
        }
4186
    } else {
4187
        if (u) {
4188
            gen_neon_narrow_satu(size, dest, src);
4189
        } else {
4190
            gen_neon_narrow_sats(size, dest, src);
4191
        }
4192
    }
4193
}
4194

    
4195
/* Translate a NEON data processing instruction.  Return nonzero if the
4196
   instruction is invalid.
4197
   We process data in a mixture of 32-bit and 64-bit chunks.
4198
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4199

    
4200
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4201
{
4202
    int op;
4203
    int q;
4204
    int rd, rn, rm;
4205
    int size;
4206
    int shift;
4207
    int pass;
4208
    int count;
4209
    int pairwise;
4210
    int u;
4211
    int n;
4212
    uint32_t imm, mask;
4213
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4214
    TCGv_i64 tmp64;
4215

    
4216
    if (!s->vfp_enabled)
4217
      return 1;
4218
    q = (insn & (1 << 6)) != 0;
4219
    u = (insn >> 24) & 1;
4220
    VFP_DREG_D(rd, insn);
4221
    VFP_DREG_N(rn, insn);
4222
    VFP_DREG_M(rm, insn);
4223
    size = (insn >> 20) & 3;
4224
    if ((insn & (1 << 23)) == 0) {
4225
        /* Three register same length.  */
4226
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4227
        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4228
                          || op == 10 || op  == 11 || op == 16)) {
4229
            /* 64-bit element instructions.  */
4230
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4231
                neon_load_reg64(cpu_V0, rn + pass);
4232
                neon_load_reg64(cpu_V1, rm + pass);
4233
                switch (op) {
4234
                case 1: /* VQADD */
4235
                    if (u) {
4236
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4237
                                                 cpu_V0, cpu_V1);
4238
                    } else {
4239
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4240
                                                 cpu_V0, cpu_V1);
4241
                    }
4242
                    break;
4243
                case 5: /* VQSUB */
4244
                    if (u) {
4245
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4246
                                                 cpu_V0, cpu_V1);
4247
                    } else {
4248
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4249
                                                 cpu_V0, cpu_V1);
4250
                    }
4251
                    break;
4252
                case 8: /* VSHL */
4253
                    if (u) {
4254
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4255
                    } else {
4256
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4257
                    }
4258
                    break;
4259
                case 9: /* VQSHL */
4260
                    if (u) {
4261
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4262
                                                 cpu_V1, cpu_V0);
4263
                    } else {
4264
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4265
                                                 cpu_V1, cpu_V0);
4266
                    }
4267
                    break;
4268
                case 10: /* VRSHL */
4269
                    if (u) {
4270
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4271
                    } else {
4272
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4273
                    }
4274
                    break;
4275
                case 11: /* VQRSHL */
4276
                    if (u) {
4277
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4278
                                                  cpu_V1, cpu_V0);
4279
                    } else {
4280
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4281
                                                  cpu_V1, cpu_V0);
4282
                    }
4283
                    break;
4284
                case 16:
4285
                    if (u) {
4286
                        tcg_gen_sub_i64(CPU_V001);
4287
                    } else {
4288
                        tcg_gen_add_i64(CPU_V001);
4289
                    }
4290
                    break;
4291
                default:
4292
                    abort();
4293
                }
4294
                neon_store_reg64(cpu_V0, rd + pass);
4295
            }
4296
            return 0;
4297
        }
4298
        switch (op) {
4299
        case 8: /* VSHL */
4300
        case 9: /* VQSHL */
4301
        case 10: /* VRSHL */
4302
        case 11: /* VQRSHL */
4303
            {
4304
                int rtmp;
4305
                /* Shift instruction operands are reversed.  */
4306
                rtmp = rn;
4307
                rn = rm;
4308
                rm = rtmp;
4309
                pairwise = 0;
4310
            }
4311
            break;
4312
        case 20: /* VPMAX */
4313
        case 21: /* VPMIN */
4314
        case 23: /* VPADD */
4315
            pairwise = 1;
4316
            break;
4317
        case 26: /* VPADD (float) */
4318
            pairwise = (u && size < 2);
4319
            break;
4320
        case 30: /* VPMIN/VPMAX (float) */
4321
            pairwise = u;
4322
            break;
4323
        default:
4324
            pairwise = 0;
4325
            break;
4326
        }
4327

    
4328
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4329

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

    
4584
        /* Save the result.  For elementwise operations we can put it
4585
           straight into the destination register.  For pairwise operations
4586
           we have to be careful to avoid clobbering the source operands.  */
4587
        if (pairwise && rd == rm) {
4588
            neon_store_scratch(pass, tmp);
4589
        } else {
4590
            neon_store_reg(rd, pass, tmp);
4591
        }
4592

    
4593
        } /* for pass */
4594
        if (pairwise && rd == rm) {
4595
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4596
                tmp = neon_load_scratch(pass);
4597
                neon_store_reg(rd, pass, tmp);
4598
            }
4599
        }
4600
        /* End of 3 register same size operations.  */
4601
    } else if (insn & (1 << 4)) {
4602
        if ((insn & 0x00380080) != 0) {
4603
            /* Two registers and shift.  */
4604
            op = (insn >> 8) & 0xf;
4605
            if (insn & (1 << 7)) {
4606
                /* 64-bit shift.   */
4607
                size = 3;
4608
            } else {
4609
                size = 2;
4610
                while ((insn & (1 << (size + 19))) == 0)
4611
                    size--;
4612
            }
4613
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4614
            /* To avoid excessive dumplication of ops we implement shift
4615
               by immediate using the variable shift operations.  */
4616
            if (op < 8) {
4617
                /* Shift by immediate:
4618
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4619
                /* Right shifts are encoded as N - shift, where N is the
4620
                   element size in bits.  */
4621
                if (op <= 4)
4622
                    shift = shift - (1 << (size + 3));
4623
                if (size == 3) {
4624
                    count = q + 1;
4625
                } else {
4626
                    count = q ? 4: 2;
4627
                }
4628
                switch (size) {
4629
                case 0:
4630
                    imm = (uint8_t) shift;
4631
                    imm |= imm << 8;
4632
                    imm |= imm << 16;
4633
                    break;
4634
                case 1:
4635
                    imm = (uint16_t) shift;
4636
                    imm |= imm << 16;
4637
                    break;
4638
                case 2:
4639
                case 3:
4640
                    imm = shift;
4641
                    break;
4642
                default:
4643
                    abort();
4644
                }
4645

    
4646
                for (pass = 0; pass < count; pass++) {
4647
                    if (size == 3) {
4648
                        neon_load_reg64(cpu_V0, rm + pass);
4649
                        tcg_gen_movi_i64(cpu_V1, imm);
4650
                        switch (op) {
4651
                        case 0:  /* VSHR */
4652
                        case 1:  /* VSRA */
4653
                            if (u)
4654
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4655
                            else
4656
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4657
                            break;
4658
                        case 2: /* VRSHR */
4659
                        case 3: /* VRSRA */
4660
                            if (u)
4661
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4662
                            else
4663
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4664
                            break;
4665
                        case 4: /* VSRI */
4666
                            if (!u)
4667
                                return 1;
4668
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4669
                            break;
4670
                        case 5: /* VSHL, VSLI */
4671
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4672
                            break;
4673
                        case 6: /* VQSHLU */
4674
                            if (u) {
4675
                                gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
4676
                                                          cpu_V0, cpu_V1);
4677
                            } else {
4678
                                return 1;
4679
                            }
4680
                            break;
4681
                        case 7: /* VQSHL */
4682
                            if (u) {
4683
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4684
                                                         cpu_V0, cpu_V1);
4685
                            } else {
4686
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4687
                                                         cpu_V0, cpu_V1);
4688
                            }
4689
                            break;
4690
                        }
4691
                        if (op == 1 || op == 3) {
4692
                            /* Accumulate.  */
4693
                            neon_load_reg64(cpu_V1, rd + pass);
4694
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4695
                        } else if (op == 4 || (op == 5 && u)) {
4696
                            /* Insert */
4697
                            neon_load_reg64(cpu_V1, rd + pass);
4698
                            uint64_t mask;
4699
                            if (shift < -63 || shift > 63) {
4700
                                mask = 0;
4701
                            } else {
4702
                                if (op == 4) {
4703
                                    mask = 0xffffffffffffffffull >> -shift;
4704
                                } else {
4705
                                    mask = 0xffffffffffffffffull << shift;
4706
                                }
4707
                            }
4708
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
4709
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4710
                        }
4711
                        neon_store_reg64(cpu_V0, rd + pass);
4712
                    } else { /* size < 3 */
4713
                        /* Operands in T0 and T1.  */
4714
                        tmp = neon_load_reg(rm, pass);
4715
                        tmp2 = tcg_temp_new_i32();
4716
                        tcg_gen_movi_i32(tmp2, imm);
4717
                        switch (op) {
4718
                        case 0:  /* VSHR */
4719
                        case 1:  /* VSRA */
4720
                            GEN_NEON_INTEGER_OP(shl);
4721
                            break;
4722
                        case 2: /* VRSHR */
4723
                        case 3: /* VRSRA */
4724
                            GEN_NEON_INTEGER_OP(rshl);
4725
                            break;
4726
                        case 4: /* VSRI */
4727
                            if (!u)
4728
                                return 1;
4729
                            GEN_NEON_INTEGER_OP(shl);
4730
                            break;
4731
                        case 5: /* VSHL, VSLI */
4732
                            switch (size) {
4733
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
4734
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
4735
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
4736
                            default: return 1;
4737
                            }
4738
                            break;
4739
                        case 6: /* VQSHLU */
4740
                            if (!u) {
4741
                                return 1;
4742
                            }
4743
                            switch (size) {
4744
                            case 0:
4745
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
4746
                                                         tmp, tmp2);
4747
                                break;
4748
                            case 1:
4749
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
4750
                                                          tmp, tmp2);
4751
                                break;
4752
                            case 2:
4753
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
4754
                                                          tmp, tmp2);
4755
                                break;
4756
                            default:
4757
                                return 1;
4758
                            }
4759
                            break;
4760
                        case 7: /* VQSHL */
4761
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4762
                            break;
4763
                        }
4764
                        tcg_temp_free_i32(tmp2);
4765

    
4766
                        if (op == 1 || op == 3) {
4767
                            /* Accumulate.  */
4768
                            tmp2 = neon_load_reg(rd, pass);
4769
                            gen_neon_add(size, tmp, tmp2);
4770
                            tcg_temp_free_i32(tmp2);
4771
                        } else if (op == 4 || (op == 5 && u)) {
4772
                            /* Insert */
4773
                            switch (size) {
4774
                            case 0:
4775
                                if (op == 4)
4776
                                    mask = 0xff >> -shift;
4777
                                else
4778
                                    mask = (uint8_t)(0xff << shift);
4779
                                mask |= mask << 8;
4780
                                mask |= mask << 16;
4781
                                break;
4782
                            case 1:
4783
                                if (op == 4)
4784
                                    mask = 0xffff >> -shift;
4785
                                else
4786
                                    mask = (uint16_t)(0xffff << shift);
4787
                                mask |= mask << 16;
4788
                                break;
4789
                            case 2:
4790
                                if (shift < -31 || shift > 31) {
4791
                                    mask = 0;
4792
                                } else {
4793
                                    if (op == 4)
4794
                                        mask = 0xffffffffu >> -shift;
4795
                                    else
4796
                                        mask = 0xffffffffu << shift;
4797
                                }
4798
                                break;
4799
                            default:
4800
                                abort();
4801
                            }
4802
                            tmp2 = neon_load_reg(rd, pass);
4803
                            tcg_gen_andi_i32(tmp, tmp, mask);
4804
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
4805
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4806
                            tcg_temp_free_i32(tmp2);
4807
                        }
4808
                        neon_store_reg(rd, pass, tmp);
4809
                    }
4810
                } /* for pass */
4811
            } else if (op < 10) {
4812
                /* Shift by immediate and narrow:
4813
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4814
                int input_unsigned = (op == 8) ? !u : u;
4815

    
4816
                shift = shift - (1 << (size + 3));
4817
                size++;
4818
                if (size == 3) {
4819
                    tmp64 = tcg_const_i64(shift);
4820
                    neon_load_reg64(cpu_V0, rm);
4821
                    neon_load_reg64(cpu_V1, rm + 1);
4822
                    for (pass = 0; pass < 2; pass++) {
4823
                        TCGv_i64 in;
4824
                        if (pass == 0) {
4825
                            in = cpu_V0;
4826
                        } else {
4827
                            in = cpu_V1;
4828
                        }
4829
                        if (q) {
4830
                            if (input_unsigned) {
4831
                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
4832
                            } else {
4833
                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
4834
                            }
4835
                        } else {
4836
                            if (input_unsigned) {
4837
                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
4838
                            } else {
4839
                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
4840
                            }
4841
                        }
4842
                        tmp = tcg_temp_new_i32();
4843
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
4844
                        neon_store_reg(rd, pass, tmp);
4845
                    } /* for pass */
4846
                    tcg_temp_free_i64(tmp64);
4847
                } else {
4848
                    if (size == 1) {
4849
                        imm = (uint16_t)shift;
4850
                        imm |= imm << 16;
4851
                    } else {
4852
                        /* size == 2 */
4853
                        imm = (uint32_t)shift;
4854
                    }
4855
                    tmp2 = tcg_const_i32(imm);
4856
                    tmp4 = neon_load_reg(rm + 1, 0);
4857
                    tmp5 = neon_load_reg(rm + 1, 1);
4858
                    for (pass = 0; pass < 2; pass++) {
4859
                        if (pass == 0) {
4860
                            tmp = neon_load_reg(rm, 0);
4861
                        } else {
4862
                            tmp = tmp4;
4863
                        }
4864
                        gen_neon_shift_narrow(size, tmp, tmp2, q,
4865
                                              input_unsigned);
4866
                        if (pass == 0) {
4867
                            tmp3 = neon_load_reg(rm, 1);
4868
                        } else {
4869
                            tmp3 = tmp5;
4870
                        }
4871
                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
4872
                                              input_unsigned);
4873
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4874
                        tcg_temp_free_i32(tmp);
4875
                        tcg_temp_free_i32(tmp3);
4876
                        tmp = tcg_temp_new_i32();
4877
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
4878
                        neon_store_reg(rd, pass, tmp);
4879
                    } /* for pass */
4880
                    tcg_temp_free_i32(tmp2);
4881
                }
4882
            } else if (op == 10) {
4883
                /* VSHLL */
4884
                if (q || size == 3)
4885
                    return 1;
4886
                tmp = neon_load_reg(rm, 0);
4887
                tmp2 = neon_load_reg(rm, 1);
4888
                for (pass = 0; pass < 2; pass++) {
4889
                    if (pass == 1)
4890
                        tmp = tmp2;
4891

    
4892
                    gen_neon_widen(cpu_V0, tmp, size, u);
4893

    
4894
                    if (shift != 0) {
4895
                        /* The shift is less than the width of the source
4896
                           type, so we can just shift the whole register.  */
4897
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4898
                        /* Widen the result of shift: we need to clear
4899
                         * the potential overflow bits resulting from
4900
                         * left bits of the narrow input appearing as
4901
                         * right bits of left the neighbour narrow
4902
                         * input.  */
4903
                        if (size < 2 || !u) {
4904
                            uint64_t imm64;
4905
                            if (size == 0) {
4906
                                imm = (0xffu >> (8 - shift));
4907
                                imm |= imm << 16;
4908
                            } else if (size == 1) {
4909
                                imm = 0xffff >> (16 - shift);
4910
                            } else {
4911
                                /* size == 2 */
4912
                                imm = 0xffffffff >> (32 - shift);
4913
                            }
4914
                            if (size < 2) {
4915
                                imm64 = imm | (((uint64_t)imm) << 32);
4916
                            } else {
4917
                                imm64 = imm;
4918
                            }
4919
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
4920
                        }
4921
                    }
4922
                    neon_store_reg64(cpu_V0, rd + pass);
4923
                }
4924
            } else if (op >= 14) {
4925
                /* VCVT fixed-point.  */
4926
                /* We have already masked out the must-be-1 top bit of imm6,
4927
                 * hence this 32-shift where the ARM ARM has 64-imm6.
4928
                 */
4929
                shift = 32 - shift;
4930
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4931
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4932
                    if (!(op & 1)) {
4933
                        if (u)
4934
                            gen_vfp_ulto(0, shift);
4935
                        else
4936
                            gen_vfp_slto(0, shift);
4937
                    } else {
4938
                        if (u)
4939
                            gen_vfp_toul(0, shift);
4940
                        else
4941
                            gen_vfp_tosl(0, shift);
4942
                    }
4943
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4944
                }
4945
            } else {
4946
                return 1;
4947
            }
4948
        } else { /* (insn & 0x00380080) == 0 */
4949
            int invert;
4950

    
4951
            op = (insn >> 8) & 0xf;
4952
            /* One register and immediate.  */
4953
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4954
            invert = (insn & (1 << 5)) != 0;
4955
            switch (op) {
4956
            case 0: case 1:
4957
                /* no-op */
4958
                break;
4959
            case 2: case 3:
4960
                imm <<= 8;
4961
                break;
4962
            case 4: case 5:
4963
                imm <<= 16;
4964
                break;
4965
            case 6: case 7:
4966
                imm <<= 24;
4967
                break;
4968
            case 8: case 9:
4969
                imm |= imm << 16;
4970
                break;
4971
            case 10: case 11:
4972
                imm = (imm << 8) | (imm << 24);
4973
                break;
4974
            case 12:
4975
                imm = (imm << 8) | 0xff;
4976
                break;
4977
            case 13:
4978
                imm = (imm << 16) | 0xffff;
4979
                break;
4980
            case 14:
4981
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4982
                if (invert)
4983
                    imm = ~imm;
4984
                break;
4985
            case 15:
4986
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4987
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4988
                break;
4989
            }
4990
            if (invert)
4991
                imm = ~imm;
4992

    
4993
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4994
                if (op & 1 && op < 12) {
4995
                    tmp = neon_load_reg(rd, pass);
4996
                    if (invert) {
4997
                        /* The immediate value has already been inverted, so
4998
                           BIC becomes AND.  */
4999
                        tcg_gen_andi_i32(tmp, tmp, imm);
5000
                    } else {
5001
                        tcg_gen_ori_i32(tmp, tmp, imm);
5002
                    }
5003
                } else {
5004
                    /* VMOV, VMVN.  */
5005
                    tmp = tcg_temp_new_i32();
5006
                    if (op == 14 && invert) {
5007
                        uint32_t val;
5008
                        val = 0;
5009
                        for (n = 0; n < 4; n++) {
5010
                            if (imm & (1 << (n + (pass & 1) * 4)))
5011
                                val |= 0xff << (n * 8);
5012
                        }
5013
                        tcg_gen_movi_i32(tmp, val);
5014
                    } else {
5015
                        tcg_gen_movi_i32(tmp, imm);
5016
                    }
5017
                }
5018
                neon_store_reg(rd, pass, tmp);
5019
            }
5020
        }
5021
    } else { /* (insn & 0x00800010 == 0x00800000) */
5022
        if (size != 3) {
5023
            op = (insn >> 8) & 0xf;
5024
            if ((insn & (1 << 6)) == 0) {
5025
                /* Three registers of different lengths.  */
5026
                int src1_wide;
5027
                int src2_wide;
5028
                int prewiden;
5029
                /* prewiden, src1_wide, src2_wide */
5030
                static const int neon_3reg_wide[16][3] = {
5031
                    {1, 0, 0}, /* VADDL */
5032
                    {1, 1, 0}, /* VADDW */
5033
                    {1, 0, 0}, /* VSUBL */
5034
                    {1, 1, 0}, /* VSUBW */
5035
                    {0, 1, 1}, /* VADDHN */
5036
                    {0, 0, 0}, /* VABAL */
5037
                    {0, 1, 1}, /* VSUBHN */
5038
                    {0, 0, 0}, /* VABDL */
5039
                    {0, 0, 0}, /* VMLAL */
5040
                    {0, 0, 0}, /* VQDMLAL */
5041
                    {0, 0, 0}, /* VMLSL */
5042
                    {0, 0, 0}, /* VQDMLSL */
5043
                    {0, 0, 0}, /* Integer VMULL */
5044
                    {0, 0, 0}, /* VQDMULL */
5045
                    {0, 0, 0}  /* Polynomial VMULL */
5046
                };
5047

    
5048
                prewiden = neon_3reg_wide[op][0];
5049
                src1_wide = neon_3reg_wide[op][1];
5050
                src2_wide = neon_3reg_wide[op][2];
5051

    
5052
                if (size == 0 && (op == 9 || op == 11 || op == 13))
5053
                    return 1;
5054

    
5055
                /* Avoid overlapping operands.  Wide source operands are
5056
                   always aligned so will never overlap with wide
5057
                   destinations in problematic ways.  */
5058
                if (rd == rm && !src2_wide) {
5059
                    tmp = neon_load_reg(rm, 1);
5060
                    neon_store_scratch(2, tmp);
5061
                } else if (rd == rn && !src1_wide) {
5062
                    tmp = neon_load_reg(rn, 1);
5063
                    neon_store_scratch(2, tmp);
5064
                }
5065
                TCGV_UNUSED(tmp3);
5066
                for (pass = 0; pass < 2; pass++) {
5067
                    if (src1_wide) {
5068
                        neon_load_reg64(cpu_V0, rn + pass);
5069
                        TCGV_UNUSED(tmp);
5070
                    } else {
5071
                        if (pass == 1 && rd == rn) {
5072
                            tmp = neon_load_scratch(2);
5073
                        } else {
5074
                            tmp = neon_load_reg(rn, pass);
5075
                        }
5076
                        if (prewiden) {
5077
                            gen_neon_widen(cpu_V0, tmp, size, u);
5078
                        }
5079
                    }
5080
                    if (src2_wide) {
5081
                        neon_load_reg64(cpu_V1, rm + pass);
5082
                        TCGV_UNUSED(tmp2);
5083
                    } else {
5084
                        if (pass == 1 && rd == rm) {
5085
                            tmp2 = neon_load_scratch(2);
5086
                        } else {
5087
                            tmp2 = neon_load_reg(rm, pass);
5088
                        }
5089
                        if (prewiden) {
5090
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5091
                        }
5092
                    }
5093
                    switch (op) {
5094
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5095
                        gen_neon_addl(size);
5096
                        break;
5097
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5098
                        gen_neon_subl(size);
5099
                        break;
5100
                    case 5: case 7: /* VABAL, VABDL */
5101
                        switch ((size << 1) | u) {
5102
                        case 0:
5103
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5104
                            break;
5105
                        case 1:
5106
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5107
                            break;
5108
                        case 2:
5109
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5110
                            break;
5111
                        case 3:
5112
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5113
                            break;
5114
                        case 4:
5115
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5116
                            break;
5117
                        case 5:
5118
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5119
                            break;
5120
                        default: abort();
5121
                        }
5122
                        tcg_temp_free_i32(tmp2);
5123
                        tcg_temp_free_i32(tmp);
5124
                        break;
5125
                    case 8: case 9: case 10: case 11: case 12: case 13:
5126
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5127
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5128
                        break;
5129
                    case 14: /* Polynomial VMULL */
5130
                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5131
                        tcg_temp_free_i32(tmp2);
5132
                        tcg_temp_free_i32(tmp);
5133
                        break;
5134
                    default: /* 15 is RESERVED.  */
5135
                        return 1;
5136
                    }
5137
                    if (op == 13) {
5138
                        /* VQDMULL */
5139
                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5140
                        neon_store_reg64(cpu_V0, rd + pass);
5141
                    } else if (op == 5 || (op >= 8 && op <= 11)) {
5142
                        /* Accumulate.  */
5143
                        neon_load_reg64(cpu_V1, rd + pass);
5144
                        switch (op) {
5145
                        case 10: /* VMLSL */
5146
                            gen_neon_negl(cpu_V0, size);
5147
                            /* Fall through */
5148
                        case 5: case 8: /* VABAL, VMLAL */
5149
                            gen_neon_addl(size);
5150
                            break;
5151
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5152
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5153
                            if (op == 11) {
5154
                                gen_neon_negl(cpu_V0, size);
5155
                            }
5156
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5157
                            break;
5158
                        default:
5159
                            abort();
5160
                        }
5161
                        neon_store_reg64(cpu_V0, rd + pass);
5162
                    } else if (op == 4 || op == 6) {
5163
                        /* Narrowing operation.  */
5164
                        tmp = tcg_temp_new_i32();
5165
                        if (!u) {
5166
                            switch (size) {
5167
                            case 0:
5168
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5169
                                break;
5170
                            case 1:
5171
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5172
                                break;
5173
                            case 2:
5174
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5175
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5176
                                break;
5177
                            default: abort();
5178
                            }
5179
                        } else {
5180
                            switch (size) {
5181
                            case 0:
5182
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5183
                                break;
5184
                            case 1:
5185
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5186
                                break;
5187
                            case 2:
5188
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5189
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5190
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5191
                                break;
5192
                            default: abort();
5193
                            }
5194
                        }
5195
                        if (pass == 0) {
5196
                            tmp3 = tmp;
5197
                        } else {
5198
                            neon_store_reg(rd, 0, tmp3);
5199
                            neon_store_reg(rd, 1, tmp);
5200
                        }
5201
                    } else {
5202
                        /* Write back the result.  */
5203
                        neon_store_reg64(cpu_V0, rd + pass);
5204
                    }
5205
                }
5206
            } else {
5207
                /* Two registers and a scalar.  */
5208
                switch (op) {
5209
                case 0: /* Integer VMLA scalar */
5210
                case 1: /* Float VMLA scalar */
5211
                case 4: /* Integer VMLS scalar */
5212
                case 5: /* Floating point VMLS scalar */
5213
                case 8: /* Integer VMUL scalar */
5214
                case 9: /* Floating point VMUL scalar */
5215
                case 12: /* VQDMULH scalar */
5216
                case 13: /* VQRDMULH scalar */
5217
                    tmp = neon_get_scalar(size, rm);
5218
                    neon_store_scratch(0, tmp);
5219
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5220
                        tmp = neon_load_scratch(0);
5221
                        tmp2 = neon_load_reg(rn, pass);
5222
                        if (op == 12) {
5223
                            if (size == 1) {
5224
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5225
                            } else {
5226
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5227
                            }
5228
                        } else if (op == 13) {
5229
                            if (size == 1) {
5230
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5231
                            } else {
5232
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5233
                            }
5234
                        } else if (op & 1) {
5235
                            gen_helper_neon_mul_f32(tmp, tmp, tmp2);
5236
                        } else {
5237
                            switch (size) {
5238
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5239
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5240
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5241
                            default: return 1;
5242
                            }
5243
                        }
5244
                        tcg_temp_free_i32(tmp2);
5245
                        if (op < 8) {
5246
                            /* Accumulate.  */
5247
                            tmp2 = neon_load_reg(rd, pass);
5248
                            switch (op) {
5249
                            case 0:
5250
                                gen_neon_add(size, tmp, tmp2);
5251
                                break;
5252
                            case 1:
5253
                                gen_helper_neon_add_f32(tmp, tmp, tmp2);
5254
                                break;
5255
                            case 4:
5256
                                gen_neon_rsb(size, tmp, tmp2);
5257
                                break;
5258
                            case 5:
5259
                                gen_helper_neon_sub_f32(tmp, tmp2, tmp);
5260
                                break;
5261
                            default:
5262
                                abort();
5263
                            }
5264
                            tcg_temp_free_i32(tmp2);
5265
                        }
5266
                        neon_store_reg(rd, pass, tmp);
5267
                    }
5268
                    break;
5269
                case 2: /* VMLAL sclar */
5270
                case 3: /* VQDMLAL scalar */
5271
                case 6: /* VMLSL scalar */
5272
                case 7: /* VQDMLSL scalar */
5273
                case 10: /* VMULL scalar */
5274
                case 11: /* VQDMULL scalar */
5275
                    if (size == 0 && (op == 3 || op == 7 || op == 11))
5276
                        return 1;
5277

    
5278
                    tmp2 = neon_get_scalar(size, rm);
5279
                    /* We need a copy of tmp2 because gen_neon_mull
5280
                     * deletes it during pass 0.  */
5281
                    tmp4 = tcg_temp_new_i32();
5282
                    tcg_gen_mov_i32(tmp4, tmp2);
5283
                    tmp3 = neon_load_reg(rn, 1);
5284

    
5285
                    for (pass = 0; pass < 2; pass++) {
5286
                        if (pass == 0) {
5287
                            tmp = neon_load_reg(rn, 0);
5288
                        } else {
5289
                            tmp = tmp3;
5290
                            tmp2 = tmp4;
5291
                        }
5292
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5293
                        if (op != 11) {
5294
                            neon_load_reg64(cpu_V1, rd + pass);
5295
                        }
5296
                        switch (op) {
5297
                        case 6:
5298
                            gen_neon_negl(cpu_V0, size);
5299
                            /* Fall through */
5300
                        case 2:
5301
                            gen_neon_addl(size);
5302
                            break;
5303
                        case 3: case 7:
5304
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5305
                            if (op == 7) {
5306
                                gen_neon_negl(cpu_V0, size);
5307
                            }
5308
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5309
                            break;
5310
                        case 10:
5311
                            /* no-op */
5312
                            break;
5313
                        case 11:
5314
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5315
                            break;
5316
                        default:
5317
                            abort();
5318
                        }
5319
                        neon_store_reg64(cpu_V0, rd + pass);
5320
                    }
5321

    
5322

    
5323
                    break;
5324
                default: /* 14 and 15 are RESERVED */
5325
                    return 1;
5326
                }
5327
            }
5328
        } else { /* size == 3 */
5329
            if (!u) {
5330
                /* Extract.  */
5331
                imm = (insn >> 8) & 0xf;
5332

    
5333
                if (imm > 7 && !q)
5334
                    return 1;
5335

    
5336
                if (imm == 0) {
5337
                    neon_load_reg64(cpu_V0, rn);
5338
                    if (q) {
5339
                        neon_load_reg64(cpu_V1, rn + 1);
5340
                    }
5341
                } else if (imm == 8) {
5342
                    neon_load_reg64(cpu_V0, rn + 1);
5343
                    if (q) {
5344
                        neon_load_reg64(cpu_V1, rm);
5345
                    }
5346
                } else if (q) {
5347
                    tmp64 = tcg_temp_new_i64();
5348
                    if (imm < 8) {
5349
                        neon_load_reg64(cpu_V0, rn);
5350
                        neon_load_reg64(tmp64, rn + 1);
5351
                    } else {
5352
                        neon_load_reg64(cpu_V0, rn + 1);
5353
                        neon_load_reg64(tmp64, rm);
5354
                    }
5355
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5356
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5357
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5358
                    if (imm < 8) {
5359
                        neon_load_reg64(cpu_V1, rm);
5360
                    } else {
5361
                        neon_load_reg64(cpu_V1, rm + 1);
5362
                        imm -= 8;
5363
                    }
5364
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5365
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5366
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5367
                    tcg_temp_free_i64(tmp64);
5368
                } else {
5369
                    /* BUGFIX */
5370
                    neon_load_reg64(cpu_V0, rn);
5371
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5372
                    neon_load_reg64(cpu_V1, rm);
5373
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5374
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5375
                }
5376
                neon_store_reg64(cpu_V0, rd);
5377
                if (q) {
5378
                    neon_store_reg64(cpu_V1, rd + 1);
5379
                }
5380
            } else if ((insn & (1 << 11)) == 0) {
5381
                /* Two register misc.  */
5382
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5383
                size = (insn >> 18) & 3;
5384
                switch (op) {
5385
                case 0: /* VREV64 */
5386
                    if (size == 3)
5387
                        return 1;
5388
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
5389
                        tmp = neon_load_reg(rm, pass * 2);
5390
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
5391
                        switch (size) {
5392
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5393
                        case 1: gen_swap_half(tmp); break;
5394
                        case 2: /* no-op */ break;
5395
                        default: abort();
5396
                        }
5397
                        neon_store_reg(rd, pass * 2 + 1, tmp);
5398
                        if (size == 2) {
5399
                            neon_store_reg(rd, pass * 2, tmp2);
5400
                        } else {
5401
                            switch (size) {
5402
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5403
                            case 1: gen_swap_half(tmp2); break;
5404
                            default: abort();
5405
                            }
5406
                            neon_store_reg(rd, pass * 2, tmp2);
5407
                        }
5408
                    }
5409
                    break;
5410
                case 4: case 5: /* VPADDL */
5411
                case 12: case 13: /* VPADAL */
5412
                    if (size == 3)
5413
                        return 1;
5414
                    for (pass = 0; pass < q + 1; pass++) {
5415
                        tmp = neon_load_reg(rm, pass * 2);
5416
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
5417
                        tmp = neon_load_reg(rm, pass * 2 + 1);
5418
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
5419
                        switch (size) {
5420
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5421
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5422
                        case 2: tcg_gen_add_i64(CPU_V001); break;
5423
                        default: abort();
5424
                        }
5425
                        if (op >= 12) {
5426
                            /* Accumulate.  */
5427
                            neon_load_reg64(cpu_V1, rd + pass);
5428
                            gen_neon_addl(size);
5429
                        }
5430
                        neon_store_reg64(cpu_V0, rd + pass);
5431
                    }
5432
                    break;
5433
                case 33: /* VTRN */
5434
                    if (size == 2) {
5435
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
5436
                            tmp = neon_load_reg(rm, n);
5437
                            tmp2 = neon_load_reg(rd, n + 1);
5438
                            neon_store_reg(rm, n, tmp2);
5439
                            neon_store_reg(rd, n + 1, tmp);
5440
                        }
5441
                    } else {
5442
                        goto elementwise;
5443
                    }
5444
                    break;
5445
                case 34: /* VUZP */
5446
                    if (gen_neon_unzip(rd, rm, size, q)) {
5447
                        return 1;
5448
                    }
5449
                    break;
5450
                case 35: /* VZIP */
5451
                    if (gen_neon_zip(rd, rm, size, q)) {
5452
                        return 1;
5453
                    }
5454
                    break;
5455
                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
5456
                    if (size == 3)
5457
                        return 1;
5458
                    TCGV_UNUSED(tmp2);
5459
                    for (pass = 0; pass < 2; pass++) {
5460
                        neon_load_reg64(cpu_V0, rm + pass);
5461
                        tmp = tcg_temp_new_i32();
5462
                        gen_neon_narrow_op(op == 36, q, size, tmp, cpu_V0);
5463
                        if (pass == 0) {
5464
                            tmp2 = tmp;
5465
                        } else {
5466
                            neon_store_reg(rd, 0, tmp2);
5467
                            neon_store_reg(rd, 1, tmp);
5468
                        }
5469
                    }
5470
                    break;
5471
                case 38: /* VSHLL */
5472
                    if (q || size == 3)
5473
                        return 1;
5474
                    tmp = neon_load_reg(rm, 0);
5475
                    tmp2 = neon_load_reg(rm, 1);
5476
                    for (pass = 0; pass < 2; pass++) {
5477
                        if (pass == 1)
5478
                            tmp = tmp2;
5479
                        gen_neon_widen(cpu_V0, tmp, size, 1);
5480
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5481
                        neon_store_reg64(cpu_V0, rd + pass);
5482
                    }
5483
                    break;
5484
                case 44: /* VCVT.F16.F32 */
5485
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5486
                      return 1;
5487
                    tmp = tcg_temp_new_i32();
5488
                    tmp2 = tcg_temp_new_i32();
5489
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5490
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5491
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5492
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5493
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5494
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5495
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5496
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5497
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5498
                    neon_store_reg(rd, 0, tmp2);
5499
                    tmp2 = tcg_temp_new_i32();
5500
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5501
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5502
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5503
                    neon_store_reg(rd, 1, tmp2);
5504
                    tcg_temp_free_i32(tmp);
5505
                    break;
5506
                case 46: /* VCVT.F32.F16 */
5507
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
5508
                      return 1;
5509
                    tmp3 = tcg_temp_new_i32();
5510
                    tmp = neon_load_reg(rm, 0);
5511
                    tmp2 = neon_load_reg(rm, 1);
5512
                    tcg_gen_ext16u_i32(tmp3, tmp);
5513
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5514
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5515
                    tcg_gen_shri_i32(tmp3, tmp, 16);
5516
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5517
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5518
                    tcg_temp_free_i32(tmp);
5519
                    tcg_gen_ext16u_i32(tmp3, tmp2);
5520
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5521
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5522
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
5523
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5524
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5525
                    tcg_temp_free_i32(tmp2);
5526
                    tcg_temp_free_i32(tmp3);
5527
                    break;
5528
                default:
5529
                elementwise:
5530
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
5531
                        if (op == 30 || op == 31 || op >= 58) {
5532
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
5533
                                           neon_reg_offset(rm, pass));
5534
                            TCGV_UNUSED(tmp);
5535
                        } else {
5536
                            tmp = neon_load_reg(rm, pass);
5537
                        }
5538
                        switch (op) {
5539
                        case 1: /* VREV32 */
5540
                            switch (size) {
5541
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5542
                            case 1: gen_swap_half(tmp); break;
5543
                            default: return 1;
5544
                            }
5545
                            break;
5546
                        case 2: /* VREV16 */
5547
                            if (size != 0)
5548
                                return 1;
5549
                            gen_rev16(tmp);
5550
                            break;
5551
                        case 8: /* CLS */
5552
                            switch (size) {
5553
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5554
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5555
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5556
                            default: return 1;
5557
                            }
5558
                            break;
5559
                        case 9: /* CLZ */
5560
                            switch (size) {
5561
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5562
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5563
                            case 2: gen_helper_clz(tmp, tmp); break;
5564
                            default: return 1;
5565
                            }
5566
                            break;
5567
                        case 10: /* CNT */
5568
                            if (size != 0)
5569
                                return 1;
5570
                            gen_helper_neon_cnt_u8(tmp, tmp);
5571
                            break;
5572
                        case 11: /* VNOT */
5573
                            if (size != 0)
5574
                                return 1;
5575
                            tcg_gen_not_i32(tmp, tmp);
5576
                            break;
5577
                        case 14: /* VQABS */
5578
                            switch (size) {
5579
                            case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
5580
                            case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
5581
                            case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
5582
                            default: return 1;
5583
                            }
5584
                            break;
5585
                        case 15: /* VQNEG */
5586
                            switch (size) {
5587
                            case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
5588
                            case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
5589
                            case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
5590
                            default: return 1;
5591
                            }
5592
                            break;
5593
                        case 16: case 19: /* VCGT #0, VCLE #0 */
5594
                            tmp2 = tcg_const_i32(0);
5595
                            switch(size) {
5596
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5597
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5598
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5599
                            default: return 1;
5600
                            }
5601
                            tcg_temp_free(tmp2);
5602
                            if (op == 19)
5603
                                tcg_gen_not_i32(tmp, tmp);
5604
                            break;
5605
                        case 17: case 20: /* VCGE #0, VCLT #0 */
5606
                            tmp2 = tcg_const_i32(0);
5607
                            switch(size) {
5608
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
5609
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
5610
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
5611
                            default: return 1;
5612
                            }
5613
                            tcg_temp_free(tmp2);
5614
                            if (op == 20)
5615
                                tcg_gen_not_i32(tmp, tmp);
5616
                            break;
5617
                        case 18: /* VCEQ #0 */
5618
                            tmp2 = tcg_const_i32(0);
5619
                            switch(size) {
5620
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5621
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5622
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5623
                            default: return 1;
5624
                            }
5625
                            tcg_temp_free(tmp2);
5626
                            break;
5627
                        case 22: /* VABS */
5628
                            switch(size) {
5629
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
5630
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
5631
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
5632
                            default: return 1;
5633
                            }
5634
                            break;
5635
                        case 23: /* VNEG */
5636
                            if (size == 3)
5637
                                return 1;
5638
                            tmp2 = tcg_const_i32(0);
5639
                            gen_neon_rsb(size, tmp, tmp2);
5640
                            tcg_temp_free(tmp2);
5641
                            break;
5642
                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5643
                            tmp2 = tcg_const_i32(0);
5644
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
5645
                            tcg_temp_free(tmp2);
5646
                            if (op == 27)
5647
                                tcg_gen_not_i32(tmp, tmp);
5648
                            break;
5649
                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5650
                            tmp2 = tcg_const_i32(0);
5651
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2);
5652
                            tcg_temp_free(tmp2);
5653
                            if (op == 28)
5654
                                tcg_gen_not_i32(tmp, tmp);
5655
                            break;
5656
                        case 26: /* Float VCEQ #0 */
5657
                            tmp2 = tcg_const_i32(0);
5658
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
5659
                            tcg_temp_free(tmp2);
5660
                            break;
5661
                        case 30: /* Float VABS */
5662
                            gen_vfp_abs(0);
5663
                            break;
5664
                        case 31: /* Float VNEG */
5665
                            gen_vfp_neg(0);
5666
                            break;
5667
                        case 32: /* VSWP */
5668
                            tmp2 = neon_load_reg(rd, pass);
5669
                            neon_store_reg(rm, pass, tmp2);
5670
                            break;
5671
                        case 33: /* VTRN */
5672
                            tmp2 = neon_load_reg(rd, pass);
5673
                            switch (size) {
5674
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
5675
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
5676
                            case 2: abort();
5677
                            default: return 1;
5678
                            }
5679
                            neon_store_reg(rm, pass, tmp2);
5680
                            break;
5681
                        case 56: /* Integer VRECPE */
5682
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
5683
                            break;
5684
                        case 57: /* Integer VRSQRTE */
5685
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
5686
                            break;
5687
                        case 58: /* Float VRECPE */
5688
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5689
                            break;
5690
                        case 59: /* Float VRSQRTE */
5691
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5692
                            break;
5693
                        case 60: /* VCVT.F32.S32 */
5694
                            gen_vfp_sito(0);
5695
                            break;
5696
                        case 61: /* VCVT.F32.U32 */
5697
                            gen_vfp_uito(0);
5698
                            break;
5699
                        case 62: /* VCVT.S32.F32 */
5700
                            gen_vfp_tosiz(0);
5701
                            break;
5702
                        case 63: /* VCVT.U32.F32 */
5703
                            gen_vfp_touiz(0);
5704
                            break;
5705
                        default:
5706
                            /* Reserved: 21, 29, 39-56 */
5707
                            return 1;
5708
                        }
5709
                        if (op == 30 || op == 31 || op >= 58) {
5710
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
5711
                                           neon_reg_offset(rd, pass));
5712
                        } else {
5713
                            neon_store_reg(rd, pass, tmp);
5714
                        }
5715
                    }
5716
                    break;
5717
                }
5718
            } else if ((insn & (1 << 10)) == 0) {
5719
                /* VTBL, VTBX.  */
5720
                n = ((insn >> 5) & 0x18) + 8;
5721
                if (insn & (1 << 6)) {
5722
                    tmp = neon_load_reg(rd, 0);
5723
                } else {
5724
                    tmp = tcg_temp_new_i32();
5725
                    tcg_gen_movi_i32(tmp, 0);
5726
                }
5727
                tmp2 = neon_load_reg(rm, 0);
5728
                tmp4 = tcg_const_i32(rn);
5729
                tmp5 = tcg_const_i32(n);
5730
                gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
5731
                tcg_temp_free_i32(tmp);
5732
                if (insn & (1 << 6)) {
5733
                    tmp = neon_load_reg(rd, 1);
5734
                } else {
5735
                    tmp = tcg_temp_new_i32();
5736
                    tcg_gen_movi_i32(tmp, 0);
5737
                }
5738
                tmp3 = neon_load_reg(rm, 1);
5739
                gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
5740
                tcg_temp_free_i32(tmp5);
5741
                tcg_temp_free_i32(tmp4);
5742
                neon_store_reg(rd, 0, tmp2);
5743
                neon_store_reg(rd, 1, tmp3);
5744
                tcg_temp_free_i32(tmp);
5745
            } else if ((insn & 0x380) == 0) {
5746
                /* VDUP */
5747
                if (insn & (1 << 19)) {
5748
                    tmp = neon_load_reg(rm, 1);
5749
                } else {
5750
                    tmp = neon_load_reg(rm, 0);
5751
                }
5752
                if (insn & (1 << 16)) {
5753
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
5754
                } else if (insn & (1 << 17)) {
5755
                    if ((insn >> 18) & 1)
5756
                        gen_neon_dup_high16(tmp);
5757
                    else
5758
                        gen_neon_dup_low16(tmp);
5759
                }
5760
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5761
                    tmp2 = tcg_temp_new_i32();
5762
                    tcg_gen_mov_i32(tmp2, tmp);
5763
                    neon_store_reg(rd, pass, tmp2);
5764
                }
5765
                tcg_temp_free_i32(tmp);
5766
            } else {
5767
                return 1;
5768
            }
5769
        }
5770
    }
5771
    return 0;
5772
}
5773

    
5774
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5775
{
5776
    int crn = (insn >> 16) & 0xf;
5777
    int crm = insn & 0xf;
5778
    int op1 = (insn >> 21) & 7;
5779
    int op2 = (insn >> 5) & 7;
5780
    int rt = (insn >> 12) & 0xf;
5781
    TCGv tmp;
5782

    
5783
    /* Minimal set of debug registers, since we don't support debug */
5784
    if (op1 == 0 && crn == 0 && op2 == 0) {
5785
        switch (crm) {
5786
        case 0:
5787
            /* DBGDIDR: just RAZ. In particular this means the
5788
             * "debug architecture version" bits will read as
5789
             * a reserved value, which should cause Linux to
5790
             * not try to use the debug hardware.
5791
             */
5792
            tmp = tcg_const_i32(0);
5793
            store_reg(s, rt, tmp);
5794
            return 0;
5795
        case 1:
5796
        case 2:
5797
            /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
5798
             * don't implement memory mapped debug components
5799
             */
5800
            if (ENABLE_ARCH_7) {
5801
                tmp = tcg_const_i32(0);
5802
                store_reg(s, rt, tmp);
5803
                return 0;
5804
            }
5805
            break;
5806
        default:
5807
            break;
5808
        }
5809
    }
5810

    
5811
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5812
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5813
            /* TEECR */
5814
            if (IS_USER(s))
5815
                return 1;
5816
            tmp = load_cpu_field(teecr);
5817
            store_reg(s, rt, tmp);
5818
            return 0;
5819
        }
5820
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5821
            /* TEEHBR */
5822
            if (IS_USER(s) && (env->teecr & 1))
5823
                return 1;
5824
            tmp = load_cpu_field(teehbr);
5825
            store_reg(s, rt, tmp);
5826
            return 0;
5827
        }
5828
    }
5829
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5830
            op1, crn, crm, op2);
5831
    return 1;
5832
}
5833

    
5834
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5835
{
5836
    int crn = (insn >> 16) & 0xf;
5837
    int crm = insn & 0xf;
5838
    int op1 = (insn >> 21) & 7;
5839
    int op2 = (insn >> 5) & 7;
5840
    int rt = (insn >> 12) & 0xf;
5841
    TCGv tmp;
5842

    
5843
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5844
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5845
            /* TEECR */
5846
            if (IS_USER(s))
5847
                return 1;
5848
            tmp = load_reg(s, rt);
5849
            gen_helper_set_teecr(cpu_env, tmp);
5850
            tcg_temp_free_i32(tmp);
5851
            return 0;
5852
        }
5853
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5854
            /* TEEHBR */
5855
            if (IS_USER(s) && (env->teecr & 1))
5856
                return 1;
5857
            tmp = load_reg(s, rt);
5858
            store_cpu_field(tmp, teehbr);
5859
            return 0;
5860
        }
5861
    }
5862
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5863
            op1, crn, crm, op2);
5864
    return 1;
5865
}
5866

    
5867
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5868
{
5869
    int cpnum;
5870

    
5871
    cpnum = (insn >> 8) & 0xf;
5872
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5873
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5874
        return 1;
5875

    
5876
    switch (cpnum) {
5877
      case 0:
5878
      case 1:
5879
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5880
            return disas_iwmmxt_insn(env, s, insn);
5881
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5882
            return disas_dsp_insn(env, s, insn);
5883
        }
5884
        return 1;
5885
    case 10:
5886
    case 11:
5887
        return disas_vfp_insn (env, s, insn);
5888
    case 14:
5889
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5890
           Unfortunately Intel decided to ignore this.  */
5891
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5892
            goto board;
5893
        if (insn & (1 << 20))
5894
            return disas_cp14_read(env, s, insn);
5895
        else
5896
            return disas_cp14_write(env, s, insn);
5897
    case 15:
5898
        return disas_cp15_insn (env, s, insn);
5899
    default:
5900
    board:
5901
        /* Unknown coprocessor.  See if the board has hooked it.  */
5902
        return disas_cp_insn (env, s, insn);
5903
    }
5904
}
5905

    
5906

    
5907
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5908
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5909
{
5910
    TCGv tmp;
5911
    tmp = tcg_temp_new_i32();
5912
    tcg_gen_trunc_i64_i32(tmp, val);
5913
    store_reg(s, rlow, tmp);
5914
    tmp = tcg_temp_new_i32();
5915
    tcg_gen_shri_i64(val, val, 32);
5916
    tcg_gen_trunc_i64_i32(tmp, val);
5917
    store_reg(s, rhigh, tmp);
5918
}
5919

    
5920
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5921
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5922
{
5923
    TCGv_i64 tmp;
5924
    TCGv tmp2;
5925

    
5926
    /* Load value and extend to 64 bits.  */
5927
    tmp = tcg_temp_new_i64();
5928
    tmp2 = load_reg(s, rlow);
5929
    tcg_gen_extu_i32_i64(tmp, tmp2);
5930
    tcg_temp_free_i32(tmp2);
5931
    tcg_gen_add_i64(val, val, tmp);
5932
    tcg_temp_free_i64(tmp);
5933
}
5934

    
5935
/* load and add a 64-bit value from a register pair.  */
5936
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5937
{
5938
    TCGv_i64 tmp;
5939
    TCGv tmpl;
5940
    TCGv tmph;
5941

    
5942
    /* Load 64-bit value rd:rn.  */
5943
    tmpl = load_reg(s, rlow);
5944
    tmph = load_reg(s, rhigh);
5945
    tmp = tcg_temp_new_i64();
5946
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5947
    tcg_temp_free_i32(tmpl);
5948
    tcg_temp_free_i32(tmph);
5949
    tcg_gen_add_i64(val, val, tmp);
5950
    tcg_temp_free_i64(tmp);
5951
}
5952

    
5953
/* Set N and Z flags from a 64-bit value.  */
5954
static void gen_logicq_cc(TCGv_i64 val)
5955
{
5956
    TCGv tmp = tcg_temp_new_i32();
5957
    gen_helper_logicq_cc(tmp, val);
5958
    gen_logic_CC(tmp);
5959
    tcg_temp_free_i32(tmp);
5960
}
5961

    
5962
/* Load/Store exclusive instructions are implemented by remembering
5963
   the value/address loaded, and seeing if these are the same
5964
   when the store is performed. This should be is sufficient to implement
5965
   the architecturally mandated semantics, and avoids having to monitor
5966
   regular stores.
5967

5968
   In system emulation mode only one CPU will be running at once, so
5969
   this sequence is effectively atomic.  In user emulation mode we
5970
   throw an exception and handle the atomic operation elsewhere.  */
5971
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
5972
                               TCGv addr, int size)
5973
{
5974
    TCGv tmp;
5975

    
5976
    switch (size) {
5977
    case 0:
5978
        tmp = gen_ld8u(addr, IS_USER(s));
5979
        break;
5980
    case 1:
5981
        tmp = gen_ld16u(addr, IS_USER(s));
5982
        break;
5983
    case 2:
5984
    case 3:
5985
        tmp = gen_ld32(addr, IS_USER(s));
5986
        break;
5987
    default:
5988
        abort();
5989
    }
5990
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
5991
    store_reg(s, rt, tmp);
5992
    if (size == 3) {
5993
        TCGv tmp2 = tcg_temp_new_i32();
5994
        tcg_gen_addi_i32(tmp2, addr, 4);
5995
        tmp = gen_ld32(tmp2, IS_USER(s));
5996
        tcg_temp_free_i32(tmp2);
5997
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
5998
        store_reg(s, rt2, tmp);
5999
    }
6000
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6001
}
6002

    
6003
static void gen_clrex(DisasContext *s)
6004
{
6005
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6006
}
6007

    
6008
#ifdef CONFIG_USER_ONLY
6009
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6010
                                TCGv addr, int size)
6011
{
6012
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
6013
    tcg_gen_movi_i32(cpu_exclusive_info,
6014
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
6015
    gen_exception_insn(s, 4, EXCP_STREX);
6016
}
6017
#else
6018
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6019
                                TCGv addr, int size)
6020
{
6021
    TCGv tmp;
6022
    int done_label;
6023
    int fail_label;
6024

    
6025
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6026
         [addr] = {Rt};
6027
         {Rd} = 0;
6028
       } else {
6029
         {Rd} = 1;
6030
       } */
6031
    fail_label = gen_new_label();
6032
    done_label = gen_new_label();
6033
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6034
    switch (size) {
6035
    case 0:
6036
        tmp = gen_ld8u(addr, IS_USER(s));
6037
        break;
6038
    case 1:
6039
        tmp = gen_ld16u(addr, IS_USER(s));
6040
        break;
6041
    case 2:
6042
    case 3:
6043
        tmp = gen_ld32(addr, IS_USER(s));
6044
        break;
6045
    default:
6046
        abort();
6047
    }
6048
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6049
    tcg_temp_free_i32(tmp);
6050
    if (size == 3) {
6051
        TCGv tmp2 = tcg_temp_new_i32();
6052
        tcg_gen_addi_i32(tmp2, addr, 4);
6053
        tmp = gen_ld32(tmp2, IS_USER(s));
6054
        tcg_temp_free_i32(tmp2);
6055
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6056
        tcg_temp_free_i32(tmp);
6057
    }
6058
    tmp = load_reg(s, rt);
6059
    switch (size) {
6060
    case 0:
6061
        gen_st8(tmp, addr, IS_USER(s));
6062
        break;
6063
    case 1:
6064
        gen_st16(tmp, addr, IS_USER(s));
6065
        break;
6066
    case 2:
6067
    case 3:
6068
        gen_st32(tmp, addr, IS_USER(s));
6069
        break;
6070
    default:
6071
        abort();
6072
    }
6073
    if (size == 3) {
6074
        tcg_gen_addi_i32(addr, addr, 4);
6075
        tmp = load_reg(s, rt2);
6076
        gen_st32(tmp, addr, IS_USER(s));
6077
    }
6078
    tcg_gen_movi_i32(cpu_R[rd], 0);
6079
    tcg_gen_br(done_label);
6080
    gen_set_label(fail_label);
6081
    tcg_gen_movi_i32(cpu_R[rd], 1);
6082
    gen_set_label(done_label);
6083
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6084
}
6085
#endif
6086

    
6087
static void disas_arm_insn(CPUState * env, DisasContext *s)
6088
{
6089
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6090
    TCGv tmp;
6091
    TCGv tmp2;
6092
    TCGv tmp3;
6093
    TCGv addr;
6094
    TCGv_i64 tmp64;
6095

    
6096
    insn = ldl_code(s->pc);
6097
    s->pc += 4;
6098

    
6099
    /* M variants do not implement ARM mode.  */
6100
    if (IS_M(env))
6101
        goto illegal_op;
6102
    cond = insn >> 28;
6103
    if (cond == 0xf){
6104
        /* Unconditional instructions.  */
6105
        if (((insn >> 25) & 7) == 1) {
6106
            /* NEON Data processing.  */
6107
            if (!arm_feature(env, ARM_FEATURE_NEON))
6108
                goto illegal_op;
6109

    
6110
            if (disas_neon_data_insn(env, s, insn))
6111
                goto illegal_op;
6112
            return;
6113
        }
6114
        if ((insn & 0x0f100000) == 0x04000000) {
6115
            /* NEON load/store.  */
6116
            if (!arm_feature(env, ARM_FEATURE_NEON))
6117
                goto illegal_op;
6118

    
6119
            if (disas_neon_ls_insn(env, s, insn))
6120
                goto illegal_op;
6121
            return;
6122
        }
6123
        if (((insn & 0x0f30f000) == 0x0510f000) ||
6124
            ((insn & 0x0f30f010) == 0x0710f000)) {
6125
            if ((insn & (1 << 22)) == 0) {
6126
                /* PLDW; v7MP */
6127
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6128
                    goto illegal_op;
6129
                }
6130
            }
6131
            /* Otherwise PLD; v5TE+ */
6132
            return;
6133
        }
6134
        if (((insn & 0x0f70f000) == 0x0450f000) ||
6135
            ((insn & 0x0f70f010) == 0x0650f000)) {
6136
            ARCH(7);
6137
            return; /* PLI; V7 */
6138
        }
6139
        if (((insn & 0x0f700000) == 0x04100000) ||
6140
            ((insn & 0x0f700010) == 0x06100000)) {
6141
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6142
                goto illegal_op;
6143
            }
6144
            return; /* v7MP: Unallocated memory hint: must NOP */
6145
        }
6146

    
6147
        if ((insn & 0x0ffffdff) == 0x01010000) {
6148
            ARCH(6);
6149
            /* setend */
6150
            if (insn & (1 << 9)) {
6151
                /* BE8 mode not implemented.  */
6152
                goto illegal_op;
6153
            }
6154
            return;
6155
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6156
            switch ((insn >> 4) & 0xf) {
6157
            case 1: /* clrex */
6158
                ARCH(6K);
6159
                gen_clrex(s);
6160
                return;
6161
            case 4: /* dsb */
6162
            case 5: /* dmb */
6163
            case 6: /* isb */
6164
                ARCH(7);
6165
                /* We don't emulate caches so these are a no-op.  */
6166
                return;
6167
            default:
6168
                goto illegal_op;
6169
            }
6170
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6171
            /* srs */
6172
            int32_t offset;
6173
            if (IS_USER(s))
6174
                goto illegal_op;
6175
            ARCH(6);
6176
            op1 = (insn & 0x1f);
6177
            addr = tcg_temp_new_i32();
6178
            tmp = tcg_const_i32(op1);
6179
            gen_helper_get_r13_banked(addr, cpu_env, tmp);
6180
            tcg_temp_free_i32(tmp);
6181
            i = (insn >> 23) & 3;
6182
            switch (i) {
6183
            case 0: offset = -4; break; /* DA */
6184
            case 1: offset = 0; break; /* IA */
6185
            case 2: offset = -8; break; /* DB */
6186
            case 3: offset = 4; break; /* IB */
6187
            default: abort();
6188
            }
6189
            if (offset)
6190
                tcg_gen_addi_i32(addr, addr, offset);
6191
            tmp = load_reg(s, 14);
6192
            gen_st32(tmp, addr, 0);
6193
            tmp = load_cpu_field(spsr);
6194
            tcg_gen_addi_i32(addr, addr, 4);
6195
            gen_st32(tmp, addr, 0);
6196
            if (insn & (1 << 21)) {
6197
                /* Base writeback.  */
6198
                switch (i) {
6199
                case 0: offset = -8; break;
6200
                case 1: offset = 4; break;
6201
                case 2: offset = -4; break;
6202
                case 3: offset = 0; break;
6203
                default: abort();
6204
                }
6205
                if (offset)
6206
                    tcg_gen_addi_i32(addr, addr, offset);
6207
                tmp = tcg_const_i32(op1);
6208
                gen_helper_set_r13_banked(cpu_env, tmp, addr);
6209
                tcg_temp_free_i32(tmp);
6210
                tcg_temp_free_i32(addr);
6211
            } else {
6212
                tcg_temp_free_i32(addr);
6213
            }
6214
            return;
6215
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6216
            /* rfe */
6217
            int32_t offset;
6218
            if (IS_USER(s))
6219
                goto illegal_op;
6220
            ARCH(6);
6221
            rn = (insn >> 16) & 0xf;
6222
            addr = load_reg(s, rn);
6223
            i = (insn >> 23) & 3;
6224
            switch (i) {
6225
            case 0: offset = -4; break; /* DA */
6226
            case 1: offset = 0; break; /* IA */
6227
            case 2: offset = -8; break; /* DB */
6228
            case 3: offset = 4; break; /* IB */
6229
            default: abort();
6230
            }
6231
            if (offset)
6232
                tcg_gen_addi_i32(addr, addr, offset);
6233
            /* Load PC into tmp and CPSR into tmp2.  */
6234
            tmp = gen_ld32(addr, 0);
6235
            tcg_gen_addi_i32(addr, addr, 4);
6236
            tmp2 = gen_ld32(addr, 0);
6237
            if (insn & (1 << 21)) {
6238
                /* Base writeback.  */
6239
                switch (i) {
6240
                case 0: offset = -8; break;
6241
                case 1: offset = 4; break;
6242
                case 2: offset = -4; break;
6243
                case 3: offset = 0; break;
6244
                default: abort();
6245
                }
6246
                if (offset)
6247
                    tcg_gen_addi_i32(addr, addr, offset);
6248
                store_reg(s, rn, addr);
6249
            } else {
6250
                tcg_temp_free_i32(addr);
6251
            }
6252
            gen_rfe(s, tmp, tmp2);
6253
            return;
6254
        } else if ((insn & 0x0e000000) == 0x0a000000) {
6255
            /* branch link and change to thumb (blx <offset>) */
6256
            int32_t offset;
6257

    
6258
            val = (uint32_t)s->pc;
6259
            tmp = tcg_temp_new_i32();
6260
            tcg_gen_movi_i32(tmp, val);
6261
            store_reg(s, 14, tmp);
6262
            /* Sign-extend the 24-bit offset */
6263
            offset = (((int32_t)insn) << 8) >> 8;
6264
            /* offset * 4 + bit24 * 2 + (thumb bit) */
6265
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
6266
            /* pipeline offset */
6267
            val += 4;
6268
            gen_bx_im(s, val);
6269
            return;
6270
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
6271
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6272
                /* iWMMXt register transfer.  */
6273
                if (env->cp15.c15_cpar & (1 << 1))
6274
                    if (!disas_iwmmxt_insn(env, s, insn))
6275
                        return;
6276
            }
6277
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
6278
            /* Coprocessor double register transfer.  */
6279
        } else if ((insn & 0x0f000010) == 0x0e000010) {
6280
            /* Additional coprocessor register transfer.  */
6281
        } else if ((insn & 0x0ff10020) == 0x01000000) {
6282
            uint32_t mask;
6283
            uint32_t val;
6284
            /* cps (privileged) */
6285
            if (IS_USER(s))
6286
                return;
6287
            mask = val = 0;
6288
            if (insn & (1 << 19)) {
6289
                if (insn & (1 << 8))
6290
                    mask |= CPSR_A;
6291
                if (insn & (1 << 7))
6292
                    mask |= CPSR_I;
6293
                if (insn & (1 << 6))
6294
                    mask |= CPSR_F;
6295
                if (insn & (1 << 18))
6296
                    val |= mask;
6297
            }
6298
            if (insn & (1 << 17)) {
6299
                mask |= CPSR_M;
6300
                val |= (insn & 0x1f);
6301
            }
6302
            if (mask) {
6303
                gen_set_psr_im(s, mask, 0, val);
6304
            }
6305
            return;
6306
        }
6307
        goto illegal_op;
6308
    }
6309
    if (cond != 0xe) {
6310
        /* if not always execute, we generate a conditional jump to
6311
           next instruction */
6312
        s->condlabel = gen_new_label();
6313
        gen_test_cc(cond ^ 1, s->condlabel);
6314
        s->condjmp = 1;
6315
    }
6316
    if ((insn & 0x0f900000) == 0x03000000) {
6317
        if ((insn & (1 << 21)) == 0) {
6318
            ARCH(6T2);
6319
            rd = (insn >> 12) & 0xf;
6320
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6321
            if ((insn & (1 << 22)) == 0) {
6322
                /* MOVW */
6323
                tmp = tcg_temp_new_i32();
6324
                tcg_gen_movi_i32(tmp, val);
6325
            } else {
6326
                /* MOVT */
6327
                tmp = load_reg(s, rd);
6328
                tcg_gen_ext16u_i32(tmp, tmp);
6329
                tcg_gen_ori_i32(tmp, tmp, val << 16);
6330
            }
6331
            store_reg(s, rd, tmp);
6332
        } else {
6333
            if (((insn >> 12) & 0xf) != 0xf)
6334
                goto illegal_op;
6335
            if (((insn >> 16) & 0xf) == 0) {
6336
                gen_nop_hint(s, insn & 0xff);
6337
            } else {
6338
                /* CPSR = immediate */
6339
                val = insn & 0xff;
6340
                shift = ((insn >> 8) & 0xf) * 2;
6341
                if (shift)
6342
                    val = (val >> shift) | (val << (32 - shift));
6343
                i = ((insn & (1 << 22)) != 0);
6344
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6345
                    goto illegal_op;
6346
            }
6347
        }
6348
    } else if ((insn & 0x0f900000) == 0x01000000
6349
               && (insn & 0x00000090) != 0x00000090) {
6350
        /* miscellaneous instructions */
6351
        op1 = (insn >> 21) & 3;
6352
        sh = (insn >> 4) & 0xf;
6353
        rm = insn & 0xf;
6354
        switch (sh) {
6355
        case 0x0: /* move program status register */
6356
            if (op1 & 1) {
6357
                /* PSR = reg */
6358
                tmp = load_reg(s, rm);
6359
                i = ((op1 & 2) != 0);
6360
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6361
                    goto illegal_op;
6362
            } else {
6363
                /* reg = PSR */
6364
                rd = (insn >> 12) & 0xf;
6365
                if (op1 & 2) {
6366
                    if (IS_USER(s))
6367
                        goto illegal_op;
6368
                    tmp = load_cpu_field(spsr);
6369
                } else {
6370
                    tmp = tcg_temp_new_i32();
6371
                    gen_helper_cpsr_read(tmp);
6372
                }
6373
                store_reg(s, rd, tmp);
6374
            }
6375
            break;
6376
        case 0x1:
6377
            if (op1 == 1) {
6378
                /* branch/exchange thumb (bx).  */
6379
                tmp = load_reg(s, rm);
6380
                gen_bx(s, tmp);
6381
            } else if (op1 == 3) {
6382
                /* clz */
6383
                rd = (insn >> 12) & 0xf;
6384
                tmp = load_reg(s, rm);
6385
                gen_helper_clz(tmp, tmp);
6386
                store_reg(s, rd, tmp);
6387
            } else {
6388
                goto illegal_op;
6389
            }
6390
            break;
6391
        case 0x2:
6392
            if (op1 == 1) {
6393
                ARCH(5J); /* bxj */
6394
                /* Trivial implementation equivalent to bx.  */
6395
                tmp = load_reg(s, rm);
6396
                gen_bx(s, tmp);
6397
            } else {
6398
                goto illegal_op;
6399
            }
6400
            break;
6401
        case 0x3:
6402
            if (op1 != 1)
6403
              goto illegal_op;
6404

    
6405
            /* branch link/exchange thumb (blx) */
6406
            tmp = load_reg(s, rm);
6407
            tmp2 = tcg_temp_new_i32();
6408
            tcg_gen_movi_i32(tmp2, s->pc);
6409
            store_reg(s, 14, tmp2);
6410
            gen_bx(s, tmp);
6411
            break;
6412
        case 0x5: /* saturating add/subtract */
6413
            rd = (insn >> 12) & 0xf;
6414
            rn = (insn >> 16) & 0xf;
6415
            tmp = load_reg(s, rm);
6416
            tmp2 = load_reg(s, rn);
6417
            if (op1 & 2)
6418
                gen_helper_double_saturate(tmp2, tmp2);
6419
            if (op1 & 1)
6420
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6421
            else
6422
                gen_helper_add_saturate(tmp, tmp, tmp2);
6423
            tcg_temp_free_i32(tmp2);
6424
            store_reg(s, rd, tmp);
6425
            break;
6426
        case 7:
6427
            /* SMC instruction (op1 == 3)
6428
               and undefined instructions (op1 == 0 || op1 == 2)
6429
               will trap */
6430
            if (op1 != 1) {
6431
                goto illegal_op;
6432
            }
6433
            /* bkpt */
6434
            gen_exception_insn(s, 4, EXCP_BKPT);
6435
            break;
6436
        case 0x8: /* signed multiply */
6437
        case 0xa:
6438
        case 0xc:
6439
        case 0xe:
6440
            rs = (insn >> 8) & 0xf;
6441
            rn = (insn >> 12) & 0xf;
6442
            rd = (insn >> 16) & 0xf;
6443
            if (op1 == 1) {
6444
                /* (32 * 16) >> 16 */
6445
                tmp = load_reg(s, rm);
6446
                tmp2 = load_reg(s, rs);
6447
                if (sh & 4)
6448
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6449
                else
6450
                    gen_sxth(tmp2);
6451
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
6452
                tcg_gen_shri_i64(tmp64, tmp64, 16);
6453
                tmp = tcg_temp_new_i32();
6454
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6455
                tcg_temp_free_i64(tmp64);
6456
                if ((sh & 2) == 0) {
6457
                    tmp2 = load_reg(s, rn);
6458
                    gen_helper_add_setq(tmp, tmp, tmp2);
6459
                    tcg_temp_free_i32(tmp2);
6460
                }
6461
                store_reg(s, rd, tmp);
6462
            } else {
6463
                /* 16 * 16 */
6464
                tmp = load_reg(s, rm);
6465
                tmp2 = load_reg(s, rs);
6466
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6467
                tcg_temp_free_i32(tmp2);
6468
                if (op1 == 2) {
6469
                    tmp64 = tcg_temp_new_i64();
6470
                    tcg_gen_ext_i32_i64(tmp64, tmp);
6471
                    tcg_temp_free_i32(tmp);
6472
                    gen_addq(s, tmp64, rn, rd);
6473
                    gen_storeq_reg(s, rn, rd, tmp64);
6474
                    tcg_temp_free_i64(tmp64);
6475
                } else {
6476
                    if (op1 == 0) {
6477
                        tmp2 = load_reg(s, rn);
6478
                        gen_helper_add_setq(tmp, tmp, tmp2);
6479
                        tcg_temp_free_i32(tmp2);
6480
                    }
6481
                    store_reg(s, rd, tmp);
6482
                }
6483
            }
6484
            break;
6485
        default:
6486
            goto illegal_op;
6487
        }
6488
    } else if (((insn & 0x0e000000) == 0 &&
6489
                (insn & 0x00000090) != 0x90) ||
6490
               ((insn & 0x0e000000) == (1 << 25))) {
6491
        int set_cc, logic_cc, shiftop;
6492

    
6493
        op1 = (insn >> 21) & 0xf;
6494
        set_cc = (insn >> 20) & 1;
6495
        logic_cc = table_logic_cc[op1] & set_cc;
6496

    
6497
        /* data processing instruction */
6498
        if (insn & (1 << 25)) {
6499
            /* immediate operand */
6500
            val = insn & 0xff;
6501
            shift = ((insn >> 8) & 0xf) * 2;
6502
            if (shift) {
6503
                val = (val >> shift) | (val << (32 - shift));
6504
            }
6505
            tmp2 = tcg_temp_new_i32();
6506
            tcg_gen_movi_i32(tmp2, val);
6507
            if (logic_cc && shift) {
6508
                gen_set_CF_bit31(tmp2);
6509
            }
6510
        } else {
6511
            /* register */
6512
            rm = (insn) & 0xf;
6513
            tmp2 = load_reg(s, rm);
6514
            shiftop = (insn >> 5) & 3;
6515
            if (!(insn & (1 << 4))) {
6516
                shift = (insn >> 7) & 0x1f;
6517
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6518
            } else {
6519
                rs = (insn >> 8) & 0xf;
6520
                tmp = load_reg(s, rs);
6521
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6522
            }
6523
        }
6524
        if (op1 != 0x0f && op1 != 0x0d) {
6525
            rn = (insn >> 16) & 0xf;
6526
            tmp = load_reg(s, rn);
6527
        } else {
6528
            TCGV_UNUSED(tmp);
6529
        }
6530
        rd = (insn >> 12) & 0xf;
6531
        switch(op1) {
6532
        case 0x00:
6533
            tcg_gen_and_i32(tmp, tmp, tmp2);
6534
            if (logic_cc) {
6535
                gen_logic_CC(tmp);
6536
            }
6537
            store_reg_bx(env, s, rd, tmp);
6538
            break;
6539
        case 0x01:
6540
            tcg_gen_xor_i32(tmp, tmp, tmp2);
6541
            if (logic_cc) {
6542
                gen_logic_CC(tmp);
6543
            }
6544
            store_reg_bx(env, s, rd, tmp);
6545
            break;
6546
        case 0x02:
6547
            if (set_cc && rd == 15) {
6548
                /* SUBS r15, ... is used for exception return.  */
6549
                if (IS_USER(s)) {
6550
                    goto illegal_op;
6551
                }
6552
                gen_helper_sub_cc(tmp, tmp, tmp2);
6553
                gen_exception_return(s, tmp);
6554
            } else {
6555
                if (set_cc) {
6556
                    gen_helper_sub_cc(tmp, tmp, tmp2);
6557
                } else {
6558
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
6559
                }
6560
                store_reg_bx(env, s, rd, tmp);
6561
            }
6562
            break;
6563
        case 0x03:
6564
            if (set_cc) {
6565
                gen_helper_sub_cc(tmp, tmp2, tmp);
6566
            } else {
6567
                tcg_gen_sub_i32(tmp, tmp2, tmp);
6568
            }
6569
            store_reg_bx(env, s, rd, tmp);
6570
            break;
6571
        case 0x04:
6572
            if (set_cc) {
6573
                gen_helper_add_cc(tmp, tmp, tmp2);
6574
            } else {
6575
                tcg_gen_add_i32(tmp, tmp, tmp2);
6576
            }
6577
            store_reg_bx(env, s, rd, tmp);
6578
            break;
6579
        case 0x05:
6580
            if (set_cc) {
6581
                gen_helper_adc_cc(tmp, tmp, tmp2);
6582
            } else {
6583
                gen_add_carry(tmp, tmp, tmp2);
6584
            }
6585
            store_reg_bx(env, s, rd, tmp);
6586
            break;
6587
        case 0x06:
6588
            if (set_cc) {
6589
                gen_helper_sbc_cc(tmp, tmp, tmp2);
6590
            } else {
6591
                gen_sub_carry(tmp, tmp, tmp2);
6592
            }
6593
            store_reg_bx(env, s, rd, tmp);
6594
            break;
6595
        case 0x07:
6596
            if (set_cc) {
6597
                gen_helper_sbc_cc(tmp, tmp2, tmp);
6598
            } else {
6599
                gen_sub_carry(tmp, tmp2, tmp);
6600
            }
6601
            store_reg_bx(env, s, rd, tmp);
6602
            break;
6603
        case 0x08:
6604
            if (set_cc) {
6605
                tcg_gen_and_i32(tmp, tmp, tmp2);
6606
                gen_logic_CC(tmp);
6607
            }
6608
            tcg_temp_free_i32(tmp);
6609
            break;
6610
        case 0x09:
6611
            if (set_cc) {
6612
                tcg_gen_xor_i32(tmp, tmp, tmp2);
6613
                gen_logic_CC(tmp);
6614
            }
6615
            tcg_temp_free_i32(tmp);
6616
            break;
6617
        case 0x0a:
6618
            if (set_cc) {
6619
                gen_helper_sub_cc(tmp, tmp, tmp2);
6620
            }
6621
            tcg_temp_free_i32(tmp);
6622
            break;
6623
        case 0x0b:
6624
            if (set_cc) {
6625
                gen_helper_add_cc(tmp, tmp, tmp2);
6626
            }
6627
            tcg_temp_free_i32(tmp);
6628
            break;
6629
        case 0x0c:
6630
            tcg_gen_or_i32(tmp, tmp, tmp2);
6631
            if (logic_cc) {
6632
                gen_logic_CC(tmp);
6633
            }
6634
            store_reg_bx(env, s, rd, tmp);
6635
            break;
6636
        case 0x0d:
6637
            if (logic_cc && rd == 15) {
6638
                /* MOVS r15, ... is used for exception return.  */
6639
                if (IS_USER(s)) {
6640
                    goto illegal_op;
6641
                }
6642
                gen_exception_return(s, tmp2);
6643
            } else {
6644
                if (logic_cc) {
6645
                    gen_logic_CC(tmp2);
6646
                }
6647
                store_reg_bx(env, s, rd, tmp2);
6648
            }
6649
            break;
6650
        case 0x0e:
6651
            tcg_gen_andc_i32(tmp, tmp, tmp2);
6652
            if (logic_cc) {
6653
                gen_logic_CC(tmp);
6654
            }
6655
            store_reg_bx(env, s, rd, tmp);
6656
            break;
6657
        default:
6658
        case 0x0f:
6659
            tcg_gen_not_i32(tmp2, tmp2);
6660
            if (logic_cc) {
6661
                gen_logic_CC(tmp2);
6662
            }
6663
            store_reg_bx(env, s, rd, tmp2);
6664
            break;
6665
        }
6666
        if (op1 != 0x0f && op1 != 0x0d) {
6667
            tcg_temp_free_i32(tmp2);
6668
        }
6669
    } else {
6670
        /* other instructions */
6671
        op1 = (insn >> 24) & 0xf;
6672
        switch(op1) {
6673
        case 0x0:
6674
        case 0x1:
6675
            /* multiplies, extra load/stores */
6676
            sh = (insn >> 5) & 3;
6677
            if (sh == 0) {
6678
                if (op1 == 0x0) {
6679
                    rd = (insn >> 16) & 0xf;
6680
                    rn = (insn >> 12) & 0xf;
6681
                    rs = (insn >> 8) & 0xf;
6682
                    rm = (insn) & 0xf;
6683
                    op1 = (insn >> 20) & 0xf;
6684
                    switch (op1) {
6685
                    case 0: case 1: case 2: case 3: case 6:
6686
                        /* 32 bit mul */
6687
                        tmp = load_reg(s, rs);
6688
                        tmp2 = load_reg(s, rm);
6689
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
6690
                        tcg_temp_free_i32(tmp2);
6691
                        if (insn & (1 << 22)) {
6692
                            /* Subtract (mls) */
6693
                            ARCH(6T2);
6694
                            tmp2 = load_reg(s, rn);
6695
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
6696
                            tcg_temp_free_i32(tmp2);
6697
                        } else if (insn & (1 << 21)) {
6698
                            /* Add */
6699
                            tmp2 = load_reg(s, rn);
6700
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6701
                            tcg_temp_free_i32(tmp2);
6702
                        }
6703
                        if (insn & (1 << 20))
6704
                            gen_logic_CC(tmp);
6705
                        store_reg(s, rd, tmp);
6706
                        break;
6707
                    case 4:
6708
                        /* 64 bit mul double accumulate (UMAAL) */
6709
                        ARCH(6);
6710
                        tmp = load_reg(s, rs);
6711
                        tmp2 = load_reg(s, rm);
6712
                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6713
                        gen_addq_lo(s, tmp64, rn);
6714
                        gen_addq_lo(s, tmp64, rd);
6715
                        gen_storeq_reg(s, rn, rd, tmp64);
6716
                        tcg_temp_free_i64(tmp64);
6717
                        break;
6718
                    case 8: case 9: case 10: case 11:
6719
                    case 12: case 13: case 14: case 15:
6720
                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
6721
                        tmp = load_reg(s, rs);
6722
                        tmp2 = load_reg(s, rm);
6723
                        if (insn & (1 << 22)) {
6724
                            tmp64 = gen_muls_i64_i32(tmp, tmp2);
6725
                        } else {
6726
                            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6727
                        }
6728
                        if (insn & (1 << 21)) { /* mult accumulate */
6729
                            gen_addq(s, tmp64, rn, rd);
6730
                        }
6731
                        if (insn & (1 << 20)) {
6732
                            gen_logicq_cc(tmp64);
6733
                        }
6734
                        gen_storeq_reg(s, rn, rd, tmp64);
6735
                        tcg_temp_free_i64(tmp64);
6736
                        break;
6737
                    default:
6738
                        goto illegal_op;
6739
                    }
6740
                } else {
6741
                    rn = (insn >> 16) & 0xf;
6742
                    rd = (insn >> 12) & 0xf;
6743
                    if (insn & (1 << 23)) {
6744
                        /* load/store exclusive */
6745
                        op1 = (insn >> 21) & 0x3;
6746
                        if (op1)
6747
                            ARCH(6K);
6748
                        else
6749
                            ARCH(6);
6750
                        addr = tcg_temp_local_new_i32();
6751
                        load_reg_var(s, addr, rn);
6752
                        if (insn & (1 << 20)) {
6753
                            switch (op1) {
6754
                            case 0: /* ldrex */
6755
                                gen_load_exclusive(s, rd, 15, addr, 2);
6756
                                break;
6757
                            case 1: /* ldrexd */
6758
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
6759
                                break;
6760
                            case 2: /* ldrexb */
6761
                                gen_load_exclusive(s, rd, 15, addr, 0);
6762
                                break;
6763
                            case 3: /* ldrexh */
6764
                                gen_load_exclusive(s, rd, 15, addr, 1);
6765
                                break;
6766
                            default:
6767
                                abort();
6768
                            }
6769
                        } else {
6770
                            rm = insn & 0xf;
6771
                            switch (op1) {
6772
                            case 0:  /*  strex */
6773
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
6774
                                break;
6775
                            case 1: /*  strexd */
6776
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
6777
                                break;
6778
                            case 2: /*  strexb */
6779
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
6780
                                break;
6781
                            case 3: /* strexh */
6782
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
6783
                                break;
6784
                            default:
6785
                                abort();
6786
                            }
6787
                        }
6788
                        tcg_temp_free(addr);
6789
                    } else {
6790
                        /* SWP instruction */
6791
                        rm = (insn) & 0xf;
6792

    
6793
                        /* ??? This is not really atomic.  However we know
6794
                           we never have multiple CPUs running in parallel,
6795
                           so it is good enough.  */
6796
                        addr = load_reg(s, rn);
6797
                        tmp = load_reg(s, rm);
6798
                        if (insn & (1 << 22)) {
6799
                            tmp2 = gen_ld8u(addr, IS_USER(s));
6800
                            gen_st8(tmp, addr, IS_USER(s));
6801
                        } else {
6802
                            tmp2 = gen_ld32(addr, IS_USER(s));
6803
                            gen_st32(tmp, addr, IS_USER(s));
6804
                        }
6805
                        tcg_temp_free_i32(addr);
6806
                        store_reg(s, rd, tmp2);
6807
                    }
6808
                }
6809
            } else {
6810
                int address_offset;
6811
                int load;
6812
                /* Misc load/store */
6813
                rn = (insn >> 16) & 0xf;
6814
                rd = (insn >> 12) & 0xf;
6815
                addr = load_reg(s, rn);
6816
                if (insn & (1 << 24))
6817
                    gen_add_datah_offset(s, insn, 0, addr);
6818
                address_offset = 0;
6819
                if (insn & (1 << 20)) {
6820
                    /* load */
6821
                    switch(sh) {
6822
                    case 1:
6823
                        tmp = gen_ld16u(addr, IS_USER(s));
6824
                        break;
6825
                    case 2:
6826
                        tmp = gen_ld8s(addr, IS_USER(s));
6827
                        break;
6828
                    default:
6829
                    case 3:
6830
                        tmp = gen_ld16s(addr, IS_USER(s));
6831
                        break;
6832
                    }
6833
                    load = 1;
6834
                } else if (sh & 2) {
6835
                    /* doubleword */
6836
                    if (sh & 1) {
6837
                        /* store */
6838
                        tmp = load_reg(s, rd);
6839
                        gen_st32(tmp, addr, IS_USER(s));
6840
                        tcg_gen_addi_i32(addr, addr, 4);
6841
                        tmp = load_reg(s, rd + 1);
6842
                        gen_st32(tmp, addr, IS_USER(s));
6843
                        load = 0;
6844
                    } else {
6845
                        /* load */
6846
                        tmp = gen_ld32(addr, IS_USER(s));
6847
                        store_reg(s, rd, tmp);
6848
                        tcg_gen_addi_i32(addr, addr, 4);
6849
                        tmp = gen_ld32(addr, IS_USER(s));
6850
                        rd++;
6851
                        load = 1;
6852
                    }
6853
                    address_offset = -4;
6854
                } else {
6855
                    /* store */
6856
                    tmp = load_reg(s, rd);
6857
                    gen_st16(tmp, addr, IS_USER(s));
6858
                    load = 0;
6859
                }
6860
                /* Perform base writeback before the loaded value to
6861
                   ensure correct behavior with overlapping index registers.
6862
                   ldrd with base writeback is is undefined if the
6863
                   destination and index registers overlap.  */
6864
                if (!(insn & (1 << 24))) {
6865
                    gen_add_datah_offset(s, insn, address_offset, addr);
6866
                    store_reg(s, rn, addr);
6867
                } else if (insn & (1 << 21)) {
6868
                    if (address_offset)
6869
                        tcg_gen_addi_i32(addr, addr, address_offset);
6870
                    store_reg(s, rn, addr);
6871
                } else {
6872
                    tcg_temp_free_i32(addr);
6873
                }
6874
                if (load) {
6875
                    /* Complete the load.  */
6876
                    store_reg(s, rd, tmp);
6877
                }
6878
            }
6879
            break;
6880
        case 0x4:
6881
        case 0x5:
6882
            goto do_ldst;
6883
        case 0x6:
6884
        case 0x7:
6885
            if (insn & (1 << 4)) {
6886
                ARCH(6);
6887
                /* Armv6 Media instructions.  */
6888
                rm = insn & 0xf;
6889
                rn = (insn >> 16) & 0xf;
6890
                rd = (insn >> 12) & 0xf;
6891
                rs = (insn >> 8) & 0xf;
6892
                switch ((insn >> 23) & 3) {
6893
                case 0: /* Parallel add/subtract.  */
6894
                    op1 = (insn >> 20) & 7;
6895
                    tmp = load_reg(s, rn);
6896
                    tmp2 = load_reg(s, rm);
6897
                    sh = (insn >> 5) & 7;
6898
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6899
                        goto illegal_op;
6900
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6901
                    tcg_temp_free_i32(tmp2);
6902
                    store_reg(s, rd, tmp);
6903
                    break;
6904
                case 1:
6905
                    if ((insn & 0x00700020) == 0) {
6906
                        /* Halfword pack.  */
6907
                        tmp = load_reg(s, rn);
6908
                        tmp2 = load_reg(s, rm);
6909
                        shift = (insn >> 7) & 0x1f;
6910
                        if (insn & (1 << 6)) {
6911
                            /* pkhtb */
6912
                            if (shift == 0)
6913
                                shift = 31;
6914
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
6915
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6916
                            tcg_gen_ext16u_i32(tmp2, tmp2);
6917
                        } else {
6918
                            /* pkhbt */
6919
                            if (shift)
6920
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
6921
                            tcg_gen_ext16u_i32(tmp, tmp);
6922
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6923
                        }
6924
                        tcg_gen_or_i32(tmp, tmp, tmp2);
6925
                        tcg_temp_free_i32(tmp2);
6926
                        store_reg(s, rd, tmp);
6927
                    } else if ((insn & 0x00200020) == 0x00200000) {
6928
                        /* [us]sat */
6929
                        tmp = load_reg(s, rm);
6930
                        shift = (insn >> 7) & 0x1f;
6931
                        if (insn & (1 << 6)) {
6932
                            if (shift == 0)
6933
                                shift = 31;
6934
                            tcg_gen_sari_i32(tmp, tmp, shift);
6935
                        } else {
6936
                            tcg_gen_shli_i32(tmp, tmp, shift);
6937
                        }
6938
                        sh = (insn >> 16) & 0x1f;
6939
                        tmp2 = tcg_const_i32(sh);
6940
                        if (insn & (1 << 22))
6941
                          gen_helper_usat(tmp, tmp, tmp2);
6942
                        else
6943
                          gen_helper_ssat(tmp, tmp, tmp2);
6944
                        tcg_temp_free_i32(tmp2);
6945
                        store_reg(s, rd, tmp);
6946
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
6947
                        /* [us]sat16 */
6948
                        tmp = load_reg(s, rm);
6949
                        sh = (insn >> 16) & 0x1f;
6950
                        tmp2 = tcg_const_i32(sh);
6951
                        if (insn & (1 << 22))
6952
                          gen_helper_usat16(tmp, tmp, tmp2);
6953
                        else
6954
                          gen_helper_ssat16(tmp, tmp, tmp2);
6955
                        tcg_temp_free_i32(tmp2);
6956
                        store_reg(s, rd, tmp);
6957
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6958
                        /* Select bytes.  */
6959
                        tmp = load_reg(s, rn);
6960
                        tmp2 = load_reg(s, rm);
6961
                        tmp3 = tcg_temp_new_i32();
6962
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6963
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6964
                        tcg_temp_free_i32(tmp3);
6965
                        tcg_temp_free_i32(tmp2);
6966
                        store_reg(s, rd, tmp);
6967
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6968
                        tmp = load_reg(s, rm);
6969
                        shift = (insn >> 10) & 3;
6970
                        /* ??? In many cases it's not neccessary to do a
6971
                           rotate, a shift is sufficient.  */
6972
                        if (shift != 0)
6973
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
6974
                        op1 = (insn >> 20) & 7;
6975
                        switch (op1) {
6976
                        case 0: gen_sxtb16(tmp);  break;
6977
                        case 2: gen_sxtb(tmp);    break;
6978
                        case 3: gen_sxth(tmp);    break;
6979
                        case 4: gen_uxtb16(tmp);  break;
6980
                        case 6: gen_uxtb(tmp);    break;
6981
                        case 7: gen_uxth(tmp);    break;
6982
                        default: goto illegal_op;
6983
                        }
6984
                        if (rn != 15) {
6985
                            tmp2 = load_reg(s, rn);
6986
                            if ((op1 & 3) == 0) {
6987
                                gen_add16(tmp, tmp2);
6988
                            } else {
6989
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6990
                                tcg_temp_free_i32(tmp2);
6991
                            }
6992
                        }
6993
                        store_reg(s, rd, tmp);
6994
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6995
                        /* rev */
6996
                        tmp = load_reg(s, rm);
6997
                        if (insn & (1 << 22)) {
6998
                            if (insn & (1 << 7)) {
6999
                                gen_revsh(tmp);
7000
                            } else {
7001
                                ARCH(6T2);
7002
                                gen_helper_rbit(tmp, tmp);
7003
                            }
7004
                        } else {
7005
                            if (insn & (1 << 7))
7006
                                gen_rev16(tmp);
7007
                            else
7008
                                tcg_gen_bswap32_i32(tmp, tmp);
7009
                        }
7010
                        store_reg(s, rd, tmp);
7011
                    } else {
7012
                        goto illegal_op;
7013
                    }
7014
                    break;
7015
                case 2: /* Multiplies (Type 3).  */
7016
                    tmp = load_reg(s, rm);
7017
                    tmp2 = load_reg(s, rs);
7018
                    if (insn & (1 << 20)) {
7019
                        /* Signed multiply most significant [accumulate].
7020
                           (SMMUL, SMMLA, SMMLS) */
7021
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7022

    
7023
                        if (rd != 15) {
7024
                            tmp = load_reg(s, rd);
7025
                            if (insn & (1 << 6)) {
7026
                                tmp64 = gen_subq_msw(tmp64, tmp);
7027
                            } else {
7028
                                tmp64 = gen_addq_msw(tmp64, tmp);
7029
                            }
7030
                        }
7031
                        if (insn & (1 << 5)) {
7032
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7033
                        }
7034
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
7035
                        tmp = tcg_temp_new_i32();
7036
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
7037
                        tcg_temp_free_i64(tmp64);
7038
                        store_reg(s, rn, tmp);
7039
                    } else {
7040
                        if (insn & (1 << 5))
7041
                            gen_swap_half(tmp2);
7042
                        gen_smul_dual(tmp, tmp2);
7043
                        if (insn & (1 << 6)) {
7044
                            /* This subtraction cannot overflow. */
7045
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
7046
                        } else {
7047
                            /* This addition cannot overflow 32 bits;
7048
                             * however it may overflow considered as a signed
7049
                             * operation, in which case we must set the Q flag.
7050
                             */
7051
                            gen_helper_add_setq(tmp, tmp, tmp2);
7052
                        }
7053
                        tcg_temp_free_i32(tmp2);
7054
                        if (insn & (1 << 22)) {
7055
                            /* smlald, smlsld */
7056
                            tmp64 = tcg_temp_new_i64();
7057
                            tcg_gen_ext_i32_i64(tmp64, tmp);
7058
                            tcg_temp_free_i32(tmp);
7059
                            gen_addq(s, tmp64, rd, rn);
7060
                            gen_storeq_reg(s, rd, rn, tmp64);
7061
                            tcg_temp_free_i64(tmp64);
7062
                        } else {
7063
                            /* smuad, smusd, smlad, smlsd */
7064
                            if (rd != 15)
7065
                              {
7066
                                tmp2 = load_reg(s, rd);
7067
                                gen_helper_add_setq(tmp, tmp, tmp2);
7068
                                tcg_temp_free_i32(tmp2);
7069
                              }
7070
                            store_reg(s, rn, tmp);
7071
                        }
7072
                    }
7073
                    break;
7074
                case 3:
7075
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7076
                    switch (op1) {
7077
                    case 0: /* Unsigned sum of absolute differences.  */
7078
                        ARCH(6);
7079
                        tmp = load_reg(s, rm);
7080
                        tmp2 = load_reg(s, rs);
7081
                        gen_helper_usad8(tmp, tmp, tmp2);
7082
                        tcg_temp_free_i32(tmp2);
7083
                        if (rd != 15) {
7084
                            tmp2 = load_reg(s, rd);
7085
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7086
                            tcg_temp_free_i32(tmp2);
7087
                        }
7088
                        store_reg(s, rn, tmp);
7089
                        break;
7090
                    case 0x20: case 0x24: case 0x28: case 0x2c:
7091
                        /* Bitfield insert/clear.  */
7092
                        ARCH(6T2);
7093
                        shift = (insn >> 7) & 0x1f;
7094
                        i = (insn >> 16) & 0x1f;
7095
                        i = i + 1 - shift;
7096
                        if (rm == 15) {
7097
                            tmp = tcg_temp_new_i32();
7098
                            tcg_gen_movi_i32(tmp, 0);
7099
                        } else {
7100
                            tmp = load_reg(s, rm);
7101
                        }
7102
                        if (i != 32) {
7103
                            tmp2 = load_reg(s, rd);
7104
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
7105
                            tcg_temp_free_i32(tmp2);
7106
                        }
7107
                        store_reg(s, rd, tmp);
7108
                        break;
7109
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7110
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7111
                        ARCH(6T2);
7112
                        tmp = load_reg(s, rm);
7113
                        shift = (insn >> 7) & 0x1f;
7114
                        i = ((insn >> 16) & 0x1f) + 1;
7115
                        if (shift + i > 32)
7116
                            goto illegal_op;
7117
                        if (i < 32) {
7118
                            if (op1 & 0x20) {
7119
                                gen_ubfx(tmp, shift, (1u << i) - 1);
7120
                            } else {
7121
                                gen_sbfx(tmp, shift, i);
7122
                            }
7123
                        }
7124
                        store_reg(s, rd, tmp);
7125
                        break;
7126
                    default:
7127
                        goto illegal_op;
7128
                    }
7129
                    break;
7130
                }
7131
                break;
7132
            }
7133
        do_ldst:
7134
            /* Check for undefined extension instructions
7135
             * per the ARM Bible IE:
7136
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
7137
             */
7138
            sh = (0xf << 20) | (0xf << 4);
7139
            if (op1 == 0x7 && ((insn & sh) == sh))
7140
            {
7141
                goto illegal_op;
7142
            }
7143
            /* load/store byte/word */
7144
            rn = (insn >> 16) & 0xf;
7145
            rd = (insn >> 12) & 0xf;
7146
            tmp2 = load_reg(s, rn);
7147
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7148
            if (insn & (1 << 24))
7149
                gen_add_data_offset(s, insn, tmp2);
7150
            if (insn & (1 << 20)) {
7151
                /* load */
7152
                if (insn & (1 << 22)) {
7153
                    tmp = gen_ld8u(tmp2, i);
7154
                } else {
7155
                    tmp = gen_ld32(tmp2, i);
7156
                }
7157
            } else {
7158
                /* store */
7159
                tmp = load_reg(s, rd);
7160
                if (insn & (1 << 22))
7161
                    gen_st8(tmp, tmp2, i);
7162
                else
7163
                    gen_st32(tmp, tmp2, i);
7164
            }
7165
            if (!(insn & (1 << 24))) {
7166
                gen_add_data_offset(s, insn, tmp2);
7167
                store_reg(s, rn, tmp2);
7168
            } else if (insn & (1 << 21)) {
7169
                store_reg(s, rn, tmp2);
7170
            } else {
7171
                tcg_temp_free_i32(tmp2);
7172
            }
7173
            if (insn & (1 << 20)) {
7174
                /* Complete the load.  */
7175
                if (rd == 15)
7176
                    gen_bx(s, tmp);
7177
                else
7178
                    store_reg(s, rd, tmp);
7179
            }
7180
            break;
7181
        case 0x08:
7182
        case 0x09:
7183
            {
7184
                int j, n, user, loaded_base;
7185
                TCGv loaded_var;
7186
                /* load/store multiple words */
7187
                /* XXX: store correct base if write back */
7188
                user = 0;
7189
                if (insn & (1 << 22)) {
7190
                    if (IS_USER(s))
7191
                        goto illegal_op; /* only usable in supervisor mode */
7192

    
7193
                    if ((insn & (1 << 15)) == 0)
7194
                        user = 1;
7195
                }
7196
                rn = (insn >> 16) & 0xf;
7197
                addr = load_reg(s, rn);
7198

    
7199
                /* compute total size */
7200
                loaded_base = 0;
7201
                TCGV_UNUSED(loaded_var);
7202
                n = 0;
7203
                for(i=0;i<16;i++) {
7204
                    if (insn & (1 << i))
7205
                        n++;
7206
                }
7207
                /* XXX: test invalid n == 0 case ? */
7208
                if (insn & (1 << 23)) {
7209
                    if (insn & (1 << 24)) {
7210
                        /* pre increment */
7211
                        tcg_gen_addi_i32(addr, addr, 4);
7212
                    } else {
7213
                        /* post increment */
7214
                    }
7215
                } else {
7216
                    if (insn & (1 << 24)) {
7217
                        /* pre decrement */
7218
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
7219
                    } else {
7220
                        /* post decrement */
7221
                        if (n != 1)
7222
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7223
                    }
7224
                }
7225
                j = 0;
7226
                for(i=0;i<16;i++) {
7227
                    if (insn & (1 << i)) {
7228
                        if (insn & (1 << 20)) {
7229
                            /* load */
7230
                            tmp = gen_ld32(addr, IS_USER(s));
7231
                            if (i == 15) {
7232
                                gen_bx(s, tmp);
7233
                            } else if (user) {
7234
                                tmp2 = tcg_const_i32(i);
7235
                                gen_helper_set_user_reg(tmp2, tmp);
7236
                                tcg_temp_free_i32(tmp2);
7237
                                tcg_temp_free_i32(tmp);
7238
                            } else if (i == rn) {
7239
                                loaded_var = tmp;
7240
                                loaded_base = 1;
7241
                            } else {
7242
                                store_reg(s, i, tmp);
7243
                            }
7244
                        } else {
7245
                            /* store */
7246
                            if (i == 15) {
7247
                                /* special case: r15 = PC + 8 */
7248
                                val = (long)s->pc + 4;
7249
                                tmp = tcg_temp_new_i32();
7250
                                tcg_gen_movi_i32(tmp, val);
7251
                            } else if (user) {
7252
                                tmp = tcg_temp_new_i32();
7253
                                tmp2 = tcg_const_i32(i);
7254
                                gen_helper_get_user_reg(tmp, tmp2);
7255
                                tcg_temp_free_i32(tmp2);
7256
                            } else {
7257
                                tmp = load_reg(s, i);
7258
                            }
7259
                            gen_st32(tmp, addr, IS_USER(s));
7260
                        }
7261
                        j++;
7262
                        /* no need to add after the last transfer */
7263
                        if (j != n)
7264
                            tcg_gen_addi_i32(addr, addr, 4);
7265
                    }
7266
                }
7267
                if (insn & (1 << 21)) {
7268
                    /* write back */
7269
                    if (insn & (1 << 23)) {
7270
                        if (insn & (1 << 24)) {
7271
                            /* pre increment */
7272
                        } else {
7273
                            /* post increment */
7274
                            tcg_gen_addi_i32(addr, addr, 4);
7275
                        }
7276
                    } else {
7277
                        if (insn & (1 << 24)) {
7278
                            /* pre decrement */
7279
                            if (n != 1)
7280
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7281
                        } else {
7282
                            /* post decrement */
7283
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
7284
                        }
7285
                    }
7286
                    store_reg(s, rn, addr);
7287
                } else {
7288
                    tcg_temp_free_i32(addr);
7289
                }
7290
                if (loaded_base) {
7291
                    store_reg(s, rn, loaded_var);
7292
                }
7293
                if ((insn & (1 << 22)) && !user) {
7294
                    /* Restore CPSR from SPSR.  */
7295
                    tmp = load_cpu_field(spsr);
7296
                    gen_set_cpsr(tmp, 0xffffffff);
7297
                    tcg_temp_free_i32(tmp);
7298
                    s->is_jmp = DISAS_UPDATE;
7299
                }
7300
            }
7301
            break;
7302
        case 0xa:
7303
        case 0xb:
7304
            {
7305
                int32_t offset;
7306

    
7307
                /* branch (and link) */
7308
                val = (int32_t)s->pc;
7309
                if (insn & (1 << 24)) {
7310
                    tmp = tcg_temp_new_i32();
7311
                    tcg_gen_movi_i32(tmp, val);
7312
                    store_reg(s, 14, tmp);
7313
                }
7314
                offset = (((int32_t)insn << 8) >> 8);
7315
                val += (offset << 2) + 4;
7316
                gen_jmp(s, val);
7317
            }
7318
            break;
7319
        case 0xc:
7320
        case 0xd:
7321
        case 0xe:
7322
            /* Coprocessor.  */
7323
            if (disas_coproc_insn(env, s, insn))
7324
                goto illegal_op;
7325
            break;
7326
        case 0xf:
7327
            /* swi */
7328
            gen_set_pc_im(s->pc);
7329
            s->is_jmp = DISAS_SWI;
7330
            break;
7331
        default:
7332
        illegal_op:
7333
            gen_exception_insn(s, 4, EXCP_UDEF);
7334
            break;
7335
        }
7336
    }
7337
}
7338

    
7339
/* Return true if this is a Thumb-2 logical op.  */
7340
static int
7341
thumb2_logic_op(int op)
7342
{
7343
    return (op < 8);
7344
}
7345

    
7346
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7347
   then set condition code flags based on the result of the operation.
7348
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7349
   to the high bit of T1.
7350
   Returns zero if the opcode is valid.  */
7351

    
7352
static int
7353
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7354
{
7355
    int logic_cc;
7356

    
7357
    logic_cc = 0;
7358
    switch (op) {
7359
    case 0: /* and */
7360
        tcg_gen_and_i32(t0, t0, t1);
7361
        logic_cc = conds;
7362
        break;
7363
    case 1: /* bic */
7364
        tcg_gen_andc_i32(t0, t0, t1);
7365
        logic_cc = conds;
7366
        break;
7367
    case 2: /* orr */
7368
        tcg_gen_or_i32(t0, t0, t1);
7369
        logic_cc = conds;
7370
        break;
7371
    case 3: /* orn */
7372
        tcg_gen_orc_i32(t0, t0, t1);
7373
        logic_cc = conds;
7374
        break;
7375
    case 4: /* eor */
7376
        tcg_gen_xor_i32(t0, t0, t1);
7377
        logic_cc = conds;
7378
        break;
7379
    case 8: /* add */
7380
        if (conds)
7381
            gen_helper_add_cc(t0, t0, t1);
7382
        else
7383
            tcg_gen_add_i32(t0, t0, t1);
7384
        break;
7385
    case 10: /* adc */
7386
        if (conds)
7387
            gen_helper_adc_cc(t0, t0, t1);
7388
        else
7389
            gen_adc(t0, t1);
7390
        break;
7391
    case 11: /* sbc */
7392
        if (conds)
7393
            gen_helper_sbc_cc(t0, t0, t1);
7394
        else
7395
            gen_sub_carry(t0, t0, t1);
7396
        break;
7397
    case 13: /* sub */
7398
        if (conds)
7399
            gen_helper_sub_cc(t0, t0, t1);
7400
        else
7401
            tcg_gen_sub_i32(t0, t0, t1);
7402
        break;
7403
    case 14: /* rsb */
7404
        if (conds)
7405
            gen_helper_sub_cc(t0, t1, t0);
7406
        else
7407
            tcg_gen_sub_i32(t0, t1, t0);
7408
        break;
7409
    default: /* 5, 6, 7, 9, 12, 15. */
7410
        return 1;
7411
    }
7412
    if (logic_cc) {
7413
        gen_logic_CC(t0);
7414
        if (shifter_out)
7415
            gen_set_CF_bit31(t1);
7416
    }
7417
    return 0;
7418
}
7419

    
7420
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7421
   is not legal.  */
7422
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7423
{
7424
    uint32_t insn, imm, shift, offset;
7425
    uint32_t rd, rn, rm, rs;
7426
    TCGv tmp;
7427
    TCGv tmp2;
7428
    TCGv tmp3;
7429
    TCGv addr;
7430
    TCGv_i64 tmp64;
7431
    int op;
7432
    int shiftop;
7433
    int conds;
7434
    int logic_cc;
7435

    
7436
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7437
          || arm_feature (env, ARM_FEATURE_M))) {
7438
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7439
           16-bit instructions to get correct prefetch abort behavior.  */
7440
        insn = insn_hw1;
7441
        if ((insn & (1 << 12)) == 0) {
7442
            /* Second half of blx.  */
7443
            offset = ((insn & 0x7ff) << 1);
7444
            tmp = load_reg(s, 14);
7445
            tcg_gen_addi_i32(tmp, tmp, offset);
7446
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7447

    
7448
            tmp2 = tcg_temp_new_i32();
7449
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7450
            store_reg(s, 14, tmp2);
7451
            gen_bx(s, tmp);
7452
            return 0;
7453
        }
7454
        if (insn & (1 << 11)) {
7455
            /* Second half of bl.  */
7456
            offset = ((insn & 0x7ff) << 1) | 1;
7457
            tmp = load_reg(s, 14);
7458
            tcg_gen_addi_i32(tmp, tmp, offset);
7459

    
7460
            tmp2 = tcg_temp_new_i32();
7461
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7462
            store_reg(s, 14, tmp2);
7463
            gen_bx(s, tmp);
7464
            return 0;
7465
        }
7466
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7467
            /* Instruction spans a page boundary.  Implement it as two
7468
               16-bit instructions in case the second half causes an
7469
               prefetch abort.  */
7470
            offset = ((int32_t)insn << 21) >> 9;
7471
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7472
            return 0;
7473
        }
7474
        /* Fall through to 32-bit decode.  */
7475
    }
7476

    
7477
    insn = lduw_code(s->pc);
7478
    s->pc += 2;
7479
    insn |= (uint32_t)insn_hw1 << 16;
7480

    
7481
    if ((insn & 0xf800e800) != 0xf000e800) {
7482
        ARCH(6T2);
7483
    }
7484

    
7485
    rn = (insn >> 16) & 0xf;
7486
    rs = (insn >> 12) & 0xf;
7487
    rd = (insn >> 8) & 0xf;
7488
    rm = insn & 0xf;
7489
    switch ((insn >> 25) & 0xf) {
7490
    case 0: case 1: case 2: case 3:
7491
        /* 16-bit instructions.  Should never happen.  */
7492
        abort();
7493
    case 4:
7494
        if (insn & (1 << 22)) {
7495
            /* Other load/store, table branch.  */
7496
            if (insn & 0x01200000) {
7497
                /* Load/store doubleword.  */
7498
                if (rn == 15) {
7499
                    addr = tcg_temp_new_i32();
7500
                    tcg_gen_movi_i32(addr, s->pc & ~3);
7501
                } else {
7502
                    addr = load_reg(s, rn);
7503
                }
7504
                offset = (insn & 0xff) * 4;
7505
                if ((insn & (1 << 23)) == 0)
7506
                    offset = -offset;
7507
                if (insn & (1 << 24)) {
7508
                    tcg_gen_addi_i32(addr, addr, offset);
7509
                    offset = 0;
7510
                }
7511
                if (insn & (1 << 20)) {
7512
                    /* ldrd */
7513
                    tmp = gen_ld32(addr, IS_USER(s));
7514
                    store_reg(s, rs, tmp);
7515
                    tcg_gen_addi_i32(addr, addr, 4);
7516
                    tmp = gen_ld32(addr, IS_USER(s));
7517
                    store_reg(s, rd, tmp);
7518
                } else {
7519
                    /* strd */
7520
                    tmp = load_reg(s, rs);
7521
                    gen_st32(tmp, addr, IS_USER(s));
7522
                    tcg_gen_addi_i32(addr, addr, 4);
7523
                    tmp = load_reg(s, rd);
7524
                    gen_st32(tmp, addr, IS_USER(s));
7525
                }
7526
                if (insn & (1 << 21)) {
7527
                    /* Base writeback.  */
7528
                    if (rn == 15)
7529
                        goto illegal_op;
7530
                    tcg_gen_addi_i32(addr, addr, offset - 4);
7531
                    store_reg(s, rn, addr);
7532
                } else {
7533
                    tcg_temp_free_i32(addr);
7534
                }
7535
            } else if ((insn & (1 << 23)) == 0) {
7536
                /* Load/store exclusive word.  */
7537
                addr = tcg_temp_local_new();
7538
                load_reg_var(s, addr, rn);
7539
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
7540
                if (insn & (1 << 20)) {
7541
                    gen_load_exclusive(s, rs, 15, addr, 2);
7542
                } else {
7543
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
7544
                }
7545
                tcg_temp_free(addr);
7546
            } else if ((insn & (1 << 6)) == 0) {
7547
                /* Table Branch.  */
7548
                if (rn == 15) {
7549
                    addr = tcg_temp_new_i32();
7550
                    tcg_gen_movi_i32(addr, s->pc);
7551
                } else {
7552
                    addr = load_reg(s, rn);
7553
                }
7554
                tmp = load_reg(s, rm);
7555
                tcg_gen_add_i32(addr, addr, tmp);
7556
                if (insn & (1 << 4)) {
7557
                    /* tbh */
7558
                    tcg_gen_add_i32(addr, addr, tmp);
7559
                    tcg_temp_free_i32(tmp);
7560
                    tmp = gen_ld16u(addr, IS_USER(s));
7561
                } else { /* tbb */
7562
                    tcg_temp_free_i32(tmp);
7563
                    tmp = gen_ld8u(addr, IS_USER(s));
7564
                }
7565
                tcg_temp_free_i32(addr);
7566
                tcg_gen_shli_i32(tmp, tmp, 1);
7567
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7568
                store_reg(s, 15, tmp);
7569
            } else {
7570
                /* Load/store exclusive byte/halfword/doubleword.  */
7571
                ARCH(7);
7572
                op = (insn >> 4) & 0x3;
7573
                if (op == 2) {
7574
                    goto illegal_op;
7575
                }
7576
                addr = tcg_temp_local_new();
7577
                load_reg_var(s, addr, rn);
7578
                if (insn & (1 << 20)) {
7579
                    gen_load_exclusive(s, rs, rd, addr, op);
7580
                } else {
7581
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
7582
                }
7583
                tcg_temp_free(addr);
7584
            }
7585
        } else {
7586
            /* Load/store multiple, RFE, SRS.  */
7587
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7588
                /* Not available in user mode.  */
7589
                if (IS_USER(s))
7590
                    goto illegal_op;
7591
                if (insn & (1 << 20)) {
7592
                    /* rfe */
7593
                    addr = load_reg(s, rn);
7594
                    if ((insn & (1 << 24)) == 0)
7595
                        tcg_gen_addi_i32(addr, addr, -8);
7596
                    /* Load PC into tmp and CPSR into tmp2.  */
7597
                    tmp = gen_ld32(addr, 0);
7598
                    tcg_gen_addi_i32(addr, addr, 4);
7599
                    tmp2 = gen_ld32(addr, 0);
7600
                    if (insn & (1 << 21)) {
7601
                        /* Base writeback.  */
7602
                        if (insn & (1 << 24)) {
7603
                            tcg_gen_addi_i32(addr, addr, 4);
7604
                        } else {
7605
                            tcg_gen_addi_i32(addr, addr, -4);
7606
                        }
7607
                        store_reg(s, rn, addr);
7608
                    } else {
7609
                        tcg_temp_free_i32(addr);
7610
                    }
7611
                    gen_rfe(s, tmp, tmp2);
7612
                } else {
7613
                    /* srs */
7614
                    op = (insn & 0x1f);
7615
                    addr = tcg_temp_new_i32();
7616
                    tmp = tcg_const_i32(op);
7617
                    gen_helper_get_r13_banked(addr, cpu_env, tmp);
7618
                    tcg_temp_free_i32(tmp);
7619
                    if ((insn & (1 << 24)) == 0) {
7620
                        tcg_gen_addi_i32(addr, addr, -8);
7621
                    }
7622
                    tmp = load_reg(s, 14);
7623
                    gen_st32(tmp, addr, 0);
7624
                    tcg_gen_addi_i32(addr, addr, 4);
7625
                    tmp = tcg_temp_new_i32();
7626
                    gen_helper_cpsr_read(tmp);
7627
                    gen_st32(tmp, addr, 0);
7628
                    if (insn & (1 << 21)) {
7629
                        if ((insn & (1 << 24)) == 0) {
7630
                            tcg_gen_addi_i32(addr, addr, -4);
7631
                        } else {
7632
                            tcg_gen_addi_i32(addr, addr, 4);
7633
                        }
7634
                        tmp = tcg_const_i32(op);
7635
                        gen_helper_set_r13_banked(cpu_env, tmp, addr);
7636
                        tcg_temp_free_i32(tmp);
7637
                    } else {
7638
                        tcg_temp_free_i32(addr);
7639
                    }
7640
                }
7641
            } else {
7642
                int i;
7643
                /* Load/store multiple.  */
7644
                addr = load_reg(s, rn);
7645
                offset = 0;
7646
                for (i = 0; i < 16; i++) {
7647
                    if (insn & (1 << i))
7648
                        offset += 4;
7649
                }
7650
                if (insn & (1 << 24)) {
7651
                    tcg_gen_addi_i32(addr, addr, -offset);
7652
                }
7653

    
7654
                for (i = 0; i < 16; i++) {
7655
                    if ((insn & (1 << i)) == 0)
7656
                        continue;
7657
                    if (insn & (1 << 20)) {
7658
                        /* Load.  */
7659
                        tmp = gen_ld32(addr, IS_USER(s));
7660
                        if (i == 15) {
7661
                            gen_bx(s, tmp);
7662
                        } else {
7663
                            store_reg(s, i, tmp);
7664
                        }
7665
                    } else {
7666
                        /* Store.  */
7667
                        tmp = load_reg(s, i);
7668
                        gen_st32(tmp, addr, IS_USER(s));
7669
                    }
7670
                    tcg_gen_addi_i32(addr, addr, 4);
7671
                }
7672
                if (insn & (1 << 21)) {
7673
                    /* Base register writeback.  */
7674
                    if (insn & (1 << 24)) {
7675
                        tcg_gen_addi_i32(addr, addr, -offset);
7676
                    }
7677
                    /* Fault if writeback register is in register list.  */
7678
                    if (insn & (1 << rn))
7679
                        goto illegal_op;
7680
                    store_reg(s, rn, addr);
7681
                } else {
7682
                    tcg_temp_free_i32(addr);
7683
                }
7684
            }
7685
        }
7686
        break;
7687
    case 5:
7688

    
7689
        op = (insn >> 21) & 0xf;
7690
        if (op == 6) {
7691
            /* Halfword pack.  */
7692
            tmp = load_reg(s, rn);
7693
            tmp2 = load_reg(s, rm);
7694
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
7695
            if (insn & (1 << 5)) {
7696
                /* pkhtb */
7697
                if (shift == 0)
7698
                    shift = 31;
7699
                tcg_gen_sari_i32(tmp2, tmp2, shift);
7700
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7701
                tcg_gen_ext16u_i32(tmp2, tmp2);
7702
            } else {
7703
                /* pkhbt */
7704
                if (shift)
7705
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
7706
                tcg_gen_ext16u_i32(tmp, tmp);
7707
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7708
            }
7709
            tcg_gen_or_i32(tmp, tmp, tmp2);
7710
            tcg_temp_free_i32(tmp2);
7711
            store_reg(s, rd, tmp);
7712
        } else {
7713
            /* Data processing register constant shift.  */
7714
            if (rn == 15) {
7715
                tmp = tcg_temp_new_i32();
7716
                tcg_gen_movi_i32(tmp, 0);
7717
            } else {
7718
                tmp = load_reg(s, rn);
7719
            }
7720
            tmp2 = load_reg(s, rm);
7721

    
7722
            shiftop = (insn >> 4) & 3;
7723
            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7724
            conds = (insn & (1 << 20)) != 0;
7725
            logic_cc = (conds && thumb2_logic_op(op));
7726
            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7727
            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
7728
                goto illegal_op;
7729
            tcg_temp_free_i32(tmp2);
7730
            if (rd != 15) {
7731
                store_reg(s, rd, tmp);
7732
            } else {
7733
                tcg_temp_free_i32(tmp);
7734
            }
7735
        }
7736
        break;
7737
    case 13: /* Misc data processing.  */
7738
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7739
        if (op < 4 && (insn & 0xf000) != 0xf000)
7740
            goto illegal_op;
7741
        switch (op) {
7742
        case 0: /* Register controlled shift.  */
7743
            tmp = load_reg(s, rn);
7744
            tmp2 = load_reg(s, rm);
7745
            if ((insn & 0x70) != 0)
7746
                goto illegal_op;
7747
            op = (insn >> 21) & 3;
7748
            logic_cc = (insn & (1 << 20)) != 0;
7749
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7750
            if (logic_cc)
7751
                gen_logic_CC(tmp);
7752
            store_reg_bx(env, s, rd, tmp);
7753
            break;
7754
        case 1: /* Sign/zero extend.  */
7755
            tmp = load_reg(s, rm);
7756
            shift = (insn >> 4) & 3;
7757
            /* ??? In many cases it's not neccessary to do a
7758
               rotate, a shift is sufficient.  */
7759
            if (shift != 0)
7760
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7761
            op = (insn >> 20) & 7;
7762
            switch (op) {
7763
            case 0: gen_sxth(tmp);   break;
7764
            case 1: gen_uxth(tmp);   break;
7765
            case 2: gen_sxtb16(tmp); break;
7766
            case 3: gen_uxtb16(tmp); break;
7767
            case 4: gen_sxtb(tmp);   break;
7768
            case 5: gen_uxtb(tmp);   break;
7769
            default: goto illegal_op;
7770
            }
7771
            if (rn != 15) {
7772
                tmp2 = load_reg(s, rn);
7773
                if ((op >> 1) == 1) {
7774
                    gen_add16(tmp, tmp2);
7775
                } else {
7776
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7777
                    tcg_temp_free_i32(tmp2);
7778
                }
7779
            }
7780
            store_reg(s, rd, tmp);
7781
            break;
7782
        case 2: /* SIMD add/subtract.  */
7783
            op = (insn >> 20) & 7;
7784
            shift = (insn >> 4) & 7;
7785
            if ((op & 3) == 3 || (shift & 3) == 3)
7786
                goto illegal_op;
7787
            tmp = load_reg(s, rn);
7788
            tmp2 = load_reg(s, rm);
7789
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7790
            tcg_temp_free_i32(tmp2);
7791
            store_reg(s, rd, tmp);
7792
            break;
7793
        case 3: /* Other data processing.  */
7794
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7795
            if (op < 4) {
7796
                /* Saturating add/subtract.  */
7797
                tmp = load_reg(s, rn);
7798
                tmp2 = load_reg(s, rm);
7799
                if (op & 1)
7800
                    gen_helper_double_saturate(tmp, tmp);
7801
                if (op & 2)
7802
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7803
                else
7804
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7805
                tcg_temp_free_i32(tmp2);
7806
            } else {
7807
                tmp = load_reg(s, rn);
7808
                switch (op) {
7809
                case 0x0a: /* rbit */
7810
                    gen_helper_rbit(tmp, tmp);
7811
                    break;
7812
                case 0x08: /* rev */
7813
                    tcg_gen_bswap32_i32(tmp, tmp);
7814
                    break;
7815
                case 0x09: /* rev16 */
7816
                    gen_rev16(tmp);
7817
                    break;
7818
                case 0x0b: /* revsh */
7819
                    gen_revsh(tmp);
7820
                    break;
7821
                case 0x10: /* sel */
7822
                    tmp2 = load_reg(s, rm);
7823
                    tmp3 = tcg_temp_new_i32();
7824
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7825
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7826
                    tcg_temp_free_i32(tmp3);
7827
                    tcg_temp_free_i32(tmp2);
7828
                    break;
7829
                case 0x18: /* clz */
7830
                    gen_helper_clz(tmp, tmp);
7831
                    break;
7832
                default:
7833
                    goto illegal_op;
7834
                }
7835
            }
7836
            store_reg(s, rd, tmp);
7837
            break;
7838
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7839
            op = (insn >> 4) & 0xf;
7840
            tmp = load_reg(s, rn);
7841
            tmp2 = load_reg(s, rm);
7842
            switch ((insn >> 20) & 7) {
7843
            case 0: /* 32 x 32 -> 32 */
7844
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7845
                tcg_temp_free_i32(tmp2);
7846
                if (rs != 15) {
7847
                    tmp2 = load_reg(s, rs);
7848
                    if (op)
7849
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7850
                    else
7851
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7852
                    tcg_temp_free_i32(tmp2);
7853
                }
7854
                break;
7855
            case 1: /* 16 x 16 -> 32 */
7856
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7857
                tcg_temp_free_i32(tmp2);
7858
                if (rs != 15) {
7859
                    tmp2 = load_reg(s, rs);
7860
                    gen_helper_add_setq(tmp, tmp, tmp2);
7861
                    tcg_temp_free_i32(tmp2);
7862
                }
7863
                break;
7864
            case 2: /* Dual multiply add.  */
7865
            case 4: /* Dual multiply subtract.  */
7866
                if (op)
7867
                    gen_swap_half(tmp2);
7868
                gen_smul_dual(tmp, tmp2);
7869
                if (insn & (1 << 22)) {
7870
                    /* This subtraction cannot overflow. */
7871
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7872
                } else {
7873
                    /* This addition cannot overflow 32 bits;
7874
                     * however it may overflow considered as a signed
7875
                     * operation, in which case we must set the Q flag.
7876
                     */
7877
                    gen_helper_add_setq(tmp, tmp, tmp2);
7878
                }
7879
                tcg_temp_free_i32(tmp2);
7880
                if (rs != 15)
7881
                  {
7882
                    tmp2 = load_reg(s, rs);
7883
                    gen_helper_add_setq(tmp, tmp, tmp2);
7884
                    tcg_temp_free_i32(tmp2);
7885
                  }
7886
                break;
7887
            case 3: /* 32 * 16 -> 32msb */
7888
                if (op)
7889
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7890
                else
7891
                    gen_sxth(tmp2);
7892
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7893
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7894
                tmp = tcg_temp_new_i32();
7895
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7896
                tcg_temp_free_i64(tmp64);
7897
                if (rs != 15)
7898
                  {
7899
                    tmp2 = load_reg(s, rs);
7900
                    gen_helper_add_setq(tmp, tmp, tmp2);
7901
                    tcg_temp_free_i32(tmp2);
7902
                  }
7903
                break;
7904
            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
7905
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7906
                if (rs != 15) {
7907
                    tmp = load_reg(s, rs);
7908
                    if (insn & (1 << 20)) {
7909
                        tmp64 = gen_addq_msw(tmp64, tmp);
7910
                    } else {
7911
                        tmp64 = gen_subq_msw(tmp64, tmp);
7912
                    }
7913
                }
7914
                if (insn & (1 << 4)) {
7915
                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7916
                }
7917
                tcg_gen_shri_i64(tmp64, tmp64, 32);
7918
                tmp = tcg_temp_new_i32();
7919
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7920
                tcg_temp_free_i64(tmp64);
7921
                break;
7922
            case 7: /* Unsigned sum of absolute differences.  */
7923
                gen_helper_usad8(tmp, tmp, tmp2);
7924
                tcg_temp_free_i32(tmp2);
7925
                if (rs != 15) {
7926
                    tmp2 = load_reg(s, rs);
7927
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7928
                    tcg_temp_free_i32(tmp2);
7929
                }
7930
                break;
7931
            }
7932
            store_reg(s, rd, tmp);
7933
            break;
7934
        case 6: case 7: /* 64-bit multiply, Divide.  */
7935
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7936
            tmp = load_reg(s, rn);
7937
            tmp2 = load_reg(s, rm);
7938
            if ((op & 0x50) == 0x10) {
7939
                /* sdiv, udiv */
7940
                if (!arm_feature(env, ARM_FEATURE_DIV))
7941
                    goto illegal_op;
7942
                if (op & 0x20)
7943
                    gen_helper_udiv(tmp, tmp, tmp2);
7944
                else
7945
                    gen_helper_sdiv(tmp, tmp, tmp2);
7946
                tcg_temp_free_i32(tmp2);
7947
                store_reg(s, rd, tmp);
7948
            } else if ((op & 0xe) == 0xc) {
7949
                /* Dual multiply accumulate long.  */
7950
                if (op & 1)
7951
                    gen_swap_half(tmp2);
7952
                gen_smul_dual(tmp, tmp2);
7953
                if (op & 0x10) {
7954
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7955
                } else {
7956
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7957
                }
7958
                tcg_temp_free_i32(tmp2);
7959
                /* BUGFIX */
7960
                tmp64 = tcg_temp_new_i64();
7961
                tcg_gen_ext_i32_i64(tmp64, tmp);
7962
                tcg_temp_free_i32(tmp);
7963
                gen_addq(s, tmp64, rs, rd);
7964
                gen_storeq_reg(s, rs, rd, tmp64);
7965
                tcg_temp_free_i64(tmp64);
7966
            } else {
7967
                if (op & 0x20) {
7968
                    /* Unsigned 64-bit multiply  */
7969
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7970
                } else {
7971
                    if (op & 8) {
7972
                        /* smlalxy */
7973
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7974
                        tcg_temp_free_i32(tmp2);
7975
                        tmp64 = tcg_temp_new_i64();
7976
                        tcg_gen_ext_i32_i64(tmp64, tmp);
7977
                        tcg_temp_free_i32(tmp);
7978
                    } else {
7979
                        /* Signed 64-bit multiply  */
7980
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7981
                    }
7982
                }
7983
                if (op & 4) {
7984
                    /* umaal */
7985
                    gen_addq_lo(s, tmp64, rs);
7986
                    gen_addq_lo(s, tmp64, rd);
7987
                } else if (op & 0x40) {
7988
                    /* 64-bit accumulate.  */
7989
                    gen_addq(s, tmp64, rs, rd);
7990
                }
7991
                gen_storeq_reg(s, rs, rd, tmp64);
7992
                tcg_temp_free_i64(tmp64);
7993
            }
7994
            break;
7995
        }
7996
        break;
7997
    case 6: case 7: case 14: case 15:
7998
        /* Coprocessor.  */
7999
        if (((insn >> 24) & 3) == 3) {
8000
            /* Translate into the equivalent ARM encoding.  */
8001
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8002
            if (disas_neon_data_insn(env, s, insn))
8003
                goto illegal_op;
8004
        } else {
8005
            if (insn & (1 << 28))
8006
                goto illegal_op;
8007
            if (disas_coproc_insn (env, s, insn))
8008
                goto illegal_op;
8009
        }
8010
        break;
8011
    case 8: case 9: case 10: case 11:
8012
        if (insn & (1 << 15)) {
8013
            /* Branches, misc control.  */
8014
            if (insn & 0x5000) {
8015
                /* Unconditional branch.  */
8016
                /* signextend(hw1[10:0]) -> offset[:12].  */
8017
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8018
                /* hw1[10:0] -> offset[11:1].  */
8019
                offset |= (insn & 0x7ff) << 1;
8020
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8021
                   offset[24:22] already have the same value because of the
8022
                   sign extension above.  */
8023
                offset ^= ((~insn) & (1 << 13)) << 10;
8024
                offset ^= ((~insn) & (1 << 11)) << 11;
8025

    
8026
                if (insn & (1 << 14)) {
8027
                    /* Branch and link.  */
8028
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8029
                }
8030

    
8031
                offset += s->pc;
8032
                if (insn & (1 << 12)) {
8033
                    /* b/bl */
8034
                    gen_jmp(s, offset);
8035
                } else {
8036
                    /* blx */
8037
                    offset &= ~(uint32_t)2;
8038
                    gen_bx_im(s, offset);
8039
                }
8040
            } else if (((insn >> 23) & 7) == 7) {
8041
                /* Misc control */
8042
                if (insn & (1 << 13))
8043
                    goto illegal_op;
8044

    
8045
                if (insn & (1 << 26)) {
8046
                    /* Secure monitor call (v6Z) */
8047
                    goto illegal_op; /* not implemented.  */
8048
                } else {
8049
                    op = (insn >> 20) & 7;
8050
                    switch (op) {
8051
                    case 0: /* msr cpsr.  */
8052
                        if (IS_M(env)) {
8053
                            tmp = load_reg(s, rn);
8054
                            addr = tcg_const_i32(insn & 0xff);
8055
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
8056
                            tcg_temp_free_i32(addr);
8057
                            tcg_temp_free_i32(tmp);
8058
                            gen_lookup_tb(s);
8059
                            break;
8060
                        }
8061
                        /* fall through */
8062
                    case 1: /* msr spsr.  */
8063
                        if (IS_M(env))
8064
                            goto illegal_op;
8065
                        tmp = load_reg(s, rn);
8066
                        if (gen_set_psr(s,
8067
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8068
                              op == 1, tmp))
8069
                            goto illegal_op;
8070
                        break;
8071
                    case 2: /* cps, nop-hint.  */
8072
                        if (((insn >> 8) & 7) == 0) {
8073
                            gen_nop_hint(s, insn & 0xff);
8074
                        }
8075
                        /* Implemented as NOP in user mode.  */
8076
                        if (IS_USER(s))
8077
                            break;
8078
                        offset = 0;
8079
                        imm = 0;
8080
                        if (insn & (1 << 10)) {
8081
                            if (insn & (1 << 7))
8082
                                offset |= CPSR_A;
8083
                            if (insn & (1 << 6))
8084
                                offset |= CPSR_I;
8085
                            if (insn & (1 << 5))
8086
                                offset |= CPSR_F;
8087
                            if (insn & (1 << 9))
8088
                                imm = CPSR_A | CPSR_I | CPSR_F;
8089
                        }
8090
                        if (insn & (1 << 8)) {
8091
                            offset |= 0x1f;
8092
                            imm |= (insn & 0x1f);
8093
                        }
8094
                        if (offset) {
8095
                            gen_set_psr_im(s, offset, 0, imm);
8096
                        }
8097
                        break;
8098
                    case 3: /* Special control operations.  */
8099
                        ARCH(7);
8100
                        op = (insn >> 4) & 0xf;
8101
                        switch (op) {
8102
                        case 2: /* clrex */
8103
                            gen_clrex(s);
8104
                            break;
8105
                        case 4: /* dsb */
8106
                        case 5: /* dmb */
8107
                        case 6: /* isb */
8108
                            /* These execute as NOPs.  */
8109
                            break;
8110
                        default:
8111
                            goto illegal_op;
8112
                        }
8113
                        break;
8114
                    case 4: /* bxj */
8115
                        /* Trivial implementation equivalent to bx.  */
8116
                        tmp = load_reg(s, rn);
8117
                        gen_bx(s, tmp);
8118
                        break;
8119
                    case 5: /* Exception return.  */
8120
                        if (IS_USER(s)) {
8121
                            goto illegal_op;
8122
                        }
8123
                        if (rn != 14 || rd != 15) {
8124
                            goto illegal_op;
8125
                        }
8126
                        tmp = load_reg(s, rn);
8127
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8128
                        gen_exception_return(s, tmp);
8129
                        break;
8130
                    case 6: /* mrs cpsr.  */
8131
                        tmp = tcg_temp_new_i32();
8132
                        if (IS_M(env)) {
8133
                            addr = tcg_const_i32(insn & 0xff);
8134
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
8135
                            tcg_temp_free_i32(addr);
8136
                        } else {
8137
                            gen_helper_cpsr_read(tmp);
8138
                        }
8139
                        store_reg(s, rd, tmp);
8140
                        break;
8141
                    case 7: /* mrs spsr.  */
8142
                        /* Not accessible in user mode.  */
8143
                        if (IS_USER(s) || IS_M(env))
8144
                            goto illegal_op;
8145
                        tmp = load_cpu_field(spsr);
8146
                        store_reg(s, rd, tmp);
8147
                        break;
8148
                    }
8149
                }
8150
            } else {
8151
                /* Conditional branch.  */
8152
                op = (insn >> 22) & 0xf;
8153
                /* Generate a conditional jump to next instruction.  */
8154
                s->condlabel = gen_new_label();
8155
                gen_test_cc(op ^ 1, s->condlabel);
8156
                s->condjmp = 1;
8157

    
8158
                /* offset[11:1] = insn[10:0] */
8159
                offset = (insn & 0x7ff) << 1;
8160
                /* offset[17:12] = insn[21:16].  */
8161
                offset |= (insn & 0x003f0000) >> 4;
8162
                /* offset[31:20] = insn[26].  */
8163
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8164
                /* offset[18] = insn[13].  */
8165
                offset |= (insn & (1 << 13)) << 5;
8166
                /* offset[19] = insn[11].  */
8167
                offset |= (insn & (1 << 11)) << 8;
8168

    
8169
                /* jump to the offset */
8170
                gen_jmp(s, s->pc + offset);
8171
            }
8172
        } else {
8173
            /* Data processing immediate.  */
8174
            if (insn & (1 << 25)) {
8175
                if (insn & (1 << 24)) {
8176
                    if (insn & (1 << 20))
8177
                        goto illegal_op;
8178
                    /* Bitfield/Saturate.  */
8179
                    op = (insn >> 21) & 7;
8180
                    imm = insn & 0x1f;
8181
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8182
                    if (rn == 15) {
8183
                        tmp = tcg_temp_new_i32();
8184
                        tcg_gen_movi_i32(tmp, 0);
8185
                    } else {
8186
                        tmp = load_reg(s, rn);
8187
                    }
8188
                    switch (op) {
8189
                    case 2: /* Signed bitfield extract.  */
8190
                        imm++;
8191
                        if (shift + imm > 32)
8192
                            goto illegal_op;
8193
                        if (imm < 32)
8194
                            gen_sbfx(tmp, shift, imm);
8195
                        break;
8196
                    case 6: /* Unsigned bitfield extract.  */
8197
                        imm++;
8198
                        if (shift + imm > 32)
8199
                            goto illegal_op;
8200
                        if (imm < 32)
8201
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
8202
                        break;
8203
                    case 3: /* Bitfield insert/clear.  */
8204
                        if (imm < shift)
8205
                            goto illegal_op;
8206
                        imm = imm + 1 - shift;
8207
                        if (imm != 32) {
8208
                            tmp2 = load_reg(s, rd);
8209
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
8210
                            tcg_temp_free_i32(tmp2);
8211
                        }
8212
                        break;
8213
                    case 7:
8214
                        goto illegal_op;
8215
                    default: /* Saturate.  */
8216
                        if (shift) {
8217
                            if (op & 1)
8218
                                tcg_gen_sari_i32(tmp, tmp, shift);
8219
                            else
8220
                                tcg_gen_shli_i32(tmp, tmp, shift);
8221
                        }
8222
                        tmp2 = tcg_const_i32(imm);
8223
                        if (op & 4) {
8224
                            /* Unsigned.  */
8225
                            if ((op & 1) && shift == 0)
8226
                                gen_helper_usat16(tmp, tmp, tmp2);
8227
                            else
8228
                                gen_helper_usat(tmp, tmp, tmp2);
8229
                        } else {
8230
                            /* Signed.  */
8231
                            if ((op & 1) && shift == 0)
8232
                                gen_helper_ssat16(tmp, tmp, tmp2);
8233
                            else
8234
                                gen_helper_ssat(tmp, tmp, tmp2);
8235
                        }
8236
                        tcg_temp_free_i32(tmp2);
8237
                        break;
8238
                    }
8239
                    store_reg(s, rd, tmp);
8240
                } else {
8241
                    imm = ((insn & 0x04000000) >> 15)
8242
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
8243
                    if (insn & (1 << 22)) {
8244
                        /* 16-bit immediate.  */
8245
                        imm |= (insn >> 4) & 0xf000;
8246
                        if (insn & (1 << 23)) {
8247
                            /* movt */
8248
                            tmp = load_reg(s, rd);
8249
                            tcg_gen_ext16u_i32(tmp, tmp);
8250
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
8251
                        } else {
8252
                            /* movw */
8253
                            tmp = tcg_temp_new_i32();
8254
                            tcg_gen_movi_i32(tmp, imm);
8255
                        }
8256
                    } else {
8257
                        /* Add/sub 12-bit immediate.  */
8258
                        if (rn == 15) {
8259
                            offset = s->pc & ~(uint32_t)3;
8260
                            if (insn & (1 << 23))
8261
                                offset -= imm;
8262
                            else
8263
                                offset += imm;
8264
                            tmp = tcg_temp_new_i32();
8265
                            tcg_gen_movi_i32(tmp, offset);
8266
                        } else {
8267
                            tmp = load_reg(s, rn);
8268
                            if (insn & (1 << 23))
8269
                                tcg_gen_subi_i32(tmp, tmp, imm);
8270
                            else
8271
                                tcg_gen_addi_i32(tmp, tmp, imm);
8272
                        }
8273
                    }
8274
                    store_reg(s, rd, tmp);
8275
                }
8276
            } else {
8277
                int shifter_out = 0;
8278
                /* modified 12-bit immediate.  */
8279
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8280
                imm = (insn & 0xff);
8281
                switch (shift) {
8282
                case 0: /* XY */
8283
                    /* Nothing to do.  */
8284
                    break;
8285
                case 1: /* 00XY00XY */
8286
                    imm |= imm << 16;
8287
                    break;
8288
                case 2: /* XY00XY00 */
8289
                    imm |= imm << 16;
8290
                    imm <<= 8;
8291
                    break;
8292
                case 3: /* XYXYXYXY */
8293
                    imm |= imm << 16;
8294
                    imm |= imm << 8;
8295
                    break;
8296
                default: /* Rotated constant.  */
8297
                    shift = (shift << 1) | (imm >> 7);
8298
                    imm |= 0x80;
8299
                    imm = imm << (32 - shift);
8300
                    shifter_out = 1;
8301
                    break;
8302
                }
8303
                tmp2 = tcg_temp_new_i32();
8304
                tcg_gen_movi_i32(tmp2, imm);
8305
                rn = (insn >> 16) & 0xf;
8306
                if (rn == 15) {
8307
                    tmp = tcg_temp_new_i32();
8308
                    tcg_gen_movi_i32(tmp, 0);
8309
                } else {
8310
                    tmp = load_reg(s, rn);
8311
                }
8312
                op = (insn >> 21) & 0xf;
8313
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
8314
                                       shifter_out, tmp, tmp2))
8315
                    goto illegal_op;
8316
                tcg_temp_free_i32(tmp2);
8317
                rd = (insn >> 8) & 0xf;
8318
                if (rd != 15) {
8319
                    store_reg(s, rd, tmp);
8320
                } else {
8321
                    tcg_temp_free_i32(tmp);
8322
                }
8323
            }
8324
        }
8325
        break;
8326
    case 12: /* Load/store single data item.  */
8327
        {
8328
        int postinc = 0;
8329
        int writeback = 0;
8330
        int user;
8331
        if ((insn & 0x01100000) == 0x01000000) {
8332
            if (disas_neon_ls_insn(env, s, insn))
8333
                goto illegal_op;
8334
            break;
8335
        }
8336
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8337
        if (rs == 15) {
8338
            if (!(insn & (1 << 20))) {
8339
                goto illegal_op;
8340
            }
8341
            if (op != 2) {
8342
                /* Byte or halfword load space with dest == r15 : memory hints.
8343
                 * Catch them early so we don't emit pointless addressing code.
8344
                 * This space is a mix of:
8345
                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
8346
                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8347
                 *     cores)
8348
                 *  unallocated hints, which must be treated as NOPs
8349
                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
8350
                 *     which is easiest for the decoding logic
8351
                 *  Some space which must UNDEF
8352
                 */
8353
                int op1 = (insn >> 23) & 3;
8354
                int op2 = (insn >> 6) & 0x3f;
8355
                if (op & 2) {
8356
                    goto illegal_op;
8357
                }
8358
                if (rn == 15) {
8359
                    /* UNPREDICTABLE or unallocated hint */
8360
                    return 0;
8361
                }
8362
                if (op1 & 1) {
8363
                    return 0; /* PLD* or unallocated hint */
8364
                }
8365
                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
8366
                    return 0; /* PLD* or unallocated hint */
8367
                }
8368
                /* UNDEF space, or an UNPREDICTABLE */
8369
                return 1;
8370
            }
8371
        }
8372
        user = IS_USER(s);
8373
        if (rn == 15) {
8374
            addr = tcg_temp_new_i32();
8375
            /* PC relative.  */
8376
            /* s->pc has already been incremented by 4.  */
8377
            imm = s->pc & 0xfffffffc;
8378
            if (insn & (1 << 23))
8379
                imm += insn & 0xfff;
8380
            else
8381
                imm -= insn & 0xfff;
8382
            tcg_gen_movi_i32(addr, imm);
8383
        } else {
8384
            addr = load_reg(s, rn);
8385
            if (insn & (1 << 23)) {
8386
                /* Positive offset.  */
8387
                imm = insn & 0xfff;
8388
                tcg_gen_addi_i32(addr, addr, imm);
8389
            } else {
8390
                imm = insn & 0xff;
8391
                switch ((insn >> 8) & 0xf) {
8392
                case 0x0: /* Shifted Register.  */
8393
                    shift = (insn >> 4) & 0xf;
8394
                    if (shift > 3) {
8395
                        tcg_temp_free_i32(addr);
8396
                        goto illegal_op;
8397
                    }
8398
                    tmp = load_reg(s, rm);
8399
                    if (shift)
8400
                        tcg_gen_shli_i32(tmp, tmp, shift);
8401
                    tcg_gen_add_i32(addr, addr, tmp);
8402
                    tcg_temp_free_i32(tmp);
8403
                    break;
8404
                case 0xc: /* Negative offset.  */
8405
                    tcg_gen_addi_i32(addr, addr, -imm);
8406
                    break;
8407
                case 0xe: /* User privilege.  */
8408
                    tcg_gen_addi_i32(addr, addr, imm);
8409
                    user = 1;
8410
                    break;
8411
                case 0x9: /* Post-decrement.  */
8412
                    imm = -imm;
8413
                    /* Fall through.  */
8414
                case 0xb: /* Post-increment.  */
8415
                    postinc = 1;
8416
                    writeback = 1;
8417
                    break;
8418
                case 0xd: /* Pre-decrement.  */
8419
                    imm = -imm;
8420
                    /* Fall through.  */
8421
                case 0xf: /* Pre-increment.  */
8422
                    tcg_gen_addi_i32(addr, addr, imm);
8423
                    writeback = 1;
8424
                    break;
8425
                default:
8426
                    tcg_temp_free_i32(addr);
8427
                    goto illegal_op;
8428
                }
8429
            }
8430
        }
8431
        if (insn & (1 << 20)) {
8432
            /* Load.  */
8433
            switch (op) {
8434
            case 0: tmp = gen_ld8u(addr, user); break;
8435
            case 4: tmp = gen_ld8s(addr, user); break;
8436
            case 1: tmp = gen_ld16u(addr, user); break;
8437
            case 5: tmp = gen_ld16s(addr, user); break;
8438
            case 2: tmp = gen_ld32(addr, user); break;
8439
            default:
8440
                tcg_temp_free_i32(addr);
8441
                goto illegal_op;
8442
            }
8443
            if (rs == 15) {
8444
                gen_bx(s, tmp);
8445
            } else {
8446
                store_reg(s, rs, tmp);
8447
            }
8448
        } else {
8449
            /* Store.  */
8450
            tmp = load_reg(s, rs);
8451
            switch (op) {
8452
            case 0: gen_st8(tmp, addr, user); break;
8453
            case 1: gen_st16(tmp, addr, user); break;
8454
            case 2: gen_st32(tmp, addr, user); break;
8455
            default:
8456
                tcg_temp_free_i32(addr);
8457
                goto illegal_op;
8458
            }
8459
        }
8460
        if (postinc)
8461
            tcg_gen_addi_i32(addr, addr, imm);
8462
        if (writeback) {
8463
            store_reg(s, rn, addr);
8464
        } else {
8465
            tcg_temp_free_i32(addr);
8466
        }
8467
        }
8468
        break;
8469
    default:
8470
        goto illegal_op;
8471
    }
8472
    return 0;
8473
illegal_op:
8474
    return 1;
8475
}
8476

    
8477
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8478
{
8479
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8480
    int32_t offset;
8481
    int i;
8482
    TCGv tmp;
8483
    TCGv tmp2;
8484
    TCGv addr;
8485

    
8486
    if (s->condexec_mask) {
8487
        cond = s->condexec_cond;
8488
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
8489
          s->condlabel = gen_new_label();
8490
          gen_test_cc(cond ^ 1, s->condlabel);
8491
          s->condjmp = 1;
8492
        }
8493
    }
8494

    
8495
    insn = lduw_code(s->pc);
8496
    s->pc += 2;
8497

    
8498
    switch (insn >> 12) {
8499
    case 0: case 1:
8500

    
8501
        rd = insn & 7;
8502
        op = (insn >> 11) & 3;
8503
        if (op == 3) {
8504
            /* add/subtract */
8505
            rn = (insn >> 3) & 7;
8506
            tmp = load_reg(s, rn);
8507
            if (insn & (1 << 10)) {
8508
                /* immediate */
8509
                tmp2 = tcg_temp_new_i32();
8510
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8511
            } else {
8512
                /* reg */
8513
                rm = (insn >> 6) & 7;
8514
                tmp2 = load_reg(s, rm);
8515
            }
8516
            if (insn & (1 << 9)) {
8517
                if (s->condexec_mask)
8518
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8519
                else
8520
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8521
            } else {
8522
                if (s->condexec_mask)
8523
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8524
                else
8525
                    gen_helper_add_cc(tmp, tmp, tmp2);
8526
            }
8527
            tcg_temp_free_i32(tmp2);
8528
            store_reg(s, rd, tmp);
8529
        } else {
8530
            /* shift immediate */
8531
            rm = (insn >> 3) & 7;
8532
            shift = (insn >> 6) & 0x1f;
8533
            tmp = load_reg(s, rm);
8534
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8535
            if (!s->condexec_mask)
8536
                gen_logic_CC(tmp);
8537
            store_reg(s, rd, tmp);
8538
        }
8539
        break;
8540
    case 2: case 3:
8541
        /* arithmetic large immediate */
8542
        op = (insn >> 11) & 3;
8543
        rd = (insn >> 8) & 0x7;
8544
        if (op == 0) { /* mov */
8545
            tmp = tcg_temp_new_i32();
8546
            tcg_gen_movi_i32(tmp, insn & 0xff);
8547
            if (!s->condexec_mask)
8548
                gen_logic_CC(tmp);
8549
            store_reg(s, rd, tmp);
8550
        } else {
8551
            tmp = load_reg(s, rd);
8552
            tmp2 = tcg_temp_new_i32();
8553
            tcg_gen_movi_i32(tmp2, insn & 0xff);
8554
            switch (op) {
8555
            case 1: /* cmp */
8556
                gen_helper_sub_cc(tmp, tmp, tmp2);
8557
                tcg_temp_free_i32(tmp);
8558
                tcg_temp_free_i32(tmp2);
8559
                break;
8560
            case 2: /* add */
8561
                if (s->condexec_mask)
8562
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8563
                else
8564
                    gen_helper_add_cc(tmp, tmp, tmp2);
8565
                tcg_temp_free_i32(tmp2);
8566
                store_reg(s, rd, tmp);
8567
                break;
8568
            case 3: /* sub */
8569
                if (s->condexec_mask)
8570
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8571
                else
8572
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8573
                tcg_temp_free_i32(tmp2);
8574
                store_reg(s, rd, tmp);
8575
                break;
8576
            }
8577
        }
8578
        break;
8579
    case 4:
8580
        if (insn & (1 << 11)) {
8581
            rd = (insn >> 8) & 7;
8582
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8583
            val = s->pc + 2 + ((insn & 0xff) * 4);
8584
            val &= ~(uint32_t)2;
8585
            addr = tcg_temp_new_i32();
8586
            tcg_gen_movi_i32(addr, val);
8587
            tmp = gen_ld32(addr, IS_USER(s));
8588
            tcg_temp_free_i32(addr);
8589
            store_reg(s, rd, tmp);
8590
            break;
8591
        }
8592
        if (insn & (1 << 10)) {
8593
            /* data processing extended or blx */
8594
            rd = (insn & 7) | ((insn >> 4) & 8);
8595
            rm = (insn >> 3) & 0xf;
8596
            op = (insn >> 8) & 3;
8597
            switch (op) {
8598
            case 0: /* add */
8599
                tmp = load_reg(s, rd);
8600
                tmp2 = load_reg(s, rm);
8601
                tcg_gen_add_i32(tmp, tmp, tmp2);
8602
                tcg_temp_free_i32(tmp2);
8603
                store_reg(s, rd, tmp);
8604
                break;
8605
            case 1: /* cmp */
8606
                tmp = load_reg(s, rd);
8607
                tmp2 = load_reg(s, rm);
8608
                gen_helper_sub_cc(tmp, tmp, tmp2);
8609
                tcg_temp_free_i32(tmp2);
8610
                tcg_temp_free_i32(tmp);
8611
                break;
8612
            case 2: /* mov/cpy */
8613
                tmp = load_reg(s, rm);
8614
                store_reg(s, rd, tmp);
8615
                break;
8616
            case 3:/* branch [and link] exchange thumb register */
8617
                tmp = load_reg(s, rm);
8618
                if (insn & (1 << 7)) {
8619
                    val = (uint32_t)s->pc | 1;
8620
                    tmp2 = tcg_temp_new_i32();
8621
                    tcg_gen_movi_i32(tmp2, val);
8622
                    store_reg(s, 14, tmp2);
8623
                }
8624
                gen_bx(s, tmp);
8625
                break;
8626
            }
8627
            break;
8628
        }
8629

    
8630
        /* data processing register */
8631
        rd = insn & 7;
8632
        rm = (insn >> 3) & 7;
8633
        op = (insn >> 6) & 0xf;
8634
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8635
            /* the shift/rotate ops want the operands backwards */
8636
            val = rm;
8637
            rm = rd;
8638
            rd = val;
8639
            val = 1;
8640
        } else {
8641
            val = 0;
8642
        }
8643

    
8644
        if (op == 9) { /* neg */
8645
            tmp = tcg_temp_new_i32();
8646
            tcg_gen_movi_i32(tmp, 0);
8647
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
8648
            tmp = load_reg(s, rd);
8649
        } else {
8650
            TCGV_UNUSED(tmp);
8651
        }
8652

    
8653
        tmp2 = load_reg(s, rm);
8654
        switch (op) {
8655
        case 0x0: /* and */
8656
            tcg_gen_and_i32(tmp, tmp, tmp2);
8657
            if (!s->condexec_mask)
8658
                gen_logic_CC(tmp);
8659
            break;
8660
        case 0x1: /* eor */
8661
            tcg_gen_xor_i32(tmp, tmp, tmp2);
8662
            if (!s->condexec_mask)
8663
                gen_logic_CC(tmp);
8664
            break;
8665
        case 0x2: /* lsl */
8666
            if (s->condexec_mask) {
8667
                gen_helper_shl(tmp2, tmp2, tmp);
8668
            } else {
8669
                gen_helper_shl_cc(tmp2, tmp2, tmp);
8670
                gen_logic_CC(tmp2);
8671
            }
8672
            break;
8673
        case 0x3: /* lsr */
8674
            if (s->condexec_mask) {
8675
                gen_helper_shr(tmp2, tmp2, tmp);
8676
            } else {
8677
                gen_helper_shr_cc(tmp2, tmp2, tmp);
8678
                gen_logic_CC(tmp2);
8679
            }
8680
            break;
8681
        case 0x4: /* asr */
8682
            if (s->condexec_mask) {
8683
                gen_helper_sar(tmp2, tmp2, tmp);
8684
            } else {
8685
                gen_helper_sar_cc(tmp2, tmp2, tmp);
8686
                gen_logic_CC(tmp2);
8687
            }
8688
            break;
8689
        case 0x5: /* adc */
8690
            if (s->condexec_mask)
8691
                gen_adc(tmp, tmp2);
8692
            else
8693
                gen_helper_adc_cc(tmp, tmp, tmp2);
8694
            break;
8695
        case 0x6: /* sbc */
8696
            if (s->condexec_mask)
8697
                gen_sub_carry(tmp, tmp, tmp2);
8698
            else
8699
                gen_helper_sbc_cc(tmp, tmp, tmp2);
8700
            break;
8701
        case 0x7: /* ror */
8702
            if (s->condexec_mask) {
8703
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
8704
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
8705
            } else {
8706
                gen_helper_ror_cc(tmp2, tmp2, tmp);
8707
                gen_logic_CC(tmp2);
8708
            }
8709
            break;
8710
        case 0x8: /* tst */
8711
            tcg_gen_and_i32(tmp, tmp, tmp2);
8712
            gen_logic_CC(tmp);
8713
            rd = 16;
8714
            break;
8715
        case 0x9: /* neg */
8716
            if (s->condexec_mask)
8717
                tcg_gen_neg_i32(tmp, tmp2);
8718
            else
8719
                gen_helper_sub_cc(tmp, tmp, tmp2);
8720
            break;
8721
        case 0xa: /* cmp */
8722
            gen_helper_sub_cc(tmp, tmp, tmp2);
8723
            rd = 16;
8724
            break;
8725
        case 0xb: /* cmn */
8726
            gen_helper_add_cc(tmp, tmp, tmp2);
8727
            rd = 16;
8728
            break;
8729
        case 0xc: /* orr */
8730
            tcg_gen_or_i32(tmp, tmp, tmp2);
8731
            if (!s->condexec_mask)
8732
                gen_logic_CC(tmp);
8733
            break;
8734
        case 0xd: /* mul */
8735
            tcg_gen_mul_i32(tmp, tmp, tmp2);
8736
            if (!s->condexec_mask)
8737
                gen_logic_CC(tmp);
8738
            break;
8739
        case 0xe: /* bic */
8740
            tcg_gen_andc_i32(tmp, tmp, tmp2);
8741
            if (!s->condexec_mask)
8742
                gen_logic_CC(tmp);
8743
            break;
8744
        case 0xf: /* mvn */
8745
            tcg_gen_not_i32(tmp2, tmp2);
8746
            if (!s->condexec_mask)
8747
                gen_logic_CC(tmp2);
8748
            val = 1;
8749
            rm = rd;
8750
            break;
8751
        }
8752
        if (rd != 16) {
8753
            if (val) {
8754
                store_reg(s, rm, tmp2);
8755
                if (op != 0xf)
8756
                    tcg_temp_free_i32(tmp);
8757
            } else {
8758
                store_reg(s, rd, tmp);
8759
                tcg_temp_free_i32(tmp2);
8760
            }
8761
        } else {
8762
            tcg_temp_free_i32(tmp);
8763
            tcg_temp_free_i32(tmp2);
8764
        }
8765
        break;
8766

    
8767
    case 5:
8768
        /* load/store register offset.  */
8769
        rd = insn & 7;
8770
        rn = (insn >> 3) & 7;
8771
        rm = (insn >> 6) & 7;
8772
        op = (insn >> 9) & 7;
8773
        addr = load_reg(s, rn);
8774
        tmp = load_reg(s, rm);
8775
        tcg_gen_add_i32(addr, addr, tmp);
8776
        tcg_temp_free_i32(tmp);
8777

    
8778
        if (op < 3) /* store */
8779
            tmp = load_reg(s, rd);
8780

    
8781
        switch (op) {
8782
        case 0: /* str */
8783
            gen_st32(tmp, addr, IS_USER(s));
8784
            break;
8785
        case 1: /* strh */
8786
            gen_st16(tmp, addr, IS_USER(s));
8787
            break;
8788
        case 2: /* strb */
8789
            gen_st8(tmp, addr, IS_USER(s));
8790
            break;
8791
        case 3: /* ldrsb */
8792
            tmp = gen_ld8s(addr, IS_USER(s));
8793
            break;
8794
        case 4: /* ldr */
8795
            tmp = gen_ld32(addr, IS_USER(s));
8796
            break;
8797
        case 5: /* ldrh */
8798
            tmp = gen_ld16u(addr, IS_USER(s));
8799
            break;
8800
        case 6: /* ldrb */
8801
            tmp = gen_ld8u(addr, IS_USER(s));
8802
            break;
8803
        case 7: /* ldrsh */
8804
            tmp = gen_ld16s(addr, IS_USER(s));
8805
            break;
8806
        }
8807
        if (op >= 3) /* load */
8808
            store_reg(s, rd, tmp);
8809
        tcg_temp_free_i32(addr);
8810
        break;
8811

    
8812
    case 6:
8813
        /* load/store word immediate offset */
8814
        rd = insn & 7;
8815
        rn = (insn >> 3) & 7;
8816
        addr = load_reg(s, rn);
8817
        val = (insn >> 4) & 0x7c;
8818
        tcg_gen_addi_i32(addr, addr, val);
8819

    
8820
        if (insn & (1 << 11)) {
8821
            /* load */
8822
            tmp = gen_ld32(addr, IS_USER(s));
8823
            store_reg(s, rd, tmp);
8824
        } else {
8825
            /* store */
8826
            tmp = load_reg(s, rd);
8827
            gen_st32(tmp, addr, IS_USER(s));
8828
        }
8829
        tcg_temp_free_i32(addr);
8830
        break;
8831

    
8832
    case 7:
8833
        /* load/store byte immediate offset */
8834
        rd = insn & 7;
8835
        rn = (insn >> 3) & 7;
8836
        addr = load_reg(s, rn);
8837
        val = (insn >> 6) & 0x1f;
8838
        tcg_gen_addi_i32(addr, addr, val);
8839

    
8840
        if (insn & (1 << 11)) {
8841
            /* load */
8842
            tmp = gen_ld8u(addr, IS_USER(s));
8843
            store_reg(s, rd, tmp);
8844
        } else {
8845
            /* store */
8846
            tmp = load_reg(s, rd);
8847
            gen_st8(tmp, addr, IS_USER(s));
8848
        }
8849
        tcg_temp_free_i32(addr);
8850
        break;
8851

    
8852
    case 8:
8853
        /* load/store halfword immediate offset */
8854
        rd = insn & 7;
8855
        rn = (insn >> 3) & 7;
8856
        addr = load_reg(s, rn);
8857
        val = (insn >> 5) & 0x3e;
8858
        tcg_gen_addi_i32(addr, addr, val);
8859

    
8860
        if (insn & (1 << 11)) {
8861
            /* load */
8862
            tmp = gen_ld16u(addr, IS_USER(s));
8863
            store_reg(s, rd, tmp);
8864
        } else {
8865
            /* store */
8866
            tmp = load_reg(s, rd);
8867
            gen_st16(tmp, addr, IS_USER(s));
8868
        }
8869
        tcg_temp_free_i32(addr);
8870
        break;
8871

    
8872
    case 9:
8873
        /* load/store from stack */
8874
        rd = (insn >> 8) & 7;
8875
        addr = load_reg(s, 13);
8876
        val = (insn & 0xff) * 4;
8877
        tcg_gen_addi_i32(addr, addr, val);
8878

    
8879
        if (insn & (1 << 11)) {
8880
            /* load */
8881
            tmp = gen_ld32(addr, IS_USER(s));
8882
            store_reg(s, rd, tmp);
8883
        } else {
8884
            /* store */
8885
            tmp = load_reg(s, rd);
8886
            gen_st32(tmp, addr, IS_USER(s));
8887
        }
8888
        tcg_temp_free_i32(addr);
8889
        break;
8890

    
8891
    case 10:
8892
        /* add to high reg */
8893
        rd = (insn >> 8) & 7;
8894
        if (insn & (1 << 11)) {
8895
            /* SP */
8896
            tmp = load_reg(s, 13);
8897
        } else {
8898
            /* PC. bit 1 is ignored.  */
8899
            tmp = tcg_temp_new_i32();
8900
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8901
        }
8902
        val = (insn & 0xff) * 4;
8903
        tcg_gen_addi_i32(tmp, tmp, val);
8904
        store_reg(s, rd, tmp);
8905
        break;
8906

    
8907
    case 11:
8908
        /* misc */
8909
        op = (insn >> 8) & 0xf;
8910
        switch (op) {
8911
        case 0:
8912
            /* adjust stack pointer */
8913
            tmp = load_reg(s, 13);
8914
            val = (insn & 0x7f) * 4;
8915
            if (insn & (1 << 7))
8916
                val = -(int32_t)val;
8917
            tcg_gen_addi_i32(tmp, tmp, val);
8918
            store_reg(s, 13, tmp);
8919
            break;
8920

    
8921
        case 2: /* sign/zero extend.  */
8922
            ARCH(6);
8923
            rd = insn & 7;
8924
            rm = (insn >> 3) & 7;
8925
            tmp = load_reg(s, rm);
8926
            switch ((insn >> 6) & 3) {
8927
            case 0: gen_sxth(tmp); break;
8928
            case 1: gen_sxtb(tmp); break;
8929
            case 2: gen_uxth(tmp); break;
8930
            case 3: gen_uxtb(tmp); break;
8931
            }
8932
            store_reg(s, rd, tmp);
8933
            break;
8934
        case 4: case 5: case 0xc: case 0xd:
8935
            /* push/pop */
8936
            addr = load_reg(s, 13);
8937
            if (insn & (1 << 8))
8938
                offset = 4;
8939
            else
8940
                offset = 0;
8941
            for (i = 0; i < 8; i++) {
8942
                if (insn & (1 << i))
8943
                    offset += 4;
8944
            }
8945
            if ((insn & (1 << 11)) == 0) {
8946
                tcg_gen_addi_i32(addr, addr, -offset);
8947
            }
8948
            for (i = 0; i < 8; i++) {
8949
                if (insn & (1 << i)) {
8950
                    if (insn & (1 << 11)) {
8951
                        /* pop */
8952
                        tmp = gen_ld32(addr, IS_USER(s));
8953
                        store_reg(s, i, tmp);
8954
                    } else {
8955
                        /* push */
8956
                        tmp = load_reg(s, i);
8957
                        gen_st32(tmp, addr, IS_USER(s));
8958
                    }
8959
                    /* advance to the next address.  */
8960
                    tcg_gen_addi_i32(addr, addr, 4);
8961
                }
8962
            }
8963
            TCGV_UNUSED(tmp);
8964
            if (insn & (1 << 8)) {
8965
                if (insn & (1 << 11)) {
8966
                    /* pop pc */
8967
                    tmp = gen_ld32(addr, IS_USER(s));
8968
                    /* don't set the pc until the rest of the instruction
8969
                       has completed */
8970
                } else {
8971
                    /* push lr */
8972
                    tmp = load_reg(s, 14);
8973
                    gen_st32(tmp, addr, IS_USER(s));
8974
                }
8975
                tcg_gen_addi_i32(addr, addr, 4);
8976
            }
8977
            if ((insn & (1 << 11)) == 0) {
8978
                tcg_gen_addi_i32(addr, addr, -offset);
8979
            }
8980
            /* write back the new stack pointer */
8981
            store_reg(s, 13, addr);
8982
            /* set the new PC value */
8983
            if ((insn & 0x0900) == 0x0900)
8984
                gen_bx(s, tmp);
8985
            break;
8986

    
8987
        case 1: case 3: case 9: case 11: /* czb */
8988
            rm = insn & 7;
8989
            tmp = load_reg(s, rm);
8990
            s->condlabel = gen_new_label();
8991
            s->condjmp = 1;
8992
            if (insn & (1 << 11))
8993
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8994
            else
8995
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8996
            tcg_temp_free_i32(tmp);
8997
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8998
            val = (uint32_t)s->pc + 2;
8999
            val += offset;
9000
            gen_jmp(s, val);
9001
            break;
9002

    
9003
        case 15: /* IT, nop-hint.  */
9004
            if ((insn & 0xf) == 0) {
9005
                gen_nop_hint(s, (insn >> 4) & 0xf);
9006
                break;
9007
            }
9008
            /* If Then.  */
9009
            s->condexec_cond = (insn >> 4) & 0xe;
9010
            s->condexec_mask = insn & 0x1f;
9011
            /* No actual code generated for this insn, just setup state.  */
9012
            break;
9013

    
9014
        case 0xe: /* bkpt */
9015
            gen_exception_insn(s, 2, EXCP_BKPT);
9016
            break;
9017

    
9018
        case 0xa: /* rev */
9019
            ARCH(6);
9020
            rn = (insn >> 3) & 0x7;
9021
            rd = insn & 0x7;
9022
            tmp = load_reg(s, rn);
9023
            switch ((insn >> 6) & 3) {
9024
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9025
            case 1: gen_rev16(tmp); break;
9026
            case 3: gen_revsh(tmp); break;
9027
            default: goto illegal_op;
9028
            }
9029
            store_reg(s, rd, tmp);
9030
            break;
9031

    
9032
        case 6: /* cps */
9033
            ARCH(6);
9034
            if (IS_USER(s))
9035
                break;
9036
            if (IS_M(env)) {
9037
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9038
                /* PRIMASK */
9039
                if (insn & 1) {
9040
                    addr = tcg_const_i32(16);
9041
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9042
                    tcg_temp_free_i32(addr);
9043
                }
9044
                /* FAULTMASK */
9045
                if (insn & 2) {
9046
                    addr = tcg_const_i32(17);
9047
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9048
                    tcg_temp_free_i32(addr);
9049
                }
9050
                tcg_temp_free_i32(tmp);
9051
                gen_lookup_tb(s);
9052
            } else {
9053
                if (insn & (1 << 4))
9054
                    shift = CPSR_A | CPSR_I | CPSR_F;
9055
                else
9056
                    shift = 0;
9057
                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9058
            }
9059
            break;
9060

    
9061
        default:
9062
            goto undef;
9063
        }
9064
        break;
9065

    
9066
    case 12:
9067
        /* load/store multiple */
9068
        rn = (insn >> 8) & 0x7;
9069
        addr = load_reg(s, rn);
9070
        for (i = 0; i < 8; i++) {
9071
            if (insn & (1 << i)) {
9072
                if (insn & (1 << 11)) {
9073
                    /* load */
9074
                    tmp = gen_ld32(addr, IS_USER(s));
9075
                    store_reg(s, i, tmp);
9076
                } else {
9077
                    /* store */
9078
                    tmp = load_reg(s, i);
9079
                    gen_st32(tmp, addr, IS_USER(s));
9080
                }
9081
                /* advance to the next address */
9082
                tcg_gen_addi_i32(addr, addr, 4);
9083
            }
9084
        }
9085
        /* Base register writeback.  */
9086
        if ((insn & (1 << rn)) == 0) {
9087
            store_reg(s, rn, addr);
9088
        } else {
9089
            tcg_temp_free_i32(addr);
9090
        }
9091
        break;
9092

    
9093
    case 13:
9094
        /* conditional branch or swi */
9095
        cond = (insn >> 8) & 0xf;
9096
        if (cond == 0xe)
9097
            goto undef;
9098

    
9099
        if (cond == 0xf) {
9100
            /* swi */
9101
            gen_set_pc_im(s->pc);
9102
            s->is_jmp = DISAS_SWI;
9103
            break;
9104
        }
9105
        /* generate a conditional jump to next instruction */
9106
        s->condlabel = gen_new_label();
9107
        gen_test_cc(cond ^ 1, s->condlabel);
9108
        s->condjmp = 1;
9109

    
9110
        /* jump to the offset */
9111
        val = (uint32_t)s->pc + 2;
9112
        offset = ((int32_t)insn << 24) >> 24;
9113
        val += offset << 1;
9114
        gen_jmp(s, val);
9115
        break;
9116

    
9117
    case 14:
9118
        if (insn & (1 << 11)) {
9119
            if (disas_thumb2_insn(env, s, insn))
9120
              goto undef32;
9121
            break;
9122
        }
9123
        /* unconditional branch */
9124
        val = (uint32_t)s->pc;
9125
        offset = ((int32_t)insn << 21) >> 21;
9126
        val += (offset << 1) + 2;
9127
        gen_jmp(s, val);
9128
        break;
9129

    
9130
    case 15:
9131
        if (disas_thumb2_insn(env, s, insn))
9132
            goto undef32;
9133
        break;
9134
    }
9135
    return;
9136
undef32:
9137
    gen_exception_insn(s, 4, EXCP_UDEF);
9138
    return;
9139
illegal_op:
9140
undef:
9141
    gen_exception_insn(s, 2, EXCP_UDEF);
9142
}
9143

    
9144
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9145
   basic block 'tb'. If search_pc is TRUE, also generate PC
9146
   information for each intermediate instruction. */
9147
static inline void gen_intermediate_code_internal(CPUState *env,
9148
                                                  TranslationBlock *tb,
9149
                                                  int search_pc)
9150
{
9151
    DisasContext dc1, *dc = &dc1;
9152
    CPUBreakpoint *bp;
9153
    uint16_t *gen_opc_end;
9154
    int j, lj;
9155
    target_ulong pc_start;
9156
    uint32_t next_page_start;
9157
    int num_insns;
9158
    int max_insns;
9159

    
9160
    /* generate intermediate code */
9161
    pc_start = tb->pc;
9162

    
9163
    dc->tb = tb;
9164

    
9165
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9166

    
9167
    dc->is_jmp = DISAS_NEXT;
9168
    dc->pc = pc_start;
9169
    dc->singlestep_enabled = env->singlestep_enabled;
9170
    dc->condjmp = 0;
9171
    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9172
    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9173
    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9174
#if !defined(CONFIG_USER_ONLY)
9175
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9176
#endif
9177
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9178
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9179
    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9180
    cpu_F0s = tcg_temp_new_i32();
9181
    cpu_F1s = tcg_temp_new_i32();
9182
    cpu_F0d = tcg_temp_new_i64();
9183
    cpu_F1d = tcg_temp_new_i64();
9184
    cpu_V0 = cpu_F0d;
9185
    cpu_V1 = cpu_F1d;
9186
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
9187
    cpu_M0 = tcg_temp_new_i64();
9188
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9189
    lj = -1;
9190
    num_insns = 0;
9191
    max_insns = tb->cflags & CF_COUNT_MASK;
9192
    if (max_insns == 0)
9193
        max_insns = CF_COUNT_MASK;
9194

    
9195
    gen_icount_start();
9196

    
9197
    tcg_clear_temp_count();
9198

    
9199
    /* A note on handling of the condexec (IT) bits:
9200
     *
9201
     * We want to avoid the overhead of having to write the updated condexec
9202
     * bits back to the CPUState for every instruction in an IT block. So:
9203
     * (1) if the condexec bits are not already zero then we write
9204
     * zero back into the CPUState now. This avoids complications trying
9205
     * to do it at the end of the block. (For example if we don't do this
9206
     * it's hard to identify whether we can safely skip writing condexec
9207
     * at the end of the TB, which we definitely want to do for the case
9208
     * where a TB doesn't do anything with the IT state at all.)
9209
     * (2) if we are going to leave the TB then we call gen_set_condexec()
9210
     * which will write the correct value into CPUState if zero is wrong.
9211
     * This is done both for leaving the TB at the end, and for leaving
9212
     * it because of an exception we know will happen, which is done in
9213
     * gen_exception_insn(). The latter is necessary because we need to
9214
     * leave the TB with the PC/IT state just prior to execution of the
9215
     * instruction which caused the exception.
9216
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9217
     * then the CPUState will be wrong and we need to reset it.
9218
     * This is handled in the same way as restoration of the
9219
     * PC in these situations: we will be called again with search_pc=1
9220
     * and generate a mapping of the condexec bits for each PC in
9221
     * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
9222
     * the condexec bits.
9223
     *
9224
     * Note that there are no instructions which can read the condexec
9225
     * bits, and none which can write non-static values to them, so
9226
     * we don't need to care about whether CPUState is correct in the
9227
     * middle of a TB.
9228
     */
9229

    
9230
    /* Reset the conditional execution bits immediately. This avoids
9231
       complications trying to do it at the end of the block.  */
9232
    if (dc->condexec_mask || dc->condexec_cond)
9233
      {
9234
        TCGv tmp = tcg_temp_new_i32();
9235
        tcg_gen_movi_i32(tmp, 0);
9236
        store_cpu_field(tmp, condexec_bits);
9237
      }
9238
    do {
9239
#ifdef CONFIG_USER_ONLY
9240
        /* Intercept jump to the magic kernel page.  */
9241
        if (dc->pc >= 0xffff0000) {
9242
            /* We always get here via a jump, so know we are not in a
9243
               conditional execution block.  */
9244
            gen_exception(EXCP_KERNEL_TRAP);
9245
            dc->is_jmp = DISAS_UPDATE;
9246
            break;
9247
        }
9248
#else
9249
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9250
            /* We always get here via a jump, so know we are not in a
9251
               conditional execution block.  */
9252
            gen_exception(EXCP_EXCEPTION_EXIT);
9253
            dc->is_jmp = DISAS_UPDATE;
9254
            break;
9255
        }
9256
#endif
9257

    
9258
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9259
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9260
                if (bp->pc == dc->pc) {
9261
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
9262
                    /* Advance PC so that clearing the breakpoint will
9263
                       invalidate this TB.  */
9264
                    dc->pc += 2;
9265
                    goto done_generating;
9266
                    break;
9267
                }
9268
            }
9269
        }
9270
        if (search_pc) {
9271
            j = gen_opc_ptr - gen_opc_buf;
9272
            if (lj < j) {
9273
                lj++;
9274
                while (lj < j)
9275
                    gen_opc_instr_start[lj++] = 0;
9276
            }
9277
            gen_opc_pc[lj] = dc->pc;
9278
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9279
            gen_opc_instr_start[lj] = 1;
9280
            gen_opc_icount[lj] = num_insns;
9281
        }
9282

    
9283
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9284
            gen_io_start();
9285

    
9286
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
9287
            tcg_gen_debug_insn_start(dc->pc);
9288
        }
9289

    
9290
        if (dc->thumb) {
9291
            disas_thumb_insn(env, dc);
9292
            if (dc->condexec_mask) {
9293
                dc->condexec_cond = (dc->condexec_cond & 0xe)
9294
                                   | ((dc->condexec_mask >> 4) & 1);
9295
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9296
                if (dc->condexec_mask == 0) {
9297
                    dc->condexec_cond = 0;
9298
                }
9299
            }
9300
        } else {
9301
            disas_arm_insn(env, dc);
9302
        }
9303

    
9304
        if (dc->condjmp && !dc->is_jmp) {
9305
            gen_set_label(dc->condlabel);
9306
            dc->condjmp = 0;
9307
        }
9308

    
9309
        if (tcg_check_temp_count()) {
9310
            fprintf(stderr, "TCG temporary leak before %08x\n", dc->pc);
9311
        }
9312

    
9313
        /* Translation stops when a conditional branch is encountered.
9314
         * Otherwise the subsequent code could get translated several times.
9315
         * Also stop translation when a page boundary is reached.  This
9316
         * ensures prefetch aborts occur at the right place.  */
9317
        num_insns ++;
9318
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9319
             !env->singlestep_enabled &&
9320
             !singlestep &&
9321
             dc->pc < next_page_start &&
9322
             num_insns < max_insns);
9323

    
9324
    if (tb->cflags & CF_LAST_IO) {
9325
        if (dc->condjmp) {
9326
            /* FIXME:  This can theoretically happen with self-modifying
9327
               code.  */
9328
            cpu_abort(env, "IO on conditional branch instruction");
9329
        }
9330
        gen_io_end();
9331
    }
9332

    
9333
    /* At this stage dc->condjmp will only be set when the skipped
9334
       instruction was a conditional branch or trap, and the PC has
9335
       already been written.  */
9336
    if (unlikely(env->singlestep_enabled)) {
9337
        /* Make sure the pc is updated, and raise a debug exception.  */
9338
        if (dc->condjmp) {
9339
            gen_set_condexec(dc);
9340
            if (dc->is_jmp == DISAS_SWI) {
9341
                gen_exception(EXCP_SWI);
9342
            } else {
9343
                gen_exception(EXCP_DEBUG);
9344
            }
9345
            gen_set_label(dc->condlabel);
9346
        }
9347
        if (dc->condjmp || !dc->is_jmp) {
9348
            gen_set_pc_im(dc->pc);
9349
            dc->condjmp = 0;
9350
        }
9351
        gen_set_condexec(dc);
9352
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9353
            gen_exception(EXCP_SWI);
9354
        } else {
9355
            /* FIXME: Single stepping a WFI insn will not halt
9356
               the CPU.  */
9357
            gen_exception(EXCP_DEBUG);
9358
        }
9359
    } else {
9360
        /* While branches must always occur at the end of an IT block,
9361
           there are a few other things that can cause us to terminate
9362
           the TB in the middel of an IT block:
9363
            - Exception generating instructions (bkpt, swi, undefined).
9364
            - Page boundaries.
9365
            - Hardware watchpoints.
9366
           Hardware breakpoints have already been handled and skip this code.
9367
         */
9368
        gen_set_condexec(dc);
9369
        switch(dc->is_jmp) {
9370
        case DISAS_NEXT:
9371
            gen_goto_tb(dc, 1, dc->pc);
9372
            break;
9373
        default:
9374
        case DISAS_JUMP:
9375
        case DISAS_UPDATE:
9376
            /* indicate that the hash table must be used to find the next TB */
9377
            tcg_gen_exit_tb(0);
9378
            break;
9379
        case DISAS_TB_JUMP:
9380
            /* nothing more to generate */
9381
            break;
9382
        case DISAS_WFI:
9383
            gen_helper_wfi();
9384
            break;
9385
        case DISAS_SWI:
9386
            gen_exception(EXCP_SWI);
9387
            break;
9388
        }
9389
        if (dc->condjmp) {
9390
            gen_set_label(dc->condlabel);
9391
            gen_set_condexec(dc);
9392
            gen_goto_tb(dc, 1, dc->pc);
9393
            dc->condjmp = 0;
9394
        }
9395
    }
9396

    
9397
done_generating:
9398
    gen_icount_end(tb, num_insns);
9399
    *gen_opc_ptr = INDEX_op_end;
9400

    
9401
#ifdef DEBUG_DISAS
9402
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9403
        qemu_log("----------------\n");
9404
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9405
        log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);
9406
        qemu_log("\n");
9407
    }
9408
#endif
9409
    if (search_pc) {
9410
        j = gen_opc_ptr - gen_opc_buf;
9411
        lj++;
9412
        while (lj <= j)
9413
            gen_opc_instr_start[lj++] = 0;
9414
    } else {
9415
        tb->size = dc->pc - pc_start;
9416
        tb->icount = num_insns;
9417
    }
9418
}
9419

    
9420
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9421
{
9422
    gen_intermediate_code_internal(env, tb, 0);
9423
}
9424

    
9425
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9426
{
9427
    gen_intermediate_code_internal(env, tb, 1);
9428
}
9429

    
9430
static const char *cpu_mode_names[16] = {
9431
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9432
  "???", "???", "???", "und", "???", "???", "???", "sys"
9433
};
9434

    
9435
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
9436
                    int flags)
9437
{
9438
    int i;
9439
#if 0
9440
    union {
9441
        uint32_t i;
9442
        float s;
9443
    } s0, s1;
9444
    CPU_DoubleU d;
9445
    /* ??? This assumes float64 and double have the same layout.
9446
       Oh well, it's only debug dumps.  */
9447
    union {
9448
        float64 f64;
9449
        double d;
9450
    } d0;
9451
#endif
9452
    uint32_t psr;
9453

    
9454
    for(i=0;i<16;i++) {
9455
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9456
        if ((i % 4) == 3)
9457
            cpu_fprintf(f, "\n");
9458
        else
9459
            cpu_fprintf(f, " ");
9460
    }
9461
    psr = cpsr_read(env);
9462
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9463
                psr,
9464
                psr & (1 << 31) ? 'N' : '-',
9465
                psr & (1 << 30) ? 'Z' : '-',
9466
                psr & (1 << 29) ? 'C' : '-',
9467
                psr & (1 << 28) ? 'V' : '-',
9468
                psr & CPSR_T ? 'T' : 'A',
9469
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9470

    
9471
#if 0
9472
    for (i = 0; i < 16; i++) {
9473
        d.d = env->vfp.regs[i];
9474
        s0.i = d.l.lower;
9475
        s1.i = d.l.upper;
9476
        d0.f64 = d.d;
9477
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9478
                    i * 2, (int)s0.i, s0.s,
9479
                    i * 2 + 1, (int)s1.i, s1.s,
9480
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9481
                    d0.d);
9482
    }
9483
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9484
#endif
9485
}
9486

    
9487
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9488
                unsigned long searched_pc, int pc_pos, void *puc)
9489
{
9490
    env->regs[15] = gen_opc_pc[pc_pos];
9491
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
9492
}