Statistics
| Branch: | Revision:

root / target-arm / translate.c @ d2856f1a

History | View | Annotate | Download (294.9 kB)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
190

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

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

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

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

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

    
223
/* Value extensions.  */
224
#define gen_uxtb(var) tcg_gen_andi_i32(var, var, 0xff)
225
#define gen_uxth(var) tcg_gen_andi_i32(var, var, 0xffff)
226
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
227
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
228

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
454
/* FIXME:  Implement this natively.  */
455
static inline void tcg_gen_not_i32(TCGv t0, TCGv t1)
456
{
457
    tcg_gen_xori_i32(t0, t1, ~0);
458
}
459

    
460
/* FIXME:  Implement this natively.  */
461
static inline void tcg_gen_neg_i64(TCGv dest, TCGv src)
462
{
463
    tcg_gen_sub_i64(dest, tcg_const_i64(0), src);
464
}
465

    
466
/* T0 &= ~T1.  Clobbers T1.  */
467
/* FIXME: Implement bic natively.  */
468
static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
469
{
470
    TCGv tmp = new_tmp();
471
    tcg_gen_not_i32(tmp, t1);
472
    tcg_gen_and_i32(dest, t0, tmp);
473
    dead_tmp(tmp);
474
}
475
static inline void gen_op_bicl_T0_T1(void)
476
{
477
    gen_op_notl_T1();
478
    gen_op_andl_T0_T1();
479
}
480

    
481
/* FIXME:  Implement this natively.  */
482
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
483

    
484
/* FIXME:  Implement this natively.  */
485
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
486
{
487
    TCGv tmp;
488

    
489
    if (i == 0)
490
        return;
491

    
492
    tmp = new_tmp();
493
    tcg_gen_shri_i32(tmp, t1, i);
494
    tcg_gen_shli_i32(t1, t1, 32 - i);
495
    tcg_gen_or_i32(t0, t1, tmp);
496
    dead_tmp(tmp);
497
}
498

    
499
static void shifter_out_im(TCGv var, int shift)
500
{
501
    TCGv tmp = new_tmp();
502
    if (shift == 0) {
503
        tcg_gen_andi_i32(tmp, var, 1);
504
    } else {
505
        tcg_gen_shri_i32(tmp, var, shift);
506
        if (shift != 31);
507
            tcg_gen_andi_i32(tmp, tmp, 1);
508
    }
509
    gen_set_CF(tmp);
510
    dead_tmp(tmp);
511
}
512

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

    
563
static inline void gen_arm_shift_reg(TCGv var, int shiftop,
564
                                     TCGv shift, int flags)
565
{
566
    if (flags) {
567
        switch (shiftop) {
568
        case 0: gen_helper_shl_cc(var, var, shift); break;
569
        case 1: gen_helper_shr_cc(var, var, shift); break;
570
        case 2: gen_helper_sar_cc(var, var, shift); break;
571
        case 3: gen_helper_ror_cc(var, var, shift); break;
572
        }
573
    } else {
574
        switch (shiftop) {
575
        case 0: gen_helper_shl(var, var, shift); break;
576
        case 1: gen_helper_shr(var, var, shift); break;
577
        case 2: gen_helper_sar(var, var, shift); break;
578
        case 3: gen_helper_ror(var, var, shift); break;
579
        }
580
    }
581
    dead_tmp(shift);
582
}
583

    
584
#define PAS_OP(pfx) \
585
    switch (op2) {  \
586
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
587
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
588
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
589
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
590
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
591
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
592
    }
593
static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
594
{
595
    TCGv tmp;
596

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

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

    
642
    switch (op1) {
643
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
644
    case 0:
645
        tmp = tcg_temp_new(TCG_TYPE_PTR);
646
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
647
        PAS_OP(s)
648
        break;
649
    case 4:
650
        tmp = tcg_temp_new(TCG_TYPE_PTR);
651
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
652
        PAS_OP(u)
653
        break;
654
#undef gen_pas_helper
655
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
656
    case 1:
657
        PAS_OP(q);
658
        break;
659
    case 2:
660
        PAS_OP(sh);
661
        break;
662
    case 5:
663
        PAS_OP(uq);
664
        break;
665
    case 6:
666
        PAS_OP(uh);
667
        break;
668
#undef gen_pas_helper
669
    }
670
}
671
#undef PAS_OP
672

    
673
static void gen_test_cc(int cc, int label)
674
{
675
    TCGv tmp;
676
    TCGv tmp2;
677
    TCGv zero;
678
    int inv;
679

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

    
773
const uint8_t table_logic_cc[16] = {
774
    1, /* and */
775
    1, /* xor */
776
    0, /* sub */
777
    0, /* rsb */
778
    0, /* add */
779
    0, /* adc */
780
    0, /* sbc */
781
    0, /* rsc */
782
    1, /* andl */
783
    1, /* xorl */
784
    0, /* cmp */
785
    0, /* cmn */
786
    1, /* orr */
787
    1, /* mov */
788
    1, /* bic */
789
    1, /* mvn */
790
};
791

    
792
/* Set PC and Thumb state from an immediate address.  */
793
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
794
{
795
    TCGv tmp;
796

    
797
    s->is_jmp = DISAS_UPDATE;
798
    tmp = new_tmp();
799
    if (s->thumb != (addr & 1)) {
800
        tcg_gen_movi_i32(tmp, addr & 1);
801
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
802
    }
803
    tcg_gen_movi_i32(tmp, addr & ~1);
804
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
805
    dead_tmp(tmp);
806
}
807

    
808
/* Set PC and Thumb state from var.  var is marked as dead.  */
809
static inline void gen_bx(DisasContext *s, TCGv var)
810
{
811
    TCGv tmp;
812

    
813
    s->is_jmp = DISAS_UPDATE;
814
    tmp = new_tmp();
815
    tcg_gen_andi_i32(tmp, var, 1);
816
    store_cpu_field(tmp, thumb);
817
    tcg_gen_andi_i32(var, var, ~1);
818
    store_cpu_field(var, regs[15]);
819
}
820

    
821
/* TODO: This should be removed.  Use gen_bx instead.  */
822
static inline void gen_bx_T0(DisasContext *s)
823
{
824
    TCGv tmp = new_tmp();
825
    tcg_gen_mov_i32(tmp, cpu_T[0]);
826
    gen_bx(s, tmp);
827
}
828

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

    
886
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
887
{
888
    load_reg_var(s, cpu_T[0], reg);
889
}
890

    
891
static inline void gen_movl_T1_reg(DisasContext *s, int reg)
892
{
893
    load_reg_var(s, cpu_T[1], reg);
894
}
895

    
896
static inline void gen_movl_T2_reg(DisasContext *s, int reg)
897
{
898
    load_reg_var(s, cpu_T[2], reg);
899
}
900

    
901
static inline void gen_set_pc_im(uint32_t val)
902
{
903
    TCGv tmp = new_tmp();
904
    tcg_gen_movi_i32(tmp, val);
905
    store_cpu_field(tmp, regs[15]);
906
}
907

    
908
static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
909
{
910
    TCGv tmp;
911
    if (reg == 15) {
912
        tmp = new_tmp();
913
        tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
914
    } else {
915
        tmp = cpu_T[t];
916
    }
917
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
918
    if (reg == 15) {
919
        dead_tmp(tmp);
920
        s->is_jmp = DISAS_JUMP;
921
    }
922
}
923

    
924
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
925
{
926
    gen_movl_reg_TN(s, reg, 0);
927
}
928

    
929
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
930
{
931
    gen_movl_reg_TN(s, reg, 1);
932
}
933

    
934
/* Force a TB lookup after an instruction that changes the CPU state.  */
935
static inline void gen_lookup_tb(DisasContext *s)
936
{
937
    gen_op_movl_T0_im(s->pc);
938
    gen_movl_reg_T0(s, 15);
939
    s->is_jmp = DISAS_UPDATE;
940
}
941

    
942
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
943
                                       TCGv var)
944
{
945
    int val, rm, shift, shiftop;
946
    TCGv offset;
947

    
948
    if (!(insn & (1 << 25))) {
949
        /* immediate */
950
        val = insn & 0xfff;
951
        if (!(insn & (1 << 23)))
952
            val = -val;
953
        if (val != 0)
954
            tcg_gen_addi_i32(var, var, val);
955
    } else {
956
        /* shift/register */
957
        rm = (insn) & 0xf;
958
        shift = (insn >> 7) & 0x1f;
959
        shiftop = (insn >> 5) & 3;
960
        offset = load_reg(s, rm);
961
        gen_arm_shift_im(offset, shiftop, shift, 0);
962
        if (!(insn & (1 << 23)))
963
            tcg_gen_sub_i32(var, var, offset);
964
        else
965
            tcg_gen_add_i32(var, var, offset);
966
        dead_tmp(offset);
967
    }
968
}
969

    
970
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
971
                                        int extra, TCGv var)
972
{
973
    int val, rm;
974
    TCGv offset;
975

    
976
    if (insn & (1 << 22)) {
977
        /* immediate */
978
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
979
        if (!(insn & (1 << 23)))
980
            val = -val;
981
        val += extra;
982
        if (val != 0)
983
            tcg_gen_addi_i32(var, var, val);
984
    } else {
985
        /* register */
986
        if (extra)
987
            tcg_gen_addi_i32(var, var, extra);
988
        rm = (insn) & 0xf;
989
        offset = load_reg(s, rm);
990
        if (!(insn & (1 << 23)))
991
            tcg_gen_sub_i32(var, var, offset);
992
        else
993
            tcg_gen_add_i32(var, var, offset);
994
        dead_tmp(offset);
995
    }
996
}
997

    
998
#define VFP_OP2(name)                                                 \
999
static inline void gen_vfp_##name(int dp)                             \
1000
{                                                                     \
1001
    if (dp)                                                           \
1002
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
1003
    else                                                              \
1004
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
1005
}
1006

    
1007
#define VFP_OP1(name)                               \
1008
static inline void gen_vfp_##name(int dp, int arg)  \
1009
{                                                   \
1010
    if (dp)                                         \
1011
        gen_op_vfp_##name##d(arg);                  \
1012
    else                                            \
1013
        gen_op_vfp_##name##s(arg);                  \
1014
}
1015

    
1016
VFP_OP2(add)
1017
VFP_OP2(sub)
1018
VFP_OP2(mul)
1019
VFP_OP2(div)
1020

    
1021
#undef VFP_OP2
1022

    
1023
static inline void gen_vfp_abs(int dp)
1024
{
1025
    if (dp)
1026
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1027
    else
1028
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1029
}
1030

    
1031
static inline void gen_vfp_neg(int dp)
1032
{
1033
    if (dp)
1034
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1035
    else
1036
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1037
}
1038

    
1039
static inline void gen_vfp_sqrt(int dp)
1040
{
1041
    if (dp)
1042
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1043
    else
1044
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1045
}
1046

    
1047
static inline void gen_vfp_cmp(int dp)
1048
{
1049
    if (dp)
1050
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1051
    else
1052
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1053
}
1054

    
1055
static inline void gen_vfp_cmpe(int dp)
1056
{
1057
    if (dp)
1058
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1059
    else
1060
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1061
}
1062

    
1063
static inline void gen_vfp_F1_ld0(int dp)
1064
{
1065
    if (dp)
1066
        tcg_gen_movi_i64(cpu_F1d, 0);
1067
    else
1068
        tcg_gen_movi_i32(cpu_F1s, 0);
1069
}
1070

    
1071
static inline void gen_vfp_uito(int dp)
1072
{
1073
    if (dp)
1074
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1075
    else
1076
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1077
}
1078

    
1079
static inline void gen_vfp_sito(int dp)
1080
{
1081
    if (dp)
1082
        gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
1083
    else
1084
        gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
1085
}
1086

    
1087
static inline void gen_vfp_toui(int dp)
1088
{
1089
    if (dp)
1090
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1091
    else
1092
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1093
}
1094

    
1095
static inline void gen_vfp_touiz(int dp)
1096
{
1097
    if (dp)
1098
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1099
    else
1100
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1101
}
1102

    
1103
static inline void gen_vfp_tosi(int dp)
1104
{
1105
    if (dp)
1106
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1107
    else
1108
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1109
}
1110

    
1111
static inline void gen_vfp_tosiz(int dp)
1112
{
1113
    if (dp)
1114
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1115
    else
1116
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1117
}
1118

    
1119
#define VFP_GEN_FIX(name) \
1120
static inline void gen_vfp_##name(int dp, int shift) \
1121
{ \
1122
    if (dp) \
1123
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
1124
    else \
1125
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
1126
}
1127
VFP_GEN_FIX(tosh)
1128
VFP_GEN_FIX(tosl)
1129
VFP_GEN_FIX(touh)
1130
VFP_GEN_FIX(toul)
1131
VFP_GEN_FIX(shto)
1132
VFP_GEN_FIX(slto)
1133
VFP_GEN_FIX(uhto)
1134
VFP_GEN_FIX(ulto)
1135
#undef VFP_GEN_FIX
1136

    
1137
static inline void gen_vfp_ld(DisasContext *s, int dp)
1138
{
1139
    if (dp)
1140
        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1141
    else
1142
        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1143
}
1144

    
1145
static inline void gen_vfp_st(DisasContext *s, int dp)
1146
{
1147
    if (dp)
1148
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1149
    else
1150
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1151
}
1152

    
1153
static inline long
1154
vfp_reg_offset (int dp, int reg)
1155
{
1156
    if (dp)
1157
        return offsetof(CPUARMState, vfp.regs[reg]);
1158
    else if (reg & 1) {
1159
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1160
          + offsetof(CPU_DoubleU, l.upper);
1161
    } else {
1162
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
1163
          + offsetof(CPU_DoubleU, l.lower);
1164
    }
1165
}
1166

    
1167
/* Return the offset of a 32-bit piece of a NEON register.
1168
   zero is the least significant end of the register.  */
1169
static inline long
1170
neon_reg_offset (int reg, int n)
1171
{
1172
    int sreg;
1173
    sreg = reg * 2 + n;
1174
    return vfp_reg_offset(0, sreg);
1175
}
1176

    
1177
/* FIXME: Remove these.  */
1178
#define neon_T0 cpu_T[0]
1179
#define neon_T1 cpu_T[1]
1180
#define NEON_GET_REG(T, reg, n) \
1181
  tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1182
#define NEON_SET_REG(T, reg, n) \
1183
  tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
1184

    
1185
static TCGv neon_load_reg(int reg, int pass)
1186
{
1187
    TCGv tmp = new_tmp();
1188
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1189
    return tmp;
1190
}
1191

    
1192
static void neon_store_reg(int reg, int pass, TCGv var)
1193
{
1194
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1195
    dead_tmp(var);
1196
}
1197

    
1198
static inline void neon_load_reg64(TCGv var, int reg)
1199
{
1200
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1201
}
1202

    
1203
static inline void neon_store_reg64(TCGv var, int reg)
1204
{
1205
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1206
}
1207

    
1208
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1209
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1210
#define tcg_gen_st_f32 tcg_gen_st_i32
1211
#define tcg_gen_st_f64 tcg_gen_st_i64
1212

    
1213
static inline void gen_mov_F0_vreg(int dp, int reg)
1214
{
1215
    if (dp)
1216
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1217
    else
1218
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1219
}
1220

    
1221
static inline void gen_mov_F1_vreg(int dp, int reg)
1222
{
1223
    if (dp)
1224
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1225
    else
1226
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1227
}
1228

    
1229
static inline void gen_mov_vreg_F0(int dp, int reg)
1230
{
1231
    if (dp)
1232
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1233
    else
1234
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1235
}
1236

    
1237
#define ARM_CP_RW_BIT        (1 << 20)
1238

    
1239
static inline void iwmmxt_load_reg(TCGv var, int reg)
1240
{
1241
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1242
}
1243

    
1244
static inline void iwmmxt_store_reg(TCGv var, int reg)
1245
{
1246
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1247
}
1248

    
1249
static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
1250
{
1251
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1252
}
1253

    
1254
static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
1255
{
1256
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1257
}
1258

    
1259
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1260
{
1261
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1262
}
1263

    
1264
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1265
{
1266
    iwmmxt_store_reg(cpu_M0, rn);
1267
}
1268

    
1269
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1270
{
1271
    iwmmxt_load_reg(cpu_M0, rn);
1272
}
1273

    
1274
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1275
{
1276
    iwmmxt_load_reg(cpu_V1, rn);
1277
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1278
}
1279

    
1280
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1281
{
1282
    iwmmxt_load_reg(cpu_V1, rn);
1283
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1284
}
1285

    
1286
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1287
{
1288
    iwmmxt_load_reg(cpu_V1, rn);
1289
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1290
}
1291

    
1292
#define IWMMXT_OP(name) \
1293
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1294
{ \
1295
    iwmmxt_load_reg(cpu_V1, rn); \
1296
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1297
}
1298

    
1299
#define IWMMXT_OP_ENV(name) \
1300
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1301
{ \
1302
    iwmmxt_load_reg(cpu_V1, rn); \
1303
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1304
}
1305

    
1306
#define IWMMXT_OP_ENV_SIZE(name) \
1307
IWMMXT_OP_ENV(name##b) \
1308
IWMMXT_OP_ENV(name##w) \
1309
IWMMXT_OP_ENV(name##l)
1310

    
1311
#define IWMMXT_OP_ENV1(name) \
1312
static inline void gen_op_iwmmxt_##name##_M0(void) \
1313
{ \
1314
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1315
}
1316

    
1317
IWMMXT_OP(maddsq)
1318
IWMMXT_OP(madduq)
1319
IWMMXT_OP(sadb)
1320
IWMMXT_OP(sadw)
1321
IWMMXT_OP(mulslw)
1322
IWMMXT_OP(mulshw)
1323
IWMMXT_OP(mululw)
1324
IWMMXT_OP(muluhw)
1325
IWMMXT_OP(macsw)
1326
IWMMXT_OP(macuw)
1327

    
1328
IWMMXT_OP_ENV_SIZE(unpackl)
1329
IWMMXT_OP_ENV_SIZE(unpackh)
1330

    
1331
IWMMXT_OP_ENV1(unpacklub)
1332
IWMMXT_OP_ENV1(unpackluw)
1333
IWMMXT_OP_ENV1(unpacklul)
1334
IWMMXT_OP_ENV1(unpackhub)
1335
IWMMXT_OP_ENV1(unpackhuw)
1336
IWMMXT_OP_ENV1(unpackhul)
1337
IWMMXT_OP_ENV1(unpacklsb)
1338
IWMMXT_OP_ENV1(unpacklsw)
1339
IWMMXT_OP_ENV1(unpacklsl)
1340
IWMMXT_OP_ENV1(unpackhsb)
1341
IWMMXT_OP_ENV1(unpackhsw)
1342
IWMMXT_OP_ENV1(unpackhsl)
1343

    
1344
IWMMXT_OP_ENV_SIZE(cmpeq)
1345
IWMMXT_OP_ENV_SIZE(cmpgtu)
1346
IWMMXT_OP_ENV_SIZE(cmpgts)
1347

    
1348
IWMMXT_OP_ENV_SIZE(mins)
1349
IWMMXT_OP_ENV_SIZE(minu)
1350
IWMMXT_OP_ENV_SIZE(maxs)
1351
IWMMXT_OP_ENV_SIZE(maxu)
1352

    
1353
IWMMXT_OP_ENV_SIZE(subn)
1354
IWMMXT_OP_ENV_SIZE(addn)
1355
IWMMXT_OP_ENV_SIZE(subu)
1356
IWMMXT_OP_ENV_SIZE(addu)
1357
IWMMXT_OP_ENV_SIZE(subs)
1358
IWMMXT_OP_ENV_SIZE(adds)
1359

    
1360
IWMMXT_OP_ENV(avgb0)
1361
IWMMXT_OP_ENV(avgb1)
1362
IWMMXT_OP_ENV(avgw0)
1363
IWMMXT_OP_ENV(avgw1)
1364

    
1365
IWMMXT_OP(msadb)
1366

    
1367
IWMMXT_OP_ENV(packuw)
1368
IWMMXT_OP_ENV(packul)
1369
IWMMXT_OP_ENV(packuq)
1370
IWMMXT_OP_ENV(packsw)
1371
IWMMXT_OP_ENV(packsl)
1372
IWMMXT_OP_ENV(packsq)
1373

    
1374
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1375
{
1376
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1377
}
1378

    
1379
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1380
{
1381
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1382
}
1383

    
1384
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1385
{
1386
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1387
}
1388

    
1389
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1390
{
1391
    iwmmxt_load_reg(cpu_V1, rn);
1392
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1393
}
1394

    
1395
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1396
{
1397
    TCGv tmp = tcg_const_i32(shift);
1398
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1399
}
1400

    
1401
static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1402
{
1403
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1404
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1405
    tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1406
}
1407

    
1408
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1409
{
1410
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1411
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1412
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1413
}
1414

    
1415
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1416
{
1417
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1418
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1419
    if (mask != ~0u)
1420
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1421
}
1422

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

    
1431
static void gen_op_iwmmxt_set_cup(void)
1432
{
1433
    TCGv tmp;
1434
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1435
    tcg_gen_ori_i32(tmp, tmp, 1);
1436
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1437
}
1438

    
1439
static void gen_op_iwmmxt_setpsr_nz(void)
1440
{
1441
    TCGv tmp = new_tmp();
1442
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1443
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1444
}
1445

    
1446
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1447
{
1448
    iwmmxt_load_reg(cpu_V1, rn);
1449
    tcg_gen_andi_i64(cpu_V1, cpu_V1, 0xffffffffu);
1450
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1451
}
1452

    
1453

    
1454
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1455
{
1456
    iwmmxt_load_reg(cpu_V0, rn);
1457
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1458
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1459
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1460
}
1461

    
1462
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1463
{
1464
    tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1465
    tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1466
    tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1467
    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1468
    iwmmxt_store_reg(cpu_V0, rn);
1469
}
1470

    
1471
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1472
{
1473
    int rd;
1474
    uint32_t offset;
1475

    
1476
    rd = (insn >> 16) & 0xf;
1477
    gen_movl_T1_reg(s, rd);
1478

    
1479
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1480
    if (insn & (1 << 24)) {
1481
        /* Pre indexed */
1482
        if (insn & (1 << 23))
1483
            gen_op_addl_T1_im(offset);
1484
        else
1485
            gen_op_addl_T1_im(-offset);
1486

    
1487
        if (insn & (1 << 21))
1488
            gen_movl_reg_T1(s, rd);
1489
    } else if (insn & (1 << 21)) {
1490
        /* Post indexed */
1491
        if (insn & (1 << 23))
1492
            gen_op_movl_T0_im(offset);
1493
        else
1494
            gen_op_movl_T0_im(- offset);
1495
        gen_op_addl_T0_T1();
1496
        gen_movl_reg_T0(s, rd);
1497
    } else if (!(insn & (1 << 23)))
1498
        return 1;
1499
    return 0;
1500
}
1501

    
1502
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1503
{
1504
    int rd = (insn >> 0) & 0xf;
1505

    
1506
    if (insn & (1 << 8))
1507
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1508
            return 1;
1509
        else
1510
            gen_op_iwmmxt_movl_T0_wCx(rd);
1511
    else
1512
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1513

    
1514
    gen_op_movl_T1_im(mask);
1515
    gen_op_andl_T0_T1();
1516
    return 0;
1517
}
1518

    
1519
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1520
   (ie. an undefined instruction).  */
1521
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1522
{
1523
    int rd, wrd;
1524
    int rdhi, rdlo, rd0, rd1, i;
1525
    TCGv tmp;
1526

    
1527
    if ((insn & 0x0e000e00) == 0x0c000000) {
1528
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1529
            wrd = insn & 0xf;
1530
            rdlo = (insn >> 12) & 0xf;
1531
            rdhi = (insn >> 16) & 0xf;
1532
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1533
                gen_iwmmxt_movl_T0_T1_wRn(wrd);
1534
                gen_movl_reg_T0(s, rdlo);
1535
                gen_movl_reg_T1(s, rdhi);
1536
            } else {                                        /* TMCRR */
1537
                gen_movl_T0_reg(s, rdlo);
1538
                gen_movl_T1_reg(s, rdhi);
1539
                gen_iwmmxt_movl_wRn_T0_T1(wrd);
1540
                gen_op_iwmmxt_set_mup();
1541
            }
1542
            return 0;
1543
        }
1544

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

    
1607
    if ((insn & 0x0f000000) != 0x0e000000)
1608
        return 1;
1609

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

    
2482
    return 0;
2483
}
2484

    
2485
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2486
   (ie. an undefined instruction).  */
2487
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2488
{
2489
    int acc, rd0, rd1, rdhi, rdlo;
2490

    
2491
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2492
        /* Multiply with Internal Accumulate Format */
2493
        rd0 = (insn >> 12) & 0xf;
2494
        rd1 = insn & 0xf;
2495
        acc = (insn >> 5) & 7;
2496

    
2497
        if (acc != 0)
2498
            return 1;
2499

    
2500
        switch ((insn >> 16) & 0xf) {
2501
        case 0x0:                                        /* MIA */
2502
            gen_movl_T0_reg(s, rd0);
2503
            gen_movl_T1_reg(s, rd1);
2504
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2505
            break;
2506
        case 0x8:                                        /* MIAPH */
2507
            gen_movl_T0_reg(s, rd0);
2508
            gen_movl_T1_reg(s, rd1);
2509
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2510
            break;
2511
        case 0xc:                                        /* MIABB */
2512
        case 0xd:                                        /* MIABT */
2513
        case 0xe:                                        /* MIATB */
2514
        case 0xf:                                        /* MIATT */
2515
            gen_movl_T1_reg(s, rd0);
2516
            if (insn & (1 << 16))
2517
                gen_op_shrl_T1_im(16);
2518
            gen_op_movl_T0_T1();
2519
            gen_movl_T1_reg(s, rd1);
2520
            if (insn & (1 << 17))
2521
                gen_op_shrl_T1_im(16);
2522
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2523
            break;
2524
        default:
2525
            return 1;
2526
        }
2527

    
2528
        gen_op_iwmmxt_movq_wRn_M0(acc);
2529
        return 0;
2530
    }
2531

    
2532
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2533
        /* Internal Accumulator Access Format */
2534
        rdhi = (insn >> 16) & 0xf;
2535
        rdlo = (insn >> 12) & 0xf;
2536
        acc = insn & 7;
2537

    
2538
        if (acc != 0)
2539
            return 1;
2540

    
2541
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2542
            gen_iwmmxt_movl_T0_T1_wRn(acc);
2543
            gen_movl_reg_T0(s, rdlo);
2544
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2545
            gen_op_andl_T0_T1();
2546
            gen_movl_reg_T0(s, rdhi);
2547
        } else {                                        /* MAR */
2548
            gen_movl_T0_reg(s, rdlo);
2549
            gen_movl_T1_reg(s, rdhi);
2550
            gen_iwmmxt_movl_wRn_T0_T1(acc);
2551
        }
2552
        return 0;
2553
    }
2554

    
2555
    return 1;
2556
}
2557

    
2558
/* Disassemble system coprocessor instruction.  Return nonzero if
2559
   instruction is not defined.  */
2560
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2561
{
2562
    TCGv tmp;
2563
    uint32_t rd = (insn >> 12) & 0xf;
2564
    uint32_t cp = (insn >> 8) & 0xf;
2565
    if (IS_USER(s)) {
2566
        return 1;
2567
    }
2568

    
2569
    if (insn & ARM_CP_RW_BIT) {
2570
        if (!env->cp[cp].cp_read)
2571
            return 1;
2572
        gen_set_pc_im(s->pc);
2573
        tmp = new_tmp();
2574
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2575
        store_reg(s, rd, tmp);
2576
    } else {
2577
        if (!env->cp[cp].cp_write)
2578
            return 1;
2579
        gen_set_pc_im(s->pc);
2580
        tmp = load_reg(s, rd);
2581
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2582
    }
2583
    return 0;
2584
}
2585

    
2586
static int cp15_user_ok(uint32_t insn)
2587
{
2588
    int cpn = (insn >> 16) & 0xf;
2589
    int cpm = insn & 0xf;
2590
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2591

    
2592
    if (cpn == 13 && cpm == 0) {
2593
        /* TLS register.  */
2594
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2595
            return 1;
2596
    }
2597
    if (cpn == 7) {
2598
        /* ISB, DSB, DMB.  */
2599
        if ((cpm == 5 && op == 4)
2600
                || (cpm == 10 && (op == 4 || op == 5)))
2601
            return 1;
2602
    }
2603
    return 0;
2604
}
2605

    
2606
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2607
   instruction is not defined.  */
2608
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2609
{
2610
    uint32_t rd;
2611
    TCGv tmp;
2612

    
2613
    /* M profile cores use memory mapped registers instead of cp15.  */
2614
    if (arm_feature(env, ARM_FEATURE_M))
2615
        return 1;
2616

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

    
2662
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2663
#define VFP_SREG(insn, bigbit, smallbit) \
2664
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2665
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2666
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2667
        reg = (((insn) >> (bigbit)) & 0x0f) \
2668
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2669
    } else { \
2670
        if (insn & (1 << (smallbit))) \
2671
            return 1; \
2672
        reg = ((insn) >> (bigbit)) & 0x0f; \
2673
    }} while (0)
2674

    
2675
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2676
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2677
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2678
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2679
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2680
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2681

    
2682
/* Move between integer and VFP cores.  */
2683
static TCGv gen_vfp_mrs(void)
2684
{
2685
    TCGv tmp = new_tmp();
2686
    tcg_gen_mov_i32(tmp, cpu_F0s);
2687
    return tmp;
2688
}
2689

    
2690
static void gen_vfp_msr(TCGv tmp)
2691
{
2692
    tcg_gen_mov_i32(cpu_F0s, tmp);
2693
    dead_tmp(tmp);
2694
}
2695

    
2696
static inline int
2697
vfp_enabled(CPUState * env)
2698
{
2699
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2700
}
2701

    
2702
static void gen_neon_dup_u8(TCGv var, int shift)
2703
{
2704
    TCGv tmp = new_tmp();
2705
    if (shift)
2706
        tcg_gen_shri_i32(var, var, shift);
2707
    tcg_gen_andi_i32(var, var, 0xff);
2708
    tcg_gen_shli_i32(tmp, var, 8);
2709
    tcg_gen_or_i32(var, var, tmp);
2710
    tcg_gen_shli_i32(tmp, var, 16);
2711
    tcg_gen_or_i32(var, var, tmp);
2712
    dead_tmp(tmp);
2713
}
2714

    
2715
static void gen_neon_dup_low16(TCGv var)
2716
{
2717
    TCGv tmp = new_tmp();
2718
    tcg_gen_andi_i32(var, var, 0xffff);
2719
    tcg_gen_shli_i32(tmp, var, 16);
2720
    tcg_gen_or_i32(var, var, tmp);
2721
    dead_tmp(tmp);
2722
}
2723

    
2724
static void gen_neon_dup_high16(TCGv var)
2725
{
2726
    TCGv tmp = new_tmp();
2727
    tcg_gen_andi_i32(var, var, 0xffff0000);
2728
    tcg_gen_shri_i32(tmp, var, 16);
2729
    tcg_gen_or_i32(var, var, tmp);
2730
    dead_tmp(tmp);
2731
}
2732

    
2733
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2734
   (ie. an undefined instruction).  */
2735
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2736
{
2737
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2738
    int dp, veclen;
2739
    TCGv tmp;
2740
    TCGv tmp2;
2741

    
2742
    if (!arm_feature(env, ARM_FEATURE_VFP))
2743
        return 1;
2744

    
2745
    if (!vfp_enabled(env)) {
2746
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2747
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2748
            return 1;
2749
        rn = (insn >> 16) & 0xf;
2750
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2751
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2752
            return 1;
2753
    }
2754
    dp = ((insn & 0xf00) == 0xb00);
2755
    switch ((insn >> 24) & 0xf) {
2756
    case 0xe:
2757
        if (insn & (1 << 4)) {
2758
            /* single register transfer */
2759
            rd = (insn >> 12) & 0xf;
2760
            if (dp) {
2761
                int size;
2762
                int pass;
2763

    
2764
                VFP_DREG_N(rn, insn);
2765
                if (insn & 0xf)
2766
                    return 1;
2767
                if (insn & 0x00c00060
2768
                    && !arm_feature(env, ARM_FEATURE_NEON))
2769
                    return 1;
2770

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

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

    
2958
                if (op == 15 && (rn == 15 || rn > 17)) {
2959
                    /* Integer or single precision destination.  */
2960
                    rd = VFP_SREG_D(insn);
2961
                } else {
2962
                    VFP_DREG_D(rd, insn);
2963
                }
2964

    
2965
                if (op == 15 && (rn == 16 || rn == 17)) {
2966
                    /* Integer source.  */
2967
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2968
                } else {
2969
                    VFP_DREG_M(rm, insn);
2970
                }
2971
            } else {
2972
                rn = VFP_SREG_N(insn);
2973
                if (op == 15 && rn == 15) {
2974
                    /* Double precision destination.  */
2975
                    VFP_DREG_D(rd, insn);
2976
                } else {
2977
                    rd = VFP_SREG_D(insn);
2978
                }
2979
                rm = VFP_SREG_M(insn);
2980
            }
2981

    
2982
            veclen = env->vfp.vec_len;
2983
            if (op == 15 && rn > 3)
2984
                veclen = 0;
2985

    
2986
            /* Shut up compiler warnings.  */
2987
            delta_m = 0;
2988
            delta_d = 0;
2989
            bank_mask = 0;
2990

    
2991
            if (veclen > 0) {
2992
                if (dp)
2993
                    bank_mask = 0xc;
2994
                else
2995
                    bank_mask = 0x18;
2996

    
2997
                /* Figure out what type of vector operation this is.  */
2998
                if ((rd & bank_mask) == 0) {
2999
                    /* scalar */
3000
                    veclen = 0;
3001
                } else {
3002
                    if (dp)
3003
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
3004
                    else
3005
                        delta_d = env->vfp.vec_stride + 1;
3006

    
3007
                    if ((rm & bank_mask) == 0) {
3008
                        /* mixed scalar/vector */
3009
                        delta_m = 0;
3010
                    } else {
3011
                        /* vector */
3012
                        delta_m = delta_d;
3013
                    }
3014
                }
3015
            }
3016

    
3017
            /* Load the initial operands.  */
3018
            if (op == 15) {
3019
                switch (rn) {
3020
                case 16:
3021
                case 17:
3022
                    /* Integer source */
3023
                    gen_mov_F0_vreg(0, rm);
3024
                    break;
3025
                case 8:
3026
                case 9:
3027
                    /* Compare */
3028
                    gen_mov_F0_vreg(dp, rd);
3029
                    gen_mov_F1_vreg(dp, rm);
3030
                    break;
3031
                case 10:
3032
                case 11:
3033
                    /* Compare with zero */
3034
                    gen_mov_F0_vreg(dp, rd);
3035
                    gen_vfp_F1_ld0(dp);
3036
                    break;
3037
                case 20:
3038
                case 21:
3039
                case 22:
3040
                case 23:
3041
                    /* Source and destination the same.  */
3042
                    gen_mov_F0_vreg(dp, rd);
3043
                    break;
3044
                default:
3045
                    /* One source operand.  */
3046
                    gen_mov_F0_vreg(dp, rm);
3047
                    break;
3048
                }
3049
            } else {
3050
                /* Two source operands.  */
3051
                gen_mov_F0_vreg(dp, rn);
3052
                gen_mov_F1_vreg(dp, rm);
3053
            }
3054

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

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

    
3219
                /* Write back the result.  */
3220
                if (op == 15 && (rn >= 8 && rn <= 11))
3221
                    ; /* Comparison, do nothing.  */
3222
                else if (op == 15 && rn > 17)
3223
                    /* Integer result.  */
3224
                    gen_mov_vreg_F0(0, rd);
3225
                else if (op == 15 && rn == 15)
3226
                    /* conversion */
3227
                    gen_mov_vreg_F0(!dp, rd);
3228
                else
3229
                    gen_mov_vreg_F0(dp, rd);
3230

    
3231
                /* break out of the loop if we have finished  */
3232
                if (veclen == 0)
3233
                    break;
3234

    
3235
                if (op == 15 && delta_m == 0) {
3236
                    /* single source one-many */
3237
                    while (veclen--) {
3238
                        rd = ((rd + delta_d) & (bank_mask - 1))
3239
                             | (rd & bank_mask);
3240
                        gen_mov_vreg_F0(dp, rd);
3241
                    }
3242
                    break;
3243
                }
3244
                /* Setup the next operands.  */
3245
                veclen--;
3246
                rd = ((rd + delta_d) & (bank_mask - 1))
3247
                     | (rd & bank_mask);
3248

    
3249
                if (op == 15) {
3250
                    /* One source operand.  */
3251
                    rm = ((rm + delta_m) & (bank_mask - 1))
3252
                         | (rm & bank_mask);
3253
                    gen_mov_F0_vreg(dp, rm);
3254
                } else {
3255
                    /* Two source operands.  */
3256
                    rn = ((rn + delta_d) & (bank_mask - 1))
3257
                         | (rn & bank_mask);
3258
                    gen_mov_F0_vreg(dp, rn);
3259
                    if (delta_m) {
3260
                        rm = ((rm + delta_m) & (bank_mask - 1))
3261
                             | (rm & bank_mask);
3262
                        gen_mov_F1_vreg(dp, rm);
3263
                    }
3264
                }
3265
            }
3266
        }
3267
        break;
3268
    case 0xc:
3269
    case 0xd:
3270
        if (dp && (insn & 0x03e00000) == 0x00400000) {
3271
            /* two-register transfer */
3272
            rn = (insn >> 16) & 0xf;
3273
            rd = (insn >> 12) & 0xf;
3274
            if (dp) {
3275
                VFP_DREG_M(rm, insn);
3276
            } else {
3277
                rm = VFP_SREG_M(insn);
3278
            }
3279

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

    
3347
                if (insn & (1 << 24)) /* pre-decrement */
3348
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3349

    
3350
                if (dp)
3351
                    offset = 8;
3352
                else
3353
                    offset = 4;
3354
                for (i = 0; i < n; i++) {
3355
                    if (insn & ARM_CP_RW_BIT) {
3356
                        /* load */
3357
                        gen_vfp_ld(s, dp);
3358
                        gen_mov_vreg_F0(dp, rd + i);
3359
                    } else {
3360
                        /* store */
3361
                        gen_mov_F0_vreg(dp, rd + i);
3362
                        gen_vfp_st(s, dp);
3363
                    }
3364
                    gen_op_addl_T1_im(offset);
3365
                }
3366
                if (insn & (1 << 21)) {
3367
                    /* writeback */
3368
                    if (insn & (1 << 24))
3369
                        offset = -offset * n;
3370
                    else if (dp && (insn & 1))
3371
                        offset = 4;
3372
                    else
3373
                        offset = 0;
3374

    
3375
                    if (offset != 0)
3376
                        gen_op_addl_T1_im(offset);
3377
                    gen_movl_reg_T1(s, rn);
3378
                }
3379
            }
3380
        }
3381
        break;
3382
    default:
3383
        /* Should never happen.  */
3384
        return 1;
3385
    }
3386
    return 0;
3387
}
3388

    
3389
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3390
{
3391
    TranslationBlock *tb;
3392

    
3393
    tb = s->tb;
3394
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3395
        tcg_gen_goto_tb(n);
3396
        gen_set_pc_im(dest);
3397
        tcg_gen_exit_tb((long)tb + n);
3398
    } else {
3399
        gen_set_pc_im(dest);
3400
        tcg_gen_exit_tb(0);
3401
    }
3402
}
3403

    
3404
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3405
{
3406
    if (__builtin_expect(s->singlestep_enabled, 0)) {
3407
        /* An indirect jump so that we still trigger the debug exception.  */
3408
        if (s->thumb)
3409
            dest |= 1;
3410
        gen_bx_im(s, dest);
3411
    } else {
3412
        gen_goto_tb(s, 0, dest);
3413
        s->is_jmp = DISAS_TB_JUMP;
3414
    }
3415
}
3416

    
3417
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3418
{
3419
    if (x)
3420
        tcg_gen_sari_i32(t0, t0, 16);
3421
    else
3422
        gen_sxth(t0);
3423
    if (y)
3424
        tcg_gen_sari_i32(t1, t1, 16);
3425
    else
3426
        gen_sxth(t1);
3427
    tcg_gen_mul_i32(t0, t0, t1);
3428
}
3429

    
3430
/* Return the mask of PSR bits set by a MSR instruction.  */
3431
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3432
    uint32_t mask;
3433

    
3434
    mask = 0;
3435
    if (flags & (1 << 0))
3436
        mask |= 0xff;
3437
    if (flags & (1 << 1))
3438
        mask |= 0xff00;
3439
    if (flags & (1 << 2))
3440
        mask |= 0xff0000;
3441
    if (flags & (1 << 3))
3442
        mask |= 0xff000000;
3443

    
3444
    /* Mask out undefined bits.  */
3445
    mask &= ~CPSR_RESERVED;
3446
    if (!arm_feature(env, ARM_FEATURE_V6))
3447
        mask &= ~(CPSR_E | CPSR_GE);
3448
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3449
        mask &= ~CPSR_IT;
3450
    /* Mask out execution state bits.  */
3451
    if (!spsr)
3452
        mask &= ~CPSR_EXEC;
3453
    /* Mask out privileged bits.  */
3454
    if (IS_USER(s))
3455
        mask &= CPSR_USER;
3456
    return mask;
3457
}
3458

    
3459
/* Returns nonzero if access to the PSR is not permitted.  */
3460
static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3461
{
3462
    TCGv tmp;
3463
    if (spsr) {
3464
        /* ??? This is also undefined in system mode.  */
3465
        if (IS_USER(s))
3466
            return 1;
3467

    
3468
        tmp = load_cpu_field(spsr);
3469
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3470
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3471
        tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3472
        store_cpu_field(tmp, spsr);
3473
    } else {
3474
        gen_set_cpsr(cpu_T[0], mask);
3475
    }
3476
    gen_lookup_tb(s);
3477
    return 0;
3478
}
3479

    
3480
/* Generate an old-style exception return.  */
3481
static void gen_exception_return(DisasContext *s)
3482
{
3483
    TCGv tmp;
3484
    gen_movl_reg_T0(s, 15);
3485
    tmp = load_cpu_field(spsr);
3486
    gen_set_cpsr(tmp, 0xffffffff);
3487
    dead_tmp(tmp);
3488
    s->is_jmp = DISAS_UPDATE;
3489
}
3490

    
3491
/* Generate a v6 exception return.  Marks both values as dead.  */
3492
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3493
{
3494
    gen_set_cpsr(cpsr, 0xffffffff);
3495
    dead_tmp(cpsr);
3496
    store_reg(s, 15, pc);
3497
    s->is_jmp = DISAS_UPDATE;
3498
}
3499

    
3500
static inline void
3501
gen_set_condexec (DisasContext *s)
3502
{
3503
    if (s->condexec_mask) {
3504
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3505
        TCGv tmp = new_tmp();
3506
        tcg_gen_movi_i32(tmp, val);
3507
        store_cpu_field(tmp, condexec_bits);
3508
    }
3509
}
3510

    
3511
static void gen_nop_hint(DisasContext *s, int val)
3512
{
3513
    switch (val) {
3514
    case 3: /* wfi */
3515
        gen_set_pc_im(s->pc);
3516
        s->is_jmp = DISAS_WFI;
3517
        break;
3518
    case 2: /* wfe */
3519
    case 4: /* sev */
3520
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3521
    default: /* nop */
3522
        break;
3523
    }
3524
}
3525

    
3526
/* These macros help make the code more readable when migrating from the
3527
   old dyngen helpers.  They should probably be removed when
3528
   T0/T1 are removed.  */
3529
#define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
3530
#define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
3531

    
3532
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3533

    
3534
static inline int gen_neon_add(int size)
3535
{
3536
    switch (size) {
3537
    case 0: gen_helper_neon_add_u8(CPU_T001); break;
3538
    case 1: gen_helper_neon_add_u16(CPU_T001); break;
3539
    case 2: gen_op_addl_T0_T1(); break;
3540
    default: return 1;
3541
    }
3542
    return 0;
3543
}
3544

    
3545
static inline void gen_neon_rsb(int size)
3546
{
3547
    switch (size) {
3548
    case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3549
    case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
3550
    case 2: gen_op_rsbl_T0_T1(); break;
3551
    default: return;
3552
    }
3553
}
3554

    
3555
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3556
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3557
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3558
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3559
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3560

    
3561
/* FIXME: This is wrong.  They set the wrong overflow bit.  */
3562
#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
3563
#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
3564
#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
3565
#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
3566

    
3567
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3568
    switch ((size << 1) | u) { \
3569
    case 0: \
3570
        gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3571
        break; \
3572
    case 1: \
3573
        gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3574
        break; \
3575
    case 2: \
3576
        gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3577
        break; \
3578
    case 3: \
3579
        gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3580
        break; \
3581
    case 4: \
3582
        gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3583
        break; \
3584
    case 5: \
3585
        gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
3586
        break; \
3587
    default: return 1; \
3588
    }} while (0)
3589

    
3590
#define GEN_NEON_INTEGER_OP(name) do { \
3591
    switch ((size << 1) | u) { \
3592
    case 0: \
3593
        gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3594
        break; \
3595
    case 1: \
3596
        gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
3597
        break; \
3598
    case 2: \
3599
        gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3600
        break; \
3601
    case 3: \
3602
        gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
3603
        break; \
3604
    case 4: \
3605
        gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3606
        break; \
3607
    case 5: \
3608
        gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
3609
        break; \
3610
    default: return 1; \
3611
    }} while (0)
3612

    
3613
static inline void
3614
gen_neon_movl_scratch_T0(int scratch)
3615
{
3616
  uint32_t offset;
3617

    
3618
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3619
  tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
3620
}
3621

    
3622
static inline void
3623
gen_neon_movl_scratch_T1(int scratch)
3624
{
3625
  uint32_t offset;
3626

    
3627
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3628
  tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
3629
}
3630

    
3631
static inline void
3632
gen_neon_movl_T0_scratch(int scratch)
3633
{
3634
  uint32_t offset;
3635

    
3636
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3637
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3638
}
3639

    
3640
static inline void
3641
gen_neon_movl_T1_scratch(int scratch)
3642
{
3643
  uint32_t offset;
3644

    
3645
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3646
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3647
}
3648

    
3649
static inline void gen_neon_get_scalar(int size, int reg)
3650
{
3651
    if (size == 1) {
3652
        NEON_GET_REG(T0, reg >> 1, reg & 1);
3653
    } else {
3654
        NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3655
        if (reg & 1)
3656
            gen_neon_dup_low16(cpu_T[0]);
3657
        else
3658
            gen_neon_dup_high16(cpu_T[0]);
3659
    }
3660
}
3661

    
3662
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3663
{
3664
    int n;
3665

    
3666
    for (n = 0; n < q + 1; n += 2) {
3667
        NEON_GET_REG(T0, reg, n);
3668
        NEON_GET_REG(T0, reg, n + n);
3669
        switch (size) {
3670
        case 0: gen_helper_neon_unzip_u8(); break;
3671
        case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same.  */
3672
        case 2: /* no-op */; break;
3673
        default: abort();
3674
        }
3675
        gen_neon_movl_scratch_T0(tmp + n);
3676
        gen_neon_movl_scratch_T1(tmp + n + 1);
3677
    }
3678
}
3679

    
3680
static struct {
3681
    int nregs;
3682
    int interleave;
3683
    int spacing;
3684
} neon_ls_element_type[11] = {
3685
    {4, 4, 1},
3686
    {4, 4, 2},
3687
    {4, 1, 1},
3688
    {4, 2, 1},
3689
    {3, 3, 1},
3690
    {3, 3, 2},
3691
    {3, 1, 1},
3692
    {1, 1, 1},
3693
    {2, 2, 1},
3694
    {2, 2, 2},
3695
    {2, 1, 1}
3696
};
3697

    
3698
/* Translate a NEON load/store element instruction.  Return nonzero if the
3699
   instruction is invalid.  */
3700
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3701
{
3702
    int rd, rn, rm;
3703
    int op;
3704
    int nregs;
3705
    int interleave;
3706
    int stride;
3707
    int size;
3708
    int reg;
3709
    int pass;
3710
    int load;
3711
    int shift;
3712
    int n;
3713
    TCGv tmp;
3714
    TCGv tmp2;
3715

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

    
3899
        base = load_reg(s, rn);
3900
        if (rm == 13) {
3901
            tcg_gen_addi_i32(base, base, stride);
3902
        } else {
3903
            TCGv index;
3904
            index = load_reg(s, rm);
3905
            tcg_gen_add_i32(base, base, index);
3906
            dead_tmp(index);
3907
        }
3908
        store_reg(s, rn, base);
3909
    }
3910
    return 0;
3911
}
3912

    
3913
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
3914
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
3915
{
3916
    tcg_gen_and_i32(t, t, c);
3917
    tcg_gen_bic_i32(f, f, c);
3918
    tcg_gen_or_i32(dest, t, f);
3919
}
3920

    
3921
static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
3922
{
3923
    switch (size) {
3924
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
3925
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
3926
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
3927
    default: abort();
3928
    }
3929
}
3930

    
3931
static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
3932
{
3933
    switch (size) {
3934
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3935
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3936
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3937
    default: abort();
3938
    }
3939
}
3940

    
3941
static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
3942
{
3943
    switch (size) {
3944
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3945
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3946
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3947
    default: abort();
3948
    }
3949
}
3950

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

    
3985
static inline void gen_neon_widen(TCGv dest, TCGv src, int size, int u)
3986
{
3987
    if (u) {
3988
        switch (size) {
3989
        case 0: gen_helper_neon_widen_u8(dest, src); break;
3990
        case 1: gen_helper_neon_widen_u16(dest, src); break;
3991
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
3992
        default: abort();
3993
        }
3994
    } else {
3995
        switch (size) {
3996
        case 0: gen_helper_neon_widen_s8(dest, src); break;
3997
        case 1: gen_helper_neon_widen_s16(dest, src); break;
3998
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
3999
        default: abort();
4000
        }
4001
    }
4002
    dead_tmp(src);
4003
}
4004

    
4005
static inline void gen_neon_addl(int size)
4006
{
4007
    switch (size) {
4008
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4009
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4010
    case 2: tcg_gen_add_i64(CPU_V001); break;
4011
    default: abort();
4012
    }
4013
}
4014

    
4015
static inline void gen_neon_subl(int size)
4016
{
4017
    switch (size) {
4018
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4019
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4020
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4021
    default: abort();
4022
    }
4023
}
4024

    
4025
static inline void gen_neon_negl(TCGv var, int size)
4026
{
4027
    switch (size) {
4028
    case 0: gen_helper_neon_negl_u16(var, var); break;
4029
    case 1: gen_helper_neon_negl_u32(var, var); break;
4030
    case 2: gen_helper_neon_negl_u64(var, var); break;
4031
    default: abort();
4032
    }
4033
}
4034

    
4035
static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4036
{
4037
    switch (size) {
4038
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4039
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4040
    default: abort();
4041
    }
4042
}
4043

    
4044
static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4045
{
4046
    TCGv tmp;
4047

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

    
4069
/* Translate a NEON data processing instruction.  Return nonzero if the
4070
   instruction is invalid.
4071
   We process data in a mixture of 32-bit and 64-bit chunks.
4072
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4073

    
4074
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
4075
{
4076
    int op;
4077
    int q;
4078
    int rd, rn, rm;
4079
    int size;
4080
    int shift;
4081
    int pass;
4082
    int count;
4083
    int pairwise;
4084
    int u;
4085
    int n;
4086
    uint32_t imm;
4087
    TCGv tmp;
4088
    TCGv tmp2;
4089
    TCGv tmp3;
4090

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

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

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

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

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

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

    
4709
                    gen_neon_widen(cpu_V0, tmp, size, u);
4710

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

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

    
4794
            if (op != 14 || !invert)
4795
                gen_op_movl_T1_im(imm);
4796

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

    
4852
                prewiden = neon_3reg_wide[op][0];
4853
                src1_wide = neon_3reg_wide[op][1];
4854
                src2_wide = neon_3reg_wide[op][2];
4855

    
4856
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4857
                    return 1;
4858

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

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

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

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

    
5081
                    gen_neon_get_scalar(size, rm);
5082
                    NEON_GET_REG(T1, rn, 1);
5083

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

    
5130
                if (imm > 7 && !q)
5131
                    return 1;
5132

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

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

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

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

    
5587

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

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

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

    
5615
/* load and add a 64-bit value from a register pair.  */
5616
static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5617
{
5618
    TCGv tmp;
5619
    TCGv tmp2;
5620

    
5621
    /* Load 64-bit value rd:rn.  */
5622
    tmp = tcg_temp_new(TCG_TYPE_I64);
5623
    tmp2 = load_reg(s, rhigh);
5624
    tcg_gen_extu_i32_i64(tmp, tmp2);
5625
    dead_tmp(tmp2);
5626
    tcg_gen_shli_i64(tmp, tmp, 32);
5627
    tcg_gen_add_i64(val, val, tmp);
5628

    
5629
    tmp2 = load_reg(s, rlow);
5630
    tcg_gen_extu_i32_i64(tmp, tmp2);
5631
    dead_tmp(tmp2);
5632
    tcg_gen_add_i64(val, val, tmp);
5633
}
5634

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

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

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

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

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

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

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

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

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

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

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

    
6647
                    if ((insn & (1 << 15)) == 0)
6648
                        user = 1;
6649
                }
6650
                rn = (insn >> 16) & 0xf;
6651
                addr = load_reg(s, rn);
6652

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

    
6756
                /* branch (and link) */
6757
                val = (int32_t)s->pc;
6758
                if (insn & (1 << 24)) {
6759
                    tmp = new_tmp();
6760
                    tcg_gen_movi_i32(tmp, val);
6761
                    store_reg(s, 14, tmp);
6762
                }
6763
                offset = (((int32_t)insn << 8) >> 8);
6764
                val += (offset << 2) + 4;
6765
                gen_jmp(s, val);
6766
            }
6767
            break;
6768
        case 0xc:
6769
        case 0xd:
6770
        case 0xe:
6771
            /* Coprocessor.  */
6772
            if (disas_coproc_insn(env, s, insn))
6773
                goto illegal_op;
6774
            break;
6775
        case 0xf:
6776
            /* swi */
6777
            gen_set_pc_im(s->pc);
6778
            s->is_jmp = DISAS_SWI;
6779
            break;
6780
        default:
6781
        illegal_op:
6782
            gen_set_condexec(s);
6783
            gen_set_pc_im(s->pc - 4);
6784
            gen_exception(EXCP_UDEF);
6785
            s->is_jmp = DISAS_JUMP;
6786
            break;
6787
        }
6788
    }
6789
}
6790

    
6791
/* Return true if this is a Thumb-2 logical op.  */
6792
static int
6793
thumb2_logic_op(int op)
6794
{
6795
    return (op < 8);
6796
}
6797

    
6798
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6799
   then set condition code flags based on the result of the operation.
6800
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6801
   to the high bit of T1.
6802
   Returns zero if the opcode is valid.  */
6803

    
6804
static int
6805
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6806
{
6807
    int logic_cc;
6808

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

    
6873
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
6874
   is not legal.  */
6875
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6876
{
6877
    uint32_t insn, imm, shift, offset;
6878
    uint32_t rd, rn, rm, rs;
6879
    TCGv tmp;
6880
    TCGv tmp2;
6881
    TCGv tmp3;
6882
    TCGv addr;
6883
    int op;
6884
    int shiftop;
6885
    int conds;
6886
    int logic_cc;
6887

    
6888
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6889
          || arm_feature (env, ARM_FEATURE_M))) {
6890
        /* Thumb-1 cores may need to treat bl and blx as a pair of
6891
           16-bit instructions to get correct prefetch abort behavior.  */
6892
        insn = insn_hw1;
6893
        if ((insn & (1 << 12)) == 0) {
6894
            /* Second half of blx.  */
6895
            offset = ((insn & 0x7ff) << 1);
6896
            tmp = load_reg(s, 14);
6897
            tcg_gen_addi_i32(tmp, tmp, offset);
6898
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6899

    
6900
            tmp2 = new_tmp();
6901
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6902
            store_reg(s, 14, tmp2);
6903
            gen_bx(s, tmp);
6904
            return 0;
6905
        }
6906
        if (insn & (1 << 11)) {
6907
            /* Second half of bl.  */
6908
            offset = ((insn & 0x7ff) << 1) | 1;
6909
            tmp = load_reg(s, 14);
6910
            tcg_gen_addi_i32(tmp, tmp, offset);
6911

    
6912
            tmp2 = new_tmp();
6913
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6914
            store_reg(s, 14, tmp2);
6915
            gen_bx(s, tmp);
6916
            return 0;
6917
        }
6918
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6919
            /* Instruction spans a page boundary.  Implement it as two
6920
               16-bit instructions in case the second half causes an
6921
               prefetch abort.  */
6922
            offset = ((int32_t)insn << 21) >> 9;
6923
            gen_op_movl_T0_im(s->pc + 2 + offset);
6924
            gen_movl_reg_T0(s, 14);
6925
            return 0;
6926
        }
6927
        /* Fall through to 32-bit decode.  */
6928
    }
6929

    
6930
    insn = lduw_code(s->pc);
6931
    s->pc += 2;
6932
    insn |= (uint32_t)insn_hw1 << 16;
6933

    
6934
    if ((insn & 0xf800e800) != 0xf000e800) {
6935
        ARCH(6T2);
6936
    }
6937

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

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

    
7490
                if (insn & (1 << 14)) {
7491
                    /* Branch and link.  */
7492
                    gen_op_movl_T1_im(s->pc | 1);
7493
                    gen_movl_reg_T1(s, 14);
7494
                }
7495

    
7496
                offset += s->pc;
7497
                if (insn & (1 << 12)) {
7498
                    /* b/bl */
7499
                    gen_jmp(s, offset);
7500
                } else {
7501
                    /* blx */
7502
                    offset &= ~(uint32_t)2;
7503
                    gen_bx_im(s, offset);
7504
                }
7505
            } else if (((insn >> 23) & 7) == 7) {
7506
                /* Misc control */
7507
                if (insn & (1 << 13))
7508
                    goto illegal_op;
7509

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

    
7613
                /* offset[11:1] = insn[10:0] */
7614
                offset = (insn & 0x7ff) << 1;
7615
                /* offset[17:12] = insn[21:16].  */
7616
                offset |= (insn & 0x003f0000) >> 4;
7617
                /* offset[31:20] = insn[26].  */
7618
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7619
                /* offset[18] = insn[13].  */
7620
                offset |= (insn & (1 << 13)) << 5;
7621
                /* offset[19] = insn[11].  */
7622
                offset |= (insn & (1 << 11)) << 8;
7623

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

    
7892
static void disas_thumb_insn(CPUState *env, DisasContext *s)
7893
{
7894
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
7895
    int32_t offset;
7896
    int i;
7897
    TCGv tmp;
7898
    TCGv tmp2;
7899
    TCGv addr;
7900

    
7901
    if (s->condexec_mask) {
7902
        cond = s->condexec_cond;
7903
        s->condlabel = gen_new_label();
7904
        gen_test_cc(cond ^ 1, s->condlabel);
7905
        s->condjmp = 1;
7906
    }
7907

    
7908
    insn = lduw_code(s->pc);
7909
    s->pc += 2;
7910

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

    
8032
        /* data processing register */
8033
        rd = insn & 7;
8034
        rm = (insn >> 3) & 7;
8035
        op = (insn >> 6) & 0xf;
8036
        if (op == 2 || op == 3 || op == 4 || op == 7) {
8037
            /* the shift/rotate ops want the operands backwards */
8038
            val = rm;
8039
            rm = rd;
8040
            rd = val;
8041
            val = 1;
8042
        } else {
8043
            val = 0;
8044
        }
8045

    
8046
        if (op == 9) /* neg */
8047
            gen_op_movl_T0_im(0);
8048
        else if (op != 0xf) /* mvn doesn't read its first operand */
8049
            gen_movl_T0_reg(s, rd);
8050

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

    
8157
    case 5:
8158
        /* load/store register offset.  */
8159
        rd = insn & 7;
8160
        rn = (insn >> 3) & 7;
8161
        rm = (insn >> 6) & 7;
8162
        op = (insn >> 9) & 7;
8163
        addr = load_reg(s, rn);
8164
        tmp = load_reg(s, rm);
8165
        tcg_gen_add_i32(addr, addr, tmp);
8166
        dead_tmp(tmp);
8167

    
8168
        if (op < 3) /* store */
8169
            tmp = load_reg(s, rd);
8170

    
8171
        switch (op) {
8172
        case 0: /* str */
8173
            gen_st32(tmp, addr, IS_USER(s));
8174
            break;
8175
        case 1: /* strh */
8176
            gen_st16(tmp, addr, IS_USER(s));
8177
            break;
8178
        case 2: /* strb */
8179
            gen_st8(tmp, addr, IS_USER(s));
8180
            break;
8181
        case 3: /* ldrsb */
8182
            tmp = gen_ld8s(addr, IS_USER(s));
8183
            break;
8184
        case 4: /* ldr */
8185
            tmp = gen_ld32(addr, IS_USER(s));
8186
            break;
8187
        case 5: /* ldrh */
8188
            tmp = gen_ld16u(addr, IS_USER(s));
8189
            break;
8190
        case 6: /* ldrb */
8191
            tmp = gen_ld8u(addr, IS_USER(s));
8192
            break;
8193
        case 7: /* ldrsh */
8194
            tmp = gen_ld16s(addr, IS_USER(s));
8195
            break;
8196
        }
8197
        if (op >= 3) /* load */
8198
            store_reg(s, rd, tmp);
8199
        dead_tmp(addr);
8200
        break;
8201

    
8202
    case 6:
8203
        /* load/store word immediate offset */
8204
        rd = insn & 7;
8205
        rn = (insn >> 3) & 7;
8206
        addr = load_reg(s, rn);
8207
        val = (insn >> 4) & 0x7c;
8208
        tcg_gen_addi_i32(addr, addr, val);
8209

    
8210
        if (insn & (1 << 11)) {
8211
            /* load */
8212
            tmp = gen_ld32(addr, IS_USER(s));
8213
            store_reg(s, rd, tmp);
8214
        } else {
8215
            /* store */
8216
            tmp = load_reg(s, rd);
8217
            gen_st32(tmp, addr, IS_USER(s));
8218
        }
8219
        dead_tmp(addr);
8220
        break;
8221

    
8222
    case 7:
8223
        /* load/store byte immediate offset */
8224
        rd = insn & 7;
8225
        rn = (insn >> 3) & 7;
8226
        addr = load_reg(s, rn);
8227
        val = (insn >> 6) & 0x1f;
8228
        tcg_gen_addi_i32(addr, addr, val);
8229

    
8230
        if (insn & (1 << 11)) {
8231
            /* load */
8232
            tmp = gen_ld8u(addr, IS_USER(s));
8233
            store_reg(s, rd, tmp);
8234
        } else {
8235
            /* store */
8236
            tmp = load_reg(s, rd);
8237
            gen_st8(tmp, addr, IS_USER(s));
8238
        }
8239
        dead_tmp(addr);
8240
        break;
8241

    
8242
    case 8:
8243
        /* load/store halfword immediate offset */
8244
        rd = insn & 7;
8245
        rn = (insn >> 3) & 7;
8246
        addr = load_reg(s, rn);
8247
        val = (insn >> 5) & 0x3e;
8248
        tcg_gen_addi_i32(addr, addr, val);
8249

    
8250
        if (insn & (1 << 11)) {
8251
            /* load */
8252
            tmp = gen_ld16u(addr, IS_USER(s));
8253
            store_reg(s, rd, tmp);
8254
        } else {
8255
            /* store */
8256
            tmp = load_reg(s, rd);
8257
            gen_st16(tmp, addr, IS_USER(s));
8258
        }
8259
        dead_tmp(addr);
8260
        break;
8261

    
8262
    case 9:
8263
        /* load/store from stack */
8264
        rd = (insn >> 8) & 7;
8265
        addr = load_reg(s, 13);
8266
        val = (insn & 0xff) * 4;
8267
        tcg_gen_addi_i32(addr, addr, val);
8268

    
8269
        if (insn & (1 << 11)) {
8270
            /* load */
8271
            tmp = gen_ld32(addr, IS_USER(s));
8272
            store_reg(s, rd, tmp);
8273
        } else {
8274
            /* store */
8275
            tmp = load_reg(s, rd);
8276
            gen_st32(tmp, addr, IS_USER(s));
8277
        }
8278
        dead_tmp(addr);
8279
        break;
8280

    
8281
    case 10:
8282
        /* add to high reg */
8283
        rd = (insn >> 8) & 7;
8284
        if (insn & (1 << 11)) {
8285
            /* SP */
8286
            tmp = load_reg(s, 13);
8287
        } else {
8288
            /* PC. bit 1 is ignored.  */
8289
            tmp = new_tmp();
8290
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8291
        }
8292
        val = (insn & 0xff) * 4;
8293
        tcg_gen_addi_i32(tmp, tmp, val);
8294
        store_reg(s, rd, tmp);
8295
        break;
8296

    
8297
    case 11:
8298
        /* misc */
8299
        op = (insn >> 8) & 0xf;
8300
        switch (op) {
8301
        case 0:
8302
            /* adjust stack pointer */
8303
            tmp = load_reg(s, 13);
8304
            val = (insn & 0x7f) * 4;
8305
            if (insn & (1 << 7))
8306
                val = -(int32_t)val;
8307
            tcg_gen_addi_i32(tmp, tmp, val);
8308
            store_reg(s, 13, tmp);
8309
            break;
8310

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

    
8376
        case 1: case 3: case 9: case 11: /* czb */
8377
            rm = insn & 7;
8378
            tmp = load_reg(s, rm);
8379
            tmp2 = tcg_const_i32(0);
8380
            s->condlabel = gen_new_label();
8381
            s->condjmp = 1;
8382
            if (insn & (1 << 11))
8383
                tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, s->condlabel);
8384
            else
8385
                tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, s->condlabel);
8386
            dead_tmp(tmp);
8387
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8388
            val = (uint32_t)s->pc + 2;
8389
            val += offset;
8390
            gen_jmp(s, val);
8391
            break;
8392

    
8393
        case 15: /* IT, nop-hint.  */
8394
            if ((insn & 0xf) == 0) {
8395
                gen_nop_hint(s, (insn >> 4) & 0xf);
8396
                break;
8397
            }
8398
            /* If Then.  */
8399
            s->condexec_cond = (insn >> 4) & 0xe;
8400
            s->condexec_mask = insn & 0x1f;
8401
            /* No actual code generated for this insn, just setup state.  */
8402
            break;
8403

    
8404
        case 0xe: /* bkpt */
8405
            gen_set_condexec(s);
8406
            gen_set_pc_im(s->pc - 2);
8407
            gen_exception(EXCP_BKPT);
8408
            s->is_jmp = DISAS_JUMP;
8409
            break;
8410

    
8411
        case 0xa: /* rev */
8412
            ARCH(6);
8413
            rn = (insn >> 3) & 0x7;
8414
            rd = insn & 0x7;
8415
            tmp = load_reg(s, rn);
8416
            switch ((insn >> 6) & 3) {
8417
            case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8418
            case 1: gen_rev16(tmp); break;
8419
            case 3: gen_revsh(tmp); break;
8420
            default: goto illegal_op;
8421
            }
8422
            store_reg(s, rd, tmp);
8423
            break;
8424

    
8425
        case 6: /* cps */
8426
            ARCH(6);
8427
            if (IS_USER(s))
8428
                break;
8429
            if (IS_M(env)) {
8430
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8431
                /* PRIMASK */
8432
                if (insn & 1) {
8433
                    addr = tcg_const_i32(16);
8434
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8435
                }
8436
                /* FAULTMASK */
8437
                if (insn & 2) {
8438
                    addr = tcg_const_i32(17);
8439
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8440
                }
8441
                gen_lookup_tb(s);
8442
            } else {
8443
                if (insn & (1 << 4))
8444
                    shift = CPSR_A | CPSR_I | CPSR_F;
8445
                else
8446
                    shift = 0;
8447

    
8448
                val = ((insn & 7) << 6) & shift;
8449
                gen_op_movl_T0_im(val);
8450
                gen_set_psr_T0(s, shift, 0);
8451
            }
8452
            break;
8453

    
8454
        default:
8455
            goto undef;
8456
        }
8457
        break;
8458

    
8459
    case 12:
8460
        /* load/store multiple */
8461
        rn = (insn >> 8) & 0x7;
8462
        addr = load_reg(s, rn);
8463
        for (i = 0; i < 8; i++) {
8464
            if (insn & (1 << i)) {
8465
                if (insn & (1 << 11)) {
8466
                    /* load */
8467
                    tmp = gen_ld32(addr, IS_USER(s));
8468
                    store_reg(s, i, tmp);
8469
                } else {
8470
                    /* store */
8471
                    tmp = load_reg(s, i);
8472
                    gen_st32(tmp, addr, IS_USER(s));
8473
                }
8474
                /* advance to the next address */
8475
                tcg_gen_addi_i32(addr, addr, 4);
8476
            }
8477
        }
8478
        /* Base register writeback.  */
8479
        if ((insn & (1 << rn)) == 0) {
8480
            store_reg(s, rn, addr);
8481
        } else {
8482
            dead_tmp(addr);
8483
        }
8484
        break;
8485

    
8486
    case 13:
8487
        /* conditional branch or swi */
8488
        cond = (insn >> 8) & 0xf;
8489
        if (cond == 0xe)
8490
            goto undef;
8491

    
8492
        if (cond == 0xf) {
8493
            /* swi */
8494
            gen_set_condexec(s);
8495
            gen_set_pc_im(s->pc);
8496
            s->is_jmp = DISAS_SWI;
8497
            break;
8498
        }
8499
        /* generate a conditional jump to next instruction */
8500
        s->condlabel = gen_new_label();
8501
        gen_test_cc(cond ^ 1, s->condlabel);
8502
        s->condjmp = 1;
8503
        gen_movl_T1_reg(s, 15);
8504

    
8505
        /* jump to the offset */
8506
        val = (uint32_t)s->pc + 2;
8507
        offset = ((int32_t)insn << 24) >> 24;
8508
        val += offset << 1;
8509
        gen_jmp(s, val);
8510
        break;
8511

    
8512
    case 14:
8513
        if (insn & (1 << 11)) {
8514
            if (disas_thumb2_insn(env, s, insn))
8515
              goto undef32;
8516
            break;
8517
        }
8518
        /* unconditional branch */
8519
        val = (uint32_t)s->pc;
8520
        offset = ((int32_t)insn << 21) >> 21;
8521
        val += (offset << 1) + 2;
8522
        gen_jmp(s, val);
8523
        break;
8524

    
8525
    case 15:
8526
        if (disas_thumb2_insn(env, s, insn))
8527
            goto undef32;
8528
        break;
8529
    }
8530
    return;
8531
undef32:
8532
    gen_set_condexec(s);
8533
    gen_set_pc_im(s->pc - 4);
8534
    gen_exception(EXCP_UDEF);
8535
    s->is_jmp = DISAS_JUMP;
8536
    return;
8537
illegal_op:
8538
undef:
8539
    gen_set_condexec(s);
8540
    gen_set_pc_im(s->pc - 2);
8541
    gen_exception(EXCP_UDEF);
8542
    s->is_jmp = DISAS_JUMP;
8543
}
8544

    
8545
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8546
   basic block 'tb'. If search_pc is TRUE, also generate PC
8547
   information for each intermediate instruction. */
8548
static inline int gen_intermediate_code_internal(CPUState *env,
8549
                                                 TranslationBlock *tb,
8550
                                                 int search_pc)
8551
{
8552
    DisasContext dc1, *dc = &dc1;
8553
    uint16_t *gen_opc_end;
8554
    int j, lj;
8555
    target_ulong pc_start;
8556
    uint32_t next_page_start;
8557

    
8558
    /* generate intermediate code */
8559
    num_temps = 0;
8560
    memset(temps, 0, sizeof(temps));
8561

    
8562
    pc_start = tb->pc;
8563

    
8564
    dc->tb = tb;
8565

    
8566
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8567

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

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

    
8636
        if (env->thumb) {
8637
            disas_thumb_insn(env, dc);
8638
            if (dc->condexec_mask) {
8639
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8640
                                   | ((dc->condexec_mask >> 4) & 1);
8641
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8642
                if (dc->condexec_mask == 0) {
8643
                    dc->condexec_cond = 0;
8644
                }
8645
            }
8646
        } else {
8647
            disas_arm_insn(env, dc);
8648
        }
8649
        if (num_temps) {
8650
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8651
            num_temps = 0;
8652
        }
8653

    
8654
        if (dc->condjmp && !dc->is_jmp) {
8655
            gen_set_label(dc->condlabel);
8656
            dc->condjmp = 0;
8657
        }
8658
        /* Terminate the TB on memory ops if watchpoints are present.  */
8659
        /* FIXME: This should be replacd by the deterministic execution
8660
         * IRQ raising bits.  */
8661
        if (dc->is_mem && env->nb_watchpoints)
8662
            break;
8663

    
8664
        /* Translation stops when a conditional branch is enoutered.
8665
         * Otherwise the subsequent code could get translated several times.
8666
         * Also stop translation when a page boundary is reached.  This
8667
         * ensures prefech aborts occur at the right place.  */
8668
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8669
             !env->singlestep_enabled &&
8670
             dc->pc < next_page_start);
8671

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

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

    
8757
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8758
{
8759
    return gen_intermediate_code_internal(env, tb, 0);
8760
}
8761

    
8762
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8763
{
8764
    return gen_intermediate_code_internal(env, tb, 1);
8765
}
8766

    
8767
static const char *cpu_mode_names[16] = {
8768
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8769
  "???", "???", "???", "und", "???", "???", "???", "sys"
8770
};
8771

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

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

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

    
8823
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8824
                unsigned long searched_pc, int pc_pos, void *puc)
8825
{
8826
    env->regs[15] = gen_opc_pc[pc_pos];
8827
}