Statistics
| Branch: | Revision:

root / target-arm / translate.c @ fe1479c3

History | View | Annotate | Download (299.4 kB)

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

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

    
34
#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
#define gen_op_rscl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[1], cpu_T[0])
211

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
860
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
861
{
862
    load_reg_var(s, cpu_T[0], reg);
863
}
864

    
865
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
866
{
867
    load_reg_var(s, cpu_T[1], reg);
868
}
869

    
870
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
871
{
872
    load_reg_var(s, cpu_T[2], reg);
873
}
874

    
875
static inline void gen_set_pc_im(uint32_t val)
876
{
877
    TCGv tmp = new_tmp();
878
    tcg_gen_movi_i32(tmp, val);
879
    store_cpu_field(tmp, regs[15]);
880
}
881

    
882
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
883
{
884
    TCGv tmp;
885
    if (reg == 15) {
886
        tmp = new_tmp();
887
        tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
888
    } else {
889
        tmp = cpu_T[t];
890
    }
891
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
892
    if (reg == 15) {
893
        dead_tmp(tmp);
894
        s->is_jmp = DISAS_JUMP;
895
    }
896
}
897

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

    
903
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
904
{
905
    gen_movl_reg_TN(s, reg, 1);
906
}
907

    
908
/* Force a TB lookup after an instruction that changes the CPU state.  */
909
static inline void gen_lookup_tb(DisasContext *s)
910
{
911
    gen_op_movl_T0_im(s->pc);
912
    gen_movl_reg_T0(s, 15);
913
    s->is_jmp = DISAS_UPDATE;
914
}
915

    
916
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
917
                                       TCGv var)
918
{
919
    int val, rm, shift, shiftop;
920
    TCGv offset;
921

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

    
944
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
945
                                        int extra, TCGv var)
946
{
947
    int val, rm;
948
    TCGv offset;
949

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

    
972
#define VFP_OP2(name)                                                 \
973
static inline void gen_vfp_##name(int dp)                             \
974
{                                                                     \
975
    if (dp)                                                           \
976
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
977
    else                                                              \
978
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
979
}
980

    
981
VFP_OP2(add)
982
VFP_OP2(sub)
983
VFP_OP2(mul)
984
VFP_OP2(div)
985

    
986
#undef VFP_OP2
987

    
988
static inline void gen_vfp_abs(int dp)
989
{
990
    if (dp)
991
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
992
    else
993
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
994
}
995

    
996
static inline void gen_vfp_neg(int dp)
997
{
998
    if (dp)
999
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1000
    else
1001
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1002
}
1003

    
1004
static inline void gen_vfp_sqrt(int dp)
1005
{
1006
    if (dp)
1007
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1008
    else
1009
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1010
}
1011

    
1012
static inline void gen_vfp_cmp(int dp)
1013
{
1014
    if (dp)
1015
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1016
    else
1017
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1018
}
1019

    
1020
static inline void gen_vfp_cmpe(int dp)
1021
{
1022
    if (dp)
1023
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1024
    else
1025
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1026
}
1027

    
1028
static inline void gen_vfp_F1_ld0(int dp)
1029
{
1030
    if (dp)
1031
        tcg_gen_movi_i64(cpu_F1d, 0);
1032
    else
1033
        tcg_gen_movi_i32(cpu_F1s, 0);
1034
}
1035

    
1036
static inline void gen_vfp_uito(int dp)
1037
{
1038
    if (dp)
1039
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1040
    else
1041
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1042
}
1043

    
1044
static inline void gen_vfp_sito(int dp)
1045
{
1046
    if (dp)
1047
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1048
    else
1049
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1050
}
1051

    
1052
static inline void gen_vfp_toui(int dp)
1053
{
1054
    if (dp)
1055
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1056
    else
1057
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1058
}
1059

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

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

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

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

    
1102
static inline void gen_vfp_ld(DisasContext *s, int dp)
1103
{
1104
    if (dp)
1105
        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1106
    else
1107
        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1108
}
1109

    
1110
static inline void gen_vfp_st(DisasContext *s, int dp)
1111
{
1112
    if (dp)
1113
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1114
    else
1115
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1116
}
1117

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

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

    
1142
/* FIXME: Remove these.  */
1143
#define neon_T0 cpu_T[0]
1144
#define neon_T1 cpu_T[1]
1145
#define NEON_GET_REG(T, reg, n) \
1146
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1147
#define NEON_SET_REG(T, reg, n) \
1148
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1149

    
1150
static TCGv neon_load_reg(int reg, int pass)
1151
{
1152
    TCGv tmp = new_tmp();
1153
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1154
    return tmp;
1155
}
1156

    
1157
static void neon_store_reg(int reg, int pass, TCGv var)
1158
{
1159
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1160
    dead_tmp(var);
1161
}
1162

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

    
1168
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1169
{
1170
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1171
}
1172

    
1173
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1174
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1175
#define tcg_gen_st_f32 tcg_gen_st_i32
1176
#define tcg_gen_st_f64 tcg_gen_st_i64
1177

    
1178
static inline void gen_mov_F0_vreg(int dp, int reg)
1179
{
1180
    if (dp)
1181
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1182
    else
1183
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1184
}
1185

    
1186
static inline void gen_mov_F1_vreg(int dp, int reg)
1187
{
1188
    if (dp)
1189
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1190
    else
1191
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1192
}
1193

    
1194
static inline void gen_mov_vreg_F0(int dp, int reg)
1195
{
1196
    if (dp)
1197
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1198
    else
1199
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1200
}
1201

    
1202
#define ARM_CP_RW_BIT        (1 << 20)
1203

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

    
1209
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1210
{
1211
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1212
}
1213

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

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

    
1224
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1225
{
1226
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1227
}
1228

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

    
1234
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1235
{
1236
    iwmmxt_load_reg(cpu_M0, rn);
1237
}
1238

    
1239
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1240
{
1241
    iwmmxt_load_reg(cpu_V1, rn);
1242
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1243
}
1244

    
1245
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1246
{
1247
    iwmmxt_load_reg(cpu_V1, rn);
1248
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1249
}
1250

    
1251
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1252
{
1253
    iwmmxt_load_reg(cpu_V1, rn);
1254
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1255
}
1256

    
1257
#define IWMMXT_OP(name) \
1258
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1259
{ \
1260
    iwmmxt_load_reg(cpu_V1, rn); \
1261
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1262
}
1263

    
1264
#define IWMMXT_OP_ENV(name) \
1265
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1266
{ \
1267
    iwmmxt_load_reg(cpu_V1, rn); \
1268
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1269
}
1270

    
1271
#define IWMMXT_OP_ENV_SIZE(name) \
1272
IWMMXT_OP_ENV(name##b) \
1273
IWMMXT_OP_ENV(name##w) \
1274
IWMMXT_OP_ENV(name##l)
1275

    
1276
#define IWMMXT_OP_ENV1(name) \
1277
static inline void gen_op_iwmmxt_##name##_M0(void) \
1278
{ \
1279
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1280
}
1281

    
1282
IWMMXT_OP(maddsq)
1283
IWMMXT_OP(madduq)
1284
IWMMXT_OP(sadb)
1285
IWMMXT_OP(sadw)
1286
IWMMXT_OP(mulslw)
1287
IWMMXT_OP(mulshw)
1288
IWMMXT_OP(mululw)
1289
IWMMXT_OP(muluhw)
1290
IWMMXT_OP(macsw)
1291
IWMMXT_OP(macuw)
1292

    
1293
IWMMXT_OP_ENV_SIZE(unpackl)
1294
IWMMXT_OP_ENV_SIZE(unpackh)
1295

    
1296
IWMMXT_OP_ENV1(unpacklub)
1297
IWMMXT_OP_ENV1(unpackluw)
1298
IWMMXT_OP_ENV1(unpacklul)
1299
IWMMXT_OP_ENV1(unpackhub)
1300
IWMMXT_OP_ENV1(unpackhuw)
1301
IWMMXT_OP_ENV1(unpackhul)
1302
IWMMXT_OP_ENV1(unpacklsb)
1303
IWMMXT_OP_ENV1(unpacklsw)
1304
IWMMXT_OP_ENV1(unpacklsl)
1305
IWMMXT_OP_ENV1(unpackhsb)
1306
IWMMXT_OP_ENV1(unpackhsw)
1307
IWMMXT_OP_ENV1(unpackhsl)
1308

    
1309
IWMMXT_OP_ENV_SIZE(cmpeq)
1310
IWMMXT_OP_ENV_SIZE(cmpgtu)
1311
IWMMXT_OP_ENV_SIZE(cmpgts)
1312

    
1313
IWMMXT_OP_ENV_SIZE(mins)
1314
IWMMXT_OP_ENV_SIZE(minu)
1315
IWMMXT_OP_ENV_SIZE(maxs)
1316
IWMMXT_OP_ENV_SIZE(maxu)
1317

    
1318
IWMMXT_OP_ENV_SIZE(subn)
1319
IWMMXT_OP_ENV_SIZE(addn)
1320
IWMMXT_OP_ENV_SIZE(subu)
1321
IWMMXT_OP_ENV_SIZE(addu)
1322
IWMMXT_OP_ENV_SIZE(subs)
1323
IWMMXT_OP_ENV_SIZE(adds)
1324

    
1325
IWMMXT_OP_ENV(avgb0)
1326
IWMMXT_OP_ENV(avgb1)
1327
IWMMXT_OP_ENV(avgw0)
1328
IWMMXT_OP_ENV(avgw1)
1329

    
1330
IWMMXT_OP(msadb)
1331

    
1332
IWMMXT_OP_ENV(packuw)
1333
IWMMXT_OP_ENV(packul)
1334
IWMMXT_OP_ENV(packuq)
1335
IWMMXT_OP_ENV(packsw)
1336
IWMMXT_OP_ENV(packsl)
1337
IWMMXT_OP_ENV(packsq)
1338

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

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

    
1349
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1350
{
1351
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1352
}
1353

    
1354
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1355
{
1356
    iwmmxt_load_reg(cpu_V1, rn);
1357
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1358
}
1359

    
1360
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1361
{
1362
    TCGv tmp = tcg_const_i32(shift);
1363
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1364
}
1365

    
1366
static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1367
{
1368
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1369
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1370
    tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1371
}
1372

    
1373
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1374
{
1375
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1376
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1377
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1378
}
1379

    
1380
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1381
{
1382
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1383
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1384
    if (mask != ~0u)
1385
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1386
}
1387

    
1388
static void gen_op_iwmmxt_set_mup(void)
1389
{
1390
    TCGv tmp;
1391
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1392
    tcg_gen_ori_i32(tmp, tmp, 2);
1393
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1394
}
1395

    
1396
static void gen_op_iwmmxt_set_cup(void)
1397
{
1398
    TCGv tmp;
1399
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1400
    tcg_gen_ori_i32(tmp, tmp, 1);
1401
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1402
}
1403

    
1404
static void gen_op_iwmmxt_setpsr_nz(void)
1405
{
1406
    TCGv tmp = new_tmp();
1407
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1408
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1409
}
1410

    
1411
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1412
{
1413
    iwmmxt_load_reg(cpu_V1, rn);
1414
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1415
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1416
}
1417

    
1418

    
1419
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1420
{
1421
    iwmmxt_load_reg(cpu_V0, rn);
1422
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1423
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1424
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1425
}
1426

    
1427
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1428
{
1429
    tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
1430
    iwmmxt_store_reg(cpu_V0, rn);
1431
}
1432

    
1433
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1434
{
1435
    int rd;
1436
    uint32_t offset;
1437

    
1438
    rd = (insn >> 16) & 0xf;
1439
    gen_movl_T1_reg(s, rd);
1440

    
1441
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1442
    if (insn & (1 << 24)) {
1443
        /* Pre indexed */
1444
        if (insn & (1 << 23))
1445
            gen_op_addl_T1_im(offset);
1446
        else
1447
            gen_op_addl_T1_im(-offset);
1448

    
1449
        if (insn & (1 << 21))
1450
            gen_movl_reg_T1(s, rd);
1451
    } else if (insn & (1 << 21)) {
1452
        /* Post indexed */
1453
        if (insn & (1 << 23))
1454
            gen_op_movl_T0_im(offset);
1455
        else
1456
            gen_op_movl_T0_im(- offset);
1457
        gen_op_addl_T0_T1();
1458
        gen_movl_reg_T0(s, rd);
1459
    } else if (!(insn & (1 << 23)))
1460
        return 1;
1461
    return 0;
1462
}
1463

    
1464
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1465
{
1466
    int rd = (insn >> 0) & 0xf;
1467

    
1468
    if (insn & (1 << 8))
1469
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1470
            return 1;
1471
        else
1472
            gen_op_iwmmxt_movl_T0_wCx(rd);
1473
    else
1474
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1475

    
1476
    gen_op_movl_T1_im(mask);
1477
    gen_op_andl_T0_T1();
1478
    return 0;
1479
}
1480

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

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

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

    
1569
    if ((insn & 0x0f000000) != 0x0e000000)
1570
        return 1;
1571

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

    
2444
    return 0;
2445
}
2446

    
2447
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2448
   (ie. an undefined instruction).  */
2449
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2450
{
2451
    int acc, rd0, rd1, rdhi, rdlo;
2452

    
2453
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2454
        /* Multiply with Internal Accumulate Format */
2455
        rd0 = (insn >> 12) & 0xf;
2456
        rd1 = insn & 0xf;
2457
        acc = (insn >> 5) & 7;
2458

    
2459
        if (acc != 0)
2460
            return 1;
2461

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

    
2490
        gen_op_iwmmxt_movq_wRn_M0(acc);
2491
        return 0;
2492
    }
2493

    
2494
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2495
        /* Internal Accumulator Access Format */
2496
        rdhi = (insn >> 16) & 0xf;
2497
        rdlo = (insn >> 12) & 0xf;
2498
        acc = insn & 7;
2499

    
2500
        if (acc != 0)
2501
            return 1;
2502

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

    
2517
    return 1;
2518
}
2519

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

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

    
2549
static int cp15_user_ok(uint32_t insn)
2550
{
2551
    int cpn = (insn >> 16) & 0xf;
2552
    int cpm = insn & 0xf;
2553
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2554

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

    
2569
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2570
   instruction is not defined.  */
2571
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2572
{
2573
    uint32_t rd;
2574
    TCGv tmp;
2575

    
2576
    /* M profile cores use memory mapped registers instead of cp15.  */
2577
    if (arm_feature(env, ARM_FEATURE_M))
2578
        return 1;
2579

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

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

    
2638
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2639
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2640
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2641
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2642
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2643
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2644

    
2645
/* Move between integer and VFP cores.  */
2646
static TCGv gen_vfp_mrs(void)
2647
{
2648
    TCGv tmp = new_tmp();
2649
    tcg_gen_mov_i32(tmp, cpu_F0s);
2650
    return tmp;
2651
}
2652

    
2653
static void gen_vfp_msr(TCGv tmp)
2654
{
2655
    tcg_gen_mov_i32(cpu_F0s, tmp);
2656
    dead_tmp(tmp);
2657
}
2658

    
2659
static inline int
2660
vfp_enabled(CPUState * env)
2661
{
2662
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2663
}
2664

    
2665
static void gen_neon_dup_u8(TCGv var, int shift)
2666
{
2667
    TCGv tmp = new_tmp();
2668
    if (shift)
2669
        tcg_gen_shri_i32(var, var, shift);
2670
    tcg_gen_ext8u_i32(var, var);
2671
    tcg_gen_shli_i32(tmp, var, 8);
2672
    tcg_gen_or_i32(var, var, tmp);
2673
    tcg_gen_shli_i32(tmp, var, 16);
2674
    tcg_gen_or_i32(var, var, tmp);
2675
    dead_tmp(tmp);
2676
}
2677

    
2678
static void gen_neon_dup_low16(TCGv var)
2679
{
2680
    TCGv tmp = new_tmp();
2681
    tcg_gen_ext16u_i32(var, var);
2682
    tcg_gen_shli_i32(tmp, var, 16);
2683
    tcg_gen_or_i32(var, var, tmp);
2684
    dead_tmp(tmp);
2685
}
2686

    
2687
static void gen_neon_dup_high16(TCGv var)
2688
{
2689
    TCGv tmp = new_tmp();
2690
    tcg_gen_andi_i32(var, var, 0xffff0000);
2691
    tcg_gen_shri_i32(tmp, var, 16);
2692
    tcg_gen_or_i32(var, var, tmp);
2693
    dead_tmp(tmp);
2694
}
2695

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

    
2705
    if (!arm_feature(env, ARM_FEATURE_VFP))
2706
        return 1;
2707

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

    
2727
                VFP_DREG_N(rn, insn);
2728
                if (insn & 0xf)
2729
                    return 1;
2730
                if (insn & 0x00c00060
2731
                    && !arm_feature(env, ARM_FEATURE_NEON))
2732
                    return 1;
2733

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

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

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

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

    
2945
            veclen = env->vfp.vec_len;
2946
            if (op == 15 && rn > 3)
2947
                veclen = 0;
2948

    
2949
            /* Shut up compiler warnings.  */
2950
            delta_m = 0;
2951
            delta_d = 0;
2952
            bank_mask = 0;
2953

    
2954
            if (veclen > 0) {
2955
                if (dp)
2956
                    bank_mask = 0xc;
2957
                else
2958
                    bank_mask = 0x18;
2959

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

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

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

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

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

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

    
3198
                /* break out of the loop if we have finished  */
3199
                if (veclen == 0)
3200
                    break;
3201

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

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

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

    
3314
                if (insn & (1 << 24)) /* pre-decrement */
3315
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3316

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

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

    
3356
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3357
{
3358
    TranslationBlock *tb;
3359

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

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

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

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

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

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

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

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

    
3447
/* Generate an old-style exception return.  */
3448
static void gen_exception_return(DisasContext *s)
3449
{
3450
    TCGv tmp;
3451
    gen_movl_reg_T0(s, 15);
3452
    tmp = load_cpu_field(spsr);
3453
    gen_set_cpsr(tmp, 0xffffffff);
3454
    dead_tmp(tmp);
3455
    s->is_jmp = DISAS_UPDATE;
3456
}
3457

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

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

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

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

    
3499
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3500

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

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

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

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

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

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

    
3580
static inline void
3581
gen_neon_movl_scratch_T0(int scratch)
3582
{
3583
  uint32_t offset;
3584

    
3585
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3586
  tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3587
}
3588

    
3589
static inline void
3590
gen_neon_movl_scratch_T1(int scratch)
3591
{
3592
  uint32_t offset;
3593

    
3594
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3595
  tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3596
}
3597

    
3598
static inline void
3599
gen_neon_movl_T0_scratch(int scratch)
3600
{
3601
  uint32_t offset;
3602

    
3603
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3604
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3605
}
3606

    
3607
static inline void
3608
gen_neon_movl_T1_scratch(int scratch)
3609
{
3610
  uint32_t offset;
3611

    
3612
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3613
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3614
}
3615

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

    
3629
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3630
{
3631
    int n;
3632

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4016
static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4017
{
4018
    TCGv_i64 tmp;
4019

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

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

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

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

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

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

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

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

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

    
4683
                    gen_neon_widen(cpu_V0, tmp, size, u);
4684

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

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

    
4768
            if (op != 14 || !invert)
4769
                gen_op_movl_T1_im(imm);
4770

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

    
4826
                prewiden = neon_3reg_wide[op][0];
4827
                src1_wide = neon_3reg_wide[op][1];
4828
                src2_wide = neon_3reg_wide[op][2];
4829

    
4830
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4831
                    return 1;
4832

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

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

    
4923
                        if (op != 13) {
4924
                            neon_load_reg64(cpu_V1, rd + pass);
4925
                        }
4926

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

    
5058
                    gen_neon_get_scalar(size, rm);
5059
                    NEON_GET_REG(T1, rn, 1);
5060

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

    
5107
                if (imm > 7 && !q)
5108
                    return 1;
5109

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

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

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

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

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

    
5604
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5605
{
5606
    int cpnum;
5607

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

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

    
5643

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

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

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

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

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

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

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

    
5706
    insn = ldl_code(s->pc);
5707
    s->pc += 4;
5708

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

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

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

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

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

    
6079
        op1 = (insn >> 21) & 0xf;
6080
        set_cc = (insn >> 20) & 1;
6081
        logic_cc = table_logic_cc[op1] & set_cc;
6082

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

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

    
6748
                    if ((insn & (1 << 15)) == 0)
6749
                        user = 1;
6750
                }
6751
                rn = (insn >> 16) & 0xf;
6752
                addr = load_reg(s, rn);
6753

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

    
6858
                /* branch (and link) */
6859
                val = (int32_t)s->pc;
6860
                if (insn & (1 << 24)) {
6861
                    tmp = new_tmp();
6862
                    tcg_gen_movi_i32(tmp, val);
6863
                    store_reg(s, 14, tmp);
6864
                }
6865
                offset = (((int32_t)insn << 8) >> 8);
6866
                val += (offset << 2) + 4;
6867
                gen_jmp(s, val);
6868
            }
6869
            break;
6870
        case 0xc:
6871
        case 0xd:
6872
        case 0xe:
6873
            /* Coprocessor.  */
6874
            if (disas_coproc_insn(env, s, insn))
6875
                goto illegal_op;
6876
            break;
6877
        case 0xf:
6878
            /* swi */
6879
            gen_set_pc_im(s->pc);
6880
            s->is_jmp = DISAS_SWI;
6881
            break;
6882
        default:
6883
        illegal_op:
6884
            gen_set_condexec(s);
6885
            gen_set_pc_im(s->pc - 4);
6886
            gen_exception(EXCP_UDEF);
6887
            s->is_jmp = DISAS_JUMP;
6888
            break;
6889
        }
6890
    }
6891
}
6892

    
6893
/* Return true if this is a Thumb-2 logical op.  */
6894
static int
6895
thumb2_logic_op(int op)
6896
{
6897
    return (op < 8);
6898
}
6899

    
6900
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6901
   then set condition code flags based on the result of the operation.
6902
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6903
   to the high bit of T1.
6904
   Returns zero if the opcode is valid.  */
6905

    
6906
static int
6907
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6908
{
6909
    int logic_cc;
6910

    
6911
    logic_cc = 0;
6912
    switch (op) {
6913
    case 0: /* and */
6914
        gen_op_andl_T0_T1();
6915
        logic_cc = conds;
6916
        break;
6917
    case 1: /* bic */
6918
        gen_op_bicl_T0_T1();
6919
        logic_cc = conds;
6920
        break;
6921
    case 2: /* orr */
6922
        gen_op_orl_T0_T1();
6923
        logic_cc = conds;
6924
        break;
6925
    case 3: /* orn */
6926
        gen_op_notl_T1();
6927
        gen_op_orl_T0_T1();
6928
        logic_cc = conds;
6929
        break;
6930
    case 4: /* eor */
6931
        gen_op_xorl_T0_T1();
6932
        logic_cc = conds;
6933
        break;
6934
    case 8: /* add */
6935
        if (conds)
6936
            gen_op_addl_T0_T1_cc();
6937
        else
6938
            gen_op_addl_T0_T1();
6939
        break;
6940
    case 10: /* adc */
6941
        if (conds)
6942
            gen_op_adcl_T0_T1_cc();
6943
        else
6944
            gen_adc_T0_T1();
6945
        break;
6946
    case 11: /* sbc */
6947
        if (conds)
6948
            gen_op_sbcl_T0_T1_cc();
6949
        else
6950
            gen_sbc_T0_T1();
6951
        break;
6952
    case 13: /* sub */
6953
        if (conds)
6954
            gen_op_subl_T0_T1_cc();
6955
        else
6956
            gen_op_subl_T0_T1();
6957
        break;
6958
    case 14: /* rsb */
6959
        if (conds)
6960
            gen_op_rsbl_T0_T1_cc();
6961
        else
6962
            gen_op_rsbl_T0_T1();
6963
        break;
6964
    default: /* 5, 6, 7, 9, 12, 15. */
6965
        return 1;
6966
    }
6967
    if (logic_cc) {
6968
        gen_op_logic_T0_cc();
6969
        if (shifter_out)
6970
            gen_set_CF_bit31(cpu_T[1]);
6971
    }
6972
    return 0;
6973
}
6974

    
6975
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
6976
   is not legal.  */
6977
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6978
{
6979
    uint32_t insn, imm, shift, offset;
6980
    uint32_t rd, rn, rm, rs;
6981
    TCGv tmp;
6982
    TCGv tmp2;
6983
    TCGv tmp3;
6984
    TCGv addr;
6985
    TCGv_i64 tmp64;
6986
    int op;
6987
    int shiftop;
6988
    int conds;
6989
    int logic_cc;
6990

    
6991
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6992
          || arm_feature (env, ARM_FEATURE_M))) {
6993
        /* Thumb-1 cores may need to treat bl and blx as a pair of
6994
           16-bit instructions to get correct prefetch abort behavior.  */
6995
        insn = insn_hw1;
6996
        if ((insn & (1 << 12)) == 0) {
6997
            /* Second half of blx.  */
6998
            offset = ((insn & 0x7ff) << 1);
6999
            tmp = load_reg(s, 14);
7000
            tcg_gen_addi_i32(tmp, tmp, offset);
7001
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7002

    
7003
            tmp2 = new_tmp();
7004
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7005
            store_reg(s, 14, tmp2);
7006
            gen_bx(s, tmp);
7007
            return 0;
7008
        }
7009
        if (insn & (1 << 11)) {
7010
            /* Second half of bl.  */
7011
            offset = ((insn & 0x7ff) << 1) | 1;
7012
            tmp = load_reg(s, 14);
7013
            tcg_gen_addi_i32(tmp, tmp, offset);
7014

    
7015
            tmp2 = new_tmp();
7016
            tcg_gen_movi_i32(tmp2, s->pc | 1);
7017
            store_reg(s, 14, tmp2);
7018
            gen_bx(s, tmp);
7019
            return 0;
7020
        }
7021
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7022
            /* Instruction spans a page boundary.  Implement it as two
7023
               16-bit instructions in case the second half causes an
7024
               prefetch abort.  */
7025
            offset = ((int32_t)insn << 21) >> 9;
7026
            gen_op_movl_T0_im(s->pc + 2 + offset);
7027
            gen_movl_reg_T0(s, 14);
7028
            return 0;
7029
        }
7030
        /* Fall through to 32-bit decode.  */
7031
    }
7032

    
7033
    insn = lduw_code(s->pc);
7034
    s->pc += 2;
7035
    insn |= (uint32_t)insn_hw1 << 16;
7036

    
7037
    if ((insn & 0xf800e800) != 0xf000e800) {
7038
        ARCH(6T2);
7039
    }
7040

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

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

    
7594
                if (insn & (1 << 14)) {
7595
                    /* Branch and link.  */
7596
                    gen_op_movl_T1_im(s->pc | 1);
7597
                    gen_movl_reg_T1(s, 14);
7598
                }
7599

    
7600
                offset += s->pc;
7601
                if (insn & (1 << 12)) {
7602
                    /* b/bl */
7603
                    gen_jmp(s, offset);
7604
                } else {
7605
                    /* blx */
7606
                    offset &= ~(uint32_t)2;
7607
                    gen_bx_im(s, offset);
7608
                }
7609
            } else if (((insn >> 23) & 7) == 7) {
7610
                /* Misc control */
7611
                if (insn & (1 << 13))
7612
                    goto illegal_op;
7613

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

    
7717
                /* offset[11:1] = insn[10:0] */
7718
                offset = (insn & 0x7ff) << 1;
7719
                /* offset[17:12] = insn[21:16].  */
7720
                offset |= (insn & 0x003f0000) >> 4;
7721
                /* offset[31:20] = insn[26].  */
7722
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7723
                /* offset[18] = insn[13].  */
7724
                offset |= (insn & (1 << 13)) << 5;
7725
                /* offset[19] = insn[11].  */
7726
                offset |= (insn & (1 << 11)) << 8;
7727

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

    
7996
static void disas_thumb_insn(CPUState *env, DisasContext *s)
7997
{
7998
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
7999
    int32_t offset;
8000
    int i;
8001
    TCGv tmp;
8002
    TCGv tmp2;
8003
    TCGv addr;
8004

    
8005
    if (s->condexec_mask) {
8006
        cond = s->condexec_cond;
8007
        s->condlabel = gen_new_label();
8008
        gen_test_cc(cond ^ 1, s->condlabel);
8009
        s->condjmp = 1;
8010
    }
8011

    
8012
    insn = lduw_code(s->pc);
8013
    s->pc += 2;
8014

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

    
8136
        /* data processing register */
8137
        rd = insn & 7;
8138
        rm = (insn >> 3) & 7;
8139
        op = (insn >> 6) & 0xf;
8140
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8141
            /* the shift/rotate ops want the operands backwards */
8142
            val = rm;
8143
            rm = rd;
8144
            rd = val;
8145
            val = 1;
8146
        } else {
8147
            val = 0;
8148
        }
8149

    
8150
        if (op == 9) /* neg */
8151
            gen_op_movl_T0_im(0);
8152
        else if (op != 0xf) /* mvn doesn't read its first operand */
8153
            gen_movl_T0_reg(s, rd);
8154

    
8155
        gen_movl_T1_reg(s, rm);
8156
        switch (op) {
8157
        case 0x0: /* and */
8158
            gen_op_andl_T0_T1();
8159
            if (!s->condexec_mask)
8160
                gen_op_logic_T0_cc();
8161
            break;
8162
        case 0x1: /* eor */
8163
            gen_op_xorl_T0_T1();
8164
            if (!s->condexec_mask)
8165
                gen_op_logic_T0_cc();
8166
            break;
8167
        case 0x2: /* lsl */
8168
            if (s->condexec_mask) {
8169
                gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8170
            } else {
8171
                gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8172
                gen_op_logic_T1_cc();
8173
            }
8174
            break;
8175
        case 0x3: /* lsr */
8176
            if (s->condexec_mask) {
8177
                gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8178
            } else {
8179
                gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8180
                gen_op_logic_T1_cc();
8181
            }
8182
            break;
8183
        case 0x4: /* asr */
8184
            if (s->condexec_mask) {
8185
                gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8186
            } else {
8187
                gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8188
                gen_op_logic_T1_cc();
8189
            }
8190
            break;
8191
        case 0x5: /* adc */
8192
            if (s->condexec_mask)
8193
                gen_adc_T0_T1();
8194
            else
8195
                gen_op_adcl_T0_T1_cc();
8196
            break;
8197
        case 0x6: /* sbc */
8198
            if (s->condexec_mask)
8199
                gen_sbc_T0_T1();
8200
            else
8201
                gen_op_sbcl_T0_T1_cc();
8202
            break;
8203
        case 0x7: /* ror */
8204
            if (s->condexec_mask) {
8205
                gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8206
            } else {
8207
                gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8208
                gen_op_logic_T1_cc();
8209
            }
8210
            break;
8211
        case 0x8: /* tst */
8212
            gen_op_andl_T0_T1();
8213
            gen_op_logic_T0_cc();
8214
            rd = 16;
8215
            break;
8216
        case 0x9: /* neg */
8217
            if (s->condexec_mask)
8218
                tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8219
            else
8220
                gen_op_subl_T0_T1_cc();
8221
            break;
8222
        case 0xa: /* cmp */
8223
            gen_op_subl_T0_T1_cc();
8224
            rd = 16;
8225
            break;
8226
        case 0xb: /* cmn */
8227
            gen_op_addl_T0_T1_cc();
8228
            rd = 16;
8229
            break;
8230
        case 0xc: /* orr */
8231
            gen_op_orl_T0_T1();
8232
            if (!s->condexec_mask)
8233
                gen_op_logic_T0_cc();
8234
            break;
8235
        case 0xd: /* mul */
8236
            gen_op_mull_T0_T1();
8237
            if (!s->condexec_mask)
8238
                gen_op_logic_T0_cc();
8239
            break;
8240
        case 0xe: /* bic */
8241
            gen_op_bicl_T0_T1();
8242
            if (!s->condexec_mask)
8243
                gen_op_logic_T0_cc();
8244
            break;
8245
        case 0xf: /* mvn */
8246
            gen_op_notl_T1();
8247
            if (!s->condexec_mask)
8248
                gen_op_logic_T1_cc();
8249
            val = 1;
8250
            rm = rd;
8251
            break;
8252
        }
8253
        if (rd != 16) {
8254
            if (val)
8255
                gen_movl_reg_T1(s, rm);
8256
            else
8257
                gen_movl_reg_T0(s, rd);
8258
        }
8259
        break;
8260

    
8261
    case 5:
8262
        /* load/store register offset.  */
8263
        rd = insn & 7;
8264
        rn = (insn >> 3) & 7;
8265
        rm = (insn >> 6) & 7;
8266
        op = (insn >> 9) & 7;
8267
        addr = load_reg(s, rn);
8268
        tmp = load_reg(s, rm);
8269
        tcg_gen_add_i32(addr, addr, tmp);
8270
        dead_tmp(tmp);
8271

    
8272
        if (op < 3) /* store */
8273
            tmp = load_reg(s, rd);
8274

    
8275
        switch (op) {
8276
        case 0: /* str */
8277
            gen_st32(tmp, addr, IS_USER(s));
8278
            break;
8279
        case 1: /* strh */
8280
            gen_st16(tmp, addr, IS_USER(s));
8281
            break;
8282
        case 2: /* strb */
8283
            gen_st8(tmp, addr, IS_USER(s));
8284
            break;
8285
        case 3: /* ldrsb */
8286
            tmp = gen_ld8s(addr, IS_USER(s));
8287
            break;
8288
        case 4: /* ldr */
8289
            tmp = gen_ld32(addr, IS_USER(s));
8290
            break;
8291
        case 5: /* ldrh */
8292
            tmp = gen_ld16u(addr, IS_USER(s));
8293
            break;
8294
        case 6: /* ldrb */
8295
            tmp = gen_ld8u(addr, IS_USER(s));
8296
            break;
8297
        case 7: /* ldrsh */
8298
            tmp = gen_ld16s(addr, IS_USER(s));
8299
            break;
8300
        }
8301
        if (op >= 3) /* load */
8302
            store_reg(s, rd, tmp);
8303
        dead_tmp(addr);
8304
        break;
8305

    
8306
    case 6:
8307
        /* load/store word immediate offset */
8308
        rd = insn & 7;
8309
        rn = (insn >> 3) & 7;
8310
        addr = load_reg(s, rn);
8311
        val = (insn >> 4) & 0x7c;
8312
        tcg_gen_addi_i32(addr, addr, val);
8313

    
8314
        if (insn & (1 << 11)) {
8315
            /* load */
8316
            tmp = gen_ld32(addr, IS_USER(s));
8317
            store_reg(s, rd, tmp);
8318
        } else {
8319
            /* store */
8320
            tmp = load_reg(s, rd);
8321
            gen_st32(tmp, addr, IS_USER(s));
8322
        }
8323
        dead_tmp(addr);
8324
        break;
8325

    
8326
    case 7:
8327
        /* load/store byte immediate offset */
8328
        rd = insn & 7;
8329
        rn = (insn >> 3) & 7;
8330
        addr = load_reg(s, rn);
8331
        val = (insn >> 6) & 0x1f;
8332
        tcg_gen_addi_i32(addr, addr, val);
8333

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

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

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

    
8366
    case 9:
8367
        /* load/store from stack */
8368
        rd = (insn >> 8) & 7;
8369
        addr = load_reg(s, 13);
8370
        val = (insn & 0xff) * 4;
8371
        tcg_gen_addi_i32(addr, addr, val);
8372

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

    
8385
    case 10:
8386
        /* add to high reg */
8387
        rd = (insn >> 8) & 7;
8388
        if (insn & (1 << 11)) {
8389
            /* SP */
8390
            tmp = load_reg(s, 13);
8391
        } else {
8392
            /* PC. bit 1 is ignored.  */
8393
            tmp = new_tmp();
8394
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8395
        }
8396
        val = (insn & 0xff) * 4;
8397
        tcg_gen_addi_i32(tmp, tmp, val);
8398
        store_reg(s, rd, tmp);
8399
        break;
8400

    
8401
    case 11:
8402
        /* misc */
8403
        op = (insn >> 8) & 0xf;
8404
        switch (op) {
8405
        case 0:
8406
            /* adjust stack pointer */
8407
            tmp = load_reg(s, 13);
8408
            val = (insn & 0x7f) * 4;
8409
            if (insn & (1 << 7))
8410
                val = -(int32_t)val;
8411
            tcg_gen_addi_i32(tmp, tmp, val);
8412
            store_reg(s, 13, tmp);
8413
            break;
8414

    
8415
        case 2: /* sign/zero extend.  */
8416
            ARCH(6);
8417
            rd = insn & 7;
8418
            rm = (insn >> 3) & 7;
8419
            tmp = load_reg(s, rm);
8420
            switch ((insn >> 6) & 3) {
8421
            case 0: gen_sxth(tmp); break;
8422
            case 1: gen_sxtb(tmp); break;
8423
            case 2: gen_uxth(tmp); break;
8424
            case 3: gen_uxtb(tmp); break;
8425
            }
8426
            store_reg(s, rd, tmp);
8427
            break;
8428
        case 4: case 5: case 0xc: case 0xd:
8429
            /* push/pop */
8430
            addr = load_reg(s, 13);
8431
            if (insn & (1 << 8))
8432
                offset = 4;
8433
            else
8434
                offset = 0;
8435
            for (i = 0; i < 8; i++) {
8436
                if (insn & (1 << i))
8437
                    offset += 4;
8438
            }
8439
            if ((insn & (1 << 11)) == 0) {
8440
                tcg_gen_addi_i32(addr, addr, -offset);
8441
            }
8442
            for (i = 0; i < 8; i++) {
8443
                if (insn & (1 << i)) {
8444
                    if (insn & (1 << 11)) {
8445
                        /* pop */
8446
                        tmp = gen_ld32(addr, IS_USER(s));
8447
                        store_reg(s, i, tmp);
8448
                    } else {
8449
                        /* push */
8450
                        tmp = load_reg(s, i);
8451
                        gen_st32(tmp, addr, IS_USER(s));
8452
                    }
8453
                    /* advance to the next address.  */
8454
                    tcg_gen_addi_i32(addr, addr, 4);
8455
                }
8456
            }
8457
            TCGV_UNUSED(tmp);
8458
            if (insn & (1 << 8)) {
8459
                if (insn & (1 << 11)) {
8460
                    /* pop pc */
8461
                    tmp = gen_ld32(addr, IS_USER(s));
8462
                    /* don't set the pc until the rest of the instruction
8463
                       has completed */
8464
                } else {
8465
                    /* push lr */
8466
                    tmp = load_reg(s, 14);
8467
                    gen_st32(tmp, addr, IS_USER(s));
8468
                }
8469
                tcg_gen_addi_i32(addr, addr, 4);
8470
            }
8471
            if ((insn & (1 << 11)) == 0) {
8472
                tcg_gen_addi_i32(addr, addr, -offset);
8473
            }
8474
            /* write back the new stack pointer */
8475
            store_reg(s, 13, addr);
8476
            /* set the new PC value */
8477
            if ((insn & 0x0900) == 0x0900)
8478
                gen_bx(s, tmp);
8479
            break;
8480

    
8481
        case 1: case 3: case 9: case 11: /* czb */
8482
            rm = insn & 7;
8483
            tmp = load_reg(s, rm);
8484
            s->condlabel = gen_new_label();
8485
            s->condjmp = 1;
8486
            if (insn & (1 << 11))
8487
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8488
            else
8489
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8490
            dead_tmp(tmp);
8491
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8492
            val = (uint32_t)s->pc + 2;
8493
            val += offset;
8494
            gen_jmp(s, val);
8495
            break;
8496

    
8497
        case 15: /* IT, nop-hint.  */
8498
            if ((insn & 0xf) == 0) {
8499
                gen_nop_hint(s, (insn >> 4) & 0xf);
8500
                break;
8501
            }
8502
            /* If Then.  */
8503
            s->condexec_cond = (insn >> 4) & 0xe;
8504
            s->condexec_mask = insn & 0x1f;
8505
            /* No actual code generated for this insn, just setup state.  */
8506
            break;
8507

    
8508
        case 0xe: /* bkpt */
8509
            gen_set_condexec(s);
8510
            gen_set_pc_im(s->pc - 2);
8511
            gen_exception(EXCP_BKPT);
8512
            s->is_jmp = DISAS_JUMP;
8513
            break;
8514

    
8515
        case 0xa: /* rev */
8516
            ARCH(6);
8517
            rn = (insn >> 3) & 0x7;
8518
            rd = insn & 0x7;
8519
            tmp = load_reg(s, rn);
8520
            switch ((insn >> 6) & 3) {
8521
            case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8522
            case 1: gen_rev16(tmp); break;
8523
            case 3: gen_revsh(tmp); break;
8524
            default: goto illegal_op;
8525
            }
8526
            store_reg(s, rd, tmp);
8527
            break;
8528

    
8529
        case 6: /* cps */
8530
            ARCH(6);
8531
            if (IS_USER(s))
8532
                break;
8533
            if (IS_M(env)) {
8534
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8535
                /* PRIMASK */
8536
                if (insn & 1) {
8537
                    addr = tcg_const_i32(16);
8538
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8539
                }
8540
                /* FAULTMASK */
8541
                if (insn & 2) {
8542
                    addr = tcg_const_i32(17);
8543
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8544
                }
8545
                gen_lookup_tb(s);
8546
            } else {
8547
                if (insn & (1 << 4))
8548
                    shift = CPSR_A | CPSR_I | CPSR_F;
8549
                else
8550
                    shift = 0;
8551

    
8552
                val = ((insn & 7) << 6) & shift;
8553
                gen_op_movl_T0_im(val);
8554
                gen_set_psr_T0(s, shift, 0);
8555
            }
8556
            break;
8557

    
8558
        default:
8559
            goto undef;
8560
        }
8561
        break;
8562

    
8563
    case 12:
8564
        /* load/store multiple */
8565
        rn = (insn >> 8) & 0x7;
8566
        addr = load_reg(s, rn);
8567
        for (i = 0; i < 8; i++) {
8568
            if (insn & (1 << i)) {
8569
                if (insn & (1 << 11)) {
8570
                    /* load */
8571
                    tmp = gen_ld32(addr, IS_USER(s));
8572
                    store_reg(s, i, tmp);
8573
                } else {
8574
                    /* store */
8575
                    tmp = load_reg(s, i);
8576
                    gen_st32(tmp, addr, IS_USER(s));
8577
                }
8578
                /* advance to the next address */
8579
                tcg_gen_addi_i32(addr, addr, 4);
8580
            }
8581
        }
8582
        /* Base register writeback.  */
8583
        if ((insn & (1 << rn)) == 0) {
8584
            store_reg(s, rn, addr);
8585
        } else {
8586
            dead_tmp(addr);
8587
        }
8588
        break;
8589

    
8590
    case 13:
8591
        /* conditional branch or swi */
8592
        cond = (insn >> 8) & 0xf;
8593
        if (cond == 0xe)
8594
            goto undef;
8595

    
8596
        if (cond == 0xf) {
8597
            /* swi */
8598
            gen_set_condexec(s);
8599
            gen_set_pc_im(s->pc);
8600
            s->is_jmp = DISAS_SWI;
8601
            break;
8602
        }
8603
        /* generate a conditional jump to next instruction */
8604
        s->condlabel = gen_new_label();
8605
        gen_test_cc(cond ^ 1, s->condlabel);
8606
        s->condjmp = 1;
8607
        gen_movl_T1_reg(s, 15);
8608

    
8609
        /* jump to the offset */
8610
        val = (uint32_t)s->pc + 2;
8611
        offset = ((int32_t)insn << 24) >> 24;
8612
        val += offset << 1;
8613
        gen_jmp(s, val);
8614
        break;
8615

    
8616
    case 14:
8617
        if (insn & (1 << 11)) {
8618
            if (disas_thumb2_insn(env, s, insn))
8619
              goto undef32;
8620
            break;
8621
        }
8622
        /* unconditional branch */
8623
        val = (uint32_t)s->pc;
8624
        offset = ((int32_t)insn << 21) >> 21;
8625
        val += (offset << 1) + 2;
8626
        gen_jmp(s, val);
8627
        break;
8628

    
8629
    case 15:
8630
        if (disas_thumb2_insn(env, s, insn))
8631
            goto undef32;
8632
        break;
8633
    }
8634
    return;
8635
undef32:
8636
    gen_set_condexec(s);
8637
    gen_set_pc_im(s->pc - 4);
8638
    gen_exception(EXCP_UDEF);
8639
    s->is_jmp = DISAS_JUMP;
8640
    return;
8641
illegal_op:
8642
undef:
8643
    gen_set_condexec(s);
8644
    gen_set_pc_im(s->pc - 2);
8645
    gen_exception(EXCP_UDEF);
8646
    s->is_jmp = DISAS_JUMP;
8647
}
8648

    
8649
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8650
   basic block 'tb'. If search_pc is TRUE, also generate PC
8651
   information for each intermediate instruction. */
8652
static inline void gen_intermediate_code_internal(CPUState *env,
8653
                                                  TranslationBlock *tb,
8654
                                                  int search_pc)
8655
{
8656
    DisasContext dc1, *dc = &dc1;
8657
    CPUBreakpoint *bp;
8658
    uint16_t *gen_opc_end;
8659
    int j, lj;
8660
    target_ulong pc_start;
8661
    uint32_t next_page_start;
8662
    int num_insns;
8663
    int max_insns;
8664

    
8665
    /* generate intermediate code */
8666
    num_temps = 0;
8667
    memset(temps, 0, sizeof(temps));
8668

    
8669
    pc_start = tb->pc;
8670

    
8671
    dc->tb = tb;
8672

    
8673
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8674

    
8675
    dc->is_jmp = DISAS_NEXT;
8676
    dc->pc = pc_start;
8677
    dc->singlestep_enabled = env->singlestep_enabled;
8678
    dc->condjmp = 0;
8679
    dc->thumb = env->thumb;
8680
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8681
    dc->condexec_cond = env->condexec_bits >> 4;
8682
#if !defined(CONFIG_USER_ONLY)
8683
    if (IS_M(env)) {
8684
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8685
    } else {
8686
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8687
    }
8688
#endif
8689
    cpu_F0s = tcg_temp_new_i32();
8690
    cpu_F1s = tcg_temp_new_i32();
8691
    cpu_F0d = tcg_temp_new_i64();
8692
    cpu_F1d = tcg_temp_new_i64();
8693
    cpu_V0 = cpu_F0d;
8694
    cpu_V1 = cpu_F1d;
8695
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
8696
    cpu_M0 = tcg_temp_new_i64();
8697
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8698
    lj = -1;
8699
    num_insns = 0;
8700
    max_insns = tb->cflags & CF_COUNT_MASK;
8701
    if (max_insns == 0)
8702
        max_insns = CF_COUNT_MASK;
8703

    
8704
    gen_icount_start();
8705
    /* Reset the conditional execution bits immediately. This avoids
8706
       complications trying to do it at the end of the block.  */
8707
    if (env->condexec_bits)
8708
      {
8709
        TCGv tmp = new_tmp();
8710
        tcg_gen_movi_i32(tmp, 0);
8711
        store_cpu_field(tmp, condexec_bits);
8712
      }
8713
    do {
8714
#ifdef CONFIG_USER_ONLY
8715
        /* Intercept jump to the magic kernel page.  */
8716
        if (dc->pc >= 0xffff0000) {
8717
            /* We always get here via a jump, so know we are not in a
8718
               conditional execution block.  */
8719
            gen_exception(EXCP_KERNEL_TRAP);
8720
            dc->is_jmp = DISAS_UPDATE;
8721
            break;
8722
        }
8723
#else
8724
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8725
            /* We always get here via a jump, so know we are not in a
8726
               conditional execution block.  */
8727
            gen_exception(EXCP_EXCEPTION_EXIT);
8728
            dc->is_jmp = DISAS_UPDATE;
8729
            break;
8730
        }
8731
#endif
8732

    
8733
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8734
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8735
                if (bp->pc == dc->pc) {
8736
                    gen_set_condexec(dc);
8737
                    gen_set_pc_im(dc->pc);
8738
                    gen_exception(EXCP_DEBUG);
8739
                    dc->is_jmp = DISAS_JUMP;
8740
                    /* Advance PC so that clearing the breakpoint will
8741
                       invalidate this TB.  */
8742
                    dc->pc += 2;
8743
                    goto done_generating;
8744
                    break;
8745
                }
8746
            }
8747
        }
8748
        if (search_pc) {
8749
            j = gen_opc_ptr - gen_opc_buf;
8750
            if (lj < j) {
8751
                lj++;
8752
                while (lj < j)
8753
                    gen_opc_instr_start[lj++] = 0;
8754
            }
8755
            gen_opc_pc[lj] = dc->pc;
8756
            gen_opc_instr_start[lj] = 1;
8757
            gen_opc_icount[lj] = num_insns;
8758
        }
8759

    
8760
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8761
            gen_io_start();
8762

    
8763
        if (env->thumb) {
8764
            disas_thumb_insn(env, dc);
8765
            if (dc->condexec_mask) {
8766
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8767
                                   | ((dc->condexec_mask >> 4) & 1);
8768
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8769
                if (dc->condexec_mask == 0) {
8770
                    dc->condexec_cond = 0;
8771
                }
8772
            }
8773
        } else {
8774
            disas_arm_insn(env, dc);
8775
        }
8776
        if (num_temps) {
8777
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8778
            num_temps = 0;
8779
        }
8780

    
8781
        if (dc->condjmp && !dc->is_jmp) {
8782
            gen_set_label(dc->condlabel);
8783
            dc->condjmp = 0;
8784
        }
8785
        /* Translation stops when a conditional branch is encountered.
8786
         * Otherwise the subsequent code could get translated several times.
8787
         * Also stop translation when a page boundary is reached.  This
8788
         * ensures prefetch aborts occur at the right place.  */
8789
        num_insns ++;
8790
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8791
             !env->singlestep_enabled &&
8792
             dc->pc < next_page_start &&
8793
             num_insns < max_insns);
8794

    
8795
    if (tb->cflags & CF_LAST_IO) {
8796
        if (dc->condjmp) {
8797
            /* FIXME:  This can theoretically happen with self-modifying
8798
               code.  */
8799
            cpu_abort(env, "IO on conditional branch instruction");
8800
        }
8801
        gen_io_end();
8802
    }
8803

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

    
8868
done_generating:
8869
    gen_icount_end(tb, num_insns);
8870
    *gen_opc_ptr = INDEX_op_end;
8871

    
8872
#ifdef DEBUG_DISAS
8873
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8874
        fprintf(logfile, "----------------\n");
8875
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8876
        target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8877
        fprintf(logfile, "\n");
8878
    }
8879
#endif
8880
    if (search_pc) {
8881
        j = gen_opc_ptr - gen_opc_buf;
8882
        lj++;
8883
        while (lj <= j)
8884
            gen_opc_instr_start[lj++] = 0;
8885
    } else {
8886
        tb->size = dc->pc - pc_start;
8887
        tb->icount = num_insns;
8888
    }
8889
}
8890

    
8891
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8892
{
8893
    gen_intermediate_code_internal(env, tb, 0);
8894
}
8895

    
8896
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8897
{
8898
    gen_intermediate_code_internal(env, tb, 1);
8899
}
8900

    
8901
static const char *cpu_mode_names[16] = {
8902
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8903
  "???", "???", "???", "und", "???", "???", "???", "sys"
8904
};
8905

    
8906
void cpu_dump_state(CPUState *env, FILE *f,
8907
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8908
                    int flags)
8909
{
8910
    int i;
8911
#if 0
8912
    union {
8913
        uint32_t i;
8914
        float s;
8915
    } s0, s1;
8916
    CPU_DoubleU d;
8917
    /* ??? This assumes float64 and double have the same layout.
8918
       Oh well, it's only debug dumps.  */
8919
    union {
8920
        float64 f64;
8921
        double d;
8922
    } d0;
8923
#endif
8924
    uint32_t psr;
8925

    
8926
    for(i=0;i<16;i++) {
8927
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8928
        if ((i % 4) == 3)
8929
            cpu_fprintf(f, "\n");
8930
        else
8931
            cpu_fprintf(f, " ");
8932
    }
8933
    psr = cpsr_read(env);
8934
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8935
                psr,
8936
                psr & (1 << 31) ? 'N' : '-',
8937
                psr & (1 << 30) ? 'Z' : '-',
8938
                psr & (1 << 29) ? 'C' : '-',
8939
                psr & (1 << 28) ? 'V' : '-',
8940
                psr & CPSR_T ? 'T' : 'A',
8941
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8942

    
8943
#if 0
8944
    for (i = 0; i < 16; i++) {
8945
        d.d = env->vfp.regs[i];
8946
        s0.i = d.l.lower;
8947
        s1.i = d.l.upper;
8948
        d0.f64 = d.d;
8949
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8950
                    i * 2, (int)s0.i, s0.s,
8951
                    i * 2 + 1, (int)s1.i, s1.s,
8952
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8953
                    d0.d);
8954
    }
8955
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8956
#endif
8957
}
8958

    
8959
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8960
                unsigned long searched_pc, int pc_pos, void *puc)
8961
{
8962
    env->regs[15] = gen_opc_pc[pc_pos];
8963
}