Statistics
| Branch: | Revision:

root / target-arm / translate.c @ d60bb01c

History | View | Annotate | Download (296 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

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

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

    
42
#define ARCH(x) if (!ENABLE_ARCH_##x) goto illegal_op;
43

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

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

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

    
75
/* XXX: move that elsewhere */
76
extern FILE *logfile;
77
extern int loglevel;
78

    
79
static TCGv cpu_env;
80
/* We reuse the same 64-bit temporaries for efficiency.  */
81
static TCGv cpu_V0, cpu_V1, cpu_M0;
82

    
83
/* FIXME:  These should be removed.  */
84
static TCGv cpu_T[2];
85
static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
86

    
87
#define ICOUNT_TEMP cpu_T[0]
88
#include "gen-icount.h"
89

    
90
/* initialize TCG globals.  */
91
void arm_translate_init(void)
92
{
93
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
94

    
95
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
96
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
97
}
98

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

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

    
112
    if (GET_TCGV(temps[num_temps]))
113
      return temps[num_temps++];
114

    
115
    tmp = tcg_temp_new(TCG_TYPE_I32);
116
    temps[num_temps++] = tmp;
117
    return tmp;
118
}
119

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

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

    
139
static inline TCGv load_cpu_offset(int offset)
140
{
141
    TCGv tmp = new_tmp();
142
    tcg_gen_ld_i32(tmp, cpu_env, offset);
143
    return tmp;
144
}
145

    
146
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
147

    
148
static inline void store_cpu_offset(TCGv var, int offset)
149
{
150
    tcg_gen_st_i32(var, cpu_env, offset);
151
    dead_tmp(var);
152
}
153

    
154
#define store_cpu_field(var, name) \
155
    store_cpu_offset(var, offsetof(CPUState, name))
156

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

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

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

    
193

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

    
200
#define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
201
#define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
202
#define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
203
#define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
204

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

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

    
220
#define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
221
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
222
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
223
#define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
224
#define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
225

    
226
/* Value extensions.  */
227
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
228
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
229
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
230
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
231

    
232
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
233
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
234

    
235
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
236

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

    
241
static void gen_exception(int excp)
242
{
243
    TCGv tmp = new_tmp();
244
    tcg_gen_movi_i32(tmp, excp);
245
    gen_helper_exception(tmp);
246
    dead_tmp(tmp);
247
}
248

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

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

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

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

    
296
/* Signed bitfield extract.  */
297
static void gen_sbfx(TCGv var, int shift, int width)
298
{
299
    uint32_t signbit;
300

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

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

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

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

    
335
    tcg_gen_extu_i32_i64(tmp1, a);
336
    dead_tmp(a);
337
    tcg_gen_extu_i32_i64(tmp2, b);
338
    dead_tmp(b);
339
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
340
    return tmp1;
341
}
342

    
343
static TCGv gen_muls_i64_i32(TCGv a, TCGv b)
344
{
345
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
346
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
347

    
348
    tcg_gen_ext_i32_i64(tmp1, a);
349
    dead_tmp(a);
350
    tcg_gen_ext_i32_i64(tmp2, b);
351
    dead_tmp(b);
352
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
353
    return tmp1;
354
}
355

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

    
362
    tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
363
    tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
364
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
365
    tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
366
    tcg_gen_shri_i64(tmp1, tmp1, 32);
367
    tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
368
}
369

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

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

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

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

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

    
415
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
416

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

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

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

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

    
454
#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
455
#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
456

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

    
472
/* FIXME:  Implement this natively.  */
473
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
474

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

    
480
    if (i == 0)
481
        return;
482

    
483
    tmp = new_tmp();
484
    tcg_gen_shri_i32(tmp, t1, i);
485
    tcg_gen_shli_i32(t1, t1, 32 - i);
486
    tcg_gen_or_i32(t0, t1, tmp);
487
    dead_tmp(tmp);
488
}
489

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

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

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

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

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

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

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

    
664
static void gen_test_cc(int cc, int label)
665
{
666
    TCGv tmp;
667
    TCGv tmp2;
668
    int inv;
669

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

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

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

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

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

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

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

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

    
875
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
876
{
877
    load_reg_var(s, cpu_T[0], reg);
878
}
879

    
880
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
881
{
882
    load_reg_var(s, cpu_T[1], reg);
883
}
884

    
885
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
886
{
887
    load_reg_var(s, cpu_T[2], reg);
888
}
889

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

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

    
913
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
914
{
915
    gen_movl_reg_TN(s, reg, 0);
916
}
917

    
918
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
919
{
920
    gen_movl_reg_TN(s, reg, 1);
921
}
922

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

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

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

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

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

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

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

    
1005
VFP_OP2(add)
1006
VFP_OP2(sub)
1007
VFP_OP2(mul)
1008
VFP_OP2(div)
1009

    
1010
#undef VFP_OP2
1011

    
1012
static inline void gen_vfp_abs(int dp)
1013
{
1014
    if (dp)
1015
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1016
    else
1017
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1018
}
1019

    
1020
static inline void gen_vfp_neg(int dp)
1021
{
1022
    if (dp)
1023
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1024
    else
1025
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1026
}
1027

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1174
static TCGv neon_load_reg(int reg, int pass)
1175
{
1176
    TCGv tmp = new_tmp();
1177
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1178
    return tmp;
1179
}
1180

    
1181
static void neon_store_reg(int reg, int pass, TCGv var)
1182
{
1183
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1184
    dead_tmp(var);
1185
}
1186

    
1187
static inline void neon_load_reg64(TCGv var, int reg)
1188
{
1189
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1190
}
1191

    
1192
static inline void neon_store_reg64(TCGv var, int reg)
1193
{
1194
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1195
}
1196

    
1197
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1198
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1199
#define tcg_gen_st_f32 tcg_gen_st_i32
1200
#define tcg_gen_st_f64 tcg_gen_st_i64
1201

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

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

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

    
1226
#define ARM_CP_RW_BIT        (1 << 20)
1227

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

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

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

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

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

    
1253
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1254
{
1255
    iwmmxt_store_reg(cpu_M0, rn);
1256
}
1257

    
1258
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1259
{
1260
    iwmmxt_load_reg(cpu_M0, rn);
1261
}
1262

    
1263
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1264
{
1265
    iwmmxt_load_reg(cpu_V1, rn);
1266
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1267
}
1268

    
1269
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1270
{
1271
    iwmmxt_load_reg(cpu_V1, rn);
1272
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1273
}
1274

    
1275
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1276
{
1277
    iwmmxt_load_reg(cpu_V1, rn);
1278
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1279
}
1280

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

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

    
1295
#define IWMMXT_OP_ENV_SIZE(name) \
1296
IWMMXT_OP_ENV(name##b) \
1297
IWMMXT_OP_ENV(name##w) \
1298
IWMMXT_OP_ENV(name##l)
1299

    
1300
#define IWMMXT_OP_ENV1(name) \
1301
static inline void gen_op_iwmmxt_##name##_M0(void) \
1302
{ \
1303
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1304
}
1305

    
1306
IWMMXT_OP(maddsq)
1307
IWMMXT_OP(madduq)
1308
IWMMXT_OP(sadb)
1309
IWMMXT_OP(sadw)
1310
IWMMXT_OP(mulslw)
1311
IWMMXT_OP(mulshw)
1312
IWMMXT_OP(mululw)
1313
IWMMXT_OP(muluhw)
1314
IWMMXT_OP(macsw)
1315
IWMMXT_OP(macuw)
1316

    
1317
IWMMXT_OP_ENV_SIZE(unpackl)
1318
IWMMXT_OP_ENV_SIZE(unpackh)
1319

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

    
1333
IWMMXT_OP_ENV_SIZE(cmpeq)
1334
IWMMXT_OP_ENV_SIZE(cmpgtu)
1335
IWMMXT_OP_ENV_SIZE(cmpgts)
1336

    
1337
IWMMXT_OP_ENV_SIZE(mins)
1338
IWMMXT_OP_ENV_SIZE(minu)
1339
IWMMXT_OP_ENV_SIZE(maxs)
1340
IWMMXT_OP_ENV_SIZE(maxu)
1341

    
1342
IWMMXT_OP_ENV_SIZE(subn)
1343
IWMMXT_OP_ENV_SIZE(addn)
1344
IWMMXT_OP_ENV_SIZE(subu)
1345
IWMMXT_OP_ENV_SIZE(addu)
1346
IWMMXT_OP_ENV_SIZE(subs)
1347
IWMMXT_OP_ENV_SIZE(adds)
1348

    
1349
IWMMXT_OP_ENV(avgb0)
1350
IWMMXT_OP_ENV(avgb1)
1351
IWMMXT_OP_ENV(avgw0)
1352
IWMMXT_OP_ENV(avgw1)
1353

    
1354
IWMMXT_OP(msadb)
1355

    
1356
IWMMXT_OP_ENV(packuw)
1357
IWMMXT_OP_ENV(packul)
1358
IWMMXT_OP_ENV(packuq)
1359
IWMMXT_OP_ENV(packsw)
1360
IWMMXT_OP_ENV(packsl)
1361
IWMMXT_OP_ENV(packsq)
1362

    
1363
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1364
{
1365
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1366
}
1367

    
1368
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1369
{
1370
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1371
}
1372

    
1373
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1374
{
1375
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1376
}
1377

    
1378
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1379
{
1380
    iwmmxt_load_reg(cpu_V1, rn);
1381
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1382
}
1383

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

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

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

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

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

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

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

    
1435
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1436
{
1437
    iwmmxt_load_reg(cpu_V1, rn);
1438
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1439
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1440
}
1441

    
1442

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

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

    
1460
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1461
{
1462
    int rd;
1463
    uint32_t offset;
1464

    
1465
    rd = (insn >> 16) & 0xf;
1466
    gen_movl_T1_reg(s, rd);
1467

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

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

    
1491
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1492
{
1493
    int rd = (insn >> 0) & 0xf;
1494

    
1495
    if (insn & (1 << 8))
1496
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1497
            return 1;
1498
        else
1499
            gen_op_iwmmxt_movl_T0_wCx(rd);
1500
    else
1501
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1502

    
1503
    gen_op_movl_T1_im(mask);
1504
    gen_op_andl_T0_T1();
1505
    return 0;
1506
}
1507

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

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

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

    
1596
    if ((insn & 0x0f000000) != 0x0e000000)
1597
        return 1;
1598

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

    
2471
    return 0;
2472
}
2473

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

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

    
2486
        if (acc != 0)
2487
            return 1;
2488

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

    
2517
        gen_op_iwmmxt_movq_wRn_M0(acc);
2518
        return 0;
2519
    }
2520

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

    
2527
        if (acc != 0)
2528
            return 1;
2529

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

    
2544
    return 1;
2545
}
2546

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

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

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

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

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

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

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

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

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

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

    
2680
static void gen_vfp_msr(TCGv tmp)
2681
{
2682
    tcg_gen_mov_i32(cpu_F0s, tmp);
2683
    dead_tmp(tmp);
2684
}
2685

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

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

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

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

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

    
2732
    if (!arm_feature(env, ARM_FEATURE_VFP))
2733
        return 1;
2734

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

    
2754
                VFP_DREG_N(rn, insn);
2755
                if (insn & 0xf)
2756
                    return 1;
2757
                if (insn & 0x00c00060
2758
                    && !arm_feature(env, ARM_FEATURE_NEON))
2759
                    return 1;
2760

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

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

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

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

    
2972
            veclen = env->vfp.vec_len;
2973
            if (op == 15 && rn > 3)
2974
                veclen = 0;
2975

    
2976
            /* Shut up compiler warnings.  */
2977
            delta_m = 0;
2978
            delta_d = 0;
2979
            bank_mask = 0;
2980

    
2981
            if (veclen > 0) {
2982
                if (dp)
2983
                    bank_mask = 0xc;
2984
                else
2985
                    bank_mask = 0x18;
2986

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

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

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

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

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

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

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

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

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

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

    
3337
                if (insn & (1 << 24)) /* pre-decrement */
3338
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3339

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

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

    
3379
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3380
{
3381
    TranslationBlock *tb;
3382

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3522
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3523

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

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

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

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

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

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

    
3603
static inline void
3604
gen_neon_movl_scratch_T0(int scratch)
3605
{
3606
  uint32_t offset;
3607

    
3608
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3609
  tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3610
}
3611

    
3612
static inline void
3613
gen_neon_movl_scratch_T1(int scratch)
3614
{
3615
  uint32_t offset;
3616

    
3617
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3618
  tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3619
}
3620

    
3621
static inline void
3622
gen_neon_movl_T0_scratch(int scratch)
3623
{
3624
  uint32_t offset;
3625

    
3626
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3627
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3628
}
3629

    
3630
static inline void
3631
gen_neon_movl_T1_scratch(int scratch)
3632
{
3633
  uint32_t offset;
3634

    
3635
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3636
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3637
}
3638

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

    
3652
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3653
{
3654
    int n;
3655

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4039
static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4040
{
4041
    TCGv tmp;
4042

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

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

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

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

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

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

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

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

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

    
4704
                    gen_neon_widen(cpu_V0, tmp, size, u);
4705

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

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

    
4789
            if (op != 14 || !invert)
4790
                gen_op_movl_T1_im(imm);
4791

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

    
4847
                prewiden = neon_3reg_wide[op][0];
4848
                src1_wide = neon_3reg_wide[op][1];
4849
                src2_wide = neon_3reg_wide[op][2];
4850

    
4851
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4852
                    return 1;
4853

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

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

    
4944
                        if (op != 13) {
4945
                            neon_load_reg64(cpu_V1, rd + pass);
4946
                        }
4947

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

    
5079
                    gen_neon_get_scalar(size, rm);
5080
                    NEON_GET_REG(T1, rn, 1);
5081

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

    
5128
                if (imm > 7 && !q)
5129
                    return 1;
5130

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

    
5557
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5558
{
5559
    int cpnum;
5560

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

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

    
5586

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

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

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

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

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

    
5628
    tmp2 = load_reg(s, rlow);
5629
    tcg_gen_extu_i32_i64(tmp, tmp2);
5630
    dead_tmp(tmp2);
5631
    tcg_gen_add_i64(val, val, tmp);
5632
}
5633

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

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

    
5651
    insn = ldl_code(s->pc);
5652
    s->pc += 4;
5653

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7907
    insn = lduw_code(s->pc);
7908
    s->pc += 2;
7909

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8453
        default:
8454
            goto undef;
8455
        }
8456
        break;
8457

    
8458
    case 12:
8459
        /* load/store multiple */
8460
        rn = (insn >> 8) & 0x7;
8461
        addr = load_reg(s, rn);
8462
        for (i = 0; i < 8; i++) {
8463
            if (insn & (1 << i)) {
8464
                if (insn & (1 << 11)) {
8465
                    /* load */
8466
                    tmp = gen_ld32(addr, IS_USER(s));
8467
                    store_reg(s, i, tmp);
8468
                } else {
8469
                    /* store */
8470
                    tmp = load_reg(s, i);
8471
                    gen_st32(tmp, addr, IS_USER(s));
8472
                }
8473
                /* advance to the next address */
8474
                tcg_gen_addi_i32(addr, addr, 4);
8475
            }
8476
        }
8477
        /* Base register writeback.  */
8478
        if ((insn & (1 << rn)) == 0) {
8479
            store_reg(s, rn, addr);
8480
        } else {
8481
            dead_tmp(addr);
8482
        }
8483
        break;
8484

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

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

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

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

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

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

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

    
8563
    pc_start = tb->pc;
8564

    
8565
    dc->tb = tb;
8566

    
8567
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8568

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

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

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

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

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

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

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

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

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

    
8769
done_generating:
8770
    gen_icount_end(tb, num_insns);
8771
    *gen_opc_ptr = INDEX_op_end;
8772

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

    
8793
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8794
{
8795
    return gen_intermediate_code_internal(env, tb, 0);
8796
}
8797

    
8798
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8799
{
8800
    return gen_intermediate_code_internal(env, tb, 1);
8801
}
8802

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

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

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

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

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