Statistics
| Branch: | Revision:

root / target-arm / translate.c @ c0ce998e

History | View | Annotate | Download (298 kB)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
195

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

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

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

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

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

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

    
234
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
235
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
236

    
237
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
238

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

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

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

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

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

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

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

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

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

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

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

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

    
345
static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
346
{
347
    TCGv_i64 tmp1 = tcg_temp_new_i64();
348
    TCGv_i64 tmp2 = tcg_temp_new_i64();
349

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

    
358
/* Unsigned 32x32->64 multiply.  */
359
static void gen_op_mull_T0_T1(void)
360
{
361
    TCGv_i64 tmp1 = tcg_temp_new_i64();
362
    TCGv_i64 tmp2 = tcg_temp_new_i64();
363

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

    
372
/* Signed 32x32->64 multiply.  */
373
static void gen_imull(TCGv a, TCGv b)
374
{
375
    TCGv_i64 tmp1 = tcg_temp_new_i64();
376
    TCGv_i64 tmp2 = tcg_temp_new_i64();
377

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

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

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

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

    
417
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
418

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

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

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

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

    
456
#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
457
#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
458

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

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

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

    
482
    if (i == 0)
483
        return;
484

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1007
VFP_OP2(add)
1008
VFP_OP2(sub)
1009
VFP_OP2(mul)
1010
VFP_OP2(div)
1011

    
1012
#undef VFP_OP2
1013

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1189
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1190
{
1191
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192
}
1193

    
1194
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1195
{
1196
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1197
}
1198

    
1199
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1200
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1201
#define tcg_gen_st_f32 tcg_gen_st_i32
1202
#define tcg_gen_st_f64 tcg_gen_st_i64
1203

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

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

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

    
1228
#define ARM_CP_RW_BIT        (1 << 20)
1229

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

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

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

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

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

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

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

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

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

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

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

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

    
1297
#define IWMMXT_OP_ENV_SIZE(name) \
1298
IWMMXT_OP_ENV(name##b) \
1299
IWMMXT_OP_ENV(name##w) \
1300
IWMMXT_OP_ENV(name##l)
1301

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

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

    
1319
IWMMXT_OP_ENV_SIZE(unpackl)
1320
IWMMXT_OP_ENV_SIZE(unpackh)
1321

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

    
1335
IWMMXT_OP_ENV_SIZE(cmpeq)
1336
IWMMXT_OP_ENV_SIZE(cmpgtu)
1337
IWMMXT_OP_ENV_SIZE(cmpgts)
1338

    
1339
IWMMXT_OP_ENV_SIZE(mins)
1340
IWMMXT_OP_ENV_SIZE(minu)
1341
IWMMXT_OP_ENV_SIZE(maxs)
1342
IWMMXT_OP_ENV_SIZE(maxu)
1343

    
1344
IWMMXT_OP_ENV_SIZE(subn)
1345
IWMMXT_OP_ENV_SIZE(addn)
1346
IWMMXT_OP_ENV_SIZE(subu)
1347
IWMMXT_OP_ENV_SIZE(addu)
1348
IWMMXT_OP_ENV_SIZE(subs)
1349
IWMMXT_OP_ENV_SIZE(adds)
1350

    
1351
IWMMXT_OP_ENV(avgb0)
1352
IWMMXT_OP_ENV(avgb1)
1353
IWMMXT_OP_ENV(avgw0)
1354
IWMMXT_OP_ENV(avgw1)
1355

    
1356
IWMMXT_OP(msadb)
1357

    
1358
IWMMXT_OP_ENV(packuw)
1359
IWMMXT_OP_ENV(packul)
1360
IWMMXT_OP_ENV(packuq)
1361
IWMMXT_OP_ENV(packsw)
1362
IWMMXT_OP_ENV(packsl)
1363
IWMMXT_OP_ENV(packsq)
1364

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

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

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

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

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

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

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

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

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

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

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

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

    
1444

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

    
1453
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1454
{
1455
    tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
1456
    iwmmxt_store_reg(cpu_V0, rn);
1457
}
1458

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

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

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

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

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

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

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

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

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

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

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

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

    
2470
    return 0;
2471
}
2472

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

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

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

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

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

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

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

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

    
2543
    return 1;
2544
}
2545

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3521
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3522

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5560
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5561
{
5562
    int cpnum;
5563

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

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

    
5589

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

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

    
5609
    /* Load value and extend to 64 bits.  */
5610
    tmp = tcg_temp_new_i64();
5611
    tmp2 = load_reg(s, rlow);
5612
    tcg_gen_extu_i32_i64(tmp, tmp2);
5613
    dead_tmp(tmp2);
5614
    tcg_gen_add_i64(val, val, tmp);
5615
}
5616

    
5617
/* load and add a 64-bit value from a register pair.  */
5618
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
5619
{
5620
    TCGv_i64 tmp;
5621
    TCGv tmpl;
5622
    TCGv tmph;
5623

    
5624
    /* Load 64-bit value rd:rn.  */
5625
    tmpl = load_reg(s, rlow);
5626
    tmph = load_reg(s, rhigh);
5627
    tmp = tcg_temp_new_i64();
5628
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
5629
    dead_tmp(tmpl);
5630
    dead_tmp(tmph);
5631
    tcg_gen_add_i64(val, val, tmp);
5632
}
5633

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

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

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

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

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

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

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

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

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

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

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

    
6694
                    if ((insn & (1 << 15)) == 0)
6695
                        user = 1;
6696
                }
6697
                rn = (insn >> 16) & 0xf;
6698
                addr = load_reg(s, rn);
6699

    
6700
                /* compute total size */
6701
                loaded_base = 0;
6702
                TCGV_UNUSED(loaded_var);
6703
                n = 0;
6704
                for(i=0;i<16;i++) {
6705
                    if (insn & (1 << i))
6706
                        n++;
6707
                }
6708
                /* XXX: test invalid n == 0 case ? */
6709
                if (insn & (1 << 23)) {
6710
                    if (insn & (1 << 24)) {
6711
                        /* pre increment */
6712
                        tcg_gen_addi_i32(addr, addr, 4);
6713
                    } else {
6714
                        /* post increment */
6715
                    }
6716
                } else {
6717
                    if (insn & (1 << 24)) {
6718
                        /* pre decrement */
6719
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
6720
                    } else {
6721
                        /* post decrement */
6722
                        if (n != 1)
6723
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6724
                    }
6725
                }
6726
                j = 0;
6727
                for(i=0;i<16;i++) {
6728
                    if (insn & (1 << i)) {
6729
                        if (insn & (1 << 20)) {
6730
                            /* load */
6731
                            tmp = gen_ld32(addr, IS_USER(s));
6732
                            if (i == 15) {
6733
                                gen_bx(s, tmp);
6734
                            } else if (user) {
6735
                                gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6736
                                dead_tmp(tmp);
6737
                            } else if (i == rn) {
6738
                                loaded_var = tmp;
6739
                                loaded_base = 1;
6740
                            } else {
6741
                                store_reg(s, i, tmp);
6742
                            }
6743
                        } else {
6744
                            /* store */
6745
                            if (i == 15) {
6746
                                /* special case: r15 = PC + 8 */
6747
                                val = (long)s->pc + 4;
6748
                                tmp = new_tmp();
6749
                                tcg_gen_movi_i32(tmp, val);
6750
                            } else if (user) {
6751
                                tmp = new_tmp();
6752
                                gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6753
                            } else {
6754
                                tmp = load_reg(s, i);
6755
                            }
6756
                            gen_st32(tmp, addr, IS_USER(s));
6757
                        }
6758
                        j++;
6759
                        /* no need to add after the last transfer */
6760
                        if (j != n)
6761
                            tcg_gen_addi_i32(addr, addr, 4);
6762
                    }
6763
                }
6764
                if (insn & (1 << 21)) {
6765
                    /* write back */
6766
                    if (insn & (1 << 23)) {
6767
                        if (insn & (1 << 24)) {
6768
                            /* pre increment */
6769
                        } else {
6770
                            /* post increment */
6771
                            tcg_gen_addi_i32(addr, addr, 4);
6772
                        }
6773
                    } else {
6774
                        if (insn & (1 << 24)) {
6775
                            /* pre decrement */
6776
                            if (n != 1)
6777
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6778
                        } else {
6779
                            /* post decrement */
6780
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
6781
                        }
6782
                    }
6783
                    store_reg(s, rn, addr);
6784
                } else {
6785
                    dead_tmp(addr);
6786
                }
6787
                if (loaded_base) {
6788
                    store_reg(s, rn, loaded_var);
6789
                }
6790
                if ((insn & (1 << 22)) && !user) {
6791
                    /* Restore CPSR from SPSR.  */
6792
                    tmp = load_cpu_field(spsr);
6793
                    gen_set_cpsr(tmp, 0xffffffff);
6794
                    dead_tmp(tmp);
6795
                    s->is_jmp = DISAS_UPDATE;
6796
                }
6797
            }
6798
            break;
6799
        case 0xa:
6800
        case 0xb:
6801
            {
6802
                int32_t offset;
6803

    
6804
                /* branch (and link) */
6805
                val = (int32_t)s->pc;
6806
                if (insn & (1 << 24)) {
6807
                    tmp = new_tmp();
6808
                    tcg_gen_movi_i32(tmp, val);
6809
                    store_reg(s, 14, tmp);
6810
                }
6811
                offset = (((int32_t)insn << 8) >> 8);
6812
                val += (offset << 2) + 4;
6813
                gen_jmp(s, val);
6814
            }
6815
            break;
6816
        case 0xc:
6817
        case 0xd:
6818
        case 0xe:
6819
            /* Coprocessor.  */
6820
            if (disas_coproc_insn(env, s, insn))
6821
                goto illegal_op;
6822
            break;
6823
        case 0xf:
6824
            /* swi */
6825
            gen_set_pc_im(s->pc);
6826
            s->is_jmp = DISAS_SWI;
6827
            break;
6828
        default:
6829
        illegal_op:
6830
            gen_set_condexec(s);
6831
            gen_set_pc_im(s->pc - 4);
6832
            gen_exception(EXCP_UDEF);
6833
            s->is_jmp = DISAS_JUMP;
6834
            break;
6835
        }
6836
    }
6837
}
6838

    
6839
/* Return true if this is a Thumb-2 logical op.  */
6840
static int
6841
thumb2_logic_op(int op)
6842
{
6843
    return (op < 8);
6844
}
6845

    
6846
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6847
   then set condition code flags based on the result of the operation.
6848
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6849
   to the high bit of T1.
6850
   Returns zero if the opcode is valid.  */
6851

    
6852
static int
6853
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6854
{
6855
    int logic_cc;
6856

    
6857
    logic_cc = 0;
6858
    switch (op) {
6859
    case 0: /* and */
6860
        gen_op_andl_T0_T1();
6861
        logic_cc = conds;
6862
        break;
6863
    case 1: /* bic */
6864
        gen_op_bicl_T0_T1();
6865
        logic_cc = conds;
6866
        break;
6867
    case 2: /* orr */
6868
        gen_op_orl_T0_T1();
6869
        logic_cc = conds;
6870
        break;
6871
    case 3: /* orn */
6872
        gen_op_notl_T1();
6873
        gen_op_orl_T0_T1();
6874
        logic_cc = conds;
6875
        break;
6876
    case 4: /* eor */
6877
        gen_op_xorl_T0_T1();
6878
        logic_cc = conds;
6879
        break;
6880
    case 8: /* add */
6881
        if (conds)
6882
            gen_op_addl_T0_T1_cc();
6883
        else
6884
            gen_op_addl_T0_T1();
6885
        break;
6886
    case 10: /* adc */
6887
        if (conds)
6888
            gen_op_adcl_T0_T1_cc();
6889
        else
6890
            gen_adc_T0_T1();
6891
        break;
6892
    case 11: /* sbc */
6893
        if (conds)
6894
            gen_op_sbcl_T0_T1_cc();
6895
        else
6896
            gen_sbc_T0_T1();
6897
        break;
6898
    case 13: /* sub */
6899
        if (conds)
6900
            gen_op_subl_T0_T1_cc();
6901
        else
6902
            gen_op_subl_T0_T1();
6903
        break;
6904
    case 14: /* rsb */
6905
        if (conds)
6906
            gen_op_rsbl_T0_T1_cc();
6907
        else
6908
            gen_op_rsbl_T0_T1();
6909
        break;
6910
    default: /* 5, 6, 7, 9, 12, 15. */
6911
        return 1;
6912
    }
6913
    if (logic_cc) {
6914
        gen_op_logic_T0_cc();
6915
        if (shifter_out)
6916
            gen_set_CF_bit31(cpu_T[1]);
6917
    }
6918
    return 0;
6919
}
6920

    
6921
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
6922
   is not legal.  */
6923
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6924
{
6925
    uint32_t insn, imm, shift, offset;
6926
    uint32_t rd, rn, rm, rs;
6927
    TCGv tmp;
6928
    TCGv tmp2;
6929
    TCGv tmp3;
6930
    TCGv addr;
6931
    TCGv_i64 tmp64;
6932
    int op;
6933
    int shiftop;
6934
    int conds;
6935
    int logic_cc;
6936

    
6937
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6938
          || arm_feature (env, ARM_FEATURE_M))) {
6939
        /* Thumb-1 cores may need to treat bl and blx as a pair of
6940
           16-bit instructions to get correct prefetch abort behavior.  */
6941
        insn = insn_hw1;
6942
        if ((insn & (1 << 12)) == 0) {
6943
            /* Second half of blx.  */
6944
            offset = ((insn & 0x7ff) << 1);
6945
            tmp = load_reg(s, 14);
6946
            tcg_gen_addi_i32(tmp, tmp, offset);
6947
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6948

    
6949
            tmp2 = new_tmp();
6950
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6951
            store_reg(s, 14, tmp2);
6952
            gen_bx(s, tmp);
6953
            return 0;
6954
        }
6955
        if (insn & (1 << 11)) {
6956
            /* Second half of bl.  */
6957
            offset = ((insn & 0x7ff) << 1) | 1;
6958
            tmp = load_reg(s, 14);
6959
            tcg_gen_addi_i32(tmp, tmp, offset);
6960

    
6961
            tmp2 = new_tmp();
6962
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6963
            store_reg(s, 14, tmp2);
6964
            gen_bx(s, tmp);
6965
            return 0;
6966
        }
6967
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6968
            /* Instruction spans a page boundary.  Implement it as two
6969
               16-bit instructions in case the second half causes an
6970
               prefetch abort.  */
6971
            offset = ((int32_t)insn << 21) >> 9;
6972
            gen_op_movl_T0_im(s->pc + 2 + offset);
6973
            gen_movl_reg_T0(s, 14);
6974
            return 0;
6975
        }
6976
        /* Fall through to 32-bit decode.  */
6977
    }
6978

    
6979
    insn = lduw_code(s->pc);
6980
    s->pc += 2;
6981
    insn |= (uint32_t)insn_hw1 << 16;
6982

    
6983
    if ((insn & 0xf800e800) != 0xf000e800) {
6984
        ARCH(6T2);
6985
    }
6986

    
6987
    rn = (insn >> 16) & 0xf;
6988
    rs = (insn >> 12) & 0xf;
6989
    rd = (insn >> 8) & 0xf;
6990
    rm = insn & 0xf;
6991
    switch ((insn >> 25) & 0xf) {
6992
    case 0: case 1: case 2: case 3:
6993
        /* 16-bit instructions.  Should never happen.  */
6994
        abort();
6995
    case 4:
6996
        if (insn & (1 << 22)) {
6997
            /* Other load/store, table branch.  */
6998
            if (insn & 0x01200000) {
6999
                /* Load/store doubleword.  */
7000
                if (rn == 15) {
7001
                    addr = new_tmp();
7002
                    tcg_gen_movi_i32(addr, s->pc & ~3);
7003
                } else {
7004
                    addr = load_reg(s, rn);
7005
                }
7006
                offset = (insn & 0xff) * 4;
7007
                if ((insn & (1 << 23)) == 0)
7008
                    offset = -offset;
7009
                if (insn & (1 << 24)) {
7010
                    tcg_gen_addi_i32(addr, addr, offset);
7011
                    offset = 0;
7012
                }
7013
                if (insn & (1 << 20)) {
7014
                    /* ldrd */
7015
                    tmp = gen_ld32(addr, IS_USER(s));
7016
                    store_reg(s, rs, tmp);
7017
                    tcg_gen_addi_i32(addr, addr, 4);
7018
                    tmp = gen_ld32(addr, IS_USER(s));
7019
                    store_reg(s, rd, tmp);
7020
                } else {
7021
                    /* strd */
7022
                    tmp = load_reg(s, rs);
7023
                    gen_st32(tmp, addr, IS_USER(s));
7024
                    tcg_gen_addi_i32(addr, addr, 4);
7025
                    tmp = load_reg(s, rd);
7026
                    gen_st32(tmp, addr, IS_USER(s));
7027
                }
7028
                if (insn & (1 << 21)) {
7029
                    /* Base writeback.  */
7030
                    if (rn == 15)
7031
                        goto illegal_op;
7032
                    tcg_gen_addi_i32(addr, addr, offset - 4);
7033
                    store_reg(s, rn, addr);
7034
                } else {
7035
                    dead_tmp(addr);
7036
                }
7037
            } else if ((insn & (1 << 23)) == 0) {
7038
                /* Load/store exclusive word.  */
7039
                gen_movl_T1_reg(s, rn);
7040
                addr = cpu_T[1];
7041
                if (insn & (1 << 20)) {
7042
                    gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
7043
                    tmp = gen_ld32(addr, IS_USER(s));
7044
                    store_reg(s, rd, tmp);
7045
                } else {
7046
                    int label = gen_new_label();
7047
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7048
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
7049
                                        0, label);
7050
                    tmp = load_reg(s, rs);
7051
                    gen_st32(tmp, cpu_T[1], IS_USER(s));
7052
                    gen_set_label(label);
7053
                    gen_movl_reg_T0(s, rd);
7054
                }
7055
            } else if ((insn & (1 << 6)) == 0) {
7056
                /* Table Branch.  */
7057
                if (rn == 15) {
7058
                    addr = new_tmp();
7059
                    tcg_gen_movi_i32(addr, s->pc);
7060
                } else {
7061
                    addr = load_reg(s, rn);
7062
                }
7063
                tmp = load_reg(s, rm);
7064
                tcg_gen_add_i32(addr, addr, tmp);
7065
                if (insn & (1 << 4)) {
7066
                    /* tbh */
7067
                    tcg_gen_add_i32(addr, addr, tmp);
7068
                    dead_tmp(tmp);
7069
                    tmp = gen_ld16u(addr, IS_USER(s));
7070
                } else { /* tbb */
7071
                    dead_tmp(tmp);
7072
                    tmp = gen_ld8u(addr, IS_USER(s));
7073
                }
7074
                dead_tmp(addr);
7075
                tcg_gen_shli_i32(tmp, tmp, 1);
7076
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7077
                store_reg(s, 15, tmp);
7078
            } else {
7079
                /* Load/store exclusive byte/halfword/doubleword.  */
7080
                /* ??? These are not really atomic.  However we know
7081
                   we never have multiple CPUs running in parallel,
7082
                   so it is good enough.  */
7083
                op = (insn >> 4) & 0x3;
7084
                /* Must use a global reg for the address because we have
7085
                   a conditional branch in the store instruction.  */
7086
                gen_movl_T1_reg(s, rn);
7087
                addr = cpu_T[1];
7088
                if (insn & (1 << 20)) {
7089
                    gen_helper_mark_exclusive(cpu_env, addr);
7090
                    switch (op) {
7091
                    case 0:
7092
                        tmp = gen_ld8u(addr, IS_USER(s));
7093
                        break;
7094
                    case 1:
7095
                        tmp = gen_ld16u(addr, IS_USER(s));
7096
                        break;
7097
                    case 3:
7098
                        tmp = gen_ld32(addr, IS_USER(s));
7099
                        tcg_gen_addi_i32(addr, addr, 4);
7100
                        tmp2 = gen_ld32(addr, IS_USER(s));
7101
                        store_reg(s, rd, tmp2);
7102
                        break;
7103
                    default:
7104
                        goto illegal_op;
7105
                    }
7106
                    store_reg(s, rs, tmp);
7107
                } else {
7108
                    int label = gen_new_label();
7109
                    /* Must use a global that is not killed by the branch.  */
7110
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7111
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
7112
                    tmp = load_reg(s, rs);
7113
                    switch (op) {
7114
                    case 0:
7115
                        gen_st8(tmp, addr, IS_USER(s));
7116
                        break;
7117
                    case 1:
7118
                        gen_st16(tmp, addr, IS_USER(s));
7119
                        break;
7120
                    case 3:
7121
                        gen_st32(tmp, addr, IS_USER(s));
7122
                        tcg_gen_addi_i32(addr, addr, 4);
7123
                        tmp = load_reg(s, rd);
7124
                        gen_st32(tmp, addr, IS_USER(s));
7125
                        break;
7126
                    default:
7127
                        goto illegal_op;
7128
                    }
7129
                    gen_set_label(label);
7130
                    gen_movl_reg_T0(s, rm);
7131
                }
7132
            }
7133
        } else {
7134
            /* Load/store multiple, RFE, SRS.  */
7135
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7136
                /* Not available in user mode.  */
7137
                if (IS_USER(s))
7138
                    goto illegal_op;
7139
                if (insn & (1 << 20)) {
7140
                    /* rfe */
7141
                    addr = load_reg(s, rn);
7142
                    if ((insn & (1 << 24)) == 0)
7143
                        tcg_gen_addi_i32(addr, addr, -8);
7144
                    /* Load PC into tmp and CPSR into tmp2.  */
7145
                    tmp = gen_ld32(addr, 0);
7146
                    tcg_gen_addi_i32(addr, addr, 4);
7147
                    tmp2 = gen_ld32(addr, 0);
7148
                    if (insn & (1 << 21)) {
7149
                        /* Base writeback.  */
7150
                        if (insn & (1 << 24)) {
7151
                            tcg_gen_addi_i32(addr, addr, 4);
7152
                        } else {
7153
                            tcg_gen_addi_i32(addr, addr, -4);
7154
                        }
7155
                        store_reg(s, rn, addr);
7156
                    } else {
7157
                        dead_tmp(addr);
7158
                    }
7159
                    gen_rfe(s, tmp, tmp2);
7160
                } else {
7161
                    /* srs */
7162
                    op = (insn & 0x1f);
7163
                    if (op == (env->uncached_cpsr & CPSR_M)) {
7164
                        addr = load_reg(s, 13);
7165
                    } else {
7166
                        addr = new_tmp();
7167
                        gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7168
                    }
7169
                    if ((insn & (1 << 24)) == 0) {
7170
                        tcg_gen_addi_i32(addr, addr, -8);
7171
                    }
7172
                    tmp = load_reg(s, 14);
7173
                    gen_st32(tmp, addr, 0);
7174
                    tcg_gen_addi_i32(addr, addr, 4);
7175
                    tmp = new_tmp();
7176
                    gen_helper_cpsr_read(tmp);
7177
                    gen_st32(tmp, addr, 0);
7178
                    if (insn & (1 << 21)) {
7179
                        if ((insn & (1 << 24)) == 0) {
7180
                            tcg_gen_addi_i32(addr, addr, -4);
7181
                        } else {
7182
                            tcg_gen_addi_i32(addr, addr, 4);
7183
                        }
7184
                        if (op == (env->uncached_cpsr & CPSR_M)) {
7185
                            store_reg(s, 13, addr);
7186
                        } else {
7187
                            gen_helper_set_r13_banked(cpu_env,
7188
                                tcg_const_i32(op), addr);
7189
                        }
7190
                    } else {
7191
                        dead_tmp(addr);
7192
                    }
7193
                }
7194
            } else {
7195
                int i;
7196
                /* Load/store multiple.  */
7197
                addr = load_reg(s, rn);
7198
                offset = 0;
7199
                for (i = 0; i < 16; i++) {
7200
                    if (insn & (1 << i))
7201
                        offset += 4;
7202
                }
7203
                if (insn & (1 << 24)) {
7204
                    tcg_gen_addi_i32(addr, addr, -offset);
7205
                }
7206

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

    
7540
                if (insn & (1 << 14)) {
7541
                    /* Branch and link.  */
7542
                    gen_op_movl_T1_im(s->pc | 1);
7543
                    gen_movl_reg_T1(s, 14);
7544
                }
7545

    
7546
                offset += s->pc;
7547
                if (insn & (1 << 12)) {
7548
                    /* b/bl */
7549
                    gen_jmp(s, offset);
7550
                } else {
7551
                    /* blx */
7552
                    offset &= ~(uint32_t)2;
7553
                    gen_bx_im(s, offset);
7554
                }
7555
            } else if (((insn >> 23) & 7) == 7) {
7556
                /* Misc control */
7557
                if (insn & (1 << 13))
7558
                    goto illegal_op;
7559

    
7560
                if (insn & (1 << 26)) {
7561
                    /* Secure monitor call (v6Z) */
7562
                    goto illegal_op; /* not implemented.  */
7563
                } else {
7564
                    op = (insn >> 20) & 7;
7565
                    switch (op) {
7566
                    case 0: /* msr cpsr.  */
7567
                        if (IS_M(env)) {
7568
                            tmp = load_reg(s, rn);
7569
                            addr = tcg_const_i32(insn & 0xff);
7570
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7571
                            gen_lookup_tb(s);
7572
                            break;
7573
                        }
7574
                        /* fall through */
7575
                    case 1: /* msr spsr.  */
7576
                        if (IS_M(env))
7577
                            goto illegal_op;
7578
                        gen_movl_T0_reg(s, rn);
7579
                        if (gen_set_psr_T0(s,
7580
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7581
                              op == 1))
7582
                            goto illegal_op;
7583
                        break;
7584
                    case 2: /* cps, nop-hint.  */
7585
                        if (((insn >> 8) & 7) == 0) {
7586
                            gen_nop_hint(s, insn & 0xff);
7587
                        }
7588
                        /* Implemented as NOP in user mode.  */
7589
                        if (IS_USER(s))
7590
                            break;
7591
                        offset = 0;
7592
                        imm = 0;
7593
                        if (insn & (1 << 10)) {
7594
                            if (insn & (1 << 7))
7595
                                offset |= CPSR_A;
7596
                            if (insn & (1 << 6))
7597
                                offset |= CPSR_I;
7598
                            if (insn & (1 << 5))
7599
                                offset |= CPSR_F;
7600
                            if (insn & (1 << 9))
7601
                                imm = CPSR_A | CPSR_I | CPSR_F;
7602
                        }
7603
                        if (insn & (1 << 8)) {
7604
                            offset |= 0x1f;
7605
                            imm |= (insn & 0x1f);
7606
                        }
7607
                        if (offset) {
7608
                            gen_op_movl_T0_im(imm);
7609
                            gen_set_psr_T0(s, offset, 0);
7610
                        }
7611
                        break;
7612
                    case 3: /* Special control operations.  */
7613
                        op = (insn >> 4) & 0xf;
7614
                        switch (op) {
7615
                        case 2: /* clrex */
7616
                            gen_helper_clrex(cpu_env);
7617
                            break;
7618
                        case 4: /* dsb */
7619
                        case 5: /* dmb */
7620
                        case 6: /* isb */
7621
                            /* These execute as NOPs.  */
7622
                            ARCH(7);
7623
                            break;
7624
                        default:
7625
                            goto illegal_op;
7626
                        }
7627
                        break;
7628
                    case 4: /* bxj */
7629
                        /* Trivial implementation equivalent to bx.  */
7630
                        tmp = load_reg(s, rn);
7631
                        gen_bx(s, tmp);
7632
                        break;
7633
                    case 5: /* Exception return.  */
7634
                        /* Unpredictable in user mode.  */
7635
                        goto illegal_op;
7636
                    case 6: /* mrs cpsr.  */
7637
                        tmp = new_tmp();
7638
                        if (IS_M(env)) {
7639
                            addr = tcg_const_i32(insn & 0xff);
7640
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
7641
                        } else {
7642
                            gen_helper_cpsr_read(tmp);
7643
                        }
7644
                        store_reg(s, rd, tmp);
7645
                        break;
7646
                    case 7: /* mrs spsr.  */
7647
                        /* Not accessible in user mode.  */
7648
                        if (IS_USER(s) || IS_M(env))
7649
                            goto illegal_op;
7650
                        tmp = load_cpu_field(spsr);
7651
                        store_reg(s, rd, tmp);
7652
                        break;
7653
                    }
7654
                }
7655
            } else {
7656
                /* Conditional branch.  */
7657
                op = (insn >> 22) & 0xf;
7658
                /* Generate a conditional jump to next instruction.  */
7659
                s->condlabel = gen_new_label();
7660
                gen_test_cc(op ^ 1, s->condlabel);
7661
                s->condjmp = 1;
7662

    
7663
                /* offset[11:1] = insn[10:0] */
7664
                offset = (insn & 0x7ff) << 1;
7665
                /* offset[17:12] = insn[21:16].  */
7666
                offset |= (insn & 0x003f0000) >> 4;
7667
                /* offset[31:20] = insn[26].  */
7668
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7669
                /* offset[18] = insn[13].  */
7670
                offset |= (insn & (1 << 13)) << 5;
7671
                /* offset[19] = insn[11].  */
7672
                offset |= (insn & (1 << 11)) << 8;
7673

    
7674
                /* jump to the offset */
7675
                gen_jmp(s, s->pc + offset);
7676
            }
7677
        } else {
7678
            /* Data processing immediate.  */
7679
            if (insn & (1 << 25)) {
7680
                if (insn & (1 << 24)) {
7681
                    if (insn & (1 << 20))
7682
                        goto illegal_op;
7683
                    /* Bitfield/Saturate.  */
7684
                    op = (insn >> 21) & 7;
7685
                    imm = insn & 0x1f;
7686
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7687
                    if (rn == 15) {
7688
                        tmp = new_tmp();
7689
                        tcg_gen_movi_i32(tmp, 0);
7690
                    } else {
7691
                        tmp = load_reg(s, rn);
7692
                    }
7693
                    switch (op) {
7694
                    case 2: /* Signed bitfield extract.  */
7695
                        imm++;
7696
                        if (shift + imm > 32)
7697
                            goto illegal_op;
7698
                        if (imm < 32)
7699
                            gen_sbfx(tmp, shift, imm);
7700
                        break;
7701
                    case 6: /* Unsigned bitfield extract.  */
7702
                        imm++;
7703
                        if (shift + imm > 32)
7704
                            goto illegal_op;
7705
                        if (imm < 32)
7706
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
7707
                        break;
7708
                    case 3: /* Bitfield insert/clear.  */
7709
                        if (imm < shift)
7710
                            goto illegal_op;
7711
                        imm = imm + 1 - shift;
7712
                        if (imm != 32) {
7713
                            tmp2 = load_reg(s, rd);
7714
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7715
                            dead_tmp(tmp2);
7716
                        }
7717
                        break;
7718
                    case 7:
7719
                        goto illegal_op;
7720
                    default: /* Saturate.  */
7721
                        if (shift) {
7722
                            if (op & 1)
7723
                                tcg_gen_sari_i32(tmp, tmp, shift);
7724
                            else
7725
                                tcg_gen_shli_i32(tmp, tmp, shift);
7726
                        }
7727
                        tmp2 = tcg_const_i32(imm);
7728
                        if (op & 4) {
7729
                            /* Unsigned.  */
7730
                            if ((op & 1) && shift == 0)
7731
                                gen_helper_usat16(tmp, tmp, tmp2);
7732
                            else
7733
                                gen_helper_usat(tmp, tmp, tmp2);
7734
                        } else {
7735
                            /* Signed.  */
7736
                            if ((op & 1) && shift == 0)
7737
                                gen_helper_ssat16(tmp, tmp, tmp2);
7738
                            else
7739
                                gen_helper_ssat(tmp, tmp, tmp2);
7740
                        }
7741
                        break;
7742
                    }
7743
                    store_reg(s, rd, tmp);
7744
                } else {
7745
                    imm = ((insn & 0x04000000) >> 15)
7746
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
7747
                    if (insn & (1 << 22)) {
7748
                        /* 16-bit immediate.  */
7749
                        imm |= (insn >> 4) & 0xf000;
7750
                        if (insn & (1 << 23)) {
7751
                            /* movt */
7752
                            tmp = load_reg(s, rd);
7753
                            tcg_gen_ext16u_i32(tmp, tmp);
7754
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
7755
                        } else {
7756
                            /* movw */
7757
                            tmp = new_tmp();
7758
                            tcg_gen_movi_i32(tmp, imm);
7759
                        }
7760
                    } else {
7761
                        /* Add/sub 12-bit immediate.  */
7762
                        if (rn == 15) {
7763
                            offset = s->pc & ~(uint32_t)3;
7764
                            if (insn & (1 << 23))
7765
                                offset -= imm;
7766
                            else
7767
                                offset += imm;
7768
                            tmp = new_tmp();
7769
                            tcg_gen_movi_i32(tmp, offset);
7770
                        } else {
7771
                            tmp = load_reg(s, rn);
7772
                            if (insn & (1 << 23))
7773
                                tcg_gen_subi_i32(tmp, tmp, imm);
7774
                            else
7775
                                tcg_gen_addi_i32(tmp, tmp, imm);
7776
                        }
7777
                    }
7778
                    store_reg(s, rd, tmp);
7779
                }
7780
            } else {
7781
                int shifter_out = 0;
7782
                /* modified 12-bit immediate.  */
7783
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7784
                imm = (insn & 0xff);
7785
                switch (shift) {
7786
                case 0: /* XY */
7787
                    /* Nothing to do.  */
7788
                    break;
7789
                case 1: /* 00XY00XY */
7790
                    imm |= imm << 16;
7791
                    break;
7792
                case 2: /* XY00XY00 */
7793
                    imm |= imm << 16;
7794
                    imm <<= 8;
7795
                    break;
7796
                case 3: /* XYXYXYXY */
7797
                    imm |= imm << 16;
7798
                    imm |= imm << 8;
7799
                    break;
7800
                default: /* Rotated constant.  */
7801
                    shift = (shift << 1) | (imm >> 7);
7802
                    imm |= 0x80;
7803
                    imm = imm << (32 - shift);
7804
                    shifter_out = 1;
7805
                    break;
7806
                }
7807
                gen_op_movl_T1_im(imm);
7808
                rn = (insn >> 16) & 0xf;
7809
                if (rn == 15)
7810
                    gen_op_movl_T0_im(0);
7811
                else
7812
                    gen_movl_T0_reg(s, rn);
7813
                op = (insn >> 21) & 0xf;
7814
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7815
                                       shifter_out))
7816
                    goto illegal_op;
7817
                rd = (insn >> 8) & 0xf;
7818
                if (rd != 15) {
7819
                    gen_movl_reg_T0(s, rd);
7820
                }
7821
            }
7822
        }
7823
        break;
7824
    case 12: /* Load/store single data item.  */
7825
        {
7826
        int postinc = 0;
7827
        int writeback = 0;
7828
        int user;
7829
        if ((insn & 0x01100000) == 0x01000000) {
7830
            if (disas_neon_ls_insn(env, s, insn))
7831
                goto illegal_op;
7832
            break;
7833
        }
7834
        user = IS_USER(s);
7835
        if (rn == 15) {
7836
            addr = new_tmp();
7837
            /* PC relative.  */
7838
            /* s->pc has already been incremented by 4.  */
7839
            imm = s->pc & 0xfffffffc;
7840
            if (insn & (1 << 23))
7841
                imm += insn & 0xfff;
7842
            else
7843
                imm -= insn & 0xfff;
7844
            tcg_gen_movi_i32(addr, imm);
7845
        } else {
7846
            addr = load_reg(s, rn);
7847
            if (insn & (1 << 23)) {
7848
                /* Positive offset.  */
7849
                imm = insn & 0xfff;
7850
                tcg_gen_addi_i32(addr, addr, imm);
7851
            } else {
7852
                op = (insn >> 8) & 7;
7853
                imm = insn & 0xff;
7854
                switch (op) {
7855
                case 0: case 8: /* Shifted Register.  */
7856
                    shift = (insn >> 4) & 0xf;
7857
                    if (shift > 3)
7858
                        goto illegal_op;
7859
                    tmp = load_reg(s, rm);
7860
                    if (shift)
7861
                        tcg_gen_shli_i32(tmp, tmp, shift);
7862
                    tcg_gen_add_i32(addr, addr, tmp);
7863
                    dead_tmp(tmp);
7864
                    break;
7865
                case 4: /* Negative offset.  */
7866
                    tcg_gen_addi_i32(addr, addr, -imm);
7867
                    break;
7868
                case 6: /* User privilege.  */
7869
                    tcg_gen_addi_i32(addr, addr, imm);
7870
                    user = 1;
7871
                    break;
7872
                case 1: /* Post-decrement.  */
7873
                    imm = -imm;
7874
                    /* Fall through.  */
7875
                case 3: /* Post-increment.  */
7876
                    postinc = 1;
7877
                    writeback = 1;
7878
                    break;
7879
                case 5: /* Pre-decrement.  */
7880
                    imm = -imm;
7881
                    /* Fall through.  */
7882
                case 7: /* Pre-increment.  */
7883
                    tcg_gen_addi_i32(addr, addr, imm);
7884
                    writeback = 1;
7885
                    break;
7886
                default:
7887
                    goto illegal_op;
7888
                }
7889
            }
7890
        }
7891
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7892
        if (insn & (1 << 20)) {
7893
            /* Load.  */
7894
            if (rs == 15 && op != 2) {
7895
                if (op & 2)
7896
                    goto illegal_op;
7897
                /* Memory hint.  Implemented as NOP.  */
7898
            } else {
7899
                switch (op) {
7900
                case 0: tmp = gen_ld8u(addr, user); break;
7901
                case 4: tmp = gen_ld8s(addr, user); break;
7902
                case 1: tmp = gen_ld16u(addr, user); break;
7903
                case 5: tmp = gen_ld16s(addr, user); break;
7904
                case 2: tmp = gen_ld32(addr, user); break;
7905
                default: goto illegal_op;
7906
                }
7907
                if (rs == 15) {
7908
                    gen_bx(s, tmp);
7909
                } else {
7910
                    store_reg(s, rs, tmp);
7911
                }
7912
            }
7913
        } else {
7914
            /* Store.  */
7915
            if (rs == 15)
7916
                goto illegal_op;
7917
            tmp = load_reg(s, rs);
7918
            switch (op) {
7919
            case 0: gen_st8(tmp, addr, user); break;
7920
            case 1: gen_st16(tmp, addr, user); break;
7921
            case 2: gen_st32(tmp, addr, user); break;
7922
            default: goto illegal_op;
7923
            }
7924
        }
7925
        if (postinc)
7926
            tcg_gen_addi_i32(addr, addr, imm);
7927
        if (writeback) {
7928
            store_reg(s, rn, addr);
7929
        } else {
7930
            dead_tmp(addr);
7931
        }
7932
        }
7933
        break;
7934
    default:
7935
        goto illegal_op;
7936
    }
7937
    return 0;
7938
illegal_op:
7939
    return 1;
7940
}
7941

    
7942
static void disas_thumb_insn(CPUState *env, DisasContext *s)
7943
{
7944
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
7945
    int32_t offset;
7946
    int i;
7947
    TCGv tmp;
7948
    TCGv tmp2;
7949
    TCGv addr;
7950

    
7951
    if (s->condexec_mask) {
7952
        cond = s->condexec_cond;
7953
        s->condlabel = gen_new_label();
7954
        gen_test_cc(cond ^ 1, s->condlabel);
7955
        s->condjmp = 1;
7956
    }
7957

    
7958
    insn = lduw_code(s->pc);
7959
    s->pc += 2;
7960

    
7961
    switch (insn >> 12) {
7962
    case 0: case 1:
7963
        rd = insn & 7;
7964
        op = (insn >> 11) & 3;
7965
        if (op == 3) {
7966
            /* add/subtract */
7967
            rn = (insn >> 3) & 7;
7968
            gen_movl_T0_reg(s, rn);
7969
            if (insn & (1 << 10)) {
7970
                /* immediate */
7971
                gen_op_movl_T1_im((insn >> 6) & 7);
7972
            } else {
7973
                /* reg */
7974
                rm = (insn >> 6) & 7;
7975
                gen_movl_T1_reg(s, rm);
7976
            }
7977
            if (insn & (1 << 9)) {
7978
                if (s->condexec_mask)
7979
                    gen_op_subl_T0_T1();
7980
                else
7981
                    gen_op_subl_T0_T1_cc();
7982
            } else {
7983
                if (s->condexec_mask)
7984
                    gen_op_addl_T0_T1();
7985
                else
7986
                    gen_op_addl_T0_T1_cc();
7987
            }
7988
            gen_movl_reg_T0(s, rd);
7989
        } else {
7990
            /* shift immediate */
7991
            rm = (insn >> 3) & 7;
7992
            shift = (insn >> 6) & 0x1f;
7993
            tmp = load_reg(s, rm);
7994
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7995
            if (!s->condexec_mask)
7996
                gen_logic_CC(tmp);
7997
            store_reg(s, rd, tmp);
7998
        }
7999
        break;
8000
    case 2: case 3:
8001
        /* arithmetic large immediate */
8002
        op = (insn >> 11) & 3;
8003
        rd = (insn >> 8) & 0x7;
8004
        if (op == 0) {
8005
            gen_op_movl_T0_im(insn & 0xff);
8006
        } else {
8007
            gen_movl_T0_reg(s, rd);
8008
            gen_op_movl_T1_im(insn & 0xff);
8009
        }
8010
        switch (op) {
8011
        case 0: /* mov */
8012
            if (!s->condexec_mask)
8013
                gen_op_logic_T0_cc();
8014
            break;
8015
        case 1: /* cmp */
8016
            gen_op_subl_T0_T1_cc();
8017
            break;
8018
        case 2: /* add */
8019
            if (s->condexec_mask)
8020
                gen_op_addl_T0_T1();
8021
            else
8022
                gen_op_addl_T0_T1_cc();
8023
            break;
8024
        case 3: /* sub */
8025
            if (s->condexec_mask)
8026
                gen_op_subl_T0_T1();
8027
            else
8028
                gen_op_subl_T0_T1_cc();
8029
            break;
8030
        }
8031
        if (op != 1)
8032
            gen_movl_reg_T0(s, rd);
8033
        break;
8034
    case 4:
8035
        if (insn & (1 << 11)) {
8036
            rd = (insn >> 8) & 7;
8037
            /* load pc-relative.  Bit 1 of PC is ignored.  */
8038
            val = s->pc + 2 + ((insn & 0xff) * 4);
8039
            val &= ~(uint32_t)2;
8040
            addr = new_tmp();
8041
            tcg_gen_movi_i32(addr, val);
8042
            tmp = gen_ld32(addr, IS_USER(s));
8043
            dead_tmp(addr);
8044
            store_reg(s, rd, tmp);
8045
            break;
8046
        }
8047
        if (insn & (1 << 10)) {
8048
            /* data processing extended or blx */
8049
            rd = (insn & 7) | ((insn >> 4) & 8);
8050
            rm = (insn >> 3) & 0xf;
8051
            op = (insn >> 8) & 3;
8052
            switch (op) {
8053
            case 0: /* add */
8054
                gen_movl_T0_reg(s, rd);
8055
                gen_movl_T1_reg(s, rm);
8056
                gen_op_addl_T0_T1();
8057
                gen_movl_reg_T0(s, rd);
8058
                break;
8059
            case 1: /* cmp */
8060
                gen_movl_T0_reg(s, rd);
8061
                gen_movl_T1_reg(s, rm);
8062
                gen_op_subl_T0_T1_cc();
8063
                break;
8064
            case 2: /* mov/cpy */
8065
                gen_movl_T0_reg(s, rm);
8066
                gen_movl_reg_T0(s, rd);
8067
                break;
8068
            case 3:/* branch [and link] exchange thumb register */
8069
                tmp = load_reg(s, rm);
8070
                if (insn & (1 << 7)) {
8071
                    val = (uint32_t)s->pc | 1;
8072
                    tmp2 = new_tmp();
8073
                    tcg_gen_movi_i32(tmp2, val);
8074
                    store_reg(s, 14, tmp2);
8075
                }
8076
                gen_bx(s, tmp);
8077
                break;
8078
            }
8079
            break;
8080
        }
8081

    
8082
        /* data processing register */
8083
        rd = insn & 7;
8084
        rm = (insn >> 3) & 7;
8085
        op = (insn >> 6) & 0xf;
8086
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8087
            /* the shift/rotate ops want the operands backwards */
8088
            val = rm;
8089
            rm = rd;
8090
            rd = val;
8091
            val = 1;
8092
        } else {
8093
            val = 0;
8094
        }
8095

    
8096
        if (op == 9) /* neg */
8097
            gen_op_movl_T0_im(0);
8098
        else if (op != 0xf) /* mvn doesn't read its first operand */
8099
            gen_movl_T0_reg(s, rd);
8100

    
8101
        gen_movl_T1_reg(s, rm);
8102
        switch (op) {
8103
        case 0x0: /* and */
8104
            gen_op_andl_T0_T1();
8105
            if (!s->condexec_mask)
8106
                gen_op_logic_T0_cc();
8107
            break;
8108
        case 0x1: /* eor */
8109
            gen_op_xorl_T0_T1();
8110
            if (!s->condexec_mask)
8111
                gen_op_logic_T0_cc();
8112
            break;
8113
        case 0x2: /* lsl */
8114
            if (s->condexec_mask) {
8115
                gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8116
            } else {
8117
                gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8118
                gen_op_logic_T1_cc();
8119
            }
8120
            break;
8121
        case 0x3: /* lsr */
8122
            if (s->condexec_mask) {
8123
                gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8124
            } else {
8125
                gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8126
                gen_op_logic_T1_cc();
8127
            }
8128
            break;
8129
        case 0x4: /* asr */
8130
            if (s->condexec_mask) {
8131
                gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8132
            } else {
8133
                gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8134
                gen_op_logic_T1_cc();
8135
            }
8136
            break;
8137
        case 0x5: /* adc */
8138
            if (s->condexec_mask)
8139
                gen_adc_T0_T1();
8140
            else
8141
                gen_op_adcl_T0_T1_cc();
8142
            break;
8143
        case 0x6: /* sbc */
8144
            if (s->condexec_mask)
8145
                gen_sbc_T0_T1();
8146
            else
8147
                gen_op_sbcl_T0_T1_cc();
8148
            break;
8149
        case 0x7: /* ror */
8150
            if (s->condexec_mask) {
8151
                gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8152
            } else {
8153
                gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8154
                gen_op_logic_T1_cc();
8155
            }
8156
            break;
8157
        case 0x8: /* tst */
8158
            gen_op_andl_T0_T1();
8159
            gen_op_logic_T0_cc();
8160
            rd = 16;
8161
            break;
8162
        case 0x9: /* neg */
8163
            if (s->condexec_mask)
8164
                tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8165
            else
8166
                gen_op_subl_T0_T1_cc();
8167
            break;
8168
        case 0xa: /* cmp */
8169
            gen_op_subl_T0_T1_cc();
8170
            rd = 16;
8171
            break;
8172
        case 0xb: /* cmn */
8173
            gen_op_addl_T0_T1_cc();
8174
            rd = 16;
8175
            break;
8176
        case 0xc: /* orr */
8177
            gen_op_orl_T0_T1();
8178
            if (!s->condexec_mask)
8179
                gen_op_logic_T0_cc();
8180
            break;
8181
        case 0xd: /* mul */
8182
            gen_op_mull_T0_T1();
8183
            if (!s->condexec_mask)
8184
                gen_op_logic_T0_cc();
8185
            break;
8186
        case 0xe: /* bic */
8187
            gen_op_bicl_T0_T1();
8188
            if (!s->condexec_mask)
8189
                gen_op_logic_T0_cc();
8190
            break;
8191
        case 0xf: /* mvn */
8192
            gen_op_notl_T1();
8193
            if (!s->condexec_mask)
8194
                gen_op_logic_T1_cc();
8195
            val = 1;
8196
            rm = rd;
8197
            break;
8198
        }
8199
        if (rd != 16) {
8200
            if (val)
8201
                gen_movl_reg_T1(s, rm);
8202
            else
8203
                gen_movl_reg_T0(s, rd);
8204
        }
8205
        break;
8206

    
8207
    case 5:
8208
        /* load/store register offset.  */
8209
        rd = insn & 7;
8210
        rn = (insn >> 3) & 7;
8211
        rm = (insn >> 6) & 7;
8212
        op = (insn >> 9) & 7;
8213
        addr = load_reg(s, rn);
8214
        tmp = load_reg(s, rm);
8215
        tcg_gen_add_i32(addr, addr, tmp);
8216
        dead_tmp(tmp);
8217

    
8218
        if (op < 3) /* store */
8219
            tmp = load_reg(s, rd);
8220

    
8221
        switch (op) {
8222
        case 0: /* str */
8223
            gen_st32(tmp, addr, IS_USER(s));
8224
            break;
8225
        case 1: /* strh */
8226
            gen_st16(tmp, addr, IS_USER(s));
8227
            break;
8228
        case 2: /* strb */
8229
            gen_st8(tmp, addr, IS_USER(s));
8230
            break;
8231
        case 3: /* ldrsb */
8232
            tmp = gen_ld8s(addr, IS_USER(s));
8233
            break;
8234
        case 4: /* ldr */
8235
            tmp = gen_ld32(addr, IS_USER(s));
8236
            break;
8237
        case 5: /* ldrh */
8238
            tmp = gen_ld16u(addr, IS_USER(s));
8239
            break;
8240
        case 6: /* ldrb */
8241
            tmp = gen_ld8u(addr, IS_USER(s));
8242
            break;
8243
        case 7: /* ldrsh */
8244
            tmp = gen_ld16s(addr, IS_USER(s));
8245
            break;
8246
        }
8247
        if (op >= 3) /* load */
8248
            store_reg(s, rd, tmp);
8249
        dead_tmp(addr);
8250
        break;
8251

    
8252
    case 6:
8253
        /* load/store word immediate offset */
8254
        rd = insn & 7;
8255
        rn = (insn >> 3) & 7;
8256
        addr = load_reg(s, rn);
8257
        val = (insn >> 4) & 0x7c;
8258
        tcg_gen_addi_i32(addr, addr, val);
8259

    
8260
        if (insn & (1 << 11)) {
8261
            /* load */
8262
            tmp = gen_ld32(addr, IS_USER(s));
8263
            store_reg(s, rd, tmp);
8264
        } else {
8265
            /* store */
8266
            tmp = load_reg(s, rd);
8267
            gen_st32(tmp, addr, IS_USER(s));
8268
        }
8269
        dead_tmp(addr);
8270
        break;
8271

    
8272
    case 7:
8273
        /* load/store byte immediate offset */
8274
        rd = insn & 7;
8275
        rn = (insn >> 3) & 7;
8276
        addr = load_reg(s, rn);
8277
        val = (insn >> 6) & 0x1f;
8278
        tcg_gen_addi_i32(addr, addr, val);
8279

    
8280
        if (insn & (1 << 11)) {
8281
            /* load */
8282
            tmp = gen_ld8u(addr, IS_USER(s));
8283
            store_reg(s, rd, tmp);
8284
        } else {
8285
            /* store */
8286
            tmp = load_reg(s, rd);
8287
            gen_st8(tmp, addr, IS_USER(s));
8288
        }
8289
        dead_tmp(addr);
8290
        break;
8291

    
8292
    case 8:
8293
        /* load/store halfword immediate offset */
8294
        rd = insn & 7;
8295
        rn = (insn >> 3) & 7;
8296
        addr = load_reg(s, rn);
8297
        val = (insn >> 5) & 0x3e;
8298
        tcg_gen_addi_i32(addr, addr, val);
8299

    
8300
        if (insn & (1 << 11)) {
8301
            /* load */
8302
            tmp = gen_ld16u(addr, IS_USER(s));
8303
            store_reg(s, rd, tmp);
8304
        } else {
8305
            /* store */
8306
            tmp = load_reg(s, rd);
8307
            gen_st16(tmp, addr, IS_USER(s));
8308
        }
8309
        dead_tmp(addr);
8310
        break;
8311

    
8312
    case 9:
8313
        /* load/store from stack */
8314
        rd = (insn >> 8) & 7;
8315
        addr = load_reg(s, 13);
8316
        val = (insn & 0xff) * 4;
8317
        tcg_gen_addi_i32(addr, addr, val);
8318

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

    
8331
    case 10:
8332
        /* add to high reg */
8333
        rd = (insn >> 8) & 7;
8334
        if (insn & (1 << 11)) {
8335
            /* SP */
8336
            tmp = load_reg(s, 13);
8337
        } else {
8338
            /* PC. bit 1 is ignored.  */
8339
            tmp = new_tmp();
8340
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8341
        }
8342
        val = (insn & 0xff) * 4;
8343
        tcg_gen_addi_i32(tmp, tmp, val);
8344
        store_reg(s, rd, tmp);
8345
        break;
8346

    
8347
    case 11:
8348
        /* misc */
8349
        op = (insn >> 8) & 0xf;
8350
        switch (op) {
8351
        case 0:
8352
            /* adjust stack pointer */
8353
            tmp = load_reg(s, 13);
8354
            val = (insn & 0x7f) * 4;
8355
            if (insn & (1 << 7))
8356
                val = -(int32_t)val;
8357
            tcg_gen_addi_i32(tmp, tmp, val);
8358
            store_reg(s, 13, tmp);
8359
            break;
8360

    
8361
        case 2: /* sign/zero extend.  */
8362
            ARCH(6);
8363
            rd = insn & 7;
8364
            rm = (insn >> 3) & 7;
8365
            tmp = load_reg(s, rm);
8366
            switch ((insn >> 6) & 3) {
8367
            case 0: gen_sxth(tmp); break;
8368
            case 1: gen_sxtb(tmp); break;
8369
            case 2: gen_uxth(tmp); break;
8370
            case 3: gen_uxtb(tmp); break;
8371
            }
8372
            store_reg(s, rd, tmp);
8373
            break;
8374
        case 4: case 5: case 0xc: case 0xd:
8375
            /* push/pop */
8376
            addr = load_reg(s, 13);
8377
            if (insn & (1 << 8))
8378
                offset = 4;
8379
            else
8380
                offset = 0;
8381
            for (i = 0; i < 8; i++) {
8382
                if (insn & (1 << i))
8383
                    offset += 4;
8384
            }
8385
            if ((insn & (1 << 11)) == 0) {
8386
                tcg_gen_addi_i32(addr, addr, -offset);
8387
            }
8388
            for (i = 0; i < 8; i++) {
8389
                if (insn & (1 << i)) {
8390
                    if (insn & (1 << 11)) {
8391
                        /* pop */
8392
                        tmp = gen_ld32(addr, IS_USER(s));
8393
                        store_reg(s, i, tmp);
8394
                    } else {
8395
                        /* push */
8396
                        tmp = load_reg(s, i);
8397
                        gen_st32(tmp, addr, IS_USER(s));
8398
                    }
8399
                    /* advance to the next address.  */
8400
                    tcg_gen_addi_i32(addr, addr, 4);
8401
                }
8402
            }
8403
            TCGV_UNUSED(tmp);
8404
            if (insn & (1 << 8)) {
8405
                if (insn & (1 << 11)) {
8406
                    /* pop pc */
8407
                    tmp = gen_ld32(addr, IS_USER(s));
8408
                    /* don't set the pc until the rest of the instruction
8409
                       has completed */
8410
                } else {
8411
                    /* push lr */
8412
                    tmp = load_reg(s, 14);
8413
                    gen_st32(tmp, addr, IS_USER(s));
8414
                }
8415
                tcg_gen_addi_i32(addr, addr, 4);
8416
            }
8417
            if ((insn & (1 << 11)) == 0) {
8418
                tcg_gen_addi_i32(addr, addr, -offset);
8419
            }
8420
            /* write back the new stack pointer */
8421
            store_reg(s, 13, addr);
8422
            /* set the new PC value */
8423
            if ((insn & 0x0900) == 0x0900)
8424
                gen_bx(s, tmp);
8425
            break;
8426

    
8427
        case 1: case 3: case 9: case 11: /* czb */
8428
            rm = insn & 7;
8429
            tmp = load_reg(s, rm);
8430
            s->condlabel = gen_new_label();
8431
            s->condjmp = 1;
8432
            if (insn & (1 << 11))
8433
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8434
            else
8435
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8436
            dead_tmp(tmp);
8437
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8438
            val = (uint32_t)s->pc + 2;
8439
            val += offset;
8440
            gen_jmp(s, val);
8441
            break;
8442

    
8443
        case 15: /* IT, nop-hint.  */
8444
            if ((insn & 0xf) == 0) {
8445
                gen_nop_hint(s, (insn >> 4) & 0xf);
8446
                break;
8447
            }
8448
            /* If Then.  */
8449
            s->condexec_cond = (insn >> 4) & 0xe;
8450
            s->condexec_mask = insn & 0x1f;
8451
            /* No actual code generated for this insn, just setup state.  */
8452
            break;
8453

    
8454
        case 0xe: /* bkpt */
8455
            gen_set_condexec(s);
8456
            gen_set_pc_im(s->pc - 2);
8457
            gen_exception(EXCP_BKPT);
8458
            s->is_jmp = DISAS_JUMP;
8459
            break;
8460

    
8461
        case 0xa: /* rev */
8462
            ARCH(6);
8463
            rn = (insn >> 3) & 0x7;
8464
            rd = insn & 0x7;
8465
            tmp = load_reg(s, rn);
8466
            switch ((insn >> 6) & 3) {
8467
            case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8468
            case 1: gen_rev16(tmp); break;
8469
            case 3: gen_revsh(tmp); break;
8470
            default: goto illegal_op;
8471
            }
8472
            store_reg(s, rd, tmp);
8473
            break;
8474

    
8475
        case 6: /* cps */
8476
            ARCH(6);
8477
            if (IS_USER(s))
8478
                break;
8479
            if (IS_M(env)) {
8480
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8481
                /* PRIMASK */
8482
                if (insn & 1) {
8483
                    addr = tcg_const_i32(16);
8484
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8485
                }
8486
                /* FAULTMASK */
8487
                if (insn & 2) {
8488
                    addr = tcg_const_i32(17);
8489
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8490
                }
8491
                gen_lookup_tb(s);
8492
            } else {
8493
                if (insn & (1 << 4))
8494
                    shift = CPSR_A | CPSR_I | CPSR_F;
8495
                else
8496
                    shift = 0;
8497

    
8498
                val = ((insn & 7) << 6) & shift;
8499
                gen_op_movl_T0_im(val);
8500
                gen_set_psr_T0(s, shift, 0);
8501
            }
8502
            break;
8503

    
8504
        default:
8505
            goto undef;
8506
        }
8507
        break;
8508

    
8509
    case 12:
8510
        /* load/store multiple */
8511
        rn = (insn >> 8) & 0x7;
8512
        addr = load_reg(s, rn);
8513
        for (i = 0; i < 8; i++) {
8514
            if (insn & (1 << i)) {
8515
                if (insn & (1 << 11)) {
8516
                    /* load */
8517
                    tmp = gen_ld32(addr, IS_USER(s));
8518
                    store_reg(s, i, tmp);
8519
                } else {
8520
                    /* store */
8521
                    tmp = load_reg(s, i);
8522
                    gen_st32(tmp, addr, IS_USER(s));
8523
                }
8524
                /* advance to the next address */
8525
                tcg_gen_addi_i32(addr, addr, 4);
8526
            }
8527
        }
8528
        /* Base register writeback.  */
8529
        if ((insn & (1 << rn)) == 0) {
8530
            store_reg(s, rn, addr);
8531
        } else {
8532
            dead_tmp(addr);
8533
        }
8534
        break;
8535

    
8536
    case 13:
8537
        /* conditional branch or swi */
8538
        cond = (insn >> 8) & 0xf;
8539
        if (cond == 0xe)
8540
            goto undef;
8541

    
8542
        if (cond == 0xf) {
8543
            /* swi */
8544
            gen_set_condexec(s);
8545
            gen_set_pc_im(s->pc);
8546
            s->is_jmp = DISAS_SWI;
8547
            break;
8548
        }
8549
        /* generate a conditional jump to next instruction */
8550
        s->condlabel = gen_new_label();
8551
        gen_test_cc(cond ^ 1, s->condlabel);
8552
        s->condjmp = 1;
8553
        gen_movl_T1_reg(s, 15);
8554

    
8555
        /* jump to the offset */
8556
        val = (uint32_t)s->pc + 2;
8557
        offset = ((int32_t)insn << 24) >> 24;
8558
        val += offset << 1;
8559
        gen_jmp(s, val);
8560
        break;
8561

    
8562
    case 14:
8563
        if (insn & (1 << 11)) {
8564
            if (disas_thumb2_insn(env, s, insn))
8565
              goto undef32;
8566
            break;
8567
        }
8568
        /* unconditional branch */
8569
        val = (uint32_t)s->pc;
8570
        offset = ((int32_t)insn << 21) >> 21;
8571
        val += (offset << 1) + 2;
8572
        gen_jmp(s, val);
8573
        break;
8574

    
8575
    case 15:
8576
        if (disas_thumb2_insn(env, s, insn))
8577
            goto undef32;
8578
        break;
8579
    }
8580
    return;
8581
undef32:
8582
    gen_set_condexec(s);
8583
    gen_set_pc_im(s->pc - 4);
8584
    gen_exception(EXCP_UDEF);
8585
    s->is_jmp = DISAS_JUMP;
8586
    return;
8587
illegal_op:
8588
undef:
8589
    gen_set_condexec(s);
8590
    gen_set_pc_im(s->pc - 2);
8591
    gen_exception(EXCP_UDEF);
8592
    s->is_jmp = DISAS_JUMP;
8593
}
8594

    
8595
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8596
   basic block 'tb'. If search_pc is TRUE, also generate PC
8597
   information for each intermediate instruction. */
8598
static inline void gen_intermediate_code_internal(CPUState *env,
8599
                                                  TranslationBlock *tb,
8600
                                                  int search_pc)
8601
{
8602
    DisasContext dc1, *dc = &dc1;
8603
    CPUBreakpoint *bp;
8604
    uint16_t *gen_opc_end;
8605
    int j, lj;
8606
    target_ulong pc_start;
8607
    uint32_t next_page_start;
8608
    int num_insns;
8609
    int max_insns;
8610

    
8611
    /* generate intermediate code */
8612
    num_temps = 0;
8613
    memset(temps, 0, sizeof(temps));
8614

    
8615
    pc_start = tb->pc;
8616

    
8617
    dc->tb = tb;
8618

    
8619
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8620

    
8621
    dc->is_jmp = DISAS_NEXT;
8622
    dc->pc = pc_start;
8623
    dc->singlestep_enabled = env->singlestep_enabled;
8624
    dc->condjmp = 0;
8625
    dc->thumb = env->thumb;
8626
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8627
    dc->condexec_cond = env->condexec_bits >> 4;
8628
    dc->is_mem = 0;
8629
#if !defined(CONFIG_USER_ONLY)
8630
    if (IS_M(env)) {
8631
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8632
    } else {
8633
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8634
    }
8635
#endif
8636
    cpu_F0s = tcg_temp_new_i32();
8637
    cpu_F1s = tcg_temp_new_i32();
8638
    cpu_F0d = tcg_temp_new_i64();
8639
    cpu_F1d = tcg_temp_new_i64();
8640
    cpu_V0 = cpu_F0d;
8641
    cpu_V1 = cpu_F1d;
8642
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
8643
    cpu_M0 = tcg_temp_new_i64();
8644
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8645
    lj = -1;
8646
    num_insns = 0;
8647
    max_insns = tb->cflags & CF_COUNT_MASK;
8648
    if (max_insns == 0)
8649
        max_insns = CF_COUNT_MASK;
8650

    
8651
    gen_icount_start();
8652
    /* Reset the conditional execution bits immediately. This avoids
8653
       complications trying to do it at the end of the block.  */
8654
    if (env->condexec_bits)
8655
      {
8656
        TCGv tmp = new_tmp();
8657
        tcg_gen_movi_i32(tmp, 0);
8658
        store_cpu_field(tmp, condexec_bits);
8659
      }
8660
    do {
8661
#ifdef CONFIG_USER_ONLY
8662
        /* Intercept jump to the magic kernel page.  */
8663
        if (dc->pc >= 0xffff0000) {
8664
            /* We always get here via a jump, so know we are not in a
8665
               conditional execution block.  */
8666
            gen_exception(EXCP_KERNEL_TRAP);
8667
            dc->is_jmp = DISAS_UPDATE;
8668
            break;
8669
        }
8670
#else
8671
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8672
            /* We always get here via a jump, so know we are not in a
8673
               conditional execution block.  */
8674
            gen_exception(EXCP_EXCEPTION_EXIT);
8675
            dc->is_jmp = DISAS_UPDATE;
8676
            break;
8677
        }
8678
#endif
8679

    
8680
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8681
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8682
                if (bp->pc == dc->pc) {
8683
                    gen_set_condexec(dc);
8684
                    gen_set_pc_im(dc->pc);
8685
                    gen_exception(EXCP_DEBUG);
8686
                    dc->is_jmp = DISAS_JUMP;
8687
                    /* Advance PC so that clearing the breakpoint will
8688
                       invalidate this TB.  */
8689
                    dc->pc += 2;
8690
                    goto done_generating;
8691
                    break;
8692
                }
8693
            }
8694
        }
8695
        if (search_pc) {
8696
            j = gen_opc_ptr - gen_opc_buf;
8697
            if (lj < j) {
8698
                lj++;
8699
                while (lj < j)
8700
                    gen_opc_instr_start[lj++] = 0;
8701
            }
8702
            gen_opc_pc[lj] = dc->pc;
8703
            gen_opc_instr_start[lj] = 1;
8704
            gen_opc_icount[lj] = num_insns;
8705
        }
8706

    
8707
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8708
            gen_io_start();
8709

    
8710
        if (env->thumb) {
8711
            disas_thumb_insn(env, dc);
8712
            if (dc->condexec_mask) {
8713
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8714
                                   | ((dc->condexec_mask >> 4) & 1);
8715
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8716
                if (dc->condexec_mask == 0) {
8717
                    dc->condexec_cond = 0;
8718
                }
8719
            }
8720
        } else {
8721
            disas_arm_insn(env, dc);
8722
        }
8723
        if (num_temps) {
8724
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8725
            num_temps = 0;
8726
        }
8727

    
8728
        if (dc->condjmp && !dc->is_jmp) {
8729
            gen_set_label(dc->condlabel);
8730
            dc->condjmp = 0;
8731
        }
8732
        /* Translation stops when a conditional branch is enoutered.
8733
         * Otherwise the subsequent code could get translated several times.
8734
         * Also stop translation when a page boundary is reached.  This
8735
         * ensures prefetch aborts occur at the right place.  */
8736
        num_insns ++;
8737
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8738
             !env->singlestep_enabled &&
8739
             dc->pc < next_page_start &&
8740
             num_insns < max_insns);
8741

    
8742
    if (tb->cflags & CF_LAST_IO) {
8743
        if (dc->condjmp) {
8744
            /* FIXME:  This can theoretically happen with self-modifying
8745
               code.  */
8746
            cpu_abort(env, "IO on conditional branch instruction");
8747
        }
8748
        gen_io_end();
8749
    }
8750

    
8751
    /* At this stage dc->condjmp will only be set when the skipped
8752
       instruction was a conditional branch or trap, and the PC has
8753
       already been written.  */
8754
    if (unlikely(env->singlestep_enabled)) {
8755
        /* Make sure the pc is updated, and raise a debug exception.  */
8756
        if (dc->condjmp) {
8757
            gen_set_condexec(dc);
8758
            if (dc->is_jmp == DISAS_SWI) {
8759
                gen_exception(EXCP_SWI);
8760
            } else {
8761
                gen_exception(EXCP_DEBUG);
8762
            }
8763
            gen_set_label(dc->condlabel);
8764
        }
8765
        if (dc->condjmp || !dc->is_jmp) {
8766
            gen_set_pc_im(dc->pc);
8767
            dc->condjmp = 0;
8768
        }
8769
        gen_set_condexec(dc);
8770
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8771
            gen_exception(EXCP_SWI);
8772
        } else {
8773
            /* FIXME: Single stepping a WFI insn will not halt
8774
               the CPU.  */
8775
            gen_exception(EXCP_DEBUG);
8776
        }
8777
    } else {
8778
        /* While branches must always occur at the end of an IT block,
8779
           there are a few other things that can cause us to terminate
8780
           the TB in the middel of an IT block:
8781
            - Exception generating instructions (bkpt, swi, undefined).
8782
            - Page boundaries.
8783
            - Hardware watchpoints.
8784
           Hardware breakpoints have already been handled and skip this code.
8785
         */
8786
        gen_set_condexec(dc);
8787
        switch(dc->is_jmp) {
8788
        case DISAS_NEXT:
8789
            gen_goto_tb(dc, 1, dc->pc);
8790
            break;
8791
        default:
8792
        case DISAS_JUMP:
8793
        case DISAS_UPDATE:
8794
            /* indicate that the hash table must be used to find the next TB */
8795
            tcg_gen_exit_tb(0);
8796
            break;
8797
        case DISAS_TB_JUMP:
8798
            /* nothing more to generate */
8799
            break;
8800
        case DISAS_WFI:
8801
            gen_helper_wfi();
8802
            break;
8803
        case DISAS_SWI:
8804
            gen_exception(EXCP_SWI);
8805
            break;
8806
        }
8807
        if (dc->condjmp) {
8808
            gen_set_label(dc->condlabel);
8809
            gen_set_condexec(dc);
8810
            gen_goto_tb(dc, 1, dc->pc);
8811
            dc->condjmp = 0;
8812
        }
8813
    }
8814

    
8815
done_generating:
8816
    gen_icount_end(tb, num_insns);
8817
    *gen_opc_ptr = INDEX_op_end;
8818

    
8819
#ifdef DEBUG_DISAS
8820
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8821
        fprintf(logfile, "----------------\n");
8822
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8823
        target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8824
        fprintf(logfile, "\n");
8825
    }
8826
#endif
8827
    if (search_pc) {
8828
        j = gen_opc_ptr - gen_opc_buf;
8829
        lj++;
8830
        while (lj <= j)
8831
            gen_opc_instr_start[lj++] = 0;
8832
    } else {
8833
        tb->size = dc->pc - pc_start;
8834
        tb->icount = num_insns;
8835
    }
8836
}
8837

    
8838
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8839
{
8840
    gen_intermediate_code_internal(env, tb, 0);
8841
}
8842

    
8843
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8844
{
8845
    gen_intermediate_code_internal(env, tb, 1);
8846
}
8847

    
8848
static const char *cpu_mode_names[16] = {
8849
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8850
  "???", "???", "???", "und", "???", "???", "???", "sys"
8851
};
8852

    
8853
void cpu_dump_state(CPUState *env, FILE *f,
8854
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8855
                    int flags)
8856
{
8857
    int i;
8858
#if 0
8859
    union {
8860
        uint32_t i;
8861
        float s;
8862
    } s0, s1;
8863
    CPU_DoubleU d;
8864
    /* ??? This assumes float64 and double have the same layout.
8865
       Oh well, it's only debug dumps.  */
8866
    union {
8867
        float64 f64;
8868
        double d;
8869
    } d0;
8870
#endif
8871
    uint32_t psr;
8872

    
8873
    for(i=0;i<16;i++) {
8874
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8875
        if ((i % 4) == 3)
8876
            cpu_fprintf(f, "\n");
8877
        else
8878
            cpu_fprintf(f, " ");
8879
    }
8880
    psr = cpsr_read(env);
8881
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8882
                psr,
8883
                psr & (1 << 31) ? 'N' : '-',
8884
                psr & (1 << 30) ? 'Z' : '-',
8885
                psr & (1 << 29) ? 'C' : '-',
8886
                psr & (1 << 28) ? 'V' : '-',
8887
                psr & CPSR_T ? 'T' : 'A',
8888
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8889

    
8890
#if 0
8891
    for (i = 0; i < 16; i++) {
8892
        d.d = env->vfp.regs[i];
8893
        s0.i = d.l.lower;
8894
        s1.i = d.l.upper;
8895
        d0.f64 = d.d;
8896
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8897
                    i * 2, (int)s0.i, s0.s,
8898
                    i * 2 + 1, (int)s1.i, s1.s,
8899
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8900
                    d0.d);
8901
    }
8902
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8903
#endif
8904
}
8905

    
8906
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8907
                unsigned long searched_pc, int pc_pos, void *puc)
8908
{
8909
    env->regs[15] = gen_opc_pc[pc_pos];
8910
}