Statistics
| Branch: | Revision:

root / target-arm / translate.c @ b0109805

History | View | Annotate | Download (277 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
/* FIXME:  These should be removed.  */
81
static TCGv cpu_T[3];
82

    
83
/* initialize TCG globals.  */
84
void arm_translate_init(void)
85
{
86
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
87

    
88
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
89
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
90
    cpu_T[2] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG3, "T2");
91
}
92

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

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

    
106
    if (GET_TCGV(temps[num_temps]))
107
      return temps[num_temps++];
108

    
109
    tmp = tcg_temp_new(TCG_TYPE_I32);
110
    temps[num_temps++] = tmp;
111
    return tmp;
112
}
113

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

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

    
133
static inline TCGv load_cpu_offset(int offset)
134
{
135
    TCGv tmp = new_tmp();
136
    tcg_gen_ld_i32(tmp, cpu_env, offset);
137
    return tmp;
138
}
139

    
140
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
141

    
142
static inline void store_cpu_offset(TCGv var, int offset)
143
{
144
    tcg_gen_st_i32(var, cpu_env, offset);
145
    dead_tmp(var);
146
}
147

    
148
#define store_cpu_field(var, name) \
149
    store_cpu_offset(var, offsetof(CPUState, name))
150

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

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

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

    
187

    
188
/* Basic operations.  */
189
#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
190
#define gen_op_movl_T0_T2() tcg_gen_mov_i32(cpu_T[0], cpu_T[2])
191
#define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
192
#define gen_op_movl_T1_T2() tcg_gen_mov_i32(cpu_T[1], cpu_T[2])
193
#define gen_op_movl_T2_T0() tcg_gen_mov_i32(cpu_T[2], 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
#define gen_op_movl_T2_im(im) tcg_gen_movi_i32(cpu_T[2], im)
197

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

    
203
#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
204
#define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
205
#define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
206
#define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
207
#define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
208
#define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
209
#define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
210

    
211
#define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
212
#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
213
#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
214
#define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
215
#define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
216

    
217
/* Value extensions.  */
218
#define gen_uxtb(var) tcg_gen_andi_i32(var, var, 0xff)
219
#define gen_uxth(var) tcg_gen_andi_i32(var, var, 0xffff)
220
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
221
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
222

    
223
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
224
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
225

    
226
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
227

    
228
#define gen_op_addl_T0_T1_setq() \
229
    gen_helper_add_setq(cpu_T[0], cpu_T[0], cpu_T[1])
230
#define gen_op_addl_T0_T1_saturate() \
231
    gen_helper_add_saturate(cpu_T[0], cpu_T[0], cpu_T[1])
232
#define gen_op_subl_T0_T1_saturate() \
233
    gen_helper_sub_saturate(cpu_T[0], cpu_T[0], cpu_T[1])
234
#define gen_op_addl_T0_T1_usaturate() \
235
    gen_helper_add_usaturate(cpu_T[0], cpu_T[0], cpu_T[1])
236
#define gen_op_subl_T0_T1_usaturate() \
237
    gen_helper_sub_usaturate(cpu_T[0], cpu_T[0], cpu_T[1])
238

    
239
/* Copy the most significant bit of T0 to all bits of T1.  */
240
#define gen_op_signbit_T1_T0() tcg_gen_sari_i32(cpu_T[1], cpu_T[0], 31)
241

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

    
246
static void gen_exception(int excp)
247
{
248
    TCGv tmp = new_tmp();
249
    tcg_gen_movi_i32(tmp, excp);
250
    gen_helper_exception(tmp);
251
    dead_tmp(tmp);
252
}
253

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

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

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

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

    
301
/* Signed bitfield extract.  */
302
static void gen_sbfx(TCGv var, int shift, int width)
303
{
304
    uint32_t signbit;
305

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

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

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

    
332
/* FIXME: Most targets have native widening multiplication.
333
   It would be good to use that instead of a full wide multiply.  */
334
/* Unsigned 32x32->64 multiply.  */
335
static void gen_op_mull_T0_T1(void)
336
{
337
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
338
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
339

    
340
    tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
341
    tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
342
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
343
    tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
344
    tcg_gen_shri_i64(tmp1, tmp1, 32);
345
    tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
346
}
347

    
348
/* Signed 32x32->64 multiply.  */
349
static void gen_imull(TCGv a, TCGv b)
350
{
351
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
352
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
353

    
354
    tcg_gen_ext_i32_i64(tmp1, a);
355
    tcg_gen_ext_i32_i64(tmp2, b);
356
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
357
    tcg_gen_trunc_i64_i32(a, tmp1);
358
    tcg_gen_shri_i64(tmp1, tmp1, 32);
359
    tcg_gen_trunc_i64_i32(b, tmp1);
360
}
361
#define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
362

    
363
/* Signed 32x16 multiply, top 32 bits.  */
364
static void gen_imulw(TCGv a, TCGv b)
365
{
366
  gen_imull(a, b);
367
  tcg_gen_shri_i32(a, a, 16);
368
  tcg_gen_shli_i32(b, b, 16);
369
  tcg_gen_or_i32(a, a, b);
370
}
371

    
372
/* Swap low and high halfwords.  */
373
static void gen_swap_half(TCGv var)
374
{
375
    TCGv tmp = new_tmp();
376
    tcg_gen_shri_i32(tmp, var, 16);
377
    tcg_gen_shli_i32(var, var, 16);
378
    tcg_gen_or_i32(var, var, tmp);
379
    dead_tmp(tmp);
380
}
381

    
382
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
383
    tmp = (t0 ^ t1) & 0x8000;
384
    t0 &= ~0x8000;
385
    t1 &= ~0x8000;
386
    t0 = (t0 + t1) ^ tmp;
387
 */
388

    
389
static void gen_add16(TCGv t0, TCGv t1)
390
{
391
    TCGv tmp = new_tmp();
392
    tcg_gen_xor_i32(tmp, t0, t1);
393
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
394
    tcg_gen_andi_i32(t0, t0, ~0x8000);
395
    tcg_gen_andi_i32(t1, t1, ~0x8000);
396
    tcg_gen_add_i32(t0, t0, t1);
397
    tcg_gen_xor_i32(t0, t0, tmp);
398
    dead_tmp(tmp);
399
    dead_tmp(t1);
400
}
401

    
402
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
403

    
404
/* Set CF to the top bit of var.  */
405
static void gen_set_CF_bit31(TCGv var)
406
{
407
    TCGv tmp = new_tmp();
408
    tcg_gen_shri_i32(tmp, var, 31);
409
    gen_set_CF(var);
410
    dead_tmp(tmp);
411
}
412

    
413
/* Set N and Z flags from var.  */
414
static inline void gen_logic_CC(TCGv var)
415
{
416
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NZF));
417
}
418

    
419
/* T0 += T1 + CF.  */
420
static void gen_adc_T0_T1(void)
421
{
422
    TCGv tmp;
423
    gen_op_addl_T0_T1();
424
    tmp = load_cpu_field(CF);
425
    tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
426
    dead_tmp(tmp);
427
}
428

    
429
/* dest = T0 - T1 + CF - 1.  */
430
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
431
{
432
    TCGv tmp;
433
    tcg_gen_sub_i32(dest, t0, t1);
434
    tmp = load_cpu_field(CF);
435
    tcg_gen_add_i32(dest, dest, tmp);
436
    tcg_gen_subi_i32(dest, dest, 1);
437
    dead_tmp(tmp);
438
}
439

    
440
#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
441
#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
442

    
443
/* FIXME:  Implement this natively.  */
444
static inline void tcg_gen_not_i32(TCGv t0, TCGv t1)
445
{
446
    tcg_gen_xori_i32(t0, t1, ~0);
447
}
448

    
449
/* T0 &= ~T1.  Clobbers T1.  */
450
/* FIXME: Implement bic natively.  */
451
static inline void gen_op_bicl_T0_T1(void)
452
{
453
    gen_op_notl_T1();
454
    gen_op_andl_T0_T1();
455
}
456

    
457
/* FIXME:  Implement this natively.  */
458
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
459
{
460
    TCGv tmp;
461

    
462
    if (i == 0)
463
        return;
464

    
465
    tmp = new_tmp();
466
    tcg_gen_shri_i32(tmp, t1, i);
467
    tcg_gen_shli_i32(t1, t1, 32 - i);
468
    tcg_gen_or_i32(t0, t1, tmp);
469
    dead_tmp(tmp);
470
}
471

    
472
static void shifter_out_im(TCGv var, int shift)
473
{
474
    TCGv tmp = new_tmp();
475
    if (shift == 0) {
476
        tcg_gen_andi_i32(tmp, var, 1);
477
    } else {
478
        tcg_gen_shri_i32(tmp, var, shift);
479
        if (shift != 31);
480
            tcg_gen_andi_i32(tmp, tmp, 1);
481
    }
482
    gen_set_CF(tmp);
483
    dead_tmp(tmp);
484
}
485

    
486
/* Shift by immediate.  Includes special handling for shift == 0.  */
487
static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
488
{
489
    switch (shiftop) {
490
    case 0: /* LSL */
491
        if (shift != 0) {
492
            if (flags)
493
                shifter_out_im(var, 32 - shift);
494
            tcg_gen_shli_i32(var, var, shift);
495
        }
496
        break;
497
    case 1: /* LSR */
498
        if (shift == 0) {
499
            if (flags) {
500
                tcg_gen_shri_i32(var, var, 31);
501
                gen_set_CF(var);
502
            }
503
            tcg_gen_movi_i32(var, 0);
504
        } else {
505
            if (flags)
506
                shifter_out_im(var, shift - 1);
507
            tcg_gen_shri_i32(var, var, shift);
508
        }
509
        break;
510
    case 2: /* ASR */
511
        if (shift == 0)
512
            shift = 32;
513
        if (flags)
514
            shifter_out_im(var, shift - 1);
515
        if (shift == 32)
516
          shift = 31;
517
        tcg_gen_sari_i32(var, var, shift);
518
        break;
519
    case 3: /* ROR/RRX */
520
        if (shift != 0) {
521
            if (flags)
522
                shifter_out_im(var, shift - 1);
523
            tcg_gen_rori_i32(var, var, shift); break;
524
        } else {
525
            TCGv tmp = load_cpu_field(CF);
526
            if (flags)
527
                shifter_out_im(var, 0);
528
            tcg_gen_shri_i32(var, var, 1);
529
            tcg_gen_shli_i32(tmp, tmp, 31);
530
            tcg_gen_or_i32(var, var, tmp);
531
            dead_tmp(tmp);
532
        }
533
    }
534
};
535

    
536
#define PAS_OP(pfx) \
537
    switch (op2) {  \
538
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
539
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
540
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
541
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
542
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
543
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
544
    }
545
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
546
{
547
    TCGv tmp;
548

    
549
    switch (op1) {
550
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
551
    case 1:
552
        tmp = tcg_temp_new(TCG_TYPE_PTR);
553
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
554
        PAS_OP(s)
555
        break;
556
    case 5:
557
        tmp = tcg_temp_new(TCG_TYPE_PTR);
558
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
559
        PAS_OP(u)
560
        break;
561
#undef gen_pas_helper
562
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
563
    case 2:
564
        PAS_OP(q);
565
        break;
566
    case 3:
567
        PAS_OP(sh);
568
        break;
569
    case 6:
570
        PAS_OP(uq);
571
        break;
572
    case 7:
573
        PAS_OP(uh);
574
        break;
575
#undef gen_pas_helper
576
    }
577
}
578
#undef PAS_OP
579

    
580
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
581
#define PAS_OP(pfx) \
582
    switch (op2) {  \
583
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
584
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
585
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
586
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
587
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
588
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
589
    }
590
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
591
{
592
    TCGv tmp;
593

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

    
625
static void gen_test_cc(int cc, int label)
626
{
627
    TCGv tmp;
628
    TCGv tmp2;
629
    TCGv zero;
630
    int inv;
631

    
632
    zero = tcg_const_i32(0);
633
    switch (cc) {
634
    case 0: /* eq: Z */
635
        tmp = load_cpu_field(NZF);
636
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
637
        break;
638
    case 1: /* ne: !Z */
639
        tmp = load_cpu_field(NZF);
640
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
641
        break;
642
    case 2: /* cs: C */
643
        tmp = load_cpu_field(CF);
644
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
645
        break;
646
    case 3: /* cc: !C */
647
        tmp = load_cpu_field(CF);
648
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
649
        break;
650
    case 4: /* mi: N */
651
        tmp = load_cpu_field(NZF);
652
        tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
653
        break;
654
    case 5: /* pl: !N */
655
        tmp = load_cpu_field(NZF);
656
        tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
657
        break;
658
    case 6: /* vs: V */
659
        tmp = load_cpu_field(VF);
660
        tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
661
        break;
662
    case 7: /* vc: !V */
663
        tmp = load_cpu_field(VF);
664
        tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
665
        break;
666
    case 8: /* hi: C && !Z */
667
        inv = gen_new_label();
668
        tmp = load_cpu_field(CF);
669
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
670
        dead_tmp(tmp);
671
        tmp = load_cpu_field(NZF);
672
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, zero, label);
673
        gen_set_label(inv);
674
        break;
675
    case 9: /* ls: !C || Z */
676
        tmp = load_cpu_field(CF);
677
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
678
        dead_tmp(tmp);
679
        tmp = load_cpu_field(NZF);
680
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
681
        break;
682
    case 10: /* ge: N == V -> N ^ V == 0 */
683
        tmp = load_cpu_field(VF);
684
        tmp2 = load_cpu_field(NZF);
685
        tcg_gen_xor_i32(tmp, tmp, tmp2);
686
        dead_tmp(tmp2);
687
        tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
688
        break;
689
    case 11: /* lt: N != V -> N ^ V != 0 */
690
        tmp = load_cpu_field(VF);
691
        tmp2 = load_cpu_field(NZF);
692
        tcg_gen_xor_i32(tmp, tmp, tmp2);
693
        dead_tmp(tmp2);
694
        tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
695
        break;
696
    case 12: /* gt: !Z && N == V */
697
        inv = gen_new_label();
698
        tmp = load_cpu_field(NZF);
699
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, inv);
700
        dead_tmp(tmp);
701
        tmp = load_cpu_field(VF);
702
        tmp2 = load_cpu_field(NZF);
703
        tcg_gen_xor_i32(tmp, tmp, tmp2);
704
        dead_tmp(tmp2);
705
        tcg_gen_brcond_i32(TCG_COND_GE, tmp, zero, label);
706
        gen_set_label(inv);
707
        break;
708
    case 13: /* le: Z || N != V */
709
        tmp = load_cpu_field(NZF);
710
        tcg_gen_brcond_i32(TCG_COND_EQ, tmp, zero, label);
711
        dead_tmp(tmp);
712
        tmp = load_cpu_field(VF);
713
        tmp2 = load_cpu_field(NZF);
714
        tcg_gen_xor_i32(tmp, tmp, tmp2);
715
        dead_tmp(tmp2);
716
        tcg_gen_brcond_i32(TCG_COND_LT, tmp, zero, label);
717
        break;
718
    default:
719
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
720
        abort();
721
    }
722
    dead_tmp(tmp);
723
}
724

    
725
const uint8_t table_logic_cc[16] = {
726
    1, /* and */
727
    1, /* xor */
728
    0, /* sub */
729
    0, /* rsb */
730
    0, /* add */
731
    0, /* adc */
732
    0, /* sbc */
733
    0, /* rsc */
734
    1, /* andl */
735
    1, /* xorl */
736
    0, /* cmp */
737
    0, /* cmn */
738
    1, /* orr */
739
    1, /* mov */
740
    1, /* bic */
741
    1, /* mvn */
742
};
743

    
744
static GenOpFunc *gen_shift_T1_T0[4] = {
745
    gen_op_shll_T1_T0,
746
    gen_op_shrl_T1_T0,
747
    gen_op_sarl_T1_T0,
748
    gen_op_rorl_T1_T0,
749
};
750

    
751
static GenOpFunc *gen_shift_T1_T0_cc[4] = {
752
    gen_op_shll_T1_T0_cc,
753
    gen_op_shrl_T1_T0_cc,
754
    gen_op_sarl_T1_T0_cc,
755
    gen_op_rorl_T1_T0_cc,
756
};
757

    
758
/* Set PC and Thumb state from an immediate address.  */
759
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
760
{
761
    TCGv tmp;
762

    
763
    s->is_jmp = DISAS_UPDATE;
764
    tmp = new_tmp();
765
    if (s->thumb != (addr & 1)) {
766
        tcg_gen_movi_i32(tmp, addr & 1);
767
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
768
    }
769
    tcg_gen_movi_i32(tmp, addr & ~1);
770
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
771
    dead_tmp(tmp);
772
}
773

    
774
/* Set PC and Thumb state from var.  var is marked as dead.  */
775
static inline void gen_bx(DisasContext *s, TCGv var)
776
{
777
    TCGv tmp;
778

    
779
    s->is_jmp = DISAS_UPDATE;
780
    tmp = new_tmp();
781
    tcg_gen_andi_i32(tmp, var, 1);
782
    store_cpu_field(tmp, thumb);
783
    tcg_gen_andi_i32(var, var, ~1);
784
    store_cpu_field(var, regs[15]);
785
}
786

    
787
/* TODO: This should be removed.  Use gen_bx instead.  */
788
static inline void gen_bx_T0(DisasContext *s)
789
{
790
    TCGv tmp = new_tmp();
791
    tcg_gen_mov_i32(tmp, cpu_T[0]);
792
    gen_bx(s, tmp);
793
}
794

    
795
#if defined(CONFIG_USER_ONLY)
796
#define gen_ldst(name, s) gen_op_##name##_raw()
797
#else
798
#define gen_ldst(name, s) do { \
799
    s->is_mem = 1; \
800
    if (IS_USER(s)) \
801
        gen_op_##name##_user(); \
802
    else \
803
        gen_op_##name##_kernel(); \
804
    } while (0)
805
#endif
806
static inline TCGv gen_ld8s(TCGv addr, int index)
807
{
808
    TCGv tmp = new_tmp();
809
    tcg_gen_qemu_ld8s(tmp, addr, index);
810
    return tmp;
811
}
812
static inline TCGv gen_ld8u(TCGv addr, int index)
813
{
814
    TCGv tmp = new_tmp();
815
    tcg_gen_qemu_ld8u(tmp, addr, index);
816
    return tmp;
817
}
818
static inline TCGv gen_ld16s(TCGv addr, int index)
819
{
820
    TCGv tmp = new_tmp();
821
    tcg_gen_qemu_ld16s(tmp, addr, index);
822
    return tmp;
823
}
824
static inline TCGv gen_ld16u(TCGv addr, int index)
825
{
826
    TCGv tmp = new_tmp();
827
    tcg_gen_qemu_ld16u(tmp, addr, index);
828
    return tmp;
829
}
830
static inline TCGv gen_ld32(TCGv addr, int index)
831
{
832
    TCGv tmp = new_tmp();
833
    tcg_gen_qemu_ld32u(tmp, addr, index);
834
    return tmp;
835
}
836
static inline void gen_st8(TCGv val, TCGv addr, int index)
837
{
838
    tcg_gen_qemu_st8(val, addr, index);
839
    dead_tmp(val);
840
}
841
static inline void gen_st16(TCGv val, TCGv addr, int index)
842
{
843
    tcg_gen_qemu_st16(val, addr, index);
844
    dead_tmp(val);
845
}
846
static inline void gen_st32(TCGv val, TCGv addr, int index)
847
{
848
    tcg_gen_qemu_st32(val, addr, index);
849
    dead_tmp(val);
850
}
851

    
852
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
853
{
854
    load_reg_var(s, cpu_T[0], reg);
855
}
856

    
857
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
858
{
859
    load_reg_var(s, cpu_T[1], reg);
860
}
861

    
862
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
863
{
864
    load_reg_var(s, cpu_T[2], reg);
865
}
866

    
867
static inline void gen_set_pc_T0(void)
868
{
869
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, regs[15]));
870
}
871

    
872
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
873
{
874
    TCGv tmp;
875
    if (reg == 15) {
876
        tmp = new_tmp();
877
        tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
878
    } else {
879
        tmp = cpu_T[t];
880
    }
881
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
882
    if (reg == 15) {
883
        dead_tmp(tmp);
884
        s->is_jmp = DISAS_JUMP;
885
    }
886
}
887

    
888
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
889
{
890
    gen_movl_reg_TN(s, reg, 0);
891
}
892

    
893
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
894
{
895
    gen_movl_reg_TN(s, reg, 1);
896
}
897

    
898
/* Force a TB lookup after an instruction that changes the CPU state.  */
899
static inline void gen_lookup_tb(DisasContext *s)
900
{
901
    gen_op_movl_T0_im(s->pc);
902
    gen_movl_reg_T0(s, 15);
903
    s->is_jmp = DISAS_UPDATE;
904
}
905

    
906
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
907
                                       TCGv var)
908
{
909
    int val, rm, shift, shiftop;
910
    TCGv offset;
911

    
912
    if (!(insn & (1 << 25))) {
913
        /* immediate */
914
        val = insn & 0xfff;
915
        if (!(insn & (1 << 23)))
916
            val = -val;
917
        if (val != 0)
918
            tcg_gen_addi_i32(var, var, val);
919
    } else {
920
        /* shift/register */
921
        rm = (insn) & 0xf;
922
        shift = (insn >> 7) & 0x1f;
923
        shiftop = (insn >> 5) & 3;
924
        offset = load_reg(s, rm);
925
        gen_arm_shift_im(offset, shiftop, shift, 0);
926
        if (!(insn & (1 << 23)))
927
            tcg_gen_sub_i32(var, var, offset);
928
        else
929
            tcg_gen_add_i32(var, var, offset);
930
        dead_tmp(offset);
931
    }
932
}
933

    
934
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
935
                                        int extra, TCGv var)
936
{
937
    int val, rm;
938
    TCGv offset;
939

    
940
    if (insn & (1 << 22)) {
941
        /* immediate */
942
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
943
        if (!(insn & (1 << 23)))
944
            val = -val;
945
        val += extra;
946
        if (val != 0)
947
            tcg_gen_addi_i32(var, var, val);
948
    } else {
949
        /* register */
950
        if (extra)
951
            tcg_gen_addi_i32(var, var, extra);
952
        rm = (insn) & 0xf;
953
        offset = load_reg(s, rm);
954
        if (!(insn & (1 << 23)))
955
            tcg_gen_sub_i32(var, var, offset);
956
        else
957
            tcg_gen_add_i32(var, var, offset);
958
        dead_tmp(offset);
959
    }
960
}
961

    
962
#define VFP_OP(name)                      \
963
static inline void gen_vfp_##name(int dp) \
964
{                                         \
965
    if (dp)                               \
966
        gen_op_vfp_##name##d();           \
967
    else                                  \
968
        gen_op_vfp_##name##s();           \
969
}
970

    
971
#define VFP_OP1(name)                               \
972
static inline void gen_vfp_##name(int dp, int arg)  \
973
{                                                   \
974
    if (dp)                                         \
975
        gen_op_vfp_##name##d(arg);                  \
976
    else                                            \
977
        gen_op_vfp_##name##s(arg);                  \
978
}
979

    
980
VFP_OP(add)
981
VFP_OP(sub)
982
VFP_OP(mul)
983
VFP_OP(div)
984
VFP_OP(neg)
985
VFP_OP(abs)
986
VFP_OP(sqrt)
987
VFP_OP(cmp)
988
VFP_OP(cmpe)
989
VFP_OP(F1_ld0)
990
VFP_OP(uito)
991
VFP_OP(sito)
992
VFP_OP(toui)
993
VFP_OP(touiz)
994
VFP_OP(tosi)
995
VFP_OP(tosiz)
996
VFP_OP1(tosh)
997
VFP_OP1(tosl)
998
VFP_OP1(touh)
999
VFP_OP1(toul)
1000
VFP_OP1(shto)
1001
VFP_OP1(slto)
1002
VFP_OP1(uhto)
1003
VFP_OP1(ulto)
1004

    
1005
#undef VFP_OP
1006

    
1007
static inline void gen_vfp_fconst(int dp, uint32_t val)
1008
{
1009
    if (dp)
1010
        gen_op_vfp_fconstd(val);
1011
    else
1012
        gen_op_vfp_fconsts(val);
1013
}
1014

    
1015
static inline void gen_vfp_ld(DisasContext *s, int dp)
1016
{
1017
    if (dp)
1018
        gen_ldst(vfp_ldd, s);
1019
    else
1020
        gen_ldst(vfp_lds, s);
1021
}
1022

    
1023
static inline void gen_vfp_st(DisasContext *s, int dp)
1024
{
1025
    if (dp)
1026
        gen_ldst(vfp_std, s);
1027
    else
1028
        gen_ldst(vfp_sts, s);
1029
}
1030

    
1031
static inline long
1032
vfp_reg_offset (int dp, int reg)
1033
{
1034
    if (dp)
1035
        return offsetof(CPUARMState, vfp.regs[reg]);
1036
    else if (reg & 1) {
1037
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1038
          + offsetof(CPU_DoubleU, l.upper);
1039
    } else {
1040
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1041
          + offsetof(CPU_DoubleU, l.lower);
1042
    }
1043
}
1044

    
1045
/* Return the offset of a 32-bit piece of a NEON register.
1046
   zero is the least significant end of the register.  */
1047
static inline long
1048
neon_reg_offset (int reg, int n)
1049
{
1050
    int sreg;
1051
    sreg = reg * 2 + n;
1052
    return vfp_reg_offset(0, sreg);
1053
}
1054

    
1055
#define NEON_GET_REG(T, reg, n) gen_op_neon_getreg_##T(neon_reg_offset(reg, n))
1056
#define NEON_SET_REG(T, reg, n) gen_op_neon_setreg_##T(neon_reg_offset(reg, n))
1057

    
1058
static inline void gen_mov_F0_vreg(int dp, int reg)
1059
{
1060
    if (dp)
1061
        gen_op_vfp_getreg_F0d(vfp_reg_offset(dp, reg));
1062
    else
1063
        gen_op_vfp_getreg_F0s(vfp_reg_offset(dp, reg));
1064
}
1065

    
1066
static inline void gen_mov_F1_vreg(int dp, int reg)
1067
{
1068
    if (dp)
1069
        gen_op_vfp_getreg_F1d(vfp_reg_offset(dp, reg));
1070
    else
1071
        gen_op_vfp_getreg_F1s(vfp_reg_offset(dp, reg));
1072
}
1073

    
1074
static inline void gen_mov_vreg_F0(int dp, int reg)
1075
{
1076
    if (dp)
1077
        gen_op_vfp_setreg_F0d(vfp_reg_offset(dp, reg));
1078
    else
1079
        gen_op_vfp_setreg_F0s(vfp_reg_offset(dp, reg));
1080
}
1081

    
1082
#define ARM_CP_RW_BIT        (1 << 20)
1083

    
1084
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1085
{
1086
    int rd;
1087
    uint32_t offset;
1088

    
1089
    rd = (insn >> 16) & 0xf;
1090
    gen_movl_T1_reg(s, rd);
1091

    
1092
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1093
    if (insn & (1 << 24)) {
1094
        /* Pre indexed */
1095
        if (insn & (1 << 23))
1096
            gen_op_addl_T1_im(offset);
1097
        else
1098
            gen_op_addl_T1_im(-offset);
1099

    
1100
        if (insn & (1 << 21))
1101
            gen_movl_reg_T1(s, rd);
1102
    } else if (insn & (1 << 21)) {
1103
        /* Post indexed */
1104
        if (insn & (1 << 23))
1105
            gen_op_movl_T0_im(offset);
1106
        else
1107
            gen_op_movl_T0_im(- offset);
1108
        gen_op_addl_T0_T1();
1109
        gen_movl_reg_T0(s, rd);
1110
    } else if (!(insn & (1 << 23)))
1111
        return 1;
1112
    return 0;
1113
}
1114

    
1115
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1116
{
1117
    int rd = (insn >> 0) & 0xf;
1118

    
1119
    if (insn & (1 << 8))
1120
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1121
            return 1;
1122
        else
1123
            gen_op_iwmmxt_movl_T0_wCx(rd);
1124
    else
1125
        gen_op_iwmmxt_movl_T0_T1_wRn(rd);
1126

    
1127
    gen_op_movl_T1_im(mask);
1128
    gen_op_andl_T0_T1();
1129
    return 0;
1130
}
1131

    
1132
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1133
   (ie. an undefined instruction).  */
1134
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1135
{
1136
    int rd, wrd;
1137
    int rdhi, rdlo, rd0, rd1, i;
1138
    TCGv tmp;
1139

    
1140
    if ((insn & 0x0e000e00) == 0x0c000000) {
1141
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1142
            wrd = insn & 0xf;
1143
            rdlo = (insn >> 12) & 0xf;
1144
            rdhi = (insn >> 16) & 0xf;
1145
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1146
                gen_op_iwmmxt_movl_T0_T1_wRn(wrd);
1147
                gen_movl_reg_T0(s, rdlo);
1148
                gen_movl_reg_T1(s, rdhi);
1149
            } else {                                        /* TMCRR */
1150
                gen_movl_T0_reg(s, rdlo);
1151
                gen_movl_T1_reg(s, rdhi);
1152
                gen_op_iwmmxt_movl_wRn_T0_T1(wrd);
1153
                gen_op_iwmmxt_set_mup();
1154
            }
1155
            return 0;
1156
        }
1157

    
1158
        wrd = (insn >> 12) & 0xf;
1159
        if (gen_iwmmxt_address(s, insn))
1160
            return 1;
1161
        if (insn & ARM_CP_RW_BIT) {
1162
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1163
                tmp = gen_ld32(cpu_T[1], IS_USER(s));
1164
                tcg_gen_mov_i32(cpu_T[0], tmp);
1165
                dead_tmp(tmp);
1166
                gen_op_iwmmxt_movl_wCx_T0(wrd);
1167
            } else {
1168
                if (insn & (1 << 8))
1169
                    if (insn & (1 << 22))                /* WLDRD */
1170
                        gen_ldst(iwmmxt_ldq, s);
1171
                    else                                /* WLDRW wRd */
1172
                        gen_ldst(iwmmxt_ldl, s);
1173
                else
1174
                    if (insn & (1 << 22))                /* WLDRH */
1175
                        gen_ldst(iwmmxt_ldw, s);
1176
                    else                                /* WLDRB */
1177
                        gen_ldst(iwmmxt_ldb, s);
1178
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1179
            }
1180
        } else {
1181
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1182
                gen_op_iwmmxt_movl_T0_wCx(wrd);
1183
                tmp = new_tmp();
1184
                tcg_gen_mov_i32(tmp, cpu_T[0]);
1185
                gen_st32(tmp, cpu_T[1], IS_USER(s));
1186
            } else {
1187
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1188
                if (insn & (1 << 8))
1189
                    if (insn & (1 << 22))                /* WSTRD */
1190
                        gen_ldst(iwmmxt_stq, s);
1191
                    else                                /* WSTRW wRd */
1192
                        gen_ldst(iwmmxt_stl, s);
1193
                else
1194
                    if (insn & (1 << 22))                /* WSTRH */
1195
                        gen_ldst(iwmmxt_ldw, s);
1196
                    else                                /* WSTRB */
1197
                        gen_ldst(iwmmxt_stb, s);
1198
            }
1199
        }
1200
        return 0;
1201
    }
1202

    
1203
    if ((insn & 0x0f000000) != 0x0e000000)
1204
        return 1;
1205

    
1206
    switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1207
    case 0x000:                                                /* WOR */
1208
        wrd = (insn >> 12) & 0xf;
1209
        rd0 = (insn >> 0) & 0xf;
1210
        rd1 = (insn >> 16) & 0xf;
1211
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1212
        gen_op_iwmmxt_orq_M0_wRn(rd1);
1213
        gen_op_iwmmxt_setpsr_nz();
1214
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1215
        gen_op_iwmmxt_set_mup();
1216
        gen_op_iwmmxt_set_cup();
1217
        break;
1218
    case 0x011:                                                /* TMCR */
1219
        if (insn & 0xf)
1220
            return 1;
1221
        rd = (insn >> 12) & 0xf;
1222
        wrd = (insn >> 16) & 0xf;
1223
        switch (wrd) {
1224
        case ARM_IWMMXT_wCID:
1225
        case ARM_IWMMXT_wCASF:
1226
            break;
1227
        case ARM_IWMMXT_wCon:
1228
            gen_op_iwmmxt_set_cup();
1229
            /* Fall through.  */
1230
        case ARM_IWMMXT_wCSSF:
1231
            gen_op_iwmmxt_movl_T0_wCx(wrd);
1232
            gen_movl_T1_reg(s, rd);
1233
            gen_op_bicl_T0_T1();
1234
            gen_op_iwmmxt_movl_wCx_T0(wrd);
1235
            break;
1236
        case ARM_IWMMXT_wCGR0:
1237
        case ARM_IWMMXT_wCGR1:
1238
        case ARM_IWMMXT_wCGR2:
1239
        case ARM_IWMMXT_wCGR3:
1240
            gen_op_iwmmxt_set_cup();
1241
            gen_movl_reg_T0(s, rd);
1242
            gen_op_iwmmxt_movl_wCx_T0(wrd);
1243
            break;
1244
        default:
1245
            return 1;
1246
        }
1247
        break;
1248
    case 0x100:                                                /* WXOR */
1249
        wrd = (insn >> 12) & 0xf;
1250
        rd0 = (insn >> 0) & 0xf;
1251
        rd1 = (insn >> 16) & 0xf;
1252
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1253
        gen_op_iwmmxt_xorq_M0_wRn(rd1);
1254
        gen_op_iwmmxt_setpsr_nz();
1255
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1256
        gen_op_iwmmxt_set_mup();
1257
        gen_op_iwmmxt_set_cup();
1258
        break;
1259
    case 0x111:                                                /* TMRC */
1260
        if (insn & 0xf)
1261
            return 1;
1262
        rd = (insn >> 12) & 0xf;
1263
        wrd = (insn >> 16) & 0xf;
1264
        gen_op_iwmmxt_movl_T0_wCx(wrd);
1265
        gen_movl_reg_T0(s, rd);
1266
        break;
1267
    case 0x300:                                                /* WANDN */
1268
        wrd = (insn >> 12) & 0xf;
1269
        rd0 = (insn >> 0) & 0xf;
1270
        rd1 = (insn >> 16) & 0xf;
1271
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1272
        gen_op_iwmmxt_negq_M0();
1273
        gen_op_iwmmxt_andq_M0_wRn(rd1);
1274
        gen_op_iwmmxt_setpsr_nz();
1275
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1276
        gen_op_iwmmxt_set_mup();
1277
        gen_op_iwmmxt_set_cup();
1278
        break;
1279
    case 0x200:                                                /* WAND */
1280
        wrd = (insn >> 12) & 0xf;
1281
        rd0 = (insn >> 0) & 0xf;
1282
        rd1 = (insn >> 16) & 0xf;
1283
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1284
        gen_op_iwmmxt_andq_M0_wRn(rd1);
1285
        gen_op_iwmmxt_setpsr_nz();
1286
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1287
        gen_op_iwmmxt_set_mup();
1288
        gen_op_iwmmxt_set_cup();
1289
        break;
1290
    case 0x810: case 0xa10:                                /* WMADD */
1291
        wrd = (insn >> 12) & 0xf;
1292
        rd0 = (insn >> 0) & 0xf;
1293
        rd1 = (insn >> 16) & 0xf;
1294
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1295
        if (insn & (1 << 21))
1296
            gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1297
        else
1298
            gen_op_iwmmxt_madduq_M0_wRn(rd1);
1299
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1300
        gen_op_iwmmxt_set_mup();
1301
        break;
1302
    case 0x10e: case 0x50e: case 0x90e: case 0xd0e:        /* WUNPCKIL */
1303
        wrd = (insn >> 12) & 0xf;
1304
        rd0 = (insn >> 16) & 0xf;
1305
        rd1 = (insn >> 0) & 0xf;
1306
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1307
        switch ((insn >> 22) & 3) {
1308
        case 0:
1309
            gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1310
            break;
1311
        case 1:
1312
            gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1313
            break;
1314
        case 2:
1315
            gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1316
            break;
1317
        case 3:
1318
            return 1;
1319
        }
1320
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1321
        gen_op_iwmmxt_set_mup();
1322
        gen_op_iwmmxt_set_cup();
1323
        break;
1324
    case 0x10c: case 0x50c: case 0x90c: case 0xd0c:        /* WUNPCKIH */
1325
        wrd = (insn >> 12) & 0xf;
1326
        rd0 = (insn >> 16) & 0xf;
1327
        rd1 = (insn >> 0) & 0xf;
1328
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1329
        switch ((insn >> 22) & 3) {
1330
        case 0:
1331
            gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1332
            break;
1333
        case 1:
1334
            gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1335
            break;
1336
        case 2:
1337
            gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1338
            break;
1339
        case 3:
1340
            return 1;
1341
        }
1342
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1343
        gen_op_iwmmxt_set_mup();
1344
        gen_op_iwmmxt_set_cup();
1345
        break;
1346
    case 0x012: case 0x112: case 0x412: case 0x512:        /* WSAD */
1347
        wrd = (insn >> 12) & 0xf;
1348
        rd0 = (insn >> 16) & 0xf;
1349
        rd1 = (insn >> 0) & 0xf;
1350
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1351
        if (insn & (1 << 22))
1352
            gen_op_iwmmxt_sadw_M0_wRn(rd1);
1353
        else
1354
            gen_op_iwmmxt_sadb_M0_wRn(rd1);
1355
        if (!(insn & (1 << 20)))
1356
            gen_op_iwmmxt_addl_M0_wRn(wrd);
1357
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1358
        gen_op_iwmmxt_set_mup();
1359
        break;
1360
    case 0x010: case 0x110: case 0x210: case 0x310:        /* WMUL */
1361
        wrd = (insn >> 12) & 0xf;
1362
        rd0 = (insn >> 16) & 0xf;
1363
        rd1 = (insn >> 0) & 0xf;
1364
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1365
        if (insn & (1 << 21))
1366
            gen_op_iwmmxt_mulsw_M0_wRn(rd1, (insn & (1 << 20)) ? 16 : 0);
1367
        else
1368
            gen_op_iwmmxt_muluw_M0_wRn(rd1, (insn & (1 << 20)) ? 16 : 0);
1369
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1370
        gen_op_iwmmxt_set_mup();
1371
        break;
1372
    case 0x410: case 0x510: case 0x610: case 0x710:        /* WMAC */
1373
        wrd = (insn >> 12) & 0xf;
1374
        rd0 = (insn >> 16) & 0xf;
1375
        rd1 = (insn >> 0) & 0xf;
1376
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1377
        if (insn & (1 << 21))
1378
            gen_op_iwmmxt_macsw_M0_wRn(rd1);
1379
        else
1380
            gen_op_iwmmxt_macuw_M0_wRn(rd1);
1381
        if (!(insn & (1 << 20))) {
1382
            if (insn & (1 << 21))
1383
                gen_op_iwmmxt_addsq_M0_wRn(wrd);
1384
            else
1385
                gen_op_iwmmxt_adduq_M0_wRn(wrd);
1386
        }
1387
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1388
        gen_op_iwmmxt_set_mup();
1389
        break;
1390
    case 0x006: case 0x406: case 0x806: case 0xc06:        /* WCMPEQ */
1391
        wrd = (insn >> 12) & 0xf;
1392
        rd0 = (insn >> 16) & 0xf;
1393
        rd1 = (insn >> 0) & 0xf;
1394
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1395
        switch ((insn >> 22) & 3) {
1396
        case 0:
1397
            gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1398
            break;
1399
        case 1:
1400
            gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1401
            break;
1402
        case 2:
1403
            gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1404
            break;
1405
        case 3:
1406
            return 1;
1407
        }
1408
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1409
        gen_op_iwmmxt_set_mup();
1410
        gen_op_iwmmxt_set_cup();
1411
        break;
1412
    case 0x800: case 0x900: case 0xc00: case 0xd00:        /* WAVG2 */
1413
        wrd = (insn >> 12) & 0xf;
1414
        rd0 = (insn >> 16) & 0xf;
1415
        rd1 = (insn >> 0) & 0xf;
1416
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1417
        if (insn & (1 << 22))
1418
            gen_op_iwmmxt_avgw_M0_wRn(rd1, (insn >> 20) & 1);
1419
        else
1420
            gen_op_iwmmxt_avgb_M0_wRn(rd1, (insn >> 20) & 1);
1421
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1422
        gen_op_iwmmxt_set_mup();
1423
        gen_op_iwmmxt_set_cup();
1424
        break;
1425
    case 0x802: case 0x902: case 0xa02: case 0xb02:        /* WALIGNR */
1426
        wrd = (insn >> 12) & 0xf;
1427
        rd0 = (insn >> 16) & 0xf;
1428
        rd1 = (insn >> 0) & 0xf;
1429
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1430
        gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1431
        gen_op_movl_T1_im(7);
1432
        gen_op_andl_T0_T1();
1433
        gen_op_iwmmxt_align_M0_T0_wRn(rd1);
1434
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1435
        gen_op_iwmmxt_set_mup();
1436
        break;
1437
    case 0x601: case 0x605: case 0x609: case 0x60d:        /* TINSR */
1438
        rd = (insn >> 12) & 0xf;
1439
        wrd = (insn >> 16) & 0xf;
1440
        gen_movl_T0_reg(s, rd);
1441
        gen_op_iwmmxt_movq_M0_wRn(wrd);
1442
        switch ((insn >> 6) & 3) {
1443
        case 0:
1444
            gen_op_movl_T1_im(0xff);
1445
            gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
1446
            break;
1447
        case 1:
1448
            gen_op_movl_T1_im(0xffff);
1449
            gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
1450
            break;
1451
        case 2:
1452
            gen_op_movl_T1_im(0xffffffff);
1453
            gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
1454
            break;
1455
        case 3:
1456
            return 1;
1457
        }
1458
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1459
        gen_op_iwmmxt_set_mup();
1460
        break;
1461
    case 0x107: case 0x507: case 0x907: case 0xd07:        /* TEXTRM */
1462
        rd = (insn >> 12) & 0xf;
1463
        wrd = (insn >> 16) & 0xf;
1464
        if (rd == 15)
1465
            return 1;
1466
        gen_op_iwmmxt_movq_M0_wRn(wrd);
1467
        switch ((insn >> 22) & 3) {
1468
        case 0:
1469
            if (insn & 8)
1470
                gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
1471
            else {
1472
                gen_op_movl_T1_im(0xff);
1473
                gen_op_iwmmxt_extru_T0_M0_T1((insn & 7) << 3);
1474
            }
1475
            break;
1476
        case 1:
1477
            if (insn & 8)
1478
                gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
1479
            else {
1480
                gen_op_movl_T1_im(0xffff);
1481
                gen_op_iwmmxt_extru_T0_M0_T1((insn & 3) << 4);
1482
            }
1483
            break;
1484
        case 2:
1485
            gen_op_movl_T1_im(0xffffffff);
1486
            gen_op_iwmmxt_extru_T0_M0_T1((insn & 1) << 5);
1487
            break;
1488
        case 3:
1489
            return 1;
1490
        }
1491
        gen_movl_reg_T0(s, rd);
1492
        break;
1493
    case 0x117: case 0x517: case 0x917: case 0xd17:        /* TEXTRC */
1494
        if ((insn & 0x000ff008) != 0x0003f000)
1495
            return 1;
1496
        gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1497
        switch ((insn >> 22) & 3) {
1498
        case 0:
1499
            gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
1500
            break;
1501
        case 1:
1502
            gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
1503
            break;
1504
        case 2:
1505
            gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
1506
            break;
1507
        case 3:
1508
            return 1;
1509
        }
1510
        gen_op_shll_T1_im(28);
1511
        gen_set_nzcv(cpu_T[1]);
1512
        break;
1513
    case 0x401: case 0x405: case 0x409: case 0x40d:        /* TBCST */
1514
        rd = (insn >> 12) & 0xf;
1515
        wrd = (insn >> 16) & 0xf;
1516
        gen_movl_T0_reg(s, rd);
1517
        switch ((insn >> 6) & 3) {
1518
        case 0:
1519
            gen_op_iwmmxt_bcstb_M0_T0();
1520
            break;
1521
        case 1:
1522
            gen_op_iwmmxt_bcstw_M0_T0();
1523
            break;
1524
        case 2:
1525
            gen_op_iwmmxt_bcstl_M0_T0();
1526
            break;
1527
        case 3:
1528
            return 1;
1529
        }
1530
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1531
        gen_op_iwmmxt_set_mup();
1532
        break;
1533
    case 0x113: case 0x513: case 0x913: case 0xd13:        /* TANDC */
1534
        if ((insn & 0x000ff00f) != 0x0003f000)
1535
            return 1;
1536
        gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1537
        switch ((insn >> 22) & 3) {
1538
        case 0:
1539
            for (i = 0; i < 7; i ++) {
1540
                gen_op_shll_T1_im(4);
1541
                gen_op_andl_T0_T1();
1542
            }
1543
            break;
1544
        case 1:
1545
            for (i = 0; i < 3; i ++) {
1546
                gen_op_shll_T1_im(8);
1547
                gen_op_andl_T0_T1();
1548
            }
1549
            break;
1550
        case 2:
1551
            gen_op_shll_T1_im(16);
1552
            gen_op_andl_T0_T1();
1553
            break;
1554
        case 3:
1555
            return 1;
1556
        }
1557
        gen_set_nzcv(cpu_T[0]);
1558
        break;
1559
    case 0x01c: case 0x41c: case 0x81c: case 0xc1c:        /* WACC */
1560
        wrd = (insn >> 12) & 0xf;
1561
        rd0 = (insn >> 16) & 0xf;
1562
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1563
        switch ((insn >> 22) & 3) {
1564
        case 0:
1565
            gen_op_iwmmxt_addcb_M0();
1566
            break;
1567
        case 1:
1568
            gen_op_iwmmxt_addcw_M0();
1569
            break;
1570
        case 2:
1571
            gen_op_iwmmxt_addcl_M0();
1572
            break;
1573
        case 3:
1574
            return 1;
1575
        }
1576
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1577
        gen_op_iwmmxt_set_mup();
1578
        break;
1579
    case 0x115: case 0x515: case 0x915: case 0xd15:        /* TORC */
1580
        if ((insn & 0x000ff00f) != 0x0003f000)
1581
            return 1;
1582
        gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
1583
        switch ((insn >> 22) & 3) {
1584
        case 0:
1585
            for (i = 0; i < 7; i ++) {
1586
                gen_op_shll_T1_im(4);
1587
                gen_op_orl_T0_T1();
1588
            }
1589
            break;
1590
        case 1:
1591
            for (i = 0; i < 3; i ++) {
1592
                gen_op_shll_T1_im(8);
1593
                gen_op_orl_T0_T1();
1594
            }
1595
            break;
1596
        case 2:
1597
            gen_op_shll_T1_im(16);
1598
            gen_op_orl_T0_T1();
1599
            break;
1600
        case 3:
1601
            return 1;
1602
        }
1603
        gen_set_nzcv(cpu_T[0]);
1604
        break;
1605
    case 0x103: case 0x503: case 0x903: case 0xd03:        /* TMOVMSK */
1606
        rd = (insn >> 12) & 0xf;
1607
        rd0 = (insn >> 16) & 0xf;
1608
        if ((insn & 0xf) != 0)
1609
            return 1;
1610
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1611
        switch ((insn >> 22) & 3) {
1612
        case 0:
1613
            gen_op_iwmmxt_msbb_T0_M0();
1614
            break;
1615
        case 1:
1616
            gen_op_iwmmxt_msbw_T0_M0();
1617
            break;
1618
        case 2:
1619
            gen_op_iwmmxt_msbl_T0_M0();
1620
            break;
1621
        case 3:
1622
            return 1;
1623
        }
1624
        gen_movl_reg_T0(s, rd);
1625
        break;
1626
    case 0x106: case 0x306: case 0x506: case 0x706:        /* WCMPGT */
1627
    case 0x906: case 0xb06: case 0xd06: case 0xf06:
1628
        wrd = (insn >> 12) & 0xf;
1629
        rd0 = (insn >> 16) & 0xf;
1630
        rd1 = (insn >> 0) & 0xf;
1631
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1632
        switch ((insn >> 22) & 3) {
1633
        case 0:
1634
            if (insn & (1 << 21))
1635
                gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1636
            else
1637
                gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1638
            break;
1639
        case 1:
1640
            if (insn & (1 << 21))
1641
                gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1642
            else
1643
                gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
1644
            break;
1645
        case 2:
1646
            if (insn & (1 << 21))
1647
                gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
1648
            else
1649
                gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
1650
            break;
1651
        case 3:
1652
            return 1;
1653
        }
1654
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1655
        gen_op_iwmmxt_set_mup();
1656
        gen_op_iwmmxt_set_cup();
1657
        break;
1658
    case 0x00e: case 0x20e: case 0x40e: case 0x60e:        /* WUNPCKEL */
1659
    case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1660
        wrd = (insn >> 12) & 0xf;
1661
        rd0 = (insn >> 16) & 0xf;
1662
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1663
        switch ((insn >> 22) & 3) {
1664
        case 0:
1665
            if (insn & (1 << 21))
1666
                gen_op_iwmmxt_unpacklsb_M0();
1667
            else
1668
                gen_op_iwmmxt_unpacklub_M0();
1669
            break;
1670
        case 1:
1671
            if (insn & (1 << 21))
1672
                gen_op_iwmmxt_unpacklsw_M0();
1673
            else
1674
                gen_op_iwmmxt_unpackluw_M0();
1675
            break;
1676
        case 2:
1677
            if (insn & (1 << 21))
1678
                gen_op_iwmmxt_unpacklsl_M0();
1679
            else
1680
                gen_op_iwmmxt_unpacklul_M0();
1681
            break;
1682
        case 3:
1683
            return 1;
1684
        }
1685
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1686
        gen_op_iwmmxt_set_mup();
1687
        gen_op_iwmmxt_set_cup();
1688
        break;
1689
    case 0x00c: case 0x20c: case 0x40c: case 0x60c:        /* WUNPCKEH */
1690
    case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1691
        wrd = (insn >> 12) & 0xf;
1692
        rd0 = (insn >> 16) & 0xf;
1693
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1694
        switch ((insn >> 22) & 3) {
1695
        case 0:
1696
            if (insn & (1 << 21))
1697
                gen_op_iwmmxt_unpackhsb_M0();
1698
            else
1699
                gen_op_iwmmxt_unpackhub_M0();
1700
            break;
1701
        case 1:
1702
            if (insn & (1 << 21))
1703
                gen_op_iwmmxt_unpackhsw_M0();
1704
            else
1705
                gen_op_iwmmxt_unpackhuw_M0();
1706
            break;
1707
        case 2:
1708
            if (insn & (1 << 21))
1709
                gen_op_iwmmxt_unpackhsl_M0();
1710
            else
1711
                gen_op_iwmmxt_unpackhul_M0();
1712
            break;
1713
        case 3:
1714
            return 1;
1715
        }
1716
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1717
        gen_op_iwmmxt_set_mup();
1718
        gen_op_iwmmxt_set_cup();
1719
        break;
1720
    case 0x204: case 0x604: case 0xa04: case 0xe04:        /* WSRL */
1721
    case 0x214: case 0x614: case 0xa14: case 0xe14:
1722
        wrd = (insn >> 12) & 0xf;
1723
        rd0 = (insn >> 16) & 0xf;
1724
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1725
        if (gen_iwmmxt_shift(insn, 0xff))
1726
            return 1;
1727
        switch ((insn >> 22) & 3) {
1728
        case 0:
1729
            return 1;
1730
        case 1:
1731
            gen_op_iwmmxt_srlw_M0_T0();
1732
            break;
1733
        case 2:
1734
            gen_op_iwmmxt_srll_M0_T0();
1735
            break;
1736
        case 3:
1737
            gen_op_iwmmxt_srlq_M0_T0();
1738
            break;
1739
        }
1740
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1741
        gen_op_iwmmxt_set_mup();
1742
        gen_op_iwmmxt_set_cup();
1743
        break;
1744
    case 0x004: case 0x404: case 0x804: case 0xc04:        /* WSRA */
1745
    case 0x014: case 0x414: case 0x814: case 0xc14:
1746
        wrd = (insn >> 12) & 0xf;
1747
        rd0 = (insn >> 16) & 0xf;
1748
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1749
        if (gen_iwmmxt_shift(insn, 0xff))
1750
            return 1;
1751
        switch ((insn >> 22) & 3) {
1752
        case 0:
1753
            return 1;
1754
        case 1:
1755
            gen_op_iwmmxt_sraw_M0_T0();
1756
            break;
1757
        case 2:
1758
            gen_op_iwmmxt_sral_M0_T0();
1759
            break;
1760
        case 3:
1761
            gen_op_iwmmxt_sraq_M0_T0();
1762
            break;
1763
        }
1764
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1765
        gen_op_iwmmxt_set_mup();
1766
        gen_op_iwmmxt_set_cup();
1767
        break;
1768
    case 0x104: case 0x504: case 0x904: case 0xd04:        /* WSLL */
1769
    case 0x114: case 0x514: case 0x914: case 0xd14:
1770
        wrd = (insn >> 12) & 0xf;
1771
        rd0 = (insn >> 16) & 0xf;
1772
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1773
        if (gen_iwmmxt_shift(insn, 0xff))
1774
            return 1;
1775
        switch ((insn >> 22) & 3) {
1776
        case 0:
1777
            return 1;
1778
        case 1:
1779
            gen_op_iwmmxt_sllw_M0_T0();
1780
            break;
1781
        case 2:
1782
            gen_op_iwmmxt_slll_M0_T0();
1783
            break;
1784
        case 3:
1785
            gen_op_iwmmxt_sllq_M0_T0();
1786
            break;
1787
        }
1788
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1789
        gen_op_iwmmxt_set_mup();
1790
        gen_op_iwmmxt_set_cup();
1791
        break;
1792
    case 0x304: case 0x704: case 0xb04: case 0xf04:        /* WROR */
1793
    case 0x314: case 0x714: case 0xb14: case 0xf14:
1794
        wrd = (insn >> 12) & 0xf;
1795
        rd0 = (insn >> 16) & 0xf;
1796
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1797
        switch ((insn >> 22) & 3) {
1798
        case 0:
1799
            return 1;
1800
        case 1:
1801
            if (gen_iwmmxt_shift(insn, 0xf))
1802
                return 1;
1803
            gen_op_iwmmxt_rorw_M0_T0();
1804
            break;
1805
        case 2:
1806
            if (gen_iwmmxt_shift(insn, 0x1f))
1807
                return 1;
1808
            gen_op_iwmmxt_rorl_M0_T0();
1809
            break;
1810
        case 3:
1811
            if (gen_iwmmxt_shift(insn, 0x3f))
1812
                return 1;
1813
            gen_op_iwmmxt_rorq_M0_T0();
1814
            break;
1815
        }
1816
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1817
        gen_op_iwmmxt_set_mup();
1818
        gen_op_iwmmxt_set_cup();
1819
        break;
1820
    case 0x116: case 0x316: case 0x516: case 0x716:        /* WMIN */
1821
    case 0x916: case 0xb16: case 0xd16: case 0xf16:
1822
        wrd = (insn >> 12) & 0xf;
1823
        rd0 = (insn >> 16) & 0xf;
1824
        rd1 = (insn >> 0) & 0xf;
1825
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1826
        switch ((insn >> 22) & 3) {
1827
        case 0:
1828
            if (insn & (1 << 21))
1829
                gen_op_iwmmxt_minsb_M0_wRn(rd1);
1830
            else
1831
                gen_op_iwmmxt_minub_M0_wRn(rd1);
1832
            break;
1833
        case 1:
1834
            if (insn & (1 << 21))
1835
                gen_op_iwmmxt_minsw_M0_wRn(rd1);
1836
            else
1837
                gen_op_iwmmxt_minuw_M0_wRn(rd1);
1838
            break;
1839
        case 2:
1840
            if (insn & (1 << 21))
1841
                gen_op_iwmmxt_minsl_M0_wRn(rd1);
1842
            else
1843
                gen_op_iwmmxt_minul_M0_wRn(rd1);
1844
            break;
1845
        case 3:
1846
            return 1;
1847
        }
1848
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1849
        gen_op_iwmmxt_set_mup();
1850
        break;
1851
    case 0x016: case 0x216: case 0x416: case 0x616:        /* WMAX */
1852
    case 0x816: case 0xa16: case 0xc16: case 0xe16:
1853
        wrd = (insn >> 12) & 0xf;
1854
        rd0 = (insn >> 16) & 0xf;
1855
        rd1 = (insn >> 0) & 0xf;
1856
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1857
        switch ((insn >> 22) & 3) {
1858
        case 0:
1859
            if (insn & (1 << 21))
1860
                gen_op_iwmmxt_maxsb_M0_wRn(rd1);
1861
            else
1862
                gen_op_iwmmxt_maxub_M0_wRn(rd1);
1863
            break;
1864
        case 1:
1865
            if (insn & (1 << 21))
1866
                gen_op_iwmmxt_maxsw_M0_wRn(rd1);
1867
            else
1868
                gen_op_iwmmxt_maxuw_M0_wRn(rd1);
1869
            break;
1870
        case 2:
1871
            if (insn & (1 << 21))
1872
                gen_op_iwmmxt_maxsl_M0_wRn(rd1);
1873
            else
1874
                gen_op_iwmmxt_maxul_M0_wRn(rd1);
1875
            break;
1876
        case 3:
1877
            return 1;
1878
        }
1879
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1880
        gen_op_iwmmxt_set_mup();
1881
        break;
1882
    case 0x002: case 0x102: case 0x202: case 0x302:        /* WALIGNI */
1883
    case 0x402: case 0x502: case 0x602: case 0x702:
1884
        wrd = (insn >> 12) & 0xf;
1885
        rd0 = (insn >> 16) & 0xf;
1886
        rd1 = (insn >> 0) & 0xf;
1887
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1888
        gen_op_movl_T0_im((insn >> 20) & 3);
1889
        gen_op_iwmmxt_align_M0_T0_wRn(rd1);
1890
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1891
        gen_op_iwmmxt_set_mup();
1892
        break;
1893
    case 0x01a: case 0x11a: case 0x21a: case 0x31a:        /* WSUB */
1894
    case 0x41a: case 0x51a: case 0x61a: case 0x71a:
1895
    case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
1896
    case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
1897
        wrd = (insn >> 12) & 0xf;
1898
        rd0 = (insn >> 16) & 0xf;
1899
        rd1 = (insn >> 0) & 0xf;
1900
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1901
        switch ((insn >> 20) & 0xf) {
1902
        case 0x0:
1903
            gen_op_iwmmxt_subnb_M0_wRn(rd1);
1904
            break;
1905
        case 0x1:
1906
            gen_op_iwmmxt_subub_M0_wRn(rd1);
1907
            break;
1908
        case 0x3:
1909
            gen_op_iwmmxt_subsb_M0_wRn(rd1);
1910
            break;
1911
        case 0x4:
1912
            gen_op_iwmmxt_subnw_M0_wRn(rd1);
1913
            break;
1914
        case 0x5:
1915
            gen_op_iwmmxt_subuw_M0_wRn(rd1);
1916
            break;
1917
        case 0x7:
1918
            gen_op_iwmmxt_subsw_M0_wRn(rd1);
1919
            break;
1920
        case 0x8:
1921
            gen_op_iwmmxt_subnl_M0_wRn(rd1);
1922
            break;
1923
        case 0x9:
1924
            gen_op_iwmmxt_subul_M0_wRn(rd1);
1925
            break;
1926
        case 0xb:
1927
            gen_op_iwmmxt_subsl_M0_wRn(rd1);
1928
            break;
1929
        default:
1930
            return 1;
1931
        }
1932
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1933
        gen_op_iwmmxt_set_mup();
1934
        gen_op_iwmmxt_set_cup();
1935
        break;
1936
    case 0x01e: case 0x11e: case 0x21e: case 0x31e:        /* WSHUFH */
1937
    case 0x41e: case 0x51e: case 0x61e: case 0x71e:
1938
    case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
1939
    case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
1940
        wrd = (insn >> 12) & 0xf;
1941
        rd0 = (insn >> 16) & 0xf;
1942
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1943
        gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
1944
        gen_op_iwmmxt_shufh_M0_T0();
1945
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1946
        gen_op_iwmmxt_set_mup();
1947
        gen_op_iwmmxt_set_cup();
1948
        break;
1949
    case 0x018: case 0x118: case 0x218: case 0x318:        /* WADD */
1950
    case 0x418: case 0x518: case 0x618: case 0x718:
1951
    case 0x818: case 0x918: case 0xa18: case 0xb18:
1952
    case 0xc18: case 0xd18: case 0xe18: case 0xf18:
1953
        wrd = (insn >> 12) & 0xf;
1954
        rd0 = (insn >> 16) & 0xf;
1955
        rd1 = (insn >> 0) & 0xf;
1956
        gen_op_iwmmxt_movq_M0_wRn(rd0);
1957
        switch ((insn >> 20) & 0xf) {
1958
        case 0x0:
1959
            gen_op_iwmmxt_addnb_M0_wRn(rd1);
1960
            break;
1961
        case 0x1:
1962
            gen_op_iwmmxt_addub_M0_wRn(rd1);
1963
            break;
1964
        case 0x3:
1965
            gen_op_iwmmxt_addsb_M0_wRn(rd1);
1966
            break;
1967
        case 0x4:
1968
            gen_op_iwmmxt_addnw_M0_wRn(rd1);
1969
            break;
1970
        case 0x5:
1971
            gen_op_iwmmxt_adduw_M0_wRn(rd1);
1972
            break;
1973
        case 0x7:
1974
            gen_op_iwmmxt_addsw_M0_wRn(rd1);
1975
            break;
1976
        case 0x8:
1977
            gen_op_iwmmxt_addnl_M0_wRn(rd1);
1978
            break;
1979
        case 0x9:
1980
            gen_op_iwmmxt_addul_M0_wRn(rd1);
1981
            break;
1982
        case 0xb:
1983
            gen_op_iwmmxt_addsl_M0_wRn(rd1);
1984
            break;
1985
        default:
1986
            return 1;
1987
        }
1988
        gen_op_iwmmxt_movq_wRn_M0(wrd);
1989
        gen_op_iwmmxt_set_mup();
1990
        gen_op_iwmmxt_set_cup();
1991
        break;
1992
    case 0x008: case 0x108: case 0x208: case 0x308:        /* WPACK */
1993
    case 0x408: case 0x508: case 0x608: case 0x708:
1994
    case 0x808: case 0x908: case 0xa08: case 0xb08:
1995
    case 0xc08: case 0xd08: case 0xe08: case 0xf08:
1996
        wrd = (insn >> 12) & 0xf;
1997
        rd0 = (insn >> 16) & 0xf;
1998
        rd1 = (insn >> 0) & 0xf;
1999
        gen_op_iwmmxt_movq_M0_wRn(rd0);
2000
        if (!(insn & (1 << 20)))
2001
            return 1;
2002
        switch ((insn >> 22) & 3) {
2003
        case 0:
2004
            return 1;
2005
        case 1:
2006
            if (insn & (1 << 21))
2007
                gen_op_iwmmxt_packsw_M0_wRn(rd1);
2008
            else
2009
                gen_op_iwmmxt_packuw_M0_wRn(rd1);
2010
            break;
2011
        case 2:
2012
            if (insn & (1 << 21))
2013
                gen_op_iwmmxt_packsl_M0_wRn(rd1);
2014
            else
2015
                gen_op_iwmmxt_packul_M0_wRn(rd1);
2016
            break;
2017
        case 3:
2018
            if (insn & (1 << 21))
2019
                gen_op_iwmmxt_packsq_M0_wRn(rd1);
2020
            else
2021
                gen_op_iwmmxt_packuq_M0_wRn(rd1);
2022
            break;
2023
        }
2024
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2025
        gen_op_iwmmxt_set_mup();
2026
        gen_op_iwmmxt_set_cup();
2027
        break;
2028
    case 0x201: case 0x203: case 0x205: case 0x207:
2029
    case 0x209: case 0x20b: case 0x20d: case 0x20f:
2030
    case 0x211: case 0x213: case 0x215: case 0x217:
2031
    case 0x219: case 0x21b: case 0x21d: case 0x21f:
2032
        wrd = (insn >> 5) & 0xf;
2033
        rd0 = (insn >> 12) & 0xf;
2034
        rd1 = (insn >> 0) & 0xf;
2035
        if (rd0 == 0xf || rd1 == 0xf)
2036
            return 1;
2037
        gen_op_iwmmxt_movq_M0_wRn(wrd);
2038
        switch ((insn >> 16) & 0xf) {
2039
        case 0x0:                                        /* TMIA */
2040
            gen_movl_T0_reg(s, rd0);
2041
            gen_movl_T1_reg(s, rd1);
2042
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2043
            break;
2044
        case 0x8:                                        /* TMIAPH */
2045
            gen_movl_T0_reg(s, rd0);
2046
            gen_movl_T1_reg(s, rd1);
2047
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2048
            break;
2049
        case 0xc: case 0xd: case 0xe: case 0xf:                /* TMIAxy */
2050
            gen_movl_T1_reg(s, rd0);
2051
            if (insn & (1 << 16))
2052
                gen_op_shrl_T1_im(16);
2053
            gen_op_movl_T0_T1();
2054
            gen_movl_T1_reg(s, rd1);
2055
            if (insn & (1 << 17))
2056
                gen_op_shrl_T1_im(16);
2057
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2058
            break;
2059
        default:
2060
            return 1;
2061
        }
2062
        gen_op_iwmmxt_movq_wRn_M0(wrd);
2063
        gen_op_iwmmxt_set_mup();
2064
        break;
2065
    default:
2066
        return 1;
2067
    }
2068

    
2069
    return 0;
2070
}
2071

    
2072
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2073
   (ie. an undefined instruction).  */
2074
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2075
{
2076
    int acc, rd0, rd1, rdhi, rdlo;
2077

    
2078
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2079
        /* Multiply with Internal Accumulate Format */
2080
        rd0 = (insn >> 12) & 0xf;
2081
        rd1 = insn & 0xf;
2082
        acc = (insn >> 5) & 7;
2083

    
2084
        if (acc != 0)
2085
            return 1;
2086

    
2087
        switch ((insn >> 16) & 0xf) {
2088
        case 0x0:                                        /* MIA */
2089
            gen_movl_T0_reg(s, rd0);
2090
            gen_movl_T1_reg(s, rd1);
2091
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2092
            break;
2093
        case 0x8:                                        /* MIAPH */
2094
            gen_movl_T0_reg(s, rd0);
2095
            gen_movl_T1_reg(s, rd1);
2096
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2097
            break;
2098
        case 0xc:                                        /* MIABB */
2099
        case 0xd:                                        /* MIABT */
2100
        case 0xe:                                        /* MIATB */
2101
        case 0xf:                                        /* MIATT */
2102
            gen_movl_T1_reg(s, rd0);
2103
            if (insn & (1 << 16))
2104
                gen_op_shrl_T1_im(16);
2105
            gen_op_movl_T0_T1();
2106
            gen_movl_T1_reg(s, rd1);
2107
            if (insn & (1 << 17))
2108
                gen_op_shrl_T1_im(16);
2109
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2110
            break;
2111
        default:
2112
            return 1;
2113
        }
2114

    
2115
        gen_op_iwmmxt_movq_wRn_M0(acc);
2116
        return 0;
2117
    }
2118

    
2119
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2120
        /* Internal Accumulator Access Format */
2121
        rdhi = (insn >> 16) & 0xf;
2122
        rdlo = (insn >> 12) & 0xf;
2123
        acc = insn & 7;
2124

    
2125
        if (acc != 0)
2126
            return 1;
2127

    
2128
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2129
            gen_op_iwmmxt_movl_T0_T1_wRn(acc);
2130
            gen_movl_reg_T0(s, rdlo);
2131
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2132
            gen_op_andl_T0_T1();
2133
            gen_movl_reg_T0(s, rdhi);
2134
        } else {                                        /* MAR */
2135
            gen_movl_T0_reg(s, rdlo);
2136
            gen_movl_T1_reg(s, rdhi);
2137
            gen_op_iwmmxt_movl_wRn_T0_T1(acc);
2138
        }
2139
        return 0;
2140
    }
2141

    
2142
    return 1;
2143
}
2144

    
2145
/* Disassemble system coprocessor instruction.  Return nonzero if
2146
   instruction is not defined.  */
2147
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2148
{
2149
    uint32_t rd = (insn >> 12) & 0xf;
2150
    uint32_t cp = (insn >> 8) & 0xf;
2151
    if (IS_USER(s)) {
2152
        return 1;
2153
    }
2154

    
2155
    if (insn & ARM_CP_RW_BIT) {
2156
        if (!env->cp[cp].cp_read)
2157
            return 1;
2158
        gen_op_movl_T0_im((uint32_t) s->pc);
2159
        gen_set_pc_T0();
2160
        gen_op_movl_T0_cp(insn);
2161
        gen_movl_reg_T0(s, rd);
2162
    } else {
2163
        if (!env->cp[cp].cp_write)
2164
            return 1;
2165
        gen_op_movl_T0_im((uint32_t) s->pc);
2166
        gen_set_pc_T0();
2167
        gen_movl_T0_reg(s, rd);
2168
        gen_op_movl_cp_T0(insn);
2169
    }
2170
    return 0;
2171
}
2172

    
2173
static int cp15_user_ok(uint32_t insn)
2174
{
2175
    int cpn = (insn >> 16) & 0xf;
2176
    int cpm = insn & 0xf;
2177
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2178

    
2179
    if (cpn == 13 && cpm == 0) {
2180
        /* TLS register.  */
2181
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2182
            return 1;
2183
    }
2184
    if (cpn == 7) {
2185
        /* ISB, DSB, DMB.  */
2186
        if ((cpm == 5 && op == 4)
2187
                || (cpm == 10 && (op == 4 || op == 5)))
2188
            return 1;
2189
    }
2190
    return 0;
2191
}
2192

    
2193
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2194
   instruction is not defined.  */
2195
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2196
{
2197
    uint32_t rd;
2198

    
2199
    /* M profile cores use memory mapped registers instead of cp15.  */
2200
    if (arm_feature(env, ARM_FEATURE_M))
2201
        return 1;
2202

    
2203
    if ((insn & (1 << 25)) == 0) {
2204
        if (insn & (1 << 20)) {
2205
            /* mrrc */
2206
            return 1;
2207
        }
2208
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2209
        return 0;
2210
    }
2211
    if ((insn & (1 << 4)) == 0) {
2212
        /* cdp */
2213
        return 1;
2214
    }
2215
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2216
        return 1;
2217
    }
2218
    if ((insn & 0x0fff0fff) == 0x0e070f90
2219
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2220
        /* Wait for interrupt.  */
2221
        gen_op_movl_T0_im((long)s->pc);
2222
        gen_set_pc_T0();
2223
        s->is_jmp = DISAS_WFI;
2224
        return 0;
2225
    }
2226
    rd = (insn >> 12) & 0xf;
2227
    if (insn & ARM_CP_RW_BIT) {
2228
        gen_op_movl_T0_cp15(insn);
2229
        /* If the destination register is r15 then sets condition codes.  */
2230
        if (rd != 15)
2231
            gen_movl_reg_T0(s, rd);
2232
    } else {
2233
        gen_movl_T0_reg(s, rd);
2234
        gen_op_movl_cp15_T0(insn);
2235
        /* Normally we would always end the TB here, but Linux
2236
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2237
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2238
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2239
                (insn & 0x0fff0fff) != 0x0e010f10)
2240
            gen_lookup_tb(s);
2241
    }
2242
    return 0;
2243
}
2244

    
2245
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2246
#define VFP_SREG(insn, bigbit, smallbit) \
2247
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2248
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2249
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2250
        reg = (((insn) >> (bigbit)) & 0x0f) \
2251
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2252
    } else { \
2253
        if (insn & (1 << (smallbit))) \
2254
            return 1; \
2255
        reg = ((insn) >> (bigbit)) & 0x0f; \
2256
    }} while (0)
2257

    
2258
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2259
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2260
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2261
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2262
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2263
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2264

    
2265
static inline int
2266
vfp_enabled(CPUState * env)
2267
{
2268
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2269
}
2270

    
2271
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2272
   (ie. an undefined instruction).  */
2273
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2274
{
2275
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2276
    int dp, veclen;
2277

    
2278
    if (!arm_feature(env, ARM_FEATURE_VFP))
2279
        return 1;
2280

    
2281
    if (!vfp_enabled(env)) {
2282
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2283
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2284
            return 1;
2285
        rn = (insn >> 16) & 0xf;
2286
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2287
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2288
            return 1;
2289
    }
2290
    dp = ((insn & 0xf00) == 0xb00);
2291
    switch ((insn >> 24) & 0xf) {
2292
    case 0xe:
2293
        if (insn & (1 << 4)) {
2294
            /* single register transfer */
2295
            rd = (insn >> 12) & 0xf;
2296
            if (dp) {
2297
                int size;
2298
                int pass;
2299

    
2300
                VFP_DREG_N(rn, insn);
2301
                if (insn & 0xf)
2302
                    return 1;
2303
                if (insn & 0x00c00060
2304
                    && !arm_feature(env, ARM_FEATURE_NEON))
2305
                    return 1;
2306

    
2307
                pass = (insn >> 21) & 1;
2308
                if (insn & (1 << 22)) {
2309
                    size = 0;
2310
                    offset = ((insn >> 5) & 3) * 8;
2311
                } else if (insn & (1 << 5)) {
2312
                    size = 1;
2313
                    offset = (insn & (1 << 6)) ? 16 : 0;
2314
                } else {
2315
                    size = 2;
2316
                    offset = 0;
2317
                }
2318
                if (insn & ARM_CP_RW_BIT) {
2319
                    /* vfp->arm */
2320
                    switch (size) {
2321
                    case 0:
2322
                        NEON_GET_REG(T1, rn, pass);
2323
                        if (offset)
2324
                            gen_op_shrl_T1_im(offset);
2325
                        if (insn & (1 << 23))
2326
                            gen_uxtb(cpu_T[1]);
2327
                        else
2328
                            gen_sxtb(cpu_T[1]);
2329
                        break;
2330
                    case 1:
2331
                        NEON_GET_REG(T1, rn, pass);
2332
                        if (insn & (1 << 23)) {
2333
                            if (offset) {
2334
                                gen_op_shrl_T1_im(16);
2335
                            } else {
2336
                                gen_uxth(cpu_T[1]);
2337
                            }
2338
                        } else {
2339
                            if (offset) {
2340
                                gen_op_sarl_T1_im(16);
2341
                            } else {
2342
                                gen_sxth(cpu_T[1]);
2343
                            }
2344
                        }
2345
                        break;
2346
                    case 2:
2347
                        NEON_GET_REG(T1, rn, pass);
2348
                        break;
2349
                    }
2350
                    gen_movl_reg_T1(s, rd);
2351
                } else {
2352
                    /* arm->vfp */
2353
                    gen_movl_T0_reg(s, rd);
2354
                    if (insn & (1 << 23)) {
2355
                        /* VDUP */
2356
                        if (size == 0) {
2357
                            gen_op_neon_dup_u8(0);
2358
                        } else if (size == 1) {
2359
                            gen_op_neon_dup_low16();
2360
                        }
2361
                        NEON_SET_REG(T0, rn, 0);
2362
                        NEON_SET_REG(T0, rn, 1);
2363
                    } else {
2364
                        /* VMOV */
2365
                        switch (size) {
2366
                        case 0:
2367
                            NEON_GET_REG(T2, rn, pass);
2368
                            gen_op_movl_T1_im(0xff);
2369
                            gen_op_andl_T0_T1();
2370
                            gen_op_neon_insert_elt(offset, ~(0xff << offset));
2371
                            NEON_SET_REG(T2, rn, pass);
2372
                            break;
2373
                        case 1:
2374
                            NEON_GET_REG(T2, rn, pass);
2375
                            gen_op_movl_T1_im(0xffff);
2376
                            gen_op_andl_T0_T1();
2377
                            bank_mask = offset ? 0xffff : 0xffff0000;
2378
                            gen_op_neon_insert_elt(offset, bank_mask);
2379
                            NEON_SET_REG(T2, rn, pass);
2380
                            break;
2381
                        case 2:
2382
                            NEON_SET_REG(T0, rn, pass);
2383
                            break;
2384
                        }
2385
                    }
2386
                }
2387
            } else { /* !dp */
2388
                if ((insn & 0x6f) != 0x00)
2389
                    return 1;
2390
                rn = VFP_SREG_N(insn);
2391
                if (insn & ARM_CP_RW_BIT) {
2392
                    /* vfp->arm */
2393
                    if (insn & (1 << 21)) {
2394
                        /* system register */
2395
                        rn >>= 1;
2396

    
2397
                        switch (rn) {
2398
                        case ARM_VFP_FPSID:
2399
                            /* VFP2 allows access for FSID from userspace.
2400
                               VFP3 restricts all id registers to privileged
2401
                               accesses.  */
2402
                            if (IS_USER(s)
2403
                                && arm_feature(env, ARM_FEATURE_VFP3))
2404
                                return 1;
2405
                            gen_op_vfp_movl_T0_xreg(rn);
2406
                            break;
2407
                        case ARM_VFP_FPEXC:
2408
                            if (IS_USER(s))
2409
                                return 1;
2410
                            gen_op_vfp_movl_T0_xreg(rn);
2411
                            break;
2412
                        case ARM_VFP_FPINST:
2413
                        case ARM_VFP_FPINST2:
2414
                            /* Not present in VFP3.  */
2415
                            if (IS_USER(s)
2416
                                || arm_feature(env, ARM_FEATURE_VFP3))
2417
                                return 1;
2418
                            gen_op_vfp_movl_T0_xreg(rn);
2419
                            break;
2420
                        case ARM_VFP_FPSCR:
2421
                            if (rd == 15)
2422
                                gen_op_vfp_movl_T0_fpscr_flags();
2423
                            else
2424
                                gen_op_vfp_movl_T0_fpscr();
2425
                            break;
2426
                        case ARM_VFP_MVFR0:
2427
                        case ARM_VFP_MVFR1:
2428
                            if (IS_USER(s)
2429
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2430
                                return 1;
2431
                            gen_op_vfp_movl_T0_xreg(rn);
2432
                            break;
2433
                        default:
2434
                            return 1;
2435
                        }
2436
                    } else {
2437
                        gen_mov_F0_vreg(0, rn);
2438
                        gen_op_vfp_mrs();
2439
                    }
2440
                    if (rd == 15) {
2441
                        /* Set the 4 flag bits in the CPSR.  */
2442
                        gen_set_nzcv(cpu_T[0]);
2443
                    } else
2444
                        gen_movl_reg_T0(s, rd);
2445
                } else {
2446
                    /* arm->vfp */
2447
                    gen_movl_T0_reg(s, rd);
2448
                    if (insn & (1 << 21)) {
2449
                        rn >>= 1;
2450
                        /* system register */
2451
                        switch (rn) {
2452
                        case ARM_VFP_FPSID:
2453
                        case ARM_VFP_MVFR0:
2454
                        case ARM_VFP_MVFR1:
2455
                            /* Writes are ignored.  */
2456
                            break;
2457
                        case ARM_VFP_FPSCR:
2458
                            gen_op_vfp_movl_fpscr_T0();
2459
                            gen_lookup_tb(s);
2460
                            break;
2461
                        case ARM_VFP_FPEXC:
2462
                            if (IS_USER(s))
2463
                                return 1;
2464
                            gen_op_vfp_movl_xreg_T0(rn);
2465
                            gen_lookup_tb(s);
2466
                            break;
2467
                        case ARM_VFP_FPINST:
2468
                        case ARM_VFP_FPINST2:
2469
                            gen_op_vfp_movl_xreg_T0(rn);
2470
                            break;
2471
                        default:
2472
                            return 1;
2473
                        }
2474
                    } else {
2475
                        gen_op_vfp_msr();
2476
                        gen_mov_vreg_F0(0, rn);
2477
                    }
2478
                }
2479
            }
2480
        } else {
2481
            /* data processing */
2482
            /* The opcode is in bits 23, 21, 20 and 6.  */
2483
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2484
            if (dp) {
2485
                if (op == 15) {
2486
                    /* rn is opcode */
2487
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2488
                } else {
2489
                    /* rn is register number */
2490
                    VFP_DREG_N(rn, insn);
2491
                }
2492

    
2493
                if (op == 15 && (rn == 15 || rn > 17)) {
2494
                    /* Integer or single precision destination.  */
2495
                    rd = VFP_SREG_D(insn);
2496
                } else {
2497
                    VFP_DREG_D(rd, insn);
2498
                }
2499

    
2500
                if (op == 15 && (rn == 16 || rn == 17)) {
2501
                    /* Integer source.  */
2502
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2503
                } else {
2504
                    VFP_DREG_M(rm, insn);
2505
                }
2506
            } else {
2507
                rn = VFP_SREG_N(insn);
2508
                if (op == 15 && rn == 15) {
2509
                    /* Double precision destination.  */
2510
                    VFP_DREG_D(rd, insn);
2511
                } else {
2512
                    rd = VFP_SREG_D(insn);
2513
                }
2514
                rm = VFP_SREG_M(insn);
2515
            }
2516

    
2517
            veclen = env->vfp.vec_len;
2518
            if (op == 15 && rn > 3)
2519
                veclen = 0;
2520

    
2521
            /* Shut up compiler warnings.  */
2522
            delta_m = 0;
2523
            delta_d = 0;
2524
            bank_mask = 0;
2525

    
2526
            if (veclen > 0) {
2527
                if (dp)
2528
                    bank_mask = 0xc;
2529
                else
2530
                    bank_mask = 0x18;
2531

    
2532
                /* Figure out what type of vector operation this is.  */
2533
                if ((rd & bank_mask) == 0) {
2534
                    /* scalar */
2535
                    veclen = 0;
2536
                } else {
2537
                    if (dp)
2538
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2539
                    else
2540
                        delta_d = env->vfp.vec_stride + 1;
2541

    
2542
                    if ((rm & bank_mask) == 0) {
2543
                        /* mixed scalar/vector */
2544
                        delta_m = 0;
2545
                    } else {
2546
                        /* vector */
2547
                        delta_m = delta_d;
2548
                    }
2549
                }
2550
            }
2551

    
2552
            /* Load the initial operands.  */
2553
            if (op == 15) {
2554
                switch (rn) {
2555
                case 16:
2556
                case 17:
2557
                    /* Integer source */
2558
                    gen_mov_F0_vreg(0, rm);
2559
                    break;
2560
                case 8:
2561
                case 9:
2562
                    /* Compare */
2563
                    gen_mov_F0_vreg(dp, rd);
2564
                    gen_mov_F1_vreg(dp, rm);
2565
                    break;
2566
                case 10:
2567
                case 11:
2568
                    /* Compare with zero */
2569
                    gen_mov_F0_vreg(dp, rd);
2570
                    gen_vfp_F1_ld0(dp);
2571
                    break;
2572
                case 20:
2573
                case 21:
2574
                case 22:
2575
                case 23:
2576
                    /* Source and destination the same.  */
2577
                    gen_mov_F0_vreg(dp, rd);
2578
                    break;
2579
                default:
2580
                    /* One source operand.  */
2581
                    gen_mov_F0_vreg(dp, rm);
2582
                    break;
2583
                }
2584
            } else {
2585
                /* Two source operands.  */
2586
                gen_mov_F0_vreg(dp, rn);
2587
                gen_mov_F1_vreg(dp, rm);
2588
            }
2589

    
2590
            for (;;) {
2591
                /* Perform the calculation.  */
2592
                switch (op) {
2593
                case 0: /* mac: fd + (fn * fm) */
2594
                    gen_vfp_mul(dp);
2595
                    gen_mov_F1_vreg(dp, rd);
2596
                    gen_vfp_add(dp);
2597
                    break;
2598
                case 1: /* nmac: fd - (fn * fm) */
2599
                    gen_vfp_mul(dp);
2600
                    gen_vfp_neg(dp);
2601
                    gen_mov_F1_vreg(dp, rd);
2602
                    gen_vfp_add(dp);
2603
                    break;
2604
                case 2: /* msc: -fd + (fn * fm) */
2605
                    gen_vfp_mul(dp);
2606
                    gen_mov_F1_vreg(dp, rd);
2607
                    gen_vfp_sub(dp);
2608
                    break;
2609
                case 3: /* nmsc: -fd - (fn * fm)  */
2610
                    gen_vfp_mul(dp);
2611
                    gen_mov_F1_vreg(dp, rd);
2612
                    gen_vfp_add(dp);
2613
                    gen_vfp_neg(dp);
2614
                    break;
2615
                case 4: /* mul: fn * fm */
2616
                    gen_vfp_mul(dp);
2617
                    break;
2618
                case 5: /* nmul: -(fn * fm) */
2619
                    gen_vfp_mul(dp);
2620
                    gen_vfp_neg(dp);
2621
                    break;
2622
                case 6: /* add: fn + fm */
2623
                    gen_vfp_add(dp);
2624
                    break;
2625
                case 7: /* sub: fn - fm */
2626
                    gen_vfp_sub(dp);
2627
                    break;
2628
                case 8: /* div: fn / fm */
2629
                    gen_vfp_div(dp);
2630
                    break;
2631
                case 14: /* fconst */
2632
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
2633
                      return 1;
2634

    
2635
                    n = (insn << 12) & 0x80000000;
2636
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
2637
                    if (dp) {
2638
                        if (i & 0x40)
2639
                            i |= 0x3f80;
2640
                        else
2641
                            i |= 0x4000;
2642
                        n |= i << 16;
2643
                    } else {
2644
                        if (i & 0x40)
2645
                            i |= 0x780;
2646
                        else
2647
                            i |= 0x800;
2648
                        n |= i << 19;
2649
                    }
2650
                    gen_vfp_fconst(dp, n);
2651
                    break;
2652
                case 15: /* extension space */
2653
                    switch (rn) {
2654
                    case 0: /* cpy */
2655
                        /* no-op */
2656
                        break;
2657
                    case 1: /* abs */
2658
                        gen_vfp_abs(dp);
2659
                        break;
2660
                    case 2: /* neg */
2661
                        gen_vfp_neg(dp);
2662
                        break;
2663
                    case 3: /* sqrt */
2664
                        gen_vfp_sqrt(dp);
2665
                        break;
2666
                    case 8: /* cmp */
2667
                        gen_vfp_cmp(dp);
2668
                        break;
2669
                    case 9: /* cmpe */
2670
                        gen_vfp_cmpe(dp);
2671
                        break;
2672
                    case 10: /* cmpz */
2673
                        gen_vfp_cmp(dp);
2674
                        break;
2675
                    case 11: /* cmpez */
2676
                        gen_vfp_F1_ld0(dp);
2677
                        gen_vfp_cmpe(dp);
2678
                        break;
2679
                    case 15: /* single<->double conversion */
2680
                        if (dp)
2681
                            gen_op_vfp_fcvtsd();
2682
                        else
2683
                            gen_op_vfp_fcvtds();
2684
                        break;
2685
                    case 16: /* fuito */
2686
                        gen_vfp_uito(dp);
2687
                        break;
2688
                    case 17: /* fsito */
2689
                        gen_vfp_sito(dp);
2690
                        break;
2691
                    case 20: /* fshto */
2692
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2693
                          return 1;
2694
                        gen_vfp_shto(dp, rm);
2695
                        break;
2696
                    case 21: /* fslto */
2697
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2698
                          return 1;
2699
                        gen_vfp_slto(dp, rm);
2700
                        break;
2701
                    case 22: /* fuhto */
2702
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2703
                          return 1;
2704
                        gen_vfp_uhto(dp, rm);
2705
                        break;
2706
                    case 23: /* fulto */
2707
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2708
                          return 1;
2709
                        gen_vfp_ulto(dp, rm);
2710
                        break;
2711
                    case 24: /* ftoui */
2712
                        gen_vfp_toui(dp);
2713
                        break;
2714
                    case 25: /* ftouiz */
2715
                        gen_vfp_touiz(dp);
2716
                        break;
2717
                    case 26: /* ftosi */
2718
                        gen_vfp_tosi(dp);
2719
                        break;
2720
                    case 27: /* ftosiz */
2721
                        gen_vfp_tosiz(dp);
2722
                        break;
2723
                    case 28: /* ftosh */
2724
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2725
                          return 1;
2726
                        gen_vfp_tosh(dp, rm);
2727
                        break;
2728
                    case 29: /* ftosl */
2729
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2730
                          return 1;
2731
                        gen_vfp_tosl(dp, rm);
2732
                        break;
2733
                    case 30: /* ftouh */
2734
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2735
                          return 1;
2736
                        gen_vfp_touh(dp, rm);
2737
                        break;
2738
                    case 31: /* ftoul */
2739
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2740
                          return 1;
2741
                        gen_vfp_toul(dp, rm);
2742
                        break;
2743
                    default: /* undefined */
2744
                        printf ("rn:%d\n", rn);
2745
                        return 1;
2746
                    }
2747
                    break;
2748
                default: /* undefined */
2749
                    printf ("op:%d\n", op);
2750
                    return 1;
2751
                }
2752

    
2753
                /* Write back the result.  */
2754
                if (op == 15 && (rn >= 8 && rn <= 11))
2755
                    ; /* Comparison, do nothing.  */
2756
                else if (op == 15 && rn > 17)
2757
                    /* Integer result.  */
2758
                    gen_mov_vreg_F0(0, rd);
2759
                else if (op == 15 && rn == 15)
2760
                    /* conversion */
2761
                    gen_mov_vreg_F0(!dp, rd);
2762
                else
2763
                    gen_mov_vreg_F0(dp, rd);
2764

    
2765
                /* break out of the loop if we have finished  */
2766
                if (veclen == 0)
2767
                    break;
2768

    
2769
                if (op == 15 && delta_m == 0) {
2770
                    /* single source one-many */
2771
                    while (veclen--) {
2772
                        rd = ((rd + delta_d) & (bank_mask - 1))
2773
                             | (rd & bank_mask);
2774
                        gen_mov_vreg_F0(dp, rd);
2775
                    }
2776
                    break;
2777
                }
2778
                /* Setup the next operands.  */
2779
                veclen--;
2780
                rd = ((rd + delta_d) & (bank_mask - 1))
2781
                     | (rd & bank_mask);
2782

    
2783
                if (op == 15) {
2784
                    /* One source operand.  */
2785
                    rm = ((rm + delta_m) & (bank_mask - 1))
2786
                         | (rm & bank_mask);
2787
                    gen_mov_F0_vreg(dp, rm);
2788
                } else {
2789
                    /* Two source operands.  */
2790
                    rn = ((rn + delta_d) & (bank_mask - 1))
2791
                         | (rn & bank_mask);
2792
                    gen_mov_F0_vreg(dp, rn);
2793
                    if (delta_m) {
2794
                        rm = ((rm + delta_m) & (bank_mask - 1))
2795
                             | (rm & bank_mask);
2796
                        gen_mov_F1_vreg(dp, rm);
2797
                    }
2798
                }
2799
            }
2800
        }
2801
        break;
2802
    case 0xc:
2803
    case 0xd:
2804
        if (dp && (insn & 0x03e00000) == 0x00400000) {
2805
            /* two-register transfer */
2806
            rn = (insn >> 16) & 0xf;
2807
            rd = (insn >> 12) & 0xf;
2808
            if (dp) {
2809
                VFP_DREG_M(rm, insn);
2810
            } else {
2811
                rm = VFP_SREG_M(insn);
2812
            }
2813

    
2814
            if (insn & ARM_CP_RW_BIT) {
2815
                /* vfp->arm */
2816
                if (dp) {
2817
                    gen_mov_F0_vreg(1, rm);
2818
                    gen_op_vfp_mrrd();
2819
                    gen_movl_reg_T0(s, rd);
2820
                    gen_movl_reg_T1(s, rn);
2821
                } else {
2822
                    gen_mov_F0_vreg(0, rm);
2823
                    gen_op_vfp_mrs();
2824
                    gen_movl_reg_T0(s, rn);
2825
                    gen_mov_F0_vreg(0, rm + 1);
2826
                    gen_op_vfp_mrs();
2827
                    gen_movl_reg_T0(s, rd);
2828
                }
2829
            } else {
2830
                /* arm->vfp */
2831
                if (dp) {
2832
                    gen_movl_T0_reg(s, rd);
2833
                    gen_movl_T1_reg(s, rn);
2834
                    gen_op_vfp_mdrr();
2835
                    gen_mov_vreg_F0(1, rm);
2836
                } else {
2837
                    gen_movl_T0_reg(s, rn);
2838
                    gen_op_vfp_msr();
2839
                    gen_mov_vreg_F0(0, rm);
2840
                    gen_movl_T0_reg(s, rd);
2841
                    gen_op_vfp_msr();
2842
                    gen_mov_vreg_F0(0, rm + 1);
2843
                }
2844
            }
2845
        } else {
2846
            /* Load/store */
2847
            rn = (insn >> 16) & 0xf;
2848
            if (dp)
2849
                VFP_DREG_D(rd, insn);
2850
            else
2851
                rd = VFP_SREG_D(insn);
2852
            if (s->thumb && rn == 15) {
2853
                gen_op_movl_T1_im(s->pc & ~2);
2854
            } else {
2855
                gen_movl_T1_reg(s, rn);
2856
            }
2857
            if ((insn & 0x01200000) == 0x01000000) {
2858
                /* Single load/store */
2859
                offset = (insn & 0xff) << 2;
2860
                if ((insn & (1 << 23)) == 0)
2861
                    offset = -offset;
2862
                gen_op_addl_T1_im(offset);
2863
                if (insn & (1 << 20)) {
2864
                    gen_vfp_ld(s, dp);
2865
                    gen_mov_vreg_F0(dp, rd);
2866
                } else {
2867
                    gen_mov_F0_vreg(dp, rd);
2868
                    gen_vfp_st(s, dp);
2869
                }
2870
            } else {
2871
                /* load/store multiple */
2872
                if (dp)
2873
                    n = (insn >> 1) & 0x7f;
2874
                else
2875
                    n = insn & 0xff;
2876

    
2877
                if (insn & (1 << 24)) /* pre-decrement */
2878
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
2879

    
2880
                if (dp)
2881
                    offset = 8;
2882
                else
2883
                    offset = 4;
2884
                for (i = 0; i < n; i++) {
2885
                    if (insn & ARM_CP_RW_BIT) {
2886
                        /* load */
2887
                        gen_vfp_ld(s, dp);
2888
                        gen_mov_vreg_F0(dp, rd + i);
2889
                    } else {
2890
                        /* store */
2891
                        gen_mov_F0_vreg(dp, rd + i);
2892
                        gen_vfp_st(s, dp);
2893
                    }
2894
                    gen_op_addl_T1_im(offset);
2895
                }
2896
                if (insn & (1 << 21)) {
2897
                    /* writeback */
2898
                    if (insn & (1 << 24))
2899
                        offset = -offset * n;
2900
                    else if (dp && (insn & 1))
2901
                        offset = 4;
2902
                    else
2903
                        offset = 0;
2904

    
2905
                    if (offset != 0)
2906
                        gen_op_addl_T1_im(offset);
2907
                    gen_movl_reg_T1(s, rn);
2908
                }
2909
            }
2910
        }
2911
        break;
2912
    default:
2913
        /* Should never happen.  */
2914
        return 1;
2915
    }
2916
    return 0;
2917
}
2918

    
2919
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
2920
{
2921
    TranslationBlock *tb;
2922

    
2923
    tb = s->tb;
2924
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2925
        tcg_gen_goto_tb(n);
2926
        gen_op_movl_T0_im(dest);
2927
        gen_set_pc_T0();
2928
        tcg_gen_exit_tb((long)tb + n);
2929
    } else {
2930
        gen_op_movl_T0_im(dest);
2931
        gen_set_pc_T0();
2932
        tcg_gen_exit_tb(0);
2933
    }
2934
}
2935

    
2936
static inline void gen_jmp (DisasContext *s, uint32_t dest)
2937
{
2938
    if (__builtin_expect(s->singlestep_enabled, 0)) {
2939
        /* An indirect jump so that we still trigger the debug exception.  */
2940
        if (s->thumb)
2941
            dest |= 1;
2942
        gen_bx_im(s, dest);
2943
    } else {
2944
        gen_goto_tb(s, 0, dest);
2945
        s->is_jmp = DISAS_TB_JUMP;
2946
    }
2947
}
2948

    
2949
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
2950
{
2951
    if (x)
2952
        tcg_gen_sari_i32(t0, t0, 16);
2953
    else
2954
        gen_sxth(t0);
2955
    if (y)
2956
        tcg_gen_sari_i32(t1, t1, 16);
2957
    else
2958
        gen_sxth(t1);
2959
    tcg_gen_mul_i32(t0, t0, t1);
2960
}
2961

    
2962
/* Return the mask of PSR bits set by a MSR instruction.  */
2963
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
2964
    uint32_t mask;
2965

    
2966
    mask = 0;
2967
    if (flags & (1 << 0))
2968
        mask |= 0xff;
2969
    if (flags & (1 << 1))
2970
        mask |= 0xff00;
2971
    if (flags & (1 << 2))
2972
        mask |= 0xff0000;
2973
    if (flags & (1 << 3))
2974
        mask |= 0xff000000;
2975

    
2976
    /* Mask out undefined bits.  */
2977
    mask &= ~CPSR_RESERVED;
2978
    if (!arm_feature(env, ARM_FEATURE_V6))
2979
        mask &= ~(CPSR_E | CPSR_GE);
2980
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
2981
        mask &= ~CPSR_IT;
2982
    /* Mask out execution state bits.  */
2983
    if (!spsr)
2984
        mask &= ~CPSR_EXEC;
2985
    /* Mask out privileged bits.  */
2986
    if (IS_USER(s))
2987
        mask &= CPSR_USER;
2988
    return mask;
2989
}
2990

    
2991
/* Returns nonzero if access to the PSR is not permitted.  */
2992
static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
2993
{
2994
    TCGv tmp;
2995
    if (spsr) {
2996
        /* ??? This is also undefined in system mode.  */
2997
        if (IS_USER(s))
2998
            return 1;
2999

    
3000
        tmp = load_cpu_field(spsr);
3001
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3002
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3003
        tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3004
        store_cpu_field(tmp, spsr);
3005
    } else {
3006
        gen_set_cpsr(cpu_T[0], mask);
3007
    }
3008
    gen_lookup_tb(s);
3009
    return 0;
3010
}
3011

    
3012
/* Generate an old-style exception return.  */
3013
static void gen_exception_return(DisasContext *s)
3014
{
3015
    TCGv tmp;
3016
    gen_set_pc_T0();
3017
    tmp = load_cpu_field(spsr);
3018
    gen_set_cpsr(tmp, 0xffffffff);
3019
    dead_tmp(tmp);
3020
    s->is_jmp = DISAS_UPDATE;
3021
}
3022

    
3023
/* Generate a v6 exception return.  Marks both values as dead.  */
3024
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3025
{
3026
    gen_set_cpsr(cpsr, 0xffffffff);
3027
    dead_tmp(cpsr);
3028
    store_reg(s, 15, pc);
3029
    s->is_jmp = DISAS_UPDATE;
3030
}
3031

    
3032
static inline void
3033
gen_set_condexec (DisasContext *s)
3034
{
3035
    if (s->condexec_mask) {
3036
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3037
        TCGv tmp = new_tmp();
3038
        tcg_gen_movi_i32(tmp, val);
3039
        store_cpu_field(tmp, condexec_bits);
3040
    }
3041
}
3042

    
3043
static void gen_nop_hint(DisasContext *s, int val)
3044
{
3045
    switch (val) {
3046
    case 3: /* wfi */
3047
        gen_op_movl_T0_im((long)s->pc);
3048
        gen_set_pc_T0();
3049
        s->is_jmp = DISAS_WFI;
3050
        break;
3051
    case 2: /* wfe */
3052
    case 4: /* sev */
3053
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3054
    default: /* nop */
3055
        break;
3056
    }
3057
}
3058

    
3059
/* Neon shift by constant.  The actual ops are the same as used for variable
3060
   shifts.  [OP][U][SIZE]  */
3061
static GenOpFunc *gen_neon_shift_im[8][2][4] = {
3062
    { /* 0 */ /* VSHR */
3063
      {
3064
        gen_op_neon_shl_u8,
3065
        gen_op_neon_shl_u16,
3066
        gen_op_neon_shl_u32,
3067
        gen_op_neon_shl_u64
3068
      }, {
3069
        gen_op_neon_shl_s8,
3070
        gen_op_neon_shl_s16,
3071
        gen_op_neon_shl_s32,
3072
        gen_op_neon_shl_s64
3073
      }
3074
    }, { /* 1 */ /* VSRA */
3075
      {
3076
        gen_op_neon_shl_u8,
3077
        gen_op_neon_shl_u16,
3078
        gen_op_neon_shl_u32,
3079
        gen_op_neon_shl_u64
3080
      }, {
3081
        gen_op_neon_shl_s8,
3082
        gen_op_neon_shl_s16,
3083
        gen_op_neon_shl_s32,
3084
        gen_op_neon_shl_s64
3085
      }
3086
    }, { /* 2 */ /* VRSHR */
3087
      {
3088
        gen_op_neon_rshl_u8,
3089
        gen_op_neon_rshl_u16,
3090
        gen_op_neon_rshl_u32,
3091
        gen_op_neon_rshl_u64
3092
      }, {
3093
        gen_op_neon_rshl_s8,
3094
        gen_op_neon_rshl_s16,
3095
        gen_op_neon_rshl_s32,
3096
        gen_op_neon_rshl_s64
3097
      }
3098
    }, { /* 3 */ /* VRSRA */
3099
      {
3100
        gen_op_neon_rshl_u8,
3101
        gen_op_neon_rshl_u16,
3102
        gen_op_neon_rshl_u32,
3103
        gen_op_neon_rshl_u64
3104
      }, {
3105
        gen_op_neon_rshl_s8,
3106
        gen_op_neon_rshl_s16,
3107
        gen_op_neon_rshl_s32,
3108
        gen_op_neon_rshl_s64
3109
      }
3110
    }, { /* 4 */
3111
      {
3112
        NULL, NULL, NULL, NULL
3113
      }, { /* VSRI */
3114
        gen_op_neon_shl_u8,
3115
        gen_op_neon_shl_u16,
3116
        gen_op_neon_shl_u32,
3117
        gen_op_neon_shl_u64,
3118
      }
3119
    }, { /* 5 */
3120
      { /* VSHL */
3121
        gen_op_neon_shl_u8,
3122
        gen_op_neon_shl_u16,
3123
        gen_op_neon_shl_u32,
3124
        gen_op_neon_shl_u64,
3125
      }, { /* VSLI */
3126
        gen_op_neon_shl_u8,
3127
        gen_op_neon_shl_u16,
3128
        gen_op_neon_shl_u32,
3129
        gen_op_neon_shl_u64,
3130
      }
3131
    }, { /* 6 */ /* VQSHL */
3132
      {
3133
        gen_op_neon_qshl_u8,
3134
        gen_op_neon_qshl_u16,
3135
        gen_op_neon_qshl_u32,
3136
        gen_op_neon_qshl_u64
3137
      }, {
3138
        gen_op_neon_qshl_s8,
3139
        gen_op_neon_qshl_s16,
3140
        gen_op_neon_qshl_s32,
3141
        gen_op_neon_qshl_s64
3142
      }
3143
    }, { /* 7 */ /* VQSHLU */
3144
      {
3145
        gen_op_neon_qshl_u8,
3146
        gen_op_neon_qshl_u16,
3147
        gen_op_neon_qshl_u32,
3148
        gen_op_neon_qshl_u64
3149
      }, {
3150
        gen_op_neon_qshl_u8,
3151
        gen_op_neon_qshl_u16,
3152
        gen_op_neon_qshl_u32,
3153
        gen_op_neon_qshl_u64
3154
      }
3155
    }
3156
};
3157

    
3158
/* [R][U][size - 1] */
3159
static GenOpFunc *gen_neon_shift_im_narrow[2][2][3] = {
3160
    {
3161
      {
3162
        gen_op_neon_shl_u16,
3163
        gen_op_neon_shl_u32,
3164
        gen_op_neon_shl_u64
3165
      }, {
3166
        gen_op_neon_shl_s16,
3167
        gen_op_neon_shl_s32,
3168
        gen_op_neon_shl_s64
3169
      }
3170
    }, {
3171
      {
3172
        gen_op_neon_rshl_u16,
3173
        gen_op_neon_rshl_u32,
3174
        gen_op_neon_rshl_u64
3175
      }, {
3176
        gen_op_neon_rshl_s16,
3177
        gen_op_neon_rshl_s32,
3178
        gen_op_neon_rshl_s64
3179
      }
3180
    }
3181
};
3182

    
3183
static inline void
3184
gen_op_neon_narrow_u32 ()
3185
{
3186
    /* No-op.  */
3187
}
3188

    
3189
static GenOpFunc *gen_neon_narrow[3] = {
3190
    gen_op_neon_narrow_u8,
3191
    gen_op_neon_narrow_u16,
3192
    gen_op_neon_narrow_u32
3193
};
3194

    
3195
static GenOpFunc *gen_neon_narrow_satu[3] = {
3196
    gen_op_neon_narrow_sat_u8,
3197
    gen_op_neon_narrow_sat_u16,
3198
    gen_op_neon_narrow_sat_u32
3199
};
3200

    
3201
static GenOpFunc *gen_neon_narrow_sats[3] = {
3202
    gen_op_neon_narrow_sat_s8,
3203
    gen_op_neon_narrow_sat_s16,
3204
    gen_op_neon_narrow_sat_s32
3205
};
3206

    
3207
static inline int gen_neon_add(int size)
3208
{
3209
    switch (size) {
3210
    case 0: gen_op_neon_add_u8(); break;
3211
    case 1: gen_op_neon_add_u16(); break;
3212
    case 2: gen_op_addl_T0_T1(); break;
3213
    default: return 1;
3214
    }
3215
    return 0;
3216
}
3217

    
3218
/* 32-bit pairwise ops end up the same as the elementsise versions.  */
3219
#define gen_op_neon_pmax_s32  gen_op_neon_max_s32
3220
#define gen_op_neon_pmax_u32  gen_op_neon_max_u32
3221
#define gen_op_neon_pmin_s32  gen_op_neon_min_s32
3222
#define gen_op_neon_pmin_u32  gen_op_neon_min_u32
3223

    
3224
#define GEN_NEON_INTEGER_OP(name) do { \
3225
    switch ((size << 1) | u) { \
3226
    case 0: gen_op_neon_##name##_s8(); break; \
3227
    case 1: gen_op_neon_##name##_u8(); break; \
3228
    case 2: gen_op_neon_##name##_s16(); break; \
3229
    case 3: gen_op_neon_##name##_u16(); break; \
3230
    case 4: gen_op_neon_##name##_s32(); break; \
3231
    case 5: gen_op_neon_##name##_u32(); break; \
3232
    default: return 1; \
3233
    }} while (0)
3234

    
3235
static inline void
3236
gen_neon_movl_scratch_T0(int scratch)
3237
{
3238
  uint32_t offset;
3239

    
3240
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3241
  gen_op_neon_setreg_T0(offset);
3242
}
3243

    
3244
static inline void
3245
gen_neon_movl_scratch_T1(int scratch)
3246
{
3247
  uint32_t offset;
3248

    
3249
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3250
  gen_op_neon_setreg_T1(offset);
3251
}
3252

    
3253
static inline void
3254
gen_neon_movl_T0_scratch(int scratch)
3255
{
3256
  uint32_t offset;
3257

    
3258
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3259
  gen_op_neon_getreg_T0(offset);
3260
}
3261

    
3262
static inline void
3263
gen_neon_movl_T1_scratch(int scratch)
3264
{
3265
  uint32_t offset;
3266

    
3267
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3268
  gen_op_neon_getreg_T1(offset);
3269
}
3270

    
3271
static inline void gen_op_neon_widen_u32(void)
3272
{
3273
    gen_op_movl_T1_im(0);
3274
}
3275

    
3276
static inline void gen_neon_get_scalar(int size, int reg)
3277
{
3278
    if (size == 1) {
3279
        NEON_GET_REG(T0, reg >> 1, reg & 1);
3280
    } else {
3281
        NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3282
        if (reg & 1)
3283
            gen_op_neon_dup_low16();
3284
        else
3285
            gen_op_neon_dup_high16();
3286
    }
3287
}
3288

    
3289
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3290
{
3291
    int n;
3292

    
3293
    for (n = 0; n < q + 1; n += 2) {
3294
        NEON_GET_REG(T0, reg, n);
3295
        NEON_GET_REG(T0, reg, n + n);
3296
        switch (size) {
3297
        case 0: gen_op_neon_unzip_u8(); break;
3298
        case 1: gen_op_neon_zip_u16(); break; /* zip and unzip are the same.  */
3299
        case 2: /* no-op */; break;
3300
        default: abort();
3301
        }
3302
        gen_neon_movl_scratch_T0(tmp + n);
3303
        gen_neon_movl_scratch_T1(tmp + n + 1);
3304
    }
3305
}
3306

    
3307
static struct {
3308
    int nregs;
3309
    int interleave;
3310
    int spacing;
3311
} neon_ls_element_type[11] = {
3312
    {4, 4, 1},
3313
    {4, 4, 2},
3314
    {4, 1, 1},
3315
    {4, 2, 1},
3316
    {3, 3, 1},
3317
    {3, 3, 2},
3318
    {3, 1, 1},
3319
    {1, 1, 1},
3320
    {2, 2, 1},
3321
    {2, 2, 2},
3322
    {2, 1, 1}
3323
};
3324

    
3325
/* Translate a NEON load/store element instruction.  Return nonzero if the
3326
   instruction is invalid.  */
3327
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3328
{
3329
    int rd, rn, rm;
3330
    int op;
3331
    int nregs;
3332
    int interleave;
3333
    int stride;
3334
    int size;
3335
    int reg;
3336
    int pass;
3337
    int load;
3338
    int shift;
3339
    uint32_t mask;
3340
    int n;
3341
    TCGv tmp;
3342

    
3343
    if (!vfp_enabled(env))
3344
      return 1;
3345
    VFP_DREG_D(rd, insn);
3346
    rn = (insn >> 16) & 0xf;
3347
    rm = insn & 0xf;
3348
    load = (insn & (1 << 21)) != 0;
3349
    if ((insn & (1 << 23)) == 0) {
3350
        /* Load store all elements.  */
3351
        op = (insn >> 8) & 0xf;
3352
        size = (insn >> 6) & 3;
3353
        if (op > 10 || size == 3)
3354
            return 1;
3355
        nregs = neon_ls_element_type[op].nregs;
3356
        interleave = neon_ls_element_type[op].interleave;
3357
        gen_movl_T1_reg(s, rn);
3358
        stride = (1 << size) * interleave;
3359
        for (reg = 0; reg < nregs; reg++) {
3360
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3361
                gen_movl_T1_reg(s, rn);
3362
                gen_op_addl_T1_im((1 << size) * reg);
3363
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3364
                gen_movl_T1_reg(s, rn);
3365
                gen_op_addl_T1_im(1 << size);
3366
            }
3367
            for (pass = 0; pass < 2; pass++) {
3368
                if (size == 2) {
3369
                    if (load) {
3370
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3371
                        tcg_gen_mov_i32(cpu_T[0], tmp);
3372
                        dead_tmp(tmp);
3373
                        NEON_SET_REG(T0, rd, pass);
3374
                    } else {
3375
                        NEON_GET_REG(T0, rd, pass);
3376
                        tmp = new_tmp();
3377
                        tcg_gen_mov_i32(tmp, cpu_T[0]);
3378
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3379
                    }
3380
                    gen_op_addl_T1_im(stride);
3381
                } else if (size == 1) {
3382
                    if (load) {
3383
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3384
                        tcg_gen_mov_i32(cpu_T[0], tmp);
3385
                        dead_tmp(tmp);
3386
                        gen_op_addl_T1_im(stride);
3387
                        gen_op_movl_T2_T0();
3388
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3389
                        tcg_gen_mov_i32(cpu_T[0], tmp);
3390
                        dead_tmp(tmp);
3391
                        gen_op_addl_T1_im(stride);
3392
                        gen_op_neon_insert_elt(16, 0xffff);
3393
                        NEON_SET_REG(T2, rd, pass);
3394
                    } else {
3395
                        NEON_GET_REG(T2, rd, pass);
3396
                        gen_op_movl_T0_T2();
3397
                        tmp = new_tmp();
3398
                        tcg_gen_mov_i32(tmp, cpu_T[0]);
3399
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3400
                        gen_op_addl_T1_im(stride);
3401
                        gen_op_neon_extract_elt(16, 0xffff0000);
3402
                        tmp = new_tmp();
3403
                        tcg_gen_mov_i32(tmp, cpu_T[0]);
3404
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3405
                        gen_op_addl_T1_im(stride);
3406
                    }
3407
                } else /* size == 0 */ {
3408
                    if (load) {
3409
                        mask = 0xff;
3410
                        for (n = 0; n < 4; n++) {
3411
                            tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3412
                            tcg_gen_mov_i32(cpu_T[0], tmp);
3413
                            dead_tmp(tmp);
3414
                            gen_op_addl_T1_im(stride);
3415
                            if (n == 0) {
3416
                                gen_op_movl_T2_T0();
3417
                            } else {
3418
                                gen_op_neon_insert_elt(n * 8, ~mask);
3419
                            }
3420
                            mask <<= 8;
3421
                        }
3422
                        NEON_SET_REG(T2, rd, pass);
3423
                    } else {
3424
                        NEON_GET_REG(T2, rd, pass);
3425
                        mask = 0xff;
3426
                        for (n = 0; n < 4; n++) {
3427
                            if (n == 0) {
3428
                                gen_op_movl_T0_T2();
3429
                            } else {
3430
                                gen_op_neon_extract_elt(n * 8, mask);
3431
                            }
3432
                            tmp = new_tmp();
3433
                            tcg_gen_mov_i32(tmp, cpu_T[0]);
3434
                            gen_st8(tmp, cpu_T[1], IS_USER(s));
3435
                            gen_op_addl_T1_im(stride);
3436
                            mask <<= 8;
3437
                        }
3438
                    }
3439
                }
3440
            }
3441
            rd += neon_ls_element_type[op].spacing;
3442
        }
3443
        stride = nregs * 8;
3444
    } else {
3445
        size = (insn >> 10) & 3;
3446
        if (size == 3) {
3447
            /* Load single element to all lanes.  */
3448
            if (!load)
3449
                return 1;
3450
            size = (insn >> 6) & 3;
3451
            nregs = ((insn >> 8) & 3) + 1;
3452
            stride = (insn & (1 << 5)) ? 2 : 1;
3453
            gen_movl_T1_reg(s, rn);
3454
            for (reg = 0; reg < nregs; reg++) {
3455
                switch (size) {
3456
                case 0:
3457
                    tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3458
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3459
                    dead_tmp(tmp);
3460
                    gen_op_neon_dup_u8(0);
3461
                    break;
3462
                case 1:
3463
                    tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3464
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3465
                    dead_tmp(tmp);
3466
                    gen_op_neon_dup_low16();
3467
                    break;
3468
                case 2:
3469
                    tmp = gen_ld32(cpu_T[0], IS_USER(s));
3470
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3471
                    dead_tmp(tmp);
3472
                    break;
3473
                case 3:
3474
                    return 1;
3475
                }
3476
                gen_op_addl_T1_im(1 << size);
3477
                NEON_SET_REG(T0, rd, 0);
3478
                NEON_SET_REG(T0, rd, 1);
3479
                rd += stride;
3480
            }
3481
            stride = (1 << size) * nregs;
3482
        } else {
3483
            /* Single element.  */
3484
            pass = (insn >> 7) & 1;
3485
            switch (size) {
3486
            case 0:
3487
                shift = ((insn >> 5) & 3) * 8;
3488
                mask = 0xff << shift;
3489
                stride = 1;
3490
                break;
3491
            case 1:
3492
                shift = ((insn >> 6) & 1) * 16;
3493
                mask = shift ? 0xffff0000 : 0xffff;
3494
                stride = (insn & (1 << 5)) ? 2 : 1;
3495
                break;
3496
            case 2:
3497
                shift = 0;
3498
                mask = 0xffffffff;
3499
                stride = (insn & (1 << 6)) ? 2 : 1;
3500
                break;
3501
            default:
3502
                abort();
3503
            }
3504
            nregs = ((insn >> 8) & 3) + 1;
3505
            gen_movl_T1_reg(s, rn);
3506
            for (reg = 0; reg < nregs; reg++) {
3507
                if (load) {
3508
                    if (size != 2) {
3509
                        NEON_GET_REG(T2, rd, pass);
3510
                    }
3511
                    switch (size) {
3512
                    case 0:
3513
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3514
                        break;
3515
                    case 1:
3516
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3517
                        break;
3518
                    case 2:
3519
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3520
                        break;
3521
                    }
3522
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3523
                    dead_tmp(tmp);
3524
                    if (size != 2) {
3525
                        gen_op_neon_insert_elt(shift, ~mask);
3526
                        NEON_SET_REG(T0, rd, pass);
3527
                    } else {
3528
                        NEON_SET_REG(T0, rd, pass);
3529
                    }
3530
                } else { /* Store */
3531
                    if (size == 2) {
3532
                        NEON_GET_REG(T0, rd, pass);
3533
                    } else {
3534
                        NEON_GET_REG(T2, rd, pass);
3535
                        gen_op_neon_extract_elt(shift, mask);
3536
                    }
3537
                    tmp = new_tmp();
3538
                    tcg_gen_mov_i32(tmp, cpu_T[0]);
3539
                    switch (size) {
3540
                    case 0:
3541
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
3542
                        break;
3543
                    case 1:
3544
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3545
                        break;
3546
                    case 2:
3547
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3548
                        break;
3549
                    }
3550
                }
3551
                rd += stride;
3552
                gen_op_addl_T1_im(1 << size);
3553
            }
3554
            stride = nregs * (1 << size);
3555
        }
3556
    }
3557
    if (rm != 15) {
3558
        TCGv base;
3559

    
3560
        base = load_reg(s, rn);
3561
        if (rm == 13) {
3562
            tcg_gen_addi_i32(base, base, stride);
3563
        } else {
3564
            TCGv index;
3565
            index = load_reg(s, rm);
3566
            tcg_gen_add_i32(base, base, index);
3567
            dead_tmp(index);
3568
        }
3569
        store_reg(s, rn, base);
3570
    }
3571
    return 0;
3572
}
3573

    
3574
/* Translate a NEON data processing instruction.  Return nonzero if the
3575
   instruction is invalid.
3576
   In general we process vectors in 32-bit chunks.  This means we can reuse
3577
   some of the scalar ops, and hopefully the code generated for 32-bit
3578
   hosts won't be too awful.  The downside is that the few 64-bit operations
3579
   (mainly shifts) get complicated.  */
3580

    
3581
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
3582
{
3583
    int op;
3584
    int q;
3585
    int rd, rn, rm;
3586
    int size;
3587
    int shift;
3588
    int pass;
3589
    int count;
3590
    int pairwise;
3591
    int u;
3592
    int n;
3593
    uint32_t imm;
3594

    
3595
    if (!vfp_enabled(env))
3596
      return 1;
3597
    q = (insn & (1 << 6)) != 0;
3598
    u = (insn >> 24) & 1;
3599
    VFP_DREG_D(rd, insn);
3600
    VFP_DREG_N(rn, insn);
3601
    VFP_DREG_M(rm, insn);
3602
    size = (insn >> 20) & 3;
3603
    if ((insn & (1 << 23)) == 0) {
3604
        /* Three register same length.  */
3605
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
3606
        if (size == 3 && (op == 1 || op == 5 || op == 16)) {
3607
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
3608
                NEON_GET_REG(T0, rm, pass * 2);
3609
                NEON_GET_REG(T1, rm, pass * 2 + 1);
3610
                gen_neon_movl_scratch_T0(0);
3611
                gen_neon_movl_scratch_T1(1);
3612
                NEON_GET_REG(T0, rn, pass * 2);
3613
                NEON_GET_REG(T1, rn, pass * 2 + 1);
3614
                switch (op) {
3615
                case 1: /* VQADD */
3616
                    if (u) {
3617
                        gen_op_neon_addl_saturate_u64();
3618
                    } else {
3619
                        gen_op_neon_addl_saturate_s64();
3620
                    }
3621
                    break;
3622
                case 5: /* VQSUB */
3623
                    if (u) {
3624
                        gen_op_neon_subl_saturate_u64();
3625
                    } else {
3626
                        gen_op_neon_subl_saturate_s64();
3627
                    }
3628
                    break;
3629
                case 16:
3630
                    if (u) {
3631
                        gen_op_neon_subl_u64();
3632
                    } else {
3633
                        gen_op_neon_addl_u64();
3634
                    }
3635
                    break;
3636
                default:
3637
                    abort();
3638
                }
3639
                NEON_SET_REG(T0, rd, pass * 2);
3640
                NEON_SET_REG(T1, rd, pass * 2 + 1);
3641
            }
3642
            return 0;
3643
        }
3644
        switch (op) {
3645
        case 8: /* VSHL */
3646
        case 9: /* VQSHL */
3647
        case 10: /* VRSHL */
3648
        case 11: /* VQSHL */
3649
            /* Shift operations have Rn and Rm reversed.  */
3650
            {
3651
                int tmp;
3652
                tmp = rn;
3653
                rn = rm;
3654
                rm = tmp;
3655
                pairwise = 0;
3656
            }
3657
            break;
3658
        case 20: /* VPMAX */
3659
        case 21: /* VPMIN */
3660
        case 23: /* VPADD */
3661
            pairwise = 1;
3662
            break;
3663
        case 26: /* VPADD (float) */
3664
            pairwise = (u && size < 2);
3665
            break;
3666
        case 30: /* VPMIN/VPMAX (float) */
3667
            pairwise = u;
3668
            break;
3669
        default:
3670
            pairwise = 0;
3671
            break;
3672
        }
3673
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
3674

    
3675
        if (pairwise) {
3676
            /* Pairwise.  */
3677
            if (q)
3678
                n = (pass & 1) * 2;
3679
            else
3680
                n = 0;
3681
            if (pass < q + 1) {
3682
                NEON_GET_REG(T0, rn, n);
3683
                NEON_GET_REG(T1, rn, n + 1);
3684
            } else {
3685
                NEON_GET_REG(T0, rm, n);
3686
                NEON_GET_REG(T1, rm, n + 1);
3687
            }
3688
        } else {
3689
            /* Elementwise.  */
3690
            NEON_GET_REG(T0, rn, pass);
3691
            NEON_GET_REG(T1, rm, pass);
3692
        }
3693
        switch (op) {
3694
        case 0: /* VHADD */
3695
            GEN_NEON_INTEGER_OP(hadd);
3696
            break;
3697
        case 1: /* VQADD */
3698
            switch (size << 1| u) {
3699
            case 0: gen_op_neon_qadd_s8(); break;
3700
            case 1: gen_op_neon_qadd_u8(); break;
3701
            case 2: gen_op_neon_qadd_s16(); break;
3702
            case 3: gen_op_neon_qadd_u16(); break;
3703
            case 4: gen_op_addl_T0_T1_saturate(); break;
3704
            case 5: gen_op_addl_T0_T1_usaturate(); break;
3705
            default: abort();
3706
            }
3707
            break;
3708
        case 2: /* VRHADD */
3709
            GEN_NEON_INTEGER_OP(rhadd);
3710
            break;
3711
        case 3: /* Logic ops.  */
3712
            switch ((u << 2) | size) {
3713
            case 0: /* VAND */
3714
                gen_op_andl_T0_T1();
3715
                break;
3716
            case 1: /* BIC */
3717
                gen_op_bicl_T0_T1();
3718
                break;
3719
            case 2: /* VORR */
3720
                gen_op_orl_T0_T1();
3721
                break;
3722
            case 3: /* VORN */
3723
                gen_op_notl_T1();
3724
                gen_op_orl_T0_T1();
3725
                break;
3726
            case 4: /* VEOR */
3727
                gen_op_xorl_T0_T1();
3728
                break;
3729
            case 5: /* VBSL */
3730
                NEON_GET_REG(T2, rd, pass);
3731
                gen_op_neon_bsl();
3732
                break;
3733
            case 6: /* VBIT */
3734
                NEON_GET_REG(T2, rd, pass);
3735
                gen_op_neon_bit();
3736
                break;
3737
            case 7: /* VBIF */
3738
                NEON_GET_REG(T2, rd, pass);
3739
                gen_op_neon_bif();
3740
                break;
3741
            }
3742
            break;
3743
        case 4: /* VHSUB */
3744
            GEN_NEON_INTEGER_OP(hsub);
3745
            break;
3746
        case 5: /* VQSUB */
3747
            switch ((size << 1) | u) {
3748
            case 0: gen_op_neon_qsub_s8(); break;
3749
            case 1: gen_op_neon_qsub_u8(); break;
3750
            case 2: gen_op_neon_qsub_s16(); break;
3751
            case 3: gen_op_neon_qsub_u16(); break;
3752
            case 4: gen_op_subl_T0_T1_saturate(); break;
3753
            case 5: gen_op_subl_T0_T1_usaturate(); break;
3754
            default: abort();
3755
            }
3756
            break;
3757
        case 6: /* VCGT */
3758
            GEN_NEON_INTEGER_OP(cgt);
3759
            break;
3760
        case 7: /* VCGE */
3761
            GEN_NEON_INTEGER_OP(cge);
3762
            break;
3763
        case 8: /* VSHL */
3764
            switch ((size << 1) | u) {
3765
            case 0: gen_op_neon_shl_s8(); break;
3766
            case 1: gen_op_neon_shl_u8(); break;
3767
            case 2: gen_op_neon_shl_s16(); break;
3768
            case 3: gen_op_neon_shl_u16(); break;
3769
            case 4: gen_op_neon_shl_s32(); break;
3770
            case 5: gen_op_neon_shl_u32(); break;
3771
#if 0
3772
            /* ??? Implementing these is tricky because the vector ops work
3773
               on 32-bit pieces.  */
3774
            case 6: gen_op_neon_shl_s64(); break;
3775
            case 7: gen_op_neon_shl_u64(); break;
3776
#else
3777
            case 6: case 7: cpu_abort(env, "VSHL.64 not implemented");
3778
#endif
3779
            }
3780
            break;
3781
        case 9: /* VQSHL */
3782
            switch ((size << 1) | u) {
3783
            case 0: gen_op_neon_qshl_s8(); break;
3784
            case 1: gen_op_neon_qshl_u8(); break;
3785
            case 2: gen_op_neon_qshl_s16(); break;
3786
            case 3: gen_op_neon_qshl_u16(); break;
3787
            case 4: gen_op_neon_qshl_s32(); break;
3788
            case 5: gen_op_neon_qshl_u32(); break;
3789
#if 0
3790
            /* ??? Implementing these is tricky because the vector ops work
3791
               on 32-bit pieces.  */
3792
            case 6: gen_op_neon_qshl_s64(); break;
3793
            case 7: gen_op_neon_qshl_u64(); break;
3794
#else
3795
            case 6: case 7: cpu_abort(env, "VQSHL.64 not implemented");
3796
#endif
3797
            }
3798
            break;
3799
        case 10: /* VRSHL */
3800
            switch ((size << 1) | u) {
3801
            case 0: gen_op_neon_rshl_s8(); break;
3802
            case 1: gen_op_neon_rshl_u8(); break;
3803
            case 2: gen_op_neon_rshl_s16(); break;
3804
            case 3: gen_op_neon_rshl_u16(); break;
3805
            case 4: gen_op_neon_rshl_s32(); break;
3806
            case 5: gen_op_neon_rshl_u32(); break;
3807
#if 0
3808
            /* ??? Implementing these is tricky because the vector ops work
3809
               on 32-bit pieces.  */
3810
            case 6: gen_op_neon_rshl_s64(); break;
3811
            case 7: gen_op_neon_rshl_u64(); break;
3812
#else
3813
            case 6: case 7: cpu_abort(env, "VRSHL.64 not implemented");
3814
#endif
3815
            }
3816
            break;
3817
        case 11: /* VQRSHL */
3818
            switch ((size << 1) | u) {
3819
            case 0: gen_op_neon_qrshl_s8(); break;
3820
            case 1: gen_op_neon_qrshl_u8(); break;
3821
            case 2: gen_op_neon_qrshl_s16(); break;
3822
            case 3: gen_op_neon_qrshl_u16(); break;
3823
            case 4: gen_op_neon_qrshl_s32(); break;
3824
            case 5: gen_op_neon_qrshl_u32(); break;
3825
#if 0
3826
            /* ??? Implementing these is tricky because the vector ops work
3827
               on 32-bit pieces.  */
3828
            case 6: gen_op_neon_qrshl_s64(); break;
3829
            case 7: gen_op_neon_qrshl_u64(); break;
3830
#else
3831
            case 6: case 7: cpu_abort(env, "VQRSHL.64 not implemented");
3832
#endif
3833
            }
3834
            break;
3835
        case 12: /* VMAX */
3836
            GEN_NEON_INTEGER_OP(max);
3837
            break;
3838
        case 13: /* VMIN */
3839
            GEN_NEON_INTEGER_OP(min);
3840
            break;
3841
        case 14: /* VABD */
3842
            GEN_NEON_INTEGER_OP(abd);
3843
            break;
3844
        case 15: /* VABA */
3845
            GEN_NEON_INTEGER_OP(abd);
3846
            NEON_GET_REG(T1, rd, pass);
3847
            gen_neon_add(size);
3848
            break;
3849
        case 16:
3850
            if (!u) { /* VADD */
3851
                if (gen_neon_add(size))
3852
                    return 1;
3853
            } else { /* VSUB */
3854
                switch (size) {
3855
                case 0: gen_op_neon_sub_u8(); break;
3856
                case 1: gen_op_neon_sub_u16(); break;
3857
                case 2: gen_op_subl_T0_T1(); break;
3858
                default: return 1;
3859
                }
3860
            }
3861
            break;
3862
        case 17:
3863
            if (!u) { /* VTST */
3864
                switch (size) {
3865
                case 0: gen_op_neon_tst_u8(); break;
3866
                case 1: gen_op_neon_tst_u16(); break;
3867
                case 2: gen_op_neon_tst_u32(); break;
3868
                default: return 1;
3869
                }
3870
            } else { /* VCEQ */
3871
                switch (size) {
3872
                case 0: gen_op_neon_ceq_u8(); break;
3873
                case 1: gen_op_neon_ceq_u16(); break;
3874
                case 2: gen_op_neon_ceq_u32(); break;
3875
                default: return 1;
3876
                }
3877
            }
3878
            break;
3879
        case 18: /* Multiply.  */
3880
            switch (size) {
3881
            case 0: gen_op_neon_mul_u8(); break;
3882
            case 1: gen_op_neon_mul_u16(); break;
3883
            case 2: gen_op_mul_T0_T1(); break;
3884
            default: return 1;
3885
            }
3886
            NEON_GET_REG(T1, rd, pass);
3887
            if (u) { /* VMLS */
3888
                switch (size) {
3889
                case 0: gen_op_neon_rsb_u8(); break;
3890
                case 1: gen_op_neon_rsb_u16(); break;
3891
                case 2: gen_op_rsbl_T0_T1(); break;
3892
                default: return 1;
3893
                }
3894
            } else { /* VMLA */
3895
                gen_neon_add(size);
3896
            }
3897
            break;
3898
        case 19: /* VMUL */
3899
            if (u) { /* polynomial */
3900
                gen_op_neon_mul_p8();
3901
            } else { /* Integer */
3902
                switch (size) {
3903
                case 0: gen_op_neon_mul_u8(); break;
3904
                case 1: gen_op_neon_mul_u16(); break;
3905
                case 2: gen_op_mul_T0_T1(); break;
3906
                default: return 1;
3907
                }
3908
            }
3909
            break;
3910
        case 20: /* VPMAX */
3911
            GEN_NEON_INTEGER_OP(pmax);
3912
            break;
3913
        case 21: /* VPMIN */
3914
            GEN_NEON_INTEGER_OP(pmin);
3915
            break;
3916
        case 22: /* Hultiply high.  */
3917
            if (!u) { /* VQDMULH */
3918
                switch (size) {
3919
                case 1: gen_op_neon_qdmulh_s16(); break;
3920
                case 2: gen_op_neon_qdmulh_s32(); break;
3921
                default: return 1;
3922
                }
3923
            } else { /* VQRDHMUL */
3924
                switch (size) {
3925
                case 1: gen_op_neon_qrdmulh_s16(); break;
3926
                case 2: gen_op_neon_qrdmulh_s32(); break;
3927
                default: return 1;
3928
                }
3929
            }
3930
            break;
3931
        case 23: /* VPADD */
3932
            if (u)
3933
                return 1;
3934
            switch (size) {
3935
            case 0: gen_op_neon_padd_u8(); break;
3936
            case 1: gen_op_neon_padd_u16(); break;
3937
            case 2: gen_op_addl_T0_T1(); break;
3938
            default: return 1;
3939
            }
3940
            break;
3941
        case 26: /* Floating point arithnetic.  */
3942
            switch ((u << 2) | size) {
3943
            case 0: /* VADD */
3944
                gen_op_neon_add_f32();
3945
                break;
3946
            case 2: /* VSUB */
3947
                gen_op_neon_sub_f32();
3948
                break;
3949
            case 4: /* VPADD */
3950
                gen_op_neon_add_f32();
3951
                break;
3952
            case 6: /* VABD */
3953
                gen_op_neon_abd_f32();
3954
                break;
3955
            default:
3956
                return 1;
3957
            }
3958
            break;
3959
        case 27: /* Float multiply.  */
3960
            gen_op_neon_mul_f32();
3961
            if (!u) {
3962
                NEON_GET_REG(T1, rd, pass);
3963
                if (size == 0) {
3964
                    gen_op_neon_add_f32();
3965
                } else {
3966
                    gen_op_neon_rsb_f32();
3967
                }
3968
            }
3969
            break;
3970
        case 28: /* Float compare.  */
3971
            if (!u) {
3972
                gen_op_neon_ceq_f32();
3973
            } else {
3974
                if (size == 0)
3975
                    gen_op_neon_cge_f32();
3976
                else
3977
                    gen_op_neon_cgt_f32();
3978
            }
3979
            break;
3980
        case 29: /* Float compare absolute.  */
3981
            if (!u)
3982
                return 1;
3983
            if (size == 0)
3984
                gen_op_neon_acge_f32();
3985
            else
3986
                gen_op_neon_acgt_f32();
3987
            break;
3988
        case 30: /* Float min/max.  */
3989
            if (size == 0)
3990
                gen_op_neon_max_f32();
3991
            else
3992
                gen_op_neon_min_f32();
3993
            break;
3994
        case 31:
3995
            if (size == 0)
3996
                gen_op_neon_recps_f32();
3997
            else
3998
                gen_op_neon_rsqrts_f32();
3999
            break;
4000
        default:
4001
            abort();
4002
        }
4003
        /* Save the result.  For elementwise operations we can put it
4004
           straight into the destination register.  For pairwise operations
4005
           we have to be careful to avoid clobbering the source operands.  */
4006
        if (pairwise && rd == rm) {
4007
            gen_neon_movl_scratch_T0(pass);
4008
        } else {
4009
            NEON_SET_REG(T0, rd, pass);
4010
        }
4011

    
4012
        } /* for pass */
4013
        if (pairwise && rd == rm) {
4014
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4015
                gen_neon_movl_T0_scratch(pass);
4016
                NEON_SET_REG(T0, rd, pass);
4017
            }
4018
        }
4019
    } else if (insn & (1 << 4)) {
4020
        if ((insn & 0x00380080) != 0) {
4021
            /* Two registers and shift.  */
4022
            op = (insn >> 8) & 0xf;
4023
            if (insn & (1 << 7)) {
4024
                /* 64-bit shift.   */
4025
                size = 3;
4026
            } else {
4027
                size = 2;
4028
                while ((insn & (1 << (size + 19))) == 0)
4029
                    size--;
4030
            }
4031
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4032
            /* To avoid excessive dumplication of ops we implement shift
4033
               by immediate using the variable shift operations.  */
4034
            if (op < 8) {
4035
                /* Shift by immediate:
4036
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4037
                /* Right shifts are encoded as N - shift, where N is the
4038
                   element size in bits.  */
4039
                if (op <= 4)
4040
                    shift = shift - (1 << (size + 3));
4041
                else
4042
                    shift++;
4043
                if (size == 3) {
4044
                    count = q + 1;
4045
                } else {
4046
                    count = q ? 4: 2;
4047
                }
4048
                switch (size) {
4049
                case 0:
4050
                    imm = (uint8_t) shift;
4051
                    imm |= imm << 8;
4052
                    imm |= imm << 16;
4053
                    break;
4054
                case 1:
4055
                    imm = (uint16_t) shift;
4056
                    imm |= imm << 16;
4057
                    break;
4058
                case 2:
4059
                case 3:
4060
                    imm = shift;
4061
                    break;
4062
                default:
4063
                    abort();
4064
                }
4065

    
4066
                for (pass = 0; pass < count; pass++) {
4067
                    if (size < 3) {
4068
                        /* Operands in T0 and T1.  */
4069
                        gen_op_movl_T1_im(imm);
4070
                        NEON_GET_REG(T0, rm, pass);
4071
                    } else {
4072
                        /* Operands in {T0, T1} and env->vfp.scratch.  */
4073
                        gen_op_movl_T0_im(imm);
4074
                        gen_neon_movl_scratch_T0(0);
4075
                        gen_op_movl_T0_im((int32_t)imm >> 31);
4076
                        gen_neon_movl_scratch_T0(1);
4077
                        NEON_GET_REG(T0, rm, pass * 2);
4078
                        NEON_GET_REG(T1, rm, pass * 2 + 1);
4079
                    }
4080

    
4081
                    if (gen_neon_shift_im[op][u][size] == NULL)
4082
                        return 1;
4083
                    gen_neon_shift_im[op][u][size]();
4084

    
4085
                    if (op == 1 || op == 3) {
4086
                        /* Accumulate.  */
4087
                        if (size == 3) {
4088
                            gen_neon_movl_scratch_T0(0);
4089
                            gen_neon_movl_scratch_T1(1);
4090
                            NEON_GET_REG(T0, rd, pass * 2);
4091
                            NEON_GET_REG(T1, rd, pass * 2 + 1);
4092
                            gen_op_neon_addl_u64();
4093
                        } else {
4094
                            NEON_GET_REG(T1, rd, pass);
4095
                            gen_neon_add(size);
4096
                        }
4097
                    } else if (op == 4 || (op == 5 && u)) {
4098
                        /* Insert */
4099
                        if (size == 3) {
4100
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4101
                        }
4102
                        switch (size) {
4103
                        case 0:
4104
                            if (op == 4)
4105
                                imm = 0xff >> -shift;
4106
                            else
4107
                                imm = (uint8_t)(0xff << shift);
4108
                            imm |= imm << 8;
4109
                            imm |= imm << 16;
4110
                            break;
4111
                        case 1:
4112
                            if (op == 4)
4113
                                imm = 0xffff >> -shift;
4114
                            else
4115
                                imm = (uint16_t)(0xffff << shift);
4116
                            imm |= imm << 16;
4117
                            break;
4118
                        case 2:
4119
                            if (op == 4)
4120
                                imm = 0xffffffffu >> -shift;
4121
                            else
4122
                                imm = 0xffffffffu << shift;
4123
                            break;
4124
                        default:
4125
                            abort();
4126
                        }
4127
                        NEON_GET_REG(T1, rd, pass);
4128
                        gen_op_movl_T2_im(imm);
4129
                        gen_op_neon_bsl();
4130
                    }
4131
                    if (size == 3) {
4132
                        NEON_SET_REG(T0, rd, pass * 2);
4133
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4134
                    } else {
4135
                        NEON_SET_REG(T0, rd, pass);
4136
                    }
4137
                } /* for pass */
4138
            } else if (op < 10) {
4139
                /* Shift by immedaiate and narrow:
4140
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4141
                shift = shift - (1 << (size + 3));
4142
                size++;
4143
                if (size == 3) {
4144
                    count = q + 1;
4145
                } else {
4146
                    count = q ? 4: 2;
4147
                }
4148
                switch (size) {
4149
                case 1:
4150
                    imm = (uint16_t) shift;
4151
                    imm |= imm << 16;
4152
                    break;
4153
                case 2:
4154
                case 3:
4155
                    imm = shift;
4156
                    break;
4157
                default:
4158
                    abort();
4159
                }
4160

    
4161
                /* Processing MSB first means we need to do less shuffling at
4162
                   the end.  */
4163
                for (pass =  count - 1; pass >= 0; pass--) {
4164
                    /* Avoid clobbering the second operand before it has been
4165
                       written.  */
4166
                    n = pass;
4167
                    if (rd == rm)
4168
                        n ^= (count - 1);
4169
                    else
4170
                        n = pass;
4171

    
4172
                    if (size < 3) {
4173
                        /* Operands in T0 and T1.  */
4174
                        gen_op_movl_T1_im(imm);
4175
                        NEON_GET_REG(T0, rm, n);
4176
                    } else {
4177
                        /* Operands in {T0, T1} and env->vfp.scratch.  */
4178
                        gen_op_movl_T0_im(imm);
4179
                        gen_neon_movl_scratch_T0(0);
4180
                        gen_op_movl_T0_im((int32_t)imm >> 31);
4181
                        gen_neon_movl_scratch_T0(1);
4182
                        NEON_GET_REG(T0, rm, n * 2);
4183
                        NEON_GET_REG(T0, rm, n * 2 + 1);
4184
                    }
4185

    
4186
                    gen_neon_shift_im_narrow[q][u][size - 1]();
4187

    
4188
                    if (size < 3 && (pass & 1) == 0) {
4189
                        gen_neon_movl_scratch_T0(0);
4190
                    } else {
4191
                        uint32_t offset;
4192

    
4193
                        if (size < 3)
4194
                            gen_neon_movl_T1_scratch(0);
4195

    
4196
                        if (op == 8 && !u) {
4197
                            gen_neon_narrow[size - 1]();
4198
                        } else {
4199
                            if (op == 8)
4200
                                gen_neon_narrow_sats[size - 2]();
4201
                            else
4202
                                gen_neon_narrow_satu[size - 1]();
4203
                        }
4204
                        if (size == 3)
4205
                            offset = neon_reg_offset(rd, n);
4206
                        else
4207
                            offset = neon_reg_offset(rd, n >> 1);
4208
                        gen_op_neon_setreg_T0(offset);
4209
                    }
4210
                } /* for pass */
4211
            } else if (op == 10) {
4212
                /* VSHLL */
4213
                if (q)
4214
                    return 1;
4215
                for (pass = 0; pass < 2; pass++) {
4216
                    /* Avoid clobbering the input operand.  */
4217
                    if (rd == rm)
4218
                        n = 1 - pass;
4219
                    else
4220
                        n = pass;
4221

    
4222
                    NEON_GET_REG(T0, rm, n);
4223
                    GEN_NEON_INTEGER_OP(widen);
4224
                    if (shift != 0) {
4225
                        /* The shift is less than the width of the source
4226
                           type, so in some cases we can just
4227
                           shift the whole register.  */
4228
                        if (size == 1 || (size == 0 && u)) {
4229
                            gen_op_shll_T0_im(shift);
4230
                            gen_op_shll_T1_im(shift);
4231
                        } else {
4232
                            switch (size) {
4233
                            case 0: gen_op_neon_shll_u16(shift); break;
4234
                            case 2: gen_op_neon_shll_u64(shift); break;
4235
                            default: abort();
4236
                            }
4237
                        }
4238
                    }
4239
                    NEON_SET_REG(T0, rd, n * 2);
4240
                    NEON_SET_REG(T1, rd, n * 2 + 1);
4241
                }
4242
            } else if (op == 15 || op == 16) {
4243
                /* VCVT fixed-point.  */
4244
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4245
                    gen_op_vfp_getreg_F0s(neon_reg_offset(rm, pass));
4246
                    if (op & 1) {
4247
                        if (u)
4248
                            gen_op_vfp_ultos(shift);
4249
                        else
4250
                            gen_op_vfp_sltos(shift);
4251
                    } else {
4252
                        if (u)
4253
                            gen_op_vfp_touls(shift);
4254
                        else
4255
                            gen_op_vfp_tosls(shift);
4256
                    }
4257
                    gen_op_vfp_setreg_F0s(neon_reg_offset(rd, pass));
4258
                }
4259
            } else {
4260
                return 1;
4261
            }
4262
        } else { /* (insn & 0x00380080) == 0 */
4263
            int invert;
4264

    
4265
            op = (insn >> 8) & 0xf;
4266
            /* One register and immediate.  */
4267
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4268
            invert = (insn & (1 << 5)) != 0;
4269
            switch (op) {
4270
            case 0: case 1:
4271
                /* no-op */
4272
                break;
4273
            case 2: case 3:
4274
                imm <<= 8;
4275
                break;
4276
            case 4: case 5:
4277
                imm <<= 16;
4278
                break;
4279
            case 6: case 7:
4280
                imm <<= 24;
4281
                break;
4282
            case 8: case 9:
4283
                imm |= imm << 16;
4284
                break;
4285
            case 10: case 11:
4286
                imm = (imm << 8) | (imm << 24);
4287
                break;
4288
            case 12:
4289
                imm = (imm < 8) | 0xff;
4290
                break;
4291
            case 13:
4292
                imm = (imm << 16) | 0xffff;
4293
                break;
4294
            case 14:
4295
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4296
                if (invert)
4297
                    imm = ~imm;
4298
                break;
4299
            case 15:
4300
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4301
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4302
                break;
4303
            }
4304
            if (invert)
4305
                imm = ~imm;
4306

    
4307
            if (op != 14 || !invert)
4308
                gen_op_movl_T1_im(imm);
4309

    
4310
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4311
                if (op & 1 && op < 12) {
4312
                    NEON_GET_REG(T0, rd, pass);
4313
                    if (invert) {
4314
                        /* The immediate value has already been inverted, so
4315
                           BIC becomes AND.  */
4316
                        gen_op_andl_T0_T1();
4317
                    } else {
4318
                        gen_op_orl_T0_T1();
4319
                    }
4320
                    NEON_SET_REG(T0, rd, pass);
4321
                } else {
4322
                    if (op == 14 && invert) {
4323
                        uint32_t tmp;
4324
                        tmp = 0;
4325
                        for (n = 0; n < 4; n++) {
4326
                            if (imm & (1 << (n + (pass & 1) * 4)))
4327
                                tmp |= 0xff << (n * 8);
4328
                        }
4329
                        gen_op_movl_T1_im(tmp);
4330
                    }
4331
                    /* VMOV, VMVN.  */
4332
                    NEON_SET_REG(T1, rd, pass);
4333
                }
4334
            }
4335
        }
4336
    } else { /* (insn & 0x00800010 == 0x00800010) */
4337
        if (size != 3) {
4338
            op = (insn >> 8) & 0xf;
4339
            if ((insn & (1 << 6)) == 0) {
4340
                /* Three registers of different lengths.  */
4341
                int src1_wide;
4342
                int src2_wide;
4343
                int prewiden;
4344
                /* prewiden, src1_wide, src2_wide */
4345
                static const int neon_3reg_wide[16][3] = {
4346
                    {1, 0, 0}, /* VADDL */
4347
                    {1, 1, 0}, /* VADDW */
4348
                    {1, 0, 0}, /* VSUBL */
4349
                    {1, 1, 0}, /* VSUBW */
4350
                    {0, 1, 1}, /* VADDHN */
4351
                    {0, 0, 0}, /* VABAL */
4352
                    {0, 1, 1}, /* VSUBHN */
4353
                    {0, 0, 0}, /* VABDL */
4354
                    {0, 0, 0}, /* VMLAL */
4355
                    {0, 0, 0}, /* VQDMLAL */
4356
                    {0, 0, 0}, /* VMLSL */
4357
                    {0, 0, 0}, /* VQDMLSL */
4358
                    {0, 0, 0}, /* Integer VMULL */
4359
                    {0, 0, 0}, /* VQDMULL */
4360
                    {0, 0, 0}  /* Polynomial VMULL */
4361
                };
4362

    
4363
                prewiden = neon_3reg_wide[op][0];
4364
                src1_wide = neon_3reg_wide[op][1];
4365
                src2_wide = neon_3reg_wide[op][2];
4366

    
4367
                /* Avoid overlapping operands.  Wide source operands are
4368
                   always aligned so will never overlap with wide
4369
                   destinations in problematic ways.  */
4370
                if (rd == rm) {
4371
                    NEON_GET_REG(T2, rm, 1);
4372
                } else if (rd == rn) {
4373
                    NEON_GET_REG(T2, rn, 1);
4374
                }
4375
                for (pass = 0; pass < 2; pass++) {
4376
                    /* Load the second operand into env->vfp.scratch.
4377
                       Also widen narrow operands.  */
4378
                    if (pass == 1 && rd == rm) {
4379
                        if (prewiden) {
4380
                            gen_op_movl_T0_T2();
4381
                        } else {
4382
                            gen_op_movl_T1_T2();
4383
                        }
4384
                    } else {
4385
                        if (src2_wide) {
4386
                            NEON_GET_REG(T0, rm, pass * 2);
4387
                            NEON_GET_REG(T1, rm, pass * 2 + 1);
4388
                        } else {
4389
                            if (prewiden) {
4390
                                NEON_GET_REG(T0, rm, pass);
4391
                            } else {
4392
                                NEON_GET_REG(T1, rm, pass);
4393
                            }
4394
                        }
4395
                    }
4396
                    if (prewiden && !src2_wide) {
4397
                        GEN_NEON_INTEGER_OP(widen);
4398
                    }
4399
                    if (prewiden || src2_wide) {
4400
                        gen_neon_movl_scratch_T0(0);
4401
                        gen_neon_movl_scratch_T1(1);
4402
                    }
4403

    
4404
                    /* Load the first operand.  */
4405
                    if (pass == 1 && rd == rn) {
4406
                        gen_op_movl_T0_T2();
4407
                    } else {
4408
                        if (src1_wide) {
4409
                            NEON_GET_REG(T0, rn, pass * 2);
4410
                            NEON_GET_REG(T1, rn, pass * 2 + 1);
4411
                        } else {
4412
                            NEON_GET_REG(T0, rn, pass);
4413
                        }
4414
                    }
4415
                    if (prewiden && !src1_wide) {
4416
                        GEN_NEON_INTEGER_OP(widen);
4417
                    }
4418
                    switch (op) {
4419
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4420
                        switch (size) {
4421
                        case 0: gen_op_neon_addl_u16(); break;
4422
                        case 1: gen_op_neon_addl_u32(); break;
4423
                        case 2: gen_op_neon_addl_u64(); break;
4424
                        default: abort();
4425
                        }
4426
                        break;
4427
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4428
                        switch (size) {
4429
                        case 0: gen_op_neon_subl_u16(); break;
4430
                        case 1: gen_op_neon_subl_u32(); break;
4431
                        case 2: gen_op_neon_subl_u64(); break;
4432
                        default: abort();
4433
                        }
4434
                        break;
4435
                    case 5: case 7: /* VABAL, VABDL */
4436
                        switch ((size << 1) | u) {
4437
                        case 0: gen_op_neon_abdl_s16(); break;
4438
                        case 1: gen_op_neon_abdl_u16(); break;
4439
                        case 2: gen_op_neon_abdl_s32(); break;
4440
                        case 3: gen_op_neon_abdl_u32(); break;
4441
                        case 4: gen_op_neon_abdl_s64(); break;
4442
                        case 5: gen_op_neon_abdl_u64(); break;
4443
                        default: abort();
4444
                        }
4445
                        break;
4446
                    case 8: case 9: case 10: case 11: case 12: case 13:
4447
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4448
                        switch ((size << 1) | u) {
4449
                        case 0: gen_op_neon_mull_s8(); break;
4450
                        case 1: gen_op_neon_mull_u8(); break;
4451
                        case 2: gen_op_neon_mull_s16(); break;
4452
                        case 3: gen_op_neon_mull_u16(); break;
4453
                        case 4: gen_op_imull_T0_T1(); break;
4454
                        case 5: gen_op_mull_T0_T1(); break;
4455
                        default: abort();
4456
                        }
4457
                        break;
4458
                    case 14: /* Polynomial VMULL */
4459
                        cpu_abort(env, "Polynomial VMULL not implemented");
4460

    
4461
                    default: /* 15 is RESERVED.  */
4462
                        return 1;
4463
                    }
4464
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4465
                        /* Accumulate.  */
4466
                        if (op == 10 || op == 11) {
4467
                            switch (size) {
4468
                            case 0: gen_op_neon_negl_u16(); break;
4469
                            case 1: gen_op_neon_negl_u32(); break;
4470
                            case 2: gen_op_neon_negl_u64(); break;
4471
                            default: abort();
4472
                            }
4473
                        }
4474

    
4475
                        gen_neon_movl_scratch_T0(0);
4476
                        gen_neon_movl_scratch_T1(1);
4477

    
4478
                        if (op != 13) {
4479
                            NEON_GET_REG(T0, rd, pass * 2);
4480
                            NEON_GET_REG(T1, rd, pass * 2 + 1);
4481
                        }
4482

    
4483
                        switch (op) {
4484
                        case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4485
                            switch (size) {
4486
                            case 0: gen_op_neon_addl_u16(); break;
4487
                            case 1: gen_op_neon_addl_u32(); break;
4488
                            case 2: gen_op_neon_addl_u64(); break;
4489
                            default: abort();
4490
                            }
4491
                            break;
4492
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
4493
                            switch (size) {
4494
                            case 1: gen_op_neon_addl_saturate_s32(); break;
4495
                            case 2: gen_op_neon_addl_saturate_s64(); break;
4496
                            default: abort();
4497
                            }
4498
                            /* Fall through.  */
4499
                        case 13: /* VQDMULL */
4500
                            switch (size) {
4501
                            case 1: gen_op_neon_addl_saturate_s32(); break;
4502
                            case 2: gen_op_neon_addl_saturate_s64(); break;
4503
                            default: abort();
4504
                            }
4505
                            break;
4506
                        default:
4507
                            abort();
4508
                        }
4509
                        NEON_SET_REG(T0, rd, pass * 2);
4510
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4511
                    } else if (op == 4 || op == 6) {
4512
                        /* Narrowing operation.  */
4513
                        if (u) {
4514
                            switch (size) {
4515
                            case 0: gen_op_neon_narrow_high_u8(); break;
4516
                            case 1: gen_op_neon_narrow_high_u16(); break;
4517
                            case 2: gen_op_movl_T0_T1(); break;
4518
                            default: abort();
4519
                            }
4520
                        } else {
4521
                            switch (size) {
4522
                            case 0: gen_op_neon_narrow_high_round_u8(); break;
4523
                            case 1: gen_op_neon_narrow_high_round_u16(); break;
4524
                            case 2: gen_op_neon_narrow_high_round_u32(); break;
4525
                            default: abort();
4526
                            }
4527
                        }
4528
                        NEON_SET_REG(T0, rd, pass);
4529
                    } else {
4530
                        /* Write back the result.  */
4531
                        NEON_SET_REG(T0, rd, pass * 2);
4532
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4533
                    }
4534
                }
4535
            } else {
4536
                /* Two registers and a scalar.  */
4537
                switch (op) {
4538
                case 0: /* Integer VMLA scalar */
4539
                case 1: /* Float VMLA scalar */
4540
                case 4: /* Integer VMLS scalar */
4541
                case 5: /* Floating point VMLS scalar */
4542
                case 8: /* Integer VMUL scalar */
4543
                case 9: /* Floating point VMUL scalar */
4544
                case 12: /* VQDMULH scalar */
4545
                case 13: /* VQRDMULH scalar */
4546
                    gen_neon_get_scalar(size, rm);
4547
                    gen_op_movl_T2_T0();
4548
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
4549
                        if (pass != 0)
4550
                            gen_op_movl_T0_T2();
4551
                        NEON_GET_REG(T1, rn, pass);
4552
                        if (op == 12) {
4553
                            if (size == 1) {
4554
                                gen_op_neon_qdmulh_s16();
4555
                            } else {
4556
                                gen_op_neon_qdmulh_s32();
4557
                            }
4558
                        } else if (op == 13) {
4559
                            if (size == 1) {
4560
                                gen_op_neon_qrdmulh_s16();
4561
                            } else {
4562
                                gen_op_neon_qrdmulh_s32();
4563
                            }
4564
                        } else if (op & 1) {
4565
                            gen_op_neon_mul_f32();
4566
                        } else {
4567
                            switch (size) {
4568
                            case 0: gen_op_neon_mul_u8(); break;
4569
                            case 1: gen_op_neon_mul_u16(); break;
4570
                            case 2: gen_op_mul_T0_T1(); break;
4571
                            default: return 1;
4572
                            }
4573
                        }
4574
                        if (op < 8) {
4575
                            /* Accumulate.  */
4576
                            NEON_GET_REG(T1, rd, pass);
4577
                            switch (op) {
4578
                            case 0:
4579
                                gen_neon_add(size);
4580
                                break;
4581
                            case 1:
4582
                                gen_op_neon_add_f32();
4583
                                break;
4584
                            case 4:
4585
                                switch (size) {
4586
                                case 0: gen_op_neon_rsb_u8(); break;
4587
                                case 1: gen_op_neon_rsb_u16(); break;
4588
                                case 2: gen_op_rsbl_T0_T1(); break;
4589
                                default: return 1;
4590
                                }
4591
                                break;
4592
                            case 5:
4593
                                gen_op_neon_rsb_f32();
4594
                                break;
4595
                            default:
4596
                                abort();
4597
                            }
4598
                        }
4599
                        NEON_SET_REG(T0, rd, pass);
4600
                    }
4601
                    break;
4602
                case 2: /* VMLAL sclar */
4603
                case 3: /* VQDMLAL scalar */
4604
                case 6: /* VMLSL scalar */
4605
                case 7: /* VQDMLSL scalar */
4606
                case 10: /* VMULL scalar */
4607
                case 11: /* VQDMULL scalar */
4608
                    if (rd == rn) {
4609
                        /* Save overlapping operands before they are
4610
                           clobbered.  */
4611
                        NEON_GET_REG(T0, rn, 1);
4612
                        gen_neon_movl_scratch_T0(2);
4613
                    }
4614
                    gen_neon_get_scalar(size, rm);
4615
                    gen_op_movl_T2_T0();
4616
                    for (pass = 0; pass < 2; pass++) {
4617
                        if (pass != 0) {
4618
                            gen_op_movl_T0_T2();
4619
                        }
4620
                        if (pass != 0 && rd == rn) {
4621
                            gen_neon_movl_T1_scratch(2);
4622
                        } else {
4623
                            NEON_GET_REG(T1, rn, pass);
4624
                        }
4625
                        switch ((size << 1) | u) {
4626
                        case 0: gen_op_neon_mull_s8(); break;
4627
                        case 1: gen_op_neon_mull_u8(); break;
4628
                        case 2: gen_op_neon_mull_s16(); break;
4629
                        case 3: gen_op_neon_mull_u16(); break;
4630
                        case 4: gen_op_imull_T0_T1(); break;
4631
                        case 5: gen_op_mull_T0_T1(); break;
4632
                        default: abort();
4633
                        }
4634
                        if (op == 6 || op == 7) {
4635
                            switch (size) {
4636
                            case 0: gen_op_neon_negl_u16(); break;
4637
                            case 1: gen_op_neon_negl_u32(); break;
4638
                            case 2: gen_op_neon_negl_u64(); break;
4639
                            default: abort();
4640
                            }
4641
                        }
4642
                        gen_neon_movl_scratch_T0(0);
4643
                        gen_neon_movl_scratch_T1(1);
4644
                        NEON_GET_REG(T0, rd, pass * 2);
4645
                        NEON_GET_REG(T1, rd, pass * 2 + 1);
4646
                        switch (op) {
4647
                        case 2: case 6:
4648
                            switch (size) {
4649
                            case 0: gen_op_neon_addl_u16(); break;
4650
                            case 1: gen_op_neon_addl_u32(); break;
4651
                            case 2: gen_op_neon_addl_u64(); break;
4652
                            default: abort();
4653
                            }
4654
                            break;
4655
                        case 3: case 7:
4656
                            switch (size) {
4657
                            case 1:
4658
                                gen_op_neon_addl_saturate_s32();
4659
                                gen_op_neon_addl_saturate_s32();
4660
                                break;
4661
                            case 2:
4662
                                gen_op_neon_addl_saturate_s64();
4663
                                gen_op_neon_addl_saturate_s64();
4664
                                break;
4665
                            default: abort();
4666
                            }
4667
                            break;
4668
                        case 10:
4669
                            /* no-op */
4670
                            break;
4671
                        case 11:
4672
                            switch (size) {
4673
                            case 1: gen_op_neon_addl_saturate_s32(); break;
4674
                            case 2: gen_op_neon_addl_saturate_s64(); break;
4675
                            default: abort();
4676
                            }
4677
                            break;
4678
                        default:
4679
                            abort();
4680
                        }
4681
                        NEON_SET_REG(T0, rd, pass * 2);
4682
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4683
                    }
4684
                    break;
4685
                default: /* 14 and 15 are RESERVED */
4686
                    return 1;
4687
                }
4688
            }
4689
        } else { /* size == 3 */
4690
            if (!u) {
4691
                /* Extract.  */
4692
                int reg;
4693
                imm = (insn >> 8) & 0xf;
4694
                reg = rn;
4695
                count = q ? 4 : 2;
4696
                n = imm >> 2;
4697
                NEON_GET_REG(T0, reg, n);
4698
                for (pass = 0; pass < count; pass++) {
4699
                    n++;
4700
                    if (n > count) {
4701
                        reg = rm;
4702
                        n -= count;
4703
                    }
4704
                    if (imm & 3) {
4705
                        NEON_GET_REG(T1, reg, n);
4706
                        gen_op_neon_extract((insn << 3) & 0x1f);
4707
                    }
4708
                    /* ??? This is broken if rd and rm overlap */
4709
                    NEON_SET_REG(T0, rd, pass);
4710
                    if (imm & 3) {
4711
                        gen_op_movl_T0_T1();
4712
                    } else {
4713
                        NEON_GET_REG(T0, reg, n);
4714
                    }
4715
                }
4716
            } else if ((insn & (1 << 11)) == 0) {
4717
                /* Two register misc.  */
4718
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
4719
                size = (insn >> 18) & 3;
4720
                switch (op) {
4721
                case 0: /* VREV64 */
4722
                    if (size == 3)
4723
                        return 1;
4724
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
4725
                        NEON_GET_REG(T0, rm, pass * 2);
4726
                        NEON_GET_REG(T1, rm, pass * 2 + 1);
4727
                        switch (size) {
4728
                        case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4729
                        case 1: gen_swap_half(cpu_T[0]); break;
4730
                        case 2: /* no-op */ break;
4731
                        default: abort();
4732
                        }
4733
                        NEON_SET_REG(T0, rd, pass * 2 + 1);
4734
                        if (size == 2) {
4735
                            NEON_SET_REG(T1, rd, pass * 2);
4736
                        } else {
4737
                            gen_op_movl_T0_T1();
4738
                            switch (size) {
4739
                            case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4740
                            case 1: gen_swap_half(cpu_T[0]); break;
4741
                            default: abort();
4742
                            }
4743
                            NEON_SET_REG(T0, rd, pass * 2);
4744
                        }
4745
                    }
4746
                    break;
4747
                case 4: case 5: /* VPADDL */
4748
                case 12: case 13: /* VPADAL */
4749
                    if (size < 2)
4750
                        goto elementwise;
4751
                    if (size == 3)
4752
                        return 1;
4753
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
4754
                        NEON_GET_REG(T0, rm, pass * 2);
4755
                        NEON_GET_REG(T1, rm, pass * 2 + 1);
4756
                        if (op & 1)
4757
                            gen_op_neon_paddl_u32();
4758
                        else
4759
                            gen_op_neon_paddl_s32();
4760
                        if (op >= 12) {
4761
                            /* Accumulate.  */
4762
                            gen_neon_movl_scratch_T0(0);
4763
                            gen_neon_movl_scratch_T1(1);
4764

    
4765
                            NEON_GET_REG(T0, rd, pass * 2);
4766
                            NEON_GET_REG(T1, rd, pass * 2 + 1);
4767
                            gen_op_neon_addl_u64();
4768
                        }
4769
                        NEON_SET_REG(T0, rd, pass * 2);
4770
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4771
                    }
4772
                    break;
4773
                case 33: /* VTRN */
4774
                    if (size == 2) {
4775
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
4776
                            NEON_GET_REG(T0, rm, n);
4777
                            NEON_GET_REG(T1, rd, n + 1);
4778
                            NEON_SET_REG(T1, rm, n);
4779
                            NEON_SET_REG(T0, rd, n + 1);
4780
                        }
4781
                    } else {
4782
                        goto elementwise;
4783
                    }
4784
                    break;
4785
                case 34: /* VUZP */
4786
                    /* Reg  Before       After
4787
                       Rd   A3 A2 A1 A0  B2 B0 A2 A0
4788
                       Rm   B3 B2 B1 B0  B3 B1 A3 A1
4789
                     */
4790
                    if (size == 3)
4791
                        return 1;
4792
                    gen_neon_unzip(rd, q, 0, size);
4793
                    gen_neon_unzip(rm, q, 4, size);
4794
                    if (q) {
4795
                        static int unzip_order_q[8] =
4796
                            {0, 2, 4, 6, 1, 3, 5, 7};
4797
                        for (n = 0; n < 8; n++) {
4798
                            int reg = (n < 4) ? rd : rm;
4799
                            gen_neon_movl_T0_scratch(unzip_order_q[n]);
4800
                            NEON_SET_REG(T0, reg, n % 4);
4801
                        }
4802
                    } else {
4803
                        static int unzip_order[4] =
4804
                            {0, 4, 1, 5};
4805
                        for (n = 0; n < 4; n++) {
4806
                            int reg = (n < 2) ? rd : rm;
4807
                            gen_neon_movl_T0_scratch(unzip_order[n]);
4808
                            NEON_SET_REG(T0, reg, n % 2);
4809
                        }
4810
                    }
4811
                    break;
4812
                case 35: /* VZIP */
4813
                    /* Reg  Before       After
4814
                       Rd   A3 A2 A1 A0  B1 A1 B0 A0
4815
                       Rm   B3 B2 B1 B0  B3 A3 B2 A2
4816
                     */
4817
                    if (size == 3)
4818
                        return 1;
4819
                    count = (q ? 4 : 2);
4820
                    for (n = 0; n < count; n++) {
4821
                        NEON_GET_REG(T0, rd, n);
4822
                        NEON_GET_REG(T1, rd, n);
4823
                        switch (size) {
4824
                        case 0: gen_op_neon_zip_u8(); break;
4825
                        case 1: gen_op_neon_zip_u16(); break;
4826
                        case 2: /* no-op */; break;
4827
                        default: abort();
4828
                        }
4829
                        gen_neon_movl_scratch_T0(n * 2);
4830
                        gen_neon_movl_scratch_T1(n * 2 + 1);
4831
                    }
4832
                    for (n = 0; n < count * 2; n++) {
4833
                        int reg = (n < count) ? rd : rm;
4834
                        gen_neon_movl_T0_scratch(n);
4835
                        NEON_SET_REG(T0, reg, n % count);
4836
                    }
4837
                    break;
4838
                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
4839
                    for (pass = 0; pass < 2; pass++) {
4840
                        if (rd == rm + 1) {
4841
                            n = 1 - pass;
4842
                        } else {
4843
                            n = pass;
4844
                        }
4845
                        NEON_GET_REG(T0, rm, n * 2);
4846
                        NEON_GET_REG(T1, rm, n * 2 + 1);
4847
                        if (op == 36 && q == 0) {
4848
                            switch (size) {
4849
                            case 0: gen_op_neon_narrow_u8(); break;
4850
                            case 1: gen_op_neon_narrow_u16(); break;
4851
                            case 2: /* no-op */ break;
4852
                            default: return 1;
4853
                            }
4854
                        } else if (q) {
4855
                            switch (size) {
4856
                            case 0: gen_op_neon_narrow_sat_u8(); break;
4857
                            case 1: gen_op_neon_narrow_sat_u16(); break;
4858
                            case 2: gen_op_neon_narrow_sat_u32(); break;
4859
                            default: return 1;
4860
                            }
4861
                        } else {
4862
                            switch (size) {
4863
                            case 0: gen_op_neon_narrow_sat_s8(); break;
4864
                            case 1: gen_op_neon_narrow_sat_s16(); break;
4865
                            case 2: gen_op_neon_narrow_sat_s32(); break;
4866
                            default: return 1;
4867
                            }
4868
                        }
4869
                        NEON_SET_REG(T0, rd, n);
4870
                    }
4871
                    break;
4872
                case 38: /* VSHLL */
4873
                    if (q)
4874
                        return 1;
4875
                    if (rm == rd) {
4876
                        NEON_GET_REG(T2, rm, 1);
4877
                    }
4878
                    for (pass = 0; pass < 2; pass++) {
4879
                        if (pass == 1 && rm == rd) {
4880
                            gen_op_movl_T0_T2();
4881
                        } else {
4882
                            NEON_GET_REG(T0, rm, pass);
4883
                        }
4884
                        switch (size) {
4885
                        case 0: gen_op_neon_widen_high_u8(); break;
4886
                        case 1: gen_op_neon_widen_high_u16(); break;
4887
                        case 2:
4888
                            gen_op_movl_T1_T0();
4889
                            gen_op_movl_T0_im(0);
4890
                            break;
4891
                        default: return 1;
4892
                        }
4893
                        NEON_SET_REG(T0, rd, pass * 2);
4894
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4895
                    }
4896
                    break;
4897
                default:
4898
                elementwise:
4899
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
4900
                        if (op == 30 || op == 31 || op >= 58) {
4901
                            gen_op_vfp_getreg_F0s(neon_reg_offset(rm, pass));
4902
                        } else {
4903
                            NEON_GET_REG(T0, rm, pass);
4904
                        }
4905
                        switch (op) {
4906
                        case 1: /* VREV32 */
4907
                            switch (size) {
4908
                            case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4909
                            case 1: gen_swap_half(cpu_T[0]); break;
4910
                            default: return 1;
4911
                            }
4912
                            break;
4913
                        case 2: /* VREV16 */
4914
                            if (size != 0)
4915
                                return 1;
4916
                            gen_rev16(cpu_T[0]);
4917
                            break;
4918
                        case 4: case 5: /* VPADDL */
4919
                        case 12: case 13: /* VPADAL */
4920
                            switch ((size << 1) | (op & 1)) {
4921
                            case 0: gen_op_neon_paddl_s8(); break;
4922
                            case 1: gen_op_neon_paddl_u8(); break;
4923
                            case 2: gen_op_neon_paddl_s16(); break;
4924
                            case 3: gen_op_neon_paddl_u16(); break;
4925
                            default: abort();
4926
                            }
4927
                            if (op >= 12) {
4928
                                /* Accumulate */
4929
                                NEON_GET_REG(T1, rd, pass);
4930
                                switch (size) {
4931
                                case 0: gen_op_neon_add_u16(); break;
4932
                                case 1: gen_op_addl_T0_T1(); break;
4933
                                default: abort();
4934
                                }
4935
                            }
4936
                            break;
4937
                        case 8: /* CLS */
4938
                            switch (size) {
4939
                            case 0: gen_op_neon_cls_s8(); break;
4940
                            case 1: gen_op_neon_cls_s16(); break;
4941
                            case 2: gen_op_neon_cls_s32(); break;
4942
                            default: return 1;
4943
                            }
4944
                            break;
4945
                        case 9: /* CLZ */
4946
                            switch (size) {
4947
                            case 0: gen_op_neon_clz_u8(); break;
4948
                            case 1: gen_op_neon_clz_u16(); break;
4949
                            case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
4950
                            default: return 1;
4951
                            }
4952
                            break;
4953
                        case 10: /* CNT */
4954
                            if (size != 0)
4955
                                return 1;
4956
                            gen_op_neon_cnt_u8();
4957
                            break;
4958
                        case 11: /* VNOT */
4959
                            if (size != 0)
4960
                                return 1;
4961
                            gen_op_notl_T0();
4962
                            break;
4963
                        case 14: /* VQABS */
4964
                            switch (size) {
4965
                            case 0: gen_op_neon_qabs_s8(); break;
4966
                            case 1: gen_op_neon_qabs_s16(); break;
4967
                            case 2: gen_op_neon_qabs_s32(); break;
4968
                            default: return 1;
4969
                            }
4970
                            break;
4971
                        case 15: /* VQNEG */
4972
                            switch (size) {
4973
                            case 0: gen_op_neon_qneg_s8(); break;
4974
                            case 1: gen_op_neon_qneg_s16(); break;
4975
                            case 2: gen_op_neon_qneg_s32(); break;
4976
                            default: return 1;
4977
                            }
4978
                            break;
4979
                        case 16: case 19: /* VCGT #0, VCLE #0 */
4980
                            gen_op_movl_T1_im(0);
4981
                            switch(size) {
4982
                            case 0: gen_op_neon_cgt_s8(); break;
4983
                            case 1: gen_op_neon_cgt_s16(); break;
4984
                            case 2: gen_op_neon_cgt_s32(); break;
4985
                            default: return 1;
4986
                            }
4987
                            if (op == 19)
4988
                                gen_op_notl_T0();
4989
                            break;
4990
                        case 17: case 20: /* VCGE #0, VCLT #0 */
4991
                            gen_op_movl_T1_im(0);
4992
                            switch(size) {
4993
                            case 0: gen_op_neon_cge_s8(); break;
4994
                            case 1: gen_op_neon_cge_s16(); break;
4995
                            case 2: gen_op_neon_cge_s32(); break;
4996
                            default: return 1;
4997
                            }
4998
                            if (op == 20)
4999
                                gen_op_notl_T0();
5000
                            break;
5001
                        case 18: /* VCEQ #0 */
5002
                            gen_op_movl_T1_im(0);
5003
                            switch(size) {
5004
                            case 0: gen_op_neon_ceq_u8(); break;
5005
                            case 1: gen_op_neon_ceq_u16(); break;
5006
                            case 2: gen_op_neon_ceq_u32(); break;
5007
                            default: return 1;
5008
                            }
5009
                            break;
5010
                        case 22: /* VABS */
5011
                            switch(size) {
5012
                            case 0: gen_op_neon_abs_s8(); break;
5013
                            case 1: gen_op_neon_abs_s16(); break;
5014
                            case 2: gen_op_neon_abs_s32(); break;
5015
                            default: return 1;
5016
                            }
5017
                            break;
5018
                        case 23: /* VNEG */
5019
                            gen_op_movl_T1_im(0);
5020
                            switch(size) {
5021
                            case 0: gen_op_neon_rsb_u8(); break;
5022
                            case 1: gen_op_neon_rsb_u16(); break;
5023
                            case 2: gen_op_rsbl_T0_T1(); break;
5024
                            default: return 1;
5025
                            }
5026
                            break;
5027
                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5028
                            gen_op_movl_T1_im(0);
5029
                            gen_op_neon_cgt_f32();
5030
                            if (op == 27)
5031
                                gen_op_notl_T0();
5032
                            break;
5033
                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5034
                            gen_op_movl_T1_im(0);
5035
                            gen_op_neon_cge_f32();
5036
                            if (op == 28)
5037
                                gen_op_notl_T0();
5038
                            break;
5039
                        case 26: /* Float VCEQ #0 */
5040
                            gen_op_movl_T1_im(0);
5041
                            gen_op_neon_ceq_f32();
5042
                            break;
5043
                        case 30: /* Float VABS */
5044
                            gen_op_vfp_abss();
5045
                            break;
5046
                        case 31: /* Float VNEG */
5047
                            gen_op_vfp_negs();
5048
                            break;
5049
                        case 32: /* VSWP */
5050
                            NEON_GET_REG(T1, rd, pass);
5051
                            NEON_SET_REG(T1, rm, pass);
5052
                            break;
5053
                        case 33: /* VTRN */
5054
                            NEON_GET_REG(T1, rd, pass);
5055
                            switch (size) {
5056
                            case 0: gen_op_neon_trn_u8(); break;
5057
                            case 1: gen_op_neon_trn_u16(); break;
5058
                            case 2: abort();
5059
                            default: return 1;
5060
                            }
5061
                            NEON_SET_REG(T1, rm, pass);
5062
                            break;
5063
                        case 56: /* Integer VRECPE */
5064
                            gen_op_neon_recpe_u32();
5065
                            break;
5066
                        case 57: /* Integer VRSQRTE */
5067
                            gen_op_neon_rsqrte_u32();
5068
                            break;
5069
                        case 58: /* Float VRECPE */
5070
                            gen_op_neon_recpe_f32();
5071
                            break;
5072
                        case 59: /* Float VRSQRTE */
5073
                            gen_op_neon_rsqrte_f32();
5074
                            break;
5075
                        case 60: /* VCVT.F32.S32 */
5076
                            gen_op_vfp_tosizs();
5077
                            break;
5078
                        case 61: /* VCVT.F32.U32 */
5079
                            gen_op_vfp_touizs();
5080
                            break;
5081
                        case 62: /* VCVT.S32.F32 */
5082
                            gen_op_vfp_sitos();
5083
                            break;
5084
                        case 63: /* VCVT.U32.F32 */
5085
                            gen_op_vfp_uitos();
5086
                            break;
5087
                        default:
5088
                            /* Reserved: 21, 29, 39-56 */
5089
                            return 1;
5090
                        }
5091
                        if (op == 30 || op == 31 || op >= 58) {
5092
                            gen_op_vfp_setreg_F0s(neon_reg_offset(rm, pass));
5093
                        } else {
5094
                            NEON_SET_REG(T0, rd, pass);
5095
                        }
5096
                    }
5097
                    break;
5098
                }
5099
            } else if ((insn & (1 << 10)) == 0) {
5100
                /* VTBL, VTBX.  */
5101
                n = (insn >> 5) & 0x18;
5102
                NEON_GET_REG(T1, rm, 0);
5103
                if (insn & (1 << 6)) {
5104
                    NEON_GET_REG(T0, rd, 0);
5105
                } else {
5106
                    gen_op_movl_T0_im(0);
5107
                }
5108
                gen_op_neon_tbl(rn, n);
5109
                gen_op_movl_T2_T0();
5110
                NEON_GET_REG(T1, rm, 1);
5111
                if (insn & (1 << 6)) {
5112
                    NEON_GET_REG(T0, rd, 0);
5113
                } else {
5114
                    gen_op_movl_T0_im(0);
5115
                }
5116
                gen_op_neon_tbl(rn, n);
5117
                NEON_SET_REG(T2, rd, 0);
5118
                NEON_SET_REG(T0, rd, 1);
5119
            } else if ((insn & 0x380) == 0) {
5120
                /* VDUP */
5121
                if (insn & (1 << 19)) {
5122
                    NEON_SET_REG(T0, rm, 1);
5123
                } else {
5124
                    NEON_SET_REG(T0, rm, 0);
5125
                }
5126
                if (insn & (1 << 16)) {
5127
                    gen_op_neon_dup_u8(((insn >> 17) & 3) * 8);
5128
                } else if (insn & (1 << 17)) {
5129
                    if ((insn >> 18) & 1)
5130
                        gen_op_neon_dup_high16();
5131
                    else
5132
                        gen_op_neon_dup_low16();
5133
                }
5134
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5135
                    NEON_SET_REG(T0, rd, pass);
5136
                }
5137
            } else {
5138
                return 1;
5139
            }
5140
        }
5141
    }
5142
    return 0;
5143
}
5144

    
5145
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5146
{
5147
    int cpnum;
5148

    
5149
    cpnum = (insn >> 8) & 0xf;
5150
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5151
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5152
        return 1;
5153

    
5154
    switch (cpnum) {
5155
      case 0:
5156
      case 1:
5157
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5158
            return disas_iwmmxt_insn(env, s, insn);
5159
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5160
            return disas_dsp_insn(env, s, insn);
5161
        }
5162
        return 1;
5163
    case 10:
5164
    case 11:
5165
        return disas_vfp_insn (env, s, insn);
5166
    case 15:
5167
        return disas_cp15_insn (env, s, insn);
5168
    default:
5169
        /* Unknown coprocessor.  See if the board has hooked it.  */
5170
        return disas_cp_insn (env, s, insn);
5171
    }
5172
}
5173

    
5174
static void disas_arm_insn(CPUState * env, DisasContext *s)
5175
{
5176
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5177
    TCGv tmp;
5178
    TCGv tmp2;
5179
    TCGv tmp3;
5180
    TCGv addr;
5181

    
5182
    insn = ldl_code(s->pc);
5183
    s->pc += 4;
5184

    
5185
    /* M variants do not implement ARM mode.  */
5186
    if (IS_M(env))
5187
        goto illegal_op;
5188
    cond = insn >> 28;
5189
    if (cond == 0xf){
5190
        /* Unconditional instructions.  */
5191
        if (((insn >> 25) & 7) == 1) {
5192
            /* NEON Data processing.  */
5193
            if (!arm_feature(env, ARM_FEATURE_NEON))
5194
                goto illegal_op;
5195

    
5196
            if (disas_neon_data_insn(env, s, insn))
5197
                goto illegal_op;
5198
            return;
5199
        }
5200
        if ((insn & 0x0f100000) == 0x04000000) {
5201
            /* NEON load/store.  */
5202
            if (!arm_feature(env, ARM_FEATURE_NEON))
5203
                goto illegal_op;
5204

    
5205
            if (disas_neon_ls_insn(env, s, insn))
5206
                goto illegal_op;
5207
            return;
5208
        }
5209
        if ((insn & 0x0d70f000) == 0x0550f000)
5210
            return; /* PLD */
5211
        else if ((insn & 0x0ffffdff) == 0x01010000) {
5212
            ARCH(6);
5213
            /* setend */
5214
            if (insn & (1 << 9)) {
5215
                /* BE8 mode not implemented.  */
5216
                goto illegal_op;
5217
            }
5218
            return;
5219
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
5220
            switch ((insn >> 4) & 0xf) {
5221
            case 1: /* clrex */
5222
                ARCH(6K);
5223
                gen_op_clrex();
5224
                return;
5225
            case 4: /* dsb */
5226
            case 5: /* dmb */
5227
            case 6: /* isb */
5228
                ARCH(7);
5229
                /* We don't emulate caches so these are a no-op.  */
5230
                return;
5231
            default:
5232
                goto illegal_op;
5233
            }
5234
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5235
            /* srs */
5236
            uint32_t offset;
5237
            if (IS_USER(s))
5238
                goto illegal_op;
5239
            ARCH(6);
5240
            op1 = (insn & 0x1f);
5241
            if (op1 == (env->uncached_cpsr & CPSR_M)) {
5242
                addr = load_reg(s, 13);
5243
            } else {
5244
                addr = new_tmp();
5245
                gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5246
            }
5247
            i = (insn >> 23) & 3;
5248
            switch (i) {
5249
            case 0: offset = -4; break; /* DA */
5250
            case 1: offset = -8; break; /* DB */
5251
            case 2: offset = 0; break; /* IA */
5252
            case 3: offset = 4; break; /* IB */
5253
            default: abort();
5254
            }
5255
            if (offset)
5256
                tcg_gen_addi_i32(addr, addr, offset);
5257
            tmp = load_reg(s, 14);
5258
            gen_st32(tmp, addr, 0);
5259
            tmp = new_tmp();
5260
            gen_helper_cpsr_read(tmp);
5261
            tcg_gen_addi_i32(addr, addr, 4);
5262
            gen_st32(tmp, addr, 0);
5263
            if (insn & (1 << 21)) {
5264
                /* Base writeback.  */
5265
                switch (i) {
5266
                case 0: offset = -8; break;
5267
                case 1: offset = -4; break;
5268
                case 2: offset = 4; break;
5269
                case 3: offset = 0; break;
5270
                default: abort();
5271
                }
5272
                if (offset)
5273
                    tcg_gen_addi_i32(addr, tmp, offset);
5274
                if (op1 == (env->uncached_cpsr & CPSR_M)) {
5275
                    gen_movl_reg_T1(s, 13);
5276
                } else {
5277
                    gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5278
                }
5279
            } else {
5280
                dead_tmp(addr);
5281
            }
5282
        } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5283
            /* rfe */
5284
            uint32_t offset;
5285
            if (IS_USER(s))
5286
                goto illegal_op;
5287
            ARCH(6);
5288
            rn = (insn >> 16) & 0xf;
5289
            addr = load_reg(s, rn);
5290
            i = (insn >> 23) & 3;
5291
            switch (i) {
5292
            case 0: offset = -4; break; /* DA */
5293
            case 1: offset = -8; break; /* DB */
5294
            case 2: offset = 0; break; /* IA */
5295
            case 3: offset = 4; break; /* IB */
5296
            default: abort();
5297
            }
5298
            if (offset)
5299
                tcg_gen_addi_i32(addr, addr, offset);
5300
            /* Load PC into tmp and CPSR into tmp2.  */
5301
            tmp = gen_ld32(addr, 0);
5302
            tcg_gen_addi_i32(addr, addr, 4);
5303
            tmp2 = gen_ld32(addr, 0);
5304
            if (insn & (1 << 21)) {
5305
                /* Base writeback.  */
5306
                switch (i) {
5307
                case 0: offset = -8; break;
5308
                case 1: offset = -4; break;
5309
                case 2: offset = 4; break;
5310
                case 3: offset = 0; break;
5311
                default: abort();
5312
                }
5313
                if (offset)
5314
                    tcg_gen_addi_i32(addr, addr, offset);
5315
                store_reg(s, rn, addr);
5316
            } else {
5317
                dead_tmp(addr);
5318
            }
5319
            gen_rfe(s, tmp, tmp2);
5320
        } else if ((insn & 0x0e000000) == 0x0a000000) {
5321
            /* branch link and change to thumb (blx <offset>) */
5322
            int32_t offset;
5323

    
5324
            val = (uint32_t)s->pc;
5325
            tmp = new_tmp();
5326
            tcg_gen_movi_i32(tmp, val);
5327
            store_reg(s, 14, tmp);
5328
            /* Sign-extend the 24-bit offset */
5329
            offset = (((int32_t)insn) << 8) >> 8;
5330
            /* offset * 4 + bit24 * 2 + (thumb bit) */
5331
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
5332
            /* pipeline offset */
5333
            val += 4;
5334
            gen_bx_im(s, val);
5335
            return;
5336
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
5337
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5338
                /* iWMMXt register transfer.  */
5339
                if (env->cp15.c15_cpar & (1 << 1))
5340
                    if (!disas_iwmmxt_insn(env, s, insn))
5341
                        return;
5342
            }
5343
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
5344
            /* Coprocessor double register transfer.  */
5345
        } else if ((insn & 0x0f000010) == 0x0e000010) {
5346
            /* Additional coprocessor register transfer.  */
5347
        } else if ((insn & 0x0ff10010) == 0x01000000) {
5348
            uint32_t mask;
5349
            uint32_t val;
5350
            /* cps (privileged) */
5351
            if (IS_USER(s))
5352
                return;
5353
            mask = val = 0;
5354
            if (insn & (1 << 19)) {
5355
                if (insn & (1 << 8))
5356
                    mask |= CPSR_A;
5357
                if (insn & (1 << 7))
5358
                    mask |= CPSR_I;
5359
                if (insn & (1 << 6))
5360
                    mask |= CPSR_F;
5361
                if (insn & (1 << 18))
5362
                    val |= mask;
5363
            }
5364
            if (insn & (1 << 14)) {
5365
                mask |= CPSR_M;
5366
                val |= (insn & 0x1f);
5367
            }
5368
            if (mask) {
5369
                gen_op_movl_T0_im(val);
5370
                gen_set_psr_T0(s, mask, 0);
5371
            }
5372
            return;
5373
        }
5374
        goto illegal_op;
5375
    }
5376
    if (cond != 0xe) {
5377
        /* if not always execute, we generate a conditional jump to
5378
           next instruction */
5379
        s->condlabel = gen_new_label();
5380
        gen_test_cc(cond ^ 1, s->condlabel);
5381
        s->condjmp = 1;
5382
    }
5383
    if ((insn & 0x0f900000) == 0x03000000) {
5384
        if ((insn & (1 << 21)) == 0) {
5385
            ARCH(6T2);
5386
            rd = (insn >> 12) & 0xf;
5387
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5388
            if ((insn & (1 << 22)) == 0) {
5389
                /* MOVW */
5390
                gen_op_movl_T0_im(val);
5391
            } else {
5392
                /* MOVT */
5393
                gen_movl_T0_reg(s, rd);
5394
                gen_op_movl_T1_im(0xffff);
5395
                gen_op_andl_T0_T1();
5396
                gen_op_movl_T1_im(val << 16);
5397
                gen_op_orl_T0_T1();
5398
            }
5399
            gen_movl_reg_T0(s, rd);
5400
        } else {
5401
            if (((insn >> 12) & 0xf) != 0xf)
5402
                goto illegal_op;
5403
            if (((insn >> 16) & 0xf) == 0) {
5404
                gen_nop_hint(s, insn & 0xff);
5405
            } else {
5406
                /* CPSR = immediate */
5407
                val = insn & 0xff;
5408
                shift = ((insn >> 8) & 0xf) * 2;
5409
                if (shift)
5410
                    val = (val >> shift) | (val << (32 - shift));
5411
                gen_op_movl_T0_im(val);
5412
                i = ((insn & (1 << 22)) != 0);
5413
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5414
                    goto illegal_op;
5415
            }
5416
        }
5417
    } else if ((insn & 0x0f900000) == 0x01000000
5418
               && (insn & 0x00000090) != 0x00000090) {
5419
        /* miscellaneous instructions */
5420
        op1 = (insn >> 21) & 3;
5421
        sh = (insn >> 4) & 0xf;
5422
        rm = insn & 0xf;
5423
        switch (sh) {
5424
        case 0x0: /* move program status register */
5425
            if (op1 & 1) {
5426
                /* PSR = reg */
5427
                gen_movl_T0_reg(s, rm);
5428
                i = ((op1 & 2) != 0);
5429
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5430
                    goto illegal_op;
5431
            } else {
5432
                /* reg = PSR */
5433
                rd = (insn >> 12) & 0xf;
5434
                if (op1 & 2) {
5435
                    if (IS_USER(s))
5436
                        goto illegal_op;
5437
                    tmp = load_cpu_field(spsr);
5438
                } else {
5439
                    tmp = new_tmp();
5440
                    gen_helper_cpsr_read(tmp);
5441
                }
5442
                store_reg(s, rd, tmp);
5443
            }
5444
            break;
5445
        case 0x1:
5446
            if (op1 == 1) {
5447
                /* branch/exchange thumb (bx).  */
5448
                tmp = load_reg(s, rm);
5449
                gen_bx(s, tmp);
5450
            } else if (op1 == 3) {
5451
                /* clz */
5452
                rd = (insn >> 12) & 0xf;
5453
                tmp = load_reg(s, rm);
5454
                gen_helper_clz(tmp, tmp);
5455
                store_reg(s, rd, tmp);
5456
            } else {
5457
                goto illegal_op;
5458
            }
5459
            break;
5460
        case 0x2:
5461
            if (op1 == 1) {
5462
                ARCH(5J); /* bxj */
5463
                /* Trivial implementation equivalent to bx.  */
5464
                tmp = load_reg(s, rm);
5465
                gen_bx(s, tmp);
5466
            } else {
5467
                goto illegal_op;
5468
            }
5469
            break;
5470
        case 0x3:
5471
            if (op1 != 1)
5472
              goto illegal_op;
5473

    
5474
            /* branch link/exchange thumb (blx) */
5475
            tmp = load_reg(s, rm);
5476
            tmp2 = new_tmp();
5477
            tcg_gen_movi_i32(tmp2, s->pc);
5478
            store_reg(s, 14, tmp2);
5479
            gen_bx(s, tmp);
5480
            break;
5481
        case 0x5: /* saturating add/subtract */
5482
            rd = (insn >> 12) & 0xf;
5483
            rn = (insn >> 16) & 0xf;
5484
            gen_movl_T0_reg(s, rm);
5485
            gen_movl_T1_reg(s, rn);
5486
            if (op1 & 2)
5487
                gen_helper_double_saturate(cpu_T[1], cpu_T[1]);
5488
            if (op1 & 1)
5489
                gen_op_subl_T0_T1_saturate();
5490
            else
5491
                gen_op_addl_T0_T1_saturate();
5492
            gen_movl_reg_T0(s, rd);
5493
            break;
5494
        case 7: /* bkpt */
5495
            gen_set_condexec(s);
5496
            gen_op_movl_T0_im((long)s->pc - 4);
5497
            gen_set_pc_T0();
5498
            gen_exception(EXCP_BKPT);
5499
            s->is_jmp = DISAS_JUMP;
5500
            break;
5501
        case 0x8: /* signed multiply */
5502
        case 0xa:
5503
        case 0xc:
5504
        case 0xe:
5505
            rs = (insn >> 8) & 0xf;
5506
            rn = (insn >> 12) & 0xf;
5507
            rd = (insn >> 16) & 0xf;
5508
            if (op1 == 1) {
5509
                /* (32 * 16) >> 16 */
5510
                gen_movl_T0_reg(s, rm);
5511
                gen_movl_T1_reg(s, rs);
5512
                if (sh & 4)
5513
                    gen_op_sarl_T1_im(16);
5514
                else
5515
                    gen_sxth(cpu_T[1]);
5516
                gen_imulw(cpu_T[0], cpu_T[1]);
5517
                if ((sh & 2) == 0) {
5518
                    gen_movl_T1_reg(s, rn);
5519
                    gen_op_addl_T0_T1_setq();
5520
                }
5521
                gen_movl_reg_T0(s, rd);
5522
            } else {
5523
                /* 16 * 16 */
5524
                gen_movl_T0_reg(s, rm);
5525
                gen_movl_T1_reg(s, rs);
5526
                gen_mulxy(cpu_T[0], cpu_T[1], sh & 2, sh & 4);
5527
                if (op1 == 2) {
5528
                    gen_op_signbit_T1_T0();
5529
                    gen_op_addq_T0_T1(rn, rd);
5530
                    gen_movl_reg_T0(s, rn);
5531
                    gen_movl_reg_T1(s, rd);
5532
                } else {
5533
                    if (op1 == 0) {
5534
                        gen_movl_T1_reg(s, rn);
5535
                        gen_op_addl_T0_T1_setq();
5536
                    }
5537
                    gen_movl_reg_T0(s, rd);
5538
                }
5539
            }
5540
            break;
5541
        default:
5542
            goto illegal_op;
5543
        }
5544
    } else if (((insn & 0x0e000000) == 0 &&
5545
                (insn & 0x00000090) != 0x90) ||
5546
               ((insn & 0x0e000000) == (1 << 25))) {
5547
        int set_cc, logic_cc, shiftop;
5548

    
5549
        op1 = (insn >> 21) & 0xf;
5550
        set_cc = (insn >> 20) & 1;
5551
        logic_cc = table_logic_cc[op1] & set_cc;
5552

    
5553
        /* data processing instruction */
5554
        if (insn & (1 << 25)) {
5555
            /* immediate operand */
5556
            val = insn & 0xff;
5557
            shift = ((insn >> 8) & 0xf) * 2;
5558
            if (shift)
5559
                val = (val >> shift) | (val << (32 - shift));
5560
            gen_op_movl_T1_im(val);
5561
            if (logic_cc && shift)
5562
                gen_set_CF_bit31(cpu_T[1]);
5563
        } else {
5564
            /* register */
5565
            rm = (insn) & 0xf;
5566
            gen_movl_T1_reg(s, rm);
5567
            shiftop = (insn >> 5) & 3;
5568
            if (!(insn & (1 << 4))) {
5569
                shift = (insn >> 7) & 0x1f;
5570
                gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
5571
            } else {
5572
                rs = (insn >> 8) & 0xf;
5573
                gen_movl_T0_reg(s, rs);
5574
                if (logic_cc) {
5575
                    gen_shift_T1_T0_cc[shiftop]();
5576
                } else {
5577
                    gen_shift_T1_T0[shiftop]();
5578
                }
5579
            }
5580
        }
5581
        if (op1 != 0x0f && op1 != 0x0d) {
5582
            rn = (insn >> 16) & 0xf;
5583
            gen_movl_T0_reg(s, rn);
5584
        }
5585
        rd = (insn >> 12) & 0xf;
5586
        switch(op1) {
5587
        case 0x00:
5588
            gen_op_andl_T0_T1();
5589
            gen_movl_reg_T0(s, rd);
5590
            if (logic_cc)
5591
                gen_op_logic_T0_cc();
5592
            break;
5593
        case 0x01:
5594
            gen_op_xorl_T0_T1();
5595
            gen_movl_reg_T0(s, rd);
5596
            if (logic_cc)
5597
                gen_op_logic_T0_cc();
5598
            break;
5599
        case 0x02:
5600
            if (set_cc && rd == 15) {
5601
                /* SUBS r15, ... is used for exception return.  */
5602
                if (IS_USER(s))
5603
                    goto illegal_op;
5604
                gen_op_subl_T0_T1_cc();
5605
                gen_exception_return(s);
5606
            } else {
5607
                if (set_cc)
5608
                    gen_op_subl_T0_T1_cc();
5609
                else
5610
                    gen_op_subl_T0_T1();
5611
                gen_movl_reg_T0(s, rd);
5612
            }
5613
            break;
5614
        case 0x03:
5615
            if (set_cc)
5616
                gen_op_rsbl_T0_T1_cc();
5617
            else
5618
                gen_op_rsbl_T0_T1();
5619
            gen_movl_reg_T0(s, rd);
5620
            break;
5621
        case 0x04:
5622
            if (set_cc)
5623
                gen_op_addl_T0_T1_cc();
5624
            else
5625
                gen_op_addl_T0_T1();
5626
            gen_movl_reg_T0(s, rd);
5627
            break;
5628
        case 0x05:
5629
            if (set_cc)
5630
                gen_op_adcl_T0_T1_cc();
5631
            else
5632
                gen_adc_T0_T1();
5633
            gen_movl_reg_T0(s, rd);
5634
            break;
5635
        case 0x06:
5636
            if (set_cc)
5637
                gen_op_sbcl_T0_T1_cc();
5638
            else
5639
                gen_sbc_T0_T1();
5640
            gen_movl_reg_T0(s, rd);
5641
            break;
5642
        case 0x07:
5643
            if (set_cc)
5644
                gen_op_rscl_T0_T1_cc();
5645
            else
5646
                gen_rsc_T0_T1();
5647
            gen_movl_reg_T0(s, rd);
5648
            break;
5649
        case 0x08:
5650
            if (set_cc) {
5651
                gen_op_andl_T0_T1();
5652
                gen_op_logic_T0_cc();
5653
            }
5654
            break;
5655
        case 0x09:
5656
            if (set_cc) {
5657
                gen_op_xorl_T0_T1();
5658
                gen_op_logic_T0_cc();
5659
            }
5660
            break;
5661
        case 0x0a:
5662
            if (set_cc) {
5663
                gen_op_subl_T0_T1_cc();
5664
            }
5665
            break;
5666
        case 0x0b:
5667
            if (set_cc) {
5668
                gen_op_addl_T0_T1_cc();
5669
            }
5670
            break;
5671
        case 0x0c:
5672
            gen_op_orl_T0_T1();
5673
            gen_movl_reg_T0(s, rd);
5674
            if (logic_cc)
5675
                gen_op_logic_T0_cc();
5676
            break;
5677
        case 0x0d:
5678
            if (logic_cc && rd == 15) {
5679
                /* MOVS r15, ... is used for exception return.  */
5680
                if (IS_USER(s))
5681
                    goto illegal_op;
5682
                gen_op_movl_T0_T1();
5683
                gen_exception_return(s);
5684
            } else {
5685
                gen_movl_reg_T1(s, rd);
5686
                if (logic_cc)
5687
                    gen_op_logic_T1_cc();
5688
            }
5689
            break;
5690
        case 0x0e:
5691
            gen_op_bicl_T0_T1();
5692
            gen_movl_reg_T0(s, rd);
5693
            if (logic_cc)
5694
                gen_op_logic_T0_cc();
5695
            break;
5696
        default:
5697
        case 0x0f:
5698
            gen_op_notl_T1();
5699
            gen_movl_reg_T1(s, rd);
5700
            if (logic_cc)
5701
                gen_op_logic_T1_cc();
5702
            break;
5703
        }
5704
    } else {
5705
        /* other instructions */
5706
        op1 = (insn >> 24) & 0xf;
5707
        switch(op1) {
5708
        case 0x0:
5709
        case 0x1:
5710
            /* multiplies, extra load/stores */
5711
            sh = (insn >> 5) & 3;
5712
            if (sh == 0) {
5713
                if (op1 == 0x0) {
5714
                    rd = (insn >> 16) & 0xf;
5715
                    rn = (insn >> 12) & 0xf;
5716
                    rs = (insn >> 8) & 0xf;
5717
                    rm = (insn) & 0xf;
5718
                    op1 = (insn >> 20) & 0xf;
5719
                    switch (op1) {
5720
                    case 0: case 1: case 2: case 3: case 6:
5721
                        /* 32 bit mul */
5722
                        gen_movl_T0_reg(s, rs);
5723
                        gen_movl_T1_reg(s, rm);
5724
                        gen_op_mul_T0_T1();
5725
                        if (insn & (1 << 22)) {
5726
                            /* Subtract (mls) */
5727
                            ARCH(6T2);
5728
                            gen_movl_T1_reg(s, rn);
5729
                            gen_op_rsbl_T0_T1();
5730
                        } else if (insn & (1 << 21)) {
5731
                            /* Add */
5732
                            gen_movl_T1_reg(s, rn);
5733
                            gen_op_addl_T0_T1();
5734
                        }
5735
                        if (insn & (1 << 20))
5736
                            gen_op_logic_T0_cc();
5737
                        gen_movl_reg_T0(s, rd);
5738
                        break;
5739
                    default:
5740
                        /* 64 bit mul */
5741
                        gen_movl_T0_reg(s, rs);
5742
                        gen_movl_T1_reg(s, rm);
5743
                        if (insn & (1 << 22))
5744
                            gen_op_imull_T0_T1();
5745
                        else
5746
                            gen_op_mull_T0_T1();
5747
                        if (insn & (1 << 21)) /* mult accumulate */
5748
                            gen_op_addq_T0_T1(rn, rd);
5749
                        if (!(insn & (1 << 23))) { /* double accumulate */
5750
                            ARCH(6);
5751
                            gen_op_addq_lo_T0_T1(rn);
5752
                            gen_op_addq_lo_T0_T1(rd);
5753
                        }
5754
                        if (insn & (1 << 20))
5755
                            gen_op_logicq_cc();
5756
                        gen_movl_reg_T0(s, rn);
5757
                        gen_movl_reg_T1(s, rd);
5758
                        break;
5759
                    }
5760
                } else {
5761
                    rn = (insn >> 16) & 0xf;
5762
                    rd = (insn >> 12) & 0xf;
5763
                    if (insn & (1 << 23)) {
5764
                        /* load/store exclusive */
5765
                        gen_movl_T1_reg(s, rn);
5766
                        if (insn & (1 << 20)) {
5767
                            gen_ldst(ldlex, s);
5768
                        } else {
5769
                            rm = insn & 0xf;
5770
                            gen_movl_T0_reg(s, rm);
5771
                            gen_ldst(stlex, s);
5772
                        }
5773
                        gen_movl_reg_T0(s, rd);
5774
                    } else {
5775
                        /* SWP instruction */
5776
                        rm = (insn) & 0xf;
5777

    
5778
                        gen_movl_T0_reg(s, rm);
5779
                        gen_movl_T1_reg(s, rn);
5780
                        if (insn & (1 << 22)) {
5781
                            gen_ldst(swpb, s);
5782
                        } else {
5783
                            gen_ldst(swpl, s);
5784
                        }
5785
                        gen_movl_reg_T0(s, rd);
5786
                    }
5787
                }
5788
            } else {
5789
                int address_offset;
5790
                int load;
5791
                /* Misc load/store */
5792
                rn = (insn >> 16) & 0xf;
5793
                rd = (insn >> 12) & 0xf;
5794
                addr = load_reg(s, rn);
5795
                if (insn & (1 << 24))
5796
                    gen_add_datah_offset(s, insn, 0, addr);
5797
                address_offset = 0;
5798
                if (insn & (1 << 20)) {
5799
                    /* load */
5800
                    switch(sh) {
5801
                    case 1:
5802
                        tmp = gen_ld16u(addr, IS_USER(s));
5803
                        break;
5804
                    case 2:
5805
                        tmp = gen_ld8s(addr, IS_USER(s));
5806
                        break;
5807
                    default:
5808
                    case 3:
5809
                        tmp = gen_ld16s(addr, IS_USER(s));
5810
                        break;
5811
                    }
5812
                    load = 1;
5813
                } else if (sh & 2) {
5814
                    /* doubleword */
5815
                    if (sh & 1) {
5816
                        /* store */
5817
                        tmp = load_reg(s, rd);
5818
                        gen_st32(tmp, addr, IS_USER(s));
5819
                        tcg_gen_addi_i32(addr, addr, 4);
5820
                        tmp = load_reg(s, rd + 1);
5821
                        gen_st32(tmp, addr, IS_USER(s));
5822
                        load = 0;
5823
                    } else {
5824
                        /* load */
5825
                        tmp = gen_ld32(addr, IS_USER(s));
5826
                        store_reg(s, rd, tmp);
5827
                        tcg_gen_addi_i32(addr, addr, 4);
5828
                        tmp = gen_ld32(addr, IS_USER(s));
5829
                        rd++;
5830
                        load = 1;
5831
                    }
5832
                    address_offset = -4;
5833
                } else {
5834
                    /* store */
5835
                    tmp = load_reg(s, rd);
5836
                    gen_st16(tmp, addr, IS_USER(s));
5837
                    load = 0;
5838
                }
5839
                /* Perform base writeback before the loaded value to
5840
                   ensure correct behavior with overlapping index registers.
5841
                   ldrd with base writeback is is undefined if the
5842
                   destination and index registers overlap.  */
5843
                if (!(insn & (1 << 24))) {
5844
                    gen_add_datah_offset(s, insn, address_offset, addr);
5845
                    store_reg(s, rn, addr);
5846
                } else if (insn & (1 << 21)) {
5847
                    if (address_offset)
5848
                        tcg_gen_addi_i32(addr, addr, address_offset);
5849
                    store_reg(s, rn, addr);
5850
                } else {
5851
                    dead_tmp(addr);
5852
                }
5853
                if (load) {
5854
                    /* Complete the load.  */
5855
                    store_reg(s, rd, tmp);
5856
                }
5857
            }
5858
            break;
5859
        case 0x4:
5860
        case 0x5:
5861
            goto do_ldst;
5862
        case 0x6:
5863
        case 0x7:
5864
            if (insn & (1 << 4)) {
5865
                ARCH(6);
5866
                /* Armv6 Media instructions.  */
5867
                rm = insn & 0xf;
5868
                rn = (insn >> 16) & 0xf;
5869
                rd = (insn >> 12) & 0xf;
5870
                rs = (insn >> 8) & 0xf;
5871
                switch ((insn >> 23) & 3) {
5872
                case 0: /* Parallel add/subtract.  */
5873
                    op1 = (insn >> 20) & 7;
5874
                    tmp = load_reg(s, rn);
5875
                    tmp2 = load_reg(s, rm);
5876
                    sh = (insn >> 5) & 7;
5877
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
5878
                        goto illegal_op;
5879
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
5880
                    dead_tmp(tmp2);
5881
                    store_reg(s, rd, tmp);
5882
                    break;
5883
                case 1:
5884
                    if ((insn & 0x00700020) == 0) {
5885
                        /* Hafword pack.  */
5886
                        tmp = load_reg(s, rn);
5887
                        tmp2 = load_reg(s, rm);
5888
                        shift = (insn >> 7) & 0x1f;
5889
                        if (shift)
5890
                            tcg_gen_shli_i32(tmp2, tmp2, shift);
5891
                        if (insn & (1 << 6)) {
5892
                            /* pkhtb */
5893
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
5894
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
5895
                        } else {
5896
                            /* pkhbt */
5897
                            tcg_gen_andi_i32(tmp, tmp, 0xffff);
5898
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
5899
                        }
5900
                        tcg_gen_or_i32(tmp, tmp, tmp2);
5901
                        store_reg(s, rd, tmp);
5902
                    } else if ((insn & 0x00200020) == 0x00200000) {
5903
                        /* [us]sat */
5904
                        tmp = load_reg(s, rm);
5905
                        shift = (insn >> 7) & 0x1f;
5906
                        if (insn & (1 << 6)) {
5907
                            if (shift == 0)
5908
                                shift = 31;
5909
                            tcg_gen_sari_i32(tmp, tmp, shift);
5910
                        } else {
5911
                            tcg_gen_shli_i32(tmp, tmp, shift);
5912
                        }
5913
                        sh = (insn >> 16) & 0x1f;
5914
                        if (sh != 0) {
5915
                            if (insn & (1 << 22))
5916
                                gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
5917
                            else
5918
                                gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
5919
                        }
5920
                        store_reg(s, rd, tmp);
5921
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
5922
                        /* [us]sat16 */
5923
                        tmp = load_reg(s, rm);
5924
                        sh = (insn >> 16) & 0x1f;
5925
                        if (sh != 0) {
5926
                            if (insn & (1 << 22))
5927
                                gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
5928
                            else
5929
                                gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
5930
                        }
5931
                        store_reg(s, rd, tmp);
5932
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
5933
                        /* Select bytes.  */
5934
                        tmp = load_reg(s, rn);
5935
                        tmp2 = load_reg(s, rm);
5936
                        tmp3 = new_tmp();
5937
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
5938
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
5939
                        dead_tmp(tmp3);
5940
                        dead_tmp(tmp2);
5941
                        store_reg(s, rd, tmp);
5942
                    } else if ((insn & 0x000003e0) == 0x00000060) {
5943
                        gen_movl_T1_reg(s, rm);
5944
                        shift = (insn >> 10) & 3;
5945
                        /* ??? In many cases it's not neccessary to do a
5946
                           rotate, a shift is sufficient.  */
5947
                        if (shift != 0)
5948
                            gen_op_rorl_T1_im(shift * 8);
5949
                        op1 = (insn >> 20) & 7;
5950
                        switch (op1) {
5951
                        case 0: gen_sxtb16(cpu_T[1]); break;
5952
                        case 2: gen_sxtb(cpu_T[1]);   break;
5953
                        case 3: gen_sxth(cpu_T[1]);   break;
5954
                        case 4: gen_uxtb16(cpu_T[1]); break;
5955
                        case 6: gen_uxtb(cpu_T[1]);   break;
5956
                        case 7: gen_uxth(cpu_T[1]);   break;
5957
                        default: goto illegal_op;
5958
                        }
5959
                        if (rn != 15) {
5960
                            tmp = load_reg(s, rn);
5961
                            if ((op1 & 3) == 0) {
5962
                                gen_add16(cpu_T[1], tmp);
5963
                            } else {
5964
                                tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp);
5965
                                dead_tmp(tmp);
5966
                            }
5967
                        }
5968
                        gen_movl_reg_T1(s, rd);
5969
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
5970
                        /* rev */
5971
                        tmp = load_reg(s, rm);
5972
                        if (insn & (1 << 22)) {
5973
                            if (insn & (1 << 7)) {
5974
                                gen_revsh(tmp);
5975
                            } else {
5976
                                ARCH(6T2);
5977
                                gen_helper_rbit(tmp, tmp);
5978
                            }
5979
                        } else {
5980
                            if (insn & (1 << 7))
5981
                                gen_rev16(tmp);
5982
                            else
5983
                                tcg_gen_bswap_i32(tmp, tmp);
5984
                        }
5985
                        store_reg(s, rd, tmp);
5986
                    } else {
5987
                        goto illegal_op;
5988
                    }
5989
                    break;
5990
                case 2: /* Multiplies (Type 3).  */
5991
                    gen_movl_T0_reg(s, rm);
5992
                    gen_movl_T1_reg(s, rs);
5993
                    if (insn & (1 << 20)) {
5994
                        /* Signed multiply most significant [accumulate].  */
5995
                        gen_op_imull_T0_T1();
5996
                        if (insn & (1 << 5))
5997
                            gen_roundqd(cpu_T[0], cpu_T[1]);
5998
                        else
5999
                            gen_op_movl_T0_T1();
6000
                        if (rn != 15) {
6001
                            gen_movl_T1_reg(s, rn);
6002
                            if (insn & (1 << 6)) {
6003
                                gen_op_addl_T0_T1();
6004
                            } else {
6005
                                gen_op_rsbl_T0_T1();
6006
                            }
6007
                        }
6008
                        gen_movl_reg_T0(s, rd);
6009
                    } else {
6010
                        if (insn & (1 << 5))
6011
                            gen_swap_half(cpu_T[1]);
6012
                        gen_smul_dual(cpu_T[0], cpu_T[1]);
6013
                        if (insn & (1 << 22)) {
6014
                            if (insn & (1 << 6)) {
6015
                                /* smlald */
6016
                                gen_op_addq_T0_T1_dual(rn, rd);
6017
                            } else {
6018
                                /* smlsld */
6019
                                gen_op_subq_T0_T1_dual(rn, rd);
6020
                            }
6021
                        } else {
6022
                            /* This addition cannot overflow.  */
6023
                            if (insn & (1 << 6)) {
6024
                                /* sm[ul]sd */
6025
                                gen_op_subl_T0_T1();
6026
                            } else {
6027
                                /* sm[ul]ad */
6028
                                gen_op_addl_T0_T1();
6029
                            }
6030
                            if (rn != 15)
6031
                              {
6032
                                gen_movl_T1_reg(s, rn);
6033
                                gen_op_addl_T0_T1_setq();
6034
                              }
6035
                            gen_movl_reg_T0(s, rd);
6036
                        }
6037
                    }
6038
                    break;
6039
                case 3:
6040
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6041
                    switch (op1) {
6042
                    case 0: /* Unsigned sum of absolute differences.  */
6043
                        ARCH(6);
6044
                        tmp = load_reg(s, rm);
6045
                        tmp2 = load_reg(s, rs);
6046
                        gen_helper_usad8(tmp, tmp, tmp2);
6047
                        dead_tmp(tmp2);
6048
                        if (rn != 15) {
6049
                            tmp2 = load_reg(s, rn);
6050
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6051
                            dead_tmp(tmp2);
6052
                        }
6053
                        store_reg(s, rd, tmp);
6054
                        break;
6055
                    case 0x20: case 0x24: case 0x28: case 0x2c:
6056
                        /* Bitfield insert/clear.  */
6057
                        ARCH(6T2);
6058
                        shift = (insn >> 7) & 0x1f;
6059
                        i = (insn >> 16) & 0x1f;
6060
                        i = i + 1 - shift;
6061
                        if (rm == 15) {
6062
                            gen_op_movl_T1_im(0);
6063
                        } else {
6064
                            gen_movl_T1_reg(s, rm);
6065
                        }
6066
                        if (i != 32) {
6067
                            gen_movl_T0_reg(s, rd);
6068
                            gen_bfi(cpu_T[1], cpu_T[0], cpu_T[1],
6069
                                    shift, ((1u << i) - 1) << shift);
6070
                        }
6071
                        gen_movl_reg_T1(s, rd);
6072
                        break;
6073
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6074
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6075
                        gen_movl_T1_reg(s, rm);
6076
                        shift = (insn >> 7) & 0x1f;
6077
                        i = ((insn >> 16) & 0x1f) + 1;
6078
                        if (shift + i > 32)
6079
                            goto illegal_op;
6080
                        if (i < 32) {
6081
                            if (op1 & 0x20) {
6082
                                gen_ubfx(cpu_T[1], shift, (1u << i) - 1);
6083
                            } else {
6084
                                gen_sbfx(cpu_T[1], shift, i);
6085
                            }
6086
                        }
6087
                        gen_movl_reg_T1(s, rd);
6088
                        break;
6089
                    default:
6090
                        goto illegal_op;
6091
                    }
6092
                    break;
6093
                }
6094
                break;
6095
            }
6096
        do_ldst:
6097
            /* Check for undefined extension instructions
6098
             * per the ARM Bible IE:
6099
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
6100
             */
6101
            sh = (0xf << 20) | (0xf << 4);
6102
            if (op1 == 0x7 && ((insn & sh) == sh))
6103
            {
6104
                goto illegal_op;
6105
            }
6106
            /* load/store byte/word */
6107
            rn = (insn >> 16) & 0xf;
6108
            rd = (insn >> 12) & 0xf;
6109
            tmp2 = load_reg(s, rn);
6110
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6111
            if (insn & (1 << 24))
6112
                gen_add_data_offset(s, insn, tmp2);
6113
            if (insn & (1 << 20)) {
6114
                /* load */
6115
                s->is_mem = 1;
6116
                if (insn & (1 << 22)) {
6117
                    tmp = gen_ld8u(tmp2, i);
6118
                } else {
6119
                    tmp = gen_ld32(tmp2, i);
6120
                }
6121
            } else {
6122
                /* store */
6123
                tmp = load_reg(s, rd);
6124
                if (insn & (1 << 22))
6125
                    gen_st8(tmp, tmp2, i);
6126
                else
6127
                    gen_st32(tmp, tmp2, i);
6128
            }
6129
            if (!(insn & (1 << 24))) {
6130
                gen_add_data_offset(s, insn, tmp2);
6131
                store_reg(s, rn, tmp2);
6132
            } else if (insn & (1 << 21)) {
6133
                store_reg(s, rn, tmp2);
6134
            } else {
6135
                dead_tmp(tmp2);
6136
            }
6137
            if (insn & (1 << 20)) {
6138
                /* Complete the load.  */
6139
                if (rd == 15)
6140
                    gen_bx(s, tmp);
6141
                else
6142
                    store_reg(s, rd, tmp);
6143
            }
6144
            break;
6145
        case 0x08:
6146
        case 0x09:
6147
            {
6148
                int j, n, user, loaded_base;
6149
                TCGv loaded_var;
6150
                /* load/store multiple words */
6151
                /* XXX: store correct base if write back */
6152
                user = 0;
6153
                if (insn & (1 << 22)) {
6154
                    if (IS_USER(s))
6155
                        goto illegal_op; /* only usable in supervisor mode */
6156

    
6157
                    if ((insn & (1 << 15)) == 0)
6158
                        user = 1;
6159
                }
6160
                rn = (insn >> 16) & 0xf;
6161
                addr = load_reg(s, rn);
6162

    
6163
                /* compute total size */
6164
                loaded_base = 0;
6165
                n = 0;
6166
                for(i=0;i<16;i++) {
6167
                    if (insn & (1 << i))
6168
                        n++;
6169
                }
6170
                /* XXX: test invalid n == 0 case ? */
6171
                if (insn & (1 << 23)) {
6172
                    if (insn & (1 << 24)) {
6173
                        /* pre increment */
6174
                        tcg_gen_addi_i32(addr, addr, 4);
6175
                    } else {
6176
                        /* post increment */
6177
                    }
6178
                } else {
6179
                    if (insn & (1 << 24)) {
6180
                        /* pre decrement */
6181
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
6182
                    } else {
6183
                        /* post decrement */
6184
                        if (n != 1)
6185
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6186
                    }
6187
                }
6188
                j = 0;
6189
                for(i=0;i<16;i++) {
6190
                    if (insn & (1 << i)) {
6191
                        if (insn & (1 << 20)) {
6192
                            /* load */
6193
                            tmp = gen_ld32(addr, IS_USER(s));
6194
                            if (i == 15) {
6195
                                gen_bx(s, tmp);
6196
                            } else if (user) {
6197
                                gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6198
                                dead_tmp(tmp);
6199
                            } else if (i == rn) {
6200
                                loaded_var = tmp;
6201
                                loaded_base = 1;
6202
                            } else {
6203
                                store_reg(s, i, tmp);
6204
                            }
6205
                        } else {
6206
                            /* store */
6207
                            if (i == 15) {
6208
                                /* special case: r15 = PC + 8 */
6209
                                val = (long)s->pc + 4;
6210
                                tmp = new_tmp();
6211
                                tcg_gen_movi_i32(tmp, val);
6212
                            } else if (user) {
6213
                                tmp = new_tmp();
6214
                                gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6215
                            } else {
6216
                                tmp = load_reg(s, i);
6217
                            }
6218
                            gen_st32(tmp, addr, IS_USER(s));
6219
                        }
6220
                        j++;
6221
                        /* no need to add after the last transfer */
6222
                        if (j != n)
6223
                            tcg_gen_addi_i32(addr, addr, 4);
6224
                    }
6225
                }
6226
                if (insn & (1 << 21)) {
6227
                    /* write back */
6228
                    if (insn & (1 << 23)) {
6229
                        if (insn & (1 << 24)) {
6230
                            /* pre increment */
6231
                        } else {
6232
                            /* post increment */
6233
                            tcg_gen_addi_i32(addr, addr, 4);
6234
                        }
6235
                    } else {
6236
                        if (insn & (1 << 24)) {
6237
                            /* pre decrement */
6238
                            if (n != 1)
6239
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6240
                        } else {
6241
                            /* post decrement */
6242
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
6243
                        }
6244
                    }
6245
                    store_reg(s, rn, addr);
6246
                } else {
6247
                    dead_tmp(addr);
6248
                }
6249
                if (loaded_base) {
6250
                    store_reg(s, rn, loaded_var);
6251
                }
6252
                if ((insn & (1 << 22)) && !user) {
6253
                    /* Restore CPSR from SPSR.  */
6254
                    tmp = load_cpu_field(spsr);
6255
                    gen_set_cpsr(tmp, 0xffffffff);
6256
                    dead_tmp(tmp);
6257
                    s->is_jmp = DISAS_UPDATE;
6258
                }
6259
            }
6260
            break;
6261
        case 0xa:
6262
        case 0xb:
6263
            {
6264
                int32_t offset;
6265

    
6266
                /* branch (and link) */
6267
                val = (int32_t)s->pc;
6268
                if (insn & (1 << 24)) {
6269
                    gen_op_movl_T0_im(val);
6270
                    gen_movl_reg_T0(s, 14);
6271
                }
6272
                offset = (((int32_t)insn << 8) >> 8);
6273
                val += (offset << 2) + 4;
6274
                gen_jmp(s, val);
6275
            }
6276
            break;
6277
        case 0xc:
6278
        case 0xd:
6279
        case 0xe:
6280
            /* Coprocessor.  */
6281
            if (disas_coproc_insn(env, s, insn))
6282
                goto illegal_op;
6283
            break;
6284
        case 0xf:
6285
            /* swi */
6286
            gen_op_movl_T0_im((long)s->pc);
6287
            gen_set_pc_T0();
6288
            s->is_jmp = DISAS_SWI;
6289
            break;
6290
        default:
6291
        illegal_op:
6292
            gen_set_condexec(s);
6293
            gen_op_movl_T0_im((long)s->pc - 4);
6294
            gen_set_pc_T0();
6295
            gen_exception(EXCP_UDEF);
6296
            s->is_jmp = DISAS_JUMP;
6297
            break;
6298
        }
6299
    }
6300
}
6301

    
6302
/* Return true if this is a Thumb-2 logical op.  */
6303
static int
6304
thumb2_logic_op(int op)
6305
{
6306
    return (op < 8);
6307
}
6308

    
6309
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6310
   then set condition code flags based on the result of the operation.
6311
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6312
   to the high bit of T1.
6313
   Returns zero if the opcode is valid.  */
6314

    
6315
static int
6316
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6317
{
6318
    int logic_cc;
6319

    
6320
    logic_cc = 0;
6321
    switch (op) {
6322
    case 0: /* and */
6323
        gen_op_andl_T0_T1();
6324
        logic_cc = conds;
6325
        break;
6326
    case 1: /* bic */
6327
        gen_op_bicl_T0_T1();
6328
        logic_cc = conds;
6329
        break;
6330
    case 2: /* orr */
6331
        gen_op_orl_T0_T1();
6332
        logic_cc = conds;
6333
        break;
6334
    case 3: /* orn */
6335
        gen_op_notl_T1();
6336
        gen_op_orl_T0_T1();
6337
        logic_cc = conds;
6338
        break;
6339
    case 4: /* eor */
6340
        gen_op_xorl_T0_T1();
6341
        logic_cc = conds;
6342
        break;
6343
    case 8: /* add */
6344
        if (conds)
6345
            gen_op_addl_T0_T1_cc();
6346
        else
6347
            gen_op_addl_T0_T1();
6348
        break;
6349
    case 10: /* adc */
6350
        if (conds)
6351
            gen_op_adcl_T0_T1_cc();
6352
        else
6353
            gen_adc_T0_T1();
6354
        break;
6355
    case 11: /* sbc */
6356
        if (conds)
6357
            gen_op_sbcl_T0_T1_cc();
6358
        else
6359
            gen_sbc_T0_T1();
6360
        break;
6361
    case 13: /* sub */
6362
        if (conds)
6363
            gen_op_subl_T0_T1_cc();
6364
        else
6365
            gen_op_subl_T0_T1();
6366
        break;
6367
    case 14: /* rsb */
6368
        if (conds)
6369
            gen_op_rsbl_T0_T1_cc();
6370
        else
6371
            gen_op_rsbl_T0_T1();
6372
        break;
6373
    default: /* 5, 6, 7, 9, 12, 15. */
6374
        return 1;
6375
    }
6376
    if (logic_cc) {
6377
        gen_op_logic_T0_cc();
6378
        if (shifter_out)
6379
            gen_set_CF_bit31(cpu_T[1]);
6380
    }
6381
    return 0;
6382
}
6383

    
6384
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
6385
   is not legal.  */
6386
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6387
{
6388
    uint32_t insn, imm, shift, offset;
6389
    uint32_t rd, rn, rm, rs;
6390
    TCGv tmp;
6391
    TCGv tmp2;
6392
    TCGv tmp3;
6393
    TCGv addr;
6394
    int op;
6395
    int shiftop;
6396
    int conds;
6397
    int logic_cc;
6398

    
6399
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6400
          || arm_feature (env, ARM_FEATURE_M))) {
6401
        /* Thumb-1 cores may need to tread bl and blx as a pair of
6402
           16-bit instructions to get correct prefetch abort behavior.  */
6403
        insn = insn_hw1;
6404
        if ((insn & (1 << 12)) == 0) {
6405
            /* Second half of blx.  */
6406
            offset = ((insn & 0x7ff) << 1);
6407
            tmp = load_reg(s, 14);
6408
            tcg_gen_addi_i32(tmp, tmp, offset);
6409
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6410

    
6411
            tmp2 = new_tmp();
6412
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6413
            store_reg(s, 14, tmp2);
6414
            gen_bx(s, tmp);
6415
            return 0;
6416
        }
6417
        if (insn & (1 << 11)) {
6418
            /* Second half of bl.  */
6419
            offset = ((insn & 0x7ff) << 1) | 1;
6420
            tmp = load_reg(s, 14);
6421
            tcg_gen_addi_i32(tmp, tmp, 14);
6422

    
6423
            tmp2 = new_tmp();
6424
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6425
            store_reg(s, 14, tmp2);
6426
            gen_bx(s, tmp);
6427
            return 0;
6428
        }
6429
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6430
            /* Instruction spans a page boundary.  Implement it as two
6431
               16-bit instructions in case the second half causes an
6432
               prefetch abort.  */
6433
            offset = ((int32_t)insn << 21) >> 9;
6434
            gen_op_movl_T0_im(s->pc + 2 + offset);
6435
            gen_movl_reg_T0(s, 14);
6436
            return 0;
6437
        }
6438
        /* Fall through to 32-bit decode.  */
6439
    }
6440

    
6441
    insn = lduw_code(s->pc);
6442
    s->pc += 2;
6443
    insn |= (uint32_t)insn_hw1 << 16;
6444

    
6445
    if ((insn & 0xf800e800) != 0xf000e800) {
6446
        ARCH(6T2);
6447
    }
6448

    
6449
    rn = (insn >> 16) & 0xf;
6450
    rs = (insn >> 12) & 0xf;
6451
    rd = (insn >> 8) & 0xf;
6452
    rm = insn & 0xf;
6453
    switch ((insn >> 25) & 0xf) {
6454
    case 0: case 1: case 2: case 3:
6455
        /* 16-bit instructions.  Should never happen.  */
6456
        abort();
6457
    case 4:
6458
        if (insn & (1 << 22)) {
6459
            /* Other load/store, table branch.  */
6460
            if (insn & 0x01200000) {
6461
                /* Load/store doubleword.  */
6462
                if (rn == 15) {
6463
                    addr = new_tmp();
6464
                    tcg_gen_movi_i32(addr, s->pc & ~3);
6465
                } else {
6466
                    addr = load_reg(s, rn);
6467
                }
6468
                offset = (insn & 0xff) * 4;
6469
                if ((insn & (1 << 23)) == 0)
6470
                    offset = -offset;
6471
                if (insn & (1 << 24)) {
6472
                    tcg_gen_addi_i32(addr, addr, offset);
6473
                    offset = 0;
6474
                }
6475
                if (insn & (1 << 20)) {
6476
                    /* ldrd */
6477
                    tmp = gen_ld32(addr, IS_USER(s));
6478
                    store_reg(s, rs, tmp);
6479
                    tcg_gen_addi_i32(addr, addr, 4);
6480
                    tmp = gen_ld32(addr, IS_USER(s));
6481
                    store_reg(s, rd, tmp);
6482
                } else {
6483
                    /* strd */
6484
                    tmp = load_reg(s, rs);
6485
                    gen_st32(tmp, addr, IS_USER(s));
6486
                    tcg_gen_addi_i32(addr, addr, 4);
6487
                    tmp = load_reg(s, rd);
6488
                    gen_st32(tmp, addr, IS_USER(s));
6489
                }
6490
                if (insn & (1 << 21)) {
6491
                    /* Base writeback.  */
6492
                    if (rn == 15)
6493
                        goto illegal_op;
6494
                    tcg_gen_addi_i32(addr, addr, offset - 4);
6495
                    store_reg(s, rn, addr);
6496
                } else {
6497
                    dead_tmp(addr);
6498
                }
6499
            } else if ((insn & (1 << 23)) == 0) {
6500
                /* Load/store exclusive word.  */
6501
                gen_movl_T0_reg(s, rd);
6502
                gen_movl_T1_reg(s, rn);
6503
                if (insn & (1 << 20)) {
6504
                    gen_ldst(ldlex, s);
6505
                } else {
6506
                    gen_ldst(stlex, s);
6507
                }
6508
                gen_movl_reg_T0(s, rd);
6509
            } else if ((insn & (1 << 6)) == 0) {
6510
                /* Table Branch.  */
6511
                if (rn == 15) {
6512
                    addr = new_tmp();
6513
                    tcg_gen_movi_i32(addr, s->pc);
6514
                } else {
6515
                    addr = load_reg(s, rn);
6516
                }
6517
                tmp = load_reg(s, rm);
6518
                tcg_gen_add_i32(addr, addr, tmp);
6519
                if (insn & (1 << 4)) {
6520
                    /* tbh */
6521
                    tcg_gen_add_i32(addr, addr, tmp);
6522
                    dead_tmp(tmp);
6523
                    tmp = gen_ld16u(addr, IS_USER(s));
6524
                } else { /* tbb */
6525
                    dead_tmp(tmp);
6526
                    tmp = gen_ld8u(addr, IS_USER(s));
6527
                }
6528
                dead_tmp(addr);
6529
                tcg_gen_shli_i32(tmp, tmp, 1);
6530
                tcg_gen_addi_i32(tmp, tmp, s->pc);
6531
                store_reg(s, 15, tmp);
6532
            } else {
6533
                /* Load/store exclusive byte/halfword/doubleword.  */
6534
                op = (insn >> 4) & 0x3;
6535
                gen_movl_T1_reg(s, rn);
6536
                if (insn & (1 << 20)) {
6537
                    switch (op) {
6538
                    case 0:
6539
                        gen_ldst(ldbex, s);
6540
                        break;
6541
                    case 1:
6542
                        gen_ldst(ldwex, s);
6543
                        break;
6544
                    case 3:
6545
                        gen_ldst(ldqex, s);
6546
                        gen_movl_reg_T1(s, rd);
6547
                        break;
6548
                    default:
6549
                        goto illegal_op;
6550
                    }
6551
                    gen_movl_reg_T0(s, rs);
6552
                } else {
6553
                    gen_movl_T0_reg(s, rs);
6554
                    switch (op) {
6555
                    case 0:
6556
                        gen_ldst(stbex, s);
6557
                        break;
6558
                    case 1:
6559
                        gen_ldst(stwex, s);
6560
                        break;
6561
                    case 3:
6562
                        gen_movl_T2_reg(s, rd);
6563
                        gen_ldst(stqex, s);
6564
                        break;
6565
                    default:
6566
                        goto illegal_op;
6567
                    }
6568
                    gen_movl_reg_T0(s, rm);
6569
                }
6570
            }
6571
        } else {
6572
            /* Load/store multiple, RFE, SRS.  */
6573
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
6574
                /* Not available in user mode.  */
6575
                if (IS_USER(s))
6576
                    goto illegal_op;
6577
                if (insn & (1 << 20)) {
6578
                    /* rfe */
6579
                    addr = load_reg(s, rn);
6580
                    if ((insn & (1 << 24)) == 0)
6581
                        tcg_gen_addi_i32(addr, addr, -8);
6582
                    /* Load PC into tmp and CPSR into tmp2.  */
6583
                    tmp = gen_ld32(addr, 0);
6584
                    tcg_gen_addi_i32(addr, addr, 4);
6585
                    tmp2 = gen_ld32(addr, 0);
6586
                    if (insn & (1 << 21)) {
6587
                        /* Base writeback.  */
6588
                        if (insn & (1 << 24)) {
6589
                            tcg_gen_addi_i32(addr, addr, 4);
6590
                        } else {
6591
                            tcg_gen_addi_i32(addr, addr, -4);
6592
                        }
6593
                        store_reg(s, rn, addr);
6594
                    } else {
6595
                        dead_tmp(addr);
6596
                    }
6597
                    gen_rfe(s, tmp, tmp2);
6598
                } else {
6599
                    /* srs */
6600
                    op = (insn & 0x1f);
6601
                    if (op == (env->uncached_cpsr & CPSR_M)) {
6602
                        addr = load_reg(s, 13);
6603
                    } else {
6604
                        addr = new_tmp();
6605
                        gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
6606
                    }
6607
                    if ((insn & (1 << 24)) == 0) {
6608
                        tcg_gen_addi_i32(addr, addr, -8);
6609
                    }
6610
                    tmp = load_reg(s, 14);
6611
                    gen_st32(tmp, addr, 0);
6612
                    tcg_gen_addi_i32(addr, addr, 4);
6613
                    tmp = new_tmp();
6614
                    gen_helper_cpsr_read(tmp);
6615
                    gen_st32(tmp, addr, 0);
6616
                    if (insn & (1 << 21)) {
6617
                        if ((insn & (1 << 24)) == 0) {
6618
                            tcg_gen_addi_i32(addr, addr, -4);
6619
                        } else {
6620
                            tcg_gen_addi_i32(addr, addr, 4);
6621
                        }
6622
                        if (op == (env->uncached_cpsr & CPSR_M)) {
6623
                            store_reg(s, 13, addr);
6624
                        } else {
6625
                            gen_helper_set_r13_banked(cpu_env,
6626
                                tcg_const_i32(op), addr);
6627
                        }
6628
                    } else {
6629
                        dead_tmp(addr);
6630
                    }
6631
                }
6632
            } else {
6633
                int i;
6634
                /* Load/store multiple.  */
6635
                addr = load_reg(s, rn);
6636
                offset = 0;
6637
                for (i = 0; i < 16; i++) {
6638
                    if (insn & (1 << i))
6639
                        offset += 4;
6640
                }
6641
                if (insn & (1 << 24)) {
6642
                    tcg_gen_addi_i32(addr, addr, -offset);
6643
                }
6644

    
6645
                for (i = 0; i < 16; i++) {
6646
                    if ((insn & (1 << i)) == 0)
6647
                        continue;
6648
                    if (insn & (1 << 20)) {
6649
                        /* Load.  */
6650
                        tmp = gen_ld32(addr, IS_USER(s));
6651
                        if (i == 15) {
6652
                            gen_bx(s, tmp);
6653
                        } else {
6654
                            store_reg(s, i, tmp);
6655
                        }
6656
                    } else {
6657
                        /* Store.  */
6658
                        tmp = load_reg(s, i);
6659
                        gen_st32(tmp, addr, IS_USER(s));
6660
                    }
6661
                    tcg_gen_addi_i32(addr, addr, 4);
6662
                }
6663
                if (insn & (1 << 21)) {
6664
                    /* Base register writeback.  */
6665
                    if (insn & (1 << 24)) {
6666
                        tcg_gen_addi_i32(addr, addr, -offset);
6667
                    }
6668
                    /* Fault if writeback register is in register list.  */
6669
                    if (insn & (1 << rn))
6670
                        goto illegal_op;
6671
                    store_reg(s, rn, addr);
6672
                } else {
6673
                    dead_tmp(addr);
6674
                }
6675
            }
6676
        }
6677
        break;
6678
    case 5: /* Data processing register constant shift.  */
6679
        if (rn == 15)
6680
            gen_op_movl_T0_im(0);
6681
        else
6682
            gen_movl_T0_reg(s, rn);
6683
        gen_movl_T1_reg(s, rm);
6684
        op = (insn >> 21) & 0xf;
6685
        shiftop = (insn >> 4) & 3;
6686
        shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
6687
        conds = (insn & (1 << 20)) != 0;
6688
        logic_cc = (conds && thumb2_logic_op(op));
6689
        gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
6690
        if (gen_thumb2_data_op(s, op, conds, 0))
6691
            goto illegal_op;
6692
        if (rd != 15)
6693
            gen_movl_reg_T0(s, rd);
6694
        break;
6695
    case 13: /* Misc data processing.  */
6696
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
6697
        if (op < 4 && (insn & 0xf000) != 0xf000)
6698
            goto illegal_op;
6699
        switch (op) {
6700
        case 0: /* Register controlled shift.  */
6701
            gen_movl_T0_reg(s, rm);
6702
            gen_movl_T1_reg(s, rn);
6703
            if ((insn & 0x70) != 0)
6704
                goto illegal_op;
6705
            op = (insn >> 21) & 3;
6706
            if (insn & (1 << 20)) {
6707
                gen_shift_T1_T0_cc[op]();
6708
                gen_op_logic_T1_cc();
6709
            } else {
6710
                gen_shift_T1_T0[op]();
6711
            }
6712
            gen_movl_reg_T1(s, rd);
6713
            break;
6714
        case 1: /* Sign/zero extend.  */
6715
            gen_movl_T1_reg(s, rm);
6716
            shift = (insn >> 4) & 3;
6717
            /* ??? In many cases it's not neccessary to do a
6718
               rotate, a shift is sufficient.  */
6719
            if (shift != 0)
6720
                gen_op_rorl_T1_im(shift * 8);
6721
            op = (insn >> 20) & 7;
6722
            switch (op) {
6723
            case 0: gen_sxth(cpu_T[1]);   break;
6724
            case 1: gen_uxth(cpu_T[1]);   break;
6725
            case 2: gen_sxtb16(cpu_T[1]); break;
6726
            case 3: gen_uxtb16(cpu_T[1]); break;
6727
            case 4: gen_sxtb(cpu_T[1]);   break;
6728
            case 5: gen_uxtb(cpu_T[1]);   break;
6729
            default: goto illegal_op;
6730
            }
6731
            if (rn != 15) {
6732
                tmp = load_reg(s, rn);
6733
                if ((op >> 1) == 1) {
6734
                    gen_add16(cpu_T[1], tmp);
6735
                } else {
6736
                    tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp);
6737
                    dead_tmp(tmp);
6738
                }
6739
            }
6740
            gen_movl_reg_T1(s, rd);
6741
            break;
6742
        case 2: /* SIMD add/subtract.  */
6743
            op = (insn >> 20) & 7;
6744
            shift = (insn >> 4) & 7;
6745
            if ((op & 3) == 3 || (shift & 3) == 3)
6746
                goto illegal_op;
6747
            tmp = load_reg(s, rn);
6748
            tmp2 = load_reg(s, rm);
6749
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
6750
            dead_tmp(tmp2);
6751
            store_reg(s, rd, tmp);
6752
            break;
6753
        case 3: /* Other data processing.  */
6754
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
6755
            if (op < 4) {
6756
                /* Saturating add/subtract.  */
6757
                tmp = load_reg(s, rn);
6758
                tmp2 = load_reg(s, rm);
6759
                if (op & 2)
6760
                    gen_helper_double_saturate(tmp, tmp);
6761
                if (op & 1)
6762
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
6763
                else
6764
                    gen_helper_add_saturate(tmp, tmp, tmp2);
6765
                dead_tmp(tmp2);
6766
            } else {
6767
                tmp = load_reg(s, rn);
6768
                switch (op) {
6769
                case 0x0a: /* rbit */
6770
                    gen_helper_rbit(tmp, tmp);
6771
                    break;
6772
                case 0x08: /* rev */
6773
                    tcg_gen_bswap_i32(tmp, tmp);
6774
                    break;
6775
                case 0x09: /* rev16 */
6776
                    gen_rev16(tmp);
6777
                    break;
6778
                case 0x0b: /* revsh */
6779
                    gen_revsh(tmp);
6780
                    break;
6781
                case 0x10: /* sel */
6782
                    tmp2 = load_reg(s, rm);
6783
                    tmp3 = new_tmp();
6784
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6785
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6786
                    dead_tmp(tmp3);
6787
                    dead_tmp(tmp2);
6788
                    break;
6789
                case 0x18: /* clz */
6790
                    gen_helper_clz(tmp, tmp);
6791
                    break;
6792
                default:
6793
                    goto illegal_op;
6794
                }
6795
            }
6796
            store_reg(s, rd, tmp);
6797
            break;
6798
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
6799
            op = (insn >> 4) & 0xf;
6800
            tmp = load_reg(s, rn);
6801
            tmp2 = load_reg(s, rm);
6802
            switch ((insn >> 20) & 7) {
6803
            case 0: /* 32 x 32 -> 32 */
6804
                tcg_gen_mul_i32(tmp, tmp, tmp2);
6805
                dead_tmp(tmp2);
6806
                if (rs != 15) {
6807
                    tmp2 = load_reg(s, rs);
6808
                    if (op)
6809
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
6810
                    else
6811
                        tcg_gen_add_i32(tmp, tmp, tmp2);
6812
                    dead_tmp(tmp2);
6813
                }
6814
                break;
6815
            case 1: /* 16 x 16 -> 32 */
6816
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
6817
                dead_tmp(tmp2);
6818
                if (rs != 15) {
6819
                    tmp2 = load_reg(s, rs);
6820
                    gen_helper_add_setq(tmp, tmp, tmp2);
6821
                    dead_tmp(tmp2);
6822
                }
6823
                break;
6824
            case 2: /* Dual multiply add.  */
6825
            case 4: /* Dual multiply subtract.  */
6826
                if (op)
6827
                    gen_swap_half(tmp2);
6828
                gen_smul_dual(tmp, tmp2);
6829
                /* This addition cannot overflow.  */
6830
                if (insn & (1 << 22)) {
6831
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
6832
                } else {
6833
                    tcg_gen_add_i32(tmp, tmp, tmp2);
6834
                }
6835
                dead_tmp(tmp2);
6836
                if (rs != 15)
6837
                  {
6838
                    tmp2 = load_reg(s, rs);
6839
                    gen_helper_add_setq(tmp, tmp, tmp2);
6840
                    dead_tmp(tmp2);
6841
                  }
6842
                break;
6843
            case 3: /* 32 * 16 -> 32msb */
6844
                if (op)
6845
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6846
                else
6847
                    gen_sxth(tmp2);
6848
                gen_imulw(tmp, tmp2);
6849
                dead_tmp(tmp2);
6850
                if (rs != 15)
6851
                  {
6852
                    tmp2 = load_reg(s, rs);
6853
                    gen_helper_add_setq(tmp, tmp, tmp2);
6854
                    dead_tmp(tmp2);
6855
                  }
6856
                break;
6857
            case 5: case 6: /* 32 * 32 -> 32msb */
6858
                gen_imull(tmp, tmp2);
6859
                if (insn & (1 << 5)) {
6860
                    gen_roundqd(tmp, tmp2);
6861
                    dead_tmp(tmp2);
6862
                } else {
6863
                    dead_tmp(tmp);
6864
                    tmp = tmp2;
6865
                }
6866
                if (rs != 15) {
6867
                    tmp2 = load_reg(s, rs);
6868
                    if (insn & (1 << 21)) {
6869
                        tcg_gen_add_i32(tmp, tmp, tmp2);
6870
                    } else {
6871
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
6872
                    }
6873
                    dead_tmp(tmp2);
6874
                }
6875
                break;
6876
            case 7: /* Unsigned sum of absolute differences.  */
6877
                gen_helper_usad8(tmp, tmp, tmp2);
6878
                dead_tmp(tmp2);
6879
                if (rs != 15) {
6880
                    tmp2 = load_reg(s, rs);
6881
                    tcg_gen_add_i32(tmp, tmp, tmp2);
6882
                    dead_tmp(tmp2);
6883
                }
6884
                break;
6885
            }
6886
            store_reg(s, rd, tmp);
6887
            break;
6888
        case 6: case 7: /* 64-bit multiply, Divide.  */
6889
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
6890
            gen_movl_T0_reg(s, rn);
6891
            gen_movl_T1_reg(s, rm);
6892
            if ((op & 0x50) == 0x10) {
6893
                /* sdiv, udiv */
6894
                if (!arm_feature(env, ARM_FEATURE_DIV))
6895
                    goto illegal_op;
6896
                if (op & 0x20)
6897
                    gen_helper_udiv(cpu_T[0], cpu_T[0], cpu_T[1]);
6898
                else
6899
                    gen_helper_sdiv(cpu_T[0], cpu_T[0], cpu_T[1]);
6900
                gen_movl_reg_T0(s, rd);
6901
            } else if ((op & 0xe) == 0xc) {
6902
                /* Dual multiply accumulate long.  */
6903
                if (op & 1)
6904
                    gen_swap_half(cpu_T[1]);
6905
                gen_smul_dual(cpu_T[0], cpu_T[1]);
6906
                if (op & 0x10) {
6907
                    gen_op_subl_T0_T1();
6908
                } else {
6909
                    gen_op_addl_T0_T1();
6910
                }
6911
                gen_op_signbit_T1_T0();
6912
                gen_op_addq_T0_T1(rs, rd);
6913
                gen_movl_reg_T0(s, rs);
6914
                gen_movl_reg_T1(s, rd);
6915
            } else {
6916
                if (op & 0x20) {
6917
                    /* Unsigned 64-bit multiply  */
6918
                    gen_op_mull_T0_T1();
6919
                } else {
6920
                    if (op & 8) {
6921
                        /* smlalxy */
6922
                        gen_mulxy(cpu_T[0], cpu_T[1], op & 2, op & 1);
6923
                        gen_op_signbit_T1_T0();
6924
                    } else {
6925
                        /* Signed 64-bit multiply  */
6926
                        gen_op_imull_T0_T1();
6927
                    }
6928
                }
6929
                if (op & 4) {
6930
                    /* umaal */
6931
                    gen_op_addq_lo_T0_T1(rs);
6932
                    gen_op_addq_lo_T0_T1(rd);
6933
                } else if (op & 0x40) {
6934
                    /* 64-bit accumulate.  */
6935
                    gen_op_addq_T0_T1(rs, rd);
6936
                }
6937
                gen_movl_reg_T0(s, rs);
6938
                gen_movl_reg_T1(s, rd);
6939
            }
6940
            break;
6941
        }
6942
        break;
6943
    case 6: case 7: case 14: case 15:
6944
        /* Coprocessor.  */
6945
        if (((insn >> 24) & 3) == 3) {
6946
            /* Translate into the equivalent ARM encoding.  */
6947
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
6948
            if (disas_neon_data_insn(env, s, insn))
6949
                goto illegal_op;
6950
        } else {
6951
            if (insn & (1 << 28))
6952
                goto illegal_op;
6953
            if (disas_coproc_insn (env, s, insn))
6954
                goto illegal_op;
6955
        }
6956
        break;
6957
    case 8: case 9: case 10: case 11:
6958
        if (insn & (1 << 15)) {
6959
            /* Branches, misc control.  */
6960
            if (insn & 0x5000) {
6961
                /* Unconditional branch.  */
6962
                /* signextend(hw1[10:0]) -> offset[:12].  */
6963
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
6964
                /* hw1[10:0] -> offset[11:1].  */
6965
                offset |= (insn & 0x7ff) << 1;
6966
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
6967
                   offset[24:22] already have the same value because of the
6968
                   sign extension above.  */
6969
                offset ^= ((~insn) & (1 << 13)) << 10;
6970
                offset ^= ((~insn) & (1 << 11)) << 11;
6971

    
6972
                if (insn & (1 << 14)) {
6973
                    /* Branch and link.  */
6974
                    gen_op_movl_T1_im(s->pc | 1);
6975
                    gen_movl_reg_T1(s, 14);
6976
                }
6977

    
6978
                offset += s->pc;
6979
                if (insn & (1 << 12)) {
6980
                    /* b/bl */
6981
                    gen_jmp(s, offset);
6982
                } else {
6983
                    /* blx */
6984
                    offset &= ~(uint32_t)2;
6985
                    gen_bx_im(s, offset);
6986
                }
6987
            } else if (((insn >> 23) & 7) == 7) {
6988
                /* Misc control */
6989
                if (insn & (1 << 13))
6990
                    goto illegal_op;
6991

    
6992
                if (insn & (1 << 26)) {
6993
                    /* Secure monitor call (v6Z) */
6994
                    goto illegal_op; /* not implemented.  */
6995
                } else {
6996
                    op = (insn >> 20) & 7;
6997
                    switch (op) {
6998
                    case 0: /* msr cpsr.  */
6999
                        if (IS_M(env)) {
7000
                            gen_op_v7m_msr_T0(insn & 0xff);
7001
                            gen_movl_reg_T0(s, rn);
7002
                            gen_lookup_tb(s);
7003
                            break;
7004
                        }
7005
                        /* fall through */
7006
                    case 1: /* msr spsr.  */
7007
                        if (IS_M(env))
7008
                            goto illegal_op;
7009
                        gen_movl_T0_reg(s, rn);
7010
                        if (gen_set_psr_T0(s,
7011
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7012
                              op == 1))
7013
                            goto illegal_op;
7014
                        break;
7015
                    case 2: /* cps, nop-hint.  */
7016
                        if (((insn >> 8) & 7) == 0) {
7017
                            gen_nop_hint(s, insn & 0xff);
7018
                        }
7019
                        /* Implemented as NOP in user mode.  */
7020
                        if (IS_USER(s))
7021
                            break;
7022
                        offset = 0;
7023
                        imm = 0;
7024
                        if (insn & (1 << 10)) {
7025
                            if (insn & (1 << 7))
7026
                                offset |= CPSR_A;
7027
                            if (insn & (1 << 6))
7028
                                offset |= CPSR_I;
7029
                            if (insn & (1 << 5))
7030
                                offset |= CPSR_F;
7031
                            if (insn & (1 << 9))
7032
                                imm = CPSR_A | CPSR_I | CPSR_F;
7033
                        }
7034
                        if (insn & (1 << 8)) {
7035
                            offset |= 0x1f;
7036
                            imm |= (insn & 0x1f);
7037
                        }
7038
                        if (offset) {
7039
                            gen_op_movl_T0_im(imm);
7040
                            gen_set_psr_T0(s, offset, 0);
7041
                        }
7042
                        break;
7043
                    case 3: /* Special control operations.  */
7044
                        op = (insn >> 4) & 0xf;
7045
                        switch (op) {
7046
                        case 2: /* clrex */
7047
                            gen_op_clrex();
7048
                            break;
7049
                        case 4: /* dsb */
7050
                        case 5: /* dmb */
7051
                        case 6: /* isb */
7052
                            /* These execute as NOPs.  */
7053
                            ARCH(7);
7054
                            break;
7055
                        default:
7056
                            goto illegal_op;
7057
                        }
7058
                        break;
7059
                    case 4: /* bxj */
7060
                        /* Trivial implementation equivalent to bx.  */
7061
                        tmp = load_reg(s, rn);
7062
                        gen_bx(s, tmp);
7063
                        break;
7064
                    case 5: /* Exception return.  */
7065
                        /* Unpredictable in user mode.  */
7066
                        goto illegal_op;
7067
                    case 6: /* mrs cpsr.  */
7068
                        if (IS_M(env)) {
7069
                            gen_op_v7m_mrs_T0(insn & 0xff);
7070
                        } else {
7071
                            gen_helper_cpsr_read(cpu_T[0]);
7072
                        }
7073
                        gen_movl_reg_T0(s, rd);
7074
                        break;
7075
                    case 7: /* mrs spsr.  */
7076
                        /* Not accessible in user mode.  */
7077
                        if (IS_USER(s) || IS_M(env))
7078
                            goto illegal_op;
7079
                        tmp = load_cpu_field(spsr);
7080
                        store_reg(s, rd, tmp);
7081
                        break;
7082
                    }
7083
                }
7084
            } else {
7085
                /* Conditional branch.  */
7086
                op = (insn >> 22) & 0xf;
7087
                /* Generate a conditional jump to next instruction.  */
7088
                s->condlabel = gen_new_label();
7089
                gen_test_cc(op ^ 1, s->condlabel);
7090
                s->condjmp = 1;
7091

    
7092
                /* offset[11:1] = insn[10:0] */
7093
                offset = (insn & 0x7ff) << 1;
7094
                /* offset[17:12] = insn[21:16].  */
7095
                offset |= (insn & 0x003f0000) >> 4;
7096
                /* offset[31:20] = insn[26].  */
7097
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7098
                /* offset[18] = insn[13].  */
7099
                offset |= (insn & (1 << 13)) << 5;
7100
                /* offset[19] = insn[11].  */
7101
                offset |= (insn & (1 << 11)) << 8;
7102

    
7103
                /* jump to the offset */
7104
                gen_jmp(s, s->pc + offset);
7105
            }
7106
        } else {
7107
            /* Data processing immediate.  */
7108
            if (insn & (1 << 25)) {
7109
                if (insn & (1 << 24)) {
7110
                    if (insn & (1 << 20))
7111
                        goto illegal_op;
7112
                    /* Bitfield/Saturate.  */
7113
                    op = (insn >> 21) & 7;
7114
                    imm = insn & 0x1f;
7115
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7116
                    if (rn == 15) {
7117
                        tmp = new_tmp();
7118
                        tcg_gen_movi_i32(tmp, 0);
7119
                    } else {
7120
                        tmp = load_reg(s, rn);
7121
                    }
7122
                    switch (op) {
7123
                    case 2: /* Signed bitfield extract.  */
7124
                        imm++;
7125
                        if (shift + imm > 32)
7126
                            goto illegal_op;
7127
                        if (imm < 32)
7128
                            gen_sbfx(tmp, shift, imm);
7129
                        break;
7130
                    case 6: /* Unsigned bitfield extract.  */
7131
                        imm++;
7132
                        if (shift + imm > 32)
7133
                            goto illegal_op;
7134
                        if (imm < 32)
7135
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
7136
                        break;
7137
                    case 3: /* Bitfield insert/clear.  */
7138
                        if (imm < shift)
7139
                            goto illegal_op;
7140
                        imm = imm + 1 - shift;
7141
                        if (imm != 32) {
7142
                            tmp2 = load_reg(s, rd);
7143
                            gen_bfi(tmp, tmp2, tmp,
7144
                                    shift, ((1u << imm) - 1) << shift);
7145
                            dead_tmp(tmp2);
7146
                        }
7147
                        break;
7148
                    case 7:
7149
                        goto illegal_op;
7150
                    default: /* Saturate.  */
7151
                        if (shift) {
7152
                            if (op & 1)
7153
                                tcg_gen_sari_i32(tmp, tmp, shift);
7154
                            else
7155
                                tcg_gen_shli_i32(tmp, tmp, shift);
7156
                        }
7157
                        tmp2 = tcg_const_i32(imm);
7158
                        if (op & 4) {
7159
                            /* Unsigned.  */
7160
                            if ((op & 1) && shift == 0)
7161
                                gen_helper_usat16(tmp, tmp, tmp2);
7162
                            else
7163
                                gen_helper_usat(tmp, tmp, tmp2);
7164
                        } else {
7165
                            /* Signed.  */
7166
                            if ((op & 1) && shift == 0)
7167
                                gen_helper_ssat16(tmp, tmp, tmp2);
7168
                            else
7169
                                gen_helper_ssat(tmp, tmp, tmp2);
7170
                        }
7171
                        break;
7172
                    }
7173
                    store_reg(s, rd, tmp);
7174
                } else {
7175
                    imm = ((insn & 0x04000000) >> 15)
7176
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
7177
                    if (insn & (1 << 22)) {
7178
                        /* 16-bit immediate.  */
7179
                        imm |= (insn >> 4) & 0xf000;
7180
                        if (insn & (1 << 23)) {
7181
                            /* movt */
7182
                            gen_movl_T0_reg(s, rd);
7183
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
7184
                            tcg_gen_ori_i32(cpu_T[0], cpu_T[0], imm << 16);
7185
                        } else {
7186
                            /* movw */
7187
                            gen_op_movl_T0_im(imm);
7188
                        }
7189
                    } else {
7190
                        /* Add/sub 12-bit immediate.  */
7191
                        if (rn == 15) {
7192
                            offset = s->pc & ~(uint32_t)3;
7193
                            if (insn & (1 << 23))
7194
                                offset -= imm;
7195
                            else
7196
                                offset += imm;
7197
                            gen_op_movl_T0_im(offset);
7198
                        } else {
7199
                            gen_movl_T0_reg(s, rn);
7200
                            gen_op_movl_T1_im(imm);
7201
                            if (insn & (1 << 23))
7202
                                gen_op_subl_T0_T1();
7203
                            else
7204
                                gen_op_addl_T0_T1();
7205
                        }
7206
                    }
7207
                    gen_movl_reg_T0(s, rd);
7208
                }
7209
            } else {
7210
                int shifter_out = 0;
7211
                /* modified 12-bit immediate.  */
7212
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7213
                imm = (insn & 0xff);
7214
                switch (shift) {
7215
                case 0: /* XY */
7216
                    /* Nothing to do.  */
7217
                    break;
7218
                case 1: /* 00XY00XY */
7219
                    imm |= imm << 16;
7220
                    break;
7221
                case 2: /* XY00XY00 */
7222
                    imm |= imm << 16;
7223
                    imm <<= 8;
7224
                    break;
7225
                case 3: /* XYXYXYXY */
7226
                    imm |= imm << 16;
7227
                    imm |= imm << 8;
7228
                    break;
7229
                default: /* Rotated constant.  */
7230
                    shift = (shift << 1) | (imm >> 7);
7231
                    imm |= 0x80;
7232
                    imm = imm << (32 - shift);
7233
                    shifter_out = 1;
7234
                    break;
7235
                }
7236
                gen_op_movl_T1_im(imm);
7237
                rn = (insn >> 16) & 0xf;
7238
                if (rn == 15)
7239
                    gen_op_movl_T0_im(0);
7240
                else
7241
                    gen_movl_T0_reg(s, rn);
7242
                op = (insn >> 21) & 0xf;
7243
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7244
                                       shifter_out))
7245
                    goto illegal_op;
7246
                rd = (insn >> 8) & 0xf;
7247
                if (rd != 15) {
7248
                    gen_movl_reg_T0(s, rd);
7249
                }
7250
            }
7251
        }
7252
        break;
7253
    case 12: /* Load/store single data item.  */
7254
        {
7255
        int postinc = 0;
7256
        int writeback = 0;
7257
        int user;
7258
        if ((insn & 0x01100000) == 0x01000000) {
7259
            if (disas_neon_ls_insn(env, s, insn))
7260
                goto illegal_op;
7261
            break;
7262
        }
7263
        user = IS_USER(s);
7264
        if (rn == 15) {
7265
            addr = new_tmp();
7266
            /* PC relative.  */
7267
            /* s->pc has already been incremented by 4.  */
7268
            imm = s->pc & 0xfffffffc;
7269
            if (insn & (1 << 23))
7270
                imm += insn & 0xfff;
7271
            else
7272
                imm -= insn & 0xfff;
7273
            tcg_gen_movi_i32(addr, imm);
7274
        } else {
7275
            addr = load_reg(s, rn);
7276
            if (insn & (1 << 23)) {
7277
                /* Positive offset.  */
7278
                imm = insn & 0xfff;
7279
                tcg_gen_addi_i32(addr, addr, imm);
7280
            } else {
7281
                op = (insn >> 8) & 7;
7282
                imm = insn & 0xff;
7283
                switch (op) {
7284
                case 0: case 8: /* Shifted Register.  */
7285
                    shift = (insn >> 4) & 0xf;
7286
                    if (shift > 3)
7287
                        goto illegal_op;
7288
                    tmp = load_reg(s, rm);
7289
                    if (shift)
7290
                        tcg_gen_shli_i32(tmp, tmp, shift);
7291
                    tcg_gen_add_i32(addr, addr, tmp);
7292
                    dead_tmp(tmp);
7293
                    break;
7294
                case 4: /* Negative offset.  */
7295
                    tcg_gen_addi_i32(addr, addr, -imm);
7296
                    break;
7297
                case 6: /* User privilege.  */
7298
                    tcg_gen_addi_i32(addr, addr, imm);
7299
                    user = 1;
7300
                    break;
7301
                case 1: /* Post-decrement.  */
7302
                    imm = -imm;
7303
                    /* Fall through.  */
7304
                case 3: /* Post-increment.  */
7305
                    postinc = 1;
7306
                    writeback = 1;
7307
                    break;
7308
                case 5: /* Pre-decrement.  */
7309
                    imm = -imm;
7310
                    /* Fall through.  */
7311
                case 7: /* Pre-increment.  */
7312
                    tcg_gen_addi_i32(addr, addr, imm);
7313
                    writeback = 1;
7314
                    break;
7315
                default:
7316
                    goto illegal_op;
7317
                }
7318
            }
7319
        }
7320
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7321
        if (insn & (1 << 20)) {
7322
            /* Load.  */
7323
            if (rs == 15 && op != 2) {
7324
                if (op & 2)
7325
                    goto illegal_op;
7326
                /* Memory hint.  Implemented as NOP.  */
7327
            } else {
7328
                switch (op) {
7329
                case 0: tmp = gen_ld8u(addr, user); break;
7330
                case 4: tmp = gen_ld8s(addr, user); break;
7331
                case 1: tmp = gen_ld16u(addr, user); break;
7332
                case 5: tmp = gen_ld16s(addr, user); break;
7333
                case 2: tmp = gen_ld32(addr, user); break;
7334
                default: goto illegal_op;
7335
                }
7336
                if (rs == 15) {
7337
                    gen_bx(s, tmp);
7338
                } else {
7339
                    store_reg(s, rs, tmp);
7340
                }
7341
            }
7342
        } else {
7343
            /* Store.  */
7344
            if (rs == 15)
7345
                goto illegal_op;
7346
            tmp = load_reg(s, rs);
7347
            switch (op) {
7348
            case 0: gen_st8(tmp, addr, user); break;
7349
            case 1: gen_st16(tmp, addr, user); break;
7350
            case 2: gen_st32(tmp, addr, user); break;
7351
            default: goto illegal_op;
7352
            }
7353
        }
7354
        if (postinc)
7355
            tcg_gen_addi_i32(addr, addr, imm);
7356
        if (writeback) {
7357
            store_reg(s, rn, addr);
7358
        } else {
7359
            dead_tmp(addr);
7360
        }
7361
        }
7362
        break;
7363
    default:
7364
        goto illegal_op;
7365
    }
7366
    return 0;
7367
illegal_op:
7368
    return 1;
7369
}
7370

    
7371
static void disas_thumb_insn(CPUState *env, DisasContext *s)
7372
{
7373
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
7374
    int32_t offset;
7375
    int i;
7376
    TCGv tmp;
7377
    TCGv tmp2;
7378
    TCGv addr;
7379

    
7380
    if (s->condexec_mask) {
7381
        cond = s->condexec_cond;
7382
        s->condlabel = gen_new_label();
7383
        gen_test_cc(cond ^ 1, s->condlabel);
7384
        s->condjmp = 1;
7385
    }
7386

    
7387
    insn = lduw_code(s->pc);
7388
    s->pc += 2;
7389

    
7390
    switch (insn >> 12) {
7391
    case 0: case 1:
7392
        rd = insn & 7;
7393
        op = (insn >> 11) & 3;
7394
        if (op == 3) {
7395
            /* add/subtract */
7396
            rn = (insn >> 3) & 7;
7397
            gen_movl_T0_reg(s, rn);
7398
            if (insn & (1 << 10)) {
7399
                /* immediate */
7400
                gen_op_movl_T1_im((insn >> 6) & 7);
7401
            } else {
7402
                /* reg */
7403
                rm = (insn >> 6) & 7;
7404
                gen_movl_T1_reg(s, rm);
7405
            }
7406
            if (insn & (1 << 9)) {
7407
                if (s->condexec_mask)
7408
                    gen_op_subl_T0_T1();
7409
                else
7410
                    gen_op_subl_T0_T1_cc();
7411
            } else {
7412
                if (s->condexec_mask)
7413
                    gen_op_addl_T0_T1();
7414
                else
7415
                    gen_op_addl_T0_T1_cc();
7416
            }
7417
            gen_movl_reg_T0(s, rd);
7418
        } else {
7419
            /* shift immediate */
7420
            rm = (insn >> 3) & 7;
7421
            shift = (insn >> 6) & 0x1f;
7422
            tmp = load_reg(s, rm);
7423
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7424
            if (!s->condexec_mask)
7425
                gen_logic_CC(tmp);
7426
            store_reg(s, rd, tmp);
7427
        }
7428
        break;
7429
    case 2: case 3:
7430
        /* arithmetic large immediate */
7431
        op = (insn >> 11) & 3;
7432
        rd = (insn >> 8) & 0x7;
7433
        if (op == 0) {
7434
            gen_op_movl_T0_im(insn & 0xff);
7435
        } else {
7436
            gen_movl_T0_reg(s, rd);
7437
            gen_op_movl_T1_im(insn & 0xff);
7438
        }
7439
        switch (op) {
7440
        case 0: /* mov */
7441
            if (!s->condexec_mask)
7442
                gen_op_logic_T0_cc();
7443
            break;
7444
        case 1: /* cmp */
7445
            gen_op_subl_T0_T1_cc();
7446
            break;
7447
        case 2: /* add */
7448
            if (s->condexec_mask)
7449
                gen_op_addl_T0_T1();
7450
            else
7451
                gen_op_addl_T0_T1_cc();
7452
            break;
7453
        case 3: /* sub */
7454
            if (s->condexec_mask)
7455
                gen_op_subl_T0_T1();
7456
            else
7457
                gen_op_subl_T0_T1_cc();
7458
            break;
7459
        }
7460
        if (op != 1)
7461
            gen_movl_reg_T0(s, rd);
7462
        break;
7463
    case 4:
7464
        if (insn & (1 << 11)) {
7465
            rd = (insn >> 8) & 7;
7466
            /* load pc-relative.  Bit 1 of PC is ignored.  */
7467
            val = s->pc + 2 + ((insn & 0xff) * 4);
7468
            val &= ~(uint32_t)2;
7469
            addr = new_tmp();
7470
            tcg_gen_movi_i32(addr, val);
7471
            tmp = gen_ld32(addr, IS_USER(s));
7472
            dead_tmp(addr);
7473
            store_reg(s, rd, tmp);
7474
            break;
7475
        }
7476
        if (insn & (1 << 10)) {
7477
            /* data processing extended or blx */
7478
            rd = (insn & 7) | ((insn >> 4) & 8);
7479
            rm = (insn >> 3) & 0xf;
7480
            op = (insn >> 8) & 3;
7481
            switch (op) {
7482
            case 0: /* add */
7483
                gen_movl_T0_reg(s, rd);
7484
                gen_movl_T1_reg(s, rm);
7485
                gen_op_addl_T0_T1();
7486
                gen_movl_reg_T0(s, rd);
7487
                break;
7488
            case 1: /* cmp */
7489
                gen_movl_T0_reg(s, rd);
7490
                gen_movl_T1_reg(s, rm);
7491
                gen_op_subl_T0_T1_cc();
7492
                break;
7493
            case 2: /* mov/cpy */
7494
                gen_movl_T0_reg(s, rm);
7495
                gen_movl_reg_T0(s, rd);
7496
                break;
7497
            case 3:/* branch [and link] exchange thumb register */
7498
                tmp = load_reg(s, rm);
7499
                if (insn & (1 << 7)) {
7500
                    val = (uint32_t)s->pc | 1;
7501
                    tmp2 = new_tmp();
7502
                    tcg_gen_movi_i32(tmp2, val);
7503
                    store_reg(s, 14, tmp2);
7504
                }
7505
                gen_bx(s, tmp);
7506
                break;
7507
            }
7508
            break;
7509
        }
7510

    
7511
        /* data processing register */
7512
        rd = insn & 7;
7513
        rm = (insn >> 3) & 7;
7514
        op = (insn >> 6) & 0xf;
7515
        if (op == 2 || op == 3 || op == 4 || op == 7) {
7516
            /* the shift/rotate ops want the operands backwards */
7517
            val = rm;
7518
            rm = rd;
7519
            rd = val;
7520
            val = 1;
7521
        } else {
7522
            val = 0;
7523
        }
7524

    
7525
        if (op == 9) /* neg */
7526
            gen_op_movl_T0_im(0);
7527
        else if (op != 0xf) /* mvn doesn't read its first operand */
7528
            gen_movl_T0_reg(s, rd);
7529

    
7530
        gen_movl_T1_reg(s, rm);
7531
        switch (op) {
7532
        case 0x0: /* and */
7533
            gen_op_andl_T0_T1();
7534
            if (!s->condexec_mask)
7535
                gen_op_logic_T0_cc();
7536
            break;
7537
        case 0x1: /* eor */
7538
            gen_op_xorl_T0_T1();
7539
            if (!s->condexec_mask)
7540
                gen_op_logic_T0_cc();
7541
            break;
7542
        case 0x2: /* lsl */
7543
            if (s->condexec_mask) {
7544
                gen_op_shll_T1_T0();
7545
            } else {
7546
                gen_op_shll_T1_T0_cc();
7547
                gen_op_logic_T1_cc();
7548
            }
7549
            break;
7550
        case 0x3: /* lsr */
7551
            if (s->condexec_mask) {
7552
                gen_op_shrl_T1_T0();
7553
            } else {
7554
                gen_op_shrl_T1_T0_cc();
7555
                gen_op_logic_T1_cc();
7556
            }
7557
            break;
7558
        case 0x4: /* asr */
7559
            if (s->condexec_mask) {
7560
                gen_op_sarl_T1_T0();
7561
            } else {
7562
                gen_op_sarl_T1_T0_cc();
7563
                gen_op_logic_T1_cc();
7564
            }
7565
            break;
7566
        case 0x5: /* adc */
7567
            if (s->condexec_mask)
7568
                gen_adc_T0_T1();
7569
            else
7570
                gen_op_adcl_T0_T1_cc();
7571
            break;
7572
        case 0x6: /* sbc */
7573
            if (s->condexec_mask)
7574
                gen_sbc_T0_T1();
7575
            else
7576
                gen_op_sbcl_T0_T1_cc();
7577
            break;
7578
        case 0x7: /* ror */
7579
            if (s->condexec_mask) {
7580
                gen_op_rorl_T1_T0();
7581
            } else {
7582
                gen_op_rorl_T1_T0_cc();
7583
                gen_op_logic_T1_cc();
7584
            }
7585
            break;
7586
        case 0x8: /* tst */
7587
            gen_op_andl_T0_T1();
7588
            gen_op_logic_T0_cc();
7589
            rd = 16;
7590
            break;
7591
        case 0x9: /* neg */
7592
            if (s->condexec_mask)
7593
                gen_op_subl_T0_T1();
7594
            else
7595
                gen_op_subl_T0_T1_cc();
7596
            break;
7597
        case 0xa: /* cmp */
7598
            gen_op_subl_T0_T1_cc();
7599
            rd = 16;
7600
            break;
7601
        case 0xb: /* cmn */
7602
            gen_op_addl_T0_T1_cc();
7603
            rd = 16;
7604
            break;
7605
        case 0xc: /* orr */
7606
            gen_op_orl_T0_T1();
7607
            if (!s->condexec_mask)
7608
                gen_op_logic_T0_cc();
7609
            break;
7610
        case 0xd: /* mul */
7611
            gen_op_mull_T0_T1();
7612
            if (!s->condexec_mask)
7613
                gen_op_logic_T0_cc();
7614
            break;
7615
        case 0xe: /* bic */
7616
            gen_op_bicl_T0_T1();
7617
            if (!s->condexec_mask)
7618
                gen_op_logic_T0_cc();
7619
            break;
7620
        case 0xf: /* mvn */
7621
            gen_op_notl_T1();
7622
            if (!s->condexec_mask)
7623
                gen_op_logic_T1_cc();
7624
            val = 1;
7625
            rm = rd;
7626
            break;
7627
        }
7628
        if (rd != 16) {
7629
            if (val)
7630
                gen_movl_reg_T1(s, rm);
7631
            else
7632
                gen_movl_reg_T0(s, rd);
7633
        }
7634
        break;
7635

    
7636
    case 5:
7637
        /* load/store register offset.  */
7638
        rd = insn & 7;
7639
        rn = (insn >> 3) & 7;
7640
        rm = (insn >> 6) & 7;
7641
        op = (insn >> 9) & 7;
7642
        addr = load_reg(s, rn);
7643
        tmp = load_reg(s, rm);
7644
        tcg_gen_add_i32(addr, addr, tmp);
7645
        dead_tmp(tmp);
7646

    
7647
        if (op < 3) /* store */
7648
            tmp = load_reg(s, rd);
7649

    
7650
        switch (op) {
7651
        case 0: /* str */
7652
            gen_st32(tmp, addr, IS_USER(s));
7653
            break;
7654
        case 1: /* strh */
7655
            gen_st16(tmp, addr, IS_USER(s));
7656
            break;
7657
        case 2: /* strb */
7658
            gen_st8(tmp, addr, IS_USER(s));
7659
            break;
7660
        case 3: /* ldrsb */
7661
            tmp = gen_ld8s(addr, IS_USER(s));
7662
            break;
7663
        case 4: /* ldr */
7664
            tmp = gen_ld32(addr, IS_USER(s));
7665
            break;
7666
        case 5: /* ldrh */
7667
            tmp = gen_ld16u(addr, IS_USER(s));
7668
            break;
7669
        case 6: /* ldrb */
7670
            tmp = gen_ld8u(addr, IS_USER(s));
7671
            break;
7672
        case 7: /* ldrsh */
7673
            tmp = gen_ld16s(addr, IS_USER(s));
7674
            break;
7675
        }
7676
        if (op >= 3) /* load */
7677
            store_reg(s, rd, tmp);
7678
        dead_tmp(addr);
7679
        break;
7680

    
7681
    case 6:
7682
        /* load/store word immediate offset */
7683
        rd = insn & 7;
7684
        rn = (insn >> 3) & 7;
7685
        addr = load_reg(s, rn);
7686
        val = (insn >> 4) & 0x7c;
7687
        tcg_gen_addi_i32(addr, addr, val);
7688

    
7689
        if (insn & (1 << 11)) {
7690
            /* load */
7691
            tmp = gen_ld32(addr, IS_USER(s));
7692
            store_reg(s, rd, tmp);
7693
        } else {
7694
            /* store */
7695
            tmp = load_reg(s, rd);
7696
            gen_st32(tmp, addr, IS_USER(s));
7697
        }
7698
        dead_tmp(addr);
7699
        break;
7700

    
7701
    case 7:
7702
        /* load/store byte immediate offset */
7703
        rd = insn & 7;
7704
        rn = (insn >> 3) & 7;
7705
        addr = load_reg(s, rn);
7706
        val = (insn >> 6) & 0x1f;
7707
        tcg_gen_addi_i32(addr, addr, val);
7708

    
7709
        if (insn & (1 << 11)) {
7710
            /* load */
7711
            tmp = gen_ld8u(addr, IS_USER(s));
7712
            store_reg(s, rd, tmp);
7713
        } else {
7714
            /* store */
7715
            tmp = load_reg(s, rd);
7716
            gen_st8(tmp, addr, IS_USER(s));
7717
        }
7718
        dead_tmp(addr);
7719
        break;
7720

    
7721
    case 8:
7722
        /* load/store halfword immediate offset */
7723
        rd = insn & 7;
7724
        rn = (insn >> 3) & 7;
7725
        addr = load_reg(s, rn);
7726
        val = (insn >> 5) & 0x3e;
7727
        tcg_gen_addi_i32(addr, addr, val);
7728

    
7729
        if (insn & (1 << 11)) {
7730
            /* load */
7731
            tmp = gen_ld16u(addr, IS_USER(s));
7732
            store_reg(s, rd, tmp);
7733
        } else {
7734
            /* store */
7735
            tmp = load_reg(s, rd);
7736
            gen_st16(tmp, addr, IS_USER(s));
7737
        }
7738
        dead_tmp(addr);
7739
        break;
7740

    
7741
    case 9:
7742
        /* load/store from stack */
7743
        rd = (insn >> 8) & 7;
7744
        addr = load_reg(s, 13);
7745
        val = (insn & 0xff) * 4;
7746
        tcg_gen_addi_i32(addr, addr, val);
7747

    
7748
        if (insn & (1 << 11)) {
7749
            /* load */
7750
            tmp = gen_ld32(addr, IS_USER(s));
7751
            store_reg(s, rd, tmp);
7752
        } else {
7753
            /* store */
7754
            tmp = load_reg(s, rd);
7755
            gen_st32(tmp, addr, IS_USER(s));
7756
        }
7757
        dead_tmp(addr);
7758
        break;
7759

    
7760
    case 10:
7761
        /* add to high reg */
7762
        rd = (insn >> 8) & 7;
7763
        if (insn & (1 << 11)) {
7764
            /* SP */
7765
            gen_movl_T0_reg(s, 13);
7766
        } else {
7767
            /* PC. bit 1 is ignored.  */
7768
            gen_op_movl_T0_im((s->pc + 2) & ~(uint32_t)2);
7769
        }
7770
        val = (insn & 0xff) * 4;
7771
        gen_op_movl_T1_im(val);
7772
        gen_op_addl_T0_T1();
7773
        gen_movl_reg_T0(s, rd);
7774
        break;
7775

    
7776
    case 11:
7777
        /* misc */
7778
        op = (insn >> 8) & 0xf;
7779
        switch (op) {
7780
        case 0:
7781
            /* adjust stack pointer */
7782
            tmp = load_reg(s, 13);
7783
            val = (insn & 0x7f) * 4;
7784
            if (insn & (1 << 7))
7785
              val = -(int32_t)val;
7786
            tcg_gen_addi_i32(tmp, tmp, val);
7787
            store_reg(s, 13, tmp);
7788
            break;
7789

    
7790
        case 2: /* sign/zero extend.  */
7791
            ARCH(6);
7792
            rd = insn & 7;
7793
            rm = (insn >> 3) & 7;
7794
            tmp = load_reg(s, rm);
7795
            switch ((insn >> 6) & 3) {
7796
            case 0: gen_sxth(tmp); break;
7797
            case 1: gen_sxtb(tmp); break;
7798
            case 2: gen_uxth(tmp); break;
7799
            case 3: gen_uxtb(tmp); break;
7800
            }
7801
            store_reg(s, rd, tmp);
7802
            break;
7803
        case 4: case 5: case 0xc: case 0xd:
7804
            /* push/pop */
7805
            addr = load_reg(s, 13);
7806
            if (insn & (1 << 8))
7807
                offset = 4;
7808
            else
7809
                offset = 0;
7810
            for (i = 0; i < 8; i++) {
7811
                if (insn & (1 << i))
7812
                    offset += 4;
7813
            }
7814
            if ((insn & (1 << 11)) == 0) {
7815
                tcg_gen_addi_i32(addr, addr, -offset);
7816
            }
7817
            for (i = 0; i < 8; i++) {
7818
                if (insn & (1 << i)) {
7819
                    if (insn & (1 << 11)) {
7820
                        /* pop */
7821
                        tmp = gen_ld32(addr, IS_USER(s));
7822
                        store_reg(s, i, tmp);
7823
                    } else {
7824
                        /* push */
7825
                        tmp = load_reg(s, i);
7826
                        gen_st32(tmp, addr, IS_USER(s));
7827
                    }
7828
                    /* advance to the next address.  */
7829
                    tcg_gen_addi_i32(addr, addr, 4);
7830
                }
7831
            }
7832
            if (insn & (1 << 8)) {
7833
                if (insn & (1 << 11)) {
7834
                    /* pop pc */
7835
                    tmp = gen_ld32(addr, IS_USER(s));
7836
                    /* don't set the pc until the rest of the instruction
7837
                       has completed */
7838
                } else {
7839
                    /* push lr */
7840
                    tmp = load_reg(s, 14);
7841
                    gen_st32(tmp, addr, IS_USER(s));
7842
                }
7843
                tcg_gen_addi_i32(addr, addr, 4);
7844
            }
7845
            if ((insn & (1 << 11)) == 0) {
7846
                tcg_gen_addi_i32(addr, addr, -offset);
7847
            }
7848
            /* write back the new stack pointer */
7849
            store_reg(s, 13, addr);
7850
            /* set the new PC value */
7851
            if ((insn & 0x0900) == 0x0900)
7852
                gen_bx(s, tmp);
7853
            break;
7854

    
7855
        case 1: case 3: case 9: case 11: /* czb */
7856
            rm = insn & 7;
7857
            tmp = load_reg(s, rm);
7858
            tmp2 = tcg_const_i32(0);
7859
            s->condlabel = gen_new_label();
7860
            s->condjmp = 1;
7861
            if (insn & (1 << 11))
7862
                tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, s->condlabel);
7863
            else
7864
                tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, s->condlabel);
7865
            dead_tmp(tmp);
7866
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
7867
            val = (uint32_t)s->pc + 2;
7868
            val += offset;
7869
            gen_jmp(s, val);
7870
            break;
7871

    
7872
        case 15: /* IT, nop-hint.  */
7873
            if ((insn & 0xf) == 0) {
7874
                gen_nop_hint(s, (insn >> 4) & 0xf);
7875
                break;
7876
            }
7877
            /* If Then.  */
7878
            s->condexec_cond = (insn >> 4) & 0xe;
7879
            s->condexec_mask = insn & 0x1f;
7880
            /* No actual code generated for this insn, just setup state.  */
7881
            break;
7882

    
7883
        case 0xe: /* bkpt */
7884
            gen_set_condexec(s);
7885
            gen_op_movl_T0_im((long)s->pc - 2);
7886
            gen_set_pc_T0();
7887
            gen_exception(EXCP_BKPT);
7888
            s->is_jmp = DISAS_JUMP;
7889
            break;
7890

    
7891
        case 0xa: /* rev */
7892
            ARCH(6);
7893
            rn = (insn >> 3) & 0x7;
7894
            rd = insn & 0x7;
7895
            tmp = load_reg(s, rn);
7896
            switch ((insn >> 6) & 3) {
7897
            case 0: tcg_gen_bswap_i32(tmp, tmp); break;
7898
            case 1: gen_rev16(tmp); break;
7899
            case 3: gen_revsh(tmp); break;
7900
            default: goto illegal_op;
7901
            }
7902
            store_reg(s, rd, tmp);
7903
            break;
7904

    
7905
        case 6: /* cps */
7906
            ARCH(6);
7907
            if (IS_USER(s))
7908
                break;
7909
            if (IS_M(env)) {
7910
                val = (insn & (1 << 4)) != 0;
7911
                gen_op_movl_T0_im(val);
7912
                /* PRIMASK */
7913
                if (insn & 1)
7914
                    gen_op_v7m_msr_T0(16);
7915
                /* FAULTMASK */
7916
                if (insn & 2)
7917
                    gen_op_v7m_msr_T0(17);
7918

    
7919
                gen_lookup_tb(s);
7920
            } else {
7921
                if (insn & (1 << 4))
7922
                    shift = CPSR_A | CPSR_I | CPSR_F;
7923
                else
7924
                    shift = 0;
7925

    
7926
                val = ((insn & 7) << 6) & shift;
7927
                gen_op_movl_T0_im(val);
7928
                gen_set_psr_T0(s, shift, 0);
7929
            }
7930
            break;
7931

    
7932
        default:
7933
            goto undef;
7934
        }
7935
        break;
7936

    
7937
    case 12:
7938
        /* load/store multiple */
7939
        rn = (insn >> 8) & 0x7;
7940
        addr = load_reg(s, rn);
7941
        for (i = 0; i < 8; i++) {
7942
            if (insn & (1 << i)) {
7943
                if (insn & (1 << 11)) {
7944
                    /* load */
7945
                    tmp = gen_ld32(addr, IS_USER(s));
7946
                    store_reg(s, i, tmp);
7947
                } else {
7948
                    /* store */
7949
                    tmp = load_reg(s, i);
7950
                    gen_st32(tmp, addr, IS_USER(s));
7951
                }
7952
                /* advance to the next address */
7953
                tcg_gen_addi_i32(addr, addr, 4);
7954
            }
7955
        }
7956
        /* Base register writeback.  */
7957
        if ((insn & (1 << rn)) == 0) {
7958
            store_reg(s, rn, addr);
7959
        } else {
7960
            dead_tmp(addr);
7961
        }
7962
        break;
7963

    
7964
    case 13:
7965
        /* conditional branch or swi */
7966
        cond = (insn >> 8) & 0xf;
7967
        if (cond == 0xe)
7968
            goto undef;
7969

    
7970
        if (cond == 0xf) {
7971
            /* swi */
7972
            gen_set_condexec(s);
7973
            gen_op_movl_T0_im((long)s->pc | 1);
7974
            /* Don't set r15.  */
7975
            gen_set_pc_T0();
7976
            s->is_jmp = DISAS_SWI;
7977
            break;
7978
        }
7979
        /* generate a conditional jump to next instruction */
7980
        s->condlabel = gen_new_label();
7981
        gen_test_cc(cond ^ 1, s->condlabel);
7982
        s->condjmp = 1;
7983
        gen_movl_T1_reg(s, 15);
7984

    
7985
        /* jump to the offset */
7986
        val = (uint32_t)s->pc + 2;
7987
        offset = ((int32_t)insn << 24) >> 24;
7988
        val += offset << 1;
7989
        gen_jmp(s, val);
7990
        break;
7991

    
7992
    case 14:
7993
        if (insn & (1 << 11)) {
7994
            if (disas_thumb2_insn(env, s, insn))
7995
              goto undef32;
7996
            break;
7997
        }
7998
        /* unconditional branch */
7999
        val = (uint32_t)s->pc;
8000
        offset = ((int32_t)insn << 21) >> 21;
8001
        val += (offset << 1) + 2;
8002
        gen_jmp(s, val);
8003
        break;
8004

    
8005
    case 15:
8006
        if (disas_thumb2_insn(env, s, insn))
8007
          goto undef32;
8008
        break;
8009
    }
8010
    return;
8011
undef32:
8012
    gen_set_condexec(s);
8013
    gen_op_movl_T0_im((long)s->pc - 4);
8014
    gen_set_pc_T0();
8015
    gen_exception(EXCP_UDEF);
8016
    s->is_jmp = DISAS_JUMP;
8017
    return;
8018
illegal_op:
8019
undef:
8020
    gen_set_condexec(s);
8021
    gen_op_movl_T0_im((long)s->pc - 2);
8022
    gen_set_pc_T0();
8023
    gen_exception(EXCP_UDEF);
8024
    s->is_jmp = DISAS_JUMP;
8025
}
8026

    
8027
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8028
   basic block 'tb'. If search_pc is TRUE, also generate PC
8029
   information for each intermediate instruction. */
8030
static inline int gen_intermediate_code_internal(CPUState *env,
8031
                                                 TranslationBlock *tb,
8032
                                                 int search_pc)
8033
{
8034
    DisasContext dc1, *dc = &dc1;
8035
    uint16_t *gen_opc_end;
8036
    int j, lj;
8037
    target_ulong pc_start;
8038
    uint32_t next_page_start;
8039

    
8040
    /* generate intermediate code */
8041
    num_temps = 0;
8042
    memset(temps, 0, sizeof(temps));
8043

    
8044
    pc_start = tb->pc;
8045

    
8046
    dc->tb = tb;
8047

    
8048
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8049

    
8050
    dc->is_jmp = DISAS_NEXT;
8051
    dc->pc = pc_start;
8052
    dc->singlestep_enabled = env->singlestep_enabled;
8053
    dc->condjmp = 0;
8054
    dc->thumb = env->thumb;
8055
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8056
    dc->condexec_cond = env->condexec_bits >> 4;
8057
    dc->is_mem = 0;
8058
#if !defined(CONFIG_USER_ONLY)
8059
    if (IS_M(env)) {
8060
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8061
    } else {
8062
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8063
    }
8064
#endif
8065
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8066
    lj = -1;
8067
    /* Reset the conditional execution bits immediately. This avoids
8068
       complications trying to do it at the end of the block.  */
8069
    if (env->condexec_bits)
8070
      {
8071
        TCGv tmp = new_tmp();
8072
        tcg_gen_movi_i32(tmp, 0);
8073
        store_cpu_field(tmp, condexec_bits);
8074
      }
8075
    do {
8076
#ifndef CONFIG_USER_ONLY
8077
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8078
            /* We always get here via a jump, so know we are not in a
8079
               conditional execution block.  */
8080
            gen_exception(EXCP_EXCEPTION_EXIT);
8081
        }
8082
#endif
8083

    
8084
        if (env->nb_breakpoints > 0) {
8085
            for(j = 0; j < env->nb_breakpoints; j++) {
8086
                if (env->breakpoints[j] == dc->pc) {
8087
                    gen_set_condexec(dc);
8088
                    gen_op_movl_T0_im((long)dc->pc);
8089
                    gen_set_pc_T0();
8090
                    gen_exception(EXCP_DEBUG);
8091
                    dc->is_jmp = DISAS_JUMP;
8092
                    /* Advance PC so that clearing the breakpoint will
8093
                       invalidate this TB.  */
8094
                    dc->pc += 2;
8095
                    goto done_generating;
8096
                    break;
8097
                }
8098
            }
8099
        }
8100
        if (search_pc) {
8101
            j = gen_opc_ptr - gen_opc_buf;
8102
            if (lj < j) {
8103
                lj++;
8104
                while (lj < j)
8105
                    gen_opc_instr_start[lj++] = 0;
8106
            }
8107
            gen_opc_pc[lj] = dc->pc;
8108
            gen_opc_instr_start[lj] = 1;
8109
        }
8110

    
8111
        if (env->thumb) {
8112
            disas_thumb_insn(env, dc);
8113
            if (dc->condexec_mask) {
8114
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8115
                                   | ((dc->condexec_mask >> 4) & 1);
8116
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8117
                if (dc->condexec_mask == 0) {
8118
                    dc->condexec_cond = 0;
8119
                }
8120
            }
8121
        } else {
8122
            disas_arm_insn(env, dc);
8123
        }
8124
        if (num_temps) {
8125
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8126
            num_temps = 0;
8127
        }
8128

    
8129
        if (dc->condjmp && !dc->is_jmp) {
8130
            gen_set_label(dc->condlabel);
8131
            dc->condjmp = 0;
8132
        }
8133
        /* Terminate the TB on memory ops if watchpoints are present.  */
8134
        /* FIXME: This should be replacd by the deterministic execution
8135
         * IRQ raising bits.  */
8136
        if (dc->is_mem && env->nb_watchpoints)
8137
            break;
8138

    
8139
        /* Translation stops when a conditional branch is enoutered.
8140
         * Otherwise the subsequent code could get translated several times.
8141
         * Also stop translation when a page boundary is reached.  This
8142
         * ensures prefech aborts occur at the right place.  */
8143
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8144
             !env->singlestep_enabled &&
8145
             dc->pc < next_page_start);
8146

    
8147
    /* At this stage dc->condjmp will only be set when the skipped
8148
       instruction was a conditional branch or trap, and the PC has
8149
       already been written.  */
8150
    if (__builtin_expect(env->singlestep_enabled, 0)) {
8151
        /* Make sure the pc is updated, and raise a debug exception.  */
8152
        if (dc->condjmp) {
8153
            gen_set_condexec(dc);
8154
            if (dc->is_jmp == DISAS_SWI) {
8155
                gen_exception(EXCP_SWI);
8156
            } else {
8157
                gen_exception(EXCP_DEBUG);
8158
            }
8159
            gen_set_label(dc->condlabel);
8160
        }
8161
        if (dc->condjmp || !dc->is_jmp) {
8162
            gen_op_movl_T0_im((long)dc->pc);
8163
            gen_set_pc_T0();
8164
            dc->condjmp = 0;
8165
        }
8166
        gen_set_condexec(dc);
8167
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8168
            gen_exception(EXCP_SWI);
8169
        } else {
8170
            /* FIXME: Single stepping a WFI insn will not halt
8171
               the CPU.  */
8172
            gen_exception(EXCP_DEBUG);
8173
        }
8174
    } else {
8175
        /* While branches must always occur at the end of an IT block,
8176
           there are a few other things that can cause us to terminate
8177
           the TB in the middel of an IT block:
8178
            - Exception generating instructions (bkpt, swi, undefined).
8179
            - Page boundaries.
8180
            - Hardware watchpoints.
8181
           Hardware breakpoints have already been handled and skip this code.
8182
         */
8183
        gen_set_condexec(dc);
8184
        switch(dc->is_jmp) {
8185
        case DISAS_NEXT:
8186
            gen_goto_tb(dc, 1, dc->pc);
8187
            break;
8188
        default:
8189
        case DISAS_JUMP:
8190
        case DISAS_UPDATE:
8191
            /* indicate that the hash table must be used to find the next TB */
8192
            tcg_gen_exit_tb(0);
8193
            break;
8194
        case DISAS_TB_JUMP:
8195
            /* nothing more to generate */
8196
            break;
8197
        case DISAS_WFI:
8198
            gen_helper_wfi();
8199
            break;
8200
        case DISAS_SWI:
8201
            gen_exception(EXCP_SWI);
8202
            break;
8203
        }
8204
        if (dc->condjmp) {
8205
            gen_set_label(dc->condlabel);
8206
            gen_set_condexec(dc);
8207
            gen_goto_tb(dc, 1, dc->pc);
8208
            dc->condjmp = 0;
8209
        }
8210
    }
8211
done_generating:
8212
    *gen_opc_ptr = INDEX_op_end;
8213

    
8214
#ifdef DEBUG_DISAS
8215
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8216
        fprintf(logfile, "----------------\n");
8217
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8218
        target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8219
        fprintf(logfile, "\n");
8220
    }
8221
#endif
8222
    if (search_pc) {
8223
        j = gen_opc_ptr - gen_opc_buf;
8224
        lj++;
8225
        while (lj <= j)
8226
            gen_opc_instr_start[lj++] = 0;
8227
    } else {
8228
        tb->size = dc->pc - pc_start;
8229
    }
8230
    return 0;
8231
}
8232

    
8233
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8234
{
8235
    return gen_intermediate_code_internal(env, tb, 0);
8236
}
8237

    
8238
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8239
{
8240
    return gen_intermediate_code_internal(env, tb, 1);
8241
}
8242

    
8243
static const char *cpu_mode_names[16] = {
8244
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8245
  "???", "???", "???", "und", "???", "???", "???", "sys"
8246
};
8247

    
8248
void cpu_dump_state(CPUState *env, FILE *f,
8249
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8250
                    int flags)
8251
{
8252
    int i;
8253
    union {
8254
        uint32_t i;
8255
        float s;
8256
    } s0, s1;
8257
    CPU_DoubleU d;
8258
    /* ??? This assumes float64 and double have the same layout.
8259
       Oh well, it's only debug dumps.  */
8260
    union {
8261
        float64 f64;
8262
        double d;
8263
    } d0;
8264
    uint32_t psr;
8265

    
8266
    for(i=0;i<16;i++) {
8267
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8268
        if ((i % 4) == 3)
8269
            cpu_fprintf(f, "\n");
8270
        else
8271
            cpu_fprintf(f, " ");
8272
    }
8273
    psr = cpsr_read(env);
8274
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8275
                psr,
8276
                psr & (1 << 31) ? 'N' : '-',
8277
                psr & (1 << 30) ? 'Z' : '-',
8278
                psr & (1 << 29) ? 'C' : '-',
8279
                psr & (1 << 28) ? 'V' : '-',
8280
                psr & CPSR_T ? 'T' : 'A',
8281
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8282

    
8283
    for (i = 0; i < 16; i++) {
8284
        d.d = env->vfp.regs[i];
8285
        s0.i = d.l.lower;
8286
        s1.i = d.l.upper;
8287
        d0.f64 = d.d;
8288
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8289
                    i * 2, (int)s0.i, s0.s,
8290
                    i * 2 + 1, (int)s1.i, s1.s,
8291
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8292
                    d0.d);
8293
    }
8294
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8295
}
8296