Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 8984bd2e

History | View | Annotate | Download (285 kB)

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

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

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

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

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

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

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

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

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

    
79
static TCGv cpu_env;
80
/* FIXME:  These should be removed.  */
81
static TCGv cpu_T[3];
82
static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
83

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
188

    
189
/* Basic operations.  */
190
#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
191
#define gen_op_movl_T0_T2() tcg_gen_mov_i32(cpu_T[0], cpu_T[2])
192
#define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
193
#define gen_op_movl_T1_T2() tcg_gen_mov_i32(cpu_T[1], cpu_T[2])
194
#define gen_op_movl_T2_T0() tcg_gen_mov_i32(cpu_T[2], cpu_T[0])
195
#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
196
#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
197
#define gen_op_movl_T2_im(im) tcg_gen_movi_i32(cpu_T[2], im)
198

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

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

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

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

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

    
231
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
232
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
233

    
234
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
235

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
414
#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
415

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

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

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

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

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

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

    
461
/* T0 &= ~T1.  Clobbers T1.  */
462
/* FIXME: Implement bic natively.  */
463
static inline void gen_op_bicl_T0_T1(void)
464
{
465
    gen_op_notl_T1();
466
    gen_op_andl_T0_T1();
467
}
468

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

    
474
    if (i == 0)
475
        return;
476

    
477
    tmp = new_tmp();
478
    tcg_gen_shri_i32(tmp, t1, i);
479
    tcg_gen_shli_i32(t1, t1, 32 - i);
480
    tcg_gen_or_i32(t0, t1, tmp);
481
    dead_tmp(tmp);
482
}
483

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

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

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

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

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

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

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

    
658
static void gen_test_cc(int cc, int label)
659
{
660
    TCGv tmp;
661
    TCGv tmp2;
662
    TCGv zero;
663
    int inv;
664

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

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

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

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

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

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

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

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

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

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

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

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

    
893
static inline void gen_set_pc_T0(void)
894
{
895
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, regs[15]));
896
}
897

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

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

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

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

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

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

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

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

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

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

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

    
1011
#undef VFP_OP2
1012

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1167
#define NEON_GET_REG(T, reg, n) gen_op_neon_getreg_##T(neon_reg_offset(reg, n))
1168
#define NEON_SET_REG(T, reg, n) gen_op_neon_setreg_##T(neon_reg_offset(reg, n))
1169

    
1170
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1171
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1172
#define tcg_gen_st_f32 tcg_gen_st_i32
1173
#define tcg_gen_st_f64 tcg_gen_st_i64
1174

    
1175
static inline void gen_mov_F0_vreg(int dp, int reg)
1176
{
1177
    if (dp)
1178
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1179
    else
1180
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1181
}
1182

    
1183
static inline void gen_mov_F1_vreg(int dp, int reg)
1184
{
1185
    if (dp)
1186
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1187
    else
1188
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1189
}
1190

    
1191
static inline void gen_mov_vreg_F0(int dp, int reg)
1192
{
1193
    if (dp)
1194
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1195
    else
1196
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1197
}
1198

    
1199
#define ARM_CP_RW_BIT        (1 << 20)
1200

    
1201
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
1202
{
1203
    int rd;
1204
    uint32_t offset;
1205

    
1206
    rd = (insn >> 16) & 0xf;
1207
    gen_movl_T1_reg(s, rd);
1208

    
1209
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1210
    if (insn & (1 << 24)) {
1211
        /* Pre indexed */
1212
        if (insn & (1 << 23))
1213
            gen_op_addl_T1_im(offset);
1214
        else
1215
            gen_op_addl_T1_im(-offset);
1216

    
1217
        if (insn & (1 << 21))
1218
            gen_movl_reg_T1(s, rd);
1219
    } else if (insn & (1 << 21)) {
1220
        /* Post indexed */
1221
        if (insn & (1 << 23))
1222
            gen_op_movl_T0_im(offset);
1223
        else
1224
            gen_op_movl_T0_im(- offset);
1225
        gen_op_addl_T0_T1();
1226
        gen_movl_reg_T0(s, rd);
1227
    } else if (!(insn & (1 << 23)))
1228
        return 1;
1229
    return 0;
1230
}
1231

    
1232
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
1233
{
1234
    int rd = (insn >> 0) & 0xf;
1235

    
1236
    if (insn & (1 << 8))
1237
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
1238
            return 1;
1239
        else
1240
            gen_op_iwmmxt_movl_T0_wCx(rd);
1241
    else
1242
        gen_op_iwmmxt_movl_T0_T1_wRn(rd);
1243

    
1244
    gen_op_movl_T1_im(mask);
1245
    gen_op_andl_T0_T1();
1246
    return 0;
1247
}
1248

    
1249
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
1250
   (ie. an undefined instruction).  */
1251
static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
1252
{
1253
    int rd, wrd;
1254
    int rdhi, rdlo, rd0, rd1, i;
1255
    TCGv tmp;
1256

    
1257
    if ((insn & 0x0e000e00) == 0x0c000000) {
1258
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1259
            wrd = insn & 0xf;
1260
            rdlo = (insn >> 12) & 0xf;
1261
            rdhi = (insn >> 16) & 0xf;
1262
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1263
                gen_op_iwmmxt_movl_T0_T1_wRn(wrd);
1264
                gen_movl_reg_T0(s, rdlo);
1265
                gen_movl_reg_T1(s, rdhi);
1266
            } else {                                        /* TMCRR */
1267
                gen_movl_T0_reg(s, rdlo);
1268
                gen_movl_T1_reg(s, rdhi);
1269
                gen_op_iwmmxt_movl_wRn_T0_T1(wrd);
1270
                gen_op_iwmmxt_set_mup();
1271
            }
1272
            return 0;
1273
        }
1274

    
1275
        wrd = (insn >> 12) & 0xf;
1276
        if (gen_iwmmxt_address(s, insn))
1277
            return 1;
1278
        if (insn & ARM_CP_RW_BIT) {
1279
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1280
                tmp = gen_ld32(cpu_T[1], IS_USER(s));
1281
                tcg_gen_mov_i32(cpu_T[0], tmp);
1282
                dead_tmp(tmp);
1283
                gen_op_iwmmxt_movl_wCx_T0(wrd);
1284
            } else {
1285
                if (insn & (1 << 8))
1286
                    if (insn & (1 << 22))                /* WLDRD */
1287
                        gen_ldst(iwmmxt_ldq, s);
1288
                    else                                /* WLDRW wRd */
1289
                        gen_ldst(iwmmxt_ldl, s);
1290
                else
1291
                    if (insn & (1 << 22))                /* WLDRH */
1292
                        gen_ldst(iwmmxt_ldw, s);
1293
                    else                                /* WLDRB */
1294
                        gen_ldst(iwmmxt_ldb, s);
1295
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1296
            }
1297
        } else {
1298
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1299
                gen_op_iwmmxt_movl_T0_wCx(wrd);
1300
                tmp = new_tmp();
1301
                tcg_gen_mov_i32(tmp, cpu_T[0]);
1302
                gen_st32(tmp, cpu_T[1], IS_USER(s));
1303
            } else {
1304
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1305
                if (insn & (1 << 8))
1306
                    if (insn & (1 << 22))                /* WSTRD */
1307
                        gen_ldst(iwmmxt_stq, s);
1308
                    else                                /* WSTRW wRd */
1309
                        gen_ldst(iwmmxt_stl, s);
1310
                else
1311
                    if (insn & (1 << 22))                /* WSTRH */
1312
                        gen_ldst(iwmmxt_ldw, s);
1313
                    else                                /* WSTRB */
1314
                        gen_ldst(iwmmxt_stb, s);
1315
            }
1316
        }
1317
        return 0;
1318
    }
1319

    
1320
    if ((insn & 0x0f000000) != 0x0e000000)
1321
        return 1;
1322

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

    
2186
    return 0;
2187
}
2188

    
2189
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
2190
   (ie. an undefined instruction).  */
2191
static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2192
{
2193
    int acc, rd0, rd1, rdhi, rdlo;
2194

    
2195
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2196
        /* Multiply with Internal Accumulate Format */
2197
        rd0 = (insn >> 12) & 0xf;
2198
        rd1 = insn & 0xf;
2199
        acc = (insn >> 5) & 7;
2200

    
2201
        if (acc != 0)
2202
            return 1;
2203

    
2204
        switch ((insn >> 16) & 0xf) {
2205
        case 0x0:                                        /* MIA */
2206
            gen_movl_T0_reg(s, rd0);
2207
            gen_movl_T1_reg(s, rd1);
2208
            gen_op_iwmmxt_muladdsl_M0_T0_T1();
2209
            break;
2210
        case 0x8:                                        /* MIAPH */
2211
            gen_movl_T0_reg(s, rd0);
2212
            gen_movl_T1_reg(s, rd1);
2213
            gen_op_iwmmxt_muladdsw_M0_T0_T1();
2214
            break;
2215
        case 0xc:                                        /* MIABB */
2216
        case 0xd:                                        /* MIABT */
2217
        case 0xe:                                        /* MIATB */
2218
        case 0xf:                                        /* MIATT */
2219
            gen_movl_T1_reg(s, rd0);
2220
            if (insn & (1 << 16))
2221
                gen_op_shrl_T1_im(16);
2222
            gen_op_movl_T0_T1();
2223
            gen_movl_T1_reg(s, rd1);
2224
            if (insn & (1 << 17))
2225
                gen_op_shrl_T1_im(16);
2226
            gen_op_iwmmxt_muladdswl_M0_T0_T1();
2227
            break;
2228
        default:
2229
            return 1;
2230
        }
2231

    
2232
        gen_op_iwmmxt_movq_wRn_M0(acc);
2233
        return 0;
2234
    }
2235

    
2236
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2237
        /* Internal Accumulator Access Format */
2238
        rdhi = (insn >> 16) & 0xf;
2239
        rdlo = (insn >> 12) & 0xf;
2240
        acc = insn & 7;
2241

    
2242
        if (acc != 0)
2243
            return 1;
2244

    
2245
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2246
            gen_op_iwmmxt_movl_T0_T1_wRn(acc);
2247
            gen_movl_reg_T0(s, rdlo);
2248
            gen_op_movl_T0_im((1 << (40 - 32)) - 1);
2249
            gen_op_andl_T0_T1();
2250
            gen_movl_reg_T0(s, rdhi);
2251
        } else {                                        /* MAR */
2252
            gen_movl_T0_reg(s, rdlo);
2253
            gen_movl_T1_reg(s, rdhi);
2254
            gen_op_iwmmxt_movl_wRn_T0_T1(acc);
2255
        }
2256
        return 0;
2257
    }
2258

    
2259
    return 1;
2260
}
2261

    
2262
/* Disassemble system coprocessor instruction.  Return nonzero if
2263
   instruction is not defined.  */
2264
static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
2265
{
2266
    TCGv tmp;
2267
    uint32_t rd = (insn >> 12) & 0xf;
2268
    uint32_t cp = (insn >> 8) & 0xf;
2269
    if (IS_USER(s)) {
2270
        return 1;
2271
    }
2272

    
2273
    if (insn & ARM_CP_RW_BIT) {
2274
        if (!env->cp[cp].cp_read)
2275
            return 1;
2276
        gen_set_pc_im(s->pc);
2277
        tmp = new_tmp();
2278
        gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
2279
        store_reg(s, rd, tmp);
2280
    } else {
2281
        if (!env->cp[cp].cp_write)
2282
            return 1;
2283
        gen_set_pc_im(s->pc);
2284
        tmp = load_reg(s, rd);
2285
        gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
2286
    }
2287
    return 0;
2288
}
2289

    
2290
static int cp15_user_ok(uint32_t insn)
2291
{
2292
    int cpn = (insn >> 16) & 0xf;
2293
    int cpm = insn & 0xf;
2294
    int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
2295

    
2296
    if (cpn == 13 && cpm == 0) {
2297
        /* TLS register.  */
2298
        if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
2299
            return 1;
2300
    }
2301
    if (cpn == 7) {
2302
        /* ISB, DSB, DMB.  */
2303
        if ((cpm == 5 && op == 4)
2304
                || (cpm == 10 && (op == 4 || op == 5)))
2305
            return 1;
2306
    }
2307
    return 0;
2308
}
2309

    
2310
/* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
2311
   instruction is not defined.  */
2312
static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
2313
{
2314
    uint32_t rd;
2315
    TCGv tmp;
2316

    
2317
    /* M profile cores use memory mapped registers instead of cp15.  */
2318
    if (arm_feature(env, ARM_FEATURE_M))
2319
        return 1;
2320

    
2321
    if ((insn & (1 << 25)) == 0) {
2322
        if (insn & (1 << 20)) {
2323
            /* mrrc */
2324
            return 1;
2325
        }
2326
        /* mcrr.  Used for block cache operations, so implement as no-op.  */
2327
        return 0;
2328
    }
2329
    if ((insn & (1 << 4)) == 0) {
2330
        /* cdp */
2331
        return 1;
2332
    }
2333
    if (IS_USER(s) && !cp15_user_ok(insn)) {
2334
        return 1;
2335
    }
2336
    if ((insn & 0x0fff0fff) == 0x0e070f90
2337
        || (insn & 0x0fff0fff) == 0x0e070f58) {
2338
        /* Wait for interrupt.  */
2339
        gen_set_pc_im(s->pc);
2340
        s->is_jmp = DISAS_WFI;
2341
        return 0;
2342
    }
2343
    rd = (insn >> 12) & 0xf;
2344
    if (insn & ARM_CP_RW_BIT) {
2345
        tmp = new_tmp();
2346
        gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
2347
        /* If the destination register is r15 then sets condition codes.  */
2348
        if (rd != 15)
2349
            store_reg(s, rd, tmp);
2350
        else
2351
            dead_tmp(tmp);
2352
    } else {
2353
        tmp = load_reg(s, rd);
2354
        gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
2355
        dead_tmp(tmp);
2356
        /* Normally we would always end the TB here, but Linux
2357
         * arch/arm/mach-pxa/sleep.S expects two instructions following
2358
         * an MMU enable to execute from cache.  Imitate this behaviour.  */
2359
        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
2360
                (insn & 0x0fff0fff) != 0x0e010f10)
2361
            gen_lookup_tb(s);
2362
    }
2363
    return 0;
2364
}
2365

    
2366
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2367
#define VFP_SREG(insn, bigbit, smallbit) \
2368
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2369
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2370
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2371
        reg = (((insn) >> (bigbit)) & 0x0f) \
2372
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2373
    } else { \
2374
        if (insn & (1 << (smallbit))) \
2375
            return 1; \
2376
        reg = ((insn) >> (bigbit)) & 0x0f; \
2377
    }} while (0)
2378

    
2379
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2380
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2381
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2382
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2383
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2384
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2385

    
2386
/* Move between integer and VFP cores.  */
2387
static TCGv gen_vfp_mrs(void)
2388
{
2389
    TCGv tmp = new_tmp();
2390
    tcg_gen_mov_i32(tmp, cpu_F0s);
2391
    return tmp;
2392
}
2393

    
2394
static void gen_vfp_msr(TCGv tmp)
2395
{
2396
    tcg_gen_mov_i32(cpu_F0s, tmp);
2397
    dead_tmp(tmp);
2398
}
2399

    
2400
static inline int
2401
vfp_enabled(CPUState * env)
2402
{
2403
    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
2404
}
2405

    
2406
/* Disassemble a VFP instruction.  Returns nonzero if an error occured
2407
   (ie. an undefined instruction).  */
2408
static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
2409
{
2410
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2411
    int dp, veclen;
2412
    TCGv tmp;
2413

    
2414
    if (!arm_feature(env, ARM_FEATURE_VFP))
2415
        return 1;
2416

    
2417
    if (!vfp_enabled(env)) {
2418
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2419
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2420
            return 1;
2421
        rn = (insn >> 16) & 0xf;
2422
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2423
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2424
            return 1;
2425
    }
2426
    dp = ((insn & 0xf00) == 0xb00);
2427
    switch ((insn >> 24) & 0xf) {
2428
    case 0xe:
2429
        if (insn & (1 << 4)) {
2430
            /* single register transfer */
2431
            rd = (insn >> 12) & 0xf;
2432
            if (dp) {
2433
                int size;
2434
                int pass;
2435

    
2436
                VFP_DREG_N(rn, insn);
2437
                if (insn & 0xf)
2438
                    return 1;
2439
                if (insn & 0x00c00060
2440
                    && !arm_feature(env, ARM_FEATURE_NEON))
2441
                    return 1;
2442

    
2443
                pass = (insn >> 21) & 1;
2444
                if (insn & (1 << 22)) {
2445
                    size = 0;
2446
                    offset = ((insn >> 5) & 3) * 8;
2447
                } else if (insn & (1 << 5)) {
2448
                    size = 1;
2449
                    offset = (insn & (1 << 6)) ? 16 : 0;
2450
                } else {
2451
                    size = 2;
2452
                    offset = 0;
2453
                }
2454
                if (insn & ARM_CP_RW_BIT) {
2455
                    /* vfp->arm */
2456
                    switch (size) {
2457
                    case 0:
2458
                        NEON_GET_REG(T1, rn, pass);
2459
                        if (offset)
2460
                            gen_op_shrl_T1_im(offset);
2461
                        if (insn & (1 << 23))
2462
                            gen_uxtb(cpu_T[1]);
2463
                        else
2464
                            gen_sxtb(cpu_T[1]);
2465
                        break;
2466
                    case 1:
2467
                        NEON_GET_REG(T1, rn, pass);
2468
                        if (insn & (1 << 23)) {
2469
                            if (offset) {
2470
                                gen_op_shrl_T1_im(16);
2471
                            } else {
2472
                                gen_uxth(cpu_T[1]);
2473
                            }
2474
                        } else {
2475
                            if (offset) {
2476
                                gen_op_sarl_T1_im(16);
2477
                            } else {
2478
                                gen_sxth(cpu_T[1]);
2479
                            }
2480
                        }
2481
                        break;
2482
                    case 2:
2483
                        NEON_GET_REG(T1, rn, pass);
2484
                        break;
2485
                    }
2486
                    gen_movl_reg_T1(s, rd);
2487
                } else {
2488
                    /* arm->vfp */
2489
                    gen_movl_T0_reg(s, rd);
2490
                    if (insn & (1 << 23)) {
2491
                        /* VDUP */
2492
                        if (size == 0) {
2493
                            gen_op_neon_dup_u8(0);
2494
                        } else if (size == 1) {
2495
                            gen_op_neon_dup_low16();
2496
                        }
2497
                        NEON_SET_REG(T0, rn, 0);
2498
                        NEON_SET_REG(T0, rn, 1);
2499
                    } else {
2500
                        /* VMOV */
2501
                        switch (size) {
2502
                        case 0:
2503
                            NEON_GET_REG(T2, rn, pass);
2504
                            gen_op_movl_T1_im(0xff);
2505
                            gen_op_andl_T0_T1();
2506
                            gen_op_neon_insert_elt(offset, ~(0xff << offset));
2507
                            NEON_SET_REG(T2, rn, pass);
2508
                            break;
2509
                        case 1:
2510
                            NEON_GET_REG(T2, rn, pass);
2511
                            gen_op_movl_T1_im(0xffff);
2512
                            gen_op_andl_T0_T1();
2513
                            bank_mask = offset ? 0xffff : 0xffff0000;
2514
                            gen_op_neon_insert_elt(offset, bank_mask);
2515
                            NEON_SET_REG(T2, rn, pass);
2516
                            break;
2517
                        case 2:
2518
                            NEON_SET_REG(T0, rn, pass);
2519
                            break;
2520
                        }
2521
                    }
2522
                }
2523
            } else { /* !dp */
2524
                if ((insn & 0x6f) != 0x00)
2525
                    return 1;
2526
                rn = VFP_SREG_N(insn);
2527
                if (insn & ARM_CP_RW_BIT) {
2528
                    /* vfp->arm */
2529
                    if (insn & (1 << 21)) {
2530
                        /* system register */
2531
                        rn >>= 1;
2532

    
2533
                        switch (rn) {
2534
                        case ARM_VFP_FPSID:
2535
                            /* VFP2 allows access to FSID from userspace.
2536
                               VFP3 restricts all id registers to privileged
2537
                               accesses.  */
2538
                            if (IS_USER(s)
2539
                                && arm_feature(env, ARM_FEATURE_VFP3))
2540
                                return 1;
2541
                            tmp = load_cpu_field(vfp.xregs[rn]);
2542
                            break;
2543
                        case ARM_VFP_FPEXC:
2544
                            if (IS_USER(s))
2545
                                return 1;
2546
                            tmp = load_cpu_field(vfp.xregs[rn]);
2547
                            break;
2548
                        case ARM_VFP_FPINST:
2549
                        case ARM_VFP_FPINST2:
2550
                            /* Not present in VFP3.  */
2551
                            if (IS_USER(s)
2552
                                || arm_feature(env, ARM_FEATURE_VFP3))
2553
                                return 1;
2554
                            tmp = load_cpu_field(vfp.xregs[rn]);
2555
                            break;
2556
                        case ARM_VFP_FPSCR:
2557
                            if (rd == 15) {
2558
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2559
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2560
                            } else {
2561
                                tmp = new_tmp();
2562
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2563
                            }
2564
                            break;
2565
                        case ARM_VFP_MVFR0:
2566
                        case ARM_VFP_MVFR1:
2567
                            if (IS_USER(s)
2568
                                || !arm_feature(env, ARM_FEATURE_VFP3))
2569
                                return 1;
2570
                            tmp = load_cpu_field(vfp.xregs[rn]);
2571
                            break;
2572
                        default:
2573
                            return 1;
2574
                        }
2575
                    } else {
2576
                        gen_mov_F0_vreg(0, rn);
2577
                        tmp = gen_vfp_mrs();
2578
                    }
2579
                    if (rd == 15) {
2580
                        /* Set the 4 flag bits in the CPSR.  */
2581
                        gen_set_nzcv(tmp);
2582
                        dead_tmp(tmp);
2583
                    } else {
2584
                        store_reg(s, rd, tmp);
2585
                    }
2586
                } else {
2587
                    /* arm->vfp */
2588
                    tmp = load_reg(s, rd);
2589
                    if (insn & (1 << 21)) {
2590
                        rn >>= 1;
2591
                        /* system register */
2592
                        switch (rn) {
2593
                        case ARM_VFP_FPSID:
2594
                        case ARM_VFP_MVFR0:
2595
                        case ARM_VFP_MVFR1:
2596
                            /* Writes are ignored.  */
2597
                            break;
2598
                        case ARM_VFP_FPSCR:
2599
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2600
                            dead_tmp(tmp);
2601
                            gen_lookup_tb(s);
2602
                            break;
2603
                        case ARM_VFP_FPEXC:
2604
                            if (IS_USER(s))
2605
                                return 1;
2606
                            store_cpu_field(tmp, vfp.xregs[rn]);
2607
                            gen_lookup_tb(s);
2608
                            break;
2609
                        case ARM_VFP_FPINST:
2610
                        case ARM_VFP_FPINST2:
2611
                            store_cpu_field(tmp, vfp.xregs[rn]);
2612
                            break;
2613
                        default:
2614
                            return 1;
2615
                        }
2616
                    } else {
2617
                        gen_vfp_msr(tmp);
2618
                        gen_mov_vreg_F0(0, rn);
2619
                    }
2620
                }
2621
            }
2622
        } else {
2623
            /* data processing */
2624
            /* The opcode is in bits 23, 21, 20 and 6.  */
2625
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2626
            if (dp) {
2627
                if (op == 15) {
2628
                    /* rn is opcode */
2629
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2630
                } else {
2631
                    /* rn is register number */
2632
                    VFP_DREG_N(rn, insn);
2633
                }
2634

    
2635
                if (op == 15 && (rn == 15 || rn > 17)) {
2636
                    /* Integer or single precision destination.  */
2637
                    rd = VFP_SREG_D(insn);
2638
                } else {
2639
                    VFP_DREG_D(rd, insn);
2640
                }
2641

    
2642
                if (op == 15 && (rn == 16 || rn == 17)) {
2643
                    /* Integer source.  */
2644
                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
2645
                } else {
2646
                    VFP_DREG_M(rm, insn);
2647
                }
2648
            } else {
2649
                rn = VFP_SREG_N(insn);
2650
                if (op == 15 && rn == 15) {
2651
                    /* Double precision destination.  */
2652
                    VFP_DREG_D(rd, insn);
2653
                } else {
2654
                    rd = VFP_SREG_D(insn);
2655
                }
2656
                rm = VFP_SREG_M(insn);
2657
            }
2658

    
2659
            veclen = env->vfp.vec_len;
2660
            if (op == 15 && rn > 3)
2661
                veclen = 0;
2662

    
2663
            /* Shut up compiler warnings.  */
2664
            delta_m = 0;
2665
            delta_d = 0;
2666
            bank_mask = 0;
2667

    
2668
            if (veclen > 0) {
2669
                if (dp)
2670
                    bank_mask = 0xc;
2671
                else
2672
                    bank_mask = 0x18;
2673

    
2674
                /* Figure out what type of vector operation this is.  */
2675
                if ((rd & bank_mask) == 0) {
2676
                    /* scalar */
2677
                    veclen = 0;
2678
                } else {
2679
                    if (dp)
2680
                        delta_d = (env->vfp.vec_stride >> 1) + 1;
2681
                    else
2682
                        delta_d = env->vfp.vec_stride + 1;
2683

    
2684
                    if ((rm & bank_mask) == 0) {
2685
                        /* mixed scalar/vector */
2686
                        delta_m = 0;
2687
                    } else {
2688
                        /* vector */
2689
                        delta_m = delta_d;
2690
                    }
2691
                }
2692
            }
2693

    
2694
            /* Load the initial operands.  */
2695
            if (op == 15) {
2696
                switch (rn) {
2697
                case 16:
2698
                case 17:
2699
                    /* Integer source */
2700
                    gen_mov_F0_vreg(0, rm);
2701
                    break;
2702
                case 8:
2703
                case 9:
2704
                    /* Compare */
2705
                    gen_mov_F0_vreg(dp, rd);
2706
                    gen_mov_F1_vreg(dp, rm);
2707
                    break;
2708
                case 10:
2709
                case 11:
2710
                    /* Compare with zero */
2711
                    gen_mov_F0_vreg(dp, rd);
2712
                    gen_vfp_F1_ld0(dp);
2713
                    break;
2714
                case 20:
2715
                case 21:
2716
                case 22:
2717
                case 23:
2718
                    /* Source and destination the same.  */
2719
                    gen_mov_F0_vreg(dp, rd);
2720
                    break;
2721
                default:
2722
                    /* One source operand.  */
2723
                    gen_mov_F0_vreg(dp, rm);
2724
                    break;
2725
                }
2726
            } else {
2727
                /* Two source operands.  */
2728
                gen_mov_F0_vreg(dp, rn);
2729
                gen_mov_F1_vreg(dp, rm);
2730
            }
2731

    
2732
            for (;;) {
2733
                /* Perform the calculation.  */
2734
                switch (op) {
2735
                case 0: /* mac: fd + (fn * fm) */
2736
                    gen_vfp_mul(dp);
2737
                    gen_mov_F1_vreg(dp, rd);
2738
                    gen_vfp_add(dp);
2739
                    break;
2740
                case 1: /* nmac: fd - (fn * fm) */
2741
                    gen_vfp_mul(dp);
2742
                    gen_vfp_neg(dp);
2743
                    gen_mov_F1_vreg(dp, rd);
2744
                    gen_vfp_add(dp);
2745
                    break;
2746
                case 2: /* msc: -fd + (fn * fm) */
2747
                    gen_vfp_mul(dp);
2748
                    gen_mov_F1_vreg(dp, rd);
2749
                    gen_vfp_sub(dp);
2750
                    break;
2751
                case 3: /* nmsc: -fd - (fn * fm)  */
2752
                    gen_vfp_mul(dp);
2753
                    gen_mov_F1_vreg(dp, rd);
2754
                    gen_vfp_add(dp);
2755
                    gen_vfp_neg(dp);
2756
                    break;
2757
                case 4: /* mul: fn * fm */
2758
                    gen_vfp_mul(dp);
2759
                    break;
2760
                case 5: /* nmul: -(fn * fm) */
2761
                    gen_vfp_mul(dp);
2762
                    gen_vfp_neg(dp);
2763
                    break;
2764
                case 6: /* add: fn + fm */
2765
                    gen_vfp_add(dp);
2766
                    break;
2767
                case 7: /* sub: fn - fm */
2768
                    gen_vfp_sub(dp);
2769
                    break;
2770
                case 8: /* div: fn / fm */
2771
                    gen_vfp_div(dp);
2772
                    break;
2773
                case 14: /* fconst */
2774
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
2775
                      return 1;
2776

    
2777
                    n = (insn << 12) & 0x80000000;
2778
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
2779
                    if (dp) {
2780
                        if (i & 0x40)
2781
                            i |= 0x3f80;
2782
                        else
2783
                            i |= 0x4000;
2784
                        n |= i << 16;
2785
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
2786
                    } else {
2787
                        if (i & 0x40)
2788
                            i |= 0x780;
2789
                        else
2790
                            i |= 0x800;
2791
                        n |= i << 19;
2792
                        tcg_gen_movi_i32(cpu_F0d, ((uint64_t)n) << 32);
2793
                    }
2794
                    break;
2795
                case 15: /* extension space */
2796
                    switch (rn) {
2797
                    case 0: /* cpy */
2798
                        /* no-op */
2799
                        break;
2800
                    case 1: /* abs */
2801
                        gen_vfp_abs(dp);
2802
                        break;
2803
                    case 2: /* neg */
2804
                        gen_vfp_neg(dp);
2805
                        break;
2806
                    case 3: /* sqrt */
2807
                        gen_vfp_sqrt(dp);
2808
                        break;
2809
                    case 8: /* cmp */
2810
                        gen_vfp_cmp(dp);
2811
                        break;
2812
                    case 9: /* cmpe */
2813
                        gen_vfp_cmpe(dp);
2814
                        break;
2815
                    case 10: /* cmpz */
2816
                        gen_vfp_cmp(dp);
2817
                        break;
2818
                    case 11: /* cmpez */
2819
                        gen_vfp_F1_ld0(dp);
2820
                        gen_vfp_cmpe(dp);
2821
                        break;
2822
                    case 15: /* single<->double conversion */
2823
                        if (dp)
2824
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
2825
                        else
2826
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
2827
                        break;
2828
                    case 16: /* fuito */
2829
                        gen_vfp_uito(dp);
2830
                        break;
2831
                    case 17: /* fsito */
2832
                        gen_vfp_sito(dp);
2833
                        break;
2834
                    case 20: /* fshto */
2835
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2836
                          return 1;
2837
                        gen_vfp_shto(dp, rm);
2838
                        break;
2839
                    case 21: /* fslto */
2840
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2841
                          return 1;
2842
                        gen_vfp_slto(dp, rm);
2843
                        break;
2844
                    case 22: /* fuhto */
2845
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2846
                          return 1;
2847
                        gen_vfp_uhto(dp, rm);
2848
                        break;
2849
                    case 23: /* fulto */
2850
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2851
                          return 1;
2852
                        gen_vfp_ulto(dp, rm);
2853
                        break;
2854
                    case 24: /* ftoui */
2855
                        gen_vfp_toui(dp);
2856
                        break;
2857
                    case 25: /* ftouiz */
2858
                        gen_vfp_touiz(dp);
2859
                        break;
2860
                    case 26: /* ftosi */
2861
                        gen_vfp_tosi(dp);
2862
                        break;
2863
                    case 27: /* ftosiz */
2864
                        gen_vfp_tosiz(dp);
2865
                        break;
2866
                    case 28: /* ftosh */
2867
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2868
                          return 1;
2869
                        gen_vfp_tosh(dp, rm);
2870
                        break;
2871
                    case 29: /* ftosl */
2872
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2873
                          return 1;
2874
                        gen_vfp_tosl(dp, rm);
2875
                        break;
2876
                    case 30: /* ftouh */
2877
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2878
                          return 1;
2879
                        gen_vfp_touh(dp, rm);
2880
                        break;
2881
                    case 31: /* ftoul */
2882
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
2883
                          return 1;
2884
                        gen_vfp_toul(dp, rm);
2885
                        break;
2886
                    default: /* undefined */
2887
                        printf ("rn:%d\n", rn);
2888
                        return 1;
2889
                    }
2890
                    break;
2891
                default: /* undefined */
2892
                    printf ("op:%d\n", op);
2893
                    return 1;
2894
                }
2895

    
2896
                /* Write back the result.  */
2897
                if (op == 15 && (rn >= 8 && rn <= 11))
2898
                    ; /* Comparison, do nothing.  */
2899
                else if (op == 15 && rn > 17)
2900
                    /* Integer result.  */
2901
                    gen_mov_vreg_F0(0, rd);
2902
                else if (op == 15 && rn == 15)
2903
                    /* conversion */
2904
                    gen_mov_vreg_F0(!dp, rd);
2905
                else
2906
                    gen_mov_vreg_F0(dp, rd);
2907

    
2908
                /* break out of the loop if we have finished  */
2909
                if (veclen == 0)
2910
                    break;
2911

    
2912
                if (op == 15 && delta_m == 0) {
2913
                    /* single source one-many */
2914
                    while (veclen--) {
2915
                        rd = ((rd + delta_d) & (bank_mask - 1))
2916
                             | (rd & bank_mask);
2917
                        gen_mov_vreg_F0(dp, rd);
2918
                    }
2919
                    break;
2920
                }
2921
                /* Setup the next operands.  */
2922
                veclen--;
2923
                rd = ((rd + delta_d) & (bank_mask - 1))
2924
                     | (rd & bank_mask);
2925

    
2926
                if (op == 15) {
2927
                    /* One source operand.  */
2928
                    rm = ((rm + delta_m) & (bank_mask - 1))
2929
                         | (rm & bank_mask);
2930
                    gen_mov_F0_vreg(dp, rm);
2931
                } else {
2932
                    /* Two source operands.  */
2933
                    rn = ((rn + delta_d) & (bank_mask - 1))
2934
                         | (rn & bank_mask);
2935
                    gen_mov_F0_vreg(dp, rn);
2936
                    if (delta_m) {
2937
                        rm = ((rm + delta_m) & (bank_mask - 1))
2938
                             | (rm & bank_mask);
2939
                        gen_mov_F1_vreg(dp, rm);
2940
                    }
2941
                }
2942
            }
2943
        }
2944
        break;
2945
    case 0xc:
2946
    case 0xd:
2947
        if (dp && (insn & 0x03e00000) == 0x00400000) {
2948
            /* two-register transfer */
2949
            rn = (insn >> 16) & 0xf;
2950
            rd = (insn >> 12) & 0xf;
2951
            if (dp) {
2952
                VFP_DREG_M(rm, insn);
2953
            } else {
2954
                rm = VFP_SREG_M(insn);
2955
            }
2956

    
2957
            if (insn & ARM_CP_RW_BIT) {
2958
                /* vfp->arm */
2959
                if (dp) {
2960
                    gen_mov_F0_vreg(0, rm * 2);
2961
                    tmp = gen_vfp_mrs();
2962
                    store_reg(s, rd, tmp);
2963
                    gen_mov_F0_vreg(0, rm * 2 + 1);
2964
                    tmp = gen_vfp_mrs();
2965
                    store_reg(s, rn, tmp);
2966
                } else {
2967
                    gen_mov_F0_vreg(0, rm);
2968
                    tmp = gen_vfp_mrs();
2969
                    store_reg(s, rn, tmp);
2970
                    gen_mov_F0_vreg(0, rm + 1);
2971
                    tmp = gen_vfp_mrs();
2972
                    store_reg(s, rd, tmp);
2973
                }
2974
            } else {
2975
                /* arm->vfp */
2976
                if (dp) {
2977
                    tmp = load_reg(s, rd);
2978
                    gen_vfp_msr(tmp);
2979
                    gen_mov_vreg_F0(0, rm * 2);
2980
                    tmp = load_reg(s, rn);
2981
                    gen_vfp_msr(tmp);
2982
                    gen_mov_vreg_F0(0, rm * 2 + 1);
2983
                } else {
2984
                    tmp = load_reg(s, rn);
2985
                    gen_vfp_msr(tmp);
2986
                    gen_mov_vreg_F0(0, rm);
2987
                    tmp = load_reg(s, rd);
2988
                    gen_vfp_msr(tmp);
2989
                    gen_mov_vreg_F0(0, rm + 1);
2990
                }
2991
            }
2992
        } else {
2993
            /* Load/store */
2994
            rn = (insn >> 16) & 0xf;
2995
            if (dp)
2996
                VFP_DREG_D(rd, insn);
2997
            else
2998
                rd = VFP_SREG_D(insn);
2999
            if (s->thumb && rn == 15) {
3000
                gen_op_movl_T1_im(s->pc & ~2);
3001
            } else {
3002
                gen_movl_T1_reg(s, rn);
3003
            }
3004
            if ((insn & 0x01200000) == 0x01000000) {
3005
                /* Single load/store */
3006
                offset = (insn & 0xff) << 2;
3007
                if ((insn & (1 << 23)) == 0)
3008
                    offset = -offset;
3009
                gen_op_addl_T1_im(offset);
3010
                if (insn & (1 << 20)) {
3011
                    gen_vfp_ld(s, dp);
3012
                    gen_mov_vreg_F0(dp, rd);
3013
                } else {
3014
                    gen_mov_F0_vreg(dp, rd);
3015
                    gen_vfp_st(s, dp);
3016
                }
3017
            } else {
3018
                /* load/store multiple */
3019
                if (dp)
3020
                    n = (insn >> 1) & 0x7f;
3021
                else
3022
                    n = insn & 0xff;
3023

    
3024
                if (insn & (1 << 24)) /* pre-decrement */
3025
                    gen_op_addl_T1_im(-((insn & 0xff) << 2));
3026

    
3027
                if (dp)
3028
                    offset = 8;
3029
                else
3030
                    offset = 4;
3031
                for (i = 0; i < n; i++) {
3032
                    if (insn & ARM_CP_RW_BIT) {
3033
                        /* load */
3034
                        gen_vfp_ld(s, dp);
3035
                        gen_mov_vreg_F0(dp, rd + i);
3036
                    } else {
3037
                        /* store */
3038
                        gen_mov_F0_vreg(dp, rd + i);
3039
                        gen_vfp_st(s, dp);
3040
                    }
3041
                    gen_op_addl_T1_im(offset);
3042
                }
3043
                if (insn & (1 << 21)) {
3044
                    /* writeback */
3045
                    if (insn & (1 << 24))
3046
                        offset = -offset * n;
3047
                    else if (dp && (insn & 1))
3048
                        offset = 4;
3049
                    else
3050
                        offset = 0;
3051

    
3052
                    if (offset != 0)
3053
                        gen_op_addl_T1_im(offset);
3054
                    gen_movl_reg_T1(s, rn);
3055
                }
3056
            }
3057
        }
3058
        break;
3059
    default:
3060
        /* Should never happen.  */
3061
        return 1;
3062
    }
3063
    return 0;
3064
}
3065

    
3066
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3067
{
3068
    TranslationBlock *tb;
3069

    
3070
    tb = s->tb;
3071
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3072
        tcg_gen_goto_tb(n);
3073
        gen_set_pc_im(dest);
3074
        tcg_gen_exit_tb((long)tb + n);
3075
    } else {
3076
        gen_set_pc_im(dest);
3077
        tcg_gen_exit_tb(0);
3078
    }
3079
}
3080

    
3081
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3082
{
3083
    if (__builtin_expect(s->singlestep_enabled, 0)) {
3084
        /* An indirect jump so that we still trigger the debug exception.  */
3085
        if (s->thumb)
3086
            dest |= 1;
3087
        gen_bx_im(s, dest);
3088
    } else {
3089
        gen_goto_tb(s, 0, dest);
3090
        s->is_jmp = DISAS_TB_JUMP;
3091
    }
3092
}
3093

    
3094
static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3095
{
3096
    if (x)
3097
        tcg_gen_sari_i32(t0, t0, 16);
3098
    else
3099
        gen_sxth(t0);
3100
    if (y)
3101
        tcg_gen_sari_i32(t1, t1, 16);
3102
    else
3103
        gen_sxth(t1);
3104
    tcg_gen_mul_i32(t0, t0, t1);
3105
}
3106

    
3107
/* Return the mask of PSR bits set by a MSR instruction.  */
3108
static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
3109
    uint32_t mask;
3110

    
3111
    mask = 0;
3112
    if (flags & (1 << 0))
3113
        mask |= 0xff;
3114
    if (flags & (1 << 1))
3115
        mask |= 0xff00;
3116
    if (flags & (1 << 2))
3117
        mask |= 0xff0000;
3118
    if (flags & (1 << 3))
3119
        mask |= 0xff000000;
3120

    
3121
    /* Mask out undefined bits.  */
3122
    mask &= ~CPSR_RESERVED;
3123
    if (!arm_feature(env, ARM_FEATURE_V6))
3124
        mask &= ~(CPSR_E | CPSR_GE);
3125
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3126
        mask &= ~CPSR_IT;
3127
    /* Mask out execution state bits.  */
3128
    if (!spsr)
3129
        mask &= ~CPSR_EXEC;
3130
    /* Mask out privileged bits.  */
3131
    if (IS_USER(s))
3132
        mask &= CPSR_USER;
3133
    return mask;
3134
}
3135

    
3136
/* Returns nonzero if access to the PSR is not permitted.  */
3137
static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
3138
{
3139
    TCGv tmp;
3140
    if (spsr) {
3141
        /* ??? This is also undefined in system mode.  */
3142
        if (IS_USER(s))
3143
            return 1;
3144

    
3145
        tmp = load_cpu_field(spsr);
3146
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3147
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
3148
        tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
3149
        store_cpu_field(tmp, spsr);
3150
    } else {
3151
        gen_set_cpsr(cpu_T[0], mask);
3152
    }
3153
    gen_lookup_tb(s);
3154
    return 0;
3155
}
3156

    
3157
/* Generate an old-style exception return.  */
3158
static void gen_exception_return(DisasContext *s)
3159
{
3160
    TCGv tmp;
3161
    gen_set_pc_T0();
3162
    tmp = load_cpu_field(spsr);
3163
    gen_set_cpsr(tmp, 0xffffffff);
3164
    dead_tmp(tmp);
3165
    s->is_jmp = DISAS_UPDATE;
3166
}
3167

    
3168
/* Generate a v6 exception return.  Marks both values as dead.  */
3169
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3170
{
3171
    gen_set_cpsr(cpsr, 0xffffffff);
3172
    dead_tmp(cpsr);
3173
    store_reg(s, 15, pc);
3174
    s->is_jmp = DISAS_UPDATE;
3175
}
3176

    
3177
static inline void
3178
gen_set_condexec (DisasContext *s)
3179
{
3180
    if (s->condexec_mask) {
3181
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3182
        TCGv tmp = new_tmp();
3183
        tcg_gen_movi_i32(tmp, val);
3184
        store_cpu_field(tmp, condexec_bits);
3185
    }
3186
}
3187

    
3188
static void gen_nop_hint(DisasContext *s, int val)
3189
{
3190
    switch (val) {
3191
    case 3: /* wfi */
3192
        gen_set_pc_im(s->pc);
3193
        s->is_jmp = DISAS_WFI;
3194
        break;
3195
    case 2: /* wfe */
3196
    case 4: /* sev */
3197
        /* TODO: Implement SEV and WFE.  May help SMP performance.  */
3198
    default: /* nop */
3199
        break;
3200
    }
3201
}
3202

    
3203
/* Neon shift by constant.  The actual ops are the same as used for variable
3204
   shifts.  [OP][U][SIZE]  */
3205
static GenOpFunc *gen_neon_shift_im[8][2][4] = {
3206
    { /* 0 */ /* VSHR */
3207
      {
3208
        gen_op_neon_shl_u8,
3209
        gen_op_neon_shl_u16,
3210
        gen_op_neon_shl_u32,
3211
        gen_op_neon_shl_u64
3212
      }, {
3213
        gen_op_neon_shl_s8,
3214
        gen_op_neon_shl_s16,
3215
        gen_op_neon_shl_s32,
3216
        gen_op_neon_shl_s64
3217
      }
3218
    }, { /* 1 */ /* VSRA */
3219
      {
3220
        gen_op_neon_shl_u8,
3221
        gen_op_neon_shl_u16,
3222
        gen_op_neon_shl_u32,
3223
        gen_op_neon_shl_u64
3224
      }, {
3225
        gen_op_neon_shl_s8,
3226
        gen_op_neon_shl_s16,
3227
        gen_op_neon_shl_s32,
3228
        gen_op_neon_shl_s64
3229
      }
3230
    }, { /* 2 */ /* VRSHR */
3231
      {
3232
        gen_op_neon_rshl_u8,
3233
        gen_op_neon_rshl_u16,
3234
        gen_op_neon_rshl_u32,
3235
        gen_op_neon_rshl_u64
3236
      }, {
3237
        gen_op_neon_rshl_s8,
3238
        gen_op_neon_rshl_s16,
3239
        gen_op_neon_rshl_s32,
3240
        gen_op_neon_rshl_s64
3241
      }
3242
    }, { /* 3 */ /* VRSRA */
3243
      {
3244
        gen_op_neon_rshl_u8,
3245
        gen_op_neon_rshl_u16,
3246
        gen_op_neon_rshl_u32,
3247
        gen_op_neon_rshl_u64
3248
      }, {
3249
        gen_op_neon_rshl_s8,
3250
        gen_op_neon_rshl_s16,
3251
        gen_op_neon_rshl_s32,
3252
        gen_op_neon_rshl_s64
3253
      }
3254
    }, { /* 4 */
3255
      {
3256
        NULL, NULL, NULL, NULL
3257
      }, { /* VSRI */
3258
        gen_op_neon_shl_u8,
3259
        gen_op_neon_shl_u16,
3260
        gen_op_neon_shl_u32,
3261
        gen_op_neon_shl_u64,
3262
      }
3263
    }, { /* 5 */
3264
      { /* VSHL */
3265
        gen_op_neon_shl_u8,
3266
        gen_op_neon_shl_u16,
3267
        gen_op_neon_shl_u32,
3268
        gen_op_neon_shl_u64,
3269
      }, { /* VSLI */
3270
        gen_op_neon_shl_u8,
3271
        gen_op_neon_shl_u16,
3272
        gen_op_neon_shl_u32,
3273
        gen_op_neon_shl_u64,
3274
      }
3275
    }, { /* 6 */ /* VQSHL */
3276
      {
3277
        gen_op_neon_qshl_u8,
3278
        gen_op_neon_qshl_u16,
3279
        gen_op_neon_qshl_u32,
3280
        gen_op_neon_qshl_u64
3281
      }, {
3282
        gen_op_neon_qshl_s8,
3283
        gen_op_neon_qshl_s16,
3284
        gen_op_neon_qshl_s32,
3285
        gen_op_neon_qshl_s64
3286
      }
3287
    }, { /* 7 */ /* VQSHLU */
3288
      {
3289
        gen_op_neon_qshl_u8,
3290
        gen_op_neon_qshl_u16,
3291
        gen_op_neon_qshl_u32,
3292
        gen_op_neon_qshl_u64
3293
      }, {
3294
        gen_op_neon_qshl_u8,
3295
        gen_op_neon_qshl_u16,
3296
        gen_op_neon_qshl_u32,
3297
        gen_op_neon_qshl_u64
3298
      }
3299
    }
3300
};
3301

    
3302
/* [R][U][size - 1] */
3303
static GenOpFunc *gen_neon_shift_im_narrow[2][2][3] = {
3304
    {
3305
      {
3306
        gen_op_neon_shl_u16,
3307
        gen_op_neon_shl_u32,
3308
        gen_op_neon_shl_u64
3309
      }, {
3310
        gen_op_neon_shl_s16,
3311
        gen_op_neon_shl_s32,
3312
        gen_op_neon_shl_s64
3313
      }
3314
    }, {
3315
      {
3316
        gen_op_neon_rshl_u16,
3317
        gen_op_neon_rshl_u32,
3318
        gen_op_neon_rshl_u64
3319
      }, {
3320
        gen_op_neon_rshl_s16,
3321
        gen_op_neon_rshl_s32,
3322
        gen_op_neon_rshl_s64
3323
      }
3324
    }
3325
};
3326

    
3327
static inline void
3328
gen_op_neon_narrow_u32 ()
3329
{
3330
    /* No-op.  */
3331
}
3332

    
3333
static GenOpFunc *gen_neon_narrow[3] = {
3334
    gen_op_neon_narrow_u8,
3335
    gen_op_neon_narrow_u16,
3336
    gen_op_neon_narrow_u32
3337
};
3338

    
3339
static GenOpFunc *gen_neon_narrow_satu[3] = {
3340
    gen_op_neon_narrow_sat_u8,
3341
    gen_op_neon_narrow_sat_u16,
3342
    gen_op_neon_narrow_sat_u32
3343
};
3344

    
3345
static GenOpFunc *gen_neon_narrow_sats[3] = {
3346
    gen_op_neon_narrow_sat_s8,
3347
    gen_op_neon_narrow_sat_s16,
3348
    gen_op_neon_narrow_sat_s32
3349
};
3350

    
3351
static inline int gen_neon_add(int size)
3352
{
3353
    switch (size) {
3354
    case 0: gen_op_neon_add_u8(); break;
3355
    case 1: gen_op_neon_add_u16(); break;
3356
    case 2: gen_op_addl_T0_T1(); break;
3357
    default: return 1;
3358
    }
3359
    return 0;
3360
}
3361

    
3362
/* 32-bit pairwise ops end up the same as the elementsise versions.  */
3363
#define gen_op_neon_pmax_s32  gen_op_neon_max_s32
3364
#define gen_op_neon_pmax_u32  gen_op_neon_max_u32
3365
#define gen_op_neon_pmin_s32  gen_op_neon_min_s32
3366
#define gen_op_neon_pmin_u32  gen_op_neon_min_u32
3367

    
3368
#define GEN_NEON_INTEGER_OP(name) do { \
3369
    switch ((size << 1) | u) { \
3370
    case 0: gen_op_neon_##name##_s8(); break; \
3371
    case 1: gen_op_neon_##name##_u8(); break; \
3372
    case 2: gen_op_neon_##name##_s16(); break; \
3373
    case 3: gen_op_neon_##name##_u16(); break; \
3374
    case 4: gen_op_neon_##name##_s32(); break; \
3375
    case 5: gen_op_neon_##name##_u32(); break; \
3376
    default: return 1; \
3377
    }} while (0)
3378

    
3379
static inline void
3380
gen_neon_movl_scratch_T0(int scratch)
3381
{
3382
  uint32_t offset;
3383

    
3384
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3385
  gen_op_neon_setreg_T0(offset);
3386
}
3387

    
3388
static inline void
3389
gen_neon_movl_scratch_T1(int scratch)
3390
{
3391
  uint32_t offset;
3392

    
3393
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3394
  gen_op_neon_setreg_T1(offset);
3395
}
3396

    
3397
static inline void
3398
gen_neon_movl_T0_scratch(int scratch)
3399
{
3400
  uint32_t offset;
3401

    
3402
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3403
  gen_op_neon_getreg_T0(offset);
3404
}
3405

    
3406
static inline void
3407
gen_neon_movl_T1_scratch(int scratch)
3408
{
3409
  uint32_t offset;
3410

    
3411
  offset = offsetof(CPUARMState, vfp.scratch[scratch]);
3412
  gen_op_neon_getreg_T1(offset);
3413
}
3414

    
3415
static inline void gen_op_neon_widen_u32(void)
3416
{
3417
    gen_op_movl_T1_im(0);
3418
}
3419

    
3420
static inline void gen_neon_get_scalar(int size, int reg)
3421
{
3422
    if (size == 1) {
3423
        NEON_GET_REG(T0, reg >> 1, reg & 1);
3424
    } else {
3425
        NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
3426
        if (reg & 1)
3427
            gen_op_neon_dup_low16();
3428
        else
3429
            gen_op_neon_dup_high16();
3430
    }
3431
}
3432

    
3433
static void gen_neon_unzip(int reg, int q, int tmp, int size)
3434
{
3435
    int n;
3436

    
3437
    for (n = 0; n < q + 1; n += 2) {
3438
        NEON_GET_REG(T0, reg, n);
3439
        NEON_GET_REG(T0, reg, n + n);
3440
        switch (size) {
3441
        case 0: gen_op_neon_unzip_u8(); break;
3442
        case 1: gen_op_neon_zip_u16(); break; /* zip and unzip are the same.  */
3443
        case 2: /* no-op */; break;
3444
        default: abort();
3445
        }
3446
        gen_neon_movl_scratch_T0(tmp + n);
3447
        gen_neon_movl_scratch_T1(tmp + n + 1);
3448
    }
3449
}
3450

    
3451
static struct {
3452
    int nregs;
3453
    int interleave;
3454
    int spacing;
3455
} neon_ls_element_type[11] = {
3456
    {4, 4, 1},
3457
    {4, 4, 2},
3458
    {4, 1, 1},
3459
    {4, 2, 1},
3460
    {3, 3, 1},
3461
    {3, 3, 2},
3462
    {3, 1, 1},
3463
    {1, 1, 1},
3464
    {2, 2, 1},
3465
    {2, 2, 2},
3466
    {2, 1, 1}
3467
};
3468

    
3469
/* Translate a NEON load/store element instruction.  Return nonzero if the
3470
   instruction is invalid.  */
3471
static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
3472
{
3473
    int rd, rn, rm;
3474
    int op;
3475
    int nregs;
3476
    int interleave;
3477
    int stride;
3478
    int size;
3479
    int reg;
3480
    int pass;
3481
    int load;
3482
    int shift;
3483
    uint32_t mask;
3484
    int n;
3485
    TCGv tmp;
3486

    
3487
    if (!vfp_enabled(env))
3488
      return 1;
3489
    VFP_DREG_D(rd, insn);
3490
    rn = (insn >> 16) & 0xf;
3491
    rm = insn & 0xf;
3492
    load = (insn & (1 << 21)) != 0;
3493
    if ((insn & (1 << 23)) == 0) {
3494
        /* Load store all elements.  */
3495
        op = (insn >> 8) & 0xf;
3496
        size = (insn >> 6) & 3;
3497
        if (op > 10 || size == 3)
3498
            return 1;
3499
        nregs = neon_ls_element_type[op].nregs;
3500
        interleave = neon_ls_element_type[op].interleave;
3501
        gen_movl_T1_reg(s, rn);
3502
        stride = (1 << size) * interleave;
3503
        for (reg = 0; reg < nregs; reg++) {
3504
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3505
                gen_movl_T1_reg(s, rn);
3506
                gen_op_addl_T1_im((1 << size) * reg);
3507
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3508
                gen_movl_T1_reg(s, rn);
3509
                gen_op_addl_T1_im(1 << size);
3510
            }
3511
            for (pass = 0; pass < 2; pass++) {
3512
                if (size == 2) {
3513
                    if (load) {
3514
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3515
                        tcg_gen_mov_i32(cpu_T[0], tmp);
3516
                        dead_tmp(tmp);
3517
                        NEON_SET_REG(T0, rd, pass);
3518
                    } else {
3519
                        NEON_GET_REG(T0, rd, pass);
3520
                        tmp = new_tmp();
3521
                        tcg_gen_mov_i32(tmp, cpu_T[0]);
3522
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3523
                    }
3524
                    gen_op_addl_T1_im(stride);
3525
                } else if (size == 1) {
3526
                    if (load) {
3527
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3528
                        tcg_gen_mov_i32(cpu_T[0], tmp);
3529
                        dead_tmp(tmp);
3530
                        gen_op_addl_T1_im(stride);
3531
                        gen_op_movl_T2_T0();
3532
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3533
                        tcg_gen_mov_i32(cpu_T[0], tmp);
3534
                        dead_tmp(tmp);
3535
                        gen_op_addl_T1_im(stride);
3536
                        gen_op_neon_insert_elt(16, 0xffff);
3537
                        NEON_SET_REG(T2, rd, pass);
3538
                    } else {
3539
                        NEON_GET_REG(T2, rd, pass);
3540
                        gen_op_movl_T0_T2();
3541
                        tmp = new_tmp();
3542
                        tcg_gen_mov_i32(tmp, cpu_T[0]);
3543
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3544
                        gen_op_addl_T1_im(stride);
3545
                        gen_op_neon_extract_elt(16, 0xffff0000);
3546
                        tmp = new_tmp();
3547
                        tcg_gen_mov_i32(tmp, cpu_T[0]);
3548
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3549
                        gen_op_addl_T1_im(stride);
3550
                    }
3551
                } else /* size == 0 */ {
3552
                    if (load) {
3553
                        mask = 0xff;
3554
                        for (n = 0; n < 4; n++) {
3555
                            tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3556
                            tcg_gen_mov_i32(cpu_T[0], tmp);
3557
                            dead_tmp(tmp);
3558
                            gen_op_addl_T1_im(stride);
3559
                            if (n == 0) {
3560
                                gen_op_movl_T2_T0();
3561
                            } else {
3562
                                gen_op_neon_insert_elt(n * 8, ~mask);
3563
                            }
3564
                            mask <<= 8;
3565
                        }
3566
                        NEON_SET_REG(T2, rd, pass);
3567
                    } else {
3568
                        NEON_GET_REG(T2, rd, pass);
3569
                        mask = 0xff;
3570
                        for (n = 0; n < 4; n++) {
3571
                            if (n == 0) {
3572
                                gen_op_movl_T0_T2();
3573
                            } else {
3574
                                gen_op_neon_extract_elt(n * 8, mask);
3575
                            }
3576
                            tmp = new_tmp();
3577
                            tcg_gen_mov_i32(tmp, cpu_T[0]);
3578
                            gen_st8(tmp, cpu_T[1], IS_USER(s));
3579
                            gen_op_addl_T1_im(stride);
3580
                            mask <<= 8;
3581
                        }
3582
                    }
3583
                }
3584
            }
3585
            rd += neon_ls_element_type[op].spacing;
3586
        }
3587
        stride = nregs * 8;
3588
    } else {
3589
        size = (insn >> 10) & 3;
3590
        if (size == 3) {
3591
            /* Load single element to all lanes.  */
3592
            if (!load)
3593
                return 1;
3594
            size = (insn >> 6) & 3;
3595
            nregs = ((insn >> 8) & 3) + 1;
3596
            stride = (insn & (1 << 5)) ? 2 : 1;
3597
            gen_movl_T1_reg(s, rn);
3598
            for (reg = 0; reg < nregs; reg++) {
3599
                switch (size) {
3600
                case 0:
3601
                    tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3602
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3603
                    dead_tmp(tmp);
3604
                    gen_op_neon_dup_u8(0);
3605
                    break;
3606
                case 1:
3607
                    tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3608
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3609
                    dead_tmp(tmp);
3610
                    gen_op_neon_dup_low16();
3611
                    break;
3612
                case 2:
3613
                    tmp = gen_ld32(cpu_T[0], IS_USER(s));
3614
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3615
                    dead_tmp(tmp);
3616
                    break;
3617
                case 3:
3618
                    return 1;
3619
                }
3620
                gen_op_addl_T1_im(1 << size);
3621
                NEON_SET_REG(T0, rd, 0);
3622
                NEON_SET_REG(T0, rd, 1);
3623
                rd += stride;
3624
            }
3625
            stride = (1 << size) * nregs;
3626
        } else {
3627
            /* Single element.  */
3628
            pass = (insn >> 7) & 1;
3629
            switch (size) {
3630
            case 0:
3631
                shift = ((insn >> 5) & 3) * 8;
3632
                mask = 0xff << shift;
3633
                stride = 1;
3634
                break;
3635
            case 1:
3636
                shift = ((insn >> 6) & 1) * 16;
3637
                mask = shift ? 0xffff0000 : 0xffff;
3638
                stride = (insn & (1 << 5)) ? 2 : 1;
3639
                break;
3640
            case 2:
3641
                shift = 0;
3642
                mask = 0xffffffff;
3643
                stride = (insn & (1 << 6)) ? 2 : 1;
3644
                break;
3645
            default:
3646
                abort();
3647
            }
3648
            nregs = ((insn >> 8) & 3) + 1;
3649
            gen_movl_T1_reg(s, rn);
3650
            for (reg = 0; reg < nregs; reg++) {
3651
                if (load) {
3652
                    if (size != 2) {
3653
                        NEON_GET_REG(T2, rd, pass);
3654
                    }
3655
                    switch (size) {
3656
                    case 0:
3657
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3658
                        break;
3659
                    case 1:
3660
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3661
                        break;
3662
                    case 2:
3663
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3664
                        break;
3665
                    }
3666
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3667
                    dead_tmp(tmp);
3668
                    if (size != 2) {
3669
                        gen_op_neon_insert_elt(shift, ~mask);
3670
                        NEON_SET_REG(T0, rd, pass);
3671
                    } else {
3672
                        NEON_SET_REG(T0, rd, pass);
3673
                    }
3674
                } else { /* Store */
3675
                    if (size == 2) {
3676
                        NEON_GET_REG(T0, rd, pass);
3677
                    } else {
3678
                        NEON_GET_REG(T2, rd, pass);
3679
                        gen_op_neon_extract_elt(shift, mask);
3680
                    }
3681
                    tmp = new_tmp();
3682
                    tcg_gen_mov_i32(tmp, cpu_T[0]);
3683
                    switch (size) {
3684
                    case 0:
3685
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
3686
                        break;
3687
                    case 1:
3688
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3689
                        break;
3690
                    case 2:
3691
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3692
                        break;
3693
                    }
3694
                }
3695
                rd += stride;
3696
                gen_op_addl_T1_im(1 << size);
3697
            }
3698
            stride = nregs * (1 << size);
3699
        }
3700
    }
3701
    if (rm != 15) {
3702
        TCGv base;
3703

    
3704
        base = load_reg(s, rn);
3705
        if (rm == 13) {
3706
            tcg_gen_addi_i32(base, base, stride);
3707
        } else {
3708
            TCGv index;
3709
            index = load_reg(s, rm);
3710
            tcg_gen_add_i32(base, base, index);
3711
            dead_tmp(index);
3712
        }
3713
        store_reg(s, rn, base);
3714
    }
3715
    return 0;
3716
}
3717

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

    
3725
static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
3726
{
3727
    int op;
3728
    int q;
3729
    int rd, rn, rm;
3730
    int size;
3731
    int shift;
3732
    int pass;
3733
    int count;
3734
    int pairwise;
3735
    int u;
3736
    int n;
3737
    uint32_t imm;
3738

    
3739
    if (!vfp_enabled(env))
3740
      return 1;
3741
    q = (insn & (1 << 6)) != 0;
3742
    u = (insn >> 24) & 1;
3743
    VFP_DREG_D(rd, insn);
3744
    VFP_DREG_N(rn, insn);
3745
    VFP_DREG_M(rm, insn);
3746
    size = (insn >> 20) & 3;
3747
    if ((insn & (1 << 23)) == 0) {
3748
        /* Three register same length.  */
3749
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
3750
        if (size == 3 && (op == 1 || op == 5 || op == 16)) {
3751
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
3752
                NEON_GET_REG(T0, rm, pass * 2);
3753
                NEON_GET_REG(T1, rm, pass * 2 + 1);
3754
                gen_neon_movl_scratch_T0(0);
3755
                gen_neon_movl_scratch_T1(1);
3756
                NEON_GET_REG(T0, rn, pass * 2);
3757
                NEON_GET_REG(T1, rn, pass * 2 + 1);
3758
                switch (op) {
3759
                case 1: /* VQADD */
3760
                    if (u) {
3761
                        gen_op_neon_addl_saturate_u64();
3762
                    } else {
3763
                        gen_op_neon_addl_saturate_s64();
3764
                    }
3765
                    break;
3766
                case 5: /* VQSUB */
3767
                    if (u) {
3768
                        gen_op_neon_subl_saturate_u64();
3769
                    } else {
3770
                        gen_op_neon_subl_saturate_s64();
3771
                    }
3772
                    break;
3773
                case 16:
3774
                    if (u) {
3775
                        gen_op_neon_subl_u64();
3776
                    } else {
3777
                        gen_op_neon_addl_u64();
3778
                    }
3779
                    break;
3780
                default:
3781
                    abort();
3782
                }
3783
                NEON_SET_REG(T0, rd, pass * 2);
3784
                NEON_SET_REG(T1, rd, pass * 2 + 1);
3785
            }
3786
            return 0;
3787
        }
3788
        switch (op) {
3789
        case 8: /* VSHL */
3790
        case 9: /* VQSHL */
3791
        case 10: /* VRSHL */
3792
        case 11: /* VQSHL */
3793
            /* Shift operations have Rn and Rm reversed.  */
3794
            {
3795
                int tmp;
3796
                tmp = rn;
3797
                rn = rm;
3798
                rm = tmp;
3799
                pairwise = 0;
3800
            }
3801
            break;
3802
        case 20: /* VPMAX */
3803
        case 21: /* VPMIN */
3804
        case 23: /* VPADD */
3805
            pairwise = 1;
3806
            break;
3807
        case 26: /* VPADD (float) */
3808
            pairwise = (u && size < 2);
3809
            break;
3810
        case 30: /* VPMIN/VPMAX (float) */
3811
            pairwise = u;
3812
            break;
3813
        default:
3814
            pairwise = 0;
3815
            break;
3816
        }
3817
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
3818

    
3819
        if (pairwise) {
3820
            /* Pairwise.  */
3821
            if (q)
3822
                n = (pass & 1) * 2;
3823
            else
3824
                n = 0;
3825
            if (pass < q + 1) {
3826
                NEON_GET_REG(T0, rn, n);
3827
                NEON_GET_REG(T1, rn, n + 1);
3828
            } else {
3829
                NEON_GET_REG(T0, rm, n);
3830
                NEON_GET_REG(T1, rm, n + 1);
3831
            }
3832
        } else {
3833
            /* Elementwise.  */
3834
            NEON_GET_REG(T0, rn, pass);
3835
            NEON_GET_REG(T1, rm, pass);
3836
        }
3837
        switch (op) {
3838
        case 0: /* VHADD */
3839
            GEN_NEON_INTEGER_OP(hadd);
3840
            break;
3841
        case 1: /* VQADD */
3842
            switch (size << 1| u) {
3843
            case 0: gen_op_neon_qadd_s8(); break;
3844
            case 1: gen_op_neon_qadd_u8(); break;
3845
            case 2: gen_op_neon_qadd_s16(); break;
3846
            case 3: gen_op_neon_qadd_u16(); break;
3847
            case 4:
3848
                gen_helper_add_saturate(cpu_T[0], cpu_T[0], cpu_T[1]);
3849
                break;
3850
            case 5:
3851
                gen_helper_add_usaturate(cpu_T[0], cpu_T[0], cpu_T[1]);
3852
                break;
3853
            default: abort();
3854
            }
3855
            break;
3856
        case 2: /* VRHADD */
3857
            GEN_NEON_INTEGER_OP(rhadd);
3858
            break;
3859
        case 3: /* Logic ops.  */
3860
            switch ((u << 2) | size) {
3861
            case 0: /* VAND */
3862
                gen_op_andl_T0_T1();
3863
                break;
3864
            case 1: /* BIC */
3865
                gen_op_bicl_T0_T1();
3866
                break;
3867
            case 2: /* VORR */
3868
                gen_op_orl_T0_T1();
3869
                break;
3870
            case 3: /* VORN */
3871
                gen_op_notl_T1();
3872
                gen_op_orl_T0_T1();
3873
                break;
3874
            case 4: /* VEOR */
3875
                gen_op_xorl_T0_T1();
3876
                break;
3877
            case 5: /* VBSL */
3878
                NEON_GET_REG(T2, rd, pass);
3879
                gen_op_neon_bsl();
3880
                break;
3881
            case 6: /* VBIT */
3882
                NEON_GET_REG(T2, rd, pass);
3883
                gen_op_neon_bit();
3884
                break;
3885
            case 7: /* VBIF */
3886
                NEON_GET_REG(T2, rd, pass);
3887
                gen_op_neon_bif();
3888
                break;
3889
            }
3890
            break;
3891
        case 4: /* VHSUB */
3892
            GEN_NEON_INTEGER_OP(hsub);
3893
            break;
3894
        case 5: /* VQSUB */
3895
            switch ((size << 1) | u) {
3896
            case 0: gen_op_neon_qsub_s8(); break;
3897
            case 1: gen_op_neon_qsub_u8(); break;
3898
            case 2: gen_op_neon_qsub_s16(); break;
3899
            case 3: gen_op_neon_qsub_u16(); break;
3900
            case 4:
3901
                gen_helper_sub_saturate(cpu_T[0], cpu_T[0], cpu_T[1]);
3902
                break;
3903
            case 5:
3904
                gen_helper_sub_usaturate(cpu_T[0], cpu_T[0], cpu_T[1]);
3905
                break;
3906
            default: abort();
3907
            }
3908
            break;
3909
        case 6: /* VCGT */
3910
            GEN_NEON_INTEGER_OP(cgt);
3911
            break;
3912
        case 7: /* VCGE */
3913
            GEN_NEON_INTEGER_OP(cge);
3914
            break;
3915
        case 8: /* VSHL */
3916
            switch ((size << 1) | u) {
3917
            case 0: gen_op_neon_shl_s8(); break;
3918
            case 1: gen_op_neon_shl_u8(); break;
3919
            case 2: gen_op_neon_shl_s16(); break;
3920
            case 3: gen_op_neon_shl_u16(); break;
3921
            case 4: gen_op_neon_shl_s32(); break;
3922
            case 5: gen_op_neon_shl_u32(); break;
3923
#if 0
3924
            /* ??? Implementing these is tricky because the vector ops work
3925
               on 32-bit pieces.  */
3926
            case 6: gen_op_neon_shl_s64(); break;
3927
            case 7: gen_op_neon_shl_u64(); break;
3928
#else
3929
            case 6: case 7: cpu_abort(env, "VSHL.64 not implemented");
3930
#endif
3931
            }
3932
            break;
3933
        case 9: /* VQSHL */
3934
            switch ((size << 1) | u) {
3935
            case 0: gen_op_neon_qshl_s8(); break;
3936
            case 1: gen_op_neon_qshl_u8(); break;
3937
            case 2: gen_op_neon_qshl_s16(); break;
3938
            case 3: gen_op_neon_qshl_u16(); break;
3939
            case 4: gen_op_neon_qshl_s32(); break;
3940
            case 5: gen_op_neon_qshl_u32(); break;
3941
#if 0
3942
            /* ??? Implementing these is tricky because the vector ops work
3943
               on 32-bit pieces.  */
3944
            case 6: gen_op_neon_qshl_s64(); break;
3945
            case 7: gen_op_neon_qshl_u64(); break;
3946
#else
3947
            case 6: case 7: cpu_abort(env, "VQSHL.64 not implemented");
3948
#endif
3949
            }
3950
            break;
3951
        case 10: /* VRSHL */
3952
            switch ((size << 1) | u) {
3953
            case 0: gen_op_neon_rshl_s8(); break;
3954
            case 1: gen_op_neon_rshl_u8(); break;
3955
            case 2: gen_op_neon_rshl_s16(); break;
3956
            case 3: gen_op_neon_rshl_u16(); break;
3957
            case 4: gen_op_neon_rshl_s32(); break;
3958
            case 5: gen_op_neon_rshl_u32(); break;
3959
#if 0
3960
            /* ??? Implementing these is tricky because the vector ops work
3961
               on 32-bit pieces.  */
3962
            case 6: gen_op_neon_rshl_s64(); break;
3963
            case 7: gen_op_neon_rshl_u64(); break;
3964
#else
3965
            case 6: case 7: cpu_abort(env, "VRSHL.64 not implemented");
3966
#endif
3967
            }
3968
            break;
3969
        case 11: /* VQRSHL */
3970
            switch ((size << 1) | u) {
3971
            case 0: gen_op_neon_qrshl_s8(); break;
3972
            case 1: gen_op_neon_qrshl_u8(); break;
3973
            case 2: gen_op_neon_qrshl_s16(); break;
3974
            case 3: gen_op_neon_qrshl_u16(); break;
3975
            case 4: gen_op_neon_qrshl_s32(); break;
3976
            case 5: gen_op_neon_qrshl_u32(); break;
3977
#if 0
3978
            /* ??? Implementing these is tricky because the vector ops work
3979
               on 32-bit pieces.  */
3980
            case 6: gen_op_neon_qrshl_s64(); break;
3981
            case 7: gen_op_neon_qrshl_u64(); break;
3982
#else
3983
            case 6: case 7: cpu_abort(env, "VQRSHL.64 not implemented");
3984
#endif
3985
            }
3986
            break;
3987
        case 12: /* VMAX */
3988
            GEN_NEON_INTEGER_OP(max);
3989
            break;
3990
        case 13: /* VMIN */
3991
            GEN_NEON_INTEGER_OP(min);
3992
            break;
3993
        case 14: /* VABD */
3994
            GEN_NEON_INTEGER_OP(abd);
3995
            break;
3996
        case 15: /* VABA */
3997
            GEN_NEON_INTEGER_OP(abd);
3998
            NEON_GET_REG(T1, rd, pass);
3999
            gen_neon_add(size);
4000
            break;
4001
        case 16:
4002
            if (!u) { /* VADD */
4003
                if (gen_neon_add(size))
4004
                    return 1;
4005
            } else { /* VSUB */
4006
                switch (size) {
4007
                case 0: gen_op_neon_sub_u8(); break;
4008
                case 1: gen_op_neon_sub_u16(); break;
4009
                case 2: gen_op_subl_T0_T1(); break;
4010
                default: return 1;
4011
                }
4012
            }
4013
            break;
4014
        case 17:
4015
            if (!u) { /* VTST */
4016
                switch (size) {
4017
                case 0: gen_op_neon_tst_u8(); break;
4018
                case 1: gen_op_neon_tst_u16(); break;
4019
                case 2: gen_op_neon_tst_u32(); break;
4020
                default: return 1;
4021
                }
4022
            } else { /* VCEQ */
4023
                switch (size) {
4024
                case 0: gen_op_neon_ceq_u8(); break;
4025
                case 1: gen_op_neon_ceq_u16(); break;
4026
                case 2: gen_op_neon_ceq_u32(); break;
4027
                default: return 1;
4028
                }
4029
            }
4030
            break;
4031
        case 18: /* Multiply.  */
4032
            switch (size) {
4033
            case 0: gen_op_neon_mul_u8(); break;
4034
            case 1: gen_op_neon_mul_u16(); break;
4035
            case 2: gen_op_mul_T0_T1(); break;
4036
            default: return 1;
4037
            }
4038
            NEON_GET_REG(T1, rd, pass);
4039
            if (u) { /* VMLS */
4040
                switch (size) {
4041
                case 0: gen_op_neon_rsb_u8(); break;
4042
                case 1: gen_op_neon_rsb_u16(); break;
4043
                case 2: gen_op_rsbl_T0_T1(); break;
4044
                default: return 1;
4045
                }
4046
            } else { /* VMLA */
4047
                gen_neon_add(size);
4048
            }
4049
            break;
4050
        case 19: /* VMUL */
4051
            if (u) { /* polynomial */
4052
                gen_op_neon_mul_p8();
4053
            } else { /* Integer */
4054
                switch (size) {
4055
                case 0: gen_op_neon_mul_u8(); break;
4056
                case 1: gen_op_neon_mul_u16(); break;
4057
                case 2: gen_op_mul_T0_T1(); break;
4058
                default: return 1;
4059
                }
4060
            }
4061
            break;
4062
        case 20: /* VPMAX */
4063
            GEN_NEON_INTEGER_OP(pmax);
4064
            break;
4065
        case 21: /* VPMIN */
4066
            GEN_NEON_INTEGER_OP(pmin);
4067
            break;
4068
        case 22: /* Hultiply high.  */
4069
            if (!u) { /* VQDMULH */
4070
                switch (size) {
4071
                case 1: gen_op_neon_qdmulh_s16(); break;
4072
                case 2: gen_op_neon_qdmulh_s32(); break;
4073
                default: return 1;
4074
                }
4075
            } else { /* VQRDHMUL */
4076
                switch (size) {
4077
                case 1: gen_op_neon_qrdmulh_s16(); break;
4078
                case 2: gen_op_neon_qrdmulh_s32(); break;
4079
                default: return 1;
4080
                }
4081
            }
4082
            break;
4083
        case 23: /* VPADD */
4084
            if (u)
4085
                return 1;
4086
            switch (size) {
4087
            case 0: gen_op_neon_padd_u8(); break;
4088
            case 1: gen_op_neon_padd_u16(); break;
4089
            case 2: gen_op_addl_T0_T1(); break;
4090
            default: return 1;
4091
            }
4092
            break;
4093
        case 26: /* Floating point arithnetic.  */
4094
            switch ((u << 2) | size) {
4095
            case 0: /* VADD */
4096
                gen_op_neon_add_f32();
4097
                break;
4098
            case 2: /* VSUB */
4099
                gen_op_neon_sub_f32();
4100
                break;
4101
            case 4: /* VPADD */
4102
                gen_op_neon_add_f32();
4103
                break;
4104
            case 6: /* VABD */
4105
                gen_op_neon_abd_f32();
4106
                break;
4107
            default:
4108
                return 1;
4109
            }
4110
            break;
4111
        case 27: /* Float multiply.  */
4112
            gen_op_neon_mul_f32();
4113
            if (!u) {
4114
                NEON_GET_REG(T1, rd, pass);
4115
                if (size == 0) {
4116
                    gen_op_neon_add_f32();
4117
                } else {
4118
                    gen_op_neon_rsb_f32();
4119
                }
4120
            }
4121
            break;
4122
        case 28: /* Float compare.  */
4123
            if (!u) {
4124
                gen_op_neon_ceq_f32();
4125
            } else {
4126
                if (size == 0)
4127
                    gen_op_neon_cge_f32();
4128
                else
4129
                    gen_op_neon_cgt_f32();
4130
            }
4131
            break;
4132
        case 29: /* Float compare absolute.  */
4133
            if (!u)
4134
                return 1;
4135
            if (size == 0)
4136
                gen_op_neon_acge_f32();
4137
            else
4138
                gen_op_neon_acgt_f32();
4139
            break;
4140
        case 30: /* Float min/max.  */
4141
            if (size == 0)
4142
                gen_op_neon_max_f32();
4143
            else
4144
                gen_op_neon_min_f32();
4145
            break;
4146
        case 31:
4147
            if (size == 0)
4148
                gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4149
            else
4150
                gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
4151
            break;
4152
        default:
4153
            abort();
4154
        }
4155
        /* Save the result.  For elementwise operations we can put it
4156
           straight into the destination register.  For pairwise operations
4157
           we have to be careful to avoid clobbering the source operands.  */
4158
        if (pairwise && rd == rm) {
4159
            gen_neon_movl_scratch_T0(pass);
4160
        } else {
4161
            NEON_SET_REG(T0, rd, pass);
4162
        }
4163

    
4164
        } /* for pass */
4165
        if (pairwise && rd == rm) {
4166
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4167
                gen_neon_movl_T0_scratch(pass);
4168
                NEON_SET_REG(T0, rd, pass);
4169
            }
4170
        }
4171
    } else if (insn & (1 << 4)) {
4172
        if ((insn & 0x00380080) != 0) {
4173
            /* Two registers and shift.  */
4174
            op = (insn >> 8) & 0xf;
4175
            if (insn & (1 << 7)) {
4176
                /* 64-bit shift.   */
4177
                size = 3;
4178
            } else {
4179
                size = 2;
4180
                while ((insn & (1 << (size + 19))) == 0)
4181
                    size--;
4182
            }
4183
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4184
            /* To avoid excessive dumplication of ops we implement shift
4185
               by immediate using the variable shift operations.  */
4186
            if (op < 8) {
4187
                /* Shift by immediate:
4188
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
4189
                /* Right shifts are encoded as N - shift, where N is the
4190
                   element size in bits.  */
4191
                if (op <= 4)
4192
                    shift = shift - (1 << (size + 3));
4193
                else
4194
                    shift++;
4195
                if (size == 3) {
4196
                    count = q + 1;
4197
                } else {
4198
                    count = q ? 4: 2;
4199
                }
4200
                switch (size) {
4201
                case 0:
4202
                    imm = (uint8_t) shift;
4203
                    imm |= imm << 8;
4204
                    imm |= imm << 16;
4205
                    break;
4206
                case 1:
4207
                    imm = (uint16_t) shift;
4208
                    imm |= imm << 16;
4209
                    break;
4210
                case 2:
4211
                case 3:
4212
                    imm = shift;
4213
                    break;
4214
                default:
4215
                    abort();
4216
                }
4217

    
4218
                for (pass = 0; pass < count; pass++) {
4219
                    if (size < 3) {
4220
                        /* Operands in T0 and T1.  */
4221
                        gen_op_movl_T1_im(imm);
4222
                        NEON_GET_REG(T0, rm, pass);
4223
                    } else {
4224
                        /* Operands in {T0, T1} and env->vfp.scratch.  */
4225
                        gen_op_movl_T0_im(imm);
4226
                        gen_neon_movl_scratch_T0(0);
4227
                        gen_op_movl_T0_im((int32_t)imm >> 31);
4228
                        gen_neon_movl_scratch_T0(1);
4229
                        NEON_GET_REG(T0, rm, pass * 2);
4230
                        NEON_GET_REG(T1, rm, pass * 2 + 1);
4231
                    }
4232

    
4233
                    if (gen_neon_shift_im[op][u][size] == NULL)
4234
                        return 1;
4235
                    gen_neon_shift_im[op][u][size]();
4236

    
4237
                    if (op == 1 || op == 3) {
4238
                        /* Accumulate.  */
4239
                        if (size == 3) {
4240
                            gen_neon_movl_scratch_T0(0);
4241
                            gen_neon_movl_scratch_T1(1);
4242
                            NEON_GET_REG(T0, rd, pass * 2);
4243
                            NEON_GET_REG(T1, rd, pass * 2 + 1);
4244
                            gen_op_neon_addl_u64();
4245
                        } else {
4246
                            NEON_GET_REG(T1, rd, pass);
4247
                            gen_neon_add(size);
4248
                        }
4249
                    } else if (op == 4 || (op == 5 && u)) {
4250
                        /* Insert */
4251
                        if (size == 3) {
4252
                            cpu_abort(env, "VS[LR]I.64 not implemented");
4253
                        }
4254
                        switch (size) {
4255
                        case 0:
4256
                            if (op == 4)
4257
                                imm = 0xff >> -shift;
4258
                            else
4259
                                imm = (uint8_t)(0xff << shift);
4260
                            imm |= imm << 8;
4261
                            imm |= imm << 16;
4262
                            break;
4263
                        case 1:
4264
                            if (op == 4)
4265
                                imm = 0xffff >> -shift;
4266
                            else
4267
                                imm = (uint16_t)(0xffff << shift);
4268
                            imm |= imm << 16;
4269
                            break;
4270
                        case 2:
4271
                            if (op == 4)
4272
                                imm = 0xffffffffu >> -shift;
4273
                            else
4274
                                imm = 0xffffffffu << shift;
4275
                            break;
4276
                        default:
4277
                            abort();
4278
                        }
4279
                        NEON_GET_REG(T1, rd, pass);
4280
                        gen_op_movl_T2_im(imm);
4281
                        gen_op_neon_bsl();
4282
                    }
4283
                    if (size == 3) {
4284
                        NEON_SET_REG(T0, rd, pass * 2);
4285
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4286
                    } else {
4287
                        NEON_SET_REG(T0, rd, pass);
4288
                    }
4289
                } /* for pass */
4290
            } else if (op < 10) {
4291
                /* Shift by immedaiate and narrow:
4292
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
4293
                shift = shift - (1 << (size + 3));
4294
                size++;
4295
                if (size == 3) {
4296
                    count = q + 1;
4297
                } else {
4298
                    count = q ? 4: 2;
4299
                }
4300
                switch (size) {
4301
                case 1:
4302
                    imm = (uint16_t) shift;
4303
                    imm |= imm << 16;
4304
                    break;
4305
                case 2:
4306
                case 3:
4307
                    imm = shift;
4308
                    break;
4309
                default:
4310
                    abort();
4311
                }
4312

    
4313
                /* Processing MSB first means we need to do less shuffling at
4314
                   the end.  */
4315
                for (pass =  count - 1; pass >= 0; pass--) {
4316
                    /* Avoid clobbering the second operand before it has been
4317
                       written.  */
4318
                    n = pass;
4319
                    if (rd == rm)
4320
                        n ^= (count - 1);
4321
                    else
4322
                        n = pass;
4323

    
4324
                    if (size < 3) {
4325
                        /* Operands in T0 and T1.  */
4326
                        gen_op_movl_T1_im(imm);
4327
                        NEON_GET_REG(T0, rm, n);
4328
                    } else {
4329
                        /* Operands in {T0, T1} and env->vfp.scratch.  */
4330
                        gen_op_movl_T0_im(imm);
4331
                        gen_neon_movl_scratch_T0(0);
4332
                        gen_op_movl_T0_im((int32_t)imm >> 31);
4333
                        gen_neon_movl_scratch_T0(1);
4334
                        NEON_GET_REG(T0, rm, n * 2);
4335
                        NEON_GET_REG(T0, rm, n * 2 + 1);
4336
                    }
4337

    
4338
                    gen_neon_shift_im_narrow[q][u][size - 1]();
4339

    
4340
                    if (size < 3 && (pass & 1) == 0) {
4341
                        gen_neon_movl_scratch_T0(0);
4342
                    } else {
4343
                        uint32_t offset;
4344

    
4345
                        if (size < 3)
4346
                            gen_neon_movl_T1_scratch(0);
4347

    
4348
                        if (op == 8 && !u) {
4349
                            gen_neon_narrow[size - 1]();
4350
                        } else {
4351
                            if (op == 8)
4352
                                gen_neon_narrow_sats[size - 2]();
4353
                            else
4354
                                gen_neon_narrow_satu[size - 1]();
4355
                        }
4356
                        if (size == 3)
4357
                            offset = neon_reg_offset(rd, n);
4358
                        else
4359
                            offset = neon_reg_offset(rd, n >> 1);
4360
                        gen_op_neon_setreg_T0(offset);
4361
                    }
4362
                } /* for pass */
4363
            } else if (op == 10) {
4364
                /* VSHLL */
4365
                if (q)
4366
                    return 1;
4367
                for (pass = 0; pass < 2; pass++) {
4368
                    /* Avoid clobbering the input operand.  */
4369
                    if (rd == rm)
4370
                        n = 1 - pass;
4371
                    else
4372
                        n = pass;
4373

    
4374
                    NEON_GET_REG(T0, rm, n);
4375
                    GEN_NEON_INTEGER_OP(widen);
4376
                    if (shift != 0) {
4377
                        /* The shift is less than the width of the source
4378
                           type, so in some cases we can just
4379
                           shift the whole register.  */
4380
                        if (size == 1 || (size == 0 && u)) {
4381
                            gen_op_shll_T0_im(shift);
4382
                            gen_op_shll_T1_im(shift);
4383
                        } else {
4384
                            switch (size) {
4385
                            case 0: gen_op_neon_shll_u16(shift); break;
4386
                            case 2: gen_op_neon_shll_u64(shift); break;
4387
                            default: abort();
4388
                            }
4389
                        }
4390
                    }
4391
                    NEON_SET_REG(T0, rd, n * 2);
4392
                    NEON_SET_REG(T1, rd, n * 2 + 1);
4393
                }
4394
            } else if (op == 15 || op == 16) {
4395
                /* VCVT fixed-point.  */
4396
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
4397
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
4398
                    if (op & 1) {
4399
                        if (u)
4400
                            gen_vfp_ulto(0, shift);
4401
                        else
4402
                            gen_vfp_slto(0, shift);
4403
                    } else {
4404
                        if (u)
4405
                            gen_vfp_toul(0, shift);
4406
                        else
4407
                            gen_vfp_tosl(0, shift);
4408
                    }
4409
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
4410
                }
4411
            } else {
4412
                return 1;
4413
            }
4414
        } else { /* (insn & 0x00380080) == 0 */
4415
            int invert;
4416

    
4417
            op = (insn >> 8) & 0xf;
4418
            /* One register and immediate.  */
4419
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
4420
            invert = (insn & (1 << 5)) != 0;
4421
            switch (op) {
4422
            case 0: case 1:
4423
                /* no-op */
4424
                break;
4425
            case 2: case 3:
4426
                imm <<= 8;
4427
                break;
4428
            case 4: case 5:
4429
                imm <<= 16;
4430
                break;
4431
            case 6: case 7:
4432
                imm <<= 24;
4433
                break;
4434
            case 8: case 9:
4435
                imm |= imm << 16;
4436
                break;
4437
            case 10: case 11:
4438
                imm = (imm << 8) | (imm << 24);
4439
                break;
4440
            case 12:
4441
                imm = (imm < 8) | 0xff;
4442
                break;
4443
            case 13:
4444
                imm = (imm << 16) | 0xffff;
4445
                break;
4446
            case 14:
4447
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
4448
                if (invert)
4449
                    imm = ~imm;
4450
                break;
4451
            case 15:
4452
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
4453
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
4454
                break;
4455
            }
4456
            if (invert)
4457
                imm = ~imm;
4458

    
4459
            if (op != 14 || !invert)
4460
                gen_op_movl_T1_im(imm);
4461

    
4462
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4463
                if (op & 1 && op < 12) {
4464
                    NEON_GET_REG(T0, rd, pass);
4465
                    if (invert) {
4466
                        /* The immediate value has already been inverted, so
4467
                           BIC becomes AND.  */
4468
                        gen_op_andl_T0_T1();
4469
                    } else {
4470
                        gen_op_orl_T0_T1();
4471
                    }
4472
                    NEON_SET_REG(T0, rd, pass);
4473
                } else {
4474
                    if (op == 14 && invert) {
4475
                        uint32_t tmp;
4476
                        tmp = 0;
4477
                        for (n = 0; n < 4; n++) {
4478
                            if (imm & (1 << (n + (pass & 1) * 4)))
4479
                                tmp |= 0xff << (n * 8);
4480
                        }
4481
                        gen_op_movl_T1_im(tmp);
4482
                    }
4483
                    /* VMOV, VMVN.  */
4484
                    NEON_SET_REG(T1, rd, pass);
4485
                }
4486
            }
4487
        }
4488
    } else { /* (insn & 0x00800010 == 0x00800010) */
4489
        if (size != 3) {
4490
            op = (insn >> 8) & 0xf;
4491
            if ((insn & (1 << 6)) == 0) {
4492
                /* Three registers of different lengths.  */
4493
                int src1_wide;
4494
                int src2_wide;
4495
                int prewiden;
4496
                /* prewiden, src1_wide, src2_wide */
4497
                static const int neon_3reg_wide[16][3] = {
4498
                    {1, 0, 0}, /* VADDL */
4499
                    {1, 1, 0}, /* VADDW */
4500
                    {1, 0, 0}, /* VSUBL */
4501
                    {1, 1, 0}, /* VSUBW */
4502
                    {0, 1, 1}, /* VADDHN */
4503
                    {0, 0, 0}, /* VABAL */
4504
                    {0, 1, 1}, /* VSUBHN */
4505
                    {0, 0, 0}, /* VABDL */
4506
                    {0, 0, 0}, /* VMLAL */
4507
                    {0, 0, 0}, /* VQDMLAL */
4508
                    {0, 0, 0}, /* VMLSL */
4509
                    {0, 0, 0}, /* VQDMLSL */
4510
                    {0, 0, 0}, /* Integer VMULL */
4511
                    {0, 0, 0}, /* VQDMULL */
4512
                    {0, 0, 0}  /* Polynomial VMULL */
4513
                };
4514

    
4515
                prewiden = neon_3reg_wide[op][0];
4516
                src1_wide = neon_3reg_wide[op][1];
4517
                src2_wide = neon_3reg_wide[op][2];
4518

    
4519
                /* Avoid overlapping operands.  Wide source operands are
4520
                   always aligned so will never overlap with wide
4521
                   destinations in problematic ways.  */
4522
                if (rd == rm) {
4523
                    NEON_GET_REG(T2, rm, 1);
4524
                } else if (rd == rn) {
4525
                    NEON_GET_REG(T2, rn, 1);
4526
                }
4527
                for (pass = 0; pass < 2; pass++) {
4528
                    /* Load the second operand into env->vfp.scratch.
4529
                       Also widen narrow operands.  */
4530
                    if (pass == 1 && rd == rm) {
4531
                        if (prewiden) {
4532
                            gen_op_movl_T0_T2();
4533
                        } else {
4534
                            gen_op_movl_T1_T2();
4535
                        }
4536
                    } else {
4537
                        if (src2_wide) {
4538
                            NEON_GET_REG(T0, rm, pass * 2);
4539
                            NEON_GET_REG(T1, rm, pass * 2 + 1);
4540
                        } else {
4541
                            if (prewiden) {
4542
                                NEON_GET_REG(T0, rm, pass);
4543
                            } else {
4544
                                NEON_GET_REG(T1, rm, pass);
4545
                            }
4546
                        }
4547
                    }
4548
                    if (prewiden && !src2_wide) {
4549
                        GEN_NEON_INTEGER_OP(widen);
4550
                    }
4551
                    if (prewiden || src2_wide) {
4552
                        gen_neon_movl_scratch_T0(0);
4553
                        gen_neon_movl_scratch_T1(1);
4554
                    }
4555

    
4556
                    /* Load the first operand.  */
4557
                    if (pass == 1 && rd == rn) {
4558
                        gen_op_movl_T0_T2();
4559
                    } else {
4560
                        if (src1_wide) {
4561
                            NEON_GET_REG(T0, rn, pass * 2);
4562
                            NEON_GET_REG(T1, rn, pass * 2 + 1);
4563
                        } else {
4564
                            NEON_GET_REG(T0, rn, pass);
4565
                        }
4566
                    }
4567
                    if (prewiden && !src1_wide) {
4568
                        GEN_NEON_INTEGER_OP(widen);
4569
                    }
4570
                    switch (op) {
4571
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
4572
                        switch (size) {
4573
                        case 0: gen_op_neon_addl_u16(); break;
4574
                        case 1: gen_op_neon_addl_u32(); break;
4575
                        case 2: gen_op_neon_addl_u64(); break;
4576
                        default: abort();
4577
                        }
4578
                        break;
4579
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
4580
                        switch (size) {
4581
                        case 0: gen_op_neon_subl_u16(); break;
4582
                        case 1: gen_op_neon_subl_u32(); break;
4583
                        case 2: gen_op_neon_subl_u64(); break;
4584
                        default: abort();
4585
                        }
4586
                        break;
4587
                    case 5: case 7: /* VABAL, VABDL */
4588
                        switch ((size << 1) | u) {
4589
                        case 0: gen_op_neon_abdl_s16(); break;
4590
                        case 1: gen_op_neon_abdl_u16(); break;
4591
                        case 2: gen_op_neon_abdl_s32(); break;
4592
                        case 3: gen_op_neon_abdl_u32(); break;
4593
                        case 4: gen_op_neon_abdl_s64(); break;
4594
                        case 5: gen_op_neon_abdl_u64(); break;
4595
                        default: abort();
4596
                        }
4597
                        break;
4598
                    case 8: case 9: case 10: case 11: case 12: case 13:
4599
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
4600
                        switch ((size << 1) | u) {
4601
                        case 0: gen_op_neon_mull_s8(); break;
4602
                        case 1: gen_op_neon_mull_u8(); break;
4603
                        case 2: gen_op_neon_mull_s16(); break;
4604
                        case 3: gen_op_neon_mull_u16(); break;
4605
                        case 4: gen_op_imull_T0_T1(); break;
4606
                        case 5: gen_op_mull_T0_T1(); break;
4607
                        default: abort();
4608
                        }
4609
                        break;
4610
                    case 14: /* Polynomial VMULL */
4611
                        cpu_abort(env, "Polynomial VMULL not implemented");
4612

    
4613
                    default: /* 15 is RESERVED.  */
4614
                        return 1;
4615
                    }
4616
                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
4617
                        /* Accumulate.  */
4618
                        if (op == 10 || op == 11) {
4619
                            switch (size) {
4620
                            case 0: gen_op_neon_negl_u16(); break;
4621
                            case 1: gen_op_neon_negl_u32(); break;
4622
                            case 2: gen_op_neon_negl_u64(); break;
4623
                            default: abort();
4624
                            }
4625
                        }
4626

    
4627
                        gen_neon_movl_scratch_T0(0);
4628
                        gen_neon_movl_scratch_T1(1);
4629

    
4630
                        if (op != 13) {
4631
                            NEON_GET_REG(T0, rd, pass * 2);
4632
                            NEON_GET_REG(T1, rd, pass * 2 + 1);
4633
                        }
4634

    
4635
                        switch (op) {
4636
                        case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
4637
                            switch (size) {
4638
                            case 0: gen_op_neon_addl_u16(); break;
4639
                            case 1: gen_op_neon_addl_u32(); break;
4640
                            case 2: gen_op_neon_addl_u64(); break;
4641
                            default: abort();
4642
                            }
4643
                            break;
4644
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
4645
                            switch (size) {
4646
                            case 1: gen_op_neon_addl_saturate_s32(); break;
4647
                            case 2: gen_op_neon_addl_saturate_s64(); break;
4648
                            default: abort();
4649
                            }
4650
                            /* Fall through.  */
4651
                        case 13: /* VQDMULL */
4652
                            switch (size) {
4653
                            case 1: gen_op_neon_addl_saturate_s32(); break;
4654
                            case 2: gen_op_neon_addl_saturate_s64(); break;
4655
                            default: abort();
4656
                            }
4657
                            break;
4658
                        default:
4659
                            abort();
4660
                        }
4661
                        NEON_SET_REG(T0, rd, pass * 2);
4662
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4663
                    } else if (op == 4 || op == 6) {
4664
                        /* Narrowing operation.  */
4665
                        if (u) {
4666
                            switch (size) {
4667
                            case 0: gen_op_neon_narrow_high_u8(); break;
4668
                            case 1: gen_op_neon_narrow_high_u16(); break;
4669
                            case 2: gen_op_movl_T0_T1(); break;
4670
                            default: abort();
4671
                            }
4672
                        } else {
4673
                            switch (size) {
4674
                            case 0: gen_op_neon_narrow_high_round_u8(); break;
4675
                            case 1: gen_op_neon_narrow_high_round_u16(); break;
4676
                            case 2: gen_op_neon_narrow_high_round_u32(); break;
4677
                            default: abort();
4678
                            }
4679
                        }
4680
                        NEON_SET_REG(T0, rd, pass);
4681
                    } else {
4682
                        /* Write back the result.  */
4683
                        NEON_SET_REG(T0, rd, pass * 2);
4684
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4685
                    }
4686
                }
4687
            } else {
4688
                /* Two registers and a scalar.  */
4689
                switch (op) {
4690
                case 0: /* Integer VMLA scalar */
4691
                case 1: /* Float VMLA scalar */
4692
                case 4: /* Integer VMLS scalar */
4693
                case 5: /* Floating point VMLS scalar */
4694
                case 8: /* Integer VMUL scalar */
4695
                case 9: /* Floating point VMUL scalar */
4696
                case 12: /* VQDMULH scalar */
4697
                case 13: /* VQRDMULH scalar */
4698
                    gen_neon_get_scalar(size, rm);
4699
                    gen_op_movl_T2_T0();
4700
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
4701
                        if (pass != 0)
4702
                            gen_op_movl_T0_T2();
4703
                        NEON_GET_REG(T1, rn, pass);
4704
                        if (op == 12) {
4705
                            if (size == 1) {
4706
                                gen_op_neon_qdmulh_s16();
4707
                            } else {
4708
                                gen_op_neon_qdmulh_s32();
4709
                            }
4710
                        } else if (op == 13) {
4711
                            if (size == 1) {
4712
                                gen_op_neon_qrdmulh_s16();
4713
                            } else {
4714
                                gen_op_neon_qrdmulh_s32();
4715
                            }
4716
                        } else if (op & 1) {
4717
                            gen_op_neon_mul_f32();
4718
                        } else {
4719
                            switch (size) {
4720
                            case 0: gen_op_neon_mul_u8(); break;
4721
                            case 1: gen_op_neon_mul_u16(); break;
4722
                            case 2: gen_op_mul_T0_T1(); break;
4723
                            default: return 1;
4724
                            }
4725
                        }
4726
                        if (op < 8) {
4727
                            /* Accumulate.  */
4728
                            NEON_GET_REG(T1, rd, pass);
4729
                            switch (op) {
4730
                            case 0:
4731
                                gen_neon_add(size);
4732
                                break;
4733
                            case 1:
4734
                                gen_op_neon_add_f32();
4735
                                break;
4736
                            case 4:
4737
                                switch (size) {
4738
                                case 0: gen_op_neon_rsb_u8(); break;
4739
                                case 1: gen_op_neon_rsb_u16(); break;
4740
                                case 2: gen_op_rsbl_T0_T1(); break;
4741
                                default: return 1;
4742
                                }
4743
                                break;
4744
                            case 5:
4745
                                gen_op_neon_rsb_f32();
4746
                                break;
4747
                            default:
4748
                                abort();
4749
                            }
4750
                        }
4751
                        NEON_SET_REG(T0, rd, pass);
4752
                    }
4753
                    break;
4754
                case 2: /* VMLAL sclar */
4755
                case 3: /* VQDMLAL scalar */
4756
                case 6: /* VMLSL scalar */
4757
                case 7: /* VQDMLSL scalar */
4758
                case 10: /* VMULL scalar */
4759
                case 11: /* VQDMULL scalar */
4760
                    if (rd == rn) {
4761
                        /* Save overlapping operands before they are
4762
                           clobbered.  */
4763
                        NEON_GET_REG(T0, rn, 1);
4764
                        gen_neon_movl_scratch_T0(2);
4765
                    }
4766
                    gen_neon_get_scalar(size, rm);
4767
                    gen_op_movl_T2_T0();
4768
                    for (pass = 0; pass < 2; pass++) {
4769
                        if (pass != 0) {
4770
                            gen_op_movl_T0_T2();
4771
                        }
4772
                        if (pass != 0 && rd == rn) {
4773
                            gen_neon_movl_T1_scratch(2);
4774
                        } else {
4775
                            NEON_GET_REG(T1, rn, pass);
4776
                        }
4777
                        switch ((size << 1) | u) {
4778
                        case 0: gen_op_neon_mull_s8(); break;
4779
                        case 1: gen_op_neon_mull_u8(); break;
4780
                        case 2: gen_op_neon_mull_s16(); break;
4781
                        case 3: gen_op_neon_mull_u16(); break;
4782
                        case 4: gen_op_imull_T0_T1(); break;
4783
                        case 5: gen_op_mull_T0_T1(); break;
4784
                        default: abort();
4785
                        }
4786
                        if (op == 6 || op == 7) {
4787
                            switch (size) {
4788
                            case 0: gen_op_neon_negl_u16(); break;
4789
                            case 1: gen_op_neon_negl_u32(); break;
4790
                            case 2: gen_op_neon_negl_u64(); break;
4791
                            default: abort();
4792
                            }
4793
                        }
4794
                        gen_neon_movl_scratch_T0(0);
4795
                        gen_neon_movl_scratch_T1(1);
4796
                        NEON_GET_REG(T0, rd, pass * 2);
4797
                        NEON_GET_REG(T1, rd, pass * 2 + 1);
4798
                        switch (op) {
4799
                        case 2: case 6:
4800
                            switch (size) {
4801
                            case 0: gen_op_neon_addl_u16(); break;
4802
                            case 1: gen_op_neon_addl_u32(); break;
4803
                            case 2: gen_op_neon_addl_u64(); break;
4804
                            default: abort();
4805
                            }
4806
                            break;
4807
                        case 3: case 7:
4808
                            switch (size) {
4809
                            case 1:
4810
                                gen_op_neon_addl_saturate_s32();
4811
                                gen_op_neon_addl_saturate_s32();
4812
                                break;
4813
                            case 2:
4814
                                gen_op_neon_addl_saturate_s64();
4815
                                gen_op_neon_addl_saturate_s64();
4816
                                break;
4817
                            default: abort();
4818
                            }
4819
                            break;
4820
                        case 10:
4821
                            /* no-op */
4822
                            break;
4823
                        case 11:
4824
                            switch (size) {
4825
                            case 1: gen_op_neon_addl_saturate_s32(); break;
4826
                            case 2: gen_op_neon_addl_saturate_s64(); break;
4827
                            default: abort();
4828
                            }
4829
                            break;
4830
                        default:
4831
                            abort();
4832
                        }
4833
                        NEON_SET_REG(T0, rd, pass * 2);
4834
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4835
                    }
4836
                    break;
4837
                default: /* 14 and 15 are RESERVED */
4838
                    return 1;
4839
                }
4840
            }
4841
        } else { /* size == 3 */
4842
            if (!u) {
4843
                /* Extract.  */
4844
                int reg;
4845
                imm = (insn >> 8) & 0xf;
4846
                reg = rn;
4847
                count = q ? 4 : 2;
4848
                n = imm >> 2;
4849
                NEON_GET_REG(T0, reg, n);
4850
                for (pass = 0; pass < count; pass++) {
4851
                    n++;
4852
                    if (n > count) {
4853
                        reg = rm;
4854
                        n -= count;
4855
                    }
4856
                    if (imm & 3) {
4857
                        NEON_GET_REG(T1, reg, n);
4858
                        gen_op_neon_extract((insn << 3) & 0x1f);
4859
                    }
4860
                    /* ??? This is broken if rd and rm overlap */
4861
                    NEON_SET_REG(T0, rd, pass);
4862
                    if (imm & 3) {
4863
                        gen_op_movl_T0_T1();
4864
                    } else {
4865
                        NEON_GET_REG(T0, reg, n);
4866
                    }
4867
                }
4868
            } else if ((insn & (1 << 11)) == 0) {
4869
                /* Two register misc.  */
4870
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
4871
                size = (insn >> 18) & 3;
4872
                switch (op) {
4873
                case 0: /* VREV64 */
4874
                    if (size == 3)
4875
                        return 1;
4876
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
4877
                        NEON_GET_REG(T0, rm, pass * 2);
4878
                        NEON_GET_REG(T1, rm, pass * 2 + 1);
4879
                        switch (size) {
4880
                        case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4881
                        case 1: gen_swap_half(cpu_T[0]); break;
4882
                        case 2: /* no-op */ break;
4883
                        default: abort();
4884
                        }
4885
                        NEON_SET_REG(T0, rd, pass * 2 + 1);
4886
                        if (size == 2) {
4887
                            NEON_SET_REG(T1, rd, pass * 2);
4888
                        } else {
4889
                            gen_op_movl_T0_T1();
4890
                            switch (size) {
4891
                            case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4892
                            case 1: gen_swap_half(cpu_T[0]); break;
4893
                            default: abort();
4894
                            }
4895
                            NEON_SET_REG(T0, rd, pass * 2);
4896
                        }
4897
                    }
4898
                    break;
4899
                case 4: case 5: /* VPADDL */
4900
                case 12: case 13: /* VPADAL */
4901
                    if (size < 2)
4902
                        goto elementwise;
4903
                    if (size == 3)
4904
                        return 1;
4905
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
4906
                        NEON_GET_REG(T0, rm, pass * 2);
4907
                        NEON_GET_REG(T1, rm, pass * 2 + 1);
4908
                        if (op & 1)
4909
                            gen_op_neon_paddl_u32();
4910
                        else
4911
                            gen_op_neon_paddl_s32();
4912
                        if (op >= 12) {
4913
                            /* Accumulate.  */
4914
                            gen_neon_movl_scratch_T0(0);
4915
                            gen_neon_movl_scratch_T1(1);
4916

    
4917
                            NEON_GET_REG(T0, rd, pass * 2);
4918
                            NEON_GET_REG(T1, rd, pass * 2 + 1);
4919
                            gen_op_neon_addl_u64();
4920
                        }
4921
                        NEON_SET_REG(T0, rd, pass * 2);
4922
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
4923
                    }
4924
                    break;
4925
                case 33: /* VTRN */
4926
                    if (size == 2) {
4927
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
4928
                            NEON_GET_REG(T0, rm, n);
4929
                            NEON_GET_REG(T1, rd, n + 1);
4930
                            NEON_SET_REG(T1, rm, n);
4931
                            NEON_SET_REG(T0, rd, n + 1);
4932
                        }
4933
                    } else {
4934
                        goto elementwise;
4935
                    }
4936
                    break;
4937
                case 34: /* VUZP */
4938
                    /* Reg  Before       After
4939
                       Rd   A3 A2 A1 A0  B2 B0 A2 A0
4940
                       Rm   B3 B2 B1 B0  B3 B1 A3 A1
4941
                     */
4942
                    if (size == 3)
4943
                        return 1;
4944
                    gen_neon_unzip(rd, q, 0, size);
4945
                    gen_neon_unzip(rm, q, 4, size);
4946
                    if (q) {
4947
                        static int unzip_order_q[8] =
4948
                            {0, 2, 4, 6, 1, 3, 5, 7};
4949
                        for (n = 0; n < 8; n++) {
4950
                            int reg = (n < 4) ? rd : rm;
4951
                            gen_neon_movl_T0_scratch(unzip_order_q[n]);
4952
                            NEON_SET_REG(T0, reg, n % 4);
4953
                        }
4954
                    } else {
4955
                        static int unzip_order[4] =
4956
                            {0, 4, 1, 5};
4957
                        for (n = 0; n < 4; n++) {
4958
                            int reg = (n < 2) ? rd : rm;
4959
                            gen_neon_movl_T0_scratch(unzip_order[n]);
4960
                            NEON_SET_REG(T0, reg, n % 2);
4961
                        }
4962
                    }
4963
                    break;
4964
                case 35: /* VZIP */
4965
                    /* Reg  Before       After
4966
                       Rd   A3 A2 A1 A0  B1 A1 B0 A0
4967
                       Rm   B3 B2 B1 B0  B3 A3 B2 A2
4968
                     */
4969
                    if (size == 3)
4970
                        return 1;
4971
                    count = (q ? 4 : 2);
4972
                    for (n = 0; n < count; n++) {
4973
                        NEON_GET_REG(T0, rd, n);
4974
                        NEON_GET_REG(T1, rd, n);
4975
                        switch (size) {
4976
                        case 0: gen_op_neon_zip_u8(); break;
4977
                        case 1: gen_op_neon_zip_u16(); break;
4978
                        case 2: /* no-op */; break;
4979
                        default: abort();
4980
                        }
4981
                        gen_neon_movl_scratch_T0(n * 2);
4982
                        gen_neon_movl_scratch_T1(n * 2 + 1);
4983
                    }
4984
                    for (n = 0; n < count * 2; n++) {
4985
                        int reg = (n < count) ? rd : rm;
4986
                        gen_neon_movl_T0_scratch(n);
4987
                        NEON_SET_REG(T0, reg, n % count);
4988
                    }
4989
                    break;
4990
                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
4991
                    for (pass = 0; pass < 2; pass++) {
4992
                        if (rd == rm + 1) {
4993
                            n = 1 - pass;
4994
                        } else {
4995
                            n = pass;
4996
                        }
4997
                        NEON_GET_REG(T0, rm, n * 2);
4998
                        NEON_GET_REG(T1, rm, n * 2 + 1);
4999
                        if (op == 36 && q == 0) {
5000
                            switch (size) {
5001
                            case 0: gen_op_neon_narrow_u8(); break;
5002
                            case 1: gen_op_neon_narrow_u16(); break;
5003
                            case 2: /* no-op */ break;
5004
                            default: return 1;
5005
                            }
5006
                        } else if (q) {
5007
                            switch (size) {
5008
                            case 0: gen_op_neon_narrow_sat_u8(); break;
5009
                            case 1: gen_op_neon_narrow_sat_u16(); break;
5010
                            case 2: gen_op_neon_narrow_sat_u32(); break;
5011
                            default: return 1;
5012
                            }
5013
                        } else {
5014
                            switch (size) {
5015
                            case 0: gen_op_neon_narrow_sat_s8(); break;
5016
                            case 1: gen_op_neon_narrow_sat_s16(); break;
5017
                            case 2: gen_op_neon_narrow_sat_s32(); break;
5018
                            default: return 1;
5019
                            }
5020
                        }
5021
                        NEON_SET_REG(T0, rd, n);
5022
                    }
5023
                    break;
5024
                case 38: /* VSHLL */
5025
                    if (q)
5026
                        return 1;
5027
                    if (rm == rd) {
5028
                        NEON_GET_REG(T2, rm, 1);
5029
                    }
5030
                    for (pass = 0; pass < 2; pass++) {
5031
                        if (pass == 1 && rm == rd) {
5032
                            gen_op_movl_T0_T2();
5033
                        } else {
5034
                            NEON_GET_REG(T0, rm, pass);
5035
                        }
5036
                        switch (size) {
5037
                        case 0: gen_op_neon_widen_high_u8(); break;
5038
                        case 1: gen_op_neon_widen_high_u16(); break;
5039
                        case 2:
5040
                            gen_op_movl_T1_T0();
5041
                            gen_op_movl_T0_im(0);
5042
                            break;
5043
                        default: return 1;
5044
                        }
5045
                        NEON_SET_REG(T0, rd, pass * 2);
5046
                        NEON_SET_REG(T1, rd, pass * 2 + 1);
5047
                    }
5048
                    break;
5049
                default:
5050
                elementwise:
5051
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
5052
                        if (op == 30 || op == 31 || op >= 58) {
5053
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
5054
                                           neon_reg_offset(rm, pass));
5055
                        } else {
5056
                            NEON_GET_REG(T0, rm, pass);
5057
                        }
5058
                        switch (op) {
5059
                        case 1: /* VREV32 */
5060
                            switch (size) {
5061
                            case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
5062
                            case 1: gen_swap_half(cpu_T[0]); break;
5063
                            default: return 1;
5064
                            }
5065
                            break;
5066
                        case 2: /* VREV16 */
5067
                            if (size != 0)
5068
                                return 1;
5069
                            gen_rev16(cpu_T[0]);
5070
                            break;
5071
                        case 4: case 5: /* VPADDL */
5072
                        case 12: case 13: /* VPADAL */
5073
                            switch ((size << 1) | (op & 1)) {
5074
                            case 0: gen_op_neon_paddl_s8(); break;
5075
                            case 1: gen_op_neon_paddl_u8(); break;
5076
                            case 2: gen_op_neon_paddl_s16(); break;
5077
                            case 3: gen_op_neon_paddl_u16(); break;
5078
                            default: abort();
5079
                            }
5080
                            if (op >= 12) {
5081
                                /* Accumulate */
5082
                                NEON_GET_REG(T1, rd, pass);
5083
                                switch (size) {
5084
                                case 0: gen_op_neon_add_u16(); break;
5085
                                case 1: gen_op_addl_T0_T1(); break;
5086
                                default: abort();
5087
                                }
5088
                            }
5089
                            break;
5090
                        case 8: /* CLS */
5091
                            switch (size) {
5092
                            case 0: gen_op_neon_cls_s8(); break;
5093
                            case 1: gen_op_neon_cls_s16(); break;
5094
                            case 2: gen_op_neon_cls_s32(); break;
5095
                            default: return 1;
5096
                            }
5097
                            break;
5098
                        case 9: /* CLZ */
5099
                            switch (size) {
5100
                            case 0: gen_op_neon_clz_u8(); break;
5101
                            case 1: gen_op_neon_clz_u16(); break;
5102
                            case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
5103
                            default: return 1;
5104
                            }
5105
                            break;
5106
                        case 10: /* CNT */
5107
                            if (size != 0)
5108
                                return 1;
5109
                            gen_op_neon_cnt_u8();
5110
                            break;
5111
                        case 11: /* VNOT */
5112
                            if (size != 0)
5113
                                return 1;
5114
                            gen_op_notl_T0();
5115
                            break;
5116
                        case 14: /* VQABS */
5117
                            switch (size) {
5118
                            case 0: gen_op_neon_qabs_s8(); break;
5119
                            case 1: gen_op_neon_qabs_s16(); break;
5120
                            case 2: gen_op_neon_qabs_s32(); break;
5121
                            default: return 1;
5122
                            }
5123
                            break;
5124
                        case 15: /* VQNEG */
5125
                            switch (size) {
5126
                            case 0: gen_op_neon_qneg_s8(); break;
5127
                            case 1: gen_op_neon_qneg_s16(); break;
5128
                            case 2: gen_op_neon_qneg_s32(); break;
5129
                            default: return 1;
5130
                            }
5131
                            break;
5132
                        case 16: case 19: /* VCGT #0, VCLE #0 */
5133
                            gen_op_movl_T1_im(0);
5134
                            switch(size) {
5135
                            case 0: gen_op_neon_cgt_s8(); break;
5136
                            case 1: gen_op_neon_cgt_s16(); break;
5137
                            case 2: gen_op_neon_cgt_s32(); break;
5138
                            default: return 1;
5139
                            }
5140
                            if (op == 19)
5141
                                gen_op_notl_T0();
5142
                            break;
5143
                        case 17: case 20: /* VCGE #0, VCLT #0 */
5144
                            gen_op_movl_T1_im(0);
5145
                            switch(size) {
5146
                            case 0: gen_op_neon_cge_s8(); break;
5147
                            case 1: gen_op_neon_cge_s16(); break;
5148
                            case 2: gen_op_neon_cge_s32(); break;
5149
                            default: return 1;
5150
                            }
5151
                            if (op == 20)
5152
                                gen_op_notl_T0();
5153
                            break;
5154
                        case 18: /* VCEQ #0 */
5155
                            gen_op_movl_T1_im(0);
5156
                            switch(size) {
5157
                            case 0: gen_op_neon_ceq_u8(); break;
5158
                            case 1: gen_op_neon_ceq_u16(); break;
5159
                            case 2: gen_op_neon_ceq_u32(); break;
5160
                            default: return 1;
5161
                            }
5162
                            break;
5163
                        case 22: /* VABS */
5164
                            switch(size) {
5165
                            case 0: gen_op_neon_abs_s8(); break;
5166
                            case 1: gen_op_neon_abs_s16(); break;
5167
                            case 2: gen_op_neon_abs_s32(); break;
5168
                            default: return 1;
5169
                            }
5170
                            break;
5171
                        case 23: /* VNEG */
5172
                            gen_op_movl_T1_im(0);
5173
                            switch(size) {
5174
                            case 0: gen_op_neon_rsb_u8(); break;
5175
                            case 1: gen_op_neon_rsb_u16(); break;
5176
                            case 2: gen_op_rsbl_T0_T1(); break;
5177
                            default: return 1;
5178
                            }
5179
                            break;
5180
                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
5181
                            gen_op_movl_T1_im(0);
5182
                            gen_op_neon_cgt_f32();
5183
                            if (op == 27)
5184
                                gen_op_notl_T0();
5185
                            break;
5186
                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
5187
                            gen_op_movl_T1_im(0);
5188
                            gen_op_neon_cge_f32();
5189
                            if (op == 28)
5190
                                gen_op_notl_T0();
5191
                            break;
5192
                        case 26: /* Float VCEQ #0 */
5193
                            gen_op_movl_T1_im(0);
5194
                            gen_op_neon_ceq_f32();
5195
                            break;
5196
                        case 30: /* Float VABS */
5197
                            gen_vfp_abs(0);
5198
                            break;
5199
                        case 31: /* Float VNEG */
5200
                            gen_vfp_neg(0);
5201
                            break;
5202
                        case 32: /* VSWP */
5203
                            NEON_GET_REG(T1, rd, pass);
5204
                            NEON_SET_REG(T1, rm, pass);
5205
                            break;
5206
                        case 33: /* VTRN */
5207
                            NEON_GET_REG(T1, rd, pass);
5208
                            switch (size) {
5209
                            case 0: gen_op_neon_trn_u8(); break;
5210
                            case 1: gen_op_neon_trn_u16(); break;
5211
                            case 2: abort();
5212
                            default: return 1;
5213
                            }
5214
                            NEON_SET_REG(T1, rm, pass);
5215
                            break;
5216
                        case 56: /* Integer VRECPE */
5217
                            gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
5218
                            break;
5219
                        case 57: /* Integer VRSQRTE */
5220
                            gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
5221
                            break;
5222
                        case 58: /* Float VRECPE */
5223
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
5224
                            break;
5225
                        case 59: /* Float VRSQRTE */
5226
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
5227
                            break;
5228
                        case 60: /* VCVT.F32.S32 */
5229
                            gen_vfp_tosiz(0);
5230
                            break;
5231
                        case 61: /* VCVT.F32.U32 */
5232
                            gen_vfp_touiz(0);
5233
                            break;
5234
                        case 62: /* VCVT.S32.F32 */
5235
                            gen_vfp_sito(0);
5236
                            break;
5237
                        case 63: /* VCVT.U32.F32 */
5238
                            gen_vfp_uito(0);
5239
                            break;
5240
                        default:
5241
                            /* Reserved: 21, 29, 39-56 */
5242
                            return 1;
5243
                        }
5244
                        if (op == 30 || op == 31 || op >= 58) {
5245
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
5246
                                           neon_reg_offset(rd, pass));
5247
                        } else {
5248
                            NEON_SET_REG(T0, rd, pass);
5249
                        }
5250
                    }
5251
                    break;
5252
                }
5253
            } else if ((insn & (1 << 10)) == 0) {
5254
                /* VTBL, VTBX.  */
5255
                n = (insn >> 5) & 0x18;
5256
                NEON_GET_REG(T1, rm, 0);
5257
                if (insn & (1 << 6)) {
5258
                    NEON_GET_REG(T0, rd, 0);
5259
                } else {
5260
                    gen_op_movl_T0_im(0);
5261
                }
5262
                gen_op_neon_tbl(rn, n);
5263
                gen_op_movl_T2_T0();
5264
                NEON_GET_REG(T1, rm, 1);
5265
                if (insn & (1 << 6)) {
5266
                    NEON_GET_REG(T0, rd, 0);
5267
                } else {
5268
                    gen_op_movl_T0_im(0);
5269
                }
5270
                gen_op_neon_tbl(rn, n);
5271
                NEON_SET_REG(T2, rd, 0);
5272
                NEON_SET_REG(T0, rd, 1);
5273
            } else if ((insn & 0x380) == 0) {
5274
                /* VDUP */
5275
                if (insn & (1 << 19)) {
5276
                    NEON_SET_REG(T0, rm, 1);
5277
                } else {
5278
                    NEON_SET_REG(T0, rm, 0);
5279
                }
5280
                if (insn & (1 << 16)) {
5281
                    gen_op_neon_dup_u8(((insn >> 17) & 3) * 8);
5282
                } else if (insn & (1 << 17)) {
5283
                    if ((insn >> 18) & 1)
5284
                        gen_op_neon_dup_high16();
5285
                    else
5286
                        gen_op_neon_dup_low16();
5287
                }
5288
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5289
                    NEON_SET_REG(T0, rd, pass);
5290
                }
5291
            } else {
5292
                return 1;
5293
            }
5294
        }
5295
    }
5296
    return 0;
5297
}
5298

    
5299
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5300
{
5301
    int cpnum;
5302

    
5303
    cpnum = (insn >> 8) & 0xf;
5304
    if (arm_feature(env, ARM_FEATURE_XSCALE)
5305
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
5306
        return 1;
5307

    
5308
    switch (cpnum) {
5309
      case 0:
5310
      case 1:
5311
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5312
            return disas_iwmmxt_insn(env, s, insn);
5313
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
5314
            return disas_dsp_insn(env, s, insn);
5315
        }
5316
        return 1;
5317
    case 10:
5318
    case 11:
5319
        return disas_vfp_insn (env, s, insn);
5320
    case 15:
5321
        return disas_cp15_insn (env, s, insn);
5322
    default:
5323
        /* Unknown coprocessor.  See if the board has hooked it.  */
5324
        return disas_cp_insn (env, s, insn);
5325
    }
5326
}
5327

    
5328

    
5329
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5330
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5331
{
5332
    TCGv tmp;
5333
    tmp = new_tmp();
5334
    tcg_gen_trunc_i64_i32(tmp, val);
5335
    store_reg(s, rlow, tmp);
5336
    tmp = new_tmp();
5337
    tcg_gen_shri_i64(val, val, 32);
5338
    tcg_gen_trunc_i64_i32(tmp, val);
5339
    store_reg(s, rhigh, tmp);
5340
}
5341

    
5342
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5343
static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5344
{
5345
    TCGv tmp;
5346
    TCGv tmp2;
5347

    
5348
    /* Load 64-bit value rd:rn.  */
5349
    tmp = tcg_temp_new(TCG_TYPE_I64);
5350
    tmp2 = load_reg(s, rlow);
5351
    tcg_gen_extu_i32_i64(tmp, tmp2);
5352
    dead_tmp(tmp2);
5353
    tcg_gen_add_i64(val, val, tmp);
5354
}
5355

    
5356
/* load and add a 64-bit value from a register pair.  */
5357
static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5358
{
5359
    TCGv tmp;
5360
    TCGv tmp2;
5361

    
5362
    /* Load 64-bit value rd:rn.  */
5363
    tmp = tcg_temp_new(TCG_TYPE_I64);
5364
    tmp2 = load_reg(s, rhigh);
5365
    tcg_gen_extu_i32_i64(tmp, tmp2);
5366
    dead_tmp(tmp2);
5367
    tcg_gen_shli_i64(tmp, tmp, 32);
5368
    tcg_gen_add_i64(val, val, tmp);
5369

    
5370
    tmp2 = load_reg(s, rlow);
5371
    tcg_gen_extu_i32_i64(tmp, tmp2);
5372
    dead_tmp(tmp2);
5373
    tcg_gen_add_i64(val, val, tmp);
5374
}
5375

    
5376
/* Set N and Z flags from a 64-bit value.  */
5377
static void gen_logicq_cc(TCGv val)
5378
{
5379
    TCGv tmp = new_tmp();
5380
    gen_helper_logicq_cc(tmp, val);
5381
    store_cpu_field(tmp, NZF);
5382
}
5383

    
5384
static void disas_arm_insn(CPUState * env, DisasContext *s)
5385
{
5386
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
5387
    TCGv tmp;
5388
    TCGv tmp2;
5389
    TCGv tmp3;
5390
    TCGv addr;
5391

    
5392
    insn = ldl_code(s->pc);
5393
    s->pc += 4;
5394

    
5395
    /* M variants do not implement ARM mode.  */
5396
    if (IS_M(env))
5397
        goto illegal_op;
5398
    cond = insn >> 28;
5399
    if (cond == 0xf){
5400
        /* Unconditional instructions.  */
5401
        if (((insn >> 25) & 7) == 1) {
5402
            /* NEON Data processing.  */
5403
            if (!arm_feature(env, ARM_FEATURE_NEON))
5404
                goto illegal_op;
5405

    
5406
            if (disas_neon_data_insn(env, s, insn))
5407
                goto illegal_op;
5408
            return;
5409
        }
5410
        if ((insn & 0x0f100000) == 0x04000000) {
5411
            /* NEON load/store.  */
5412
            if (!arm_feature(env, ARM_FEATURE_NEON))
5413
                goto illegal_op;
5414

    
5415
            if (disas_neon_ls_insn(env, s, insn))
5416
                goto illegal_op;
5417
            return;
5418
        }
5419
        if ((insn & 0x0d70f000) == 0x0550f000)
5420
            return; /* PLD */
5421
        else if ((insn & 0x0ffffdff) == 0x01010000) {
5422
            ARCH(6);
5423
            /* setend */
5424
            if (insn & (1 << 9)) {
5425
                /* BE8 mode not implemented.  */
5426
                goto illegal_op;
5427
            }
5428
            return;
5429
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
5430
            switch ((insn >> 4) & 0xf) {
5431
            case 1: /* clrex */
5432
                ARCH(6K);
5433
                gen_op_clrex();
5434
                return;
5435
            case 4: /* dsb */
5436
            case 5: /* dmb */
5437
            case 6: /* isb */
5438
                ARCH(7);
5439
                /* We don't emulate caches so these are a no-op.  */
5440
                return;
5441
            default:
5442
                goto illegal_op;
5443
            }
5444
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
5445
            /* srs */
5446
            uint32_t offset;
5447
            if (IS_USER(s))
5448
                goto illegal_op;
5449
            ARCH(6);
5450
            op1 = (insn & 0x1f);
5451
            if (op1 == (env->uncached_cpsr & CPSR_M)) {
5452
                addr = load_reg(s, 13);
5453
            } else {
5454
                addr = new_tmp();
5455
                gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5456
            }
5457
            i = (insn >> 23) & 3;
5458
            switch (i) {
5459
            case 0: offset = -4; break; /* DA */
5460
            case 1: offset = -8; break; /* DB */
5461
            case 2: offset = 0; break; /* IA */
5462
            case 3: offset = 4; break; /* IB */
5463
            default: abort();
5464
            }
5465
            if (offset)
5466
                tcg_gen_addi_i32(addr, addr, offset);
5467
            tmp = load_reg(s, 14);
5468
            gen_st32(tmp, addr, 0);
5469
            tmp = new_tmp();
5470
            gen_helper_cpsr_read(tmp);
5471
            tcg_gen_addi_i32(addr, addr, 4);
5472
            gen_st32(tmp, addr, 0);
5473
            if (insn & (1 << 21)) {
5474
                /* Base writeback.  */
5475
                switch (i) {
5476
                case 0: offset = -8; break;
5477
                case 1: offset = -4; break;
5478
                case 2: offset = 4; break;
5479
                case 3: offset = 0; break;
5480
                default: abort();
5481
                }
5482
                if (offset)
5483
                    tcg_gen_addi_i32(addr, tmp, offset);
5484
                if (op1 == (env->uncached_cpsr & CPSR_M)) {
5485
                    gen_movl_reg_T1(s, 13);
5486
                } else {
5487
                    gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5488
                }
5489
            } else {
5490
                dead_tmp(addr);
5491
            }
5492
        } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5493
            /* rfe */
5494
            uint32_t offset;
5495
            if (IS_USER(s))
5496
                goto illegal_op;
5497
            ARCH(6);
5498
            rn = (insn >> 16) & 0xf;
5499
            addr = load_reg(s, rn);
5500
            i = (insn >> 23) & 3;
5501
            switch (i) {
5502
            case 0: offset = -4; break; /* DA */
5503
            case 1: offset = -8; break; /* DB */
5504
            case 2: offset = 0; break; /* IA */
5505
            case 3: offset = 4; break; /* IB */
5506
            default: abort();
5507
            }
5508
            if (offset)
5509
                tcg_gen_addi_i32(addr, addr, offset);
5510
            /* Load PC into tmp and CPSR into tmp2.  */
5511
            tmp = gen_ld32(addr, 0);
5512
            tcg_gen_addi_i32(addr, addr, 4);
5513
            tmp2 = gen_ld32(addr, 0);
5514
            if (insn & (1 << 21)) {
5515
                /* Base writeback.  */
5516
                switch (i) {
5517
                case 0: offset = -8; break;
5518
                case 1: offset = -4; break;
5519
                case 2: offset = 4; break;
5520
                case 3: offset = 0; break;
5521
                default: abort();
5522
                }
5523
                if (offset)
5524
                    tcg_gen_addi_i32(addr, addr, offset);
5525
                store_reg(s, rn, addr);
5526
            } else {
5527
                dead_tmp(addr);
5528
            }
5529
            gen_rfe(s, tmp, tmp2);
5530
        } else if ((insn & 0x0e000000) == 0x0a000000) {
5531
            /* branch link and change to thumb (blx <offset>) */
5532
            int32_t offset;
5533

    
5534
            val = (uint32_t)s->pc;
5535
            tmp = new_tmp();
5536
            tcg_gen_movi_i32(tmp, val);
5537
            store_reg(s, 14, tmp);
5538
            /* Sign-extend the 24-bit offset */
5539
            offset = (((int32_t)insn) << 8) >> 8;
5540
            /* offset * 4 + bit24 * 2 + (thumb bit) */
5541
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
5542
            /* pipeline offset */
5543
            val += 4;
5544
            gen_bx_im(s, val);
5545
            return;
5546
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
5547
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
5548
                /* iWMMXt register transfer.  */
5549
                if (env->cp15.c15_cpar & (1 << 1))
5550
                    if (!disas_iwmmxt_insn(env, s, insn))
5551
                        return;
5552
            }
5553
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
5554
            /* Coprocessor double register transfer.  */
5555
        } else if ((insn & 0x0f000010) == 0x0e000010) {
5556
            /* Additional coprocessor register transfer.  */
5557
        } else if ((insn & 0x0ff10010) == 0x01000000) {
5558
            uint32_t mask;
5559
            uint32_t val;
5560
            /* cps (privileged) */
5561
            if (IS_USER(s))
5562
                return;
5563
            mask = val = 0;
5564
            if (insn & (1 << 19)) {
5565
                if (insn & (1 << 8))
5566
                    mask |= CPSR_A;
5567
                if (insn & (1 << 7))
5568
                    mask |= CPSR_I;
5569
                if (insn & (1 << 6))
5570
                    mask |= CPSR_F;
5571
                if (insn & (1 << 18))
5572
                    val |= mask;
5573
            }
5574
            if (insn & (1 << 14)) {
5575
                mask |= CPSR_M;
5576
                val |= (insn & 0x1f);
5577
            }
5578
            if (mask) {
5579
                gen_op_movl_T0_im(val);
5580
                gen_set_psr_T0(s, mask, 0);
5581
            }
5582
            return;
5583
        }
5584
        goto illegal_op;
5585
    }
5586
    if (cond != 0xe) {
5587
        /* if not always execute, we generate a conditional jump to
5588
           next instruction */
5589
        s->condlabel = gen_new_label();
5590
        gen_test_cc(cond ^ 1, s->condlabel);
5591
        s->condjmp = 1;
5592
    }
5593
    if ((insn & 0x0f900000) == 0x03000000) {
5594
        if ((insn & (1 << 21)) == 0) {
5595
            ARCH(6T2);
5596
            rd = (insn >> 12) & 0xf;
5597
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5598
            if ((insn & (1 << 22)) == 0) {
5599
                /* MOVW */
5600
                tmp = new_tmp();
5601
                tcg_gen_movi_i32(tmp, val);
5602
            } else {
5603
                /* MOVT */
5604
                tmp = load_reg(s, rd);
5605
                tcg_gen_andi_i32(tmp, tmp, 0xffff);
5606
                tcg_gen_ori_i32(tmp, tmp, val << 16);
5607
            }
5608
            store_reg(s, rd, tmp);
5609
        } else {
5610
            if (((insn >> 12) & 0xf) != 0xf)
5611
                goto illegal_op;
5612
            if (((insn >> 16) & 0xf) == 0) {
5613
                gen_nop_hint(s, insn & 0xff);
5614
            } else {
5615
                /* CPSR = immediate */
5616
                val = insn & 0xff;
5617
                shift = ((insn >> 8) & 0xf) * 2;
5618
                if (shift)
5619
                    val = (val >> shift) | (val << (32 - shift));
5620
                gen_op_movl_T0_im(val);
5621
                i = ((insn & (1 << 22)) != 0);
5622
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5623
                    goto illegal_op;
5624
            }
5625
        }
5626
    } else if ((insn & 0x0f900000) == 0x01000000
5627
               && (insn & 0x00000090) != 0x00000090) {
5628
        /* miscellaneous instructions */
5629
        op1 = (insn >> 21) & 3;
5630
        sh = (insn >> 4) & 0xf;
5631
        rm = insn & 0xf;
5632
        switch (sh) {
5633
        case 0x0: /* move program status register */
5634
            if (op1 & 1) {
5635
                /* PSR = reg */
5636
                gen_movl_T0_reg(s, rm);
5637
                i = ((op1 & 2) != 0);
5638
                if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
5639
                    goto illegal_op;
5640
            } else {
5641
                /* reg = PSR */
5642
                rd = (insn >> 12) & 0xf;
5643
                if (op1 & 2) {
5644
                    if (IS_USER(s))
5645
                        goto illegal_op;
5646
                    tmp = load_cpu_field(spsr);
5647
                } else {
5648
                    tmp = new_tmp();
5649
                    gen_helper_cpsr_read(tmp);
5650
                }
5651
                store_reg(s, rd, tmp);
5652
            }
5653
            break;
5654
        case 0x1:
5655
            if (op1 == 1) {
5656
                /* branch/exchange thumb (bx).  */
5657
                tmp = load_reg(s, rm);
5658
                gen_bx(s, tmp);
5659
            } else if (op1 == 3) {
5660
                /* clz */
5661
                rd = (insn >> 12) & 0xf;
5662
                tmp = load_reg(s, rm);
5663
                gen_helper_clz(tmp, tmp);
5664
                store_reg(s, rd, tmp);
5665
            } else {
5666
                goto illegal_op;
5667
            }
5668
            break;
5669
        case 0x2:
5670
            if (op1 == 1) {
5671
                ARCH(5J); /* bxj */
5672
                /* Trivial implementation equivalent to bx.  */
5673
                tmp = load_reg(s, rm);
5674
                gen_bx(s, tmp);
5675
            } else {
5676
                goto illegal_op;
5677
            }
5678
            break;
5679
        case 0x3:
5680
            if (op1 != 1)
5681
              goto illegal_op;
5682

    
5683
            /* branch link/exchange thumb (blx) */
5684
            tmp = load_reg(s, rm);
5685
            tmp2 = new_tmp();
5686
            tcg_gen_movi_i32(tmp2, s->pc);
5687
            store_reg(s, 14, tmp2);
5688
            gen_bx(s, tmp);
5689
            break;
5690
        case 0x5: /* saturating add/subtract */
5691
            rd = (insn >> 12) & 0xf;
5692
            rn = (insn >> 16) & 0xf;
5693
            tmp = load_reg(s, rn);
5694
            tmp2 = load_reg(s, rn);
5695
            if (op1 & 2)
5696
                gen_helper_double_saturate(tmp2, tmp2);
5697
            if (op1 & 1)
5698
                gen_helper_sub_saturate(tmp, tmp, tmp2);
5699
            else
5700
                gen_helper_add_saturate(tmp, tmp, tmp2);
5701
            dead_tmp(tmp2);
5702
            store_reg(s, rd, tmp);
5703
            break;
5704
        case 7: /* bkpt */
5705
            gen_set_condexec(s);
5706
            gen_set_pc_im(s->pc - 4);
5707
            gen_exception(EXCP_BKPT);
5708
            s->is_jmp = DISAS_JUMP;
5709
            break;
5710
        case 0x8: /* signed multiply */
5711
        case 0xa:
5712
        case 0xc:
5713
        case 0xe:
5714
            rs = (insn >> 8) & 0xf;
5715
            rn = (insn >> 12) & 0xf;
5716
            rd = (insn >> 16) & 0xf;
5717
            if (op1 == 1) {
5718
                /* (32 * 16) >> 16 */
5719
                tmp = load_reg(s, rm);
5720
                tmp2 = load_reg(s, rs);
5721
                if (sh & 4)
5722
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
5723
                else
5724
                    gen_sxth(tmp2);
5725
                tmp2 = gen_muls_i64_i32(tmp, tmp2);
5726
                tcg_gen_shri_i64(tmp2, tmp2, 16);
5727
                tmp = new_tmp();
5728
                tcg_gen_trunc_i64_i32(tmp, tmp2);
5729
                if ((sh & 2) == 0) {
5730
                    tmp2 = load_reg(s, rn);
5731
                    gen_helper_add_setq(tmp, tmp, tmp2);
5732
                    dead_tmp(tmp2);
5733
                }
5734
                store_reg(s, rd, tmp);
5735
            } else {
5736
                /* 16 * 16 */
5737
                tmp = load_reg(s, rm);
5738
                tmp2 = load_reg(s, rs);
5739
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
5740
                dead_tmp(tmp2);
5741
                if (op1 == 2) {
5742
                    tmp = tcg_temp_new(TCG_TYPE_I64);
5743
                    tcg_gen_ext_i32_i64(tmp, cpu_T[0]);
5744
                    gen_addq(s, tmp, rn, rd);
5745
                    gen_storeq_reg(s, rn, rd, tmp);
5746
                } else {
5747
                    if (op1 == 0) {
5748
                        tmp2 = load_reg(s, rn);
5749
                        gen_helper_add_setq(tmp, tmp, tmp2);
5750
                        dead_tmp(tmp2);
5751
                    }
5752
                    store_reg(s, rd, tmp);
5753
                }
5754
            }
5755
            break;
5756
        default:
5757
            goto illegal_op;
5758
        }
5759
    } else if (((insn & 0x0e000000) == 0 &&
5760
                (insn & 0x00000090) != 0x90) ||
5761
               ((insn & 0x0e000000) == (1 << 25))) {
5762
        int set_cc, logic_cc, shiftop;
5763

    
5764
        op1 = (insn >> 21) & 0xf;
5765
        set_cc = (insn >> 20) & 1;
5766
        logic_cc = table_logic_cc[op1] & set_cc;
5767

    
5768
        /* data processing instruction */
5769
        if (insn & (1 << 25)) {
5770
            /* immediate operand */
5771
            val = insn & 0xff;
5772
            shift = ((insn >> 8) & 0xf) * 2;
5773
            if (shift)
5774
                val = (val >> shift) | (val << (32 - shift));
5775
            gen_op_movl_T1_im(val);
5776
            if (logic_cc && shift)
5777
                gen_set_CF_bit31(cpu_T[1]);
5778
        } else {
5779
            /* register */
5780
            rm = (insn) & 0xf;
5781
            gen_movl_T1_reg(s, rm);
5782
            shiftop = (insn >> 5) & 3;
5783
            if (!(insn & (1 << 4))) {
5784
                shift = (insn >> 7) & 0x1f;
5785
                gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
5786
            } else {
5787
                rs = (insn >> 8) & 0xf;
5788
                tmp = load_reg(s, rs);
5789
                gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc);
5790
            }
5791
        }
5792
        if (op1 != 0x0f && op1 != 0x0d) {
5793
            rn = (insn >> 16) & 0xf;
5794
            gen_movl_T0_reg(s, rn);
5795
        }
5796
        rd = (insn >> 12) & 0xf;
5797
        switch(op1) {
5798
        case 0x00:
5799
            gen_op_andl_T0_T1();
5800
            gen_movl_reg_T0(s, rd);
5801
            if (logic_cc)
5802
                gen_op_logic_T0_cc();
5803
            break;
5804
        case 0x01:
5805
            gen_op_xorl_T0_T1();
5806
            gen_movl_reg_T0(s, rd);
5807
            if (logic_cc)
5808
                gen_op_logic_T0_cc();
5809
            break;
5810
        case 0x02:
5811
            if (set_cc && rd == 15) {
5812
                /* SUBS r15, ... is used for exception return.  */
5813
                if (IS_USER(s))
5814
                    goto illegal_op;
5815
                gen_op_subl_T0_T1_cc();
5816
                gen_exception_return(s);
5817
            } else {
5818
                if (set_cc)
5819
                    gen_op_subl_T0_T1_cc();
5820
                else
5821
                    gen_op_subl_T0_T1();
5822
                gen_movl_reg_T0(s, rd);
5823
            }
5824
            break;
5825
        case 0x03:
5826
            if (set_cc)
5827
                gen_op_rsbl_T0_T1_cc();
5828
            else
5829
                gen_op_rsbl_T0_T1();
5830
            gen_movl_reg_T0(s, rd);
5831
            break;
5832
        case 0x04:
5833
            if (set_cc)
5834
                gen_op_addl_T0_T1_cc();
5835
            else
5836
                gen_op_addl_T0_T1();
5837
            gen_movl_reg_T0(s, rd);
5838
            break;
5839
        case 0x05:
5840
            if (set_cc)
5841
                gen_op_adcl_T0_T1_cc();
5842
            else
5843
                gen_adc_T0_T1();
5844
            gen_movl_reg_T0(s, rd);
5845
            break;
5846
        case 0x06:
5847
            if (set_cc)
5848
                gen_op_sbcl_T0_T1_cc();
5849
            else
5850
                gen_sbc_T0_T1();
5851
            gen_movl_reg_T0(s, rd);
5852
            break;
5853
        case 0x07:
5854
            if (set_cc)
5855
                gen_op_rscl_T0_T1_cc();
5856
            else
5857
                gen_rsc_T0_T1();
5858
            gen_movl_reg_T0(s, rd);
5859
            break;
5860
        case 0x08:
5861
            if (set_cc) {
5862
                gen_op_andl_T0_T1();
5863
                gen_op_logic_T0_cc();
5864
            }
5865
            break;
5866
        case 0x09:
5867
            if (set_cc) {
5868
                gen_op_xorl_T0_T1();
5869
                gen_op_logic_T0_cc();
5870
            }
5871
            break;
5872
        case 0x0a:
5873
            if (set_cc) {
5874
                gen_op_subl_T0_T1_cc();
5875
            }
5876
            break;
5877
        case 0x0b:
5878
            if (set_cc) {
5879
                gen_op_addl_T0_T1_cc();
5880
            }
5881
            break;
5882
        case 0x0c:
5883
            gen_op_orl_T0_T1();
5884
            gen_movl_reg_T0(s, rd);
5885
            if (logic_cc)
5886
                gen_op_logic_T0_cc();
5887
            break;
5888
        case 0x0d:
5889
            if (logic_cc && rd == 15) {
5890
                /* MOVS r15, ... is used for exception return.  */
5891
                if (IS_USER(s))
5892
                    goto illegal_op;
5893
                gen_op_movl_T0_T1();
5894
                gen_exception_return(s);
5895
            } else {
5896
                gen_movl_reg_T1(s, rd);
5897
                if (logic_cc)
5898
                    gen_op_logic_T1_cc();
5899
            }
5900
            break;
5901
        case 0x0e:
5902
            gen_op_bicl_T0_T1();
5903
            gen_movl_reg_T0(s, rd);
5904
            if (logic_cc)
5905
                gen_op_logic_T0_cc();
5906
            break;
5907
        default:
5908
        case 0x0f:
5909
            gen_op_notl_T1();
5910
            gen_movl_reg_T1(s, rd);
5911
            if (logic_cc)
5912
                gen_op_logic_T1_cc();
5913
            break;
5914
        }
5915
    } else {
5916
        /* other instructions */
5917
        op1 = (insn >> 24) & 0xf;
5918
        switch(op1) {
5919
        case 0x0:
5920
        case 0x1:
5921
            /* multiplies, extra load/stores */
5922
            sh = (insn >> 5) & 3;
5923
            if (sh == 0) {
5924
                if (op1 == 0x0) {
5925
                    rd = (insn >> 16) & 0xf;
5926
                    rn = (insn >> 12) & 0xf;
5927
                    rs = (insn >> 8) & 0xf;
5928
                    rm = (insn) & 0xf;
5929
                    op1 = (insn >> 20) & 0xf;
5930
                    switch (op1) {
5931
                    case 0: case 1: case 2: case 3: case 6:
5932
                        /* 32 bit mul */
5933
                        tmp = load_reg(s, rs);
5934
                        tmp2 = load_reg(s, rm);
5935
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
5936
                        dead_tmp(tmp2);
5937
                        if (insn & (1 << 22)) {
5938
                            /* Subtract (mls) */
5939
                            ARCH(6T2);
5940
                            tmp2 = load_reg(s, rn);
5941
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
5942
                            dead_tmp(tmp2);
5943
                        } else if (insn & (1 << 21)) {
5944
                            /* Add */
5945
                            tmp2 = load_reg(s, rn);
5946
                            tcg_gen_add_i32(tmp, tmp, tmp2);
5947
                            dead_tmp(tmp2);
5948
                        }
5949
                        if (insn & (1 << 20))
5950
                            gen_logic_CC(tmp);
5951
                        store_reg(s, rd, tmp);
5952
                        break;
5953
                    default:
5954
                        /* 64 bit mul */
5955
                        tmp = load_reg(s, rs);
5956
                        tmp2 = load_reg(s, rm);
5957
                        if (insn & (1 << 22))
5958
                            tmp = gen_muls_i64_i32(tmp, tmp2);
5959
                        else
5960
                            tmp = gen_mulu_i64_i32(tmp, tmp2);
5961
                        if (insn & (1 << 21)) /* mult accumulate */
5962
                            gen_addq(s, tmp, rn, rd);
5963
                        if (!(insn & (1 << 23))) { /* double accumulate */
5964
                            ARCH(6);
5965
                            gen_addq_lo(s, tmp, rn);
5966
                            gen_addq_lo(s, tmp, rd);
5967
                        }
5968
                        if (insn & (1 << 20))
5969
                            gen_logicq_cc(tmp);
5970
                        gen_storeq_reg(s, rn, rd, tmp);
5971
                        break;
5972
                    }
5973
                } else {
5974
                    rn = (insn >> 16) & 0xf;
5975
                    rd = (insn >> 12) & 0xf;
5976
                    if (insn & (1 << 23)) {
5977
                        /* load/store exclusive */
5978
                        gen_movl_T1_reg(s, rn);
5979
                        if (insn & (1 << 20)) {
5980
                            gen_ldst(ldlex, s);
5981
                        } else {
5982
                            rm = insn & 0xf;
5983
                            gen_movl_T0_reg(s, rm);
5984
                            gen_ldst(stlex, s);
5985
                        }
5986
                        gen_movl_reg_T0(s, rd);
5987
                    } else {
5988
                        /* SWP instruction */
5989
                        rm = (insn) & 0xf;
5990

    
5991
                        /* ??? This is not really atomic.  However we know
5992
                           we never have multiple CPUs running in parallel,
5993
                           so it is good enough.  */
5994
                        addr = load_reg(s, rn);
5995
                        tmp = load_reg(s, rm);
5996
                        if (insn & (1 << 22)) {
5997
                            tmp2 = gen_ld8u(addr, IS_USER(s));
5998
                            gen_st8(tmp, addr, IS_USER(s));
5999
                        } else {
6000
                            tmp2 = gen_ld32(addr, IS_USER(s));
6001
                            gen_st32(tmp, addr, IS_USER(s));
6002
                        }
6003
                        dead_tmp(addr);
6004
                        store_reg(s, rd, tmp2);
6005
                    }
6006
                }
6007
            } else {
6008
                int address_offset;
6009
                int load;
6010
                /* Misc load/store */
6011
                rn = (insn >> 16) & 0xf;
6012
                rd = (insn >> 12) & 0xf;
6013
                addr = load_reg(s, rn);
6014
                if (insn & (1 << 24))
6015
                    gen_add_datah_offset(s, insn, 0, addr);
6016
                address_offset = 0;
6017
                if (insn & (1 << 20)) {
6018
                    /* load */
6019
                    switch(sh) {
6020
                    case 1:
6021
                        tmp = gen_ld16u(addr, IS_USER(s));
6022
                        break;
6023
                    case 2:
6024
                        tmp = gen_ld8s(addr, IS_USER(s));
6025
                        break;
6026
                    default:
6027
                    case 3:
6028
                        tmp = gen_ld16s(addr, IS_USER(s));
6029
                        break;
6030
                    }
6031
                    load = 1;
6032
                } else if (sh & 2) {
6033
                    /* doubleword */
6034
                    if (sh & 1) {
6035
                        /* store */
6036
                        tmp = load_reg(s, rd);
6037
                        gen_st32(tmp, addr, IS_USER(s));
6038
                        tcg_gen_addi_i32(addr, addr, 4);
6039
                        tmp = load_reg(s, rd + 1);
6040
                        gen_st32(tmp, addr, IS_USER(s));
6041
                        load = 0;
6042
                    } else {
6043
                        /* load */
6044
                        tmp = gen_ld32(addr, IS_USER(s));
6045
                        store_reg(s, rd, tmp);
6046
                        tcg_gen_addi_i32(addr, addr, 4);
6047
                        tmp = gen_ld32(addr, IS_USER(s));
6048
                        rd++;
6049
                        load = 1;
6050
                    }
6051
                    address_offset = -4;
6052
                } else {
6053
                    /* store */
6054
                    tmp = load_reg(s, rd);
6055
                    gen_st16(tmp, addr, IS_USER(s));
6056
                    load = 0;
6057
                }
6058
                /* Perform base writeback before the loaded value to
6059
                   ensure correct behavior with overlapping index registers.
6060
                   ldrd with base writeback is is undefined if the
6061
                   destination and index registers overlap.  */
6062
                if (!(insn & (1 << 24))) {
6063
                    gen_add_datah_offset(s, insn, address_offset, addr);
6064
                    store_reg(s, rn, addr);
6065
                } else if (insn & (1 << 21)) {
6066
                    if (address_offset)
6067
                        tcg_gen_addi_i32(addr, addr, address_offset);
6068
                    store_reg(s, rn, addr);
6069
                } else {
6070
                    dead_tmp(addr);
6071
                }
6072
                if (load) {
6073
                    /* Complete the load.  */
6074
                    store_reg(s, rd, tmp);
6075
                }
6076
            }
6077
            break;
6078
        case 0x4:
6079
        case 0x5:
6080
            goto do_ldst;
6081
        case 0x6:
6082
        case 0x7:
6083
            if (insn & (1 << 4)) {
6084
                ARCH(6);
6085
                /* Armv6 Media instructions.  */
6086
                rm = insn & 0xf;
6087
                rn = (insn >> 16) & 0xf;
6088
                rd = (insn >> 12) & 0xf;
6089
                rs = (insn >> 8) & 0xf;
6090
                switch ((insn >> 23) & 3) {
6091
                case 0: /* Parallel add/subtract.  */
6092
                    op1 = (insn >> 20) & 7;
6093
                    tmp = load_reg(s, rn);
6094
                    tmp2 = load_reg(s, rm);
6095
                    sh = (insn >> 5) & 7;
6096
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
6097
                        goto illegal_op;
6098
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
6099
                    dead_tmp(tmp2);
6100
                    store_reg(s, rd, tmp);
6101
                    break;
6102
                case 1:
6103
                    if ((insn & 0x00700020) == 0) {
6104
                        /* Hafword pack.  */
6105
                        tmp = load_reg(s, rn);
6106
                        tmp2 = load_reg(s, rm);
6107
                        shift = (insn >> 7) & 0x1f;
6108
                        if (shift)
6109
                            tcg_gen_shli_i32(tmp2, tmp2, shift);
6110
                        if (insn & (1 << 6)) {
6111
                            /* pkhtb */
6112
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6113
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
6114
                        } else {
6115
                            /* pkhbt */
6116
                            tcg_gen_andi_i32(tmp, tmp, 0xffff);
6117
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6118
                        }
6119
                        tcg_gen_or_i32(tmp, tmp, tmp2);
6120
                        store_reg(s, rd, tmp);
6121
                    } else if ((insn & 0x00200020) == 0x00200000) {
6122
                        /* [us]sat */
6123
                        tmp = load_reg(s, rm);
6124
                        shift = (insn >> 7) & 0x1f;
6125
                        if (insn & (1 << 6)) {
6126
                            if (shift == 0)
6127
                                shift = 31;
6128
                            tcg_gen_sari_i32(tmp, tmp, shift);
6129
                        } else {
6130
                            tcg_gen_shli_i32(tmp, tmp, shift);
6131
                        }
6132
                        sh = (insn >> 16) & 0x1f;
6133
                        if (sh != 0) {
6134
                            if (insn & (1 << 22))
6135
                                gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
6136
                            else
6137
                                gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
6138
                        }
6139
                        store_reg(s, rd, tmp);
6140
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
6141
                        /* [us]sat16 */
6142
                        tmp = load_reg(s, rm);
6143
                        sh = (insn >> 16) & 0x1f;
6144
                        if (sh != 0) {
6145
                            if (insn & (1 << 22))
6146
                                gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
6147
                            else
6148
                                gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
6149
                        }
6150
                        store_reg(s, rd, tmp);
6151
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
6152
                        /* Select bytes.  */
6153
                        tmp = load_reg(s, rn);
6154
                        tmp2 = load_reg(s, rm);
6155
                        tmp3 = new_tmp();
6156
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
6157
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
6158
                        dead_tmp(tmp3);
6159
                        dead_tmp(tmp2);
6160
                        store_reg(s, rd, tmp);
6161
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6162
                        tmp = load_reg(s, rm);
6163
                        shift = (insn >> 10) & 3;
6164
                        /* ??? In many cases it's not neccessary to do a
6165
                           rotate, a shift is sufficient.  */
6166
                        if (shift != 0)
6167
                            tcg_gen_rori_i32(tmp, tmp, shift * 8);
6168
                        op1 = (insn >> 20) & 7;
6169
                        switch (op1) {
6170
                        case 0: gen_sxtb16(tmp);  break;
6171
                        case 2: gen_sxtb(tmp);    break;
6172
                        case 3: gen_sxth(tmp);    break;
6173
                        case 4: gen_uxtb16(tmp);  break;
6174
                        case 6: gen_uxtb(tmp);    break;
6175
                        case 7: gen_uxth(tmp);    break;
6176
                        default: goto illegal_op;
6177
                        }
6178
                        if (rn != 15) {
6179
                            tmp2 = load_reg(s, rn);
6180
                            if ((op1 & 3) == 0) {
6181
                                gen_add16(tmp, tmp2);
6182
                            } else {
6183
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6184
                                dead_tmp(tmp2);
6185
                            }
6186
                        }
6187
                        store_reg(s, rd, tmp2);
6188
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6189
                        /* rev */
6190
                        tmp = load_reg(s, rm);
6191
                        if (insn & (1 << 22)) {
6192
                            if (insn & (1 << 7)) {
6193
                                gen_revsh(tmp);
6194
                            } else {
6195
                                ARCH(6T2);
6196
                                gen_helper_rbit(tmp, tmp);
6197
                            }
6198
                        } else {
6199
                            if (insn & (1 << 7))
6200
                                gen_rev16(tmp);
6201
                            else
6202
                                tcg_gen_bswap_i32(tmp, tmp);
6203
                        }
6204
                        store_reg(s, rd, tmp);
6205
                    } else {
6206
                        goto illegal_op;
6207
                    }
6208
                    break;
6209
                case 2: /* Multiplies (Type 3).  */
6210
                    tmp = load_reg(s, rm);
6211
                    tmp2 = load_reg(s, rs);
6212
                    if (insn & (1 << 20)) {
6213
                        /* Signed multiply most significant [accumulate].  */
6214
                        tmp2 = gen_muls_i64_i32(tmp, tmp2);
6215
                        if (insn & (1 << 5))
6216
                            tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
6217
                        tcg_gen_shri_i64(tmp2, tmp2, 32);
6218
                        tmp = new_tmp();
6219
                        tcg_gen_trunc_i64_i32(tmp, tmp2);
6220
                        if (rn != 15) {
6221
                            tmp2 = load_reg(s, rn);
6222
                            if (insn & (1 << 6)) {
6223
                                tcg_gen_sub_i32(tmp, tmp, tmp2);
6224
                            } else {
6225
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6226
                            }
6227
                            dead_tmp(tmp2);
6228
                        }
6229
                        store_reg(s, rd, tmp);
6230
                    } else {
6231
                        if (insn & (1 << 5))
6232
                            gen_swap_half(tmp2);
6233
                        gen_smul_dual(tmp, tmp2);
6234
                        /* This addition cannot overflow.  */
6235
                        if (insn & (1 << 6)) {
6236
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
6237
                        } else {
6238
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6239
                        }
6240
                        dead_tmp(tmp2);
6241
                        if (insn & (1 << 22)) {
6242
                            /* smlald, smlsld */
6243
                            tmp2 = tcg_temp_new(TCG_TYPE_I64);
6244
                            tcg_gen_ext_i32_i64(tmp2, tmp);
6245
                            dead_tmp(tmp);
6246
                            gen_addq(s, tmp2, rn, rd);
6247
                            gen_storeq_reg(s, rn, rd, tmp2);
6248
                        } else {
6249
                            /* smuad, smusd, smlad, smlsd */
6250
                            if (rn != 15)
6251
                              {
6252
                                tmp2 = load_reg(s, rn);
6253
                                gen_helper_add_setq(tmp, tmp, tmp2);
6254
                                dead_tmp(tmp2);
6255
                              }
6256
                            store_reg(s, rd, tmp);
6257
                        }
6258
                    }
6259
                    break;
6260
                case 3:
6261
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
6262
                    switch (op1) {
6263
                    case 0: /* Unsigned sum of absolute differences.  */
6264
                        ARCH(6);
6265
                        tmp = load_reg(s, rm);
6266
                        tmp2 = load_reg(s, rs);
6267
                        gen_helper_usad8(tmp, tmp, tmp2);
6268
                        dead_tmp(tmp2);
6269
                        if (rn != 15) {
6270
                            tmp2 = load_reg(s, rn);
6271
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6272
                            dead_tmp(tmp2);
6273
                        }
6274
                        store_reg(s, rd, tmp);
6275
                        break;
6276
                    case 0x20: case 0x24: case 0x28: case 0x2c:
6277
                        /* Bitfield insert/clear.  */
6278
                        ARCH(6T2);
6279
                        shift = (insn >> 7) & 0x1f;
6280
                        i = (insn >> 16) & 0x1f;
6281
                        i = i + 1 - shift;
6282
                        if (rm == 15) {
6283
                            tmp = new_tmp();
6284
                            tcg_gen_movi_i32(tmp, 0);
6285
                        } else {
6286
                            tmp = load_reg(s, rm);
6287
                        }
6288
                        if (i != 32) {
6289
                            tmp2 = load_reg(s, rd);
6290
                            gen_bfi(tmp, tmp2, tmp,
6291
                                    shift, ((1u << i) - 1) << shift);
6292
                            dead_tmp(tmp2);
6293
                        }
6294
                        store_reg(s, rd, tmp);
6295
                        break;
6296
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6297
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6298
                        tmp = load_reg(s, rm);
6299
                        shift = (insn >> 7) & 0x1f;
6300
                        i = ((insn >> 16) & 0x1f) + 1;
6301
                        if (shift + i > 32)
6302
                            goto illegal_op;
6303
                        if (i < 32) {
6304
                            if (op1 & 0x20) {
6305
                                gen_ubfx(tmp, shift, (1u << i) - 1);
6306
                            } else {
6307
                                gen_sbfx(tmp, shift, i);
6308
                            }
6309
                        }
6310
                        store_reg(s, rd, tmp);
6311
                        break;
6312
                    default:
6313
                        goto illegal_op;
6314
                    }
6315
                    break;
6316
                }
6317
                break;
6318
            }
6319
        do_ldst:
6320
            /* Check for undefined extension instructions
6321
             * per the ARM Bible IE:
6322
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
6323
             */
6324
            sh = (0xf << 20) | (0xf << 4);
6325
            if (op1 == 0x7 && ((insn & sh) == sh))
6326
            {
6327
                goto illegal_op;
6328
            }
6329
            /* load/store byte/word */
6330
            rn = (insn >> 16) & 0xf;
6331
            rd = (insn >> 12) & 0xf;
6332
            tmp2 = load_reg(s, rn);
6333
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6334
            if (insn & (1 << 24))
6335
                gen_add_data_offset(s, insn, tmp2);
6336
            if (insn & (1 << 20)) {
6337
                /* load */
6338
                s->is_mem = 1;
6339
                if (insn & (1 << 22)) {
6340
                    tmp = gen_ld8u(tmp2, i);
6341
                } else {
6342
                    tmp = gen_ld32(tmp2, i);
6343
                }
6344
            } else {
6345
                /* store */
6346
                tmp = load_reg(s, rd);
6347
                if (insn & (1 << 22))
6348
                    gen_st8(tmp, tmp2, i);
6349
                else
6350
                    gen_st32(tmp, tmp2, i);
6351
            }
6352
            if (!(insn & (1 << 24))) {
6353
                gen_add_data_offset(s, insn, tmp2);
6354
                store_reg(s, rn, tmp2);
6355
            } else if (insn & (1 << 21)) {
6356
                store_reg(s, rn, tmp2);
6357
            } else {
6358
                dead_tmp(tmp2);
6359
            }
6360
            if (insn & (1 << 20)) {
6361
                /* Complete the load.  */
6362
                if (rd == 15)
6363
                    gen_bx(s, tmp);
6364
                else
6365
                    store_reg(s, rd, tmp);
6366
            }
6367
            break;
6368
        case 0x08:
6369
        case 0x09:
6370
            {
6371
                int j, n, user, loaded_base;
6372
                TCGv loaded_var;
6373
                /* load/store multiple words */
6374
                /* XXX: store correct base if write back */
6375
                user = 0;
6376
                if (insn & (1 << 22)) {
6377
                    if (IS_USER(s))
6378
                        goto illegal_op; /* only usable in supervisor mode */
6379

    
6380
                    if ((insn & (1 << 15)) == 0)
6381
                        user = 1;
6382
                }
6383
                rn = (insn >> 16) & 0xf;
6384
                addr = load_reg(s, rn);
6385

    
6386
                /* compute total size */
6387
                loaded_base = 0;
6388
                n = 0;
6389
                for(i=0;i<16;i++) {
6390
                    if (insn & (1 << i))
6391
                        n++;
6392
                }
6393
                /* XXX: test invalid n == 0 case ? */
6394
                if (insn & (1 << 23)) {
6395
                    if (insn & (1 << 24)) {
6396
                        /* pre increment */
6397
                        tcg_gen_addi_i32(addr, addr, 4);
6398
                    } else {
6399
                        /* post increment */
6400
                    }
6401
                } else {
6402
                    if (insn & (1 << 24)) {
6403
                        /* pre decrement */
6404
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
6405
                    } else {
6406
                        /* post decrement */
6407
                        if (n != 1)
6408
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6409
                    }
6410
                }
6411
                j = 0;
6412
                for(i=0;i<16;i++) {
6413
                    if (insn & (1 << i)) {
6414
                        if (insn & (1 << 20)) {
6415
                            /* load */
6416
                            tmp = gen_ld32(addr, IS_USER(s));
6417
                            if (i == 15) {
6418
                                gen_bx(s, tmp);
6419
                            } else if (user) {
6420
                                gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6421
                                dead_tmp(tmp);
6422
                            } else if (i == rn) {
6423
                                loaded_var = tmp;
6424
                                loaded_base = 1;
6425
                            } else {
6426
                                store_reg(s, i, tmp);
6427
                            }
6428
                        } else {
6429
                            /* store */
6430
                            if (i == 15) {
6431
                                /* special case: r15 = PC + 8 */
6432
                                val = (long)s->pc + 4;
6433
                                tmp = new_tmp();
6434
                                tcg_gen_movi_i32(tmp, val);
6435
                            } else if (user) {
6436
                                tmp = new_tmp();
6437
                                gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6438
                            } else {
6439
                                tmp = load_reg(s, i);
6440
                            }
6441
                            gen_st32(tmp, addr, IS_USER(s));
6442
                        }
6443
                        j++;
6444
                        /* no need to add after the last transfer */
6445
                        if (j != n)
6446
                            tcg_gen_addi_i32(addr, addr, 4);
6447
                    }
6448
                }
6449
                if (insn & (1 << 21)) {
6450
                    /* write back */
6451
                    if (insn & (1 << 23)) {
6452
                        if (insn & (1 << 24)) {
6453
                            /* pre increment */
6454
                        } else {
6455
                            /* post increment */
6456
                            tcg_gen_addi_i32(addr, addr, 4);
6457
                        }
6458
                    } else {
6459
                        if (insn & (1 << 24)) {
6460
                            /* pre decrement */
6461
                            if (n != 1)
6462
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6463
                        } else {
6464
                            /* post decrement */
6465
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
6466
                        }
6467
                    }
6468
                    store_reg(s, rn, addr);
6469
                } else {
6470
                    dead_tmp(addr);
6471
                }
6472
                if (loaded_base) {
6473
                    store_reg(s, rn, loaded_var);
6474
                }
6475
                if ((insn & (1 << 22)) && !user) {
6476
                    /* Restore CPSR from SPSR.  */
6477
                    tmp = load_cpu_field(spsr);
6478
                    gen_set_cpsr(tmp, 0xffffffff);
6479
                    dead_tmp(tmp);
6480
                    s->is_jmp = DISAS_UPDATE;
6481
                }
6482
            }
6483
            break;
6484
        case 0xa:
6485
        case 0xb:
6486
            {
6487
                int32_t offset;
6488

    
6489
                /* branch (and link) */
6490
                val = (int32_t)s->pc;
6491
                if (insn & (1 << 24)) {
6492
                    tmp = new_tmp();
6493
                    tcg_gen_movi_i32(tmp, val);
6494
                    store_reg(s, 14, tmp);
6495
                }
6496
                offset = (((int32_t)insn << 8) >> 8);
6497
                val += (offset << 2) + 4;
6498
                gen_jmp(s, val);
6499
            }
6500
            break;
6501
        case 0xc:
6502
        case 0xd:
6503
        case 0xe:
6504
            /* Coprocessor.  */
6505
            if (disas_coproc_insn(env, s, insn))
6506
                goto illegal_op;
6507
            break;
6508
        case 0xf:
6509
            /* swi */
6510
            gen_set_pc_im(s->pc);
6511
            s->is_jmp = DISAS_SWI;
6512
            break;
6513
        default:
6514
        illegal_op:
6515
            gen_set_condexec(s);
6516
            gen_set_pc_im(s->pc - 4);
6517
            gen_exception(EXCP_UDEF);
6518
            s->is_jmp = DISAS_JUMP;
6519
            break;
6520
        }
6521
    }
6522
}
6523

    
6524
/* Return true if this is a Thumb-2 logical op.  */
6525
static int
6526
thumb2_logic_op(int op)
6527
{
6528
    return (op < 8);
6529
}
6530

    
6531
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
6532
   then set condition code flags based on the result of the operation.
6533
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
6534
   to the high bit of T1.
6535
   Returns zero if the opcode is valid.  */
6536

    
6537
static int
6538
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
6539
{
6540
    int logic_cc;
6541

    
6542
    logic_cc = 0;
6543
    switch (op) {
6544
    case 0: /* and */
6545
        gen_op_andl_T0_T1();
6546
        logic_cc = conds;
6547
        break;
6548
    case 1: /* bic */
6549
        gen_op_bicl_T0_T1();
6550
        logic_cc = conds;
6551
        break;
6552
    case 2: /* orr */
6553
        gen_op_orl_T0_T1();
6554
        logic_cc = conds;
6555
        break;
6556
    case 3: /* orn */
6557
        gen_op_notl_T1();
6558
        gen_op_orl_T0_T1();
6559
        logic_cc = conds;
6560
        break;
6561
    case 4: /* eor */
6562
        gen_op_xorl_T0_T1();
6563
        logic_cc = conds;
6564
        break;
6565
    case 8: /* add */
6566
        if (conds)
6567
            gen_op_addl_T0_T1_cc();
6568
        else
6569
            gen_op_addl_T0_T1();
6570
        break;
6571
    case 10: /* adc */
6572
        if (conds)
6573
            gen_op_adcl_T0_T1_cc();
6574
        else
6575
            gen_adc_T0_T1();
6576
        break;
6577
    case 11: /* sbc */
6578
        if (conds)
6579
            gen_op_sbcl_T0_T1_cc();
6580
        else
6581
            gen_sbc_T0_T1();
6582
        break;
6583
    case 13: /* sub */
6584
        if (conds)
6585
            gen_op_subl_T0_T1_cc();
6586
        else
6587
            gen_op_subl_T0_T1();
6588
        break;
6589
    case 14: /* rsb */
6590
        if (conds)
6591
            gen_op_rsbl_T0_T1_cc();
6592
        else
6593
            gen_op_rsbl_T0_T1();
6594
        break;
6595
    default: /* 5, 6, 7, 9, 12, 15. */
6596
        return 1;
6597
    }
6598
    if (logic_cc) {
6599
        gen_op_logic_T0_cc();
6600
        if (shifter_out)
6601
            gen_set_CF_bit31(cpu_T[1]);
6602
    }
6603
    return 0;
6604
}
6605

    
6606
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
6607
   is not legal.  */
6608
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6609
{
6610
    uint32_t insn, imm, shift, offset;
6611
    uint32_t rd, rn, rm, rs;
6612
    TCGv tmp;
6613
    TCGv tmp2;
6614
    TCGv tmp3;
6615
    TCGv addr;
6616
    int op;
6617
    int shiftop;
6618
    int conds;
6619
    int logic_cc;
6620

    
6621
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
6622
          || arm_feature (env, ARM_FEATURE_M))) {
6623
        /* Thumb-1 cores may need to tread bl and blx as a pair of
6624
           16-bit instructions to get correct prefetch abort behavior.  */
6625
        insn = insn_hw1;
6626
        if ((insn & (1 << 12)) == 0) {
6627
            /* Second half of blx.  */
6628
            offset = ((insn & 0x7ff) << 1);
6629
            tmp = load_reg(s, 14);
6630
            tcg_gen_addi_i32(tmp, tmp, offset);
6631
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6632

    
6633
            tmp2 = new_tmp();
6634
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6635
            store_reg(s, 14, tmp2);
6636
            gen_bx(s, tmp);
6637
            return 0;
6638
        }
6639
        if (insn & (1 << 11)) {
6640
            /* Second half of bl.  */
6641
            offset = ((insn & 0x7ff) << 1) | 1;
6642
            tmp = load_reg(s, 14);
6643
            tcg_gen_addi_i32(tmp, tmp, 14);
6644

    
6645
            tmp2 = new_tmp();
6646
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6647
            store_reg(s, 14, tmp2);
6648
            gen_bx(s, tmp);
6649
            return 0;
6650
        }
6651
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
6652
            /* Instruction spans a page boundary.  Implement it as two
6653
               16-bit instructions in case the second half causes an
6654
               prefetch abort.  */
6655
            offset = ((int32_t)insn << 21) >> 9;
6656
            gen_op_movl_T0_im(s->pc + 2 + offset);
6657
            gen_movl_reg_T0(s, 14);
6658
            return 0;
6659
        }
6660
        /* Fall through to 32-bit decode.  */
6661
    }
6662

    
6663
    insn = lduw_code(s->pc);
6664
    s->pc += 2;
6665
    insn |= (uint32_t)insn_hw1 << 16;
6666

    
6667
    if ((insn & 0xf800e800) != 0xf000e800) {
6668
        ARCH(6T2);
6669
    }
6670

    
6671
    rn = (insn >> 16) & 0xf;
6672
    rs = (insn >> 12) & 0xf;
6673
    rd = (insn >> 8) & 0xf;
6674
    rm = insn & 0xf;
6675
    switch ((insn >> 25) & 0xf) {
6676
    case 0: case 1: case 2: case 3:
6677
        /* 16-bit instructions.  Should never happen.  */
6678
        abort();
6679
    case 4:
6680
        if (insn & (1 << 22)) {
6681
            /* Other load/store, table branch.  */
6682
            if (insn & 0x01200000) {
6683
                /* Load/store doubleword.  */
6684
                if (rn == 15) {
6685
                    addr = new_tmp();
6686
                    tcg_gen_movi_i32(addr, s->pc & ~3);
6687
                } else {
6688
                    addr = load_reg(s, rn);
6689
                }
6690
                offset = (insn & 0xff) * 4;
6691
                if ((insn & (1 << 23)) == 0)
6692
                    offset = -offset;
6693
                if (insn & (1 << 24)) {
6694
                    tcg_gen_addi_i32(addr, addr, offset);
6695
                    offset = 0;
6696
                }
6697
                if (insn & (1 << 20)) {
6698
                    /* ldrd */
6699
                    tmp = gen_ld32(addr, IS_USER(s));
6700
                    store_reg(s, rs, tmp);
6701
                    tcg_gen_addi_i32(addr, addr, 4);
6702
                    tmp = gen_ld32(addr, IS_USER(s));
6703
                    store_reg(s, rd, tmp);
6704
                } else {
6705
                    /* strd */
6706
                    tmp = load_reg(s, rs);
6707
                    gen_st32(tmp, addr, IS_USER(s));
6708
                    tcg_gen_addi_i32(addr, addr, 4);
6709
                    tmp = load_reg(s, rd);
6710
                    gen_st32(tmp, addr, IS_USER(s));
6711
                }
6712
                if (insn & (1 << 21)) {
6713
                    /* Base writeback.  */
6714
                    if (rn == 15)
6715
                        goto illegal_op;
6716
                    tcg_gen_addi_i32(addr, addr, offset - 4);
6717
                    store_reg(s, rn, addr);
6718
                } else {
6719
                    dead_tmp(addr);
6720
                }
6721
            } else if ((insn & (1 << 23)) == 0) {
6722
                /* Load/store exclusive word.  */
6723
                gen_movl_T0_reg(s, rd);
6724
                gen_movl_T1_reg(s, rn);
6725
                if (insn & (1 << 20)) {
6726
                    gen_ldst(ldlex, s);
6727
                } else {
6728
                    gen_ldst(stlex, s);
6729
                }
6730
                gen_movl_reg_T0(s, rd);
6731
            } else if ((insn & (1 << 6)) == 0) {
6732
                /* Table Branch.  */
6733
                if (rn == 15) {
6734
                    addr = new_tmp();
6735
                    tcg_gen_movi_i32(addr, s->pc);
6736
                } else {
6737
                    addr = load_reg(s, rn);
6738
                }
6739
                tmp = load_reg(s, rm);
6740
                tcg_gen_add_i32(addr, addr, tmp);
6741
                if (insn & (1 << 4)) {
6742
                    /* tbh */
6743
                    tcg_gen_add_i32(addr, addr, tmp);
6744
                    dead_tmp(tmp);
6745
                    tmp = gen_ld16u(addr, IS_USER(s));
6746
                } else { /* tbb */
6747
                    dead_tmp(tmp);
6748
                    tmp = gen_ld8u(addr, IS_USER(s));
6749
                }
6750
                dead_tmp(addr);
6751
                tcg_gen_shli_i32(tmp, tmp, 1);
6752
                tcg_gen_addi_i32(tmp, tmp, s->pc);
6753
                store_reg(s, 15, tmp);
6754
            } else {
6755
                /* Load/store exclusive byte/halfword/doubleword.  */
6756
                op = (insn >> 4) & 0x3;
6757
                gen_movl_T1_reg(s, rn);
6758
                if (insn & (1 << 20)) {
6759
                    switch (op) {
6760
                    case 0:
6761
                        gen_ldst(ldbex, s);
6762
                        break;
6763
                    case 1:
6764
                        gen_ldst(ldwex, s);
6765
                        break;
6766
                    case 3:
6767
                        gen_ldst(ldqex, s);
6768
                        gen_movl_reg_T1(s, rd);
6769
                        break;
6770
                    default:
6771
                        goto illegal_op;
6772
                    }
6773
                    gen_movl_reg_T0(s, rs);
6774
                } else {
6775
                    gen_movl_T0_reg(s, rs);
6776
                    switch (op) {
6777
                    case 0:
6778
                        gen_ldst(stbex, s);
6779
                        break;
6780
                    case 1:
6781
                        gen_ldst(stwex, s);
6782
                        break;
6783
                    case 3:
6784
                        gen_movl_T2_reg(s, rd);
6785
                        gen_ldst(stqex, s);
6786
                        break;
6787
                    default:
6788
                        goto illegal_op;
6789
                    }
6790
                    gen_movl_reg_T0(s, rm);
6791
                }
6792
            }
6793
        } else {
6794
            /* Load/store multiple, RFE, SRS.  */
6795
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
6796
                /* Not available in user mode.  */
6797
                if (IS_USER(s))
6798
                    goto illegal_op;
6799
                if (insn & (1 << 20)) {
6800
                    /* rfe */
6801
                    addr = load_reg(s, rn);
6802
                    if ((insn & (1 << 24)) == 0)
6803
                        tcg_gen_addi_i32(addr, addr, -8);
6804
                    /* Load PC into tmp and CPSR into tmp2.  */
6805
                    tmp = gen_ld32(addr, 0);
6806
                    tcg_gen_addi_i32(addr, addr, 4);
6807
                    tmp2 = gen_ld32(addr, 0);
6808
                    if (insn & (1 << 21)) {
6809
                        /* Base writeback.  */
6810
                        if (insn & (1 << 24)) {
6811
                            tcg_gen_addi_i32(addr, addr, 4);
6812
                        } else {
6813
                            tcg_gen_addi_i32(addr, addr, -4);
6814
                        }
6815
                        store_reg(s, rn, addr);
6816
                    } else {
6817
                        dead_tmp(addr);
6818
                    }
6819
                    gen_rfe(s, tmp, tmp2);
6820
                } else {
6821
                    /* srs */
6822
                    op = (insn & 0x1f);
6823
                    if (op == (env->uncached_cpsr & CPSR_M)) {
6824
                        addr = load_reg(s, 13);
6825
                    } else {
6826
                        addr = new_tmp();
6827
                        gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
6828
                    }
6829
                    if ((insn & (1 << 24)) == 0) {
6830
                        tcg_gen_addi_i32(addr, addr, -8);
6831
                    }
6832
                    tmp = load_reg(s, 14);
6833
                    gen_st32(tmp, addr, 0);
6834
                    tcg_gen_addi_i32(addr, addr, 4);
6835
                    tmp = new_tmp();
6836
                    gen_helper_cpsr_read(tmp);
6837
                    gen_st32(tmp, addr, 0);
6838
                    if (insn & (1 << 21)) {
6839
                        if ((insn & (1 << 24)) == 0) {
6840
                            tcg_gen_addi_i32(addr, addr, -4);
6841
                        } else {
6842
                            tcg_gen_addi_i32(addr, addr, 4);
6843
                        }
6844
                        if (op == (env->uncached_cpsr & CPSR_M)) {
6845
                            store_reg(s, 13, addr);
6846
                        } else {
6847
                            gen_helper_set_r13_banked(cpu_env,
6848
                                tcg_const_i32(op), addr);
6849
                        }
6850
                    } else {
6851
                        dead_tmp(addr);
6852
                    }
6853
                }
6854
            } else {
6855
                int i;
6856
                /* Load/store multiple.  */
6857
                addr = load_reg(s, rn);
6858
                offset = 0;
6859
                for (i = 0; i < 16; i++) {
6860
                    if (insn & (1 << i))
6861
                        offset += 4;
6862
                }
6863
                if (insn & (1 << 24)) {
6864
                    tcg_gen_addi_i32(addr, addr, -offset);
6865
                }
6866

    
6867
                for (i = 0; i < 16; i++) {
6868
                    if ((insn & (1 << i)) == 0)
6869
                        continue;
6870
                    if (insn & (1 << 20)) {
6871
                        /* Load.  */
6872
                        tmp = gen_ld32(addr, IS_USER(s));
6873
                        if (i == 15) {
6874
                            gen_bx(s, tmp);
6875
                        } else {
6876
                            store_reg(s, i, tmp);
6877
                        }
6878
                    } else {
6879
                        /* Store.  */
6880
                        tmp = load_reg(s, i);
6881
                        gen_st32(tmp, addr, IS_USER(s));
6882
                    }
6883
                    tcg_gen_addi_i32(addr, addr, 4);
6884
                }
6885
                if (insn & (1 << 21)) {
6886
                    /* Base register writeback.  */
6887
                    if (insn & (1 << 24)) {
6888
                        tcg_gen_addi_i32(addr, addr, -offset);
6889
                    }
6890
                    /* Fault if writeback register is in register list.  */
6891
                    if (insn & (1 << rn))
6892
                        goto illegal_op;
6893
                    store_reg(s, rn, addr);
6894
                } else {
6895
                    dead_tmp(addr);
6896
                }
6897
            }
6898
        }
6899
        break;
6900
    case 5: /* Data processing register constant shift.  */
6901
        if (rn == 15)
6902
            gen_op_movl_T0_im(0);
6903
        else
6904
            gen_movl_T0_reg(s, rn);
6905
        gen_movl_T1_reg(s, rm);
6906
        op = (insn >> 21) & 0xf;
6907
        shiftop = (insn >> 4) & 3;
6908
        shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
6909
        conds = (insn & (1 << 20)) != 0;
6910
        logic_cc = (conds && thumb2_logic_op(op));
6911
        gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
6912
        if (gen_thumb2_data_op(s, op, conds, 0))
6913
            goto illegal_op;
6914
        if (rd != 15)
6915
            gen_movl_reg_T0(s, rd);
6916
        break;
6917
    case 13: /* Misc data processing.  */
6918
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
6919
        if (op < 4 && (insn & 0xf000) != 0xf000)
6920
            goto illegal_op;
6921
        switch (op) {
6922
        case 0: /* Register controlled shift.  */
6923
            tmp = load_reg(s, rn);
6924
            tmp2 = load_reg(s, rm);
6925
            if ((insn & 0x70) != 0)
6926
                goto illegal_op;
6927
            op = (insn >> 21) & 3;
6928
            logic_cc = (insn & (1 << 20)) != 0;
6929
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
6930
            if (logic_cc)
6931
                gen_logic_CC(tmp);
6932
            store_reg(s, rd, tmp);
6933
            break;
6934
        case 1: /* Sign/zero extend.  */
6935
            tmp = load_reg(s, rm);
6936
            shift = (insn >> 4) & 3;
6937
            /* ??? In many cases it's not neccessary to do a
6938
               rotate, a shift is sufficient.  */
6939
            if (shift != 0)
6940
                tcg_gen_rori_i32(tmp, tmp, shift * 8);
6941
            op = (insn >> 20) & 7;
6942
            switch (op) {
6943
            case 0: gen_sxth(tmp);   break;
6944
            case 1: gen_uxth(tmp);   break;
6945
            case 2: gen_sxtb16(tmp); break;
6946
            case 3: gen_uxtb16(tmp); break;
6947
            case 4: gen_sxtb(tmp);   break;
6948
            case 5: gen_uxtb(tmp);   break;
6949
            default: goto illegal_op;
6950
            }
6951
            if (rn != 15) {
6952
                tmp2 = load_reg(s, rn);
6953
                if ((op >> 1) == 1) {
6954
                    gen_add16(tmp, tmp2);
6955
                } else {
6956
                    tcg_gen_add_i32(tmp, tmp, tmp2);
6957
                    dead_tmp(tmp2);
6958
                }
6959
            }
6960
            store_reg(s, rd, tmp);
6961
            break;
6962
        case 2: /* SIMD add/subtract.  */
6963
            op = (insn >> 20) & 7;
6964
            shift = (insn >> 4) & 7;
6965
            if ((op & 3) == 3 || (shift & 3) == 3)
6966
                goto illegal_op;
6967
            tmp = load_reg(s, rn);
6968
            tmp2 = load_reg(s, rm);
6969
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
6970
            dead_tmp(tmp2);
6971
            store_reg(s, rd, tmp);
6972
            break;
6973
        case 3: /* Other data processing.  */
6974
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
6975
            if (op < 4) {
6976
                /* Saturating add/subtract.  */
6977
                tmp = load_reg(s, rn);
6978
                tmp2 = load_reg(s, rm);
6979
                if (op & 2)
6980
                    gen_helper_double_saturate(tmp, tmp);
6981
                if (op & 1)
6982
                    gen_helper_sub_saturate(tmp, tmp2, tmp);
6983
                else
6984
                    gen_helper_add_saturate(tmp, tmp, tmp2);
6985
                dead_tmp(tmp2);
6986
            } else {
6987
                tmp = load_reg(s, rn);
6988
                switch (op) {
6989
                case 0x0a: /* rbit */
6990
                    gen_helper_rbit(tmp, tmp);
6991
                    break;
6992
                case 0x08: /* rev */
6993
                    tcg_gen_bswap_i32(tmp, tmp);
6994
                    break;
6995
                case 0x09: /* rev16 */
6996
                    gen_rev16(tmp);
6997
                    break;
6998
                case 0x0b: /* revsh */
6999
                    gen_revsh(tmp);
7000
                    break;
7001
                case 0x10: /* sel */
7002
                    tmp2 = load_reg(s, rm);
7003
                    tmp3 = new_tmp();
7004
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
7005
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7006
                    dead_tmp(tmp3);
7007
                    dead_tmp(tmp2);
7008
                    break;
7009
                case 0x18: /* clz */
7010
                    gen_helper_clz(tmp, tmp);
7011
                    break;
7012
                default:
7013
                    goto illegal_op;
7014
                }
7015
            }
7016
            store_reg(s, rd, tmp);
7017
            break;
7018
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
7019
            op = (insn >> 4) & 0xf;
7020
            tmp = load_reg(s, rn);
7021
            tmp2 = load_reg(s, rm);
7022
            switch ((insn >> 20) & 7) {
7023
            case 0: /* 32 x 32 -> 32 */
7024
                tcg_gen_mul_i32(tmp, tmp, tmp2);
7025
                dead_tmp(tmp2);
7026
                if (rs != 15) {
7027
                    tmp2 = load_reg(s, rs);
7028
                    if (op)
7029
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7030
                    else
7031
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7032
                    dead_tmp(tmp2);
7033
                }
7034
                break;
7035
            case 1: /* 16 x 16 -> 32 */
7036
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
7037
                dead_tmp(tmp2);
7038
                if (rs != 15) {
7039
                    tmp2 = load_reg(s, rs);
7040
                    gen_helper_add_setq(tmp, tmp, tmp2);
7041
                    dead_tmp(tmp2);
7042
                }
7043
                break;
7044
            case 2: /* Dual multiply add.  */
7045
            case 4: /* Dual multiply subtract.  */
7046
                if (op)
7047
                    gen_swap_half(tmp2);
7048
                gen_smul_dual(tmp, tmp2);
7049
                /* This addition cannot overflow.  */
7050
                if (insn & (1 << 22)) {
7051
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7052
                } else {
7053
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7054
                }
7055
                dead_tmp(tmp2);
7056
                if (rs != 15)
7057
                  {
7058
                    tmp2 = load_reg(s, rs);
7059
                    gen_helper_add_setq(tmp, tmp, tmp2);
7060
                    dead_tmp(tmp2);
7061
                  }
7062
                break;
7063
            case 3: /* 32 * 16 -> 32msb */
7064
                if (op)
7065
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7066
                else
7067
                    gen_sxth(tmp2);
7068
                tmp2 = gen_muls_i64_i32(tmp, tmp2);
7069
                tcg_gen_shri_i64(tmp2, tmp2, 16);
7070
                tmp = new_tmp();
7071
                tcg_gen_trunc_i64_i32(tmp, tmp2);
7072
                if (rs != 15)
7073
                  {
7074
                    tmp2 = load_reg(s, rs);
7075
                    gen_helper_add_setq(tmp, tmp, tmp2);
7076
                    dead_tmp(tmp2);
7077
                  }
7078
                break;
7079
            case 5: case 6: /* 32 * 32 -> 32msb */
7080
                gen_imull(tmp, tmp2);
7081
                if (insn & (1 << 5)) {
7082
                    gen_roundqd(tmp, tmp2);
7083
                    dead_tmp(tmp2);
7084
                } else {
7085
                    dead_tmp(tmp);
7086
                    tmp = tmp2;
7087
                }
7088
                if (rs != 15) {
7089
                    tmp2 = load_reg(s, rs);
7090
                    if (insn & (1 << 21)) {
7091
                        tcg_gen_add_i32(tmp, tmp, tmp2);
7092
                    } else {
7093
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
7094
                    }
7095
                    dead_tmp(tmp2);
7096
                }
7097
                break;
7098
            case 7: /* Unsigned sum of absolute differences.  */
7099
                gen_helper_usad8(tmp, tmp, tmp2);
7100
                dead_tmp(tmp2);
7101
                if (rs != 15) {
7102
                    tmp2 = load_reg(s, rs);
7103
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7104
                    dead_tmp(tmp2);
7105
                }
7106
                break;
7107
            }
7108
            store_reg(s, rd, tmp);
7109
            break;
7110
        case 6: case 7: /* 64-bit multiply, Divide.  */
7111
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7112
            tmp = load_reg(s, rn);
7113
            tmp2 = load_reg(s, rm);
7114
            if ((op & 0x50) == 0x10) {
7115
                /* sdiv, udiv */
7116
                if (!arm_feature(env, ARM_FEATURE_DIV))
7117
                    goto illegal_op;
7118
                if (op & 0x20)
7119
                    gen_helper_udiv(tmp, tmp, tmp2);
7120
                else
7121
                    gen_helper_sdiv(tmp, tmp, tmp2);
7122
                dead_tmp(tmp2);
7123
                store_reg(s, rd, tmp);
7124
            } else if ((op & 0xe) == 0xc) {
7125
                /* Dual multiply accumulate long.  */
7126
                if (op & 1)
7127
                    gen_swap_half(tmp2);
7128
                gen_smul_dual(tmp, tmp2);
7129
                if (op & 0x10) {
7130
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7131
                } else {
7132
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7133
                }
7134
                dead_tmp(tmp2);
7135
                tmp2 = tcg_temp_new(TCG_TYPE_I64);
7136
                gen_addq(s, tmp, rs, rd);
7137
                gen_storeq_reg(s, rs, rd, tmp);
7138
            } else {
7139
                if (op & 0x20) {
7140
                    /* Unsigned 64-bit multiply  */
7141
                    tmp = gen_mulu_i64_i32(tmp, tmp2);
7142
                } else {
7143
                    if (op & 8) {
7144
                        /* smlalxy */
7145
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7146
                        dead_tmp(tmp2);
7147
                        tmp2 = tcg_temp_new(TCG_TYPE_I64);
7148
                        tcg_gen_ext_i32_i64(tmp2, tmp);
7149
                        dead_tmp(tmp);
7150
                        tmp = tmp2;
7151
                    } else {
7152
                        /* Signed 64-bit multiply  */
7153
                        tmp = gen_muls_i64_i32(tmp, tmp2);
7154
                    }
7155
                }
7156
                if (op & 4) {
7157
                    /* umaal */
7158
                    gen_addq_lo(s, tmp, rs);
7159
                    gen_addq_lo(s, tmp, rd);
7160
                } else if (op & 0x40) {
7161
                    /* 64-bit accumulate.  */
7162
                    gen_addq(s, tmp, rs, rd);
7163
                }
7164
                gen_storeq_reg(s, rs, rd, tmp);
7165
            }
7166
            break;
7167
        }
7168
        break;
7169
    case 6: case 7: case 14: case 15:
7170
        /* Coprocessor.  */
7171
        if (((insn >> 24) & 3) == 3) {
7172
            /* Translate into the equivalent ARM encoding.  */
7173
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
7174
            if (disas_neon_data_insn(env, s, insn))
7175
                goto illegal_op;
7176
        } else {
7177
            if (insn & (1 << 28))
7178
                goto illegal_op;
7179
            if (disas_coproc_insn (env, s, insn))
7180
                goto illegal_op;
7181
        }
7182
        break;
7183
    case 8: case 9: case 10: case 11:
7184
        if (insn & (1 << 15)) {
7185
            /* Branches, misc control.  */
7186
            if (insn & 0x5000) {
7187
                /* Unconditional branch.  */
7188
                /* signextend(hw1[10:0]) -> offset[:12].  */
7189
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
7190
                /* hw1[10:0] -> offset[11:1].  */
7191
                offset |= (insn & 0x7ff) << 1;
7192
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
7193
                   offset[24:22] already have the same value because of the
7194
                   sign extension above.  */
7195
                offset ^= ((~insn) & (1 << 13)) << 10;
7196
                offset ^= ((~insn) & (1 << 11)) << 11;
7197

    
7198
                if (insn & (1 << 14)) {
7199
                    /* Branch and link.  */
7200
                    gen_op_movl_T1_im(s->pc | 1);
7201
                    gen_movl_reg_T1(s, 14);
7202
                }
7203

    
7204
                offset += s->pc;
7205
                if (insn & (1 << 12)) {
7206
                    /* b/bl */
7207
                    gen_jmp(s, offset);
7208
                } else {
7209
                    /* blx */
7210
                    offset &= ~(uint32_t)2;
7211
                    gen_bx_im(s, offset);
7212
                }
7213
            } else if (((insn >> 23) & 7) == 7) {
7214
                /* Misc control */
7215
                if (insn & (1 << 13))
7216
                    goto illegal_op;
7217

    
7218
                if (insn & (1 << 26)) {
7219
                    /* Secure monitor call (v6Z) */
7220
                    goto illegal_op; /* not implemented.  */
7221
                } else {
7222
                    op = (insn >> 20) & 7;
7223
                    switch (op) {
7224
                    case 0: /* msr cpsr.  */
7225
                        if (IS_M(env)) {
7226
                            tmp = load_reg(s, rn);
7227
                            addr = tcg_const_i32(insn & 0xff);
7228
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
7229
                            gen_lookup_tb(s);
7230
                            break;
7231
                        }
7232
                        /* fall through */
7233
                    case 1: /* msr spsr.  */
7234
                        if (IS_M(env))
7235
                            goto illegal_op;
7236
                        gen_movl_T0_reg(s, rn);
7237
                        if (gen_set_psr_T0(s,
7238
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
7239
                              op == 1))
7240
                            goto illegal_op;
7241
                        break;
7242
                    case 2: /* cps, nop-hint.  */
7243
                        if (((insn >> 8) & 7) == 0) {
7244
                            gen_nop_hint(s, insn & 0xff);
7245
                        }
7246
                        /* Implemented as NOP in user mode.  */
7247
                        if (IS_USER(s))
7248
                            break;
7249
                        offset = 0;
7250
                        imm = 0;
7251
                        if (insn & (1 << 10)) {
7252
                            if (insn & (1 << 7))
7253
                                offset |= CPSR_A;
7254
                            if (insn & (1 << 6))
7255
                                offset |= CPSR_I;
7256
                            if (insn & (1 << 5))
7257
                                offset |= CPSR_F;
7258
                            if (insn & (1 << 9))
7259
                                imm = CPSR_A | CPSR_I | CPSR_F;
7260
                        }
7261
                        if (insn & (1 << 8)) {
7262
                            offset |= 0x1f;
7263
                            imm |= (insn & 0x1f);
7264
                        }
7265
                        if (offset) {
7266
                            gen_op_movl_T0_im(imm);
7267
                            gen_set_psr_T0(s, offset, 0);
7268
                        }
7269
                        break;
7270
                    case 3: /* Special control operations.  */
7271
                        op = (insn >> 4) & 0xf;
7272
                        switch (op) {
7273
                        case 2: /* clrex */
7274
                            gen_op_clrex();
7275
                            break;
7276
                        case 4: /* dsb */
7277
                        case 5: /* dmb */
7278
                        case 6: /* isb */
7279
                            /* These execute as NOPs.  */
7280
                            ARCH(7);
7281
                            break;
7282
                        default:
7283
                            goto illegal_op;
7284
                        }
7285
                        break;
7286
                    case 4: /* bxj */
7287
                        /* Trivial implementation equivalent to bx.  */
7288
                        tmp = load_reg(s, rn);
7289
                        gen_bx(s, tmp);
7290
                        break;
7291
                    case 5: /* Exception return.  */
7292
                        /* Unpredictable in user mode.  */
7293
                        goto illegal_op;
7294
                    case 6: /* mrs cpsr.  */
7295
                        tmp = new_tmp();
7296
                        if (IS_M(env)) {
7297
                            addr = tcg_const_i32(insn & 0xff);
7298
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
7299
                        } else {
7300
                            gen_helper_cpsr_read(tmp);
7301
                        }
7302
                        store_reg(s, rd, tmp);
7303
                        break;
7304
                    case 7: /* mrs spsr.  */
7305
                        /* Not accessible in user mode.  */
7306
                        if (IS_USER(s) || IS_M(env))
7307
                            goto illegal_op;
7308
                        tmp = load_cpu_field(spsr);
7309
                        store_reg(s, rd, tmp);
7310
                        break;
7311
                    }
7312
                }
7313
            } else {
7314
                /* Conditional branch.  */
7315
                op = (insn >> 22) & 0xf;
7316
                /* Generate a conditional jump to next instruction.  */
7317
                s->condlabel = gen_new_label();
7318
                gen_test_cc(op ^ 1, s->condlabel);
7319
                s->condjmp = 1;
7320

    
7321
                /* offset[11:1] = insn[10:0] */
7322
                offset = (insn & 0x7ff) << 1;
7323
                /* offset[17:12] = insn[21:16].  */
7324
                offset |= (insn & 0x003f0000) >> 4;
7325
                /* offset[31:20] = insn[26].  */
7326
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
7327
                /* offset[18] = insn[13].  */
7328
                offset |= (insn & (1 << 13)) << 5;
7329
                /* offset[19] = insn[11].  */
7330
                offset |= (insn & (1 << 11)) << 8;
7331

    
7332
                /* jump to the offset */
7333
                gen_jmp(s, s->pc + offset);
7334
            }
7335
        } else {
7336
            /* Data processing immediate.  */
7337
            if (insn & (1 << 25)) {
7338
                if (insn & (1 << 24)) {
7339
                    if (insn & (1 << 20))
7340
                        goto illegal_op;
7341
                    /* Bitfield/Saturate.  */
7342
                    op = (insn >> 21) & 7;
7343
                    imm = insn & 0x1f;
7344
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
7345
                    if (rn == 15) {
7346
                        tmp = new_tmp();
7347
                        tcg_gen_movi_i32(tmp, 0);
7348
                    } else {
7349
                        tmp = load_reg(s, rn);
7350
                    }
7351
                    switch (op) {
7352
                    case 2: /* Signed bitfield extract.  */
7353
                        imm++;
7354
                        if (shift + imm > 32)
7355
                            goto illegal_op;
7356
                        if (imm < 32)
7357
                            gen_sbfx(tmp, shift, imm);
7358
                        break;
7359
                    case 6: /* Unsigned bitfield extract.  */
7360
                        imm++;
7361
                        if (shift + imm > 32)
7362
                            goto illegal_op;
7363
                        if (imm < 32)
7364
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
7365
                        break;
7366
                    case 3: /* Bitfield insert/clear.  */
7367
                        if (imm < shift)
7368
                            goto illegal_op;
7369
                        imm = imm + 1 - shift;
7370
                        if (imm != 32) {
7371
                            tmp2 = load_reg(s, rd);
7372
                            gen_bfi(tmp, tmp2, tmp,
7373
                                    shift, ((1u << imm) - 1) << shift);
7374
                            dead_tmp(tmp2);
7375
                        }
7376
                        break;
7377
                    case 7:
7378
                        goto illegal_op;
7379
                    default: /* Saturate.  */
7380
                        if (shift) {
7381
                            if (op & 1)
7382
                                tcg_gen_sari_i32(tmp, tmp, shift);
7383
                            else
7384
                                tcg_gen_shli_i32(tmp, tmp, shift);
7385
                        }
7386
                        tmp2 = tcg_const_i32(imm);
7387
                        if (op & 4) {
7388
                            /* Unsigned.  */
7389
                            if ((op & 1) && shift == 0)
7390
                                gen_helper_usat16(tmp, tmp, tmp2);
7391
                            else
7392
                                gen_helper_usat(tmp, tmp, tmp2);
7393
                        } else {
7394
                            /* Signed.  */
7395
                            if ((op & 1) && shift == 0)
7396
                                gen_helper_ssat16(tmp, tmp, tmp2);
7397
                            else
7398
                                gen_helper_ssat(tmp, tmp, tmp2);
7399
                        }
7400
                        break;
7401
                    }
7402
                    store_reg(s, rd, tmp);
7403
                } else {
7404
                    imm = ((insn & 0x04000000) >> 15)
7405
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
7406
                    if (insn & (1 << 22)) {
7407
                        /* 16-bit immediate.  */
7408
                        imm |= (insn >> 4) & 0xf000;
7409
                        if (insn & (1 << 23)) {
7410
                            /* movt */
7411
                            tmp = load_reg(s, rd);
7412
                            tcg_gen_andi_i32(tmp, tmp, 0xffff);
7413
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
7414
                        } else {
7415
                            /* movw */
7416
                            tmp = new_tmp();
7417
                            tcg_gen_movi_i32(tmp, imm);
7418
                        }
7419
                    } else {
7420
                        /* Add/sub 12-bit immediate.  */
7421
                        if (rn == 15) {
7422
                            offset = s->pc & ~(uint32_t)3;
7423
                            if (insn & (1 << 23))
7424
                                offset -= imm;
7425
                            else
7426
                                offset += imm;
7427
                            tmp = new_tmp();
7428
                            tcg_gen_movi_i32(tmp, offset);
7429
                        } else {
7430
                            tmp = load_reg(s, rn);
7431
                            if (insn & (1 << 23))
7432
                                tcg_gen_subi_i32(tmp, tmp, imm);
7433
                            else
7434
                                tcg_gen_addi_i32(tmp, tmp, imm);
7435
                        }
7436
                    }
7437
                    store_reg(s, rd, tmp);
7438
                }
7439
            } else {
7440
                int shifter_out = 0;
7441
                /* modified 12-bit immediate.  */
7442
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
7443
                imm = (insn & 0xff);
7444
                switch (shift) {
7445
                case 0: /* XY */
7446
                    /* Nothing to do.  */
7447
                    break;
7448
                case 1: /* 00XY00XY */
7449
                    imm |= imm << 16;
7450
                    break;
7451
                case 2: /* XY00XY00 */
7452
                    imm |= imm << 16;
7453
                    imm <<= 8;
7454
                    break;
7455
                case 3: /* XYXYXYXY */
7456
                    imm |= imm << 16;
7457
                    imm |= imm << 8;
7458
                    break;
7459
                default: /* Rotated constant.  */
7460
                    shift = (shift << 1) | (imm >> 7);
7461
                    imm |= 0x80;
7462
                    imm = imm << (32 - shift);
7463
                    shifter_out = 1;
7464
                    break;
7465
                }
7466
                gen_op_movl_T1_im(imm);
7467
                rn = (insn >> 16) & 0xf;
7468
                if (rn == 15)
7469
                    gen_op_movl_T0_im(0);
7470
                else
7471
                    gen_movl_T0_reg(s, rn);
7472
                op = (insn >> 21) & 0xf;
7473
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
7474
                                       shifter_out))
7475
                    goto illegal_op;
7476
                rd = (insn >> 8) & 0xf;
7477
                if (rd != 15) {
7478
                    gen_movl_reg_T0(s, rd);
7479
                }
7480
            }
7481
        }
7482
        break;
7483
    case 12: /* Load/store single data item.  */
7484
        {
7485
        int postinc = 0;
7486
        int writeback = 0;
7487
        int user;
7488
        if ((insn & 0x01100000) == 0x01000000) {
7489
            if (disas_neon_ls_insn(env, s, insn))
7490
                goto illegal_op;
7491
            break;
7492
        }
7493
        user = IS_USER(s);
7494
        if (rn == 15) {
7495
            addr = new_tmp();
7496
            /* PC relative.  */
7497
            /* s->pc has already been incremented by 4.  */
7498
            imm = s->pc & 0xfffffffc;
7499
            if (insn & (1 << 23))
7500
                imm += insn & 0xfff;
7501
            else
7502
                imm -= insn & 0xfff;
7503
            tcg_gen_movi_i32(addr, imm);
7504
        } else {
7505
            addr = load_reg(s, rn);
7506
            if (insn & (1 << 23)) {
7507
                /* Positive offset.  */
7508
                imm = insn & 0xfff;
7509
                tcg_gen_addi_i32(addr, addr, imm);
7510
            } else {
7511
                op = (insn >> 8) & 7;
7512
                imm = insn & 0xff;
7513
                switch (op) {
7514
                case 0: case 8: /* Shifted Register.  */
7515
                    shift = (insn >> 4) & 0xf;
7516
                    if (shift > 3)
7517
                        goto illegal_op;
7518
                    tmp = load_reg(s, rm);
7519
                    if (shift)
7520
                        tcg_gen_shli_i32(tmp, tmp, shift);
7521
                    tcg_gen_add_i32(addr, addr, tmp);
7522
                    dead_tmp(tmp);
7523
                    break;
7524
                case 4: /* Negative offset.  */
7525
                    tcg_gen_addi_i32(addr, addr, -imm);
7526
                    break;
7527
                case 6: /* User privilege.  */
7528
                    tcg_gen_addi_i32(addr, addr, imm);
7529
                    user = 1;
7530
                    break;
7531
                case 1: /* Post-decrement.  */
7532
                    imm = -imm;
7533
                    /* Fall through.  */
7534
                case 3: /* Post-increment.  */
7535
                    postinc = 1;
7536
                    writeback = 1;
7537
                    break;
7538
                case 5: /* Pre-decrement.  */
7539
                    imm = -imm;
7540
                    /* Fall through.  */
7541
                case 7: /* Pre-increment.  */
7542
                    tcg_gen_addi_i32(addr, addr, imm);
7543
                    writeback = 1;
7544
                    break;
7545
                default:
7546
                    goto illegal_op;
7547
                }
7548
            }
7549
        }
7550
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
7551
        if (insn & (1 << 20)) {
7552
            /* Load.  */
7553
            if (rs == 15 && op != 2) {
7554
                if (op & 2)
7555
                    goto illegal_op;
7556
                /* Memory hint.  Implemented as NOP.  */
7557
            } else {
7558
                switch (op) {
7559
                case 0: tmp = gen_ld8u(addr, user); break;
7560
                case 4: tmp = gen_ld8s(addr, user); break;
7561
                case 1: tmp = gen_ld16u(addr, user); break;
7562
                case 5: tmp = gen_ld16s(addr, user); break;
7563
                case 2: tmp = gen_ld32(addr, user); break;
7564
                default: goto illegal_op;
7565
                }
7566
                if (rs == 15) {
7567
                    gen_bx(s, tmp);
7568
                } else {
7569
                    store_reg(s, rs, tmp);
7570
                }
7571
            }
7572
        } else {
7573
            /* Store.  */
7574
            if (rs == 15)
7575
                goto illegal_op;
7576
            tmp = load_reg(s, rs);
7577
            switch (op) {
7578
            case 0: gen_st8(tmp, addr, user); break;
7579
            case 1: gen_st16(tmp, addr, user); break;
7580
            case 2: gen_st32(tmp, addr, user); break;
7581
            default: goto illegal_op;
7582
            }
7583
        }
7584
        if (postinc)
7585
            tcg_gen_addi_i32(addr, addr, imm);
7586
        if (writeback) {
7587
            store_reg(s, rn, addr);
7588
        } else {
7589
            dead_tmp(addr);
7590
        }
7591
        }
7592
        break;
7593
    default:
7594
        goto illegal_op;
7595
    }
7596
    return 0;
7597
illegal_op:
7598
    return 1;
7599
}
7600

    
7601
static void disas_thumb_insn(CPUState *env, DisasContext *s)
7602
{
7603
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
7604
    int32_t offset;
7605
    int i;
7606
    TCGv tmp;
7607
    TCGv tmp2;
7608
    TCGv addr;
7609

    
7610
    if (s->condexec_mask) {
7611
        cond = s->condexec_cond;
7612
        s->condlabel = gen_new_label();
7613
        gen_test_cc(cond ^ 1, s->condlabel);
7614
        s->condjmp = 1;
7615
    }
7616

    
7617
    insn = lduw_code(s->pc);
7618
    s->pc += 2;
7619

    
7620
    switch (insn >> 12) {
7621
    case 0: case 1:
7622
        rd = insn & 7;
7623
        op = (insn >> 11) & 3;
7624
        if (op == 3) {
7625
            /* add/subtract */
7626
            rn = (insn >> 3) & 7;
7627
            gen_movl_T0_reg(s, rn);
7628
            if (insn & (1 << 10)) {
7629
                /* immediate */
7630
                gen_op_movl_T1_im((insn >> 6) & 7);
7631
            } else {
7632
                /* reg */
7633
                rm = (insn >> 6) & 7;
7634
                gen_movl_T1_reg(s, rm);
7635
            }
7636
            if (insn & (1 << 9)) {
7637
                if (s->condexec_mask)
7638
                    gen_op_subl_T0_T1();
7639
                else
7640
                    gen_op_subl_T0_T1_cc();
7641
            } else {
7642
                if (s->condexec_mask)
7643
                    gen_op_addl_T0_T1();
7644
                else
7645
                    gen_op_addl_T0_T1_cc();
7646
            }
7647
            gen_movl_reg_T0(s, rd);
7648
        } else {
7649
            /* shift immediate */
7650
            rm = (insn >> 3) & 7;
7651
            shift = (insn >> 6) & 0x1f;
7652
            tmp = load_reg(s, rm);
7653
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
7654
            if (!s->condexec_mask)
7655
                gen_logic_CC(tmp);
7656
            store_reg(s, rd, tmp);
7657
        }
7658
        break;
7659
    case 2: case 3:
7660
        /* arithmetic large immediate */
7661
        op = (insn >> 11) & 3;
7662
        rd = (insn >> 8) & 0x7;
7663
        if (op == 0) {
7664
            gen_op_movl_T0_im(insn & 0xff);
7665
        } else {
7666
            gen_movl_T0_reg(s, rd);
7667
            gen_op_movl_T1_im(insn & 0xff);
7668
        }
7669
        switch (op) {
7670
        case 0: /* mov */
7671
            if (!s->condexec_mask)
7672
                gen_op_logic_T0_cc();
7673
            break;
7674
        case 1: /* cmp */
7675
            gen_op_subl_T0_T1_cc();
7676
            break;
7677
        case 2: /* add */
7678
            if (s->condexec_mask)
7679
                gen_op_addl_T0_T1();
7680
            else
7681
                gen_op_addl_T0_T1_cc();
7682
            break;
7683
        case 3: /* sub */
7684
            if (s->condexec_mask)
7685
                gen_op_subl_T0_T1();
7686
            else
7687
                gen_op_subl_T0_T1_cc();
7688
            break;
7689
        }
7690
        if (op != 1)
7691
            gen_movl_reg_T0(s, rd);
7692
        break;
7693
    case 4:
7694
        if (insn & (1 << 11)) {
7695
            rd = (insn >> 8) & 7;
7696
            /* load pc-relative.  Bit 1 of PC is ignored.  */
7697
            val = s->pc + 2 + ((insn & 0xff) * 4);
7698
            val &= ~(uint32_t)2;
7699
            addr = new_tmp();
7700
            tcg_gen_movi_i32(addr, val);
7701
            tmp = gen_ld32(addr, IS_USER(s));
7702
            dead_tmp(addr);
7703
            store_reg(s, rd, tmp);
7704
            break;
7705
        }
7706
        if (insn & (1 << 10)) {
7707
            /* data processing extended or blx */
7708
            rd = (insn & 7) | ((insn >> 4) & 8);
7709
            rm = (insn >> 3) & 0xf;
7710
            op = (insn >> 8) & 3;
7711
            switch (op) {
7712
            case 0: /* add */
7713
                gen_movl_T0_reg(s, rd);
7714
                gen_movl_T1_reg(s, rm);
7715
                gen_op_addl_T0_T1();
7716
                gen_movl_reg_T0(s, rd);
7717
                break;
7718
            case 1: /* cmp */
7719
                gen_movl_T0_reg(s, rd);
7720
                gen_movl_T1_reg(s, rm);
7721
                gen_op_subl_T0_T1_cc();
7722
                break;
7723
            case 2: /* mov/cpy */
7724
                gen_movl_T0_reg(s, rm);
7725
                gen_movl_reg_T0(s, rd);
7726
                break;
7727
            case 3:/* branch [and link] exchange thumb register */
7728
                tmp = load_reg(s, rm);
7729
                if (insn & (1 << 7)) {
7730
                    val = (uint32_t)s->pc | 1;
7731
                    tmp2 = new_tmp();
7732
                    tcg_gen_movi_i32(tmp2, val);
7733
                    store_reg(s, 14, tmp2);
7734
                }
7735
                gen_bx(s, tmp);
7736
                break;
7737
            }
7738
            break;
7739
        }
7740

    
7741
        /* data processing register */
7742
        rd = insn & 7;
7743
        rm = (insn >> 3) & 7;
7744
        op = (insn >> 6) & 0xf;
7745
        if (op == 2 || op == 3 || op == 4 || op == 7) {
7746
            /* the shift/rotate ops want the operands backwards */
7747
            val = rm;
7748
            rm = rd;
7749
            rd = val;
7750
            val = 1;
7751
        } else {
7752
            val = 0;
7753
        }
7754

    
7755
        if (op == 9) /* neg */
7756
            gen_op_movl_T0_im(0);
7757
        else if (op != 0xf) /* mvn doesn't read its first operand */
7758
            gen_movl_T0_reg(s, rd);
7759

    
7760
        gen_movl_T1_reg(s, rm);
7761
        switch (op) {
7762
        case 0x0: /* and */
7763
            gen_op_andl_T0_T1();
7764
            if (!s->condexec_mask)
7765
                gen_op_logic_T0_cc();
7766
            break;
7767
        case 0x1: /* eor */
7768
            gen_op_xorl_T0_T1();
7769
            if (!s->condexec_mask)
7770
                gen_op_logic_T0_cc();
7771
            break;
7772
        case 0x2: /* lsl */
7773
            if (s->condexec_mask) {
7774
                gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
7775
            } else {
7776
                gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
7777
                gen_op_logic_T1_cc();
7778
            }
7779
            break;
7780
        case 0x3: /* lsr */
7781
            if (s->condexec_mask) {
7782
                gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
7783
            } else {
7784
                gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
7785
                gen_op_logic_T1_cc();
7786
            }
7787
            break;
7788
        case 0x4: /* asr */
7789
            if (s->condexec_mask) {
7790
                gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
7791
            } else {
7792
                gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
7793
                gen_op_logic_T1_cc();
7794
            }
7795
            break;
7796
        case 0x5: /* adc */
7797
            if (s->condexec_mask)
7798
                gen_adc_T0_T1();
7799
            else
7800
                gen_op_adcl_T0_T1_cc();
7801
            break;
7802
        case 0x6: /* sbc */
7803
            if (s->condexec_mask)
7804
                gen_sbc_T0_T1();
7805
            else
7806
                gen_op_sbcl_T0_T1_cc();
7807
            break;
7808
        case 0x7: /* ror */
7809
            if (s->condexec_mask) {
7810
                gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
7811
            } else {
7812
                gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
7813
                gen_op_logic_T1_cc();
7814
            }
7815
            break;
7816
        case 0x8: /* tst */
7817
            gen_op_andl_T0_T1();
7818
            gen_op_logic_T0_cc();
7819
            rd = 16;
7820
            break;
7821
        case 0x9: /* neg */
7822
            if (s->condexec_mask)
7823
                gen_op_subl_T0_T1();
7824
            else
7825
                gen_op_subl_T0_T1_cc();
7826
            break;
7827
        case 0xa: /* cmp */
7828
            gen_op_subl_T0_T1_cc();
7829
            rd = 16;
7830
            break;
7831
        case 0xb: /* cmn */
7832
            gen_op_addl_T0_T1_cc();
7833
            rd = 16;
7834
            break;
7835
        case 0xc: /* orr */
7836
            gen_op_orl_T0_T1();
7837
            if (!s->condexec_mask)
7838
                gen_op_logic_T0_cc();
7839
            break;
7840
        case 0xd: /* mul */
7841
            gen_op_mull_T0_T1();
7842
            if (!s->condexec_mask)
7843
                gen_op_logic_T0_cc();
7844
            break;
7845
        case 0xe: /* bic */
7846
            gen_op_bicl_T0_T1();
7847
            if (!s->condexec_mask)
7848
                gen_op_logic_T0_cc();
7849
            break;
7850
        case 0xf: /* mvn */
7851
            gen_op_notl_T1();
7852
            if (!s->condexec_mask)
7853
                gen_op_logic_T1_cc();
7854
            val = 1;
7855
            rm = rd;
7856
            break;
7857
        }
7858
        if (rd != 16) {
7859
            if (val)
7860
                gen_movl_reg_T1(s, rm);
7861
            else
7862
                gen_movl_reg_T0(s, rd);
7863
        }
7864
        break;
7865

    
7866
    case 5:
7867
        /* load/store register offset.  */
7868
        rd = insn & 7;
7869
        rn = (insn >> 3) & 7;
7870
        rm = (insn >> 6) & 7;
7871
        op = (insn >> 9) & 7;
7872
        addr = load_reg(s, rn);
7873
        tmp = load_reg(s, rm);
7874
        tcg_gen_add_i32(addr, addr, tmp);
7875
        dead_tmp(tmp);
7876

    
7877
        if (op < 3) /* store */
7878
            tmp = load_reg(s, rd);
7879

    
7880
        switch (op) {
7881
        case 0: /* str */
7882
            gen_st32(tmp, addr, IS_USER(s));
7883
            break;
7884
        case 1: /* strh */
7885
            gen_st16(tmp, addr, IS_USER(s));
7886
            break;
7887
        case 2: /* strb */
7888
            gen_st8(tmp, addr, IS_USER(s));
7889
            break;
7890
        case 3: /* ldrsb */
7891
            tmp = gen_ld8s(addr, IS_USER(s));
7892
            break;
7893
        case 4: /* ldr */
7894
            tmp = gen_ld32(addr, IS_USER(s));
7895
            break;
7896
        case 5: /* ldrh */
7897
            tmp = gen_ld16u(addr, IS_USER(s));
7898
            break;
7899
        case 6: /* ldrb */
7900
            tmp = gen_ld8u(addr, IS_USER(s));
7901
            break;
7902
        case 7: /* ldrsh */
7903
            tmp = gen_ld16s(addr, IS_USER(s));
7904
            break;
7905
        }
7906
        if (op >= 3) /* load */
7907
            store_reg(s, rd, tmp);
7908
        dead_tmp(addr);
7909
        break;
7910

    
7911
    case 6:
7912
        /* load/store word immediate offset */
7913
        rd = insn & 7;
7914
        rn = (insn >> 3) & 7;
7915
        addr = load_reg(s, rn);
7916
        val = (insn >> 4) & 0x7c;
7917
        tcg_gen_addi_i32(addr, addr, val);
7918

    
7919
        if (insn & (1 << 11)) {
7920
            /* load */
7921
            tmp = gen_ld32(addr, IS_USER(s));
7922
            store_reg(s, rd, tmp);
7923
        } else {
7924
            /* store */
7925
            tmp = load_reg(s, rd);
7926
            gen_st32(tmp, addr, IS_USER(s));
7927
        }
7928
        dead_tmp(addr);
7929
        break;
7930

    
7931
    case 7:
7932
        /* load/store byte immediate offset */
7933
        rd = insn & 7;
7934
        rn = (insn >> 3) & 7;
7935
        addr = load_reg(s, rn);
7936
        val = (insn >> 6) & 0x1f;
7937
        tcg_gen_addi_i32(addr, addr, val);
7938

    
7939
        if (insn & (1 << 11)) {
7940
            /* load */
7941
            tmp = gen_ld8u(addr, IS_USER(s));
7942
            store_reg(s, rd, tmp);
7943
        } else {
7944
            /* store */
7945
            tmp = load_reg(s, rd);
7946
            gen_st8(tmp, addr, IS_USER(s));
7947
        }
7948
        dead_tmp(addr);
7949
        break;
7950

    
7951
    case 8:
7952
        /* load/store halfword immediate offset */
7953
        rd = insn & 7;
7954
        rn = (insn >> 3) & 7;
7955
        addr = load_reg(s, rn);
7956
        val = (insn >> 5) & 0x3e;
7957
        tcg_gen_addi_i32(addr, addr, val);
7958

    
7959
        if (insn & (1 << 11)) {
7960
            /* load */
7961
            tmp = gen_ld16u(addr, IS_USER(s));
7962
            store_reg(s, rd, tmp);
7963
        } else {
7964
            /* store */
7965
            tmp = load_reg(s, rd);
7966
            gen_st16(tmp, addr, IS_USER(s));
7967
        }
7968
        dead_tmp(addr);
7969
        break;
7970

    
7971
    case 9:
7972
        /* load/store from stack */
7973
        rd = (insn >> 8) & 7;
7974
        addr = load_reg(s, 13);
7975
        val = (insn & 0xff) * 4;
7976
        tcg_gen_addi_i32(addr, addr, val);
7977

    
7978
        if (insn & (1 << 11)) {
7979
            /* load */
7980
            tmp = gen_ld32(addr, IS_USER(s));
7981
            store_reg(s, rd, tmp);
7982
        } else {
7983
            /* store */
7984
            tmp = load_reg(s, rd);
7985
            gen_st32(tmp, addr, IS_USER(s));
7986
        }
7987
        dead_tmp(addr);
7988
        break;
7989

    
7990
    case 10:
7991
        /* add to high reg */
7992
        rd = (insn >> 8) & 7;
7993
        if (insn & (1 << 11)) {
7994
            /* SP */
7995
            tmp = load_reg(s, 13);
7996
        } else {
7997
            /* PC. bit 1 is ignored.  */
7998
            tmp = new_tmp();
7999
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
8000
        }
8001
        val = (insn & 0xff) * 4;
8002
        tcg_gen_addi_i32(tmp, tmp, val);
8003
        store_reg(s, rd, tmp);
8004
        break;
8005

    
8006
    case 11:
8007
        /* misc */
8008
        op = (insn >> 8) & 0xf;
8009
        switch (op) {
8010
        case 0:
8011
            /* adjust stack pointer */
8012
            tmp = load_reg(s, 13);
8013
            val = (insn & 0x7f) * 4;
8014
            if (insn & (1 << 7))
8015
              val = -(int32_t)val;
8016
            tcg_gen_addi_i32(tmp, tmp, val);
8017
            store_reg(s, 13, tmp);
8018
            break;
8019

    
8020
        case 2: /* sign/zero extend.  */
8021
            ARCH(6);
8022
            rd = insn & 7;
8023
            rm = (insn >> 3) & 7;
8024
            tmp = load_reg(s, rm);
8025
            switch ((insn >> 6) & 3) {
8026
            case 0: gen_sxth(tmp); break;
8027
            case 1: gen_sxtb(tmp); break;
8028
            case 2: gen_uxth(tmp); break;
8029
            case 3: gen_uxtb(tmp); break;
8030
            }
8031
            store_reg(s, rd, tmp);
8032
            break;
8033
        case 4: case 5: case 0xc: case 0xd:
8034
            /* push/pop */
8035
            addr = load_reg(s, 13);
8036
            if (insn & (1 << 8))
8037
                offset = 4;
8038
            else
8039
                offset = 0;
8040
            for (i = 0; i < 8; i++) {
8041
                if (insn & (1 << i))
8042
                    offset += 4;
8043
            }
8044
            if ((insn & (1 << 11)) == 0) {
8045
                tcg_gen_addi_i32(addr, addr, -offset);
8046
            }
8047
            for (i = 0; i < 8; i++) {
8048
                if (insn & (1 << i)) {
8049
                    if (insn & (1 << 11)) {
8050
                        /* pop */
8051
                        tmp = gen_ld32(addr, IS_USER(s));
8052
                        store_reg(s, i, tmp);
8053
                    } else {
8054
                        /* push */
8055
                        tmp = load_reg(s, i);
8056
                        gen_st32(tmp, addr, IS_USER(s));
8057
                    }
8058
                    /* advance to the next address.  */
8059
                    tcg_gen_addi_i32(addr, addr, 4);
8060
                }
8061
            }
8062
            if (insn & (1 << 8)) {
8063
                if (insn & (1 << 11)) {
8064
                    /* pop pc */
8065
                    tmp = gen_ld32(addr, IS_USER(s));
8066
                    /* don't set the pc until the rest of the instruction
8067
                       has completed */
8068
                } else {
8069
                    /* push lr */
8070
                    tmp = load_reg(s, 14);
8071
                    gen_st32(tmp, addr, IS_USER(s));
8072
                }
8073
                tcg_gen_addi_i32(addr, addr, 4);
8074
            }
8075
            if ((insn & (1 << 11)) == 0) {
8076
                tcg_gen_addi_i32(addr, addr, -offset);
8077
            }
8078
            /* write back the new stack pointer */
8079
            store_reg(s, 13, addr);
8080
            /* set the new PC value */
8081
            if ((insn & 0x0900) == 0x0900)
8082
                gen_bx(s, tmp);
8083
            break;
8084

    
8085
        case 1: case 3: case 9: case 11: /* czb */
8086
            rm = insn & 7;
8087
            tmp = load_reg(s, rm);
8088
            tmp2 = tcg_const_i32(0);
8089
            s->condlabel = gen_new_label();
8090
            s->condjmp = 1;
8091
            if (insn & (1 << 11))
8092
                tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, s->condlabel);
8093
            else
8094
                tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, s->condlabel);
8095
            dead_tmp(tmp);
8096
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
8097
            val = (uint32_t)s->pc + 2;
8098
            val += offset;
8099
            gen_jmp(s, val);
8100
            break;
8101

    
8102
        case 15: /* IT, nop-hint.  */
8103
            if ((insn & 0xf) == 0) {
8104
                gen_nop_hint(s, (insn >> 4) & 0xf);
8105
                break;
8106
            }
8107
            /* If Then.  */
8108
            s->condexec_cond = (insn >> 4) & 0xe;
8109
            s->condexec_mask = insn & 0x1f;
8110
            /* No actual code generated for this insn, just setup state.  */
8111
            break;
8112

    
8113
        case 0xe: /* bkpt */
8114
            gen_set_condexec(s);
8115
            gen_set_pc_im(s->pc - 2);
8116
            gen_exception(EXCP_BKPT);
8117
            s->is_jmp = DISAS_JUMP;
8118
            break;
8119

    
8120
        case 0xa: /* rev */
8121
            ARCH(6);
8122
            rn = (insn >> 3) & 0x7;
8123
            rd = insn & 0x7;
8124
            tmp = load_reg(s, rn);
8125
            switch ((insn >> 6) & 3) {
8126
            case 0: tcg_gen_bswap_i32(tmp, tmp); break;
8127
            case 1: gen_rev16(tmp); break;
8128
            case 3: gen_revsh(tmp); break;
8129
            default: goto illegal_op;
8130
            }
8131
            store_reg(s, rd, tmp);
8132
            break;
8133

    
8134
        case 6: /* cps */
8135
            ARCH(6);
8136
            if (IS_USER(s))
8137
                break;
8138
            if (IS_M(env)) {
8139
                tmp = tcg_const_i32((insn & (1 << 4)) != 0);
8140
                /* PRIMASK */
8141
                if (insn & 1) {
8142
                    addr = tcg_const_i32(16);
8143
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8144
                }
8145
                /* FAULTMASK */
8146
                if (insn & 2) {
8147
                    addr = tcg_const_i32(17);
8148
                    gen_helper_v7m_msr(cpu_env, addr, tmp);
8149
                }
8150
                gen_lookup_tb(s);
8151
            } else {
8152
                if (insn & (1 << 4))
8153
                    shift = CPSR_A | CPSR_I | CPSR_F;
8154
                else
8155
                    shift = 0;
8156

    
8157
                val = ((insn & 7) << 6) & shift;
8158
                gen_op_movl_T0_im(val);
8159
                gen_set_psr_T0(s, shift, 0);
8160
            }
8161
            break;
8162

    
8163
        default:
8164
            goto undef;
8165
        }
8166
        break;
8167

    
8168
    case 12:
8169
        /* load/store multiple */
8170
        rn = (insn >> 8) & 0x7;
8171
        addr = load_reg(s, rn);
8172
        for (i = 0; i < 8; i++) {
8173
            if (insn & (1 << i)) {
8174
                if (insn & (1 << 11)) {
8175
                    /* load */
8176
                    tmp = gen_ld32(addr, IS_USER(s));
8177
                    store_reg(s, i, tmp);
8178
                } else {
8179
                    /* store */
8180
                    tmp = load_reg(s, i);
8181
                    gen_st32(tmp, addr, IS_USER(s));
8182
                }
8183
                /* advance to the next address */
8184
                tcg_gen_addi_i32(addr, addr, 4);
8185
            }
8186
        }
8187
        /* Base register writeback.  */
8188
        if ((insn & (1 << rn)) == 0) {
8189
            store_reg(s, rn, addr);
8190
        } else {
8191
            dead_tmp(addr);
8192
        }
8193
        break;
8194

    
8195
    case 13:
8196
        /* conditional branch or swi */
8197
        cond = (insn >> 8) & 0xf;
8198
        if (cond == 0xe)
8199
            goto undef;
8200

    
8201
        if (cond == 0xf) {
8202
            /* swi */
8203
            gen_set_condexec(s);
8204
            gen_set_pc_im(s->pc | 1);
8205
            s->is_jmp = DISAS_SWI;
8206
            break;
8207
        }
8208
        /* generate a conditional jump to next instruction */
8209
        s->condlabel = gen_new_label();
8210
        gen_test_cc(cond ^ 1, s->condlabel);
8211
        s->condjmp = 1;
8212
        gen_movl_T1_reg(s, 15);
8213

    
8214
        /* jump to the offset */
8215
        val = (uint32_t)s->pc + 2;
8216
        offset = ((int32_t)insn << 24) >> 24;
8217
        val += offset << 1;
8218
        gen_jmp(s, val);
8219
        break;
8220

    
8221
    case 14:
8222
        if (insn & (1 << 11)) {
8223
            if (disas_thumb2_insn(env, s, insn))
8224
              goto undef32;
8225
            break;
8226
        }
8227
        /* unconditional branch */
8228
        val = (uint32_t)s->pc;
8229
        offset = ((int32_t)insn << 21) >> 21;
8230
        val += (offset << 1) + 2;
8231
        gen_jmp(s, val);
8232
        break;
8233

    
8234
    case 15:
8235
        if (disas_thumb2_insn(env, s, insn))
8236
          goto undef32;
8237
        break;
8238
    }
8239
    return;
8240
undef32:
8241
    gen_set_condexec(s);
8242
    gen_set_pc_im(s->pc - 4);
8243
    gen_exception(EXCP_UDEF);
8244
    s->is_jmp = DISAS_JUMP;
8245
    return;
8246
illegal_op:
8247
undef:
8248
    gen_set_condexec(s);
8249
    gen_set_pc_im(s->pc - 2);
8250
    gen_exception(EXCP_UDEF);
8251
    s->is_jmp = DISAS_JUMP;
8252
}
8253

    
8254
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
8255
   basic block 'tb'. If search_pc is TRUE, also generate PC
8256
   information for each intermediate instruction. */
8257
static inline int gen_intermediate_code_internal(CPUState *env,
8258
                                                 TranslationBlock *tb,
8259
                                                 int search_pc)
8260
{
8261
    DisasContext dc1, *dc = &dc1;
8262
    uint16_t *gen_opc_end;
8263
    int j, lj;
8264
    target_ulong pc_start;
8265
    uint32_t next_page_start;
8266

    
8267
    /* generate intermediate code */
8268
    num_temps = 0;
8269
    memset(temps, 0, sizeof(temps));
8270

    
8271
    pc_start = tb->pc;
8272

    
8273
    dc->tb = tb;
8274

    
8275
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8276

    
8277
    dc->is_jmp = DISAS_NEXT;
8278
    dc->pc = pc_start;
8279
    dc->singlestep_enabled = env->singlestep_enabled;
8280
    dc->condjmp = 0;
8281
    dc->thumb = env->thumb;
8282
    dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
8283
    dc->condexec_cond = env->condexec_bits >> 4;
8284
    dc->is_mem = 0;
8285
#if !defined(CONFIG_USER_ONLY)
8286
    if (IS_M(env)) {
8287
        dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
8288
    } else {
8289
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
8290
    }
8291
#endif
8292
    cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
8293
    cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
8294
    cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
8295
    cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
8296
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8297
    lj = -1;
8298
    /* Reset the conditional execution bits immediately. This avoids
8299
       complications trying to do it at the end of the block.  */
8300
    if (env->condexec_bits)
8301
      {
8302
        TCGv tmp = new_tmp();
8303
        tcg_gen_movi_i32(tmp, 0);
8304
        store_cpu_field(tmp, condexec_bits);
8305
      }
8306
    do {
8307
#ifndef CONFIG_USER_ONLY
8308
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
8309
            /* We always get here via a jump, so know we are not in a
8310
               conditional execution block.  */
8311
            gen_exception(EXCP_EXCEPTION_EXIT);
8312
        }
8313
#endif
8314

    
8315
        if (env->nb_breakpoints > 0) {
8316
            for(j = 0; j < env->nb_breakpoints; j++) {
8317
                if (env->breakpoints[j] == dc->pc) {
8318
                    gen_set_condexec(dc);
8319
                    gen_set_pc_im(dc->pc);
8320
                    gen_exception(EXCP_DEBUG);
8321
                    dc->is_jmp = DISAS_JUMP;
8322
                    /* Advance PC so that clearing the breakpoint will
8323
                       invalidate this TB.  */
8324
                    dc->pc += 2;
8325
                    goto done_generating;
8326
                    break;
8327
                }
8328
            }
8329
        }
8330
        if (search_pc) {
8331
            j = gen_opc_ptr - gen_opc_buf;
8332
            if (lj < j) {
8333
                lj++;
8334
                while (lj < j)
8335
                    gen_opc_instr_start[lj++] = 0;
8336
            }
8337
            gen_opc_pc[lj] = dc->pc;
8338
            gen_opc_instr_start[lj] = 1;
8339
        }
8340

    
8341
        if (env->thumb) {
8342
            disas_thumb_insn(env, dc);
8343
            if (dc->condexec_mask) {
8344
                dc->condexec_cond = (dc->condexec_cond & 0xe)
8345
                                   | ((dc->condexec_mask >> 4) & 1);
8346
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
8347
                if (dc->condexec_mask == 0) {
8348
                    dc->condexec_cond = 0;
8349
                }
8350
            }
8351
        } else {
8352
            disas_arm_insn(env, dc);
8353
        }
8354
        if (num_temps) {
8355
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
8356
            num_temps = 0;
8357
        }
8358

    
8359
        if (dc->condjmp && !dc->is_jmp) {
8360
            gen_set_label(dc->condlabel);
8361
            dc->condjmp = 0;
8362
        }
8363
        /* Terminate the TB on memory ops if watchpoints are present.  */
8364
        /* FIXME: This should be replacd by the deterministic execution
8365
         * IRQ raising bits.  */
8366
        if (dc->is_mem && env->nb_watchpoints)
8367
            break;
8368

    
8369
        /* Translation stops when a conditional branch is enoutered.
8370
         * Otherwise the subsequent code could get translated several times.
8371
         * Also stop translation when a page boundary is reached.  This
8372
         * ensures prefech aborts occur at the right place.  */
8373
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
8374
             !env->singlestep_enabled &&
8375
             dc->pc < next_page_start);
8376

    
8377
    /* At this stage dc->condjmp will only be set when the skipped
8378
       instruction was a conditional branch or trap, and the PC has
8379
       already been written.  */
8380
    if (__builtin_expect(env->singlestep_enabled, 0)) {
8381
        /* Make sure the pc is updated, and raise a debug exception.  */
8382
        if (dc->condjmp) {
8383
            gen_set_condexec(dc);
8384
            if (dc->is_jmp == DISAS_SWI) {
8385
                gen_exception(EXCP_SWI);
8386
            } else {
8387
                gen_exception(EXCP_DEBUG);
8388
            }
8389
            gen_set_label(dc->condlabel);
8390
        }
8391
        if (dc->condjmp || !dc->is_jmp) {
8392
            gen_set_pc_im(dc->pc);
8393
            dc->condjmp = 0;
8394
        }
8395
        gen_set_condexec(dc);
8396
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
8397
            gen_exception(EXCP_SWI);
8398
        } else {
8399
            /* FIXME: Single stepping a WFI insn will not halt
8400
               the CPU.  */
8401
            gen_exception(EXCP_DEBUG);
8402
        }
8403
    } else {
8404
        /* While branches must always occur at the end of an IT block,
8405
           there are a few other things that can cause us to terminate
8406
           the TB in the middel of an IT block:
8407
            - Exception generating instructions (bkpt, swi, undefined).
8408
            - Page boundaries.
8409
            - Hardware watchpoints.
8410
           Hardware breakpoints have already been handled and skip this code.
8411
         */
8412
        gen_set_condexec(dc);
8413
        switch(dc->is_jmp) {
8414
        case DISAS_NEXT:
8415
            gen_goto_tb(dc, 1, dc->pc);
8416
            break;
8417
        default:
8418
        case DISAS_JUMP:
8419
        case DISAS_UPDATE:
8420
            /* indicate that the hash table must be used to find the next TB */
8421
            tcg_gen_exit_tb(0);
8422
            break;
8423
        case DISAS_TB_JUMP:
8424
            /* nothing more to generate */
8425
            break;
8426
        case DISAS_WFI:
8427
            gen_helper_wfi();
8428
            break;
8429
        case DISAS_SWI:
8430
            gen_exception(EXCP_SWI);
8431
            break;
8432
        }
8433
        if (dc->condjmp) {
8434
            gen_set_label(dc->condlabel);
8435
            gen_set_condexec(dc);
8436
            gen_goto_tb(dc, 1, dc->pc);
8437
            dc->condjmp = 0;
8438
        }
8439
    }
8440
done_generating:
8441
    *gen_opc_ptr = INDEX_op_end;
8442

    
8443
#ifdef DEBUG_DISAS
8444
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8445
        fprintf(logfile, "----------------\n");
8446
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8447
        target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
8448
        fprintf(logfile, "\n");
8449
    }
8450
#endif
8451
    if (search_pc) {
8452
        j = gen_opc_ptr - gen_opc_buf;
8453
        lj++;
8454
        while (lj <= j)
8455
            gen_opc_instr_start[lj++] = 0;
8456
    } else {
8457
        tb->size = dc->pc - pc_start;
8458
    }
8459
    return 0;
8460
}
8461

    
8462
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
8463
{
8464
    return gen_intermediate_code_internal(env, tb, 0);
8465
}
8466

    
8467
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
8468
{
8469
    return gen_intermediate_code_internal(env, tb, 1);
8470
}
8471

    
8472
static const char *cpu_mode_names[16] = {
8473
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
8474
  "???", "???", "???", "und", "???", "???", "???", "sys"
8475
};
8476

    
8477
void cpu_dump_state(CPUState *env, FILE *f,
8478
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8479
                    int flags)
8480
{
8481
    int i;
8482
    union {
8483
        uint32_t i;
8484
        float s;
8485
    } s0, s1;
8486
    CPU_DoubleU d;
8487
    /* ??? This assumes float64 and double have the same layout.
8488
       Oh well, it's only debug dumps.  */
8489
    union {
8490
        float64 f64;
8491
        double d;
8492
    } d0;
8493
    uint32_t psr;
8494

    
8495
    for(i=0;i<16;i++) {
8496
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
8497
        if ((i % 4) == 3)
8498
            cpu_fprintf(f, "\n");
8499
        else
8500
            cpu_fprintf(f, " ");
8501
    }
8502
    psr = cpsr_read(env);
8503
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
8504
                psr,
8505
                psr & (1 << 31) ? 'N' : '-',
8506
                psr & (1 << 30) ? 'Z' : '-',
8507
                psr & (1 << 29) ? 'C' : '-',
8508
                psr & (1 << 28) ? 'V' : '-',
8509
                psr & CPSR_T ? 'T' : 'A',
8510
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8511

    
8512
#if 0
8513
    for (i = 0; i < 16; i++) {
8514
        d.d = env->vfp.regs[i];
8515
        s0.i = d.l.lower;
8516
        s1.i = d.l.upper;
8517
        d0.f64 = d.d;
8518
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
8519
                    i * 2, (int)s0.i, s0.s,
8520
                    i * 2 + 1, (int)s1.i, s1.s,
8521
                    i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
8522
                    d0.d);
8523
    }
8524
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8525
#endif
8526
}
8527