Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 72cf2d4f

History | View | Annotate | Download (300.6 kB)

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

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

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

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

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

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

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

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

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

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

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

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

    
92
    cpu_T[0] = tcg_global_reg_new_i32(TCG_AREG1, "T0");
93
    cpu_T[1] = tcg_global_reg_new_i32(TCG_AREG2, "T1");
94

    
95
#define GEN_HELPER 2
96
#include "helpers.h"
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_i32 new_tmp(void)
107
{
108
    TCGv tmp;
109
    if (num_temps == MAX_TEMPS)
110
        abort();
111

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

    
115
    tmp = tcg_temp_new_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 (TCGV_EQUAL(temps[i], tmp))
127
        return;
128

    
129
    /* Shuffle this temp to the last slot.  */
130
    while (!TCGV_EQUAL(temps[i], 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_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
197
#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
198

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

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

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

    
218
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
219
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
220

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

    
227
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
228
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
229

    
230
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
231

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

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

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

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

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

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

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

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

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

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

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

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

    
338
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
339
{
340
    TCGv_i64 tmp1 = tcg_temp_new_i64();
341
    TCGv_i64 tmp2 = tcg_temp_new_i64();
342

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

    
351
/* Unsigned 32x32->64 multiply.  */
352
static void gen_op_mull_T0_T1(void)
353
{
354
    TCGv_i64 tmp1 = tcg_temp_new_i64();
355
    TCGv_i64 tmp2 = tcg_temp_new_i64();
356

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

    
365
/* Signed 32x32->64 multiply.  */
366
static void gen_imull(TCGv a, TCGv b)
367
{
368
    TCGv_i64 tmp1 = tcg_temp_new_i64();
369
    TCGv_i64 tmp2 = tcg_temp_new_i64();
370

    
371
    tcg_gen_ext_i32_i64(tmp1, a);
372
    tcg_gen_ext_i32_i64(tmp2, b);
373
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
374
    tcg_gen_trunc_i64_i32(a, tmp1);
375
    tcg_gen_shri_i64(tmp1, tmp1, 32);
376
    tcg_gen_trunc_i64_i32(b, tmp1);
377
}
378

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

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

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

    
409
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
410

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

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

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

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

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

    
458
#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
459
#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
460

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

    
476
/* FIXME:  Implement this natively.  */
477
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
478

    
479
/* FIXME:  Implement this natively.  */
480
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
481
{
482
    TCGv tmp;
483

    
484
    if (i == 0)
485
        return;
486

    
487
    tmp = new_tmp();
488
    tcg_gen_shri_i32(tmp, t1, i);
489
    tcg_gen_shli_i32(t1, t1, 32 - i);
490
    tcg_gen_or_i32(t0, t1, tmp);
491
    dead_tmp(tmp);
492
}
493

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

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

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

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

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

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

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

    
668
static void gen_test_cc(int cc, int label)
669
{
670
    TCGv tmp;
671
    TCGv tmp2;
672
    int inv;
673

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

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

    
785
/* Set PC and Thumb state from an immediate address.  */
786
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
787
{
788
    TCGv tmp;
789

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

    
801
/* Set PC and Thumb state from var.  var is marked as dead.  */
802
static inline void gen_bx(DisasContext *s, TCGv var)
803
{
804
    TCGv tmp;
805

    
806
    s->is_jmp = DISAS_UPDATE;
807
    tmp = new_tmp();
808
    tcg_gen_andi_i32(tmp, var, 1);
809
    store_cpu_field(tmp, thumb);
810
    tcg_gen_andi_i32(var, var, ~1);
811
    store_cpu_field(var, regs[15]);
812
}
813

    
814
/* Variant of store_reg which uses branch&exchange logic when storing
815
   to r15 in ARM architecture v7 and above. The source must be a temporary
816
   and will be marked as dead. */
817
static inline void store_reg_bx(CPUState *env, DisasContext *s,
818
                                int reg, TCGv var)
819
{
820
    if (reg == 15 && ENABLE_ARCH_7) {
821
        gen_bx(s, var);
822
    } else {
823
        store_reg(s, reg, var);
824
    }
825
}
826

    
827
static inline TCGv gen_ld8s(TCGv addr, int index)
828
{
829
    TCGv tmp = new_tmp();
830
    tcg_gen_qemu_ld8s(tmp, addr, index);
831
    return tmp;
832
}
833
static inline TCGv gen_ld8u(TCGv addr, int index)
834
{
835
    TCGv tmp = new_tmp();
836
    tcg_gen_qemu_ld8u(tmp, addr, index);
837
    return tmp;
838
}
839
static inline TCGv gen_ld16s(TCGv addr, int index)
840
{
841
    TCGv tmp = new_tmp();
842
    tcg_gen_qemu_ld16s(tmp, addr, index);
843
    return tmp;
844
}
845
static inline TCGv gen_ld16u(TCGv addr, int index)
846
{
847
    TCGv tmp = new_tmp();
848
    tcg_gen_qemu_ld16u(tmp, addr, index);
849
    return tmp;
850
}
851
static inline TCGv gen_ld32(TCGv addr, int index)
852
{
853
    TCGv tmp = new_tmp();
854
    tcg_gen_qemu_ld32u(tmp, addr, index);
855
    return tmp;
856
}
857
static inline void gen_st8(TCGv val, TCGv addr, int index)
858
{
859
    tcg_gen_qemu_st8(val, addr, index);
860
    dead_tmp(val);
861
}
862
static inline void gen_st16(TCGv val, TCGv addr, int index)
863
{
864
    tcg_gen_qemu_st16(val, addr, index);
865
    dead_tmp(val);
866
}
867
static inline void gen_st32(TCGv val, TCGv addr, int index)
868
{
869
    tcg_gen_qemu_st32(val, addr, index);
870
    dead_tmp(val);
871
}
872

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

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

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

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

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

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

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

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

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

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

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

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

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

    
994
VFP_OP2(add)
995
VFP_OP2(sub)
996
VFP_OP2(mul)
997
VFP_OP2(div)
998

    
999
#undef VFP_OP2
1000

    
1001
static inline void gen_vfp_abs(int dp)
1002
{
1003
    if (dp)
1004
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1005
    else
1006
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1007
}
1008

    
1009
static inline void gen_vfp_neg(int dp)
1010
{
1011
    if (dp)
1012
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1013
    else
1014
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1015
}
1016

    
1017
static inline void gen_vfp_sqrt(int dp)
1018
{
1019
    if (dp)
1020
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1021
    else
1022
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1023
}
1024

    
1025
static inline void gen_vfp_cmp(int dp)
1026
{
1027
    if (dp)
1028
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1029
    else
1030
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1031
}
1032

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

    
1041
static inline void gen_vfp_F1_ld0(int dp)
1042
{
1043
    if (dp)
1044
        tcg_gen_movi_i64(cpu_F1d, 0);
1045
    else
1046
        tcg_gen_movi_i32(cpu_F1s, 0);
1047
}
1048

    
1049
static inline void gen_vfp_uito(int dp)
1050
{
1051
    if (dp)
1052
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1053
    else
1054
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1055
}
1056

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

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

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

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

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

    
1097
#define VFP_GEN_FIX(name) \
1098
static inline void gen_vfp_##name(int dp, int shift) \
1099
{ \
1100
    if (dp) \
1101
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1102
    else \
1103
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1104
}
1105
VFP_GEN_FIX(tosh)
1106
VFP_GEN_FIX(tosl)
1107
VFP_GEN_FIX(touh)
1108
VFP_GEN_FIX(toul)
1109
VFP_GEN_FIX(shto)
1110
VFP_GEN_FIX(slto)
1111
VFP_GEN_FIX(uhto)
1112
VFP_GEN_FIX(ulto)
1113
#undef VFP_GEN_FIX
1114

    
1115
static inline void gen_vfp_ld(DisasContext *s, int dp)
1116
{
1117
    if (dp)
1118
        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1119
    else
1120
        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1121
}
1122

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

    
1131
static inline long
1132
vfp_reg_offset (int dp, int reg)
1133
{
1134
    if (dp)
1135
        return offsetof(CPUARMState, vfp.regs[reg]);
1136
    else if (reg & 1) {
1137
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1138
          + offsetof(CPU_DoubleU, l.upper);
1139
    } else {
1140
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1141
          + offsetof(CPU_DoubleU, l.lower);
1142
    }
1143
}
1144

    
1145
/* Return the offset of a 32-bit piece of a NEON register.
1146
   zero is the least significant end of the register.  */
1147
static inline long
1148
neon_reg_offset (int reg, int n)
1149
{
1150
    int sreg;
1151
    sreg = reg * 2 + n;
1152
    return vfp_reg_offset(0, sreg);
1153
}
1154

    
1155
/* FIXME: Remove these.  */
1156
#define neon_T0 cpu_T[0]
1157
#define neon_T1 cpu_T[1]
1158
#define NEON_GET_REG(T, reg, n) \
1159
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1160
#define NEON_SET_REG(T, reg, n) \
1161
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1162

    
1163
static TCGv neon_load_reg(int reg, int pass)
1164
{
1165
    TCGv tmp = new_tmp();
1166
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1167
    return tmp;
1168
}
1169

    
1170
static void neon_store_reg(int reg, int pass, TCGv var)
1171
{
1172
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1173
    dead_tmp(var);
1174
}
1175

    
1176
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1177
{
1178
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1179
}
1180

    
1181
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1182
{
1183
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1184
}
1185

    
1186
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1187
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1188
#define tcg_gen_st_f32 tcg_gen_st_i32
1189
#define tcg_gen_st_f64 tcg_gen_st_i64
1190

    
1191
static inline void gen_mov_F0_vreg(int dp, int reg)
1192
{
1193
    if (dp)
1194
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1195
    else
1196
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1197
}
1198

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

    
1207
static inline void gen_mov_vreg_F0(int dp, int reg)
1208
{
1209
    if (dp)
1210
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1211
    else
1212
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1213
}
1214

    
1215
#define ARM_CP_RW_BIT        (1 << 20)
1216

    
1217
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1218
{
1219
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1220
}
1221

    
1222
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1223
{
1224
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1225
}
1226

    
1227
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1228
{
1229
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1230
}
1231

    
1232
static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1233
{
1234
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1235
}
1236

    
1237
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1238
{
1239
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1240
}
1241

    
1242
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1243
{
1244
    iwmmxt_store_reg(cpu_M0, rn);
1245
}
1246

    
1247
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1248
{
1249
    iwmmxt_load_reg(cpu_M0, rn);
1250
}
1251

    
1252
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1253
{
1254
    iwmmxt_load_reg(cpu_V1, rn);
1255
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1256
}
1257

    
1258
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1259
{
1260
    iwmmxt_load_reg(cpu_V1, rn);
1261
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1262
}
1263

    
1264
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1265
{
1266
    iwmmxt_load_reg(cpu_V1, rn);
1267
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1268
}
1269

    
1270
#define IWMMXT_OP(name) \
1271
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1272
{ \
1273
    iwmmxt_load_reg(cpu_V1, rn); \
1274
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1275
}
1276

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

    
1284
#define IWMMXT_OP_ENV_SIZE(name) \
1285
IWMMXT_OP_ENV(name##b) \
1286
IWMMXT_OP_ENV(name##w) \
1287
IWMMXT_OP_ENV(name##l)
1288

    
1289
#define IWMMXT_OP_ENV1(name) \
1290
static inline void gen_op_iwmmxt_##name##_M0(void) \
1291
{ \
1292
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1293
}
1294

    
1295
IWMMXT_OP(maddsq)
1296
IWMMXT_OP(madduq)
1297
IWMMXT_OP(sadb)
1298
IWMMXT_OP(sadw)
1299
IWMMXT_OP(mulslw)
1300
IWMMXT_OP(mulshw)
1301
IWMMXT_OP(mululw)
1302
IWMMXT_OP(muluhw)
1303
IWMMXT_OP(macsw)
1304
IWMMXT_OP(macuw)
1305

    
1306
IWMMXT_OP_ENV_SIZE(unpackl)
1307
IWMMXT_OP_ENV_SIZE(unpackh)
1308

    
1309
IWMMXT_OP_ENV1(unpacklub)
1310
IWMMXT_OP_ENV1(unpackluw)
1311
IWMMXT_OP_ENV1(unpacklul)
1312
IWMMXT_OP_ENV1(unpackhub)
1313
IWMMXT_OP_ENV1(unpackhuw)
1314
IWMMXT_OP_ENV1(unpackhul)
1315
IWMMXT_OP_ENV1(unpacklsb)
1316
IWMMXT_OP_ENV1(unpacklsw)
1317
IWMMXT_OP_ENV1(unpacklsl)
1318
IWMMXT_OP_ENV1(unpackhsb)
1319
IWMMXT_OP_ENV1(unpackhsw)
1320
IWMMXT_OP_ENV1(unpackhsl)
1321

    
1322
IWMMXT_OP_ENV_SIZE(cmpeq)
1323
IWMMXT_OP_ENV_SIZE(cmpgtu)
1324
IWMMXT_OP_ENV_SIZE(cmpgts)
1325

    
1326
IWMMXT_OP_ENV_SIZE(mins)
1327
IWMMXT_OP_ENV_SIZE(minu)
1328
IWMMXT_OP_ENV_SIZE(maxs)
1329
IWMMXT_OP_ENV_SIZE(maxu)
1330

    
1331
IWMMXT_OP_ENV_SIZE(subn)
1332
IWMMXT_OP_ENV_SIZE(addn)
1333
IWMMXT_OP_ENV_SIZE(subu)
1334
IWMMXT_OP_ENV_SIZE(addu)
1335
IWMMXT_OP_ENV_SIZE(subs)
1336
IWMMXT_OP_ENV_SIZE(adds)
1337

    
1338
IWMMXT_OP_ENV(avgb0)
1339
IWMMXT_OP_ENV(avgb1)
1340
IWMMXT_OP_ENV(avgw0)
1341
IWMMXT_OP_ENV(avgw1)
1342

    
1343
IWMMXT_OP(msadb)
1344

    
1345
IWMMXT_OP_ENV(packuw)
1346
IWMMXT_OP_ENV(packul)
1347
IWMMXT_OP_ENV(packuq)
1348
IWMMXT_OP_ENV(packsw)
1349
IWMMXT_OP_ENV(packsl)
1350
IWMMXT_OP_ENV(packsq)
1351

    
1352
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1353
{
1354
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1355
}
1356

    
1357
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1358
{
1359
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1360
}
1361

    
1362
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1363
{
1364
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1365
}
1366

    
1367
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1368
{
1369
    iwmmxt_load_reg(cpu_V1, rn);
1370
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1371
}
1372

    
1373
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1374
{
1375
    TCGv tmp = tcg_const_i32(shift);
1376
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1377
}
1378

    
1379
static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1380
{
1381
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1382
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1383
    tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1384
}
1385

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

    
1393
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1394
{
1395
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1396
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1397
    if (mask != ~0u)
1398
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1399
}
1400

    
1401
static void gen_op_iwmmxt_set_mup(void)
1402
{
1403
    TCGv tmp;
1404
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1405
    tcg_gen_ori_i32(tmp, tmp, 2);
1406
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1407
}
1408

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

    
1417
static void gen_op_iwmmxt_setpsr_nz(void)
1418
{
1419
    TCGv tmp = new_tmp();
1420
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1421
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1422
}
1423

    
1424
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1425
{
1426
    iwmmxt_load_reg(cpu_V1, rn);
1427
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1428
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1429
}
1430

    
1431

    
1432
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1433
{
1434
    iwmmxt_load_reg(cpu_V0, rn);
1435
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1436
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1437
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1438
}
1439

    
1440
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1441
{
1442
    tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
1443
    iwmmxt_store_reg(cpu_V0, rn);
1444
}
1445

    
1446
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1447
{
1448
    int rd;
1449
    uint32_t offset;
1450

    
1451
    rd = (insn >> 16) & 0xf;
1452
    gen_movl_T1_reg(s, rd);
1453

    
1454
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1455
    if (insn & (1 << 24)) {
1456
        /* Pre indexed */
1457
        if (insn & (1 << 23))
1458
            gen_op_addl_T1_im(offset);
1459
        else
1460
            gen_op_addl_T1_im(-offset);
1461

    
1462
        if (insn & (1 << 21))
1463
            gen_movl_reg_T1(s, rd);
1464
    } else if (insn & (1 << 21)) {
1465
        /* Post indexed */
1466
        if (insn & (1 << 23))
1467
            gen_op_movl_T0_im(offset);
1468
        else
1469
            gen_op_movl_T0_im(- offset);
1470
        gen_op_addl_T0_T1();
1471
        gen_movl_reg_T0(s, rd);
1472
    } else if (!(insn & (1 << 23)))
1473
        return 1;
1474
    return 0;
1475
}
1476

    
1477
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1478
{
1479
    int rd = (insn >> 0) & 0xf;
1480

    
1481
    if (insn & (1 << 8))
1482
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1483
            return 1;
1484
        else
1485
            gen_op_iwmmxt_movl_T0_wCx(rd);
1486
    else
1487
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1488

    
1489
    gen_op_movl_T1_im(mask);
1490
    gen_op_andl_T0_T1();
1491
    return 0;
1492
}
1493

    
1494
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1495
   (ie. an undefined instruction).  */
1496
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1497
{
1498
    int rd, wrd;
1499
    int rdhi, rdlo, rd0, rd1, i;
1500
    TCGv tmp;
1501

    
1502
    if ((insn & 0x0e000e00) == 0x0c000000) {
1503
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1504
            wrd = insn & 0xf;
1505
            rdlo = (insn >> 12) & 0xf;
1506
            rdhi = (insn >> 16) & 0xf;
1507
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1508
                gen_iwmmxt_movl_T0_T1_wRn(wrd);
1509
                gen_movl_reg_T0(s, rdlo);
1510
                gen_movl_reg_T1(s, rdhi);
1511
            } else {                                        /* TMCRR */
1512
                gen_movl_T0_reg(s, rdlo);
1513
                gen_movl_T1_reg(s, rdhi);
1514
                gen_iwmmxt_movl_wRn_T0_T1(wrd);
1515
                gen_op_iwmmxt_set_mup();
1516
            }
1517
            return 0;
1518
        }
1519

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

    
1582
    if ((insn & 0x0f000000) != 0x0e000000)
1583
        return 1;
1584

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

    
2457
    return 0;
2458
}
2459

    
2460
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2461
   (ie. an undefined instruction).  */
2462
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2463
{
2464
    int acc, rd0, rd1, rdhi, rdlo;
2465

    
2466
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2467
        /* Multiply with Internal Accumulate Format */
2468
        rd0 = (insn >> 12) & 0xf;
2469
        rd1 = insn & 0xf;
2470
        acc = (insn >> 5) & 7;
2471

    
2472
        if (acc != 0)
2473
            return 1;
2474

    
2475
        switch ((insn >> 16) & 0xf) {
2476
        case 0x0:                                        /* MIA */
2477
            gen_movl_T0_reg(s, rd0);
2478
            gen_movl_T1_reg(s, rd1);
2479
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2480
            break;
2481
        case 0x8:                                        /* MIAPH */
2482
            gen_movl_T0_reg(s, rd0);
2483
            gen_movl_T1_reg(s, rd1);
2484
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2485
            break;
2486
        case 0xc:                                        /* MIABB */
2487
        case 0xd:                                        /* MIABT */
2488
        case 0xe:                                        /* MIATB */
2489
        case 0xf:                                        /* MIATT */
2490
            gen_movl_T1_reg(s, rd0);
2491
            if (insn & (1 << 16))
2492
                gen_op_shrl_T1_im(16);
2493
            gen_op_movl_T0_T1();
2494
            gen_movl_T1_reg(s, rd1);
2495
            if (insn & (1 << 17))
2496
                gen_op_shrl_T1_im(16);
2497
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2498
            break;
2499
        default:
2500
            return 1;
2501
        }
2502

    
2503
        gen_op_iwmmxt_movq_wRn_M0(acc);
2504
        return 0;
2505
    }
2506

    
2507
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2508
        /* Internal Accumulator Access Format */
2509
        rdhi = (insn >> 16) & 0xf;
2510
        rdlo = (insn >> 12) & 0xf;
2511
        acc = insn & 7;
2512

    
2513
        if (acc != 0)
2514
            return 1;
2515

    
2516
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2517
            gen_iwmmxt_movl_T0_T1_wRn(acc);
2518
            gen_movl_reg_T0(s, rdlo);
2519
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2520
            gen_op_andl_T0_T1();
2521
            gen_movl_reg_T0(s, rdhi);
2522
        } else {                                        /* MAR */
2523
            gen_movl_T0_reg(s, rdlo);
2524
            gen_movl_T1_reg(s, rdhi);
2525
            gen_iwmmxt_movl_wRn_T0_T1(acc);
2526
        }
2527
        return 0;
2528
    }
2529

    
2530
    return 1;
2531
}
2532

    
2533
/* Disassemble system coprocessor instruction.  Return nonzero if
2534
   instruction is not defined.  */
2535
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2536
{
2537
    TCGv tmp;
2538
    uint32_t rd = (insn >> 12) & 0xf;
2539
    uint32_t cp = (insn >> 8) & 0xf;
2540
    if (IS_USER(s)) {
2541
        return 1;
2542
    }
2543

    
2544
    if (insn & ARM_CP_RW_BIT) {
2545
        if (!env->cp[cp].cp_read)
2546
            return 1;
2547
        gen_set_pc_im(s->pc);
2548
        tmp = new_tmp();
2549
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2550
        store_reg(s, rd, tmp);
2551
    } else {
2552
        if (!env->cp[cp].cp_write)
2553
            return 1;
2554
        gen_set_pc_im(s->pc);
2555
        tmp = load_reg(s, rd);
2556
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2557
        dead_tmp(tmp);
2558
    }
2559
    return 0;
2560
}
2561

    
2562
static int cp15_user_ok(uint32_t insn)
2563
{
2564
    int cpn = (insn >> 16) & 0xf;
2565
    int cpm = insn & 0xf;
2566
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2567

    
2568
    if (cpn == 13 && cpm == 0) {
2569
        /* TLS register.  */
2570
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2571
            return 1;
2572
    }
2573
    if (cpn == 7) {
2574
        /* ISB, DSB, DMB.  */
2575
        if ((cpm == 5 && op == 4)
2576
                || (cpm == 10 && (op == 4 || op == 5)))
2577
            return 1;
2578
    }
2579
    return 0;
2580
}
2581

    
2582
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2583
   instruction is not defined.  */
2584
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2585
{
2586
    uint32_t rd;
2587
    TCGv tmp;
2588

    
2589
    /* M profile cores use memory mapped registers instead of cp15.  */
2590
    if (arm_feature(env, ARM_FEATURE_M))
2591
        return 1;
2592

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

    
2638
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2639
#define VFP_SREG(insn, bigbit, smallbit) \
2640
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2641
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2642
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2643
        reg = (((insn) >> (bigbit)) & 0x0f) \
2644
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2645
    } else { \
2646
        if (insn & (1 << (smallbit))) \
2647
            return 1; \
2648
        reg = ((insn) >> (bigbit)) & 0x0f; \
2649
    }} while (0)
2650

    
2651
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2652
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2653
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2654
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2655
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2656
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2657

    
2658
/* Move between integer and VFP cores.  */
2659
static TCGv gen_vfp_mrs(void)
2660
{
2661
    TCGv tmp = new_tmp();
2662
    tcg_gen_mov_i32(tmp, cpu_F0s);
2663
    return tmp;
2664
}
2665

    
2666
static void gen_vfp_msr(TCGv tmp)
2667
{
2668
    tcg_gen_mov_i32(cpu_F0s, tmp);
2669
    dead_tmp(tmp);
2670
}
2671

    
2672
static inline int
2673
vfp_enabled(CPUState * env)
2674
{
2675
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2676
}
2677

    
2678
static void gen_neon_dup_u8(TCGv var, int shift)
2679
{
2680
    TCGv tmp = new_tmp();
2681
    if (shift)
2682
        tcg_gen_shri_i32(var, var, shift);
2683
    tcg_gen_ext8u_i32(var, var);
2684
    tcg_gen_shli_i32(tmp, var, 8);
2685
    tcg_gen_or_i32(var, var, tmp);
2686
    tcg_gen_shli_i32(tmp, var, 16);
2687
    tcg_gen_or_i32(var, var, tmp);
2688
    dead_tmp(tmp);
2689
}
2690

    
2691
static void gen_neon_dup_low16(TCGv var)
2692
{
2693
    TCGv tmp = new_tmp();
2694
    tcg_gen_ext16u_i32(var, var);
2695
    tcg_gen_shli_i32(tmp, var, 16);
2696
    tcg_gen_or_i32(var, var, tmp);
2697
    dead_tmp(tmp);
2698
}
2699

    
2700
static void gen_neon_dup_high16(TCGv var)
2701
{
2702
    TCGv tmp = new_tmp();
2703
    tcg_gen_andi_i32(var, var, 0xffff0000);
2704
    tcg_gen_shri_i32(tmp, var, 16);
2705
    tcg_gen_or_i32(var, var, tmp);
2706
    dead_tmp(tmp);
2707
}
2708

    
2709
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2710
   (ie. an undefined instruction).  */
2711
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2712
{
2713
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2714
    int dp, veclen;
2715
    TCGv tmp;
2716
    TCGv tmp2;
2717

    
2718
    if (!arm_feature(env, ARM_FEATURE_VFP))
2719
        return 1;
2720

    
2721
    if (!vfp_enabled(env)) {
2722
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2723
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2724
            return 1;
2725
        rn = (insn >> 16) & 0xf;
2726
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2727
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2728
            return 1;
2729
    }
2730
    dp = ((insn & 0xf00) == 0xb00);
2731
    switch ((insn >> 24) & 0xf) {
2732
    case 0xe:
2733
        if (insn & (1 << 4)) {
2734
            /* single register transfer */
2735
            rd = (insn >> 12) & 0xf;
2736
            if (dp) {
2737
                int size;
2738
                int pass;
2739

    
2740
                VFP_DREG_N(rn, insn);
2741
                if (insn & 0xf)
2742
                    return 1;
2743
                if (insn & 0x00c00060
2744
                    && !arm_feature(env, ARM_FEATURE_NEON))
2745
                    return 1;
2746

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

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

    
2936
                if (op == 15 && (rn == 15 || rn > 17)) {
2937
                    /* Integer or single precision destination.  */
2938
                    rd = VFP_SREG_D(insn);
2939
                } else {
2940
                    VFP_DREG_D(rd, insn);
2941
                }
2942

    
2943
                if (op == 15 && (rn == 16 || rn == 17)) {
2944
                    /* Integer source.  */
2945
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2946
                } else {
2947
                    VFP_DREG_M(rm, insn);
2948
                }
2949
            } else {
2950
                rn = VFP_SREG_N(insn);
2951
                if (op == 15 && rn == 15) {
2952
                    /* Double precision destination.  */
2953
                    VFP_DREG_D(rd, insn);
2954
                } else {
2955
                    rd = VFP_SREG_D(insn);
2956
                }
2957
                rm = VFP_SREG_M(insn);
2958
            }
2959

    
2960
            veclen = env->vfp.vec_len;
2961
            if (op == 15 && rn > 3)
2962
                veclen = 0;
2963

    
2964
            /* Shut up compiler warnings.  */
2965
            delta_m = 0;
2966
            delta_d = 0;
2967
            bank_mask = 0;
2968

    
2969
            if (veclen > 0) {
2970
                if (dp)
2971
                    bank_mask = 0xc;
2972
                else
2973
                    bank_mask = 0x18;
2974

    
2975
                /* Figure out what type of vector operation this is.  */
2976
                if ((rd & bank_mask) == 0) {
2977
                    /* scalar */
2978
                    veclen = 0;
2979
                } else {
2980
                    if (dp)
2981
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2982
                    else
2983
                        delta_d = env->vfp.vec_stride + 1;
2984

    
2985
                    if ((rm & bank_mask) == 0) {
2986
                        /* mixed scalar/vector */
2987
                        delta_m = 0;
2988
                    } else {
2989
                        /* vector */
2990
                        delta_m = delta_d;
2991
                    }
2992
                }
2993
            }
2994

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

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

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

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

    
3213
                /* break out of the loop if we have finished  */
3214
                if (veclen == 0)
3215
                    break;
3216

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

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

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

    
3329
                if (insn & (1 << 24)) /* pre-decrement */
3330
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3331

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

    
3357
                    if (offset != 0)
3358
                        gen_op_addl_T1_im(offset);
3359
                    gen_movl_reg_T1(s, rn);
3360
                }
3361
            }
3362
        }
3363
        break;
3364
    default:
3365
        /* Should never happen.  */
3366
        return 1;
3367
    }
3368
    return 0;
3369
}
3370

    
3371
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3372
{
3373
    TranslationBlock *tb;
3374

    
3375
    tb = s->tb;
3376
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3377
        tcg_gen_goto_tb(n);
3378
        gen_set_pc_im(dest);
3379
        tcg_gen_exit_tb((long)tb + n);
3380
    } else {
3381
        gen_set_pc_im(dest);
3382
        tcg_gen_exit_tb(0);
3383
    }
3384
}
3385

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

    
3399
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3400
{
3401
    if (x)
3402
        tcg_gen_sari_i32(t0, t0, 16);
3403
    else
3404
        gen_sxth(t0);
3405
    if (y)
3406
        tcg_gen_sari_i32(t1, t1, 16);
3407
    else
3408
        gen_sxth(t1);
3409
    tcg_gen_mul_i32(t0, t0, t1);
3410
}
3411

    
3412
/* Return the mask of PSR bits set by a MSR instruction.  */
3413
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3414
    uint32_t mask;
3415

    
3416
    mask = 0;
3417
    if (flags & (1 << 0))
3418
        mask |= 0xff;
3419
    if (flags & (1 << 1))
3420
        mask |= 0xff00;
3421
    if (flags & (1 << 2))
3422
        mask |= 0xff0000;
3423
    if (flags & (1 << 3))
3424
        mask |= 0xff000000;
3425

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

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

    
3450
        tmp = load_cpu_field(spsr);
3451
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3452
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3453
        tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3454
        store_cpu_field(tmp, spsr);
3455
    } else {
3456
        gen_set_cpsr(cpu_T[0], mask);
3457
    }
3458
    gen_lookup_tb(s);
3459
    return 0;
3460
}
3461

    
3462
/* Generate an old-style exception return. Marks pc as dead. */
3463
static void gen_exception_return(DisasContext *s, TCGv pc)
3464
{
3465
    TCGv tmp;
3466
    store_reg(s, 15, pc);
3467
    tmp = load_cpu_field(spsr);
3468
    gen_set_cpsr(tmp, 0xffffffff);
3469
    dead_tmp(tmp);
3470
    s->is_jmp = DISAS_UPDATE;
3471
}
3472

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

    
3482
static inline void
3483
gen_set_condexec (DisasContext *s)
3484
{
3485
    if (s->condexec_mask) {
3486
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3487
        TCGv tmp = new_tmp();
3488
        tcg_gen_movi_i32(tmp, val);
3489
        store_cpu_field(tmp, condexec_bits);
3490
    }
3491
}
3492

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

    
3508
/* These macros help make the code more readable when migrating from the
3509
   old dyngen helpers.  They should probably be removed when
3510
   T0/T1 are removed.  */
3511
#define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3512
#define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3513

    
3514
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3515

    
3516
static inline int gen_neon_add(int size)
3517
{
3518
    switch (size) {
3519
    case 0: gen_helper_neon_add_u8(CPU_T001); break;
3520
    case 1: gen_helper_neon_add_u16(CPU_T001); break;
3521
    case 2: gen_op_addl_T0_T1(); break;
3522
    default: return 1;
3523
    }
3524
    return 0;
3525
}
3526

    
3527
static inline void gen_neon_rsb(int size)
3528
{
3529
    switch (size) {
3530
    case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3531
    case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3532
    case 2: gen_op_rsbl_T0_T1(); break;
3533
    default: return;
3534
    }
3535
}
3536

    
3537
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3538
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3539
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3540
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3541
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3542

    
3543
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3544
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3545
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3546
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3547
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3548

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

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

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

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

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

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

    
3613
static inline void
3614
gen_neon_movl_T0_scratch(int scratch)
3615
{
3616
  uint32_t offset;
3617

    
3618
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3619
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3620
}
3621

    
3622
static inline void
3623
gen_neon_movl_T1_scratch(int scratch)
3624
{
3625
  uint32_t offset;
3626

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

    
3631
static inline void gen_neon_get_scalar(int size, int reg)
3632
{
3633
    if (size == 1) {
3634
        NEON_GET_REG(T0, reg >> 1, reg & 1);
3635
    } else {
3636
        NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3637
        if (reg & 1)
3638
            gen_neon_dup_low16(cpu_T[0]);
3639
        else
3640
            gen_neon_dup_high16(cpu_T[0]);
3641
    }
3642
}
3643

    
3644
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3645
{
3646
    int n;
3647

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

    
3662
static struct {
3663
    int nregs;
3664
    int interleave;
3665
    int spacing;
3666
} neon_ls_element_type[11] = {
3667
    {4, 4, 1},
3668
    {4, 4, 2},
3669
    {4, 1, 1},
3670
    {4, 2, 1},
3671
    {3, 3, 1},
3672
    {3, 3, 2},
3673
    {3, 1, 1},
3674
    {1, 1, 1},
3675
    {2, 2, 1},
3676
    {2, 2, 2},
3677
    {2, 1, 1}
3678
};
3679

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

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

    
3886
        base = load_reg(s, rn);
3887
        if (rm == 13) {
3888
            tcg_gen_addi_i32(base, base, stride);
3889
        } else {
3890
            TCGv index;
3891
            index = load_reg(s, rm);
3892
            tcg_gen_add_i32(base, base, index);
3893
            dead_tmp(index);
3894
        }
3895
        store_reg(s, rn, base);
3896
    }
3897
    return 0;
3898
}
3899

    
3900
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3901
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3902
{
3903
    tcg_gen_and_i32(t, t, c);
3904
    tcg_gen_bic_i32(f, f, c);
3905
    tcg_gen_or_i32(dest, t, f);
3906
}
3907

    
3908
static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
3909
{
3910
    switch (size) {
3911
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
3912
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
3913
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3914
    default: abort();
3915
    }
3916
}
3917

    
3918
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
3919
{
3920
    switch (size) {
3921
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3922
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3923
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3924
    default: abort();
3925
    }
3926
}
3927

    
3928
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
3929
{
3930
    switch (size) {
3931
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3932
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3933
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3934
    default: abort();
3935
    }
3936
}
3937

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

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

    
3992
static inline void gen_neon_addl(int size)
3993
{
3994
    switch (size) {
3995
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3996
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3997
    case 2: tcg_gen_add_i64(CPU_V001); break;
3998
    default: abort();
3999
    }
4000
}
4001

    
4002
static inline void gen_neon_subl(int size)
4003
{
4004
    switch (size) {
4005
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4006
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4007
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4008
    default: abort();
4009
    }
4010
}
4011

    
4012
static inline void gen_neon_negl(TCGv_i64 var, int size)
4013
{
4014
    switch (size) {
4015
    case 0: gen_helper_neon_negl_u16(var, var); break;
4016
    case 1: gen_helper_neon_negl_u32(var, var); break;
4017
    case 2: gen_helper_neon_negl_u64(var, var); break;
4018
    default: abort();
4019
    }
4020
}
4021

    
4022
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4023
{
4024
    switch (size) {
4025
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4026
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4027
    default: abort();
4028
    }
4029
}
4030

    
4031
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4032
{
4033
    TCGv_i64 tmp;
4034

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

    
4056
/* Translate a NEON data processing instruction.  Return nonzero if the
4057
   instruction is invalid.
4058
   We process data in a mixture of 32-bit and 64-bit chunks.
4059
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4060

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

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

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

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

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

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

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

    
4698
                    gen_neon_widen(cpu_V0, tmp, size, u);
4699

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

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

    
4783
            if (op != 14 || !invert)
4784
                gen_op_movl_T1_im(imm);
4785

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

    
4841
                prewiden = neon_3reg_wide[op][0];
4842
                src1_wide = neon_3reg_wide[op][1];
4843
                src2_wide = neon_3reg_wide[op][2];
4844

    
4845
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4846
                    return 1;
4847

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

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

    
4938
                        if (op != 13) {
4939
                            neon_load_reg64(cpu_V1, rd + pass);
4940
                        }
4941

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

    
5073
                    gen_neon_get_scalar(size, rm);
5074
                    NEON_GET_REG(T1, rn, 1);
5075

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

    
5122
                if (imm > 7 && !q)
5123
                    return 1;
5124

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

    
5554
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
5555
{
5556
    int crn = (insn >> 16) & 0xf;
5557
    int crm = insn & 0xf;
5558
    int op1 = (insn >> 21) & 7;
5559
    int op2 = (insn >> 5) & 7;
5560
    int rt = (insn >> 12) & 0xf;
5561
    TCGv tmp;
5562

    
5563
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5564
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5565
            /* TEECR */
5566
            if (IS_USER(s))
5567
                return 1;
5568
            tmp = load_cpu_field(teecr);
5569
            store_reg(s, rt, tmp);
5570
            return 0;
5571
        }
5572
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5573
            /* TEEHBR */
5574
            if (IS_USER(s) && (env->teecr & 1))
5575
                return 1;
5576
            tmp = load_cpu_field(teehbr);
5577
            store_reg(s, rt, tmp);
5578
            return 0;
5579
        }
5580
    }
5581
    fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
5582
            op1, crn, crm, op2);
5583
    return 1;
5584
}
5585

    
5586
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
5587
{
5588
    int crn = (insn >> 16) & 0xf;
5589
    int crm = insn & 0xf;
5590
    int op1 = (insn >> 21) & 7;
5591
    int op2 = (insn >> 5) & 7;
5592
    int rt = (insn >> 12) & 0xf;
5593
    TCGv tmp;
5594

    
5595
    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
5596
        if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
5597
            /* TEECR */
5598
            if (IS_USER(s))
5599
                return 1;
5600
            tmp = load_reg(s, rt);
5601
            gen_helper_set_teecr(cpu_env, tmp);
5602
            dead_tmp(tmp);
5603
            return 0;
5604
        }
5605
        if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
5606
            /* TEEHBR */
5607
            if (IS_USER(s) && (env->teecr & 1))
5608
                return 1;
5609
            tmp = load_reg(s, rt);
5610
            store_cpu_field(tmp, teehbr);
5611
            return 0;
5612
        }
5613
    }
5614
    fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
5615
            op1, crn, crm, op2);
5616
    return 1;
5617
}
5618

    
5619
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5620
{
5621
    int cpnum;
5622

    
5623
    cpnum = (insn >> 8) & 0xf;
5624
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5625
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5626
        return 1;
5627

    
5628
    switch (cpnum) {
5629
      case 0:
5630
      case 1:
5631
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5632
            return disas_iwmmxt_insn(env, s, insn);
5633
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5634
            return disas_dsp_insn(env, s, insn);
5635
        }
5636
        return 1;
5637
    case 10:
5638
    case 11:
5639
        return disas_vfp_insn (env, s, insn);
5640
    case 14:
5641
        /* Coprocessors 7-15 are architecturally reserved by ARM.
5642
           Unfortunately Intel decided to ignore this.  */
5643
        if (arm_feature(env, ARM_FEATURE_XSCALE))
5644
            goto board;
5645
        if (insn & (1 << 20))
5646
            return disas_cp14_read(env, s, insn);
5647
        else
5648
            return disas_cp14_write(env, s, insn);
5649
    case 15:
5650
        return disas_cp15_insn (env, s, insn);
5651
    default:
5652
    board:
5653
        /* Unknown coprocessor.  See if the board has hooked it.  */
5654
        return disas_cp_insn (env, s, insn);
5655
    }
5656
}
5657

    
5658

    
5659
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5660
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
5661
{
5662
    TCGv tmp;
5663
    tmp = new_tmp();
5664
    tcg_gen_trunc_i64_i32(tmp, val);
5665
    store_reg(s, rlow, tmp);
5666
    tmp = new_tmp();
5667
    tcg_gen_shri_i64(val, val, 32);
5668
    tcg_gen_trunc_i64_i32(tmp, val);
5669
    store_reg(s, rhigh, tmp);
5670
}
5671

    
5672
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5673
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
5674
{
5675
    TCGv_i64 tmp;
5676
    TCGv tmp2;
5677

    
5678
    /* Load value and extend to 64 bits.  */
5679
    tmp = tcg_temp_new_i64();
5680
    tmp2 = load_reg(s, rlow);
5681
    tcg_gen_extu_i32_i64(tmp, tmp2);
5682
    dead_tmp(tmp2);
5683
    tcg_gen_add_i64(val, val, tmp);
5684
}
5685

    
5686
/* load and add a 64-bit value from a register pair.  */
5687
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5688
{
5689
    TCGv_i64 tmp;
5690
    TCGv tmpl;
5691
    TCGv tmph;
5692

    
5693
    /* Load 64-bit value rd:rn.  */
5694
    tmpl = load_reg(s, rlow);
5695
    tmph = load_reg(s, rhigh);
5696
    tmp = tcg_temp_new_i64();
5697
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5698
    dead_tmp(tmpl);
5699
    dead_tmp(tmph);
5700
    tcg_gen_add_i64(val, val, tmp);
5701
}
5702

    
5703
/* Set N and Z flags from a 64-bit value.  */
5704
static void gen_logicq_cc(TCGv_i64 val)
5705
{
5706
    TCGv tmp = new_tmp();
5707
    gen_helper_logicq_cc(tmp, val);
5708
    gen_logic_CC(tmp);
5709
    dead_tmp(tmp);
5710
}
5711

    
5712
static void disas_arm_insn(CPUState * env, DisasContext *s)
5713
{
5714
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5715
    TCGv tmp;
5716
    TCGv tmp2;
5717
    TCGv tmp3;
5718
    TCGv addr;
5719
    TCGv_i64 tmp64;
5720

    
5721
    insn = ldl_code(s->pc);
5722
    s->pc += 4;
5723

    
5724
    /* M variants do not implement ARM mode.  */
5725
    if (IS_M(env))
5726
        goto illegal_op;
5727
    cond = insn >> 28;
5728
    if (cond == 0xf){
5729
        /* Unconditional instructions.  */
5730
        if (((insn >> 25) & 7) == 1) {
5731
            /* NEON Data processing.  */
5732
            if (!arm_feature(env, ARM_FEATURE_NEON))
5733
                goto illegal_op;
5734

    
5735
            if (disas_neon_data_insn(env, s, insn))
5736
                goto illegal_op;
5737
            return;
5738
        }
5739
        if ((insn & 0x0f100000) == 0x04000000) {
5740
            /* NEON load/store.  */
5741
            if (!arm_feature(env, ARM_FEATURE_NEON))
5742
                goto illegal_op;
5743

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

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

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

    
6094
        op1 = (insn >> 21) & 0xf;
6095
        set_cc = (insn >> 20) & 1;
6096
        logic_cc = table_logic_cc[op1] & set_cc;
6097

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

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

    
6788
                    if ((insn & (1 << 15)) == 0)
6789
                        user = 1;
6790
                }
6791
                rn = (insn >> 16) & 0xf;
6792
                addr = load_reg(s, rn);
6793

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

    
6898
                /* branch (and link) */
6899
                val = (int32_t)s->pc;
6900
                if (insn & (1 << 24)) {
6901
                    tmp = new_tmp();
6902
                    tcg_gen_movi_i32(tmp, val);
6903
                    store_reg(s, 14, tmp);
6904
                }
6905
                offset = (((int32_t)insn << 8) >> 8);
6906
                val += (offset << 2) + 4;
6907
                gen_jmp(s, val);
6908
            }
6909
            break;
6910
        case 0xc:
6911
        case 0xd:
6912
        case 0xe:
6913
            /* Coprocessor.  */
6914
            if (disas_coproc_insn(env, s, insn))
6915
                goto illegal_op;
6916
            break;
6917
        case 0xf:
6918
            /* swi */
6919
            gen_set_pc_im(s->pc);
6920
            s->is_jmp = DISAS_SWI;
6921
            break;
6922
        default:
6923
        illegal_op:
6924
            gen_set_condexec(s);
6925
            gen_set_pc_im(s->pc - 4);
6926
            gen_exception(EXCP_UDEF);
6927
            s->is_jmp = DISAS_JUMP;
6928
            break;
6929
        }
6930
    }
6931
}
6932

    
6933
/* Return true if this is a Thumb-2 logical op.  */
6934
static int
6935
thumb2_logic_op(int op)
6936
{
6937
    return (op < 8);
6938
}
6939

    
6940
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6941
   then set condition code flags based on the result of the operation.
6942
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6943
   to the high bit of T1.
6944
   Returns zero if the opcode is valid.  */
6945

    
6946
static int
6947
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6948
{
6949
    int logic_cc;
6950

    
6951
    logic_cc = 0;
6952
    switch (op) {
6953
    case 0: /* and */
6954
        gen_op_andl_T0_T1();
6955
        logic_cc = conds;
6956
        break;
6957
    case 1: /* bic */
6958
        gen_op_bicl_T0_T1();
6959
        logic_cc = conds;
6960
        break;
6961
    case 2: /* orr */
6962
        gen_op_orl_T0_T1();
6963
        logic_cc = conds;
6964
        break;
6965
    case 3: /* orn */
6966
        gen_op_notl_T1();
6967
        gen_op_orl_T0_T1();
6968
        logic_cc = conds;
6969
        break;
6970
    case 4: /* eor */
6971
        gen_op_xorl_T0_T1();
6972
        logic_cc = conds;
6973
        break;
6974
    case 8: /* add */
6975
        if (conds)
6976
            gen_op_addl_T0_T1_cc();
6977
        else
6978
            gen_op_addl_T0_T1();
6979
        break;
6980
    case 10: /* adc */
6981
        if (conds)
6982
            gen_op_adcl_T0_T1_cc();
6983
        else
6984
            gen_adc_T0_T1();
6985
        break;
6986
    case 11: /* sbc */
6987
        if (conds)
6988
            gen_op_sbcl_T0_T1_cc();
6989
        else
6990
            gen_sbc_T0_T1();
6991
        break;
6992
    case 13: /* sub */
6993
        if (conds)
6994
            gen_op_subl_T0_T1_cc();
6995
        else
6996
            gen_op_subl_T0_T1();
6997
        break;
6998
    case 14: /* rsb */
6999
        if (conds)
7000
            gen_op_rsbl_T0_T1_cc();
7001
        else
7002
            gen_op_rsbl_T0_T1();
7003
        break;
7004
    default: /* 5, 6, 7, 9, 12, 15. */
7005
        return 1;
7006
    }
7007
    if (logic_cc) {
7008
        gen_op_logic_T0_cc();
7009
        if (shifter_out)
7010
            gen_set_CF_bit31(cpu_T[1]);
7011
    }
7012
    return 0;
7013
}
7014

    
7015
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
7016
   is not legal.  */
7017
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7018
{
7019
    uint32_t insn, imm, shift, offset;
7020
    uint32_t rd, rn, rm, rs;
7021
    TCGv tmp;
7022
    TCGv tmp2;
7023
    TCGv tmp3;
7024
    TCGv addr;
7025
    TCGv_i64 tmp64;
7026
    int op;
7027
    int shiftop;
7028
    int conds;
7029
    int logic_cc;
7030

    
7031
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7032
          || arm_feature (env, ARM_FEATURE_M))) {
7033
        /* Thumb-1 cores may need to treat bl and blx as a pair of
7034
           16-bit instructions to get correct prefetch abort behavior.  */
7035
        insn = insn_hw1;
7036
        if ((insn & (1 << 12)) == 0) {
7037
            /* Second half of blx.  */
7038
            offset = ((insn & 0x7ff) << 1);
7039
            tmp = load_reg(s, 14);
7040
            tcg_gen_addi_i32(tmp, tmp, offset);
7041
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7042

    
7043
            tmp2 = new_tmp();
7044
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7045
            store_reg(s, 14, tmp2);
7046
            gen_bx(s, tmp);
7047
            return 0;
7048
        }
7049
        if (insn & (1 << 11)) {
7050
            /* Second half of bl.  */
7051
            offset = ((insn & 0x7ff) << 1) | 1;
7052
            tmp = load_reg(s, 14);
7053
            tcg_gen_addi_i32(tmp, tmp, offset);
7054

    
7055
            tmp2 = new_tmp();
7056
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7057
            store_reg(s, 14, tmp2);
7058
            gen_bx(s, tmp);
7059
            return 0;
7060
        }
7061
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7062
            /* Instruction spans a page boundary.  Implement it as two
7063
               16-bit instructions in case the second half causes an
7064
               prefetch abort.  */
7065
            offset = ((int32_t)insn << 21) >> 9;
7066
            gen_op_movl_T0_im(s->pc + 2 + offset);
7067
            gen_movl_reg_T0(s, 14);
7068
            return 0;
7069
        }
7070
        /* Fall through to 32-bit decode.  */
7071
    }
7072

    
7073
    insn = lduw_code(s->pc);
7074
    s->pc += 2;
7075
    insn |= (uint32_t)insn_hw1 << 16;
7076

    
7077
    if ((insn & 0xf800e800) != 0xf000e800) {
7078
        ARCH(6T2);
7079
    }
7080

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

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

    
7634
                if (insn & (1 << 14)) {
7635
                    /* Branch and link.  */
7636
                    gen_op_movl_T1_im(s->pc | 1);
7637
                    gen_movl_reg_T1(s, 14);
7638
                }
7639

    
7640
                offset += s->pc;
7641
                if (insn & (1 << 12)) {
7642
                    /* b/bl */
7643
                    gen_jmp(s, offset);
7644
                } else {
7645
                    /* blx */
7646
                    offset &= ~(uint32_t)2;
7647
                    gen_bx_im(s, offset);
7648
                }
7649
            } else if (((insn >> 23) & 7) == 7) {
7650
                /* Misc control */
7651
                if (insn & (1 << 13))
7652
                    goto illegal_op;
7653

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

    
7757
                /* offset[11:1] = insn[10:0] */
7758
                offset = (insn & 0x7ff) << 1;
7759
                /* offset[17:12] = insn[21:16].  */
7760
                offset |= (insn & 0x003f0000) >> 4;
7761
                /* offset[31:20] = insn[26].  */
7762
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7763
                /* offset[18] = insn[13].  */
7764
                offset |= (insn & (1 << 13)) << 5;
7765
                /* offset[19] = insn[11].  */
7766
                offset |= (insn & (1 << 11)) << 8;
7767

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

    
8036
static void disas_thumb_insn(CPUState *env, DisasContext *s)
8037
{
8038
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
8039
    int32_t offset;
8040
    int i;
8041
    TCGv tmp;
8042
    TCGv tmp2;
8043
    TCGv addr;
8044

    
8045
    if (s->condexec_mask) {
8046
        cond = s->condexec_cond;
8047
        s->condlabel = gen_new_label();
8048
        gen_test_cc(cond ^ 1, s->condlabel);
8049
        s->condjmp = 1;
8050
    }
8051

    
8052
    insn = lduw_code(s->pc);
8053
    s->pc += 2;
8054

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

    
8176
        /* data processing register */
8177
        rd = insn & 7;
8178
        rm = (insn >> 3) & 7;
8179
        op = (insn >> 6) & 0xf;
8180
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8181
            /* the shift/rotate ops want the operands backwards */
8182
            val = rm;
8183
            rm = rd;
8184
            rd = val;
8185
            val = 1;
8186
        } else {
8187
            val = 0;
8188
        }
8189

    
8190
        if (op == 9) /* neg */
8191
            gen_op_movl_T0_im(0);
8192
        else if (op != 0xf) /* mvn doesn't read its first operand */
8193
            gen_movl_T0_reg(s, rd);
8194

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

    
8301
    case 5:
8302
        /* load/store register offset.  */
8303
        rd = insn & 7;
8304
        rn = (insn >> 3) & 7;
8305
        rm = (insn >> 6) & 7;
8306
        op = (insn >> 9) & 7;
8307
        addr = load_reg(s, rn);
8308
        tmp = load_reg(s, rm);
8309
        tcg_gen_add_i32(addr, addr, tmp);
8310
        dead_tmp(tmp);
8311

    
8312
        if (op < 3) /* store */
8313
            tmp = load_reg(s, rd);
8314

    
8315
        switch (op) {
8316
        case 0: /* str */
8317
            gen_st32(tmp, addr, IS_USER(s));
8318
            break;
8319
        case 1: /* strh */
8320
            gen_st16(tmp, addr, IS_USER(s));
8321
            break;
8322
        case 2: /* strb */
8323
            gen_st8(tmp, addr, IS_USER(s));
8324
            break;
8325
        case 3: /* ldrsb */
8326
            tmp = gen_ld8s(addr, IS_USER(s));
8327
            break;
8328
        case 4: /* ldr */
8329
            tmp = gen_ld32(addr, IS_USER(s));
8330
            break;
8331
        case 5: /* ldrh */
8332
            tmp = gen_ld16u(addr, IS_USER(s));
8333
            break;
8334
        case 6: /* ldrb */
8335
            tmp = gen_ld8u(addr, IS_USER(s));
8336
            break;
8337
        case 7: /* ldrsh */
8338
            tmp = gen_ld16s(addr, IS_USER(s));
8339
            break;
8340
        }
8341
        if (op >= 3) /* load */
8342
            store_reg(s, rd, tmp);
8343
        dead_tmp(addr);
8344
        break;
8345

    
8346
    case 6:
8347
        /* load/store word immediate offset */
8348
        rd = insn & 7;
8349
        rn = (insn >> 3) & 7;
8350
        addr = load_reg(s, rn);
8351
        val = (insn >> 4) & 0x7c;
8352
        tcg_gen_addi_i32(addr, addr, val);
8353

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

    
8366
    case 7:
8367
        /* load/store byte immediate offset */
8368
        rd = insn & 7;
8369
        rn = (insn >> 3) & 7;
8370
        addr = load_reg(s, rn);
8371
        val = (insn >> 6) & 0x1f;
8372
        tcg_gen_addi_i32(addr, addr, val);
8373

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

    
8386
    case 8:
8387
        /* load/store halfword immediate offset */
8388
        rd = insn & 7;
8389
        rn = (insn >> 3) & 7;
8390
        addr = load_reg(s, rn);
8391
        val = (insn >> 5) & 0x3e;
8392
        tcg_gen_addi_i32(addr, addr, val);
8393

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

    
8406
    case 9:
8407
        /* load/store from stack */
8408
        rd = (insn >> 8) & 7;
8409
        addr = load_reg(s, 13);
8410
        val = (insn & 0xff) * 4;
8411
        tcg_gen_addi_i32(addr, addr, val);
8412

    
8413
        if (insn & (1 << 11)) {
8414
            /* load */
8415
            tmp = gen_ld32(addr, IS_USER(s));
8416
            store_reg(s, rd, tmp);
8417
        } else {
8418
            /* store */
8419
            tmp = load_reg(s, rd);
8420
            gen_st32(tmp, addr, IS_USER(s));
8421
        }
8422
        dead_tmp(addr);
8423
        break;
8424

    
8425
    case 10:
8426
        /* add to high reg */
8427
        rd = (insn >> 8) & 7;
8428
        if (insn & (1 << 11)) {
8429
            /* SP */
8430
            tmp = load_reg(s, 13);
8431
        } else {
8432
            /* PC. bit 1 is ignored.  */
8433
            tmp = new_tmp();
8434
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8435
        }
8436
        val = (insn & 0xff) * 4;
8437
        tcg_gen_addi_i32(tmp, tmp, val);
8438
        store_reg(s, rd, tmp);
8439
        break;
8440

    
8441
    case 11:
8442
        /* misc */
8443
        op = (insn >> 8) & 0xf;
8444
        switch (op) {
8445
        case 0:
8446
            /* adjust stack pointer */
8447
            tmp = load_reg(s, 13);
8448
            val = (insn & 0x7f) * 4;
8449
            if (insn & (1 << 7))
8450
                val = -(int32_t)val;
8451
            tcg_gen_addi_i32(tmp, tmp, val);
8452
            store_reg(s, 13, tmp);
8453
            break;
8454

    
8455
        case 2: /* sign/zero extend.  */
8456
            ARCH(6);
8457
            rd = insn & 7;
8458
            rm = (insn >> 3) & 7;
8459
            tmp = load_reg(s, rm);
8460
            switch ((insn >> 6) & 3) {
8461
            case 0: gen_sxth(tmp); break;
8462
            case 1: gen_sxtb(tmp); break;
8463
            case 2: gen_uxth(tmp); break;
8464
            case 3: gen_uxtb(tmp); break;
8465
            }
8466
            store_reg(s, rd, tmp);
8467
            break;
8468
        case 4: case 5: case 0xc: case 0xd:
8469
            /* push/pop */
8470
            addr = load_reg(s, 13);
8471
            if (insn & (1 << 8))
8472
                offset = 4;
8473
            else
8474
                offset = 0;
8475
            for (i = 0; i < 8; i++) {
8476
                if (insn & (1 << i))
8477
                    offset += 4;
8478
            }
8479
            if ((insn & (1 << 11)) == 0) {
8480
                tcg_gen_addi_i32(addr, addr, -offset);
8481
            }
8482
            for (i = 0; i < 8; i++) {
8483
                if (insn & (1 << i)) {
8484
                    if (insn & (1 << 11)) {
8485
                        /* pop */
8486
                        tmp = gen_ld32(addr, IS_USER(s));
8487
                        store_reg(s, i, tmp);
8488
                    } else {
8489
                        /* push */
8490
                        tmp = load_reg(s, i);
8491
                        gen_st32(tmp, addr, IS_USER(s));
8492
                    }
8493
                    /* advance to the next address.  */
8494
                    tcg_gen_addi_i32(addr, addr, 4);
8495
                }
8496
            }
8497
            TCGV_UNUSED(tmp);
8498
            if (insn & (1 << 8)) {
8499
                if (insn & (1 << 11)) {
8500
                    /* pop pc */
8501
                    tmp = gen_ld32(addr, IS_USER(s));
8502
                    /* don't set the pc until the rest of the instruction
8503
                       has completed */
8504
                } else {
8505
                    /* push lr */
8506
                    tmp = load_reg(s, 14);
8507
                    gen_st32(tmp, addr, IS_USER(s));
8508
                }
8509
                tcg_gen_addi_i32(addr, addr, 4);
8510
            }
8511
            if ((insn & (1 << 11)) == 0) {
8512
                tcg_gen_addi_i32(addr, addr, -offset);
8513
            }
8514
            /* write back the new stack pointer */
8515
            store_reg(s, 13, addr);
8516
            /* set the new PC value */
8517
            if ((insn & 0x0900) == 0x0900)
8518
                gen_bx(s, tmp);
8519
            break;
8520

    
8521
        case 1: case 3: case 9: case 11: /* czb */
8522
            rm = insn & 7;
8523
            tmp = load_reg(s, rm);
8524
            s->condlabel = gen_new_label();
8525
            s->condjmp = 1;
8526
            if (insn & (1 << 11))
8527
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8528
            else
8529
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8530
            dead_tmp(tmp);
8531
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8532
            val = (uint32_t)s->pc + 2;
8533
            val += offset;
8534
            gen_jmp(s, val);
8535
            break;
8536

    
8537
        case 15: /* IT, nop-hint.  */
8538
            if ((insn & 0xf) == 0) {
8539
                gen_nop_hint(s, (insn >> 4) & 0xf);
8540
                break;
8541
            }
8542
            /* If Then.  */
8543
            s->condexec_cond = (insn >> 4) & 0xe;
8544
            s->condexec_mask = insn & 0x1f;
8545
            /* No actual code generated for this insn, just setup state.  */
8546
            break;
8547

    
8548
        case 0xe: /* bkpt */
8549
            gen_set_condexec(s);
8550
            gen_set_pc_im(s->pc - 2);
8551
            gen_exception(EXCP_BKPT);
8552
            s->is_jmp = DISAS_JUMP;
8553
            break;
8554

    
8555
        case 0xa: /* rev */
8556
            ARCH(6);
8557
            rn = (insn >> 3) & 0x7;
8558
            rd = insn & 0x7;
8559
            tmp = load_reg(s, rn);
8560
            switch ((insn >> 6) & 3) {
8561
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8562
            case 1: gen_rev16(tmp); break;
8563
            case 3: gen_revsh(tmp); break;
8564
            default: goto illegal_op;
8565
            }
8566
            store_reg(s, rd, tmp);
8567
            break;
8568

    
8569
        case 6: /* cps */
8570
            ARCH(6);
8571
            if (IS_USER(s))
8572
                break;
8573
            if (IS_M(env)) {
8574
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8575
                /* PRIMASK */
8576
                if (insn & 1) {
8577
                    addr = tcg_const_i32(16);
8578
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8579
                }
8580
                /* FAULTMASK */
8581
                if (insn & 2) {
8582
                    addr = tcg_const_i32(17);
8583
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8584
                }
8585
                gen_lookup_tb(s);
8586
            } else {
8587
                if (insn & (1 << 4))
8588
                    shift = CPSR_A | CPSR_I | CPSR_F;
8589
                else
8590
                    shift = 0;
8591

    
8592
                val = ((insn & 7) << 6) & shift;
8593
                gen_op_movl_T0_im(val);
8594
                gen_set_psr_T0(s, shift, 0);
8595
            }
8596
            break;
8597

    
8598
        default:
8599
            goto undef;
8600
        }
8601
        break;
8602

    
8603
    case 12:
8604
        /* load/store multiple */
8605
        rn = (insn >> 8) & 0x7;
8606
        addr = load_reg(s, rn);
8607
        for (i = 0; i < 8; i++) {
8608
            if (insn & (1 << i)) {
8609
                if (insn & (1 << 11)) {
8610
                    /* load */
8611
                    tmp = gen_ld32(addr, IS_USER(s));
8612
                    store_reg(s, i, tmp);
8613
                } else {
8614
                    /* store */
8615
                    tmp = load_reg(s, i);
8616
                    gen_st32(tmp, addr, IS_USER(s));
8617
                }
8618
                /* advance to the next address */
8619
                tcg_gen_addi_i32(addr, addr, 4);
8620
            }
8621
        }
8622
        /* Base register writeback.  */
8623
        if ((insn & (1 << rn)) == 0) {
8624
            store_reg(s, rn, addr);
8625
        } else {
8626
            dead_tmp(addr);
8627
        }
8628
        break;
8629

    
8630
    case 13:
8631
        /* conditional branch or swi */
8632
        cond = (insn >> 8) & 0xf;
8633
        if (cond == 0xe)
8634
            goto undef;
8635

    
8636
        if (cond == 0xf) {
8637
            /* swi */
8638
            gen_set_condexec(s);
8639
            gen_set_pc_im(s->pc);
8640
            s->is_jmp = DISAS_SWI;
8641
            break;
8642
        }
8643
        /* generate a conditional jump to next instruction */
8644
        s->condlabel = gen_new_label();
8645
        gen_test_cc(cond ^ 1, s->condlabel);
8646
        s->condjmp = 1;
8647
        gen_movl_T1_reg(s, 15);
8648

    
8649
        /* jump to the offset */
8650
        val = (uint32_t)s->pc + 2;
8651
        offset = ((int32_t)insn << 24) >> 24;
8652
        val += offset << 1;
8653
        gen_jmp(s, val);
8654
        break;
8655

    
8656
    case 14:
8657
        if (insn & (1 << 11)) {
8658
            if (disas_thumb2_insn(env, s, insn))
8659
              goto undef32;
8660
            break;
8661
        }
8662
        /* unconditional branch */
8663
        val = (uint32_t)s->pc;
8664
        offset = ((int32_t)insn << 21) >> 21;
8665
        val += (offset << 1) + 2;
8666
        gen_jmp(s, val);
8667
        break;
8668

    
8669
    case 15:
8670
        if (disas_thumb2_insn(env, s, insn))
8671
            goto undef32;
8672
        break;
8673
    }
8674
    return;
8675
undef32:
8676
    gen_set_condexec(s);
8677
    gen_set_pc_im(s->pc - 4);
8678
    gen_exception(EXCP_UDEF);
8679
    s->is_jmp = DISAS_JUMP;
8680
    return;
8681
illegal_op:
8682
undef:
8683
    gen_set_condexec(s);
8684
    gen_set_pc_im(s->pc - 2);
8685
    gen_exception(EXCP_UDEF);
8686
    s->is_jmp = DISAS_JUMP;
8687
}
8688

    
8689
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8690
   basic block 'tb'. If search_pc is TRUE, also generate PC
8691
   information for each intermediate instruction. */
8692
static inline void gen_intermediate_code_internal(CPUState *env,
8693
                                                  TranslationBlock *tb,
8694
                                                  int search_pc)
8695
{
8696
    DisasContext dc1, *dc = &dc1;
8697
    CPUBreakpoint *bp;
8698
    uint16_t *gen_opc_end;
8699
    int j, lj;
8700
    target_ulong pc_start;
8701
    uint32_t next_page_start;
8702
    int num_insns;
8703
    int max_insns;
8704

    
8705
    /* generate intermediate code */
8706
    num_temps = 0;
8707
    memset(temps, 0, sizeof(temps));
8708

    
8709
    pc_start = tb->pc;
8710

    
8711
    dc->tb = tb;
8712

    
8713
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8714

    
8715
    dc->is_jmp = DISAS_NEXT;
8716
    dc->pc = pc_start;
8717
    dc->singlestep_enabled = env->singlestep_enabled;
8718
    dc->condjmp = 0;
8719
    dc->thumb = env->thumb;
8720
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8721
    dc->condexec_cond = env->condexec_bits >> 4;
8722
#if !defined(CONFIG_USER_ONLY)
8723
    if (IS_M(env)) {
8724
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8725
    } else {
8726
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8727
    }
8728
#endif
8729
    cpu_F0s = tcg_temp_new_i32();
8730
    cpu_F1s = tcg_temp_new_i32();
8731
    cpu_F0d = tcg_temp_new_i64();
8732
    cpu_F1d = tcg_temp_new_i64();
8733
    cpu_V0 = cpu_F0d;
8734
    cpu_V1 = cpu_F1d;
8735
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
8736
    cpu_M0 = tcg_temp_new_i64();
8737
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8738
    lj = -1;
8739
    num_insns = 0;
8740
    max_insns = tb->cflags & CF_COUNT_MASK;
8741
    if (max_insns == 0)
8742
        max_insns = CF_COUNT_MASK;
8743

    
8744
    gen_icount_start();
8745
    /* Reset the conditional execution bits immediately. This avoids
8746
       complications trying to do it at the end of the block.  */
8747
    if (env->condexec_bits)
8748
      {
8749
        TCGv tmp = new_tmp();
8750
        tcg_gen_movi_i32(tmp, 0);
8751
        store_cpu_field(tmp, condexec_bits);
8752
      }
8753
    do {
8754
#ifdef CONFIG_USER_ONLY
8755
        /* Intercept jump to the magic kernel page.  */
8756
        if (dc->pc >= 0xffff0000) {
8757
            /* We always get here via a jump, so know we are not in a
8758
               conditional execution block.  */
8759
            gen_exception(EXCP_KERNEL_TRAP);
8760
            dc->is_jmp = DISAS_UPDATE;
8761
            break;
8762
        }
8763
#else
8764
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8765
            /* We always get here via a jump, so know we are not in a
8766
               conditional execution block.  */
8767
            gen_exception(EXCP_EXCEPTION_EXIT);
8768
            dc->is_jmp = DISAS_UPDATE;
8769
            break;
8770
        }
8771
#endif
8772

    
8773
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
8774
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
8775
                if (bp->pc == dc->pc) {
8776
                    gen_set_condexec(dc);
8777
                    gen_set_pc_im(dc->pc);
8778
                    gen_exception(EXCP_DEBUG);
8779
                    dc->is_jmp = DISAS_JUMP;
8780
                    /* Advance PC so that clearing the breakpoint will
8781
                       invalidate this TB.  */
8782
                    dc->pc += 2;
8783
                    goto done_generating;
8784
                    break;
8785
                }
8786
            }
8787
        }
8788
        if (search_pc) {
8789
            j = gen_opc_ptr - gen_opc_buf;
8790
            if (lj < j) {
8791
                lj++;
8792
                while (lj < j)
8793
                    gen_opc_instr_start[lj++] = 0;
8794
            }
8795
            gen_opc_pc[lj] = dc->pc;
8796
            gen_opc_instr_start[lj] = 1;
8797
            gen_opc_icount[lj] = num_insns;
8798
        }
8799

    
8800
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8801
            gen_io_start();
8802

    
8803
        if (env->thumb) {
8804
            disas_thumb_insn(env, dc);
8805
            if (dc->condexec_mask) {
8806
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8807
                                   | ((dc->condexec_mask >> 4) & 1);
8808
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8809
                if (dc->condexec_mask == 0) {
8810
                    dc->condexec_cond = 0;
8811
                }
8812
            }
8813
        } else {
8814
            disas_arm_insn(env, dc);
8815
        }
8816
        if (num_temps) {
8817
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8818
            num_temps = 0;
8819
        }
8820

    
8821
        if (dc->condjmp && !dc->is_jmp) {
8822
            gen_set_label(dc->condlabel);
8823
            dc->condjmp = 0;
8824
        }
8825
        /* Translation stops when a conditional branch is encountered.
8826
         * Otherwise the subsequent code could get translated several times.
8827
         * Also stop translation when a page boundary is reached.  This
8828
         * ensures prefetch aborts occur at the right place.  */
8829
        num_insns ++;
8830
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8831
             !env->singlestep_enabled &&
8832
             !singlestep &&
8833
             dc->pc < next_page_start &&
8834
             num_insns < max_insns);
8835

    
8836
    if (tb->cflags & CF_LAST_IO) {
8837
        if (dc->condjmp) {
8838
            /* FIXME:  This can theoretically happen with self-modifying
8839
               code.  */
8840
            cpu_abort(env, "IO on conditional branch instruction");
8841
        }
8842
        gen_io_end();
8843
    }
8844

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

    
8909
done_generating:
8910
    gen_icount_end(tb, num_insns);
8911
    *gen_opc_ptr = INDEX_op_end;
8912

    
8913
#ifdef DEBUG_DISAS
8914
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8915
        qemu_log("----------------\n");
8916
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8917
        log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
8918
        qemu_log("\n");
8919
    }
8920
#endif
8921
    if (search_pc) {
8922
        j = gen_opc_ptr - gen_opc_buf;
8923
        lj++;
8924
        while (lj <= j)
8925
            gen_opc_instr_start[lj++] = 0;
8926
    } else {
8927
        tb->size = dc->pc - pc_start;
8928
        tb->icount = num_insns;
8929
    }
8930
}
8931

    
8932
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8933
{
8934
    gen_intermediate_code_internal(env, tb, 0);
8935
}
8936

    
8937
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8938
{
8939
    gen_intermediate_code_internal(env, tb, 1);
8940
}
8941

    
8942
static const char *cpu_mode_names[16] = {
8943
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8944
  "???", "???", "???", "und", "???", "???", "???", "sys"
8945
};
8946

    
8947
void cpu_dump_state(CPUState *env, FILE *f,
8948
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8949
                    int flags)
8950
{
8951
    int i;
8952
#if 0
8953
    union {
8954
        uint32_t i;
8955
        float s;
8956
    } s0, s1;
8957
    CPU_DoubleU d;
8958
    /* ??? This assumes float64 and double have the same layout.
8959
       Oh well, it's only debug dumps.  */
8960
    union {
8961
        float64 f64;
8962
        double d;
8963
    } d0;
8964
#endif
8965
    uint32_t psr;
8966

    
8967
    for(i=0;i<16;i++) {
8968
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8969
        if ((i % 4) == 3)
8970
            cpu_fprintf(f, "\n");
8971
        else
8972
            cpu_fprintf(f, " ");
8973
    }
8974
    psr = cpsr_read(env);
8975
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8976
                psr,
8977
                psr & (1 << 31) ? 'N' : '-',
8978
                psr & (1 << 30) ? 'Z' : '-',
8979
                psr & (1 << 29) ? 'C' : '-',
8980
                psr & (1 << 28) ? 'V' : '-',
8981
                psr & CPSR_T ? 'T' : 'A',
8982
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8983

    
8984
#if 0
8985
    for (i = 0; i < 16; i++) {
8986
        d.d = env->vfp.regs[i];
8987
        s0.i = d.l.lower;
8988
        s1.i = d.l.upper;
8989
        d0.f64 = d.d;
8990
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8991
                    i * 2, (int)s0.i, s0.s,
8992
                    i * 2 + 1, (int)s1.i, s1.s,
8993
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8994
                    d0.d);
8995
    }
8996
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8997
#endif
8998
}
8999

    
9000
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9001
                unsigned long searched_pc, int pc_pos, void *puc)
9002
{
9003
    env->regs[15] = gen_opc_pc[pc_pos];
9004
}