Statistics
| Branch: | Revision:

root / target-arm / translate.c @ f8ed7070

History | View | Annotate | Download (294.7 kB)

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

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

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

    
42
#define ARCH(x) if (!ENABLE_ARCH_##x) goto illegal_op;
43

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

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

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

    
75
/* XXX: move that elsewhere */
76
extern FILE *logfile;
77
extern int loglevel;
78

    
79
static TCGv cpu_env;
80
/* We reuse the same 64-bit temporaries for efficiency.  */
81
static TCGv cpu_V0, cpu_V1, cpu_M0;
82

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

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

    
92
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
93
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
94
}
95

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

    
102
/* Allocate a temporary variable.  */
103
static TCGv new_tmp(void)
104
{
105
    TCGv tmp;
106
    if (num_temps == MAX_TEMPS)
107
        abort();
108

    
109
    if (GET_TCGV(temps[num_temps]))
110
      return temps[num_temps++];
111

    
112
    tmp = tcg_temp_new(TCG_TYPE_I32);
113
    temps[num_temps++] = tmp;
114
    return tmp;
115
}
116

    
117
/* Release a temporary variable.  */
118
static void dead_tmp(TCGv tmp)
119
{
120
    int i;
121
    num_temps--;
122
    i = num_temps;
123
    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
124
        return;
125

    
126
    /* Shuffle this temp to the last slot.  */
127
    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
128
        i--;
129
    while (i < num_temps) {
130
        temps[i] = temps[i + 1];
131
        i++;
132
    }
133
    temps[i] = tmp;
134
}
135

    
136
static inline TCGv load_cpu_offset(int offset)
137
{
138
    TCGv tmp = new_tmp();
139
    tcg_gen_ld_i32(tmp, cpu_env, offset);
140
    return tmp;
141
}
142

    
143
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
144

    
145
static inline void store_cpu_offset(TCGv var, int offset)
146
{
147
    tcg_gen_st_i32(var, cpu_env, offset);
148
    dead_tmp(var);
149
}
150

    
151
#define store_cpu_field(var, name) \
152
    store_cpu_offset(var, offsetof(CPUState, name))
153

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

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

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

    
190

    
191
/* Basic operations.  */
192
#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
193
#define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
194
#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
195
#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
196

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

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

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

    
217
#define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
218
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
219
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
220
#define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
221
#define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
222

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
373
    tcg_gen_ext_i32_i64(tmp1, a);
374
    tcg_gen_ext_i32_i64(tmp2, b);
375
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
376
    tcg_gen_trunc_i64_i32(a, tmp1);
377
    tcg_gen_shri_i64(tmp1, tmp1, 32);
378
    tcg_gen_trunc_i64_i32(b, tmp1);
379
}
380
#define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
381

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
993
#define VFP_OP1(name)                               \
994
static inline void gen_vfp_##name(int dp, int arg)  \
995
{                                                   \
996
    if (dp)                                         \
997
        gen_op_vfp_##name##d(arg);                  \
998
    else                                            \
999
        gen_op_vfp_##name##s(arg);                  \
1000
}
1001

    
1002
VFP_OP2(add)
1003
VFP_OP2(sub)
1004
VFP_OP2(mul)
1005
VFP_OP2(div)
1006

    
1007
#undef VFP_OP2
1008

    
1009
static inline void gen_vfp_abs(int dp)
1010
{
1011
    if (dp)
1012
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1013
    else
1014
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1015
}
1016

    
1017
static inline void gen_vfp_neg(int dp)
1018
{
1019
    if (dp)
1020
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1021
    else
1022
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1023
}
1024

    
1025
static inline void gen_vfp_sqrt(int dp)
1026
{
1027
    if (dp)
1028
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1029
    else
1030
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1031
}
1032

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

    
1041
static inline void gen_vfp_cmpe(int dp)
1042
{
1043
    if (dp)
1044
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1045
    else
1046
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1047
}
1048

    
1049
static inline void gen_vfp_F1_ld0(int dp)
1050
{
1051
    if (dp)
1052
        tcg_gen_movi_i64(cpu_F1d, 0);
1053
    else
1054
        tcg_gen_movi_i32(cpu_F1s, 0);
1055
}
1056

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

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

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

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

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

    
1097
static inline void gen_vfp_tosiz(int dp)
1098
{
1099
    if (dp)
1100
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1101
    else
1102
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1103
}
1104

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

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

    
1131
static inline void gen_vfp_st(DisasContext *s, int dp)
1132
{
1133
    if (dp)
1134
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1135
    else
1136
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1137
}
1138

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

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

    
1163
/* FIXME: Remove these.  */
1164
#define neon_T0 cpu_T[0]
1165
#define neon_T1 cpu_T[1]
1166
#define NEON_GET_REG(T, reg, n) \
1167
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1168
#define NEON_SET_REG(T, reg, n) \
1169
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1170

    
1171
static TCGv neon_load_reg(int reg, int pass)
1172
{
1173
    TCGv tmp = new_tmp();
1174
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1175
    return tmp;
1176
}
1177

    
1178
static void neon_store_reg(int reg, int pass, TCGv var)
1179
{
1180
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1181
    dead_tmp(var);
1182
}
1183

    
1184
static inline void neon_load_reg64(TCGv var, int reg)
1185
{
1186
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1187
}
1188

    
1189
static inline void neon_store_reg64(TCGv var, int reg)
1190
{
1191
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192
}
1193

    
1194
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1195
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1196
#define tcg_gen_st_f32 tcg_gen_st_i32
1197
#define tcg_gen_st_f64 tcg_gen_st_i64
1198

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

    
1207
static inline void gen_mov_F1_vreg(int dp, int reg)
1208
{
1209
    if (dp)
1210
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1211
    else
1212
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1213
}
1214

    
1215
static inline void gen_mov_vreg_F0(int dp, int reg)
1216
{
1217
    if (dp)
1218
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1219
    else
1220
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1221
}
1222

    
1223
#define ARM_CP_RW_BIT        (1 << 20)
1224

    
1225
static inline void iwmmxt_load_reg(TCGv var, int reg)
1226
{
1227
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1228
}
1229

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

    
1235
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1236
{
1237
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1238
}
1239

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

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

    
1250
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1251
{
1252
    iwmmxt_store_reg(cpu_M0, rn);
1253
}
1254

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

    
1260
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1261
{
1262
    iwmmxt_load_reg(cpu_V1, rn);
1263
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1264
}
1265

    
1266
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1267
{
1268
    iwmmxt_load_reg(cpu_V1, rn);
1269
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1270
}
1271

    
1272
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1273
{
1274
    iwmmxt_load_reg(cpu_V1, rn);
1275
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1276
}
1277

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

    
1285
#define IWMMXT_OP_ENV(name) \
1286
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1287
{ \
1288
    iwmmxt_load_reg(cpu_V1, rn); \
1289
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1290
}
1291

    
1292
#define IWMMXT_OP_ENV_SIZE(name) \
1293
IWMMXT_OP_ENV(name##b) \
1294
IWMMXT_OP_ENV(name##w) \
1295
IWMMXT_OP_ENV(name##l)
1296

    
1297
#define IWMMXT_OP_ENV1(name) \
1298
static inline void gen_op_iwmmxt_##name##_M0(void) \
1299
{ \
1300
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1301
}
1302

    
1303
IWMMXT_OP(maddsq)
1304
IWMMXT_OP(madduq)
1305
IWMMXT_OP(sadb)
1306
IWMMXT_OP(sadw)
1307
IWMMXT_OP(mulslw)
1308
IWMMXT_OP(mulshw)
1309
IWMMXT_OP(mululw)
1310
IWMMXT_OP(muluhw)
1311
IWMMXT_OP(macsw)
1312
IWMMXT_OP(macuw)
1313

    
1314
IWMMXT_OP_ENV_SIZE(unpackl)
1315
IWMMXT_OP_ENV_SIZE(unpackh)
1316

    
1317
IWMMXT_OP_ENV1(unpacklub)
1318
IWMMXT_OP_ENV1(unpackluw)
1319
IWMMXT_OP_ENV1(unpacklul)
1320
IWMMXT_OP_ENV1(unpackhub)
1321
IWMMXT_OP_ENV1(unpackhuw)
1322
IWMMXT_OP_ENV1(unpackhul)
1323
IWMMXT_OP_ENV1(unpacklsb)
1324
IWMMXT_OP_ENV1(unpacklsw)
1325
IWMMXT_OP_ENV1(unpacklsl)
1326
IWMMXT_OP_ENV1(unpackhsb)
1327
IWMMXT_OP_ENV1(unpackhsw)
1328
IWMMXT_OP_ENV1(unpackhsl)
1329

    
1330
IWMMXT_OP_ENV_SIZE(cmpeq)
1331
IWMMXT_OP_ENV_SIZE(cmpgtu)
1332
IWMMXT_OP_ENV_SIZE(cmpgts)
1333

    
1334
IWMMXT_OP_ENV_SIZE(mins)
1335
IWMMXT_OP_ENV_SIZE(minu)
1336
IWMMXT_OP_ENV_SIZE(maxs)
1337
IWMMXT_OP_ENV_SIZE(maxu)
1338

    
1339
IWMMXT_OP_ENV_SIZE(subn)
1340
IWMMXT_OP_ENV_SIZE(addn)
1341
IWMMXT_OP_ENV_SIZE(subu)
1342
IWMMXT_OP_ENV_SIZE(addu)
1343
IWMMXT_OP_ENV_SIZE(subs)
1344
IWMMXT_OP_ENV_SIZE(adds)
1345

    
1346
IWMMXT_OP_ENV(avgb0)
1347
IWMMXT_OP_ENV(avgb1)
1348
IWMMXT_OP_ENV(avgw0)
1349
IWMMXT_OP_ENV(avgw1)
1350

    
1351
IWMMXT_OP(msadb)
1352

    
1353
IWMMXT_OP_ENV(packuw)
1354
IWMMXT_OP_ENV(packul)
1355
IWMMXT_OP_ENV(packuq)
1356
IWMMXT_OP_ENV(packsw)
1357
IWMMXT_OP_ENV(packsl)
1358
IWMMXT_OP_ENV(packsq)
1359

    
1360
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1361
{
1362
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1363
}
1364

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

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

    
1375
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1376
{
1377
    iwmmxt_load_reg(cpu_V1, rn);
1378
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1379
}
1380

    
1381
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1382
{
1383
    TCGv tmp = tcg_const_i32(shift);
1384
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1385
}
1386

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

    
1394
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1395
{
1396
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1397
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1398
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1399
}
1400

    
1401
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1402
{
1403
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1404
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1405
    if (mask != ~0u)
1406
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1407
}
1408

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

    
1417
static void gen_op_iwmmxt_set_cup(void)
1418
{
1419
    TCGv tmp;
1420
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1421
    tcg_gen_ori_i32(tmp, tmp, 1);
1422
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1423
}
1424

    
1425
static void gen_op_iwmmxt_setpsr_nz(void)
1426
{
1427
    TCGv tmp = new_tmp();
1428
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1429
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1430
}
1431

    
1432
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1433
{
1434
    iwmmxt_load_reg(cpu_V1, rn);
1435
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1436
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1437
}
1438

    
1439

    
1440
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1441
{
1442
    iwmmxt_load_reg(cpu_V0, rn);
1443
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1444
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1445
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1446
}
1447

    
1448
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1449
{
1450
    tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1451
    tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1452
    tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1453
    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1454
    iwmmxt_store_reg(cpu_V0, rn);
1455
}
1456

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

    
1462
    rd = (insn >> 16) & 0xf;
1463
    gen_movl_T1_reg(s, rd);
1464

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

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

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

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

    
1500
    gen_op_movl_T1_im(mask);
1501
    gen_op_andl_T0_T1();
1502
    return 0;
1503
}
1504

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

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

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

    
1593
    if ((insn & 0x0f000000) != 0x0e000000)
1594
        return 1;
1595

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

    
2468
    return 0;
2469
}
2470

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

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

    
2483
        if (acc != 0)
2484
            return 1;
2485

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

    
2514
        gen_op_iwmmxt_movq_wRn_M0(acc);
2515
        return 0;
2516
    }
2517

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

    
2524
        if (acc != 0)
2525
            return 1;
2526

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

    
2541
    return 1;
2542
}
2543

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

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

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

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

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

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

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

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

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

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

    
2676
static void gen_vfp_msr(TCGv tmp)
2677
{
2678
    tcg_gen_mov_i32(cpu_F0s, tmp);
2679
    dead_tmp(tmp);
2680
}
2681

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

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

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

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

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

    
2728
    if (!arm_feature(env, ARM_FEATURE_VFP))
2729
        return 1;
2730

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

    
2750
                VFP_DREG_N(rn, insn);
2751
                if (insn & 0xf)
2752
                    return 1;
2753
                if (insn & 0x00c00060
2754
                    && !arm_feature(env, ARM_FEATURE_NEON))
2755
                    return 1;
2756

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

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

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

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

    
2968
            veclen = env->vfp.vec_len;
2969
            if (op == 15 && rn > 3)
2970
                veclen = 0;
2971

    
2972
            /* Shut up compiler warnings.  */
2973
            delta_m = 0;
2974
            delta_d = 0;
2975
            bank_mask = 0;
2976

    
2977
            if (veclen > 0) {
2978
                if (dp)
2979
                    bank_mask = 0xc;
2980
                else
2981
                    bank_mask = 0x18;
2982

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

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

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

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

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

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

    
3217
                /* break out of the loop if we have finished  */
3218
                if (veclen == 0)
3219
                    break;
3220

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

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

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

    
3333
                if (insn & (1 << 24)) /* pre-decrement */
3334
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3335

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

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

    
3375
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3376
{
3377
    TranslationBlock *tb;
3378

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3518
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3519

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

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

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

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

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

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

    
3599
static inline void
3600
gen_neon_movl_scratch_T0(int scratch)
3601
{
3602
  uint32_t offset;
3603

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

    
3608
static inline void
3609
gen_neon_movl_scratch_T1(int scratch)
3610
{
3611
  uint32_t offset;
3612

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

    
3617
static inline void
3618
gen_neon_movl_T0_scratch(int scratch)
3619
{
3620
  uint32_t offset;
3621

    
3622
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3623
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3624
}
3625

    
3626
static inline void
3627
gen_neon_movl_T1_scratch(int scratch)
3628
{
3629
  uint32_t offset;
3630

    
3631
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3632
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3633
}
3634

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

    
3648
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3649
{
3650
    int n;
3651

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4695
                    gen_neon_widen(cpu_V0, tmp, size, u);
4696

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

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

    
4780
            if (op != 14 || !invert)
4781
                gen_op_movl_T1_im(imm);
4782

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

    
4838
                prewiden = neon_3reg_wide[op][0];
4839
                src1_wide = neon_3reg_wide[op][1];
4840
                src2_wide = neon_3reg_wide[op][2];
4841

    
4842
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4843
                    return 1;
4844

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

    
4923
                    default: /* 15 is RESERVED.  */
4924
                        return 1;
4925
                    }
4926
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4927
                        /* Accumulate.  */
4928
                        if (op == 10 || op == 11) {
4929
                            gen_neon_negl(cpu_V0, size);
4930
                        }
4931

    
4932
                        if (op != 13) {
4933
                            neon_load_reg64(cpu_V1, rd + pass);
4934
                        }
4935

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

    
5067
                    gen_neon_get_scalar(size, rm);
5068
                    NEON_GET_REG(T1, rn, 1);
5069

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

    
5116
                if (imm > 7 && !q)
5117
                    return 1;
5118

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

    
5544
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5545
{
5546
    int cpnum;
5547

    
5548
    cpnum = (insn >> 8) & 0xf;
5549
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5550
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5551
        return 1;
5552

    
5553
    switch (cpnum) {
5554
      case 0:
5555
      case 1:
5556
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5557
            return disas_iwmmxt_insn(env, s, insn);
5558
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5559
            return disas_dsp_insn(env, s, insn);
5560
        }
5561
        return 1;
5562
    case 10:
5563
    case 11:
5564
        return disas_vfp_insn (env, s, insn);
5565
    case 15:
5566
        return disas_cp15_insn (env, s, insn);
5567
    default:
5568
        /* Unknown coprocessor.  See if the board has hooked it.  */
5569
        return disas_cp_insn (env, s, insn);
5570
    }
5571
}
5572

    
5573

    
5574
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5575
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5576
{
5577
    TCGv tmp;
5578
    tmp = new_tmp();
5579
    tcg_gen_trunc_i64_i32(tmp, val);
5580
    store_reg(s, rlow, tmp);
5581
    tmp = new_tmp();
5582
    tcg_gen_shri_i64(val, val, 32);
5583
    tcg_gen_trunc_i64_i32(tmp, val);
5584
    store_reg(s, rhigh, tmp);
5585
}
5586

    
5587
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5588
static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5589
{
5590
    TCGv tmp;
5591
    TCGv tmp2;
5592

    
5593
    /* Load 64-bit value rd:rn.  */
5594
    tmp = tcg_temp_new(TCG_TYPE_I64);
5595
    tmp2 = load_reg(s, rlow);
5596
    tcg_gen_extu_i32_i64(tmp, tmp2);
5597
    dead_tmp(tmp2);
5598
    tcg_gen_add_i64(val, val, tmp);
5599
}
5600

    
5601
/* load and add a 64-bit value from a register pair.  */
5602
static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5603
{
5604
    TCGv tmp;
5605
    TCGv tmp2;
5606

    
5607
    /* Load 64-bit value rd:rn.  */
5608
    tmp = tcg_temp_new(TCG_TYPE_I64);
5609
    tmp2 = load_reg(s, rhigh);
5610
    tcg_gen_extu_i32_i64(tmp, tmp2);
5611
    dead_tmp(tmp2);
5612
    tcg_gen_shli_i64(tmp, tmp, 32);
5613
    tcg_gen_add_i64(val, val, tmp);
5614

    
5615
    tmp2 = load_reg(s, rlow);
5616
    tcg_gen_extu_i32_i64(tmp, tmp2);
5617
    dead_tmp(tmp2);
5618
    tcg_gen_add_i64(val, val, tmp);
5619
}
5620

    
5621
/* Set N and Z flags from a 64-bit value.  */
5622
static void gen_logicq_cc(TCGv val)
5623
{
5624
    TCGv tmp = new_tmp();
5625
    gen_helper_logicq_cc(tmp, val);
5626
    gen_logic_CC(tmp);
5627
    dead_tmp(tmp);
5628
}
5629

    
5630
static void disas_arm_insn(CPUState * env, DisasContext *s)
5631
{
5632
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5633
    TCGv tmp;
5634
    TCGv tmp2;
5635
    TCGv tmp3;
5636
    TCGv addr;
5637

    
5638
    insn = ldl_code(s->pc);
5639
    s->pc += 4;
5640

    
5641
    /* M variants do not implement ARM mode.  */
5642
    if (IS_M(env))
5643
        goto illegal_op;
5644
    cond = insn >> 28;
5645
    if (cond == 0xf){
5646
        /* Unconditional instructions.  */
5647
        if (((insn >> 25) & 7) == 1) {
5648
            /* NEON Data processing.  */
5649
            if (!arm_feature(env, ARM_FEATURE_NEON))
5650
                goto illegal_op;
5651

    
5652
            if (disas_neon_data_insn(env, s, insn))
5653
                goto illegal_op;
5654
            return;
5655
        }
5656
        if ((insn & 0x0f100000) == 0x04000000) {
5657
            /* NEON load/store.  */
5658
            if (!arm_feature(env, ARM_FEATURE_NEON))
5659
                goto illegal_op;
5660

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

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

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

    
6010
        op1 = (insn >> 21) & 0xf;
6011
        set_cc = (insn >> 20) & 1;
6012
        logic_cc = table_logic_cc[op1] & set_cc;
6013

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

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

    
6633
                    if ((insn & (1 << 15)) == 0)
6634
                        user = 1;
6635
                }
6636
                rn = (insn >> 16) & 0xf;
6637
                addr = load_reg(s, rn);
6638

    
6639
                /* compute total size */
6640
                loaded_base = 0;
6641
                n = 0;
6642
                for(i=0;i<16;i++) {
6643
                    if (insn & (1 << i))
6644
                        n++;
6645
                }
6646
                /* XXX: test invalid n == 0 case ? */
6647
                if (insn & (1 << 23)) {
6648
                    if (insn & (1 << 24)) {
6649
                        /* pre increment */
6650
                        tcg_gen_addi_i32(addr, addr, 4);
6651
                    } else {
6652
                        /* post increment */
6653
                    }
6654
                } else {
6655
                    if (insn & (1 << 24)) {
6656
                        /* pre decrement */
6657
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
6658
                    } else {
6659
                        /* post decrement */
6660
                        if (n != 1)
6661
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6662
                    }
6663
                }
6664
                j = 0;
6665
                for(i=0;i<16;i++) {
6666
                    if (insn & (1 << i)) {
6667
                        if (insn & (1 << 20)) {
6668
                            /* load */
6669
                            tmp = gen_ld32(addr, IS_USER(s));
6670
                            if (i == 15) {
6671
                                gen_bx(s, tmp);
6672
                            } else if (user) {
6673
                                gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6674
                                dead_tmp(tmp);
6675
                            } else if (i == rn) {
6676
                                loaded_var = tmp;
6677
                                loaded_base = 1;
6678
                            } else {
6679
                                store_reg(s, i, tmp);
6680
                            }
6681
                        } else {
6682
                            /* store */
6683
                            if (i == 15) {
6684
                                /* special case: r15 = PC + 8 */
6685
                                val = (long)s->pc + 4;
6686
                                tmp = new_tmp();
6687
                                tcg_gen_movi_i32(tmp, val);
6688
                            } else if (user) {
6689
                                tmp = new_tmp();
6690
                                gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6691
                            } else {
6692
                                tmp = load_reg(s, i);
6693
                            }
6694
                            gen_st32(tmp, addr, IS_USER(s));
6695
                        }
6696
                        j++;
6697
                        /* no need to add after the last transfer */
6698
                        if (j != n)
6699
                            tcg_gen_addi_i32(addr, addr, 4);
6700
                    }
6701
                }
6702
                if (insn & (1 << 21)) {
6703
                    /* write back */
6704
                    if (insn & (1 << 23)) {
6705
                        if (insn & (1 << 24)) {
6706
                            /* pre increment */
6707
                        } else {
6708
                            /* post increment */
6709
                            tcg_gen_addi_i32(addr, addr, 4);
6710
                        }
6711
                    } else {
6712
                        if (insn & (1 << 24)) {
6713
                            /* pre decrement */
6714
                            if (n != 1)
6715
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6716
                        } else {
6717
                            /* post decrement */
6718
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
6719
                        }
6720
                    }
6721
                    store_reg(s, rn, addr);
6722
                } else {
6723
                    dead_tmp(addr);
6724
                }
6725
                if (loaded_base) {
6726
                    store_reg(s, rn, loaded_var);
6727
                }
6728
                if ((insn & (1 << 22)) && !user) {
6729
                    /* Restore CPSR from SPSR.  */
6730
                    tmp = load_cpu_field(spsr);
6731
                    gen_set_cpsr(tmp, 0xffffffff);
6732
                    dead_tmp(tmp);
6733
                    s->is_jmp = DISAS_UPDATE;
6734
                }
6735
            }
6736
            break;
6737
        case 0xa:
6738
        case 0xb:
6739
            {
6740
                int32_t offset;
6741

    
6742
                /* branch (and link) */
6743
                val = (int32_t)s->pc;
6744
                if (insn & (1 << 24)) {
6745
                    tmp = new_tmp();
6746
                    tcg_gen_movi_i32(tmp, val);
6747
                    store_reg(s, 14, tmp);
6748
                }
6749
                offset = (((int32_t)insn << 8) >> 8);
6750
                val += (offset << 2) + 4;
6751
                gen_jmp(s, val);
6752
            }
6753
            break;
6754
        case 0xc:
6755
        case 0xd:
6756
        case 0xe:
6757
            /* Coprocessor.  */
6758
            if (disas_coproc_insn(env, s, insn))
6759
                goto illegal_op;
6760
            break;
6761
        case 0xf:
6762
            /* swi */
6763
            gen_set_pc_im(s->pc);
6764
            s->is_jmp = DISAS_SWI;
6765
            break;
6766
        default:
6767
        illegal_op:
6768
            gen_set_condexec(s);
6769
            gen_set_pc_im(s->pc - 4);
6770
            gen_exception(EXCP_UDEF);
6771
            s->is_jmp = DISAS_JUMP;
6772
            break;
6773
        }
6774
    }
6775
}
6776

    
6777
/* Return true if this is a Thumb-2 logical op.  */
6778
static int
6779
thumb2_logic_op(int op)
6780
{
6781
    return (op < 8);
6782
}
6783

    
6784
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6785
   then set condition code flags based on the result of the operation.
6786
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6787
   to the high bit of T1.
6788
   Returns zero if the opcode is valid.  */
6789

    
6790
static int
6791
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6792
{
6793
    int logic_cc;
6794

    
6795
    logic_cc = 0;
6796
    switch (op) {
6797
    case 0: /* and */
6798
        gen_op_andl_T0_T1();
6799
        logic_cc = conds;
6800
        break;
6801
    case 1: /* bic */
6802
        gen_op_bicl_T0_T1();
6803
        logic_cc = conds;
6804
        break;
6805
    case 2: /* orr */
6806
        gen_op_orl_T0_T1();
6807
        logic_cc = conds;
6808
        break;
6809
    case 3: /* orn */
6810
        gen_op_notl_T1();
6811
        gen_op_orl_T0_T1();
6812
        logic_cc = conds;
6813
        break;
6814
    case 4: /* eor */
6815
        gen_op_xorl_T0_T1();
6816
        logic_cc = conds;
6817
        break;
6818
    case 8: /* add */
6819
        if (conds)
6820
            gen_op_addl_T0_T1_cc();
6821
        else
6822
            gen_op_addl_T0_T1();
6823
        break;
6824
    case 10: /* adc */
6825
        if (conds)
6826
            gen_op_adcl_T0_T1_cc();
6827
        else
6828
            gen_adc_T0_T1();
6829
        break;
6830
    case 11: /* sbc */
6831
        if (conds)
6832
            gen_op_sbcl_T0_T1_cc();
6833
        else
6834
            gen_sbc_T0_T1();
6835
        break;
6836
    case 13: /* sub */
6837
        if (conds)
6838
            gen_op_subl_T0_T1_cc();
6839
        else
6840
            gen_op_subl_T0_T1();
6841
        break;
6842
    case 14: /* rsb */
6843
        if (conds)
6844
            gen_op_rsbl_T0_T1_cc();
6845
        else
6846
            gen_op_rsbl_T0_T1();
6847
        break;
6848
    default: /* 5, 6, 7, 9, 12, 15. */
6849
        return 1;
6850
    }
6851
    if (logic_cc) {
6852
        gen_op_logic_T0_cc();
6853
        if (shifter_out)
6854
            gen_set_CF_bit31(cpu_T[1]);
6855
    }
6856
    return 0;
6857
}
6858

    
6859
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
6860
   is not legal.  */
6861
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6862
{
6863
    uint32_t insn, imm, shift, offset;
6864
    uint32_t rd, rn, rm, rs;
6865
    TCGv tmp;
6866
    TCGv tmp2;
6867
    TCGv tmp3;
6868
    TCGv addr;
6869
    int op;
6870
    int shiftop;
6871
    int conds;
6872
    int logic_cc;
6873

    
6874
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6875
          || arm_feature (env, ARM_FEATURE_M))) {
6876
        /* Thumb-1 cores may need to treat bl and blx as a pair of
6877
           16-bit instructions to get correct prefetch abort behavior.  */
6878
        insn = insn_hw1;
6879
        if ((insn & (1 << 12)) == 0) {
6880
            /* Second half of blx.  */
6881
            offset = ((insn & 0x7ff) << 1);
6882
            tmp = load_reg(s, 14);
6883
            tcg_gen_addi_i32(tmp, tmp, offset);
6884
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6885

    
6886
            tmp2 = new_tmp();
6887
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6888
            store_reg(s, 14, tmp2);
6889
            gen_bx(s, tmp);
6890
            return 0;
6891
        }
6892
        if (insn & (1 << 11)) {
6893
            /* Second half of bl.  */
6894
            offset = ((insn & 0x7ff) << 1) | 1;
6895
            tmp = load_reg(s, 14);
6896
            tcg_gen_addi_i32(tmp, tmp, offset);
6897

    
6898
            tmp2 = new_tmp();
6899
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6900
            store_reg(s, 14, tmp2);
6901
            gen_bx(s, tmp);
6902
            return 0;
6903
        }
6904
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6905
            /* Instruction spans a page boundary.  Implement it as two
6906
               16-bit instructions in case the second half causes an
6907
               prefetch abort.  */
6908
            offset = ((int32_t)insn << 21) >> 9;
6909
            gen_op_movl_T0_im(s->pc + 2 + offset);
6910
            gen_movl_reg_T0(s, 14);
6911
            return 0;
6912
        }
6913
        /* Fall through to 32-bit decode.  */
6914
    }
6915

    
6916
    insn = lduw_code(s->pc);
6917
    s->pc += 2;
6918
    insn |= (uint32_t)insn_hw1 << 16;
6919

    
6920
    if ((insn & 0xf800e800) != 0xf000e800) {
6921
        ARCH(6T2);
6922
    }
6923

    
6924
    rn = (insn >> 16) & 0xf;
6925
    rs = (insn >> 12) & 0xf;
6926
    rd = (insn >> 8) & 0xf;
6927
    rm = insn & 0xf;
6928
    switch ((insn >> 25) & 0xf) {
6929
    case 0: case 1: case 2: case 3:
6930
        /* 16-bit instructions.  Should never happen.  */
6931
        abort();
6932
    case 4:
6933
        if (insn & (1 << 22)) {
6934
            /* Other load/store, table branch.  */
6935
            if (insn & 0x01200000) {
6936
                /* Load/store doubleword.  */
6937
                if (rn == 15) {
6938
                    addr = new_tmp();
6939
                    tcg_gen_movi_i32(addr, s->pc & ~3);
6940
                } else {
6941
                    addr = load_reg(s, rn);
6942
                }
6943
                offset = (insn & 0xff) * 4;
6944
                if ((insn & (1 << 23)) == 0)
6945
                    offset = -offset;
6946
                if (insn & (1 << 24)) {
6947
                    tcg_gen_addi_i32(addr, addr, offset);
6948
                    offset = 0;
6949
                }
6950
                if (insn & (1 << 20)) {
6951
                    /* ldrd */
6952
                    tmp = gen_ld32(addr, IS_USER(s));
6953
                    store_reg(s, rs, tmp);
6954
                    tcg_gen_addi_i32(addr, addr, 4);
6955
                    tmp = gen_ld32(addr, IS_USER(s));
6956
                    store_reg(s, rd, tmp);
6957
                } else {
6958
                    /* strd */
6959
                    tmp = load_reg(s, rs);
6960
                    gen_st32(tmp, addr, IS_USER(s));
6961
                    tcg_gen_addi_i32(addr, addr, 4);
6962
                    tmp = load_reg(s, rd);
6963
                    gen_st32(tmp, addr, IS_USER(s));
6964
                }
6965
                if (insn & (1 << 21)) {
6966
                    /* Base writeback.  */
6967
                    if (rn == 15)
6968
                        goto illegal_op;
6969
                    tcg_gen_addi_i32(addr, addr, offset - 4);
6970
                    store_reg(s, rn, addr);
6971
                } else {
6972
                    dead_tmp(addr);
6973
                }
6974
            } else if ((insn & (1 << 23)) == 0) {
6975
                /* Load/store exclusive word.  */
6976
                gen_movl_T1_reg(s, rn);
6977
                addr = cpu_T[1];
6978
                if (insn & (1 << 20)) {
6979
                    gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
6980
                    tmp = gen_ld32(addr, IS_USER(s));
6981
                    store_reg(s, rd, tmp);
6982
                } else {
6983
                    int label = gen_new_label();
6984
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
6985
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
6986
                                        0, label);
6987
                    tmp = load_reg(s, rs);
6988
                    gen_st32(tmp, cpu_T[1], IS_USER(s));
6989
                    gen_set_label(label);
6990
                    gen_movl_reg_T0(s, rd);
6991
                }
6992
            } else if ((insn & (1 << 6)) == 0) {
6993
                /* Table Branch.  */
6994
                if (rn == 15) {
6995
                    addr = new_tmp();
6996
                    tcg_gen_movi_i32(addr, s->pc);
6997
                } else {
6998
                    addr = load_reg(s, rn);
6999
                }
7000
                tmp = load_reg(s, rm);
7001
                tcg_gen_add_i32(addr, addr, tmp);
7002
                if (insn & (1 << 4)) {
7003
                    /* tbh */
7004
                    tcg_gen_add_i32(addr, addr, tmp);
7005
                    dead_tmp(tmp);
7006
                    tmp = gen_ld16u(addr, IS_USER(s));
7007
                } else { /* tbb */
7008
                    dead_tmp(tmp);
7009
                    tmp = gen_ld8u(addr, IS_USER(s));
7010
                }
7011
                dead_tmp(addr);
7012
                tcg_gen_shli_i32(tmp, tmp, 1);
7013
                tcg_gen_addi_i32(tmp, tmp, s->pc);
7014
                store_reg(s, 15, tmp);
7015
            } else {
7016
                /* Load/store exclusive byte/halfword/doubleword.  */
7017
                /* ??? These are not really atomic.  However we know
7018
                   we never have multiple CPUs running in parallel,
7019
                   so it is good enough.  */
7020
                op = (insn >> 4) & 0x3;
7021
                /* Must use a global reg for the address because we have
7022
                   a conditional branch in the store instruction.  */
7023
                gen_movl_T1_reg(s, rn);
7024
                addr = cpu_T[1];
7025
                if (insn & (1 << 20)) {
7026
                    gen_helper_mark_exclusive(cpu_env, addr);
7027
                    switch (op) {
7028
                    case 0:
7029
                        tmp = gen_ld8u(addr, IS_USER(s));
7030
                        break;
7031
                    case 1:
7032
                        tmp = gen_ld16u(addr, IS_USER(s));
7033
                        break;
7034
                    case 3:
7035
                        tmp = gen_ld32(addr, IS_USER(s));
7036
                        tcg_gen_addi_i32(addr, addr, 4);
7037
                        tmp2 = gen_ld32(addr, IS_USER(s));
7038
                        store_reg(s, rd, tmp2);
7039
                        break;
7040
                    default:
7041
                        goto illegal_op;
7042
                    }
7043
                    store_reg(s, rs, tmp);
7044
                } else {
7045
                    int label = gen_new_label();
7046
                    /* Must use a global that is not killed by the branch.  */
7047
                    gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
7048
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
7049
                    tmp = load_reg(s, rs);
7050
                    switch (op) {
7051
                    case 0:
7052
                        gen_st8(tmp, addr, IS_USER(s));
7053
                        break;
7054
                    case 1:
7055
                        gen_st16(tmp, addr, IS_USER(s));
7056
                        break;
7057
                    case 3:
7058
                        gen_st32(tmp, addr, IS_USER(s));
7059
                        tcg_gen_addi_i32(addr, addr, 4);
7060
                        tmp = load_reg(s, rd);
7061
                        gen_st32(tmp, addr, IS_USER(s));
7062
                        break;
7063
                    default:
7064
                        goto illegal_op;
7065
                    }
7066
                    gen_set_label(label);
7067
                    gen_movl_reg_T0(s, rm);
7068
                }
7069
            }
7070
        } else {
7071
            /* Load/store multiple, RFE, SRS.  */
7072
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
7073
                /* Not available in user mode.  */
7074
                if (IS_USER(s))
7075
                    goto illegal_op;
7076
                if (insn & (1 << 20)) {
7077
                    /* rfe */
7078
                    addr = load_reg(s, rn);
7079
                    if ((insn & (1 << 24)) == 0)
7080
                        tcg_gen_addi_i32(addr, addr, -8);
7081
                    /* Load PC into tmp and CPSR into tmp2.  */
7082
                    tmp = gen_ld32(addr, 0);
7083
                    tcg_gen_addi_i32(addr, addr, 4);
7084
                    tmp2 = gen_ld32(addr, 0);
7085
                    if (insn & (1 << 21)) {
7086
                        /* Base writeback.  */
7087
                        if (insn & (1 << 24)) {
7088
                            tcg_gen_addi_i32(addr, addr, 4);
7089
                        } else {
7090
                            tcg_gen_addi_i32(addr, addr, -4);
7091
                        }
7092
                        store_reg(s, rn, addr);
7093
                    } else {
7094
                        dead_tmp(addr);
7095
                    }
7096
                    gen_rfe(s, tmp, tmp2);
7097
                } else {
7098
                    /* srs */
7099
                    op = (insn & 0x1f);
7100
                    if (op == (env->uncached_cpsr & CPSR_M)) {
7101
                        addr = load_reg(s, 13);
7102
                    } else {
7103
                        addr = new_tmp();
7104
                        gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
7105
                    }
7106
                    if ((insn & (1 << 24)) == 0) {
7107
                        tcg_gen_addi_i32(addr, addr, -8);
7108
                    }
7109
                    tmp = load_reg(s, 14);
7110
                    gen_st32(tmp, addr, 0);
7111
                    tcg_gen_addi_i32(addr, addr, 4);
7112
                    tmp = new_tmp();
7113
                    gen_helper_cpsr_read(tmp);
7114
                    gen_st32(tmp, addr, 0);
7115
                    if (insn & (1 << 21)) {
7116
                        if ((insn & (1 << 24)) == 0) {
7117
                            tcg_gen_addi_i32(addr, addr, -4);
7118
                        } else {
7119
                            tcg_gen_addi_i32(addr, addr, 4);
7120
                        }
7121
                        if (op == (env->uncached_cpsr & CPSR_M)) {
7122
                            store_reg(s, 13, addr);
7123
                        } else {
7124
                            gen_helper_set_r13_banked(cpu_env,
7125
                                tcg_const_i32(op), addr);
7126
                        }
7127
                    } else {
7128
                        dead_tmp(addr);
7129
                    }
7130
                }
7131
            } else {
7132
                int i;
7133
                /* Load/store multiple.  */
7134
                addr = load_reg(s, rn);
7135
                offset = 0;
7136
                for (i = 0; i < 16; i++) {
7137
                    if (insn & (1 << i))
7138
                        offset += 4;
7139
                }
7140
                if (insn & (1 << 24)) {
7141
                    tcg_gen_addi_i32(addr, addr, -offset);
7142
                }
7143

    
7144
                for (i = 0; i < 16; i++) {
7145
                    if ((insn & (1 << i)) == 0)
7146
                        continue;
7147
                    if (insn & (1 << 20)) {
7148
                        /* Load.  */
7149
                        tmp = gen_ld32(addr, IS_USER(s));
7150
                        if (i == 15) {
7151
                            gen_bx(s, tmp);
7152
                        } else {
7153
                            store_reg(s, i, tmp);
7154
                        }
7155
                    } else {
7156
                        /* Store.  */
7157
                        tmp = load_reg(s, i);
7158
                        gen_st32(tmp, addr, IS_USER(s));
7159
                    }
7160
                    tcg_gen_addi_i32(addr, addr, 4);
7161
                }
7162
                if (insn & (1 << 21)) {
7163
                    /* Base register writeback.  */
7164
                    if (insn & (1 << 24)) {
7165
                        tcg_gen_addi_i32(addr, addr, -offset);
7166
                    }
7167
                    /* Fault if writeback register is in register list.  */
7168
                    if (insn & (1 << rn))
7169
                        goto illegal_op;
7170
                    store_reg(s, rn, addr);
7171
                } else {
7172
                    dead_tmp(addr);
7173
                }
7174
            }
7175
        }
7176
        break;
7177
    case 5: /* Data processing register constant shift.  */
7178
        if (rn == 15)
7179
            gen_op_movl_T0_im(0);
7180
        else
7181
            gen_movl_T0_reg(s, rn);
7182
        gen_movl_T1_reg(s, rm);
7183
        op = (insn >> 21) & 0xf;
7184
        shiftop = (insn >> 4) & 3;
7185
        shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7186
        conds = (insn & (1 << 20)) != 0;
7187
        logic_cc = (conds && thumb2_logic_op(op));
7188
        gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
7189
        if (gen_thumb2_data_op(s, op, conds, 0))
7190
            goto illegal_op;
7191
        if (rd != 15)
7192
            gen_movl_reg_T0(s, rd);
7193
        break;
7194
    case 13: /* Misc data processing.  */
7195
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
7196
        if (op < 4 && (insn & 0xf000) != 0xf000)
7197
            goto illegal_op;
7198
        switch (op) {
7199
        case 0: /* Register controlled shift.  */
7200
            tmp = load_reg(s, rn);
7201
            tmp2 = load_reg(s, rm);
7202
            if ((insn & 0x70) != 0)
7203
                goto illegal_op;
7204
            op = (insn >> 21) & 3;
7205
            logic_cc = (insn & (1 << 20)) != 0;
7206
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
7207
            if (logic_cc)
7208
                gen_logic_CC(tmp);
7209
            store_reg(s, rd, tmp);
7210
            break;
7211
        case 1: /* Sign/zero extend.  */
7212
            tmp = load_reg(s, rm);
7213
            shift = (insn >> 4) & 3;
7214
            /* ??? In many cases it's not neccessary to do a
7215
               rotate, a shift is sufficient.  */
7216
            if (shift != 0)
7217
                tcg_gen_rori_i32(tmp, tmp, shift * 8);
7218
            op = (insn >> 20) & 7;
7219
            switch (op) {
7220
            case 0: gen_sxth(tmp);   break;
7221
            case 1: gen_uxth(tmp);   break;
7222
            case 2: gen_sxtb16(tmp); break;
7223
            case 3: gen_uxtb16(tmp); break;
7224
            case 4: gen_sxtb(tmp);   break;
7225
            case 5: gen_uxtb(tmp);   break;
7226
            default: goto illegal_op;
7227
            }
7228
            if (rn != 15) {
7229
                tmp2 = load_reg(s, rn);
7230
                if ((op >> 1) == 1) {
7231
                    gen_add16(tmp, tmp2);
7232
                } else {
7233
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7234
                    dead_tmp(tmp2);
7235
                }
7236
            }
7237
            store_reg(s, rd, tmp);
7238
            break;
7239
        case 2: /* SIMD add/subtract.  */
7240
            op = (insn >> 20) & 7;
7241
            shift = (insn >> 4) & 7;
7242
            if ((op & 3) == 3 || (shift & 3) == 3)
7243
                goto illegal_op;
7244
            tmp = load_reg(s, rn);
7245
            tmp2 = load_reg(s, rm);
7246
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
7247
            dead_tmp(tmp2);
7248
            store_reg(s, rd, tmp);
7249
            break;
7250
        case 3: /* Other data processing.  */
7251
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
7252
            if (op < 4) {
7253
                /* Saturating add/subtract.  */
7254
                tmp = load_reg(s, rn);
7255
                tmp2 = load_reg(s, rm);
7256
                if (op & 2)
7257
                    gen_helper_double_saturate(tmp, tmp);
7258
                if (op & 1)
7259
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
7260
                else
7261
                    gen_helper_add_saturate(tmp, tmp, tmp2);
7262
                dead_tmp(tmp2);
7263
            } else {
7264
                tmp = load_reg(s, rn);
7265
                switch (op) {
7266
                case 0x0a: /* rbit */
7267
                    gen_helper_rbit(tmp, tmp);
7268
                    break;
7269
                case 0x08: /* rev */
7270
                    tcg_gen_bswap_i32(tmp, tmp);
7271
                    break;
7272
                case 0x09: /* rev16 */
7273
                    gen_rev16(tmp);
7274
                    break;
7275
                case 0x0b: /* revsh */
7276
                    gen_revsh(tmp);
7277
                    break;
7278
                case 0x10: /* sel */
7279
                    tmp2 = load_reg(s, rm);
7280
                    tmp3 = new_tmp();
7281
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7282
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7283
                    dead_tmp(tmp3);
7284
                    dead_tmp(tmp2);
7285
                    break;
7286
                case 0x18: /* clz */
7287
                    gen_helper_clz(tmp, tmp);
7288
                    break;
7289
                default:
7290
                    goto illegal_op;
7291
                }
7292
            }
7293
            store_reg(s, rd, tmp);
7294
            break;
7295
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7296
            op = (insn >> 4) & 0xf;
7297
            tmp = load_reg(s, rn);
7298
            tmp2 = load_reg(s, rm);
7299
            switch ((insn >> 20) & 7) {
7300
            case 0: /* 32 x 32 -> 32 */
7301
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7302
                dead_tmp(tmp2);
7303
                if (rs != 15) {
7304
                    tmp2 = load_reg(s, rs);
7305
                    if (op)
7306
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7307
                    else
7308
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7309
                    dead_tmp(tmp2);
7310
                }
7311
                break;
7312
            case 1: /* 16 x 16 -> 32 */
7313
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7314
                dead_tmp(tmp2);
7315
                if (rs != 15) {
7316
                    tmp2 = load_reg(s, rs);
7317
                    gen_helper_add_setq(tmp, tmp, tmp2);
7318
                    dead_tmp(tmp2);
7319
                }
7320
                break;
7321
            case 2: /* Dual multiply add.  */
7322
            case 4: /* Dual multiply subtract.  */
7323
                if (op)
7324
                    gen_swap_half(tmp2);
7325
                gen_smul_dual(tmp, tmp2);
7326
                /* This addition cannot overflow.  */
7327
                if (insn & (1 << 22)) {
7328
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7329
                } else {
7330
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7331
                }
7332
                dead_tmp(tmp2);
7333
                if (rs != 15)
7334
                  {
7335
                    tmp2 = load_reg(s, rs);
7336
                    gen_helper_add_setq(tmp, tmp, tmp2);
7337
                    dead_tmp(tmp2);
7338
                  }
7339
                break;
7340
            case 3: /* 32 * 16 -> 32msb */
7341
                if (op)
7342
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7343
                else
7344
                    gen_sxth(tmp2);
7345
                tmp2 = gen_muls_i64_i32(tmp, tmp2);
7346
                tcg_gen_shri_i64(tmp2, tmp2, 16);
7347
                tmp = new_tmp();
7348
                tcg_gen_trunc_i64_i32(tmp, tmp2);
7349
                if (rs != 15)
7350
                  {
7351
                    tmp2 = load_reg(s, rs);
7352
                    gen_helper_add_setq(tmp, tmp, tmp2);
7353
                    dead_tmp(tmp2);
7354
                  }
7355
                break;
7356
            case 5: case 6: /* 32 * 32 -> 32msb */
7357
                gen_imull(tmp, tmp2);
7358
                if (insn & (1 << 5)) {
7359
                    gen_roundqd(tmp, tmp2);
7360
                    dead_tmp(tmp2);
7361
                } else {
7362
                    dead_tmp(tmp);
7363
                    tmp = tmp2;
7364
                }
7365
                if (rs != 15) {
7366
                    tmp2 = load_reg(s, rs);
7367
                    if (insn & (1 << 21)) {
7368
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7369
                    } else {
7370
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7371
                    }
7372
                    dead_tmp(tmp2);
7373
                }
7374
                break;
7375
            case 7: /* Unsigned sum of absolute differences.  */
7376
                gen_helper_usad8(tmp, tmp, tmp2);
7377
                dead_tmp(tmp2);
7378
                if (rs != 15) {
7379
                    tmp2 = load_reg(s, rs);
7380
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7381
                    dead_tmp(tmp2);
7382
                }
7383
                break;
7384
            }
7385
            store_reg(s, rd, tmp);
7386
            break;
7387
        case 6: case 7: /* 64-bit multiply, Divide.  */
7388
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7389
            tmp = load_reg(s, rn);
7390
            tmp2 = load_reg(s, rm);
7391
            if ((op & 0x50) == 0x10) {
7392
                /* sdiv, udiv */
7393
                if (!arm_feature(env, ARM_FEATURE_DIV))
7394
                    goto illegal_op;
7395
                if (op & 0x20)
7396
                    gen_helper_udiv(tmp, tmp, tmp2);
7397
                else
7398
                    gen_helper_sdiv(tmp, tmp, tmp2);
7399
                dead_tmp(tmp2);
7400
                store_reg(s, rd, tmp);
7401
            } else if ((op & 0xe) == 0xc) {
7402
                /* Dual multiply accumulate long.  */
7403
                if (op & 1)
7404
                    gen_swap_half(tmp2);
7405
                gen_smul_dual(tmp, tmp2);
7406
                if (op & 0x10) {
7407
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7408
                } else {
7409
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7410
                }
7411
                dead_tmp(tmp2);
7412
                tmp2 = tcg_temp_new(TCG_TYPE_I64);
7413
                gen_addq(s, tmp, rs, rd);
7414
                gen_storeq_reg(s, rs, rd, tmp);
7415
            } else {
7416
                if (op & 0x20) {
7417
                    /* Unsigned 64-bit multiply  */
7418
                    tmp = gen_mulu_i64_i32(tmp, tmp2);
7419
                } else {
7420
                    if (op & 8) {
7421
                        /* smlalxy */
7422
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7423
                        dead_tmp(tmp2);
7424
                        tmp2 = tcg_temp_new(TCG_TYPE_I64);
7425
                        tcg_gen_ext_i32_i64(tmp2, tmp);
7426
                        dead_tmp(tmp);
7427
                        tmp = tmp2;
7428
                    } else {
7429
                        /* Signed 64-bit multiply  */
7430
                        tmp = gen_muls_i64_i32(tmp, tmp2);
7431
                    }
7432
                }
7433
                if (op & 4) {
7434
                    /* umaal */
7435
                    gen_addq_lo(s, tmp, rs);
7436
                    gen_addq_lo(s, tmp, rd);
7437
                } else if (op & 0x40) {
7438
                    /* 64-bit accumulate.  */
7439
                    gen_addq(s, tmp, rs, rd);
7440
                }
7441
                gen_storeq_reg(s, rs, rd, tmp);
7442
            }
7443
            break;
7444
        }
7445
        break;
7446
    case 6: case 7: case 14: case 15:
7447
        /* Coprocessor.  */
7448
        if (((insn >> 24) & 3) == 3) {
7449
            /* Translate into the equivalent ARM encoding.  */
7450
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7451
            if (disas_neon_data_insn(env, s, insn))
7452
                goto illegal_op;
7453
        } else {
7454
            if (insn & (1 << 28))
7455
                goto illegal_op;
7456
            if (disas_coproc_insn (env, s, insn))
7457
                goto illegal_op;
7458
        }
7459
        break;
7460
    case 8: case 9: case 10: case 11:
7461
        if (insn & (1 << 15)) {
7462
            /* Branches, misc control.  */
7463
            if (insn & 0x5000) {
7464
                /* Unconditional branch.  */
7465
                /* signextend(hw1[10:0]) -> offset[:12].  */
7466
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7467
                /* hw1[10:0] -> offset[11:1].  */
7468
                offset |= (insn & 0x7ff) << 1;
7469
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7470
                   offset[24:22] already have the same value because of the
7471
                   sign extension above.  */
7472
                offset ^= ((~insn) & (1 << 13)) << 10;
7473
                offset ^= ((~insn) & (1 << 11)) << 11;
7474

    
7475
                if (insn & (1 << 14)) {
7476
                    /* Branch and link.  */
7477
                    gen_op_movl_T1_im(s->pc | 1);
7478
                    gen_movl_reg_T1(s, 14);
7479
                }
7480

    
7481
                offset += s->pc;
7482
                if (insn & (1 << 12)) {
7483
                    /* b/bl */
7484
                    gen_jmp(s, offset);
7485
                } else {
7486
                    /* blx */
7487
                    offset &= ~(uint32_t)2;
7488
                    gen_bx_im(s, offset);
7489
                }
7490
            } else if (((insn >> 23) & 7) == 7) {
7491
                /* Misc control */
7492
                if (insn & (1 << 13))
7493
                    goto illegal_op;
7494

    
7495
                if (insn & (1 << 26)) {
7496
                    /* Secure monitor call (v6Z) */
7497
                    goto illegal_op; /* not implemented.  */
7498
                } else {
7499
                    op = (insn >> 20) & 7;
7500
                    switch (op) {
7501
                    case 0: /* msr cpsr.  */
7502
                        if (IS_M(env)) {
7503
                            tmp = load_reg(s, rn);
7504
                            addr = tcg_const_i32(insn & 0xff);
7505
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7506
                            gen_lookup_tb(s);
7507
                            break;
7508
                        }
7509
                        /* fall through */
7510
                    case 1: /* msr spsr.  */
7511
                        if (IS_M(env))
7512
                            goto illegal_op;
7513
                        gen_movl_T0_reg(s, rn);
7514
                        if (gen_set_psr_T0(s,
7515
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7516
                              op == 1))
7517
                            goto illegal_op;
7518
                        break;
7519
                    case 2: /* cps, nop-hint.  */
7520
                        if (((insn >> 8) & 7) == 0) {
7521
                            gen_nop_hint(s, insn & 0xff);
7522
                        }
7523
                        /* Implemented as NOP in user mode.  */
7524
                        if (IS_USER(s))
7525
                            break;
7526
                        offset = 0;
7527
                        imm = 0;
7528
                        if (insn & (1 << 10)) {
7529
                            if (insn & (1 << 7))
7530
                                offset |= CPSR_A;
7531
                            if (insn & (1 << 6))
7532
                                offset |= CPSR_I;
7533
                            if (insn & (1 << 5))
7534
                                offset |= CPSR_F;
7535
                            if (insn & (1 << 9))
7536
                                imm = CPSR_A | CPSR_I | CPSR_F;
7537
                        }
7538
                        if (insn & (1 << 8)) {
7539
                            offset |= 0x1f;
7540
                            imm |= (insn & 0x1f);
7541
                        }
7542
                        if (offset) {
7543
                            gen_op_movl_T0_im(imm);
7544
                            gen_set_psr_T0(s, offset, 0);
7545
                        }
7546
                        break;
7547
                    case 3: /* Special control operations.  */
7548
                        op = (insn >> 4) & 0xf;
7549
                        switch (op) {
7550
                        case 2: /* clrex */
7551
                            gen_helper_clrex(cpu_env);
7552
                            break;
7553
                        case 4: /* dsb */
7554
                        case 5: /* dmb */
7555
                        case 6: /* isb */
7556
                            /* These execute as NOPs.  */
7557
                            ARCH(7);
7558
                            break;
7559
                        default:
7560
                            goto illegal_op;
7561
                        }
7562
                        break;
7563
                    case 4: /* bxj */
7564
                        /* Trivial implementation equivalent to bx.  */
7565
                        tmp = load_reg(s, rn);
7566
                        gen_bx(s, tmp);
7567
                        break;
7568
                    case 5: /* Exception return.  */
7569
                        /* Unpredictable in user mode.  */
7570
                        goto illegal_op;
7571
                    case 6: /* mrs cpsr.  */
7572
                        tmp = new_tmp();
7573
                        if (IS_M(env)) {
7574
                            addr = tcg_const_i32(insn & 0xff);
7575
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
7576
                        } else {
7577
                            gen_helper_cpsr_read(tmp);
7578
                        }
7579
                        store_reg(s, rd, tmp);
7580
                        break;
7581
                    case 7: /* mrs spsr.  */
7582
                        /* Not accessible in user mode.  */
7583
                        if (IS_USER(s) || IS_M(env))
7584
                            goto illegal_op;
7585
                        tmp = load_cpu_field(spsr);
7586
                        store_reg(s, rd, tmp);
7587
                        break;
7588
                    }
7589
                }
7590
            } else {
7591
                /* Conditional branch.  */
7592
                op = (insn >> 22) & 0xf;
7593
                /* Generate a conditional jump to next instruction.  */
7594
                s->condlabel = gen_new_label();
7595
                gen_test_cc(op ^ 1, s->condlabel);
7596
                s->condjmp = 1;
7597

    
7598
                /* offset[11:1] = insn[10:0] */
7599
                offset = (insn & 0x7ff) << 1;
7600
                /* offset[17:12] = insn[21:16].  */
7601
                offset |= (insn & 0x003f0000) >> 4;
7602
                /* offset[31:20] = insn[26].  */
7603
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7604
                /* offset[18] = insn[13].  */
7605
                offset |= (insn & (1 << 13)) << 5;
7606
                /* offset[19] = insn[11].  */
7607
                offset |= (insn & (1 << 11)) << 8;
7608

    
7609
                /* jump to the offset */
7610
                gen_jmp(s, s->pc + offset);
7611
            }
7612
        } else {
7613
            /* Data processing immediate.  */
7614
            if (insn & (1 << 25)) {
7615
                if (insn & (1 << 24)) {
7616
                    if (insn & (1 << 20))
7617
                        goto illegal_op;
7618
                    /* Bitfield/Saturate.  */
7619
                    op = (insn >> 21) & 7;
7620
                    imm = insn & 0x1f;
7621
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7622
                    if (rn == 15) {
7623
                        tmp = new_tmp();
7624
                        tcg_gen_movi_i32(tmp, 0);
7625
                    } else {
7626
                        tmp = load_reg(s, rn);
7627
                    }
7628
                    switch (op) {
7629
                    case 2: /* Signed bitfield extract.  */
7630
                        imm++;
7631
                        if (shift + imm > 32)
7632
                            goto illegal_op;
7633
                        if (imm < 32)
7634
                            gen_sbfx(tmp, shift, imm);
7635
                        break;
7636
                    case 6: /* Unsigned bitfield extract.  */
7637
                        imm++;
7638
                        if (shift + imm > 32)
7639
                            goto illegal_op;
7640
                        if (imm < 32)
7641
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
7642
                        break;
7643
                    case 3: /* Bitfield insert/clear.  */
7644
                        if (imm < shift)
7645
                            goto illegal_op;
7646
                        imm = imm + 1 - shift;
7647
                        if (imm != 32) {
7648
                            tmp2 = load_reg(s, rd);
7649
                            gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
7650
                            dead_tmp(tmp2);
7651
                        }
7652
                        break;
7653
                    case 7:
7654
                        goto illegal_op;
7655
                    default: /* Saturate.  */
7656
                        if (shift) {
7657
                            if (op & 1)
7658
                                tcg_gen_sari_i32(tmp, tmp, shift);
7659
                            else
7660
                                tcg_gen_shli_i32(tmp, tmp, shift);
7661
                        }
7662
                        tmp2 = tcg_const_i32(imm);
7663
                        if (op & 4) {
7664
                            /* Unsigned.  */
7665
                            if ((op & 1) && shift == 0)
7666
                                gen_helper_usat16(tmp, tmp, tmp2);
7667
                            else
7668
                                gen_helper_usat(tmp, tmp, tmp2);
7669
                        } else {
7670
                            /* Signed.  */
7671
                            if ((op & 1) && shift == 0)
7672
                                gen_helper_ssat16(tmp, tmp, tmp2);
7673
                            else
7674
                                gen_helper_ssat(tmp, tmp, tmp2);
7675
                        }
7676
                        break;
7677
                    }
7678
                    store_reg(s, rd, tmp);
7679
                } else {
7680
                    imm = ((insn & 0x04000000) >> 15)
7681
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
7682
                    if (insn & (1 << 22)) {
7683
                        /* 16-bit immediate.  */
7684
                        imm |= (insn >> 4) & 0xf000;
7685
                        if (insn & (1 << 23)) {
7686
                            /* movt */
7687
                            tmp = load_reg(s, rd);
7688
                            tcg_gen_ext16u_i32(tmp, tmp);
7689
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
7690
                        } else {
7691
                            /* movw */
7692
                            tmp = new_tmp();
7693
                            tcg_gen_movi_i32(tmp, imm);
7694
                        }
7695
                    } else {
7696
                        /* Add/sub 12-bit immediate.  */
7697
                        if (rn == 15) {
7698
                            offset = s->pc & ~(uint32_t)3;
7699
                            if (insn & (1 << 23))
7700
                                offset -= imm;
7701
                            else
7702
                                offset += imm;
7703
                            tmp = new_tmp();
7704
                            tcg_gen_movi_i32(tmp, offset);
7705
                        } else {
7706
                            tmp = load_reg(s, rn);
7707
                            if (insn & (1 << 23))
7708
                                tcg_gen_subi_i32(tmp, tmp, imm);
7709
                            else
7710
                                tcg_gen_addi_i32(tmp, tmp, imm);
7711
                        }
7712
                    }
7713
                    store_reg(s, rd, tmp);
7714
                }
7715
            } else {
7716
                int shifter_out = 0;
7717
                /* modified 12-bit immediate.  */
7718
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7719
                imm = (insn & 0xff);
7720
                switch (shift) {
7721
                case 0: /* XY */
7722
                    /* Nothing to do.  */
7723
                    break;
7724
                case 1: /* 00XY00XY */
7725
                    imm |= imm << 16;
7726
                    break;
7727
                case 2: /* XY00XY00 */
7728
                    imm |= imm << 16;
7729
                    imm <<= 8;
7730
                    break;
7731
                case 3: /* XYXYXYXY */
7732
                    imm |= imm << 16;
7733
                    imm |= imm << 8;
7734
                    break;
7735
                default: /* Rotated constant.  */
7736
                    shift = (shift << 1) | (imm >> 7);
7737
                    imm |= 0x80;
7738
                    imm = imm << (32 - shift);
7739
                    shifter_out = 1;
7740
                    break;
7741
                }
7742
                gen_op_movl_T1_im(imm);
7743
                rn = (insn >> 16) & 0xf;
7744
                if (rn == 15)
7745
                    gen_op_movl_T0_im(0);
7746
                else
7747
                    gen_movl_T0_reg(s, rn);
7748
                op = (insn >> 21) & 0xf;
7749
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7750
                                       shifter_out))
7751
                    goto illegal_op;
7752
                rd = (insn >> 8) & 0xf;
7753
                if (rd != 15) {
7754
                    gen_movl_reg_T0(s, rd);
7755
                }
7756
            }
7757
        }
7758
        break;
7759
    case 12: /* Load/store single data item.  */
7760
        {
7761
        int postinc = 0;
7762
        int writeback = 0;
7763
        int user;
7764
        if ((insn & 0x01100000) == 0x01000000) {
7765
            if (disas_neon_ls_insn(env, s, insn))
7766
                goto illegal_op;
7767
            break;
7768
        }
7769
        user = IS_USER(s);
7770
        if (rn == 15) {
7771
            addr = new_tmp();
7772
            /* PC relative.  */
7773
            /* s->pc has already been incremented by 4.  */
7774
            imm = s->pc & 0xfffffffc;
7775
            if (insn & (1 << 23))
7776
                imm += insn & 0xfff;
7777
            else
7778
                imm -= insn & 0xfff;
7779
            tcg_gen_movi_i32(addr, imm);
7780
        } else {
7781
            addr = load_reg(s, rn);
7782
            if (insn & (1 << 23)) {
7783
                /* Positive offset.  */
7784
                imm = insn & 0xfff;
7785
                tcg_gen_addi_i32(addr, addr, imm);
7786
            } else {
7787
                op = (insn >> 8) & 7;
7788
                imm = insn & 0xff;
7789
                switch (op) {
7790
                case 0: case 8: /* Shifted Register.  */
7791
                    shift = (insn >> 4) & 0xf;
7792
                    if (shift > 3)
7793
                        goto illegal_op;
7794
                    tmp = load_reg(s, rm);
7795
                    if (shift)
7796
                        tcg_gen_shli_i32(tmp, tmp, shift);
7797
                    tcg_gen_add_i32(addr, addr, tmp);
7798
                    dead_tmp(tmp);
7799
                    break;
7800
                case 4: /* Negative offset.  */
7801
                    tcg_gen_addi_i32(addr, addr, -imm);
7802
                    break;
7803
                case 6: /* User privilege.  */
7804
                    tcg_gen_addi_i32(addr, addr, imm);
7805
                    user = 1;
7806
                    break;
7807
                case 1: /* Post-decrement.  */
7808
                    imm = -imm;
7809
                    /* Fall through.  */
7810
                case 3: /* Post-increment.  */
7811
                    postinc = 1;
7812
                    writeback = 1;
7813
                    break;
7814
                case 5: /* Pre-decrement.  */
7815
                    imm = -imm;
7816
                    /* Fall through.  */
7817
                case 7: /* Pre-increment.  */
7818
                    tcg_gen_addi_i32(addr, addr, imm);
7819
                    writeback = 1;
7820
                    break;
7821
                default:
7822
                    goto illegal_op;
7823
                }
7824
            }
7825
        }
7826
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7827
        if (insn & (1 << 20)) {
7828
            /* Load.  */
7829
            if (rs == 15 && op != 2) {
7830
                if (op & 2)
7831
                    goto illegal_op;
7832
                /* Memory hint.  Implemented as NOP.  */
7833
            } else {
7834
                switch (op) {
7835
                case 0: tmp = gen_ld8u(addr, user); break;
7836
                case 4: tmp = gen_ld8s(addr, user); break;
7837
                case 1: tmp = gen_ld16u(addr, user); break;
7838
                case 5: tmp = gen_ld16s(addr, user); break;
7839
                case 2: tmp = gen_ld32(addr, user); break;
7840
                default: goto illegal_op;
7841
                }
7842
                if (rs == 15) {
7843
                    gen_bx(s, tmp);
7844
                } else {
7845
                    store_reg(s, rs, tmp);
7846
                }
7847
            }
7848
        } else {
7849
            /* Store.  */
7850
            if (rs == 15)
7851
                goto illegal_op;
7852
            tmp = load_reg(s, rs);
7853
            switch (op) {
7854
            case 0: gen_st8(tmp, addr, user); break;
7855
            case 1: gen_st16(tmp, addr, user); break;
7856
            case 2: gen_st32(tmp, addr, user); break;
7857
            default: goto illegal_op;
7858
            }
7859
        }
7860
        if (postinc)
7861
            tcg_gen_addi_i32(addr, addr, imm);
7862
        if (writeback) {
7863
            store_reg(s, rn, addr);
7864
        } else {
7865
            dead_tmp(addr);
7866
        }
7867
        }
7868
        break;
7869
    default:
7870
        goto illegal_op;
7871
    }
7872
    return 0;
7873
illegal_op:
7874
    return 1;
7875
}
7876

    
7877
static void disas_thumb_insn(CPUState *env, DisasContext *s)
7878
{
7879
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
7880
    int32_t offset;
7881
    int i;
7882
    TCGv tmp;
7883
    TCGv tmp2;
7884
    TCGv addr;
7885

    
7886
    if (s->condexec_mask) {
7887
        cond = s->condexec_cond;
7888
        s->condlabel = gen_new_label();
7889
        gen_test_cc(cond ^ 1, s->condlabel);
7890
        s->condjmp = 1;
7891
    }
7892

    
7893
    insn = lduw_code(s->pc);
7894
    s->pc += 2;
7895

    
7896
    switch (insn >> 12) {
7897
    case 0: case 1:
7898
        rd = insn & 7;
7899
        op = (insn >> 11) & 3;
7900
        if (op == 3) {
7901
            /* add/subtract */
7902
            rn = (insn >> 3) & 7;
7903
            gen_movl_T0_reg(s, rn);
7904
            if (insn & (1 << 10)) {
7905
                /* immediate */
7906
                gen_op_movl_T1_im((insn >> 6) & 7);
7907
            } else {
7908
                /* reg */
7909
                rm = (insn >> 6) & 7;
7910
                gen_movl_T1_reg(s, rm);
7911
            }
7912
            if (insn & (1 << 9)) {
7913
                if (s->condexec_mask)
7914
                    gen_op_subl_T0_T1();
7915
                else
7916
                    gen_op_subl_T0_T1_cc();
7917
            } else {
7918
                if (s->condexec_mask)
7919
                    gen_op_addl_T0_T1();
7920
                else
7921
                    gen_op_addl_T0_T1_cc();
7922
            }
7923
            gen_movl_reg_T0(s, rd);
7924
        } else {
7925
            /* shift immediate */
7926
            rm = (insn >> 3) & 7;
7927
            shift = (insn >> 6) & 0x1f;
7928
            tmp = load_reg(s, rm);
7929
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7930
            if (!s->condexec_mask)
7931
                gen_logic_CC(tmp);
7932
            store_reg(s, rd, tmp);
7933
        }
7934
        break;
7935
    case 2: case 3:
7936
        /* arithmetic large immediate */
7937
        op = (insn >> 11) & 3;
7938
        rd = (insn >> 8) & 0x7;
7939
        if (op == 0) {
7940
            gen_op_movl_T0_im(insn & 0xff);
7941
        } else {
7942
            gen_movl_T0_reg(s, rd);
7943
            gen_op_movl_T1_im(insn & 0xff);
7944
        }
7945
        switch (op) {
7946
        case 0: /* mov */
7947
            if (!s->condexec_mask)
7948
                gen_op_logic_T0_cc();
7949
            break;
7950
        case 1: /* cmp */
7951
            gen_op_subl_T0_T1_cc();
7952
            break;
7953
        case 2: /* add */
7954
            if (s->condexec_mask)
7955
                gen_op_addl_T0_T1();
7956
            else
7957
                gen_op_addl_T0_T1_cc();
7958
            break;
7959
        case 3: /* sub */
7960
            if (s->condexec_mask)
7961
                gen_op_subl_T0_T1();
7962
            else
7963
                gen_op_subl_T0_T1_cc();
7964
            break;
7965
        }
7966
        if (op != 1)
7967
            gen_movl_reg_T0(s, rd);
7968
        break;
7969
    case 4:
7970
        if (insn & (1 << 11)) {
7971
            rd = (insn >> 8) & 7;
7972
            /* load pc-relative.  Bit 1 of PC is ignored.  */
7973
            val = s->pc + 2 + ((insn & 0xff) * 4);
7974
            val &= ~(uint32_t)2;
7975
            addr = new_tmp();
7976
            tcg_gen_movi_i32(addr, val);
7977
            tmp = gen_ld32(addr, IS_USER(s));
7978
            dead_tmp(addr);
7979
            store_reg(s, rd, tmp);
7980
            break;
7981
        }
7982
        if (insn & (1 << 10)) {
7983
            /* data processing extended or blx */
7984
            rd = (insn & 7) | ((insn >> 4) & 8);
7985
            rm = (insn >> 3) & 0xf;
7986
            op = (insn >> 8) & 3;
7987
            switch (op) {
7988
            case 0: /* add */
7989
                gen_movl_T0_reg(s, rd);
7990
                gen_movl_T1_reg(s, rm);
7991
                gen_op_addl_T0_T1();
7992
                gen_movl_reg_T0(s, rd);
7993
                break;
7994
            case 1: /* cmp */
7995
                gen_movl_T0_reg(s, rd);
7996
                gen_movl_T1_reg(s, rm);
7997
                gen_op_subl_T0_T1_cc();
7998
                break;
7999
            case 2: /* mov/cpy */
8000
                gen_movl_T0_reg(s, rm);
8001
                gen_movl_reg_T0(s, rd);
8002
                break;
8003
            case 3:/* branch [and link] exchange thumb register */
8004
                tmp = load_reg(s, rm);
8005
                if (insn & (1 << 7)) {
8006
                    val = (uint32_t)s->pc | 1;
8007
                    tmp2 = new_tmp();
8008
                    tcg_gen_movi_i32(tmp2, val);
8009
                    store_reg(s, 14, tmp2);
8010
                }
8011
                gen_bx(s, tmp);
8012
                break;
8013
            }
8014
            break;
8015
        }
8016

    
8017
        /* data processing register */
8018
        rd = insn & 7;
8019
        rm = (insn >> 3) & 7;
8020
        op = (insn >> 6) & 0xf;
8021
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8022
            /* the shift/rotate ops want the operands backwards */
8023
            val = rm;
8024
            rm = rd;
8025
            rd = val;
8026
            val = 1;
8027
        } else {
8028
            val = 0;
8029
        }
8030

    
8031
        if (op == 9) /* neg */
8032
            gen_op_movl_T0_im(0);
8033
        else if (op != 0xf) /* mvn doesn't read its first operand */
8034
            gen_movl_T0_reg(s, rd);
8035

    
8036
        gen_movl_T1_reg(s, rm);
8037
        switch (op) {
8038
        case 0x0: /* and */
8039
            gen_op_andl_T0_T1();
8040
            if (!s->condexec_mask)
8041
                gen_op_logic_T0_cc();
8042
            break;
8043
        case 0x1: /* eor */
8044
            gen_op_xorl_T0_T1();
8045
            if (!s->condexec_mask)
8046
                gen_op_logic_T0_cc();
8047
            break;
8048
        case 0x2: /* lsl */
8049
            if (s->condexec_mask) {
8050
                gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
8051
            } else {
8052
                gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8053
                gen_op_logic_T1_cc();
8054
            }
8055
            break;
8056
        case 0x3: /* lsr */
8057
            if (s->condexec_mask) {
8058
                gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
8059
            } else {
8060
                gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8061
                gen_op_logic_T1_cc();
8062
            }
8063
            break;
8064
        case 0x4: /* asr */
8065
            if (s->condexec_mask) {
8066
                gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
8067
            } else {
8068
                gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8069
                gen_op_logic_T1_cc();
8070
            }
8071
            break;
8072
        case 0x5: /* adc */
8073
            if (s->condexec_mask)
8074
                gen_adc_T0_T1();
8075
            else
8076
                gen_op_adcl_T0_T1_cc();
8077
            break;
8078
        case 0x6: /* sbc */
8079
            if (s->condexec_mask)
8080
                gen_sbc_T0_T1();
8081
            else
8082
                gen_op_sbcl_T0_T1_cc();
8083
            break;
8084
        case 0x7: /* ror */
8085
            if (s->condexec_mask) {
8086
                gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
8087
            } else {
8088
                gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
8089
                gen_op_logic_T1_cc();
8090
            }
8091
            break;
8092
        case 0x8: /* tst */
8093
            gen_op_andl_T0_T1();
8094
            gen_op_logic_T0_cc();
8095
            rd = 16;
8096
            break;
8097
        case 0x9: /* neg */
8098
            if (s->condexec_mask)
8099
                tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8100
            else
8101
                gen_op_subl_T0_T1_cc();
8102
            break;
8103
        case 0xa: /* cmp */
8104
            gen_op_subl_T0_T1_cc();
8105
            rd = 16;
8106
            break;
8107
        case 0xb: /* cmn */
8108
            gen_op_addl_T0_T1_cc();
8109
            rd = 16;
8110
            break;
8111
        case 0xc: /* orr */
8112
            gen_op_orl_T0_T1();
8113
            if (!s->condexec_mask)
8114
                gen_op_logic_T0_cc();
8115
            break;
8116
        case 0xd: /* mul */
8117
            gen_op_mull_T0_T1();
8118
            if (!s->condexec_mask)
8119
                gen_op_logic_T0_cc();
8120
            break;
8121
        case 0xe: /* bic */
8122
            gen_op_bicl_T0_T1();
8123
            if (!s->condexec_mask)
8124
                gen_op_logic_T0_cc();
8125
            break;
8126
        case 0xf: /* mvn */
8127
            gen_op_notl_T1();
8128
            if (!s->condexec_mask)
8129
                gen_op_logic_T1_cc();
8130
            val = 1;
8131
            rm = rd;
8132
            break;
8133
        }
8134
        if (rd != 16) {
8135
            if (val)
8136
                gen_movl_reg_T1(s, rm);
8137
            else
8138
                gen_movl_reg_T0(s, rd);
8139
        }
8140
        break;
8141

    
8142
    case 5:
8143
        /* load/store register offset.  */
8144
        rd = insn & 7;
8145
        rn = (insn >> 3) & 7;
8146
        rm = (insn >> 6) & 7;
8147
        op = (insn >> 9) & 7;
8148
        addr = load_reg(s, rn);
8149
        tmp = load_reg(s, rm);
8150
        tcg_gen_add_i32(addr, addr, tmp);
8151
        dead_tmp(tmp);
8152

    
8153
        if (op < 3) /* store */
8154
            tmp = load_reg(s, rd);
8155

    
8156
        switch (op) {
8157
        case 0: /* str */
8158
            gen_st32(tmp, addr, IS_USER(s));
8159
            break;
8160
        case 1: /* strh */
8161
            gen_st16(tmp, addr, IS_USER(s));
8162
            break;
8163
        case 2: /* strb */
8164
            gen_st8(tmp, addr, IS_USER(s));
8165
            break;
8166
        case 3: /* ldrsb */
8167
            tmp = gen_ld8s(addr, IS_USER(s));
8168
            break;
8169
        case 4: /* ldr */
8170
            tmp = gen_ld32(addr, IS_USER(s));
8171
            break;
8172
        case 5: /* ldrh */
8173
            tmp = gen_ld16u(addr, IS_USER(s));
8174
            break;
8175
        case 6: /* ldrb */
8176
            tmp = gen_ld8u(addr, IS_USER(s));
8177
            break;
8178
        case 7: /* ldrsh */
8179
            tmp = gen_ld16s(addr, IS_USER(s));
8180
            break;
8181
        }
8182
        if (op >= 3) /* load */
8183
            store_reg(s, rd, tmp);
8184
        dead_tmp(addr);
8185
        break;
8186

    
8187
    case 6:
8188
        /* load/store word immediate offset */
8189
        rd = insn & 7;
8190
        rn = (insn >> 3) & 7;
8191
        addr = load_reg(s, rn);
8192
        val = (insn >> 4) & 0x7c;
8193
        tcg_gen_addi_i32(addr, addr, val);
8194

    
8195
        if (insn & (1 << 11)) {
8196
            /* load */
8197
            tmp = gen_ld32(addr, IS_USER(s));
8198
            store_reg(s, rd, tmp);
8199
        } else {
8200
            /* store */
8201
            tmp = load_reg(s, rd);
8202
            gen_st32(tmp, addr, IS_USER(s));
8203
        }
8204
        dead_tmp(addr);
8205
        break;
8206

    
8207
    case 7:
8208
        /* load/store byte immediate offset */
8209
        rd = insn & 7;
8210
        rn = (insn >> 3) & 7;
8211
        addr = load_reg(s, rn);
8212
        val = (insn >> 6) & 0x1f;
8213
        tcg_gen_addi_i32(addr, addr, val);
8214

    
8215
        if (insn & (1 << 11)) {
8216
            /* load */
8217
            tmp = gen_ld8u(addr, IS_USER(s));
8218
            store_reg(s, rd, tmp);
8219
        } else {
8220
            /* store */
8221
            tmp = load_reg(s, rd);
8222
            gen_st8(tmp, addr, IS_USER(s));
8223
        }
8224
        dead_tmp(addr);
8225
        break;
8226

    
8227
    case 8:
8228
        /* load/store halfword immediate offset */
8229
        rd = insn & 7;
8230
        rn = (insn >> 3) & 7;
8231
        addr = load_reg(s, rn);
8232
        val = (insn >> 5) & 0x3e;
8233
        tcg_gen_addi_i32(addr, addr, val);
8234

    
8235
        if (insn & (1 << 11)) {
8236
            /* load */
8237
            tmp = gen_ld16u(addr, IS_USER(s));
8238
            store_reg(s, rd, tmp);
8239
        } else {
8240
            /* store */
8241
            tmp = load_reg(s, rd);
8242
            gen_st16(tmp, addr, IS_USER(s));
8243
        }
8244
        dead_tmp(addr);
8245
        break;
8246

    
8247
    case 9:
8248
        /* load/store from stack */
8249
        rd = (insn >> 8) & 7;
8250
        addr = load_reg(s, 13);
8251
        val = (insn & 0xff) * 4;
8252
        tcg_gen_addi_i32(addr, addr, val);
8253

    
8254
        if (insn & (1 << 11)) {
8255
            /* load */
8256
            tmp = gen_ld32(addr, IS_USER(s));
8257
            store_reg(s, rd, tmp);
8258
        } else {
8259
            /* store */
8260
            tmp = load_reg(s, rd);
8261
            gen_st32(tmp, addr, IS_USER(s));
8262
        }
8263
        dead_tmp(addr);
8264
        break;
8265

    
8266
    case 10:
8267
        /* add to high reg */
8268
        rd = (insn >> 8) & 7;
8269
        if (insn & (1 << 11)) {
8270
            /* SP */
8271
            tmp = load_reg(s, 13);
8272
        } else {
8273
            /* PC. bit 1 is ignored.  */
8274
            tmp = new_tmp();
8275
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8276
        }
8277
        val = (insn & 0xff) * 4;
8278
        tcg_gen_addi_i32(tmp, tmp, val);
8279
        store_reg(s, rd, tmp);
8280
        break;
8281

    
8282
    case 11:
8283
        /* misc */
8284
        op = (insn >> 8) & 0xf;
8285
        switch (op) {
8286
        case 0:
8287
            /* adjust stack pointer */
8288
            tmp = load_reg(s, 13);
8289
            val = (insn & 0x7f) * 4;
8290
            if (insn & (1 << 7))
8291
                val = -(int32_t)val;
8292
            tcg_gen_addi_i32(tmp, tmp, val);
8293
            store_reg(s, 13, tmp);
8294
            break;
8295

    
8296
        case 2: /* sign/zero extend.  */
8297
            ARCH(6);
8298
            rd = insn & 7;
8299
            rm = (insn >> 3) & 7;
8300
            tmp = load_reg(s, rm);
8301
            switch ((insn >> 6) & 3) {
8302
            case 0: gen_sxth(tmp); break;
8303
            case 1: gen_sxtb(tmp); break;
8304
            case 2: gen_uxth(tmp); break;
8305
            case 3: gen_uxtb(tmp); break;
8306
            }
8307
            store_reg(s, rd, tmp);
8308
            break;
8309
        case 4: case 5: case 0xc: case 0xd:
8310
            /* push/pop */
8311
            addr = load_reg(s, 13);
8312
            if (insn & (1 << 8))
8313
                offset = 4;
8314
            else
8315
                offset = 0;
8316
            for (i = 0; i < 8; i++) {
8317
                if (insn & (1 << i))
8318
                    offset += 4;
8319
            }
8320
            if ((insn & (1 << 11)) == 0) {
8321
                tcg_gen_addi_i32(addr, addr, -offset);
8322
            }
8323
            for (i = 0; i < 8; i++) {
8324
                if (insn & (1 << i)) {
8325
                    if (insn & (1 << 11)) {
8326
                        /* pop */
8327
                        tmp = gen_ld32(addr, IS_USER(s));
8328
                        store_reg(s, i, tmp);
8329
                    } else {
8330
                        /* push */
8331
                        tmp = load_reg(s, i);
8332
                        gen_st32(tmp, addr, IS_USER(s));
8333
                    }
8334
                    /* advance to the next address.  */
8335
                    tcg_gen_addi_i32(addr, addr, 4);
8336
                }
8337
            }
8338
            if (insn & (1 << 8)) {
8339
                if (insn & (1 << 11)) {
8340
                    /* pop pc */
8341
                    tmp = gen_ld32(addr, IS_USER(s));
8342
                    /* don't set the pc until the rest of the instruction
8343
                       has completed */
8344
                } else {
8345
                    /* push lr */
8346
                    tmp = load_reg(s, 14);
8347
                    gen_st32(tmp, addr, IS_USER(s));
8348
                }
8349
                tcg_gen_addi_i32(addr, addr, 4);
8350
            }
8351
            if ((insn & (1 << 11)) == 0) {
8352
                tcg_gen_addi_i32(addr, addr, -offset);
8353
            }
8354
            /* write back the new stack pointer */
8355
            store_reg(s, 13, addr);
8356
            /* set the new PC value */
8357
            if ((insn & 0x0900) == 0x0900)
8358
                gen_bx(s, tmp);
8359
            break;
8360

    
8361
        case 1: case 3: case 9: case 11: /* czb */
8362
            rm = insn & 7;
8363
            tmp = load_reg(s, rm);
8364
            s->condlabel = gen_new_label();
8365
            s->condjmp = 1;
8366
            if (insn & (1 << 11))
8367
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
8368
            else
8369
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
8370
            dead_tmp(tmp);
8371
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8372
            val = (uint32_t)s->pc + 2;
8373
            val += offset;
8374
            gen_jmp(s, val);
8375
            break;
8376

    
8377
        case 15: /* IT, nop-hint.  */
8378
            if ((insn & 0xf) == 0) {
8379
                gen_nop_hint(s, (insn >> 4) & 0xf);
8380
                break;
8381
            }
8382
            /* If Then.  */
8383
            s->condexec_cond = (insn >> 4) & 0xe;
8384
            s->condexec_mask = insn & 0x1f;
8385
            /* No actual code generated for this insn, just setup state.  */
8386
            break;
8387

    
8388
        case 0xe: /* bkpt */
8389
            gen_set_condexec(s);
8390
            gen_set_pc_im(s->pc - 2);
8391
            gen_exception(EXCP_BKPT);
8392
            s->is_jmp = DISAS_JUMP;
8393
            break;
8394

    
8395
        case 0xa: /* rev */
8396
            ARCH(6);
8397
            rn = (insn >> 3) & 0x7;
8398
            rd = insn & 0x7;
8399
            tmp = load_reg(s, rn);
8400
            switch ((insn >> 6) & 3) {
8401
            case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8402
            case 1: gen_rev16(tmp); break;
8403
            case 3: gen_revsh(tmp); break;
8404
            default: goto illegal_op;
8405
            }
8406
            store_reg(s, rd, tmp);
8407
            break;
8408

    
8409
        case 6: /* cps */
8410
            ARCH(6);
8411
            if (IS_USER(s))
8412
                break;
8413
            if (IS_M(env)) {
8414
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8415
                /* PRIMASK */
8416
                if (insn & 1) {
8417
                    addr = tcg_const_i32(16);
8418
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8419
                }
8420
                /* FAULTMASK */
8421
                if (insn & 2) {
8422
                    addr = tcg_const_i32(17);
8423
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8424
                }
8425
                gen_lookup_tb(s);
8426
            } else {
8427
                if (insn & (1 << 4))
8428
                    shift = CPSR_A | CPSR_I | CPSR_F;
8429
                else
8430
                    shift = 0;
8431

    
8432
                val = ((insn & 7) << 6) & shift;
8433
                gen_op_movl_T0_im(val);
8434
                gen_set_psr_T0(s, shift, 0);
8435
            }
8436
            break;
8437

    
8438
        default:
8439
            goto undef;
8440
        }
8441
        break;
8442

    
8443
    case 12:
8444
        /* load/store multiple */
8445
        rn = (insn >> 8) & 0x7;
8446
        addr = load_reg(s, rn);
8447
        for (i = 0; i < 8; i++) {
8448
            if (insn & (1 << i)) {
8449
                if (insn & (1 << 11)) {
8450
                    /* load */
8451
                    tmp = gen_ld32(addr, IS_USER(s));
8452
                    store_reg(s, i, tmp);
8453
                } else {
8454
                    /* store */
8455
                    tmp = load_reg(s, i);
8456
                    gen_st32(tmp, addr, IS_USER(s));
8457
                }
8458
                /* advance to the next address */
8459
                tcg_gen_addi_i32(addr, addr, 4);
8460
            }
8461
        }
8462
        /* Base register writeback.  */
8463
        if ((insn & (1 << rn)) == 0) {
8464
            store_reg(s, rn, addr);
8465
        } else {
8466
            dead_tmp(addr);
8467
        }
8468
        break;
8469

    
8470
    case 13:
8471
        /* conditional branch or swi */
8472
        cond = (insn >> 8) & 0xf;
8473
        if (cond == 0xe)
8474
            goto undef;
8475

    
8476
        if (cond == 0xf) {
8477
            /* swi */
8478
            gen_set_condexec(s);
8479
            gen_set_pc_im(s->pc);
8480
            s->is_jmp = DISAS_SWI;
8481
            break;
8482
        }
8483
        /* generate a conditional jump to next instruction */
8484
        s->condlabel = gen_new_label();
8485
        gen_test_cc(cond ^ 1, s->condlabel);
8486
        s->condjmp = 1;
8487
        gen_movl_T1_reg(s, 15);
8488

    
8489
        /* jump to the offset */
8490
        val = (uint32_t)s->pc + 2;
8491
        offset = ((int32_t)insn << 24) >> 24;
8492
        val += offset << 1;
8493
        gen_jmp(s, val);
8494
        break;
8495

    
8496
    case 14:
8497
        if (insn & (1 << 11)) {
8498
            if (disas_thumb2_insn(env, s, insn))
8499
              goto undef32;
8500
            break;
8501
        }
8502
        /* unconditional branch */
8503
        val = (uint32_t)s->pc;
8504
        offset = ((int32_t)insn << 21) >> 21;
8505
        val += (offset << 1) + 2;
8506
        gen_jmp(s, val);
8507
        break;
8508

    
8509
    case 15:
8510
        if (disas_thumb2_insn(env, s, insn))
8511
            goto undef32;
8512
        break;
8513
    }
8514
    return;
8515
undef32:
8516
    gen_set_condexec(s);
8517
    gen_set_pc_im(s->pc - 4);
8518
    gen_exception(EXCP_UDEF);
8519
    s->is_jmp = DISAS_JUMP;
8520
    return;
8521
illegal_op:
8522
undef:
8523
    gen_set_condexec(s);
8524
    gen_set_pc_im(s->pc - 2);
8525
    gen_exception(EXCP_UDEF);
8526
    s->is_jmp = DISAS_JUMP;
8527
}
8528

    
8529
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8530
   basic block 'tb'. If search_pc is TRUE, also generate PC
8531
   information for each intermediate instruction. */
8532
static inline int gen_intermediate_code_internal(CPUState *env,
8533
                                                 TranslationBlock *tb,
8534
                                                 int search_pc)
8535
{
8536
    DisasContext dc1, *dc = &dc1;
8537
    uint16_t *gen_opc_end;
8538
    int j, lj;
8539
    target_ulong pc_start;
8540
    uint32_t next_page_start;
8541

    
8542
    /* generate intermediate code */
8543
    num_temps = 0;
8544
    memset(temps, 0, sizeof(temps));
8545

    
8546
    pc_start = tb->pc;
8547

    
8548
    dc->tb = tb;
8549

    
8550
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8551

    
8552
    dc->is_jmp = DISAS_NEXT;
8553
    dc->pc = pc_start;
8554
    dc->singlestep_enabled = env->singlestep_enabled;
8555
    dc->condjmp = 0;
8556
    dc->thumb = env->thumb;
8557
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8558
    dc->condexec_cond = env->condexec_bits >> 4;
8559
    dc->is_mem = 0;
8560
#if !defined(CONFIG_USER_ONLY)
8561
    if (IS_M(env)) {
8562
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8563
    } else {
8564
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8565
    }
8566
#endif
8567
    cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
8568
    cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
8569
    cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
8570
    cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8571
    cpu_V0 = cpu_F0d;
8572
    cpu_V1 = cpu_F1d;
8573
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
8574
    cpu_M0 = tcg_temp_new(TCG_TYPE_I64);
8575
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8576
    lj = -1;
8577
    /* Reset the conditional execution bits immediately. This avoids
8578
       complications trying to do it at the end of the block.  */
8579
    if (env->condexec_bits)
8580
      {
8581
        TCGv tmp = new_tmp();
8582
        tcg_gen_movi_i32(tmp, 0);
8583
        store_cpu_field(tmp, condexec_bits);
8584
      }
8585
    do {
8586
#ifdef CONFIG_USER_ONLY
8587
        /* Intercept jump to the magic kernel page.  */
8588
        if (dc->pc >= 0xffff0000) {
8589
            /* We always get here via a jump, so know we are not in a
8590
               conditional execution block.  */
8591
            gen_exception(EXCP_KERNEL_TRAP);
8592
            dc->is_jmp = DISAS_UPDATE;
8593
            break;
8594
        }
8595
#else
8596
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8597
            /* We always get here via a jump, so know we are not in a
8598
               conditional execution block.  */
8599
            gen_exception(EXCP_EXCEPTION_EXIT);
8600
        }
8601
#endif
8602

    
8603
        if (env->nb_breakpoints > 0) {
8604
            for(j = 0; j < env->nb_breakpoints; j++) {
8605
                if (env->breakpoints[j] == dc->pc) {
8606
                    gen_set_condexec(dc);
8607
                    gen_set_pc_im(dc->pc);
8608
                    gen_exception(EXCP_DEBUG);
8609
                    dc->is_jmp = DISAS_JUMP;
8610
                    /* Advance PC so that clearing the breakpoint will
8611
                       invalidate this TB.  */
8612
                    dc->pc += 2;
8613
                    goto done_generating;
8614
                    break;
8615
                }
8616
            }
8617
        }
8618
        if (search_pc) {
8619
            j = gen_opc_ptr - gen_opc_buf;
8620
            if (lj < j) {
8621
                lj++;
8622
                while (lj < j)
8623
                    gen_opc_instr_start[lj++] = 0;
8624
            }
8625
            gen_opc_pc[lj] = dc->pc;
8626
            gen_opc_instr_start[lj] = 1;
8627
        }
8628

    
8629
        if (env->thumb) {
8630
            disas_thumb_insn(env, dc);
8631
            if (dc->condexec_mask) {
8632
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8633
                                   | ((dc->condexec_mask >> 4) & 1);
8634
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8635
                if (dc->condexec_mask == 0) {
8636
                    dc->condexec_cond = 0;
8637
                }
8638
            }
8639
        } else {
8640
            disas_arm_insn(env, dc);
8641
        }
8642
        if (num_temps) {
8643
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8644
            num_temps = 0;
8645
        }
8646

    
8647
        if (dc->condjmp && !dc->is_jmp) {
8648
            gen_set_label(dc->condlabel);
8649
            dc->condjmp = 0;
8650
        }
8651
        /* Terminate the TB on memory ops if watchpoints are present.  */
8652
        /* FIXME: This should be replacd by the deterministic execution
8653
         * IRQ raising bits.  */
8654
        if (dc->is_mem && env->nb_watchpoints)
8655
            break;
8656

    
8657
        /* Translation stops when a conditional branch is enoutered.
8658
         * Otherwise the subsequent code could get translated several times.
8659
         * Also stop translation when a page boundary is reached.  This
8660
         * ensures prefech aborts occur at the right place.  */
8661
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8662
             !env->singlestep_enabled &&
8663
             dc->pc < next_page_start);
8664

    
8665
    /* At this stage dc->condjmp will only be set when the skipped
8666
       instruction was a conditional branch or trap, and the PC has
8667
       already been written.  */
8668
    if (__builtin_expect(env->singlestep_enabled, 0)) {
8669
        /* Make sure the pc is updated, and raise a debug exception.  */
8670
        if (dc->condjmp) {
8671
            gen_set_condexec(dc);
8672
            if (dc->is_jmp == DISAS_SWI) {
8673
                gen_exception(EXCP_SWI);
8674
            } else {
8675
                gen_exception(EXCP_DEBUG);
8676
            }
8677
            gen_set_label(dc->condlabel);
8678
        }
8679
        if (dc->condjmp || !dc->is_jmp) {
8680
            gen_set_pc_im(dc->pc);
8681
            dc->condjmp = 0;
8682
        }
8683
        gen_set_condexec(dc);
8684
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8685
            gen_exception(EXCP_SWI);
8686
        } else {
8687
            /* FIXME: Single stepping a WFI insn will not halt
8688
               the CPU.  */
8689
            gen_exception(EXCP_DEBUG);
8690
        }
8691
    } else {
8692
        /* While branches must always occur at the end of an IT block,
8693
           there are a few other things that can cause us to terminate
8694
           the TB in the middel of an IT block:
8695
            - Exception generating instructions (bkpt, swi, undefined).
8696
            - Page boundaries.
8697
            - Hardware watchpoints.
8698
           Hardware breakpoints have already been handled and skip this code.
8699
         */
8700
        gen_set_condexec(dc);
8701
        switch(dc->is_jmp) {
8702
        case DISAS_NEXT:
8703
            gen_goto_tb(dc, 1, dc->pc);
8704
            break;
8705
        default:
8706
        case DISAS_JUMP:
8707
        case DISAS_UPDATE:
8708
            /* indicate that the hash table must be used to find the next TB */
8709
            tcg_gen_exit_tb(0);
8710
            break;
8711
        case DISAS_TB_JUMP:
8712
            /* nothing more to generate */
8713
            break;
8714
        case DISAS_WFI:
8715
            gen_helper_wfi();
8716
            break;
8717
        case DISAS_SWI:
8718
            gen_exception(EXCP_SWI);
8719
            break;
8720
        }
8721
        if (dc->condjmp) {
8722
            gen_set_label(dc->condlabel);
8723
            gen_set_condexec(dc);
8724
            gen_goto_tb(dc, 1, dc->pc);
8725
            dc->condjmp = 0;
8726
        }
8727
    }
8728
done_generating:
8729
    *gen_opc_ptr = INDEX_op_end;
8730

    
8731
#ifdef DEBUG_DISAS
8732
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8733
        fprintf(logfile, "----------------\n");
8734
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8735
        target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8736
        fprintf(logfile, "\n");
8737
    }
8738
#endif
8739
    if (search_pc) {
8740
        j = gen_opc_ptr - gen_opc_buf;
8741
        lj++;
8742
        while (lj <= j)
8743
            gen_opc_instr_start[lj++] = 0;
8744
    } else {
8745
        tb->size = dc->pc - pc_start;
8746
    }
8747
    return 0;
8748
}
8749

    
8750
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8751
{
8752
    return gen_intermediate_code_internal(env, tb, 0);
8753
}
8754

    
8755
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8756
{
8757
    return gen_intermediate_code_internal(env, tb, 1);
8758
}
8759

    
8760
static const char *cpu_mode_names[16] = {
8761
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8762
  "???", "???", "???", "und", "???", "???", "???", "sys"
8763
};
8764

    
8765
void cpu_dump_state(CPUState *env, FILE *f,
8766
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8767
                    int flags)
8768
{
8769
    int i;
8770
    union {
8771
        uint32_t i;
8772
        float s;
8773
    } s0, s1;
8774
    CPU_DoubleU d;
8775
    /* ??? This assumes float64 and double have the same layout.
8776
       Oh well, it's only debug dumps.  */
8777
    union {
8778
        float64 f64;
8779
        double d;
8780
    } d0;
8781
    uint32_t psr;
8782

    
8783
    for(i=0;i<16;i++) {
8784
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8785
        if ((i % 4) == 3)
8786
            cpu_fprintf(f, "\n");
8787
        else
8788
            cpu_fprintf(f, " ");
8789
    }
8790
    psr = cpsr_read(env);
8791
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8792
                psr,
8793
                psr & (1 << 31) ? 'N' : '-',
8794
                psr & (1 << 30) ? 'Z' : '-',
8795
                psr & (1 << 29) ? 'C' : '-',
8796
                psr & (1 << 28) ? 'V' : '-',
8797
                psr & CPSR_T ? 'T' : 'A',
8798
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8799

    
8800
#if 0
8801
    for (i = 0; i < 16; i++) {
8802
        d.d = env->vfp.regs[i];
8803
        s0.i = d.l.lower;
8804
        s1.i = d.l.upper;
8805
        d0.f64 = d.d;
8806
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8807
                    i * 2, (int)s0.i, s0.s,
8808
                    i * 2 + 1, (int)s1.i, s1.s,
8809
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8810
                    d0.d);
8811
    }
8812
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8813
#endif
8814
}
8815

    
8816
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8817
                unsigned long searched_pc, int pc_pos, void *puc)
8818
{
8819
    env->regs[15] = gen_opc_pc[pc_pos];
8820
}