Statistics
| Branch: | Revision:

root / target-arm / translate.c @ b40d0353

History | View | Annotate | Download (296.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, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
#include <stdarg.h>
23
#include <stdlib.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include <inttypes.h>
27

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

    
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) if (!ENABLE_ARCH_##x) goto illegal_op;
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
    int is_mem;
60
#if !defined(CONFIG_USER_ONLY)
61
    int user;
62
#endif
63
} DisasContext;
64

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

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

    
76
static TCGv cpu_env;
77
/* We reuse the same 64-bit temporaries for efficiency.  */
78
static TCGv cpu_V0, cpu_V1, cpu_M0;
79

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

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

    
87
/* initialize TCG globals.  */
88
void arm_translate_init(void)
89
{
90
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
91

    
92
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
93
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
94
}
95

    
96
/* The code generator doesn't like lots of temporaries, so maintain our own
97
   cache for reuse within a function.  */
98
#define MAX_TEMPS 8
99
static int num_temps;
100
static TCGv temps[MAX_TEMPS];
101

    
102
/* Allocate a temporary variable.  */
103
static TCGv new_tmp(void)
104
{
105
    TCGv tmp;
106
    if (num_temps == MAX_TEMPS)
107
        abort();
108

    
109
    if (GET_TCGV(temps[num_temps]))
110
      return temps[num_temps++];
111

    
112
    tmp = tcg_temp_new(TCG_TYPE_I32);
113
    temps[num_temps++] = tmp;
114
    return tmp;
115
}
116

    
117
/* Release a temporary variable.  */
118
static void dead_tmp(TCGv tmp)
119
{
120
    int i;
121
    num_temps--;
122
    i = num_temps;
123
    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
124
        return;
125

    
126
    /* Shuffle this temp to the last slot.  */
127
    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
128
        i--;
129
    while (i < num_temps) {
130
        temps[i] = temps[i + 1];
131
        i++;
132
    }
133
    temps[i] = tmp;
134
}
135

    
136
static inline TCGv load_cpu_offset(int offset)
137
{
138
    TCGv tmp = new_tmp();
139
    tcg_gen_ld_i32(tmp, cpu_env, offset);
140
    return tmp;
141
}
142

    
143
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
144

    
145
static inline void store_cpu_offset(TCGv var, int offset)
146
{
147
    tcg_gen_st_i32(var, cpu_env, offset);
148
    dead_tmp(var);
149
}
150

    
151
#define store_cpu_field(var, name) \
152
    store_cpu_offset(var, offsetof(CPUState, name))
153

    
154
/* Set a variable to the value of a CPU register.  */
155
static void load_reg_var(DisasContext *s, TCGv var, int reg)
156
{
157
    if (reg == 15) {
158
        uint32_t addr;
159
        /* normaly, since we updated PC, we need only to add one insn */
160
        if (s->thumb)
161
            addr = (long)s->pc + 2;
162
        else
163
            addr = (long)s->pc + 4;
164
        tcg_gen_movi_i32(var, addr);
165
    } else {
166
        tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
167
    }
168
}
169

    
170
/* Create a new temporary and set it to the value of a CPU register.  */
171
static inline TCGv load_reg(DisasContext *s, int reg)
172
{
173
    TCGv tmp = new_tmp();
174
    load_reg_var(s, tmp, reg);
175
    return tmp;
176
}
177

    
178
/* Set a CPU register.  The source must be a temporary and will be
179
   marked as dead.  */
180
static void store_reg(DisasContext *s, int reg, TCGv var)
181
{
182
    if (reg == 15) {
183
        tcg_gen_andi_i32(var, var, ~1);
184
        s->is_jmp = DISAS_JUMP;
185
    }
186
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
187
    dead_tmp(var);
188
}
189

    
190

    
191
/* Basic operations.  */
192
#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
193
#define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
194
#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
195
#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
196

    
197
#define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
198
#define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
199
#define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
200
#define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
201

    
202
#define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
203
#define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
204
#define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
205
#define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
206
#define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
207
#define gen_op_rscl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[1], cpu_T[0])
208

    
209
#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
210
#define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
211
#define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
212
#define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
213
#define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
214
#define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
215
#define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
216

    
217
#define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
218
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
219
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
220
#define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
221
#define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
222

    
223
/* Value extensions.  */
224
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
225
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
226
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
227
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
228

    
229
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
230
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
231

    
232
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
233

    
234
#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
235
/* Set NZCV flags from the high 4 bits of var.  */
236
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
237

    
238
static void gen_exception(int excp)
239
{
240
    TCGv tmp = new_tmp();
241
    tcg_gen_movi_i32(tmp, excp);
242
    gen_helper_exception(tmp);
243
    dead_tmp(tmp);
244
}
245

    
246
static void gen_smul_dual(TCGv a, TCGv b)
247
{
248
    TCGv tmp1 = new_tmp();
249
    TCGv tmp2 = new_tmp();
250
    tcg_gen_ext16s_i32(tmp1, a);
251
    tcg_gen_ext16s_i32(tmp2, b);
252
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
253
    dead_tmp(tmp2);
254
    tcg_gen_sari_i32(a, a, 16);
255
    tcg_gen_sari_i32(b, b, 16);
256
    tcg_gen_mul_i32(b, b, a);
257
    tcg_gen_mov_i32(a, tmp1);
258
    dead_tmp(tmp1);
259
}
260

    
261
/* Byteswap each halfword.  */
262
static void gen_rev16(TCGv var)
263
{
264
    TCGv tmp = new_tmp();
265
    tcg_gen_shri_i32(tmp, var, 8);
266
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
267
    tcg_gen_shli_i32(var, var, 8);
268
    tcg_gen_andi_i32(var, var, 0xff00ff00);
269
    tcg_gen_or_i32(var, var, tmp);
270
    dead_tmp(tmp);
271
}
272

    
273
/* Byteswap low halfword and sign extend.  */
274
static void gen_revsh(TCGv var)
275
{
276
    TCGv tmp = new_tmp();
277
    tcg_gen_shri_i32(tmp, var, 8);
278
    tcg_gen_andi_i32(tmp, tmp, 0x00ff);
279
    tcg_gen_shli_i32(var, var, 8);
280
    tcg_gen_ext8s_i32(var, var);
281
    tcg_gen_or_i32(var, var, tmp);
282
    dead_tmp(tmp);
283
}
284

    
285
/* Unsigned bitfield extract.  */
286
static void gen_ubfx(TCGv var, int shift, uint32_t mask)
287
{
288
    if (shift)
289
        tcg_gen_shri_i32(var, var, shift);
290
    tcg_gen_andi_i32(var, var, mask);
291
}
292

    
293
/* Signed bitfield extract.  */
294
static void gen_sbfx(TCGv var, int shift, int width)
295
{
296
    uint32_t signbit;
297

    
298
    if (shift)
299
        tcg_gen_sari_i32(var, var, shift);
300
    if (shift + width < 32) {
301
        signbit = 1u << (width - 1);
302
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
303
        tcg_gen_xori_i32(var, var, signbit);
304
        tcg_gen_subi_i32(var, var, signbit);
305
    }
306
}
307

    
308
/* Bitfield insertion.  Insert val into base.  Clobbers base and val.  */
309
static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
310
{
311
    tcg_gen_andi_i32(val, val, mask);
312
    tcg_gen_shli_i32(val, val, shift);
313
    tcg_gen_andi_i32(base, base, ~(mask << shift));
314
    tcg_gen_or_i32(dest, base, val);
315
}
316

    
317
/* Round the top 32 bits of a 64-bit value.  */
318
static void gen_roundqd(TCGv a, TCGv b)
319
{
320
    tcg_gen_shri_i32(a, a, 31);
321
    tcg_gen_add_i32(a, a, b);
322
}
323

    
324
/* FIXME: Most targets have native widening multiplication.
325
   It would be good to use that instead of a full wide multiply.  */
326
/* 32x32->64 multiply.  Marks inputs as dead.  */
327
static TCGv gen_mulu_i64_i32(TCGv a, TCGv b)
328
{
329
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
330
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
331

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

    
340
static TCGv gen_muls_i64_i32(TCGv a, TCGv b)
341
{
342
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
343
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
344

    
345
    tcg_gen_ext_i32_i64(tmp1, a);
346
    dead_tmp(a);
347
    tcg_gen_ext_i32_i64(tmp2, b);
348
    dead_tmp(b);
349
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
350
    return tmp1;
351
}
352

    
353
/* Unsigned 32x32->64 multiply.  */
354
static void gen_op_mull_T0_T1(void)
355
{
356
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
357
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
358

    
359
    tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
360
    tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
361
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
362
    tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
363
    tcg_gen_shri_i64(tmp1, tmp1, 32);
364
    tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
365
}
366

    
367
/* Signed 32x32->64 multiply.  */
368
static void gen_imull(TCGv a, TCGv b)
369
{
370
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
371
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
372

    
373
    tcg_gen_ext_i32_i64(tmp1, a);
374
    tcg_gen_ext_i32_i64(tmp2, b);
375
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
376
    tcg_gen_trunc_i64_i32(a, tmp1);
377
    tcg_gen_shri_i64(tmp1, tmp1, 32);
378
    tcg_gen_trunc_i64_i32(b, tmp1);
379
}
380
#define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
381

    
382
/* Swap low and high halfwords.  */
383
static void gen_swap_half(TCGv var)
384
{
385
    TCGv tmp = new_tmp();
386
    tcg_gen_shri_i32(tmp, var, 16);
387
    tcg_gen_shli_i32(var, var, 16);
388
    tcg_gen_or_i32(var, var, tmp);
389
    dead_tmp(tmp);
390
}
391

    
392
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
393
    tmp = (t0 ^ t1) & 0x8000;
394
    t0 &= ~0x8000;
395
    t1 &= ~0x8000;
396
    t0 = (t0 + t1) ^ tmp;
397
 */
398

    
399
static void gen_add16(TCGv t0, TCGv t1)
400
{
401
    TCGv tmp = new_tmp();
402
    tcg_gen_xor_i32(tmp, t0, t1);
403
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
404
    tcg_gen_andi_i32(t0, t0, ~0x8000);
405
    tcg_gen_andi_i32(t1, t1, ~0x8000);
406
    tcg_gen_add_i32(t0, t0, t1);
407
    tcg_gen_xor_i32(t0, t0, tmp);
408
    dead_tmp(tmp);
409
    dead_tmp(t1);
410
}
411

    
412
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
413

    
414
/* Set CF to the top bit of var.  */
415
static void gen_set_CF_bit31(TCGv var)
416
{
417
    TCGv tmp = new_tmp();
418
    tcg_gen_shri_i32(tmp, var, 31);
419
    gen_set_CF(var);
420
    dead_tmp(tmp);
421
}
422

    
423
/* Set N and Z flags from var.  */
424
static inline void gen_logic_CC(TCGv var)
425
{
426
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
427
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
428
}
429

    
430
/* T0 += T1 + CF.  */
431
static void gen_adc_T0_T1(void)
432
{
433
    TCGv tmp;
434
    gen_op_addl_T0_T1();
435
    tmp = load_cpu_field(CF);
436
    tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
437
    dead_tmp(tmp);
438
}
439

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

    
451
#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
452
#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
453

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

    
469
/* FIXME:  Implement this natively.  */
470
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
471

    
472
/* FIXME:  Implement this natively.  */
473
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
474
{
475
    TCGv tmp;
476

    
477
    if (i == 0)
478
        return;
479

    
480
    tmp = new_tmp();
481
    tcg_gen_shri_i32(tmp, t1, i);
482
    tcg_gen_shli_i32(t1, t1, 32 - i);
483
    tcg_gen_or_i32(t0, t1, tmp);
484
    dead_tmp(tmp);
485
}
486

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

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

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

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

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

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

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

    
661
static void gen_test_cc(int cc, int label)
662
{
663
    TCGv tmp;
664
    TCGv tmp2;
665
    int inv;
666

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

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

    
778
/* Set PC and Thumb state from an immediate address.  */
779
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
780
{
781
    TCGv tmp;
782

    
783
    s->is_jmp = DISAS_UPDATE;
784
    tmp = new_tmp();
785
    if (s->thumb != (addr & 1)) {
786
        tcg_gen_movi_i32(tmp, addr & 1);
787
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
788
    }
789
    tcg_gen_movi_i32(tmp, addr & ~1);
790
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
791
    dead_tmp(tmp);
792
}
793

    
794
/* Set PC and Thumb state from var.  var is marked as dead.  */
795
static inline void gen_bx(DisasContext *s, TCGv var)
796
{
797
    TCGv tmp;
798

    
799
    s->is_jmp = DISAS_UPDATE;
800
    tmp = new_tmp();
801
    tcg_gen_andi_i32(tmp, var, 1);
802
    store_cpu_field(tmp, thumb);
803
    tcg_gen_andi_i32(var, var, ~1);
804
    store_cpu_field(var, regs[15]);
805
}
806

    
807
/* TODO: This should be removed.  Use gen_bx instead.  */
808
static inline void gen_bx_T0(DisasContext *s)
809
{
810
    TCGv tmp = new_tmp();
811
    tcg_gen_mov_i32(tmp, cpu_T[0]);
812
    gen_bx(s, tmp);
813
}
814

    
815
#if defined(CONFIG_USER_ONLY)
816
#define gen_ldst(name, s) gen_op_##name##_raw()
817
#else
818
#define gen_ldst(name, s) do { \
819
    s->is_mem = 1; \
820
    if (IS_USER(s)) \
821
        gen_op_##name##_user(); \
822
    else \
823
        gen_op_##name##_kernel(); \
824
    } while (0)
825
#endif
826
static inline TCGv gen_ld8s(TCGv addr, int index)
827
{
828
    TCGv tmp = new_tmp();
829
    tcg_gen_qemu_ld8s(tmp, addr, index);
830
    return tmp;
831
}
832
static inline TCGv gen_ld8u(TCGv addr, int index)
833
{
834
    TCGv tmp = new_tmp();
835
    tcg_gen_qemu_ld8u(tmp, addr, index);
836
    return tmp;
837
}
838
static inline TCGv gen_ld16s(TCGv addr, int index)
839
{
840
    TCGv tmp = new_tmp();
841
    tcg_gen_qemu_ld16s(tmp, addr, index);
842
    return tmp;
843
}
844
static inline TCGv gen_ld16u(TCGv addr, int index)
845
{
846
    TCGv tmp = new_tmp();
847
    tcg_gen_qemu_ld16u(tmp, addr, index);
848
    return tmp;
849
}
850
static inline TCGv gen_ld32(TCGv addr, int index)
851
{
852
    TCGv tmp = new_tmp();
853
    tcg_gen_qemu_ld32u(tmp, addr, index);
854
    return tmp;
855
}
856
static inline void gen_st8(TCGv val, TCGv addr, int index)
857
{
858
    tcg_gen_qemu_st8(val, addr, index);
859
    dead_tmp(val);
860
}
861
static inline void gen_st16(TCGv val, TCGv addr, int index)
862
{
863
    tcg_gen_qemu_st16(val, addr, index);
864
    dead_tmp(val);
865
}
866
static inline void gen_st32(TCGv val, TCGv addr, int index)
867
{
868
    tcg_gen_qemu_st32(val, addr, index);
869
    dead_tmp(val);
870
}
871

    
872
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
873
{
874
    load_reg_var(s, cpu_T[0], reg);
875
}
876

    
877
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
878
{
879
    load_reg_var(s, cpu_T[1], reg);
880
}
881

    
882
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
883
{
884
    load_reg_var(s, cpu_T[2], reg);
885
}
886

    
887
static inline void gen_set_pc_im(uint32_t val)
888
{
889
    TCGv tmp = new_tmp();
890
    tcg_gen_movi_i32(tmp, val);
891
    store_cpu_field(tmp, regs[15]);
892
}
893

    
894
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
895
{
896
    TCGv tmp;
897
    if (reg == 15) {
898
        tmp = new_tmp();
899
        tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
900
    } else {
901
        tmp = cpu_T[t];
902
    }
903
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
904
    if (reg == 15) {
905
        dead_tmp(tmp);
906
        s->is_jmp = DISAS_JUMP;
907
    }
908
}
909

    
910
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
911
{
912
    gen_movl_reg_TN(s, reg, 0);
913
}
914

    
915
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
916
{
917
    gen_movl_reg_TN(s, reg, 1);
918
}
919

    
920
/* Force a TB lookup after an instruction that changes the CPU state.  */
921
static inline void gen_lookup_tb(DisasContext *s)
922
{
923
    gen_op_movl_T0_im(s->pc);
924
    gen_movl_reg_T0(s, 15);
925
    s->is_jmp = DISAS_UPDATE;
926
}
927

    
928
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
929
                                       TCGv var)
930
{
931
    int val, rm, shift, shiftop;
932
    TCGv offset;
933

    
934
    if (!(insn & (1 << 25))) {
935
        /* immediate */
936
        val = insn & 0xfff;
937
        if (!(insn & (1 << 23)))
938
            val = -val;
939
        if (val != 0)
940
            tcg_gen_addi_i32(var, var, val);
941
    } else {
942
        /* shift/register */
943
        rm = (insn) & 0xf;
944
        shift = (insn >> 7) & 0x1f;
945
        shiftop = (insn >> 5) & 3;
946
        offset = load_reg(s, rm);
947
        gen_arm_shift_im(offset, shiftop, shift, 0);
948
        if (!(insn & (1 << 23)))
949
            tcg_gen_sub_i32(var, var, offset);
950
        else
951
            tcg_gen_add_i32(var, var, offset);
952
        dead_tmp(offset);
953
    }
954
}
955

    
956
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
957
                                        int extra, TCGv var)
958
{
959
    int val, rm;
960
    TCGv offset;
961

    
962
    if (insn & (1 << 22)) {
963
        /* immediate */
964
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
965
        if (!(insn & (1 << 23)))
966
            val = -val;
967
        val += extra;
968
        if (val != 0)
969
            tcg_gen_addi_i32(var, var, val);
970
    } else {
971
        /* register */
972
        if (extra)
973
            tcg_gen_addi_i32(var, var, extra);
974
        rm = (insn) & 0xf;
975
        offset = load_reg(s, rm);
976
        if (!(insn & (1 << 23)))
977
            tcg_gen_sub_i32(var, var, offset);
978
        else
979
            tcg_gen_add_i32(var, var, offset);
980
        dead_tmp(offset);
981
    }
982
}
983

    
984
#define VFP_OP2(name)                                                 \
985
static inline void gen_vfp_##name(int dp)                             \
986
{                                                                     \
987
    if (dp)                                                           \
988
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
989
    else                                                              \
990
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
991
}
992

    
993
#define VFP_OP1(name)                               \
994
static inline void gen_vfp_##name(int dp, int arg)  \
995
{                                                   \
996
    if (dp)                                         \
997
        gen_op_vfp_##name##d(arg);                  \
998
    else                                            \
999
        gen_op_vfp_##name##s(arg);                  \
1000
}
1001

    
1002
VFP_OP2(add)
1003
VFP_OP2(sub)
1004
VFP_OP2(mul)
1005
VFP_OP2(div)
1006

    
1007
#undef VFP_OP2
1008

    
1009
static inline void gen_vfp_abs(int dp)
1010
{
1011
    if (dp)
1012
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1013
    else
1014
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1015
}
1016

    
1017
static inline void gen_vfp_neg(int dp)
1018
{
1019
    if (dp)
1020
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1021
    else
1022
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1023
}
1024

    
1025
static inline void gen_vfp_sqrt(int dp)
1026
{
1027
    if (dp)
1028
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1029
    else
1030
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1031
}
1032

    
1033
static inline void gen_vfp_cmp(int dp)
1034
{
1035
    if (dp)
1036
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1037
    else
1038
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1039
}
1040

    
1041
static inline void gen_vfp_cmpe(int dp)
1042
{
1043
    if (dp)
1044
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1045
    else
1046
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1047
}
1048

    
1049
static inline void gen_vfp_F1_ld0(int dp)
1050
{
1051
    if (dp)
1052
        tcg_gen_movi_i64(cpu_F1d, 0);
1053
    else
1054
        tcg_gen_movi_i32(cpu_F1s, 0);
1055
}
1056

    
1057
static inline void gen_vfp_uito(int dp)
1058
{
1059
    if (dp)
1060
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1061
    else
1062
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1063
}
1064

    
1065
static inline void gen_vfp_sito(int dp)
1066
{
1067
    if (dp)
1068
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1069
    else
1070
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1071
}
1072

    
1073
static inline void gen_vfp_toui(int dp)
1074
{
1075
    if (dp)
1076
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1077
    else
1078
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1079
}
1080

    
1081
static inline void gen_vfp_touiz(int dp)
1082
{
1083
    if (dp)
1084
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1085
    else
1086
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1087
}
1088

    
1089
static inline void gen_vfp_tosi(int dp)
1090
{
1091
    if (dp)
1092
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1093
    else
1094
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1095
}
1096

    
1097
static inline void gen_vfp_tosiz(int dp)
1098
{
1099
    if (dp)
1100
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1101
    else
1102
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1103
}
1104

    
1105
#define VFP_GEN_FIX(name) \
1106
static inline void gen_vfp_##name(int dp, int shift) \
1107
{ \
1108
    if (dp) \
1109
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1110
    else \
1111
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1112
}
1113
VFP_GEN_FIX(tosh)
1114
VFP_GEN_FIX(tosl)
1115
VFP_GEN_FIX(touh)
1116
VFP_GEN_FIX(toul)
1117
VFP_GEN_FIX(shto)
1118
VFP_GEN_FIX(slto)
1119
VFP_GEN_FIX(uhto)
1120
VFP_GEN_FIX(ulto)
1121
#undef VFP_GEN_FIX
1122

    
1123
static inline void gen_vfp_ld(DisasContext *s, int dp)
1124
{
1125
    if (dp)
1126
        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1127
    else
1128
        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1129
}
1130

    
1131
static inline void gen_vfp_st(DisasContext *s, int dp)
1132
{
1133
    if (dp)
1134
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1135
    else
1136
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1137
}
1138

    
1139
static inline long
1140
vfp_reg_offset (int dp, int reg)
1141
{
1142
    if (dp)
1143
        return offsetof(CPUARMState, vfp.regs[reg]);
1144
    else if (reg & 1) {
1145
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1146
          + offsetof(CPU_DoubleU, l.upper);
1147
    } else {
1148
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1149
          + offsetof(CPU_DoubleU, l.lower);
1150
    }
1151
}
1152

    
1153
/* Return the offset of a 32-bit piece of a NEON register.
1154
   zero is the least significant end of the register.  */
1155
static inline long
1156
neon_reg_offset (int reg, int n)
1157
{
1158
    int sreg;
1159
    sreg = reg * 2 + n;
1160
    return vfp_reg_offset(0, sreg);
1161
}
1162

    
1163
/* FIXME: Remove these.  */
1164
#define neon_T0 cpu_T[0]
1165
#define neon_T1 cpu_T[1]
1166
#define NEON_GET_REG(T, reg, n) \
1167
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1168
#define NEON_SET_REG(T, reg, n) \
1169
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1170

    
1171
static TCGv neon_load_reg(int reg, int pass)
1172
{
1173
    TCGv tmp = new_tmp();
1174
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1175
    return tmp;
1176
}
1177

    
1178
static void neon_store_reg(int reg, int pass, TCGv var)
1179
{
1180
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1181
    dead_tmp(var);
1182
}
1183

    
1184
static inline void neon_load_reg64(TCGv var, int reg)
1185
{
1186
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1187
}
1188

    
1189
static inline void neon_store_reg64(TCGv var, int reg)
1190
{
1191
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192
}
1193

    
1194
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1195
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1196
#define tcg_gen_st_f32 tcg_gen_st_i32
1197
#define tcg_gen_st_f64 tcg_gen_st_i64
1198

    
1199
static inline void gen_mov_F0_vreg(int dp, int reg)
1200
{
1201
    if (dp)
1202
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1203
    else
1204
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1205
}
1206

    
1207
static inline void gen_mov_F1_vreg(int dp, int reg)
1208
{
1209
    if (dp)
1210
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1211
    else
1212
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1213
}
1214

    
1215
static inline void gen_mov_vreg_F0(int dp, int reg)
1216
{
1217
    if (dp)
1218
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1219
    else
1220
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1221
}
1222

    
1223
#define ARM_CP_RW_BIT        (1 << 20)
1224

    
1225
static inline void iwmmxt_load_reg(TCGv var, int reg)
1226
{
1227
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1228
}
1229

    
1230
static inline void iwmmxt_store_reg(TCGv var, int reg)
1231
{
1232
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1233
}
1234

    
1235
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1236
{
1237
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1238
}
1239

    
1240
static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1241
{
1242
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1243
}
1244

    
1245
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1246
{
1247
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1248
}
1249

    
1250
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1251
{
1252
    iwmmxt_store_reg(cpu_M0, rn);
1253
}
1254

    
1255
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1256
{
1257
    iwmmxt_load_reg(cpu_M0, rn);
1258
}
1259

    
1260
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1261
{
1262
    iwmmxt_load_reg(cpu_V1, rn);
1263
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1264
}
1265

    
1266
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1267
{
1268
    iwmmxt_load_reg(cpu_V1, rn);
1269
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1270
}
1271

    
1272
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1273
{
1274
    iwmmxt_load_reg(cpu_V1, rn);
1275
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1276
}
1277

    
1278
#define IWMMXT_OP(name) \
1279
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1280
{ \
1281
    iwmmxt_load_reg(cpu_V1, rn); \
1282
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1283
}
1284

    
1285
#define IWMMXT_OP_ENV(name) \
1286
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1287
{ \
1288
    iwmmxt_load_reg(cpu_V1, rn); \
1289
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1290
}
1291

    
1292
#define IWMMXT_OP_ENV_SIZE(name) \
1293
IWMMXT_OP_ENV(name##b) \
1294
IWMMXT_OP_ENV(name##w) \
1295
IWMMXT_OP_ENV(name##l)
1296

    
1297
#define IWMMXT_OP_ENV1(name) \
1298
static inline void gen_op_iwmmxt_##name##_M0(void) \
1299
{ \
1300
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1301
}
1302

    
1303
IWMMXT_OP(maddsq)
1304
IWMMXT_OP(madduq)
1305
IWMMXT_OP(sadb)
1306
IWMMXT_OP(sadw)
1307
IWMMXT_OP(mulslw)
1308
IWMMXT_OP(mulshw)
1309
IWMMXT_OP(mululw)
1310
IWMMXT_OP(muluhw)
1311
IWMMXT_OP(macsw)
1312
IWMMXT_OP(macuw)
1313

    
1314
IWMMXT_OP_ENV_SIZE(unpackl)
1315
IWMMXT_OP_ENV_SIZE(unpackh)
1316

    
1317
IWMMXT_OP_ENV1(unpacklub)
1318
IWMMXT_OP_ENV1(unpackluw)
1319
IWMMXT_OP_ENV1(unpacklul)
1320
IWMMXT_OP_ENV1(unpackhub)
1321
IWMMXT_OP_ENV1(unpackhuw)
1322
IWMMXT_OP_ENV1(unpackhul)
1323
IWMMXT_OP_ENV1(unpacklsb)
1324
IWMMXT_OP_ENV1(unpacklsw)
1325
IWMMXT_OP_ENV1(unpacklsl)
1326
IWMMXT_OP_ENV1(unpackhsb)
1327
IWMMXT_OP_ENV1(unpackhsw)
1328
IWMMXT_OP_ENV1(unpackhsl)
1329

    
1330
IWMMXT_OP_ENV_SIZE(cmpeq)
1331
IWMMXT_OP_ENV_SIZE(cmpgtu)
1332
IWMMXT_OP_ENV_SIZE(cmpgts)
1333

    
1334
IWMMXT_OP_ENV_SIZE(mins)
1335
IWMMXT_OP_ENV_SIZE(minu)
1336
IWMMXT_OP_ENV_SIZE(maxs)
1337
IWMMXT_OP_ENV_SIZE(maxu)
1338

    
1339
IWMMXT_OP_ENV_SIZE(subn)
1340
IWMMXT_OP_ENV_SIZE(addn)
1341
IWMMXT_OP_ENV_SIZE(subu)
1342
IWMMXT_OP_ENV_SIZE(addu)
1343
IWMMXT_OP_ENV_SIZE(subs)
1344
IWMMXT_OP_ENV_SIZE(adds)
1345

    
1346
IWMMXT_OP_ENV(avgb0)
1347
IWMMXT_OP_ENV(avgb1)
1348
IWMMXT_OP_ENV(avgw0)
1349
IWMMXT_OP_ENV(avgw1)
1350

    
1351
IWMMXT_OP(msadb)
1352

    
1353
IWMMXT_OP_ENV(packuw)
1354
IWMMXT_OP_ENV(packul)
1355
IWMMXT_OP_ENV(packuq)
1356
IWMMXT_OP_ENV(packsw)
1357
IWMMXT_OP_ENV(packsl)
1358
IWMMXT_OP_ENV(packsq)
1359

    
1360
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1361
{
1362
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1363
}
1364

    
1365
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1366
{
1367
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1368
}
1369

    
1370
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1371
{
1372
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1373
}
1374

    
1375
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1376
{
1377
    iwmmxt_load_reg(cpu_V1, rn);
1378
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1379
}
1380

    
1381
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1382
{
1383
    TCGv tmp = tcg_const_i32(shift);
1384
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1385
}
1386

    
1387
static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1388
{
1389
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1390
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1391
    tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1392
}
1393

    
1394
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1395
{
1396
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1397
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1398
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1399
}
1400

    
1401
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1402
{
1403
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1404
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1405
    if (mask != ~0u)
1406
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1407
}
1408

    
1409
static void gen_op_iwmmxt_set_mup(void)
1410
{
1411
    TCGv tmp;
1412
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1413
    tcg_gen_ori_i32(tmp, tmp, 2);
1414
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1415
}
1416

    
1417
static void gen_op_iwmmxt_set_cup(void)
1418
{
1419
    TCGv tmp;
1420
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1421
    tcg_gen_ori_i32(tmp, tmp, 1);
1422
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1423
}
1424

    
1425
static void gen_op_iwmmxt_setpsr_nz(void)
1426
{
1427
    TCGv tmp = new_tmp();
1428
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1429
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1430
}
1431

    
1432
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1433
{
1434
    iwmmxt_load_reg(cpu_V1, rn);
1435
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1436
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1437
}
1438

    
1439

    
1440
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1441
{
1442
    iwmmxt_load_reg(cpu_V0, rn);
1443
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1444
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1445
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1446
}
1447

    
1448
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1449
{
1450
    tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1451
    tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1452
    tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1453
    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1454
    iwmmxt_store_reg(cpu_V0, rn);
1455
}
1456

    
1457
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1458
{
1459
    int rd;
1460
    uint32_t offset;
1461

    
1462
    rd = (insn >> 16) & 0xf;
1463
    gen_movl_T1_reg(s, rd);
1464

    
1465
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1466
    if (insn & (1 << 24)) {
1467
        /* Pre indexed */
1468
        if (insn & (1 << 23))
1469
            gen_op_addl_T1_im(offset);
1470
        else
1471
            gen_op_addl_T1_im(-offset);
1472

    
1473
        if (insn & (1 << 21))
1474
            gen_movl_reg_T1(s, rd);
1475
    } else if (insn & (1 << 21)) {
1476
        /* Post indexed */
1477
        if (insn & (1 << 23))
1478
            gen_op_movl_T0_im(offset);
1479
        else
1480
            gen_op_movl_T0_im(- offset);
1481
        gen_op_addl_T0_T1();
1482
        gen_movl_reg_T0(s, rd);
1483
    } else if (!(insn & (1 << 23)))
1484
        return 1;
1485
    return 0;
1486
}
1487

    
1488
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1489
{
1490
    int rd = (insn >> 0) & 0xf;
1491

    
1492
    if (insn & (1 << 8))
1493
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1494
            return 1;
1495
        else
1496
            gen_op_iwmmxt_movl_T0_wCx(rd);
1497
    else
1498
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1499

    
1500
    gen_op_movl_T1_im(mask);
1501
    gen_op_andl_T0_T1();
1502
    return 0;
1503
}
1504

    
1505
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1506
   (ie. an undefined instruction).  */
1507
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1508
{
1509
    int rd, wrd;
1510
    int rdhi, rdlo, rd0, rd1, i;
1511
    TCGv tmp;
1512

    
1513
    if ((insn & 0x0e000e00) == 0x0c000000) {
1514
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1515
            wrd = insn & 0xf;
1516
            rdlo = (insn >> 12) & 0xf;
1517
            rdhi = (insn >> 16) & 0xf;
1518
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1519
                gen_iwmmxt_movl_T0_T1_wRn(wrd);
1520
                gen_movl_reg_T0(s, rdlo);
1521
                gen_movl_reg_T1(s, rdhi);
1522
            } else {                                        /* TMCRR */
1523
                gen_movl_T0_reg(s, rdlo);
1524
                gen_movl_T1_reg(s, rdhi);
1525
                gen_iwmmxt_movl_wRn_T0_T1(wrd);
1526
                gen_op_iwmmxt_set_mup();
1527
            }
1528
            return 0;
1529
        }
1530

    
1531
        wrd = (insn >> 12) & 0xf;
1532
        if (gen_iwmmxt_address(s, insn))
1533
            return 1;
1534
        if (insn & ARM_CP_RW_BIT) {
1535
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1536
                tmp = gen_ld32(cpu_T[1], IS_USER(s));
1537
                tcg_gen_mov_i32(cpu_T[0], tmp);
1538
                dead_tmp(tmp);
1539
                gen_op_iwmmxt_movl_wCx_T0(wrd);
1540
            } else {
1541
                i = 1;
1542
                if (insn & (1 << 8)) {
1543
                    if (insn & (1 << 22)) {                /* WLDRD */
1544
                        tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
1545
                        i = 0;
1546
                    } else {                                /* WLDRW wRd */
1547
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
1548
                    }
1549
                } else {
1550
                    if (insn & (1 << 22)) {                /* WLDRH */
1551
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
1552
                    } else {                                /* WLDRB */
1553
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
1554
                    }
1555
                }
1556
                if (i) {
1557
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
1558
                    dead_tmp(tmp);
1559
                }
1560
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1561
            }
1562
        } else {
1563
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1564
                gen_op_iwmmxt_movl_T0_wCx(wrd);
1565
                tmp = new_tmp();
1566
                tcg_gen_mov_i32(tmp, cpu_T[0]);
1567
                gen_st32(tmp, cpu_T[1], IS_USER(s));
1568
            } else {
1569
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1570
                tmp = new_tmp();
1571
                if (insn & (1 << 8)) {
1572
                    if (insn & (1 << 22)) {                /* WSTRD */
1573
                        dead_tmp(tmp);
1574
                        tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
1575
                    } else {                                /* WSTRW wRd */
1576
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1577
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
1578
                    }
1579
                } else {
1580
                    if (insn & (1 << 22)) {                /* WSTRH */
1581
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1582
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
1583
                    } else {                                /* WSTRB */
1584
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1585
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
1586
                    }
1587
                }
1588
            }
1589
        }
1590
        return 0;
1591
    }
1592

    
1593
    if ((insn & 0x0f000000) != 0x0e000000)
1594
        return 1;
1595

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

    
2468
    return 0;
2469
}
2470

    
2471
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2472
   (ie. an undefined instruction).  */
2473
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2474
{
2475
    int acc, rd0, rd1, rdhi, rdlo;
2476

    
2477
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2478
        /* Multiply with Internal Accumulate Format */
2479
        rd0 = (insn >> 12) & 0xf;
2480
        rd1 = insn & 0xf;
2481
        acc = (insn >> 5) & 7;
2482

    
2483
        if (acc != 0)
2484
            return 1;
2485

    
2486
        switch ((insn >> 16) & 0xf) {
2487
        case 0x0:                                        /* MIA */
2488
            gen_movl_T0_reg(s, rd0);
2489
            gen_movl_T1_reg(s, rd1);
2490
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2491
            break;
2492
        case 0x8:                                        /* MIAPH */
2493
            gen_movl_T0_reg(s, rd0);
2494
            gen_movl_T1_reg(s, rd1);
2495
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2496
            break;
2497
        case 0xc:                                        /* MIABB */
2498
        case 0xd:                                        /* MIABT */
2499
        case 0xe:                                        /* MIATB */
2500
        case 0xf:                                        /* MIATT */
2501
            gen_movl_T1_reg(s, rd0);
2502
            if (insn & (1 << 16))
2503
                gen_op_shrl_T1_im(16);
2504
            gen_op_movl_T0_T1();
2505
            gen_movl_T1_reg(s, rd1);
2506
            if (insn & (1 << 17))
2507
                gen_op_shrl_T1_im(16);
2508
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2509
            break;
2510
        default:
2511
            return 1;
2512
        }
2513

    
2514
        gen_op_iwmmxt_movq_wRn_M0(acc);
2515
        return 0;
2516
    }
2517

    
2518
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2519
        /* Internal Accumulator Access Format */
2520
        rdhi = (insn >> 16) & 0xf;
2521
        rdlo = (insn >> 12) & 0xf;
2522
        acc = insn & 7;
2523

    
2524
        if (acc != 0)
2525
            return 1;
2526

    
2527
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2528
            gen_iwmmxt_movl_T0_T1_wRn(acc);
2529
            gen_movl_reg_T0(s, rdlo);
2530
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2531
            gen_op_andl_T0_T1();
2532
            gen_movl_reg_T0(s, rdhi);
2533
        } else {                                        /* MAR */
2534
            gen_movl_T0_reg(s, rdlo);
2535
            gen_movl_T1_reg(s, rdhi);
2536
            gen_iwmmxt_movl_wRn_T0_T1(acc);
2537
        }
2538
        return 0;
2539
    }
2540

    
2541
    return 1;
2542
}
2543

    
2544
/* Disassemble system coprocessor instruction.  Return nonzero if
2545
   instruction is not defined.  */
2546
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2547
{
2548
    TCGv tmp;
2549
    uint32_t rd = (insn >> 12) & 0xf;
2550
    uint32_t cp = (insn >> 8) & 0xf;
2551
    if (IS_USER(s)) {
2552
        return 1;
2553
    }
2554

    
2555
    if (insn & ARM_CP_RW_BIT) {
2556
        if (!env->cp[cp].cp_read)
2557
            return 1;
2558
        gen_set_pc_im(s->pc);
2559
        tmp = new_tmp();
2560
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2561
        store_reg(s, rd, tmp);
2562
    } else {
2563
        if (!env->cp[cp].cp_write)
2564
            return 1;
2565
        gen_set_pc_im(s->pc);
2566
        tmp = load_reg(s, rd);
2567
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2568
        dead_tmp(tmp);
2569
    }
2570
    return 0;
2571
}
2572

    
2573
static int cp15_user_ok(uint32_t insn)
2574
{
2575
    int cpn = (insn >> 16) & 0xf;
2576
    int cpm = insn & 0xf;
2577
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2578

    
2579
    if (cpn == 13 && cpm == 0) {
2580
        /* TLS register.  */
2581
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2582
            return 1;
2583
    }
2584
    if (cpn == 7) {
2585
        /* ISB, DSB, DMB.  */
2586
        if ((cpm == 5 && op == 4)
2587
                || (cpm == 10 && (op == 4 || op == 5)))
2588
            return 1;
2589
    }
2590
    return 0;
2591
}
2592

    
2593
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2594
   instruction is not defined.  */
2595
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2596
{
2597
    uint32_t rd;
2598
    TCGv tmp;
2599

    
2600
    /* M profile cores use memory mapped registers instead of cp15.  */
2601
    if (arm_feature(env, ARM_FEATURE_M))
2602
        return 1;
2603

    
2604
    if ((insn & (1 << 25)) == 0) {
2605
        if (insn & (1 << 20)) {
2606
            /* mrrc */
2607
            return 1;
2608
        }
2609
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2610
        return 0;
2611
    }
2612
    if ((insn & (1 << 4)) == 0) {
2613
        /* cdp */
2614
        return 1;
2615
    }
2616
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2617
        return 1;
2618
    }
2619
    if ((insn & 0x0fff0fff) == 0x0e070f90
2620
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2621
        /* Wait for interrupt.  */
2622
        gen_set_pc_im(s->pc);
2623
        s->is_jmp = DISAS_WFI;
2624
        return 0;
2625
    }
2626
    rd = (insn >> 12) & 0xf;
2627
    if (insn & ARM_CP_RW_BIT) {
2628
        tmp = new_tmp();
2629
        gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2630
        /* If the destination register is r15 then sets condition codes.  */
2631
        if (rd != 15)
2632
            store_reg(s, rd, tmp);
2633
        else
2634
            dead_tmp(tmp);
2635
    } else {
2636
        tmp = load_reg(s, rd);
2637
        gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2638
        dead_tmp(tmp);
2639
        /* Normally we would always end the TB here, but Linux
2640
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2641
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2642
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2643
                (insn & 0x0fff0fff) != 0x0e010f10)
2644
            gen_lookup_tb(s);
2645
    }
2646
    return 0;
2647
}
2648

    
2649
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2650
#define VFP_SREG(insn, bigbit, smallbit) \
2651
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2652
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2653
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2654
        reg = (((insn) >> (bigbit)) & 0x0f) \
2655
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2656
    } else { \
2657
        if (insn & (1 << (smallbit))) \
2658
            return 1; \
2659
        reg = ((insn) >> (bigbit)) & 0x0f; \
2660
    }} while (0)
2661

    
2662
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2663
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2664
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2665
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2666
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2667
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2668

    
2669
/* Move between integer and VFP cores.  */
2670
static TCGv gen_vfp_mrs(void)
2671
{
2672
    TCGv tmp = new_tmp();
2673
    tcg_gen_mov_i32(tmp, cpu_F0s);
2674
    return tmp;
2675
}
2676

    
2677
static void gen_vfp_msr(TCGv tmp)
2678
{
2679
    tcg_gen_mov_i32(cpu_F0s, tmp);
2680
    dead_tmp(tmp);
2681
}
2682

    
2683
static inline int
2684
vfp_enabled(CPUState * env)
2685
{
2686
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2687
}
2688

    
2689
static void gen_neon_dup_u8(TCGv var, int shift)
2690
{
2691
    TCGv tmp = new_tmp();
2692
    if (shift)
2693
        tcg_gen_shri_i32(var, var, shift);
2694
    tcg_gen_ext8u_i32(var, var);
2695
    tcg_gen_shli_i32(tmp, var, 8);
2696
    tcg_gen_or_i32(var, var, tmp);
2697
    tcg_gen_shli_i32(tmp, var, 16);
2698
    tcg_gen_or_i32(var, var, tmp);
2699
    dead_tmp(tmp);
2700
}
2701

    
2702
static void gen_neon_dup_low16(TCGv var)
2703
{
2704
    TCGv tmp = new_tmp();
2705
    tcg_gen_ext16u_i32(var, var);
2706
    tcg_gen_shli_i32(tmp, var, 16);
2707
    tcg_gen_or_i32(var, var, tmp);
2708
    dead_tmp(tmp);
2709
}
2710

    
2711
static void gen_neon_dup_high16(TCGv var)
2712
{
2713
    TCGv tmp = new_tmp();
2714
    tcg_gen_andi_i32(var, var, 0xffff0000);
2715
    tcg_gen_shri_i32(tmp, var, 16);
2716
    tcg_gen_or_i32(var, var, tmp);
2717
    dead_tmp(tmp);
2718
}
2719

    
2720
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2721
   (ie. an undefined instruction).  */
2722
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2723
{
2724
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2725
    int dp, veclen;
2726
    TCGv tmp;
2727
    TCGv tmp2;
2728

    
2729
    if (!arm_feature(env, ARM_FEATURE_VFP))
2730
        return 1;
2731

    
2732
    if (!vfp_enabled(env)) {
2733
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2734
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2735
            return 1;
2736
        rn = (insn >> 16) & 0xf;
2737
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2738
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2739
            return 1;
2740
    }
2741
    dp = ((insn & 0xf00) == 0xb00);
2742
    switch ((insn >> 24) & 0xf) {
2743
    case 0xe:
2744
        if (insn & (1 << 4)) {
2745
            /* single register transfer */
2746
            rd = (insn >> 12) & 0xf;
2747
            if (dp) {
2748
                int size;
2749
                int pass;
2750

    
2751
                VFP_DREG_N(rn, insn);
2752
                if (insn & 0xf)
2753
                    return 1;
2754
                if (insn & 0x00c00060
2755
                    && !arm_feature(env, ARM_FEATURE_NEON))
2756
                    return 1;
2757

    
2758
                pass = (insn >> 21) & 1;
2759
                if (insn & (1 << 22)) {
2760
                    size = 0;
2761
                    offset = ((insn >> 5) & 3) * 8;
2762
                } else if (insn & (1 << 5)) {
2763
                    size = 1;
2764
                    offset = (insn & (1 << 6)) ? 16 : 0;
2765
                } else {
2766
                    size = 2;
2767
                    offset = 0;
2768
                }
2769
                if (insn & ARM_CP_RW_BIT) {
2770
                    /* vfp->arm */
2771
                    tmp = neon_load_reg(rn, pass);
2772
                    switch (size) {
2773
                    case 0:
2774
                        if (offset)
2775
                            tcg_gen_shri_i32(tmp, tmp, offset);
2776
                        if (insn & (1 << 23))
2777
                            gen_uxtb(tmp);
2778
                        else
2779
                            gen_sxtb(tmp);
2780
                        break;
2781
                    case 1:
2782
                        if (insn & (1 << 23)) {
2783
                            if (offset) {
2784
                                tcg_gen_shri_i32(tmp, tmp, 16);
2785
                            } else {
2786
                                gen_uxth(tmp);
2787
                            }
2788
                        } else {
2789
                            if (offset) {
2790
                                tcg_gen_sari_i32(tmp, tmp, 16);
2791
                            } else {
2792
                                gen_sxth(tmp);
2793
                            }
2794
                        }
2795
                        break;
2796
                    case 2:
2797
                        break;
2798
                    }
2799
                    store_reg(s, rd, tmp);
2800
                } else {
2801
                    /* arm->vfp */
2802
                    tmp = load_reg(s, rd);
2803
                    if (insn & (1 << 23)) {
2804
                        /* VDUP */
2805
                        if (size == 0) {
2806
                            gen_neon_dup_u8(tmp, 0);
2807
                        } else if (size == 1) {
2808
                            gen_neon_dup_low16(tmp);
2809
                        }
2810
                        tmp2 = new_tmp();
2811
                        tcg_gen_mov_i32(tmp2, tmp);
2812
                        neon_store_reg(rn, 0, tmp2);
2813
                        neon_store_reg(rn, 0, tmp);
2814
                    } else {
2815
                        /* VMOV */
2816
                        switch (size) {
2817
                        case 0:
2818
                            tmp2 = neon_load_reg(rn, pass);
2819
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2820
                            dead_tmp(tmp2);
2821
                            break;
2822
                        case 1:
2823
                            tmp2 = neon_load_reg(rn, pass);
2824
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2825
                            dead_tmp(tmp2);
2826
                            break;
2827
                        case 2:
2828
                            break;
2829
                        }
2830
                        neon_store_reg(rn, pass, tmp);
2831
                    }
2832
                }
2833
            } else { /* !dp */
2834
                if ((insn & 0x6f) != 0x00)
2835
                    return 1;
2836
                rn = VFP_SREG_N(insn);
2837
                if (insn & ARM_CP_RW_BIT) {
2838
                    /* vfp->arm */
2839
                    if (insn & (1 << 21)) {
2840
                        /* system register */
2841
                        rn >>= 1;
2842

    
2843
                        switch (rn) {
2844
                        case ARM_VFP_FPSID:
2845
                            /* VFP2 allows access to FSID from userspace.
2846
                               VFP3 restricts all id registers to privileged
2847
                               accesses.  */
2848
                            if (IS_USER(s)
2849
                                && arm_feature(env, ARM_FEATURE_VFP3))
2850
                                return 1;
2851
                            tmp = load_cpu_field(vfp.xregs[rn]);
2852
                            break;
2853
                        case ARM_VFP_FPEXC:
2854
                            if (IS_USER(s))
2855
                                return 1;
2856
                            tmp = load_cpu_field(vfp.xregs[rn]);
2857
                            break;
2858
                        case ARM_VFP_FPINST:
2859
                        case ARM_VFP_FPINST2:
2860
                            /* Not present in VFP3.  */
2861
                            if (IS_USER(s)
2862
                                || arm_feature(env, ARM_FEATURE_VFP3))
2863
                                return 1;
2864
                            tmp = load_cpu_field(vfp.xregs[rn]);
2865
                            break;
2866
                        case ARM_VFP_FPSCR:
2867
                            if (rd == 15) {
2868
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2869
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2870
                            } else {
2871
                                tmp = new_tmp();
2872
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2873
                            }
2874
                            break;
2875
                        case ARM_VFP_MVFR0:
2876
                        case ARM_VFP_MVFR1:
2877
                            if (IS_USER(s)
2878
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2879
                                return 1;
2880
                            tmp = load_cpu_field(vfp.xregs[rn]);
2881
                            break;
2882
                        default:
2883
                            return 1;
2884
                        }
2885
                    } else {
2886
                        gen_mov_F0_vreg(0, rn);
2887
                        tmp = gen_vfp_mrs();
2888
                    }
2889
                    if (rd == 15) {
2890
                        /* Set the 4 flag bits in the CPSR.  */
2891
                        gen_set_nzcv(tmp);
2892
                        dead_tmp(tmp);
2893
                    } else {
2894
                        store_reg(s, rd, tmp);
2895
                    }
2896
                } else {
2897
                    /* arm->vfp */
2898
                    tmp = load_reg(s, rd);
2899
                    if (insn & (1 << 21)) {
2900
                        rn >>= 1;
2901
                        /* system register */
2902
                        switch (rn) {
2903
                        case ARM_VFP_FPSID:
2904
                        case ARM_VFP_MVFR0:
2905
                        case ARM_VFP_MVFR1:
2906
                            /* Writes are ignored.  */
2907
                            break;
2908
                        case ARM_VFP_FPSCR:
2909
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2910
                            dead_tmp(tmp);
2911
                            gen_lookup_tb(s);
2912
                            break;
2913
                        case ARM_VFP_FPEXC:
2914
                            if (IS_USER(s))
2915
                                return 1;
2916
                            store_cpu_field(tmp, vfp.xregs[rn]);
2917
                            gen_lookup_tb(s);
2918
                            break;
2919
                        case ARM_VFP_FPINST:
2920
                        case ARM_VFP_FPINST2:
2921
                            store_cpu_field(tmp, vfp.xregs[rn]);
2922
                            break;
2923
                        default:
2924
                            return 1;
2925
                        }
2926
                    } else {
2927
                        gen_vfp_msr(tmp);
2928
                        gen_mov_vreg_F0(0, rn);
2929
                    }
2930
                }
2931
            }
2932
        } else {
2933
            /* data processing */
2934
            /* The opcode is in bits 23, 21, 20 and 6.  */
2935
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2936
            if (dp) {
2937
                if (op == 15) {
2938
                    /* rn is opcode */
2939
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2940
                } else {
2941
                    /* rn is register number */
2942
                    VFP_DREG_N(rn, insn);
2943
                }
2944

    
2945
                if (op == 15 && (rn == 15 || rn > 17)) {
2946
                    /* Integer or single precision destination.  */
2947
                    rd = VFP_SREG_D(insn);
2948
                } else {
2949
                    VFP_DREG_D(rd, insn);
2950
                }
2951

    
2952
                if (op == 15 && (rn == 16 || rn == 17)) {
2953
                    /* Integer source.  */
2954
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2955
                } else {
2956
                    VFP_DREG_M(rm, insn);
2957
                }
2958
            } else {
2959
                rn = VFP_SREG_N(insn);
2960
                if (op == 15 && rn == 15) {
2961
                    /* Double precision destination.  */
2962
                    VFP_DREG_D(rd, insn);
2963
                } else {
2964
                    rd = VFP_SREG_D(insn);
2965
                }
2966
                rm = VFP_SREG_M(insn);
2967
            }
2968

    
2969
            veclen = env->vfp.vec_len;
2970
            if (op == 15 && rn > 3)
2971
                veclen = 0;
2972

    
2973
            /* Shut up compiler warnings.  */
2974
            delta_m = 0;
2975
            delta_d = 0;
2976
            bank_mask = 0;
2977

    
2978
            if (veclen > 0) {
2979
                if (dp)
2980
                    bank_mask = 0xc;
2981
                else
2982
                    bank_mask = 0x18;
2983

    
2984
                /* Figure out what type of vector operation this is.  */
2985
                if ((rd & bank_mask) == 0) {
2986
                    /* scalar */
2987
                    veclen = 0;
2988
                } else {
2989
                    if (dp)
2990
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2991
                    else
2992
                        delta_d = env->vfp.vec_stride + 1;
2993

    
2994
                    if ((rm & bank_mask) == 0) {
2995
                        /* mixed scalar/vector */
2996
                        delta_m = 0;
2997
                    } else {
2998
                        /* vector */
2999
                        delta_m = delta_d;
3000
                    }
3001
                }
3002
            }
3003

    
3004
            /* Load the initial operands.  */
3005
            if (op == 15) {
3006
                switch (rn) {
3007
                case 16:
3008
                case 17:
3009
                    /* Integer source */
3010
                    gen_mov_F0_vreg(0, rm);
3011
                    break;
3012
                case 8:
3013
                case 9:
3014
                    /* Compare */
3015
                    gen_mov_F0_vreg(dp, rd);
3016
                    gen_mov_F1_vreg(dp, rm);
3017
                    break;
3018
                case 10:
3019
                case 11:
3020
                    /* Compare with zero */
3021
                    gen_mov_F0_vreg(dp, rd);
3022
                    gen_vfp_F1_ld0(dp);
3023
                    break;
3024
                case 20:
3025
                case 21:
3026
                case 22:
3027
                case 23:
3028
                    /* Source and destination the same.  */
3029
                    gen_mov_F0_vreg(dp, rd);
3030
                    break;
3031
                default:
3032
                    /* One source operand.  */
3033
                    gen_mov_F0_vreg(dp, rm);
3034
                    break;
3035
                }
3036
            } else {
3037
                /* Two source operands.  */
3038
                gen_mov_F0_vreg(dp, rn);
3039
                gen_mov_F1_vreg(dp, rm);
3040
            }
3041

    
3042
            for (;;) {
3043
                /* Perform the calculation.  */
3044
                switch (op) {
3045
                case 0: /* mac: fd + (fn * fm) */
3046
                    gen_vfp_mul(dp);
3047
                    gen_mov_F1_vreg(dp, rd);
3048
                    gen_vfp_add(dp);
3049
                    break;
3050
                case 1: /* nmac: fd - (fn * fm) */
3051
                    gen_vfp_mul(dp);
3052
                    gen_vfp_neg(dp);
3053
                    gen_mov_F1_vreg(dp, rd);
3054
                    gen_vfp_add(dp);
3055
                    break;
3056
                case 2: /* msc: -fd + (fn * fm) */
3057
                    gen_vfp_mul(dp);
3058
                    gen_mov_F1_vreg(dp, rd);
3059
                    gen_vfp_sub(dp);
3060
                    break;
3061
                case 3: /* nmsc: -fd - (fn * fm)  */
3062
                    gen_vfp_mul(dp);
3063
                    gen_mov_F1_vreg(dp, rd);
3064
                    gen_vfp_add(dp);
3065
                    gen_vfp_neg(dp);
3066
                    break;
3067
                case 4: /* mul: fn * fm */
3068
                    gen_vfp_mul(dp);
3069
                    break;
3070
                case 5: /* nmul: -(fn * fm) */
3071
                    gen_vfp_mul(dp);
3072
                    gen_vfp_neg(dp);
3073
                    break;
3074
                case 6: /* add: fn + fm */
3075
                    gen_vfp_add(dp);
3076
                    break;
3077
                case 7: /* sub: fn - fm */
3078
                    gen_vfp_sub(dp);
3079
                    break;
3080
                case 8: /* div: fn / fm */
3081
                    gen_vfp_div(dp);
3082
                    break;
3083
                case 14: /* fconst */
3084
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3085
                      return 1;
3086

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

    
3206
                /* Write back the result.  */
3207
                if (op == 15 && (rn >= 8 && rn <= 11))
3208
                    ; /* Comparison, do nothing.  */
3209
                else if (op == 15 && rn > 17)
3210
                    /* Integer result.  */
3211
                    gen_mov_vreg_F0(0, rd);
3212
                else if (op == 15 && rn == 15)
3213
                    /* conversion */
3214
                    gen_mov_vreg_F0(!dp, rd);
3215
                else
3216
                    gen_mov_vreg_F0(dp, rd);
3217

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

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

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

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

    
3334
                if (insn & (1 << 24)) /* pre-decrement */
3335
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3336

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

    
3362
                    if (offset != 0)
3363
                        gen_op_addl_T1_im(offset);
3364
                    gen_movl_reg_T1(s, rn);
3365
                }
3366
            }
3367
        }
3368
        break;
3369
    default:
3370
        /* Should never happen.  */
3371
        return 1;
3372
    }
3373
    return 0;
3374
}
3375

    
3376
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3377
{
3378
    TranslationBlock *tb;
3379

    
3380
    tb = s->tb;
3381
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3382
        tcg_gen_goto_tb(n);
3383
        gen_set_pc_im(dest);
3384
        tcg_gen_exit_tb((long)tb + n);
3385
    } else {
3386
        gen_set_pc_im(dest);
3387
        tcg_gen_exit_tb(0);
3388
    }
3389
}
3390

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

    
3404
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3405
{
3406
    if (x)
3407
        tcg_gen_sari_i32(t0, t0, 16);
3408
    else
3409
        gen_sxth(t0);
3410
    if (y)
3411
        tcg_gen_sari_i32(t1, t1, 16);
3412
    else
3413
        gen_sxth(t1);
3414
    tcg_gen_mul_i32(t0, t0, t1);
3415
}
3416

    
3417
/* Return the mask of PSR bits set by a MSR instruction.  */
3418
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3419
    uint32_t mask;
3420

    
3421
    mask = 0;
3422
    if (flags & (1 << 0))
3423
        mask |= 0xff;
3424
    if (flags & (1 << 1))
3425
        mask |= 0xff00;
3426
    if (flags & (1 << 2))
3427
        mask |= 0xff0000;
3428
    if (flags & (1 << 3))
3429
        mask |= 0xff000000;
3430

    
3431
    /* Mask out undefined bits.  */
3432
    mask &= ~CPSR_RESERVED;
3433
    if (!arm_feature(env, ARM_FEATURE_V6))
3434
        mask &= ~(CPSR_E | CPSR_GE);
3435
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3436
        mask &= ~CPSR_IT;
3437
    /* Mask out execution state bits.  */
3438
    if (!spsr)
3439
        mask &= ~CPSR_EXEC;
3440
    /* Mask out privileged bits.  */
3441
    if (IS_USER(s))
3442
        mask &= CPSR_USER;
3443
    return mask;
3444
}
3445

    
3446
/* Returns nonzero if access to the PSR is not permitted.  */
3447
static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3448
{
3449
    TCGv tmp;
3450
    if (spsr) {
3451
        /* ??? This is also undefined in system mode.  */
3452
        if (IS_USER(s))
3453
            return 1;
3454

    
3455
        tmp = load_cpu_field(spsr);
3456
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3457
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3458
        tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3459
        store_cpu_field(tmp, spsr);
3460
    } else {
3461
        gen_set_cpsr(cpu_T[0], mask);
3462
    }
3463
    gen_lookup_tb(s);
3464
    return 0;
3465
}
3466

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

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

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

    
3498
static void gen_nop_hint(DisasContext *s, int val)
3499
{
3500
    switch (val) {
3501
    case 3: /* wfi */
3502
        gen_set_pc_im(s->pc);
3503
        s->is_jmp = DISAS_WFI;
3504
        break;
3505
    case 2: /* wfe */
3506
    case 4: /* sev */
3507
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3508
    default: /* nop */
3509
        break;
3510
    }
3511
}
3512

    
3513
/* These macros help make the code more readable when migrating from the
3514
   old dyngen helpers.  They should probably be removed when
3515
   T0/T1 are removed.  */
3516
#define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3517
#define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3518

    
3519
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3520

    
3521
static inline int gen_neon_add(int size)
3522
{
3523
    switch (size) {
3524
    case 0: gen_helper_neon_add_u8(CPU_T001); break;
3525
    case 1: gen_helper_neon_add_u16(CPU_T001); break;
3526
    case 2: gen_op_addl_T0_T1(); break;
3527
    default: return 1;
3528
    }
3529
    return 0;
3530
}
3531

    
3532
static inline void gen_neon_rsb(int size)
3533
{
3534
    switch (size) {
3535
    case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3536
    case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3537
    case 2: gen_op_rsbl_T0_T1(); break;
3538
    default: return;
3539
    }
3540
}
3541

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

    
3548
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3549
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3550
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3551
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3552
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3553

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

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

    
3600
static inline void
3601
gen_neon_movl_scratch_T0(int scratch)
3602
{
3603
  uint32_t offset;
3604

    
3605
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3606
  tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3607
}
3608

    
3609
static inline void
3610
gen_neon_movl_scratch_T1(int scratch)
3611
{
3612
  uint32_t offset;
3613

    
3614
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3615
  tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3616
}
3617

    
3618
static inline void
3619
gen_neon_movl_T0_scratch(int scratch)
3620
{
3621
  uint32_t offset;
3622

    
3623
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3624
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3625
}
3626

    
3627
static inline void
3628
gen_neon_movl_T1_scratch(int scratch)
3629
{
3630
  uint32_t offset;
3631

    
3632
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3633
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3634
}
3635

    
3636
static inline void gen_neon_get_scalar(int size, int reg)
3637
{
3638
    if (size == 1) {
3639
        NEON_GET_REG(T0, reg >> 1, reg & 1);
3640
    } else {
3641
        NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3642
        if (reg & 1)
3643
            gen_neon_dup_low16(cpu_T[0]);
3644
        else
3645
            gen_neon_dup_high16(cpu_T[0]);
3646
    }
3647
}
3648

    
3649
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3650
{
3651
    int n;
3652

    
3653
    for (n = 0; n < q + 1; n += 2) {
3654
        NEON_GET_REG(T0, reg, n);
3655
        NEON_GET_REG(T0, reg, n + n);
3656
        switch (size) {
3657
        case 0: gen_helper_neon_unzip_u8(); break;
3658
        case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same.  */
3659
        case 2: /* no-op */; break;
3660
        default: abort();
3661
        }
3662
        gen_neon_movl_scratch_T0(tmp + n);
3663
        gen_neon_movl_scratch_T1(tmp + n + 1);
3664
    }
3665
}
3666

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

    
3685
/* Translate a NEON load/store element instruction.  Return nonzero if the
3686
   instruction is invalid.  */
3687
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3688
{
3689
    int rd, rn, rm;
3690
    int op;
3691
    int nregs;
3692
    int interleave;
3693
    int stride;
3694
    int size;
3695
    int reg;
3696
    int pass;
3697
    int load;
3698
    int shift;
3699
    int n;
3700
    TCGv tmp;
3701
    TCGv tmp2;
3702

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

    
3891
        base = load_reg(s, rn);
3892
        if (rm == 13) {
3893
            tcg_gen_addi_i32(base, base, stride);
3894
        } else {
3895
            TCGv index;
3896
            index = load_reg(s, rm);
3897
            tcg_gen_add_i32(base, base, index);
3898
            dead_tmp(index);
3899
        }
3900
        store_reg(s, rn, base);
3901
    }
3902
    return 0;
3903
}
3904

    
3905
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3906
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3907
{
3908
    tcg_gen_and_i32(t, t, c);
3909
    tcg_gen_bic_i32(f, f, c);
3910
    tcg_gen_or_i32(dest, t, f);
3911
}
3912

    
3913
static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
3914
{
3915
    switch (size) {
3916
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
3917
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
3918
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3919
    default: abort();
3920
    }
3921
}
3922

    
3923
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
3924
{
3925
    switch (size) {
3926
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3927
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3928
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3929
    default: abort();
3930
    }
3931
}
3932

    
3933
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
3934
{
3935
    switch (size) {
3936
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3937
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3938
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3939
    default: abort();
3940
    }
3941
}
3942

    
3943
static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
3944
                                         int q, int u)
3945
{
3946
    if (q) {
3947
        if (u) {
3948
            switch (size) {
3949
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3950
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3951
            default: abort();
3952
            }
3953
        } else {
3954
            switch (size) {
3955
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3956
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3957
            default: abort();
3958
            }
3959
        }
3960
    } else {
3961
        if (u) {
3962
            switch (size) {
3963
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3964
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3965
            default: abort();
3966
            }
3967
        } else {
3968
            switch (size) {
3969
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3970
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3971
            default: abort();
3972
            }
3973
        }
3974
    }
3975
}
3976

    
3977
static inline void gen_neon_widen(TCGv dest, TCGv src, int size, int u)
3978
{
3979
    if (u) {
3980
        switch (size) {
3981
        case 0: gen_helper_neon_widen_u8(dest, src); break;
3982
        case 1: gen_helper_neon_widen_u16(dest, src); break;
3983
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
3984
        default: abort();
3985
        }
3986
    } else {
3987
        switch (size) {
3988
        case 0: gen_helper_neon_widen_s8(dest, src); break;
3989
        case 1: gen_helper_neon_widen_s16(dest, src); break;
3990
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
3991
        default: abort();
3992
        }
3993
    }
3994
    dead_tmp(src);
3995
}
3996

    
3997
static inline void gen_neon_addl(int size)
3998
{
3999
    switch (size) {
4000
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4001
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4002
    case 2: tcg_gen_add_i64(CPU_V001); break;
4003
    default: abort();
4004
    }
4005
}
4006

    
4007
static inline void gen_neon_subl(int size)
4008
{
4009
    switch (size) {
4010
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4011
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4012
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4013
    default: abort();
4014
    }
4015
}
4016

    
4017
static inline void gen_neon_negl(TCGv var, int size)
4018
{
4019
    switch (size) {
4020
    case 0: gen_helper_neon_negl_u16(var, var); break;
4021
    case 1: gen_helper_neon_negl_u32(var, var); break;
4022
    case 2: gen_helper_neon_negl_u64(var, var); break;
4023
    default: abort();
4024
    }
4025
}
4026

    
4027
static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4028
{
4029
    switch (size) {
4030
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4031
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4032
    default: abort();
4033
    }
4034
}
4035

    
4036
static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4037
{
4038
    TCGv tmp;
4039

    
4040
    switch ((size << 1) | u) {
4041
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4042
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4043
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4044
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4045
    case 4:
4046
        tmp = gen_muls_i64_i32(a, b);
4047
        tcg_gen_mov_i64(dest, tmp);
4048
        break;
4049
    case 5:
4050
        tmp = gen_mulu_i64_i32(a, b);
4051
        tcg_gen_mov_i64(dest, tmp);
4052
        break;
4053
    default: abort();
4054
    }
4055
    if (size < 2) {
4056
        dead_tmp(b);
4057
        dead_tmp(a);
4058
    }
4059
}
4060

    
4061
/* Translate a NEON data processing instruction.  Return nonzero if the
4062
   instruction is invalid.
4063
   We process data in a mixture of 32-bit and 64-bit chunks.
4064
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4065

    
4066
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4067
{
4068
    int op;
4069
    int q;
4070
    int rd, rn, rm;
4071
    int size;
4072
    int shift;
4073
    int pass;
4074
    int count;
4075
    int pairwise;
4076
    int u;
4077
    int n;
4078
    uint32_t imm;
4079
    TCGv tmp;
4080
    TCGv tmp2;
4081
    TCGv tmp3;
4082

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

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

    
4451
        } /* for pass */
4452
        if (pairwise && rd == rm) {
4453
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4454
                gen_neon_movl_T0_scratch(pass);
4455
                NEON_SET_REG(T0, rd, pass);
4456
            }
4457
        }
4458
        /* End of 3 register same size operations.  */
4459
    } else if (insn & (1 << 4)) {
4460
        if ((insn & 0x00380080) != 0) {
4461
            /* Two registers and shift.  */
4462
            op = (insn >> 8) & 0xf;
4463
            if (insn & (1 << 7)) {
4464
                /* 64-bit shift.   */
4465
                size = 3;
4466
            } else {
4467
                size = 2;
4468
                while ((insn & (1 << (size + 19))) == 0)
4469
                    size--;
4470
            }
4471
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4472
            /* To avoid excessive dumplication of ops we implement shift
4473
               by immediate using the variable shift operations.  */
4474
            if (op < 8) {
4475
                /* Shift by immediate:
4476
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4477
                /* Right shifts are encoded as N - shift, where N is the
4478
                   element size in bits.  */
4479
                if (op <= 4)
4480
                    shift = shift - (1 << (size + 3));
4481
                if (size == 3) {
4482
                    count = q + 1;
4483
                } else {
4484
                    count = q ? 4: 2;
4485
                }
4486
                switch (size) {
4487
                case 0:
4488
                    imm = (uint8_t) shift;
4489
                    imm |= imm << 8;
4490
                    imm |= imm << 16;
4491
                    break;
4492
                case 1:
4493
                    imm = (uint16_t) shift;
4494
                    imm |= imm << 16;
4495
                    break;
4496
                case 2:
4497
                case 3:
4498
                    imm = shift;
4499
                    break;
4500
                default:
4501
                    abort();
4502
                }
4503

    
4504
                for (pass = 0; pass < count; pass++) {
4505
                    if (size == 3) {
4506
                        neon_load_reg64(cpu_V0, rm + pass);
4507
                        tcg_gen_movi_i64(cpu_V1, imm);
4508
                        switch (op) {
4509
                        case 0:  /* VSHR */
4510
                        case 1:  /* VSRA */
4511
                            if (u)
4512
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4513
                            else
4514
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4515
                            break;
4516
                        case 2: /* VRSHR */
4517
                        case 3: /* VRSRA */
4518
                            if (u)
4519
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4520
                            else
4521
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4522
                            break;
4523
                        case 4: /* VSRI */
4524
                            if (!u)
4525
                                return 1;
4526
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4527
                            break;
4528
                        case 5: /* VSHL, VSLI */
4529
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4530
                            break;
4531
                        case 6: /* VQSHL */
4532
                            if (u)
4533
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4534
                            else
4535
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4536
                            break;
4537
                        case 7: /* VQSHLU */
4538
                            gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
4539
                            break;
4540
                        }
4541
                        if (op == 1 || op == 3) {
4542
                            /* Accumulate.  */
4543
                            neon_load_reg64(cpu_V0, rd + pass);
4544
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
4545
                        } else if (op == 4 || (op == 5 && u)) {
4546
                            /* Insert */
4547
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4548
                        }
4549
                        neon_store_reg64(cpu_V0, rd + pass);
4550
                    } else { /* size < 3 */
4551
                        /* Operands in T0 and T1.  */
4552
                        gen_op_movl_T1_im(imm);
4553
                        NEON_GET_REG(T0, rm, pass);
4554
                        switch (op) {
4555
                        case 0:  /* VSHR */
4556
                        case 1:  /* VSRA */
4557
                            GEN_NEON_INTEGER_OP(shl);
4558
                            break;
4559
                        case 2: /* VRSHR */
4560
                        case 3: /* VRSRA */
4561
                            GEN_NEON_INTEGER_OP(rshl);
4562
                            break;
4563
                        case 4: /* VSRI */
4564
                            if (!u)
4565
                                return 1;
4566
                            GEN_NEON_INTEGER_OP(shl);
4567
                            break;
4568
                        case 5: /* VSHL, VSLI */
4569
                            switch (size) {
4570
                            case 0: gen_helper_neon_shl_u8(CPU_T001); break;
4571
                            case 1: gen_helper_neon_shl_u16(CPU_T001); break;
4572
                            case 2: gen_helper_neon_shl_u32(CPU_T001); break;
4573
                            default: return 1;
4574
                            }
4575
                            break;
4576
                        case 6: /* VQSHL */
4577
                            GEN_NEON_INTEGER_OP_ENV(qshl);
4578
                            break;
4579
                        case 7: /* VQSHLU */
4580
                            switch (size) {
4581
                            case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
4582
                            case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
4583
                            case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
4584
                            default: return 1;
4585
                            }
4586
                            break;
4587
                        }
4588

    
4589
                        if (op == 1 || op == 3) {
4590
                            /* Accumulate.  */
4591
                            NEON_GET_REG(T1, rd, pass);
4592
                            gen_neon_add(size);
4593
                        } else if (op == 4 || (op == 5 && u)) {
4594
                            /* Insert */
4595
                            switch (size) {
4596
                            case 0:
4597
                                if (op == 4)
4598
                                    imm = 0xff >> -shift;
4599
                                else
4600
                                    imm = (uint8_t)(0xff << shift);
4601
                                imm |= imm << 8;
4602
                                imm |= imm << 16;
4603
                                break;
4604
                            case 1:
4605
                                if (op == 4)
4606
                                    imm = 0xffff >> -shift;
4607
                                else
4608
                                    imm = (uint16_t)(0xffff << shift);
4609
                                imm |= imm << 16;
4610
                                break;
4611
                            case 2:
4612
                                if (op == 4)
4613
                                    imm = 0xffffffffu >> -shift;
4614
                                else
4615
                                    imm = 0xffffffffu << shift;
4616
                                break;
4617
                            default:
4618
                                abort();
4619
                            }
4620
                            tmp = neon_load_reg(rd, pass);
4621
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
4622
                            tcg_gen_andi_i32(tmp, tmp, ~imm);
4623
                            tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
4624
                        }
4625
                        NEON_SET_REG(T0, rd, pass);
4626
                    }
4627
                } /* for pass */
4628
            } else if (op < 10) {
4629
                /* Shift by immediate and narrow:
4630
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4631
                shift = shift - (1 << (size + 3));
4632
                size++;
4633
                switch (size) {
4634
                case 1:
4635
                    imm = (uint16_t)shift;
4636
                    imm |= imm << 16;
4637
                    tmp2 = tcg_const_i32(imm);
4638
                    break;
4639
                case 2:
4640
                    imm = (uint32_t)shift;
4641
                    tmp2 = tcg_const_i32(imm);
4642
                case 3:
4643
                    tmp2 = tcg_const_i64(shift);
4644
                    break;
4645
                default:
4646
                    abort();
4647
                }
4648

    
4649
                for (pass = 0; pass < 2; pass++) {
4650
                    if (size == 3) {
4651
                        neon_load_reg64(cpu_V0, rm + pass);
4652
                        if (q) {
4653
                          if (u)
4654
                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp2);
4655
                          else
4656
                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp2);
4657
                        } else {
4658
                          if (u)
4659
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp2);
4660
                          else
4661
                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp2);
4662
                        }
4663
                    } else {
4664
                        tmp = neon_load_reg(rm + pass, 0);
4665
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4666
                        tcg_gen_extu_i32_i64(cpu_V0, tmp);
4667
                        dead_tmp(tmp);
4668
                        tmp = neon_load_reg(rm + pass, 1);
4669
                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);
4670
                        tcg_gen_extu_i32_i64(cpu_V1, tmp);
4671
                        dead_tmp(tmp);
4672
                        tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
4673
                        tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
4674
                    }
4675
                    tmp = new_tmp();
4676
                    if (op == 8 && !u) {
4677
                        gen_neon_narrow(size - 1, tmp, cpu_V0);
4678
                    } else {
4679
                        if (op == 8)
4680
                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
4681
                        else
4682
                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
4683
                    }
4684
                    if (pass == 0) {
4685
                        tmp2 = tmp;
4686
                    } else {
4687
                        neon_store_reg(rd, 0, tmp2);
4688
                        neon_store_reg(rd, 1, tmp);
4689
                    }
4690
                } /* for pass */
4691
            } else if (op == 10) {
4692
                /* VSHLL */
4693
                if (q || size == 3)
4694
                    return 1;
4695
                tmp = neon_load_reg(rm, 0);
4696
                tmp2 = neon_load_reg(rm, 1);
4697
                for (pass = 0; pass < 2; pass++) {
4698
                    if (pass == 1)
4699
                        tmp = tmp2;
4700

    
4701
                    gen_neon_widen(cpu_V0, tmp, size, u);
4702

    
4703
                    if (shift != 0) {
4704
                        /* The shift is less than the width of the source
4705
                           type, so we can just shift the whole register.  */
4706
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
4707
                        if (size < 2 || !u) {
4708
                            uint64_t imm64;
4709
                            if (size == 0) {
4710
                                imm = (0xffu >> (8 - shift));
4711
                                imm |= imm << 16;
4712
                            } else {
4713
                                imm = 0xffff >> (16 - shift);
4714
                            }
4715
                            imm64 = imm | (((uint64_t)imm) << 32);
4716
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
4717
                        }
4718
                    }
4719
                    neon_store_reg64(cpu_V0, rd + pass);
4720
                }
4721
            } else if (op == 15 || op == 16) {
4722
                /* VCVT fixed-point.  */
4723
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4724
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4725
                    if (op & 1) {
4726
                        if (u)
4727
                            gen_vfp_ulto(0, shift);
4728
                        else
4729
                            gen_vfp_slto(0, shift);
4730
                    } else {
4731
                        if (u)
4732
                            gen_vfp_toul(0, shift);
4733
                        else
4734
                            gen_vfp_tosl(0, shift);
4735
                    }
4736
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4737
                }
4738
            } else {
4739
                return 1;
4740
            }
4741
        } else { /* (insn & 0x00380080) == 0 */
4742
            int invert;
4743

    
4744
            op = (insn >> 8) & 0xf;
4745
            /* One register and immediate.  */
4746
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4747
            invert = (insn & (1 << 5)) != 0;
4748
            switch (op) {
4749
            case 0: case 1:
4750
                /* no-op */
4751
                break;
4752
            case 2: case 3:
4753
                imm <<= 8;
4754
                break;
4755
            case 4: case 5:
4756
                imm <<= 16;
4757
                break;
4758
            case 6: case 7:
4759
                imm <<= 24;
4760
                break;
4761
            case 8: case 9:
4762
                imm |= imm << 16;
4763
                break;
4764
            case 10: case 11:
4765
                imm = (imm << 8) | (imm << 24);
4766
                break;
4767
            case 12:
4768
                imm = (imm < 8) | 0xff;
4769
                break;
4770
            case 13:
4771
                imm = (imm << 16) | 0xffff;
4772
                break;
4773
            case 14:
4774
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4775
                if (invert)
4776
                    imm = ~imm;
4777
                break;
4778
            case 15:
4779
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4780
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4781
                break;
4782
            }
4783
            if (invert)
4784
                imm = ~imm;
4785

    
4786
            if (op != 14 || !invert)
4787
                gen_op_movl_T1_im(imm);
4788

    
4789
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4790
                if (op & 1 && op < 12) {
4791
                    tmp = neon_load_reg(rd, pass);
4792
                    if (invert) {
4793
                        /* The immediate value has already been inverted, so
4794
                           BIC becomes AND.  */
4795
                        tcg_gen_andi_i32(tmp, tmp, imm);
4796
                    } else {
4797
                        tcg_gen_ori_i32(tmp, tmp, imm);
4798
                    }
4799
                } else {
4800
                    /* VMOV, VMVN.  */
4801
                    tmp = new_tmp();
4802
                    if (op == 14 && invert) {
4803
                        uint32_t val;
4804
                        val = 0;
4805
                        for (n = 0; n < 4; n++) {
4806
                            if (imm & (1 << (n + (pass & 1) * 4)))
4807
                                val |= 0xff << (n * 8);
4808
                        }
4809
                        tcg_gen_movi_i32(tmp, val);
4810
                    } else {
4811
                        tcg_gen_movi_i32(tmp, imm);
4812
                    }
4813
                }
4814
                neon_store_reg(rd, pass, tmp);
4815
            }
4816
        }
4817
    } else { /* (insn & 0x00800010 == 0x00800010) */
4818
        if (size != 3) {
4819
            op = (insn >> 8) & 0xf;
4820
            if ((insn & (1 << 6)) == 0) {
4821
                /* Three registers of different lengths.  */
4822
                int src1_wide;
4823
                int src2_wide;
4824
                int prewiden;
4825
                /* prewiden, src1_wide, src2_wide */
4826
                static const int neon_3reg_wide[16][3] = {
4827
                    {1, 0, 0}, /* VADDL */
4828
                    {1, 1, 0}, /* VADDW */
4829
                    {1, 0, 0}, /* VSUBL */
4830
                    {1, 1, 0}, /* VSUBW */
4831
                    {0, 1, 1}, /* VADDHN */
4832
                    {0, 0, 0}, /* VABAL */
4833
                    {0, 1, 1}, /* VSUBHN */
4834
                    {0, 0, 0}, /* VABDL */
4835
                    {0, 0, 0}, /* VMLAL */
4836
                    {0, 0, 0}, /* VQDMLAL */
4837
                    {0, 0, 0}, /* VMLSL */
4838
                    {0, 0, 0}, /* VQDMLSL */
4839
                    {0, 0, 0}, /* Integer VMULL */
4840
                    {0, 0, 0}, /* VQDMULL */
4841
                    {0, 0, 0}  /* Polynomial VMULL */
4842
                };
4843

    
4844
                prewiden = neon_3reg_wide[op][0];
4845
                src1_wide = neon_3reg_wide[op][1];
4846
                src2_wide = neon_3reg_wide[op][2];
4847

    
4848
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4849
                    return 1;
4850

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

    
4932
                    default: /* 15 is RESERVED.  */
4933
                        return 1;
4934
                    }
4935
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4936
                        /* Accumulate.  */
4937
                        if (op == 10 || op == 11) {
4938
                            gen_neon_negl(cpu_V0, size);
4939
                        }
4940

    
4941
                        if (op != 13) {
4942
                            neon_load_reg64(cpu_V1, rd + pass);
4943
                        }
4944

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

    
5076
                    gen_neon_get_scalar(size, rm);
5077
                    NEON_GET_REG(T1, rn, 1);
5078

    
5079
                    for (pass = 0; pass < 2; pass++) {
5080
                        if (pass == 0) {
5081
                            tmp = neon_load_reg(rn, 0);
5082
                        } else {
5083
                            tmp = new_tmp();
5084
                            tcg_gen_mov_i32(tmp, cpu_T[1]);
5085
                        }
5086
                        tmp2 = new_tmp();
5087
                        tcg_gen_mov_i32(tmp2, cpu_T[0]);
5088
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5089
                        if (op == 6 || op == 7) {
5090
                            gen_neon_negl(cpu_V0, size);
5091
                        }
5092
                        if (op != 11) {
5093
                            neon_load_reg64(cpu_V1, rd + pass);
5094
                        }
5095
                        switch (op) {
5096
                        case 2: case 6:
5097
                            gen_neon_addl(size);
5098
                            break;
5099
                        case 3: case 7:
5100
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5101
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5102
                            break;
5103
                        case 10:
5104
                            /* no-op */
5105
                            break;
5106
                        case 11:
5107
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5108
                            break;
5109
                        default:
5110
                            abort();
5111
                        }
5112
                        neon_store_reg64(cpu_V0, rd + pass);
5113
                    }
5114
                    break;
5115
                default: /* 14 and 15 are RESERVED */
5116
                    return 1;
5117
                }
5118
            }
5119
        } else { /* size == 3 */
5120
            if (!u) {
5121
                /* Extract.  */
5122
                imm = (insn >> 8) & 0xf;
5123
                count = q + 1;
5124

    
5125
                if (imm > 7 && !q)
5126
                    return 1;
5127

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

    
5554
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5555
{
5556
    int cpnum;
5557

    
5558
    cpnum = (insn >> 8) & 0xf;
5559
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5560
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5561
        return 1;
5562

    
5563
    switch (cpnum) {
5564
      case 0:
5565
      case 1:
5566
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5567
            return disas_iwmmxt_insn(env, s, insn);
5568
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5569
            return disas_dsp_insn(env, s, insn);
5570
        }
5571
        return 1;
5572
    case 10:
5573
    case 11:
5574
        return disas_vfp_insn (env, s, insn);
5575
    case 15:
5576
        return disas_cp15_insn (env, s, insn);
5577
    default:
5578
        /* Unknown coprocessor.  See if the board has hooked it.  */
5579
        return disas_cp_insn (env, s, insn);
5580
    }
5581
}
5582

    
5583

    
5584
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5585
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5586
{
5587
    TCGv tmp;
5588
    tmp = new_tmp();
5589
    tcg_gen_trunc_i64_i32(tmp, val);
5590
    store_reg(s, rlow, tmp);
5591
    tmp = new_tmp();
5592
    tcg_gen_shri_i64(val, val, 32);
5593
    tcg_gen_trunc_i64_i32(tmp, val);
5594
    store_reg(s, rhigh, tmp);
5595
}
5596

    
5597
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5598
static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5599
{
5600
    TCGv tmp;
5601
    TCGv tmp2;
5602

    
5603
    /* Load 64-bit value rd:rn.  */
5604
    tmp = tcg_temp_new(TCG_TYPE_I64);
5605
    tmp2 = load_reg(s, rlow);
5606
    tcg_gen_extu_i32_i64(tmp, tmp2);
5607
    dead_tmp(tmp2);
5608
    tcg_gen_add_i64(val, val, tmp);
5609
}
5610

    
5611
/* load and add a 64-bit value from a register pair.  */
5612
static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5613
{
5614
    TCGv tmp;
5615
    TCGv tmp2;
5616

    
5617
    /* Load 64-bit value rd:rn.  */
5618
    tmp = tcg_temp_new(TCG_TYPE_I64);
5619
    tmp2 = load_reg(s, rhigh);
5620
    tcg_gen_extu_i32_i64(tmp, tmp2);
5621
    dead_tmp(tmp2);
5622
    tcg_gen_shli_i64(tmp, tmp, 32);
5623
    tcg_gen_add_i64(val, val, tmp);
5624

    
5625
    tmp2 = load_reg(s, rlow);
5626
    tcg_gen_extu_i32_i64(tmp, tmp2);
5627
    dead_tmp(tmp2);
5628
    tcg_gen_add_i64(val, val, tmp);
5629
}
5630

    
5631
/* Set N and Z flags from a 64-bit value.  */
5632
static void gen_logicq_cc(TCGv val)
5633
{
5634
    TCGv tmp = new_tmp();
5635
    gen_helper_logicq_cc(tmp, val);
5636
    gen_logic_CC(tmp);
5637
    dead_tmp(tmp);
5638
}
5639

    
5640
static void disas_arm_insn(CPUState * env, DisasContext *s)
5641
{
5642
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5643
    TCGv tmp;
5644
    TCGv tmp2;
5645
    TCGv tmp3;
5646
    TCGv addr;
5647

    
5648
    insn = ldl_code(s->pc);
5649
    s->pc += 4;
5650

    
5651
    /* M variants do not implement ARM mode.  */
5652
    if (IS_M(env))
5653
        goto illegal_op;
5654
    cond = insn >> 28;
5655
    if (cond == 0xf){
5656
        /* Unconditional instructions.  */
5657
        if (((insn >> 25) & 7) == 1) {
5658
            /* NEON Data processing.  */
5659
            if (!arm_feature(env, ARM_FEATURE_NEON))
5660
                goto illegal_op;
5661

    
5662
            if (disas_neon_data_insn(env, s, insn))
5663
                goto illegal_op;
5664
            return;
5665
        }
5666
        if ((insn & 0x0f100000) == 0x04000000) {
5667
            /* NEON load/store.  */
5668
            if (!arm_feature(env, ARM_FEATURE_NEON))
5669
                goto illegal_op;
5670

    
5671
            if (disas_neon_ls_insn(env, s, insn))
5672
                goto illegal_op;
5673
            return;
5674
        }
5675
        if ((insn & 0x0d70f000) == 0x0550f000)
5676
            return; /* PLD */
5677
        else if ((insn & 0x0ffffdff) == 0x01010000) {
5678
            ARCH(6);
5679
            /* setend */
5680
            if (insn & (1 << 9)) {
5681
                /* BE8 mode not implemented.  */
5682
                goto illegal_op;
5683
            }
5684
            return;
5685
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
5686
            switch ((insn >> 4) & 0xf) {
5687
            case 1: /* clrex */
5688
                ARCH(6K);
5689
                gen_helper_clrex(cpu_env);
5690
                return;
5691
            case 4: /* dsb */
5692
            case 5: /* dmb */
5693
            case 6: /* isb */
5694
                ARCH(7);
5695
                /* We don't emulate caches so these are a no-op.  */
5696
                return;
5697
            default:
5698
                goto illegal_op;
5699
            }
5700
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5701
            /* srs */
5702
            uint32_t offset;
5703
            if (IS_USER(s))
5704
                goto illegal_op;
5705
            ARCH(6);
5706
            op1 = (insn & 0x1f);
5707
            if (op1 == (env->uncached_cpsr & CPSR_M)) {
5708
                addr = load_reg(s, 13);
5709
            } else {
5710
                addr = new_tmp();
5711
                gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5712
            }
5713
            i = (insn >> 23) & 3;
5714
            switch (i) {
5715
            case 0: offset = -4; break; /* DA */
5716
            case 1: offset = -8; break; /* DB */
5717
            case 2: offset = 0; break; /* IA */
5718
            case 3: offset = 4; break; /* IB */
5719
            default: abort();
5720
            }
5721
            if (offset)
5722
                tcg_gen_addi_i32(addr, addr, offset);
5723
            tmp = load_reg(s, 14);
5724
            gen_st32(tmp, addr, 0);
5725
            tmp = new_tmp();
5726
            gen_helper_cpsr_read(tmp);
5727
            tcg_gen_addi_i32(addr, addr, 4);
5728
            gen_st32(tmp, addr, 0);
5729
            if (insn & (1 << 21)) {
5730
                /* Base writeback.  */
5731
                switch (i) {
5732
                case 0: offset = -8; break;
5733
                case 1: offset = -4; break;
5734
                case 2: offset = 4; break;
5735
                case 3: offset = 0; break;
5736
                default: abort();
5737
                }
5738
                if (offset)
5739
                    tcg_gen_addi_i32(addr, tmp, offset);
5740
                if (op1 == (env->uncached_cpsr & CPSR_M)) {
5741
                    gen_movl_reg_T1(s, 13);
5742
                } else {
5743
                    gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5744
                }
5745
            } else {
5746
                dead_tmp(addr);
5747
            }
5748
        } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5749
            /* rfe */
5750
            uint32_t offset;
5751
            if (IS_USER(s))
5752
                goto illegal_op;
5753
            ARCH(6);
5754
            rn = (insn >> 16) & 0xf;
5755
            addr = load_reg(s, rn);
5756
            i = (insn >> 23) & 3;
5757
            switch (i) {
5758
            case 0: offset = -4; break; /* DA */
5759
            case 1: offset = -8; break; /* DB */
5760
            case 2: offset = 0; break; /* IA */
5761
            case 3: offset = 4; break; /* IB */
5762
            default: abort();
5763
            }
5764
            if (offset)
5765
                tcg_gen_addi_i32(addr, addr, offset);
5766
            /* Load PC into tmp and CPSR into tmp2.  */
5767
            tmp = gen_ld32(addr, 0);
5768
            tcg_gen_addi_i32(addr, addr, 4);
5769
            tmp2 = gen_ld32(addr, 0);
5770
            if (insn & (1 << 21)) {
5771
                /* Base writeback.  */
5772
                switch (i) {
5773
                case 0: offset = -8; break;
5774
                case 1: offset = -4; break;
5775
                case 2: offset = 4; break;
5776
                case 3: offset = 0; break;
5777
                default: abort();
5778
                }
5779
                if (offset)
5780
                    tcg_gen_addi_i32(addr, addr, offset);
5781
                store_reg(s, rn, addr);
5782
            } else {
5783
                dead_tmp(addr);
5784
            }
5785
            gen_rfe(s, tmp, tmp2);
5786
        } else if ((insn & 0x0e000000) == 0x0a000000) {
5787
            /* branch link and change to thumb (blx <offset>) */
5788
            int32_t offset;
5789

    
5790
            val = (uint32_t)s->pc;
5791
            tmp = new_tmp();
5792
            tcg_gen_movi_i32(tmp, val);
5793
            store_reg(s, 14, tmp);
5794
            /* Sign-extend the 24-bit offset */
5795
            offset = (((int32_t)insn) << 8) >> 8;
5796
            /* offset * 4 + bit24 * 2 + (thumb bit) */
5797
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
5798
            /* pipeline offset */
5799
            val += 4;
5800
            gen_bx_im(s, val);
5801
            return;
5802
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
5803
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5804
                /* iWMMXt register transfer.  */
5805
                if (env->cp15.c15_cpar & (1 << 1))
5806
                    if (!disas_iwmmxt_insn(env, s, insn))
5807
                        return;
5808
            }
5809
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
5810
            /* Coprocessor double register transfer.  */
5811
        } else if ((insn & 0x0f000010) == 0x0e000010) {
5812
            /* Additional coprocessor register transfer.  */
5813
        } else if ((insn & 0x0ff10020) == 0x01000000) {
5814
            uint32_t mask;
5815
            uint32_t val;
5816
            /* cps (privileged) */
5817
            if (IS_USER(s))
5818
                return;
5819
            mask = val = 0;
5820
            if (insn & (1 << 19)) {
5821
                if (insn & (1 << 8))
5822
                    mask |= CPSR_A;
5823
                if (insn & (1 << 7))
5824
                    mask |= CPSR_I;
5825
                if (insn & (1 << 6))
5826
                    mask |= CPSR_F;
5827
                if (insn & (1 << 18))
5828
                    val |= mask;
5829
            }
5830
            if (insn & (1 << 17)) {
5831
                mask |= CPSR_M;
5832
                val |= (insn & 0x1f);
5833
            }
5834
            if (mask) {
5835
                gen_op_movl_T0_im(val);
5836
                gen_set_psr_T0(s, mask, 0);
5837
            }
5838
            return;
5839
        }
5840
        goto illegal_op;
5841
    }
5842
    if (cond != 0xe) {
5843
        /* if not always execute, we generate a conditional jump to
5844
           next instruction */
5845
        s->condlabel = gen_new_label();
5846
        gen_test_cc(cond ^ 1, s->condlabel);
5847
        s->condjmp = 1;
5848
    }
5849
    if ((insn & 0x0f900000) == 0x03000000) {
5850
        if ((insn & (1 << 21)) == 0) {
5851
            ARCH(6T2);
5852
            rd = (insn >> 12) & 0xf;
5853
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5854
            if ((insn & (1 << 22)) == 0) {
5855
                /* MOVW */
5856
                tmp = new_tmp();
5857
                tcg_gen_movi_i32(tmp, val);
5858
            } else {
5859
                /* MOVT */
5860
                tmp = load_reg(s, rd);
5861
                tcg_gen_ext16u_i32(tmp, tmp);
5862
                tcg_gen_ori_i32(tmp, tmp, val << 16);
5863
            }
5864
            store_reg(s, rd, tmp);
5865
        } else {
5866
            if (((insn >> 12) & 0xf) != 0xf)
5867
                goto illegal_op;
5868
            if (((insn >> 16) & 0xf) == 0) {
5869
                gen_nop_hint(s, insn & 0xff);
5870
            } else {
5871
                /* CPSR = immediate */
5872
                val = insn & 0xff;
5873
                shift = ((insn >> 8) & 0xf) * 2;
5874
                if (shift)
5875
                    val = (val >> shift) | (val << (32 - shift));
5876
                gen_op_movl_T0_im(val);
5877
                i = ((insn & (1 << 22)) != 0);
5878
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5879
                    goto illegal_op;
5880
            }
5881
        }
5882
    } else if ((insn & 0x0f900000) == 0x01000000
5883
               && (insn & 0x00000090) != 0x00000090) {
5884
        /* miscellaneous instructions */
5885
        op1 = (insn >> 21) & 3;
5886
        sh = (insn >> 4) & 0xf;
5887
        rm = insn & 0xf;
5888
        switch (sh) {
5889
        case 0x0: /* move program status register */
5890
            if (op1 & 1) {
5891
                /* PSR = reg */
5892
                gen_movl_T0_reg(s, rm);
5893
                i = ((op1 & 2) != 0);
5894
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5895
                    goto illegal_op;
5896
            } else {
5897
                /* reg = PSR */
5898
                rd = (insn >> 12) & 0xf;
5899
                if (op1 & 2) {
5900
                    if (IS_USER(s))
5901
                        goto illegal_op;
5902
                    tmp = load_cpu_field(spsr);
5903
                } else {
5904
                    tmp = new_tmp();
5905
                    gen_helper_cpsr_read(tmp);
5906
                }
5907
                store_reg(s, rd, tmp);
5908
            }
5909
            break;
5910
        case 0x1:
5911
            if (op1 == 1) {
5912
                /* branch/exchange thumb (bx).  */
5913
                tmp = load_reg(s, rm);
5914
                gen_bx(s, tmp);
5915
            } else if (op1 == 3) {
5916
                /* clz */
5917
                rd = (insn >> 12) & 0xf;
5918
                tmp = load_reg(s, rm);
5919
                gen_helper_clz(tmp, tmp);
5920
                store_reg(s, rd, tmp);
5921
            } else {
5922
                goto illegal_op;
5923
            }
5924
            break;
5925
        case 0x2:
5926
            if (op1 == 1) {
5927
                ARCH(5J); /* bxj */
5928
                /* Trivial implementation equivalent to bx.  */
5929
                tmp = load_reg(s, rm);
5930
                gen_bx(s, tmp);
5931
            } else {
5932
                goto illegal_op;
5933
            }
5934
            break;
5935
        case 0x3:
5936
            if (op1 != 1)
5937
              goto illegal_op;
5938

    
5939
            /* branch link/exchange thumb (blx) */
5940
            tmp = load_reg(s, rm);
5941
            tmp2 = new_tmp();
5942
            tcg_gen_movi_i32(tmp2, s->pc);
5943
            store_reg(s, 14, tmp2);
5944
            gen_bx(s, tmp);
5945
            break;
5946
        case 0x5: /* saturating add/subtract */
5947
            rd = (insn >> 12) & 0xf;
5948
            rn = (insn >> 16) & 0xf;
5949
            tmp = load_reg(s, rm);
5950
            tmp2 = load_reg(s, rn);
5951
            if (op1 & 2)
5952
                gen_helper_double_saturate(tmp2, tmp2);
5953
            if (op1 & 1)
5954
                gen_helper_sub_saturate(tmp, tmp, tmp2);
5955
            else
5956
                gen_helper_add_saturate(tmp, tmp, tmp2);
5957
            dead_tmp(tmp2);
5958
            store_reg(s, rd, tmp);
5959
            break;
5960
        case 7: /* bkpt */
5961
            gen_set_condexec(s);
5962
            gen_set_pc_im(s->pc - 4);
5963
            gen_exception(EXCP_BKPT);
5964
            s->is_jmp = DISAS_JUMP;
5965
            break;
5966
        case 0x8: /* signed multiply */
5967
        case 0xa:
5968
        case 0xc:
5969
        case 0xe:
5970
            rs = (insn >> 8) & 0xf;
5971
            rn = (insn >> 12) & 0xf;
5972
            rd = (insn >> 16) & 0xf;
5973
            if (op1 == 1) {
5974
                /* (32 * 16) >> 16 */
5975
                tmp = load_reg(s, rm);
5976
                tmp2 = load_reg(s, rs);
5977
                if (sh & 4)
5978
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
5979
                else
5980
                    gen_sxth(tmp2);
5981
                tmp2 = gen_muls_i64_i32(tmp, tmp2);
5982
                tcg_gen_shri_i64(tmp2, tmp2, 16);
5983
                tmp = new_tmp();
5984
                tcg_gen_trunc_i64_i32(tmp, tmp2);
5985
                if ((sh & 2) == 0) {
5986
                    tmp2 = load_reg(s, rn);
5987
                    gen_helper_add_setq(tmp, tmp, tmp2);
5988
                    dead_tmp(tmp2);
5989
                }
5990
                store_reg(s, rd, tmp);
5991
            } else {
5992
                /* 16 * 16 */
5993
                tmp = load_reg(s, rm);
5994
                tmp2 = load_reg(s, rs);
5995
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
5996
                dead_tmp(tmp2);
5997
                if (op1 == 2) {
5998
                    tmp2 = tcg_temp_new(TCG_TYPE_I64);
5999
                    tcg_gen_ext_i32_i64(tmp2, tmp);
6000
                    dead_tmp(tmp);
6001
                    gen_addq(s, tmp2, rn, rd);
6002
                    gen_storeq_reg(s, rn, rd, tmp2);
6003
                } else {
6004
                    if (op1 == 0) {
6005
                        tmp2 = load_reg(s, rn);
6006
                        gen_helper_add_setq(tmp, tmp, tmp2);
6007
                        dead_tmp(tmp2);
6008
                    }
6009
                    store_reg(s, rd, tmp);
6010
                }
6011
            }
6012
            break;
6013
        default:
6014
            goto illegal_op;
6015
        }
6016
    } else if (((insn & 0x0e000000) == 0 &&
6017
                (insn & 0x00000090) != 0x90) ||
6018
               ((insn & 0x0e000000) == (1 << 25))) {
6019
        int set_cc, logic_cc, shiftop;
6020

    
6021
        op1 = (insn >> 21) & 0xf;
6022
        set_cc = (insn >> 20) & 1;
6023
        logic_cc = table_logic_cc[op1] & set_cc;
6024

    
6025
        /* data processing instruction */
6026
        if (insn & (1 << 25)) {
6027
            /* immediate operand */
6028
            val = insn & 0xff;
6029
            shift = ((insn >> 8) & 0xf) * 2;
6030
            if (shift)
6031
                val = (val >> shift) | (val << (32 - shift));
6032
            gen_op_movl_T1_im(val);
6033
            if (logic_cc && shift)
6034
                gen_set_CF_bit31(cpu_T[1]);
6035
        } else {
6036
            /* register */
6037
            rm = (insn) & 0xf;
6038
            gen_movl_T1_reg(s, rm);
6039
            shiftop = (insn >> 5) & 3;
6040
            if (!(insn & (1 << 4))) {
6041
                shift = (insn >> 7) & 0x1f;
6042
                gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
6043
            } else {
6044
                rs = (insn >> 8) & 0xf;
6045
                tmp = load_reg(s, rs);
6046
                gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc);
6047
            }
6048
        }
6049
        if (op1 != 0x0f && op1 != 0x0d) {
6050
            rn = (insn >> 16) & 0xf;
6051
            gen_movl_T0_reg(s, rn);
6052
        }
6053
        rd = (insn >> 12) & 0xf;
6054
        switch(op1) {
6055
        case 0x00:
6056
            gen_op_andl_T0_T1();
6057
            gen_movl_reg_T0(s, rd);
6058
            if (logic_cc)
6059
                gen_op_logic_T0_cc();
6060
            break;
6061
        case 0x01:
6062
            gen_op_xorl_T0_T1();
6063
            gen_movl_reg_T0(s, rd);
6064
            if (logic_cc)
6065
                gen_op_logic_T0_cc();
6066
            break;
6067
        case 0x02:
6068
            if (set_cc && rd == 15) {
6069
                /* SUBS r15, ... is used for exception return.  */
6070
                if (IS_USER(s))
6071
                    goto illegal_op;
6072
                gen_op_subl_T0_T1_cc();
6073
                gen_exception_return(s);
6074
            } else {
6075
                if (set_cc)
6076
                    gen_op_subl_T0_T1_cc();
6077
                else
6078
                    gen_op_subl_T0_T1();
6079
                gen_movl_reg_T0(s, rd);
6080
            }
6081
            break;
6082
        case 0x03:
6083
            if (set_cc)
6084
                gen_op_rsbl_T0_T1_cc();
6085
            else
6086
                gen_op_rsbl_T0_T1();
6087
            gen_movl_reg_T0(s, rd);
6088
            break;
6089
        case 0x04:
6090
            if (set_cc)
6091
                gen_op_addl_T0_T1_cc();
6092
            else
6093
                gen_op_addl_T0_T1();
6094
            gen_movl_reg_T0(s, rd);
6095
            break;
6096
        case 0x05:
6097
            if (set_cc)
6098
                gen_op_adcl_T0_T1_cc();
6099
            else
6100
                gen_adc_T0_T1();
6101
            gen_movl_reg_T0(s, rd);
6102
            break;
6103
        case 0x06:
6104
            if (set_cc)
6105
                gen_op_sbcl_T0_T1_cc();
6106
            else
6107
                gen_sbc_T0_T1();
6108
            gen_movl_reg_T0(s, rd);
6109
            break;
6110
        case 0x07:
6111
            if (set_cc)
6112
                gen_op_rscl_T0_T1_cc();
6113
            else
6114
                gen_rsc_T0_T1();
6115
            gen_movl_reg_T0(s, rd);
6116
            break;
6117
        case 0x08:
6118
            if (set_cc) {
6119
                gen_op_andl_T0_T1();
6120
                gen_op_logic_T0_cc();
6121
            }
6122
            break;
6123
        case 0x09:
6124
            if (set_cc) {
6125
                gen_op_xorl_T0_T1();
6126
                gen_op_logic_T0_cc();
6127
            }
6128
            break;
6129
        case 0x0a:
6130
            if (set_cc) {
6131
                gen_op_subl_T0_T1_cc();
6132
            }
6133
            break;
6134
        case 0x0b:
6135
            if (set_cc) {
6136
                gen_op_addl_T0_T1_cc();
6137
            }
6138
            break;
6139
        case 0x0c:
6140
            gen_op_orl_T0_T1();
6141
            gen_movl_reg_T0(s, rd);
6142
            if (logic_cc)
6143
                gen_op_logic_T0_cc();
6144
            break;
6145
        case 0x0d:
6146
            if (logic_cc && rd == 15) {
6147
                /* MOVS r15, ... is used for exception return.  */
6148
                if (IS_USER(s))
6149
                    goto illegal_op;
6150
                gen_op_movl_T0_T1();
6151
                gen_exception_return(s);
6152
            } else {
6153
                gen_movl_reg_T1(s, rd);
6154
                if (logic_cc)
6155
                    gen_op_logic_T1_cc();
6156
            }
6157
            break;
6158
        case 0x0e:
6159
            gen_op_bicl_T0_T1();
6160
            gen_movl_reg_T0(s, rd);
6161
            if (logic_cc)
6162
                gen_op_logic_T0_cc();
6163
            break;
6164
        default:
6165
        case 0x0f:
6166
            gen_op_notl_T1();
6167
            gen_movl_reg_T1(s, rd);
6168
            if (logic_cc)
6169
                gen_op_logic_T1_cc();
6170
            break;
6171
        }
6172
    } else {
6173
        /* other instructions */
6174
        op1 = (insn >> 24) & 0xf;
6175
        switch(op1) {
6176
        case 0x0:
6177
        case 0x1:
6178
            /* multiplies, extra load/stores */
6179
            sh = (insn >> 5) & 3;
6180
            if (sh == 0) {
6181
                if (op1 == 0x0) {
6182
                    rd = (insn >> 16) & 0xf;
6183
                    rn = (insn >> 12) & 0xf;
6184
                    rs = (insn >> 8) & 0xf;
6185
                    rm = (insn) & 0xf;
6186
                    op1 = (insn >> 20) & 0xf;
6187
                    switch (op1) {
6188
                    case 0: case 1: case 2: case 3: case 6:
6189
                        /* 32 bit mul */
6190
                        tmp = load_reg(s, rs);
6191
                        tmp2 = load_reg(s, rm);
6192
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
6193
                        dead_tmp(tmp2);
6194
                        if (insn & (1 << 22)) {
6195
                            /* Subtract (mls) */
6196
                            ARCH(6T2);
6197
                            tmp2 = load_reg(s, rn);
6198
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
6199
                            dead_tmp(tmp2);
6200
                        } else if (insn & (1 << 21)) {
6201
                            /* Add */
6202
                            tmp2 = load_reg(s, rn);
6203
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6204
                            dead_tmp(tmp2);
6205
                        }
6206
                        if (insn & (1 << 20))
6207
                            gen_logic_CC(tmp);
6208
                        store_reg(s, rd, tmp);
6209
                        break;
6210
                    default:
6211
                        /* 64 bit mul */
6212
                        tmp = load_reg(s, rs);
6213
                        tmp2 = load_reg(s, rm);
6214
                        if (insn & (1 << 22))
6215
                            tmp = gen_muls_i64_i32(tmp, tmp2);
6216
                        else
6217
                            tmp = gen_mulu_i64_i32(tmp, tmp2);
6218
                        if (insn & (1 << 21)) /* mult accumulate */
6219
                            gen_addq(s, tmp, rn, rd);
6220
                        if (!(insn & (1 << 23))) { /* double accumulate */
6221
                            ARCH(6);
6222
                            gen_addq_lo(s, tmp, rn);
6223
                            gen_addq_lo(s, tmp, rd);
6224
                        }
6225
                        if (insn & (1 << 20))
6226
                            gen_logicq_cc(tmp);
6227
                        gen_storeq_reg(s, rn, rd, tmp);
6228
                        break;
6229
                    }
6230
                } else {
6231
                    rn = (insn >> 16) & 0xf;
6232
                    rd = (insn >> 12) & 0xf;
6233
                    if (insn & (1 << 23)) {
6234
                        /* load/store exclusive */
6235
                        gen_movl_T1_reg(s, rn);
6236
                        addr = cpu_T[1];
6237
                        if (insn & (1 << 20)) {
6238
                            gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6239
                            tmp = gen_ld32(addr, IS_USER(s));
6240
                            store_reg(s, rd, tmp);
6241
                        } else {
6242
                            int label = gen_new_label();
6243
                            rm = insn & 0xf;
6244
                            gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6245
                            tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
6246
                                                0, label);
6247
                            tmp = load_reg(s,rm);
6248
                            gen_st32(tmp, cpu_T[1], IS_USER(s));
6249
                            gen_set_label(label);
6250
                            gen_movl_reg_T0(s, rd);
6251
                        }
6252
                    } else {
6253
                        /* SWP instruction */
6254
                        rm = (insn) & 0xf;
6255

    
6256
                        /* ??? This is not really atomic.  However we know
6257
                           we never have multiple CPUs running in parallel,
6258
                           so it is good enough.  */
6259
                        addr = load_reg(s, rn);
6260
                        tmp = load_reg(s, rm);
6261
                        if (insn & (1 << 22)) {
6262
                            tmp2 = gen_ld8u(addr, IS_USER(s));
6263
                            gen_st8(tmp, addr, IS_USER(s));
6264
                        } else {
6265
                            tmp2 = gen_ld32(addr, IS_USER(s));
6266
                            gen_st32(tmp, addr, IS_USER(s));
6267
                        }
6268
                        dead_tmp(addr);
6269
                        store_reg(s, rd, tmp2);
6270
                    }
6271
                }
6272
            } else {
6273
                int address_offset;
6274
                int load;
6275
                /* Misc load/store */
6276
                rn = (insn >> 16) & 0xf;
6277
                rd = (insn >> 12) & 0xf;
6278
                addr = load_reg(s, rn);
6279
                if (insn & (1 << 24))
6280
                    gen_add_datah_offset(s, insn, 0, addr);
6281
                address_offset = 0;
6282
                if (insn & (1 << 20)) {
6283
                    /* load */
6284
                    switch(sh) {
6285
                    case 1:
6286
                        tmp = gen_ld16u(addr, IS_USER(s));
6287
                        break;
6288
                    case 2:
6289
                        tmp = gen_ld8s(addr, IS_USER(s));
6290
                        break;
6291
                    default:
6292
                    case 3:
6293
                        tmp = gen_ld16s(addr, IS_USER(s));
6294
                        break;
6295
                    }
6296
                    load = 1;
6297
                } else if (sh & 2) {
6298
                    /* doubleword */
6299
                    if (sh & 1) {
6300
                        /* store */
6301
                        tmp = load_reg(s, rd);
6302
                        gen_st32(tmp, addr, IS_USER(s));
6303
                        tcg_gen_addi_i32(addr, addr, 4);
6304
                        tmp = load_reg(s, rd + 1);
6305
                        gen_st32(tmp, addr, IS_USER(s));
6306
                        load = 0;
6307
                    } else {
6308
                        /* load */
6309
                        tmp = gen_ld32(addr, IS_USER(s));
6310
                        store_reg(s, rd, tmp);
6311
                        tcg_gen_addi_i32(addr, addr, 4);
6312
                        tmp = gen_ld32(addr, IS_USER(s));
6313
                        rd++;
6314
                        load = 1;
6315
                    }
6316
                    address_offset = -4;
6317
                } else {
6318
                    /* store */
6319
                    tmp = load_reg(s, rd);
6320
                    gen_st16(tmp, addr, IS_USER(s));
6321
                    load = 0;
6322
                }
6323
                /* Perform base writeback before the loaded value to
6324
                   ensure correct behavior with overlapping index registers.
6325
                   ldrd with base writeback is is undefined if the
6326
                   destination and index registers overlap.  */
6327
                if (!(insn & (1 << 24))) {
6328
                    gen_add_datah_offset(s, insn, address_offset, addr);
6329
                    store_reg(s, rn, addr);
6330
                } else if (insn & (1 << 21)) {
6331
                    if (address_offset)
6332
                        tcg_gen_addi_i32(addr, addr, address_offset);
6333
                    store_reg(s, rn, addr);
6334
                } else {
6335
                    dead_tmp(addr);
6336
                }
6337
                if (load) {
6338
                    /* Complete the load.  */
6339
                    store_reg(s, rd, tmp);
6340
                }
6341
            }
6342
            break;
6343
        case 0x4:
6344
        case 0x5:
6345
            goto do_ldst;
6346
        case 0x6:
6347
        case 0x7:
6348
            if (insn & (1 << 4)) {
6349
                ARCH(6);
6350
                /* Armv6 Media instructions.  */
6351
                rm = insn & 0xf;
6352
                rn = (insn >> 16) & 0xf;
6353
                rd = (insn >> 12) & 0xf;
6354
                rs = (insn >> 8) & 0xf;
6355
                switch ((insn >> 23) & 3) {
6356
                case 0: /* Parallel add/subtract.  */
6357
                    op1 = (insn >> 20) & 7;
6358
                    tmp = load_reg(s, rn);
6359
                    tmp2 = load_reg(s, rm);
6360
                    sh = (insn >> 5) & 7;
6361
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6362
                        goto illegal_op;
6363
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6364
                    dead_tmp(tmp2);
6365
                    store_reg(s, rd, tmp);
6366
                    break;
6367
                case 1:
6368
                    if ((insn & 0x00700020) == 0) {
6369
                        /* Halfword pack.  */
6370
                        tmp = load_reg(s, rn);
6371
                        tmp2 = load_reg(s, rm);
6372
                        shift = (insn >> 7) & 0x1f;
6373
                        if (insn & (1 << 6)) {
6374
                            /* pkhtb */
6375
                            if (shift == 0)
6376
                                shift = 31;
6377
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
6378
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6379
                            tcg_gen_ext16u_i32(tmp2, tmp2);
6380
                        } else {
6381
                            /* pkhbt */
6382
                            if (shift)
6383
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
6384
                            tcg_gen_ext16u_i32(tmp, tmp);
6385
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6386
                        }
6387
                        tcg_gen_or_i32(tmp, tmp, tmp2);
6388
                        dead_tmp(tmp2);
6389
                        store_reg(s, rd, tmp);
6390
                    } else if ((insn & 0x00200020) == 0x00200000) {
6391
                        /* [us]sat */
6392
                        tmp = load_reg(s, rm);
6393
                        shift = (insn >> 7) & 0x1f;
6394
                        if (insn & (1 << 6)) {
6395
                            if (shift == 0)
6396
                                shift = 31;
6397
                            tcg_gen_sari_i32(tmp, tmp, shift);
6398
                        } else {
6399
                            tcg_gen_shli_i32(tmp, tmp, shift);
6400
                        }
6401
                        sh = (insn >> 16) & 0x1f;
6402
                        if (sh != 0) {
6403
                            if (insn & (1 << 22))
6404
                                gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6405
                            else
6406
                                gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6407
                        }
6408
                        store_reg(s, rd, tmp);
6409
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
6410
                        /* [us]sat16 */
6411
                        tmp = load_reg(s, rm);
6412
                        sh = (insn >> 16) & 0x1f;
6413
                        if (sh != 0) {
6414
                            if (insn & (1 << 22))
6415
                                gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6416
                            else
6417
                                gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6418
                        }
6419
                        store_reg(s, rd, tmp);
6420
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6421
                        /* Select bytes.  */
6422
                        tmp = load_reg(s, rn);
6423
                        tmp2 = load_reg(s, rm);
6424
                        tmp3 = new_tmp();
6425
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6426
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6427
                        dead_tmp(tmp3);
6428
                        dead_tmp(tmp2);
6429
                        store_reg(s, rd, tmp);
6430
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6431
                        tmp = load_reg(s, rm);
6432
                        shift = (insn >> 10) & 3;
6433
                        /* ??? In many cases it's not neccessary to do a
6434
                           rotate, a shift is sufficient.  */
6435
                        if (shift != 0)
6436
                            tcg_gen_rori_i32(tmp, tmp, shift * 8);
6437
                        op1 = (insn >> 20) & 7;
6438
                        switch (op1) {
6439
                        case 0: gen_sxtb16(tmp);  break;
6440
                        case 2: gen_sxtb(tmp);    break;
6441
                        case 3: gen_sxth(tmp);    break;
6442
                        case 4: gen_uxtb16(tmp);  break;
6443
                        case 6: gen_uxtb(tmp);    break;
6444
                        case 7: gen_uxth(tmp);    break;
6445
                        default: goto illegal_op;
6446
                        }
6447
                        if (rn != 15) {
6448
                            tmp2 = load_reg(s, rn);
6449
                            if ((op1 & 3) == 0) {
6450
                                gen_add16(tmp, tmp2);
6451
                            } else {
6452
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6453
                                dead_tmp(tmp2);
6454
                            }
6455
                        }
6456
                        store_reg(s, rd, tmp);
6457
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6458
                        /* rev */
6459
                        tmp = load_reg(s, rm);
6460
                        if (insn & (1 << 22)) {
6461
                            if (insn & (1 << 7)) {
6462
                                gen_revsh(tmp);
6463
                            } else {
6464
                                ARCH(6T2);
6465
                                gen_helper_rbit(tmp, tmp);
6466
                            }
6467
                        } else {
6468
                            if (insn & (1 << 7))
6469
                                gen_rev16(tmp);
6470
                            else
6471
                                tcg_gen_bswap_i32(tmp, tmp);
6472
                        }
6473
                        store_reg(s, rd, tmp);
6474
                    } else {
6475
                        goto illegal_op;
6476
                    }
6477
                    break;
6478
                case 2: /* Multiplies (Type 3).  */
6479
                    tmp = load_reg(s, rm);
6480
                    tmp2 = load_reg(s, rs);
6481
                    if (insn & (1 << 20)) {
6482
                        /* Signed multiply most significant [accumulate].  */
6483
                        tmp2 = gen_muls_i64_i32(tmp, tmp2);
6484
                        if (insn & (1 << 5))
6485
                            tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
6486
                        tcg_gen_shri_i64(tmp2, tmp2, 32);
6487
                        tmp = new_tmp();
6488
                        tcg_gen_trunc_i64_i32(tmp, tmp2);
6489
                        if (rn != 15) {
6490
                            tmp2 = load_reg(s, rn);
6491
                            if (insn & (1 << 6)) {
6492
                                tcg_gen_sub_i32(tmp, tmp, tmp2);
6493
                            } else {
6494
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6495
                            }
6496
                            dead_tmp(tmp2);
6497
                        }
6498
                        store_reg(s, rd, tmp);
6499
                    } else {
6500
                        if (insn & (1 << 5))
6501
                            gen_swap_half(tmp2);
6502
                        gen_smul_dual(tmp, tmp2);
6503
                        /* This addition cannot overflow.  */
6504
                        if (insn & (1 << 6)) {
6505
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
6506
                        } else {
6507
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6508
                        }
6509
                        dead_tmp(tmp2);
6510
                        if (insn & (1 << 22)) {
6511
                            /* smlald, smlsld */
6512
                            tmp2 = tcg_temp_new(TCG_TYPE_I64);
6513
                            tcg_gen_ext_i32_i64(tmp2, tmp);
6514
                            dead_tmp(tmp);
6515
                            gen_addq(s, tmp2, rd, rn);
6516
                            gen_storeq_reg(s, rd, rn, tmp2);
6517
                        } else {
6518
                            /* smuad, smusd, smlad, smlsd */
6519
                            if (rd != 15)
6520
                              {
6521
                                tmp2 = load_reg(s, rd);
6522
                                gen_helper_add_setq(tmp, tmp, tmp2);
6523
                                dead_tmp(tmp2);
6524
                              }
6525
                            store_reg(s, rn, tmp);
6526
                        }
6527
                    }
6528
                    break;
6529
                case 3:
6530
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6531
                    switch (op1) {
6532
                    case 0: /* Unsigned sum of absolute differences.  */
6533
                        ARCH(6);
6534
                        tmp = load_reg(s, rm);
6535
                        tmp2 = load_reg(s, rs);
6536
                        gen_helper_usad8(tmp, tmp, tmp2);
6537
                        dead_tmp(tmp2);
6538
                        if (rn != 15) {
6539
                            tmp2 = load_reg(s, rn);
6540
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6541
                            dead_tmp(tmp2);
6542
                        }
6543
                        store_reg(s, rd, tmp);
6544
                        break;
6545
                    case 0x20: case 0x24: case 0x28: case 0x2c:
6546
                        /* Bitfield insert/clear.  */
6547
                        ARCH(6T2);
6548
                        shift = (insn >> 7) & 0x1f;
6549
                        i = (insn >> 16) & 0x1f;
6550
                        i = i + 1 - shift;
6551
                        if (rm == 15) {
6552
                            tmp = new_tmp();
6553
                            tcg_gen_movi_i32(tmp, 0);
6554
                        } else {
6555
                            tmp = load_reg(s, rm);
6556
                        }
6557
                        if (i != 32) {
6558
                            tmp2 = load_reg(s, rd);
6559
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
6560
                            dead_tmp(tmp2);
6561
                        }
6562
                        store_reg(s, rd, tmp);
6563
                        break;
6564
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6565
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6566
                        tmp = load_reg(s, rm);
6567
                        shift = (insn >> 7) & 0x1f;
6568
                        i = ((insn >> 16) & 0x1f) + 1;
6569
                        if (shift + i > 32)
6570
                            goto illegal_op;
6571
                        if (i < 32) {
6572
                            if (op1 & 0x20) {
6573
                                gen_ubfx(tmp, shift, (1u << i) - 1);
6574
                            } else {
6575
                                gen_sbfx(tmp, shift, i);
6576
                            }
6577
                        }
6578
                        store_reg(s, rd, tmp);
6579
                        break;
6580
                    default:
6581
                        goto illegal_op;
6582
                    }
6583
                    break;
6584
                }
6585
                break;
6586
            }
6587
        do_ldst:
6588
            /* Check for undefined extension instructions
6589
             * per the ARM Bible IE:
6590
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
6591
             */
6592
            sh = (0xf << 20) | (0xf << 4);
6593
            if (op1 == 0x7 && ((insn & sh) == sh))
6594
            {
6595
                goto illegal_op;
6596
            }
6597
            /* load/store byte/word */
6598
            rn = (insn >> 16) & 0xf;
6599
            rd = (insn >> 12) & 0xf;
6600
            tmp2 = load_reg(s, rn);
6601
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6602
            if (insn & (1 << 24))
6603
                gen_add_data_offset(s, insn, tmp2);
6604
            if (insn & (1 << 20)) {
6605
                /* load */
6606
                s->is_mem = 1;
6607
                if (insn & (1 << 22)) {
6608
                    tmp = gen_ld8u(tmp2, i);
6609
                } else {
6610
                    tmp = gen_ld32(tmp2, i);
6611
                }
6612
            } else {
6613
                /* store */
6614
                tmp = load_reg(s, rd);
6615
                if (insn & (1 << 22))
6616
                    gen_st8(tmp, tmp2, i);
6617
                else
6618
                    gen_st32(tmp, tmp2, i);
6619
            }
6620
            if (!(insn & (1 << 24))) {
6621
                gen_add_data_offset(s, insn, tmp2);
6622
                store_reg(s, rn, tmp2);
6623
            } else if (insn & (1 << 21)) {
6624
                store_reg(s, rn, tmp2);
6625
            } else {
6626
                dead_tmp(tmp2);
6627
            }
6628
            if (insn & (1 << 20)) {
6629
                /* Complete the load.  */
6630
                if (rd == 15)
6631
                    gen_bx(s, tmp);
6632
                else
6633
                    store_reg(s, rd, tmp);
6634
            }
6635
            break;
6636
        case 0x08:
6637
        case 0x09:
6638
            {
6639
                int j, n, user, loaded_base;
6640
                TCGv loaded_var;
6641
                /* load/store multiple words */
6642
                /* XXX: store correct base if write back */
6643
                user = 0;
6644
                if (insn & (1 << 22)) {
6645
                    if (IS_USER(s))
6646
                        goto illegal_op; /* only usable in supervisor mode */
6647

    
6648
                    if ((insn & (1 << 15)) == 0)
6649
                        user = 1;
6650
                }
6651
                rn = (insn >> 16) & 0xf;
6652
                addr = load_reg(s, rn);
6653

    
6654
                /* compute total size */
6655
                loaded_base = 0;
6656
                TCGV_UNUSED(loaded_var);
6657
                n = 0;
6658
                for(i=0;i<16;i++) {
6659
                    if (insn & (1 << i))
6660
                        n++;
6661
                }
6662
                /* XXX: test invalid n == 0 case ? */
6663
                if (insn & (1 << 23)) {
6664
                    if (insn & (1 << 24)) {
6665
                        /* pre increment */
6666
                        tcg_gen_addi_i32(addr, addr, 4);
6667
                    } else {
6668
                        /* post increment */
6669
                    }
6670
                } else {
6671
                    if (insn & (1 << 24)) {
6672
                        /* pre decrement */
6673
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
6674
                    } else {
6675
                        /* post decrement */
6676
                        if (n != 1)
6677
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6678
                    }
6679
                }
6680
                j = 0;
6681
                for(i=0;i<16;i++) {
6682
                    if (insn & (1 << i)) {
6683
                        if (insn & (1 << 20)) {
6684
                            /* load */
6685
                            tmp = gen_ld32(addr, IS_USER(s));
6686
                            if (i == 15) {
6687
                                gen_bx(s, tmp);
6688
                            } else if (user) {
6689
                                gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6690
                                dead_tmp(tmp);
6691
                            } else if (i == rn) {
6692
                                loaded_var = tmp;
6693
                                loaded_base = 1;
6694
                            } else {
6695
                                store_reg(s, i, tmp);
6696
                            }
6697
                        } else {
6698
                            /* store */
6699
                            if (i == 15) {
6700
                                /* special case: r15 = PC + 8 */
6701
                                val = (long)s->pc + 4;
6702
                                tmp = new_tmp();
6703
                                tcg_gen_movi_i32(tmp, val);
6704
                            } else if (user) {
6705
                                tmp = new_tmp();
6706
                                gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6707
                            } else {
6708
                                tmp = load_reg(s, i);
6709
                            }
6710
                            gen_st32(tmp, addr, IS_USER(s));
6711
                        }
6712
                        j++;
6713
                        /* no need to add after the last transfer */
6714
                        if (j != n)
6715
                            tcg_gen_addi_i32(addr, addr, 4);
6716
                    }
6717
                }
6718
                if (insn & (1 << 21)) {
6719
                    /* write back */
6720
                    if (insn & (1 << 23)) {
6721
                        if (insn & (1 << 24)) {
6722
                            /* pre increment */
6723
                        } else {
6724
                            /* post increment */
6725
                            tcg_gen_addi_i32(addr, addr, 4);
6726
                        }
6727
                    } else {
6728
                        if (insn & (1 << 24)) {
6729
                            /* pre decrement */
6730
                            if (n != 1)
6731
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6732
                        } else {
6733
                            /* post decrement */
6734
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
6735
                        }
6736
                    }
6737
                    store_reg(s, rn, addr);
6738
                } else {
6739
                    dead_tmp(addr);
6740
                }
6741
                if (loaded_base) {
6742
                    store_reg(s, rn, loaded_var);
6743
                }
6744
                if ((insn & (1 << 22)) && !user) {
6745
                    /* Restore CPSR from SPSR.  */
6746
                    tmp = load_cpu_field(spsr);
6747
                    gen_set_cpsr(tmp, 0xffffffff);
6748
                    dead_tmp(tmp);
6749
                    s->is_jmp = DISAS_UPDATE;
6750
                }
6751
            }
6752
            break;
6753
        case 0xa:
6754
        case 0xb:
6755
            {
6756
                int32_t offset;
6757

    
6758
                /* branch (and link) */
6759
                val = (int32_t)s->pc;
6760
                if (insn & (1 << 24)) {
6761
                    tmp = new_tmp();
6762
                    tcg_gen_movi_i32(tmp, val);
6763
                    store_reg(s, 14, tmp);
6764
                }
6765
                offset = (((int32_t)insn << 8) >> 8);
6766
                val += (offset << 2) + 4;
6767
                gen_jmp(s, val);
6768
            }
6769
            break;
6770
        case 0xc:
6771
        case 0xd:
6772
        case 0xe:
6773
            /* Coprocessor.  */
6774
            if (disas_coproc_insn(env, s, insn))
6775
                goto illegal_op;
6776
            break;
6777
        case 0xf:
6778
            /* swi */
6779
            gen_set_pc_im(s->pc);
6780
            s->is_jmp = DISAS_SWI;
6781
            break;
6782
        default:
6783
        illegal_op:
6784
            gen_set_condexec(s);
6785
            gen_set_pc_im(s->pc - 4);
6786
            gen_exception(EXCP_UDEF);
6787
            s->is_jmp = DISAS_JUMP;
6788
            break;
6789
        }
6790
    }
6791
}
6792

    
6793
/* Return true if this is a Thumb-2 logical op.  */
6794
static int
6795
thumb2_logic_op(int op)
6796
{
6797
    return (op < 8);
6798
}
6799

    
6800
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6801
   then set condition code flags based on the result of the operation.
6802
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6803
   to the high bit of T1.
6804
   Returns zero if the opcode is valid.  */
6805

    
6806
static int
6807
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6808
{
6809
    int logic_cc;
6810

    
6811
    logic_cc = 0;
6812
    switch (op) {
6813
    case 0: /* and */
6814
        gen_op_andl_T0_T1();
6815
        logic_cc = conds;
6816
        break;
6817
    case 1: /* bic */
6818
        gen_op_bicl_T0_T1();
6819
        logic_cc = conds;
6820
        break;
6821
    case 2: /* orr */
6822
        gen_op_orl_T0_T1();
6823
        logic_cc = conds;
6824
        break;
6825
    case 3: /* orn */
6826
        gen_op_notl_T1();
6827
        gen_op_orl_T0_T1();
6828
        logic_cc = conds;
6829
        break;
6830
    case 4: /* eor */
6831
        gen_op_xorl_T0_T1();
6832
        logic_cc = conds;
6833
        break;
6834
    case 8: /* add */
6835
        if (conds)
6836
            gen_op_addl_T0_T1_cc();
6837
        else
6838
            gen_op_addl_T0_T1();
6839
        break;
6840
    case 10: /* adc */
6841
        if (conds)
6842
            gen_op_adcl_T0_T1_cc();
6843
        else
6844
            gen_adc_T0_T1();
6845
        break;
6846
    case 11: /* sbc */
6847
        if (conds)
6848
            gen_op_sbcl_T0_T1_cc();
6849
        else
6850
            gen_sbc_T0_T1();
6851
        break;
6852
    case 13: /* sub */
6853
        if (conds)
6854
            gen_op_subl_T0_T1_cc();
6855
        else
6856
            gen_op_subl_T0_T1();
6857
        break;
6858
    case 14: /* rsb */
6859
        if (conds)
6860
            gen_op_rsbl_T0_T1_cc();
6861
        else
6862
            gen_op_rsbl_T0_T1();
6863
        break;
6864
    default: /* 5, 6, 7, 9, 12, 15. */
6865
        return 1;
6866
    }
6867
    if (logic_cc) {
6868
        gen_op_logic_T0_cc();
6869
        if (shifter_out)
6870
            gen_set_CF_bit31(cpu_T[1]);
6871
    }
6872
    return 0;
6873
}
6874

    
6875
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
6876
   is not legal.  */
6877
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6878
{
6879
    uint32_t insn, imm, shift, offset;
6880
    uint32_t rd, rn, rm, rs;
6881
    TCGv tmp;
6882
    TCGv tmp2;
6883
    TCGv tmp3;
6884
    TCGv addr;
6885
    int op;
6886
    int shiftop;
6887
    int conds;
6888
    int logic_cc;
6889

    
6890
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6891
          || arm_feature (env, ARM_FEATURE_M))) {
6892
        /* Thumb-1 cores may need to treat bl and blx as a pair of
6893
           16-bit instructions to get correct prefetch abort behavior.  */
6894
        insn = insn_hw1;
6895
        if ((insn & (1 << 12)) == 0) {
6896
            /* Second half of blx.  */
6897
            offset = ((insn & 0x7ff) << 1);
6898
            tmp = load_reg(s, 14);
6899
            tcg_gen_addi_i32(tmp, tmp, offset);
6900
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6901

    
6902
            tmp2 = new_tmp();
6903
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6904
            store_reg(s, 14, tmp2);
6905
            gen_bx(s, tmp);
6906
            return 0;
6907
        }
6908
        if (insn & (1 << 11)) {
6909
            /* Second half of bl.  */
6910
            offset = ((insn & 0x7ff) << 1) | 1;
6911
            tmp = load_reg(s, 14);
6912
            tcg_gen_addi_i32(tmp, tmp, offset);
6913

    
6914
            tmp2 = new_tmp();
6915
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6916
            store_reg(s, 14, tmp2);
6917
            gen_bx(s, tmp);
6918
            return 0;
6919
        }
6920
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6921
            /* Instruction spans a page boundary.  Implement it as two
6922
               16-bit instructions in case the second half causes an
6923
               prefetch abort.  */
6924
            offset = ((int32_t)insn << 21) >> 9;
6925
            gen_op_movl_T0_im(s->pc + 2 + offset);
6926
            gen_movl_reg_T0(s, 14);
6927
            return 0;
6928
        }
6929
        /* Fall through to 32-bit decode.  */
6930
    }
6931

    
6932
    insn = lduw_code(s->pc);
6933
    s->pc += 2;
6934
    insn |= (uint32_t)insn_hw1 << 16;
6935

    
6936
    if ((insn & 0xf800e800) != 0xf000e800) {
6937
        ARCH(6T2);
6938
    }
6939

    
6940
    rn = (insn >> 16) & 0xf;
6941
    rs = (insn >> 12) & 0xf;
6942
    rd = (insn >> 8) & 0xf;
6943
    rm = insn & 0xf;
6944
    switch ((insn >> 25) & 0xf) {
6945
    case 0: case 1: case 2: case 3:
6946
        /* 16-bit instructions.  Should never happen.  */
6947
        abort();
6948
    case 4:
6949
        if (insn & (1 << 22)) {
6950
            /* Other load/store, table branch.  */
6951
            if (insn & 0x01200000) {
6952
                /* Load/store doubleword.  */
6953
                if (rn == 15) {
6954
                    addr = new_tmp();
6955
                    tcg_gen_movi_i32(addr, s->pc & ~3);
6956
                } else {
6957
                    addr = load_reg(s, rn);
6958
                }
6959
                offset = (insn & 0xff) * 4;
6960
                if ((insn & (1 << 23)) == 0)
6961
                    offset = -offset;
6962
                if (insn & (1 << 24)) {
6963
                    tcg_gen_addi_i32(addr, addr, offset);
6964
                    offset = 0;
6965
                }
6966
                if (insn & (1 << 20)) {
6967
                    /* ldrd */
6968
                    tmp = gen_ld32(addr, IS_USER(s));
6969
                    store_reg(s, rs, tmp);
6970
                    tcg_gen_addi_i32(addr, addr, 4);
6971
                    tmp = gen_ld32(addr, IS_USER(s));
6972
                    store_reg(s, rd, tmp);
6973
                } else {
6974
                    /* strd */
6975
                    tmp = load_reg(s, rs);
6976
                    gen_st32(tmp, addr, IS_USER(s));
6977
                    tcg_gen_addi_i32(addr, addr, 4);
6978
                    tmp = load_reg(s, rd);
6979
                    gen_st32(tmp, addr, IS_USER(s));
6980
                }
6981
                if (insn & (1 << 21)) {
6982
                    /* Base writeback.  */
6983
                    if (rn == 15)
6984
                        goto illegal_op;
6985
                    tcg_gen_addi_i32(addr, addr, offset - 4);
6986
                    store_reg(s, rn, addr);
6987
                } else {
6988
                    dead_tmp(addr);
6989
                }
6990
            } else if ((insn & (1 << 23)) == 0) {
6991
                /* Load/store exclusive word.  */
6992
                gen_movl_T1_reg(s, rn);
6993
                addr = cpu_T[1];
6994
                if (insn & (1 << 20)) {
6995
                    gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6996
                    tmp = gen_ld32(addr, IS_USER(s));
6997
                    store_reg(s, rd, tmp);
6998
                } else {
6999
                    int label = gen_new_label();
7000
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7001
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
7002
                                        0, label);
7003
                    tmp = load_reg(s, rs);
7004
                    gen_st32(tmp, cpu_T[1], IS_USER(s));
7005
                    gen_set_label(label);
7006
                    gen_movl_reg_T0(s, rd);
7007
                }
7008
            } else if ((insn & (1 << 6)) == 0) {
7009
                /* Table Branch.  */
7010
                if (rn == 15) {
7011
                    addr = new_tmp();
7012
                    tcg_gen_movi_i32(addr, s->pc);
7013
                } else {
7014
                    addr = load_reg(s, rn);
7015
                }
7016
                tmp = load_reg(s, rm);
7017
                tcg_gen_add_i32(addr, addr, tmp);
7018
                if (insn & (1 << 4)) {
7019
                    /* tbh */
7020
                    tcg_gen_add_i32(addr, addr, tmp);
7021
                    dead_tmp(tmp);
7022
                    tmp = gen_ld16u(addr, IS_USER(s));
7023
                } else { /* tbb */
7024
                    dead_tmp(tmp);
7025
                    tmp = gen_ld8u(addr, IS_USER(s));
7026
                }
7027
                dead_tmp(addr);
7028
                tcg_gen_shli_i32(tmp, tmp, 1);
7029
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7030
                store_reg(s, 15, tmp);
7031
            } else {
7032
                /* Load/store exclusive byte/halfword/doubleword.  */
7033
                /* ??? These are not really atomic.  However we know
7034
                   we never have multiple CPUs running in parallel,
7035
                   so it is good enough.  */
7036
                op = (insn >> 4) & 0x3;
7037
                /* Must use a global reg for the address because we have
7038
                   a conditional branch in the store instruction.  */
7039
                gen_movl_T1_reg(s, rn);
7040
                addr = cpu_T[1];
7041
                if (insn & (1 << 20)) {
7042
                    gen_helper_mark_exclusive(cpu_env, addr);
7043
                    switch (op) {
7044
                    case 0:
7045
                        tmp = gen_ld8u(addr, IS_USER(s));
7046
                        break;
7047
                    case 1:
7048
                        tmp = gen_ld16u(addr, IS_USER(s));
7049
                        break;
7050
                    case 3:
7051
                        tmp = gen_ld32(addr, IS_USER(s));
7052
                        tcg_gen_addi_i32(addr, addr, 4);
7053
                        tmp2 = gen_ld32(addr, IS_USER(s));
7054
                        store_reg(s, rd, tmp2);
7055
                        break;
7056
                    default:
7057
                        goto illegal_op;
7058
                    }
7059
                    store_reg(s, rs, tmp);
7060
                } else {
7061
                    int label = gen_new_label();
7062
                    /* Must use a global that is not killed by the branch.  */
7063
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7064
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
7065
                    tmp = load_reg(s, rs);
7066
                    switch (op) {
7067
                    case 0:
7068
                        gen_st8(tmp, addr, IS_USER(s));
7069
                        break;
7070
                    case 1:
7071
                        gen_st16(tmp, addr, IS_USER(s));
7072
                        break;
7073
                    case 3:
7074
                        gen_st32(tmp, addr, IS_USER(s));
7075
                        tcg_gen_addi_i32(addr, addr, 4);
7076
                        tmp = load_reg(s, rd);
7077
                        gen_st32(tmp, addr, IS_USER(s));
7078
                        break;
7079
                    default:
7080
                        goto illegal_op;
7081
                    }
7082
                    gen_set_label(label);
7083
                    gen_movl_reg_T0(s, rm);
7084
                }
7085
            }
7086
        } else {
7087
            /* Load/store multiple, RFE, SRS.  */
7088
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7089
                /* Not available in user mode.  */
7090
                if (IS_USER(s))
7091
                    goto illegal_op;
7092
                if (insn & (1 << 20)) {
7093
                    /* rfe */
7094
                    addr = load_reg(s, rn);
7095
                    if ((insn & (1 << 24)) == 0)
7096
                        tcg_gen_addi_i32(addr, addr, -8);
7097
                    /* Load PC into tmp and CPSR into tmp2.  */
7098
                    tmp = gen_ld32(addr, 0);
7099
                    tcg_gen_addi_i32(addr, addr, 4);
7100
                    tmp2 = gen_ld32(addr, 0);
7101
                    if (insn & (1 << 21)) {
7102
                        /* Base writeback.  */
7103
                        if (insn & (1 << 24)) {
7104
                            tcg_gen_addi_i32(addr, addr, 4);
7105
                        } else {
7106
                            tcg_gen_addi_i32(addr, addr, -4);
7107
                        }
7108
                        store_reg(s, rn, addr);
7109
                    } else {
7110
                        dead_tmp(addr);
7111
                    }
7112
                    gen_rfe(s, tmp, tmp2);
7113
                } else {
7114
                    /* srs */
7115
                    op = (insn & 0x1f);
7116
                    if (op == (env->uncached_cpsr & CPSR_M)) {
7117
                        addr = load_reg(s, 13);
7118
                    } else {
7119
                        addr = new_tmp();
7120
                        gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7121
                    }
7122
                    if ((insn & (1 << 24)) == 0) {
7123
                        tcg_gen_addi_i32(addr, addr, -8);
7124
                    }
7125
                    tmp = load_reg(s, 14);
7126
                    gen_st32(tmp, addr, 0);
7127
                    tcg_gen_addi_i32(addr, addr, 4);
7128
                    tmp = new_tmp();
7129
                    gen_helper_cpsr_read(tmp);
7130
                    gen_st32(tmp, addr, 0);
7131
                    if (insn & (1 << 21)) {
7132
                        if ((insn & (1 << 24)) == 0) {
7133
                            tcg_gen_addi_i32(addr, addr, -4);
7134
                        } else {
7135
                            tcg_gen_addi_i32(addr, addr, 4);
7136
                        }
7137
                        if (op == (env->uncached_cpsr & CPSR_M)) {
7138
                            store_reg(s, 13, addr);
7139
                        } else {
7140
                            gen_helper_set_r13_banked(cpu_env,
7141
                                tcg_const_i32(op), addr);
7142
                        }
7143
                    } else {
7144
                        dead_tmp(addr);
7145
                    }
7146
                }
7147
            } else {
7148
                int i;
7149
                /* Load/store multiple.  */
7150
                addr = load_reg(s, rn);
7151
                offset = 0;
7152
                for (i = 0; i < 16; i++) {
7153
                    if (insn & (1 << i))
7154
                        offset += 4;
7155
                }
7156
                if (insn & (1 << 24)) {
7157
                    tcg_gen_addi_i32(addr, addr, -offset);
7158
                }
7159

    
7160
                for (i = 0; i < 16; i++) {
7161
                    if ((insn & (1 << i)) == 0)
7162
                        continue;
7163
                    if (insn & (1 << 20)) {
7164
                        /* Load.  */
7165
                        tmp = gen_ld32(addr, IS_USER(s));
7166
                        if (i == 15) {
7167
                            gen_bx(s, tmp);
7168
                        } else {
7169
                            store_reg(s, i, tmp);
7170
                        }
7171
                    } else {
7172
                        /* Store.  */
7173
                        tmp = load_reg(s, i);
7174
                        gen_st32(tmp, addr, IS_USER(s));
7175
                    }
7176
                    tcg_gen_addi_i32(addr, addr, 4);
7177
                }
7178
                if (insn & (1 << 21)) {
7179
                    /* Base register writeback.  */
7180
                    if (insn & (1 << 24)) {
7181
                        tcg_gen_addi_i32(addr, addr, -offset);
7182
                    }
7183
                    /* Fault if writeback register is in register list.  */
7184
                    if (insn & (1 << rn))
7185
                        goto illegal_op;
7186
                    store_reg(s, rn, addr);
7187
                } else {
7188
                    dead_tmp(addr);
7189
                }
7190
            }
7191
        }
7192
        break;
7193
    case 5: /* Data processing register constant shift.  */
7194
        if (rn == 15)
7195
            gen_op_movl_T0_im(0);
7196
        else
7197
            gen_movl_T0_reg(s, rn);
7198
        gen_movl_T1_reg(s, rm);
7199
        op = (insn >> 21) & 0xf;
7200
        shiftop = (insn >> 4) & 3;
7201
        shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7202
        conds = (insn & (1 << 20)) != 0;
7203
        logic_cc = (conds && thumb2_logic_op(op));
7204
        gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7205
        if (gen_thumb2_data_op(s, op, conds, 0))
7206
            goto illegal_op;
7207
        if (rd != 15)
7208
            gen_movl_reg_T0(s, rd);
7209
        break;
7210
    case 13: /* Misc data processing.  */
7211
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7212
        if (op < 4 && (insn & 0xf000) != 0xf000)
7213
            goto illegal_op;
7214
        switch (op) {
7215
        case 0: /* Register controlled shift.  */
7216
            tmp = load_reg(s, rn);
7217
            tmp2 = load_reg(s, rm);
7218
            if ((insn & 0x70) != 0)
7219
                goto illegal_op;
7220
            op = (insn >> 21) & 3;
7221
            logic_cc = (insn & (1 << 20)) != 0;
7222
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7223
            if (logic_cc)
7224
                gen_logic_CC(tmp);
7225
            store_reg(s, rd, tmp);
7226
            break;
7227
        case 1: /* Sign/zero extend.  */
7228
            tmp = load_reg(s, rm);
7229
            shift = (insn >> 4) & 3;
7230
            /* ??? In many cases it's not neccessary to do a
7231
               rotate, a shift is sufficient.  */
7232
            if (shift != 0)
7233
                tcg_gen_rori_i32(tmp, tmp, shift * 8);
7234
            op = (insn >> 20) & 7;
7235
            switch (op) {
7236
            case 0: gen_sxth(tmp);   break;
7237
            case 1: gen_uxth(tmp);   break;
7238
            case 2: gen_sxtb16(tmp); break;
7239
            case 3: gen_uxtb16(tmp); break;
7240
            case 4: gen_sxtb(tmp);   break;
7241
            case 5: gen_uxtb(tmp);   break;
7242
            default: goto illegal_op;
7243
            }
7244
            if (rn != 15) {
7245
                tmp2 = load_reg(s, rn);
7246
                if ((op >> 1) == 1) {
7247
                    gen_add16(tmp, tmp2);
7248
                } else {
7249
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7250
                    dead_tmp(tmp2);
7251
                }
7252
            }
7253
            store_reg(s, rd, tmp);
7254
            break;
7255
        case 2: /* SIMD add/subtract.  */
7256
            op = (insn >> 20) & 7;
7257
            shift = (insn >> 4) & 7;
7258
            if ((op & 3) == 3 || (shift & 3) == 3)
7259
                goto illegal_op;
7260
            tmp = load_reg(s, rn);
7261
            tmp2 = load_reg(s, rm);
7262
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7263
            dead_tmp(tmp2);
7264
            store_reg(s, rd, tmp);
7265
            break;
7266
        case 3: /* Other data processing.  */
7267
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7268
            if (op < 4) {
7269
                /* Saturating add/subtract.  */
7270
                tmp = load_reg(s, rn);
7271
                tmp2 = load_reg(s, rm);
7272
                if (op & 2)
7273
                    gen_helper_double_saturate(tmp, tmp);
7274
                if (op & 1)
7275
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7276
                else
7277
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7278
                dead_tmp(tmp2);
7279
            } else {
7280
                tmp = load_reg(s, rn);
7281
                switch (op) {
7282
                case 0x0a: /* rbit */
7283
                    gen_helper_rbit(tmp, tmp);
7284
                    break;
7285
                case 0x08: /* rev */
7286
                    tcg_gen_bswap_i32(tmp, tmp);
7287
                    break;
7288
                case 0x09: /* rev16 */
7289
                    gen_rev16(tmp);
7290
                    break;
7291
                case 0x0b: /* revsh */
7292
                    gen_revsh(tmp);
7293
                    break;
7294
                case 0x10: /* sel */
7295
                    tmp2 = load_reg(s, rm);
7296
                    tmp3 = new_tmp();
7297
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7298
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7299
                    dead_tmp(tmp3);
7300
                    dead_tmp(tmp2);
7301
                    break;
7302
                case 0x18: /* clz */
7303
                    gen_helper_clz(tmp, tmp);
7304
                    break;
7305
                default:
7306
                    goto illegal_op;
7307
                }
7308
            }
7309
            store_reg(s, rd, tmp);
7310
            break;
7311
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7312
            op = (insn >> 4) & 0xf;
7313
            tmp = load_reg(s, rn);
7314
            tmp2 = load_reg(s, rm);
7315
            switch ((insn >> 20) & 7) {
7316
            case 0: /* 32 x 32 -> 32 */
7317
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7318
                dead_tmp(tmp2);
7319
                if (rs != 15) {
7320
                    tmp2 = load_reg(s, rs);
7321
                    if (op)
7322
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7323
                    else
7324
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7325
                    dead_tmp(tmp2);
7326
                }
7327
                break;
7328
            case 1: /* 16 x 16 -> 32 */
7329
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7330
                dead_tmp(tmp2);
7331
                if (rs != 15) {
7332
                    tmp2 = load_reg(s, rs);
7333
                    gen_helper_add_setq(tmp, tmp, tmp2);
7334
                    dead_tmp(tmp2);
7335
                }
7336
                break;
7337
            case 2: /* Dual multiply add.  */
7338
            case 4: /* Dual multiply subtract.  */
7339
                if (op)
7340
                    gen_swap_half(tmp2);
7341
                gen_smul_dual(tmp, tmp2);
7342
                /* This addition cannot overflow.  */
7343
                if (insn & (1 << 22)) {
7344
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7345
                } else {
7346
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7347
                }
7348
                dead_tmp(tmp2);
7349
                if (rs != 15)
7350
                  {
7351
                    tmp2 = load_reg(s, rs);
7352
                    gen_helper_add_setq(tmp, tmp, tmp2);
7353
                    dead_tmp(tmp2);
7354
                  }
7355
                break;
7356
            case 3: /* 32 * 16 -> 32msb */
7357
                if (op)
7358
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7359
                else
7360
                    gen_sxth(tmp2);
7361
                tmp2 = gen_muls_i64_i32(tmp, tmp2);
7362
                tcg_gen_shri_i64(tmp2, tmp2, 16);
7363
                tmp = new_tmp();
7364
                tcg_gen_trunc_i64_i32(tmp, tmp2);
7365
                if (rs != 15)
7366
                  {
7367
                    tmp2 = load_reg(s, rs);
7368
                    gen_helper_add_setq(tmp, tmp, tmp2);
7369
                    dead_tmp(tmp2);
7370
                  }
7371
                break;
7372
            case 5: case 6: /* 32 * 32 -> 32msb */
7373
                gen_imull(tmp, tmp2);
7374
                if (insn & (1 << 5)) {
7375
                    gen_roundqd(tmp, tmp2);
7376
                    dead_tmp(tmp2);
7377
                } else {
7378
                    dead_tmp(tmp);
7379
                    tmp = tmp2;
7380
                }
7381
                if (rs != 15) {
7382
                    tmp2 = load_reg(s, rs);
7383
                    if (insn & (1 << 21)) {
7384
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7385
                    } else {
7386
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7387
                    }
7388
                    dead_tmp(tmp2);
7389
                }
7390
                break;
7391
            case 7: /* Unsigned sum of absolute differences.  */
7392
                gen_helper_usad8(tmp, tmp, tmp2);
7393
                dead_tmp(tmp2);
7394
                if (rs != 15) {
7395
                    tmp2 = load_reg(s, rs);
7396
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7397
                    dead_tmp(tmp2);
7398
                }
7399
                break;
7400
            }
7401
            store_reg(s, rd, tmp);
7402
            break;
7403
        case 6: case 7: /* 64-bit multiply, Divide.  */
7404
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7405
            tmp = load_reg(s, rn);
7406
            tmp2 = load_reg(s, rm);
7407
            if ((op & 0x50) == 0x10) {
7408
                /* sdiv, udiv */
7409
                if (!arm_feature(env, ARM_FEATURE_DIV))
7410
                    goto illegal_op;
7411
                if (op & 0x20)
7412
                    gen_helper_udiv(tmp, tmp, tmp2);
7413
                else
7414
                    gen_helper_sdiv(tmp, tmp, tmp2);
7415
                dead_tmp(tmp2);
7416
                store_reg(s, rd, tmp);
7417
            } else if ((op & 0xe) == 0xc) {
7418
                /* Dual multiply accumulate long.  */
7419
                if (op & 1)
7420
                    gen_swap_half(tmp2);
7421
                gen_smul_dual(tmp, tmp2);
7422
                if (op & 0x10) {
7423
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7424
                } else {
7425
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7426
                }
7427
                dead_tmp(tmp2);
7428
                tmp2 = tcg_temp_new(TCG_TYPE_I64);
7429
                gen_addq(s, tmp, rs, rd);
7430
                gen_storeq_reg(s, rs, rd, tmp);
7431
            } else {
7432
                if (op & 0x20) {
7433
                    /* Unsigned 64-bit multiply  */
7434
                    tmp = gen_mulu_i64_i32(tmp, tmp2);
7435
                } else {
7436
                    if (op & 8) {
7437
                        /* smlalxy */
7438
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7439
                        dead_tmp(tmp2);
7440
                        tmp2 = tcg_temp_new(TCG_TYPE_I64);
7441
                        tcg_gen_ext_i32_i64(tmp2, tmp);
7442
                        dead_tmp(tmp);
7443
                        tmp = tmp2;
7444
                    } else {
7445
                        /* Signed 64-bit multiply  */
7446
                        tmp = gen_muls_i64_i32(tmp, tmp2);
7447
                    }
7448
                }
7449
                if (op & 4) {
7450
                    /* umaal */
7451
                    gen_addq_lo(s, tmp, rs);
7452
                    gen_addq_lo(s, tmp, rd);
7453
                } else if (op & 0x40) {
7454
                    /* 64-bit accumulate.  */
7455
                    gen_addq(s, tmp, rs, rd);
7456
                }
7457
                gen_storeq_reg(s, rs, rd, tmp);
7458
            }
7459
            break;
7460
        }
7461
        break;
7462
    case 6: case 7: case 14: case 15:
7463
        /* Coprocessor.  */
7464
        if (((insn >> 24) & 3) == 3) {
7465
            /* Translate into the equivalent ARM encoding.  */
7466
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7467
            if (disas_neon_data_insn(env, s, insn))
7468
                goto illegal_op;
7469
        } else {
7470
            if (insn & (1 << 28))
7471
                goto illegal_op;
7472
            if (disas_coproc_insn (env, s, insn))
7473
                goto illegal_op;
7474
        }
7475
        break;
7476
    case 8: case 9: case 10: case 11:
7477
        if (insn & (1 << 15)) {
7478
            /* Branches, misc control.  */
7479
            if (insn & 0x5000) {
7480
                /* Unconditional branch.  */
7481
                /* signextend(hw1[10:0]) -> offset[:12].  */
7482
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7483
                /* hw1[10:0] -> offset[11:1].  */
7484
                offset |= (insn & 0x7ff) << 1;
7485
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7486
                   offset[24:22] already have the same value because of the
7487
                   sign extension above.  */
7488
                offset ^= ((~insn) & (1 << 13)) << 10;
7489
                offset ^= ((~insn) & (1 << 11)) << 11;
7490

    
7491
                if (insn & (1 << 14)) {
7492
                    /* Branch and link.  */
7493
                    gen_op_movl_T1_im(s->pc | 1);
7494
                    gen_movl_reg_T1(s, 14);
7495
                }
7496

    
7497
                offset += s->pc;
7498
                if (insn & (1 << 12)) {
7499
                    /* b/bl */
7500
                    gen_jmp(s, offset);
7501
                } else {
7502
                    /* blx */
7503
                    offset &= ~(uint32_t)2;
7504
                    gen_bx_im(s, offset);
7505
                }
7506
            } else if (((insn >> 23) & 7) == 7) {
7507
                /* Misc control */
7508
                if (insn & (1 << 13))
7509
                    goto illegal_op;
7510

    
7511
                if (insn & (1 << 26)) {
7512
                    /* Secure monitor call (v6Z) */
7513
                    goto illegal_op; /* not implemented.  */
7514
                } else {
7515
                    op = (insn >> 20) & 7;
7516
                    switch (op) {
7517
                    case 0: /* msr cpsr.  */
7518
                        if (IS_M(env)) {
7519
                            tmp = load_reg(s, rn);
7520
                            addr = tcg_const_i32(insn & 0xff);
7521
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7522
                            gen_lookup_tb(s);
7523
                            break;
7524
                        }
7525
                        /* fall through */
7526
                    case 1: /* msr spsr.  */
7527
                        if (IS_M(env))
7528
                            goto illegal_op;
7529
                        gen_movl_T0_reg(s, rn);
7530
                        if (gen_set_psr_T0(s,
7531
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7532
                              op == 1))
7533
                            goto illegal_op;
7534
                        break;
7535
                    case 2: /* cps, nop-hint.  */
7536
                        if (((insn >> 8) & 7) == 0) {
7537
                            gen_nop_hint(s, insn & 0xff);
7538
                        }
7539
                        /* Implemented as NOP in user mode.  */
7540
                        if (IS_USER(s))
7541
                            break;
7542
                        offset = 0;
7543
                        imm = 0;
7544
                        if (insn & (1 << 10)) {
7545
                            if (insn & (1 << 7))
7546
                                offset |= CPSR_A;
7547
                            if (insn & (1 << 6))
7548
                                offset |= CPSR_I;
7549
                            if (insn & (1 << 5))
7550
                                offset |= CPSR_F;
7551
                            if (insn & (1 << 9))
7552
                                imm = CPSR_A | CPSR_I | CPSR_F;
7553
                        }
7554
                        if (insn & (1 << 8)) {
7555
                            offset |= 0x1f;
7556
                            imm |= (insn & 0x1f);
7557
                        }
7558
                        if (offset) {
7559
                            gen_op_movl_T0_im(imm);
7560
                            gen_set_psr_T0(s, offset, 0);
7561
                        }
7562
                        break;
7563
                    case 3: /* Special control operations.  */
7564
                        op = (insn >> 4) & 0xf;
7565
                        switch (op) {
7566
                        case 2: /* clrex */
7567
                            gen_helper_clrex(cpu_env);
7568
                            break;
7569
                        case 4: /* dsb */
7570
                        case 5: /* dmb */
7571
                        case 6: /* isb */
7572
                            /* These execute as NOPs.  */
7573
                            ARCH(7);
7574
                            break;
7575
                        default:
7576
                            goto illegal_op;
7577
                        }
7578
                        break;
7579
                    case 4: /* bxj */
7580
                        /* Trivial implementation equivalent to bx.  */
7581
                        tmp = load_reg(s, rn);
7582
                        gen_bx(s, tmp);
7583
                        break;
7584
                    case 5: /* Exception return.  */
7585
                        /* Unpredictable in user mode.  */
7586
                        goto illegal_op;
7587
                    case 6: /* mrs cpsr.  */
7588
                        tmp = new_tmp();
7589
                        if (IS_M(env)) {
7590
                            addr = tcg_const_i32(insn & 0xff);
7591
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
7592
                        } else {
7593
                            gen_helper_cpsr_read(tmp);
7594
                        }
7595
                        store_reg(s, rd, tmp);
7596
                        break;
7597
                    case 7: /* mrs spsr.  */
7598
                        /* Not accessible in user mode.  */
7599
                        if (IS_USER(s) || IS_M(env))
7600
                            goto illegal_op;
7601
                        tmp = load_cpu_field(spsr);
7602
                        store_reg(s, rd, tmp);
7603
                        break;
7604
                    }
7605
                }
7606
            } else {
7607
                /* Conditional branch.  */
7608
                op = (insn >> 22) & 0xf;
7609
                /* Generate a conditional jump to next instruction.  */
7610
                s->condlabel = gen_new_label();
7611
                gen_test_cc(op ^ 1, s->condlabel);
7612
                s->condjmp = 1;
7613

    
7614
                /* offset[11:1] = insn[10:0] */
7615
                offset = (insn & 0x7ff) << 1;
7616
                /* offset[17:12] = insn[21:16].  */
7617
                offset |= (insn & 0x003f0000) >> 4;
7618
                /* offset[31:20] = insn[26].  */
7619
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7620
                /* offset[18] = insn[13].  */
7621
                offset |= (insn & (1 << 13)) << 5;
7622
                /* offset[19] = insn[11].  */
7623
                offset |= (insn & (1 << 11)) << 8;
7624

    
7625
                /* jump to the offset */
7626
                gen_jmp(s, s->pc + offset);
7627
            }
7628
        } else {
7629
            /* Data processing immediate.  */
7630
            if (insn & (1 << 25)) {
7631
                if (insn & (1 << 24)) {
7632
                    if (insn & (1 << 20))
7633
                        goto illegal_op;
7634
                    /* Bitfield/Saturate.  */
7635
                    op = (insn >> 21) & 7;
7636
                    imm = insn & 0x1f;
7637
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7638
                    if (rn == 15) {
7639
                        tmp = new_tmp();
7640
                        tcg_gen_movi_i32(tmp, 0);
7641
                    } else {
7642
                        tmp = load_reg(s, rn);
7643
                    }
7644
                    switch (op) {
7645
                    case 2: /* Signed bitfield extract.  */
7646
                        imm++;
7647
                        if (shift + imm > 32)
7648
                            goto illegal_op;
7649
                        if (imm < 32)
7650
                            gen_sbfx(tmp, shift, imm);
7651
                        break;
7652
                    case 6: /* Unsigned bitfield extract.  */
7653
                        imm++;
7654
                        if (shift + imm > 32)
7655
                            goto illegal_op;
7656
                        if (imm < 32)
7657
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
7658
                        break;
7659
                    case 3: /* Bitfield insert/clear.  */
7660
                        if (imm < shift)
7661
                            goto illegal_op;
7662
                        imm = imm + 1 - shift;
7663
                        if (imm != 32) {
7664
                            tmp2 = load_reg(s, rd);
7665
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7666
                            dead_tmp(tmp2);
7667
                        }
7668
                        break;
7669
                    case 7:
7670
                        goto illegal_op;
7671
                    default: /* Saturate.  */
7672
                        if (shift) {
7673
                            if (op & 1)
7674
                                tcg_gen_sari_i32(tmp, tmp, shift);
7675
                            else
7676
                                tcg_gen_shli_i32(tmp, tmp, shift);
7677
                        }
7678
                        tmp2 = tcg_const_i32(imm);
7679
                        if (op & 4) {
7680
                            /* Unsigned.  */
7681
                            if ((op & 1) && shift == 0)
7682
                                gen_helper_usat16(tmp, tmp, tmp2);
7683
                            else
7684
                                gen_helper_usat(tmp, tmp, tmp2);
7685
                        } else {
7686
                            /* Signed.  */
7687
                            if ((op & 1) && shift == 0)
7688
                                gen_helper_ssat16(tmp, tmp, tmp2);
7689
                            else
7690
                                gen_helper_ssat(tmp, tmp, tmp2);
7691
                        }
7692
                        break;
7693
                    }
7694
                    store_reg(s, rd, tmp);
7695
                } else {
7696
                    imm = ((insn & 0x04000000) >> 15)
7697
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
7698
                    if (insn & (1 << 22)) {
7699
                        /* 16-bit immediate.  */
7700
                        imm |= (insn >> 4) & 0xf000;
7701
                        if (insn & (1 << 23)) {
7702
                            /* movt */
7703
                            tmp = load_reg(s, rd);
7704
                            tcg_gen_ext16u_i32(tmp, tmp);
7705
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
7706
                        } else {
7707
                            /* movw */
7708
                            tmp = new_tmp();
7709
                            tcg_gen_movi_i32(tmp, imm);
7710
                        }
7711
                    } else {
7712
                        /* Add/sub 12-bit immediate.  */
7713
                        if (rn == 15) {
7714
                            offset = s->pc & ~(uint32_t)3;
7715
                            if (insn & (1 << 23))
7716
                                offset -= imm;
7717
                            else
7718
                                offset += imm;
7719
                            tmp = new_tmp();
7720
                            tcg_gen_movi_i32(tmp, offset);
7721
                        } else {
7722
                            tmp = load_reg(s, rn);
7723
                            if (insn & (1 << 23))
7724
                                tcg_gen_subi_i32(tmp, tmp, imm);
7725
                            else
7726
                                tcg_gen_addi_i32(tmp, tmp, imm);
7727
                        }
7728
                    }
7729
                    store_reg(s, rd, tmp);
7730
                }
7731
            } else {
7732
                int shifter_out = 0;
7733
                /* modified 12-bit immediate.  */
7734
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7735
                imm = (insn & 0xff);
7736
                switch (shift) {
7737
                case 0: /* XY */
7738
                    /* Nothing to do.  */
7739
                    break;
7740
                case 1: /* 00XY00XY */
7741
                    imm |= imm << 16;
7742
                    break;
7743
                case 2: /* XY00XY00 */
7744
                    imm |= imm << 16;
7745
                    imm <<= 8;
7746
                    break;
7747
                case 3: /* XYXYXYXY */
7748
                    imm |= imm << 16;
7749
                    imm |= imm << 8;
7750
                    break;
7751
                default: /* Rotated constant.  */
7752
                    shift = (shift << 1) | (imm >> 7);
7753
                    imm |= 0x80;
7754
                    imm = imm << (32 - shift);
7755
                    shifter_out = 1;
7756
                    break;
7757
                }
7758
                gen_op_movl_T1_im(imm);
7759
                rn = (insn >> 16) & 0xf;
7760
                if (rn == 15)
7761
                    gen_op_movl_T0_im(0);
7762
                else
7763
                    gen_movl_T0_reg(s, rn);
7764
                op = (insn >> 21) & 0xf;
7765
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7766
                                       shifter_out))
7767
                    goto illegal_op;
7768
                rd = (insn >> 8) & 0xf;
7769
                if (rd != 15) {
7770
                    gen_movl_reg_T0(s, rd);
7771
                }
7772
            }
7773
        }
7774
        break;
7775
    case 12: /* Load/store single data item.  */
7776
        {
7777
        int postinc = 0;
7778
        int writeback = 0;
7779
        int user;
7780
        if ((insn & 0x01100000) == 0x01000000) {
7781
            if (disas_neon_ls_insn(env, s, insn))
7782
                goto illegal_op;
7783
            break;
7784
        }
7785
        user = IS_USER(s);
7786
        if (rn == 15) {
7787
            addr = new_tmp();
7788
            /* PC relative.  */
7789
            /* s->pc has already been incremented by 4.  */
7790
            imm = s->pc & 0xfffffffc;
7791
            if (insn & (1 << 23))
7792
                imm += insn & 0xfff;
7793
            else
7794
                imm -= insn & 0xfff;
7795
            tcg_gen_movi_i32(addr, imm);
7796
        } else {
7797
            addr = load_reg(s, rn);
7798
            if (insn & (1 << 23)) {
7799
                /* Positive offset.  */
7800
                imm = insn & 0xfff;
7801
                tcg_gen_addi_i32(addr, addr, imm);
7802
            } else {
7803
                op = (insn >> 8) & 7;
7804
                imm = insn & 0xff;
7805
                switch (op) {
7806
                case 0: case 8: /* Shifted Register.  */
7807
                    shift = (insn >> 4) & 0xf;
7808
                    if (shift > 3)
7809
                        goto illegal_op;
7810
                    tmp = load_reg(s, rm);
7811
                    if (shift)
7812
                        tcg_gen_shli_i32(tmp, tmp, shift);
7813
                    tcg_gen_add_i32(addr, addr, tmp);
7814
                    dead_tmp(tmp);
7815
                    break;
7816
                case 4: /* Negative offset.  */
7817
                    tcg_gen_addi_i32(addr, addr, -imm);
7818
                    break;
7819
                case 6: /* User privilege.  */
7820
                    tcg_gen_addi_i32(addr, addr, imm);
7821
                    user = 1;
7822
                    break;
7823
                case 1: /* Post-decrement.  */
7824
                    imm = -imm;
7825
                    /* Fall through.  */
7826
                case 3: /* Post-increment.  */
7827
                    postinc = 1;
7828
                    writeback = 1;
7829
                    break;
7830
                case 5: /* Pre-decrement.  */
7831
                    imm = -imm;
7832
                    /* Fall through.  */
7833
                case 7: /* Pre-increment.  */
7834
                    tcg_gen_addi_i32(addr, addr, imm);
7835
                    writeback = 1;
7836
                    break;
7837
                default:
7838
                    goto illegal_op;
7839
                }
7840
            }
7841
        }
7842
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7843
        if (insn & (1 << 20)) {
7844
            /* Load.  */
7845
            if (rs == 15 && op != 2) {
7846
                if (op & 2)
7847
                    goto illegal_op;
7848
                /* Memory hint.  Implemented as NOP.  */
7849
            } else {
7850
                switch (op) {
7851
                case 0: tmp = gen_ld8u(addr, user); break;
7852
                case 4: tmp = gen_ld8s(addr, user); break;
7853
                case 1: tmp = gen_ld16u(addr, user); break;
7854
                case 5: tmp = gen_ld16s(addr, user); break;
7855
                case 2: tmp = gen_ld32(addr, user); break;
7856
                default: goto illegal_op;
7857
                }
7858
                if (rs == 15) {
7859
                    gen_bx(s, tmp);
7860
                } else {
7861
                    store_reg(s, rs, tmp);
7862
                }
7863
            }
7864
        } else {
7865
            /* Store.  */
7866
            if (rs == 15)
7867
                goto illegal_op;
7868
            tmp = load_reg(s, rs);
7869
            switch (op) {
7870
            case 0: gen_st8(tmp, addr, user); break;
7871
            case 1: gen_st16(tmp, addr, user); break;
7872
            case 2: gen_st32(tmp, addr, user); break;
7873
            default: goto illegal_op;
7874
            }
7875
        }
7876
        if (postinc)
7877
            tcg_gen_addi_i32(addr, addr, imm);
7878
        if (writeback) {
7879
            store_reg(s, rn, addr);
7880
        } else {
7881
            dead_tmp(addr);
7882
        }
7883
        }
7884
        break;
7885
    default:
7886
        goto illegal_op;
7887
    }
7888
    return 0;
7889
illegal_op:
7890
    return 1;
7891
}
7892

    
7893
static void disas_thumb_insn(CPUState *env, DisasContext *s)
7894
{
7895
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
7896
    int32_t offset;
7897
    int i;
7898
    TCGv tmp;
7899
    TCGv tmp2;
7900
    TCGv addr;
7901

    
7902
    if (s->condexec_mask) {
7903
        cond = s->condexec_cond;
7904
        s->condlabel = gen_new_label();
7905
        gen_test_cc(cond ^ 1, s->condlabel);
7906
        s->condjmp = 1;
7907
    }
7908

    
7909
    insn = lduw_code(s->pc);
7910
    s->pc += 2;
7911

    
7912
    switch (insn >> 12) {
7913
    case 0: case 1:
7914
        rd = insn & 7;
7915
        op = (insn >> 11) & 3;
7916
        if (op == 3) {
7917
            /* add/subtract */
7918
            rn = (insn >> 3) & 7;
7919
            gen_movl_T0_reg(s, rn);
7920
            if (insn & (1 << 10)) {
7921
                /* immediate */
7922
                gen_op_movl_T1_im((insn >> 6) & 7);
7923
            } else {
7924
                /* reg */
7925
                rm = (insn >> 6) & 7;
7926
                gen_movl_T1_reg(s, rm);
7927
            }
7928
            if (insn & (1 << 9)) {
7929
                if (s->condexec_mask)
7930
                    gen_op_subl_T0_T1();
7931
                else
7932
                    gen_op_subl_T0_T1_cc();
7933
            } else {
7934
                if (s->condexec_mask)
7935
                    gen_op_addl_T0_T1();
7936
                else
7937
                    gen_op_addl_T0_T1_cc();
7938
            }
7939
            gen_movl_reg_T0(s, rd);
7940
        } else {
7941
            /* shift immediate */
7942
            rm = (insn >> 3) & 7;
7943
            shift = (insn >> 6) & 0x1f;
7944
            tmp = load_reg(s, rm);
7945
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7946
            if (!s->condexec_mask)
7947
                gen_logic_CC(tmp);
7948
            store_reg(s, rd, tmp);
7949
        }
7950
        break;
7951
    case 2: case 3:
7952
        /* arithmetic large immediate */
7953
        op = (insn >> 11) & 3;
7954
        rd = (insn >> 8) & 0x7;
7955
        if (op == 0) {
7956
            gen_op_movl_T0_im(insn & 0xff);
7957
        } else {
7958
            gen_movl_T0_reg(s, rd);
7959
            gen_op_movl_T1_im(insn & 0xff);
7960
        }
7961
        switch (op) {
7962
        case 0: /* mov */
7963
            if (!s->condexec_mask)
7964
                gen_op_logic_T0_cc();
7965
            break;
7966
        case 1: /* cmp */
7967
            gen_op_subl_T0_T1_cc();
7968
            break;
7969
        case 2: /* add */
7970
            if (s->condexec_mask)
7971
                gen_op_addl_T0_T1();
7972
            else
7973
                gen_op_addl_T0_T1_cc();
7974
            break;
7975
        case 3: /* sub */
7976
            if (s->condexec_mask)
7977
                gen_op_subl_T0_T1();
7978
            else
7979
                gen_op_subl_T0_T1_cc();
7980
            break;
7981
        }
7982
        if (op != 1)
7983
            gen_movl_reg_T0(s, rd);
7984
        break;
7985
    case 4:
7986
        if (insn & (1 << 11)) {
7987
            rd = (insn >> 8) & 7;
7988
            /* load pc-relative.  Bit 1 of PC is ignored.  */
7989
            val = s->pc + 2 + ((insn & 0xff) * 4);
7990
            val &= ~(uint32_t)2;
7991
            addr = new_tmp();
7992
            tcg_gen_movi_i32(addr, val);
7993
            tmp = gen_ld32(addr, IS_USER(s));
7994
            dead_tmp(addr);
7995
            store_reg(s, rd, tmp);
7996
            break;
7997
        }
7998
        if (insn & (1 << 10)) {
7999
            /* data processing extended or blx */
8000
            rd = (insn & 7) | ((insn >> 4) & 8);
8001
            rm = (insn >> 3) & 0xf;
8002
            op = (insn >> 8) & 3;
8003
            switch (op) {
8004
            case 0: /* add */
8005
                gen_movl_T0_reg(s, rd);
8006
                gen_movl_T1_reg(s, rm);
8007
                gen_op_addl_T0_T1();
8008
                gen_movl_reg_T0(s, rd);
8009
                break;
8010
            case 1: /* cmp */
8011
                gen_movl_T0_reg(s, rd);
8012
                gen_movl_T1_reg(s, rm);
8013
                gen_op_subl_T0_T1_cc();
8014
                break;
8015
            case 2: /* mov/cpy */
8016
                gen_movl_T0_reg(s, rm);
8017
                gen_movl_reg_T0(s, rd);
8018
                break;
8019
            case 3:/* branch [and link] exchange thumb register */
8020
                tmp = load_reg(s, rm);
8021
                if (insn & (1 << 7)) {
8022
                    val = (uint32_t)s->pc | 1;
8023
                    tmp2 = new_tmp();
8024
                    tcg_gen_movi_i32(tmp2, val);
8025
                    store_reg(s, 14, tmp2);
8026
                }
8027
                gen_bx(s, tmp);
8028
                break;
8029
            }
8030
            break;
8031
        }
8032

    
8033
        /* data processing register */
8034
        rd = insn & 7;
8035
        rm = (insn >> 3) & 7;
8036
        op = (insn >> 6) & 0xf;
8037
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8038
            /* the shift/rotate ops want the operands backwards */
8039
            val = rm;
8040
            rm = rd;
8041
            rd = val;
8042
            val = 1;
8043
        } else {
8044
            val = 0;
8045
        }
8046

    
8047
        if (op == 9) /* neg */
8048
            gen_op_movl_T0_im(0);
8049
        else if (op != 0xf) /* mvn doesn't read its first operand */
8050
            gen_movl_T0_reg(s, rd);
8051

    
8052
        gen_movl_T1_reg(s, rm);
8053
        switch (op) {
8054
        case 0x0: /* and */
8055
            gen_op_andl_T0_T1();
8056
            if (!s->condexec_mask)
8057
                gen_op_logic_T0_cc();
8058
            break;
8059
        case 0x1: /* eor */
8060
            gen_op_xorl_T0_T1();
8061
            if (!s->condexec_mask)
8062
                gen_op_logic_T0_cc();
8063
            break;
8064
        case 0x2: /* lsl */
8065
            if (s->condexec_mask) {
8066
                gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8067
            } else {
8068
                gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8069
                gen_op_logic_T1_cc();
8070
            }
8071
            break;
8072
        case 0x3: /* lsr */
8073
            if (s->condexec_mask) {
8074
                gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8075
            } else {
8076
                gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8077
                gen_op_logic_T1_cc();
8078
            }
8079
            break;
8080
        case 0x4: /* asr */
8081
            if (s->condexec_mask) {
8082
                gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8083
            } else {
8084
                gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8085
                gen_op_logic_T1_cc();
8086
            }
8087
            break;
8088
        case 0x5: /* adc */
8089
            if (s->condexec_mask)
8090
                gen_adc_T0_T1();
8091
            else
8092
                gen_op_adcl_T0_T1_cc();
8093
            break;
8094
        case 0x6: /* sbc */
8095
            if (s->condexec_mask)
8096
                gen_sbc_T0_T1();
8097
            else
8098
                gen_op_sbcl_T0_T1_cc();
8099
            break;
8100
        case 0x7: /* ror */
8101
            if (s->condexec_mask) {
8102
                gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8103
            } else {
8104
                gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8105
                gen_op_logic_T1_cc();
8106
            }
8107
            break;
8108
        case 0x8: /* tst */
8109
            gen_op_andl_T0_T1();
8110
            gen_op_logic_T0_cc();
8111
            rd = 16;
8112
            break;
8113
        case 0x9: /* neg */
8114
            if (s->condexec_mask)
8115
                tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8116
            else
8117
                gen_op_subl_T0_T1_cc();
8118
            break;
8119
        case 0xa: /* cmp */
8120
            gen_op_subl_T0_T1_cc();
8121
            rd = 16;
8122
            break;
8123
        case 0xb: /* cmn */
8124
            gen_op_addl_T0_T1_cc();
8125
            rd = 16;
8126
            break;
8127
        case 0xc: /* orr */
8128
            gen_op_orl_T0_T1();
8129
            if (!s->condexec_mask)
8130
                gen_op_logic_T0_cc();
8131
            break;
8132
        case 0xd: /* mul */
8133
            gen_op_mull_T0_T1();
8134
            if (!s->condexec_mask)
8135
                gen_op_logic_T0_cc();
8136
            break;
8137
        case 0xe: /* bic */
8138
            gen_op_bicl_T0_T1();
8139
            if (!s->condexec_mask)
8140
                gen_op_logic_T0_cc();
8141
            break;
8142
        case 0xf: /* mvn */
8143
            gen_op_notl_T1();
8144
            if (!s->condexec_mask)
8145
                gen_op_logic_T1_cc();
8146
            val = 1;
8147
            rm = rd;
8148
            break;
8149
        }
8150
        if (rd != 16) {
8151
            if (val)
8152
                gen_movl_reg_T1(s, rm);
8153
            else
8154
                gen_movl_reg_T0(s, rd);
8155
        }
8156
        break;
8157

    
8158
    case 5:
8159
        /* load/store register offset.  */
8160
        rd = insn & 7;
8161
        rn = (insn >> 3) & 7;
8162
        rm = (insn >> 6) & 7;
8163
        op = (insn >> 9) & 7;
8164
        addr = load_reg(s, rn);
8165
        tmp = load_reg(s, rm);
8166
        tcg_gen_add_i32(addr, addr, tmp);
8167
        dead_tmp(tmp);
8168

    
8169
        if (op < 3) /* store */
8170
            tmp = load_reg(s, rd);
8171

    
8172
        switch (op) {
8173
        case 0: /* str */
8174
            gen_st32(tmp, addr, IS_USER(s));
8175
            break;
8176
        case 1: /* strh */
8177
            gen_st16(tmp, addr, IS_USER(s));
8178
            break;
8179
        case 2: /* strb */
8180
            gen_st8(tmp, addr, IS_USER(s));
8181
            break;
8182
        case 3: /* ldrsb */
8183
            tmp = gen_ld8s(addr, IS_USER(s));
8184
            break;
8185
        case 4: /* ldr */
8186
            tmp = gen_ld32(addr, IS_USER(s));
8187
            break;
8188
        case 5: /* ldrh */
8189
            tmp = gen_ld16u(addr, IS_USER(s));
8190
            break;
8191
        case 6: /* ldrb */
8192
            tmp = gen_ld8u(addr, IS_USER(s));
8193
            break;
8194
        case 7: /* ldrsh */
8195
            tmp = gen_ld16s(addr, IS_USER(s));
8196
            break;
8197
        }
8198
        if (op >= 3) /* load */
8199
            store_reg(s, rd, tmp);
8200
        dead_tmp(addr);
8201
        break;
8202

    
8203
    case 6:
8204
        /* load/store word immediate offset */
8205
        rd = insn & 7;
8206
        rn = (insn >> 3) & 7;
8207
        addr = load_reg(s, rn);
8208
        val = (insn >> 4) & 0x7c;
8209
        tcg_gen_addi_i32(addr, addr, val);
8210

    
8211
        if (insn & (1 << 11)) {
8212
            /* load */
8213
            tmp = gen_ld32(addr, IS_USER(s));
8214
            store_reg(s, rd, tmp);
8215
        } else {
8216
            /* store */
8217
            tmp = load_reg(s, rd);
8218
            gen_st32(tmp, addr, IS_USER(s));
8219
        }
8220
        dead_tmp(addr);
8221
        break;
8222

    
8223
    case 7:
8224
        /* load/store byte immediate offset */
8225
        rd = insn & 7;
8226
        rn = (insn >> 3) & 7;
8227
        addr = load_reg(s, rn);
8228
        val = (insn >> 6) & 0x1f;
8229
        tcg_gen_addi_i32(addr, addr, val);
8230

    
8231
        if (insn & (1 << 11)) {
8232
            /* load */
8233
            tmp = gen_ld8u(addr, IS_USER(s));
8234
            store_reg(s, rd, tmp);
8235
        } else {
8236
            /* store */
8237
            tmp = load_reg(s, rd);
8238
            gen_st8(tmp, addr, IS_USER(s));
8239
        }
8240
        dead_tmp(addr);
8241
        break;
8242

    
8243
    case 8:
8244
        /* load/store halfword immediate offset */
8245
        rd = insn & 7;
8246
        rn = (insn >> 3) & 7;
8247
        addr = load_reg(s, rn);
8248
        val = (insn >> 5) & 0x3e;
8249
        tcg_gen_addi_i32(addr, addr, val);
8250

    
8251
        if (insn & (1 << 11)) {
8252
            /* load */
8253
            tmp = gen_ld16u(addr, IS_USER(s));
8254
            store_reg(s, rd, tmp);
8255
        } else {
8256
            /* store */
8257
            tmp = load_reg(s, rd);
8258
            gen_st16(tmp, addr, IS_USER(s));
8259
        }
8260
        dead_tmp(addr);
8261
        break;
8262

    
8263
    case 9:
8264
        /* load/store from stack */
8265
        rd = (insn >> 8) & 7;
8266
        addr = load_reg(s, 13);
8267
        val = (insn & 0xff) * 4;
8268
        tcg_gen_addi_i32(addr, addr, val);
8269

    
8270
        if (insn & (1 << 11)) {
8271
            /* load */
8272
            tmp = gen_ld32(addr, IS_USER(s));
8273
            store_reg(s, rd, tmp);
8274
        } else {
8275
            /* store */
8276
            tmp = load_reg(s, rd);
8277
            gen_st32(tmp, addr, IS_USER(s));
8278
        }
8279
        dead_tmp(addr);
8280
        break;
8281

    
8282
    case 10:
8283
        /* add to high reg */
8284
        rd = (insn >> 8) & 7;
8285
        if (insn & (1 << 11)) {
8286
            /* SP */
8287
            tmp = load_reg(s, 13);
8288
        } else {
8289
            /* PC. bit 1 is ignored.  */
8290
            tmp = new_tmp();
8291
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8292
        }
8293
        val = (insn & 0xff) * 4;
8294
        tcg_gen_addi_i32(tmp, tmp, val);
8295
        store_reg(s, rd, tmp);
8296
        break;
8297

    
8298
    case 11:
8299
        /* misc */
8300
        op = (insn >> 8) & 0xf;
8301
        switch (op) {
8302
        case 0:
8303
            /* adjust stack pointer */
8304
            tmp = load_reg(s, 13);
8305
            val = (insn & 0x7f) * 4;
8306
            if (insn & (1 << 7))
8307
                val = -(int32_t)val;
8308
            tcg_gen_addi_i32(tmp, tmp, val);
8309
            store_reg(s, 13, tmp);
8310
            break;
8311

    
8312
        case 2: /* sign/zero extend.  */
8313
            ARCH(6);
8314
            rd = insn & 7;
8315
            rm = (insn >> 3) & 7;
8316
            tmp = load_reg(s, rm);
8317
            switch ((insn >> 6) & 3) {
8318
            case 0: gen_sxth(tmp); break;
8319
            case 1: gen_sxtb(tmp); break;
8320
            case 2: gen_uxth(tmp); break;
8321
            case 3: gen_uxtb(tmp); break;
8322
            }
8323
            store_reg(s, rd, tmp);
8324
            break;
8325
        case 4: case 5: case 0xc: case 0xd:
8326
            /* push/pop */
8327
            addr = load_reg(s, 13);
8328
            if (insn & (1 << 8))
8329
                offset = 4;
8330
            else
8331
                offset = 0;
8332
            for (i = 0; i < 8; i++) {
8333
                if (insn & (1 << i))
8334
                    offset += 4;
8335
            }
8336
            if ((insn & (1 << 11)) == 0) {
8337
                tcg_gen_addi_i32(addr, addr, -offset);
8338
            }
8339
            for (i = 0; i < 8; i++) {
8340
                if (insn & (1 << i)) {
8341
                    if (insn & (1 << 11)) {
8342
                        /* pop */
8343
                        tmp = gen_ld32(addr, IS_USER(s));
8344
                        store_reg(s, i, tmp);
8345
                    } else {
8346
                        /* push */
8347
                        tmp = load_reg(s, i);
8348
                        gen_st32(tmp, addr, IS_USER(s));
8349
                    }
8350
                    /* advance to the next address.  */
8351
                    tcg_gen_addi_i32(addr, addr, 4);
8352
                }
8353
            }
8354
            TCGV_UNUSED(tmp);
8355
            if (insn & (1 << 8)) {
8356
                if (insn & (1 << 11)) {
8357
                    /* pop pc */
8358
                    tmp = gen_ld32(addr, IS_USER(s));
8359
                    /* don't set the pc until the rest of the instruction
8360
                       has completed */
8361
                } else {
8362
                    /* push lr */
8363
                    tmp = load_reg(s, 14);
8364
                    gen_st32(tmp, addr, IS_USER(s));
8365
                }
8366
                tcg_gen_addi_i32(addr, addr, 4);
8367
            }
8368
            if ((insn & (1 << 11)) == 0) {
8369
                tcg_gen_addi_i32(addr, addr, -offset);
8370
            }
8371
            /* write back the new stack pointer */
8372
            store_reg(s, 13, addr);
8373
            /* set the new PC value */
8374
            if ((insn & 0x0900) == 0x0900)
8375
                gen_bx(s, tmp);
8376
            break;
8377

    
8378
        case 1: case 3: case 9: case 11: /* czb */
8379
            rm = insn & 7;
8380
            tmp = load_reg(s, rm);
8381
            s->condlabel = gen_new_label();
8382
            s->condjmp = 1;
8383
            if (insn & (1 << 11))
8384
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8385
            else
8386
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8387
            dead_tmp(tmp);
8388
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8389
            val = (uint32_t)s->pc + 2;
8390
            val += offset;
8391
            gen_jmp(s, val);
8392
            break;
8393

    
8394
        case 15: /* IT, nop-hint.  */
8395
            if ((insn & 0xf) == 0) {
8396
                gen_nop_hint(s, (insn >> 4) & 0xf);
8397
                break;
8398
            }
8399
            /* If Then.  */
8400
            s->condexec_cond = (insn >> 4) & 0xe;
8401
            s->condexec_mask = insn & 0x1f;
8402
            /* No actual code generated for this insn, just setup state.  */
8403
            break;
8404

    
8405
        case 0xe: /* bkpt */
8406
            gen_set_condexec(s);
8407
            gen_set_pc_im(s->pc - 2);
8408
            gen_exception(EXCP_BKPT);
8409
            s->is_jmp = DISAS_JUMP;
8410
            break;
8411

    
8412
        case 0xa: /* rev */
8413
            ARCH(6);
8414
            rn = (insn >> 3) & 0x7;
8415
            rd = insn & 0x7;
8416
            tmp = load_reg(s, rn);
8417
            switch ((insn >> 6) & 3) {
8418
            case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8419
            case 1: gen_rev16(tmp); break;
8420
            case 3: gen_revsh(tmp); break;
8421
            default: goto illegal_op;
8422
            }
8423
            store_reg(s, rd, tmp);
8424
            break;
8425

    
8426
        case 6: /* cps */
8427
            ARCH(6);
8428
            if (IS_USER(s))
8429
                break;
8430
            if (IS_M(env)) {
8431
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8432
                /* PRIMASK */
8433
                if (insn & 1) {
8434
                    addr = tcg_const_i32(16);
8435
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8436
                }
8437
                /* FAULTMASK */
8438
                if (insn & 2) {
8439
                    addr = tcg_const_i32(17);
8440
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8441
                }
8442
                gen_lookup_tb(s);
8443
            } else {
8444
                if (insn & (1 << 4))
8445
                    shift = CPSR_A | CPSR_I | CPSR_F;
8446
                else
8447
                    shift = 0;
8448

    
8449
                val = ((insn & 7) << 6) & shift;
8450
                gen_op_movl_T0_im(val);
8451
                gen_set_psr_T0(s, shift, 0);
8452
            }
8453
            break;
8454

    
8455
        default:
8456
            goto undef;
8457
        }
8458
        break;
8459

    
8460
    case 12:
8461
        /* load/store multiple */
8462
        rn = (insn >> 8) & 0x7;
8463
        addr = load_reg(s, rn);
8464
        for (i = 0; i < 8; i++) {
8465
            if (insn & (1 << i)) {
8466
                if (insn & (1 << 11)) {
8467
                    /* load */
8468
                    tmp = gen_ld32(addr, IS_USER(s));
8469
                    store_reg(s, i, tmp);
8470
                } else {
8471
                    /* store */
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
        /* Base register writeback.  */
8480
        if ((insn & (1 << rn)) == 0) {
8481
            store_reg(s, rn, addr);
8482
        } else {
8483
            dead_tmp(addr);
8484
        }
8485
        break;
8486

    
8487
    case 13:
8488
        /* conditional branch or swi */
8489
        cond = (insn >> 8) & 0xf;
8490
        if (cond == 0xe)
8491
            goto undef;
8492

    
8493
        if (cond == 0xf) {
8494
            /* swi */
8495
            gen_set_condexec(s);
8496
            gen_set_pc_im(s->pc);
8497
            s->is_jmp = DISAS_SWI;
8498
            break;
8499
        }
8500
        /* generate a conditional jump to next instruction */
8501
        s->condlabel = gen_new_label();
8502
        gen_test_cc(cond ^ 1, s->condlabel);
8503
        s->condjmp = 1;
8504
        gen_movl_T1_reg(s, 15);
8505

    
8506
        /* jump to the offset */
8507
        val = (uint32_t)s->pc + 2;
8508
        offset = ((int32_t)insn << 24) >> 24;
8509
        val += offset << 1;
8510
        gen_jmp(s, val);
8511
        break;
8512

    
8513
    case 14:
8514
        if (insn & (1 << 11)) {
8515
            if (disas_thumb2_insn(env, s, insn))
8516
              goto undef32;
8517
            break;
8518
        }
8519
        /* unconditional branch */
8520
        val = (uint32_t)s->pc;
8521
        offset = ((int32_t)insn << 21) >> 21;
8522
        val += (offset << 1) + 2;
8523
        gen_jmp(s, val);
8524
        break;
8525

    
8526
    case 15:
8527
        if (disas_thumb2_insn(env, s, insn))
8528
            goto undef32;
8529
        break;
8530
    }
8531
    return;
8532
undef32:
8533
    gen_set_condexec(s);
8534
    gen_set_pc_im(s->pc - 4);
8535
    gen_exception(EXCP_UDEF);
8536
    s->is_jmp = DISAS_JUMP;
8537
    return;
8538
illegal_op:
8539
undef:
8540
    gen_set_condexec(s);
8541
    gen_set_pc_im(s->pc - 2);
8542
    gen_exception(EXCP_UDEF);
8543
    s->is_jmp = DISAS_JUMP;
8544
}
8545

    
8546
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8547
   basic block 'tb'. If search_pc is TRUE, also generate PC
8548
   information for each intermediate instruction. */
8549
static inline void gen_intermediate_code_internal(CPUState *env,
8550
                                                  TranslationBlock *tb,
8551
                                                  int search_pc)
8552
{
8553
    DisasContext dc1, *dc = &dc1;
8554
    uint16_t *gen_opc_end;
8555
    int j, lj;
8556
    target_ulong pc_start;
8557
    uint32_t next_page_start;
8558
    int num_insns;
8559
    int max_insns;
8560

    
8561
    /* generate intermediate code */
8562
    num_temps = 0;
8563
    memset(temps, 0, sizeof(temps));
8564

    
8565
    pc_start = tb->pc;
8566

    
8567
    dc->tb = tb;
8568

    
8569
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8570

    
8571
    dc->is_jmp = DISAS_NEXT;
8572
    dc->pc = pc_start;
8573
    dc->singlestep_enabled = env->singlestep_enabled;
8574
    dc->condjmp = 0;
8575
    dc->thumb = env->thumb;
8576
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8577
    dc->condexec_cond = env->condexec_bits >> 4;
8578
    dc->is_mem = 0;
8579
#if !defined(CONFIG_USER_ONLY)
8580
    if (IS_M(env)) {
8581
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8582
    } else {
8583
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8584
    }
8585
#endif
8586
    cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
8587
    cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
8588
    cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
8589
    cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8590
    cpu_V0 = cpu_F0d;
8591
    cpu_V1 = cpu_F1d;
8592
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
8593
    cpu_M0 = tcg_temp_new(TCG_TYPE_I64);
8594
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8595
    lj = -1;
8596
    num_insns = 0;
8597
    max_insns = tb->cflags & CF_COUNT_MASK;
8598
    if (max_insns == 0)
8599
        max_insns = CF_COUNT_MASK;
8600

    
8601
    gen_icount_start();
8602
    /* Reset the conditional execution bits immediately. This avoids
8603
       complications trying to do it at the end of the block.  */
8604
    if (env->condexec_bits)
8605
      {
8606
        TCGv tmp = new_tmp();
8607
        tcg_gen_movi_i32(tmp, 0);
8608
        store_cpu_field(tmp, condexec_bits);
8609
      }
8610
    do {
8611
#ifdef CONFIG_USER_ONLY
8612
        /* Intercept jump to the magic kernel page.  */
8613
        if (dc->pc >= 0xffff0000) {
8614
            /* We always get here via a jump, so know we are not in a
8615
               conditional execution block.  */
8616
            gen_exception(EXCP_KERNEL_TRAP);
8617
            dc->is_jmp = DISAS_UPDATE;
8618
            break;
8619
        }
8620
#else
8621
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8622
            /* We always get here via a jump, so know we are not in a
8623
               conditional execution block.  */
8624
            gen_exception(EXCP_EXCEPTION_EXIT);
8625
            dc->is_jmp = DISAS_UPDATE;
8626
            break;
8627
        }
8628
#endif
8629

    
8630
        if (env->nb_breakpoints > 0) {
8631
            for(j = 0; j < env->nb_breakpoints; j++) {
8632
                if (env->breakpoints[j] == dc->pc) {
8633
                    gen_set_condexec(dc);
8634
                    gen_set_pc_im(dc->pc);
8635
                    gen_exception(EXCP_DEBUG);
8636
                    dc->is_jmp = DISAS_JUMP;
8637
                    /* Advance PC so that clearing the breakpoint will
8638
                       invalidate this TB.  */
8639
                    dc->pc += 2;
8640
                    goto done_generating;
8641
                    break;
8642
                }
8643
            }
8644
        }
8645
        if (search_pc) {
8646
            j = gen_opc_ptr - gen_opc_buf;
8647
            if (lj < j) {
8648
                lj++;
8649
                while (lj < j)
8650
                    gen_opc_instr_start[lj++] = 0;
8651
            }
8652
            gen_opc_pc[lj] = dc->pc;
8653
            gen_opc_instr_start[lj] = 1;
8654
            gen_opc_icount[lj] = num_insns;
8655
        }
8656

    
8657
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8658
            gen_io_start();
8659

    
8660
        if (env->thumb) {
8661
            disas_thumb_insn(env, dc);
8662
            if (dc->condexec_mask) {
8663
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8664
                                   | ((dc->condexec_mask >> 4) & 1);
8665
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8666
                if (dc->condexec_mask == 0) {
8667
                    dc->condexec_cond = 0;
8668
                }
8669
            }
8670
        } else {
8671
            disas_arm_insn(env, dc);
8672
        }
8673
        if (num_temps) {
8674
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8675
            num_temps = 0;
8676
        }
8677

    
8678
        if (dc->condjmp && !dc->is_jmp) {
8679
            gen_set_label(dc->condlabel);
8680
            dc->condjmp = 0;
8681
        }
8682
        /* Terminate the TB on memory ops if watchpoints are present.  */
8683
        /* FIXME: This should be replacd by the deterministic execution
8684
         * IRQ raising bits.  */
8685
        if (dc->is_mem && env->nb_watchpoints)
8686
            break;
8687

    
8688
        /* Translation stops when a conditional branch is enoutered.
8689
         * Otherwise the subsequent code could get translated several times.
8690
         * Also stop translation when a page boundary is reached.  This
8691
         * ensures prefetch aborts occur at the right place.  */
8692
        num_insns ++;
8693
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8694
             !env->singlestep_enabled &&
8695
             dc->pc < next_page_start &&
8696
             num_insns < max_insns);
8697

    
8698
    if (tb->cflags & CF_LAST_IO) {
8699
        if (dc->condjmp) {
8700
            /* FIXME:  This can theoretically happen with self-modifying
8701
               code.  */
8702
            cpu_abort(env, "IO on conditional branch instruction");
8703
        }
8704
        gen_io_end();
8705
    }
8706

    
8707
    /* At this stage dc->condjmp will only be set when the skipped
8708
       instruction was a conditional branch or trap, and the PC has
8709
       already been written.  */
8710
    if (unlikely(env->singlestep_enabled)) {
8711
        /* Make sure the pc is updated, and raise a debug exception.  */
8712
        if (dc->condjmp) {
8713
            gen_set_condexec(dc);
8714
            if (dc->is_jmp == DISAS_SWI) {
8715
                gen_exception(EXCP_SWI);
8716
            } else {
8717
                gen_exception(EXCP_DEBUG);
8718
            }
8719
            gen_set_label(dc->condlabel);
8720
        }
8721
        if (dc->condjmp || !dc->is_jmp) {
8722
            gen_set_pc_im(dc->pc);
8723
            dc->condjmp = 0;
8724
        }
8725
        gen_set_condexec(dc);
8726
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8727
            gen_exception(EXCP_SWI);
8728
        } else {
8729
            /* FIXME: Single stepping a WFI insn will not halt
8730
               the CPU.  */
8731
            gen_exception(EXCP_DEBUG);
8732
        }
8733
    } else {
8734
        /* While branches must always occur at the end of an IT block,
8735
           there are a few other things that can cause us to terminate
8736
           the TB in the middel of an IT block:
8737
            - Exception generating instructions (bkpt, swi, undefined).
8738
            - Page boundaries.
8739
            - Hardware watchpoints.
8740
           Hardware breakpoints have already been handled and skip this code.
8741
         */
8742
        gen_set_condexec(dc);
8743
        switch(dc->is_jmp) {
8744
        case DISAS_NEXT:
8745
            gen_goto_tb(dc, 1, dc->pc);
8746
            break;
8747
        default:
8748
        case DISAS_JUMP:
8749
        case DISAS_UPDATE:
8750
            /* indicate that the hash table must be used to find the next TB */
8751
            tcg_gen_exit_tb(0);
8752
            break;
8753
        case DISAS_TB_JUMP:
8754
            /* nothing more to generate */
8755
            break;
8756
        case DISAS_WFI:
8757
            gen_helper_wfi();
8758
            break;
8759
        case DISAS_SWI:
8760
            gen_exception(EXCP_SWI);
8761
            break;
8762
        }
8763
        if (dc->condjmp) {
8764
            gen_set_label(dc->condlabel);
8765
            gen_set_condexec(dc);
8766
            gen_goto_tb(dc, 1, dc->pc);
8767
            dc->condjmp = 0;
8768
        }
8769
    }
8770

    
8771
done_generating:
8772
    gen_icount_end(tb, num_insns);
8773
    *gen_opc_ptr = INDEX_op_end;
8774

    
8775
#ifdef DEBUG_DISAS
8776
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8777
        fprintf(logfile, "----------------\n");
8778
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8779
        target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8780
        fprintf(logfile, "\n");
8781
    }
8782
#endif
8783
    if (search_pc) {
8784
        j = gen_opc_ptr - gen_opc_buf;
8785
        lj++;
8786
        while (lj <= j)
8787
            gen_opc_instr_start[lj++] = 0;
8788
    } else {
8789
        tb->size = dc->pc - pc_start;
8790
        tb->icount = num_insns;
8791
    }
8792
}
8793

    
8794
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8795
{
8796
    gen_intermediate_code_internal(env, tb, 0);
8797
}
8798

    
8799
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8800
{
8801
    gen_intermediate_code_internal(env, tb, 1);
8802
}
8803

    
8804
static const char *cpu_mode_names[16] = {
8805
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8806
  "???", "???", "???", "und", "???", "???", "???", "sys"
8807
};
8808

    
8809
void cpu_dump_state(CPUState *env, FILE *f,
8810
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8811
                    int flags)
8812
{
8813
    int i;
8814
#if 0
8815
    union {
8816
        uint32_t i;
8817
        float s;
8818
    } s0, s1;
8819
    CPU_DoubleU d;
8820
    /* ??? This assumes float64 and double have the same layout.
8821
       Oh well, it's only debug dumps.  */
8822
    union {
8823
        float64 f64;
8824
        double d;
8825
    } d0;
8826
#endif
8827
    uint32_t psr;
8828

    
8829
    for(i=0;i<16;i++) {
8830
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8831
        if ((i % 4) == 3)
8832
            cpu_fprintf(f, "\n");
8833
        else
8834
            cpu_fprintf(f, " ");
8835
    }
8836
    psr = cpsr_read(env);
8837
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8838
                psr,
8839
                psr & (1 << 31) ? 'N' : '-',
8840
                psr & (1 << 30) ? 'Z' : '-',
8841
                psr & (1 << 29) ? 'C' : '-',
8842
                psr & (1 << 28) ? 'V' : '-',
8843
                psr & CPSR_T ? 'T' : 'A',
8844
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8845

    
8846
#if 0
8847
    for (i = 0; i < 16; i++) {
8848
        d.d = env->vfp.regs[i];
8849
        s0.i = d.l.lower;
8850
        s1.i = d.l.upper;
8851
        d0.f64 = d.d;
8852
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8853
                    i * 2, (int)s0.i, s0.s,
8854
                    i * 2 + 1, (int)s1.i, s1.s,
8855
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8856
                    d0.d);
8857
    }
8858
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8859
#endif
8860
}
8861

    
8862
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8863
                unsigned long searched_pc, int pc_pos, void *puc)
8864
{
8865
    env->regs[15] = gen_opc_pc[pc_pos];
8866
}