Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 288eebe5

History | View | Annotate | Download (300.1 kB)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
112
static int num_temps;
113

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

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

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

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

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

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

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

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

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

    
182

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

    
188
#define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
189
#define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
190
#define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
191
#define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
192

    
193
#define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
194
#define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
195
#define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
196
#define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
197
#define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
198

    
199
#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
200
#define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
201
#define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
202
#define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
203
#define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
204
#define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
205
#define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
206

    
207
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
208
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
209

    
210
/* Value extensions.  */
211
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
212
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
213
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
214
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
215

    
216
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
217
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
218

    
219
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
220

    
221
#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
222
/* Set NZCV flags from the high 4 bits of var.  */
223
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
224

    
225
static void gen_exception(int excp)
226
{
227
    TCGv tmp = new_tmp();
228
    tcg_gen_movi_i32(tmp, excp);
229
    gen_helper_exception(tmp);
230
    dead_tmp(tmp);
231
}
232

    
233
static void gen_smul_dual(TCGv a, TCGv b)
234
{
235
    TCGv tmp1 = new_tmp();
236
    TCGv tmp2 = new_tmp();
237
    tcg_gen_ext16s_i32(tmp1, a);
238
    tcg_gen_ext16s_i32(tmp2, b);
239
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
240
    dead_tmp(tmp2);
241
    tcg_gen_sari_i32(a, a, 16);
242
    tcg_gen_sari_i32(b, b, 16);
243
    tcg_gen_mul_i32(b, b, a);
244
    tcg_gen_mov_i32(a, tmp1);
245
    dead_tmp(tmp1);
246
}
247

    
248
/* Byteswap each halfword.  */
249
static void gen_rev16(TCGv var)
250
{
251
    TCGv tmp = new_tmp();
252
    tcg_gen_shri_i32(tmp, var, 8);
253
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
254
    tcg_gen_shli_i32(var, var, 8);
255
    tcg_gen_andi_i32(var, var, 0xff00ff00);
256
    tcg_gen_or_i32(var, var, tmp);
257
    dead_tmp(tmp);
258
}
259

    
260
/* Byteswap low halfword and sign extend.  */
261
static void gen_revsh(TCGv var)
262
{
263
    TCGv tmp = new_tmp();
264
    tcg_gen_shri_i32(tmp, var, 8);
265
    tcg_gen_andi_i32(tmp, tmp, 0x00ff);
266
    tcg_gen_shli_i32(var, var, 8);
267
    tcg_gen_ext8s_i32(var, var);
268
    tcg_gen_or_i32(var, var, tmp);
269
    dead_tmp(tmp);
270
}
271

    
272
/* Unsigned bitfield extract.  */
273
static void gen_ubfx(TCGv var, int shift, uint32_t mask)
274
{
275
    if (shift)
276
        tcg_gen_shri_i32(var, var, shift);
277
    tcg_gen_andi_i32(var, var, mask);
278
}
279

    
280
/* Signed bitfield extract.  */
281
static void gen_sbfx(TCGv var, int shift, int width)
282
{
283
    uint32_t signbit;
284

    
285
    if (shift)
286
        tcg_gen_sari_i32(var, var, shift);
287
    if (shift + width < 32) {
288
        signbit = 1u << (width - 1);
289
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
290
        tcg_gen_xori_i32(var, var, signbit);
291
        tcg_gen_subi_i32(var, var, signbit);
292
    }
293
}
294

    
295
/* Bitfield insertion.  Insert val into base.  Clobbers base and val.  */
296
static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
297
{
298
    tcg_gen_andi_i32(val, val, mask);
299
    tcg_gen_shli_i32(val, val, shift);
300
    tcg_gen_andi_i32(base, base, ~(mask << shift));
301
    tcg_gen_or_i32(dest, base, val);
302
}
303

    
304
/* Round the top 32 bits of a 64-bit value.  */
305
static void gen_roundqd(TCGv a, TCGv b)
306
{
307
    tcg_gen_shri_i32(a, a, 31);
308
    tcg_gen_add_i32(a, a, b);
309
}
310

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

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

    
327
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
328
{
329
    TCGv_i64 tmp1 = tcg_temp_new_i64();
330
    TCGv_i64 tmp2 = tcg_temp_new_i64();
331

    
332
    tcg_gen_ext_i32_i64(tmp1, a);
333
    dead_tmp(a);
334
    tcg_gen_ext_i32_i64(tmp2, b);
335
    dead_tmp(b);
336
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
337
    return tmp1;
338
}
339

    
340
/* Unsigned 32x32->64 multiply.  */
341
static void gen_op_mull_T0_T1(void)
342
{
343
    TCGv_i64 tmp1 = tcg_temp_new_i64();
344
    TCGv_i64 tmp2 = tcg_temp_new_i64();
345

    
346
    tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
347
    tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
348
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
349
    tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
350
    tcg_gen_shri_i64(tmp1, tmp1, 32);
351
    tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
352
}
353

    
354
/* Signed 32x32->64 multiply.  */
355
static void gen_imull(TCGv a, TCGv b)
356
{
357
    TCGv_i64 tmp1 = tcg_temp_new_i64();
358
    TCGv_i64 tmp2 = tcg_temp_new_i64();
359

    
360
    tcg_gen_ext_i32_i64(tmp1, a);
361
    tcg_gen_ext_i32_i64(tmp2, b);
362
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
363
    tcg_gen_trunc_i64_i32(a, tmp1);
364
    tcg_gen_shri_i64(tmp1, tmp1, 32);
365
    tcg_gen_trunc_i64_i32(b, tmp1);
366
}
367

    
368
/* Swap low and high halfwords.  */
369
static void gen_swap_half(TCGv var)
370
{
371
    TCGv tmp = new_tmp();
372
    tcg_gen_shri_i32(tmp, var, 16);
373
    tcg_gen_shli_i32(var, var, 16);
374
    tcg_gen_or_i32(var, var, tmp);
375
    dead_tmp(tmp);
376
}
377

    
378
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
379
    tmp = (t0 ^ t1) & 0x8000;
380
    t0 &= ~0x8000;
381
    t1 &= ~0x8000;
382
    t0 = (t0 + t1) ^ tmp;
383
 */
384

    
385
static void gen_add16(TCGv t0, TCGv t1)
386
{
387
    TCGv tmp = new_tmp();
388
    tcg_gen_xor_i32(tmp, t0, t1);
389
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
390
    tcg_gen_andi_i32(t0, t0, ~0x8000);
391
    tcg_gen_andi_i32(t1, t1, ~0x8000);
392
    tcg_gen_add_i32(t0, t0, t1);
393
    tcg_gen_xor_i32(t0, t0, tmp);
394
    dead_tmp(tmp);
395
    dead_tmp(t1);
396
}
397

    
398
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
399

    
400
/* Set CF to the top bit of var.  */
401
static void gen_set_CF_bit31(TCGv var)
402
{
403
    TCGv tmp = new_tmp();
404
    tcg_gen_shri_i32(tmp, var, 31);
405
    gen_set_CF(tmp);
406
    dead_tmp(tmp);
407
}
408

    
409
/* Set N and Z flags from var.  */
410
static inline void gen_logic_CC(TCGv var)
411
{
412
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
413
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
414
}
415

    
416
/* T0 += T1 + CF.  */
417
static void gen_adc_T0_T1(void)
418
{
419
    TCGv tmp;
420
    gen_op_addl_T0_T1();
421
    tmp = load_cpu_field(CF);
422
    tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
423
    dead_tmp(tmp);
424
}
425

    
426
/* dest = T0 + T1 + CF. */
427
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
428
{
429
    TCGv tmp;
430
    tcg_gen_add_i32(dest, t0, t1);
431
    tmp = load_cpu_field(CF);
432
    tcg_gen_add_i32(dest, dest, tmp);
433
    dead_tmp(tmp);
434
}
435

    
436
/* dest = T0 - T1 + CF - 1.  */
437
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
438
{
439
    TCGv tmp;
440
    tcg_gen_sub_i32(dest, t0, t1);
441
    tmp = load_cpu_field(CF);
442
    tcg_gen_add_i32(dest, dest, tmp);
443
    tcg_gen_subi_i32(dest, dest, 1);
444
    dead_tmp(tmp);
445
}
446

    
447
#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
448
#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
449

    
450
/* T0 &= ~T1.  Clobbers T1.  */
451
/* FIXME: Implement bic natively.  */
452
static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
453
{
454
    TCGv tmp = new_tmp();
455
    tcg_gen_not_i32(tmp, t1);
456
    tcg_gen_and_i32(dest, t0, tmp);
457
    dead_tmp(tmp);
458
}
459
static inline void gen_op_bicl_T0_T1(void)
460
{
461
    gen_op_notl_T1();
462
    gen_op_andl_T0_T1();
463
}
464

    
465
/* FIXME:  Implement this natively.  */
466
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
467

    
468
/* FIXME:  Implement this natively.  */
469
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
470
{
471
    TCGv tmp;
472

    
473
    if (i == 0)
474
        return;
475

    
476
    tmp = new_tmp();
477
    tcg_gen_shri_i32(tmp, t1, i);
478
    tcg_gen_shli_i32(t1, t1, 32 - i);
479
    tcg_gen_or_i32(t0, t1, tmp);
480
    dead_tmp(tmp);
481
}
482

    
483
static void shifter_out_im(TCGv var, int shift)
484
{
485
    TCGv tmp = new_tmp();
486
    if (shift == 0) {
487
        tcg_gen_andi_i32(tmp, var, 1);
488
    } else {
489
        tcg_gen_shri_i32(tmp, var, shift);
490
        if (shift != 31)
491
            tcg_gen_andi_i32(tmp, tmp, 1);
492
    }
493
    gen_set_CF(tmp);
494
    dead_tmp(tmp);
495
}
496

    
497
/* Shift by immediate.  Includes special handling for shift == 0.  */
498
static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
499
{
500
    switch (shiftop) {
501
    case 0: /* LSL */
502
        if (shift != 0) {
503
            if (flags)
504
                shifter_out_im(var, 32 - shift);
505
            tcg_gen_shli_i32(var, var, shift);
506
        }
507
        break;
508
    case 1: /* LSR */
509
        if (shift == 0) {
510
            if (flags) {
511
                tcg_gen_shri_i32(var, var, 31);
512
                gen_set_CF(var);
513
            }
514
            tcg_gen_movi_i32(var, 0);
515
        } else {
516
            if (flags)
517
                shifter_out_im(var, shift - 1);
518
            tcg_gen_shri_i32(var, var, shift);
519
        }
520
        break;
521
    case 2: /* ASR */
522
        if (shift == 0)
523
            shift = 32;
524
        if (flags)
525
            shifter_out_im(var, shift - 1);
526
        if (shift == 32)
527
          shift = 31;
528
        tcg_gen_sari_i32(var, var, shift);
529
        break;
530
    case 3: /* ROR/RRX */
531
        if (shift != 0) {
532
            if (flags)
533
                shifter_out_im(var, shift - 1);
534
            tcg_gen_rori_i32(var, var, shift); break;
535
        } else {
536
            TCGv tmp = load_cpu_field(CF);
537
            if (flags)
538
                shifter_out_im(var, 0);
539
            tcg_gen_shri_i32(var, var, 1);
540
            tcg_gen_shli_i32(tmp, tmp, 31);
541
            tcg_gen_or_i32(var, var, tmp);
542
            dead_tmp(tmp);
543
        }
544
    }
545
};
546

    
547
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
548
                                     TCGv shift, int flags)
549
{
550
    if (flags) {
551
        switch (shiftop) {
552
        case 0: gen_helper_shl_cc(var, var, shift); break;
553
        case 1: gen_helper_shr_cc(var, var, shift); break;
554
        case 2: gen_helper_sar_cc(var, var, shift); break;
555
        case 3: gen_helper_ror_cc(var, var, shift); break;
556
        }
557
    } else {
558
        switch (shiftop) {
559
        case 0: gen_helper_shl(var, var, shift); break;
560
        case 1: gen_helper_shr(var, var, shift); break;
561
        case 2: gen_helper_sar(var, var, shift); break;
562
        case 3: gen_helper_ror(var, var, shift); break;
563
        }
564
    }
565
    dead_tmp(shift);
566
}
567

    
568
#define PAS_OP(pfx) \
569
    switch (op2) {  \
570
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
571
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
572
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
573
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
574
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
575
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
576
    }
577
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
578
{
579
    TCGv_ptr tmp;
580

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

    
612
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
613
#define PAS_OP(pfx) \
614
    switch (op2) {  \
615
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
616
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
617
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
618
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
619
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
620
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
621
    }
622
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
623
{
624
    TCGv_ptr tmp;
625

    
626
    switch (op1) {
627
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
628
    case 0:
629
        tmp = tcg_temp_new_ptr();
630
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
631
        PAS_OP(s)
632
        break;
633
    case 4:
634
        tmp = tcg_temp_new_ptr();
635
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
636
        PAS_OP(u)
637
        break;
638
#undef gen_pas_helper
639
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
640
    case 1:
641
        PAS_OP(q);
642
        break;
643
    case 2:
644
        PAS_OP(sh);
645
        break;
646
    case 5:
647
        PAS_OP(uq);
648
        break;
649
    case 6:
650
        PAS_OP(uh);
651
        break;
652
#undef gen_pas_helper
653
    }
654
}
655
#undef PAS_OP
656

    
657
static void gen_test_cc(int cc, int label)
658
{
659
    TCGv tmp;
660
    TCGv tmp2;
661
    int inv;
662

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

    
755
static const uint8_t table_logic_cc[16] = {
756
    1, /* and */
757
    1, /* xor */
758
    0, /* sub */
759
    0, /* rsb */
760
    0, /* add */
761
    0, /* adc */
762
    0, /* sbc */
763
    0, /* rsc */
764
    1, /* andl */
765
    1, /* xorl */
766
    0, /* cmp */
767
    0, /* cmn */
768
    1, /* orr */
769
    1, /* mov */
770
    1, /* bic */
771
    1, /* mvn */
772
};
773

    
774
/* Set PC and Thumb state from an immediate address.  */
775
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
776
{
777
    TCGv tmp;
778

    
779
    s->is_jmp = DISAS_UPDATE;
780
    if (s->thumb != (addr & 1)) {
781
        tmp = new_tmp();
782
        tcg_gen_movi_i32(tmp, addr & 1);
783
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
784
        dead_tmp(tmp);
785
    }
786
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
787
}
788

    
789
/* Set PC and Thumb state from var.  var is marked as dead.  */
790
static inline void gen_bx(DisasContext *s, TCGv var)
791
{
792
    s->is_jmp = DISAS_UPDATE;
793
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
794
    tcg_gen_andi_i32(var, var, 1);
795
    store_cpu_field(var, thumb);
796
}
797

    
798
/* Variant of store_reg which uses branch&exchange logic when storing
799
   to r15 in ARM architecture v7 and above. The source must be a temporary
800
   and will be marked as dead. */
801
static inline void store_reg_bx(CPUState *env, DisasContext *s,
802
                                int reg, TCGv var)
803
{
804
    if (reg == 15 && ENABLE_ARCH_7) {
805
        gen_bx(s, var);
806
    } else {
807
        store_reg(s, reg, var);
808
    }
809
}
810

    
811
static inline TCGv gen_ld8s(TCGv addr, int index)
812
{
813
    TCGv tmp = new_tmp();
814
    tcg_gen_qemu_ld8s(tmp, addr, index);
815
    return tmp;
816
}
817
static inline TCGv gen_ld8u(TCGv addr, int index)
818
{
819
    TCGv tmp = new_tmp();
820
    tcg_gen_qemu_ld8u(tmp, addr, index);
821
    return tmp;
822
}
823
static inline TCGv gen_ld16s(TCGv addr, int index)
824
{
825
    TCGv tmp = new_tmp();
826
    tcg_gen_qemu_ld16s(tmp, addr, index);
827
    return tmp;
828
}
829
static inline TCGv gen_ld16u(TCGv addr, int index)
830
{
831
    TCGv tmp = new_tmp();
832
    tcg_gen_qemu_ld16u(tmp, addr, index);
833
    return tmp;
834
}
835
static inline TCGv gen_ld32(TCGv addr, int index)
836
{
837
    TCGv tmp = new_tmp();
838
    tcg_gen_qemu_ld32u(tmp, addr, index);
839
    return tmp;
840
}
841
static inline void gen_st8(TCGv val, TCGv addr, int index)
842
{
843
    tcg_gen_qemu_st8(val, addr, index);
844
    dead_tmp(val);
845
}
846
static inline void gen_st16(TCGv val, TCGv addr, int index)
847
{
848
    tcg_gen_qemu_st16(val, addr, index);
849
    dead_tmp(val);
850
}
851
static inline void gen_st32(TCGv val, TCGv addr, int index)
852
{
853
    tcg_gen_qemu_st32(val, addr, index);
854
    dead_tmp(val);
855
}
856

    
857
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
858
{
859
    load_reg_var(s, cpu_T[0], reg);
860
}
861

    
862
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
863
{
864
    load_reg_var(s, cpu_T[1], reg);
865
}
866

    
867
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
868
{
869
    load_reg_var(s, cpu_T[2], reg);
870
}
871

    
872
static inline void gen_set_pc_im(uint32_t val)
873
{
874
    tcg_gen_movi_i32(cpu_R[15], val);
875
}
876

    
877
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
878
{
879
    TCGv tmp;
880
    if (reg == 15) {
881
        tmp = new_tmp();
882
        tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
883
    } else {
884
        tmp = cpu_T[t];
885
    }
886
    tcg_gen_mov_i32(cpu_R[reg], tmp);
887
    if (reg == 15) {
888
        dead_tmp(tmp);
889
        s->is_jmp = DISAS_JUMP;
890
    }
891
}
892

    
893
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
894
{
895
    gen_movl_reg_TN(s, reg, 0);
896
}
897

    
898
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
899
{
900
    gen_movl_reg_TN(s, reg, 1);
901
}
902

    
903
/* Force a TB lookup after an instruction that changes the CPU state.  */
904
static inline void gen_lookup_tb(DisasContext *s)
905
{
906
    gen_op_movl_T0_im(s->pc);
907
    gen_movl_reg_T0(s, 15);
908
    s->is_jmp = DISAS_UPDATE;
909
}
910

    
911
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
912
                                       TCGv var)
913
{
914
    int val, rm, shift, shiftop;
915
    TCGv offset;
916

    
917
    if (!(insn & (1 << 25))) {
918
        /* immediate */
919
        val = insn & 0xfff;
920
        if (!(insn & (1 << 23)))
921
            val = -val;
922
        if (val != 0)
923
            tcg_gen_addi_i32(var, var, val);
924
    } else {
925
        /* shift/register */
926
        rm = (insn) & 0xf;
927
        shift = (insn >> 7) & 0x1f;
928
        shiftop = (insn >> 5) & 3;
929
        offset = load_reg(s, rm);
930
        gen_arm_shift_im(offset, shiftop, shift, 0);
931
        if (!(insn & (1 << 23)))
932
            tcg_gen_sub_i32(var, var, offset);
933
        else
934
            tcg_gen_add_i32(var, var, offset);
935
        dead_tmp(offset);
936
    }
937
}
938

    
939
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
940
                                        int extra, TCGv var)
941
{
942
    int val, rm;
943
    TCGv offset;
944

    
945
    if (insn & (1 << 22)) {
946
        /* immediate */
947
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
948
        if (!(insn & (1 << 23)))
949
            val = -val;
950
        val += extra;
951
        if (val != 0)
952
            tcg_gen_addi_i32(var, var, val);
953
    } else {
954
        /* register */
955
        if (extra)
956
            tcg_gen_addi_i32(var, var, extra);
957
        rm = (insn) & 0xf;
958
        offset = load_reg(s, rm);
959
        if (!(insn & (1 << 23)))
960
            tcg_gen_sub_i32(var, var, offset);
961
        else
962
            tcg_gen_add_i32(var, var, offset);
963
        dead_tmp(offset);
964
    }
965
}
966

    
967
#define VFP_OP2(name)                                                 \
968
static inline void gen_vfp_##name(int dp)                             \
969
{                                                                     \
970
    if (dp)                                                           \
971
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
972
    else                                                              \
973
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
974
}
975

    
976
VFP_OP2(add)
977
VFP_OP2(sub)
978
VFP_OP2(mul)
979
VFP_OP2(div)
980

    
981
#undef VFP_OP2
982

    
983
static inline void gen_vfp_abs(int dp)
984
{
985
    if (dp)
986
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
987
    else
988
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
989
}
990

    
991
static inline void gen_vfp_neg(int dp)
992
{
993
    if (dp)
994
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
995
    else
996
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
997
}
998

    
999
static inline void gen_vfp_sqrt(int dp)
1000
{
1001
    if (dp)
1002
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1003
    else
1004
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1005
}
1006

    
1007
static inline void gen_vfp_cmp(int dp)
1008
{
1009
    if (dp)
1010
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1011
    else
1012
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1013
}
1014

    
1015
static inline void gen_vfp_cmpe(int dp)
1016
{
1017
    if (dp)
1018
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1019
    else
1020
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1021
}
1022

    
1023
static inline void gen_vfp_F1_ld0(int dp)
1024
{
1025
    if (dp)
1026
        tcg_gen_movi_i64(cpu_F1d, 0);
1027
    else
1028
        tcg_gen_movi_i32(cpu_F1s, 0);
1029
}
1030

    
1031
static inline void gen_vfp_uito(int dp)
1032
{
1033
    if (dp)
1034
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1035
    else
1036
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1037
}
1038

    
1039
static inline void gen_vfp_sito(int dp)
1040
{
1041
    if (dp)
1042
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1043
    else
1044
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1045
}
1046

    
1047
static inline void gen_vfp_toui(int dp)
1048
{
1049
    if (dp)
1050
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1051
    else
1052
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1053
}
1054

    
1055
static inline void gen_vfp_touiz(int dp)
1056
{
1057
    if (dp)
1058
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1059
    else
1060
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1061
}
1062

    
1063
static inline void gen_vfp_tosi(int dp)
1064
{
1065
    if (dp)
1066
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1067
    else
1068
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1069
}
1070

    
1071
static inline void gen_vfp_tosiz(int dp)
1072
{
1073
    if (dp)
1074
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1075
    else
1076
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1077
}
1078

    
1079
#define VFP_GEN_FIX(name) \
1080
static inline void gen_vfp_##name(int dp, int shift) \
1081
{ \
1082
    if (dp) \
1083
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1084
    else \
1085
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1086
}
1087
VFP_GEN_FIX(tosh)
1088
VFP_GEN_FIX(tosl)
1089
VFP_GEN_FIX(touh)
1090
VFP_GEN_FIX(toul)
1091
VFP_GEN_FIX(shto)
1092
VFP_GEN_FIX(slto)
1093
VFP_GEN_FIX(uhto)
1094
VFP_GEN_FIX(ulto)
1095
#undef VFP_GEN_FIX
1096

    
1097
static inline void gen_vfp_ld(DisasContext *s, int dp)
1098
{
1099
    if (dp)
1100
        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1101
    else
1102
        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1103
}
1104

    
1105
static inline void gen_vfp_st(DisasContext *s, int dp)
1106
{
1107
    if (dp)
1108
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1109
    else
1110
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1111
}
1112

    
1113
static inline long
1114
vfp_reg_offset (int dp, int reg)
1115
{
1116
    if (dp)
1117
        return offsetof(CPUARMState, vfp.regs[reg]);
1118
    else if (reg & 1) {
1119
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1120
          + offsetof(CPU_DoubleU, l.upper);
1121
    } else {
1122
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1123
          + offsetof(CPU_DoubleU, l.lower);
1124
    }
1125
}
1126

    
1127
/* Return the offset of a 32-bit piece of a NEON register.
1128
   zero is the least significant end of the register.  */
1129
static inline long
1130
neon_reg_offset (int reg, int n)
1131
{
1132
    int sreg;
1133
    sreg = reg * 2 + n;
1134
    return vfp_reg_offset(0, sreg);
1135
}
1136

    
1137
/* FIXME: Remove these.  */
1138
#define neon_T0 cpu_T[0]
1139
#define neon_T1 cpu_T[1]
1140
#define NEON_GET_REG(T, reg, n) \
1141
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1142
#define NEON_SET_REG(T, reg, n) \
1143
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1144

    
1145
static TCGv neon_load_reg(int reg, int pass)
1146
{
1147
    TCGv tmp = new_tmp();
1148
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1149
    return tmp;
1150
}
1151

    
1152
static void neon_store_reg(int reg, int pass, TCGv var)
1153
{
1154
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1155
    dead_tmp(var);
1156
}
1157

    
1158
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1159
{
1160
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1161
}
1162

    
1163
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1164
{
1165
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1166
}
1167

    
1168
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1169
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1170
#define tcg_gen_st_f32 tcg_gen_st_i32
1171
#define tcg_gen_st_f64 tcg_gen_st_i64
1172

    
1173
static inline void gen_mov_F0_vreg(int dp, int reg)
1174
{
1175
    if (dp)
1176
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1177
    else
1178
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1179
}
1180

    
1181
static inline void gen_mov_F1_vreg(int dp, int reg)
1182
{
1183
    if (dp)
1184
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1185
    else
1186
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1187
}
1188

    
1189
static inline void gen_mov_vreg_F0(int dp, int reg)
1190
{
1191
    if (dp)
1192
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1193
    else
1194
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1195
}
1196

    
1197
#define ARM_CP_RW_BIT        (1 << 20)
1198

    
1199
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1200
{
1201
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1202
}
1203

    
1204
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1205
{
1206
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1207
}
1208

    
1209
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1210
{
1211
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1212
}
1213

    
1214
static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1215
{
1216
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1217
}
1218

    
1219
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1220
{
1221
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1222
}
1223

    
1224
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1225
{
1226
    iwmmxt_store_reg(cpu_M0, rn);
1227
}
1228

    
1229
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1230
{
1231
    iwmmxt_load_reg(cpu_M0, rn);
1232
}
1233

    
1234
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1235
{
1236
    iwmmxt_load_reg(cpu_V1, rn);
1237
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1238
}
1239

    
1240
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1241
{
1242
    iwmmxt_load_reg(cpu_V1, rn);
1243
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1244
}
1245

    
1246
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1247
{
1248
    iwmmxt_load_reg(cpu_V1, rn);
1249
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1250
}
1251

    
1252
#define IWMMXT_OP(name) \
1253
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1254
{ \
1255
    iwmmxt_load_reg(cpu_V1, rn); \
1256
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1257
}
1258

    
1259
#define IWMMXT_OP_ENV(name) \
1260
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1261
{ \
1262
    iwmmxt_load_reg(cpu_V1, rn); \
1263
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1264
}
1265

    
1266
#define IWMMXT_OP_ENV_SIZE(name) \
1267
IWMMXT_OP_ENV(name##b) \
1268
IWMMXT_OP_ENV(name##w) \
1269
IWMMXT_OP_ENV(name##l)
1270

    
1271
#define IWMMXT_OP_ENV1(name) \
1272
static inline void gen_op_iwmmxt_##name##_M0(void) \
1273
{ \
1274
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1275
}
1276

    
1277
IWMMXT_OP(maddsq)
1278
IWMMXT_OP(madduq)
1279
IWMMXT_OP(sadb)
1280
IWMMXT_OP(sadw)
1281
IWMMXT_OP(mulslw)
1282
IWMMXT_OP(mulshw)
1283
IWMMXT_OP(mululw)
1284
IWMMXT_OP(muluhw)
1285
IWMMXT_OP(macsw)
1286
IWMMXT_OP(macuw)
1287

    
1288
IWMMXT_OP_ENV_SIZE(unpackl)
1289
IWMMXT_OP_ENV_SIZE(unpackh)
1290

    
1291
IWMMXT_OP_ENV1(unpacklub)
1292
IWMMXT_OP_ENV1(unpackluw)
1293
IWMMXT_OP_ENV1(unpacklul)
1294
IWMMXT_OP_ENV1(unpackhub)
1295
IWMMXT_OP_ENV1(unpackhuw)
1296
IWMMXT_OP_ENV1(unpackhul)
1297
IWMMXT_OP_ENV1(unpacklsb)
1298
IWMMXT_OP_ENV1(unpacklsw)
1299
IWMMXT_OP_ENV1(unpacklsl)
1300
IWMMXT_OP_ENV1(unpackhsb)
1301
IWMMXT_OP_ENV1(unpackhsw)
1302
IWMMXT_OP_ENV1(unpackhsl)
1303

    
1304
IWMMXT_OP_ENV_SIZE(cmpeq)
1305
IWMMXT_OP_ENV_SIZE(cmpgtu)
1306
IWMMXT_OP_ENV_SIZE(cmpgts)
1307

    
1308
IWMMXT_OP_ENV_SIZE(mins)
1309
IWMMXT_OP_ENV_SIZE(minu)
1310
IWMMXT_OP_ENV_SIZE(maxs)
1311
IWMMXT_OP_ENV_SIZE(maxu)
1312

    
1313
IWMMXT_OP_ENV_SIZE(subn)
1314
IWMMXT_OP_ENV_SIZE(addn)
1315
IWMMXT_OP_ENV_SIZE(subu)
1316
IWMMXT_OP_ENV_SIZE(addu)
1317
IWMMXT_OP_ENV_SIZE(subs)
1318
IWMMXT_OP_ENV_SIZE(adds)
1319

    
1320
IWMMXT_OP_ENV(avgb0)
1321
IWMMXT_OP_ENV(avgb1)
1322
IWMMXT_OP_ENV(avgw0)
1323
IWMMXT_OP_ENV(avgw1)
1324

    
1325
IWMMXT_OP(msadb)
1326

    
1327
IWMMXT_OP_ENV(packuw)
1328
IWMMXT_OP_ENV(packul)
1329
IWMMXT_OP_ENV(packuq)
1330
IWMMXT_OP_ENV(packsw)
1331
IWMMXT_OP_ENV(packsl)
1332
IWMMXT_OP_ENV(packsq)
1333

    
1334
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1335
{
1336
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1337
}
1338

    
1339
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1340
{
1341
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1342
}
1343

    
1344
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1345
{
1346
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1347
}
1348

    
1349
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1350
{
1351
    iwmmxt_load_reg(cpu_V1, rn);
1352
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1353
}
1354

    
1355
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1356
{
1357
    TCGv tmp = tcg_const_i32(shift);
1358
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1359
}
1360

    
1361
static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1362
{
1363
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1364
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1365
    tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1366
}
1367

    
1368
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1369
{
1370
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1371
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1372
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1373
}
1374

    
1375
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1376
{
1377
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1378
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1379
    if (mask != ~0u)
1380
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1381
}
1382

    
1383
static void gen_op_iwmmxt_set_mup(void)
1384
{
1385
    TCGv tmp;
1386
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1387
    tcg_gen_ori_i32(tmp, tmp, 2);
1388
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1389
}
1390

    
1391
static void gen_op_iwmmxt_set_cup(void)
1392
{
1393
    TCGv tmp;
1394
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1395
    tcg_gen_ori_i32(tmp, tmp, 1);
1396
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1397
}
1398

    
1399
static void gen_op_iwmmxt_setpsr_nz(void)
1400
{
1401
    TCGv tmp = new_tmp();
1402
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1403
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1404
}
1405

    
1406
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1407
{
1408
    iwmmxt_load_reg(cpu_V1, rn);
1409
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1410
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1411
}
1412

    
1413

    
1414
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1415
{
1416
    iwmmxt_load_reg(cpu_V0, rn);
1417
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1418
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1419
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1420
}
1421

    
1422
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1423
{
1424
    tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
1425
    iwmmxt_store_reg(cpu_V0, rn);
1426
}
1427

    
1428
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1429
{
1430
    int rd;
1431
    uint32_t offset;
1432

    
1433
    rd = (insn >> 16) & 0xf;
1434
    gen_movl_T1_reg(s, rd);
1435

    
1436
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1437
    if (insn & (1 << 24)) {
1438
        /* Pre indexed */
1439
        if (insn & (1 << 23))
1440
            gen_op_addl_T1_im(offset);
1441
        else
1442
            gen_op_addl_T1_im(-offset);
1443

    
1444
        if (insn & (1 << 21))
1445
            gen_movl_reg_T1(s, rd);
1446
    } else if (insn & (1 << 21)) {
1447
        /* Post indexed */
1448
        if (insn & (1 << 23))
1449
            gen_op_movl_T0_im(offset);
1450
        else
1451
            gen_op_movl_T0_im(- offset);
1452
        gen_op_addl_T0_T1();
1453
        gen_movl_reg_T0(s, rd);
1454
    } else if (!(insn & (1 << 23)))
1455
        return 1;
1456
    return 0;
1457
}
1458

    
1459
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1460
{
1461
    int rd = (insn >> 0) & 0xf;
1462

    
1463
    if (insn & (1 << 8))
1464
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1465
            return 1;
1466
        else
1467
            gen_op_iwmmxt_movl_T0_wCx(rd);
1468
    else
1469
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1470

    
1471
    gen_op_movl_T1_im(mask);
1472
    gen_op_andl_T0_T1();
1473
    return 0;
1474
}
1475

    
1476
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1477
   (ie. an undefined instruction).  */
1478
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1479
{
1480
    int rd, wrd;
1481
    int rdhi, rdlo, rd0, rd1, i;
1482
    TCGv tmp;
1483

    
1484
    if ((insn & 0x0e000e00) == 0x0c000000) {
1485
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1486
            wrd = insn & 0xf;
1487
            rdlo = (insn >> 12) & 0xf;
1488
            rdhi = (insn >> 16) & 0xf;
1489
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1490
                gen_iwmmxt_movl_T0_T1_wRn(wrd);
1491
                gen_movl_reg_T0(s, rdlo);
1492
                gen_movl_reg_T1(s, rdhi);
1493
            } else {                                        /* TMCRR */
1494
                gen_movl_T0_reg(s, rdlo);
1495
                gen_movl_T1_reg(s, rdhi);
1496
                gen_iwmmxt_movl_wRn_T0_T1(wrd);
1497
                gen_op_iwmmxt_set_mup();
1498
            }
1499
            return 0;
1500
        }
1501

    
1502
        wrd = (insn >> 12) & 0xf;
1503
        if (gen_iwmmxt_address(s, insn))
1504
            return 1;
1505
        if (insn & ARM_CP_RW_BIT) {
1506
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1507
                tmp = gen_ld32(cpu_T[1], IS_USER(s));
1508
                tcg_gen_mov_i32(cpu_T[0], tmp);
1509
                dead_tmp(tmp);
1510
                gen_op_iwmmxt_movl_wCx_T0(wrd);
1511
            } else {
1512
                i = 1;
1513
                if (insn & (1 << 8)) {
1514
                    if (insn & (1 << 22)) {                /* WLDRD */
1515
                        tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1516
                        i = 0;
1517
                    } else {                                /* WLDRW wRd */
1518
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
1519
                    }
1520
                } else {
1521
                    if (insn & (1 << 22)) {                /* WLDRH */
1522
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1523
                    } else {                                /* WLDRB */
1524
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1525
                    }
1526
                }
1527
                if (i) {
1528
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
1529
                    dead_tmp(tmp);
1530
                }
1531
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1532
            }
1533
        } else {
1534
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1535
                gen_op_iwmmxt_movl_T0_wCx(wrd);
1536
                tmp = new_tmp();
1537
                tcg_gen_mov_i32(tmp, cpu_T[0]);
1538
                gen_st32(tmp, cpu_T[1], IS_USER(s));
1539
            } else {
1540
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1541
                tmp = new_tmp();
1542
                if (insn & (1 << 8)) {
1543
                    if (insn & (1 << 22)) {                /* WSTRD */
1544
                        dead_tmp(tmp);
1545
                        tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1546
                    } else {                                /* WSTRW wRd */
1547
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1548
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
1549
                    }
1550
                } else {
1551
                    if (insn & (1 << 22)) {                /* WSTRH */
1552
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1553
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
1554
                    } else {                                /* WSTRB */
1555
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1556
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
1557
                    }
1558
                }
1559
            }
1560
        }
1561
        return 0;
1562
    }
1563

    
1564
    if ((insn & 0x0f000000) != 0x0e000000)
1565
        return 1;
1566

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

    
2439
    return 0;
2440
}
2441

    
2442
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2443
   (ie. an undefined instruction).  */
2444
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2445
{
2446
    int acc, rd0, rd1, rdhi, rdlo;
2447

    
2448
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2449
        /* Multiply with Internal Accumulate Format */
2450
        rd0 = (insn >> 12) & 0xf;
2451
        rd1 = insn & 0xf;
2452
        acc = (insn >> 5) & 7;
2453

    
2454
        if (acc != 0)
2455
            return 1;
2456

    
2457
        switch ((insn >> 16) & 0xf) {
2458
        case 0x0:                                        /* MIA */
2459
            gen_movl_T0_reg(s, rd0);
2460
            gen_movl_T1_reg(s, rd1);
2461
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2462
            break;
2463
        case 0x8:                                        /* MIAPH */
2464
            gen_movl_T0_reg(s, rd0);
2465
            gen_movl_T1_reg(s, rd1);
2466
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2467
            break;
2468
        case 0xc:                                        /* MIABB */
2469
        case 0xd:                                        /* MIABT */
2470
        case 0xe:                                        /* MIATB */
2471
        case 0xf:                                        /* MIATT */
2472
            gen_movl_T1_reg(s, rd0);
2473
            if (insn & (1 << 16))
2474
                gen_op_shrl_T1_im(16);
2475
            gen_op_movl_T0_T1();
2476
            gen_movl_T1_reg(s, rd1);
2477
            if (insn & (1 << 17))
2478
                gen_op_shrl_T1_im(16);
2479
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2480
            break;
2481
        default:
2482
            return 1;
2483
        }
2484

    
2485
        gen_op_iwmmxt_movq_wRn_M0(acc);
2486
        return 0;
2487
    }
2488

    
2489
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2490
        /* Internal Accumulator Access Format */
2491
        rdhi = (insn >> 16) & 0xf;
2492
        rdlo = (insn >> 12) & 0xf;
2493
        acc = insn & 7;
2494

    
2495
        if (acc != 0)
2496
            return 1;
2497

    
2498
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2499
            gen_iwmmxt_movl_T0_T1_wRn(acc);
2500
            gen_movl_reg_T0(s, rdlo);
2501
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2502
            gen_op_andl_T0_T1();
2503
            gen_movl_reg_T0(s, rdhi);
2504
        } else {                                        /* MAR */
2505
            gen_movl_T0_reg(s, rdlo);
2506
            gen_movl_T1_reg(s, rdhi);
2507
            gen_iwmmxt_movl_wRn_T0_T1(acc);
2508
        }
2509
        return 0;
2510
    }
2511

    
2512
    return 1;
2513
}
2514

    
2515
/* Disassemble system coprocessor instruction.  Return nonzero if
2516
   instruction is not defined.  */
2517
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2518
{
2519
    TCGv tmp;
2520
    uint32_t rd = (insn >> 12) & 0xf;
2521
    uint32_t cp = (insn >> 8) & 0xf;
2522
    if (IS_USER(s)) {
2523
        return 1;
2524
    }
2525

    
2526
    if (insn & ARM_CP_RW_BIT) {
2527
        if (!env->cp[cp].cp_read)
2528
            return 1;
2529
        gen_set_pc_im(s->pc);
2530
        tmp = new_tmp();
2531
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2532
        store_reg(s, rd, tmp);
2533
    } else {
2534
        if (!env->cp[cp].cp_write)
2535
            return 1;
2536
        gen_set_pc_im(s->pc);
2537
        tmp = load_reg(s, rd);
2538
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2539
        dead_tmp(tmp);
2540
    }
2541
    return 0;
2542
}
2543

    
2544
static int cp15_user_ok(uint32_t insn)
2545
{
2546
    int cpn = (insn >> 16) & 0xf;
2547
    int cpm = insn & 0xf;
2548
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2549

    
2550
    if (cpn == 13 && cpm == 0) {
2551
        /* TLS register.  */
2552
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2553
            return 1;
2554
    }
2555
    if (cpn == 7) {
2556
        /* ISB, DSB, DMB.  */
2557
        if ((cpm == 5 && op == 4)
2558
                || (cpm == 10 && (op == 4 || op == 5)))
2559
            return 1;
2560
    }
2561
    return 0;
2562
}
2563

    
2564
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2565
   instruction is not defined.  */
2566
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2567
{
2568
    uint32_t rd;
2569
    TCGv tmp;
2570

    
2571
    /* M profile cores use memory mapped registers instead of cp15.  */
2572
    if (arm_feature(env, ARM_FEATURE_M))
2573
        return 1;
2574

    
2575
    if ((insn & (1 << 25)) == 0) {
2576
        if (insn & (1 << 20)) {
2577
            /* mrrc */
2578
            return 1;
2579
        }
2580
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2581
        return 0;
2582
    }
2583
    if ((insn & (1 << 4)) == 0) {
2584
        /* cdp */
2585
        return 1;
2586
    }
2587
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2588
        return 1;
2589
    }
2590
    if ((insn & 0x0fff0fff) == 0x0e070f90
2591
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2592
        /* Wait for interrupt.  */
2593
        gen_set_pc_im(s->pc);
2594
        s->is_jmp = DISAS_WFI;
2595
        return 0;
2596
    }
2597
    rd = (insn >> 12) & 0xf;
2598
    if (insn & ARM_CP_RW_BIT) {
2599
        tmp = new_tmp();
2600
        gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2601
        /* If the destination register is r15 then sets condition codes.  */
2602
        if (rd != 15)
2603
            store_reg(s, rd, tmp);
2604
        else
2605
            dead_tmp(tmp);
2606
    } else {
2607
        tmp = load_reg(s, rd);
2608
        gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2609
        dead_tmp(tmp);
2610
        /* Normally we would always end the TB here, but Linux
2611
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2612
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2613
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2614
                (insn & 0x0fff0fff) != 0x0e010f10)
2615
            gen_lookup_tb(s);
2616
    }
2617
    return 0;
2618
}
2619

    
2620
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2621
#define VFP_SREG(insn, bigbit, smallbit) \
2622
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2623
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2624
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2625
        reg = (((insn) >> (bigbit)) & 0x0f) \
2626
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2627
    } else { \
2628
        if (insn & (1 << (smallbit))) \
2629
            return 1; \
2630
        reg = ((insn) >> (bigbit)) & 0x0f; \
2631
    }} while (0)
2632

    
2633
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2634
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2635
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2636
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2637
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2638
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2639

    
2640
/* Move between integer and VFP cores.  */
2641
static TCGv gen_vfp_mrs(void)
2642
{
2643
    TCGv tmp = new_tmp();
2644
    tcg_gen_mov_i32(tmp, cpu_F0s);
2645
    return tmp;
2646
}
2647

    
2648
static void gen_vfp_msr(TCGv tmp)
2649
{
2650
    tcg_gen_mov_i32(cpu_F0s, tmp);
2651
    dead_tmp(tmp);
2652
}
2653

    
2654
static inline int
2655
vfp_enabled(CPUState * env)
2656
{
2657
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2658
}
2659

    
2660
static void gen_neon_dup_u8(TCGv var, int shift)
2661
{
2662
    TCGv tmp = new_tmp();
2663
    if (shift)
2664
        tcg_gen_shri_i32(var, var, shift);
2665
    tcg_gen_ext8u_i32(var, var);
2666
    tcg_gen_shli_i32(tmp, var, 8);
2667
    tcg_gen_or_i32(var, var, tmp);
2668
    tcg_gen_shli_i32(tmp, var, 16);
2669
    tcg_gen_or_i32(var, var, tmp);
2670
    dead_tmp(tmp);
2671
}
2672

    
2673
static void gen_neon_dup_low16(TCGv var)
2674
{
2675
    TCGv tmp = new_tmp();
2676
    tcg_gen_ext16u_i32(var, var);
2677
    tcg_gen_shli_i32(tmp, var, 16);
2678
    tcg_gen_or_i32(var, var, tmp);
2679
    dead_tmp(tmp);
2680
}
2681

    
2682
static void gen_neon_dup_high16(TCGv var)
2683
{
2684
    TCGv tmp = new_tmp();
2685
    tcg_gen_andi_i32(var, var, 0xffff0000);
2686
    tcg_gen_shri_i32(tmp, var, 16);
2687
    tcg_gen_or_i32(var, var, tmp);
2688
    dead_tmp(tmp);
2689
}
2690

    
2691
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2692
   (ie. an undefined instruction).  */
2693
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2694
{
2695
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2696
    int dp, veclen;
2697
    TCGv tmp;
2698
    TCGv tmp2;
2699

    
2700
    if (!arm_feature(env, ARM_FEATURE_VFP))
2701
        return 1;
2702

    
2703
    if (!vfp_enabled(env)) {
2704
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2705
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2706
            return 1;
2707
        rn = (insn >> 16) & 0xf;
2708
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2709
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2710
            return 1;
2711
    }
2712
    dp = ((insn & 0xf00) == 0xb00);
2713
    switch ((insn >> 24) & 0xf) {
2714
    case 0xe:
2715
        if (insn & (1 << 4)) {
2716
            /* single register transfer */
2717
            rd = (insn >> 12) & 0xf;
2718
            if (dp) {
2719
                int size;
2720
                int pass;
2721

    
2722
                VFP_DREG_N(rn, insn);
2723
                if (insn & 0xf)
2724
                    return 1;
2725
                if (insn & 0x00c00060
2726
                    && !arm_feature(env, ARM_FEATURE_NEON))
2727
                    return 1;
2728

    
2729
                pass = (insn >> 21) & 1;
2730
                if (insn & (1 << 22)) {
2731
                    size = 0;
2732
                    offset = ((insn >> 5) & 3) * 8;
2733
                } else if (insn & (1 << 5)) {
2734
                    size = 1;
2735
                    offset = (insn & (1 << 6)) ? 16 : 0;
2736
                } else {
2737
                    size = 2;
2738
                    offset = 0;
2739
                }
2740
                if (insn & ARM_CP_RW_BIT) {
2741
                    /* vfp->arm */
2742
                    tmp = neon_load_reg(rn, pass);
2743
                    switch (size) {
2744
                    case 0:
2745
                        if (offset)
2746
                            tcg_gen_shri_i32(tmp, tmp, offset);
2747
                        if (insn & (1 << 23))
2748
                            gen_uxtb(tmp);
2749
                        else
2750
                            gen_sxtb(tmp);
2751
                        break;
2752
                    case 1:
2753
                        if (insn & (1 << 23)) {
2754
                            if (offset) {
2755
                                tcg_gen_shri_i32(tmp, tmp, 16);
2756
                            } else {
2757
                                gen_uxth(tmp);
2758
                            }
2759
                        } else {
2760
                            if (offset) {
2761
                                tcg_gen_sari_i32(tmp, tmp, 16);
2762
                            } else {
2763
                                gen_sxth(tmp);
2764
                            }
2765
                        }
2766
                        break;
2767
                    case 2:
2768
                        break;
2769
                    }
2770
                    store_reg(s, rd, tmp);
2771
                } else {
2772
                    /* arm->vfp */
2773
                    tmp = load_reg(s, rd);
2774
                    if (insn & (1 << 23)) {
2775
                        /* VDUP */
2776
                        if (size == 0) {
2777
                            gen_neon_dup_u8(tmp, 0);
2778
                        } else if (size == 1) {
2779
                            gen_neon_dup_low16(tmp);
2780
                        }
2781
                        for (n = 0; n <= pass * 2; n++) {
2782
                            tmp2 = new_tmp();
2783
                            tcg_gen_mov_i32(tmp2, tmp);
2784
                            neon_store_reg(rn, n, tmp2);
2785
                        }
2786
                        neon_store_reg(rn, n, tmp);
2787
                    } else {
2788
                        /* VMOV */
2789
                        switch (size) {
2790
                        case 0:
2791
                            tmp2 = neon_load_reg(rn, pass);
2792
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2793
                            dead_tmp(tmp2);
2794
                            break;
2795
                        case 1:
2796
                            tmp2 = neon_load_reg(rn, pass);
2797
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2798
                            dead_tmp(tmp2);
2799
                            break;
2800
                        case 2:
2801
                            break;
2802
                        }
2803
                        neon_store_reg(rn, pass, tmp);
2804
                    }
2805
                }
2806
            } else { /* !dp */
2807
                if ((insn & 0x6f) != 0x00)
2808
                    return 1;
2809
                rn = VFP_SREG_N(insn);
2810
                if (insn & ARM_CP_RW_BIT) {
2811
                    /* vfp->arm */
2812
                    if (insn & (1 << 21)) {
2813
                        /* system register */
2814
                        rn >>= 1;
2815

    
2816
                        switch (rn) {
2817
                        case ARM_VFP_FPSID:
2818
                            /* VFP2 allows access to FSID from userspace.
2819
                               VFP3 restricts all id registers to privileged
2820
                               accesses.  */
2821
                            if (IS_USER(s)
2822
                                && arm_feature(env, ARM_FEATURE_VFP3))
2823
                                return 1;
2824
                            tmp = load_cpu_field(vfp.xregs[rn]);
2825
                            break;
2826
                        case ARM_VFP_FPEXC:
2827
                            if (IS_USER(s))
2828
                                return 1;
2829
                            tmp = load_cpu_field(vfp.xregs[rn]);
2830
                            break;
2831
                        case ARM_VFP_FPINST:
2832
                        case ARM_VFP_FPINST2:
2833
                            /* Not present in VFP3.  */
2834
                            if (IS_USER(s)
2835
                                || arm_feature(env, ARM_FEATURE_VFP3))
2836
                                return 1;
2837
                            tmp = load_cpu_field(vfp.xregs[rn]);
2838
                            break;
2839
                        case ARM_VFP_FPSCR:
2840
                            if (rd == 15) {
2841
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2842
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2843
                            } else {
2844
                                tmp = new_tmp();
2845
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2846
                            }
2847
                            break;
2848
                        case ARM_VFP_MVFR0:
2849
                        case ARM_VFP_MVFR1:
2850
                            if (IS_USER(s)
2851
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2852
                                return 1;
2853
                            tmp = load_cpu_field(vfp.xregs[rn]);
2854
                            break;
2855
                        default:
2856
                            return 1;
2857
                        }
2858
                    } else {
2859
                        gen_mov_F0_vreg(0, rn);
2860
                        tmp = gen_vfp_mrs();
2861
                    }
2862
                    if (rd == 15) {
2863
                        /* Set the 4 flag bits in the CPSR.  */
2864
                        gen_set_nzcv(tmp);
2865
                        dead_tmp(tmp);
2866
                    } else {
2867
                        store_reg(s, rd, tmp);
2868
                    }
2869
                } else {
2870
                    /* arm->vfp */
2871
                    tmp = load_reg(s, rd);
2872
                    if (insn & (1 << 21)) {
2873
                        rn >>= 1;
2874
                        /* system register */
2875
                        switch (rn) {
2876
                        case ARM_VFP_FPSID:
2877
                        case ARM_VFP_MVFR0:
2878
                        case ARM_VFP_MVFR1:
2879
                            /* Writes are ignored.  */
2880
                            break;
2881
                        case ARM_VFP_FPSCR:
2882
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2883
                            dead_tmp(tmp);
2884
                            gen_lookup_tb(s);
2885
                            break;
2886
                        case ARM_VFP_FPEXC:
2887
                            if (IS_USER(s))
2888
                                return 1;
2889
                            store_cpu_field(tmp, vfp.xregs[rn]);
2890
                            gen_lookup_tb(s);
2891
                            break;
2892
                        case ARM_VFP_FPINST:
2893
                        case ARM_VFP_FPINST2:
2894
                            store_cpu_field(tmp, vfp.xregs[rn]);
2895
                            break;
2896
                        default:
2897
                            return 1;
2898
                        }
2899
                    } else {
2900
                        gen_vfp_msr(tmp);
2901
                        gen_mov_vreg_F0(0, rn);
2902
                    }
2903
                }
2904
            }
2905
        } else {
2906
            /* data processing */
2907
            /* The opcode is in bits 23, 21, 20 and 6.  */
2908
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2909
            if (dp) {
2910
                if (op == 15) {
2911
                    /* rn is opcode */
2912
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2913
                } else {
2914
                    /* rn is register number */
2915
                    VFP_DREG_N(rn, insn);
2916
                }
2917

    
2918
                if (op == 15 && (rn == 15 || rn > 17)) {
2919
                    /* Integer or single precision destination.  */
2920
                    rd = VFP_SREG_D(insn);
2921
                } else {
2922
                    VFP_DREG_D(rd, insn);
2923
                }
2924

    
2925
                if (op == 15 && (rn == 16 || rn == 17)) {
2926
                    /* Integer source.  */
2927
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2928
                } else {
2929
                    VFP_DREG_M(rm, insn);
2930
                }
2931
            } else {
2932
                rn = VFP_SREG_N(insn);
2933
                if (op == 15 && rn == 15) {
2934
                    /* Double precision destination.  */
2935
                    VFP_DREG_D(rd, insn);
2936
                } else {
2937
                    rd = VFP_SREG_D(insn);
2938
                }
2939
                rm = VFP_SREG_M(insn);
2940
            }
2941

    
2942
            veclen = env->vfp.vec_len;
2943
            if (op == 15 && rn > 3)
2944
                veclen = 0;
2945

    
2946
            /* Shut up compiler warnings.  */
2947
            delta_m = 0;
2948
            delta_d = 0;
2949
            bank_mask = 0;
2950

    
2951
            if (veclen > 0) {
2952
                if (dp)
2953
                    bank_mask = 0xc;
2954
                else
2955
                    bank_mask = 0x18;
2956

    
2957
                /* Figure out what type of vector operation this is.  */
2958
                if ((rd & bank_mask) == 0) {
2959
                    /* scalar */
2960
                    veclen = 0;
2961
                } else {
2962
                    if (dp)
2963
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2964
                    else
2965
                        delta_d = env->vfp.vec_stride + 1;
2966

    
2967
                    if ((rm & bank_mask) == 0) {
2968
                        /* mixed scalar/vector */
2969
                        delta_m = 0;
2970
                    } else {
2971
                        /* vector */
2972
                        delta_m = delta_d;
2973
                    }
2974
                }
2975
            }
2976

    
2977
            /* Load the initial operands.  */
2978
            if (op == 15) {
2979
                switch (rn) {
2980
                case 16:
2981
                case 17:
2982
                    /* Integer source */
2983
                    gen_mov_F0_vreg(0, rm);
2984
                    break;
2985
                case 8:
2986
                case 9:
2987
                    /* Compare */
2988
                    gen_mov_F0_vreg(dp, rd);
2989
                    gen_mov_F1_vreg(dp, rm);
2990
                    break;
2991
                case 10:
2992
                case 11:
2993
                    /* Compare with zero */
2994
                    gen_mov_F0_vreg(dp, rd);
2995
                    gen_vfp_F1_ld0(dp);
2996
                    break;
2997
                case 20:
2998
                case 21:
2999
                case 22:
3000
                case 23:
3001
                case 28:
3002
                case 29:
3003
                case 30:
3004
                case 31:
3005
                    /* Source and destination the same.  */
3006
                    gen_mov_F0_vreg(dp, rd);
3007
                    break;
3008
                default:
3009
                    /* One source operand.  */
3010
                    gen_mov_F0_vreg(dp, rm);
3011
                    break;
3012
                }
3013
            } else {
3014
                /* Two source operands.  */
3015
                gen_mov_F0_vreg(dp, rn);
3016
                gen_mov_F1_vreg(dp, rm);
3017
            }
3018

    
3019
            for (;;) {
3020
                /* Perform the calculation.  */
3021
                switch (op) {
3022
                case 0: /* mac: fd + (fn * fm) */
3023
                    gen_vfp_mul(dp);
3024
                    gen_mov_F1_vreg(dp, rd);
3025
                    gen_vfp_add(dp);
3026
                    break;
3027
                case 1: /* nmac: fd - (fn * fm) */
3028
                    gen_vfp_mul(dp);
3029
                    gen_vfp_neg(dp);
3030
                    gen_mov_F1_vreg(dp, rd);
3031
                    gen_vfp_add(dp);
3032
                    break;
3033
                case 2: /* msc: -fd + (fn * fm) */
3034
                    gen_vfp_mul(dp);
3035
                    gen_mov_F1_vreg(dp, rd);
3036
                    gen_vfp_sub(dp);
3037
                    break;
3038
                case 3: /* nmsc: -fd - (fn * fm)  */
3039
                    gen_vfp_mul(dp);
3040
                    gen_vfp_neg(dp);
3041
                    gen_mov_F1_vreg(dp, rd);
3042
                    gen_vfp_sub(dp);
3043
                    break;
3044
                case 4: /* mul: fn * fm */
3045
                    gen_vfp_mul(dp);
3046
                    break;
3047
                case 5: /* nmul: -(fn * fm) */
3048
                    gen_vfp_mul(dp);
3049
                    gen_vfp_neg(dp);
3050
                    break;
3051
                case 6: /* add: fn + fm */
3052
                    gen_vfp_add(dp);
3053
                    break;
3054
                case 7: /* sub: fn - fm */
3055
                    gen_vfp_sub(dp);
3056
                    break;
3057
                case 8: /* div: fn / fm */
3058
                    gen_vfp_div(dp);
3059
                    break;
3060
                case 14: /* fconst */
3061
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3062
                      return 1;
3063

    
3064
                    n = (insn << 12) & 0x80000000;
3065
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3066
                    if (dp) {
3067
                        if (i & 0x40)
3068
                            i |= 0x3f80;
3069
                        else
3070
                            i |= 0x4000;
3071
                        n |= i << 16;
3072
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3073
                    } else {
3074
                        if (i & 0x40)
3075
                            i |= 0x780;
3076
                        else
3077
                            i |= 0x800;
3078
                        n |= i << 19;
3079
                        tcg_gen_movi_i32(cpu_F0s, n);
3080
                    }
3081
                    break;
3082
                case 15: /* extension space */
3083
                    switch (rn) {
3084
                    case 0: /* cpy */
3085
                        /* no-op */
3086
                        break;
3087
                    case 1: /* abs */
3088
                        gen_vfp_abs(dp);
3089
                        break;
3090
                    case 2: /* neg */
3091
                        gen_vfp_neg(dp);
3092
                        break;
3093
                    case 3: /* sqrt */
3094
                        gen_vfp_sqrt(dp);
3095
                        break;
3096
                    case 8: /* cmp */
3097
                        gen_vfp_cmp(dp);
3098
                        break;
3099
                    case 9: /* cmpe */
3100
                        gen_vfp_cmpe(dp);
3101
                        break;
3102
                    case 10: /* cmpz */
3103
                        gen_vfp_cmp(dp);
3104
                        break;
3105
                    case 11: /* cmpez */
3106
                        gen_vfp_F1_ld0(dp);
3107
                        gen_vfp_cmpe(dp);
3108
                        break;
3109
                    case 15: /* single<->double conversion */
3110
                        if (dp)
3111
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3112
                        else
3113
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3114
                        break;
3115
                    case 16: /* fuito */
3116
                        gen_vfp_uito(dp);
3117
                        break;
3118
                    case 17: /* fsito */
3119
                        gen_vfp_sito(dp);
3120
                        break;
3121
                    case 20: /* fshto */
3122
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3123
                          return 1;
3124
                        gen_vfp_shto(dp, 16 - rm);
3125
                        break;
3126
                    case 21: /* fslto */
3127
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3128
                          return 1;
3129
                        gen_vfp_slto(dp, 32 - rm);
3130
                        break;
3131
                    case 22: /* fuhto */
3132
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3133
                          return 1;
3134
                        gen_vfp_uhto(dp, 16 - rm);
3135
                        break;
3136
                    case 23: /* fulto */
3137
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3138
                          return 1;
3139
                        gen_vfp_ulto(dp, 32 - rm);
3140
                        break;
3141
                    case 24: /* ftoui */
3142
                        gen_vfp_toui(dp);
3143
                        break;
3144
                    case 25: /* ftouiz */
3145
                        gen_vfp_touiz(dp);
3146
                        break;
3147
                    case 26: /* ftosi */
3148
                        gen_vfp_tosi(dp);
3149
                        break;
3150
                    case 27: /* ftosiz */
3151
                        gen_vfp_tosiz(dp);
3152
                        break;
3153
                    case 28: /* ftosh */
3154
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3155
                          return 1;
3156
                        gen_vfp_tosh(dp, 16 - rm);
3157
                        break;
3158
                    case 29: /* ftosl */
3159
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3160
                          return 1;
3161
                        gen_vfp_tosl(dp, 32 - rm);
3162
                        break;
3163
                    case 30: /* ftouh */
3164
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3165
                          return 1;
3166
                        gen_vfp_touh(dp, 16 - rm);
3167
                        break;
3168
                    case 31: /* ftoul */
3169
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3170
                          return 1;
3171
                        gen_vfp_toul(dp, 32 - rm);
3172
                        break;
3173
                    default: /* undefined */
3174
                        printf ("rn:%d\n", rn);
3175
                        return 1;
3176
                    }
3177
                    break;
3178
                default: /* undefined */
3179
                    printf ("op:%d\n", op);
3180
                    return 1;
3181
                }
3182

    
3183
                /* Write back the result.  */
3184
                if (op == 15 && (rn >= 8 && rn <= 11))
3185
                    ; /* Comparison, do nothing.  */
3186
                else if (op == 15 && rn > 17)
3187
                    /* Integer result.  */
3188
                    gen_mov_vreg_F0(0, rd);
3189
                else if (op == 15 && rn == 15)
3190
                    /* conversion */
3191
                    gen_mov_vreg_F0(!dp, rd);
3192
                else
3193
                    gen_mov_vreg_F0(dp, rd);
3194

    
3195
                /* break out of the loop if we have finished  */
3196
                if (veclen == 0)
3197
                    break;
3198

    
3199
                if (op == 15 && delta_m == 0) {
3200
                    /* single source one-many */
3201
                    while (veclen--) {
3202
                        rd = ((rd + delta_d) & (bank_mask - 1))
3203
                             | (rd & bank_mask);
3204
                        gen_mov_vreg_F0(dp, rd);
3205
                    }
3206
                    break;
3207
                }
3208
                /* Setup the next operands.  */
3209
                veclen--;
3210
                rd = ((rd + delta_d) & (bank_mask - 1))
3211
                     | (rd & bank_mask);
3212

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

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

    
3311
                if (insn & (1 << 24)) /* pre-decrement */
3312
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3313

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

    
3339
                    if (offset != 0)
3340
                        gen_op_addl_T1_im(offset);
3341
                    gen_movl_reg_T1(s, rn);
3342
                }
3343
            }
3344
        }
3345
        break;
3346
    default:
3347
        /* Should never happen.  */
3348
        return 1;
3349
    }
3350
    return 0;
3351
}
3352

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

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

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

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

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

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

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

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

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

    
3444
/* Generate an old-style exception return. Marks pc as dead. */
3445
static void gen_exception_return(DisasContext *s, TCGv pc)
3446
{
3447
    TCGv tmp;
3448
    store_reg(s, 15, pc);
3449
    tmp = load_cpu_field(spsr);
3450
    gen_set_cpsr(tmp, 0xffffffff);
3451
    dead_tmp(tmp);
3452
    s->is_jmp = DISAS_UPDATE;
3453
}
3454

    
3455
/* Generate a v6 exception return.  Marks both values as dead.  */
3456
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3457
{
3458
    gen_set_cpsr(cpsr, 0xffffffff);
3459
    dead_tmp(cpsr);
3460
    store_reg(s, 15, pc);
3461
    s->is_jmp = DISAS_UPDATE;
3462
}
3463

    
3464
static inline void
3465
gen_set_condexec (DisasContext *s)
3466
{
3467
    if (s->condexec_mask) {
3468
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3469
        TCGv tmp = new_tmp();
3470
        tcg_gen_movi_i32(tmp, val);
3471
        store_cpu_field(tmp, condexec_bits);
3472
    }
3473
}
3474

    
3475
static void gen_nop_hint(DisasContext *s, int val)
3476
{
3477
    switch (val) {
3478
    case 3: /* wfi */
3479
        gen_set_pc_im(s->pc);
3480
        s->is_jmp = DISAS_WFI;
3481
        break;
3482
    case 2: /* wfe */
3483
    case 4: /* sev */
3484
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3485
    default: /* nop */
3486
        break;
3487
    }
3488
}
3489

    
3490
/* These macros help make the code more readable when migrating from the
3491
   old dyngen helpers.  They should probably be removed when
3492
   T0/T1 are removed.  */
3493
#define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3494
#define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3495

    
3496
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3497

    
3498
static inline int gen_neon_add(int size)
3499
{
3500
    switch (size) {
3501
    case 0: gen_helper_neon_add_u8(CPU_T001); break;
3502
    case 1: gen_helper_neon_add_u16(CPU_T001); break;
3503
    case 2: gen_op_addl_T0_T1(); break;
3504
    default: return 1;
3505
    }
3506
    return 0;
3507
}
3508

    
3509
static inline void gen_neon_rsb(int size)
3510
{
3511
    switch (size) {
3512
    case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3513
    case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3514
    case 2: gen_op_rsbl_T0_T1(); break;
3515
    default: return;
3516
    }
3517
}
3518

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

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

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

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

    
3577
static inline void
3578
gen_neon_movl_scratch_T0(int scratch)
3579
{
3580
  uint32_t offset;
3581

    
3582
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3583
  tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3584
}
3585

    
3586
static inline void
3587
gen_neon_movl_scratch_T1(int scratch)
3588
{
3589
  uint32_t offset;
3590

    
3591
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3592
  tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3593
}
3594

    
3595
static inline void
3596
gen_neon_movl_T0_scratch(int scratch)
3597
{
3598
  uint32_t offset;
3599

    
3600
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3601
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3602
}
3603

    
3604
static inline void
3605
gen_neon_movl_T1_scratch(int scratch)
3606
{
3607
  uint32_t offset;
3608

    
3609
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3610
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3611
}
3612

    
3613
static inline void gen_neon_get_scalar(int size, int reg)
3614
{
3615
    if (size == 1) {
3616
        NEON_GET_REG(T0, reg >> 1, reg & 1);
3617
    } else {
3618
        NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3619
        if (reg & 1)
3620
            gen_neon_dup_low16(cpu_T[0]);
3621
        else
3622
            gen_neon_dup_high16(cpu_T[0]);
3623
    }
3624
}
3625

    
3626
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3627
{
3628
    int n;
3629

    
3630
    for (n = 0; n < q + 1; n += 2) {
3631
        NEON_GET_REG(T0, reg, n);
3632
        NEON_GET_REG(T0, reg, n + n);
3633
        switch (size) {
3634
        case 0: gen_helper_neon_unzip_u8(); break;
3635
        case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same.  */
3636
        case 2: /* no-op */; break;
3637
        default: abort();
3638
        }
3639
        gen_neon_movl_scratch_T0(tmp + n);
3640
        gen_neon_movl_scratch_T1(tmp + n + 1);
3641
    }
3642
}
3643

    
3644
static struct {
3645
    int nregs;
3646
    int interleave;
3647
    int spacing;
3648
} neon_ls_element_type[11] = {
3649
    {4, 4, 1},
3650
    {4, 4, 2},
3651
    {4, 1, 1},
3652
    {4, 2, 1},
3653
    {3, 3, 1},
3654
    {3, 3, 2},
3655
    {3, 1, 1},
3656
    {1, 1, 1},
3657
    {2, 2, 1},
3658
    {2, 2, 2},
3659
    {2, 1, 1}
3660
};
3661

    
3662
/* Translate a NEON load/store element instruction.  Return nonzero if the
3663
   instruction is invalid.  */
3664
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3665
{
3666
    int rd, rn, rm;
3667
    int op;
3668
    int nregs;
3669
    int interleave;
3670
    int stride;
3671
    int size;
3672
    int reg;
3673
    int pass;
3674
    int load;
3675
    int shift;
3676
    int n;
3677
    TCGv tmp;
3678
    TCGv tmp2;
3679

    
3680
    if (!vfp_enabled(env))
3681
      return 1;
3682
    VFP_DREG_D(rd, insn);
3683
    rn = (insn >> 16) & 0xf;
3684
    rm = insn & 0xf;
3685
    load = (insn & (1 << 21)) != 0;
3686
    if ((insn & (1 << 23)) == 0) {
3687
        /* Load store all elements.  */
3688
        op = (insn >> 8) & 0xf;
3689
        size = (insn >> 6) & 3;
3690
        if (op > 10 || size == 3)
3691
            return 1;
3692
        nregs = neon_ls_element_type[op].nregs;
3693
        interleave = neon_ls_element_type[op].interleave;
3694
        gen_movl_T1_reg(s, rn);
3695
        stride = (1 << size) * interleave;
3696
        for (reg = 0; reg < nregs; reg++) {
3697
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3698
                gen_movl_T1_reg(s, rn);
3699
                gen_op_addl_T1_im((1 << size) * reg);
3700
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3701
                gen_movl_T1_reg(s, rn);
3702
                gen_op_addl_T1_im(1 << size);
3703
            }
3704
            for (pass = 0; pass < 2; pass++) {
3705
                if (size == 2) {
3706
                    if (load) {
3707
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3708
                        neon_store_reg(rd, pass, tmp);
3709
                    } else {
3710
                        tmp = neon_load_reg(rd, pass);
3711
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3712
                    }
3713
                    gen_op_addl_T1_im(stride);
3714
                } else if (size == 1) {
3715
                    if (load) {
3716
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3717
                        gen_op_addl_T1_im(stride);
3718
                        tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
3719
                        gen_op_addl_T1_im(stride);
3720
                        gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
3721
                        dead_tmp(tmp2);
3722
                        neon_store_reg(rd, pass, tmp);
3723
                    } else {
3724
                        tmp = neon_load_reg(rd, pass);
3725
                        tmp2 = new_tmp();
3726
                        tcg_gen_shri_i32(tmp2, tmp, 16);
3727
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3728
                        gen_op_addl_T1_im(stride);
3729
                        gen_st16(tmp2, cpu_T[1], IS_USER(s));
3730
                        gen_op_addl_T1_im(stride);
3731
                    }
3732
                } else /* size == 0 */ {
3733
                    if (load) {
3734
                        TCGV_UNUSED(tmp2);
3735
                        for (n = 0; n < 4; n++) {
3736
                            tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3737
                            gen_op_addl_T1_im(stride);
3738
                            if (n == 0) {
3739
                                tmp2 = tmp;
3740
                            } else {
3741
                                gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
3742
                                dead_tmp(tmp);
3743
                            }
3744
                        }
3745
                        neon_store_reg(rd, pass, tmp2);
3746
                    } else {
3747
                        tmp2 = neon_load_reg(rd, pass);
3748
                        for (n = 0; n < 4; n++) {
3749
                            tmp = new_tmp();
3750
                            if (n == 0) {
3751
                                tcg_gen_mov_i32(tmp, tmp2);
3752
                            } else {
3753
                                tcg_gen_shri_i32(tmp, tmp2, n * 8);
3754
                            }
3755
                            gen_st8(tmp, cpu_T[1], IS_USER(s));
3756
                            gen_op_addl_T1_im(stride);
3757
                        }
3758
                        dead_tmp(tmp2);
3759
                    }
3760
                }
3761
            }
3762
            rd += neon_ls_element_type[op].spacing;
3763
        }
3764
        stride = nregs * 8;
3765
    } else {
3766
        size = (insn >> 10) & 3;
3767
        if (size == 3) {
3768
            /* Load single element to all lanes.  */
3769
            if (!load)
3770
                return 1;
3771
            size = (insn >> 6) & 3;
3772
            nregs = ((insn >> 8) & 3) + 1;
3773
            stride = (insn & (1 << 5)) ? 2 : 1;
3774
            gen_movl_T1_reg(s, rn);
3775
            for (reg = 0; reg < nregs; reg++) {
3776
                switch (size) {
3777
                case 0:
3778
                    tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3779
                    gen_neon_dup_u8(tmp, 0);
3780
                    break;
3781
                case 1:
3782
                    tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3783
                    gen_neon_dup_low16(tmp);
3784
                    break;
3785
                case 2:
3786
                    tmp = gen_ld32(cpu_T[0], IS_USER(s));
3787
                    break;
3788
                case 3:
3789
                    return 1;
3790
                default: /* Avoid compiler warnings.  */
3791
                    abort();
3792
                }
3793
                gen_op_addl_T1_im(1 << size);
3794
                tmp2 = new_tmp();
3795
                tcg_gen_mov_i32(tmp2, tmp);
3796
                neon_store_reg(rd, 0, tmp2);
3797
                neon_store_reg(rd, 1, tmp);
3798
                rd += stride;
3799
            }
3800
            stride = (1 << size) * nregs;
3801
        } else {
3802
            /* Single element.  */
3803
            pass = (insn >> 7) & 1;
3804
            switch (size) {
3805
            case 0:
3806
                shift = ((insn >> 5) & 3) * 8;
3807
                stride = 1;
3808
                break;
3809
            case 1:
3810
                shift = ((insn >> 6) & 1) * 16;
3811
                stride = (insn & (1 << 5)) ? 2 : 1;
3812
                break;
3813
            case 2:
3814
                shift = 0;
3815
                stride = (insn & (1 << 6)) ? 2 : 1;
3816
                break;
3817
            default:
3818
                abort();
3819
            }
3820
            nregs = ((insn >> 8) & 3) + 1;
3821
            gen_movl_T1_reg(s, rn);
3822
            for (reg = 0; reg < nregs; reg++) {
3823
                if (load) {
3824
                    switch (size) {
3825
                    case 0:
3826
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3827
                        break;
3828
                    case 1:
3829
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3830
                        break;
3831
                    case 2:
3832
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3833
                        break;
3834
                    default: /* Avoid compiler warnings.  */
3835
                        abort();
3836
                    }
3837
                    if (size != 2) {
3838
                        tmp2 = neon_load_reg(rd, pass);
3839
                        gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
3840
                        dead_tmp(tmp2);
3841
                    }
3842
                    neon_store_reg(rd, pass, tmp);
3843
                } else { /* Store */
3844
                    tmp = neon_load_reg(rd, pass);
3845
                    if (shift)
3846
                        tcg_gen_shri_i32(tmp, tmp, shift);
3847
                    switch (size) {
3848
                    case 0:
3849
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
3850
                        break;
3851
                    case 1:
3852
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3853
                        break;
3854
                    case 2:
3855
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3856
                        break;
3857
                    }
3858
                }
3859
                rd += stride;
3860
                gen_op_addl_T1_im(1 << size);
3861
            }
3862
            stride = nregs * (1 << size);
3863
        }
3864
    }
3865
    if (rm != 15) {
3866
        TCGv base;
3867

    
3868
        base = load_reg(s, rn);
3869
        if (rm == 13) {
3870
            tcg_gen_addi_i32(base, base, stride);
3871
        } else {
3872
            TCGv index;
3873
            index = load_reg(s, rm);
3874
            tcg_gen_add_i32(base, base, index);
3875
            dead_tmp(index);
3876
        }
3877
        store_reg(s, rn, base);
3878
    }
3879
    return 0;
3880
}
3881

    
3882
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3883
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3884
{
3885
    tcg_gen_and_i32(t, t, c);
3886
    tcg_gen_bic_i32(f, f, c);
3887
    tcg_gen_or_i32(dest, t, f);
3888
}
3889

    
3890
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
3891
{
3892
    switch (size) {
3893
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
3894
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
3895
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3896
    default: abort();
3897
    }
3898
}
3899

    
3900
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
3901
{
3902
    switch (size) {
3903
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3904
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3905
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3906
    default: abort();
3907
    }
3908
}
3909

    
3910
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
3911
{
3912
    switch (size) {
3913
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3914
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3915
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3916
    default: abort();
3917
    }
3918
}
3919

    
3920
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3921
                                         int q, int u)
3922
{
3923
    if (q) {
3924
        if (u) {
3925
            switch (size) {
3926
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3927
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3928
            default: abort();
3929
            }
3930
        } else {
3931
            switch (size) {
3932
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3933
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3934
            default: abort();
3935
            }
3936
        }
3937
    } else {
3938
        if (u) {
3939
            switch (size) {
3940
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3941
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3942
            default: abort();
3943
            }
3944
        } else {
3945
            switch (size) {
3946
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3947
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3948
            default: abort();
3949
            }
3950
        }
3951
    }
3952
}
3953

    
3954
static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
3955
{
3956
    if (u) {
3957
        switch (size) {
3958
        case 0: gen_helper_neon_widen_u8(dest, src); break;
3959
        case 1: gen_helper_neon_widen_u16(dest, src); break;
3960
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
3961
        default: abort();
3962
        }
3963
    } else {
3964
        switch (size) {
3965
        case 0: gen_helper_neon_widen_s8(dest, src); break;
3966
        case 1: gen_helper_neon_widen_s16(dest, src); break;
3967
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
3968
        default: abort();
3969
        }
3970
    }
3971
    dead_tmp(src);
3972
}
3973

    
3974
static inline void gen_neon_addl(int size)
3975
{
3976
    switch (size) {
3977
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3978
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3979
    case 2: tcg_gen_add_i64(CPU_V001); break;
3980
    default: abort();
3981
    }
3982
}
3983

    
3984
static inline void gen_neon_subl(int size)
3985
{
3986
    switch (size) {
3987
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3988
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3989
    case 2: tcg_gen_sub_i64(CPU_V001); break;
3990
    default: abort();
3991
    }
3992
}
3993

    
3994
static inline void gen_neon_negl(TCGv_i64 var, int size)
3995
{
3996
    switch (size) {
3997
    case 0: gen_helper_neon_negl_u16(var, var); break;
3998
    case 1: gen_helper_neon_negl_u32(var, var); break;
3999
    case 2: gen_helper_neon_negl_u64(var, var); break;
4000
    default: abort();
4001
    }
4002
}
4003

    
4004
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4005
{
4006
    switch (size) {
4007
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4008
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4009
    default: abort();
4010
    }
4011
}
4012

    
4013
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4014
{
4015
    TCGv_i64 tmp;
4016

    
4017
    switch ((size << 1) | u) {
4018
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4019
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4020
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4021
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4022
    case 4:
4023
        tmp = gen_muls_i64_i32(a, b);
4024
        tcg_gen_mov_i64(dest, tmp);
4025
        break;
4026
    case 5:
4027
        tmp = gen_mulu_i64_i32(a, b);
4028
        tcg_gen_mov_i64(dest, tmp);
4029
        break;
4030
    default: abort();
4031
    }
4032
    if (size < 2) {
4033
        dead_tmp(b);
4034
        dead_tmp(a);
4035
    }
4036
}
4037

    
4038
/* Translate a NEON data processing instruction.  Return nonzero if the
4039
   instruction is invalid.
4040
   We process data in a mixture of 32-bit and 64-bit chunks.
4041
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4042

    
4043
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4044
{
4045
    int op;
4046
    int q;
4047
    int rd, rn, rm;
4048
    int size;
4049
    int shift;
4050
    int pass;
4051
    int count;
4052
    int pairwise;
4053
    int u;
4054
    int n;
4055
    uint32_t imm;
4056
    TCGv tmp;
4057
    TCGv tmp2;
4058
    TCGv tmp3;
4059
    TCGv_i64 tmp64;
4060

    
4061
    if (!vfp_enabled(env))
4062
      return 1;
4063
    q = (insn & (1 << 6)) != 0;
4064
    u = (insn >> 24) & 1;
4065
    VFP_DREG_D(rd, insn);
4066
    VFP_DREG_N(rn, insn);
4067
    VFP_DREG_M(rm, insn);
4068
    size = (insn >> 20) & 3;
4069
    if ((insn & (1 << 23)) == 0) {
4070
        /* Three register same length.  */
4071
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4072
        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
4073
                          || op == 10 || op  == 11 || op == 16)) {
4074
            /* 64-bit element instructions.  */
4075
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4076
                neon_load_reg64(cpu_V0, rn + pass);
4077
                neon_load_reg64(cpu_V1, rm + pass);
4078
                switch (op) {
4079
                case 1: /* VQADD */
4080
                    if (u) {
4081
                        gen_helper_neon_add_saturate_u64(CPU_V001);
4082
                    } else {
4083
                        gen_helper_neon_add_saturate_s64(CPU_V001);
4084
                    }
4085
                    break;
4086
                case 5: /* VQSUB */
4087
                    if (u) {
4088
                        gen_helper_neon_sub_saturate_u64(CPU_V001);
4089
                    } else {
4090
                        gen_helper_neon_sub_saturate_s64(CPU_V001);
4091
                    }
4092
                    break;
4093
                case 8: /* VSHL */
4094
                    if (u) {
4095
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4096
                    } else {
4097
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4098
                    }
4099
                    break;
4100
                case 9: /* VQSHL */
4101
                    if (u) {
4102
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4103
                                                 cpu_V0, cpu_V0);
4104
                    } else {
4105
                        gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
4106
                                                 cpu_V1, cpu_V0);
4107
                    }
4108
                    break;
4109
                case 10: /* VRSHL */
4110
                    if (u) {
4111
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4112
                    } else {
4113
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4114
                    }
4115
                    break;
4116
                case 11: /* VQRSHL */
4117
                    if (u) {
4118
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4119
                                                  cpu_V1, cpu_V0);
4120
                    } else {
4121
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4122
                                                  cpu_V1, cpu_V0);
4123
                    }
4124
                    break;
4125
                case 16:
4126
                    if (u) {
4127
                        tcg_gen_sub_i64(CPU_V001);
4128
                    } else {
4129
                        tcg_gen_add_i64(CPU_V001);
4130
                    }
4131
                    break;
4132
                default:
4133
                    abort();
4134
                }
4135
                neon_store_reg64(cpu_V0, rd + pass);
4136
            }
4137
            return 0;
4138
        }
4139
        switch (op) {
4140
        case 8: /* VSHL */
4141
        case 9: /* VQSHL */
4142
        case 10: /* VRSHL */
4143
        case 11: /* VQRSHL */
4144
            {
4145
                int rtmp;
4146
                /* Shift instruction operands are reversed.  */
4147
                rtmp = rn;
4148
                rn = rm;
4149
                rm = rtmp;
4150
                pairwise = 0;
4151
            }
4152
            break;
4153
        case 20: /* VPMAX */
4154
        case 21: /* VPMIN */
4155
        case 23: /* VPADD */
4156
            pairwise = 1;
4157
            break;
4158
        case 26: /* VPADD (float) */
4159
            pairwise = (u && size < 2);
4160
            break;
4161
        case 30: /* VPMIN/VPMAX (float) */
4162
            pairwise = u;
4163
            break;
4164
        default:
4165
            pairwise = 0;
4166
            break;
4167
        }
4168
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4169

    
4170
        if (pairwise) {
4171
            /* Pairwise.  */
4172
            if (q)
4173
                n = (pass & 1) * 2;
4174
            else
4175
                n = 0;
4176
            if (pass < q + 1) {
4177
                NEON_GET_REG(T0, rn, n);
4178
                NEON_GET_REG(T1, rn, n + 1);
4179
            } else {
4180
                NEON_GET_REG(T0, rm, n);
4181
                NEON_GET_REG(T1, rm, n + 1);
4182
            }
4183
        } else {
4184
            /* Elementwise.  */
4185
            NEON_GET_REG(T0, rn, pass);
4186
            NEON_GET_REG(T1, rm, pass);
4187
        }
4188
        switch (op) {
4189
        case 0: /* VHADD */
4190
            GEN_NEON_INTEGER_OP(hadd);
4191
            break;
4192
        case 1: /* VQADD */
4193
            GEN_NEON_INTEGER_OP_ENV(qadd);
4194
            break;
4195
        case 2: /* VRHADD */
4196
            GEN_NEON_INTEGER_OP(rhadd);
4197
            break;
4198
        case 3: /* Logic ops.  */
4199
            switch ((u << 2) | size) {
4200
            case 0: /* VAND */
4201
                gen_op_andl_T0_T1();
4202
                break;
4203
            case 1: /* BIC */
4204
                gen_op_bicl_T0_T1();
4205
                break;
4206
            case 2: /* VORR */
4207
                gen_op_orl_T0_T1();
4208
                break;
4209
            case 3: /* VORN */
4210
                gen_op_notl_T1();
4211
                gen_op_orl_T0_T1();
4212
                break;
4213
            case 4: /* VEOR */
4214
                gen_op_xorl_T0_T1();
4215
                break;
4216
            case 5: /* VBSL */
4217
                tmp = neon_load_reg(rd, pass);
4218
                gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
4219
                dead_tmp(tmp);
4220
                break;
4221
            case 6: /* VBIT */
4222
                tmp = neon_load_reg(rd, pass);
4223
                gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
4224
                dead_tmp(tmp);
4225
                break;
4226
            case 7: /* VBIF */
4227
                tmp = neon_load_reg(rd, pass);
4228
                gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
4229
                dead_tmp(tmp);
4230
                break;
4231
            }
4232
            break;
4233
        case 4: /* VHSUB */
4234
            GEN_NEON_INTEGER_OP(hsub);
4235
            break;
4236
        case 5: /* VQSUB */
4237
            GEN_NEON_INTEGER_OP_ENV(qsub);
4238
            break;
4239
        case 6: /* VCGT */
4240
            GEN_NEON_INTEGER_OP(cgt);
4241
            break;
4242
        case 7: /* VCGE */
4243
            GEN_NEON_INTEGER_OP(cge);
4244
            break;
4245
        case 8: /* VSHL */
4246
            GEN_NEON_INTEGER_OP(shl);
4247
            break;
4248
        case 9: /* VQSHL */
4249
            GEN_NEON_INTEGER_OP_ENV(qshl);
4250
            break;
4251
        case 10: /* VRSHL */
4252
            GEN_NEON_INTEGER_OP(rshl);
4253
            break;
4254
        case 11: /* VQRSHL */
4255
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4256
            break;
4257
        case 12: /* VMAX */
4258
            GEN_NEON_INTEGER_OP(max);
4259
            break;
4260
        case 13: /* VMIN */
4261
            GEN_NEON_INTEGER_OP(min);
4262
            break;
4263
        case 14: /* VABD */
4264
            GEN_NEON_INTEGER_OP(abd);
4265
            break;
4266
        case 15: /* VABA */
4267
            GEN_NEON_INTEGER_OP(abd);
4268
            NEON_GET_REG(T1, rd, pass);
4269
            gen_neon_add(size);
4270
            break;
4271
        case 16:
4272
            if (!u) { /* VADD */
4273
                if (gen_neon_add(size))
4274
                    return 1;
4275
            } else { /* VSUB */
4276
                switch (size) {
4277
                case 0: gen_helper_neon_sub_u8(CPU_T001); break;
4278
                case 1: gen_helper_neon_sub_u16(CPU_T001); break;
4279
                case 2: gen_op_subl_T0_T1(); break;
4280
                default: return 1;
4281
                }
4282
            }
4283
            break;
4284
        case 17:
4285
            if (!u) { /* VTST */
4286
                switch (size) {
4287
                case 0: gen_helper_neon_tst_u8(CPU_T001); break;
4288
                case 1: gen_helper_neon_tst_u16(CPU_T001); break;
4289
                case 2: gen_helper_neon_tst_u32(CPU_T001); break;
4290
                default: return 1;
4291
                }
4292
            } else { /* VCEQ */
4293
                switch (size) {
4294
                case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
4295
                case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
4296
                case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
4297
                default: return 1;
4298
                }
4299
            }
4300
            break;
4301
        case 18: /* Multiply.  */
4302
            switch (size) {
4303
            case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4304
            case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4305
            case 2: gen_op_mul_T0_T1(); break;
4306
            default: return 1;
4307
            }
4308
            NEON_GET_REG(T1, rd, pass);
4309
            if (u) { /* VMLS */
4310
                gen_neon_rsb(size);
4311
            } else { /* VMLA */
4312
                gen_neon_add(size);
4313
            }
4314
            break;
4315
        case 19: /* VMUL */
4316
            if (u) { /* polynomial */
4317
                gen_helper_neon_mul_p8(CPU_T001);
4318
            } else { /* Integer */
4319
                switch (size) {
4320
                case 0: gen_helper_neon_mul_u8(CPU_T001); break;
4321
                case 1: gen_helper_neon_mul_u16(CPU_T001); break;
4322
                case 2: gen_op_mul_T0_T1(); break;
4323
                default: return 1;
4324
                }
4325
            }
4326
            break;
4327
        case 20: /* VPMAX */
4328
            GEN_NEON_INTEGER_OP(pmax);
4329
            break;
4330
        case 21: /* VPMIN */
4331
            GEN_NEON_INTEGER_OP(pmin);
4332
            break;
4333
        case 22: /* Hultiply high.  */
4334
            if (!u) { /* VQDMULH */
4335
                switch (size) {
4336
                case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
4337
                case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
4338
                default: return 1;
4339
                }
4340
            } else { /* VQRDHMUL */
4341
                switch (size) {
4342
                case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
4343
                case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
4344
                default: return 1;
4345
                }
4346
            }
4347
            break;
4348
        case 23: /* VPADD */
4349
            if (u)
4350
                return 1;
4351
            switch (size) {
4352
            case 0: gen_helper_neon_padd_u8(CPU_T001); break;
4353
            case 1: gen_helper_neon_padd_u16(CPU_T001); break;
4354
            case 2: gen_op_addl_T0_T1(); break;
4355
            default: return 1;
4356
            }
4357
            break;
4358
        case 26: /* Floating point arithnetic.  */
4359
            switch ((u << 2) | size) {
4360
            case 0: /* VADD */
4361
                gen_helper_neon_add_f32(CPU_T001);
4362
                break;
4363
            case 2: /* VSUB */
4364
                gen_helper_neon_sub_f32(CPU_T001);
4365
                break;
4366
            case 4: /* VPADD */
4367
                gen_helper_neon_add_f32(CPU_T001);
4368
                break;
4369
            case 6: /* VABD */
4370
                gen_helper_neon_abd_f32(CPU_T001);
4371
                break;
4372
            default:
4373
                return 1;
4374
            }
4375
            break;
4376
        case 27: /* Float multiply.  */
4377
            gen_helper_neon_mul_f32(CPU_T001);
4378
            if (!u) {
4379
                NEON_GET_REG(T1, rd, pass);
4380
                if (size == 0) {
4381
                    gen_helper_neon_add_f32(CPU_T001);
4382
                } else {
4383
                    gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
4384
                }
4385
            }
4386
            break;
4387
        case 28: /* Float compare.  */
4388
            if (!u) {
4389
                gen_helper_neon_ceq_f32(CPU_T001);
4390
            } else {
4391
                if (size == 0)
4392
                    gen_helper_neon_cge_f32(CPU_T001);
4393
                else
4394
                    gen_helper_neon_cgt_f32(CPU_T001);
4395
            }
4396
            break;
4397
        case 29: /* Float compare absolute.  */
4398
            if (!u)
4399
                return 1;
4400
            if (size == 0)
4401
                gen_helper_neon_acge_f32(CPU_T001);
4402
            else
4403
                gen_helper_neon_acgt_f32(CPU_T001);
4404
            break;
4405
        case 30: /* Float min/max.  */
4406
            if (size == 0)
4407
                gen_helper_neon_max_f32(CPU_T001);
4408
            else
4409
                gen_helper_neon_min_f32(CPU_T001);
4410
            break;
4411
        case 31:
4412
            if (size == 0)
4413
                gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4414
            else
4415
                gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4416
            break;
4417
        default:
4418
            abort();
4419
        }
4420
        /* Save the result.  For elementwise operations we can put it
4421
           straight into the destination register.  For pairwise operations
4422
           we have to be careful to avoid clobbering the source operands.  */
4423
        if (pairwise && rd == rm) {
4424
            gen_neon_movl_scratch_T0(pass);
4425
        } else {
4426
            NEON_SET_REG(T0, rd, pass);
4427
        }
4428

    
4429
        } /* for pass */
4430
        if (pairwise && rd == rm) {
4431
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4432
                gen_neon_movl_T0_scratch(pass);
4433
                NEON_SET_REG(T0, rd, pass);
4434
            }
4435
        }
4436
        /* End of 3 register same size operations.  */
4437
    } else if (insn & (1 << 4)) {
4438
        if ((insn & 0x00380080) != 0) {
4439
            /* Two registers and shift.  */
4440
            op = (insn >> 8) & 0xf;
4441
            if (insn & (1 << 7)) {
4442
                /* 64-bit shift.   */
4443
                size = 3;
4444
            } else {
4445
                size = 2;
4446
                while ((insn & (1 << (size + 19))) == 0)
4447
                    size--;
4448
            }
4449
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4450
            /* To avoid excessive dumplication of ops we implement shift
4451
               by immediate using the variable shift operations.  */
4452
            if (op < 8) {
4453
                /* Shift by immediate:
4454
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4455
                /* Right shifts are encoded as N - shift, where N is the
4456
                   element size in bits.  */
4457
                if (op <= 4)
4458
                    shift = shift - (1 << (size + 3));
4459
                if (size == 3) {
4460
                    count = q + 1;
4461
                } else {
4462
                    count = q ? 4: 2;
4463
                }
4464
                switch (size) {
4465
                case 0:
4466
                    imm = (uint8_t) shift;
4467
                    imm |= imm << 8;
4468
                    imm |= imm << 16;
4469
                    break;
4470
                case 1:
4471
                    imm = (uint16_t) shift;
4472
                    imm |= imm << 16;
4473
                    break;
4474
                case 2:
4475
                case 3:
4476
                    imm = shift;
4477
                    break;
4478
                default:
4479
                    abort();
4480
                }
4481

    
4482
                for (pass = 0; pass < count; pass++) {
4483
                    if (size == 3) {
4484
                        neon_load_reg64(cpu_V0, rm + pass);
4485
                        tcg_gen_movi_i64(cpu_V1, imm);
4486
                        switch (op) {
4487
                        case 0:  /* VSHR */
4488
                        case 1:  /* VSRA */
4489
                            if (u)
4490
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4491
                            else
4492
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4493
                            break;
4494
                        case 2: /* VRSHR */
4495
                        case 3: /* VRSRA */
4496
                            if (u)
4497
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4498
                            else
4499
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4500
                            break;
4501
                        case 4: /* VSRI */
4502
                            if (!u)
4503
                                return 1;
4504
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4505
                            break;
4506
                        case 5: /* VSHL, VSLI */
4507
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4508
                            break;
4509
                        case 6: /* VQSHL */
4510
                            if (u)
4511
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4512
                            else
4513
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4514
                            break;
4515
                        case 7: /* VQSHLU */
4516
                            gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4517
                            break;
4518
                        }
4519
                        if (op == 1 || op == 3) {
4520
                            /* Accumulate.  */
4521
                            neon_load_reg64(cpu_V0, rd + pass);
4522
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4523
                        } else if (op == 4 || (op == 5 && u)) {
4524
                            /* Insert */
4525
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4526
                        }
4527
                        neon_store_reg64(cpu_V0, rd + pass);
4528
                    } else { /* size < 3 */
4529
                        /* Operands in T0 and T1.  */
4530
                        gen_op_movl_T1_im(imm);
4531
                        NEON_GET_REG(T0, rm, pass);
4532
                        switch (op) {
4533
                        case 0:  /* VSHR */
4534
                        case 1:  /* VSRA */
4535
                            GEN_NEON_INTEGER_OP(shl);
4536
                            break;
4537
                        case 2: /* VRSHR */
4538
                        case 3: /* VRSRA */
4539
                            GEN_NEON_INTEGER_OP(rshl);
4540
                            break;
4541
                        case 4: /* VSRI */
4542
                            if (!u)
4543
                                return 1;
4544
                            GEN_NEON_INTEGER_OP(shl);
4545
                            break;
4546
                        case 5: /* VSHL, VSLI */
4547
                            switch (size) {
4548
                            case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4549
                            case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4550
                            case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4551
                            default: return 1;
4552
                            }
4553
                            break;
4554
                        case 6: /* VQSHL */
4555
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4556
                            break;
4557
                        case 7: /* VQSHLU */
4558
                            switch (size) {
4559
                            case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4560
                            case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4561
                            case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4562
                            default: return 1;
4563
                            }
4564
                            break;
4565
                        }
4566

    
4567
                        if (op == 1 || op == 3) {
4568
                            /* Accumulate.  */
4569
                            NEON_GET_REG(T1, rd, pass);
4570
                            gen_neon_add(size);
4571
                        } else if (op == 4 || (op == 5 && u)) {
4572
                            /* Insert */
4573
                            switch (size) {
4574
                            case 0:
4575
                                if (op == 4)
4576
                                    imm = 0xff >> -shift;
4577
                                else
4578
                                    imm = (uint8_t)(0xff << shift);
4579
                                imm |= imm << 8;
4580
                                imm |= imm << 16;
4581
                                break;
4582
                            case 1:
4583
                                if (op == 4)
4584
                                    imm = 0xffff >> -shift;
4585
                                else
4586
                                    imm = (uint16_t)(0xffff << shift);
4587
                                imm |= imm << 16;
4588
                                break;
4589
                            case 2:
4590
                                if (op == 4)
4591
                                    imm = 0xffffffffu >> -shift;
4592
                                else
4593
                                    imm = 0xffffffffu << shift;
4594
                                break;
4595
                            default:
4596
                                abort();
4597
                            }
4598
                            tmp = neon_load_reg(rd, pass);
4599
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4600
                            tcg_gen_andi_i32(tmp, tmp, ~imm);
4601
                            tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4602
                        }
4603
                        NEON_SET_REG(T0, rd, pass);
4604
                    }
4605
                } /* for pass */
4606
            } else if (op < 10) {
4607
                /* Shift by immediate and narrow:
4608
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4609
                shift = shift - (1 << (size + 3));
4610
                size++;
4611
                switch (size) {
4612
                case 1:
4613
                    imm = (uint16_t)shift;
4614
                    imm |= imm << 16;
4615
                    tmp2 = tcg_const_i32(imm);
4616
                    TCGV_UNUSED_I64(tmp64);
4617
                    break;
4618
                case 2:
4619
                    imm = (uint32_t)shift;
4620
                    tmp2 = tcg_const_i32(imm);
4621
                    TCGV_UNUSED_I64(tmp64);
4622
                    break;
4623
                case 3:
4624
                    tmp64 = tcg_const_i64(shift);
4625
                    TCGV_UNUSED(tmp2);
4626
                    break;
4627
                default:
4628
                    abort();
4629
                }
4630

    
4631
                for (pass = 0; pass < 2; pass++) {
4632
                    if (size == 3) {
4633
                        neon_load_reg64(cpu_V0, rm + pass);
4634
                        if (q) {
4635
                          if (u)
4636
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
4637
                          else
4638
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
4639
                        } else {
4640
                          if (u)
4641
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
4642
                          else
4643
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
4644
                        }
4645
                    } else {
4646
                        tmp = neon_load_reg(rm + pass, 0);
4647
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4648
                        tmp3 = neon_load_reg(rm + pass, 1);
4649
                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
4650
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
4651
                        dead_tmp(tmp);
4652
                        dead_tmp(tmp3);
4653
                    }
4654
                    tmp = new_tmp();
4655
                    if (op == 8 && !u) {
4656
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4657
                    } else {
4658
                        if (op == 8)
4659
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4660
                        else
4661
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4662
                    }
4663
                    if (pass == 0) {
4664
                        tmp2 = tmp;
4665
                    } else {
4666
                        neon_store_reg(rd, 0, tmp2);
4667
                        neon_store_reg(rd, 1, tmp);
4668
                    }
4669
                } /* for pass */
4670
            } else if (op == 10) {
4671
                /* VSHLL */
4672
                if (q || size == 3)
4673
                    return 1;
4674
                tmp = neon_load_reg(rm, 0);
4675
                tmp2 = neon_load_reg(rm, 1);
4676
                for (pass = 0; pass < 2; pass++) {
4677
                    if (pass == 1)
4678
                        tmp = tmp2;
4679

    
4680
                    gen_neon_widen(cpu_V0, tmp, size, u);
4681

    
4682
                    if (shift != 0) {
4683
                        /* The shift is less than the width of the source
4684
                           type, so we can just shift the whole register.  */
4685
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4686
                        if (size < 2 || !u) {
4687
                            uint64_t imm64;
4688
                            if (size == 0) {
4689
                                imm = (0xffu >> (8 - shift));
4690
                                imm |= imm << 16;
4691
                            } else {
4692
                                imm = 0xffff >> (16 - shift);
4693
                            }
4694
                            imm64 = imm | (((uint64_t)imm) << 32);
4695
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4696
                        }
4697
                    }
4698
                    neon_store_reg64(cpu_V0, rd + pass);
4699
                }
4700
            } else if (op == 15 || op == 16) {
4701
                /* VCVT fixed-point.  */
4702
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4703
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4704
                    if (op & 1) {
4705
                        if (u)
4706
                            gen_vfp_ulto(0, shift);
4707
                        else
4708
                            gen_vfp_slto(0, shift);
4709
                    } else {
4710
                        if (u)
4711
                            gen_vfp_toul(0, shift);
4712
                        else
4713
                            gen_vfp_tosl(0, shift);
4714
                    }
4715
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4716
                }
4717
            } else {
4718
                return 1;
4719
            }
4720
        } else { /* (insn & 0x00380080) == 0 */
4721
            int invert;
4722

    
4723
            op = (insn >> 8) & 0xf;
4724
            /* One register and immediate.  */
4725
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4726
            invert = (insn & (1 << 5)) != 0;
4727
            switch (op) {
4728
            case 0: case 1:
4729
                /* no-op */
4730
                break;
4731
            case 2: case 3:
4732
                imm <<= 8;
4733
                break;
4734
            case 4: case 5:
4735
                imm <<= 16;
4736
                break;
4737
            case 6: case 7:
4738
                imm <<= 24;
4739
                break;
4740
            case 8: case 9:
4741
                imm |= imm << 16;
4742
                break;
4743
            case 10: case 11:
4744
                imm = (imm << 8) | (imm << 24);
4745
                break;
4746
            case 12:
4747
                imm = (imm < 8) | 0xff;
4748
                break;
4749
            case 13:
4750
                imm = (imm << 16) | 0xffff;
4751
                break;
4752
            case 14:
4753
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4754
                if (invert)
4755
                    imm = ~imm;
4756
                break;
4757
            case 15:
4758
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4759
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4760
                break;
4761
            }
4762
            if (invert)
4763
                imm = ~imm;
4764

    
4765
            if (op != 14 || !invert)
4766
                gen_op_movl_T1_im(imm);
4767

    
4768
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4769
                if (op & 1 && op < 12) {
4770
                    tmp = neon_load_reg(rd, pass);
4771
                    if (invert) {
4772
                        /* The immediate value has already been inverted, so
4773
                           BIC becomes AND.  */
4774
                        tcg_gen_andi_i32(tmp, tmp, imm);
4775
                    } else {
4776
                        tcg_gen_ori_i32(tmp, tmp, imm);
4777
                    }
4778
                } else {
4779
                    /* VMOV, VMVN.  */
4780
                    tmp = new_tmp();
4781
                    if (op == 14 && invert) {
4782
                        uint32_t val;
4783
                        val = 0;
4784
                        for (n = 0; n < 4; n++) {
4785
                            if (imm & (1 << (n + (pass & 1) * 4)))
4786
                                val |= 0xff << (n * 8);
4787
                        }
4788
                        tcg_gen_movi_i32(tmp, val);
4789
                    } else {
4790
                        tcg_gen_movi_i32(tmp, imm);
4791
                    }
4792
                }
4793
                neon_store_reg(rd, pass, tmp);
4794
            }
4795
        }
4796
    } else { /* (insn & 0x00800010 == 0x00800000) */
4797
        if (size != 3) {
4798
            op = (insn >> 8) & 0xf;
4799
            if ((insn & (1 << 6)) == 0) {
4800
                /* Three registers of different lengths.  */
4801
                int src1_wide;
4802
                int src2_wide;
4803
                int prewiden;
4804
                /* prewiden, src1_wide, src2_wide */
4805
                static const int neon_3reg_wide[16][3] = {
4806
                    {1, 0, 0}, /* VADDL */
4807
                    {1, 1, 0}, /* VADDW */
4808
                    {1, 0, 0}, /* VSUBL */
4809
                    {1, 1, 0}, /* VSUBW */
4810
                    {0, 1, 1}, /* VADDHN */
4811
                    {0, 0, 0}, /* VABAL */
4812
                    {0, 1, 1}, /* VSUBHN */
4813
                    {0, 0, 0}, /* VABDL */
4814
                    {0, 0, 0}, /* VMLAL */
4815
                    {0, 0, 0}, /* VQDMLAL */
4816
                    {0, 0, 0}, /* VMLSL */
4817
                    {0, 0, 0}, /* VQDMLSL */
4818
                    {0, 0, 0}, /* Integer VMULL */
4819
                    {0, 0, 0}, /* VQDMULL */
4820
                    {0, 0, 0}  /* Polynomial VMULL */
4821
                };
4822

    
4823
                prewiden = neon_3reg_wide[op][0];
4824
                src1_wide = neon_3reg_wide[op][1];
4825
                src2_wide = neon_3reg_wide[op][2];
4826

    
4827
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4828
                    return 1;
4829

    
4830
                /* Avoid overlapping operands.  Wide source operands are
4831
                   always aligned so will never overlap with wide
4832
                   destinations in problematic ways.  */
4833
                if (rd == rm && !src2_wide) {
4834
                    NEON_GET_REG(T0, rm, 1);
4835
                    gen_neon_movl_scratch_T0(2);
4836
                } else if (rd == rn && !src1_wide) {
4837
                    NEON_GET_REG(T0, rn, 1);
4838
                    gen_neon_movl_scratch_T0(2);
4839
                }
4840
                TCGV_UNUSED(tmp3);
4841
                for (pass = 0; pass < 2; pass++) {
4842
                    if (src1_wide) {
4843
                        neon_load_reg64(cpu_V0, rn + pass);
4844
                        TCGV_UNUSED(tmp);
4845
                    } else {
4846
                        if (pass == 1 && rd == rn) {
4847
                            gen_neon_movl_T0_scratch(2);
4848
                            tmp = new_tmp();
4849
                            tcg_gen_mov_i32(tmp, cpu_T[0]);
4850
                        } else {
4851
                            tmp = neon_load_reg(rn, pass);
4852
                        }
4853
                        if (prewiden) {
4854
                            gen_neon_widen(cpu_V0, tmp, size, u);
4855
                        }
4856
                    }
4857
                    if (src2_wide) {
4858
                        neon_load_reg64(cpu_V1, rm + pass);
4859
                        TCGV_UNUSED(tmp2);
4860
                    } else {
4861
                        if (pass == 1 && rd == rm) {
4862
                            gen_neon_movl_T0_scratch(2);
4863
                            tmp2 = new_tmp();
4864
                            tcg_gen_mov_i32(tmp2, cpu_T[0]);
4865
                        } else {
4866
                            tmp2 = neon_load_reg(rm, pass);
4867
                        }
4868
                        if (prewiden) {
4869
                            gen_neon_widen(cpu_V1, tmp2, size, u);
4870
                        }
4871
                    }
4872
                    switch (op) {
4873
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4874
                        gen_neon_addl(size);
4875
                        break;
4876
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4877
                        gen_neon_subl(size);
4878
                        break;
4879
                    case 5: case 7: /* VABAL, VABDL */
4880
                        switch ((size << 1) | u) {
4881
                        case 0:
4882
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
4883
                            break;
4884
                        case 1:
4885
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
4886
                            break;
4887
                        case 2:
4888
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
4889
                            break;
4890
                        case 3:
4891
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
4892
                            break;
4893
                        case 4:
4894
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
4895
                            break;
4896
                        case 5:
4897
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
4898
                            break;
4899
                        default: abort();
4900
                        }
4901
                        dead_tmp(tmp2);
4902
                        dead_tmp(tmp);
4903
                        break;
4904
                    case 8: case 9: case 10: case 11: case 12: case 13:
4905
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4906
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
4907
                        break;
4908
                    case 14: /* Polynomial VMULL */
4909
                        cpu_abort(env, "Polynomial VMULL not implemented");
4910

    
4911
                    default: /* 15 is RESERVED.  */
4912
                        return 1;
4913
                    }
4914
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4915
                        /* Accumulate.  */
4916
                        if (op == 10 || op == 11) {
4917
                            gen_neon_negl(cpu_V0, size);
4918
                        }
4919

    
4920
                        if (op != 13) {
4921
                            neon_load_reg64(cpu_V1, rd + pass);
4922
                        }
4923

    
4924
                        switch (op) {
4925
                        case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4926
                            gen_neon_addl(size);
4927
                            break;
4928
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
4929
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4930
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
4931
                            break;
4932
                            /* Fall through.  */
4933
                        case 13: /* VQDMULL */
4934
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
4935
                            break;
4936
                        default:
4937
                            abort();
4938
                        }
4939
                        neon_store_reg64(cpu_V0, rd + pass);
4940
                    } else if (op == 4 || op == 6) {
4941
                        /* Narrowing operation.  */
4942
                        tmp = new_tmp();
4943
                        if (u) {
4944
                            switch (size) {
4945
                            case 0:
4946
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
4947
                                break;
4948
                            case 1:
4949
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
4950
                                break;
4951
                            case 2:
4952
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4953
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4954
                                break;
4955
                            default: abort();
4956
                            }
4957
                        } else {
4958
                            switch (size) {
4959
                            case 0:
4960
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
4961
                                break;
4962
                            case 1:
4963
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
4964
                                break;
4965
                            case 2:
4966
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
4967
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
4968
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
4969
                                break;
4970
                            default: abort();
4971
                            }
4972
                        }
4973
                        if (pass == 0) {
4974
                            tmp3 = tmp;
4975
                        } else {
4976
                            neon_store_reg(rd, 0, tmp3);
4977
                            neon_store_reg(rd, 1, tmp);
4978
                        }
4979
                    } else {
4980
                        /* Write back the result.  */
4981
                        neon_store_reg64(cpu_V0, rd + pass);
4982
                    }
4983
                }
4984
            } else {
4985
                /* Two registers and a scalar.  */
4986
                switch (op) {
4987
                case 0: /* Integer VMLA scalar */
4988
                case 1: /* Float VMLA scalar */
4989
                case 4: /* Integer VMLS scalar */
4990
                case 5: /* Floating point VMLS scalar */
4991
                case 8: /* Integer VMUL scalar */
4992
                case 9: /* Floating point VMUL scalar */
4993
                case 12: /* VQDMULH scalar */
4994
                case 13: /* VQRDMULH scalar */
4995
                    gen_neon_get_scalar(size, rm);
4996
                    gen_neon_movl_scratch_T0(0);
4997
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
4998
                        if (pass != 0)
4999
                            gen_neon_movl_T0_scratch(0);
5000
                        NEON_GET_REG(T1, rn, pass);
5001
                        if (op == 12) {
5002
                            if (size == 1) {
5003
                                gen_helper_neon_qdmulh_s16(CPU_T0E01);
5004
                            } else {
5005
                                gen_helper_neon_qdmulh_s32(CPU_T0E01);
5006
                            }
5007
                        } else if (op == 13) {
5008
                            if (size == 1) {
5009
                                gen_helper_neon_qrdmulh_s16(CPU_T0E01);
5010
                            } else {
5011
                                gen_helper_neon_qrdmulh_s32(CPU_T0E01);
5012
                            }
5013
                        } else if (op & 1) {
5014
                            gen_helper_neon_mul_f32(CPU_T001);
5015
                        } else {
5016
                            switch (size) {
5017
                            case 0: gen_helper_neon_mul_u8(CPU_T001); break;
5018
                            case 1: gen_helper_neon_mul_u16(CPU_T001); break;
5019
                            case 2: gen_op_mul_T0_T1(); break;
5020
                            default: return 1;
5021
                            }
5022
                        }
5023
                        if (op < 8) {
5024
                            /* Accumulate.  */
5025
                            NEON_GET_REG(T1, rd, pass);
5026
                            switch (op) {
5027
                            case 0:
5028
                                gen_neon_add(size);
5029
                                break;
5030
                            case 1:
5031
                                gen_helper_neon_add_f32(CPU_T001);
5032
                                break;
5033
                            case 4:
5034
                                gen_neon_rsb(size);
5035
                                break;
5036
                            case 5:
5037
                                gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
5038
                                break;
5039
                            default:
5040
                                abort();
5041
                            }
5042
                        }
5043
                        NEON_SET_REG(T0, rd, pass);
5044
                    }
5045
                    break;
5046
                case 2: /* VMLAL sclar */
5047
                case 3: /* VQDMLAL scalar */
5048
                case 6: /* VMLSL scalar */
5049
                case 7: /* VQDMLSL scalar */
5050
                case 10: /* VMULL scalar */
5051
                case 11: /* VQDMULL scalar */
5052
                    if (size == 0 && (op == 3 || op == 7 || op == 11))
5053
                        return 1;
5054

    
5055
                    gen_neon_get_scalar(size, rm);
5056
                    NEON_GET_REG(T1, rn, 1);
5057

    
5058
                    for (pass = 0; pass < 2; pass++) {
5059
                        if (pass == 0) {
5060
                            tmp = neon_load_reg(rn, 0);
5061
                        } else {
5062
                            tmp = new_tmp();
5063
                            tcg_gen_mov_i32(tmp, cpu_T[1]);
5064
                        }
5065
                        tmp2 = new_tmp();
5066
                        tcg_gen_mov_i32(tmp2, cpu_T[0]);
5067
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5068
                        if (op == 6 || op == 7) {
5069
                            gen_neon_negl(cpu_V0, size);
5070
                        }
5071
                        if (op != 11) {
5072
                            neon_load_reg64(cpu_V1, rd + pass);
5073
                        }
5074
                        switch (op) {
5075
                        case 2: case 6:
5076
                            gen_neon_addl(size);
5077
                            break;
5078
                        case 3: case 7:
5079
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5080
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5081
                            break;
5082
                        case 10:
5083
                            /* no-op */
5084
                            break;
5085
                        case 11:
5086
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5087
                            break;
5088
                        default:
5089
                            abort();
5090
                        }
5091
                        neon_store_reg64(cpu_V0, rd + pass);
5092
                    }
5093
                    break;
5094
                default: /* 14 and 15 are RESERVED */
5095
                    return 1;
5096
                }
5097
            }
5098
        } else { /* size == 3 */
5099
            if (!u) {
5100
                /* Extract.  */
5101
                imm = (insn >> 8) & 0xf;
5102
                count = q + 1;
5103

    
5104
                if (imm > 7 && !q)
5105
                    return 1;
5106

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

    
5536
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5537
{
5538
    int crn = (insn >> 16) & 0xf;
5539
    int crm = insn & 0xf;
5540
    int op1 = (insn >> 21) & 7;
5541
    int op2 = (insn >> 5) & 7;
5542
    int rt = (insn >> 12) & 0xf;
5543
    TCGv tmp;
5544

    
5545
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5546
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5547
            /* TEECR */
5548
            if (IS_USER(s))
5549
                return 1;
5550
            tmp = load_cpu_field(teecr);
5551
            store_reg(s, rt, tmp);
5552
            return 0;
5553
        }
5554
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5555
            /* TEEHBR */
5556
            if (IS_USER(s) && (env->teecr & 1))
5557
                return 1;
5558
            tmp = load_cpu_field(teehbr);
5559
            store_reg(s, rt, tmp);
5560
            return 0;
5561
        }
5562
    }
5563
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5564
            op1, crn, crm, op2);
5565
    return 1;
5566
}
5567

    
5568
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5569
{
5570
    int crn = (insn >> 16) & 0xf;
5571
    int crm = insn & 0xf;
5572
    int op1 = (insn >> 21) & 7;
5573
    int op2 = (insn >> 5) & 7;
5574
    int rt = (insn >> 12) & 0xf;
5575
    TCGv tmp;
5576

    
5577
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5578
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5579
            /* TEECR */
5580
            if (IS_USER(s))
5581
                return 1;
5582
            tmp = load_reg(s, rt);
5583
            gen_helper_set_teecr(cpu_env, tmp);
5584
            dead_tmp(tmp);
5585
            return 0;
5586
        }
5587
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5588
            /* TEEHBR */
5589
            if (IS_USER(s) && (env->teecr & 1))
5590
                return 1;
5591
            tmp = load_reg(s, rt);
5592
            store_cpu_field(tmp, teehbr);
5593
            return 0;
5594
        }
5595
    }
5596
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5597
            op1, crn, crm, op2);
5598
    return 1;
5599
}
5600

    
5601
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5602
{
5603
    int cpnum;
5604

    
5605
    cpnum = (insn >> 8) & 0xf;
5606
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5607
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5608
        return 1;
5609

    
5610
    switch (cpnum) {
5611
      case 0:
5612
      case 1:
5613
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5614
            return disas_iwmmxt_insn(env, s, insn);
5615
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5616
            return disas_dsp_insn(env, s, insn);
5617
        }
5618
        return 1;
5619
    case 10:
5620
    case 11:
5621
        return disas_vfp_insn (env, s, insn);
5622
    case 14:
5623
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5624
           Unfortunately Intel decided to ignore this.  */
5625
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5626
            goto board;
5627
        if (insn & (1 << 20))
5628
            return disas_cp14_read(env, s, insn);
5629
        else
5630
            return disas_cp14_write(env, s, insn);
5631
    case 15:
5632
        return disas_cp15_insn (env, s, insn);
5633
    default:
5634
    board:
5635
        /* Unknown coprocessor.  See if the board has hooked it.  */
5636
        return disas_cp_insn (env, s, insn);
5637
    }
5638
}
5639

    
5640

    
5641
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5642
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5643
{
5644
    TCGv tmp;
5645
    tmp = new_tmp();
5646
    tcg_gen_trunc_i64_i32(tmp, val);
5647
    store_reg(s, rlow, tmp);
5648
    tmp = new_tmp();
5649
    tcg_gen_shri_i64(val, val, 32);
5650
    tcg_gen_trunc_i64_i32(tmp, val);
5651
    store_reg(s, rhigh, tmp);
5652
}
5653

    
5654
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5655
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5656
{
5657
    TCGv_i64 tmp;
5658
    TCGv tmp2;
5659

    
5660
    /* Load value and extend to 64 bits.  */
5661
    tmp = tcg_temp_new_i64();
5662
    tmp2 = load_reg(s, rlow);
5663
    tcg_gen_extu_i32_i64(tmp, tmp2);
5664
    dead_tmp(tmp2);
5665
    tcg_gen_add_i64(val, val, tmp);
5666
}
5667

    
5668
/* load and add a 64-bit value from a register pair.  */
5669
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5670
{
5671
    TCGv_i64 tmp;
5672
    TCGv tmpl;
5673
    TCGv tmph;
5674

    
5675
    /* Load 64-bit value rd:rn.  */
5676
    tmpl = load_reg(s, rlow);
5677
    tmph = load_reg(s, rhigh);
5678
    tmp = tcg_temp_new_i64();
5679
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5680
    dead_tmp(tmpl);
5681
    dead_tmp(tmph);
5682
    tcg_gen_add_i64(val, val, tmp);
5683
}
5684

    
5685
/* Set N and Z flags from a 64-bit value.  */
5686
static void gen_logicq_cc(TCGv_i64 val)
5687
{
5688
    TCGv tmp = new_tmp();
5689
    gen_helper_logicq_cc(tmp, val);
5690
    gen_logic_CC(tmp);
5691
    dead_tmp(tmp);
5692
}
5693

    
5694
static void disas_arm_insn(CPUState * env, DisasContext *s)
5695
{
5696
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5697
    TCGv tmp;
5698
    TCGv tmp2;
5699
    TCGv tmp3;
5700
    TCGv addr;
5701
    TCGv_i64 tmp64;
5702

    
5703
    insn = ldl_code(s->pc);
5704
    s->pc += 4;
5705

    
5706
    /* M variants do not implement ARM mode.  */
5707
    if (IS_M(env))
5708
        goto illegal_op;
5709
    cond = insn >> 28;
5710
    if (cond == 0xf){
5711
        /* Unconditional instructions.  */
5712
        if (((insn >> 25) & 7) == 1) {
5713
            /* NEON Data processing.  */
5714
            if (!arm_feature(env, ARM_FEATURE_NEON))
5715
                goto illegal_op;
5716

    
5717
            if (disas_neon_data_insn(env, s, insn))
5718
                goto illegal_op;
5719
            return;
5720
        }
5721
        if ((insn & 0x0f100000) == 0x04000000) {
5722
            /* NEON load/store.  */
5723
            if (!arm_feature(env, ARM_FEATURE_NEON))
5724
                goto illegal_op;
5725

    
5726
            if (disas_neon_ls_insn(env, s, insn))
5727
                goto illegal_op;
5728
            return;
5729
        }
5730
        if ((insn & 0x0d70f000) == 0x0550f000)
5731
            return; /* PLD */
5732
        else if ((insn & 0x0ffffdff) == 0x01010000) {
5733
            ARCH(6);
5734
            /* setend */
5735
            if (insn & (1 << 9)) {
5736
                /* BE8 mode not implemented.  */
5737
                goto illegal_op;
5738
            }
5739
            return;
5740
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
5741
            switch ((insn >> 4) & 0xf) {
5742
            case 1: /* clrex */
5743
                ARCH(6K);
5744
                gen_helper_clrex(cpu_env);
5745
                return;
5746
            case 4: /* dsb */
5747
            case 5: /* dmb */
5748
            case 6: /* isb */
5749
                ARCH(7);
5750
                /* We don't emulate caches so these are a no-op.  */
5751
                return;
5752
            default:
5753
                goto illegal_op;
5754
            }
5755
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5756
            /* srs */
5757
            uint32_t offset;
5758
            if (IS_USER(s))
5759
                goto illegal_op;
5760
            ARCH(6);
5761
            op1 = (insn & 0x1f);
5762
            if (op1 == (env->uncached_cpsr & CPSR_M)) {
5763
                addr = load_reg(s, 13);
5764
            } else {
5765
                addr = new_tmp();
5766
                gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5767
            }
5768
            i = (insn >> 23) & 3;
5769
            switch (i) {
5770
            case 0: offset = -4; break; /* DA */
5771
            case 1: offset = -8; break; /* DB */
5772
            case 2: offset = 0; break; /* IA */
5773
            case 3: offset = 4; break; /* IB */
5774
            default: abort();
5775
            }
5776
            if (offset)
5777
                tcg_gen_addi_i32(addr, addr, offset);
5778
            tmp = load_reg(s, 14);
5779
            gen_st32(tmp, addr, 0);
5780
            tmp = new_tmp();
5781
            gen_helper_cpsr_read(tmp);
5782
            tcg_gen_addi_i32(addr, addr, 4);
5783
            gen_st32(tmp, addr, 0);
5784
            if (insn & (1 << 21)) {
5785
                /* Base writeback.  */
5786
                switch (i) {
5787
                case 0: offset = -8; break;
5788
                case 1: offset = -4; break;
5789
                case 2: offset = 4; break;
5790
                case 3: offset = 0; break;
5791
                default: abort();
5792
                }
5793
                if (offset)
5794
                    tcg_gen_addi_i32(addr, tmp, offset);
5795
                if (op1 == (env->uncached_cpsr & CPSR_M)) {
5796
                    gen_movl_reg_T1(s, 13);
5797
                } else {
5798
                    gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5799
                }
5800
            } else {
5801
                dead_tmp(addr);
5802
            }
5803
        } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5804
            /* rfe */
5805
            uint32_t offset;
5806
            if (IS_USER(s))
5807
                goto illegal_op;
5808
            ARCH(6);
5809
            rn = (insn >> 16) & 0xf;
5810
            addr = load_reg(s, rn);
5811
            i = (insn >> 23) & 3;
5812
            switch (i) {
5813
            case 0: offset = -4; break; /* DA */
5814
            case 1: offset = -8; break; /* DB */
5815
            case 2: offset = 0; break; /* IA */
5816
            case 3: offset = 4; break; /* IB */
5817
            default: abort();
5818
            }
5819
            if (offset)
5820
                tcg_gen_addi_i32(addr, addr, offset);
5821
            /* Load PC into tmp and CPSR into tmp2.  */
5822
            tmp = gen_ld32(addr, 0);
5823
            tcg_gen_addi_i32(addr, addr, 4);
5824
            tmp2 = gen_ld32(addr, 0);
5825
            if (insn & (1 << 21)) {
5826
                /* Base writeback.  */
5827
                switch (i) {
5828
                case 0: offset = -8; break;
5829
                case 1: offset = -4; break;
5830
                case 2: offset = 4; break;
5831
                case 3: offset = 0; break;
5832
                default: abort();
5833
                }
5834
                if (offset)
5835
                    tcg_gen_addi_i32(addr, addr, offset);
5836
                store_reg(s, rn, addr);
5837
            } else {
5838
                dead_tmp(addr);
5839
            }
5840
            gen_rfe(s, tmp, tmp2);
5841
        } else if ((insn & 0x0e000000) == 0x0a000000) {
5842
            /* branch link and change to thumb (blx <offset>) */
5843
            int32_t offset;
5844

    
5845
            val = (uint32_t)s->pc;
5846
            tmp = new_tmp();
5847
            tcg_gen_movi_i32(tmp, val);
5848
            store_reg(s, 14, tmp);
5849
            /* Sign-extend the 24-bit offset */
5850
            offset = (((int32_t)insn) << 8) >> 8;
5851
            /* offset * 4 + bit24 * 2 + (thumb bit) */
5852
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
5853
            /* pipeline offset */
5854
            val += 4;
5855
            gen_bx_im(s, val);
5856
            return;
5857
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
5858
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5859
                /* iWMMXt register transfer.  */
5860
                if (env->cp15.c15_cpar & (1 << 1))
5861
                    if (!disas_iwmmxt_insn(env, s, insn))
5862
                        return;
5863
            }
5864
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
5865
            /* Coprocessor double register transfer.  */
5866
        } else if ((insn & 0x0f000010) == 0x0e000010) {
5867
            /* Additional coprocessor register transfer.  */
5868
        } else if ((insn & 0x0ff10020) == 0x01000000) {
5869
            uint32_t mask;
5870
            uint32_t val;
5871
            /* cps (privileged) */
5872
            if (IS_USER(s))
5873
                return;
5874
            mask = val = 0;
5875
            if (insn & (1 << 19)) {
5876
                if (insn & (1 << 8))
5877
                    mask |= CPSR_A;
5878
                if (insn & (1 << 7))
5879
                    mask |= CPSR_I;
5880
                if (insn & (1 << 6))
5881
                    mask |= CPSR_F;
5882
                if (insn & (1 << 18))
5883
                    val |= mask;
5884
            }
5885
            if (insn & (1 << 17)) {
5886
                mask |= CPSR_M;
5887
                val |= (insn & 0x1f);
5888
            }
5889
            if (mask) {
5890
                gen_op_movl_T0_im(val);
5891
                gen_set_psr_T0(s, mask, 0);
5892
            }
5893
            return;
5894
        }
5895
        goto illegal_op;
5896
    }
5897
    if (cond != 0xe) {
5898
        /* if not always execute, we generate a conditional jump to
5899
           next instruction */
5900
        s->condlabel = gen_new_label();
5901
        gen_test_cc(cond ^ 1, s->condlabel);
5902
        s->condjmp = 1;
5903
    }
5904
    if ((insn & 0x0f900000) == 0x03000000) {
5905
        if ((insn & (1 << 21)) == 0) {
5906
            ARCH(6T2);
5907
            rd = (insn >> 12) & 0xf;
5908
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5909
            if ((insn & (1 << 22)) == 0) {
5910
                /* MOVW */
5911
                tmp = new_tmp();
5912
                tcg_gen_movi_i32(tmp, val);
5913
            } else {
5914
                /* MOVT */
5915
                tmp = load_reg(s, rd);
5916
                tcg_gen_ext16u_i32(tmp, tmp);
5917
                tcg_gen_ori_i32(tmp, tmp, val << 16);
5918
            }
5919
            store_reg(s, rd, tmp);
5920
        } else {
5921
            if (((insn >> 12) & 0xf) != 0xf)
5922
                goto illegal_op;
5923
            if (((insn >> 16) & 0xf) == 0) {
5924
                gen_nop_hint(s, insn & 0xff);
5925
            } else {
5926
                /* CPSR = immediate */
5927
                val = insn & 0xff;
5928
                shift = ((insn >> 8) & 0xf) * 2;
5929
                if (shift)
5930
                    val = (val >> shift) | (val << (32 - shift));
5931
                gen_op_movl_T0_im(val);
5932
                i = ((insn & (1 << 22)) != 0);
5933
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5934
                    goto illegal_op;
5935
            }
5936
        }
5937
    } else if ((insn & 0x0f900000) == 0x01000000
5938
               && (insn & 0x00000090) != 0x00000090) {
5939
        /* miscellaneous instructions */
5940
        op1 = (insn >> 21) & 3;
5941
        sh = (insn >> 4) & 0xf;
5942
        rm = insn & 0xf;
5943
        switch (sh) {
5944
        case 0x0: /* move program status register */
5945
            if (op1 & 1) {
5946
                /* PSR = reg */
5947
                gen_movl_T0_reg(s, rm);
5948
                i = ((op1 & 2) != 0);
5949
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5950
                    goto illegal_op;
5951
            } else {
5952
                /* reg = PSR */
5953
                rd = (insn >> 12) & 0xf;
5954
                if (op1 & 2) {
5955
                    if (IS_USER(s))
5956
                        goto illegal_op;
5957
                    tmp = load_cpu_field(spsr);
5958
                } else {
5959
                    tmp = new_tmp();
5960
                    gen_helper_cpsr_read(tmp);
5961
                }
5962
                store_reg(s, rd, tmp);
5963
            }
5964
            break;
5965
        case 0x1:
5966
            if (op1 == 1) {
5967
                /* branch/exchange thumb (bx).  */
5968
                tmp = load_reg(s, rm);
5969
                gen_bx(s, tmp);
5970
            } else if (op1 == 3) {
5971
                /* clz */
5972
                rd = (insn >> 12) & 0xf;
5973
                tmp = load_reg(s, rm);
5974
                gen_helper_clz(tmp, tmp);
5975
                store_reg(s, rd, tmp);
5976
            } else {
5977
                goto illegal_op;
5978
            }
5979
            break;
5980
        case 0x2:
5981
            if (op1 == 1) {
5982
                ARCH(5J); /* bxj */
5983
                /* Trivial implementation equivalent to bx.  */
5984
                tmp = load_reg(s, rm);
5985
                gen_bx(s, tmp);
5986
            } else {
5987
                goto illegal_op;
5988
            }
5989
            break;
5990
        case 0x3:
5991
            if (op1 != 1)
5992
              goto illegal_op;
5993

    
5994
            /* branch link/exchange thumb (blx) */
5995
            tmp = load_reg(s, rm);
5996
            tmp2 = new_tmp();
5997
            tcg_gen_movi_i32(tmp2, s->pc);
5998
            store_reg(s, 14, tmp2);
5999
            gen_bx(s, tmp);
6000
            break;
6001
        case 0x5: /* saturating add/subtract */
6002
            rd = (insn >> 12) & 0xf;
6003
            rn = (insn >> 16) & 0xf;
6004
            tmp = load_reg(s, rm);
6005
            tmp2 = load_reg(s, rn);
6006
            if (op1 & 2)
6007
                gen_helper_double_saturate(tmp2, tmp2);
6008
            if (op1 & 1)
6009
                gen_helper_sub_saturate(tmp, tmp, tmp2);
6010
            else
6011
                gen_helper_add_saturate(tmp, tmp, tmp2);
6012
            dead_tmp(tmp2);
6013
            store_reg(s, rd, tmp);
6014
            break;
6015
        case 7: /* bkpt */
6016
            gen_set_condexec(s);
6017
            gen_set_pc_im(s->pc - 4);
6018
            gen_exception(EXCP_BKPT);
6019
            s->is_jmp = DISAS_JUMP;
6020
            break;
6021
        case 0x8: /* signed multiply */
6022
        case 0xa:
6023
        case 0xc:
6024
        case 0xe:
6025
            rs = (insn >> 8) & 0xf;
6026
            rn = (insn >> 12) & 0xf;
6027
            rd = (insn >> 16) & 0xf;
6028
            if (op1 == 1) {
6029
                /* (32 * 16) >> 16 */
6030
                tmp = load_reg(s, rm);
6031
                tmp2 = load_reg(s, rs);
6032
                if (sh & 4)
6033
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6034
                else
6035
                    gen_sxth(tmp2);
6036
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
6037
                tcg_gen_shri_i64(tmp64, tmp64, 16);
6038
                tmp = new_tmp();
6039
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6040
                if ((sh & 2) == 0) {
6041
                    tmp2 = load_reg(s, rn);
6042
                    gen_helper_add_setq(tmp, tmp, tmp2);
6043
                    dead_tmp(tmp2);
6044
                }
6045
                store_reg(s, rd, tmp);
6046
            } else {
6047
                /* 16 * 16 */
6048
                tmp = load_reg(s, rm);
6049
                tmp2 = load_reg(s, rs);
6050
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6051
                dead_tmp(tmp2);
6052
                if (op1 == 2) {
6053
                    tmp64 = tcg_temp_new_i64();
6054
                    tcg_gen_ext_i32_i64(tmp64, tmp);
6055
                    dead_tmp(tmp);
6056
                    gen_addq(s, tmp64, rn, rd);
6057
                    gen_storeq_reg(s, rn, rd, tmp64);
6058
                } else {
6059
                    if (op1 == 0) {
6060
                        tmp2 = load_reg(s, rn);
6061
                        gen_helper_add_setq(tmp, tmp, tmp2);
6062
                        dead_tmp(tmp2);
6063
                    }
6064
                    store_reg(s, rd, tmp);
6065
                }
6066
            }
6067
            break;
6068
        default:
6069
            goto illegal_op;
6070
        }
6071
    } else if (((insn & 0x0e000000) == 0 &&
6072
                (insn & 0x00000090) != 0x90) ||
6073
               ((insn & 0x0e000000) == (1 << 25))) {
6074
        int set_cc, logic_cc, shiftop;
6075

    
6076
        op1 = (insn >> 21) & 0xf;
6077
        set_cc = (insn >> 20) & 1;
6078
        logic_cc = table_logic_cc[op1] & set_cc;
6079

    
6080
        /* data processing instruction */
6081
        if (insn & (1 << 25)) {
6082
            /* immediate operand */
6083
            val = insn & 0xff;
6084
            shift = ((insn >> 8) & 0xf) * 2;
6085
            if (shift) {
6086
                val = (val >> shift) | (val << (32 - shift));
6087
            }
6088
            tmp2 = new_tmp();
6089
            tcg_gen_movi_i32(tmp2, val);
6090
            if (logic_cc && shift) {
6091
                gen_set_CF_bit31(tmp2);
6092
            }
6093
        } else {
6094
            /* register */
6095
            rm = (insn) & 0xf;
6096
            tmp2 = load_reg(s, rm);
6097
            shiftop = (insn >> 5) & 3;
6098
            if (!(insn & (1 << 4))) {
6099
                shift = (insn >> 7) & 0x1f;
6100
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
6101
            } else {
6102
                rs = (insn >> 8) & 0xf;
6103
                tmp = load_reg(s, rs);
6104
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
6105
            }
6106
        }
6107
        if (op1 != 0x0f && op1 != 0x0d) {
6108
            rn = (insn >> 16) & 0xf;
6109
            tmp = load_reg(s, rn);
6110
        } else {
6111
            TCGV_UNUSED(tmp);
6112
        }
6113
        rd = (insn >> 12) & 0xf;
6114
        switch(op1) {
6115
        case 0x00:
6116
            tcg_gen_and_i32(tmp, tmp, tmp2);
6117
            if (logic_cc) {
6118
                gen_logic_CC(tmp);
6119
            }
6120
            store_reg_bx(env, s, rd, tmp);
6121
            break;
6122
        case 0x01:
6123
            tcg_gen_xor_i32(tmp, tmp, tmp2);
6124
            if (logic_cc) {
6125
                gen_logic_CC(tmp);
6126
            }
6127
            store_reg_bx(env, s, rd, tmp);
6128
            break;
6129
        case 0x02:
6130
            if (set_cc && rd == 15) {
6131
                /* SUBS r15, ... is used for exception return.  */
6132
                if (IS_USER(s)) {
6133
                    goto illegal_op;
6134
                }
6135
                gen_helper_sub_cc(tmp, tmp, tmp2);
6136
                gen_exception_return(s, tmp);
6137
            } else {
6138
                if (set_cc) {
6139
                    gen_helper_sub_cc(tmp, tmp, tmp2);
6140
                } else {
6141
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
6142
                }
6143
                store_reg_bx(env, s, rd, tmp);
6144
            }
6145
            break;
6146
        case 0x03:
6147
            if (set_cc) {
6148
                gen_helper_sub_cc(tmp, tmp2, tmp);
6149
            } else {
6150
                tcg_gen_sub_i32(tmp, tmp2, tmp);
6151
            }
6152
            store_reg_bx(env, s, rd, tmp);
6153
            break;
6154
        case 0x04:
6155
            if (set_cc) {
6156
                gen_helper_add_cc(tmp, tmp, tmp2);
6157
            } else {
6158
                tcg_gen_add_i32(tmp, tmp, tmp2);
6159
            }
6160
            store_reg_bx(env, s, rd, tmp);
6161
            break;
6162
        case 0x05:
6163
            if (set_cc) {
6164
                gen_helper_adc_cc(tmp, tmp, tmp2);
6165
            } else {
6166
                gen_add_carry(tmp, tmp, tmp2);
6167
            }
6168
            store_reg_bx(env, s, rd, tmp);
6169
            break;
6170
        case 0x06:
6171
            if (set_cc) {
6172
                gen_helper_sbc_cc(tmp, tmp, tmp2);
6173
            } else {
6174
                gen_sub_carry(tmp, tmp, tmp2);
6175
            }
6176
            store_reg_bx(env, s, rd, tmp);
6177
            break;
6178
        case 0x07:
6179
            if (set_cc) {
6180
                gen_helper_sbc_cc(tmp, tmp2, tmp);
6181
            } else {
6182
                gen_sub_carry(tmp, tmp2, tmp);
6183
            }
6184
            store_reg_bx(env, s, rd, tmp);
6185
            break;
6186
        case 0x08:
6187
            if (set_cc) {
6188
                tcg_gen_and_i32(tmp, tmp, tmp2);
6189
                gen_logic_CC(tmp);
6190
            }
6191
            dead_tmp(tmp);
6192
            break;
6193
        case 0x09:
6194
            if (set_cc) {
6195
                tcg_gen_xor_i32(tmp, tmp, tmp2);
6196
                gen_logic_CC(tmp);
6197
            }
6198
            dead_tmp(tmp);
6199
            break;
6200
        case 0x0a:
6201
            if (set_cc) {
6202
                gen_helper_sub_cc(tmp, tmp, tmp2);
6203
            }
6204
            dead_tmp(tmp);
6205
            break;
6206
        case 0x0b:
6207
            if (set_cc) {
6208
                gen_helper_add_cc(tmp, tmp, tmp2);
6209
            }
6210
            dead_tmp(tmp);
6211
            break;
6212
        case 0x0c:
6213
            tcg_gen_or_i32(tmp, tmp, tmp2);
6214
            if (logic_cc) {
6215
                gen_logic_CC(tmp);
6216
            }
6217
            store_reg_bx(env, s, rd, tmp);
6218
            break;
6219
        case 0x0d:
6220
            if (logic_cc && rd == 15) {
6221
                /* MOVS r15, ... is used for exception return.  */
6222
                if (IS_USER(s)) {
6223
                    goto illegal_op;
6224
                }
6225
                gen_exception_return(s, tmp2);
6226
            } else {
6227
                if (logic_cc) {
6228
                    gen_logic_CC(tmp2);
6229
                }
6230
                store_reg_bx(env, s, rd, tmp2);
6231
            }
6232
            break;
6233
        case 0x0e:
6234
            tcg_gen_bic_i32(tmp, tmp, tmp2);
6235
            if (logic_cc) {
6236
                gen_logic_CC(tmp);
6237
            }
6238
            store_reg_bx(env, s, rd, tmp);
6239
            break;
6240
        default:
6241
        case 0x0f:
6242
            tcg_gen_not_i32(tmp2, tmp2);
6243
            if (logic_cc) {
6244
                gen_logic_CC(tmp2);
6245
            }
6246
            store_reg_bx(env, s, rd, tmp2);
6247
            break;
6248
        }
6249
        if (op1 != 0x0f && op1 != 0x0d) {
6250
            dead_tmp(tmp2);
6251
        }
6252
    } else {
6253
        /* other instructions */
6254
        op1 = (insn >> 24) & 0xf;
6255
        switch(op1) {
6256
        case 0x0:
6257
        case 0x1:
6258
            /* multiplies, extra load/stores */
6259
            sh = (insn >> 5) & 3;
6260
            if (sh == 0) {
6261
                if (op1 == 0x0) {
6262
                    rd = (insn >> 16) & 0xf;
6263
                    rn = (insn >> 12) & 0xf;
6264
                    rs = (insn >> 8) & 0xf;
6265
                    rm = (insn) & 0xf;
6266
                    op1 = (insn >> 20) & 0xf;
6267
                    switch (op1) {
6268
                    case 0: case 1: case 2: case 3: case 6:
6269
                        /* 32 bit mul */
6270
                        tmp = load_reg(s, rs);
6271
                        tmp2 = load_reg(s, rm);
6272
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
6273
                        dead_tmp(tmp2);
6274
                        if (insn & (1 << 22)) {
6275
                            /* Subtract (mls) */
6276
                            ARCH(6T2);
6277
                            tmp2 = load_reg(s, rn);
6278
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
6279
                            dead_tmp(tmp2);
6280
                        } else if (insn & (1 << 21)) {
6281
                            /* Add */
6282
                            tmp2 = load_reg(s, rn);
6283
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6284
                            dead_tmp(tmp2);
6285
                        }
6286
                        if (insn & (1 << 20))
6287
                            gen_logic_CC(tmp);
6288
                        store_reg(s, rd, tmp);
6289
                        break;
6290
                    default:
6291
                        /* 64 bit mul */
6292
                        tmp = load_reg(s, rs);
6293
                        tmp2 = load_reg(s, rm);
6294
                        if (insn & (1 << 22))
6295
                            tmp64 = gen_muls_i64_i32(tmp, tmp2);
6296
                        else
6297
                            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
6298
                        if (insn & (1 << 21)) /* mult accumulate */
6299
                            gen_addq(s, tmp64, rn, rd);
6300
                        if (!(insn & (1 << 23))) { /* double accumulate */
6301
                            ARCH(6);
6302
                            gen_addq_lo(s, tmp64, rn);
6303
                            gen_addq_lo(s, tmp64, rd);
6304
                        }
6305
                        if (insn & (1 << 20))
6306
                            gen_logicq_cc(tmp64);
6307
                        gen_storeq_reg(s, rn, rd, tmp64);
6308
                        break;
6309
                    }
6310
                } else {
6311
                    rn = (insn >> 16) & 0xf;
6312
                    rd = (insn >> 12) & 0xf;
6313
                    if (insn & (1 << 23)) {
6314
                        /* load/store exclusive */
6315
                        op1 = (insn >> 21) & 0x3;
6316
                        if (op1)
6317
                            ARCH(6K);
6318
                        else
6319
                            ARCH(6);
6320
                        gen_movl_T1_reg(s, rn);
6321
                        addr = cpu_T[1];
6322
                        if (insn & (1 << 20)) {
6323
                            gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6324
                            switch (op1) {
6325
                            case 0: /* ldrex */
6326
                                tmp = gen_ld32(addr, IS_USER(s));
6327
                                break;
6328
                            case 1: /* ldrexd */
6329
                                tmp = gen_ld32(addr, IS_USER(s));
6330
                                store_reg(s, rd, tmp);
6331
                                tcg_gen_addi_i32(addr, addr, 4);
6332
                                tmp = gen_ld32(addr, IS_USER(s));
6333
                                rd++;
6334
                                break;
6335
                            case 2: /* ldrexb */
6336
                                tmp = gen_ld8u(addr, IS_USER(s));
6337
                                break;
6338
                            case 3: /* ldrexh */
6339
                                tmp = gen_ld16u(addr, IS_USER(s));
6340
                                break;
6341
                            default:
6342
                                abort();
6343
                            }
6344
                            store_reg(s, rd, tmp);
6345
                        } else {
6346
                            int label = gen_new_label();
6347
                            rm = insn & 0xf;
6348
                            gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6349
                            tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
6350
                                                0, label);
6351
                            tmp = load_reg(s,rm);
6352
                            switch (op1) {
6353
                            case 0:  /*  strex */
6354
                                gen_st32(tmp, addr, IS_USER(s));
6355
                                break;
6356
                            case 1: /*  strexd */
6357
                                gen_st32(tmp, addr, IS_USER(s));
6358
                                tcg_gen_addi_i32(addr, addr, 4);
6359
                                tmp = load_reg(s, rm + 1);
6360
                                gen_st32(tmp, addr, IS_USER(s));
6361
                                break;
6362
                            case 2: /*  strexb */
6363
                                gen_st8(tmp, addr, IS_USER(s));
6364
                                break;
6365
                            case 3: /* strexh */
6366
                                gen_st16(tmp, addr, IS_USER(s));
6367
                                break;
6368
                            default:
6369
                                abort();
6370
                            }
6371
                            gen_set_label(label);
6372
                            gen_movl_reg_T0(s, rd);
6373
                        }
6374
                    } else {
6375
                        /* SWP instruction */
6376
                        rm = (insn) & 0xf;
6377

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

    
6770
                    if ((insn & (1 << 15)) == 0)
6771
                        user = 1;
6772
                }
6773
                rn = (insn >> 16) & 0xf;
6774
                addr = load_reg(s, rn);
6775

    
6776
                /* compute total size */
6777
                loaded_base = 0;
6778
                TCGV_UNUSED(loaded_var);
6779
                n = 0;
6780
                for(i=0;i<16;i++) {
6781
                    if (insn & (1 << i))
6782
                        n++;
6783
                }
6784
                /* XXX: test invalid n == 0 case ? */
6785
                if (insn & (1 << 23)) {
6786
                    if (insn & (1 << 24)) {
6787
                        /* pre increment */
6788
                        tcg_gen_addi_i32(addr, addr, 4);
6789
                    } else {
6790
                        /* post increment */
6791
                    }
6792
                } else {
6793
                    if (insn & (1 << 24)) {
6794
                        /* pre decrement */
6795
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
6796
                    } else {
6797
                        /* post decrement */
6798
                        if (n != 1)
6799
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6800
                    }
6801
                }
6802
                j = 0;
6803
                for(i=0;i<16;i++) {
6804
                    if (insn & (1 << i)) {
6805
                        if (insn & (1 << 20)) {
6806
                            /* load */
6807
                            tmp = gen_ld32(addr, IS_USER(s));
6808
                            if (i == 15) {
6809
                                gen_bx(s, tmp);
6810
                            } else if (user) {
6811
                                gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6812
                                dead_tmp(tmp);
6813
                            } else if (i == rn) {
6814
                                loaded_var = tmp;
6815
                                loaded_base = 1;
6816
                            } else {
6817
                                store_reg(s, i, tmp);
6818
                            }
6819
                        } else {
6820
                            /* store */
6821
                            if (i == 15) {
6822
                                /* special case: r15 = PC + 8 */
6823
                                val = (long)s->pc + 4;
6824
                                tmp = new_tmp();
6825
                                tcg_gen_movi_i32(tmp, val);
6826
                            } else if (user) {
6827
                                tmp = new_tmp();
6828
                                gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6829
                            } else {
6830
                                tmp = load_reg(s, i);
6831
                            }
6832
                            gen_st32(tmp, addr, IS_USER(s));
6833
                        }
6834
                        j++;
6835
                        /* no need to add after the last transfer */
6836
                        if (j != n)
6837
                            tcg_gen_addi_i32(addr, addr, 4);
6838
                    }
6839
                }
6840
                if (insn & (1 << 21)) {
6841
                    /* write back */
6842
                    if (insn & (1 << 23)) {
6843
                        if (insn & (1 << 24)) {
6844
                            /* pre increment */
6845
                        } else {
6846
                            /* post increment */
6847
                            tcg_gen_addi_i32(addr, addr, 4);
6848
                        }
6849
                    } else {
6850
                        if (insn & (1 << 24)) {
6851
                            /* pre decrement */
6852
                            if (n != 1)
6853
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6854
                        } else {
6855
                            /* post decrement */
6856
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
6857
                        }
6858
                    }
6859
                    store_reg(s, rn, addr);
6860
                } else {
6861
                    dead_tmp(addr);
6862
                }
6863
                if (loaded_base) {
6864
                    store_reg(s, rn, loaded_var);
6865
                }
6866
                if ((insn & (1 << 22)) && !user) {
6867
                    /* Restore CPSR from SPSR.  */
6868
                    tmp = load_cpu_field(spsr);
6869
                    gen_set_cpsr(tmp, 0xffffffff);
6870
                    dead_tmp(tmp);
6871
                    s->is_jmp = DISAS_UPDATE;
6872
                }
6873
            }
6874
            break;
6875
        case 0xa:
6876
        case 0xb:
6877
            {
6878
                int32_t offset;
6879

    
6880
                /* branch (and link) */
6881
                val = (int32_t)s->pc;
6882
                if (insn & (1 << 24)) {
6883
                    tmp = new_tmp();
6884
                    tcg_gen_movi_i32(tmp, val);
6885
                    store_reg(s, 14, tmp);
6886
                }
6887
                offset = (((int32_t)insn << 8) >> 8);
6888
                val += (offset << 2) + 4;
6889
                gen_jmp(s, val);
6890
            }
6891
            break;
6892
        case 0xc:
6893
        case 0xd:
6894
        case 0xe:
6895
            /* Coprocessor.  */
6896
            if (disas_coproc_insn(env, s, insn))
6897
                goto illegal_op;
6898
            break;
6899
        case 0xf:
6900
            /* swi */
6901
            gen_set_pc_im(s->pc);
6902
            s->is_jmp = DISAS_SWI;
6903
            break;
6904
        default:
6905
        illegal_op:
6906
            gen_set_condexec(s);
6907
            gen_set_pc_im(s->pc - 4);
6908
            gen_exception(EXCP_UDEF);
6909
            s->is_jmp = DISAS_JUMP;
6910
            break;
6911
        }
6912
    }
6913
}
6914

    
6915
/* Return true if this is a Thumb-2 logical op.  */
6916
static int
6917
thumb2_logic_op(int op)
6918
{
6919
    return (op < 8);
6920
}
6921

    
6922
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6923
   then set condition code flags based on the result of the operation.
6924
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6925
   to the high bit of T1.
6926
   Returns zero if the opcode is valid.  */
6927

    
6928
static int
6929
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6930
{
6931
    int logic_cc;
6932

    
6933
    logic_cc = 0;
6934
    switch (op) {
6935
    case 0: /* and */
6936
        gen_op_andl_T0_T1();
6937
        logic_cc = conds;
6938
        break;
6939
    case 1: /* bic */
6940
        gen_op_bicl_T0_T1();
6941
        logic_cc = conds;
6942
        break;
6943
    case 2: /* orr */
6944
        gen_op_orl_T0_T1();
6945
        logic_cc = conds;
6946
        break;
6947
    case 3: /* orn */
6948
        gen_op_notl_T1();
6949
        gen_op_orl_T0_T1();
6950
        logic_cc = conds;
6951
        break;
6952
    case 4: /* eor */
6953
        gen_op_xorl_T0_T1();
6954
        logic_cc = conds;
6955
        break;
6956
    case 8: /* add */
6957
        if (conds)
6958
            gen_op_addl_T0_T1_cc();
6959
        else
6960
            gen_op_addl_T0_T1();
6961
        break;
6962
    case 10: /* adc */
6963
        if (conds)
6964
            gen_op_adcl_T0_T1_cc();
6965
        else
6966
            gen_adc_T0_T1();
6967
        break;
6968
    case 11: /* sbc */
6969
        if (conds)
6970
            gen_op_sbcl_T0_T1_cc();
6971
        else
6972
            gen_sbc_T0_T1();
6973
        break;
6974
    case 13: /* sub */
6975
        if (conds)
6976
            gen_op_subl_T0_T1_cc();
6977
        else
6978
            gen_op_subl_T0_T1();
6979
        break;
6980
    case 14: /* rsb */
6981
        if (conds)
6982
            gen_op_rsbl_T0_T1_cc();
6983
        else
6984
            gen_op_rsbl_T0_T1();
6985
        break;
6986
    default: /* 5, 6, 7, 9, 12, 15. */
6987
        return 1;
6988
    }
6989
    if (logic_cc) {
6990
        gen_op_logic_T0_cc();
6991
        if (shifter_out)
6992
            gen_set_CF_bit31(cpu_T[1]);
6993
    }
6994
    return 0;
6995
}
6996

    
6997
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
6998
   is not legal.  */
6999
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7000
{
7001
    uint32_t insn, imm, shift, offset;
7002
    uint32_t rd, rn, rm, rs;
7003
    TCGv tmp;
7004
    TCGv tmp2;
7005
    TCGv tmp3;
7006
    TCGv addr;
7007
    TCGv_i64 tmp64;
7008
    int op;
7009
    int shiftop;
7010
    int conds;
7011
    int logic_cc;
7012

    
7013
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7014
          || arm_feature (env, ARM_FEATURE_M))) {
7015
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7016
           16-bit instructions to get correct prefetch abort behavior.  */
7017
        insn = insn_hw1;
7018
        if ((insn & (1 << 12)) == 0) {
7019
            /* Second half of blx.  */
7020
            offset = ((insn & 0x7ff) << 1);
7021
            tmp = load_reg(s, 14);
7022
            tcg_gen_addi_i32(tmp, tmp, offset);
7023
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7024

    
7025
            tmp2 = new_tmp();
7026
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7027
            store_reg(s, 14, tmp2);
7028
            gen_bx(s, tmp);
7029
            return 0;
7030
        }
7031
        if (insn & (1 << 11)) {
7032
            /* Second half of bl.  */
7033
            offset = ((insn & 0x7ff) << 1) | 1;
7034
            tmp = load_reg(s, 14);
7035
            tcg_gen_addi_i32(tmp, tmp, offset);
7036

    
7037
            tmp2 = new_tmp();
7038
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7039
            store_reg(s, 14, tmp2);
7040
            gen_bx(s, tmp);
7041
            return 0;
7042
        }
7043
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7044
            /* Instruction spans a page boundary.  Implement it as two
7045
               16-bit instructions in case the second half causes an
7046
               prefetch abort.  */
7047
            offset = ((int32_t)insn << 21) >> 9;
7048
            gen_op_movl_T0_im(s->pc + 2 + offset);
7049
            gen_movl_reg_T0(s, 14);
7050
            return 0;
7051
        }
7052
        /* Fall through to 32-bit decode.  */
7053
    }
7054

    
7055
    insn = lduw_code(s->pc);
7056
    s->pc += 2;
7057
    insn |= (uint32_t)insn_hw1 << 16;
7058

    
7059
    if ((insn & 0xf800e800) != 0xf000e800) {
7060
        ARCH(6T2);
7061
    }
7062

    
7063
    rn = (insn >> 16) & 0xf;
7064
    rs = (insn >> 12) & 0xf;
7065
    rd = (insn >> 8) & 0xf;
7066
    rm = insn & 0xf;
7067
    switch ((insn >> 25) & 0xf) {
7068
    case 0: case 1: case 2: case 3:
7069
        /* 16-bit instructions.  Should never happen.  */
7070
        abort();
7071
    case 4:
7072
        if (insn & (1 << 22)) {
7073
            /* Other load/store, table branch.  */
7074
            if (insn & 0x01200000) {
7075
                /* Load/store doubleword.  */
7076
                if (rn == 15) {
7077
                    addr = new_tmp();
7078
                    tcg_gen_movi_i32(addr, s->pc & ~3);
7079
                } else {
7080
                    addr = load_reg(s, rn);
7081
                }
7082
                offset = (insn & 0xff) * 4;
7083
                if ((insn & (1 << 23)) == 0)
7084
                    offset = -offset;
7085
                if (insn & (1 << 24)) {
7086
                    tcg_gen_addi_i32(addr, addr, offset);
7087
                    offset = 0;
7088
                }
7089
                if (insn & (1 << 20)) {
7090
                    /* ldrd */
7091
                    tmp = gen_ld32(addr, IS_USER(s));
7092
                    store_reg(s, rs, tmp);
7093
                    tcg_gen_addi_i32(addr, addr, 4);
7094
                    tmp = gen_ld32(addr, IS_USER(s));
7095
                    store_reg(s, rd, tmp);
7096
                } else {
7097
                    /* strd */
7098
                    tmp = load_reg(s, rs);
7099
                    gen_st32(tmp, addr, IS_USER(s));
7100
                    tcg_gen_addi_i32(addr, addr, 4);
7101
                    tmp = load_reg(s, rd);
7102
                    gen_st32(tmp, addr, IS_USER(s));
7103
                }
7104
                if (insn & (1 << 21)) {
7105
                    /* Base writeback.  */
7106
                    if (rn == 15)
7107
                        goto illegal_op;
7108
                    tcg_gen_addi_i32(addr, addr, offset - 4);
7109
                    store_reg(s, rn, addr);
7110
                } else {
7111
                    dead_tmp(addr);
7112
                }
7113
            } else if ((insn & (1 << 23)) == 0) {
7114
                /* Load/store exclusive word.  */
7115
                gen_movl_T1_reg(s, rn);
7116
                addr = cpu_T[1];
7117
                if (insn & (1 << 20)) {
7118
                    gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
7119
                    tmp = gen_ld32(addr, IS_USER(s));
7120
                    store_reg(s, rd, tmp);
7121
                } else {
7122
                    int label = gen_new_label();
7123
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7124
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
7125
                                        0, label);
7126
                    tmp = load_reg(s, rs);
7127
                    gen_st32(tmp, cpu_T[1], IS_USER(s));
7128
                    gen_set_label(label);
7129
                    gen_movl_reg_T0(s, rd);
7130
                }
7131
            } else if ((insn & (1 << 6)) == 0) {
7132
                /* Table Branch.  */
7133
                if (rn == 15) {
7134
                    addr = new_tmp();
7135
                    tcg_gen_movi_i32(addr, s->pc);
7136
                } else {
7137
                    addr = load_reg(s, rn);
7138
                }
7139
                tmp = load_reg(s, rm);
7140
                tcg_gen_add_i32(addr, addr, tmp);
7141
                if (insn & (1 << 4)) {
7142
                    /* tbh */
7143
                    tcg_gen_add_i32(addr, addr, tmp);
7144
                    dead_tmp(tmp);
7145
                    tmp = gen_ld16u(addr, IS_USER(s));
7146
                } else { /* tbb */
7147
                    dead_tmp(tmp);
7148
                    tmp = gen_ld8u(addr, IS_USER(s));
7149
                }
7150
                dead_tmp(addr);
7151
                tcg_gen_shli_i32(tmp, tmp, 1);
7152
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7153
                store_reg(s, 15, tmp);
7154
            } else {
7155
                /* Load/store exclusive byte/halfword/doubleword.  */
7156
                /* ??? These are not really atomic.  However we know
7157
                   we never have multiple CPUs running in parallel,
7158
                   so it is good enough.  */
7159
                op = (insn >> 4) & 0x3;
7160
                /* Must use a global reg for the address because we have
7161
                   a conditional branch in the store instruction.  */
7162
                gen_movl_T1_reg(s, rn);
7163
                addr = cpu_T[1];
7164
                if (insn & (1 << 20)) {
7165
                    gen_helper_mark_exclusive(cpu_env, addr);
7166
                    switch (op) {
7167
                    case 0:
7168
                        tmp = gen_ld8u(addr, IS_USER(s));
7169
                        break;
7170
                    case 1:
7171
                        tmp = gen_ld16u(addr, IS_USER(s));
7172
                        break;
7173
                    case 3:
7174
                        tmp = gen_ld32(addr, IS_USER(s));
7175
                        tcg_gen_addi_i32(addr, addr, 4);
7176
                        tmp2 = gen_ld32(addr, IS_USER(s));
7177
                        store_reg(s, rd, tmp2);
7178
                        break;
7179
                    default:
7180
                        goto illegal_op;
7181
                    }
7182
                    store_reg(s, rs, tmp);
7183
                } else {
7184
                    int label = gen_new_label();
7185
                    /* Must use a global that is not killed by the branch.  */
7186
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7187
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
7188
                    tmp = load_reg(s, rs);
7189
                    switch (op) {
7190
                    case 0:
7191
                        gen_st8(tmp, addr, IS_USER(s));
7192
                        break;
7193
                    case 1:
7194
                        gen_st16(tmp, addr, IS_USER(s));
7195
                        break;
7196
                    case 3:
7197
                        gen_st32(tmp, addr, IS_USER(s));
7198
                        tcg_gen_addi_i32(addr, addr, 4);
7199
                        tmp = load_reg(s, rd);
7200
                        gen_st32(tmp, addr, IS_USER(s));
7201
                        break;
7202
                    default:
7203
                        goto illegal_op;
7204
                    }
7205
                    gen_set_label(label);
7206
                    gen_movl_reg_T0(s, rm);
7207
                }
7208
            }
7209
        } else {
7210
            /* Load/store multiple, RFE, SRS.  */
7211
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7212
                /* Not available in user mode.  */
7213
                if (IS_USER(s))
7214
                    goto illegal_op;
7215
                if (insn & (1 << 20)) {
7216
                    /* rfe */
7217
                    addr = load_reg(s, rn);
7218
                    if ((insn & (1 << 24)) == 0)
7219
                        tcg_gen_addi_i32(addr, addr, -8);
7220
                    /* Load PC into tmp and CPSR into tmp2.  */
7221
                    tmp = gen_ld32(addr, 0);
7222
                    tcg_gen_addi_i32(addr, addr, 4);
7223
                    tmp2 = gen_ld32(addr, 0);
7224
                    if (insn & (1 << 21)) {
7225
                        /* Base writeback.  */
7226
                        if (insn & (1 << 24)) {
7227
                            tcg_gen_addi_i32(addr, addr, 4);
7228
                        } else {
7229
                            tcg_gen_addi_i32(addr, addr, -4);
7230
                        }
7231
                        store_reg(s, rn, addr);
7232
                    } else {
7233
                        dead_tmp(addr);
7234
                    }
7235
                    gen_rfe(s, tmp, tmp2);
7236
                } else {
7237
                    /* srs */
7238
                    op = (insn & 0x1f);
7239
                    if (op == (env->uncached_cpsr & CPSR_M)) {
7240
                        addr = load_reg(s, 13);
7241
                    } else {
7242
                        addr = new_tmp();
7243
                        gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7244
                    }
7245
                    if ((insn & (1 << 24)) == 0) {
7246
                        tcg_gen_addi_i32(addr, addr, -8);
7247
                    }
7248
                    tmp = load_reg(s, 14);
7249
                    gen_st32(tmp, addr, 0);
7250
                    tcg_gen_addi_i32(addr, addr, 4);
7251
                    tmp = new_tmp();
7252
                    gen_helper_cpsr_read(tmp);
7253
                    gen_st32(tmp, addr, 0);
7254
                    if (insn & (1 << 21)) {
7255
                        if ((insn & (1 << 24)) == 0) {
7256
                            tcg_gen_addi_i32(addr, addr, -4);
7257
                        } else {
7258
                            tcg_gen_addi_i32(addr, addr, 4);
7259
                        }
7260
                        if (op == (env->uncached_cpsr & CPSR_M)) {
7261
                            store_reg(s, 13, addr);
7262
                        } else {
7263
                            gen_helper_set_r13_banked(cpu_env,
7264
                                tcg_const_i32(op), addr);
7265
                        }
7266
                    } else {
7267
                        dead_tmp(addr);
7268
                    }
7269
                }
7270
            } else {
7271
                int i;
7272
                /* Load/store multiple.  */
7273
                addr = load_reg(s, rn);
7274
                offset = 0;
7275
                for (i = 0; i < 16; i++) {
7276
                    if (insn & (1 << i))
7277
                        offset += 4;
7278
                }
7279
                if (insn & (1 << 24)) {
7280
                    tcg_gen_addi_i32(addr, addr, -offset);
7281
                }
7282

    
7283
                for (i = 0; i < 16; i++) {
7284
                    if ((insn & (1 << i)) == 0)
7285
                        continue;
7286
                    if (insn & (1 << 20)) {
7287
                        /* Load.  */
7288
                        tmp = gen_ld32(addr, IS_USER(s));
7289
                        if (i == 15) {
7290
                            gen_bx(s, tmp);
7291
                        } else {
7292
                            store_reg(s, i, tmp);
7293
                        }
7294
                    } else {
7295
                        /* Store.  */
7296
                        tmp = load_reg(s, i);
7297
                        gen_st32(tmp, addr, IS_USER(s));
7298
                    }
7299
                    tcg_gen_addi_i32(addr, addr, 4);
7300
                }
7301
                if (insn & (1 << 21)) {
7302
                    /* Base register writeback.  */
7303
                    if (insn & (1 << 24)) {
7304
                        tcg_gen_addi_i32(addr, addr, -offset);
7305
                    }
7306
                    /* Fault if writeback register is in register list.  */
7307
                    if (insn & (1 << rn))
7308
                        goto illegal_op;
7309
                    store_reg(s, rn, addr);
7310
                } else {
7311
                    dead_tmp(addr);
7312
                }
7313
            }
7314
        }
7315
        break;
7316
    case 5: /* Data processing register constant shift.  */
7317
        if (rn == 15)
7318
            gen_op_movl_T0_im(0);
7319
        else
7320
            gen_movl_T0_reg(s, rn);
7321
        gen_movl_T1_reg(s, rm);
7322
        op = (insn >> 21) & 0xf;
7323
        shiftop = (insn >> 4) & 3;
7324
        shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7325
        conds = (insn & (1 << 20)) != 0;
7326
        logic_cc = (conds && thumb2_logic_op(op));
7327
        gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7328
        if (gen_thumb2_data_op(s, op, conds, 0))
7329
            goto illegal_op;
7330
        if (rd != 15)
7331
            gen_movl_reg_T0(s, rd);
7332
        break;
7333
    case 13: /* Misc data processing.  */
7334
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7335
        if (op < 4 && (insn & 0xf000) != 0xf000)
7336
            goto illegal_op;
7337
        switch (op) {
7338
        case 0: /* Register controlled shift.  */
7339
            tmp = load_reg(s, rn);
7340
            tmp2 = load_reg(s, rm);
7341
            if ((insn & 0x70) != 0)
7342
                goto illegal_op;
7343
            op = (insn >> 21) & 3;
7344
            logic_cc = (insn & (1 << 20)) != 0;
7345
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7346
            if (logic_cc)
7347
                gen_logic_CC(tmp);
7348
            store_reg_bx(env, s, rd, tmp);
7349
            break;
7350
        case 1: /* Sign/zero extend.  */
7351
            tmp = load_reg(s, rm);
7352
            shift = (insn >> 4) & 3;
7353
            /* ??? In many cases it's not neccessary to do a
7354
               rotate, a shift is sufficient.  */
7355
            if (shift != 0)
7356
                tcg_gen_rori_i32(tmp, tmp, shift * 8);
7357
            op = (insn >> 20) & 7;
7358
            switch (op) {
7359
            case 0: gen_sxth(tmp);   break;
7360
            case 1: gen_uxth(tmp);   break;
7361
            case 2: gen_sxtb16(tmp); break;
7362
            case 3: gen_uxtb16(tmp); break;
7363
            case 4: gen_sxtb(tmp);   break;
7364
            case 5: gen_uxtb(tmp);   break;
7365
            default: goto illegal_op;
7366
            }
7367
            if (rn != 15) {
7368
                tmp2 = load_reg(s, rn);
7369
                if ((op >> 1) == 1) {
7370
                    gen_add16(tmp, tmp2);
7371
                } else {
7372
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7373
                    dead_tmp(tmp2);
7374
                }
7375
            }
7376
            store_reg(s, rd, tmp);
7377
            break;
7378
        case 2: /* SIMD add/subtract.  */
7379
            op = (insn >> 20) & 7;
7380
            shift = (insn >> 4) & 7;
7381
            if ((op & 3) == 3 || (shift & 3) == 3)
7382
                goto illegal_op;
7383
            tmp = load_reg(s, rn);
7384
            tmp2 = load_reg(s, rm);
7385
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7386
            dead_tmp(tmp2);
7387
            store_reg(s, rd, tmp);
7388
            break;
7389
        case 3: /* Other data processing.  */
7390
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7391
            if (op < 4) {
7392
                /* Saturating add/subtract.  */
7393
                tmp = load_reg(s, rn);
7394
                tmp2 = load_reg(s, rm);
7395
                if (op & 2)
7396
                    gen_helper_double_saturate(tmp, tmp);
7397
                if (op & 1)
7398
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7399
                else
7400
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7401
                dead_tmp(tmp2);
7402
            } else {
7403
                tmp = load_reg(s, rn);
7404
                switch (op) {
7405
                case 0x0a: /* rbit */
7406
                    gen_helper_rbit(tmp, tmp);
7407
                    break;
7408
                case 0x08: /* rev */
7409
                    tcg_gen_bswap32_i32(tmp, tmp);
7410
                    break;
7411
                case 0x09: /* rev16 */
7412
                    gen_rev16(tmp);
7413
                    break;
7414
                case 0x0b: /* revsh */
7415
                    gen_revsh(tmp);
7416
                    break;
7417
                case 0x10: /* sel */
7418
                    tmp2 = load_reg(s, rm);
7419
                    tmp3 = new_tmp();
7420
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7421
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7422
                    dead_tmp(tmp3);
7423
                    dead_tmp(tmp2);
7424
                    break;
7425
                case 0x18: /* clz */
7426
                    gen_helper_clz(tmp, tmp);
7427
                    break;
7428
                default:
7429
                    goto illegal_op;
7430
                }
7431
            }
7432
            store_reg(s, rd, tmp);
7433
            break;
7434
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7435
            op = (insn >> 4) & 0xf;
7436
            tmp = load_reg(s, rn);
7437
            tmp2 = load_reg(s, rm);
7438
            switch ((insn >> 20) & 7) {
7439
            case 0: /* 32 x 32 -> 32 */
7440
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7441
                dead_tmp(tmp2);
7442
                if (rs != 15) {
7443
                    tmp2 = load_reg(s, rs);
7444
                    if (op)
7445
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7446
                    else
7447
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7448
                    dead_tmp(tmp2);
7449
                }
7450
                break;
7451
            case 1: /* 16 x 16 -> 32 */
7452
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7453
                dead_tmp(tmp2);
7454
                if (rs != 15) {
7455
                    tmp2 = load_reg(s, rs);
7456
                    gen_helper_add_setq(tmp, tmp, tmp2);
7457
                    dead_tmp(tmp2);
7458
                }
7459
                break;
7460
            case 2: /* Dual multiply add.  */
7461
            case 4: /* Dual multiply subtract.  */
7462
                if (op)
7463
                    gen_swap_half(tmp2);
7464
                gen_smul_dual(tmp, tmp2);
7465
                /* This addition cannot overflow.  */
7466
                if (insn & (1 << 22)) {
7467
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7468
                } else {
7469
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7470
                }
7471
                dead_tmp(tmp2);
7472
                if (rs != 15)
7473
                  {
7474
                    tmp2 = load_reg(s, rs);
7475
                    gen_helper_add_setq(tmp, tmp, tmp2);
7476
                    dead_tmp(tmp2);
7477
                  }
7478
                break;
7479
            case 3: /* 32 * 16 -> 32msb */
7480
                if (op)
7481
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7482
                else
7483
                    gen_sxth(tmp2);
7484
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7485
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7486
                tmp = new_tmp();
7487
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7488
                if (rs != 15)
7489
                  {
7490
                    tmp2 = load_reg(s, rs);
7491
                    gen_helper_add_setq(tmp, tmp, tmp2);
7492
                    dead_tmp(tmp2);
7493
                  }
7494
                break;
7495
            case 5: case 6: /* 32 * 32 -> 32msb */
7496
                gen_imull(tmp, tmp2);
7497
                if (insn & (1 << 5)) {
7498
                    gen_roundqd(tmp, tmp2);
7499
                    dead_tmp(tmp2);
7500
                } else {
7501
                    dead_tmp(tmp);
7502
                    tmp = tmp2;
7503
                }
7504
                if (rs != 15) {
7505
                    tmp2 = load_reg(s, rs);
7506
                    if (insn & (1 << 21)) {
7507
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7508
                    } else {
7509
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7510
                    }
7511
                    dead_tmp(tmp2);
7512
                }
7513
                break;
7514
            case 7: /* Unsigned sum of absolute differences.  */
7515
                gen_helper_usad8(tmp, tmp, tmp2);
7516
                dead_tmp(tmp2);
7517
                if (rs != 15) {
7518
                    tmp2 = load_reg(s, rs);
7519
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7520
                    dead_tmp(tmp2);
7521
                }
7522
                break;
7523
            }
7524
            store_reg(s, rd, tmp);
7525
            break;
7526
        case 6: case 7: /* 64-bit multiply, Divide.  */
7527
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7528
            tmp = load_reg(s, rn);
7529
            tmp2 = load_reg(s, rm);
7530
            if ((op & 0x50) == 0x10) {
7531
                /* sdiv, udiv */
7532
                if (!arm_feature(env, ARM_FEATURE_DIV))
7533
                    goto illegal_op;
7534
                if (op & 0x20)
7535
                    gen_helper_udiv(tmp, tmp, tmp2);
7536
                else
7537
                    gen_helper_sdiv(tmp, tmp, tmp2);
7538
                dead_tmp(tmp2);
7539
                store_reg(s, rd, tmp);
7540
            } else if ((op & 0xe) == 0xc) {
7541
                /* Dual multiply accumulate long.  */
7542
                if (op & 1)
7543
                    gen_swap_half(tmp2);
7544
                gen_smul_dual(tmp, tmp2);
7545
                if (op & 0x10) {
7546
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7547
                } else {
7548
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7549
                }
7550
                dead_tmp(tmp2);
7551
                /* BUGFIX */
7552
                tmp64 = tcg_temp_new_i64();
7553
                tcg_gen_ext_i32_i64(tmp64, tmp);
7554
                dead_tmp(tmp);
7555
                gen_addq(s, tmp64, rs, rd);
7556
                gen_storeq_reg(s, rs, rd, tmp64);
7557
            } else {
7558
                if (op & 0x20) {
7559
                    /* Unsigned 64-bit multiply  */
7560
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7561
                } else {
7562
                    if (op & 8) {
7563
                        /* smlalxy */
7564
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7565
                        dead_tmp(tmp2);
7566
                        tmp64 = tcg_temp_new_i64();
7567
                        tcg_gen_ext_i32_i64(tmp64, tmp);
7568
                        dead_tmp(tmp);
7569
                    } else {
7570
                        /* Signed 64-bit multiply  */
7571
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7572
                    }
7573
                }
7574
                if (op & 4) {
7575
                    /* umaal */
7576
                    gen_addq_lo(s, tmp64, rs);
7577
                    gen_addq_lo(s, tmp64, rd);
7578
                } else if (op & 0x40) {
7579
                    /* 64-bit accumulate.  */
7580
                    gen_addq(s, tmp64, rs, rd);
7581
                }
7582
                gen_storeq_reg(s, rs, rd, tmp64);
7583
            }
7584
            break;
7585
        }
7586
        break;
7587
    case 6: case 7: case 14: case 15:
7588
        /* Coprocessor.  */
7589
        if (((insn >> 24) & 3) == 3) {
7590
            /* Translate into the equivalent ARM encoding.  */
7591
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7592
            if (disas_neon_data_insn(env, s, insn))
7593
                goto illegal_op;
7594
        } else {
7595
            if (insn & (1 << 28))
7596
                goto illegal_op;
7597
            if (disas_coproc_insn (env, s, insn))
7598
                goto illegal_op;
7599
        }
7600
        break;
7601
    case 8: case 9: case 10: case 11:
7602
        if (insn & (1 << 15)) {
7603
            /* Branches, misc control.  */
7604
            if (insn & 0x5000) {
7605
                /* Unconditional branch.  */
7606
                /* signextend(hw1[10:0]) -> offset[:12].  */
7607
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7608
                /* hw1[10:0] -> offset[11:1].  */
7609
                offset |= (insn & 0x7ff) << 1;
7610
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7611
                   offset[24:22] already have the same value because of the
7612
                   sign extension above.  */
7613
                offset ^= ((~insn) & (1 << 13)) << 10;
7614
                offset ^= ((~insn) & (1 << 11)) << 11;
7615

    
7616
                if (insn & (1 << 14)) {
7617
                    /* Branch and link.  */
7618
                    gen_op_movl_T1_im(s->pc | 1);
7619
                    gen_movl_reg_T1(s, 14);
7620
                }
7621

    
7622
                offset += s->pc;
7623
                if (insn & (1 << 12)) {
7624
                    /* b/bl */
7625
                    gen_jmp(s, offset);
7626
                } else {
7627
                    /* blx */
7628
                    offset &= ~(uint32_t)2;
7629
                    gen_bx_im(s, offset);
7630
                }
7631
            } else if (((insn >> 23) & 7) == 7) {
7632
                /* Misc control */
7633
                if (insn & (1 << 13))
7634
                    goto illegal_op;
7635

    
7636
                if (insn & (1 << 26)) {
7637
                    /* Secure monitor call (v6Z) */
7638
                    goto illegal_op; /* not implemented.  */
7639
                } else {
7640
                    op = (insn >> 20) & 7;
7641
                    switch (op) {
7642
                    case 0: /* msr cpsr.  */
7643
                        if (IS_M(env)) {
7644
                            tmp = load_reg(s, rn);
7645
                            addr = tcg_const_i32(insn & 0xff);
7646
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7647
                            gen_lookup_tb(s);
7648
                            break;
7649
                        }
7650
                        /* fall through */
7651
                    case 1: /* msr spsr.  */
7652
                        if (IS_M(env))
7653
                            goto illegal_op;
7654
                        gen_movl_T0_reg(s, rn);
7655
                        if (gen_set_psr_T0(s,
7656
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7657
                              op == 1))
7658
                            goto illegal_op;
7659
                        break;
7660
                    case 2: /* cps, nop-hint.  */
7661
                        if (((insn >> 8) & 7) == 0) {
7662
                            gen_nop_hint(s, insn & 0xff);
7663
                        }
7664
                        /* Implemented as NOP in user mode.  */
7665
                        if (IS_USER(s))
7666
                            break;
7667
                        offset = 0;
7668
                        imm = 0;
7669
                        if (insn & (1 << 10)) {
7670
                            if (insn & (1 << 7))
7671
                                offset |= CPSR_A;
7672
                            if (insn & (1 << 6))
7673
                                offset |= CPSR_I;
7674
                            if (insn & (1 << 5))
7675
                                offset |= CPSR_F;
7676
                            if (insn & (1 << 9))
7677
                                imm = CPSR_A | CPSR_I | CPSR_F;
7678
                        }
7679
                        if (insn & (1 << 8)) {
7680
                            offset |= 0x1f;
7681
                            imm |= (insn & 0x1f);
7682
                        }
7683
                        if (offset) {
7684
                            gen_op_movl_T0_im(imm);
7685
                            gen_set_psr_T0(s, offset, 0);
7686
                        }
7687
                        break;
7688
                    case 3: /* Special control operations.  */
7689
                        op = (insn >> 4) & 0xf;
7690
                        switch (op) {
7691
                        case 2: /* clrex */
7692
                            gen_helper_clrex(cpu_env);
7693
                            break;
7694
                        case 4: /* dsb */
7695
                        case 5: /* dmb */
7696
                        case 6: /* isb */
7697
                            /* These execute as NOPs.  */
7698
                            ARCH(7);
7699
                            break;
7700
                        default:
7701
                            goto illegal_op;
7702
                        }
7703
                        break;
7704
                    case 4: /* bxj */
7705
                        /* Trivial implementation equivalent to bx.  */
7706
                        tmp = load_reg(s, rn);
7707
                        gen_bx(s, tmp);
7708
                        break;
7709
                    case 5: /* Exception return.  */
7710
                        /* Unpredictable in user mode.  */
7711
                        goto illegal_op;
7712
                    case 6: /* mrs cpsr.  */
7713
                        tmp = new_tmp();
7714
                        if (IS_M(env)) {
7715
                            addr = tcg_const_i32(insn & 0xff);
7716
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
7717
                        } else {
7718
                            gen_helper_cpsr_read(tmp);
7719
                        }
7720
                        store_reg(s, rd, tmp);
7721
                        break;
7722
                    case 7: /* mrs spsr.  */
7723
                        /* Not accessible in user mode.  */
7724
                        if (IS_USER(s) || IS_M(env))
7725
                            goto illegal_op;
7726
                        tmp = load_cpu_field(spsr);
7727
                        store_reg(s, rd, tmp);
7728
                        break;
7729
                    }
7730
                }
7731
            } else {
7732
                /* Conditional branch.  */
7733
                op = (insn >> 22) & 0xf;
7734
                /* Generate a conditional jump to next instruction.  */
7735
                s->condlabel = gen_new_label();
7736
                gen_test_cc(op ^ 1, s->condlabel);
7737
                s->condjmp = 1;
7738

    
7739
                /* offset[11:1] = insn[10:0] */
7740
                offset = (insn & 0x7ff) << 1;
7741
                /* offset[17:12] = insn[21:16].  */
7742
                offset |= (insn & 0x003f0000) >> 4;
7743
                /* offset[31:20] = insn[26].  */
7744
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7745
                /* offset[18] = insn[13].  */
7746
                offset |= (insn & (1 << 13)) << 5;
7747
                /* offset[19] = insn[11].  */
7748
                offset |= (insn & (1 << 11)) << 8;
7749

    
7750
                /* jump to the offset */
7751
                gen_jmp(s, s->pc + offset);
7752
            }
7753
        } else {
7754
            /* Data processing immediate.  */
7755
            if (insn & (1 << 25)) {
7756
                if (insn & (1 << 24)) {
7757
                    if (insn & (1 << 20))
7758
                        goto illegal_op;
7759
                    /* Bitfield/Saturate.  */
7760
                    op = (insn >> 21) & 7;
7761
                    imm = insn & 0x1f;
7762
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7763
                    if (rn == 15) {
7764
                        tmp = new_tmp();
7765
                        tcg_gen_movi_i32(tmp, 0);
7766
                    } else {
7767
                        tmp = load_reg(s, rn);
7768
                    }
7769
                    switch (op) {
7770
                    case 2: /* Signed bitfield extract.  */
7771
                        imm++;
7772
                        if (shift + imm > 32)
7773
                            goto illegal_op;
7774
                        if (imm < 32)
7775
                            gen_sbfx(tmp, shift, imm);
7776
                        break;
7777
                    case 6: /* Unsigned bitfield extract.  */
7778
                        imm++;
7779
                        if (shift + imm > 32)
7780
                            goto illegal_op;
7781
                        if (imm < 32)
7782
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
7783
                        break;
7784
                    case 3: /* Bitfield insert/clear.  */
7785
                        if (imm < shift)
7786
                            goto illegal_op;
7787
                        imm = imm + 1 - shift;
7788
                        if (imm != 32) {
7789
                            tmp2 = load_reg(s, rd);
7790
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7791
                            dead_tmp(tmp2);
7792
                        }
7793
                        break;
7794
                    case 7:
7795
                        goto illegal_op;
7796
                    default: /* Saturate.  */
7797
                        if (shift) {
7798
                            if (op & 1)
7799
                                tcg_gen_sari_i32(tmp, tmp, shift);
7800
                            else
7801
                                tcg_gen_shli_i32(tmp, tmp, shift);
7802
                        }
7803
                        tmp2 = tcg_const_i32(imm);
7804
                        if (op & 4) {
7805
                            /* Unsigned.  */
7806
                            if ((op & 1) && shift == 0)
7807
                                gen_helper_usat16(tmp, tmp, tmp2);
7808
                            else
7809
                                gen_helper_usat(tmp, tmp, tmp2);
7810
                        } else {
7811
                            /* Signed.  */
7812
                            if ((op & 1) && shift == 0)
7813
                                gen_helper_ssat16(tmp, tmp, tmp2);
7814
                            else
7815
                                gen_helper_ssat(tmp, tmp, tmp2);
7816
                        }
7817
                        break;
7818
                    }
7819
                    store_reg(s, rd, tmp);
7820
                } else {
7821
                    imm = ((insn & 0x04000000) >> 15)
7822
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
7823
                    if (insn & (1 << 22)) {
7824
                        /* 16-bit immediate.  */
7825
                        imm |= (insn >> 4) & 0xf000;
7826
                        if (insn & (1 << 23)) {
7827
                            /* movt */
7828
                            tmp = load_reg(s, rd);
7829
                            tcg_gen_ext16u_i32(tmp, tmp);
7830
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
7831
                        } else {
7832
                            /* movw */
7833
                            tmp = new_tmp();
7834
                            tcg_gen_movi_i32(tmp, imm);
7835
                        }
7836
                    } else {
7837
                        /* Add/sub 12-bit immediate.  */
7838
                        if (rn == 15) {
7839
                            offset = s->pc & ~(uint32_t)3;
7840
                            if (insn & (1 << 23))
7841
                                offset -= imm;
7842
                            else
7843
                                offset += imm;
7844
                            tmp = new_tmp();
7845
                            tcg_gen_movi_i32(tmp, offset);
7846
                        } else {
7847
                            tmp = load_reg(s, rn);
7848
                            if (insn & (1 << 23))
7849
                                tcg_gen_subi_i32(tmp, tmp, imm);
7850
                            else
7851
                                tcg_gen_addi_i32(tmp, tmp, imm);
7852
                        }
7853
                    }
7854
                    store_reg(s, rd, tmp);
7855
                }
7856
            } else {
7857
                int shifter_out = 0;
7858
                /* modified 12-bit immediate.  */
7859
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7860
                imm = (insn & 0xff);
7861
                switch (shift) {
7862
                case 0: /* XY */
7863
                    /* Nothing to do.  */
7864
                    break;
7865
                case 1: /* 00XY00XY */
7866
                    imm |= imm << 16;
7867
                    break;
7868
                case 2: /* XY00XY00 */
7869
                    imm |= imm << 16;
7870
                    imm <<= 8;
7871
                    break;
7872
                case 3: /* XYXYXYXY */
7873
                    imm |= imm << 16;
7874
                    imm |= imm << 8;
7875
                    break;
7876
                default: /* Rotated constant.  */
7877
                    shift = (shift << 1) | (imm >> 7);
7878
                    imm |= 0x80;
7879
                    imm = imm << (32 - shift);
7880
                    shifter_out = 1;
7881
                    break;
7882
                }
7883
                gen_op_movl_T1_im(imm);
7884
                rn = (insn >> 16) & 0xf;
7885
                if (rn == 15)
7886
                    gen_op_movl_T0_im(0);
7887
                else
7888
                    gen_movl_T0_reg(s, rn);
7889
                op = (insn >> 21) & 0xf;
7890
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7891
                                       shifter_out))
7892
                    goto illegal_op;
7893
                rd = (insn >> 8) & 0xf;
7894
                if (rd != 15) {
7895
                    gen_movl_reg_T0(s, rd);
7896
                }
7897
            }
7898
        }
7899
        break;
7900
    case 12: /* Load/store single data item.  */
7901
        {
7902
        int postinc = 0;
7903
        int writeback = 0;
7904
        int user;
7905
        if ((insn & 0x01100000) == 0x01000000) {
7906
            if (disas_neon_ls_insn(env, s, insn))
7907
                goto illegal_op;
7908
            break;
7909
        }
7910
        user = IS_USER(s);
7911
        if (rn == 15) {
7912
            addr = new_tmp();
7913
            /* PC relative.  */
7914
            /* s->pc has already been incremented by 4.  */
7915
            imm = s->pc & 0xfffffffc;
7916
            if (insn & (1 << 23))
7917
                imm += insn & 0xfff;
7918
            else
7919
                imm -= insn & 0xfff;
7920
            tcg_gen_movi_i32(addr, imm);
7921
        } else {
7922
            addr = load_reg(s, rn);
7923
            if (insn & (1 << 23)) {
7924
                /* Positive offset.  */
7925
                imm = insn & 0xfff;
7926
                tcg_gen_addi_i32(addr, addr, imm);
7927
            } else {
7928
                op = (insn >> 8) & 7;
7929
                imm = insn & 0xff;
7930
                switch (op) {
7931
                case 0: case 8: /* Shifted Register.  */
7932
                    shift = (insn >> 4) & 0xf;
7933
                    if (shift > 3)
7934
                        goto illegal_op;
7935
                    tmp = load_reg(s, rm);
7936
                    if (shift)
7937
                        tcg_gen_shli_i32(tmp, tmp, shift);
7938
                    tcg_gen_add_i32(addr, addr, tmp);
7939
                    dead_tmp(tmp);
7940
                    break;
7941
                case 4: /* Negative offset.  */
7942
                    tcg_gen_addi_i32(addr, addr, -imm);
7943
                    break;
7944
                case 6: /* User privilege.  */
7945
                    tcg_gen_addi_i32(addr, addr, imm);
7946
                    user = 1;
7947
                    break;
7948
                case 1: /* Post-decrement.  */
7949
                    imm = -imm;
7950
                    /* Fall through.  */
7951
                case 3: /* Post-increment.  */
7952
                    postinc = 1;
7953
                    writeback = 1;
7954
                    break;
7955
                case 5: /* Pre-decrement.  */
7956
                    imm = -imm;
7957
                    /* Fall through.  */
7958
                case 7: /* Pre-increment.  */
7959
                    tcg_gen_addi_i32(addr, addr, imm);
7960
                    writeback = 1;
7961
                    break;
7962
                default:
7963
                    goto illegal_op;
7964
                }
7965
            }
7966
        }
7967
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7968
        if (insn & (1 << 20)) {
7969
            /* Load.  */
7970
            if (rs == 15 && op != 2) {
7971
                if (op & 2)
7972
                    goto illegal_op;
7973
                /* Memory hint.  Implemented as NOP.  */
7974
            } else {
7975
                switch (op) {
7976
                case 0: tmp = gen_ld8u(addr, user); break;
7977
                case 4: tmp = gen_ld8s(addr, user); break;
7978
                case 1: tmp = gen_ld16u(addr, user); break;
7979
                case 5: tmp = gen_ld16s(addr, user); break;
7980
                case 2: tmp = gen_ld32(addr, user); break;
7981
                default: goto illegal_op;
7982
                }
7983
                if (rs == 15) {
7984
                    gen_bx(s, tmp);
7985
                } else {
7986
                    store_reg(s, rs, tmp);
7987
                }
7988
            }
7989
        } else {
7990
            /* Store.  */
7991
            if (rs == 15)
7992
                goto illegal_op;
7993
            tmp = load_reg(s, rs);
7994
            switch (op) {
7995
            case 0: gen_st8(tmp, addr, user); break;
7996
            case 1: gen_st16(tmp, addr, user); break;
7997
            case 2: gen_st32(tmp, addr, user); break;
7998
            default: goto illegal_op;
7999
            }
8000
        }
8001
        if (postinc)
8002
            tcg_gen_addi_i32(addr, addr, imm);
8003
        if (writeback) {
8004
            store_reg(s, rn, addr);
8005
        } else {
8006
            dead_tmp(addr);
8007
        }
8008
        }
8009
        break;
8010
    default:
8011
        goto illegal_op;
8012
    }
8013
    return 0;
8014
illegal_op:
8015
    return 1;
8016
}
8017

    
8018
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8019
{
8020
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8021
    int32_t offset;
8022
    int i;
8023
    TCGv tmp;
8024
    TCGv tmp2;
8025
    TCGv addr;
8026

    
8027
    if (s->condexec_mask) {
8028
        cond = s->condexec_cond;
8029
        s->condlabel = gen_new_label();
8030
        gen_test_cc(cond ^ 1, s->condlabel);
8031
        s->condjmp = 1;
8032
    }
8033

    
8034
    insn = lduw_code(s->pc);
8035
    s->pc += 2;
8036

    
8037
    switch (insn >> 12) {
8038
    case 0: case 1:
8039
        rd = insn & 7;
8040
        op = (insn >> 11) & 3;
8041
        if (op == 3) {
8042
            /* add/subtract */
8043
            rn = (insn >> 3) & 7;
8044
            gen_movl_T0_reg(s, rn);
8045
            if (insn & (1 << 10)) {
8046
                /* immediate */
8047
                gen_op_movl_T1_im((insn >> 6) & 7);
8048
            } else {
8049
                /* reg */
8050
                rm = (insn >> 6) & 7;
8051
                gen_movl_T1_reg(s, rm);
8052
            }
8053
            if (insn & (1 << 9)) {
8054
                if (s->condexec_mask)
8055
                    gen_op_subl_T0_T1();
8056
                else
8057
                    gen_op_subl_T0_T1_cc();
8058
            } else {
8059
                if (s->condexec_mask)
8060
                    gen_op_addl_T0_T1();
8061
                else
8062
                    gen_op_addl_T0_T1_cc();
8063
            }
8064
            gen_movl_reg_T0(s, rd);
8065
        } else {
8066
            /* shift immediate */
8067
            rm = (insn >> 3) & 7;
8068
            shift = (insn >> 6) & 0x1f;
8069
            tmp = load_reg(s, rm);
8070
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
8071
            if (!s->condexec_mask)
8072
                gen_logic_CC(tmp);
8073
            store_reg(s, rd, tmp);
8074
        }
8075
        break;
8076
    case 2: case 3:
8077
        /* arithmetic large immediate */
8078
        op = (insn >> 11) & 3;
8079
        rd = (insn >> 8) & 0x7;
8080
        if (op == 0) {
8081
            gen_op_movl_T0_im(insn & 0xff);
8082
        } else {
8083
            gen_movl_T0_reg(s, rd);
8084
            gen_op_movl_T1_im(insn & 0xff);
8085
        }
8086
        switch (op) {
8087
        case 0: /* mov */
8088
            if (!s->condexec_mask)
8089
                gen_op_logic_T0_cc();
8090
            break;
8091
        case 1: /* cmp */
8092
            gen_op_subl_T0_T1_cc();
8093
            break;
8094
        case 2: /* add */
8095
            if (s->condexec_mask)
8096
                gen_op_addl_T0_T1();
8097
            else
8098
                gen_op_addl_T0_T1_cc();
8099
            break;
8100
        case 3: /* sub */
8101
            if (s->condexec_mask)
8102
                gen_op_subl_T0_T1();
8103
            else
8104
                gen_op_subl_T0_T1_cc();
8105
            break;
8106
        }
8107
        if (op != 1)
8108
            gen_movl_reg_T0(s, rd);
8109
        break;
8110
    case 4:
8111
        if (insn & (1 << 11)) {
8112
            rd = (insn >> 8) & 7;
8113
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8114
            val = s->pc + 2 + ((insn & 0xff) * 4);
8115
            val &= ~(uint32_t)2;
8116
            addr = new_tmp();
8117
            tcg_gen_movi_i32(addr, val);
8118
            tmp = gen_ld32(addr, IS_USER(s));
8119
            dead_tmp(addr);
8120
            store_reg(s, rd, tmp);
8121
            break;
8122
        }
8123
        if (insn & (1 << 10)) {
8124
            /* data processing extended or blx */
8125
            rd = (insn & 7) | ((insn >> 4) & 8);
8126
            rm = (insn >> 3) & 0xf;
8127
            op = (insn >> 8) & 3;
8128
            switch (op) {
8129
            case 0: /* add */
8130
                gen_movl_T0_reg(s, rd);
8131
                gen_movl_T1_reg(s, rm);
8132
                gen_op_addl_T0_T1();
8133
                gen_movl_reg_T0(s, rd);
8134
                break;
8135
            case 1: /* cmp */
8136
                gen_movl_T0_reg(s, rd);
8137
                gen_movl_T1_reg(s, rm);
8138
                gen_op_subl_T0_T1_cc();
8139
                break;
8140
            case 2: /* mov/cpy */
8141
                gen_movl_T0_reg(s, rm);
8142
                gen_movl_reg_T0(s, rd);
8143
                break;
8144
            case 3:/* branch [and link] exchange thumb register */
8145
                tmp = load_reg(s, rm);
8146
                if (insn & (1 << 7)) {
8147
                    val = (uint32_t)s->pc | 1;
8148
                    tmp2 = new_tmp();
8149
                    tcg_gen_movi_i32(tmp2, val);
8150
                    store_reg(s, 14, tmp2);
8151
                }
8152
                gen_bx(s, tmp);
8153
                break;
8154
            }
8155
            break;
8156
        }
8157

    
8158
        /* data processing register */
8159
        rd = insn & 7;
8160
        rm = (insn >> 3) & 7;
8161
        op = (insn >> 6) & 0xf;
8162
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8163
            /* the shift/rotate ops want the operands backwards */
8164
            val = rm;
8165
            rm = rd;
8166
            rd = val;
8167
            val = 1;
8168
        } else {
8169
            val = 0;
8170
        }
8171

    
8172
        if (op == 9) /* neg */
8173
            gen_op_movl_T0_im(0);
8174
        else if (op != 0xf) /* mvn doesn't read its first operand */
8175
            gen_movl_T0_reg(s, rd);
8176

    
8177
        gen_movl_T1_reg(s, rm);
8178
        switch (op) {
8179
        case 0x0: /* and */
8180
            gen_op_andl_T0_T1();
8181
            if (!s->condexec_mask)
8182
                gen_op_logic_T0_cc();
8183
            break;
8184
        case 0x1: /* eor */
8185
            gen_op_xorl_T0_T1();
8186
            if (!s->condexec_mask)
8187
                gen_op_logic_T0_cc();
8188
            break;
8189
        case 0x2: /* lsl */
8190
            if (s->condexec_mask) {
8191
                gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8192
            } else {
8193
                gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8194
                gen_op_logic_T1_cc();
8195
            }
8196
            break;
8197
        case 0x3: /* lsr */
8198
            if (s->condexec_mask) {
8199
                gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8200
            } else {
8201
                gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8202
                gen_op_logic_T1_cc();
8203
            }
8204
            break;
8205
        case 0x4: /* asr */
8206
            if (s->condexec_mask) {
8207
                gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8208
            } else {
8209
                gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8210
                gen_op_logic_T1_cc();
8211
            }
8212
            break;
8213
        case 0x5: /* adc */
8214
            if (s->condexec_mask)
8215
                gen_adc_T0_T1();
8216
            else
8217
                gen_op_adcl_T0_T1_cc();
8218
            break;
8219
        case 0x6: /* sbc */
8220
            if (s->condexec_mask)
8221
                gen_sbc_T0_T1();
8222
            else
8223
                gen_op_sbcl_T0_T1_cc();
8224
            break;
8225
        case 0x7: /* ror */
8226
            if (s->condexec_mask) {
8227
                gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8228
            } else {
8229
                gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8230
                gen_op_logic_T1_cc();
8231
            }
8232
            break;
8233
        case 0x8: /* tst */
8234
            gen_op_andl_T0_T1();
8235
            gen_op_logic_T0_cc();
8236
            rd = 16;
8237
            break;
8238
        case 0x9: /* neg */
8239
            if (s->condexec_mask)
8240
                tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8241
            else
8242
                gen_op_subl_T0_T1_cc();
8243
            break;
8244
        case 0xa: /* cmp */
8245
            gen_op_subl_T0_T1_cc();
8246
            rd = 16;
8247
            break;
8248
        case 0xb: /* cmn */
8249
            gen_op_addl_T0_T1_cc();
8250
            rd = 16;
8251
            break;
8252
        case 0xc: /* orr */
8253
            gen_op_orl_T0_T1();
8254
            if (!s->condexec_mask)
8255
                gen_op_logic_T0_cc();
8256
            break;
8257
        case 0xd: /* mul */
8258
            gen_op_mull_T0_T1();
8259
            if (!s->condexec_mask)
8260
                gen_op_logic_T0_cc();
8261
            break;
8262
        case 0xe: /* bic */
8263
            gen_op_bicl_T0_T1();
8264
            if (!s->condexec_mask)
8265
                gen_op_logic_T0_cc();
8266
            break;
8267
        case 0xf: /* mvn */
8268
            gen_op_notl_T1();
8269
            if (!s->condexec_mask)
8270
                gen_op_logic_T1_cc();
8271
            val = 1;
8272
            rm = rd;
8273
            break;
8274
        }
8275
        if (rd != 16) {
8276
            if (val)
8277
                gen_movl_reg_T1(s, rm);
8278
            else
8279
                gen_movl_reg_T0(s, rd);
8280
        }
8281
        break;
8282

    
8283
    case 5:
8284
        /* load/store register offset.  */
8285
        rd = insn & 7;
8286
        rn = (insn >> 3) & 7;
8287
        rm = (insn >> 6) & 7;
8288
        op = (insn >> 9) & 7;
8289
        addr = load_reg(s, rn);
8290
        tmp = load_reg(s, rm);
8291
        tcg_gen_add_i32(addr, addr, tmp);
8292
        dead_tmp(tmp);
8293

    
8294
        if (op < 3) /* store */
8295
            tmp = load_reg(s, rd);
8296

    
8297
        switch (op) {
8298
        case 0: /* str */
8299
            gen_st32(tmp, addr, IS_USER(s));
8300
            break;
8301
        case 1: /* strh */
8302
            gen_st16(tmp, addr, IS_USER(s));
8303
            break;
8304
        case 2: /* strb */
8305
            gen_st8(tmp, addr, IS_USER(s));
8306
            break;
8307
        case 3: /* ldrsb */
8308
            tmp = gen_ld8s(addr, IS_USER(s));
8309
            break;
8310
        case 4: /* ldr */
8311
            tmp = gen_ld32(addr, IS_USER(s));
8312
            break;
8313
        case 5: /* ldrh */
8314
            tmp = gen_ld16u(addr, IS_USER(s));
8315
            break;
8316
        case 6: /* ldrb */
8317
            tmp = gen_ld8u(addr, IS_USER(s));
8318
            break;
8319
        case 7: /* ldrsh */
8320
            tmp = gen_ld16s(addr, IS_USER(s));
8321
            break;
8322
        }
8323
        if (op >= 3) /* load */
8324
            store_reg(s, rd, tmp);
8325
        dead_tmp(addr);
8326
        break;
8327

    
8328
    case 6:
8329
        /* load/store word immediate offset */
8330
        rd = insn & 7;
8331
        rn = (insn >> 3) & 7;
8332
        addr = load_reg(s, rn);
8333
        val = (insn >> 4) & 0x7c;
8334
        tcg_gen_addi_i32(addr, addr, val);
8335

    
8336
        if (insn & (1 << 11)) {
8337
            /* load */
8338
            tmp = gen_ld32(addr, IS_USER(s));
8339
            store_reg(s, rd, tmp);
8340
        } else {
8341
            /* store */
8342
            tmp = load_reg(s, rd);
8343
            gen_st32(tmp, addr, IS_USER(s));
8344
        }
8345
        dead_tmp(addr);
8346
        break;
8347

    
8348
    case 7:
8349
        /* load/store byte immediate offset */
8350
        rd = insn & 7;
8351
        rn = (insn >> 3) & 7;
8352
        addr = load_reg(s, rn);
8353
        val = (insn >> 6) & 0x1f;
8354
        tcg_gen_addi_i32(addr, addr, val);
8355

    
8356
        if (insn & (1 << 11)) {
8357
            /* load */
8358
            tmp = gen_ld8u(addr, IS_USER(s));
8359
            store_reg(s, rd, tmp);
8360
        } else {
8361
            /* store */
8362
            tmp = load_reg(s, rd);
8363
            gen_st8(tmp, addr, IS_USER(s));
8364
        }
8365
        dead_tmp(addr);
8366
        break;
8367

    
8368
    case 8:
8369
        /* load/store halfword immediate offset */
8370
        rd = insn & 7;
8371
        rn = (insn >> 3) & 7;
8372
        addr = load_reg(s, rn);
8373
        val = (insn >> 5) & 0x3e;
8374
        tcg_gen_addi_i32(addr, addr, val);
8375

    
8376
        if (insn & (1 << 11)) {
8377
            /* load */
8378
            tmp = gen_ld16u(addr, IS_USER(s));
8379
            store_reg(s, rd, tmp);
8380
        } else {
8381
            /* store */
8382
            tmp = load_reg(s, rd);
8383
            gen_st16(tmp, addr, IS_USER(s));
8384
        }
8385
        dead_tmp(addr);
8386
        break;
8387

    
8388
    case 9:
8389
        /* load/store from stack */
8390
        rd = (insn >> 8) & 7;
8391
        addr = load_reg(s, 13);
8392
        val = (insn & 0xff) * 4;
8393
        tcg_gen_addi_i32(addr, addr, val);
8394

    
8395
        if (insn & (1 << 11)) {
8396
            /* load */
8397
            tmp = gen_ld32(addr, IS_USER(s));
8398
            store_reg(s, rd, tmp);
8399
        } else {
8400
            /* store */
8401
            tmp = load_reg(s, rd);
8402
            gen_st32(tmp, addr, IS_USER(s));
8403
        }
8404
        dead_tmp(addr);
8405
        break;
8406

    
8407
    case 10:
8408
        /* add to high reg */
8409
        rd = (insn >> 8) & 7;
8410
        if (insn & (1 << 11)) {
8411
            /* SP */
8412
            tmp = load_reg(s, 13);
8413
        } else {
8414
            /* PC. bit 1 is ignored.  */
8415
            tmp = new_tmp();
8416
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8417
        }
8418
        val = (insn & 0xff) * 4;
8419
        tcg_gen_addi_i32(tmp, tmp, val);
8420
        store_reg(s, rd, tmp);
8421
        break;
8422

    
8423
    case 11:
8424
        /* misc */
8425
        op = (insn >> 8) & 0xf;
8426
        switch (op) {
8427
        case 0:
8428
            /* adjust stack pointer */
8429
            tmp = load_reg(s, 13);
8430
            val = (insn & 0x7f) * 4;
8431
            if (insn & (1 << 7))
8432
                val = -(int32_t)val;
8433
            tcg_gen_addi_i32(tmp, tmp, val);
8434
            store_reg(s, 13, tmp);
8435
            break;
8436

    
8437
        case 2: /* sign/zero extend.  */
8438
            ARCH(6);
8439
            rd = insn & 7;
8440
            rm = (insn >> 3) & 7;
8441
            tmp = load_reg(s, rm);
8442
            switch ((insn >> 6) & 3) {
8443
            case 0: gen_sxth(tmp); break;
8444
            case 1: gen_sxtb(tmp); break;
8445
            case 2: gen_uxth(tmp); break;
8446
            case 3: gen_uxtb(tmp); break;
8447
            }
8448
            store_reg(s, rd, tmp);
8449
            break;
8450
        case 4: case 5: case 0xc: case 0xd:
8451
            /* push/pop */
8452
            addr = load_reg(s, 13);
8453
            if (insn & (1 << 8))
8454
                offset = 4;
8455
            else
8456
                offset = 0;
8457
            for (i = 0; i < 8; i++) {
8458
                if (insn & (1 << i))
8459
                    offset += 4;
8460
            }
8461
            if ((insn & (1 << 11)) == 0) {
8462
                tcg_gen_addi_i32(addr, addr, -offset);
8463
            }
8464
            for (i = 0; i < 8; i++) {
8465
                if (insn & (1 << i)) {
8466
                    if (insn & (1 << 11)) {
8467
                        /* pop */
8468
                        tmp = gen_ld32(addr, IS_USER(s));
8469
                        store_reg(s, i, tmp);
8470
                    } else {
8471
                        /* push */
8472
                        tmp = load_reg(s, i);
8473
                        gen_st32(tmp, addr, IS_USER(s));
8474
                    }
8475
                    /* advance to the next address.  */
8476
                    tcg_gen_addi_i32(addr, addr, 4);
8477
                }
8478
            }
8479
            TCGV_UNUSED(tmp);
8480
            if (insn & (1 << 8)) {
8481
                if (insn & (1 << 11)) {
8482
                    /* pop pc */
8483
                    tmp = gen_ld32(addr, IS_USER(s));
8484
                    /* don't set the pc until the rest of the instruction
8485
                       has completed */
8486
                } else {
8487
                    /* push lr */
8488
                    tmp = load_reg(s, 14);
8489
                    gen_st32(tmp, addr, IS_USER(s));
8490
                }
8491
                tcg_gen_addi_i32(addr, addr, 4);
8492
            }
8493
            if ((insn & (1 << 11)) == 0) {
8494
                tcg_gen_addi_i32(addr, addr, -offset);
8495
            }
8496
            /* write back the new stack pointer */
8497
            store_reg(s, 13, addr);
8498
            /* set the new PC value */
8499
            if ((insn & 0x0900) == 0x0900)
8500
                gen_bx(s, tmp);
8501
            break;
8502

    
8503
        case 1: case 3: case 9: case 11: /* czb */
8504
            rm = insn & 7;
8505
            tmp = load_reg(s, rm);
8506
            s->condlabel = gen_new_label();
8507
            s->condjmp = 1;
8508
            if (insn & (1 << 11))
8509
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8510
            else
8511
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8512
            dead_tmp(tmp);
8513
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8514
            val = (uint32_t)s->pc + 2;
8515
            val += offset;
8516
            gen_jmp(s, val);
8517
            break;
8518

    
8519
        case 15: /* IT, nop-hint.  */
8520
            if ((insn & 0xf) == 0) {
8521
                gen_nop_hint(s, (insn >> 4) & 0xf);
8522
                break;
8523
            }
8524
            /* If Then.  */
8525
            s->condexec_cond = (insn >> 4) & 0xe;
8526
            s->condexec_mask = insn & 0x1f;
8527
            /* No actual code generated for this insn, just setup state.  */
8528
            break;
8529

    
8530
        case 0xe: /* bkpt */
8531
            gen_set_condexec(s);
8532
            gen_set_pc_im(s->pc - 2);
8533
            gen_exception(EXCP_BKPT);
8534
            s->is_jmp = DISAS_JUMP;
8535
            break;
8536

    
8537
        case 0xa: /* rev */
8538
            ARCH(6);
8539
            rn = (insn >> 3) & 0x7;
8540
            rd = insn & 0x7;
8541
            tmp = load_reg(s, rn);
8542
            switch ((insn >> 6) & 3) {
8543
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8544
            case 1: gen_rev16(tmp); break;
8545
            case 3: gen_revsh(tmp); break;
8546
            default: goto illegal_op;
8547
            }
8548
            store_reg(s, rd, tmp);
8549
            break;
8550

    
8551
        case 6: /* cps */
8552
            ARCH(6);
8553
            if (IS_USER(s))
8554
                break;
8555
            if (IS_M(env)) {
8556
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8557
                /* PRIMASK */
8558
                if (insn & 1) {
8559
                    addr = tcg_const_i32(16);
8560
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8561
                }
8562
                /* FAULTMASK */
8563
                if (insn & 2) {
8564
                    addr = tcg_const_i32(17);
8565
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8566
                }
8567
                gen_lookup_tb(s);
8568
            } else {
8569
                if (insn & (1 << 4))
8570
                    shift = CPSR_A | CPSR_I | CPSR_F;
8571
                else
8572
                    shift = 0;
8573

    
8574
                val = ((insn & 7) << 6) & shift;
8575
                gen_op_movl_T0_im(val);
8576
                gen_set_psr_T0(s, shift, 0);
8577
            }
8578
            break;
8579

    
8580
        default:
8581
            goto undef;
8582
        }
8583
        break;
8584

    
8585
    case 12:
8586
        /* load/store multiple */
8587
        rn = (insn >> 8) & 0x7;
8588
        addr = load_reg(s, rn);
8589
        for (i = 0; i < 8; i++) {
8590
            if (insn & (1 << i)) {
8591
                if (insn & (1 << 11)) {
8592
                    /* load */
8593
                    tmp = gen_ld32(addr, IS_USER(s));
8594
                    store_reg(s, i, tmp);
8595
                } else {
8596
                    /* store */
8597
                    tmp = load_reg(s, i);
8598
                    gen_st32(tmp, addr, IS_USER(s));
8599
                }
8600
                /* advance to the next address */
8601
                tcg_gen_addi_i32(addr, addr, 4);
8602
            }
8603
        }
8604
        /* Base register writeback.  */
8605
        if ((insn & (1 << rn)) == 0) {
8606
            store_reg(s, rn, addr);
8607
        } else {
8608
            dead_tmp(addr);
8609
        }
8610
        break;
8611

    
8612
    case 13:
8613
        /* conditional branch or swi */
8614
        cond = (insn >> 8) & 0xf;
8615
        if (cond == 0xe)
8616
            goto undef;
8617

    
8618
        if (cond == 0xf) {
8619
            /* swi */
8620
            gen_set_condexec(s);
8621
            gen_set_pc_im(s->pc);
8622
            s->is_jmp = DISAS_SWI;
8623
            break;
8624
        }
8625
        /* generate a conditional jump to next instruction */
8626
        s->condlabel = gen_new_label();
8627
        gen_test_cc(cond ^ 1, s->condlabel);
8628
        s->condjmp = 1;
8629

    
8630
        /* jump to the offset */
8631
        val = (uint32_t)s->pc + 2;
8632
        offset = ((int32_t)insn << 24) >> 24;
8633
        val += offset << 1;
8634
        gen_jmp(s, val);
8635
        break;
8636

    
8637
    case 14:
8638
        if (insn & (1 << 11)) {
8639
            if (disas_thumb2_insn(env, s, insn))
8640
              goto undef32;
8641
            break;
8642
        }
8643
        /* unconditional branch */
8644
        val = (uint32_t)s->pc;
8645
        offset = ((int32_t)insn << 21) >> 21;
8646
        val += (offset << 1) + 2;
8647
        gen_jmp(s, val);
8648
        break;
8649

    
8650
    case 15:
8651
        if (disas_thumb2_insn(env, s, insn))
8652
            goto undef32;
8653
        break;
8654
    }
8655
    return;
8656
undef32:
8657
    gen_set_condexec(s);
8658
    gen_set_pc_im(s->pc - 4);
8659
    gen_exception(EXCP_UDEF);
8660
    s->is_jmp = DISAS_JUMP;
8661
    return;
8662
illegal_op:
8663
undef:
8664
    gen_set_condexec(s);
8665
    gen_set_pc_im(s->pc - 2);
8666
    gen_exception(EXCP_UDEF);
8667
    s->is_jmp = DISAS_JUMP;
8668
}
8669

    
8670
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8671
   basic block 'tb'. If search_pc is TRUE, also generate PC
8672
   information for each intermediate instruction. */
8673
static inline void gen_intermediate_code_internal(CPUState *env,
8674
                                                  TranslationBlock *tb,
8675
                                                  int search_pc)
8676
{
8677
    DisasContext dc1, *dc = &dc1;
8678
    CPUBreakpoint *bp;
8679
    uint16_t *gen_opc_end;
8680
    int j, lj;
8681
    target_ulong pc_start;
8682
    uint32_t next_page_start;
8683
    int num_insns;
8684
    int max_insns;
8685

    
8686
    /* generate intermediate code */
8687
    num_temps = 0;
8688

    
8689
    pc_start = tb->pc;
8690

    
8691
    dc->tb = tb;
8692

    
8693
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8694

    
8695
    dc->is_jmp = DISAS_NEXT;
8696
    dc->pc = pc_start;
8697
    dc->singlestep_enabled = env->singlestep_enabled;
8698
    dc->condjmp = 0;
8699
    dc->thumb = env->thumb;
8700
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8701
    dc->condexec_cond = env->condexec_bits >> 4;
8702
#if !defined(CONFIG_USER_ONLY)
8703
    if (IS_M(env)) {
8704
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8705
    } else {
8706
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8707
    }
8708
#endif
8709
    cpu_F0s = tcg_temp_new_i32();
8710
    cpu_F1s = tcg_temp_new_i32();
8711
    cpu_F0d = tcg_temp_new_i64();
8712
    cpu_F1d = tcg_temp_new_i64();
8713
    cpu_V0 = cpu_F0d;
8714
    cpu_V1 = cpu_F1d;
8715
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
8716
    cpu_M0 = tcg_temp_new_i64();
8717
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8718
    lj = -1;
8719
    num_insns = 0;
8720
    max_insns = tb->cflags & CF_COUNT_MASK;
8721
    if (max_insns == 0)
8722
        max_insns = CF_COUNT_MASK;
8723

    
8724
    gen_icount_start();
8725
    /* Reset the conditional execution bits immediately. This avoids
8726
       complications trying to do it at the end of the block.  */
8727
    if (env->condexec_bits)
8728
      {
8729
        TCGv tmp = new_tmp();
8730
        tcg_gen_movi_i32(tmp, 0);
8731
        store_cpu_field(tmp, condexec_bits);
8732
      }
8733
    do {
8734
#ifdef CONFIG_USER_ONLY
8735
        /* Intercept jump to the magic kernel page.  */
8736
        if (dc->pc >= 0xffff0000) {
8737
            /* We always get here via a jump, so know we are not in a
8738
               conditional execution block.  */
8739
            gen_exception(EXCP_KERNEL_TRAP);
8740
            dc->is_jmp = DISAS_UPDATE;
8741
            break;
8742
        }
8743
#else
8744
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8745
            /* We always get here via a jump, so know we are not in a
8746
               conditional execution block.  */
8747
            gen_exception(EXCP_EXCEPTION_EXIT);
8748
            dc->is_jmp = DISAS_UPDATE;
8749
            break;
8750
        }
8751
#endif
8752

    
8753
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
8754
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
8755
                if (bp->pc == dc->pc) {
8756
                    gen_set_condexec(dc);
8757
                    gen_set_pc_im(dc->pc);
8758
                    gen_exception(EXCP_DEBUG);
8759
                    dc->is_jmp = DISAS_JUMP;
8760
                    /* Advance PC so that clearing the breakpoint will
8761
                       invalidate this TB.  */
8762
                    dc->pc += 2;
8763
                    goto done_generating;
8764
                    break;
8765
                }
8766
            }
8767
        }
8768
        if (search_pc) {
8769
            j = gen_opc_ptr - gen_opc_buf;
8770
            if (lj < j) {
8771
                lj++;
8772
                while (lj < j)
8773
                    gen_opc_instr_start[lj++] = 0;
8774
            }
8775
            gen_opc_pc[lj] = dc->pc;
8776
            gen_opc_instr_start[lj] = 1;
8777
            gen_opc_icount[lj] = num_insns;
8778
        }
8779

    
8780
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8781
            gen_io_start();
8782

    
8783
        if (env->thumb) {
8784
            disas_thumb_insn(env, dc);
8785
            if (dc->condexec_mask) {
8786
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8787
                                   | ((dc->condexec_mask >> 4) & 1);
8788
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8789
                if (dc->condexec_mask == 0) {
8790
                    dc->condexec_cond = 0;
8791
                }
8792
            }
8793
        } else {
8794
            disas_arm_insn(env, dc);
8795
        }
8796
        if (num_temps) {
8797
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8798
            num_temps = 0;
8799
        }
8800

    
8801
        if (dc->condjmp && !dc->is_jmp) {
8802
            gen_set_label(dc->condlabel);
8803
            dc->condjmp = 0;
8804
        }
8805
        /* Translation stops when a conditional branch is encountered.
8806
         * Otherwise the subsequent code could get translated several times.
8807
         * Also stop translation when a page boundary is reached.  This
8808
         * ensures prefetch aborts occur at the right place.  */
8809
        num_insns ++;
8810
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8811
             !env->singlestep_enabled &&
8812
             !singlestep &&
8813
             dc->pc < next_page_start &&
8814
             num_insns < max_insns);
8815

    
8816
    if (tb->cflags & CF_LAST_IO) {
8817
        if (dc->condjmp) {
8818
            /* FIXME:  This can theoretically happen with self-modifying
8819
               code.  */
8820
            cpu_abort(env, "IO on conditional branch instruction");
8821
        }
8822
        gen_io_end();
8823
    }
8824

    
8825
    /* At this stage dc->condjmp will only be set when the skipped
8826
       instruction was a conditional branch or trap, and the PC has
8827
       already been written.  */
8828
    if (unlikely(env->singlestep_enabled)) {
8829
        /* Make sure the pc is updated, and raise a debug exception.  */
8830
        if (dc->condjmp) {
8831
            gen_set_condexec(dc);
8832
            if (dc->is_jmp == DISAS_SWI) {
8833
                gen_exception(EXCP_SWI);
8834
            } else {
8835
                gen_exception(EXCP_DEBUG);
8836
            }
8837
            gen_set_label(dc->condlabel);
8838
        }
8839
        if (dc->condjmp || !dc->is_jmp) {
8840
            gen_set_pc_im(dc->pc);
8841
            dc->condjmp = 0;
8842
        }
8843
        gen_set_condexec(dc);
8844
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8845
            gen_exception(EXCP_SWI);
8846
        } else {
8847
            /* FIXME: Single stepping a WFI insn will not halt
8848
               the CPU.  */
8849
            gen_exception(EXCP_DEBUG);
8850
        }
8851
    } else {
8852
        /* While branches must always occur at the end of an IT block,
8853
           there are a few other things that can cause us to terminate
8854
           the TB in the middel of an IT block:
8855
            - Exception generating instructions (bkpt, swi, undefined).
8856
            - Page boundaries.
8857
            - Hardware watchpoints.
8858
           Hardware breakpoints have already been handled and skip this code.
8859
         */
8860
        gen_set_condexec(dc);
8861
        switch(dc->is_jmp) {
8862
        case DISAS_NEXT:
8863
            gen_goto_tb(dc, 1, dc->pc);
8864
            break;
8865
        default:
8866
        case DISAS_JUMP:
8867
        case DISAS_UPDATE:
8868
            /* indicate that the hash table must be used to find the next TB */
8869
            tcg_gen_exit_tb(0);
8870
            break;
8871
        case DISAS_TB_JUMP:
8872
            /* nothing more to generate */
8873
            break;
8874
        case DISAS_WFI:
8875
            gen_helper_wfi();
8876
            break;
8877
        case DISAS_SWI:
8878
            gen_exception(EXCP_SWI);
8879
            break;
8880
        }
8881
        if (dc->condjmp) {
8882
            gen_set_label(dc->condlabel);
8883
            gen_set_condexec(dc);
8884
            gen_goto_tb(dc, 1, dc->pc);
8885
            dc->condjmp = 0;
8886
        }
8887
    }
8888

    
8889
done_generating:
8890
    gen_icount_end(tb, num_insns);
8891
    *gen_opc_ptr = INDEX_op_end;
8892

    
8893
#ifdef DEBUG_DISAS
8894
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8895
        qemu_log("----------------\n");
8896
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8897
        log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
8898
        qemu_log("\n");
8899
    }
8900
#endif
8901
    if (search_pc) {
8902
        j = gen_opc_ptr - gen_opc_buf;
8903
        lj++;
8904
        while (lj <= j)
8905
            gen_opc_instr_start[lj++] = 0;
8906
    } else {
8907
        tb->size = dc->pc - pc_start;
8908
        tb->icount = num_insns;
8909
    }
8910
}
8911

    
8912
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8913
{
8914
    gen_intermediate_code_internal(env, tb, 0);
8915
}
8916

    
8917
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8918
{
8919
    gen_intermediate_code_internal(env, tb, 1);
8920
}
8921

    
8922
static const char *cpu_mode_names[16] = {
8923
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8924
  "???", "???", "???", "und", "???", "???", "???", "sys"
8925
};
8926

    
8927
void cpu_dump_state(CPUState *env, FILE *f,
8928
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8929
                    int flags)
8930
{
8931
    int i;
8932
#if 0
8933
    union {
8934
        uint32_t i;
8935
        float s;
8936
    } s0, s1;
8937
    CPU_DoubleU d;
8938
    /* ??? This assumes float64 and double have the same layout.
8939
       Oh well, it's only debug dumps.  */
8940
    union {
8941
        float64 f64;
8942
        double d;
8943
    } d0;
8944
#endif
8945
    uint32_t psr;
8946

    
8947
    for(i=0;i<16;i++) {
8948
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8949
        if ((i % 4) == 3)
8950
            cpu_fprintf(f, "\n");
8951
        else
8952
            cpu_fprintf(f, " ");
8953
    }
8954
    psr = cpsr_read(env);
8955
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8956
                psr,
8957
                psr & (1 << 31) ? 'N' : '-',
8958
                psr & (1 << 30) ? 'Z' : '-',
8959
                psr & (1 << 29) ? 'C' : '-',
8960
                psr & (1 << 28) ? 'V' : '-',
8961
                psr & CPSR_T ? 'T' : 'A',
8962
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8963

    
8964
#if 0
8965
    for (i = 0; i < 16; i++) {
8966
        d.d = env->vfp.regs[i];
8967
        s0.i = d.l.lower;
8968
        s1.i = d.l.upper;
8969
        d0.f64 = d.d;
8970
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8971
                    i * 2, (int)s0.i, s0.s,
8972
                    i * 2 + 1, (int)s1.i, s1.s,
8973
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8974
                    d0.d);
8975
    }
8976
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8977
#endif
8978
}
8979

    
8980
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8981
                unsigned long searched_pc, int pc_pos, void *puc)
8982
{
8983
    env->regs[15] = gen_opc_pc[pc_pos];
8984
}