Statistics
| Branch: | Revision:

root / target-arm / translate.c @ cbbccffc

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., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
21
 */
22
#include <stdarg.h>
23
#include <stdlib.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include <inttypes.h>
27

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
194

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

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

    
205
#define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
206
#define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
207
#define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
208
#define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
209
#define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
210
#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
                        for (n = 0; n <= pass * 2; n++) {
2787
                            tmp2 = new_tmp();
2788
                            tcg_gen_mov_i32(tmp2, tmp);
2789
                            neon_store_reg(rn, n, tmp2);
2790
                        }
2791
                        neon_store_reg(rn, n, tmp);
2792
                    } else {
2793
                        /* VMOV */
2794
                        switch (size) {
2795
                        case 0:
2796
                            tmp2 = neon_load_reg(rn, pass);
2797
                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);
2798
                            dead_tmp(tmp2);
2799
                            break;
2800
                        case 1:
2801
                            tmp2 = neon_load_reg(rn, pass);
2802
                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
2803
                            dead_tmp(tmp2);
2804
                            break;
2805
                        case 2:
2806
                            break;
2807
                        }
2808
                        neon_store_reg(rn, pass, tmp);
2809
                    }
2810
                }
2811
            } else { /* !dp */
2812
                if ((insn & 0x6f) != 0x00)
2813
                    return 1;
2814
                rn = VFP_SREG_N(insn);
2815
                if (insn & ARM_CP_RW_BIT) {
2816
                    /* vfp->arm */
2817
                    if (insn & (1 << 21)) {
2818
                        /* system register */
2819
                        rn >>= 1;
2820

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3501
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3502

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

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

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

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

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

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

    
3582
static inline void
3583
gen_neon_movl_scratch_T0(int scratch)
3584
{
3585
  uint32_t offset;
3586

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

    
3591
static inline void
3592
gen_neon_movl_scratch_T1(int scratch)
3593
{
3594
  uint32_t offset;
3595

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4685
                    gen_neon_widen(cpu_V0, tmp, size, u);
4686

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

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

    
4770
            if (op != 14 || !invert)
4771
                gen_op_movl_T1_im(imm);
4772

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

    
4828
                prewiden = neon_3reg_wide[op][0];
4829
                src1_wide = neon_3reg_wide[op][1];
4830
                src2_wide = neon_3reg_wide[op][2];
4831

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

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

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

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

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

    
5060
                    gen_neon_get_scalar(size, rm);
5061
                    NEON_GET_REG(T1, rn, 1);
5062

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

    
5109
                if (imm > 7 && !q)
5110
                    return 1;
5111

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

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

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

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

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

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

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

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

    
5645

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

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

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

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

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

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

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

    
5708
    insn = ldl_code(s->pc);
5709
    s->pc += 4;
5710

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8014
    insn = lduw_code(s->pc);
8015
    s->pc += 2;
8016

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8560
        default:
8561
            goto undef;
8562
        }
8563
        break;
8564

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

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

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

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

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

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

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

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

    
8671
    pc_start = tb->pc;
8672

    
8673
    dc->tb = tb;
8674

    
8675
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8676

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

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

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

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

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

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

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

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

    
8870
done_generating:
8871
    gen_icount_end(tb, num_insns);
8872
    *gen_opc_ptr = INDEX_op_end;
8873

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

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

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

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

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

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

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

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