Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 024589f1

History | View | Annotate | Download (300.7 kB)

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

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

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

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

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

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

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

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

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

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

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

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

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

    
96
#define GEN_HELPER 2
97
#include "helpers.h"
98
}
99

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

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

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

    
116
    tmp = tcg_temp_new_i32();
117
    temps[num_temps++] = tmp;
118
    return tmp;
119
}
120

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

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

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

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

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

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

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

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

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

    
194

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1000
#undef VFP_OP2
1001

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1216
#define ARM_CP_RW_BIT        (1 << 20)
1217

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1307
IWMMXT_OP_ENV_SIZE(unpackl)
1308
IWMMXT_OP_ENV_SIZE(unpackh)
1309

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

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

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

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

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

    
1344
IWMMXT_OP(msadb)
1345

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1432

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2458
    return 0;
2459
}
2460

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

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

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

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

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

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

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

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

    
2531
    return 1;
2532
}
2533

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3515
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3516

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5659

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8710
    pc_start = tb->pc;
8711

    
8712
    dc->tb = tb;
8713

    
8714
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8715

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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