Statistics
| Branch: | Revision:

root / target-arm / translate.c @ b0109805

History | View | Annotate | Download (277 kB)

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

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

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

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

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

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

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

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

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

    
79
static TCGv cpu_env;
80
/* FIXME:  These should be removed.  */
81
static TCGv cpu_T[3];
82

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
187

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1005
#undef VFP_OP
1006

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

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

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

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

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

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

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

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

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

    
1082
#define ARM_CP_RW_BIT        (1 << 20)
1083

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

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

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

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

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

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

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

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

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

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

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

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

    
2069
    return 0;
2070
}
2071

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

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

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

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

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

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

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

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

    
2142
    return 1;
2143
}
2144

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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