Statistics
| Branch: | Revision:

root / target-arm / translate.c @ e677137d

History | View | Annotate | Download (294.7 kB)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
190

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

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

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

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

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

    
223
/* Value extensions.  */
224
#define gen_uxtb(var) tcg_gen_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, NZF));
427
}
428

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
907
static inline void gen_set_pc_T0(void)
908
{
909
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, regs[15]));
910
}
911

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

    
928
static inline void gen_movl_reg_T0(DisasContext *s, int reg)
929
{
930
    gen_movl_reg_TN(s, reg, 0);
931
}
932

    
933
static inline void gen_movl_reg_T1(DisasContext *s, int reg)
934
{
935
    gen_movl_reg_TN(s, reg, 1);
936
}
937

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

    
946
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
947
                                       TCGv var)
948
{
949
    int val, rm, shift, shiftop;
950
    TCGv offset;
951

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

    
974
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
975
                                        int extra, TCGv var)
976
{
977
    int val, rm;
978
    TCGv offset;
979

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

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

    
1011
#define VFP_OP1i(name)                               \
1012
static inline void gen_vfp_##name(int dp, int arg)  \
1013
{                                                   \
1014
    if (dp)                                         \
1015
        gen_op_vfp_##name##d(arg);                  \
1016
    else                                            \
1017
        gen_op_vfp_##name##s(arg);                  \
1018
}
1019

    
1020
VFP_OP2(add)
1021
VFP_OP2(sub)
1022
VFP_OP2(mul)
1023
VFP_OP2(div)
1024

    
1025
#undef VFP_OP2
1026

    
1027
static inline void gen_vfp_abs(int dp)
1028
{
1029
    if (dp)
1030
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1031
    else
1032
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1033
}
1034

    
1035
static inline void gen_vfp_neg(int dp)
1036
{
1037
    if (dp)
1038
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1039
    else
1040
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1041
}
1042

    
1043
static inline void gen_vfp_sqrt(int dp)
1044
{
1045
    if (dp)
1046
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1047
    else
1048
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1049
}
1050

    
1051
static inline void gen_vfp_cmp(int dp)
1052
{
1053
    if (dp)
1054
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1055
    else
1056
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1057
}
1058

    
1059
static inline void gen_vfp_cmpe(int dp)
1060
{
1061
    if (dp)
1062
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1063
    else
1064
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1065
}
1066

    
1067
static inline void gen_vfp_F1_ld0(int dp)
1068
{
1069
    if (dp)
1070
        tcg_gen_movi_i64(cpu_F0d, 0);
1071
    else
1072
        tcg_gen_movi_i32(cpu_F0s, 0);
1073
}
1074

    
1075
static inline void gen_vfp_uito(int dp)
1076
{
1077
    if (dp)
1078
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1079
    else
1080
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1081
}
1082

    
1083
static inline void gen_vfp_sito(int dp)
1084
{
1085
    if (dp)
1086
        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
1087
    else
1088
        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
1089
}
1090

    
1091
static inline void gen_vfp_toui(int dp)
1092
{
1093
    if (dp)
1094
        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
1095
    else
1096
        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
1097
}
1098

    
1099
static inline void gen_vfp_touiz(int dp)
1100
{
1101
    if (dp)
1102
        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
1103
    else
1104
        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
1105
}
1106

    
1107
static inline void gen_vfp_tosi(int dp)
1108
{
1109
    if (dp)
1110
        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
1111
    else
1112
        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
1113
}
1114

    
1115
static inline void gen_vfp_tosiz(int dp)
1116
{
1117
    if (dp)
1118
        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
1119
    else
1120
        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
1121
}
1122

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

    
1141
static inline void gen_vfp_ld(DisasContext *s, int dp)
1142
{
1143
    if (dp)
1144
        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
1145
    else
1146
        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
1147
}
1148

    
1149
static inline void gen_vfp_st(DisasContext *s, int dp)
1150
{
1151
    if (dp)
1152
        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
1153
    else
1154
        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
1155
}
1156

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

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

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

    
1189
static TCGv neon_load_reg(int reg, int pass)
1190
{
1191
    TCGv tmp = new_tmp();
1192
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1193
    return tmp;
1194
}
1195

    
1196
static void neon_store_reg(int reg, int pass, TCGv var)
1197
{
1198
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1199
    dead_tmp(var);
1200
}
1201

    
1202
static inline void neon_load_reg64(TCGv var, int reg)
1203
{
1204
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1205
}
1206

    
1207
static inline void neon_store_reg64(TCGv var, int reg)
1208
{
1209
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1210
}
1211

    
1212
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1213
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1214
#define tcg_gen_st_f32 tcg_gen_st_i32
1215
#define tcg_gen_st_f64 tcg_gen_st_i64
1216

    
1217
static inline void gen_mov_F0_vreg(int dp, int reg)
1218
{
1219
    if (dp)
1220
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1221
    else
1222
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1223
}
1224

    
1225
static inline void gen_mov_F1_vreg(int dp, int reg)
1226
{
1227
    if (dp)
1228
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1229
    else
1230
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1231
}
1232

    
1233
static inline void gen_mov_vreg_F0(int dp, int reg)
1234
{
1235
    if (dp)
1236
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1237
    else
1238
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1239
}
1240

    
1241
#define ARM_CP_RW_BIT        (1 << 20)
1242

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

    
1248
static inline void iwmmxt_store_reg(TCGv var, int reg)
1249
{
1250
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
1251
}
1252

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

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

    
1263
static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
1264
{
1265
    tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
1266
}
1267

    
1268
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1269
{
1270
    iwmmxt_store_reg(cpu_M0, rn);
1271
}
1272

    
1273
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1274
{
1275
    iwmmxt_load_reg(cpu_M0, rn);
1276
}
1277

    
1278
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1279
{
1280
    iwmmxt_load_reg(cpu_V1, rn);
1281
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1282
}
1283

    
1284
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1285
{
1286
    iwmmxt_load_reg(cpu_V1, rn);
1287
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1288
}
1289

    
1290
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1291
{
1292
    iwmmxt_load_reg(cpu_V1, rn);
1293
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1294
}
1295

    
1296
#define IWMMXT_OP(name) \
1297
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1298
{ \
1299
    iwmmxt_load_reg(cpu_V1, rn); \
1300
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1301
}
1302

    
1303
#define IWMMXT_OP_ENV(name) \
1304
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1305
{ \
1306
    iwmmxt_load_reg(cpu_V1, rn); \
1307
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1308
}
1309

    
1310
#define IWMMXT_OP_ENV_SIZE(name) \
1311
IWMMXT_OP_ENV(name##b) \
1312
IWMMXT_OP_ENV(name##w) \
1313
IWMMXT_OP_ENV(name##l)
1314

    
1315
#define IWMMXT_OP_ENV1(name) \
1316
static inline void gen_op_iwmmxt_##name##_M0(void) \
1317
{ \
1318
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1319
}
1320

    
1321
IWMMXT_OP(maddsq)
1322
IWMMXT_OP(madduq)
1323
IWMMXT_OP(sadb)
1324
IWMMXT_OP(sadw)
1325
IWMMXT_OP(mulslw)
1326
IWMMXT_OP(mulshw)
1327
IWMMXT_OP(mululw)
1328
IWMMXT_OP(muluhw)
1329
IWMMXT_OP(macsw)
1330
IWMMXT_OP(macuw)
1331

    
1332
IWMMXT_OP_ENV_SIZE(unpackl)
1333
IWMMXT_OP_ENV_SIZE(unpackh)
1334

    
1335
IWMMXT_OP_ENV1(unpacklub)
1336
IWMMXT_OP_ENV1(unpackluw)
1337
IWMMXT_OP_ENV1(unpacklul)
1338
IWMMXT_OP_ENV1(unpackhub)
1339
IWMMXT_OP_ENV1(unpackhuw)
1340
IWMMXT_OP_ENV1(unpackhul)
1341
IWMMXT_OP_ENV1(unpacklsb)
1342
IWMMXT_OP_ENV1(unpacklsw)
1343
IWMMXT_OP_ENV1(unpacklsl)
1344
IWMMXT_OP_ENV1(unpackhsb)
1345
IWMMXT_OP_ENV1(unpackhsw)
1346
IWMMXT_OP_ENV1(unpackhsl)
1347

    
1348
IWMMXT_OP_ENV_SIZE(cmpeq)
1349
IWMMXT_OP_ENV_SIZE(cmpgtu)
1350
IWMMXT_OP_ENV_SIZE(cmpgts)
1351

    
1352
IWMMXT_OP_ENV_SIZE(mins)
1353
IWMMXT_OP_ENV_SIZE(minu)
1354
IWMMXT_OP_ENV_SIZE(maxs)
1355
IWMMXT_OP_ENV_SIZE(maxu)
1356

    
1357
IWMMXT_OP_ENV_SIZE(subn)
1358
IWMMXT_OP_ENV_SIZE(addn)
1359
IWMMXT_OP_ENV_SIZE(subu)
1360
IWMMXT_OP_ENV_SIZE(addu)
1361
IWMMXT_OP_ENV_SIZE(subs)
1362
IWMMXT_OP_ENV_SIZE(adds)
1363

    
1364
IWMMXT_OP_ENV(avgb0)
1365
IWMMXT_OP_ENV(avgb1)
1366
IWMMXT_OP_ENV(avgw0)
1367
IWMMXT_OP_ENV(avgw1)
1368

    
1369
IWMMXT_OP(msadb)
1370

    
1371
IWMMXT_OP_ENV(packuw)
1372
IWMMXT_OP_ENV(packul)
1373
IWMMXT_OP_ENV(packuq)
1374
IWMMXT_OP_ENV(packsw)
1375
IWMMXT_OP_ENV(packsl)
1376
IWMMXT_OP_ENV(packsq)
1377

    
1378
static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
1379
{
1380
    gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1381
}
1382

    
1383
static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
1384
{
1385
    gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1386
}
1387

    
1388
static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
1389
{
1390
    gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
1391
}
1392

    
1393
static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
1394
{
1395
    iwmmxt_load_reg(cpu_V1, rn);
1396
    gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
1397
}
1398

    
1399
static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
1400
{
1401
    TCGv tmp = tcg_const_i32(shift);
1402
    gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
1403
}
1404

    
1405
static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
1406
{
1407
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1408
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1409
    tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1410
}
1411

    
1412
static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
1413
{
1414
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1415
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1416
    tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1417
}
1418

    
1419
static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
1420
{
1421
    tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
1422
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
1423
    if (mask != ~0u)
1424
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
1425
}
1426

    
1427
static void gen_op_iwmmxt_set_mup(void)
1428
{
1429
    TCGv tmp;
1430
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1431
    tcg_gen_ori_i32(tmp, tmp, 2);
1432
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1433
}
1434

    
1435
static void gen_op_iwmmxt_set_cup(void)
1436
{
1437
    TCGv tmp;
1438
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1439
    tcg_gen_ori_i32(tmp, tmp, 1);
1440
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1441
}
1442

    
1443
static void gen_op_iwmmxt_setpsr_nz(void)
1444
{
1445
    TCGv tmp = new_tmp();
1446
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1447
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1448
}
1449

    
1450
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1451
{
1452
    iwmmxt_load_reg(cpu_V1, rn);
1453
    tcg_gen_andi_i64(cpu_V1, cpu_V1, 0xffffffffu);
1454
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1455
}
1456

    
1457

    
1458
static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
1459
{
1460
    iwmmxt_load_reg(cpu_V0, rn);
1461
    tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
1462
    tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1463
    tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
1464
}
1465

    
1466
static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
1467
{
1468
    tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
1469
    tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
1470
    tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
1471
    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
1472
    iwmmxt_store_reg(cpu_V0, rn);
1473
}
1474

    
1475
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1476
{
1477
    int rd;
1478
    uint32_t offset;
1479

    
1480
    rd = (insn >> 16) & 0xf;
1481
    gen_movl_T1_reg(s, rd);
1482

    
1483
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1484
    if (insn & (1 << 24)) {
1485
        /* Pre indexed */
1486
        if (insn & (1 << 23))
1487
            gen_op_addl_T1_im(offset);
1488
        else
1489
            gen_op_addl_T1_im(-offset);
1490

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

    
1506
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1507
{
1508
    int rd = (insn >> 0) & 0xf;
1509

    
1510
    if (insn & (1 << 8))
1511
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1512
            return 1;
1513
        else
1514
            gen_op_iwmmxt_movl_T0_wCx(rd);
1515
    else
1516
        gen_iwmmxt_movl_T0_T1_wRn(rd);
1517

    
1518
    gen_op_movl_T1_im(mask);
1519
    gen_op_andl_T0_T1();
1520
    return 0;
1521
}
1522

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

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

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

    
1611
    if ((insn & 0x0f000000) != 0x0e000000)
1612
        return 1;
1613

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

    
2486
    return 0;
2487
}
2488

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

    
2495
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2496
        /* Multiply with Internal Accumulate Format */
2497
        rd0 = (insn >> 12) & 0xf;
2498
        rd1 = insn & 0xf;
2499
        acc = (insn >> 5) & 7;
2500

    
2501
        if (acc != 0)
2502
            return 1;
2503

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

    
2532
        gen_op_iwmmxt_movq_wRn_M0(acc);
2533
        return 0;
2534
    }
2535

    
2536
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2537
        /* Internal Accumulator Access Format */
2538
        rdhi = (insn >> 16) & 0xf;
2539
        rdlo = (insn >> 12) & 0xf;
2540
        acc = insn & 7;
2541

    
2542
        if (acc != 0)
2543
            return 1;
2544

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

    
2559
    return 1;
2560
}
2561

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

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

    
2590
static int cp15_user_ok(uint32_t insn)
2591
{
2592
    int cpn = (insn >> 16) & 0xf;
2593
    int cpm = insn & 0xf;
2594
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2595

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

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

    
2617
    /* M profile cores use memory mapped registers instead of cp15.  */
2618
    if (arm_feature(env, ARM_FEATURE_M))
2619
        return 1;
2620

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

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

    
2679
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2680
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2681
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2682
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2683
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2684
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2685

    
2686
/* Move between integer and VFP cores.  */
2687
static TCGv gen_vfp_mrs(void)
2688
{
2689
    TCGv tmp = new_tmp();
2690
    tcg_gen_mov_i32(tmp, cpu_F0s);
2691
    return tmp;
2692
}
2693

    
2694
static void gen_vfp_msr(TCGv tmp)
2695
{
2696
    tcg_gen_mov_i32(cpu_F0s, tmp);
2697
    dead_tmp(tmp);
2698
}
2699

    
2700
static inline int
2701
vfp_enabled(CPUState * env)
2702
{
2703
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2704
}
2705

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

    
2719
static void gen_neon_dup_low16(TCGv var)
2720
{
2721
    TCGv tmp = new_tmp();
2722
    tcg_gen_andi_i32(var, var, 0xffff);
2723
    tcg_gen_shli_i32(tmp, var, 16);
2724
    tcg_gen_or_i32(var, var, tmp);
2725
    dead_tmp(tmp);
2726
}
2727

    
2728
static void gen_neon_dup_high16(TCGv var)
2729
{
2730
    TCGv tmp = new_tmp();
2731
    tcg_gen_andi_i32(var, var, 0xffff0000);
2732
    tcg_gen_shri_i32(tmp, var, 16);
2733
    tcg_gen_or_i32(var, var, tmp);
2734
    dead_tmp(tmp);
2735
}
2736

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

    
2746
    if (!arm_feature(env, ARM_FEATURE_VFP))
2747
        return 1;
2748

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

    
2768
                VFP_DREG_N(rn, insn);
2769
                if (insn & 0xf)
2770
                    return 1;
2771
                if (insn & 0x00c00060
2772
                    && !arm_feature(env, ARM_FEATURE_NEON))
2773
                    return 1;
2774

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

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

    
2962
                if (op == 15 && (rn == 15 || rn > 17)) {
2963
                    /* Integer or single precision destination.  */
2964
                    rd = VFP_SREG_D(insn);
2965
                } else {
2966
                    VFP_DREG_D(rd, insn);
2967
                }
2968

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

    
2986
            veclen = env->vfp.vec_len;
2987
            if (op == 15 && rn > 3)
2988
                veclen = 0;
2989

    
2990
            /* Shut up compiler warnings.  */
2991
            delta_m = 0;
2992
            delta_d = 0;
2993
            bank_mask = 0;
2994

    
2995
            if (veclen > 0) {
2996
                if (dp)
2997
                    bank_mask = 0xc;
2998
                else
2999
                    bank_mask = 0x18;
3000

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

    
3011
                    if ((rm & bank_mask) == 0) {
3012
                        /* mixed scalar/vector */
3013
                        delta_m = 0;
3014
                    } else {
3015
                        /* vector */
3016
                        delta_m = delta_d;
3017
                    }
3018
                }
3019
            }
3020

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

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

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

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

    
3235
                /* break out of the loop if we have finished  */
3236
                if (veclen == 0)
3237
                    break;
3238

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

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

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

    
3351
                if (insn & (1 << 24)) /* pre-decrement */
3352
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3353

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

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

    
3393
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3394
{
3395
    TranslationBlock *tb;
3396

    
3397
    tb = s->tb;
3398
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3399
        tcg_gen_goto_tb(n);
3400
        gen_set_pc_im(dest);
3401
        tcg_gen_exit_tb((long)tb + n);
3402
    } else {
3403
        gen_set_pc_im(dest);
3404
        tcg_gen_exit_tb(0);
3405
    }
3406
}
3407

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

    
3421
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3422
{
3423
    if (x)
3424
        tcg_gen_sari_i32(t0, t0, 16);
3425
    else
3426
        gen_sxth(t0);
3427
    if (y)
3428
        tcg_gen_sari_i32(t1, t1, 16);
3429
    else
3430
        gen_sxth(t1);
3431
    tcg_gen_mul_i32(t0, t0, t1);
3432
}
3433

    
3434
/* Return the mask of PSR bits set by a MSR instruction.  */
3435
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3436
    uint32_t mask;
3437

    
3438
    mask = 0;
3439
    if (flags & (1 << 0))
3440
        mask |= 0xff;
3441
    if (flags & (1 << 1))
3442
        mask |= 0xff00;
3443
    if (flags & (1 << 2))
3444
        mask |= 0xff0000;
3445
    if (flags & (1 << 3))
3446
        mask |= 0xff000000;
3447

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

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

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

    
3484
/* Generate an old-style exception return.  */
3485
static void gen_exception_return(DisasContext *s)
3486
{
3487
    TCGv tmp;
3488
    gen_set_pc_T0();
3489
    tmp = load_cpu_field(spsr);
3490
    gen_set_cpsr(tmp, 0xffffffff);
3491
    dead_tmp(tmp);
3492
    s->is_jmp = DISAS_UPDATE;
3493
}
3494

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

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

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

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

    
3536
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3537

    
3538
static inline int gen_neon_add(int size)
3539
{
3540
    switch (size) {
3541
    case 0: gen_helper_neon_add_u8(CPU_T001); break;
3542
    case 1: gen_helper_neon_add_u16(CPU_T001); break;
3543
    case 2: gen_op_addl_T0_T1(); break;
3544
    default: return 1;
3545
    }
3546
    return 0;
3547
}
3548

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

    
3559
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3560
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3561
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3562
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3563
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3564

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

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

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

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

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

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

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

    
3635
static inline void
3636
gen_neon_movl_T0_scratch(int scratch)
3637
{
3638
  uint32_t offset;
3639

    
3640
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3641
  tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
3642
}
3643

    
3644
static inline void
3645
gen_neon_movl_T1_scratch(int scratch)
3646
{
3647
  uint32_t offset;
3648

    
3649
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3650
  tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
3651
}
3652

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

    
3666
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3667
{
3668
    int n;
3669

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

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

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

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

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

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

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

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

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

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

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

    
4009
static inline void gen_neon_addl(int size)
4010
{
4011
    switch (size) {
4012
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4013
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4014
    case 2: tcg_gen_add_i64(CPU_V001); break;
4015
    default: abort();
4016
    }
4017
}
4018

    
4019
static inline void gen_neon_subl(int size)
4020
{
4021
    switch (size) {
4022
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4023
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4024
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4025
    default: abort();
4026
    }
4027
}
4028

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

    
4039
static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
4040
{
4041
    switch (size) {
4042
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4043
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4044
    default: abort();
4045
    }
4046
}
4047

    
4048
static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
4049
{
4050
    TCGv tmp;
4051

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

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

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

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

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

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

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

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

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

    
4713
                    gen_neon_widen(cpu_V0, tmp, size, u);
4714

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

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

    
4798
            if (op != 14 || !invert)
4799
                gen_op_movl_T1_im(imm);
4800

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

    
4856
                prewiden = neon_3reg_wide[op][0];
4857
                src1_wide = neon_3reg_wide[op][1];
4858
                src2_wide = neon_3reg_wide[op][2];
4859

    
4860
                if (size == 0 && (op == 9 || op == 11 || op == 13))
4861
                    return 1;
4862

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

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

    
4950
                        if (op != 13) {
4951
                            neon_load_reg64(cpu_V1, rd + pass);
4952
                        }
4953

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

    
5085
                    gen_neon_get_scalar(size, rm);
5086
                    NEON_GET_REG(T1, rn, 1);
5087

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

    
5134
                if (imm > 7 && !q)
5135
                    return 1;
5136

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

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

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

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

    
5591

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

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

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

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

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

    
5633
    tmp2 = load_reg(s, rlow);
5634
    tcg_gen_extu_i32_i64(tmp, tmp2);
5635
    dead_tmp(tmp2);
5636
    tcg_gen_add_i64(val, val, tmp);
5637
}
5638

    
5639
/* Set N and Z flags from a 64-bit value.  */
5640
static void gen_logicq_cc(TCGv val)
5641
{
5642
    TCGv tmp = new_tmp();
5643
    gen_helper_logicq_cc(tmp, val);
5644
    store_cpu_field(tmp, NZF);
5645
}
5646

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

    
5655
    insn = ldl_code(s->pc);
5656
    s->pc += 4;
5657

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6939
    rn = (insn >> 16) & 0xf;
6940
    rs = (insn >> 12) & 0xf;
6941
    rd = (insn >> 8) & 0xf;
6942
    rm = insn & 0xf;
6943
    switch ((insn >> 25) & 0xf) {
6944
    case 0: case 1: case 2: case 3:
6945
        /* 16-bit instructions.  Should never happen.  */
6946
        abort();
6947
    case 4:
6948
        if (insn & (1 << 22)) {
6949
            /* Other load/store, table branch.  */
6950
            if (insn & 0x01200000) {
6951
                /* Load/store doubleword.  */
6952
                if (rn == 15) {
6953
                    addr = new_tmp();
6954
                    tcg_gen_movi_i32(addr, s->pc & ~3);
6955
                } else {
6956
                    addr = load_reg(s, rn);
6957
                }
6958
                offset = (insn & 0xff) * 4;
6959
                if ((insn & (1 << 23)) == 0)
6960
                    offset = -offset;
6961
                if (insn & (1 << 24)) {
6962
                    tcg_gen_addi_i32(addr, addr, offset);
6963
                    offset = 0;
6964
                }
6965
                if (insn & (1 << 20)) {
6966
                    /* ldrd */
6967
                    tmp = gen_ld32(addr, IS_USER(s));
6968
                    store_reg(s, rs, tmp);
6969
                    tcg_gen_addi_i32(addr, addr, 4);
6970
                    tmp = gen_ld32(addr, IS_USER(s));
6971
                    store_reg(s, rd, tmp);
6972
                } else {
6973
                    /* strd */
6974
                    tmp = load_reg(s, rs);
6975
                    gen_st32(tmp, addr, IS_USER(s));
6976
                    tcg_gen_addi_i32(addr, addr, 4);
6977
                    tmp = load_reg(s, rd);
6978
                    gen_st32(tmp, addr, IS_USER(s));
6979
                }
6980
                if (insn & (1 << 21)) {
6981
                    /* Base writeback.  */
6982
                    if (rn == 15)
6983
                        goto illegal_op;
6984
                    tcg_gen_addi_i32(addr, addr, offset - 4);
6985
                    store_reg(s, rn, addr);
6986
                } else {
6987
                    dead_tmp(addr);
6988
                }
6989
            } else if ((insn & (1 << 23)) == 0) {
6990
                /* Load/store exclusive word.  */
6991
                gen_movl_T1_reg(s, rn);
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 | 1);
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