Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 4b4a72e5

History | View | Annotate | Download (323 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_SIZE(name) \
1163
IWMMXT_OP(name##b) \
1164
IWMMXT_OP(name##w) \
1165
IWMMXT_OP(name##l)
1166

    
1167
#define IWMMXT_OP_1(name) \
1168
static inline void gen_op_iwmmxt_##name##_M0(void) \
1169
{ \
1170
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0); \
1171
}
1172

    
1173
IWMMXT_OP(maddsq)
1174
IWMMXT_OP(madduq)
1175
IWMMXT_OP(sadb)
1176
IWMMXT_OP(sadw)
1177
IWMMXT_OP(mulslw)
1178
IWMMXT_OP(mulshw)
1179
IWMMXT_OP(mululw)
1180
IWMMXT_OP(muluhw)
1181
IWMMXT_OP(macsw)
1182
IWMMXT_OP(macuw)
1183

    
1184
IWMMXT_OP_SIZE(unpackl)
1185
IWMMXT_OP_SIZE(unpackh)
1186

    
1187
IWMMXT_OP_1(unpacklub)
1188
IWMMXT_OP_1(unpackluw)
1189
IWMMXT_OP_1(unpacklul)
1190
IWMMXT_OP_1(unpackhub)
1191
IWMMXT_OP_1(unpackhuw)
1192
IWMMXT_OP_1(unpackhul)
1193
IWMMXT_OP_1(unpacklsb)
1194
IWMMXT_OP_1(unpacklsw)
1195
IWMMXT_OP_1(unpacklsl)
1196
IWMMXT_OP_1(unpackhsb)
1197
IWMMXT_OP_1(unpackhsw)
1198
IWMMXT_OP_1(unpackhsl)
1199

    
1200
IWMMXT_OP_SIZE(cmpeq)
1201
IWMMXT_OP_SIZE(cmpgtu)
1202
IWMMXT_OP_SIZE(cmpgts)
1203

    
1204
IWMMXT_OP_SIZE(mins)
1205
IWMMXT_OP_SIZE(minu)
1206
IWMMXT_OP_SIZE(maxs)
1207
IWMMXT_OP_SIZE(maxu)
1208

    
1209
IWMMXT_OP_SIZE(subn)
1210
IWMMXT_OP_SIZE(addn)
1211
IWMMXT_OP_SIZE(subu)
1212
IWMMXT_OP_SIZE(addu)
1213
IWMMXT_OP_SIZE(subs)
1214
IWMMXT_OP_SIZE(adds)
1215

    
1216
IWMMXT_OP(avgb0)
1217
IWMMXT_OP(avgb1)
1218
IWMMXT_OP(avgw0)
1219
IWMMXT_OP(avgw1)
1220

    
1221
IWMMXT_OP(msadb)
1222

    
1223
IWMMXT_OP(packuw)
1224
IWMMXT_OP(packul)
1225
IWMMXT_OP(packuq)
1226
IWMMXT_OP(packsw)
1227
IWMMXT_OP(packsl)
1228
IWMMXT_OP(packsq)
1229

    
1230
static void gen_op_iwmmxt_set_mup(void)
1231
{
1232
    TCGv tmp;
1233
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1234
    tcg_gen_ori_i32(tmp, tmp, 2);
1235
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1236
}
1237

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

    
1246
static void gen_op_iwmmxt_setpsr_nz(void)
1247
{
1248
    TCGv tmp = tcg_temp_new_i32();
1249
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1250
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1251
}
1252

    
1253
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1254
{
1255
    iwmmxt_load_reg(cpu_V1, rn);
1256
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1257
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1258
}
1259

    
1260
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1261
{
1262
    int rd;
1263
    uint32_t offset;
1264
    TCGv tmp;
1265

    
1266
    rd = (insn >> 16) & 0xf;
1267
    tmp = load_reg(s, rd);
1268

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

    
1294
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1295
{
1296
    int rd = (insn >> 0) & 0xf;
1297
    TCGv tmp;
1298

    
1299
    if (insn & (1 << 8)) {
1300
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1301
            return 1;
1302
        } else {
1303
            tmp = iwmmxt_load_creg(rd);
1304
        }
1305
    } else {
1306
        tmp = tcg_temp_new_i32();
1307
        iwmmxt_load_reg(cpu_V0, rd);
1308
        tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1309
    }
1310
    tcg_gen_andi_i32(tmp, tmp, mask);
1311
    tcg_gen_mov_i32(dest, tmp);
1312
    tcg_temp_free_i32(tmp);
1313
    return 0;
1314
}
1315

    
1316
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1317
   (ie. an undefined instruction).  */
1318
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1319
{
1320
    int rd, wrd;
1321
    int rdhi, rdlo, rd0, rd1, i;
1322
    TCGv addr;
1323
    TCGv tmp, tmp2, tmp3;
1324

    
1325
    if ((insn & 0x0e000e00) == 0x0c000000) {
1326
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1327
            wrd = insn & 0xf;
1328
            rdlo = (insn >> 12) & 0xf;
1329
            rdhi = (insn >> 16) & 0xf;
1330
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1331
                iwmmxt_load_reg(cpu_V0, wrd);
1332
                tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1333
                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1334
                tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1335
            } else {                                        /* TMCRR */
1336
                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1337
                iwmmxt_store_reg(cpu_V0, wrd);
1338
                gen_op_iwmmxt_set_mup();
1339
            }
1340
            return 0;
1341
        }
1342

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

    
1406
    if ((insn & 0x0f000000) != 0x0e000000)
1407
        return 1;
1408

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

    
2317
    return 0;
2318
}
2319

    
2320
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2321
   (ie. an undefined instruction).  */
2322
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2323
{
2324
    int acc, rd0, rd1, rdhi, rdlo;
2325
    TCGv tmp, tmp2;
2326

    
2327
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2328
        /* Multiply with Internal Accumulate Format */
2329
        rd0 = (insn >> 12) & 0xf;
2330
        rd1 = insn & 0xf;
2331
        acc = (insn >> 5) & 7;
2332

    
2333
        if (acc != 0)
2334
            return 1;
2335

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

    
2361
        gen_op_iwmmxt_movq_wRn_M0(acc);
2362
        return 0;
2363
    }
2364

    
2365
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2366
        /* Internal Accumulator Access Format */
2367
        rdhi = (insn >> 16) & 0xf;
2368
        rdlo = (insn >> 12) & 0xf;
2369
        acc = insn & 7;
2370

    
2371
        if (acc != 0)
2372
            return 1;
2373

    
2374
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2375
            iwmmxt_load_reg(cpu_V0, acc);
2376
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2377
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2378
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2379
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2380
        } else {                                        /* MAR */
2381
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2382
            iwmmxt_store_reg(cpu_V0, acc);
2383
        }
2384
        return 0;
2385
    }
2386

    
2387
    return 1;
2388
}
2389

    
2390
/* Disassemble system coprocessor instruction.  Return nonzero if
2391
   instruction is not defined.  */
2392
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2393
{
2394
    TCGv tmp, tmp2;
2395
    uint32_t rd = (insn >> 12) & 0xf;
2396
    uint32_t cp = (insn >> 8) & 0xf;
2397
    if (IS_USER(s)) {
2398
        return 1;
2399
    }
2400

    
2401
    if (insn & ARM_CP_RW_BIT) {
2402
        if (!env->cp[cp].cp_read)
2403
            return 1;
2404
        gen_set_pc_im(s->pc);
2405
        tmp = tcg_temp_new_i32();
2406
        tmp2 = tcg_const_i32(insn);
2407
        gen_helper_get_cp(tmp, cpu_env, tmp2);
2408
        tcg_temp_free(tmp2);
2409
        store_reg(s, rd, tmp);
2410
    } else {
2411
        if (!env->cp[cp].cp_write)
2412
            return 1;
2413
        gen_set_pc_im(s->pc);
2414
        tmp = load_reg(s, rd);
2415
        tmp2 = tcg_const_i32(insn);
2416
        gen_helper_set_cp(cpu_env, tmp2, tmp);
2417
        tcg_temp_free(tmp2);
2418
        tcg_temp_free_i32(tmp);
2419
    }
2420
    return 0;
2421
}
2422

    
2423
static int cp15_user_ok(uint32_t insn)
2424
{
2425
    int cpn = (insn >> 16) & 0xf;
2426
    int cpm = insn & 0xf;
2427
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2428

    
2429
    if (cpn == 13 && cpm == 0) {
2430
        /* TLS register.  */
2431
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2432
            return 1;
2433
    }
2434
    if (cpn == 7) {
2435
        /* ISB, DSB, DMB.  */
2436
        if ((cpm == 5 && op == 4)
2437
                || (cpm == 10 && (op == 4 || op == 5)))
2438
            return 1;
2439
    }
2440
    return 0;
2441
}
2442

    
2443
static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, uint32_t rd)
2444
{
2445
    TCGv tmp;
2446
    int cpn = (insn >> 16) & 0xf;
2447
    int cpm = insn & 0xf;
2448
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2449

    
2450
    if (!arm_feature(env, ARM_FEATURE_V6K))
2451
        return 0;
2452

    
2453
    if (!(cpn == 13 && cpm == 0))
2454
        return 0;
2455

    
2456
    if (insn & ARM_CP_RW_BIT) {
2457
        switch (op) {
2458
        case 2:
2459
            tmp = load_cpu_field(cp15.c13_tls1);
2460
            break;
2461
        case 3:
2462
            tmp = load_cpu_field(cp15.c13_tls2);
2463
            break;
2464
        case 4:
2465
            tmp = load_cpu_field(cp15.c13_tls3);
2466
            break;
2467
        default:
2468
            return 0;
2469
        }
2470
        store_reg(s, rd, tmp);
2471

    
2472
    } else {
2473
        tmp = load_reg(s, rd);
2474
        switch (op) {
2475
        case 2:
2476
            store_cpu_field(tmp, cp15.c13_tls1);
2477
            break;
2478
        case 3:
2479
            store_cpu_field(tmp, cp15.c13_tls2);
2480
            break;
2481
        case 4:
2482
            store_cpu_field(tmp, cp15.c13_tls3);
2483
            break;
2484
        default:
2485
            tcg_temp_free_i32(tmp);
2486
            return 0;
2487
        }
2488
    }
2489
    return 1;
2490
}
2491

    
2492
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2493
   instruction is not defined.  */
2494
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2495
{
2496
    uint32_t rd;
2497
    TCGv tmp, tmp2;
2498

    
2499
    /* M profile cores use memory mapped registers instead of cp15.  */
2500
    if (arm_feature(env, ARM_FEATURE_M))
2501
        return 1;
2502

    
2503
    if ((insn & (1 << 25)) == 0) {
2504
        if (insn & (1 << 20)) {
2505
            /* mrrc */
2506
            return 1;
2507
        }
2508
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2509
        return 0;
2510
    }
2511
    if ((insn & (1 << 4)) == 0) {
2512
        /* cdp */
2513
        return 1;
2514
    }
2515
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2516
        return 1;
2517
    }
2518

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

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

    
2550
    rd = (insn >> 12) & 0xf;
2551

    
2552
    if (cp15_tls_load_store(env, s, insn, rd))
2553
        return 0;
2554

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

    
2579
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2580
#define VFP_SREG(insn, bigbit, smallbit) \
2581
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2582
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2583
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2584
        reg = (((insn) >> (bigbit)) & 0x0f) \
2585
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2586
    } else { \
2587
        if (insn & (1 << (smallbit))) \
2588
            return 1; \
2589
        reg = ((insn) >> (bigbit)) & 0x0f; \
2590
    }} while (0)
2591

    
2592
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2593
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2594
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2595
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2596
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2597
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2598

    
2599
/* Move between integer and VFP cores.  */
2600
static TCGv gen_vfp_mrs(void)
2601
{
2602
    TCGv tmp = tcg_temp_new_i32();
2603
    tcg_gen_mov_i32(tmp, cpu_F0s);
2604
    return tmp;
2605
}
2606

    
2607
static void gen_vfp_msr(TCGv tmp)
2608
{
2609
    tcg_gen_mov_i32(cpu_F0s, tmp);
2610
    tcg_temp_free_i32(tmp);
2611
}
2612

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

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

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

    
2644
static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size)
2645
{
2646
    /* Load a single Neon element and replicate into a 32 bit TCG reg */
2647
    TCGv tmp;
2648
    switch (size) {
2649
    case 0:
2650
        tmp = gen_ld8u(addr, IS_USER(s));
2651
        gen_neon_dup_u8(tmp, 0);
2652
        break;
2653
    case 1:
2654
        tmp = gen_ld16u(addr, IS_USER(s));
2655
        gen_neon_dup_low16(tmp);
2656
        break;
2657
    case 2:
2658
        tmp = gen_ld32(addr, IS_USER(s));
2659
        break;
2660
    default: /* Avoid compiler warnings.  */
2661
        abort();
2662
    }
2663
    return tmp;
2664
}
2665

    
2666
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2667
   (ie. an undefined instruction).  */
2668
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2669
{
2670
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2671
    int dp, veclen;
2672
    TCGv addr;
2673
    TCGv tmp;
2674
    TCGv tmp2;
2675

    
2676
    if (!arm_feature(env, ARM_FEATURE_VFP))
2677
        return 1;
2678

    
2679
    if (!s->vfp_enabled) {
2680
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2681
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2682
            return 1;
2683
        rn = (insn >> 16) & 0xf;
2684
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2685
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2686
            return 1;
2687
    }
2688
    dp = ((insn & 0xf00) == 0xb00);
2689
    switch ((insn >> 24) & 0xf) {
2690
    case 0xe:
2691
        if (insn & (1 << 4)) {
2692
            /* single register transfer */
2693
            rd = (insn >> 12) & 0xf;
2694
            if (dp) {
2695
                int size;
2696
                int pass;
2697

    
2698
                VFP_DREG_N(rn, insn);
2699
                if (insn & 0xf)
2700
                    return 1;
2701
                if (insn & 0x00c00060
2702
                    && !arm_feature(env, ARM_FEATURE_NEON))
2703
                    return 1;
2704

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

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

    
2897
                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2898
                    /* Integer or single precision destination.  */
2899
                    rd = VFP_SREG_D(insn);
2900
                } else {
2901
                    VFP_DREG_D(rd, insn);
2902
                }
2903
                if (op == 15 &&
2904
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2905
                    /* VCVT from int is always from S reg regardless of dp bit.
2906
                     * VCVT with immediate frac_bits has same format as SREG_M
2907
                     */
2908
                    rm = VFP_SREG_M(insn);
2909
                } else {
2910
                    VFP_DREG_M(rm, insn);
2911
                }
2912
            } else {
2913
                rn = VFP_SREG_N(insn);
2914
                if (op == 15 && rn == 15) {
2915
                    /* Double precision destination.  */
2916
                    VFP_DREG_D(rd, insn);
2917
                } else {
2918
                    rd = VFP_SREG_D(insn);
2919
                }
2920
                /* NB that we implicitly rely on the encoding for the frac_bits
2921
                 * in VCVT of fixed to float being the same as that of an SREG_M
2922
                 */
2923
                rm = VFP_SREG_M(insn);
2924
            }
2925

    
2926
            veclen = s->vec_len;
2927
            if (op == 15 && rn > 3)
2928
                veclen = 0;
2929

    
2930
            /* Shut up compiler warnings.  */
2931
            delta_m = 0;
2932
            delta_d = 0;
2933
            bank_mask = 0;
2934

    
2935
            if (veclen > 0) {
2936
                if (dp)
2937
                    bank_mask = 0xc;
2938
                else
2939
                    bank_mask = 0x18;
2940

    
2941
                /* Figure out what type of vector operation this is.  */
2942
                if ((rd & bank_mask) == 0) {
2943
                    /* scalar */
2944
                    veclen = 0;
2945
                } else {
2946
                    if (dp)
2947
                        delta_d = (s->vec_stride >> 1) + 1;
2948
                    else
2949
                        delta_d = s->vec_stride + 1;
2950

    
2951
                    if ((rm & bank_mask) == 0) {
2952
                        /* mixed scalar/vector */
2953
                        delta_m = 0;
2954
                    } else {
2955
                        /* vector */
2956
                        delta_m = delta_d;
2957
                    }
2958
                }
2959
            }
2960

    
2961
            /* Load the initial operands.  */
2962
            if (op == 15) {
2963
                switch (rn) {
2964
                case 16:
2965
                case 17:
2966
                    /* Integer source */
2967
                    gen_mov_F0_vreg(0, rm);
2968
                    break;
2969
                case 8:
2970
                case 9:
2971
                    /* Compare */
2972
                    gen_mov_F0_vreg(dp, rd);
2973
                    gen_mov_F1_vreg(dp, rm);
2974
                    break;
2975
                case 10:
2976
                case 11:
2977
                    /* Compare with zero */
2978
                    gen_mov_F0_vreg(dp, rd);
2979
                    gen_vfp_F1_ld0(dp);
2980
                    break;
2981
                case 20:
2982
                case 21:
2983
                case 22:
2984
                case 23:
2985
                case 28:
2986
                case 29:
2987
                case 30:
2988
                case 31:
2989
                    /* Source and destination the same.  */
2990
                    gen_mov_F0_vreg(dp, rd);
2991
                    break;
2992
                default:
2993
                    /* One source operand.  */
2994
                    gen_mov_F0_vreg(dp, rm);
2995
                    break;
2996
                }
2997
            } else {
2998
                /* Two source operands.  */
2999
                gen_mov_F0_vreg(dp, rn);
3000
                gen_mov_F1_vreg(dp, rm);
3001
            }
3002

    
3003
            for (;;) {
3004
                /* Perform the calculation.  */
3005
                switch (op) {
3006
                case 0: /* mac: fd + (fn * fm) */
3007
                    gen_vfp_mul(dp);
3008
                    gen_mov_F1_vreg(dp, rd);
3009
                    gen_vfp_add(dp);
3010
                    break;
3011
                case 1: /* nmac: fd - (fn * fm) */
3012
                    gen_vfp_mul(dp);
3013
                    gen_vfp_neg(dp);
3014
                    gen_mov_F1_vreg(dp, rd);
3015
                    gen_vfp_add(dp);
3016
                    break;
3017
                case 2: /* msc: -fd + (fn * fm) */
3018
                    gen_vfp_mul(dp);
3019
                    gen_mov_F1_vreg(dp, rd);
3020
                    gen_vfp_sub(dp);
3021
                    break;
3022
                case 3: /* nmsc: -fd - (fn * fm)  */
3023
                    gen_vfp_mul(dp);
3024
                    gen_vfp_neg(dp);
3025
                    gen_mov_F1_vreg(dp, rd);
3026
                    gen_vfp_sub(dp);
3027
                    break;
3028
                case 4: /* mul: fn * fm */
3029
                    gen_vfp_mul(dp);
3030
                    break;
3031
                case 5: /* nmul: -(fn * fm) */
3032
                    gen_vfp_mul(dp);
3033
                    gen_vfp_neg(dp);
3034
                    break;
3035
                case 6: /* add: fn + fm */
3036
                    gen_vfp_add(dp);
3037
                    break;
3038
                case 7: /* sub: fn - fm */
3039
                    gen_vfp_sub(dp);
3040
                    break;
3041
                case 8: /* div: fn / fm */
3042
                    gen_vfp_div(dp);
3043
                    break;
3044
                case 14: /* fconst */
3045
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3046
                      return 1;
3047

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

    
3208
                /* Write back the result.  */
3209
                if (op == 15 && (rn >= 8 && rn <= 11))
3210
                    ; /* Comparison, do nothing.  */
3211
                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3212
                    /* VCVT double to int: always integer result. */
3213
                    gen_mov_vreg_F0(0, rd);
3214
                else if (op == 15 && rn == 15)
3215
                    /* conversion */
3216
                    gen_mov_vreg_F0(!dp, rd);
3217
                else
3218
                    gen_mov_vreg_F0(dp, rd);
3219

    
3220
                /* break out of the loop if we have finished  */
3221
                if (veclen == 0)
3222
                    break;
3223

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

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

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

    
3338
                if (insn & (1 << 24)) /* pre-decrement */
3339
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3340

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

    
3366
                    if (offset != 0)
3367
                        tcg_gen_addi_i32(addr, addr, offset);
3368
                    store_reg(s, rn, addr);
3369
                } else {
3370
                    tcg_temp_free_i32(addr);
3371
                }
3372
            }
3373
        }
3374
        break;
3375
    default:
3376
        /* Should never happen.  */
3377
        return 1;
3378
    }
3379
    return 0;
3380
}
3381

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

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

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

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

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

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

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

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

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

    
3474
/* Returns nonzero if access to the PSR is not permitted.  */
3475
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3476
{
3477
    TCGv tmp;
3478
    tmp = tcg_temp_new_i32();
3479
    tcg_gen_movi_i32(tmp, val);
3480
    return gen_set_psr(s, mask, spsr, tmp);
3481
}
3482

    
3483
/* Generate an old-style exception return. Marks pc as dead. */
3484
static void gen_exception_return(DisasContext *s, TCGv pc)
3485
{
3486
    TCGv tmp;
3487
    store_reg(s, 15, pc);
3488
    tmp = load_cpu_field(spsr);
3489
    gen_set_cpsr(tmp, 0xffffffff);
3490
    tcg_temp_free_i32(tmp);
3491
    s->is_jmp = DISAS_UPDATE;
3492
}
3493

    
3494
/* Generate a v6 exception return.  Marks both values as dead.  */
3495
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3496
{
3497
    gen_set_cpsr(cpsr, 0xffffffff);
3498
    tcg_temp_free_i32(cpsr);
3499
    store_reg(s, 15, pc);
3500
    s->is_jmp = DISAS_UPDATE;
3501
}
3502

    
3503
static inline void
3504
gen_set_condexec (DisasContext *s)
3505
{
3506
    if (s->condexec_mask) {
3507
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3508
        TCGv tmp = tcg_temp_new_i32();
3509
        tcg_gen_movi_i32(tmp, val);
3510
        store_cpu_field(tmp, condexec_bits);
3511
    }
3512
}
3513

    
3514
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3515
{
3516
    gen_set_condexec(s);
3517
    gen_set_pc_im(s->pc - offset);
3518
    gen_exception(excp);
3519
    s->is_jmp = DISAS_JUMP;
3520
}
3521

    
3522
static void gen_nop_hint(DisasContext *s, int val)
3523
{
3524
    switch (val) {
3525
    case 3: /* wfi */
3526
        gen_set_pc_im(s->pc);
3527
        s->is_jmp = DISAS_WFI;
3528
        break;
3529
    case 2: /* wfe */
3530
    case 4: /* sev */
3531
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3532
    default: /* nop */
3533
        break;
3534
    }
3535
}
3536

    
3537
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3538

    
3539
static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
3540
{
3541
    switch (size) {
3542
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3543
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3544
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3545
    default: return 1;
3546
    }
3547
    return 0;
3548
}
3549

    
3550
static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3551
{
3552
    switch (size) {
3553
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3554
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3555
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3556
    default: return;
3557
    }
3558
}
3559

    
3560
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3561
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3562
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3563
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3564
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3565

    
3566
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3567
    switch ((size << 1) | u) { \
3568
    case 0: \
3569
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3570
        break; \
3571
    case 1: \
3572
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3573
        break; \
3574
    case 2: \
3575
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3576
        break; \
3577
    case 3: \
3578
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3579
        break; \
3580
    case 4: \
3581
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3582
        break; \
3583
    case 5: \
3584
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3585
        break; \
3586
    default: return 1; \
3587
    }} while (0)
3588

    
3589
#define GEN_NEON_INTEGER_OP(name) do { \
3590
    switch ((size << 1) | u) { \
3591
    case 0: \
3592
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3593
        break; \
3594
    case 1: \
3595
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3596
        break; \
3597
    case 2: \
3598
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3599
        break; \
3600
    case 3: \
3601
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3602
        break; \
3603
    case 4: \
3604
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3605
        break; \
3606
    case 5: \
3607
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3608
        break; \
3609
    default: return 1; \
3610
    }} while (0)
3611

    
3612
static TCGv neon_load_scratch(int scratch)
3613
{
3614
    TCGv tmp = tcg_temp_new_i32();
3615
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3616
    return tmp;
3617
}
3618

    
3619
static void neon_store_scratch(int scratch, TCGv var)
3620
{
3621
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3622
    tcg_temp_free_i32(var);
3623
}
3624

    
3625
static inline TCGv neon_get_scalar(int size, int reg)
3626
{
3627
    TCGv tmp;
3628
    if (size == 1) {
3629
        tmp = neon_load_reg(reg & 7, reg >> 4);
3630
        if (reg & 8) {
3631
            gen_neon_dup_high16(tmp);
3632
        } else {
3633
            gen_neon_dup_low16(tmp);
3634
        }
3635
    } else {
3636
        tmp = neon_load_reg(reg & 15, reg >> 4);
3637
    }
3638
    return tmp;
3639
}
3640

    
3641
static int gen_neon_unzip(int rd, int rm, int size, int q)
3642
{
3643
    TCGv tmp, tmp2;
3644
    if (size == 3 || (!q && size == 2)) {
3645
        return 1;
3646
    }
3647
    tmp = tcg_const_i32(rd);
3648
    tmp2 = tcg_const_i32(rm);
3649
    if (q) {
3650
        switch (size) {
3651
        case 0:
3652
            gen_helper_neon_qunzip8(tmp, tmp2);
3653
            break;
3654
        case 1:
3655
            gen_helper_neon_qunzip16(tmp, tmp2);
3656
            break;
3657
        case 2:
3658
            gen_helper_neon_qunzip32(tmp, tmp2);
3659
            break;
3660
        default:
3661
            abort();
3662
        }
3663
    } else {
3664
        switch (size) {
3665
        case 0:
3666
            gen_helper_neon_unzip8(tmp, tmp2);
3667
            break;
3668
        case 1:
3669
            gen_helper_neon_unzip16(tmp, tmp2);
3670
            break;
3671
        default:
3672
            abort();
3673
        }
3674
    }
3675
    tcg_temp_free_i32(tmp);
3676
    tcg_temp_free_i32(tmp2);
3677
    return 0;
3678
}
3679

    
3680
static int gen_neon_zip(int rd, int rm, int size, int q)
3681
{
3682
    TCGv tmp, tmp2;
3683
    if (size == 3 || (!q && size == 2)) {
3684
        return 1;
3685
    }
3686
    tmp = tcg_const_i32(rd);
3687
    tmp2 = tcg_const_i32(rm);
3688
    if (q) {
3689
        switch (size) {
3690
        case 0:
3691
            gen_helper_neon_qzip8(tmp, tmp2);
3692
            break;
3693
        case 1:
3694
            gen_helper_neon_qzip16(tmp, tmp2);
3695
            break;
3696
        case 2:
3697
            gen_helper_neon_qzip32(tmp, tmp2);
3698
            break;
3699
        default:
3700
            abort();
3701
        }
3702
    } else {
3703
        switch (size) {
3704
        case 0:
3705
            gen_helper_neon_zip8(tmp, tmp2);
3706
            break;
3707
        case 1:
3708
            gen_helper_neon_zip16(tmp, tmp2);
3709
            break;
3710
        default:
3711
            abort();
3712
        }
3713
    }
3714
    tcg_temp_free_i32(tmp);
3715
    tcg_temp_free_i32(tmp2);
3716
    return 0;
3717
}
3718

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

    
3723
    rd = tcg_temp_new_i32();
3724
    tmp = tcg_temp_new_i32();
3725

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

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

    
3737
    tcg_temp_free_i32(tmp);
3738
    tcg_temp_free_i32(rd);
3739
}
3740

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

    
3745
    rd = tcg_temp_new_i32();
3746
    tmp = tcg_temp_new_i32();
3747

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

    
3756
    tcg_temp_free_i32(tmp);
3757
    tcg_temp_free_i32(rd);
3758
}
3759

    
3760

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

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

    
3800
    if (!s->vfp_enabled)
3801
      return 1;
3802
    VFP_DREG_D(rd, insn);
3803
    rn = (insn >> 16) & 0xf;
3804
    rm = insn & 0xf;
3805
    load = (insn & (1 << 21)) != 0;
3806
    if ((insn & (1 << 23)) == 0) {
3807
        /* Load store all elements.  */
3808
        op = (insn >> 8) & 0xf;
3809
        size = (insn >> 6) & 3;
3810
        if (op > 10)
3811
            return 1;
3812
        nregs = neon_ls_element_type[op].nregs;
3813
        interleave = neon_ls_element_type[op].interleave;
3814
        spacing = neon_ls_element_type[op].spacing;
3815
        if (size == 3 && (interleave | spacing) != 1)
3816
            return 1;
3817
        addr = tcg_temp_new_i32();
3818
        load_reg_var(s, addr, rn);
3819
        stride = (1 << size) * interleave;
3820
        for (reg = 0; reg < nregs; reg++) {
3821
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3822
                load_reg_var(s, addr, rn);
3823
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3824
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3825
                load_reg_var(s, addr, rn);
3826
                tcg_gen_addi_i32(addr, addr, 1 << size);
3827
            }
3828
            if (size == 3) {
3829
                if (load) {
3830
                    tmp64 = gen_ld64(addr, IS_USER(s));
3831
                    neon_store_reg64(tmp64, rd);
3832
                    tcg_temp_free_i64(tmp64);
3833
                } else {
3834
                    tmp64 = tcg_temp_new_i64();
3835
                    neon_load_reg64(tmp64, rd);
3836
                    gen_st64(tmp64, addr, IS_USER(s));
3837
                }
3838
                tcg_gen_addi_i32(addr, addr, stride);
3839
            } else {
3840
                for (pass = 0; pass < 2; pass++) {
3841
                    if (size == 2) {
3842
                        if (load) {
3843
                            tmp = gen_ld32(addr, IS_USER(s));
3844
                            neon_store_reg(rd, pass, tmp);
3845
                        } else {
3846
                            tmp = neon_load_reg(rd, pass);
3847
                            gen_st32(tmp, addr, IS_USER(s));
3848
                        }
3849
                        tcg_gen_addi_i32(addr, addr, stride);
3850
                    } else if (size == 1) {
3851
                        if (load) {
3852
                            tmp = gen_ld16u(addr, IS_USER(s));
3853
                            tcg_gen_addi_i32(addr, addr, stride);
3854
                            tmp2 = gen_ld16u(addr, IS_USER(s));
3855
                            tcg_gen_addi_i32(addr, addr, stride);
3856
                            tcg_gen_shli_i32(tmp2, tmp2, 16);
3857
                            tcg_gen_or_i32(tmp, tmp, tmp2);
3858
                            tcg_temp_free_i32(tmp2);
3859
                            neon_store_reg(rd, pass, tmp);
3860
                        } else {
3861
                            tmp = neon_load_reg(rd, pass);
3862
                            tmp2 = tcg_temp_new_i32();
3863
                            tcg_gen_shri_i32(tmp2, tmp, 16);
3864
                            gen_st16(tmp, addr, IS_USER(s));
3865
                            tcg_gen_addi_i32(addr, addr, stride);
3866
                            gen_st16(tmp2, addr, IS_USER(s));
3867
                            tcg_gen_addi_i32(addr, addr, stride);
3868
                        }
3869
                    } else /* size == 0 */ {
3870
                        if (load) {
3871
                            TCGV_UNUSED(tmp2);
3872
                            for (n = 0; n < 4; n++) {
3873
                                tmp = gen_ld8u(addr, IS_USER(s));
3874
                                tcg_gen_addi_i32(addr, addr, stride);
3875
                                if (n == 0) {
3876
                                    tmp2 = tmp;
3877
                                } else {
3878
                                    tcg_gen_shli_i32(tmp, tmp, n * 8);
3879
                                    tcg_gen_or_i32(tmp2, tmp2, tmp);
3880
                                    tcg_temp_free_i32(tmp);
3881
                                }
3882
                            }
3883
                            neon_store_reg(rd, pass, tmp2);
3884
                        } else {
3885
                            tmp2 = neon_load_reg(rd, pass);
3886
                            for (n = 0; n < 4; n++) {
3887
                                tmp = tcg_temp_new_i32();
3888
                                if (n == 0) {
3889
                                    tcg_gen_mov_i32(tmp, tmp2);
3890
                                } else {
3891
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
3892
                                }
3893
                                gen_st8(tmp, addr, IS_USER(s));
3894
                                tcg_gen_addi_i32(addr, addr, stride);
3895
                            }
3896
                            tcg_temp_free_i32(tmp2);
3897
                        }
3898
                    }
3899
                }
3900
            }
3901
            rd += spacing;
3902
        }
3903
        tcg_temp_free_i32(addr);
3904
        stride = nregs * 8;
3905
    } else {
3906
        size = (insn >> 10) & 3;
3907
        if (size == 3) {
3908
            /* Load single element to all lanes.  */
3909
            int a = (insn >> 4) & 1;
3910
            if (!load) {
3911
                return 1;
3912
            }
3913
            size = (insn >> 6) & 3;
3914
            nregs = ((insn >> 8) & 3) + 1;
3915

    
3916
            if (size == 3) {
3917
                if (nregs != 4 || a == 0) {
3918
                    return 1;
3919
                }
3920
                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3921
                size = 2;
3922
            }
3923
            if (nregs == 1 && a == 1 && size == 0) {
3924
                return 1;
3925
            }
3926
            if (nregs == 3 && a == 1) {
3927
                return 1;
3928
            }
3929
            addr = tcg_temp_new_i32();
3930
            load_reg_var(s, addr, rn);
3931
            if (nregs == 1) {
3932
                /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3933
                tmp = gen_load_and_replicate(s, addr, size);
3934
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
3935
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
3936
                if (insn & (1 << 5)) {
3937
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
3938
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
3939
                }
3940
                tcg_temp_free_i32(tmp);
3941
            } else {
3942
                /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3943
                stride = (insn & (1 << 5)) ? 2 : 1;
3944
                for (reg = 0; reg < nregs; reg++) {
3945
                    tmp = gen_load_and_replicate(s, addr, size);
3946
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
3947
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
3948
                    tcg_temp_free_i32(tmp);
3949
                    tcg_gen_addi_i32(addr, addr, 1 << size);
3950
                    rd += stride;
3951
                }
3952
            }
3953
            tcg_temp_free_i32(addr);
3954
            stride = (1 << size) * nregs;
3955
        } else {
3956
            /* Single element.  */
3957
            pass = (insn >> 7) & 1;
3958
            switch (size) {
3959
            case 0:
3960
                shift = ((insn >> 5) & 3) * 8;
3961
                stride = 1;
3962
                break;
3963
            case 1:
3964
                shift = ((insn >> 6) & 1) * 16;
3965
                stride = (insn & (1 << 5)) ? 2 : 1;
3966
                break;
3967
            case 2:
3968
                shift = 0;
3969
                stride = (insn & (1 << 6)) ? 2 : 1;
3970
                break;
3971
            default:
3972
                abort();
3973
            }
3974
            nregs = ((insn >> 8) & 3) + 1;
3975
            addr = tcg_temp_new_i32();
3976
            load_reg_var(s, addr, rn);
3977
            for (reg = 0; reg < nregs; reg++) {
3978
                if (load) {
3979
                    switch (size) {
3980
                    case 0:
3981
                        tmp = gen_ld8u(addr, IS_USER(s));
3982
                        break;
3983
                    case 1:
3984
                        tmp = gen_ld16u(addr, IS_USER(s));
3985
                        break;
3986
                    case 2:
3987
                        tmp = gen_ld32(addr, IS_USER(s));
3988
                        break;
3989
                    default: /* Avoid compiler warnings.  */
3990
                        abort();
3991
                    }
3992
                    if (size != 2) {
3993
                        tmp2 = neon_load_reg(rd, pass);
3994
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3995
                        tcg_temp_free_i32(tmp2);
3996
                    }
3997
                    neon_store_reg(rd, pass, tmp);
3998
                } else { /* Store */
3999
                    tmp = neon_load_reg(rd, pass);
4000
                    if (shift)
4001
                        tcg_gen_shri_i32(tmp, tmp, shift);
4002
                    switch (size) {
4003
                    case 0:
4004
                        gen_st8(tmp, addr, IS_USER(s));
4005
                        break;
4006
                    case 1:
4007
                        gen_st16(tmp, addr, IS_USER(s));
4008
                        break;
4009
                    case 2:
4010
                        gen_st32(tmp, addr, IS_USER(s));
4011
                        break;
4012
                    }
4013
                }
4014
                rd += stride;
4015
                tcg_gen_addi_i32(addr, addr, 1 << size);
4016
            }
4017
            tcg_temp_free_i32(addr);
4018
            stride = nregs * (1 << size);
4019
        }
4020
    }
4021
    if (rm != 15) {
4022
        TCGv base;
4023

    
4024
        base = load_reg(s, rn);
4025
        if (rm == 13) {
4026
            tcg_gen_addi_i32(base, base, stride);
4027
        } else {
4028
            TCGv index;
4029
            index = load_reg(s, rm);
4030
            tcg_gen_add_i32(base, base, index);
4031
            tcg_temp_free_i32(index);
4032
        }
4033
        store_reg(s, rn, base);
4034
    }
4035
    return 0;
4036
}
4037

    
4038
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4039
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4040
{
4041
    tcg_gen_and_i32(t, t, c);
4042
    tcg_gen_andc_i32(f, f, c);
4043
    tcg_gen_or_i32(dest, t, f);
4044
}
4045

    
4046
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4047
{
4048
    switch (size) {
4049
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4050
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4051
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4052
    default: abort();
4053
    }
4054
}
4055

    
4056
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4057
{
4058
    switch (size) {
4059
    case 0: gen_helper_neon_narrow_sat_s8(dest, src); break;
4060
    case 1: gen_helper_neon_narrow_sat_s16(dest, src); break;
4061
    case 2: gen_helper_neon_narrow_sat_s32(dest, src); break;
4062
    default: abort();
4063
    }
4064
}
4065

    
4066
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4067
{
4068
    switch (size) {
4069
    case 0: gen_helper_neon_narrow_sat_u8(dest, src); break;
4070
    case 1: gen_helper_neon_narrow_sat_u16(dest, src); break;
4071
    case 2: gen_helper_neon_narrow_sat_u32(dest, src); break;
4072
    default: abort();
4073
    }
4074
}
4075

    
4076
static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4077
{
4078
    switch (size) {
4079
    case 0: gen_helper_neon_unarrow_sat8(dest, src); break;
4080
    case 1: gen_helper_neon_unarrow_sat16(dest, src); break;
4081
    case 2: gen_helper_neon_unarrow_sat32(dest, src); break;
4082
    default: abort();
4083
    }
4084
}
4085

    
4086
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4087
                                         int q, int u)
4088
{
4089
    if (q) {
4090
        if (u) {
4091
            switch (size) {
4092
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4093
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4094
            default: abort();
4095
            }
4096
        } else {
4097
            switch (size) {
4098
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4099
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4100
            default: abort();
4101
            }
4102
        }
4103
    } else {
4104
        if (u) {
4105
            switch (size) {
4106
            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4107
            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4108
            default: abort();
4109
            }
4110
        } else {
4111
            switch (size) {
4112
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4113
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4114
            default: abort();
4115
            }
4116
        }
4117
    }
4118
}
4119

    
4120
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4121
{
4122
    if (u) {
4123
        switch (size) {
4124
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4125
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4126
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4127
        default: abort();
4128
        }
4129
    } else {
4130
        switch (size) {
4131
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4132
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4133
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4134
        default: abort();
4135
        }
4136
    }
4137
    tcg_temp_free_i32(src);
4138
}
4139

    
4140
static inline void gen_neon_addl(int size)
4141
{
4142
    switch (size) {
4143
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4144
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4145
    case 2: tcg_gen_add_i64(CPU_V001); break;
4146
    default: abort();
4147
    }
4148
}
4149

    
4150
static inline void gen_neon_subl(int size)
4151
{
4152
    switch (size) {
4153
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4154
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4155
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4156
    default: abort();
4157
    }
4158
}
4159

    
4160
static inline void gen_neon_negl(TCGv_i64 var, int size)
4161
{
4162
    switch (size) {
4163
    case 0: gen_helper_neon_negl_u16(var, var); break;
4164
    case 1: gen_helper_neon_negl_u32(var, var); break;
4165
    case 2: gen_helper_neon_negl_u64(var, var); break;
4166
    default: abort();
4167
    }
4168
}
4169

    
4170
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4171
{
4172
    switch (size) {
4173
    case 1: gen_helper_neon_addl_saturate_s32(op0, op0, op1); break;
4174
    case 2: gen_helper_neon_addl_saturate_s64(op0, op0, op1); break;
4175
    default: abort();
4176
    }
4177
}
4178

    
4179
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4180
{
4181
    TCGv_i64 tmp;
4182

    
4183
    switch ((size << 1) | u) {
4184
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4185
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4186
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4187
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4188
    case 4:
4189
        tmp = gen_muls_i64_i32(a, b);
4190
        tcg_gen_mov_i64(dest, tmp);
4191
        tcg_temp_free_i64(tmp);
4192
        break;
4193
    case 5:
4194
        tmp = gen_mulu_i64_i32(a, b);
4195
        tcg_gen_mov_i64(dest, tmp);
4196
        tcg_temp_free_i64(tmp);
4197
        break;
4198
    default: abort();
4199
    }
4200

    
4201
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4202
       Don't forget to clean them now.  */
4203
    if (size < 2) {
4204
        tcg_temp_free_i32(a);
4205
        tcg_temp_free_i32(b);
4206
    }
4207
}
4208

    
4209
static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
4210
{
4211
    if (op) {
4212
        if (u) {
4213
            gen_neon_unarrow_sats(size, dest, src);
4214
        } else {
4215
            gen_neon_narrow(size, dest, src);
4216
        }
4217
    } else {
4218
        if (u) {
4219
            gen_neon_narrow_satu(size, dest, src);
4220
        } else {
4221
            gen_neon_narrow_sats(size, dest, src);
4222
        }
4223
    }
4224
}
4225

    
4226
/* Translate a NEON data processing instruction.  Return nonzero if the
4227
   instruction is invalid.
4228
   We process data in a mixture of 32-bit and 64-bit chunks.
4229
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4230

    
4231
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4232
{
4233
    int op;
4234
    int q;
4235
    int rd, rn, rm;
4236
    int size;
4237
    int shift;
4238
    int pass;
4239
    int count;
4240
    int pairwise;
4241
    int u;
4242
    int n;
4243
    uint32_t imm, mask;
4244
    TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4245
    TCGv_i64 tmp64;
4246

    
4247
    if (!s->vfp_enabled)
4248
      return 1;
4249
    q = (insn & (1 << 6)) != 0;
4250
    u = (insn >> 24) & 1;
4251
    VFP_DREG_D(rd, insn);
4252
    VFP_DREG_N(rn, insn);
4253
    VFP_DREG_M(rm, insn);
4254
    size = (insn >> 20) & 3;
4255
    if ((insn & (1 << 23)) == 0) {
4256
        /* Three register same length.  */
4257
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4258
        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4259
                          || op == 10 || op  == 11 || op == 16)) {
4260
            /* 64-bit element instructions.  */
4261
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4262
                neon_load_reg64(cpu_V0, rn + pass);
4263
                neon_load_reg64(cpu_V1, rm + pass);
4264
                switch (op) {
4265
                case 1: /* VQADD */
4266
                    if (u) {
4267
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_V0, cpu_V1);
4268
                    } else {
4269
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_V0, cpu_V1);
4270
                    }
4271
                    break;
4272
                case 5: /* VQSUB */
4273
                    if (u) {
4274
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_V0, cpu_V1);
4275
                    } else {
4276
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_V0, cpu_V1);
4277
                    }
4278
                    break;
4279
                case 8: /* VSHL */
4280
                    if (u) {
4281
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4282
                    } else {
4283
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4284
                    }
4285
                    break;
4286
                case 9: /* VQSHL */
4287
                    if (u) {
4288
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_V1, cpu_V0);
4289
                    } else {
4290
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_V1, cpu_V0);
4291
                    }
4292
                    break;
4293
                case 10: /* VRSHL */
4294
                    if (u) {
4295
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4296
                    } else {
4297
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4298
                    }
4299
                    break;
4300
                case 11: /* VQRSHL */
4301
                    if (u) {
4302
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_V1, cpu_V0);
4303
                    } else {
4304
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_V1, cpu_V0);
4305
                    }
4306
                    break;
4307
                case 16:
4308
                    if (u) {
4309
                        tcg_gen_sub_i64(CPU_V001);
4310
                    } else {
4311
                        tcg_gen_add_i64(CPU_V001);
4312
                    }
4313
                    break;
4314
                default:
4315
                    abort();
4316
                }
4317
                neon_store_reg64(cpu_V0, rd + pass);
4318
            }
4319
            return 0;
4320
        }
4321
        switch (op) {
4322
        case 8: /* VSHL */
4323
        case 9: /* VQSHL */
4324
        case 10: /* VRSHL */
4325
        case 11: /* VQRSHL */
4326
            {
4327
                int rtmp;
4328
                /* Shift instruction operands are reversed.  */
4329
                rtmp = rn;
4330
                rn = rm;
4331
                rm = rtmp;
4332
                pairwise = 0;
4333
            }
4334
            break;
4335
        case 20: /* VPMAX */
4336
        case 21: /* VPMIN */
4337
        case 23: /* VPADD */
4338
            pairwise = 1;
4339
            break;
4340
        case 26: /* VPADD (float) */
4341
            pairwise = (u && size < 2);
4342
            break;
4343
        case 30: /* VPMIN/VPMAX (float) */
4344
            pairwise = u;
4345
            break;
4346
        default:
4347
            pairwise = 0;
4348
            break;
4349
        }
4350

    
4351
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4352

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

    
4607
        /* Save the result.  For elementwise operations we can put it
4608
           straight into the destination register.  For pairwise operations
4609
           we have to be careful to avoid clobbering the source operands.  */
4610
        if (pairwise && rd == rm) {
4611
            neon_store_scratch(pass, tmp);
4612
        } else {
4613
            neon_store_reg(rd, pass, tmp);
4614
        }
4615

    
4616
        } /* for pass */
4617
        if (pairwise && rd == rm) {
4618
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4619
                tmp = neon_load_scratch(pass);
4620
                neon_store_reg(rd, pass, tmp);
4621
            }
4622
        }
4623
        /* End of 3 register same size operations.  */
4624
    } else if (insn & (1 << 4)) {
4625
        if ((insn & 0x00380080) != 0) {
4626
            /* Two registers and shift.  */
4627
            op = (insn >> 8) & 0xf;
4628
            if (insn & (1 << 7)) {
4629
                /* 64-bit shift.   */
4630
                size = 3;
4631
            } else {
4632
                size = 2;
4633
                while ((insn & (1 << (size + 19))) == 0)
4634
                    size--;
4635
            }
4636
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4637
            /* To avoid excessive dumplication of ops we implement shift
4638
               by immediate using the variable shift operations.  */
4639
            if (op < 8) {
4640
                /* Shift by immediate:
4641
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4642
                /* Right shifts are encoded as N - shift, where N is the
4643
                   element size in bits.  */
4644
                if (op <= 4)
4645
                    shift = shift - (1 << (size + 3));
4646
                if (size == 3) {
4647
                    count = q + 1;
4648
                } else {
4649
                    count = q ? 4: 2;
4650
                }
4651
                switch (size) {
4652
                case 0:
4653
                    imm = (uint8_t) shift;
4654
                    imm |= imm << 8;
4655
                    imm |= imm << 16;
4656
                    break;
4657
                case 1:
4658
                    imm = (uint16_t) shift;
4659
                    imm |= imm << 16;
4660
                    break;
4661
                case 2:
4662
                case 3:
4663
                    imm = shift;
4664
                    break;
4665
                default:
4666
                    abort();
4667
                }
4668

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

    
4786
                        if (op == 1 || op == 3) {
4787
                            /* Accumulate.  */
4788
                            tmp2 = neon_load_reg(rd, pass);
4789
                            gen_neon_add(size, tmp, tmp2);
4790
                            tcg_temp_free_i32(tmp2);
4791
                        } else if (op == 4 || (op == 5 && u)) {
4792
                            /* Insert */
4793
                            switch (size) {
4794
                            case 0:
4795
                                if (op == 4)
4796
                                    mask = 0xff >> -shift;
4797
                                else
4798
                                    mask = (uint8_t)(0xff << shift);
4799
                                mask |= mask << 8;
4800
                                mask |= mask << 16;
4801
                                break;
4802
                            case 1:
4803
                                if (op == 4)
4804
                                    mask = 0xffff >> -shift;
4805
                                else
4806
                                    mask = (uint16_t)(0xffff << shift);
4807
                                mask |= mask << 16;
4808
                                break;
4809
                            case 2:
4810
                                if (shift < -31 || shift > 31) {
4811
                                    mask = 0;
4812
                                } else {
4813
                                    if (op == 4)
4814
                                        mask = 0xffffffffu >> -shift;
4815
                                    else
4816
                                        mask = 0xffffffffu << shift;
4817
                                }
4818
                                break;
4819
                            default:
4820
                                abort();
4821
                            }
4822
                            tmp2 = neon_load_reg(rd, pass);
4823
                            tcg_gen_andi_i32(tmp, tmp, mask);
4824
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
4825
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4826
                            tcg_temp_free_i32(tmp2);
4827
                        }
4828
                        neon_store_reg(rd, pass, tmp);
4829
                    }
4830
                } /* for pass */
4831
            } else if (op < 10) {
4832
                /* Shift by immediate and narrow:
4833
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4834
                int input_unsigned = (op == 8) ? !u : u;
4835

    
4836
                shift = shift - (1 << (size + 3));
4837
                size++;
4838
                if (size == 3) {
4839
                    tmp64 = tcg_const_i64(shift);
4840
                    neon_load_reg64(cpu_V0, rm);
4841
                    neon_load_reg64(cpu_V1, rm + 1);
4842
                    for (pass = 0; pass < 2; pass++) {
4843
                        TCGv_i64 in;
4844
                        if (pass == 0) {
4845
                            in = cpu_V0;
4846
                        } else {
4847
                            in = cpu_V1;
4848
                        }
4849
                        if (q) {
4850
                            if (input_unsigned) {
4851
                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
4852
                            } else {
4853
                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
4854
                            }
4855
                        } else {
4856
                            if (input_unsigned) {
4857
                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
4858
                            } else {
4859
                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
4860
                            }
4861
                        }
4862
                        tmp = tcg_temp_new_i32();
4863
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
4864
                        neon_store_reg(rd, pass, tmp);
4865
                    } /* for pass */
4866
                    tcg_temp_free_i64(tmp64);
4867
                } else {
4868
                    if (size == 1) {
4869
                        imm = (uint16_t)shift;
4870
                        imm |= imm << 16;
4871
                    } else {
4872
                        /* size == 2 */
4873
                        imm = (uint32_t)shift;
4874
                    }
4875
                    tmp2 = tcg_const_i32(imm);
4876
                    tmp4 = neon_load_reg(rm + 1, 0);
4877
                    tmp5 = neon_load_reg(rm + 1, 1);
4878
                    for (pass = 0; pass < 2; pass++) {
4879
                        if (pass == 0) {
4880
                            tmp = neon_load_reg(rm, 0);
4881
                        } else {
4882
                            tmp = tmp4;
4883
                        }
4884
                        gen_neon_shift_narrow(size, tmp, tmp2, q,
4885
                                              input_unsigned);
4886
                        if (pass == 0) {
4887
                            tmp3 = neon_load_reg(rm, 1);
4888
                        } else {
4889
                            tmp3 = tmp5;
4890
                        }
4891
                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
4892
                                              input_unsigned);
4893
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4894
                        tcg_temp_free_i32(tmp);
4895
                        tcg_temp_free_i32(tmp3);
4896
                        tmp = tcg_temp_new_i32();
4897
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
4898
                        neon_store_reg(rd, pass, tmp);
4899
                    } /* for pass */
4900
                    tcg_temp_free_i32(tmp2);
4901
                }
4902
            } else if (op == 10) {
4903
                /* VSHLL */
4904
                if (q || size == 3)
4905
                    return 1;
4906
                tmp = neon_load_reg(rm, 0);
4907
                tmp2 = neon_load_reg(rm, 1);
4908
                for (pass = 0; pass < 2; pass++) {
4909
                    if (pass == 1)
4910
                        tmp = tmp2;
4911

    
4912
                    gen_neon_widen(cpu_V0, tmp, size, u);
4913

    
4914
                    if (shift != 0) {
4915
                        /* The shift is less than the width of the source
4916
                           type, so we can just shift the whole register.  */
4917
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4918
                        /* Widen the result of shift: we need to clear
4919
                         * the potential overflow bits resulting from
4920
                         * left bits of the narrow input appearing as
4921
                         * right bits of left the neighbour narrow
4922
                         * input.  */
4923
                        if (size < 2 || !u) {
4924
                            uint64_t imm64;
4925
                            if (size == 0) {
4926
                                imm = (0xffu >> (8 - shift));
4927
                                imm |= imm << 16;
4928
                            } else if (size == 1) {
4929
                                imm = 0xffff >> (16 - shift);
4930
                            } else {
4931
                                /* size == 2 */
4932
                                imm = 0xffffffff >> (32 - shift);
4933
                            }
4934
                            if (size < 2) {
4935
                                imm64 = imm | (((uint64_t)imm) << 32);
4936
                            } else {
4937
                                imm64 = imm;
4938
                            }
4939
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
4940
                        }
4941
                    }
4942
                    neon_store_reg64(cpu_V0, rd + pass);
4943
                }
4944
            } else if (op >= 14) {
4945
                /* VCVT fixed-point.  */
4946
                /* We have already masked out the must-be-1 top bit of imm6,
4947
                 * hence this 32-shift where the ARM ARM has 64-imm6.
4948
                 */
4949
                shift = 32 - shift;
4950
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4951
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4952
                    if (!(op & 1)) {
4953
                        if (u)
4954
                            gen_vfp_ulto(0, shift);
4955
                        else
4956
                            gen_vfp_slto(0, shift);
4957
                    } else {
4958
                        if (u)
4959
                            gen_vfp_toul(0, shift);
4960
                        else
4961
                            gen_vfp_tosl(0, shift);
4962
                    }
4963
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4964
                }
4965
            } else {
4966
                return 1;
4967
            }
4968
        } else { /* (insn & 0x00380080) == 0 */
4969
            int invert;
4970

    
4971
            op = (insn >> 8) & 0xf;
4972
            /* One register and immediate.  */
4973
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4974
            invert = (insn & (1 << 5)) != 0;
4975
            switch (op) {
4976
            case 0: case 1:
4977
                /* no-op */
4978
                break;
4979
            case 2: case 3:
4980
                imm <<= 8;
4981
                break;
4982
            case 4: case 5:
4983
                imm <<= 16;
4984
                break;
4985
            case 6: case 7:
4986
                imm <<= 24;
4987
                break;
4988
            case 8: case 9:
4989
                imm |= imm << 16;
4990
                break;
4991
            case 10: case 11:
4992
                imm = (imm << 8) | (imm << 24);
4993
                break;
4994
            case 12:
4995
                imm = (imm << 8) | 0xff;
4996
                break;
4997
            case 13:
4998
                imm = (imm << 16) | 0xffff;
4999
                break;
5000
            case 14:
5001
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
5002
                if (invert)
5003
                    imm = ~imm;
5004
                break;
5005
            case 15:
5006
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5007
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5008
                break;
5009
            }
5010
            if (invert)
5011
                imm = ~imm;
5012

    
5013
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5014
                if (op & 1 && op < 12) {
5015
                    tmp = neon_load_reg(rd, pass);
5016
                    if (invert) {
5017
                        /* The immediate value has already been inverted, so
5018
                           BIC becomes AND.  */
5019
                        tcg_gen_andi_i32(tmp, tmp, imm);
5020
                    } else {
5021
                        tcg_gen_ori_i32(tmp, tmp, imm);
5022
                    }
5023
                } else {
5024
                    /* VMOV, VMVN.  */
5025
                    tmp = tcg_temp_new_i32();
5026
                    if (op == 14 && invert) {
5027
                        uint32_t val;
5028
                        val = 0;
5029
                        for (n = 0; n < 4; n++) {
5030
                            if (imm & (1 << (n + (pass & 1) * 4)))
5031
                                val |= 0xff << (n * 8);
5032
                        }
5033
                        tcg_gen_movi_i32(tmp, val);
5034
                    } else {
5035
                        tcg_gen_movi_i32(tmp, imm);
5036
                    }
5037
                }
5038
                neon_store_reg(rd, pass, tmp);
5039
            }
5040
        }
5041
    } else { /* (insn & 0x00800010 == 0x00800000) */
5042
        if (size != 3) {
5043
            op = (insn >> 8) & 0xf;
5044
            if ((insn & (1 << 6)) == 0) {
5045
                /* Three registers of different lengths.  */
5046
                int src1_wide;
5047
                int src2_wide;
5048
                int prewiden;
5049
                /* prewiden, src1_wide, src2_wide */
5050
                static const int neon_3reg_wide[16][3] = {
5051
                    {1, 0, 0}, /* VADDL */
5052
                    {1, 1, 0}, /* VADDW */
5053
                    {1, 0, 0}, /* VSUBL */
5054
                    {1, 1, 0}, /* VSUBW */
5055
                    {0, 1, 1}, /* VADDHN */
5056
                    {0, 0, 0}, /* VABAL */
5057
                    {0, 1, 1}, /* VSUBHN */
5058
                    {0, 0, 0}, /* VABDL */
5059
                    {0, 0, 0}, /* VMLAL */
5060
                    {0, 0, 0}, /* VQDMLAL */
5061
                    {0, 0, 0}, /* VMLSL */
5062
                    {0, 0, 0}, /* VQDMLSL */
5063
                    {0, 0, 0}, /* Integer VMULL */
5064
                    {0, 0, 0}, /* VQDMULL */
5065
                    {0, 0, 0}  /* Polynomial VMULL */
5066
                };
5067

    
5068
                prewiden = neon_3reg_wide[op][0];
5069
                src1_wide = neon_3reg_wide[op][1];
5070
                src2_wide = neon_3reg_wide[op][2];
5071

    
5072
                if (size == 0 && (op == 9 || op == 11 || op == 13))
5073
                    return 1;
5074

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

    
5298
                    tmp2 = neon_get_scalar(size, rm);
5299
                    /* We need a copy of tmp2 because gen_neon_mull
5300
                     * deletes it during pass 0.  */
5301
                    tmp4 = tcg_temp_new_i32();
5302
                    tcg_gen_mov_i32(tmp4, tmp2);
5303
                    tmp3 = neon_load_reg(rn, 1);
5304

    
5305
                    for (pass = 0; pass < 2; pass++) {
5306
                        if (pass == 0) {
5307
                            tmp = neon_load_reg(rn, 0);
5308
                        } else {
5309
                            tmp = tmp3;
5310
                            tmp2 = tmp4;
5311
                        }
5312
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5313
                        if (op != 11) {
5314
                            neon_load_reg64(cpu_V1, rd + pass);
5315
                        }
5316
                        switch (op) {
5317
                        case 6:
5318
                            gen_neon_negl(cpu_V0, size);
5319
                            /* Fall through */
5320
                        case 2:
5321
                            gen_neon_addl(size);
5322
                            break;
5323
                        case 3: case 7:
5324
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5325
                            if (op == 7) {
5326
                                gen_neon_negl(cpu_V0, size);
5327
                            }
5328
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5329
                            break;
5330
                        case 10:
5331
                            /* no-op */
5332
                            break;
5333
                        case 11:
5334
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5335
                            break;
5336
                        default:
5337
                            abort();
5338
                        }
5339
                        neon_store_reg64(cpu_V0, rd + pass);
5340
                    }
5341

    
5342

    
5343
                    break;
5344
                default: /* 14 and 15 are RESERVED */
5345
                    return 1;
5346
                }
5347
            }
5348
        } else { /* size == 3 */
5349
            if (!u) {
5350
                /* Extract.  */
5351
                imm = (insn >> 8) & 0xf;
5352

    
5353
                if (imm > 7 && !q)
5354
                    return 1;
5355

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

    
5800
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5801
{
5802
    int crn = (insn >> 16) & 0xf;
5803
    int crm = insn & 0xf;
5804
    int op1 = (insn >> 21) & 7;
5805
    int op2 = (insn >> 5) & 7;
5806
    int rt = (insn >> 12) & 0xf;
5807
    TCGv tmp;
5808

    
5809
    /* Minimal set of debug registers, since we don't support debug */
5810
    if (op1 == 0 && crn == 0 && op2 == 0) {
5811
        switch (crm) {
5812
        case 0:
5813
            /* DBGDIDR: just RAZ. In particular this means the
5814
             * "debug architecture version" bits will read as
5815
             * a reserved value, which should cause Linux to
5816
             * not try to use the debug hardware.
5817
             */
5818
            tmp = tcg_const_i32(0);
5819
            store_reg(s, rt, tmp);
5820
            return 0;
5821
        case 1:
5822
        case 2:
5823
            /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we
5824
             * don't implement memory mapped debug components
5825
             */
5826
            if (ENABLE_ARCH_7) {
5827
                tmp = tcg_const_i32(0);
5828
                store_reg(s, rt, tmp);
5829
                return 0;
5830
            }
5831
            break;
5832
        default:
5833
            break;
5834
        }
5835
    }
5836

    
5837
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5838
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5839
            /* TEECR */
5840
            if (IS_USER(s))
5841
                return 1;
5842
            tmp = load_cpu_field(teecr);
5843
            store_reg(s, rt, tmp);
5844
            return 0;
5845
        }
5846
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5847
            /* TEEHBR */
5848
            if (IS_USER(s) && (env->teecr & 1))
5849
                return 1;
5850
            tmp = load_cpu_field(teehbr);
5851
            store_reg(s, rt, tmp);
5852
            return 0;
5853
        }
5854
    }
5855
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5856
            op1, crn, crm, op2);
5857
    return 1;
5858
}
5859

    
5860
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5861
{
5862
    int crn = (insn >> 16) & 0xf;
5863
    int crm = insn & 0xf;
5864
    int op1 = (insn >> 21) & 7;
5865
    int op2 = (insn >> 5) & 7;
5866
    int rt = (insn >> 12) & 0xf;
5867
    TCGv tmp;
5868

    
5869
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5870
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5871
            /* TEECR */
5872
            if (IS_USER(s))
5873
                return 1;
5874
            tmp = load_reg(s, rt);
5875
            gen_helper_set_teecr(cpu_env, tmp);
5876
            tcg_temp_free_i32(tmp);
5877
            return 0;
5878
        }
5879
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5880
            /* TEEHBR */
5881
            if (IS_USER(s) && (env->teecr & 1))
5882
                return 1;
5883
            tmp = load_reg(s, rt);
5884
            store_cpu_field(tmp, teehbr);
5885
            return 0;
5886
        }
5887
    }
5888
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5889
            op1, crn, crm, op2);
5890
    return 1;
5891
}
5892

    
5893
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5894
{
5895
    int cpnum;
5896

    
5897
    cpnum = (insn >> 8) & 0xf;
5898
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5899
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5900
        return 1;
5901

    
5902
    switch (cpnum) {
5903
      case 0:
5904
      case 1:
5905
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5906
            return disas_iwmmxt_insn(env, s, insn);
5907
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5908
            return disas_dsp_insn(env, s, insn);
5909
        }
5910
        return 1;
5911
    case 10:
5912
    case 11:
5913
        return disas_vfp_insn (env, s, insn);
5914
    case 14:
5915
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5916
           Unfortunately Intel decided to ignore this.  */
5917
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5918
            goto board;
5919
        if (insn & (1 << 20))
5920
            return disas_cp14_read(env, s, insn);
5921
        else
5922
            return disas_cp14_write(env, s, insn);
5923
    case 15:
5924
        return disas_cp15_insn (env, s, insn);
5925
    default:
5926
    board:
5927
        /* Unknown coprocessor.  See if the board has hooked it.  */
5928
        return disas_cp_insn (env, s, insn);
5929
    }
5930
}
5931

    
5932

    
5933
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5934
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5935
{
5936
    TCGv tmp;
5937
    tmp = tcg_temp_new_i32();
5938
    tcg_gen_trunc_i64_i32(tmp, val);
5939
    store_reg(s, rlow, tmp);
5940
    tmp = tcg_temp_new_i32();
5941
    tcg_gen_shri_i64(val, val, 32);
5942
    tcg_gen_trunc_i64_i32(tmp, val);
5943
    store_reg(s, rhigh, tmp);
5944
}
5945

    
5946
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5947
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5948
{
5949
    TCGv_i64 tmp;
5950
    TCGv tmp2;
5951

    
5952
    /* Load value and extend to 64 bits.  */
5953
    tmp = tcg_temp_new_i64();
5954
    tmp2 = load_reg(s, rlow);
5955
    tcg_gen_extu_i32_i64(tmp, tmp2);
5956
    tcg_temp_free_i32(tmp2);
5957
    tcg_gen_add_i64(val, val, tmp);
5958
    tcg_temp_free_i64(tmp);
5959
}
5960

    
5961
/* load and add a 64-bit value from a register pair.  */
5962
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5963
{
5964
    TCGv_i64 tmp;
5965
    TCGv tmpl;
5966
    TCGv tmph;
5967

    
5968
    /* Load 64-bit value rd:rn.  */
5969
    tmpl = load_reg(s, rlow);
5970
    tmph = load_reg(s, rhigh);
5971
    tmp = tcg_temp_new_i64();
5972
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5973
    tcg_temp_free_i32(tmpl);
5974
    tcg_temp_free_i32(tmph);
5975
    tcg_gen_add_i64(val, val, tmp);
5976
    tcg_temp_free_i64(tmp);
5977
}
5978

    
5979
/* Set N and Z flags from a 64-bit value.  */
5980
static void gen_logicq_cc(TCGv_i64 val)
5981
{
5982
    TCGv tmp = tcg_temp_new_i32();
5983
    gen_helper_logicq_cc(tmp, val);
5984
    gen_logic_CC(tmp);
5985
    tcg_temp_free_i32(tmp);
5986
}
5987

    
5988
/* Load/Store exclusive instructions are implemented by remembering
5989
   the value/address loaded, and seeing if these are the same
5990
   when the store is performed. This should be is sufficient to implement
5991
   the architecturally mandated semantics, and avoids having to monitor
5992
   regular stores.
5993

5994
   In system emulation mode only one CPU will be running at once, so
5995
   this sequence is effectively atomic.  In user emulation mode we
5996
   throw an exception and handle the atomic operation elsewhere.  */
5997
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
5998
                               TCGv addr, int size)
5999
{
6000
    TCGv tmp;
6001

    
6002
    switch (size) {
6003
    case 0:
6004
        tmp = gen_ld8u(addr, IS_USER(s));
6005
        break;
6006
    case 1:
6007
        tmp = gen_ld16u(addr, IS_USER(s));
6008
        break;
6009
    case 2:
6010
    case 3:
6011
        tmp = gen_ld32(addr, IS_USER(s));
6012
        break;
6013
    default:
6014
        abort();
6015
    }
6016
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6017
    store_reg(s, rt, tmp);
6018
    if (size == 3) {
6019
        TCGv tmp2 = tcg_temp_new_i32();
6020
        tcg_gen_addi_i32(tmp2, addr, 4);
6021
        tmp = gen_ld32(tmp2, IS_USER(s));
6022
        tcg_temp_free_i32(tmp2);
6023
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6024
        store_reg(s, rt2, tmp);
6025
    }
6026
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6027
}
6028

    
6029
static void gen_clrex(DisasContext *s)
6030
{
6031
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6032
}
6033

    
6034
#ifdef CONFIG_USER_ONLY
6035
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6036
                                TCGv addr, int size)
6037
{
6038
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
6039
    tcg_gen_movi_i32(cpu_exclusive_info,
6040
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
6041
    gen_exception_insn(s, 4, EXCP_STREX);
6042
}
6043
#else
6044
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6045
                                TCGv addr, int size)
6046
{
6047
    TCGv tmp;
6048
    int done_label;
6049
    int fail_label;
6050

    
6051
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6052
         [addr] = {Rt};
6053
         {Rd} = 0;
6054
       } else {
6055
         {Rd} = 1;
6056
       } */
6057
    fail_label = gen_new_label();
6058
    done_label = gen_new_label();
6059
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6060
    switch (size) {
6061
    case 0:
6062
        tmp = gen_ld8u(addr, IS_USER(s));
6063
        break;
6064
    case 1:
6065
        tmp = gen_ld16u(addr, IS_USER(s));
6066
        break;
6067
    case 2:
6068
    case 3:
6069
        tmp = gen_ld32(addr, IS_USER(s));
6070
        break;
6071
    default:
6072
        abort();
6073
    }
6074
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6075
    tcg_temp_free_i32(tmp);
6076
    if (size == 3) {
6077
        TCGv tmp2 = tcg_temp_new_i32();
6078
        tcg_gen_addi_i32(tmp2, addr, 4);
6079
        tmp = gen_ld32(tmp2, IS_USER(s));
6080
        tcg_temp_free_i32(tmp2);
6081
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6082
        tcg_temp_free_i32(tmp);
6083
    }
6084
    tmp = load_reg(s, rt);
6085
    switch (size) {
6086
    case 0:
6087
        gen_st8(tmp, addr, IS_USER(s));
6088
        break;
6089
    case 1:
6090
        gen_st16(tmp, addr, IS_USER(s));
6091
        break;
6092
    case 2:
6093
    case 3:
6094
        gen_st32(tmp, addr, IS_USER(s));
6095
        break;
6096
    default:
6097
        abort();
6098
    }
6099
    if (size == 3) {
6100
        tcg_gen_addi_i32(addr, addr, 4);
6101
        tmp = load_reg(s, rt2);
6102
        gen_st32(tmp, addr, IS_USER(s));
6103
    }
6104
    tcg_gen_movi_i32(cpu_R[rd], 0);
6105
    tcg_gen_br(done_label);
6106
    gen_set_label(fail_label);
6107
    tcg_gen_movi_i32(cpu_R[rd], 1);
6108
    gen_set_label(done_label);
6109
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6110
}
6111
#endif
6112

    
6113
static void disas_arm_insn(CPUState * env, DisasContext *s)
6114
{
6115
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6116
    TCGv tmp;
6117
    TCGv tmp2;
6118
    TCGv tmp3;
6119
    TCGv addr;
6120
    TCGv_i64 tmp64;
6121

    
6122
    insn = ldl_code(s->pc);
6123
    s->pc += 4;
6124

    
6125
    /* M variants do not implement ARM mode.  */
6126
    if (IS_M(env))
6127
        goto illegal_op;
6128
    cond = insn >> 28;
6129
    if (cond == 0xf){
6130
        /* Unconditional instructions.  */
6131
        if (((insn >> 25) & 7) == 1) {
6132
            /* NEON Data processing.  */
6133
            if (!arm_feature(env, ARM_FEATURE_NEON))
6134
                goto illegal_op;
6135

    
6136
            if (disas_neon_data_insn(env, s, insn))
6137
                goto illegal_op;
6138
            return;
6139
        }
6140
        if ((insn & 0x0f100000) == 0x04000000) {
6141
            /* NEON load/store.  */
6142
            if (!arm_feature(env, ARM_FEATURE_NEON))
6143
                goto illegal_op;
6144

    
6145
            if (disas_neon_ls_insn(env, s, insn))
6146
                goto illegal_op;
6147
            return;
6148
        }
6149
        if (((insn & 0x0f30f000) == 0x0510f000) ||
6150
            ((insn & 0x0f30f010) == 0x0710f000)) {
6151
            if ((insn & (1 << 22)) == 0) {
6152
                /* PLDW; v7MP */
6153
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6154
                    goto illegal_op;
6155
                }
6156
            }
6157
            /* Otherwise PLD; v5TE+ */
6158
            return;
6159
        }
6160
        if (((insn & 0x0f70f000) == 0x0450f000) ||
6161
            ((insn & 0x0f70f010) == 0x0650f000)) {
6162
            ARCH(7);
6163
            return; /* PLI; V7 */
6164
        }
6165
        if (((insn & 0x0f700000) == 0x04100000) ||
6166
            ((insn & 0x0f700010) == 0x06100000)) {
6167
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6168
                goto illegal_op;
6169
            }
6170
            return; /* v7MP: Unallocated memory hint: must NOP */
6171
        }
6172

    
6173
        if ((insn & 0x0ffffdff) == 0x01010000) {
6174
            ARCH(6);
6175
            /* setend */
6176
            if (insn & (1 << 9)) {
6177
                /* BE8 mode not implemented.  */
6178
                goto illegal_op;
6179
            }
6180
            return;
6181
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6182
            switch ((insn >> 4) & 0xf) {
6183
            case 1: /* clrex */
6184
                ARCH(6K);
6185
                gen_clrex(s);
6186
                return;
6187
            case 4: /* dsb */
6188
            case 5: /* dmb */
6189
            case 6: /* isb */
6190
                ARCH(7);
6191
                /* We don't emulate caches so these are a no-op.  */
6192
                return;
6193
            default:
6194
                goto illegal_op;
6195
            }
6196
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6197
            /* srs */
6198
            int32_t offset;
6199
            if (IS_USER(s))
6200
                goto illegal_op;
6201
            ARCH(6);
6202
            op1 = (insn & 0x1f);
6203
            addr = tcg_temp_new_i32();
6204
            tmp = tcg_const_i32(op1);
6205
            gen_helper_get_r13_banked(addr, cpu_env, tmp);
6206
            tcg_temp_free_i32(tmp);
6207
            i = (insn >> 23) & 3;
6208
            switch (i) {
6209
            case 0: offset = -4; break; /* DA */
6210
            case 1: offset = 0; break; /* IA */
6211
            case 2: offset = -8; break; /* DB */
6212
            case 3: offset = 4; break; /* IB */
6213
            default: abort();
6214
            }
6215
            if (offset)
6216
                tcg_gen_addi_i32(addr, addr, offset);
6217
            tmp = load_reg(s, 14);
6218
            gen_st32(tmp, addr, 0);
6219
            tmp = load_cpu_field(spsr);
6220
            tcg_gen_addi_i32(addr, addr, 4);
6221
            gen_st32(tmp, addr, 0);
6222
            if (insn & (1 << 21)) {
6223
                /* Base writeback.  */
6224
                switch (i) {
6225
                case 0: offset = -8; break;
6226
                case 1: offset = 4; break;
6227
                case 2: offset = -4; break;
6228
                case 3: offset = 0; break;
6229
                default: abort();
6230
                }
6231
                if (offset)
6232
                    tcg_gen_addi_i32(addr, addr, offset);
6233
                tmp = tcg_const_i32(op1);
6234
                gen_helper_set_r13_banked(cpu_env, tmp, addr);
6235
                tcg_temp_free_i32(tmp);
6236
                tcg_temp_free_i32(addr);
6237
            } else {
6238
                tcg_temp_free_i32(addr);
6239
            }
6240
            return;
6241
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6242
            /* rfe */
6243
            int32_t offset;
6244
            if (IS_USER(s))
6245
                goto illegal_op;
6246
            ARCH(6);
6247
            rn = (insn >> 16) & 0xf;
6248
            addr = load_reg(s, rn);
6249
            i = (insn >> 23) & 3;
6250
            switch (i) {
6251
            case 0: offset = -4; break; /* DA */
6252
            case 1: offset = 0; break; /* IA */
6253
            case 2: offset = -8; break; /* DB */
6254
            case 3: offset = 4; break; /* IB */
6255
            default: abort();
6256
            }
6257
            if (offset)
6258
                tcg_gen_addi_i32(addr, addr, offset);
6259
            /* Load PC into tmp and CPSR into tmp2.  */
6260
            tmp = gen_ld32(addr, 0);
6261
            tcg_gen_addi_i32(addr, addr, 4);
6262
            tmp2 = gen_ld32(addr, 0);
6263
            if (insn & (1 << 21)) {
6264
                /* Base writeback.  */
6265
                switch (i) {
6266
                case 0: offset = -8; break;
6267
                case 1: offset = 4; break;
6268
                case 2: offset = -4; break;
6269
                case 3: offset = 0; break;
6270
                default: abort();
6271
                }
6272
                if (offset)
6273
                    tcg_gen_addi_i32(addr, addr, offset);
6274
                store_reg(s, rn, addr);
6275
            } else {
6276
                tcg_temp_free_i32(addr);
6277
            }
6278
            gen_rfe(s, tmp, tmp2);
6279
            return;
6280
        } else if ((insn & 0x0e000000) == 0x0a000000) {
6281
            /* branch link and change to thumb (blx <offset>) */
6282
            int32_t offset;
6283

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

    
6431
            /* branch link/exchange thumb (blx) */
6432
            tmp = load_reg(s, rm);
6433
            tmp2 = tcg_temp_new_i32();
6434
            tcg_gen_movi_i32(tmp2, s->pc);
6435
            store_reg(s, 14, tmp2);
6436
            gen_bx(s, tmp);
6437
            break;
6438
        case 0x5: /* saturating add/subtract */
6439
            rd = (insn >> 12) & 0xf;
6440
            rn = (insn >> 16) & 0xf;
6441
            tmp = load_reg(s, rm);
6442
            tmp2 = load_reg(s, rn);
6443
            if (op1 & 2)
6444
                gen_helper_double_saturate(tmp2, tmp2);
6445
            if (op1 & 1)
6446
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6447
            else
6448
                gen_helper_add_saturate(tmp, tmp, tmp2);
6449
            tcg_temp_free_i32(tmp2);
6450
            store_reg(s, rd, tmp);
6451
            break;
6452
        case 7:
6453
            /* SMC instruction (op1 == 3)
6454
               and undefined instructions (op1 == 0 || op1 == 2)
6455
               will trap */
6456
            if (op1 != 1) {
6457
                goto illegal_op;
6458
            }
6459
            /* bkpt */
6460
            gen_exception_insn(s, 4, EXCP_BKPT);
6461
            break;
6462
        case 0x8: /* signed multiply */
6463
        case 0xa:
6464
        case 0xc:
6465
        case 0xe:
6466
            rs = (insn >> 8) & 0xf;
6467
            rn = (insn >> 12) & 0xf;
6468
            rd = (insn >> 16) & 0xf;
6469
            if (op1 == 1) {
6470
                /* (32 * 16) >> 16 */
6471
                tmp = load_reg(s, rm);
6472
                tmp2 = load_reg(s, rs);
6473
                if (sh & 4)
6474
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6475
                else
6476
                    gen_sxth(tmp2);
6477
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
6478
                tcg_gen_shri_i64(tmp64, tmp64, 16);
6479
                tmp = tcg_temp_new_i32();
6480
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6481
                tcg_temp_free_i64(tmp64);
6482
                if ((sh & 2) == 0) {
6483
                    tmp2 = load_reg(s, rn);
6484
                    gen_helper_add_setq(tmp, tmp, tmp2);
6485
                    tcg_temp_free_i32(tmp2);
6486
                }
6487
                store_reg(s, rd, tmp);
6488
            } else {
6489
                /* 16 * 16 */
6490
                tmp = load_reg(s, rm);
6491
                tmp2 = load_reg(s, rs);
6492
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6493
                tcg_temp_free_i32(tmp2);
6494
                if (op1 == 2) {
6495
                    tmp64 = tcg_temp_new_i64();
6496
                    tcg_gen_ext_i32_i64(tmp64, tmp);
6497
                    tcg_temp_free_i32(tmp);
6498
                    gen_addq(s, tmp64, rn, rd);
6499
                    gen_storeq_reg(s, rn, rd, tmp64);
6500
                    tcg_temp_free_i64(tmp64);
6501
                } else {
6502
                    if (op1 == 0) {
6503
                        tmp2 = load_reg(s, rn);
6504
                        gen_helper_add_setq(tmp, tmp, tmp2);
6505
                        tcg_temp_free_i32(tmp2);
6506
                    }
6507
                    store_reg(s, rd, tmp);
6508
                }
6509
            }
6510
            break;
6511
        default:
6512
            goto illegal_op;
6513
        }
6514
    } else if (((insn & 0x0e000000) == 0 &&
6515
                (insn & 0x00000090) != 0x90) ||
6516
               ((insn & 0x0e000000) == (1 << 25))) {
6517
        int set_cc, logic_cc, shiftop;
6518

    
6519
        op1 = (insn >> 21) & 0xf;
6520
        set_cc = (insn >> 20) & 1;
6521
        logic_cc = table_logic_cc[op1] & set_cc;
6522

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

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

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

    
7219
                    if ((insn & (1 << 15)) == 0)
7220
                        user = 1;
7221
                }
7222
                rn = (insn >> 16) & 0xf;
7223
                addr = load_reg(s, rn);
7224

    
7225
                /* compute total size */
7226
                loaded_base = 0;
7227
                TCGV_UNUSED(loaded_var);
7228
                n = 0;
7229
                for(i=0;i<16;i++) {
7230
                    if (insn & (1 << i))
7231
                        n++;
7232
                }
7233
                /* XXX: test invalid n == 0 case ? */
7234
                if (insn & (1 << 23)) {
7235
                    if (insn & (1 << 24)) {
7236
                        /* pre increment */
7237
                        tcg_gen_addi_i32(addr, addr, 4);
7238
                    } else {
7239
                        /* post increment */
7240
                    }
7241
                } else {
7242
                    if (insn & (1 << 24)) {
7243
                        /* pre decrement */
7244
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
7245
                    } else {
7246
                        /* post decrement */
7247
                        if (n != 1)
7248
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7249
                    }
7250
                }
7251
                j = 0;
7252
                for(i=0;i<16;i++) {
7253
                    if (insn & (1 << i)) {
7254
                        if (insn & (1 << 20)) {
7255
                            /* load */
7256
                            tmp = gen_ld32(addr, IS_USER(s));
7257
                            if (i == 15) {
7258
                                gen_bx(s, tmp);
7259
                            } else if (user) {
7260
                                tmp2 = tcg_const_i32(i);
7261
                                gen_helper_set_user_reg(tmp2, tmp);
7262
                                tcg_temp_free_i32(tmp2);
7263
                                tcg_temp_free_i32(tmp);
7264
                            } else if (i == rn) {
7265
                                loaded_var = tmp;
7266
                                loaded_base = 1;
7267
                            } else {
7268
                                store_reg(s, i, tmp);
7269
                            }
7270
                        } else {
7271
                            /* store */
7272
                            if (i == 15) {
7273
                                /* special case: r15 = PC + 8 */
7274
                                val = (long)s->pc + 4;
7275
                                tmp = tcg_temp_new_i32();
7276
                                tcg_gen_movi_i32(tmp, val);
7277
                            } else if (user) {
7278
                                tmp = tcg_temp_new_i32();
7279
                                tmp2 = tcg_const_i32(i);
7280
                                gen_helper_get_user_reg(tmp, tmp2);
7281
                                tcg_temp_free_i32(tmp2);
7282
                            } else {
7283
                                tmp = load_reg(s, i);
7284
                            }
7285
                            gen_st32(tmp, addr, IS_USER(s));
7286
                        }
7287
                        j++;
7288
                        /* no need to add after the last transfer */
7289
                        if (j != n)
7290
                            tcg_gen_addi_i32(addr, addr, 4);
7291
                    }
7292
                }
7293
                if (insn & (1 << 21)) {
7294
                    /* write back */
7295
                    if (insn & (1 << 23)) {
7296
                        if (insn & (1 << 24)) {
7297
                            /* pre increment */
7298
                        } else {
7299
                            /* post increment */
7300
                            tcg_gen_addi_i32(addr, addr, 4);
7301
                        }
7302
                    } else {
7303
                        if (insn & (1 << 24)) {
7304
                            /* pre decrement */
7305
                            if (n != 1)
7306
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7307
                        } else {
7308
                            /* post decrement */
7309
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
7310
                        }
7311
                    }
7312
                    store_reg(s, rn, addr);
7313
                } else {
7314
                    tcg_temp_free_i32(addr);
7315
                }
7316
                if (loaded_base) {
7317
                    store_reg(s, rn, loaded_var);
7318
                }
7319
                if ((insn & (1 << 22)) && !user) {
7320
                    /* Restore CPSR from SPSR.  */
7321
                    tmp = load_cpu_field(spsr);
7322
                    gen_set_cpsr(tmp, 0xffffffff);
7323
                    tcg_temp_free_i32(tmp);
7324
                    s->is_jmp = DISAS_UPDATE;
7325
                }
7326
            }
7327
            break;
7328
        case 0xa:
7329
        case 0xb:
7330
            {
7331
                int32_t offset;
7332

    
7333
                /* branch (and link) */
7334
                val = (int32_t)s->pc;
7335
                if (insn & (1 << 24)) {
7336
                    tmp = tcg_temp_new_i32();
7337
                    tcg_gen_movi_i32(tmp, val);
7338
                    store_reg(s, 14, tmp);
7339
                }
7340
                offset = (((int32_t)insn << 8) >> 8);
7341
                val += (offset << 2) + 4;
7342
                gen_jmp(s, val);
7343
            }
7344
            break;
7345
        case 0xc:
7346
        case 0xd:
7347
        case 0xe:
7348
            /* Coprocessor.  */
7349
            if (disas_coproc_insn(env, s, insn))
7350
                goto illegal_op;
7351
            break;
7352
        case 0xf:
7353
            /* swi */
7354
            gen_set_pc_im(s->pc);
7355
            s->is_jmp = DISAS_SWI;
7356
            break;
7357
        default:
7358
        illegal_op:
7359
            gen_exception_insn(s, 4, EXCP_UDEF);
7360
            break;
7361
        }
7362
    }
7363
}
7364

    
7365
/* Return true if this is a Thumb-2 logical op.  */
7366
static int
7367
thumb2_logic_op(int op)
7368
{
7369
    return (op < 8);
7370
}
7371

    
7372
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
7373
   then set condition code flags based on the result of the operation.
7374
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7375
   to the high bit of T1.
7376
   Returns zero if the opcode is valid.  */
7377

    
7378
static int
7379
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7380
{
7381
    int logic_cc;
7382

    
7383
    logic_cc = 0;
7384
    switch (op) {
7385
    case 0: /* and */
7386
        tcg_gen_and_i32(t0, t0, t1);
7387
        logic_cc = conds;
7388
        break;
7389
    case 1: /* bic */
7390
        tcg_gen_andc_i32(t0, t0, t1);
7391
        logic_cc = conds;
7392
        break;
7393
    case 2: /* orr */
7394
        tcg_gen_or_i32(t0, t0, t1);
7395
        logic_cc = conds;
7396
        break;
7397
    case 3: /* orn */
7398
        tcg_gen_orc_i32(t0, t0, t1);
7399
        logic_cc = conds;
7400
        break;
7401
    case 4: /* eor */
7402
        tcg_gen_xor_i32(t0, t0, t1);
7403
        logic_cc = conds;
7404
        break;
7405
    case 8: /* add */
7406
        if (conds)
7407
            gen_helper_add_cc(t0, t0, t1);
7408
        else
7409
            tcg_gen_add_i32(t0, t0, t1);
7410
        break;
7411
    case 10: /* adc */
7412
        if (conds)
7413
            gen_helper_adc_cc(t0, t0, t1);
7414
        else
7415
            gen_adc(t0, t1);
7416
        break;
7417
    case 11: /* sbc */
7418
        if (conds)
7419
            gen_helper_sbc_cc(t0, t0, t1);
7420
        else
7421
            gen_sub_carry(t0, t0, t1);
7422
        break;
7423
    case 13: /* sub */
7424
        if (conds)
7425
            gen_helper_sub_cc(t0, t0, t1);
7426
        else
7427
            tcg_gen_sub_i32(t0, t0, t1);
7428
        break;
7429
    case 14: /* rsb */
7430
        if (conds)
7431
            gen_helper_sub_cc(t0, t1, t0);
7432
        else
7433
            tcg_gen_sub_i32(t0, t1, t0);
7434
        break;
7435
    default: /* 5, 6, 7, 9, 12, 15. */
7436
        return 1;
7437
    }
7438
    if (logic_cc) {
7439
        gen_logic_CC(t0);
7440
        if (shifter_out)
7441
            gen_set_CF_bit31(t1);
7442
    }
7443
    return 0;
7444
}
7445

    
7446
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7447
   is not legal.  */
7448
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7449
{
7450
    uint32_t insn, imm, shift, offset;
7451
    uint32_t rd, rn, rm, rs;
7452
    TCGv tmp;
7453
    TCGv tmp2;
7454
    TCGv tmp3;
7455
    TCGv addr;
7456
    TCGv_i64 tmp64;
7457
    int op;
7458
    int shiftop;
7459
    int conds;
7460
    int logic_cc;
7461

    
7462
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7463
          || arm_feature (env, ARM_FEATURE_M))) {
7464
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7465
           16-bit instructions to get correct prefetch abort behavior.  */
7466
        insn = insn_hw1;
7467
        if ((insn & (1 << 12)) == 0) {
7468
            /* Second half of blx.  */
7469
            offset = ((insn & 0x7ff) << 1);
7470
            tmp = load_reg(s, 14);
7471
            tcg_gen_addi_i32(tmp, tmp, offset);
7472
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7473

    
7474
            tmp2 = tcg_temp_new_i32();
7475
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7476
            store_reg(s, 14, tmp2);
7477
            gen_bx(s, tmp);
7478
            return 0;
7479
        }
7480
        if (insn & (1 << 11)) {
7481
            /* Second half of bl.  */
7482
            offset = ((insn & 0x7ff) << 1) | 1;
7483
            tmp = load_reg(s, 14);
7484
            tcg_gen_addi_i32(tmp, tmp, offset);
7485

    
7486
            tmp2 = tcg_temp_new_i32();
7487
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7488
            store_reg(s, 14, tmp2);
7489
            gen_bx(s, tmp);
7490
            return 0;
7491
        }
7492
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7493
            /* Instruction spans a page boundary.  Implement it as two
7494
               16-bit instructions in case the second half causes an
7495
               prefetch abort.  */
7496
            offset = ((int32_t)insn << 21) >> 9;
7497
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7498
            return 0;
7499
        }
7500
        /* Fall through to 32-bit decode.  */
7501
    }
7502

    
7503
    insn = lduw_code(s->pc);
7504
    s->pc += 2;
7505
    insn |= (uint32_t)insn_hw1 << 16;
7506

    
7507
    if ((insn & 0xf800e800) != 0xf000e800) {
7508
        ARCH(6T2);
7509
    }
7510

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

    
7680
                for (i = 0; i < 16; i++) {
7681
                    if ((insn & (1 << i)) == 0)
7682
                        continue;
7683
                    if (insn & (1 << 20)) {
7684
                        /* Load.  */
7685
                        tmp = gen_ld32(addr, IS_USER(s));
7686
                        if (i == 15) {
7687
                            gen_bx(s, tmp);
7688
                        } else {
7689
                            store_reg(s, i, tmp);
7690
                        }
7691
                    } else {
7692
                        /* Store.  */
7693
                        tmp = load_reg(s, i);
7694
                        gen_st32(tmp, addr, IS_USER(s));
7695
                    }
7696
                    tcg_gen_addi_i32(addr, addr, 4);
7697
                }
7698
                if (insn & (1 << 21)) {
7699
                    /* Base register writeback.  */
7700
                    if (insn & (1 << 24)) {
7701
                        tcg_gen_addi_i32(addr, addr, -offset);
7702
                    }
7703
                    /* Fault if writeback register is in register list.  */
7704
                    if (insn & (1 << rn))
7705
                        goto illegal_op;
7706
                    store_reg(s, rn, addr);
7707
                } else {
7708
                    tcg_temp_free_i32(addr);
7709
                }
7710
            }
7711
        }
7712
        break;
7713
    case 5:
7714

    
7715
        op = (insn >> 21) & 0xf;
7716
        if (op == 6) {
7717
            /* Halfword pack.  */
7718
            tmp = load_reg(s, rn);
7719
            tmp2 = load_reg(s, rm);
7720
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
7721
            if (insn & (1 << 5)) {
7722
                /* pkhtb */
7723
                if (shift == 0)
7724
                    shift = 31;
7725
                tcg_gen_sari_i32(tmp2, tmp2, shift);
7726
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7727
                tcg_gen_ext16u_i32(tmp2, tmp2);
7728
            } else {
7729
                /* pkhbt */
7730
                if (shift)
7731
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
7732
                tcg_gen_ext16u_i32(tmp, tmp);
7733
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7734
            }
7735
            tcg_gen_or_i32(tmp, tmp, tmp2);
7736
            tcg_temp_free_i32(tmp2);
7737
            store_reg(s, rd, tmp);
7738
        } else {
7739
            /* Data processing register constant shift.  */
7740
            if (rn == 15) {
7741
                tmp = tcg_temp_new_i32();
7742
                tcg_gen_movi_i32(tmp, 0);
7743
            } else {
7744
                tmp = load_reg(s, rn);
7745
            }
7746
            tmp2 = load_reg(s, rm);
7747

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

    
8052
                if (insn & (1 << 14)) {
8053
                    /* Branch and link.  */
8054
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8055
                }
8056

    
8057
                offset += s->pc;
8058
                if (insn & (1 << 12)) {
8059
                    /* b/bl */
8060
                    gen_jmp(s, offset);
8061
                } else {
8062
                    /* blx */
8063
                    offset &= ~(uint32_t)2;
8064
                    gen_bx_im(s, offset);
8065
                }
8066
            } else if (((insn >> 23) & 7) == 7) {
8067
                /* Misc control */
8068
                if (insn & (1 << 13))
8069
                    goto illegal_op;
8070

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

    
8184
                /* offset[11:1] = insn[10:0] */
8185
                offset = (insn & 0x7ff) << 1;
8186
                /* offset[17:12] = insn[21:16].  */
8187
                offset |= (insn & 0x003f0000) >> 4;
8188
                /* offset[31:20] = insn[26].  */
8189
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8190
                /* offset[18] = insn[13].  */
8191
                offset |= (insn & (1 << 13)) << 5;
8192
                /* offset[19] = insn[11].  */
8193
                offset |= (insn & (1 << 11)) << 8;
8194

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

    
8503
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8504
{
8505
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8506
    int32_t offset;
8507
    int i;
8508
    TCGv tmp;
8509
    TCGv tmp2;
8510
    TCGv addr;
8511

    
8512
    if (s->condexec_mask) {
8513
        cond = s->condexec_cond;
8514
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
8515
          s->condlabel = gen_new_label();
8516
          gen_test_cc(cond ^ 1, s->condlabel);
8517
          s->condjmp = 1;
8518
        }
8519
    }
8520

    
8521
    insn = lduw_code(s->pc);
8522
    s->pc += 2;
8523

    
8524
    switch (insn >> 12) {
8525
    case 0: case 1:
8526

    
8527
        rd = insn & 7;
8528
        op = (insn >> 11) & 3;
8529
        if (op == 3) {
8530
            /* add/subtract */
8531
            rn = (insn >> 3) & 7;
8532
            tmp = load_reg(s, rn);
8533
            if (insn & (1 << 10)) {
8534
                /* immediate */
8535
                tmp2 = tcg_temp_new_i32();
8536
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
8537
            } else {
8538
                /* reg */
8539
                rm = (insn >> 6) & 7;
8540
                tmp2 = load_reg(s, rm);
8541
            }
8542
            if (insn & (1 << 9)) {
8543
                if (s->condexec_mask)
8544
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8545
                else
8546
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8547
            } else {
8548
                if (s->condexec_mask)
8549
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8550
                else
8551
                    gen_helper_add_cc(tmp, tmp, tmp2);
8552
            }
8553
            tcg_temp_free_i32(tmp2);
8554
            store_reg(s, rd, tmp);
8555
        } else {
8556
            /* shift immediate */
8557
            rm = (insn >> 3) & 7;
8558
            shift = (insn >> 6) & 0x1f;
8559
            tmp = load_reg(s, rm);
8560
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8561
            if (!s->condexec_mask)
8562
                gen_logic_CC(tmp);
8563
            store_reg(s, rd, tmp);
8564
        }
8565
        break;
8566
    case 2: case 3:
8567
        /* arithmetic large immediate */
8568
        op = (insn >> 11) & 3;
8569
        rd = (insn >> 8) & 0x7;
8570
        if (op == 0) { /* mov */
8571
            tmp = tcg_temp_new_i32();
8572
            tcg_gen_movi_i32(tmp, insn & 0xff);
8573
            if (!s->condexec_mask)
8574
                gen_logic_CC(tmp);
8575
            store_reg(s, rd, tmp);
8576
        } else {
8577
            tmp = load_reg(s, rd);
8578
            tmp2 = tcg_temp_new_i32();
8579
            tcg_gen_movi_i32(tmp2, insn & 0xff);
8580
            switch (op) {
8581
            case 1: /* cmp */
8582
                gen_helper_sub_cc(tmp, tmp, tmp2);
8583
                tcg_temp_free_i32(tmp);
8584
                tcg_temp_free_i32(tmp2);
8585
                break;
8586
            case 2: /* add */
8587
                if (s->condexec_mask)
8588
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8589
                else
8590
                    gen_helper_add_cc(tmp, tmp, tmp2);
8591
                tcg_temp_free_i32(tmp2);
8592
                store_reg(s, rd, tmp);
8593
                break;
8594
            case 3: /* sub */
8595
                if (s->condexec_mask)
8596
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8597
                else
8598
                    gen_helper_sub_cc(tmp, tmp, tmp2);
8599
                tcg_temp_free_i32(tmp2);
8600
                store_reg(s, rd, tmp);
8601
                break;
8602
            }
8603
        }
8604
        break;
8605
    case 4:
8606
        if (insn & (1 << 11)) {
8607
            rd = (insn >> 8) & 7;
8608
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8609
            val = s->pc + 2 + ((insn & 0xff) * 4);
8610
            val &= ~(uint32_t)2;
8611
            addr = tcg_temp_new_i32();
8612
            tcg_gen_movi_i32(addr, val);
8613
            tmp = gen_ld32(addr, IS_USER(s));
8614
            tcg_temp_free_i32(addr);
8615
            store_reg(s, rd, tmp);
8616
            break;
8617
        }
8618
        if (insn & (1 << 10)) {
8619
            /* data processing extended or blx */
8620
            rd = (insn & 7) | ((insn >> 4) & 8);
8621
            rm = (insn >> 3) & 0xf;
8622
            op = (insn >> 8) & 3;
8623
            switch (op) {
8624
            case 0: /* add */
8625
                tmp = load_reg(s, rd);
8626
                tmp2 = load_reg(s, rm);
8627
                tcg_gen_add_i32(tmp, tmp, tmp2);
8628
                tcg_temp_free_i32(tmp2);
8629
                store_reg(s, rd, tmp);
8630
                break;
8631
            case 1: /* cmp */
8632
                tmp = load_reg(s, rd);
8633
                tmp2 = load_reg(s, rm);
8634
                gen_helper_sub_cc(tmp, tmp, tmp2);
8635
                tcg_temp_free_i32(tmp2);
8636
                tcg_temp_free_i32(tmp);
8637
                break;
8638
            case 2: /* mov/cpy */
8639
                tmp = load_reg(s, rm);
8640
                store_reg(s, rd, tmp);
8641
                break;
8642
            case 3:/* branch [and link] exchange thumb register */
8643
                tmp = load_reg(s, rm);
8644
                if (insn & (1 << 7)) {
8645
                    val = (uint32_t)s->pc | 1;
8646
                    tmp2 = tcg_temp_new_i32();
8647
                    tcg_gen_movi_i32(tmp2, val);
8648
                    store_reg(s, 14, tmp2);
8649
                }
8650
                gen_bx(s, tmp);
8651
                break;
8652
            }
8653
            break;
8654
        }
8655

    
8656
        /* data processing register */
8657
        rd = insn & 7;
8658
        rm = (insn >> 3) & 7;
8659
        op = (insn >> 6) & 0xf;
8660
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8661
            /* the shift/rotate ops want the operands backwards */
8662
            val = rm;
8663
            rm = rd;
8664
            rd = val;
8665
            val = 1;
8666
        } else {
8667
            val = 0;
8668
        }
8669

    
8670
        if (op == 9) { /* neg */
8671
            tmp = tcg_temp_new_i32();
8672
            tcg_gen_movi_i32(tmp, 0);
8673
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
8674
            tmp = load_reg(s, rd);
8675
        } else {
8676
            TCGV_UNUSED(tmp);
8677
        }
8678

    
8679
        tmp2 = load_reg(s, rm);
8680
        switch (op) {
8681
        case 0x0: /* and */
8682
            tcg_gen_and_i32(tmp, tmp, tmp2);
8683
            if (!s->condexec_mask)
8684
                gen_logic_CC(tmp);
8685
            break;
8686
        case 0x1: /* eor */
8687
            tcg_gen_xor_i32(tmp, tmp, tmp2);
8688
            if (!s->condexec_mask)
8689
                gen_logic_CC(tmp);
8690
            break;
8691
        case 0x2: /* lsl */
8692
            if (s->condexec_mask) {
8693
                gen_helper_shl(tmp2, tmp2, tmp);
8694
            } else {
8695
                gen_helper_shl_cc(tmp2, tmp2, tmp);
8696
                gen_logic_CC(tmp2);
8697
            }
8698
            break;
8699
        case 0x3: /* lsr */
8700
            if (s->condexec_mask) {
8701
                gen_helper_shr(tmp2, tmp2, tmp);
8702
            } else {
8703
                gen_helper_shr_cc(tmp2, tmp2, tmp);
8704
                gen_logic_CC(tmp2);
8705
            }
8706
            break;
8707
        case 0x4: /* asr */
8708
            if (s->condexec_mask) {
8709
                gen_helper_sar(tmp2, tmp2, tmp);
8710
            } else {
8711
                gen_helper_sar_cc(tmp2, tmp2, tmp);
8712
                gen_logic_CC(tmp2);
8713
            }
8714
            break;
8715
        case 0x5: /* adc */
8716
            if (s->condexec_mask)
8717
                gen_adc(tmp, tmp2);
8718
            else
8719
                gen_helper_adc_cc(tmp, tmp, tmp2);
8720
            break;
8721
        case 0x6: /* sbc */
8722
            if (s->condexec_mask)
8723
                gen_sub_carry(tmp, tmp, tmp2);
8724
            else
8725
                gen_helper_sbc_cc(tmp, tmp, tmp2);
8726
            break;
8727
        case 0x7: /* ror */
8728
            if (s->condexec_mask) {
8729
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
8730
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
8731
            } else {
8732
                gen_helper_ror_cc(tmp2, tmp2, tmp);
8733
                gen_logic_CC(tmp2);
8734
            }
8735
            break;
8736
        case 0x8: /* tst */
8737
            tcg_gen_and_i32(tmp, tmp, tmp2);
8738
            gen_logic_CC(tmp);
8739
            rd = 16;
8740
            break;
8741
        case 0x9: /* neg */
8742
            if (s->condexec_mask)
8743
                tcg_gen_neg_i32(tmp, tmp2);
8744
            else
8745
                gen_helper_sub_cc(tmp, tmp, tmp2);
8746
            break;
8747
        case 0xa: /* cmp */
8748
            gen_helper_sub_cc(tmp, tmp, tmp2);
8749
            rd = 16;
8750
            break;
8751
        case 0xb: /* cmn */
8752
            gen_helper_add_cc(tmp, tmp, tmp2);
8753
            rd = 16;
8754
            break;
8755
        case 0xc: /* orr */
8756
            tcg_gen_or_i32(tmp, tmp, tmp2);
8757
            if (!s->condexec_mask)
8758
                gen_logic_CC(tmp);
8759
            break;
8760
        case 0xd: /* mul */
8761
            tcg_gen_mul_i32(tmp, tmp, tmp2);
8762
            if (!s->condexec_mask)
8763
                gen_logic_CC(tmp);
8764
            break;
8765
        case 0xe: /* bic */
8766
            tcg_gen_andc_i32(tmp, tmp, tmp2);
8767
            if (!s->condexec_mask)
8768
                gen_logic_CC(tmp);
8769
            break;
8770
        case 0xf: /* mvn */
8771
            tcg_gen_not_i32(tmp2, tmp2);
8772
            if (!s->condexec_mask)
8773
                gen_logic_CC(tmp2);
8774
            val = 1;
8775
            rm = rd;
8776
            break;
8777
        }
8778
        if (rd != 16) {
8779
            if (val) {
8780
                store_reg(s, rm, tmp2);
8781
                if (op != 0xf)
8782
                    tcg_temp_free_i32(tmp);
8783
            } else {
8784
                store_reg(s, rd, tmp);
8785
                tcg_temp_free_i32(tmp2);
8786
            }
8787
        } else {
8788
            tcg_temp_free_i32(tmp);
8789
            tcg_temp_free_i32(tmp2);
8790
        }
8791
        break;
8792

    
8793
    case 5:
8794
        /* load/store register offset.  */
8795
        rd = insn & 7;
8796
        rn = (insn >> 3) & 7;
8797
        rm = (insn >> 6) & 7;
8798
        op = (insn >> 9) & 7;
8799
        addr = load_reg(s, rn);
8800
        tmp = load_reg(s, rm);
8801
        tcg_gen_add_i32(addr, addr, tmp);
8802
        tcg_temp_free_i32(tmp);
8803

    
8804
        if (op < 3) /* store */
8805
            tmp = load_reg(s, rd);
8806

    
8807
        switch (op) {
8808
        case 0: /* str */
8809
            gen_st32(tmp, addr, IS_USER(s));
8810
            break;
8811
        case 1: /* strh */
8812
            gen_st16(tmp, addr, IS_USER(s));
8813
            break;
8814
        case 2: /* strb */
8815
            gen_st8(tmp, addr, IS_USER(s));
8816
            break;
8817
        case 3: /* ldrsb */
8818
            tmp = gen_ld8s(addr, IS_USER(s));
8819
            break;
8820
        case 4: /* ldr */
8821
            tmp = gen_ld32(addr, IS_USER(s));
8822
            break;
8823
        case 5: /* ldrh */
8824
            tmp = gen_ld16u(addr, IS_USER(s));
8825
            break;
8826
        case 6: /* ldrb */
8827
            tmp = gen_ld8u(addr, IS_USER(s));
8828
            break;
8829
        case 7: /* ldrsh */
8830
            tmp = gen_ld16s(addr, IS_USER(s));
8831
            break;
8832
        }
8833
        if (op >= 3) /* load */
8834
            store_reg(s, rd, tmp);
8835
        tcg_temp_free_i32(addr);
8836
        break;
8837

    
8838
    case 6:
8839
        /* load/store word immediate offset */
8840
        rd = insn & 7;
8841
        rn = (insn >> 3) & 7;
8842
        addr = load_reg(s, rn);
8843
        val = (insn >> 4) & 0x7c;
8844
        tcg_gen_addi_i32(addr, addr, val);
8845

    
8846
        if (insn & (1 << 11)) {
8847
            /* load */
8848
            tmp = gen_ld32(addr, IS_USER(s));
8849
            store_reg(s, rd, tmp);
8850
        } else {
8851
            /* store */
8852
            tmp = load_reg(s, rd);
8853
            gen_st32(tmp, addr, IS_USER(s));
8854
        }
8855
        tcg_temp_free_i32(addr);
8856
        break;
8857

    
8858
    case 7:
8859
        /* load/store byte immediate offset */
8860
        rd = insn & 7;
8861
        rn = (insn >> 3) & 7;
8862
        addr = load_reg(s, rn);
8863
        val = (insn >> 6) & 0x1f;
8864
        tcg_gen_addi_i32(addr, addr, val);
8865

    
8866
        if (insn & (1 << 11)) {
8867
            /* load */
8868
            tmp = gen_ld8u(addr, IS_USER(s));
8869
            store_reg(s, rd, tmp);
8870
        } else {
8871
            /* store */
8872
            tmp = load_reg(s, rd);
8873
            gen_st8(tmp, addr, IS_USER(s));
8874
        }
8875
        tcg_temp_free_i32(addr);
8876
        break;
8877

    
8878
    case 8:
8879
        /* load/store halfword immediate offset */
8880
        rd = insn & 7;
8881
        rn = (insn >> 3) & 7;
8882
        addr = load_reg(s, rn);
8883
        val = (insn >> 5) & 0x3e;
8884
        tcg_gen_addi_i32(addr, addr, val);
8885

    
8886
        if (insn & (1 << 11)) {
8887
            /* load */
8888
            tmp = gen_ld16u(addr, IS_USER(s));
8889
            store_reg(s, rd, tmp);
8890
        } else {
8891
            /* store */
8892
            tmp = load_reg(s, rd);
8893
            gen_st16(tmp, addr, IS_USER(s));
8894
        }
8895
        tcg_temp_free_i32(addr);
8896
        break;
8897

    
8898
    case 9:
8899
        /* load/store from stack */
8900
        rd = (insn >> 8) & 7;
8901
        addr = load_reg(s, 13);
8902
        val = (insn & 0xff) * 4;
8903
        tcg_gen_addi_i32(addr, addr, val);
8904

    
8905
        if (insn & (1 << 11)) {
8906
            /* load */
8907
            tmp = gen_ld32(addr, IS_USER(s));
8908
            store_reg(s, rd, tmp);
8909
        } else {
8910
            /* store */
8911
            tmp = load_reg(s, rd);
8912
            gen_st32(tmp, addr, IS_USER(s));
8913
        }
8914
        tcg_temp_free_i32(addr);
8915
        break;
8916

    
8917
    case 10:
8918
        /* add to high reg */
8919
        rd = (insn >> 8) & 7;
8920
        if (insn & (1 << 11)) {
8921
            /* SP */
8922
            tmp = load_reg(s, 13);
8923
        } else {
8924
            /* PC. bit 1 is ignored.  */
8925
            tmp = tcg_temp_new_i32();
8926
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8927
        }
8928
        val = (insn & 0xff) * 4;
8929
        tcg_gen_addi_i32(tmp, tmp, val);
8930
        store_reg(s, rd, tmp);
8931
        break;
8932

    
8933
    case 11:
8934
        /* misc */
8935
        op = (insn >> 8) & 0xf;
8936
        switch (op) {
8937
        case 0:
8938
            /* adjust stack pointer */
8939
            tmp = load_reg(s, 13);
8940
            val = (insn & 0x7f) * 4;
8941
            if (insn & (1 << 7))
8942
                val = -(int32_t)val;
8943
            tcg_gen_addi_i32(tmp, tmp, val);
8944
            store_reg(s, 13, tmp);
8945
            break;
8946

    
8947
        case 2: /* sign/zero extend.  */
8948
            ARCH(6);
8949
            rd = insn & 7;
8950
            rm = (insn >> 3) & 7;
8951
            tmp = load_reg(s, rm);
8952
            switch ((insn >> 6) & 3) {
8953
            case 0: gen_sxth(tmp); break;
8954
            case 1: gen_sxtb(tmp); break;
8955
            case 2: gen_uxth(tmp); break;
8956
            case 3: gen_uxtb(tmp); break;
8957
            }
8958
            store_reg(s, rd, tmp);
8959
            break;
8960
        case 4: case 5: case 0xc: case 0xd:
8961
            /* push/pop */
8962
            addr = load_reg(s, 13);
8963
            if (insn & (1 << 8))
8964
                offset = 4;
8965
            else
8966
                offset = 0;
8967
            for (i = 0; i < 8; i++) {
8968
                if (insn & (1 << i))
8969
                    offset += 4;
8970
            }
8971
            if ((insn & (1 << 11)) == 0) {
8972
                tcg_gen_addi_i32(addr, addr, -offset);
8973
            }
8974
            for (i = 0; i < 8; i++) {
8975
                if (insn & (1 << i)) {
8976
                    if (insn & (1 << 11)) {
8977
                        /* pop */
8978
                        tmp = gen_ld32(addr, IS_USER(s));
8979
                        store_reg(s, i, tmp);
8980
                    } else {
8981
                        /* push */
8982
                        tmp = load_reg(s, i);
8983
                        gen_st32(tmp, addr, IS_USER(s));
8984
                    }
8985
                    /* advance to the next address.  */
8986
                    tcg_gen_addi_i32(addr, addr, 4);
8987
                }
8988
            }
8989
            TCGV_UNUSED(tmp);
8990
            if (insn & (1 << 8)) {
8991
                if (insn & (1 << 11)) {
8992
                    /* pop pc */
8993
                    tmp = gen_ld32(addr, IS_USER(s));
8994
                    /* don't set the pc until the rest of the instruction
8995
                       has completed */
8996
                } else {
8997
                    /* push lr */
8998
                    tmp = load_reg(s, 14);
8999
                    gen_st32(tmp, addr, IS_USER(s));
9000
                }
9001
                tcg_gen_addi_i32(addr, addr, 4);
9002
            }
9003
            if ((insn & (1 << 11)) == 0) {
9004
                tcg_gen_addi_i32(addr, addr, -offset);
9005
            }
9006
            /* write back the new stack pointer */
9007
            store_reg(s, 13, addr);
9008
            /* set the new PC value */
9009
            if ((insn & 0x0900) == 0x0900)
9010
                gen_bx(s, tmp);
9011
            break;
9012

    
9013
        case 1: case 3: case 9: case 11: /* czb */
9014
            rm = insn & 7;
9015
            tmp = load_reg(s, rm);
9016
            s->condlabel = gen_new_label();
9017
            s->condjmp = 1;
9018
            if (insn & (1 << 11))
9019
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9020
            else
9021
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9022
            tcg_temp_free_i32(tmp);
9023
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9024
            val = (uint32_t)s->pc + 2;
9025
            val += offset;
9026
            gen_jmp(s, val);
9027
            break;
9028

    
9029
        case 15: /* IT, nop-hint.  */
9030
            if ((insn & 0xf) == 0) {
9031
                gen_nop_hint(s, (insn >> 4) & 0xf);
9032
                break;
9033
            }
9034
            /* If Then.  */
9035
            s->condexec_cond = (insn >> 4) & 0xe;
9036
            s->condexec_mask = insn & 0x1f;
9037
            /* No actual code generated for this insn, just setup state.  */
9038
            break;
9039

    
9040
        case 0xe: /* bkpt */
9041
            gen_exception_insn(s, 2, EXCP_BKPT);
9042
            break;
9043

    
9044
        case 0xa: /* rev */
9045
            ARCH(6);
9046
            rn = (insn >> 3) & 0x7;
9047
            rd = insn & 0x7;
9048
            tmp = load_reg(s, rn);
9049
            switch ((insn >> 6) & 3) {
9050
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9051
            case 1: gen_rev16(tmp); break;
9052
            case 3: gen_revsh(tmp); break;
9053
            default: goto illegal_op;
9054
            }
9055
            store_reg(s, rd, tmp);
9056
            break;
9057

    
9058
        case 6: /* cps */
9059
            ARCH(6);
9060
            if (IS_USER(s))
9061
                break;
9062
            if (IS_M(env)) {
9063
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9064
                /* PRIMASK */
9065
                if (insn & 1) {
9066
                    addr = tcg_const_i32(16);
9067
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9068
                    tcg_temp_free_i32(addr);
9069
                }
9070
                /* FAULTMASK */
9071
                if (insn & 2) {
9072
                    addr = tcg_const_i32(17);
9073
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
9074
                    tcg_temp_free_i32(addr);
9075
                }
9076
                tcg_temp_free_i32(tmp);
9077
                gen_lookup_tb(s);
9078
            } else {
9079
                if (insn & (1 << 4))
9080
                    shift = CPSR_A | CPSR_I | CPSR_F;
9081
                else
9082
                    shift = 0;
9083
                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9084
            }
9085
            break;
9086

    
9087
        default:
9088
            goto undef;
9089
        }
9090
        break;
9091

    
9092
    case 12:
9093
        /* load/store multiple */
9094
        rn = (insn >> 8) & 0x7;
9095
        addr = load_reg(s, rn);
9096
        for (i = 0; i < 8; i++) {
9097
            if (insn & (1 << i)) {
9098
                if (insn & (1 << 11)) {
9099
                    /* load */
9100
                    tmp = gen_ld32(addr, IS_USER(s));
9101
                    store_reg(s, i, tmp);
9102
                } else {
9103
                    /* store */
9104
                    tmp = load_reg(s, i);
9105
                    gen_st32(tmp, addr, IS_USER(s));
9106
                }
9107
                /* advance to the next address */
9108
                tcg_gen_addi_i32(addr, addr, 4);
9109
            }
9110
        }
9111
        /* Base register writeback.  */
9112
        if ((insn & (1 << rn)) == 0) {
9113
            store_reg(s, rn, addr);
9114
        } else {
9115
            tcg_temp_free_i32(addr);
9116
        }
9117
        break;
9118

    
9119
    case 13:
9120
        /* conditional branch or swi */
9121
        cond = (insn >> 8) & 0xf;
9122
        if (cond == 0xe)
9123
            goto undef;
9124

    
9125
        if (cond == 0xf) {
9126
            /* swi */
9127
            gen_set_pc_im(s->pc);
9128
            s->is_jmp = DISAS_SWI;
9129
            break;
9130
        }
9131
        /* generate a conditional jump to next instruction */
9132
        s->condlabel = gen_new_label();
9133
        gen_test_cc(cond ^ 1, s->condlabel);
9134
        s->condjmp = 1;
9135

    
9136
        /* jump to the offset */
9137
        val = (uint32_t)s->pc + 2;
9138
        offset = ((int32_t)insn << 24) >> 24;
9139
        val += offset << 1;
9140
        gen_jmp(s, val);
9141
        break;
9142

    
9143
    case 14:
9144
        if (insn & (1 << 11)) {
9145
            if (disas_thumb2_insn(env, s, insn))
9146
              goto undef32;
9147
            break;
9148
        }
9149
        /* unconditional branch */
9150
        val = (uint32_t)s->pc;
9151
        offset = ((int32_t)insn << 21) >> 21;
9152
        val += (offset << 1) + 2;
9153
        gen_jmp(s, val);
9154
        break;
9155

    
9156
    case 15:
9157
        if (disas_thumb2_insn(env, s, insn))
9158
            goto undef32;
9159
        break;
9160
    }
9161
    return;
9162
undef32:
9163
    gen_exception_insn(s, 4, EXCP_UDEF);
9164
    return;
9165
illegal_op:
9166
undef:
9167
    gen_exception_insn(s, 2, EXCP_UDEF);
9168
}
9169

    
9170
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9171
   basic block 'tb'. If search_pc is TRUE, also generate PC
9172
   information for each intermediate instruction. */
9173
static inline void gen_intermediate_code_internal(CPUState *env,
9174
                                                  TranslationBlock *tb,
9175
                                                  int search_pc)
9176
{
9177
    DisasContext dc1, *dc = &dc1;
9178
    CPUBreakpoint *bp;
9179
    uint16_t *gen_opc_end;
9180
    int j, lj;
9181
    target_ulong pc_start;
9182
    uint32_t next_page_start;
9183
    int num_insns;
9184
    int max_insns;
9185

    
9186
    /* generate intermediate code */
9187
    pc_start = tb->pc;
9188

    
9189
    dc->tb = tb;
9190

    
9191
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9192

    
9193
    dc->is_jmp = DISAS_NEXT;
9194
    dc->pc = pc_start;
9195
    dc->singlestep_enabled = env->singlestep_enabled;
9196
    dc->condjmp = 0;
9197
    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9198
    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9199
    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9200
#if !defined(CONFIG_USER_ONLY)
9201
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9202
#endif
9203
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9204
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9205
    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9206
    cpu_F0s = tcg_temp_new_i32();
9207
    cpu_F1s = tcg_temp_new_i32();
9208
    cpu_F0d = tcg_temp_new_i64();
9209
    cpu_F1d = tcg_temp_new_i64();
9210
    cpu_V0 = cpu_F0d;
9211
    cpu_V1 = cpu_F1d;
9212
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
9213
    cpu_M0 = tcg_temp_new_i64();
9214
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9215
    lj = -1;
9216
    num_insns = 0;
9217
    max_insns = tb->cflags & CF_COUNT_MASK;
9218
    if (max_insns == 0)
9219
        max_insns = CF_COUNT_MASK;
9220

    
9221
    gen_icount_start();
9222

    
9223
    tcg_clear_temp_count();
9224

    
9225
    /* A note on handling of the condexec (IT) bits:
9226
     *
9227
     * We want to avoid the overhead of having to write the updated condexec
9228
     * bits back to the CPUState for every instruction in an IT block. So:
9229
     * (1) if the condexec bits are not already zero then we write
9230
     * zero back into the CPUState now. This avoids complications trying
9231
     * to do it at the end of the block. (For example if we don't do this
9232
     * it's hard to identify whether we can safely skip writing condexec
9233
     * at the end of the TB, which we definitely want to do for the case
9234
     * where a TB doesn't do anything with the IT state at all.)
9235
     * (2) if we are going to leave the TB then we call gen_set_condexec()
9236
     * which will write the correct value into CPUState if zero is wrong.
9237
     * This is done both for leaving the TB at the end, and for leaving
9238
     * it because of an exception we know will happen, which is done in
9239
     * gen_exception_insn(). The latter is necessary because we need to
9240
     * leave the TB with the PC/IT state just prior to execution of the
9241
     * instruction which caused the exception.
9242
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9243
     * then the CPUState will be wrong and we need to reset it.
9244
     * This is handled in the same way as restoration of the
9245
     * PC in these situations: we will be called again with search_pc=1
9246
     * and generate a mapping of the condexec bits for each PC in
9247
     * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
9248
     * the condexec bits.
9249
     *
9250
     * Note that there are no instructions which can read the condexec
9251
     * bits, and none which can write non-static values to them, so
9252
     * we don't need to care about whether CPUState is correct in the
9253
     * middle of a TB.
9254
     */
9255

    
9256
    /* Reset the conditional execution bits immediately. This avoids
9257
       complications trying to do it at the end of the block.  */
9258
    if (dc->condexec_mask || dc->condexec_cond)
9259
      {
9260
        TCGv tmp = tcg_temp_new_i32();
9261
        tcg_gen_movi_i32(tmp, 0);
9262
        store_cpu_field(tmp, condexec_bits);
9263
      }
9264
    do {
9265
#ifdef CONFIG_USER_ONLY
9266
        /* Intercept jump to the magic kernel page.  */
9267
        if (dc->pc >= 0xffff0000) {
9268
            /* We always get here via a jump, so know we are not in a
9269
               conditional execution block.  */
9270
            gen_exception(EXCP_KERNEL_TRAP);
9271
            dc->is_jmp = DISAS_UPDATE;
9272
            break;
9273
        }
9274
#else
9275
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9276
            /* We always get here via a jump, so know we are not in a
9277
               conditional execution block.  */
9278
            gen_exception(EXCP_EXCEPTION_EXIT);
9279
            dc->is_jmp = DISAS_UPDATE;
9280
            break;
9281
        }
9282
#endif
9283

    
9284
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9285
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9286
                if (bp->pc == dc->pc) {
9287
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
9288
                    /* Advance PC so that clearing the breakpoint will
9289
                       invalidate this TB.  */
9290
                    dc->pc += 2;
9291
                    goto done_generating;
9292
                    break;
9293
                }
9294
            }
9295
        }
9296
        if (search_pc) {
9297
            j = gen_opc_ptr - gen_opc_buf;
9298
            if (lj < j) {
9299
                lj++;
9300
                while (lj < j)
9301
                    gen_opc_instr_start[lj++] = 0;
9302
            }
9303
            gen_opc_pc[lj] = dc->pc;
9304
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9305
            gen_opc_instr_start[lj] = 1;
9306
            gen_opc_icount[lj] = num_insns;
9307
        }
9308

    
9309
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9310
            gen_io_start();
9311

    
9312
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
9313
            tcg_gen_debug_insn_start(dc->pc);
9314
        }
9315

    
9316
        if (dc->thumb) {
9317
            disas_thumb_insn(env, dc);
9318
            if (dc->condexec_mask) {
9319
                dc->condexec_cond = (dc->condexec_cond & 0xe)
9320
                                   | ((dc->condexec_mask >> 4) & 1);
9321
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9322
                if (dc->condexec_mask == 0) {
9323
                    dc->condexec_cond = 0;
9324
                }
9325
            }
9326
        } else {
9327
            disas_arm_insn(env, dc);
9328
        }
9329

    
9330
        if (dc->condjmp && !dc->is_jmp) {
9331
            gen_set_label(dc->condlabel);
9332
            dc->condjmp = 0;
9333
        }
9334

    
9335
        if (tcg_check_temp_count()) {
9336
            fprintf(stderr, "TCG temporary leak before %08x\n", dc->pc);
9337
        }
9338

    
9339
        /* Translation stops when a conditional branch is encountered.
9340
         * Otherwise the subsequent code could get translated several times.
9341
         * Also stop translation when a page boundary is reached.  This
9342
         * ensures prefetch aborts occur at the right place.  */
9343
        num_insns ++;
9344
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
9345
             !env->singlestep_enabled &&
9346
             !singlestep &&
9347
             dc->pc < next_page_start &&
9348
             num_insns < max_insns);
9349

    
9350
    if (tb->cflags & CF_LAST_IO) {
9351
        if (dc->condjmp) {
9352
            /* FIXME:  This can theoretically happen with self-modifying
9353
               code.  */
9354
            cpu_abort(env, "IO on conditional branch instruction");
9355
        }
9356
        gen_io_end();
9357
    }
9358

    
9359
    /* At this stage dc->condjmp will only be set when the skipped
9360
       instruction was a conditional branch or trap, and the PC has
9361
       already been written.  */
9362
    if (unlikely(env->singlestep_enabled)) {
9363
        /* Make sure the pc is updated, and raise a debug exception.  */
9364
        if (dc->condjmp) {
9365
            gen_set_condexec(dc);
9366
            if (dc->is_jmp == DISAS_SWI) {
9367
                gen_exception(EXCP_SWI);
9368
            } else {
9369
                gen_exception(EXCP_DEBUG);
9370
            }
9371
            gen_set_label(dc->condlabel);
9372
        }
9373
        if (dc->condjmp || !dc->is_jmp) {
9374
            gen_set_pc_im(dc->pc);
9375
            dc->condjmp = 0;
9376
        }
9377
        gen_set_condexec(dc);
9378
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9379
            gen_exception(EXCP_SWI);
9380
        } else {
9381
            /* FIXME: Single stepping a WFI insn will not halt
9382
               the CPU.  */
9383
            gen_exception(EXCP_DEBUG);
9384
        }
9385
    } else {
9386
        /* While branches must always occur at the end of an IT block,
9387
           there are a few other things that can cause us to terminate
9388
           the TB in the middel of an IT block:
9389
            - Exception generating instructions (bkpt, swi, undefined).
9390
            - Page boundaries.
9391
            - Hardware watchpoints.
9392
           Hardware breakpoints have already been handled and skip this code.
9393
         */
9394
        gen_set_condexec(dc);
9395
        switch(dc->is_jmp) {
9396
        case DISAS_NEXT:
9397
            gen_goto_tb(dc, 1, dc->pc);
9398
            break;
9399
        default:
9400
        case DISAS_JUMP:
9401
        case DISAS_UPDATE:
9402
            /* indicate that the hash table must be used to find the next TB */
9403
            tcg_gen_exit_tb(0);
9404
            break;
9405
        case DISAS_TB_JUMP:
9406
            /* nothing more to generate */
9407
            break;
9408
        case DISAS_WFI:
9409
            gen_helper_wfi();
9410
            break;
9411
        case DISAS_SWI:
9412
            gen_exception(EXCP_SWI);
9413
            break;
9414
        }
9415
        if (dc->condjmp) {
9416
            gen_set_label(dc->condlabel);
9417
            gen_set_condexec(dc);
9418
            gen_goto_tb(dc, 1, dc->pc);
9419
            dc->condjmp = 0;
9420
        }
9421
    }
9422

    
9423
done_generating:
9424
    gen_icount_end(tb, num_insns);
9425
    *gen_opc_ptr = INDEX_op_end;
9426

    
9427
#ifdef DEBUG_DISAS
9428
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9429
        qemu_log("----------------\n");
9430
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9431
        log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);
9432
        qemu_log("\n");
9433
    }
9434
#endif
9435
    if (search_pc) {
9436
        j = gen_opc_ptr - gen_opc_buf;
9437
        lj++;
9438
        while (lj <= j)
9439
            gen_opc_instr_start[lj++] = 0;
9440
    } else {
9441
        tb->size = dc->pc - pc_start;
9442
        tb->icount = num_insns;
9443
    }
9444
}
9445

    
9446
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
9447
{
9448
    gen_intermediate_code_internal(env, tb, 0);
9449
}
9450

    
9451
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
9452
{
9453
    gen_intermediate_code_internal(env, tb, 1);
9454
}
9455

    
9456
static const char *cpu_mode_names[16] = {
9457
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
9458
  "???", "???", "???", "und", "???", "???", "???", "sys"
9459
};
9460

    
9461
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
9462
                    int flags)
9463
{
9464
    int i;
9465
#if 0
9466
    union {
9467
        uint32_t i;
9468
        float s;
9469
    } s0, s1;
9470
    CPU_DoubleU d;
9471
    /* ??? This assumes float64 and double have the same layout.
9472
       Oh well, it's only debug dumps.  */
9473
    union {
9474
        float64 f64;
9475
        double d;
9476
    } d0;
9477
#endif
9478
    uint32_t psr;
9479

    
9480
    for(i=0;i<16;i++) {
9481
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
9482
        if ((i % 4) == 3)
9483
            cpu_fprintf(f, "\n");
9484
        else
9485
            cpu_fprintf(f, " ");
9486
    }
9487
    psr = cpsr_read(env);
9488
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
9489
                psr,
9490
                psr & (1 << 31) ? 'N' : '-',
9491
                psr & (1 << 30) ? 'Z' : '-',
9492
                psr & (1 << 29) ? 'C' : '-',
9493
                psr & (1 << 28) ? 'V' : '-',
9494
                psr & CPSR_T ? 'T' : 'A',
9495
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
9496

    
9497
#if 0
9498
    for (i = 0; i < 16; i++) {
9499
        d.d = env->vfp.regs[i];
9500
        s0.i = d.l.lower;
9501
        s1.i = d.l.upper;
9502
        d0.f64 = d.d;
9503
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
9504
                    i * 2, (int)s0.i, s0.s,
9505
                    i * 2 + 1, (int)s1.i, s1.s,
9506
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
9507
                    d0.d);
9508
    }
9509
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
9510
#endif
9511
}
9512

    
9513
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9514
                unsigned long searched_pc, int pc_pos, void *puc)
9515
{
9516
    env->regs[15] = gen_opc_pc[pc_pos];
9517
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
9518
}