Statistics
| Branch: | Revision:

root / target-arm / translate.c @ 40cfacdd

History | View | Annotate | Download (364.7 kB)

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

    
27
#include "cpu.h"
28
#include "disas/disas.h"
29
#include "tcg-op.h"
30
#include "qemu/log.h"
31
#include "qemu/bitops.h"
32

    
33
#include "helper.h"
34
#define GEN_HELPER 1
35
#include "helper.h"
36

    
37
#define ENABLE_ARCH_4T    arm_feature(env, ARM_FEATURE_V4T)
38
#define ENABLE_ARCH_5     arm_feature(env, ARM_FEATURE_V5)
39
/* currently all emulated v5 cores are also v5TE, so don't bother */
40
#define ENABLE_ARCH_5TE   arm_feature(env, ARM_FEATURE_V5)
41
#define ENABLE_ARCH_5J    0
42
#define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
43
#define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
44
#define ENABLE_ARCH_6T2   arm_feature(env, ARM_FEATURE_THUMB2)
45
#define ENABLE_ARCH_7     arm_feature(env, ARM_FEATURE_V7)
46
#define ENABLE_ARCH_8     arm_feature(env, ARM_FEATURE_V8)
47

    
48
#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
49

    
50
#include "translate.h"
51
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
52

    
53
#if defined(CONFIG_USER_ONLY)
54
#define IS_USER(s) 1
55
#else
56
#define IS_USER(s) (s->user)
57
#endif
58

    
59
/* These instructions trap after executing, so defer them until after the
60
   conditional execution state has been updated.  */
61
#define DISAS_WFI 4
62
#define DISAS_SWI 5
63

    
64
TCGv_ptr cpu_env;
65
/* We reuse the same 64-bit temporaries for efficiency.  */
66
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
67
static TCGv_i32 cpu_R[16];
68
static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
69
static TCGv_i32 cpu_exclusive_addr;
70
static TCGv_i32 cpu_exclusive_val;
71
static TCGv_i32 cpu_exclusive_high;
72
#ifdef CONFIG_USER_ONLY
73
static TCGv_i32 cpu_exclusive_test;
74
static TCGv_i32 cpu_exclusive_info;
75
#endif
76

    
77
/* FIXME:  These should be removed.  */
78
static TCGv_i32 cpu_F0s, cpu_F1s;
79
static TCGv_i64 cpu_F0d, cpu_F1d;
80

    
81
#include "exec/gen-icount.h"
82

    
83
static const char *regnames[] =
84
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
85
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
86

    
87
/* initialize TCG globals.  */
88
void arm_translate_init(void)
89
{
90
    int i;
91

    
92
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
93

    
94
    for (i = 0; i < 16; i++) {
95
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
96
                                          offsetof(CPUARMState, regs[i]),
97
                                          regnames[i]);
98
    }
99
    cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
100
    cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
101
    cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
102
    cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
103

    
104
    cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
105
        offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
106
    cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
107
        offsetof(CPUARMState, exclusive_val), "exclusive_val");
108
    cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
109
        offsetof(CPUARMState, exclusive_high), "exclusive_high");
110
#ifdef CONFIG_USER_ONLY
111
    cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
112
        offsetof(CPUARMState, exclusive_test), "exclusive_test");
113
    cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
114
        offsetof(CPUARMState, exclusive_info), "exclusive_info");
115
#endif
116

    
117
    a64_translate_init();
118
}
119

    
120
static inline TCGv_i32 load_cpu_offset(int offset)
121
{
122
    TCGv_i32 tmp = tcg_temp_new_i32();
123
    tcg_gen_ld_i32(tmp, cpu_env, offset);
124
    return tmp;
125
}
126

    
127
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
128

    
129
static inline void store_cpu_offset(TCGv_i32 var, int offset)
130
{
131
    tcg_gen_st_i32(var, cpu_env, offset);
132
    tcg_temp_free_i32(var);
133
}
134

    
135
#define store_cpu_field(var, name) \
136
    store_cpu_offset(var, offsetof(CPUARMState, name))
137

    
138
/* Set a variable to the value of a CPU register.  */
139
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
140
{
141
    if (reg == 15) {
142
        uint32_t addr;
143
        /* normally, since we updated PC, we need only to add one insn */
144
        if (s->thumb)
145
            addr = (long)s->pc + 2;
146
        else
147
            addr = (long)s->pc + 4;
148
        tcg_gen_movi_i32(var, addr);
149
    } else {
150
        tcg_gen_mov_i32(var, cpu_R[reg]);
151
    }
152
}
153

    
154
/* Create a new temporary and set it to the value of a CPU register.  */
155
static inline TCGv_i32 load_reg(DisasContext *s, int reg)
156
{
157
    TCGv_i32 tmp = tcg_temp_new_i32();
158
    load_reg_var(s, tmp, reg);
159
    return tmp;
160
}
161

    
162
/* Set a CPU register.  The source must be a temporary and will be
163
   marked as dead.  */
164
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
165
{
166
    if (reg == 15) {
167
        tcg_gen_andi_i32(var, var, ~1);
168
        s->is_jmp = DISAS_JUMP;
169
    }
170
    tcg_gen_mov_i32(cpu_R[reg], var);
171
    tcg_temp_free_i32(var);
172
}
173

    
174
/* Value extensions.  */
175
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
176
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
177
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
178
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
179

    
180
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
181
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
182

    
183

    
184
static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
185
{
186
    TCGv_i32 tmp_mask = tcg_const_i32(mask);
187
    gen_helper_cpsr_write(cpu_env, var, tmp_mask);
188
    tcg_temp_free_i32(tmp_mask);
189
}
190
/* Set NZCV flags from the high 4 bits of var.  */
191
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
192

    
193
static void gen_exception(int excp)
194
{
195
    TCGv_i32 tmp = tcg_temp_new_i32();
196
    tcg_gen_movi_i32(tmp, excp);
197
    gen_helper_exception(cpu_env, tmp);
198
    tcg_temp_free_i32(tmp);
199
}
200

    
201
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
202
{
203
    TCGv_i32 tmp1 = tcg_temp_new_i32();
204
    TCGv_i32 tmp2 = tcg_temp_new_i32();
205
    tcg_gen_ext16s_i32(tmp1, a);
206
    tcg_gen_ext16s_i32(tmp2, b);
207
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
208
    tcg_temp_free_i32(tmp2);
209
    tcg_gen_sari_i32(a, a, 16);
210
    tcg_gen_sari_i32(b, b, 16);
211
    tcg_gen_mul_i32(b, b, a);
212
    tcg_gen_mov_i32(a, tmp1);
213
    tcg_temp_free_i32(tmp1);
214
}
215

    
216
/* Byteswap each halfword.  */
217
static void gen_rev16(TCGv_i32 var)
218
{
219
    TCGv_i32 tmp = tcg_temp_new_i32();
220
    tcg_gen_shri_i32(tmp, var, 8);
221
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
222
    tcg_gen_shli_i32(var, var, 8);
223
    tcg_gen_andi_i32(var, var, 0xff00ff00);
224
    tcg_gen_or_i32(var, var, tmp);
225
    tcg_temp_free_i32(tmp);
226
}
227

    
228
/* Byteswap low halfword and sign extend.  */
229
static void gen_revsh(TCGv_i32 var)
230
{
231
    tcg_gen_ext16u_i32(var, var);
232
    tcg_gen_bswap16_i32(var, var);
233
    tcg_gen_ext16s_i32(var, var);
234
}
235

    
236
/* Unsigned bitfield extract.  */
237
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
238
{
239
    if (shift)
240
        tcg_gen_shri_i32(var, var, shift);
241
    tcg_gen_andi_i32(var, var, mask);
242
}
243

    
244
/* Signed bitfield extract.  */
245
static void gen_sbfx(TCGv_i32 var, int shift, int width)
246
{
247
    uint32_t signbit;
248

    
249
    if (shift)
250
        tcg_gen_sari_i32(var, var, shift);
251
    if (shift + width < 32) {
252
        signbit = 1u << (width - 1);
253
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
254
        tcg_gen_xori_i32(var, var, signbit);
255
        tcg_gen_subi_i32(var, var, signbit);
256
    }
257
}
258

    
259
/* Return (b << 32) + a. Mark inputs as dead */
260
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
261
{
262
    TCGv_i64 tmp64 = tcg_temp_new_i64();
263

    
264
    tcg_gen_extu_i32_i64(tmp64, b);
265
    tcg_temp_free_i32(b);
266
    tcg_gen_shli_i64(tmp64, tmp64, 32);
267
    tcg_gen_add_i64(a, tmp64, a);
268

    
269
    tcg_temp_free_i64(tmp64);
270
    return a;
271
}
272

    
273
/* Return (b << 32) - a. Mark inputs as dead. */
274
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
275
{
276
    TCGv_i64 tmp64 = tcg_temp_new_i64();
277

    
278
    tcg_gen_extu_i32_i64(tmp64, b);
279
    tcg_temp_free_i32(b);
280
    tcg_gen_shli_i64(tmp64, tmp64, 32);
281
    tcg_gen_sub_i64(a, tmp64, a);
282

    
283
    tcg_temp_free_i64(tmp64);
284
    return a;
285
}
286

    
287
/* 32x32->64 multiply.  Marks inputs as dead.  */
288
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
289
{
290
    TCGv_i32 lo = tcg_temp_new_i32();
291
    TCGv_i32 hi = tcg_temp_new_i32();
292
    TCGv_i64 ret;
293

    
294
    tcg_gen_mulu2_i32(lo, hi, a, b);
295
    tcg_temp_free_i32(a);
296
    tcg_temp_free_i32(b);
297

    
298
    ret = tcg_temp_new_i64();
299
    tcg_gen_concat_i32_i64(ret, lo, hi);
300
    tcg_temp_free_i32(lo);
301
    tcg_temp_free_i32(hi);
302

    
303
    return ret;
304
}
305

    
306
static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
307
{
308
    TCGv_i32 lo = tcg_temp_new_i32();
309
    TCGv_i32 hi = tcg_temp_new_i32();
310
    TCGv_i64 ret;
311

    
312
    tcg_gen_muls2_i32(lo, hi, a, b);
313
    tcg_temp_free_i32(a);
314
    tcg_temp_free_i32(b);
315

    
316
    ret = tcg_temp_new_i64();
317
    tcg_gen_concat_i32_i64(ret, lo, hi);
318
    tcg_temp_free_i32(lo);
319
    tcg_temp_free_i32(hi);
320

    
321
    return ret;
322
}
323

    
324
/* Swap low and high halfwords.  */
325
static void gen_swap_half(TCGv_i32 var)
326
{
327
    TCGv_i32 tmp = tcg_temp_new_i32();
328
    tcg_gen_shri_i32(tmp, var, 16);
329
    tcg_gen_shli_i32(var, var, 16);
330
    tcg_gen_or_i32(var, var, tmp);
331
    tcg_temp_free_i32(tmp);
332
}
333

    
334
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
335
    tmp = (t0 ^ t1) & 0x8000;
336
    t0 &= ~0x8000;
337
    t1 &= ~0x8000;
338
    t0 = (t0 + t1) ^ tmp;
339
 */
340

    
341
static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
342
{
343
    TCGv_i32 tmp = tcg_temp_new_i32();
344
    tcg_gen_xor_i32(tmp, t0, t1);
345
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
346
    tcg_gen_andi_i32(t0, t0, ~0x8000);
347
    tcg_gen_andi_i32(t1, t1, ~0x8000);
348
    tcg_gen_add_i32(t0, t0, t1);
349
    tcg_gen_xor_i32(t0, t0, tmp);
350
    tcg_temp_free_i32(tmp);
351
    tcg_temp_free_i32(t1);
352
}
353

    
354
/* Set CF to the top bit of var.  */
355
static void gen_set_CF_bit31(TCGv_i32 var)
356
{
357
    tcg_gen_shri_i32(cpu_CF, var, 31);
358
}
359

    
360
/* Set N and Z flags from var.  */
361
static inline void gen_logic_CC(TCGv_i32 var)
362
{
363
    tcg_gen_mov_i32(cpu_NF, var);
364
    tcg_gen_mov_i32(cpu_ZF, var);
365
}
366

    
367
/* T0 += T1 + CF.  */
368
static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
369
{
370
    tcg_gen_add_i32(t0, t0, t1);
371
    tcg_gen_add_i32(t0, t0, cpu_CF);
372
}
373

    
374
/* dest = T0 + T1 + CF. */
375
static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
376
{
377
    tcg_gen_add_i32(dest, t0, t1);
378
    tcg_gen_add_i32(dest, dest, cpu_CF);
379
}
380

    
381
/* dest = T0 - T1 + CF - 1.  */
382
static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
383
{
384
    tcg_gen_sub_i32(dest, t0, t1);
385
    tcg_gen_add_i32(dest, dest, cpu_CF);
386
    tcg_gen_subi_i32(dest, dest, 1);
387
}
388

    
389
/* dest = T0 + T1. Compute C, N, V and Z flags */
390
static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
391
{
392
    TCGv_i32 tmp = tcg_temp_new_i32();
393
    tcg_gen_movi_i32(tmp, 0);
394
    tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
395
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
396
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
397
    tcg_gen_xor_i32(tmp, t0, t1);
398
    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
399
    tcg_temp_free_i32(tmp);
400
    tcg_gen_mov_i32(dest, cpu_NF);
401
}
402

    
403
/* dest = T0 + T1 + CF.  Compute C, N, V and Z flags */
404
static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
405
{
406
    TCGv_i32 tmp = tcg_temp_new_i32();
407
    if (TCG_TARGET_HAS_add2_i32) {
408
        tcg_gen_movi_i32(tmp, 0);
409
        tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
410
        tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
411
    } else {
412
        TCGv_i64 q0 = tcg_temp_new_i64();
413
        TCGv_i64 q1 = tcg_temp_new_i64();
414
        tcg_gen_extu_i32_i64(q0, t0);
415
        tcg_gen_extu_i32_i64(q1, t1);
416
        tcg_gen_add_i64(q0, q0, q1);
417
        tcg_gen_extu_i32_i64(q1, cpu_CF);
418
        tcg_gen_add_i64(q0, q0, q1);
419
        tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
420
        tcg_temp_free_i64(q0);
421
        tcg_temp_free_i64(q1);
422
    }
423
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
424
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
425
    tcg_gen_xor_i32(tmp, t0, t1);
426
    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
427
    tcg_temp_free_i32(tmp);
428
    tcg_gen_mov_i32(dest, cpu_NF);
429
}
430

    
431
/* dest = T0 - T1. Compute C, N, V and Z flags */
432
static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
433
{
434
    TCGv_i32 tmp;
435
    tcg_gen_sub_i32(cpu_NF, t0, t1);
436
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
437
    tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
438
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
439
    tmp = tcg_temp_new_i32();
440
    tcg_gen_xor_i32(tmp, t0, t1);
441
    tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
442
    tcg_temp_free_i32(tmp);
443
    tcg_gen_mov_i32(dest, cpu_NF);
444
}
445

    
446
/* dest = T0 + ~T1 + CF.  Compute C, N, V and Z flags */
447
static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
448
{
449
    TCGv_i32 tmp = tcg_temp_new_i32();
450
    tcg_gen_not_i32(tmp, t1);
451
    gen_adc_CC(dest, t0, tmp);
452
    tcg_temp_free_i32(tmp);
453
}
454

    
455
#define GEN_SHIFT(name)                                               \
456
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)       \
457
{                                                                     \
458
    TCGv_i32 tmp1, tmp2, tmp3;                                        \
459
    tmp1 = tcg_temp_new_i32();                                        \
460
    tcg_gen_andi_i32(tmp1, t1, 0xff);                                 \
461
    tmp2 = tcg_const_i32(0);                                          \
462
    tmp3 = tcg_const_i32(0x1f);                                       \
463
    tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0);    \
464
    tcg_temp_free_i32(tmp3);                                          \
465
    tcg_gen_andi_i32(tmp1, tmp1, 0x1f);                               \
466
    tcg_gen_##name##_i32(dest, tmp2, tmp1);                           \
467
    tcg_temp_free_i32(tmp2);                                          \
468
    tcg_temp_free_i32(tmp1);                                          \
469
}
470
GEN_SHIFT(shl)
471
GEN_SHIFT(shr)
472
#undef GEN_SHIFT
473

    
474
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
475
{
476
    TCGv_i32 tmp1, tmp2;
477
    tmp1 = tcg_temp_new_i32();
478
    tcg_gen_andi_i32(tmp1, t1, 0xff);
479
    tmp2 = tcg_const_i32(0x1f);
480
    tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
481
    tcg_temp_free_i32(tmp2);
482
    tcg_gen_sar_i32(dest, t0, tmp1);
483
    tcg_temp_free_i32(tmp1);
484
}
485

    
486
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
487
{
488
    TCGv_i32 c0 = tcg_const_i32(0);
489
    TCGv_i32 tmp = tcg_temp_new_i32();
490
    tcg_gen_neg_i32(tmp, src);
491
    tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
492
    tcg_temp_free_i32(c0);
493
    tcg_temp_free_i32(tmp);
494
}
495

    
496
static void shifter_out_im(TCGv_i32 var, int shift)
497
{
498
    if (shift == 0) {
499
        tcg_gen_andi_i32(cpu_CF, var, 1);
500
    } else {
501
        tcg_gen_shri_i32(cpu_CF, var, shift);
502
        if (shift != 31) {
503
            tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
504
        }
505
    }
506
}
507

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

    
558
static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
559
                                     TCGv_i32 shift, int flags)
560
{
561
    if (flags) {
562
        switch (shiftop) {
563
        case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
564
        case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
565
        case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
566
        case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
567
        }
568
    } else {
569
        switch (shiftop) {
570
        case 0:
571
            gen_shl(var, var, shift);
572
            break;
573
        case 1:
574
            gen_shr(var, var, shift);
575
            break;
576
        case 2:
577
            gen_sar(var, var, shift);
578
            break;
579
        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
580
                tcg_gen_rotr_i32(var, var, shift); break;
581
        }
582
    }
583
    tcg_temp_free_i32(shift);
584
}
585

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

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

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

    
646
    switch (op2) {
647
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
648
    case 0:
649
        tmp = tcg_temp_new_ptr();
650
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
651
        PAS_OP(s)
652
        tcg_temp_free_ptr(tmp);
653
        break;
654
    case 4:
655
        tmp = tcg_temp_new_ptr();
656
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
657
        PAS_OP(u)
658
        tcg_temp_free_ptr(tmp);
659
        break;
660
#undef gen_pas_helper
661
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
662
    case 1:
663
        PAS_OP(q);
664
        break;
665
    case 2:
666
        PAS_OP(sh);
667
        break;
668
    case 5:
669
        PAS_OP(uq);
670
        break;
671
    case 6:
672
        PAS_OP(uh);
673
        break;
674
#undef gen_pas_helper
675
    }
676
}
677
#undef PAS_OP
678

    
679
static void gen_test_cc(int cc, int label)
680
{
681
    TCGv_i32 tmp;
682
    int inv;
683

    
684
    switch (cc) {
685
    case 0: /* eq: Z */
686
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
687
        break;
688
    case 1: /* ne: !Z */
689
        tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
690
        break;
691
    case 2: /* cs: C */
692
        tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
693
        break;
694
    case 3: /* cc: !C */
695
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
696
        break;
697
    case 4: /* mi: N */
698
        tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
699
        break;
700
    case 5: /* pl: !N */
701
        tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
702
        break;
703
    case 6: /* vs: V */
704
        tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
705
        break;
706
    case 7: /* vc: !V */
707
        tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
708
        break;
709
    case 8: /* hi: C && !Z */
710
        inv = gen_new_label();
711
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
712
        tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
713
        gen_set_label(inv);
714
        break;
715
    case 9: /* ls: !C || Z */
716
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
717
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
718
        break;
719
    case 10: /* ge: N == V -> N ^ V == 0 */
720
        tmp = tcg_temp_new_i32();
721
        tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
722
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
723
        tcg_temp_free_i32(tmp);
724
        break;
725
    case 11: /* lt: N != V -> N ^ V != 0 */
726
        tmp = tcg_temp_new_i32();
727
        tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
728
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
729
        tcg_temp_free_i32(tmp);
730
        break;
731
    case 12: /* gt: !Z && N == V */
732
        inv = gen_new_label();
733
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
734
        tmp = tcg_temp_new_i32();
735
        tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
736
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
737
        tcg_temp_free_i32(tmp);
738
        gen_set_label(inv);
739
        break;
740
    case 13: /* le: Z || N != V */
741
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
742
        tmp = tcg_temp_new_i32();
743
        tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
744
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
745
        tcg_temp_free_i32(tmp);
746
        break;
747
    default:
748
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
749
        abort();
750
    }
751
}
752

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

    
772
/* Set PC and Thumb state from an immediate address.  */
773
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
774
{
775
    TCGv_i32 tmp;
776

    
777
    s->is_jmp = DISAS_UPDATE;
778
    if (s->thumb != (addr & 1)) {
779
        tmp = tcg_temp_new_i32();
780
        tcg_gen_movi_i32(tmp, addr & 1);
781
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
782
        tcg_temp_free_i32(tmp);
783
    }
784
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
785
}
786

    
787
/* Set PC and Thumb state from var.  var is marked as dead.  */
788
static inline void gen_bx(DisasContext *s, TCGv_i32 var)
789
{
790
    s->is_jmp = DISAS_UPDATE;
791
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
792
    tcg_gen_andi_i32(var, var, 1);
793
    store_cpu_field(var, thumb);
794
}
795

    
796
/* Variant of store_reg which uses branch&exchange logic when storing
797
   to r15 in ARM architecture v7 and above. The source must be a temporary
798
   and will be marked as dead. */
799
static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
800
                                int reg, TCGv_i32 var)
801
{
802
    if (reg == 15 && ENABLE_ARCH_7) {
803
        gen_bx(s, var);
804
    } else {
805
        store_reg(s, reg, var);
806
    }
807
}
808

    
809
/* Variant of store_reg which uses branch&exchange logic when storing
810
 * to r15 in ARM architecture v5T and above. This is used for storing
811
 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
812
 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
813
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
814
                                       int reg, TCGv_i32 var)
815
{
816
    if (reg == 15 && ENABLE_ARCH_5) {
817
        gen_bx(s, var);
818
    } else {
819
        store_reg(s, reg, var);
820
    }
821
}
822

    
823
/* Abstractions of "generate code to do a guest load/store for
824
 * AArch32", where a vaddr is always 32 bits (and is zero
825
 * extended if we're a 64 bit core) and  data is also
826
 * 32 bits unless specifically doing a 64 bit access.
827
 * These functions work like tcg_gen_qemu_{ld,st}* except
828
 * that their arguments are TCGv_i32 rather than TCGv.
829
 */
830
#if TARGET_LONG_BITS == 32
831

    
832
#define DO_GEN_LD(OP)                                                    \
833
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
834
{                                                                        \
835
    tcg_gen_qemu_##OP(val, addr, index);                                 \
836
}
837

    
838
#define DO_GEN_ST(OP)                                                    \
839
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
840
{                                                                        \
841
    tcg_gen_qemu_##OP(val, addr, index);                                 \
842
}
843

    
844
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
845
{
846
    tcg_gen_qemu_ld64(val, addr, index);
847
}
848

    
849
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
850
{
851
    tcg_gen_qemu_st64(val, addr, index);
852
}
853

    
854
#else
855

    
856
#define DO_GEN_LD(OP)                                                    \
857
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
858
{                                                                        \
859
    TCGv addr64 = tcg_temp_new();                                        \
860
    TCGv val64 = tcg_temp_new();                                         \
861
    tcg_gen_extu_i32_i64(addr64, addr);                                  \
862
    tcg_gen_qemu_##OP(val64, addr64, index);                             \
863
    tcg_temp_free(addr64);                                               \
864
    tcg_gen_trunc_i64_i32(val, val64);                                   \
865
    tcg_temp_free(val64);                                                \
866
}
867

    
868
#define DO_GEN_ST(OP)                                                    \
869
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
870
{                                                                        \
871
    TCGv addr64 = tcg_temp_new();                                        \
872
    TCGv val64 = tcg_temp_new();                                         \
873
    tcg_gen_extu_i32_i64(addr64, addr);                                  \
874
    tcg_gen_extu_i32_i64(val64, val);                                    \
875
    tcg_gen_qemu_##OP(val64, addr64, index);                             \
876
    tcg_temp_free(addr64);                                               \
877
    tcg_temp_free(val64);                                                \
878
}
879

    
880
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
881
{
882
    TCGv addr64 = tcg_temp_new();
883
    tcg_gen_extu_i32_i64(addr64, addr);
884
    tcg_gen_qemu_ld64(val, addr64, index);
885
    tcg_temp_free(addr64);
886
}
887

    
888
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
889
{
890
    TCGv addr64 = tcg_temp_new();
891
    tcg_gen_extu_i32_i64(addr64, addr);
892
    tcg_gen_qemu_st64(val, addr64, index);
893
    tcg_temp_free(addr64);
894
}
895

    
896
#endif
897

    
898
DO_GEN_LD(ld8s)
899
DO_GEN_LD(ld8u)
900
DO_GEN_LD(ld16s)
901
DO_GEN_LD(ld16u)
902
DO_GEN_LD(ld32u)
903
DO_GEN_ST(st8)
904
DO_GEN_ST(st16)
905
DO_GEN_ST(st32)
906

    
907
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
908
{
909
    if (s->aarch64) {
910
        gen_a64_set_pc_im(val);
911
    } else {
912
        tcg_gen_movi_i32(cpu_R[15], val);
913
    }
914
}
915

    
916
/* Force a TB lookup after an instruction that changes the CPU state.  */
917
static inline void gen_lookup_tb(DisasContext *s)
918
{
919
    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
920
    s->is_jmp = DISAS_UPDATE;
921
}
922

    
923
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
924
                                       TCGv_i32 var)
925
{
926
    int val, rm, shift, shiftop;
927
    TCGv_i32 offset;
928

    
929
    if (!(insn & (1 << 25))) {
930
        /* immediate */
931
        val = insn & 0xfff;
932
        if (!(insn & (1 << 23)))
933
            val = -val;
934
        if (val != 0)
935
            tcg_gen_addi_i32(var, var, val);
936
    } else {
937
        /* shift/register */
938
        rm = (insn) & 0xf;
939
        shift = (insn >> 7) & 0x1f;
940
        shiftop = (insn >> 5) & 3;
941
        offset = load_reg(s, rm);
942
        gen_arm_shift_im(offset, shiftop, shift, 0);
943
        if (!(insn & (1 << 23)))
944
            tcg_gen_sub_i32(var, var, offset);
945
        else
946
            tcg_gen_add_i32(var, var, offset);
947
        tcg_temp_free_i32(offset);
948
    }
949
}
950

    
951
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
952
                                        int extra, TCGv_i32 var)
953
{
954
    int val, rm;
955
    TCGv_i32 offset;
956

    
957
    if (insn & (1 << 22)) {
958
        /* immediate */
959
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
960
        if (!(insn & (1 << 23)))
961
            val = -val;
962
        val += extra;
963
        if (val != 0)
964
            tcg_gen_addi_i32(var, var, val);
965
    } else {
966
        /* register */
967
        if (extra)
968
            tcg_gen_addi_i32(var, var, extra);
969
        rm = (insn) & 0xf;
970
        offset = load_reg(s, rm);
971
        if (!(insn & (1 << 23)))
972
            tcg_gen_sub_i32(var, var, offset);
973
        else
974
            tcg_gen_add_i32(var, var, offset);
975
        tcg_temp_free_i32(offset);
976
    }
977
}
978

    
979
static TCGv_ptr get_fpstatus_ptr(int neon)
980
{
981
    TCGv_ptr statusptr = tcg_temp_new_ptr();
982
    int offset;
983
    if (neon) {
984
        offset = offsetof(CPUARMState, vfp.standard_fp_status);
985
    } else {
986
        offset = offsetof(CPUARMState, vfp.fp_status);
987
    }
988
    tcg_gen_addi_ptr(statusptr, cpu_env, offset);
989
    return statusptr;
990
}
991

    
992
#define VFP_OP2(name)                                                 \
993
static inline void gen_vfp_##name(int dp)                             \
994
{                                                                     \
995
    TCGv_ptr fpst = get_fpstatus_ptr(0);                              \
996
    if (dp) {                                                         \
997
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst);    \
998
    } else {                                                          \
999
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst);    \
1000
    }                                                                 \
1001
    tcg_temp_free_ptr(fpst);                                          \
1002
}
1003

    
1004
VFP_OP2(add)
1005
VFP_OP2(sub)
1006
VFP_OP2(mul)
1007
VFP_OP2(div)
1008

    
1009
#undef VFP_OP2
1010

    
1011
static inline void gen_vfp_F1_mul(int dp)
1012
{
1013
    /* Like gen_vfp_mul() but put result in F1 */
1014
    TCGv_ptr fpst = get_fpstatus_ptr(0);
1015
    if (dp) {
1016
        gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1017
    } else {
1018
        gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1019
    }
1020
    tcg_temp_free_ptr(fpst);
1021
}
1022

    
1023
static inline void gen_vfp_F1_neg(int dp)
1024
{
1025
    /* Like gen_vfp_neg() but put result in F1 */
1026
    if (dp) {
1027
        gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1028
    } else {
1029
        gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1030
    }
1031
}
1032

    
1033
static inline void gen_vfp_abs(int dp)
1034
{
1035
    if (dp)
1036
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1037
    else
1038
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1039
}
1040

    
1041
static inline void gen_vfp_neg(int dp)
1042
{
1043
    if (dp)
1044
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1045
    else
1046
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1047
}
1048

    
1049
static inline void gen_vfp_sqrt(int dp)
1050
{
1051
    if (dp)
1052
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1053
    else
1054
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1055
}
1056

    
1057
static inline void gen_vfp_cmp(int dp)
1058
{
1059
    if (dp)
1060
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1061
    else
1062
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1063
}
1064

    
1065
static inline void gen_vfp_cmpe(int dp)
1066
{
1067
    if (dp)
1068
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1069
    else
1070
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1071
}
1072

    
1073
static inline void gen_vfp_F1_ld0(int dp)
1074
{
1075
    if (dp)
1076
        tcg_gen_movi_i64(cpu_F1d, 0);
1077
    else
1078
        tcg_gen_movi_i32(cpu_F1s, 0);
1079
}
1080

    
1081
#define VFP_GEN_ITOF(name) \
1082
static inline void gen_vfp_##name(int dp, int neon) \
1083
{ \
1084
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1085
    if (dp) { \
1086
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1087
    } else { \
1088
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1089
    } \
1090
    tcg_temp_free_ptr(statusptr); \
1091
}
1092

    
1093
VFP_GEN_ITOF(uito)
1094
VFP_GEN_ITOF(sito)
1095
#undef VFP_GEN_ITOF
1096

    
1097
#define VFP_GEN_FTOI(name) \
1098
static inline void gen_vfp_##name(int dp, int neon) \
1099
{ \
1100
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1101
    if (dp) { \
1102
        gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1103
    } else { \
1104
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1105
    } \
1106
    tcg_temp_free_ptr(statusptr); \
1107
}
1108

    
1109
VFP_GEN_FTOI(toui)
1110
VFP_GEN_FTOI(touiz)
1111
VFP_GEN_FTOI(tosi)
1112
VFP_GEN_FTOI(tosiz)
1113
#undef VFP_GEN_FTOI
1114

    
1115
#define VFP_GEN_FIX(name) \
1116
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1117
{ \
1118
    TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1119
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1120
    if (dp) { \
1121
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1122
    } else { \
1123
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1124
    } \
1125
    tcg_temp_free_i32(tmp_shift); \
1126
    tcg_temp_free_ptr(statusptr); \
1127
}
1128
VFP_GEN_FIX(tosh)
1129
VFP_GEN_FIX(tosl)
1130
VFP_GEN_FIX(touh)
1131
VFP_GEN_FIX(toul)
1132
VFP_GEN_FIX(shto)
1133
VFP_GEN_FIX(slto)
1134
VFP_GEN_FIX(uhto)
1135
VFP_GEN_FIX(ulto)
1136
#undef VFP_GEN_FIX
1137

    
1138
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1139
{
1140
    if (dp) {
1141
        gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1142
    } else {
1143
        gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1144
    }
1145
}
1146

    
1147
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1148
{
1149
    if (dp) {
1150
        gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1151
    } else {
1152
        gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1153
    }
1154
}
1155

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

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

    
1180
static TCGv_i32 neon_load_reg(int reg, int pass)
1181
{
1182
    TCGv_i32 tmp = tcg_temp_new_i32();
1183
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1184
    return tmp;
1185
}
1186

    
1187
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1188
{
1189
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1190
    tcg_temp_free_i32(var);
1191
}
1192

    
1193
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1194
{
1195
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1196
}
1197

    
1198
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1199
{
1200
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1201
}
1202

    
1203
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1204
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1205
#define tcg_gen_st_f32 tcg_gen_st_i32
1206
#define tcg_gen_st_f64 tcg_gen_st_i64
1207

    
1208
static inline void gen_mov_F0_vreg(int dp, int reg)
1209
{
1210
    if (dp)
1211
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1212
    else
1213
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1214
}
1215

    
1216
static inline void gen_mov_F1_vreg(int dp, int reg)
1217
{
1218
    if (dp)
1219
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1220
    else
1221
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1222
}
1223

    
1224
static inline void gen_mov_vreg_F0(int dp, int reg)
1225
{
1226
    if (dp)
1227
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1228
    else
1229
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1230
}
1231

    
1232
#define ARM_CP_RW_BIT        (1 << 20)
1233

    
1234
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1235
{
1236
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1237
}
1238

    
1239
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1240
{
1241
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1242
}
1243

    
1244
static inline TCGv_i32 iwmmxt_load_creg(int reg)
1245
{
1246
    TCGv_i32 var = tcg_temp_new_i32();
1247
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1248
    return var;
1249
}
1250

    
1251
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1252
{
1253
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1254
    tcg_temp_free_i32(var);
1255
}
1256

    
1257
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1258
{
1259
    iwmmxt_store_reg(cpu_M0, rn);
1260
}
1261

    
1262
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1263
{
1264
    iwmmxt_load_reg(cpu_M0, rn);
1265
}
1266

    
1267
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1268
{
1269
    iwmmxt_load_reg(cpu_V1, rn);
1270
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1271
}
1272

    
1273
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1274
{
1275
    iwmmxt_load_reg(cpu_V1, rn);
1276
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1277
}
1278

    
1279
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1280
{
1281
    iwmmxt_load_reg(cpu_V1, rn);
1282
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1283
}
1284

    
1285
#define IWMMXT_OP(name) \
1286
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1287
{ \
1288
    iwmmxt_load_reg(cpu_V1, rn); \
1289
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1290
}
1291

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

    
1299
#define IWMMXT_OP_ENV_SIZE(name) \
1300
IWMMXT_OP_ENV(name##b) \
1301
IWMMXT_OP_ENV(name##w) \
1302
IWMMXT_OP_ENV(name##l)
1303

    
1304
#define IWMMXT_OP_ENV1(name) \
1305
static inline void gen_op_iwmmxt_##name##_M0(void) \
1306
{ \
1307
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1308
}
1309

    
1310
IWMMXT_OP(maddsq)
1311
IWMMXT_OP(madduq)
1312
IWMMXT_OP(sadb)
1313
IWMMXT_OP(sadw)
1314
IWMMXT_OP(mulslw)
1315
IWMMXT_OP(mulshw)
1316
IWMMXT_OP(mululw)
1317
IWMMXT_OP(muluhw)
1318
IWMMXT_OP(macsw)
1319
IWMMXT_OP(macuw)
1320

    
1321
IWMMXT_OP_ENV_SIZE(unpackl)
1322
IWMMXT_OP_ENV_SIZE(unpackh)
1323

    
1324
IWMMXT_OP_ENV1(unpacklub)
1325
IWMMXT_OP_ENV1(unpackluw)
1326
IWMMXT_OP_ENV1(unpacklul)
1327
IWMMXT_OP_ENV1(unpackhub)
1328
IWMMXT_OP_ENV1(unpackhuw)
1329
IWMMXT_OP_ENV1(unpackhul)
1330
IWMMXT_OP_ENV1(unpacklsb)
1331
IWMMXT_OP_ENV1(unpacklsw)
1332
IWMMXT_OP_ENV1(unpacklsl)
1333
IWMMXT_OP_ENV1(unpackhsb)
1334
IWMMXT_OP_ENV1(unpackhsw)
1335
IWMMXT_OP_ENV1(unpackhsl)
1336

    
1337
IWMMXT_OP_ENV_SIZE(cmpeq)
1338
IWMMXT_OP_ENV_SIZE(cmpgtu)
1339
IWMMXT_OP_ENV_SIZE(cmpgts)
1340

    
1341
IWMMXT_OP_ENV_SIZE(mins)
1342
IWMMXT_OP_ENV_SIZE(minu)
1343
IWMMXT_OP_ENV_SIZE(maxs)
1344
IWMMXT_OP_ENV_SIZE(maxu)
1345

    
1346
IWMMXT_OP_ENV_SIZE(subn)
1347
IWMMXT_OP_ENV_SIZE(addn)
1348
IWMMXT_OP_ENV_SIZE(subu)
1349
IWMMXT_OP_ENV_SIZE(addu)
1350
IWMMXT_OP_ENV_SIZE(subs)
1351
IWMMXT_OP_ENV_SIZE(adds)
1352

    
1353
IWMMXT_OP_ENV(avgb0)
1354
IWMMXT_OP_ENV(avgb1)
1355
IWMMXT_OP_ENV(avgw0)
1356
IWMMXT_OP_ENV(avgw1)
1357

    
1358
IWMMXT_OP(msadb)
1359

    
1360
IWMMXT_OP_ENV(packuw)
1361
IWMMXT_OP_ENV(packul)
1362
IWMMXT_OP_ENV(packuq)
1363
IWMMXT_OP_ENV(packsw)
1364
IWMMXT_OP_ENV(packsl)
1365
IWMMXT_OP_ENV(packsq)
1366

    
1367
static void gen_op_iwmmxt_set_mup(void)
1368
{
1369
    TCGv_i32 tmp;
1370
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1371
    tcg_gen_ori_i32(tmp, tmp, 2);
1372
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1373
}
1374

    
1375
static void gen_op_iwmmxt_set_cup(void)
1376
{
1377
    TCGv_i32 tmp;
1378
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1379
    tcg_gen_ori_i32(tmp, tmp, 1);
1380
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1381
}
1382

    
1383
static void gen_op_iwmmxt_setpsr_nz(void)
1384
{
1385
    TCGv_i32 tmp = tcg_temp_new_i32();
1386
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1387
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1388
}
1389

    
1390
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1391
{
1392
    iwmmxt_load_reg(cpu_V1, rn);
1393
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1394
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1395
}
1396

    
1397
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1398
                                     TCGv_i32 dest)
1399
{
1400
    int rd;
1401
    uint32_t offset;
1402
    TCGv_i32 tmp;
1403

    
1404
    rd = (insn >> 16) & 0xf;
1405
    tmp = load_reg(s, rd);
1406

    
1407
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1408
    if (insn & (1 << 24)) {
1409
        /* Pre indexed */
1410
        if (insn & (1 << 23))
1411
            tcg_gen_addi_i32(tmp, tmp, offset);
1412
        else
1413
            tcg_gen_addi_i32(tmp, tmp, -offset);
1414
        tcg_gen_mov_i32(dest, tmp);
1415
        if (insn & (1 << 21))
1416
            store_reg(s, rd, tmp);
1417
        else
1418
            tcg_temp_free_i32(tmp);
1419
    } else if (insn & (1 << 21)) {
1420
        /* Post indexed */
1421
        tcg_gen_mov_i32(dest, tmp);
1422
        if (insn & (1 << 23))
1423
            tcg_gen_addi_i32(tmp, tmp, offset);
1424
        else
1425
            tcg_gen_addi_i32(tmp, tmp, -offset);
1426
        store_reg(s, rd, tmp);
1427
    } else if (!(insn & (1 << 23)))
1428
        return 1;
1429
    return 0;
1430
}
1431

    
1432
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1433
{
1434
    int rd = (insn >> 0) & 0xf;
1435
    TCGv_i32 tmp;
1436

    
1437
    if (insn & (1 << 8)) {
1438
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1439
            return 1;
1440
        } else {
1441
            tmp = iwmmxt_load_creg(rd);
1442
        }
1443
    } else {
1444
        tmp = tcg_temp_new_i32();
1445
        iwmmxt_load_reg(cpu_V0, rd);
1446
        tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1447
    }
1448
    tcg_gen_andi_i32(tmp, tmp, mask);
1449
    tcg_gen_mov_i32(dest, tmp);
1450
    tcg_temp_free_i32(tmp);
1451
    return 0;
1452
}
1453

    
1454
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occurred
1455
   (ie. an undefined instruction).  */
1456
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1457
{
1458
    int rd, wrd;
1459
    int rdhi, rdlo, rd0, rd1, i;
1460
    TCGv_i32 addr;
1461
    TCGv_i32 tmp, tmp2, tmp3;
1462

    
1463
    if ((insn & 0x0e000e00) == 0x0c000000) {
1464
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1465
            wrd = insn & 0xf;
1466
            rdlo = (insn >> 12) & 0xf;
1467
            rdhi = (insn >> 16) & 0xf;
1468
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1469
                iwmmxt_load_reg(cpu_V0, wrd);
1470
                tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1471
                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1472
                tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1473
            } else {                                        /* TMCRR */
1474
                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1475
                iwmmxt_store_reg(cpu_V0, wrd);
1476
                gen_op_iwmmxt_set_mup();
1477
            }
1478
            return 0;
1479
        }
1480

    
1481
        wrd = (insn >> 12) & 0xf;
1482
        addr = tcg_temp_new_i32();
1483
        if (gen_iwmmxt_address(s, insn, addr)) {
1484
            tcg_temp_free_i32(addr);
1485
            return 1;
1486
        }
1487
        if (insn & ARM_CP_RW_BIT) {
1488
            if ((insn >> 28) == 0xf) {                        /* WLDRW wCx */
1489
                tmp = tcg_temp_new_i32();
1490
                gen_aa32_ld32u(tmp, addr, IS_USER(s));
1491
                iwmmxt_store_creg(wrd, tmp);
1492
            } else {
1493
                i = 1;
1494
                if (insn & (1 << 8)) {
1495
                    if (insn & (1 << 22)) {                /* WLDRD */
1496
                        gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1497
                        i = 0;
1498
                    } else {                                /* WLDRW wRd */
1499
                        tmp = tcg_temp_new_i32();
1500
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
1501
                    }
1502
                } else {
1503
                    tmp = tcg_temp_new_i32();
1504
                    if (insn & (1 << 22)) {                /* WLDRH */
1505
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
1506
                    } else {                                /* WLDRB */
1507
                        gen_aa32_ld8u(tmp, addr, IS_USER(s));
1508
                    }
1509
                }
1510
                if (i) {
1511
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
1512
                    tcg_temp_free_i32(tmp);
1513
                }
1514
                gen_op_iwmmxt_movq_wRn_M0(wrd);
1515
            }
1516
        } else {
1517
            if ((insn >> 28) == 0xf) {                        /* WSTRW wCx */
1518
                tmp = iwmmxt_load_creg(wrd);
1519
                gen_aa32_st32(tmp, addr, IS_USER(s));
1520
            } else {
1521
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1522
                tmp = tcg_temp_new_i32();
1523
                if (insn & (1 << 8)) {
1524
                    if (insn & (1 << 22)) {                /* WSTRD */
1525
                        gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1526
                    } else {                                /* WSTRW wRd */
1527
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1528
                        gen_aa32_st32(tmp, addr, IS_USER(s));
1529
                    }
1530
                } else {
1531
                    if (insn & (1 << 22)) {                /* WSTRH */
1532
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1533
                        gen_aa32_st16(tmp, addr, IS_USER(s));
1534
                    } else {                                /* WSTRB */
1535
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1536
                        gen_aa32_st8(tmp, addr, IS_USER(s));
1537
                    }
1538
                }
1539
            }
1540
            tcg_temp_free_i32(tmp);
1541
        }
1542
        tcg_temp_free_i32(addr);
1543
        return 0;
1544
    }
1545

    
1546
    if ((insn & 0x0f000000) != 0x0e000000)
1547
        return 1;
1548

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

    
2457
    return 0;
2458
}
2459

    
2460
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occurred
2461
   (ie. an undefined instruction).  */
2462
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2463
{
2464
    int acc, rd0, rd1, rdhi, rdlo;
2465
    TCGv_i32 tmp, tmp2;
2466

    
2467
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2468
        /* Multiply with Internal Accumulate Format */
2469
        rd0 = (insn >> 12) & 0xf;
2470
        rd1 = insn & 0xf;
2471
        acc = (insn >> 5) & 7;
2472

    
2473
        if (acc != 0)
2474
            return 1;
2475

    
2476
        tmp = load_reg(s, rd0);
2477
        tmp2 = load_reg(s, rd1);
2478
        switch ((insn >> 16) & 0xf) {
2479
        case 0x0:                                        /* MIA */
2480
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2481
            break;
2482
        case 0x8:                                        /* MIAPH */
2483
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2484
            break;
2485
        case 0xc:                                        /* MIABB */
2486
        case 0xd:                                        /* MIABT */
2487
        case 0xe:                                        /* MIATB */
2488
        case 0xf:                                        /* MIATT */
2489
            if (insn & (1 << 16))
2490
                tcg_gen_shri_i32(tmp, tmp, 16);
2491
            if (insn & (1 << 17))
2492
                tcg_gen_shri_i32(tmp2, tmp2, 16);
2493
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2494
            break;
2495
        default:
2496
            return 1;
2497
        }
2498
        tcg_temp_free_i32(tmp2);
2499
        tcg_temp_free_i32(tmp);
2500

    
2501
        gen_op_iwmmxt_movq_wRn_M0(acc);
2502
        return 0;
2503
    }
2504

    
2505
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2506
        /* Internal Accumulator Access Format */
2507
        rdhi = (insn >> 16) & 0xf;
2508
        rdlo = (insn >> 12) & 0xf;
2509
        acc = insn & 7;
2510

    
2511
        if (acc != 0)
2512
            return 1;
2513

    
2514
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2515
            iwmmxt_load_reg(cpu_V0, acc);
2516
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2517
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2518
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2519
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2520
        } else {                                        /* MAR */
2521
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2522
            iwmmxt_store_reg(cpu_V0, acc);
2523
        }
2524
        return 0;
2525
    }
2526

    
2527
    return 1;
2528
}
2529

    
2530
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2531
#define VFP_SREG(insn, bigbit, smallbit) \
2532
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2533
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2534
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2535
        reg = (((insn) >> (bigbit)) & 0x0f) \
2536
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2537
    } else { \
2538
        if (insn & (1 << (smallbit))) \
2539
            return 1; \
2540
        reg = ((insn) >> (bigbit)) & 0x0f; \
2541
    }} while (0)
2542

    
2543
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2544
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2545
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2546
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2547
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2548
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2549

    
2550
/* Move between integer and VFP cores.  */
2551
static TCGv_i32 gen_vfp_mrs(void)
2552
{
2553
    TCGv_i32 tmp = tcg_temp_new_i32();
2554
    tcg_gen_mov_i32(tmp, cpu_F0s);
2555
    return tmp;
2556
}
2557

    
2558
static void gen_vfp_msr(TCGv_i32 tmp)
2559
{
2560
    tcg_gen_mov_i32(cpu_F0s, tmp);
2561
    tcg_temp_free_i32(tmp);
2562
}
2563

    
2564
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2565
{
2566
    TCGv_i32 tmp = tcg_temp_new_i32();
2567
    if (shift)
2568
        tcg_gen_shri_i32(var, var, shift);
2569
    tcg_gen_ext8u_i32(var, var);
2570
    tcg_gen_shli_i32(tmp, var, 8);
2571
    tcg_gen_or_i32(var, var, tmp);
2572
    tcg_gen_shli_i32(tmp, var, 16);
2573
    tcg_gen_or_i32(var, var, tmp);
2574
    tcg_temp_free_i32(tmp);
2575
}
2576

    
2577
static void gen_neon_dup_low16(TCGv_i32 var)
2578
{
2579
    TCGv_i32 tmp = tcg_temp_new_i32();
2580
    tcg_gen_ext16u_i32(var, var);
2581
    tcg_gen_shli_i32(tmp, var, 16);
2582
    tcg_gen_or_i32(var, var, tmp);
2583
    tcg_temp_free_i32(tmp);
2584
}
2585

    
2586
static void gen_neon_dup_high16(TCGv_i32 var)
2587
{
2588
    TCGv_i32 tmp = tcg_temp_new_i32();
2589
    tcg_gen_andi_i32(var, var, 0xffff0000);
2590
    tcg_gen_shri_i32(tmp, var, 16);
2591
    tcg_gen_or_i32(var, var, tmp);
2592
    tcg_temp_free_i32(tmp);
2593
}
2594

    
2595
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2596
{
2597
    /* Load a single Neon element and replicate into a 32 bit TCG reg */
2598
    TCGv_i32 tmp = tcg_temp_new_i32();
2599
    switch (size) {
2600
    case 0:
2601
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
2602
        gen_neon_dup_u8(tmp, 0);
2603
        break;
2604
    case 1:
2605
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
2606
        gen_neon_dup_low16(tmp);
2607
        break;
2608
    case 2:
2609
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
2610
        break;
2611
    default: /* Avoid compiler warnings.  */
2612
        abort();
2613
    }
2614
    return tmp;
2615
}
2616

    
2617
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2618
                       uint32_t dp)
2619
{
2620
    uint32_t cc = extract32(insn, 20, 2);
2621

    
2622
    if (dp) {
2623
        TCGv_i64 frn, frm, dest;
2624
        TCGv_i64 tmp, zero, zf, nf, vf;
2625

    
2626
        zero = tcg_const_i64(0);
2627

    
2628
        frn = tcg_temp_new_i64();
2629
        frm = tcg_temp_new_i64();
2630
        dest = tcg_temp_new_i64();
2631

    
2632
        zf = tcg_temp_new_i64();
2633
        nf = tcg_temp_new_i64();
2634
        vf = tcg_temp_new_i64();
2635

    
2636
        tcg_gen_extu_i32_i64(zf, cpu_ZF);
2637
        tcg_gen_ext_i32_i64(nf, cpu_NF);
2638
        tcg_gen_ext_i32_i64(vf, cpu_VF);
2639

    
2640
        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2641
        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2642
        switch (cc) {
2643
        case 0: /* eq: Z */
2644
            tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2645
                                frn, frm);
2646
            break;
2647
        case 1: /* vs: V */
2648
            tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2649
                                frn, frm);
2650
            break;
2651
        case 2: /* ge: N == V -> N ^ V == 0 */
2652
            tmp = tcg_temp_new_i64();
2653
            tcg_gen_xor_i64(tmp, vf, nf);
2654
            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2655
                                frn, frm);
2656
            tcg_temp_free_i64(tmp);
2657
            break;
2658
        case 3: /* gt: !Z && N == V */
2659
            tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2660
                                frn, frm);
2661
            tmp = tcg_temp_new_i64();
2662
            tcg_gen_xor_i64(tmp, vf, nf);
2663
            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2664
                                dest, frm);
2665
            tcg_temp_free_i64(tmp);
2666
            break;
2667
        }
2668
        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2669
        tcg_temp_free_i64(frn);
2670
        tcg_temp_free_i64(frm);
2671
        tcg_temp_free_i64(dest);
2672

    
2673
        tcg_temp_free_i64(zf);
2674
        tcg_temp_free_i64(nf);
2675
        tcg_temp_free_i64(vf);
2676

    
2677
        tcg_temp_free_i64(zero);
2678
    } else {
2679
        TCGv_i32 frn, frm, dest;
2680
        TCGv_i32 tmp, zero;
2681

    
2682
        zero = tcg_const_i32(0);
2683

    
2684
        frn = tcg_temp_new_i32();
2685
        frm = tcg_temp_new_i32();
2686
        dest = tcg_temp_new_i32();
2687
        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2688
        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2689
        switch (cc) {
2690
        case 0: /* eq: Z */
2691
            tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2692
                                frn, frm);
2693
            break;
2694
        case 1: /* vs: V */
2695
            tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2696
                                frn, frm);
2697
            break;
2698
        case 2: /* ge: N == V -> N ^ V == 0 */
2699
            tmp = tcg_temp_new_i32();
2700
            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2701
            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2702
                                frn, frm);
2703
            tcg_temp_free_i32(tmp);
2704
            break;
2705
        case 3: /* gt: !Z && N == V */
2706
            tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2707
                                frn, frm);
2708
            tmp = tcg_temp_new_i32();
2709
            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2710
            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2711
                                dest, frm);
2712
            tcg_temp_free_i32(tmp);
2713
            break;
2714
        }
2715
        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2716
        tcg_temp_free_i32(frn);
2717
        tcg_temp_free_i32(frm);
2718
        tcg_temp_free_i32(dest);
2719

    
2720
        tcg_temp_free_i32(zero);
2721
    }
2722

    
2723
    return 0;
2724
}
2725

    
2726
static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2727
                            uint32_t rm, uint32_t dp)
2728
{
2729
    uint32_t vmin = extract32(insn, 6, 1);
2730
    TCGv_ptr fpst = get_fpstatus_ptr(0);
2731

    
2732
    if (dp) {
2733
        TCGv_i64 frn, frm, dest;
2734

    
2735
        frn = tcg_temp_new_i64();
2736
        frm = tcg_temp_new_i64();
2737
        dest = tcg_temp_new_i64();
2738

    
2739
        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2740
        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2741
        if (vmin) {
2742
            gen_helper_vfp_minnmd(dest, frn, frm, fpst);
2743
        } else {
2744
            gen_helper_vfp_maxnmd(dest, frn, frm, fpst);
2745
        }
2746
        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2747
        tcg_temp_free_i64(frn);
2748
        tcg_temp_free_i64(frm);
2749
        tcg_temp_free_i64(dest);
2750
    } else {
2751
        TCGv_i32 frn, frm, dest;
2752

    
2753
        frn = tcg_temp_new_i32();
2754
        frm = tcg_temp_new_i32();
2755
        dest = tcg_temp_new_i32();
2756

    
2757
        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2758
        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2759
        if (vmin) {
2760
            gen_helper_vfp_minnms(dest, frn, frm, fpst);
2761
        } else {
2762
            gen_helper_vfp_maxnms(dest, frn, frm, fpst);
2763
        }
2764
        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2765
        tcg_temp_free_i32(frn);
2766
        tcg_temp_free_i32(frm);
2767
        tcg_temp_free_i32(dest);
2768
    }
2769

    
2770
    tcg_temp_free_ptr(fpst);
2771
    return 0;
2772
}
2773

    
2774
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2775
{
2776
    uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2777

    
2778
    if (!arm_feature(env, ARM_FEATURE_V8)) {
2779
        return 1;
2780
    }
2781

    
2782
    if (dp) {
2783
        VFP_DREG_D(rd, insn);
2784
        VFP_DREG_N(rn, insn);
2785
        VFP_DREG_M(rm, insn);
2786
    } else {
2787
        rd = VFP_SREG_D(insn);
2788
        rn = VFP_SREG_N(insn);
2789
        rm = VFP_SREG_M(insn);
2790
    }
2791

    
2792
    if ((insn & 0x0f800e50) == 0x0e000a00) {
2793
        return handle_vsel(insn, rd, rn, rm, dp);
2794
    } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2795
        return handle_vminmaxnm(insn, rd, rn, rm, dp);
2796
    }
2797
    return 1;
2798
}
2799

    
2800
/* Disassemble a VFP instruction.  Returns nonzero if an error occurred
2801
   (ie. an undefined instruction).  */
2802
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2803
{
2804
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2805
    int dp, veclen;
2806
    TCGv_i32 addr;
2807
    TCGv_i32 tmp;
2808
    TCGv_i32 tmp2;
2809

    
2810
    if (!arm_feature(env, ARM_FEATURE_VFP))
2811
        return 1;
2812

    
2813
    if (!s->vfp_enabled) {
2814
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2815
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2816
            return 1;
2817
        rn = (insn >> 16) & 0xf;
2818
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2819
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2820
            return 1;
2821
    }
2822

    
2823
    if (extract32(insn, 28, 4) == 0xf) {
2824
        /* Encodings with T=1 (Thumb) or unconditional (ARM):
2825
         * only used in v8 and above.
2826
         */
2827
        return disas_vfp_v8_insn(env, s, insn);
2828
    }
2829

    
2830
    dp = ((insn & 0xf00) == 0xb00);
2831
    switch ((insn >> 24) & 0xf) {
2832
    case 0xe:
2833
        if (insn & (1 << 4)) {
2834
            /* single register transfer */
2835
            rd = (insn >> 12) & 0xf;
2836
            if (dp) {
2837
                int size;
2838
                int pass;
2839

    
2840
                VFP_DREG_N(rn, insn);
2841
                if (insn & 0xf)
2842
                    return 1;
2843
                if (insn & 0x00c00060
2844
                    && !arm_feature(env, ARM_FEATURE_NEON))
2845
                    return 1;
2846

    
2847
                pass = (insn >> 21) & 1;
2848
                if (insn & (1 << 22)) {
2849
                    size = 0;
2850
                    offset = ((insn >> 5) & 3) * 8;
2851
                } else if (insn & (1 << 5)) {
2852
                    size = 1;
2853
                    offset = (insn & (1 << 6)) ? 16 : 0;
2854
                } else {
2855
                    size = 2;
2856
                    offset = 0;
2857
                }
2858
                if (insn & ARM_CP_RW_BIT) {
2859
                    /* vfp->arm */
2860
                    tmp = neon_load_reg(rn, pass);
2861
                    switch (size) {
2862
                    case 0:
2863
                        if (offset)
2864
                            tcg_gen_shri_i32(tmp, tmp, offset);
2865
                        if (insn & (1 << 23))
2866
                            gen_uxtb(tmp);
2867
                        else
2868
                            gen_sxtb(tmp);
2869
                        break;
2870
                    case 1:
2871
                        if (insn & (1 << 23)) {
2872
                            if (offset) {
2873
                                tcg_gen_shri_i32(tmp, tmp, 16);
2874
                            } else {
2875
                                gen_uxth(tmp);
2876
                            }
2877
                        } else {
2878
                            if (offset) {
2879
                                tcg_gen_sari_i32(tmp, tmp, 16);
2880
                            } else {
2881
                                gen_sxth(tmp);
2882
                            }
2883
                        }
2884
                        break;
2885
                    case 2:
2886
                        break;
2887
                    }
2888
                    store_reg(s, rd, tmp);
2889
                } else {
2890
                    /* arm->vfp */
2891
                    tmp = load_reg(s, rd);
2892
                    if (insn & (1 << 23)) {
2893
                        /* VDUP */
2894
                        if (size == 0) {
2895
                            gen_neon_dup_u8(tmp, 0);
2896
                        } else if (size == 1) {
2897
                            gen_neon_dup_low16(tmp);
2898
                        }
2899
                        for (n = 0; n <= pass * 2; n++) {
2900
                            tmp2 = tcg_temp_new_i32();
2901
                            tcg_gen_mov_i32(tmp2, tmp);
2902
                            neon_store_reg(rn, n, tmp2);
2903
                        }
2904
                        neon_store_reg(rn, n, tmp);
2905
                    } else {
2906
                        /* VMOV */
2907
                        switch (size) {
2908
                        case 0:
2909
                            tmp2 = neon_load_reg(rn, pass);
2910
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2911
                            tcg_temp_free_i32(tmp2);
2912
                            break;
2913
                        case 1:
2914
                            tmp2 = neon_load_reg(rn, pass);
2915
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2916
                            tcg_temp_free_i32(tmp2);
2917
                            break;
2918
                        case 2:
2919
                            break;
2920
                        }
2921
                        neon_store_reg(rn, pass, tmp);
2922
                    }
2923
                }
2924
            } else { /* !dp */
2925
                if ((insn & 0x6f) != 0x00)
2926
                    return 1;
2927
                rn = VFP_SREG_N(insn);
2928
                if (insn & ARM_CP_RW_BIT) {
2929
                    /* vfp->arm */
2930
                    if (insn & (1 << 21)) {
2931
                        /* system register */
2932
                        rn >>= 1;
2933

    
2934
                        switch (rn) {
2935
                        case ARM_VFP_FPSID:
2936
                            /* VFP2 allows access to FSID from userspace.
2937
                               VFP3 restricts all id registers to privileged
2938
                               accesses.  */
2939
                            if (IS_USER(s)
2940
                                && arm_feature(env, ARM_FEATURE_VFP3))
2941
                                return 1;
2942
                            tmp = load_cpu_field(vfp.xregs[rn]);
2943
                            break;
2944
                        case ARM_VFP_FPEXC:
2945
                            if (IS_USER(s))
2946
                                return 1;
2947
                            tmp = load_cpu_field(vfp.xregs[rn]);
2948
                            break;
2949
                        case ARM_VFP_FPINST:
2950
                        case ARM_VFP_FPINST2:
2951
                            /* Not present in VFP3.  */
2952
                            if (IS_USER(s)
2953
                                || arm_feature(env, ARM_FEATURE_VFP3))
2954
                                return 1;
2955
                            tmp = load_cpu_field(vfp.xregs[rn]);
2956
                            break;
2957
                        case ARM_VFP_FPSCR:
2958
                            if (rd == 15) {
2959
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2960
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2961
                            } else {
2962
                                tmp = tcg_temp_new_i32();
2963
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2964
                            }
2965
                            break;
2966
                        case ARM_VFP_MVFR0:
2967
                        case ARM_VFP_MVFR1:
2968
                            if (IS_USER(s)
2969
                                || !arm_feature(env, ARM_FEATURE_MVFR))
2970
                                return 1;
2971
                            tmp = load_cpu_field(vfp.xregs[rn]);
2972
                            break;
2973
                        default:
2974
                            return 1;
2975
                        }
2976
                    } else {
2977
                        gen_mov_F0_vreg(0, rn);
2978
                        tmp = gen_vfp_mrs();
2979
                    }
2980
                    if (rd == 15) {
2981
                        /* Set the 4 flag bits in the CPSR.  */
2982
                        gen_set_nzcv(tmp);
2983
                        tcg_temp_free_i32(tmp);
2984
                    } else {
2985
                        store_reg(s, rd, tmp);
2986
                    }
2987
                } else {
2988
                    /* arm->vfp */
2989
                    if (insn & (1 << 21)) {
2990
                        rn >>= 1;
2991
                        /* system register */
2992
                        switch (rn) {
2993
                        case ARM_VFP_FPSID:
2994
                        case ARM_VFP_MVFR0:
2995
                        case ARM_VFP_MVFR1:
2996
                            /* Writes are ignored.  */
2997
                            break;
2998
                        case ARM_VFP_FPSCR:
2999
                            tmp = load_reg(s, rd);
3000
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
3001
                            tcg_temp_free_i32(tmp);
3002
                            gen_lookup_tb(s);
3003
                            break;
3004
                        case ARM_VFP_FPEXC:
3005
                            if (IS_USER(s))
3006
                                return 1;
3007
                            /* TODO: VFP subarchitecture support.
3008
                             * For now, keep the EN bit only */
3009
                            tmp = load_reg(s, rd);
3010
                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3011
                            store_cpu_field(tmp, vfp.xregs[rn]);
3012
                            gen_lookup_tb(s);
3013
                            break;
3014
                        case ARM_VFP_FPINST:
3015
                        case ARM_VFP_FPINST2:
3016
                            tmp = load_reg(s, rd);
3017
                            store_cpu_field(tmp, vfp.xregs[rn]);
3018
                            break;
3019
                        default:
3020
                            return 1;
3021
                        }
3022
                    } else {
3023
                        tmp = load_reg(s, rd);
3024
                        gen_vfp_msr(tmp);
3025
                        gen_mov_vreg_F0(0, rn);
3026
                    }
3027
                }
3028
            }
3029
        } else {
3030
            /* data processing */
3031
            /* The opcode is in bits 23, 21, 20 and 6.  */
3032
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3033
            if (dp) {
3034
                if (op == 15) {
3035
                    /* rn is opcode */
3036
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3037
                } else {
3038
                    /* rn is register number */
3039
                    VFP_DREG_N(rn, insn);
3040
                }
3041

    
3042
                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3043
                    /* Integer or single precision destination.  */
3044
                    rd = VFP_SREG_D(insn);
3045
                } else {
3046
                    VFP_DREG_D(rd, insn);
3047
                }
3048
                if (op == 15 &&
3049
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3050
                    /* VCVT from int is always from S reg regardless of dp bit.
3051
                     * VCVT with immediate frac_bits has same format as SREG_M
3052
                     */
3053
                    rm = VFP_SREG_M(insn);
3054
                } else {
3055
                    VFP_DREG_M(rm, insn);
3056
                }
3057
            } else {
3058
                rn = VFP_SREG_N(insn);
3059
                if (op == 15 && rn == 15) {
3060
                    /* Double precision destination.  */
3061
                    VFP_DREG_D(rd, insn);
3062
                } else {
3063
                    rd = VFP_SREG_D(insn);
3064
                }
3065
                /* NB that we implicitly rely on the encoding for the frac_bits
3066
                 * in VCVT of fixed to float being the same as that of an SREG_M
3067
                 */
3068
                rm = VFP_SREG_M(insn);
3069
            }
3070

    
3071
            veclen = s->vec_len;
3072
            if (op == 15 && rn > 3)
3073
                veclen = 0;
3074

    
3075
            /* Shut up compiler warnings.  */
3076
            delta_m = 0;
3077
            delta_d = 0;
3078
            bank_mask = 0;
3079

    
3080
            if (veclen > 0) {
3081
                if (dp)
3082
                    bank_mask = 0xc;
3083
                else
3084
                    bank_mask = 0x18;
3085

    
3086
                /* Figure out what type of vector operation this is.  */
3087
                if ((rd & bank_mask) == 0) {
3088
                    /* scalar */
3089
                    veclen = 0;
3090
                } else {
3091
                    if (dp)
3092
                        delta_d = (s->vec_stride >> 1) + 1;
3093
                    else
3094
                        delta_d = s->vec_stride + 1;
3095

    
3096
                    if ((rm & bank_mask) == 0) {
3097
                        /* mixed scalar/vector */
3098
                        delta_m = 0;
3099
                    } else {
3100
                        /* vector */
3101
                        delta_m = delta_d;
3102
                    }
3103
                }
3104
            }
3105

    
3106
            /* Load the initial operands.  */
3107
            if (op == 15) {
3108
                switch (rn) {
3109
                case 16:
3110
                case 17:
3111
                    /* Integer source */
3112
                    gen_mov_F0_vreg(0, rm);
3113
                    break;
3114
                case 8:
3115
                case 9:
3116
                    /* Compare */
3117
                    gen_mov_F0_vreg(dp, rd);
3118
                    gen_mov_F1_vreg(dp, rm);
3119
                    break;
3120
                case 10:
3121
                case 11:
3122
                    /* Compare with zero */
3123
                    gen_mov_F0_vreg(dp, rd);
3124
                    gen_vfp_F1_ld0(dp);
3125
                    break;
3126
                case 20:
3127
                case 21:
3128
                case 22:
3129
                case 23:
3130
                case 28:
3131
                case 29:
3132
                case 30:
3133
                case 31:
3134
                    /* Source and destination the same.  */
3135
                    gen_mov_F0_vreg(dp, rd);
3136
                    break;
3137
                case 4:
3138
                case 5:
3139
                case 6:
3140
                case 7:
3141
                    /* VCVTB, VCVTT: only present with the halfprec extension,
3142
                     * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3143
                     */
3144
                    if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3145
                        return 1;
3146
                    }
3147
                    /* Otherwise fall through */
3148
                default:
3149
                    /* One source operand.  */
3150
                    gen_mov_F0_vreg(dp, rm);
3151
                    break;
3152
                }
3153
            } else {
3154
                /* Two source operands.  */
3155
                gen_mov_F0_vreg(dp, rn);
3156
                gen_mov_F1_vreg(dp, rm);
3157
            }
3158

    
3159
            for (;;) {
3160
                /* Perform the calculation.  */
3161
                switch (op) {
3162
                case 0: /* VMLA: fd + (fn * fm) */
3163
                    /* Note that order of inputs to the add matters for NaNs */
3164
                    gen_vfp_F1_mul(dp);
3165
                    gen_mov_F0_vreg(dp, rd);
3166
                    gen_vfp_add(dp);
3167
                    break;
3168
                case 1: /* VMLS: fd + -(fn * fm) */
3169
                    gen_vfp_mul(dp);
3170
                    gen_vfp_F1_neg(dp);
3171
                    gen_mov_F0_vreg(dp, rd);
3172
                    gen_vfp_add(dp);
3173
                    break;
3174
                case 2: /* VNMLS: -fd + (fn * fm) */
3175
                    /* Note that it isn't valid to replace (-A + B) with (B - A)
3176
                     * or similar plausible looking simplifications
3177
                     * because this will give wrong results for NaNs.
3178
                     */
3179
                    gen_vfp_F1_mul(dp);
3180
                    gen_mov_F0_vreg(dp, rd);
3181
                    gen_vfp_neg(dp);
3182
                    gen_vfp_add(dp);
3183
                    break;
3184
                case 3: /* VNMLA: -fd + -(fn * fm) */
3185
                    gen_vfp_mul(dp);
3186
                    gen_vfp_F1_neg(dp);
3187
                    gen_mov_F0_vreg(dp, rd);
3188
                    gen_vfp_neg(dp);
3189
                    gen_vfp_add(dp);
3190
                    break;
3191
                case 4: /* mul: fn * fm */
3192
                    gen_vfp_mul(dp);
3193
                    break;
3194
                case 5: /* nmul: -(fn * fm) */
3195
                    gen_vfp_mul(dp);
3196
                    gen_vfp_neg(dp);
3197
                    break;
3198
                case 6: /* add: fn + fm */
3199
                    gen_vfp_add(dp);
3200
                    break;
3201
                case 7: /* sub: fn - fm */
3202
                    gen_vfp_sub(dp);
3203
                    break;
3204
                case 8: /* div: fn / fm */
3205
                    gen_vfp_div(dp);
3206
                    break;
3207
                case 10: /* VFNMA : fd = muladd(-fd,  fn, fm) */
3208
                case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3209
                case 12: /* VFMA  : fd = muladd( fd,  fn, fm) */
3210
                case 13: /* VFMS  : fd = muladd( fd, -fn, fm) */
3211
                    /* These are fused multiply-add, and must be done as one
3212
                     * floating point operation with no rounding between the
3213
                     * multiplication and addition steps.
3214
                     * NB that doing the negations here as separate steps is
3215
                     * correct : an input NaN should come out with its sign bit
3216
                     * flipped if it is a negated-input.
3217
                     */
3218
                    if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3219
                        return 1;
3220
                    }
3221
                    if (dp) {
3222
                        TCGv_ptr fpst;
3223
                        TCGv_i64 frd;
3224
                        if (op & 1) {
3225
                            /* VFNMS, VFMS */
3226
                            gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3227
                        }
3228
                        frd = tcg_temp_new_i64();
3229
                        tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3230
                        if (op & 2) {
3231
                            /* VFNMA, VFNMS */
3232
                            gen_helper_vfp_negd(frd, frd);
3233
                        }
3234
                        fpst = get_fpstatus_ptr(0);
3235
                        gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3236
                                               cpu_F1d, frd, fpst);
3237
                        tcg_temp_free_ptr(fpst);
3238
                        tcg_temp_free_i64(frd);
3239
                    } else {
3240
                        TCGv_ptr fpst;
3241
                        TCGv_i32 frd;
3242
                        if (op & 1) {
3243
                            /* VFNMS, VFMS */
3244
                            gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3245
                        }
3246
                        frd = tcg_temp_new_i32();
3247
                        tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3248
                        if (op & 2) {
3249
                            gen_helper_vfp_negs(frd, frd);
3250
                        }
3251
                        fpst = get_fpstatus_ptr(0);
3252
                        gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3253
                                               cpu_F1s, frd, fpst);
3254
                        tcg_temp_free_ptr(fpst);
3255
                        tcg_temp_free_i32(frd);
3256
                    }
3257
                    break;
3258
                case 14: /* fconst */
3259
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3260
                      return 1;
3261

    
3262
                    n = (insn << 12) & 0x80000000;
3263
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3264
                    if (dp) {
3265
                        if (i & 0x40)
3266
                            i |= 0x3f80;
3267
                        else
3268
                            i |= 0x4000;
3269
                        n |= i << 16;
3270
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3271
                    } else {
3272
                        if (i & 0x40)
3273
                            i |= 0x780;
3274
                        else
3275
                            i |= 0x800;
3276
                        n |= i << 19;
3277
                        tcg_gen_movi_i32(cpu_F0s, n);
3278
                    }
3279
                    break;
3280
                case 15: /* extension space */
3281
                    switch (rn) {
3282
                    case 0: /* cpy */
3283
                        /* no-op */
3284
                        break;
3285
                    case 1: /* abs */
3286
                        gen_vfp_abs(dp);
3287
                        break;
3288
                    case 2: /* neg */
3289
                        gen_vfp_neg(dp);
3290
                        break;
3291
                    case 3: /* sqrt */
3292
                        gen_vfp_sqrt(dp);
3293
                        break;
3294
                    case 4: /* vcvtb.f32.f16 */
3295
                        tmp = gen_vfp_mrs();
3296
                        tcg_gen_ext16u_i32(tmp, tmp);
3297
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3298
                        tcg_temp_free_i32(tmp);
3299
                        break;
3300
                    case 5: /* vcvtt.f32.f16 */
3301
                        tmp = gen_vfp_mrs();
3302
                        tcg_gen_shri_i32(tmp, tmp, 16);
3303
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3304
                        tcg_temp_free_i32(tmp);
3305
                        break;
3306
                    case 6: /* vcvtb.f16.f32 */
3307
                        tmp = tcg_temp_new_i32();
3308
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3309
                        gen_mov_F0_vreg(0, rd);
3310
                        tmp2 = gen_vfp_mrs();
3311
                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3312
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3313
                        tcg_temp_free_i32(tmp2);
3314
                        gen_vfp_msr(tmp);
3315
                        break;
3316
                    case 7: /* vcvtt.f16.f32 */
3317
                        tmp = tcg_temp_new_i32();
3318
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3319
                        tcg_gen_shli_i32(tmp, tmp, 16);
3320
                        gen_mov_F0_vreg(0, rd);
3321
                        tmp2 = gen_vfp_mrs();
3322
                        tcg_gen_ext16u_i32(tmp2, tmp2);
3323
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3324
                        tcg_temp_free_i32(tmp2);
3325
                        gen_vfp_msr(tmp);
3326
                        break;
3327
                    case 8: /* cmp */
3328
                        gen_vfp_cmp(dp);
3329
                        break;
3330
                    case 9: /* cmpe */
3331
                        gen_vfp_cmpe(dp);
3332
                        break;
3333
                    case 10: /* cmpz */
3334
                        gen_vfp_cmp(dp);
3335
                        break;
3336
                    case 11: /* cmpez */
3337
                        gen_vfp_F1_ld0(dp);
3338
                        gen_vfp_cmpe(dp);
3339
                        break;
3340
                    case 15: /* single<->double conversion */
3341
                        if (dp)
3342
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3343
                        else
3344
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3345
                        break;
3346
                    case 16: /* fuito */
3347
                        gen_vfp_uito(dp, 0);
3348
                        break;
3349
                    case 17: /* fsito */
3350
                        gen_vfp_sito(dp, 0);
3351
                        break;
3352
                    case 20: /* fshto */
3353
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3354
                          return 1;
3355
                        gen_vfp_shto(dp, 16 - rm, 0);
3356
                        break;
3357
                    case 21: /* fslto */
3358
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3359
                          return 1;
3360
                        gen_vfp_slto(dp, 32 - rm, 0);
3361
                        break;
3362
                    case 22: /* fuhto */
3363
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3364
                          return 1;
3365
                        gen_vfp_uhto(dp, 16 - rm, 0);
3366
                        break;
3367
                    case 23: /* fulto */
3368
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3369
                          return 1;
3370
                        gen_vfp_ulto(dp, 32 - rm, 0);
3371
                        break;
3372
                    case 24: /* ftoui */
3373
                        gen_vfp_toui(dp, 0);
3374
                        break;
3375
                    case 25: /* ftouiz */
3376
                        gen_vfp_touiz(dp, 0);
3377
                        break;
3378
                    case 26: /* ftosi */
3379
                        gen_vfp_tosi(dp, 0);
3380
                        break;
3381
                    case 27: /* ftosiz */
3382
                        gen_vfp_tosiz(dp, 0);
3383
                        break;
3384
                    case 28: /* ftosh */
3385
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3386
                          return 1;
3387
                        gen_vfp_tosh(dp, 16 - rm, 0);
3388
                        break;
3389
                    case 29: /* ftosl */
3390
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3391
                          return 1;
3392
                        gen_vfp_tosl(dp, 32 - rm, 0);
3393
                        break;
3394
                    case 30: /* ftouh */
3395
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3396
                          return 1;
3397
                        gen_vfp_touh(dp, 16 - rm, 0);
3398
                        break;
3399
                    case 31: /* ftoul */
3400
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3401
                          return 1;
3402
                        gen_vfp_toul(dp, 32 - rm, 0);
3403
                        break;
3404
                    default: /* undefined */
3405
                        return 1;
3406
                    }
3407
                    break;
3408
                default: /* undefined */
3409
                    return 1;
3410
                }
3411

    
3412
                /* Write back the result.  */
3413
                if (op == 15 && (rn >= 8 && rn <= 11))
3414
                    ; /* Comparison, do nothing.  */
3415
                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3416
                    /* VCVT double to int: always integer result. */
3417
                    gen_mov_vreg_F0(0, rd);
3418
                else if (op == 15 && rn == 15)
3419
                    /* conversion */
3420
                    gen_mov_vreg_F0(!dp, rd);
3421
                else
3422
                    gen_mov_vreg_F0(dp, rd);
3423

    
3424
                /* break out of the loop if we have finished  */
3425
                if (veclen == 0)
3426
                    break;
3427

    
3428
                if (op == 15 && delta_m == 0) {
3429
                    /* single source one-many */
3430
                    while (veclen--) {
3431
                        rd = ((rd + delta_d) & (bank_mask - 1))
3432
                             | (rd & bank_mask);
3433
                        gen_mov_vreg_F0(dp, rd);
3434
                    }
3435
                    break;
3436
                }
3437
                /* Setup the next operands.  */
3438
                veclen--;
3439
                rd = ((rd + delta_d) & (bank_mask - 1))
3440
                     | (rd & bank_mask);
3441

    
3442
                if (op == 15) {
3443
                    /* One source operand.  */
3444
                    rm = ((rm + delta_m) & (bank_mask - 1))
3445
                         | (rm & bank_mask);
3446
                    gen_mov_F0_vreg(dp, rm);
3447
                } else {
3448
                    /* Two source operands.  */
3449
                    rn = ((rn + delta_d) & (bank_mask - 1))
3450
                         | (rn & bank_mask);
3451
                    gen_mov_F0_vreg(dp, rn);
3452
                    if (delta_m) {
3453
                        rm = ((rm + delta_m) & (bank_mask - 1))
3454
                             | (rm & bank_mask);
3455
                        gen_mov_F1_vreg(dp, rm);
3456
                    }
3457
                }
3458
            }
3459
        }
3460
        break;
3461
    case 0xc:
3462
    case 0xd:
3463
        if ((insn & 0x03e00000) == 0x00400000) {
3464
            /* two-register transfer */
3465
            rn = (insn >> 16) & 0xf;
3466
            rd = (insn >> 12) & 0xf;
3467
            if (dp) {
3468
                VFP_DREG_M(rm, insn);
3469
            } else {
3470
                rm = VFP_SREG_M(insn);
3471
            }
3472

    
3473
            if (insn & ARM_CP_RW_BIT) {
3474
                /* vfp->arm */
3475
                if (dp) {
3476
                    gen_mov_F0_vreg(0, rm * 2);
3477
                    tmp = gen_vfp_mrs();
3478
                    store_reg(s, rd, tmp);
3479
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3480
                    tmp = gen_vfp_mrs();
3481
                    store_reg(s, rn, tmp);
3482
                } else {
3483
                    gen_mov_F0_vreg(0, rm);
3484
                    tmp = gen_vfp_mrs();
3485
                    store_reg(s, rd, tmp);
3486
                    gen_mov_F0_vreg(0, rm + 1);
3487
                    tmp = gen_vfp_mrs();
3488
                    store_reg(s, rn, tmp);
3489
                }
3490
            } else {
3491
                /* arm->vfp */
3492
                if (dp) {
3493
                    tmp = load_reg(s, rd);
3494
                    gen_vfp_msr(tmp);
3495
                    gen_mov_vreg_F0(0, rm * 2);
3496
                    tmp = load_reg(s, rn);
3497
                    gen_vfp_msr(tmp);
3498
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3499
                } else {
3500
                    tmp = load_reg(s, rd);
3501
                    gen_vfp_msr(tmp);
3502
                    gen_mov_vreg_F0(0, rm);
3503
                    tmp = load_reg(s, rn);
3504
                    gen_vfp_msr(tmp);
3505
                    gen_mov_vreg_F0(0, rm + 1);
3506
                }
3507
            }
3508
        } else {
3509
            /* Load/store */
3510
            rn = (insn >> 16) & 0xf;
3511
            if (dp)
3512
                VFP_DREG_D(rd, insn);
3513
            else
3514
                rd = VFP_SREG_D(insn);
3515
            if ((insn & 0x01200000) == 0x01000000) {
3516
                /* Single load/store */
3517
                offset = (insn & 0xff) << 2;
3518
                if ((insn & (1 << 23)) == 0)
3519
                    offset = -offset;
3520
                if (s->thumb && rn == 15) {
3521
                    /* This is actually UNPREDICTABLE */
3522
                    addr = tcg_temp_new_i32();
3523
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3524
                } else {
3525
                    addr = load_reg(s, rn);
3526
                }
3527
                tcg_gen_addi_i32(addr, addr, offset);
3528
                if (insn & (1 << 20)) {
3529
                    gen_vfp_ld(s, dp, addr);
3530
                    gen_mov_vreg_F0(dp, rd);
3531
                } else {
3532
                    gen_mov_F0_vreg(dp, rd);
3533
                    gen_vfp_st(s, dp, addr);
3534
                }
3535
                tcg_temp_free_i32(addr);
3536
            } else {
3537
                /* load/store multiple */
3538
                int w = insn & (1 << 21);
3539
                if (dp)
3540
                    n = (insn >> 1) & 0x7f;
3541
                else
3542
                    n = insn & 0xff;
3543

    
3544
                if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3545
                    /* P == U , W == 1  => UNDEF */
3546
                    return 1;
3547
                }
3548
                if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3549
                    /* UNPREDICTABLE cases for bad immediates: we choose to
3550
                     * UNDEF to avoid generating huge numbers of TCG ops
3551
                     */
3552
                    return 1;
3553
                }
3554
                if (rn == 15 && w) {
3555
                    /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3556
                    return 1;
3557
                }
3558

    
3559
                if (s->thumb && rn == 15) {
3560
                    /* This is actually UNPREDICTABLE */
3561
                    addr = tcg_temp_new_i32();
3562
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3563
                } else {
3564
                    addr = load_reg(s, rn);
3565
                }
3566
                if (insn & (1 << 24)) /* pre-decrement */
3567
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3568

    
3569
                if (dp)
3570
                    offset = 8;
3571
                else
3572
                    offset = 4;
3573
                for (i = 0; i < n; i++) {
3574
                    if (insn & ARM_CP_RW_BIT) {
3575
                        /* load */
3576
                        gen_vfp_ld(s, dp, addr);
3577
                        gen_mov_vreg_F0(dp, rd + i);
3578
                    } else {
3579
                        /* store */
3580
                        gen_mov_F0_vreg(dp, rd + i);
3581
                        gen_vfp_st(s, dp, addr);
3582
                    }
3583
                    tcg_gen_addi_i32(addr, addr, offset);
3584
                }
3585
                if (w) {
3586
                    /* writeback */
3587
                    if (insn & (1 << 24))
3588
                        offset = -offset * n;
3589
                    else if (dp && (insn & 1))
3590
                        offset = 4;
3591
                    else
3592
                        offset = 0;
3593

    
3594
                    if (offset != 0)
3595
                        tcg_gen_addi_i32(addr, addr, offset);
3596
                    store_reg(s, rn, addr);
3597
                } else {
3598
                    tcg_temp_free_i32(addr);
3599
                }
3600
            }
3601
        }
3602
        break;
3603
    default:
3604
        /* Should never happen.  */
3605
        return 1;
3606
    }
3607
    return 0;
3608
}
3609

    
3610
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3611
{
3612
    TranslationBlock *tb;
3613

    
3614
    tb = s->tb;
3615
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3616
        tcg_gen_goto_tb(n);
3617
        gen_set_pc_im(s, dest);
3618
        tcg_gen_exit_tb((uintptr_t)tb + n);
3619
    } else {
3620
        gen_set_pc_im(s, dest);
3621
        tcg_gen_exit_tb(0);
3622
    }
3623
}
3624

    
3625
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3626
{
3627
    if (unlikely(s->singlestep_enabled)) {
3628
        /* An indirect jump so that we still trigger the debug exception.  */
3629
        if (s->thumb)
3630
            dest |= 1;
3631
        gen_bx_im(s, dest);
3632
    } else {
3633
        gen_goto_tb(s, 0, dest);
3634
        s->is_jmp = DISAS_TB_JUMP;
3635
    }
3636
}
3637

    
3638
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3639
{
3640
    if (x)
3641
        tcg_gen_sari_i32(t0, t0, 16);
3642
    else
3643
        gen_sxth(t0);
3644
    if (y)
3645
        tcg_gen_sari_i32(t1, t1, 16);
3646
    else
3647
        gen_sxth(t1);
3648
    tcg_gen_mul_i32(t0, t0, t1);
3649
}
3650

    
3651
/* Return the mask of PSR bits set by a MSR instruction.  */
3652
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3653
    uint32_t mask;
3654

    
3655
    mask = 0;
3656
    if (flags & (1 << 0))
3657
        mask |= 0xff;
3658
    if (flags & (1 << 1))
3659
        mask |= 0xff00;
3660
    if (flags & (1 << 2))
3661
        mask |= 0xff0000;
3662
    if (flags & (1 << 3))
3663
        mask |= 0xff000000;
3664

    
3665
    /* Mask out undefined bits.  */
3666
    mask &= ~CPSR_RESERVED;
3667
    if (!arm_feature(env, ARM_FEATURE_V4T))
3668
        mask &= ~CPSR_T;
3669
    if (!arm_feature(env, ARM_FEATURE_V5))
3670
        mask &= ~CPSR_Q; /* V5TE in reality*/
3671
    if (!arm_feature(env, ARM_FEATURE_V6))
3672
        mask &= ~(CPSR_E | CPSR_GE);
3673
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3674
        mask &= ~CPSR_IT;
3675
    /* Mask out execution state bits.  */
3676
    if (!spsr)
3677
        mask &= ~CPSR_EXEC;
3678
    /* Mask out privileged bits.  */
3679
    if (IS_USER(s))
3680
        mask &= CPSR_USER;
3681
    return mask;
3682
}
3683

    
3684
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3685
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3686
{
3687
    TCGv_i32 tmp;
3688
    if (spsr) {
3689
        /* ??? This is also undefined in system mode.  */
3690
        if (IS_USER(s))
3691
            return 1;
3692

    
3693
        tmp = load_cpu_field(spsr);
3694
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3695
        tcg_gen_andi_i32(t0, t0, mask);
3696
        tcg_gen_or_i32(tmp, tmp, t0);
3697
        store_cpu_field(tmp, spsr);
3698
    } else {
3699
        gen_set_cpsr(t0, mask);
3700
    }
3701
    tcg_temp_free_i32(t0);
3702
    gen_lookup_tb(s);
3703
    return 0;
3704
}
3705

    
3706
/* Returns nonzero if access to the PSR is not permitted.  */
3707
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3708
{
3709
    TCGv_i32 tmp;
3710
    tmp = tcg_temp_new_i32();
3711
    tcg_gen_movi_i32(tmp, val);
3712
    return gen_set_psr(s, mask, spsr, tmp);
3713
}
3714

    
3715
/* Generate an old-style exception return. Marks pc as dead. */
3716
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3717
{
3718
    TCGv_i32 tmp;
3719
    store_reg(s, 15, pc);
3720
    tmp = load_cpu_field(spsr);
3721
    gen_set_cpsr(tmp, 0xffffffff);
3722
    tcg_temp_free_i32(tmp);
3723
    s->is_jmp = DISAS_UPDATE;
3724
}
3725

    
3726
/* Generate a v6 exception return.  Marks both values as dead.  */
3727
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3728
{
3729
    gen_set_cpsr(cpsr, 0xffffffff);
3730
    tcg_temp_free_i32(cpsr);
3731
    store_reg(s, 15, pc);
3732
    s->is_jmp = DISAS_UPDATE;
3733
}
3734

    
3735
static inline void
3736
gen_set_condexec (DisasContext *s)
3737
{
3738
    if (s->condexec_mask) {
3739
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3740
        TCGv_i32 tmp = tcg_temp_new_i32();
3741
        tcg_gen_movi_i32(tmp, val);
3742
        store_cpu_field(tmp, condexec_bits);
3743
    }
3744
}
3745

    
3746
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3747
{
3748
    gen_set_condexec(s);
3749
    gen_set_pc_im(s, s->pc - offset);
3750
    gen_exception(excp);
3751
    s->is_jmp = DISAS_JUMP;
3752
}
3753

    
3754
static void gen_nop_hint(DisasContext *s, int val)
3755
{
3756
    switch (val) {
3757
    case 3: /* wfi */
3758
        gen_set_pc_im(s, s->pc);
3759
        s->is_jmp = DISAS_WFI;
3760
        break;
3761
    case 2: /* wfe */
3762
    case 4: /* sev */
3763
    case 5: /* sevl */
3764
        /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */
3765
    default: /* nop */
3766
        break;
3767
    }
3768
}
3769

    
3770
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3771

    
3772
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3773
{
3774
    switch (size) {
3775
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3776
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3777
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3778
    default: abort();
3779
    }
3780
}
3781

    
3782
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3783
{
3784
    switch (size) {
3785
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3786
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3787
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3788
    default: return;
3789
    }
3790
}
3791

    
3792
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3793
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3794
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3795
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3796
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3797

    
3798
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3799
    switch ((size << 1) | u) { \
3800
    case 0: \
3801
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3802
        break; \
3803
    case 1: \
3804
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3805
        break; \
3806
    case 2: \
3807
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3808
        break; \
3809
    case 3: \
3810
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3811
        break; \
3812
    case 4: \
3813
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3814
        break; \
3815
    case 5: \
3816
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3817
        break; \
3818
    default: return 1; \
3819
    }} while (0)
3820

    
3821
#define GEN_NEON_INTEGER_OP(name) do { \
3822
    switch ((size << 1) | u) { \
3823
    case 0: \
3824
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3825
        break; \
3826
    case 1: \
3827
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3828
        break; \
3829
    case 2: \
3830
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3831
        break; \
3832
    case 3: \
3833
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3834
        break; \
3835
    case 4: \
3836
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3837
        break; \
3838
    case 5: \
3839
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3840
        break; \
3841
    default: return 1; \
3842
    }} while (0)
3843

    
3844
static TCGv_i32 neon_load_scratch(int scratch)
3845
{
3846
    TCGv_i32 tmp = tcg_temp_new_i32();
3847
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3848
    return tmp;
3849
}
3850

    
3851
static void neon_store_scratch(int scratch, TCGv_i32 var)
3852
{
3853
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3854
    tcg_temp_free_i32(var);
3855
}
3856

    
3857
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3858
{
3859
    TCGv_i32 tmp;
3860
    if (size == 1) {
3861
        tmp = neon_load_reg(reg & 7, reg >> 4);
3862
        if (reg & 8) {
3863
            gen_neon_dup_high16(tmp);
3864
        } else {
3865
            gen_neon_dup_low16(tmp);
3866
        }
3867
    } else {
3868
        tmp = neon_load_reg(reg & 15, reg >> 4);
3869
    }
3870
    return tmp;
3871
}
3872

    
3873
static int gen_neon_unzip(int rd, int rm, int size, int q)
3874
{
3875
    TCGv_i32 tmp, tmp2;
3876
    if (!q && size == 2) {
3877
        return 1;
3878
    }
3879
    tmp = tcg_const_i32(rd);
3880
    tmp2 = tcg_const_i32(rm);
3881
    if (q) {
3882
        switch (size) {
3883
        case 0:
3884
            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3885
            break;
3886
        case 1:
3887
            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3888
            break;
3889
        case 2:
3890
            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3891
            break;
3892
        default:
3893
            abort();
3894
        }
3895
    } else {
3896
        switch (size) {
3897
        case 0:
3898
            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3899
            break;
3900
        case 1:
3901
            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3902
            break;
3903
        default:
3904
            abort();
3905
        }
3906
    }
3907
    tcg_temp_free_i32(tmp);
3908
    tcg_temp_free_i32(tmp2);
3909
    return 0;
3910
}
3911

    
3912
static int gen_neon_zip(int rd, int rm, int size, int q)
3913
{
3914
    TCGv_i32 tmp, tmp2;
3915
    if (!q && size == 2) {
3916
        return 1;
3917
    }
3918
    tmp = tcg_const_i32(rd);
3919
    tmp2 = tcg_const_i32(rm);
3920
    if (q) {
3921
        switch (size) {
3922
        case 0:
3923
            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3924
            break;
3925
        case 1:
3926
            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3927
            break;
3928
        case 2:
3929
            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3930
            break;
3931
        default:
3932
            abort();
3933
        }
3934
    } else {
3935
        switch (size) {
3936
        case 0:
3937
            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3938
            break;
3939
        case 1:
3940
            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3941
            break;
3942
        default:
3943
            abort();
3944
        }
3945
    }
3946
    tcg_temp_free_i32(tmp);
3947
    tcg_temp_free_i32(tmp2);
3948
    return 0;
3949
}
3950

    
3951
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3952
{
3953
    TCGv_i32 rd, tmp;
3954

    
3955
    rd = tcg_temp_new_i32();
3956
    tmp = tcg_temp_new_i32();
3957

    
3958
    tcg_gen_shli_i32(rd, t0, 8);
3959
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3960
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3961
    tcg_gen_or_i32(rd, rd, tmp);
3962

    
3963
    tcg_gen_shri_i32(t1, t1, 8);
3964
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3965
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3966
    tcg_gen_or_i32(t1, t1, tmp);
3967
    tcg_gen_mov_i32(t0, rd);
3968

    
3969
    tcg_temp_free_i32(tmp);
3970
    tcg_temp_free_i32(rd);
3971
}
3972

    
3973
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3974
{
3975
    TCGv_i32 rd, tmp;
3976

    
3977
    rd = tcg_temp_new_i32();
3978
    tmp = tcg_temp_new_i32();
3979

    
3980
    tcg_gen_shli_i32(rd, t0, 16);
3981
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3982
    tcg_gen_or_i32(rd, rd, tmp);
3983
    tcg_gen_shri_i32(t1, t1, 16);
3984
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3985
    tcg_gen_or_i32(t1, t1, tmp);
3986
    tcg_gen_mov_i32(t0, rd);
3987

    
3988
    tcg_temp_free_i32(tmp);
3989
    tcg_temp_free_i32(rd);
3990
}
3991

    
3992

    
3993
static struct {
3994
    int nregs;
3995
    int interleave;
3996
    int spacing;
3997
} neon_ls_element_type[11] = {
3998
    {4, 4, 1},
3999
    {4, 4, 2},
4000
    {4, 1, 1},
4001
    {4, 2, 1},
4002
    {3, 3, 1},
4003
    {3, 3, 2},
4004
    {3, 1, 1},
4005
    {1, 1, 1},
4006
    {2, 2, 1},
4007
    {2, 2, 2},
4008
    {2, 1, 1}
4009
};
4010

    
4011
/* Translate a NEON load/store element instruction.  Return nonzero if the
4012
   instruction is invalid.  */
4013
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4014
{
4015
    int rd, rn, rm;
4016
    int op;
4017
    int nregs;
4018
    int interleave;
4019
    int spacing;
4020
    int stride;
4021
    int size;
4022
    int reg;
4023
    int pass;
4024
    int load;
4025
    int shift;
4026
    int n;
4027
    TCGv_i32 addr;
4028
    TCGv_i32 tmp;
4029
    TCGv_i32 tmp2;
4030
    TCGv_i64 tmp64;
4031

    
4032
    if (!s->vfp_enabled)
4033
      return 1;
4034
    VFP_DREG_D(rd, insn);
4035
    rn = (insn >> 16) & 0xf;
4036
    rm = insn & 0xf;
4037
    load = (insn & (1 << 21)) != 0;
4038
    if ((insn & (1 << 23)) == 0) {
4039
        /* Load store all elements.  */
4040
        op = (insn >> 8) & 0xf;
4041
        size = (insn >> 6) & 3;
4042
        if (op > 10)
4043
            return 1;
4044
        /* Catch UNDEF cases for bad values of align field */
4045
        switch (op & 0xc) {
4046
        case 4:
4047
            if (((insn >> 5) & 1) == 1) {
4048
                return 1;
4049
            }
4050
            break;
4051
        case 8:
4052
            if (((insn >> 4) & 3) == 3) {
4053
                return 1;
4054
            }
4055
            break;
4056
        default:
4057
            break;
4058
        }
4059
        nregs = neon_ls_element_type[op].nregs;
4060
        interleave = neon_ls_element_type[op].interleave;
4061
        spacing = neon_ls_element_type[op].spacing;
4062
        if (size == 3 && (interleave | spacing) != 1)
4063
            return 1;
4064
        addr = tcg_temp_new_i32();
4065
        load_reg_var(s, addr, rn);
4066
        stride = (1 << size) * interleave;
4067
        for (reg = 0; reg < nregs; reg++) {
4068
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4069
                load_reg_var(s, addr, rn);
4070
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4071
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
4072
                load_reg_var(s, addr, rn);
4073
                tcg_gen_addi_i32(addr, addr, 1 << size);
4074
            }
4075
            if (size == 3) {
4076
                tmp64 = tcg_temp_new_i64();
4077
                if (load) {
4078
                    gen_aa32_ld64(tmp64, addr, IS_USER(s));
4079
                    neon_store_reg64(tmp64, rd);
4080
                } else {
4081
                    neon_load_reg64(tmp64, rd);
4082
                    gen_aa32_st64(tmp64, addr, IS_USER(s));
4083
                }
4084
                tcg_temp_free_i64(tmp64);
4085
                tcg_gen_addi_i32(addr, addr, stride);
4086
            } else {
4087
                for (pass = 0; pass < 2; pass++) {
4088
                    if (size == 2) {
4089
                        if (load) {
4090
                            tmp = tcg_temp_new_i32();
4091
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
4092
                            neon_store_reg(rd, pass, tmp);
4093
                        } else {
4094
                            tmp = neon_load_reg(rd, pass);
4095
                            gen_aa32_st32(tmp, addr, IS_USER(s));
4096
                            tcg_temp_free_i32(tmp);
4097
                        }
4098
                        tcg_gen_addi_i32(addr, addr, stride);
4099
                    } else if (size == 1) {
4100
                        if (load) {
4101
                            tmp = tcg_temp_new_i32();
4102
                            gen_aa32_ld16u(tmp, addr, IS_USER(s));
4103
                            tcg_gen_addi_i32(addr, addr, stride);
4104
                            tmp2 = tcg_temp_new_i32();
4105
                            gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4106
                            tcg_gen_addi_i32(addr, addr, stride);
4107
                            tcg_gen_shli_i32(tmp2, tmp2, 16);
4108
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4109
                            tcg_temp_free_i32(tmp2);
4110
                            neon_store_reg(rd, pass, tmp);
4111
                        } else {
4112
                            tmp = neon_load_reg(rd, pass);
4113
                            tmp2 = tcg_temp_new_i32();
4114
                            tcg_gen_shri_i32(tmp2, tmp, 16);
4115
                            gen_aa32_st16(tmp, addr, IS_USER(s));
4116
                            tcg_temp_free_i32(tmp);
4117
                            tcg_gen_addi_i32(addr, addr, stride);
4118
                            gen_aa32_st16(tmp2, addr, IS_USER(s));
4119
                            tcg_temp_free_i32(tmp2);
4120
                            tcg_gen_addi_i32(addr, addr, stride);
4121
                        }
4122
                    } else /* size == 0 */ {
4123
                        if (load) {
4124
                            TCGV_UNUSED_I32(tmp2);
4125
                            for (n = 0; n < 4; n++) {
4126
                                tmp = tcg_temp_new_i32();
4127
                                gen_aa32_ld8u(tmp, addr, IS_USER(s));
4128
                                tcg_gen_addi_i32(addr, addr, stride);
4129
                                if (n == 0) {
4130
                                    tmp2 = tmp;
4131
                                } else {
4132
                                    tcg_gen_shli_i32(tmp, tmp, n * 8);
4133
                                    tcg_gen_or_i32(tmp2, tmp2, tmp);
4134
                                    tcg_temp_free_i32(tmp);
4135
                                }
4136
                            }
4137
                            neon_store_reg(rd, pass, tmp2);
4138
                        } else {
4139
                            tmp2 = neon_load_reg(rd, pass);
4140
                            for (n = 0; n < 4; n++) {
4141
                                tmp = tcg_temp_new_i32();
4142
                                if (n == 0) {
4143
                                    tcg_gen_mov_i32(tmp, tmp2);
4144
                                } else {
4145
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
4146
                                }
4147
                                gen_aa32_st8(tmp, addr, IS_USER(s));
4148
                                tcg_temp_free_i32(tmp);
4149
                                tcg_gen_addi_i32(addr, addr, stride);
4150
                            }
4151
                            tcg_temp_free_i32(tmp2);
4152
                        }
4153
                    }
4154
                }
4155
            }
4156
            rd += spacing;
4157
        }
4158
        tcg_temp_free_i32(addr);
4159
        stride = nregs * 8;
4160
    } else {
4161
        size = (insn >> 10) & 3;
4162
        if (size == 3) {
4163
            /* Load single element to all lanes.  */
4164
            int a = (insn >> 4) & 1;
4165
            if (!load) {
4166
                return 1;
4167
            }
4168
            size = (insn >> 6) & 3;
4169
            nregs = ((insn >> 8) & 3) + 1;
4170

    
4171
            if (size == 3) {
4172
                if (nregs != 4 || a == 0) {
4173
                    return 1;
4174
                }
4175
                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4176
                size = 2;
4177
            }
4178
            if (nregs == 1 && a == 1 && size == 0) {
4179
                return 1;
4180
            }
4181
            if (nregs == 3 && a == 1) {
4182
                return 1;
4183
            }
4184
            addr = tcg_temp_new_i32();
4185
            load_reg_var(s, addr, rn);
4186
            if (nregs == 1) {
4187
                /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4188
                tmp = gen_load_and_replicate(s, addr, size);
4189
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4190
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4191
                if (insn & (1 << 5)) {
4192
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4193
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4194
                }
4195
                tcg_temp_free_i32(tmp);
4196
            } else {
4197
                /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4198
                stride = (insn & (1 << 5)) ? 2 : 1;
4199
                for (reg = 0; reg < nregs; reg++) {
4200
                    tmp = gen_load_and_replicate(s, addr, size);
4201
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4202
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4203
                    tcg_temp_free_i32(tmp);
4204
                    tcg_gen_addi_i32(addr, addr, 1 << size);
4205
                    rd += stride;
4206
                }
4207
            }
4208
            tcg_temp_free_i32(addr);
4209
            stride = (1 << size) * nregs;
4210
        } else {
4211
            /* Single element.  */
4212
            int idx = (insn >> 4) & 0xf;
4213
            pass = (insn >> 7) & 1;
4214
            switch (size) {
4215
            case 0:
4216
                shift = ((insn >> 5) & 3) * 8;
4217
                stride = 1;
4218
                break;
4219
            case 1:
4220
                shift = ((insn >> 6) & 1) * 16;
4221
                stride = (insn & (1 << 5)) ? 2 : 1;
4222
                break;
4223
            case 2:
4224
                shift = 0;
4225
                stride = (insn & (1 << 6)) ? 2 : 1;
4226
                break;
4227
            default:
4228
                abort();
4229
            }
4230
            nregs = ((insn >> 8) & 3) + 1;
4231
            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4232
            switch (nregs) {
4233
            case 1:
4234
                if (((idx & (1 << size)) != 0) ||
4235
                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4236
                    return 1;
4237
                }
4238
                break;
4239
            case 3:
4240
                if ((idx & 1) != 0) {
4241
                    return 1;
4242
                }
4243
                /* fall through */
4244
            case 2:
4245
                if (size == 2 && (idx & 2) != 0) {
4246
                    return 1;
4247
                }
4248
                break;
4249
            case 4:
4250
                if ((size == 2) && ((idx & 3) == 3)) {
4251
                    return 1;
4252
                }
4253
                break;
4254
            default:
4255
                abort();
4256
            }
4257
            if ((rd + stride * (nregs - 1)) > 31) {
4258
                /* Attempts to write off the end of the register file
4259
                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4260
                 * the neon_load_reg() would write off the end of the array.
4261
                 */
4262
                return 1;
4263
            }
4264
            addr = tcg_temp_new_i32();
4265
            load_reg_var(s, addr, rn);
4266
            for (reg = 0; reg < nregs; reg++) {
4267
                if (load) {
4268
                    tmp = tcg_temp_new_i32();
4269
                    switch (size) {
4270
                    case 0:
4271
                        gen_aa32_ld8u(tmp, addr, IS_USER(s));
4272
                        break;
4273
                    case 1:
4274
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
4275
                        break;
4276
                    case 2:
4277
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
4278
                        break;
4279
                    default: /* Avoid compiler warnings.  */
4280
                        abort();
4281
                    }
4282
                    if (size != 2) {
4283
                        tmp2 = neon_load_reg(rd, pass);
4284
                        tcg_gen_deposit_i32(tmp, tmp2, tmp,
4285
                                            shift, size ? 16 : 8);
4286
                        tcg_temp_free_i32(tmp2);
4287
                    }
4288
                    neon_store_reg(rd, pass, tmp);
4289
                } else { /* Store */
4290
                    tmp = neon_load_reg(rd, pass);
4291
                    if (shift)
4292
                        tcg_gen_shri_i32(tmp, tmp, shift);
4293
                    switch (size) {
4294
                    case 0:
4295
                        gen_aa32_st8(tmp, addr, IS_USER(s));
4296
                        break;
4297
                    case 1:
4298
                        gen_aa32_st16(tmp, addr, IS_USER(s));
4299
                        break;
4300
                    case 2:
4301
                        gen_aa32_st32(tmp, addr, IS_USER(s));
4302
                        break;
4303
                    }
4304
                    tcg_temp_free_i32(tmp);
4305
                }
4306
                rd += stride;
4307
                tcg_gen_addi_i32(addr, addr, 1 << size);
4308
            }
4309
            tcg_temp_free_i32(addr);
4310
            stride = nregs * (1 << size);
4311
        }
4312
    }
4313
    if (rm != 15) {
4314
        TCGv_i32 base;
4315

    
4316
        base = load_reg(s, rn);
4317
        if (rm == 13) {
4318
            tcg_gen_addi_i32(base, base, stride);
4319
        } else {
4320
            TCGv_i32 index;
4321
            index = load_reg(s, rm);
4322
            tcg_gen_add_i32(base, base, index);
4323
            tcg_temp_free_i32(index);
4324
        }
4325
        store_reg(s, rn, base);
4326
    }
4327
    return 0;
4328
}
4329

    
4330
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4331
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4332
{
4333
    tcg_gen_and_i32(t, t, c);
4334
    tcg_gen_andc_i32(f, f, c);
4335
    tcg_gen_or_i32(dest, t, f);
4336
}
4337

    
4338
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4339
{
4340
    switch (size) {
4341
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4342
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4343
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4344
    default: abort();
4345
    }
4346
}
4347

    
4348
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4349
{
4350
    switch (size) {
4351
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4352
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4353
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4354
    default: abort();
4355
    }
4356
}
4357

    
4358
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4359
{
4360
    switch (size) {
4361
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4362
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4363
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4364
    default: abort();
4365
    }
4366
}
4367

    
4368
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4369
{
4370
    switch (size) {
4371
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4372
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4373
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4374
    default: abort();
4375
    }
4376
}
4377

    
4378
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4379
                                         int q, int u)
4380
{
4381
    if (q) {
4382
        if (u) {
4383
            switch (size) {
4384
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4385
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4386
            default: abort();
4387
            }
4388
        } else {
4389
            switch (size) {
4390
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4391
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4392
            default: abort();
4393
            }
4394
        }
4395
    } else {
4396
        if (u) {
4397
            switch (size) {
4398
            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4399
            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4400
            default: abort();
4401
            }
4402
        } else {
4403
            switch (size) {
4404
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4405
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4406
            default: abort();
4407
            }
4408
        }
4409
    }
4410
}
4411

    
4412
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4413
{
4414
    if (u) {
4415
        switch (size) {
4416
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4417
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4418
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4419
        default: abort();
4420
        }
4421
    } else {
4422
        switch (size) {
4423
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4424
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4425
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4426
        default: abort();
4427
        }
4428
    }
4429
    tcg_temp_free_i32(src);
4430
}
4431

    
4432
static inline void gen_neon_addl(int size)
4433
{
4434
    switch (size) {
4435
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4436
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4437
    case 2: tcg_gen_add_i64(CPU_V001); break;
4438
    default: abort();
4439
    }
4440
}
4441

    
4442
static inline void gen_neon_subl(int size)
4443
{
4444
    switch (size) {
4445
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4446
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4447
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4448
    default: abort();
4449
    }
4450
}
4451

    
4452
static inline void gen_neon_negl(TCGv_i64 var, int size)
4453
{
4454
    switch (size) {
4455
    case 0: gen_helper_neon_negl_u16(var, var); break;
4456
    case 1: gen_helper_neon_negl_u32(var, var); break;
4457
    case 2:
4458
        tcg_gen_neg_i64(var, var);
4459
        break;
4460
    default: abort();
4461
    }
4462
}
4463

    
4464
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4465
{
4466
    switch (size) {
4467
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4468
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4469
    default: abort();
4470
    }
4471
}
4472

    
4473
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4474
                                 int size, int u)
4475
{
4476
    TCGv_i64 tmp;
4477

    
4478
    switch ((size << 1) | u) {
4479
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4480
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4481
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4482
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4483
    case 4:
4484
        tmp = gen_muls_i64_i32(a, b);
4485
        tcg_gen_mov_i64(dest, tmp);
4486
        tcg_temp_free_i64(tmp);
4487
        break;
4488
    case 5:
4489
        tmp = gen_mulu_i64_i32(a, b);
4490
        tcg_gen_mov_i64(dest, tmp);
4491
        tcg_temp_free_i64(tmp);
4492
        break;
4493
    default: abort();
4494
    }
4495

    
4496
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4497
       Don't forget to clean them now.  */
4498
    if (size < 2) {
4499
        tcg_temp_free_i32(a);
4500
        tcg_temp_free_i32(b);
4501
    }
4502
}
4503

    
4504
static void gen_neon_narrow_op(int op, int u, int size,
4505
                               TCGv_i32 dest, TCGv_i64 src)
4506
{
4507
    if (op) {
4508
        if (u) {
4509
            gen_neon_unarrow_sats(size, dest, src);
4510
        } else {
4511
            gen_neon_narrow(size, dest, src);
4512
        }
4513
    } else {
4514
        if (u) {
4515
            gen_neon_narrow_satu(size, dest, src);
4516
        } else {
4517
            gen_neon_narrow_sats(size, dest, src);
4518
        }
4519
    }
4520
}
4521

    
4522
/* Symbolic constants for op fields for Neon 3-register same-length.
4523
 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4524
 * table A7-9.
4525
 */
4526
#define NEON_3R_VHADD 0
4527
#define NEON_3R_VQADD 1
4528
#define NEON_3R_VRHADD 2
4529
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4530
#define NEON_3R_VHSUB 4
4531
#define NEON_3R_VQSUB 5
4532
#define NEON_3R_VCGT 6
4533
#define NEON_3R_VCGE 7
4534
#define NEON_3R_VSHL 8
4535
#define NEON_3R_VQSHL 9
4536
#define NEON_3R_VRSHL 10
4537
#define NEON_3R_VQRSHL 11
4538
#define NEON_3R_VMAX 12
4539
#define NEON_3R_VMIN 13
4540
#define NEON_3R_VABD 14
4541
#define NEON_3R_VABA 15
4542
#define NEON_3R_VADD_VSUB 16
4543
#define NEON_3R_VTST_VCEQ 17
4544
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4545
#define NEON_3R_VMUL 19
4546
#define NEON_3R_VPMAX 20
4547
#define NEON_3R_VPMIN 21
4548
#define NEON_3R_VQDMULH_VQRDMULH 22
4549
#define NEON_3R_VPADD 23
4550
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4551
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4552
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4553
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4554
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4555
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4556
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4557

    
4558
static const uint8_t neon_3r_sizes[] = {
4559
    [NEON_3R_VHADD] = 0x7,
4560
    [NEON_3R_VQADD] = 0xf,
4561
    [NEON_3R_VRHADD] = 0x7,
4562
    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4563
    [NEON_3R_VHSUB] = 0x7,
4564
    [NEON_3R_VQSUB] = 0xf,
4565
    [NEON_3R_VCGT] = 0x7,
4566
    [NEON_3R_VCGE] = 0x7,
4567
    [NEON_3R_VSHL] = 0xf,
4568
    [NEON_3R_VQSHL] = 0xf,
4569
    [NEON_3R_VRSHL] = 0xf,
4570
    [NEON_3R_VQRSHL] = 0xf,
4571
    [NEON_3R_VMAX] = 0x7,
4572
    [NEON_3R_VMIN] = 0x7,
4573
    [NEON_3R_VABD] = 0x7,
4574
    [NEON_3R_VABA] = 0x7,
4575
    [NEON_3R_VADD_VSUB] = 0xf,
4576
    [NEON_3R_VTST_VCEQ] = 0x7,
4577
    [NEON_3R_VML] = 0x7,
4578
    [NEON_3R_VMUL] = 0x7,
4579
    [NEON_3R_VPMAX] = 0x7,
4580
    [NEON_3R_VPMIN] = 0x7,
4581
    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4582
    [NEON_3R_VPADD] = 0x7,
4583
    [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4584
    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4585
    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4586
    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4587
    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4588
    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4589
    [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4590
};
4591

    
4592
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4593
 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4594
 * table A7-13.
4595
 */
4596
#define NEON_2RM_VREV64 0
4597
#define NEON_2RM_VREV32 1
4598
#define NEON_2RM_VREV16 2
4599
#define NEON_2RM_VPADDL 4
4600
#define NEON_2RM_VPADDL_U 5
4601
#define NEON_2RM_VCLS 8
4602
#define NEON_2RM_VCLZ 9
4603
#define NEON_2RM_VCNT 10
4604
#define NEON_2RM_VMVN 11
4605
#define NEON_2RM_VPADAL 12
4606
#define NEON_2RM_VPADAL_U 13
4607
#define NEON_2RM_VQABS 14
4608
#define NEON_2RM_VQNEG 15
4609
#define NEON_2RM_VCGT0 16
4610
#define NEON_2RM_VCGE0 17
4611
#define NEON_2RM_VCEQ0 18
4612
#define NEON_2RM_VCLE0 19
4613
#define NEON_2RM_VCLT0 20
4614
#define NEON_2RM_VABS 22
4615
#define NEON_2RM_VNEG 23
4616
#define NEON_2RM_VCGT0_F 24
4617
#define NEON_2RM_VCGE0_F 25
4618
#define NEON_2RM_VCEQ0_F 26
4619
#define NEON_2RM_VCLE0_F 27
4620
#define NEON_2RM_VCLT0_F 28
4621
#define NEON_2RM_VABS_F 30
4622
#define NEON_2RM_VNEG_F 31
4623
#define NEON_2RM_VSWP 32
4624
#define NEON_2RM_VTRN 33
4625
#define NEON_2RM_VUZP 34
4626
#define NEON_2RM_VZIP 35
4627
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4628
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4629
#define NEON_2RM_VSHLL 38
4630
#define NEON_2RM_VCVT_F16_F32 44
4631
#define NEON_2RM_VCVT_F32_F16 46
4632
#define NEON_2RM_VRECPE 56
4633
#define NEON_2RM_VRSQRTE 57
4634
#define NEON_2RM_VRECPE_F 58
4635
#define NEON_2RM_VRSQRTE_F 59
4636
#define NEON_2RM_VCVT_FS 60
4637
#define NEON_2RM_VCVT_FU 61
4638
#define NEON_2RM_VCVT_SF 62
4639
#define NEON_2RM_VCVT_UF 63
4640

    
4641
static int neon_2rm_is_float_op(int op)
4642
{
4643
    /* Return true if this neon 2reg-misc op is float-to-float */
4644
    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4645
            op >= NEON_2RM_VRECPE_F);
4646
}
4647

    
4648
/* Each entry in this array has bit n set if the insn allows
4649
 * size value n (otherwise it will UNDEF). Since unallocated
4650
 * op values will have no bits set they always UNDEF.
4651
 */
4652
static const uint8_t neon_2rm_sizes[] = {
4653
    [NEON_2RM_VREV64] = 0x7,
4654
    [NEON_2RM_VREV32] = 0x3,
4655
    [NEON_2RM_VREV16] = 0x1,
4656
    [NEON_2RM_VPADDL] = 0x7,
4657
    [NEON_2RM_VPADDL_U] = 0x7,
4658
    [NEON_2RM_VCLS] = 0x7,
4659
    [NEON_2RM_VCLZ] = 0x7,
4660
    [NEON_2RM_VCNT] = 0x1,
4661
    [NEON_2RM_VMVN] = 0x1,
4662
    [NEON_2RM_VPADAL] = 0x7,
4663
    [NEON_2RM_VPADAL_U] = 0x7,
4664
    [NEON_2RM_VQABS] = 0x7,
4665
    [NEON_2RM_VQNEG] = 0x7,
4666
    [NEON_2RM_VCGT0] = 0x7,
4667
    [NEON_2RM_VCGE0] = 0x7,
4668
    [NEON_2RM_VCEQ0] = 0x7,
4669
    [NEON_2RM_VCLE0] = 0x7,
4670
    [NEON_2RM_VCLT0] = 0x7,
4671
    [NEON_2RM_VABS] = 0x7,
4672
    [NEON_2RM_VNEG] = 0x7,
4673
    [NEON_2RM_VCGT0_F] = 0x4,
4674
    [NEON_2RM_VCGE0_F] = 0x4,
4675
    [NEON_2RM_VCEQ0_F] = 0x4,
4676
    [NEON_2RM_VCLE0_F] = 0x4,
4677
    [NEON_2RM_VCLT0_F] = 0x4,
4678
    [NEON_2RM_VABS_F] = 0x4,
4679
    [NEON_2RM_VNEG_F] = 0x4,
4680
    [NEON_2RM_VSWP] = 0x1,
4681
    [NEON_2RM_VTRN] = 0x7,
4682
    [NEON_2RM_VUZP] = 0x7,
4683
    [NEON_2RM_VZIP] = 0x7,
4684
    [NEON_2RM_VMOVN] = 0x7,
4685
    [NEON_2RM_VQMOVN] = 0x7,
4686
    [NEON_2RM_VSHLL] = 0x7,
4687
    [NEON_2RM_VCVT_F16_F32] = 0x2,
4688
    [NEON_2RM_VCVT_F32_F16] = 0x2,
4689
    [NEON_2RM_VRECPE] = 0x4,
4690
    [NEON_2RM_VRSQRTE] = 0x4,
4691
    [NEON_2RM_VRECPE_F] = 0x4,
4692
    [NEON_2RM_VRSQRTE_F] = 0x4,
4693
    [NEON_2RM_VCVT_FS] = 0x4,
4694
    [NEON_2RM_VCVT_FU] = 0x4,
4695
    [NEON_2RM_VCVT_SF] = 0x4,
4696
    [NEON_2RM_VCVT_UF] = 0x4,
4697
};
4698

    
4699
/* Translate a NEON data processing instruction.  Return nonzero if the
4700
   instruction is invalid.
4701
   We process data in a mixture of 32-bit and 64-bit chunks.
4702
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4703

    
4704
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4705
{
4706
    int op;
4707
    int q;
4708
    int rd, rn, rm;
4709
    int size;
4710
    int shift;
4711
    int pass;
4712
    int count;
4713
    int pairwise;
4714
    int u;
4715
    uint32_t imm, mask;
4716
    TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4717
    TCGv_i64 tmp64;
4718

    
4719
    if (!s->vfp_enabled)
4720
      return 1;
4721
    q = (insn & (1 << 6)) != 0;
4722
    u = (insn >> 24) & 1;
4723
    VFP_DREG_D(rd, insn);
4724
    VFP_DREG_N(rn, insn);
4725
    VFP_DREG_M(rm, insn);
4726
    size = (insn >> 20) & 3;
4727
    if ((insn & (1 << 23)) == 0) {
4728
        /* Three register same length.  */
4729
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4730
        /* Catch invalid op and bad size combinations: UNDEF */
4731
        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4732
            return 1;
4733
        }
4734
        /* All insns of this form UNDEF for either this condition or the
4735
         * superset of cases "Q==1"; we catch the latter later.
4736
         */
4737
        if (q && ((rd | rn | rm) & 1)) {
4738
            return 1;
4739
        }
4740
        if (size == 3 && op != NEON_3R_LOGIC) {
4741
            /* 64-bit element instructions. */
4742
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4743
                neon_load_reg64(cpu_V0, rn + pass);
4744
                neon_load_reg64(cpu_V1, rm + pass);
4745
                switch (op) {
4746
                case NEON_3R_VQADD:
4747
                    if (u) {
4748
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4749
                                                 cpu_V0, cpu_V1);
4750
                    } else {
4751
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4752
                                                 cpu_V0, cpu_V1);
4753
                    }
4754
                    break;
4755
                case NEON_3R_VQSUB:
4756
                    if (u) {
4757
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4758
                                                 cpu_V0, cpu_V1);
4759
                    } else {
4760
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4761
                                                 cpu_V0, cpu_V1);
4762
                    }
4763
                    break;
4764
                case NEON_3R_VSHL:
4765
                    if (u) {
4766
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4767
                    } else {
4768
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4769
                    }
4770
                    break;
4771
                case NEON_3R_VQSHL:
4772
                    if (u) {
4773
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4774
                                                 cpu_V1, cpu_V0);
4775
                    } else {
4776
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4777
                                                 cpu_V1, cpu_V0);
4778
                    }
4779
                    break;
4780
                case NEON_3R_VRSHL:
4781
                    if (u) {
4782
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4783
                    } else {
4784
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4785
                    }
4786
                    break;
4787
                case NEON_3R_VQRSHL:
4788
                    if (u) {
4789
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4790
                                                  cpu_V1, cpu_V0);
4791
                    } else {
4792
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4793
                                                  cpu_V1, cpu_V0);
4794
                    }
4795
                    break;
4796
                case NEON_3R_VADD_VSUB:
4797
                    if (u) {
4798
                        tcg_gen_sub_i64(CPU_V001);
4799
                    } else {
4800
                        tcg_gen_add_i64(CPU_V001);
4801
                    }
4802
                    break;
4803
                default:
4804
                    abort();
4805
                }
4806
                neon_store_reg64(cpu_V0, rd + pass);
4807
            }
4808
            return 0;
4809
        }
4810
        pairwise = 0;
4811
        switch (op) {
4812
        case NEON_3R_VSHL:
4813
        case NEON_3R_VQSHL:
4814
        case NEON_3R_VRSHL:
4815
        case NEON_3R_VQRSHL:
4816
            {
4817
                int rtmp;
4818
                /* Shift instruction operands are reversed.  */
4819
                rtmp = rn;
4820
                rn = rm;
4821
                rm = rtmp;
4822
            }
4823
            break;
4824
        case NEON_3R_VPADD:
4825
            if (u) {
4826
                return 1;
4827
            }
4828
            /* Fall through */
4829
        case NEON_3R_VPMAX:
4830
        case NEON_3R_VPMIN:
4831
            pairwise = 1;
4832
            break;
4833
        case NEON_3R_FLOAT_ARITH:
4834
            pairwise = (u && size < 2); /* if VPADD (float) */
4835
            break;
4836
        case NEON_3R_FLOAT_MINMAX:
4837
            pairwise = u; /* if VPMIN/VPMAX (float) */
4838
            break;
4839
        case NEON_3R_FLOAT_CMP:
4840
            if (!u && size) {
4841
                /* no encoding for U=0 C=1x */
4842
                return 1;
4843
            }
4844
            break;
4845
        case NEON_3R_FLOAT_ACMP:
4846
            if (!u) {
4847
                return 1;
4848
            }
4849
            break;
4850
        case NEON_3R_VRECPS_VRSQRTS:
4851
            if (u) {
4852
                return 1;
4853
            }
4854
            break;
4855
        case NEON_3R_VMUL:
4856
            if (u && (size != 0)) {
4857
                /* UNDEF on invalid size for polynomial subcase */
4858
                return 1;
4859
            }
4860
            break;
4861
        case NEON_3R_VFM:
4862
            if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4863
                return 1;
4864
            }
4865
            break;
4866
        default:
4867
            break;
4868
        }
4869

    
4870
        if (pairwise && q) {
4871
            /* All the pairwise insns UNDEF if Q is set */
4872
            return 1;
4873
        }
4874

    
4875
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4876

    
4877
        if (pairwise) {
4878
            /* Pairwise.  */
4879
            if (pass < 1) {
4880
                tmp = neon_load_reg(rn, 0);
4881
                tmp2 = neon_load_reg(rn, 1);
4882
            } else {
4883
                tmp = neon_load_reg(rm, 0);
4884
                tmp2 = neon_load_reg(rm, 1);
4885
            }
4886
        } else {
4887
            /* Elementwise.  */
4888
            tmp = neon_load_reg(rn, pass);
4889
            tmp2 = neon_load_reg(rm, pass);
4890
        }
4891
        switch (op) {
4892
        case NEON_3R_VHADD:
4893
            GEN_NEON_INTEGER_OP(hadd);
4894
            break;
4895
        case NEON_3R_VQADD:
4896
            GEN_NEON_INTEGER_OP_ENV(qadd);
4897
            break;
4898
        case NEON_3R_VRHADD:
4899
            GEN_NEON_INTEGER_OP(rhadd);
4900
            break;
4901
        case NEON_3R_LOGIC: /* Logic ops.  */
4902
            switch ((u << 2) | size) {
4903
            case 0: /* VAND */
4904
                tcg_gen_and_i32(tmp, tmp, tmp2);
4905
                break;
4906
            case 1: /* BIC */
4907
                tcg_gen_andc_i32(tmp, tmp, tmp2);
4908
                break;
4909
            case 2: /* VORR */
4910
                tcg_gen_or_i32(tmp, tmp, tmp2);
4911
                break;
4912
            case 3: /* VORN */
4913
                tcg_gen_orc_i32(tmp, tmp, tmp2);
4914
                break;
4915
            case 4: /* VEOR */
4916
                tcg_gen_xor_i32(tmp, tmp, tmp2);
4917
                break;
4918
            case 5: /* VBSL */
4919
                tmp3 = neon_load_reg(rd, pass);
4920
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4921
                tcg_temp_free_i32(tmp3);
4922
                break;
4923
            case 6: /* VBIT */
4924
                tmp3 = neon_load_reg(rd, pass);
4925
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4926
                tcg_temp_free_i32(tmp3);
4927
                break;
4928
            case 7: /* VBIF */
4929
                tmp3 = neon_load_reg(rd, pass);
4930
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4931
                tcg_temp_free_i32(tmp3);
4932
                break;
4933
            }
4934
            break;
4935
        case NEON_3R_VHSUB:
4936
            GEN_NEON_INTEGER_OP(hsub);
4937
            break;
4938
        case NEON_3R_VQSUB:
4939
            GEN_NEON_INTEGER_OP_ENV(qsub);
4940
            break;
4941
        case NEON_3R_VCGT:
4942
            GEN_NEON_INTEGER_OP(cgt);
4943
            break;
4944
        case NEON_3R_VCGE:
4945
            GEN_NEON_INTEGER_OP(cge);
4946
            break;
4947
        case NEON_3R_VSHL:
4948
            GEN_NEON_INTEGER_OP(shl);
4949
            break;
4950
        case NEON_3R_VQSHL:
4951
            GEN_NEON_INTEGER_OP_ENV(qshl);
4952
            break;
4953
        case NEON_3R_VRSHL:
4954
            GEN_NEON_INTEGER_OP(rshl);
4955
            break;
4956
        case NEON_3R_VQRSHL:
4957
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4958
            break;
4959
        case NEON_3R_VMAX:
4960
            GEN_NEON_INTEGER_OP(max);
4961
            break;
4962
        case NEON_3R_VMIN:
4963
            GEN_NEON_INTEGER_OP(min);
4964
            break;
4965
        case NEON_3R_VABD:
4966
            GEN_NEON_INTEGER_OP(abd);
4967
            break;
4968
        case NEON_3R_VABA:
4969
            GEN_NEON_INTEGER_OP(abd);
4970
            tcg_temp_free_i32(tmp2);
4971
            tmp2 = neon_load_reg(rd, pass);
4972
            gen_neon_add(size, tmp, tmp2);
4973
            break;
4974
        case NEON_3R_VADD_VSUB:
4975
            if (!u) { /* VADD */
4976
                gen_neon_add(size, tmp, tmp2);
4977
            } else { /* VSUB */
4978
                switch (size) {
4979
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4980
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4981
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4982
                default: abort();
4983
                }
4984
            }
4985
            break;
4986
        case NEON_3R_VTST_VCEQ:
4987
            if (!u) { /* VTST */
4988
                switch (size) {
4989
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4990
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4991
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4992
                default: abort();
4993
                }
4994
            } else { /* VCEQ */
4995
                switch (size) {
4996
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4997
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4998
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4999
                default: abort();
5000
                }
5001
            }
5002
            break;
5003
        case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5004
            switch (size) {
5005
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5006
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5007
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5008
            default: abort();
5009
            }
5010
            tcg_temp_free_i32(tmp2);
5011
            tmp2 = neon_load_reg(rd, pass);
5012
            if (u) { /* VMLS */
5013
                gen_neon_rsb(size, tmp, tmp2);
5014
            } else { /* VMLA */
5015
                gen_neon_add(size, tmp, tmp2);
5016
            }
5017
            break;
5018
        case NEON_3R_VMUL:
5019
            if (u) { /* polynomial */
5020
                gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5021
            } else { /* Integer */
5022
                switch (size) {
5023
                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5024
                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5025
                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5026
                default: abort();
5027
                }
5028
            }
5029
            break;
5030
        case NEON_3R_VPMAX:
5031
            GEN_NEON_INTEGER_OP(pmax);
5032
            break;
5033
        case NEON_3R_VPMIN:
5034
            GEN_NEON_INTEGER_OP(pmin);
5035
            break;
5036
        case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
5037
            if (!u) { /* VQDMULH */
5038
                switch (size) {
5039
                case 1:
5040
                    gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5041
                    break;
5042
                case 2:
5043
                    gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5044
                    break;
5045
                default: abort();
5046
                }
5047
            } else { /* VQRDMULH */
5048
                switch (size) {
5049
                case 1:
5050
                    gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5051
                    break;
5052
                case 2:
5053
                    gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5054
                    break;
5055
                default: abort();
5056
                }
5057
            }
5058
            break;
5059
        case NEON_3R_VPADD:
5060
            switch (size) {
5061
            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5062
            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5063
            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5064
            default: abort();
5065
            }
5066
            break;
5067
        case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5068
        {
5069
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5070
            switch ((u << 2) | size) {
5071
            case 0: /* VADD */
5072
            case 4: /* VPADD */
5073
                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5074
                break;
5075
            case 2: /* VSUB */
5076
                gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5077
                break;
5078
            case 6: /* VABD */
5079
                gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5080
                break;
5081
            default:
5082
                abort();
5083
            }
5084
            tcg_temp_free_ptr(fpstatus);
5085
            break;
5086
        }
5087
        case NEON_3R_FLOAT_MULTIPLY:
5088
        {
5089
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5090
            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5091
            if (!u) {
5092
                tcg_temp_free_i32(tmp2);
5093
                tmp2 = neon_load_reg(rd, pass);
5094
                if (size == 0) {
5095
                    gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5096
                } else {
5097
                    gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5098
                }
5099
            }
5100
            tcg_temp_free_ptr(fpstatus);
5101
            break;
5102
        }
5103
        case NEON_3R_FLOAT_CMP:
5104
        {
5105
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5106
            if (!u) {
5107
                gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5108
            } else {
5109
                if (size == 0) {
5110
                    gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5111
                } else {
5112
                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5113
                }
5114
            }
5115
            tcg_temp_free_ptr(fpstatus);
5116
            break;
5117
        }
5118
        case NEON_3R_FLOAT_ACMP:
5119
        {
5120
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5121
            if (size == 0) {
5122
                gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5123
            } else {
5124
                gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5125
            }
5126
            tcg_temp_free_ptr(fpstatus);
5127
            break;
5128
        }
5129
        case NEON_3R_FLOAT_MINMAX:
5130
        {
5131
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5132
            if (size == 0) {
5133
                gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
5134
            } else {
5135
                gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
5136
            }
5137
            tcg_temp_free_ptr(fpstatus);
5138
            break;
5139
        }
5140
        case NEON_3R_VRECPS_VRSQRTS:
5141
            if (size == 0)
5142
                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5143
            else
5144
                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5145
            break;
5146
        case NEON_3R_VFM:
5147
        {
5148
            /* VFMA, VFMS: fused multiply-add */
5149
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5150
            TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5151
            if (size) {
5152
                /* VFMS */
5153
                gen_helper_vfp_negs(tmp, tmp);
5154
            }
5155
            gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5156
            tcg_temp_free_i32(tmp3);
5157
            tcg_temp_free_ptr(fpstatus);
5158
            break;
5159
        }
5160
        default:
5161
            abort();
5162
        }
5163
        tcg_temp_free_i32(tmp2);
5164

    
5165
        /* Save the result.  For elementwise operations we can put it
5166
           straight into the destination register.  For pairwise operations
5167
           we have to be careful to avoid clobbering the source operands.  */
5168
        if (pairwise && rd == rm) {
5169
            neon_store_scratch(pass, tmp);
5170
        } else {
5171
            neon_store_reg(rd, pass, tmp);
5172
        }
5173

    
5174
        } /* for pass */
5175
        if (pairwise && rd == rm) {
5176
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5177
                tmp = neon_load_scratch(pass);
5178
                neon_store_reg(rd, pass, tmp);
5179
            }
5180
        }
5181
        /* End of 3 register same size operations.  */
5182
    } else if (insn & (1 << 4)) {
5183
        if ((insn & 0x00380080) != 0) {
5184
            /* Two registers and shift.  */
5185
            op = (insn >> 8) & 0xf;
5186
            if (insn & (1 << 7)) {
5187
                /* 64-bit shift. */
5188
                if (op > 7) {
5189
                    return 1;
5190
                }
5191
                size = 3;
5192
            } else {
5193
                size = 2;
5194
                while ((insn & (1 << (size + 19))) == 0)
5195
                    size--;
5196
            }
5197
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5198
            /* To avoid excessive duplication of ops we implement shift
5199
               by immediate using the variable shift operations.  */
5200
            if (op < 8) {
5201
                /* Shift by immediate:
5202
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
5203
                if (q && ((rd | rm) & 1)) {
5204
                    return 1;
5205
                }
5206
                if (!u && (op == 4 || op == 6)) {
5207
                    return 1;
5208
                }
5209
                /* Right shifts are encoded as N - shift, where N is the
5210
                   element size in bits.  */
5211
                if (op <= 4)
5212
                    shift = shift - (1 << (size + 3));
5213
                if (size == 3) {
5214
                    count = q + 1;
5215
                } else {
5216
                    count = q ? 4: 2;
5217
                }
5218
                switch (size) {
5219
                case 0:
5220
                    imm = (uint8_t) shift;
5221
                    imm |= imm << 8;
5222
                    imm |= imm << 16;
5223
                    break;
5224
                case 1:
5225
                    imm = (uint16_t) shift;
5226
                    imm |= imm << 16;
5227
                    break;
5228
                case 2:
5229
                case 3:
5230
                    imm = shift;
5231
                    break;
5232
                default:
5233
                    abort();
5234
                }
5235

    
5236
                for (pass = 0; pass < count; pass++) {
5237
                    if (size == 3) {
5238
                        neon_load_reg64(cpu_V0, rm + pass);
5239
                        tcg_gen_movi_i64(cpu_V1, imm);
5240
                        switch (op) {
5241
                        case 0:  /* VSHR */
5242
                        case 1:  /* VSRA */
5243
                            if (u)
5244
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5245
                            else
5246
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5247
                            break;
5248
                        case 2: /* VRSHR */
5249
                        case 3: /* VRSRA */
5250
                            if (u)
5251
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5252
                            else
5253
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5254
                            break;
5255
                        case 4: /* VSRI */
5256
                        case 5: /* VSHL, VSLI */
5257
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5258
                            break;
5259
                        case 6: /* VQSHLU */
5260
                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5261
                                                      cpu_V0, cpu_V1);
5262
                            break;
5263
                        case 7: /* VQSHL */
5264
                            if (u) {
5265
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5266
                                                         cpu_V0, cpu_V1);
5267
                            } else {
5268
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5269
                                                         cpu_V0, cpu_V1);
5270
                            }
5271
                            break;
5272
                        }
5273
                        if (op == 1 || op == 3) {
5274
                            /* Accumulate.  */
5275
                            neon_load_reg64(cpu_V1, rd + pass);
5276
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5277
                        } else if (op == 4 || (op == 5 && u)) {
5278
                            /* Insert */
5279
                            neon_load_reg64(cpu_V1, rd + pass);
5280
                            uint64_t mask;
5281
                            if (shift < -63 || shift > 63) {
5282
                                mask = 0;
5283
                            } else {
5284
                                if (op == 4) {
5285
                                    mask = 0xffffffffffffffffull >> -shift;
5286
                                } else {
5287
                                    mask = 0xffffffffffffffffull << shift;
5288
                                }
5289
                            }
5290
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5291
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5292
                        }
5293
                        neon_store_reg64(cpu_V0, rd + pass);
5294
                    } else { /* size < 3 */
5295
                        /* Operands in T0 and T1.  */
5296
                        tmp = neon_load_reg(rm, pass);
5297
                        tmp2 = tcg_temp_new_i32();
5298
                        tcg_gen_movi_i32(tmp2, imm);
5299
                        switch (op) {
5300
                        case 0:  /* VSHR */
5301
                        case 1:  /* VSRA */
5302
                            GEN_NEON_INTEGER_OP(shl);
5303
                            break;
5304
                        case 2: /* VRSHR */
5305
                        case 3: /* VRSRA */
5306
                            GEN_NEON_INTEGER_OP(rshl);
5307
                            break;
5308
                        case 4: /* VSRI */
5309
                        case 5: /* VSHL, VSLI */
5310
                            switch (size) {
5311
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5312
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5313
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5314
                            default: abort();
5315
                            }
5316
                            break;
5317
                        case 6: /* VQSHLU */
5318
                            switch (size) {
5319
                            case 0:
5320
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
5321
                                                         tmp, tmp2);
5322
                                break;
5323
                            case 1:
5324
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
5325
                                                          tmp, tmp2);
5326
                                break;
5327
                            case 2:
5328
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
5329
                                                          tmp, tmp2);
5330
                                break;
5331
                            default:
5332
                                abort();
5333
                            }
5334
                            break;
5335
                        case 7: /* VQSHL */
5336
                            GEN_NEON_INTEGER_OP_ENV(qshl);
5337
                            break;
5338
                        }
5339
                        tcg_temp_free_i32(tmp2);
5340

    
5341
                        if (op == 1 || op == 3) {
5342
                            /* Accumulate.  */
5343
                            tmp2 = neon_load_reg(rd, pass);
5344
                            gen_neon_add(size, tmp, tmp2);
5345
                            tcg_temp_free_i32(tmp2);
5346
                        } else if (op == 4 || (op == 5 && u)) {
5347
                            /* Insert */
5348
                            switch (size) {
5349
                            case 0:
5350
                                if (op == 4)
5351
                                    mask = 0xff >> -shift;
5352
                                else
5353
                                    mask = (uint8_t)(0xff << shift);
5354
                                mask |= mask << 8;
5355
                                mask |= mask << 16;
5356
                                break;
5357
                            case 1:
5358
                                if (op == 4)
5359
                                    mask = 0xffff >> -shift;
5360
                                else
5361
                                    mask = (uint16_t)(0xffff << shift);
5362
                                mask |= mask << 16;
5363
                                break;
5364
                            case 2:
5365
                                if (shift < -31 || shift > 31) {
5366
                                    mask = 0;
5367
                                } else {
5368
                                    if (op == 4)
5369
                                        mask = 0xffffffffu >> -shift;
5370
                                    else
5371
                                        mask = 0xffffffffu << shift;
5372
                                }
5373
                                break;
5374
                            default:
5375
                                abort();
5376
                            }
5377
                            tmp2 = neon_load_reg(rd, pass);
5378
                            tcg_gen_andi_i32(tmp, tmp, mask);
5379
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5380
                            tcg_gen_or_i32(tmp, tmp, tmp2);
5381
                            tcg_temp_free_i32(tmp2);
5382
                        }
5383
                        neon_store_reg(rd, pass, tmp);
5384
                    }
5385
                } /* for pass */
5386
            } else if (op < 10) {
5387
                /* Shift by immediate and narrow:
5388
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
5389
                int input_unsigned = (op == 8) ? !u : u;
5390
                if (rm & 1) {
5391
                    return 1;
5392
                }
5393
                shift = shift - (1 << (size + 3));
5394
                size++;
5395
                if (size == 3) {
5396
                    tmp64 = tcg_const_i64(shift);
5397
                    neon_load_reg64(cpu_V0, rm);
5398
                    neon_load_reg64(cpu_V1, rm + 1);
5399
                    for (pass = 0; pass < 2; pass++) {
5400
                        TCGv_i64 in;
5401
                        if (pass == 0) {
5402
                            in = cpu_V0;
5403
                        } else {
5404
                            in = cpu_V1;
5405
                        }
5406
                        if (q) {
5407
                            if (input_unsigned) {
5408
                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5409
                            } else {
5410
                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5411
                            }
5412
                        } else {
5413
                            if (input_unsigned) {
5414
                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5415
                            } else {
5416
                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5417
                            }
5418
                        }
5419
                        tmp = tcg_temp_new_i32();
5420
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5421
                        neon_store_reg(rd, pass, tmp);
5422
                    } /* for pass */
5423
                    tcg_temp_free_i64(tmp64);
5424
                } else {
5425
                    if (size == 1) {
5426
                        imm = (uint16_t)shift;
5427
                        imm |= imm << 16;
5428
                    } else {
5429
                        /* size == 2 */
5430
                        imm = (uint32_t)shift;
5431
                    }
5432
                    tmp2 = tcg_const_i32(imm);
5433
                    tmp4 = neon_load_reg(rm + 1, 0);
5434
                    tmp5 = neon_load_reg(rm + 1, 1);
5435
                    for (pass = 0; pass < 2; pass++) {
5436
                        if (pass == 0) {
5437
                            tmp = neon_load_reg(rm, 0);
5438
                        } else {
5439
                            tmp = tmp4;
5440
                        }
5441
                        gen_neon_shift_narrow(size, tmp, tmp2, q,
5442
                                              input_unsigned);
5443
                        if (pass == 0) {
5444
                            tmp3 = neon_load_reg(rm, 1);
5445
                        } else {
5446
                            tmp3 = tmp5;
5447
                        }
5448
                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
5449
                                              input_unsigned);
5450
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5451
                        tcg_temp_free_i32(tmp);
5452
                        tcg_temp_free_i32(tmp3);
5453
                        tmp = tcg_temp_new_i32();
5454
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5455
                        neon_store_reg(rd, pass, tmp);
5456
                    } /* for pass */
5457
                    tcg_temp_free_i32(tmp2);
5458
                }
5459
            } else if (op == 10) {
5460
                /* VSHLL, VMOVL */
5461
                if (q || (rd & 1)) {
5462
                    return 1;
5463
                }
5464
                tmp = neon_load_reg(rm, 0);
5465
                tmp2 = neon_load_reg(rm, 1);
5466
                for (pass = 0; pass < 2; pass++) {
5467
                    if (pass == 1)
5468
                        tmp = tmp2;
5469

    
5470
                    gen_neon_widen(cpu_V0, tmp, size, u);
5471

    
5472
                    if (shift != 0) {
5473
                        /* The shift is less than the width of the source
5474
                           type, so we can just shift the whole register.  */
5475
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5476
                        /* Widen the result of shift: we need to clear
5477
                         * the potential overflow bits resulting from
5478
                         * left bits of the narrow input appearing as
5479
                         * right bits of left the neighbour narrow
5480
                         * input.  */
5481
                        if (size < 2 || !u) {
5482
                            uint64_t imm64;
5483
                            if (size == 0) {
5484
                                imm = (0xffu >> (8 - shift));
5485
                                imm |= imm << 16;
5486
                            } else if (size == 1) {
5487
                                imm = 0xffff >> (16 - shift);
5488
                            } else {
5489
                                /* size == 2 */
5490
                                imm = 0xffffffff >> (32 - shift);
5491
                            }
5492
                            if (size < 2) {
5493
                                imm64 = imm | (((uint64_t)imm) << 32);
5494
                            } else {
5495
                                imm64 = imm;
5496
                            }
5497
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5498
                        }
5499
                    }
5500
                    neon_store_reg64(cpu_V0, rd + pass);
5501
                }
5502
            } else if (op >= 14) {
5503
                /* VCVT fixed-point.  */
5504
                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5505
                    return 1;
5506
                }
5507
                /* We have already masked out the must-be-1 top bit of imm6,
5508
                 * hence this 32-shift where the ARM ARM has 64-imm6.
5509
                 */
5510
                shift = 32 - shift;
5511
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5512
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5513
                    if (!(op & 1)) {
5514
                        if (u)
5515
                            gen_vfp_ulto(0, shift, 1);
5516
                        else
5517
                            gen_vfp_slto(0, shift, 1);
5518
                    } else {
5519
                        if (u)
5520
                            gen_vfp_toul(0, shift, 1);
5521
                        else
5522
                            gen_vfp_tosl(0, shift, 1);
5523
                    }
5524
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5525
                }
5526
            } else {
5527
                return 1;
5528
            }
5529
        } else { /* (insn & 0x00380080) == 0 */
5530
            int invert;
5531
            if (q && (rd & 1)) {
5532
                return 1;
5533
            }
5534

    
5535
            op = (insn >> 8) & 0xf;
5536
            /* One register and immediate.  */
5537
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5538
            invert = (insn & (1 << 5)) != 0;
5539
            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5540
             * We choose to not special-case this and will behave as if a
5541
             * valid constant encoding of 0 had been given.
5542
             */
5543
            switch (op) {
5544
            case 0: case 1:
5545
                /* no-op */
5546
                break;
5547
            case 2: case 3:
5548
                imm <<= 8;
5549
                break;
5550
            case 4: case 5:
5551
                imm <<= 16;
5552
                break;
5553
            case 6: case 7:
5554
                imm <<= 24;
5555
                break;
5556
            case 8: case 9:
5557
                imm |= imm << 16;
5558
                break;
5559
            case 10: case 11:
5560
                imm = (imm << 8) | (imm << 24);
5561
                break;
5562
            case 12:
5563
                imm = (imm << 8) | 0xff;
5564
                break;
5565
            case 13:
5566
                imm = (imm << 16) | 0xffff;
5567
                break;
5568
            case 14:
5569
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
5570
                if (invert)
5571
                    imm = ~imm;
5572
                break;
5573
            case 15:
5574
                if (invert) {
5575
                    return 1;
5576
                }
5577
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5578
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5579
                break;
5580
            }
5581
            if (invert)
5582
                imm = ~imm;
5583

    
5584
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5585
                if (op & 1 && op < 12) {
5586
                    tmp = neon_load_reg(rd, pass);
5587
                    if (invert) {
5588
                        /* The immediate value has already been inverted, so
5589
                           BIC becomes AND.  */
5590
                        tcg_gen_andi_i32(tmp, tmp, imm);
5591
                    } else {
5592
                        tcg_gen_ori_i32(tmp, tmp, imm);
5593
                    }
5594
                } else {
5595
                    /* VMOV, VMVN.  */
5596
                    tmp = tcg_temp_new_i32();
5597
                    if (op == 14 && invert) {
5598
                        int n;
5599
                        uint32_t val;
5600
                        val = 0;
5601
                        for (n = 0; n < 4; n++) {
5602
                            if (imm & (1 << (n + (pass & 1) * 4)))
5603
                                val |= 0xff << (n * 8);
5604
                        }
5605
                        tcg_gen_movi_i32(tmp, val);
5606
                    } else {
5607
                        tcg_gen_movi_i32(tmp, imm);
5608
                    }
5609
                }
5610
                neon_store_reg(rd, pass, tmp);
5611
            }
5612
        }
5613
    } else { /* (insn & 0x00800010 == 0x00800000) */
5614
        if (size != 3) {
5615
            op = (insn >> 8) & 0xf;
5616
            if ((insn & (1 << 6)) == 0) {
5617
                /* Three registers of different lengths.  */
5618
                int src1_wide;
5619
                int src2_wide;
5620
                int prewiden;
5621
                /* undefreq: bit 0 : UNDEF if size != 0
5622
                 *           bit 1 : UNDEF if size == 0
5623
                 *           bit 2 : UNDEF if U == 1
5624
                 * Note that [1:0] set implies 'always UNDEF'
5625
                 */
5626
                int undefreq;
5627
                /* prewiden, src1_wide, src2_wide, undefreq */
5628
                static const int neon_3reg_wide[16][4] = {
5629
                    {1, 0, 0, 0}, /* VADDL */
5630
                    {1, 1, 0, 0}, /* VADDW */
5631
                    {1, 0, 0, 0}, /* VSUBL */
5632
                    {1, 1, 0, 0}, /* VSUBW */
5633
                    {0, 1, 1, 0}, /* VADDHN */
5634
                    {0, 0, 0, 0}, /* VABAL */
5635
                    {0, 1, 1, 0}, /* VSUBHN */
5636
                    {0, 0, 0, 0}, /* VABDL */
5637
                    {0, 0, 0, 0}, /* VMLAL */
5638
                    {0, 0, 0, 6}, /* VQDMLAL */
5639
                    {0, 0, 0, 0}, /* VMLSL */
5640
                    {0, 0, 0, 6}, /* VQDMLSL */
5641
                    {0, 0, 0, 0}, /* Integer VMULL */
5642
                    {0, 0, 0, 2}, /* VQDMULL */
5643
                    {0, 0, 0, 5}, /* Polynomial VMULL */
5644
                    {0, 0, 0, 3}, /* Reserved: always UNDEF */
5645
                };
5646

    
5647
                prewiden = neon_3reg_wide[op][0];
5648
                src1_wide = neon_3reg_wide[op][1];
5649
                src2_wide = neon_3reg_wide[op][2];
5650
                undefreq = neon_3reg_wide[op][3];
5651

    
5652
                if (((undefreq & 1) && (size != 0)) ||
5653
                    ((undefreq & 2) && (size == 0)) ||
5654
                    ((undefreq & 4) && u)) {
5655
                    return 1;
5656
                }
5657
                if ((src1_wide && (rn & 1)) ||
5658
                    (src2_wide && (rm & 1)) ||
5659
                    (!src2_wide && (rd & 1))) {
5660
                    return 1;
5661
                }
5662

    
5663
                /* Avoid overlapping operands.  Wide source operands are
5664
                   always aligned so will never overlap with wide
5665
                   destinations in problematic ways.  */
5666
                if (rd == rm && !src2_wide) {
5667
                    tmp = neon_load_reg(rm, 1);
5668
                    neon_store_scratch(2, tmp);
5669
                } else if (rd == rn && !src1_wide) {
5670
                    tmp = neon_load_reg(rn, 1);
5671
                    neon_store_scratch(2, tmp);
5672
                }
5673
                TCGV_UNUSED_I32(tmp3);
5674
                for (pass = 0; pass < 2; pass++) {
5675
                    if (src1_wide) {
5676
                        neon_load_reg64(cpu_V0, rn + pass);
5677
                        TCGV_UNUSED_I32(tmp);
5678
                    } else {
5679
                        if (pass == 1 && rd == rn) {
5680
                            tmp = neon_load_scratch(2);
5681
                        } else {
5682
                            tmp = neon_load_reg(rn, pass);
5683
                        }
5684
                        if (prewiden) {
5685
                            gen_neon_widen(cpu_V0, tmp, size, u);
5686
                        }
5687
                    }
5688
                    if (src2_wide) {
5689
                        neon_load_reg64(cpu_V1, rm + pass);
5690
                        TCGV_UNUSED_I32(tmp2);
5691
                    } else {
5692
                        if (pass == 1 && rd == rm) {
5693
                            tmp2 = neon_load_scratch(2);
5694
                        } else {
5695
                            tmp2 = neon_load_reg(rm, pass);
5696
                        }
5697
                        if (prewiden) {
5698
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5699
                        }
5700
                    }
5701
                    switch (op) {
5702
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5703
                        gen_neon_addl(size);
5704
                        break;
5705
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5706
                        gen_neon_subl(size);
5707
                        break;
5708
                    case 5: case 7: /* VABAL, VABDL */
5709
                        switch ((size << 1) | u) {
5710
                        case 0:
5711
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5712
                            break;
5713
                        case 1:
5714
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5715
                            break;
5716
                        case 2:
5717
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5718
                            break;
5719
                        case 3:
5720
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5721
                            break;
5722
                        case 4:
5723
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5724
                            break;
5725
                        case 5:
5726
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5727
                            break;
5728
                        default: abort();
5729
                        }
5730
                        tcg_temp_free_i32(tmp2);
5731
                        tcg_temp_free_i32(tmp);
5732
                        break;
5733
                    case 8: case 9: case 10: case 11: case 12: case 13:
5734
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5735
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5736
                        break;
5737
                    case 14: /* Polynomial VMULL */
5738
                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5739
                        tcg_temp_free_i32(tmp2);
5740
                        tcg_temp_free_i32(tmp);
5741
                        break;
5742
                    default: /* 15 is RESERVED: caught earlier  */
5743
                        abort();
5744
                    }
5745
                    if (op == 13) {
5746
                        /* VQDMULL */
5747
                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5748
                        neon_store_reg64(cpu_V0, rd + pass);
5749
                    } else if (op == 5 || (op >= 8 && op <= 11)) {
5750
                        /* Accumulate.  */
5751
                        neon_load_reg64(cpu_V1, rd + pass);
5752
                        switch (op) {
5753
                        case 10: /* VMLSL */
5754
                            gen_neon_negl(cpu_V0, size);
5755
                            /* Fall through */
5756
                        case 5: case 8: /* VABAL, VMLAL */
5757
                            gen_neon_addl(size);
5758
                            break;
5759
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5760
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5761
                            if (op == 11) {
5762
                                gen_neon_negl(cpu_V0, size);
5763
                            }
5764
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5765
                            break;
5766
                        default:
5767
                            abort();
5768
                        }
5769
                        neon_store_reg64(cpu_V0, rd + pass);
5770
                    } else if (op == 4 || op == 6) {
5771
                        /* Narrowing operation.  */
5772
                        tmp = tcg_temp_new_i32();
5773
                        if (!u) {
5774
                            switch (size) {
5775
                            case 0:
5776
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5777
                                break;
5778
                            case 1:
5779
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5780
                                break;
5781
                            case 2:
5782
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5783
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5784
                                break;
5785
                            default: abort();
5786
                            }
5787
                        } else {
5788
                            switch (size) {
5789
                            case 0:
5790
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5791
                                break;
5792
                            case 1:
5793
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5794
                                break;
5795
                            case 2:
5796
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5797
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5798
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5799
                                break;
5800
                            default: abort();
5801
                            }
5802
                        }
5803
                        if (pass == 0) {
5804
                            tmp3 = tmp;
5805
                        } else {
5806
                            neon_store_reg(rd, 0, tmp3);
5807
                            neon_store_reg(rd, 1, tmp);
5808
                        }
5809
                    } else {
5810
                        /* Write back the result.  */
5811
                        neon_store_reg64(cpu_V0, rd + pass);
5812
                    }
5813
                }
5814
            } else {
5815
                /* Two registers and a scalar. NB that for ops of this form
5816
                 * the ARM ARM labels bit 24 as Q, but it is in our variable
5817
                 * 'u', not 'q'.
5818
                 */
5819
                if (size == 0) {
5820
                    return 1;
5821
                }
5822
                switch (op) {
5823
                case 1: /* Float VMLA scalar */
5824
                case 5: /* Floating point VMLS scalar */
5825
                case 9: /* Floating point VMUL scalar */
5826
                    if (size == 1) {
5827
                        return 1;
5828
                    }
5829
                    /* fall through */
5830
                case 0: /* Integer VMLA scalar */
5831
                case 4: /* Integer VMLS scalar */
5832
                case 8: /* Integer VMUL scalar */
5833
                case 12: /* VQDMULH scalar */
5834
                case 13: /* VQRDMULH scalar */
5835
                    if (u && ((rd | rn) & 1)) {
5836
                        return 1;
5837
                    }
5838
                    tmp = neon_get_scalar(size, rm);
5839
                    neon_store_scratch(0, tmp);
5840
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5841
                        tmp = neon_load_scratch(0);
5842
                        tmp2 = neon_load_reg(rn, pass);
5843
                        if (op == 12) {
5844
                            if (size == 1) {
5845
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5846
                            } else {
5847
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5848
                            }
5849
                        } else if (op == 13) {
5850
                            if (size == 1) {
5851
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5852
                            } else {
5853
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5854
                            }
5855
                        } else if (op & 1) {
5856
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5857
                            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5858
                            tcg_temp_free_ptr(fpstatus);
5859
                        } else {
5860
                            switch (size) {
5861
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5862
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5863
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5864
                            default: abort();
5865
                            }
5866
                        }
5867
                        tcg_temp_free_i32(tmp2);
5868
                        if (op < 8) {
5869
                            /* Accumulate.  */
5870
                            tmp2 = neon_load_reg(rd, pass);
5871
                            switch (op) {
5872
                            case 0:
5873
                                gen_neon_add(size, tmp, tmp2);
5874
                                break;
5875
                            case 1:
5876
                            {
5877
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5878
                                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5879
                                tcg_temp_free_ptr(fpstatus);
5880
                                break;
5881
                            }
5882
                            case 4:
5883
                                gen_neon_rsb(size, tmp, tmp2);
5884
                                break;
5885
                            case 5:
5886
                            {
5887
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5888
                                gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5889
                                tcg_temp_free_ptr(fpstatus);
5890
                                break;
5891
                            }
5892
                            default:
5893
                                abort();
5894
                            }
5895
                            tcg_temp_free_i32(tmp2);
5896
                        }
5897
                        neon_store_reg(rd, pass, tmp);
5898
                    }
5899
                    break;
5900
                case 3: /* VQDMLAL scalar */
5901
                case 7: /* VQDMLSL scalar */
5902
                case 11: /* VQDMULL scalar */
5903
                    if (u == 1) {
5904
                        return 1;
5905
                    }
5906
                    /* fall through */
5907
                case 2: /* VMLAL sclar */
5908
                case 6: /* VMLSL scalar */
5909
                case 10: /* VMULL scalar */
5910
                    if (rd & 1) {
5911
                        return 1;
5912
                    }
5913
                    tmp2 = neon_get_scalar(size, rm);
5914
                    /* We need a copy of tmp2 because gen_neon_mull
5915
                     * deletes it during pass 0.  */
5916
                    tmp4 = tcg_temp_new_i32();
5917
                    tcg_gen_mov_i32(tmp4, tmp2);
5918
                    tmp3 = neon_load_reg(rn, 1);
5919

    
5920
                    for (pass = 0; pass < 2; pass++) {
5921
                        if (pass == 0) {
5922
                            tmp = neon_load_reg(rn, 0);
5923
                        } else {
5924
                            tmp = tmp3;
5925
                            tmp2 = tmp4;
5926
                        }
5927
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5928
                        if (op != 11) {
5929
                            neon_load_reg64(cpu_V1, rd + pass);
5930
                        }
5931
                        switch (op) {
5932
                        case 6:
5933
                            gen_neon_negl(cpu_V0, size);
5934
                            /* Fall through */
5935
                        case 2:
5936
                            gen_neon_addl(size);
5937
                            break;
5938
                        case 3: case 7:
5939
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5940
                            if (op == 7) {
5941
                                gen_neon_negl(cpu_V0, size);
5942
                            }
5943
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5944
                            break;
5945
                        case 10:
5946
                            /* no-op */
5947
                            break;
5948
                        case 11:
5949
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5950
                            break;
5951
                        default:
5952
                            abort();
5953
                        }
5954
                        neon_store_reg64(cpu_V0, rd + pass);
5955
                    }
5956

    
5957

    
5958
                    break;
5959
                default: /* 14 and 15 are RESERVED */
5960
                    return 1;
5961
                }
5962
            }
5963
        } else { /* size == 3 */
5964
            if (!u) {
5965
                /* Extract.  */
5966
                imm = (insn >> 8) & 0xf;
5967

    
5968
                if (imm > 7 && !q)
5969
                    return 1;
5970

    
5971
                if (q && ((rd | rn | rm) & 1)) {
5972
                    return 1;
5973
                }
5974

    
5975
                if (imm == 0) {
5976
                    neon_load_reg64(cpu_V0, rn);
5977
                    if (q) {
5978
                        neon_load_reg64(cpu_V1, rn + 1);
5979
                    }
5980
                } else if (imm == 8) {
5981
                    neon_load_reg64(cpu_V0, rn + 1);
5982
                    if (q) {
5983
                        neon_load_reg64(cpu_V1, rm);
5984
                    }
5985
                } else if (q) {
5986
                    tmp64 = tcg_temp_new_i64();
5987
                    if (imm < 8) {
5988
                        neon_load_reg64(cpu_V0, rn);
5989
                        neon_load_reg64(tmp64, rn + 1);
5990
                    } else {
5991
                        neon_load_reg64(cpu_V0, rn + 1);
5992
                        neon_load_reg64(tmp64, rm);
5993
                    }
5994
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5995
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5996
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5997
                    if (imm < 8) {
5998
                        neon_load_reg64(cpu_V1, rm);
5999
                    } else {
6000
                        neon_load_reg64(cpu_V1, rm + 1);
6001
                        imm -= 8;
6002
                    }
6003
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6004
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6005
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6006
                    tcg_temp_free_i64(tmp64);
6007
                } else {
6008
                    /* BUGFIX */
6009
                    neon_load_reg64(cpu_V0, rn);
6010
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6011
                    neon_load_reg64(cpu_V1, rm);
6012
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6013
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6014
                }
6015
                neon_store_reg64(cpu_V0, rd);
6016
                if (q) {
6017
                    neon_store_reg64(cpu_V1, rd + 1);
6018
                }
6019
            } else if ((insn & (1 << 11)) == 0) {
6020
                /* Two register misc.  */
6021
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6022
                size = (insn >> 18) & 3;
6023
                /* UNDEF for unknown op values and bad op-size combinations */
6024
                if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6025
                    return 1;
6026
                }
6027
                if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6028
                    q && ((rm | rd) & 1)) {
6029
                    return 1;
6030
                }
6031
                switch (op) {
6032
                case NEON_2RM_VREV64:
6033
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
6034
                        tmp = neon_load_reg(rm, pass * 2);
6035
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
6036
                        switch (size) {
6037
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6038
                        case 1: gen_swap_half(tmp); break;
6039
                        case 2: /* no-op */ break;
6040
                        default: abort();
6041
                        }
6042
                        neon_store_reg(rd, pass * 2 + 1, tmp);
6043
                        if (size == 2) {
6044
                            neon_store_reg(rd, pass * 2, tmp2);
6045
                        } else {
6046
                            switch (size) {
6047
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6048
                            case 1: gen_swap_half(tmp2); break;
6049
                            default: abort();
6050
                            }
6051
                            neon_store_reg(rd, pass * 2, tmp2);
6052
                        }
6053
                    }
6054
                    break;
6055
                case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6056
                case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6057
                    for (pass = 0; pass < q + 1; pass++) {
6058
                        tmp = neon_load_reg(rm, pass * 2);
6059
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
6060
                        tmp = neon_load_reg(rm, pass * 2 + 1);
6061
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
6062
                        switch (size) {
6063
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6064
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6065
                        case 2: tcg_gen_add_i64(CPU_V001); break;
6066
                        default: abort();
6067
                        }
6068
                        if (op >= NEON_2RM_VPADAL) {
6069
                            /* Accumulate.  */
6070
                            neon_load_reg64(cpu_V1, rd + pass);
6071
                            gen_neon_addl(size);
6072
                        }
6073
                        neon_store_reg64(cpu_V0, rd + pass);
6074
                    }
6075
                    break;
6076
                case NEON_2RM_VTRN:
6077
                    if (size == 2) {
6078
                        int n;
6079
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
6080
                            tmp = neon_load_reg(rm, n);
6081
                            tmp2 = neon_load_reg(rd, n + 1);
6082
                            neon_store_reg(rm, n, tmp2);
6083
                            neon_store_reg(rd, n + 1, tmp);
6084
                        }
6085
                    } else {
6086
                        goto elementwise;
6087
                    }
6088
                    break;
6089
                case NEON_2RM_VUZP:
6090
                    if (gen_neon_unzip(rd, rm, size, q)) {
6091
                        return 1;
6092
                    }
6093
                    break;
6094
                case NEON_2RM_VZIP:
6095
                    if (gen_neon_zip(rd, rm, size, q)) {
6096
                        return 1;
6097
                    }
6098
                    break;
6099
                case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6100
                    /* also VQMOVUN; op field and mnemonics don't line up */
6101
                    if (rm & 1) {
6102
                        return 1;
6103
                    }
6104
                    TCGV_UNUSED_I32(tmp2);
6105
                    for (pass = 0; pass < 2; pass++) {
6106
                        neon_load_reg64(cpu_V0, rm + pass);
6107
                        tmp = tcg_temp_new_i32();
6108
                        gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6109
                                           tmp, cpu_V0);
6110
                        if (pass == 0) {
6111
                            tmp2 = tmp;
6112
                        } else {
6113
                            neon_store_reg(rd, 0, tmp2);
6114
                            neon_store_reg(rd, 1, tmp);
6115
                        }
6116
                    }
6117
                    break;
6118
                case NEON_2RM_VSHLL:
6119
                    if (q || (rd & 1)) {
6120
                        return 1;
6121
                    }
6122
                    tmp = neon_load_reg(rm, 0);
6123
                    tmp2 = neon_load_reg(rm, 1);
6124
                    for (pass = 0; pass < 2; pass++) {
6125
                        if (pass == 1)
6126
                            tmp = tmp2;
6127
                        gen_neon_widen(cpu_V0, tmp, size, 1);
6128
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6129
                        neon_store_reg64(cpu_V0, rd + pass);
6130
                    }
6131
                    break;
6132
                case NEON_2RM_VCVT_F16_F32:
6133
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6134
                        q || (rm & 1)) {
6135
                        return 1;
6136
                    }
6137
                    tmp = tcg_temp_new_i32();
6138
                    tmp2 = tcg_temp_new_i32();
6139
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6140
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6141
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6142
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6143
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
6144
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
6145
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6146
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6147
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6148
                    neon_store_reg(rd, 0, tmp2);
6149
                    tmp2 = tcg_temp_new_i32();
6150
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6151
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
6152
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
6153
                    neon_store_reg(rd, 1, tmp2);
6154
                    tcg_temp_free_i32(tmp);
6155
                    break;
6156
                case NEON_2RM_VCVT_F32_F16:
6157
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6158
                        q || (rd & 1)) {
6159
                        return 1;
6160
                    }
6161
                    tmp3 = tcg_temp_new_i32();
6162
                    tmp = neon_load_reg(rm, 0);
6163
                    tmp2 = neon_load_reg(rm, 1);
6164
                    tcg_gen_ext16u_i32(tmp3, tmp);
6165
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6166
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6167
                    tcg_gen_shri_i32(tmp3, tmp, 16);
6168
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6169
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6170
                    tcg_temp_free_i32(tmp);
6171
                    tcg_gen_ext16u_i32(tmp3, tmp2);
6172
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6173
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6174
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
6175
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6176
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6177
                    tcg_temp_free_i32(tmp2);
6178
                    tcg_temp_free_i32(tmp3);
6179
                    break;
6180
                default:
6181
                elementwise:
6182
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
6183
                        if (neon_2rm_is_float_op(op)) {
6184
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
6185
                                           neon_reg_offset(rm, pass));
6186
                            TCGV_UNUSED_I32(tmp);
6187
                        } else {
6188
                            tmp = neon_load_reg(rm, pass);
6189
                        }
6190
                        switch (op) {
6191
                        case NEON_2RM_VREV32:
6192
                            switch (size) {
6193
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6194
                            case 1: gen_swap_half(tmp); break;
6195
                            default: abort();
6196
                            }
6197
                            break;
6198
                        case NEON_2RM_VREV16:
6199
                            gen_rev16(tmp);
6200
                            break;
6201
                        case NEON_2RM_VCLS:
6202
                            switch (size) {
6203
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6204
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6205
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6206
                            default: abort();
6207
                            }
6208
                            break;
6209
                        case NEON_2RM_VCLZ:
6210
                            switch (size) {
6211
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6212
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6213
                            case 2: gen_helper_clz(tmp, tmp); break;
6214
                            default: abort();
6215
                            }
6216
                            break;
6217
                        case NEON_2RM_VCNT:
6218
                            gen_helper_neon_cnt_u8(tmp, tmp);
6219
                            break;
6220
                        case NEON_2RM_VMVN:
6221
                            tcg_gen_not_i32(tmp, tmp);
6222
                            break;
6223
                        case NEON_2RM_VQABS:
6224
                            switch (size) {
6225
                            case 0:
6226
                                gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6227
                                break;
6228
                            case 1:
6229
                                gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6230
                                break;
6231
                            case 2:
6232
                                gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6233
                                break;
6234
                            default: abort();
6235
                            }
6236
                            break;
6237
                        case NEON_2RM_VQNEG:
6238
                            switch (size) {
6239
                            case 0:
6240
                                gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6241
                                break;
6242
                            case 1:
6243
                                gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6244
                                break;
6245
                            case 2:
6246
                                gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6247
                                break;
6248
                            default: abort();
6249
                            }
6250
                            break;
6251
                        case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6252
                            tmp2 = tcg_const_i32(0);
6253
                            switch(size) {
6254
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6255
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6256
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6257
                            default: abort();
6258
                            }
6259
                            tcg_temp_free_i32(tmp2);
6260
                            if (op == NEON_2RM_VCLE0) {
6261
                                tcg_gen_not_i32(tmp, tmp);
6262
                            }
6263
                            break;
6264
                        case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6265
                            tmp2 = tcg_const_i32(0);
6266
                            switch(size) {
6267
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6268
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6269
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6270
                            default: abort();
6271
                            }
6272
                            tcg_temp_free_i32(tmp2);
6273
                            if (op == NEON_2RM_VCLT0) {
6274
                                tcg_gen_not_i32(tmp, tmp);
6275
                            }
6276
                            break;
6277
                        case NEON_2RM_VCEQ0:
6278
                            tmp2 = tcg_const_i32(0);
6279
                            switch(size) {
6280
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6281
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6282
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6283
                            default: abort();
6284
                            }
6285
                            tcg_temp_free_i32(tmp2);
6286
                            break;
6287
                        case NEON_2RM_VABS:
6288
                            switch(size) {
6289
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6290
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6291
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
6292
                            default: abort();
6293
                            }
6294
                            break;
6295
                        case NEON_2RM_VNEG:
6296
                            tmp2 = tcg_const_i32(0);
6297
                            gen_neon_rsb(size, tmp, tmp2);
6298
                            tcg_temp_free_i32(tmp2);
6299
                            break;
6300
                        case NEON_2RM_VCGT0_F:
6301
                        {
6302
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6303
                            tmp2 = tcg_const_i32(0);
6304
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6305
                            tcg_temp_free_i32(tmp2);
6306
                            tcg_temp_free_ptr(fpstatus);
6307
                            break;
6308
                        }
6309
                        case NEON_2RM_VCGE0_F:
6310
                        {
6311
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6312
                            tmp2 = tcg_const_i32(0);
6313
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6314
                            tcg_temp_free_i32(tmp2);
6315
                            tcg_temp_free_ptr(fpstatus);
6316
                            break;
6317
                        }
6318
                        case NEON_2RM_VCEQ0_F:
6319
                        {
6320
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6321
                            tmp2 = tcg_const_i32(0);
6322
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6323
                            tcg_temp_free_i32(tmp2);
6324
                            tcg_temp_free_ptr(fpstatus);
6325
                            break;
6326
                        }
6327
                        case NEON_2RM_VCLE0_F:
6328
                        {
6329
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6330
                            tmp2 = tcg_const_i32(0);
6331
                            gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6332
                            tcg_temp_free_i32(tmp2);
6333
                            tcg_temp_free_ptr(fpstatus);
6334
                            break;
6335
                        }
6336
                        case NEON_2RM_VCLT0_F:
6337
                        {
6338
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6339
                            tmp2 = tcg_const_i32(0);
6340
                            gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6341
                            tcg_temp_free_i32(tmp2);
6342
                            tcg_temp_free_ptr(fpstatus);
6343
                            break;
6344
                        }
6345
                        case NEON_2RM_VABS_F:
6346
                            gen_vfp_abs(0);
6347
                            break;
6348
                        case NEON_2RM_VNEG_F:
6349
                            gen_vfp_neg(0);
6350
                            break;
6351
                        case NEON_2RM_VSWP:
6352
                            tmp2 = neon_load_reg(rd, pass);
6353
                            neon_store_reg(rm, pass, tmp2);
6354
                            break;
6355
                        case NEON_2RM_VTRN:
6356
                            tmp2 = neon_load_reg(rd, pass);
6357
                            switch (size) {
6358
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
6359
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
6360
                            default: abort();
6361
                            }
6362
                            neon_store_reg(rm, pass, tmp2);
6363
                            break;
6364
                        case NEON_2RM_VRECPE:
6365
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
6366
                            break;
6367
                        case NEON_2RM_VRSQRTE:
6368
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6369
                            break;
6370
                        case NEON_2RM_VRECPE_F:
6371
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6372
                            break;
6373
                        case NEON_2RM_VRSQRTE_F:
6374
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6375
                            break;
6376
                        case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6377
                            gen_vfp_sito(0, 1);
6378
                            break;
6379
                        case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6380
                            gen_vfp_uito(0, 1);
6381
                            break;
6382
                        case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6383
                            gen_vfp_tosiz(0, 1);
6384
                            break;
6385
                        case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6386
                            gen_vfp_touiz(0, 1);
6387
                            break;
6388
                        default:
6389
                            /* Reserved op values were caught by the
6390
                             * neon_2rm_sizes[] check earlier.
6391
                             */
6392
                            abort();
6393
                        }
6394
                        if (neon_2rm_is_float_op(op)) {
6395
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
6396
                                           neon_reg_offset(rd, pass));
6397
                        } else {
6398
                            neon_store_reg(rd, pass, tmp);
6399
                        }
6400
                    }
6401
                    break;
6402
                }
6403
            } else if ((insn & (1 << 10)) == 0) {
6404
                /* VTBL, VTBX.  */
6405
                int n = ((insn >> 8) & 3) + 1;
6406
                if ((rn + n) > 32) {
6407
                    /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6408
                     * helper function running off the end of the register file.
6409
                     */
6410
                    return 1;
6411
                }
6412
                n <<= 3;
6413
                if (insn & (1 << 6)) {
6414
                    tmp = neon_load_reg(rd, 0);
6415
                } else {
6416
                    tmp = tcg_temp_new_i32();
6417
                    tcg_gen_movi_i32(tmp, 0);
6418
                }
6419
                tmp2 = neon_load_reg(rm, 0);
6420
                tmp4 = tcg_const_i32(rn);
6421
                tmp5 = tcg_const_i32(n);
6422
                gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6423
                tcg_temp_free_i32(tmp);
6424
                if (insn & (1 << 6)) {
6425
                    tmp = neon_load_reg(rd, 1);
6426
                } else {
6427
                    tmp = tcg_temp_new_i32();
6428
                    tcg_gen_movi_i32(tmp, 0);
6429
                }
6430
                tmp3 = neon_load_reg(rm, 1);
6431
                gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6432
                tcg_temp_free_i32(tmp5);
6433
                tcg_temp_free_i32(tmp4);
6434
                neon_store_reg(rd, 0, tmp2);
6435
                neon_store_reg(rd, 1, tmp3);
6436
                tcg_temp_free_i32(tmp);
6437
            } else if ((insn & 0x380) == 0) {
6438
                /* VDUP */
6439
                if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6440
                    return 1;
6441
                }
6442
                if (insn & (1 << 19)) {
6443
                    tmp = neon_load_reg(rm, 1);
6444
                } else {
6445
                    tmp = neon_load_reg(rm, 0);
6446
                }
6447
                if (insn & (1 << 16)) {
6448
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6449
                } else if (insn & (1 << 17)) {
6450
                    if ((insn >> 18) & 1)
6451
                        gen_neon_dup_high16(tmp);
6452
                    else
6453
                        gen_neon_dup_low16(tmp);
6454
                }
6455
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
6456
                    tmp2 = tcg_temp_new_i32();
6457
                    tcg_gen_mov_i32(tmp2, tmp);
6458
                    neon_store_reg(rd, pass, tmp2);
6459
                }
6460
                tcg_temp_free_i32(tmp);
6461
            } else {
6462
                return 1;
6463
            }
6464
        }
6465
    }
6466
    return 0;
6467
}
6468

    
6469
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6470
{
6471
    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6472
    const ARMCPRegInfo *ri;
6473
    ARMCPU *cpu = arm_env_get_cpu(env);
6474

    
6475
    cpnum = (insn >> 8) & 0xf;
6476
    if (arm_feature(env, ARM_FEATURE_XSCALE)
6477
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6478
        return 1;
6479

    
6480
    /* First check for coprocessor space used for actual instructions */
6481
    switch (cpnum) {
6482
      case 0:
6483
      case 1:
6484
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6485
            return disas_iwmmxt_insn(env, s, insn);
6486
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6487
            return disas_dsp_insn(env, s, insn);
6488
        }
6489
        return 1;
6490
    default:
6491
        break;
6492
    }
6493

    
6494
    /* Otherwise treat as a generic register access */
6495
    is64 = (insn & (1 << 25)) == 0;
6496
    if (!is64 && ((insn & (1 << 4)) == 0)) {
6497
        /* cdp */
6498
        return 1;
6499
    }
6500

    
6501
    crm = insn & 0xf;
6502
    if (is64) {
6503
        crn = 0;
6504
        opc1 = (insn >> 4) & 0xf;
6505
        opc2 = 0;
6506
        rt2 = (insn >> 16) & 0xf;
6507
    } else {
6508
        crn = (insn >> 16) & 0xf;
6509
        opc1 = (insn >> 21) & 7;
6510
        opc2 = (insn >> 5) & 7;
6511
        rt2 = 0;
6512
    }
6513
    isread = (insn >> 20) & 1;
6514
    rt = (insn >> 12) & 0xf;
6515

    
6516
    ri = get_arm_cp_reginfo(cpu,
6517
                            ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6518
    if (ri) {
6519
        /* Check access permissions */
6520
        if (!cp_access_ok(env, ri, isread)) {
6521
            return 1;
6522
        }
6523

    
6524
        /* Handle special cases first */
6525
        switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6526
        case ARM_CP_NOP:
6527
            return 0;
6528
        case ARM_CP_WFI:
6529
            if (isread) {
6530
                return 1;
6531
            }
6532
            gen_set_pc_im(s, s->pc);
6533
            s->is_jmp = DISAS_WFI;
6534
            return 0;
6535
        default:
6536
            break;
6537
        }
6538

    
6539
        if (use_icount && (ri->type & ARM_CP_IO)) {
6540
            gen_io_start();
6541
        }
6542

    
6543
        if (isread) {
6544
            /* Read */
6545
            if (is64) {
6546
                TCGv_i64 tmp64;
6547
                TCGv_i32 tmp;
6548
                if (ri->type & ARM_CP_CONST) {
6549
                    tmp64 = tcg_const_i64(ri->resetvalue);
6550
                } else if (ri->readfn) {
6551
                    TCGv_ptr tmpptr;
6552
                    gen_set_pc_im(s, s->pc);
6553
                    tmp64 = tcg_temp_new_i64();
6554
                    tmpptr = tcg_const_ptr(ri);
6555
                    gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6556
                    tcg_temp_free_ptr(tmpptr);
6557
                } else {
6558
                    tmp64 = tcg_temp_new_i64();
6559
                    tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6560
                }
6561
                tmp = tcg_temp_new_i32();
6562
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6563
                store_reg(s, rt, tmp);
6564
                tcg_gen_shri_i64(tmp64, tmp64, 32);
6565
                tmp = tcg_temp_new_i32();
6566
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6567
                tcg_temp_free_i64(tmp64);
6568
                store_reg(s, rt2, tmp);
6569
            } else {
6570
                TCGv_i32 tmp;
6571
                if (ri->type & ARM_CP_CONST) {
6572
                    tmp = tcg_const_i32(ri->resetvalue);
6573
                } else if (ri->readfn) {
6574
                    TCGv_ptr tmpptr;
6575
                    gen_set_pc_im(s, s->pc);
6576
                    tmp = tcg_temp_new_i32();
6577
                    tmpptr = tcg_const_ptr(ri);
6578
                    gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6579
                    tcg_temp_free_ptr(tmpptr);
6580
                } else {
6581
                    tmp = load_cpu_offset(ri->fieldoffset);
6582
                }
6583
                if (rt == 15) {
6584
                    /* Destination register of r15 for 32 bit loads sets
6585
                     * the condition codes from the high 4 bits of the value
6586
                     */
6587
                    gen_set_nzcv(tmp);
6588
                    tcg_temp_free_i32(tmp);
6589
                } else {
6590
                    store_reg(s, rt, tmp);
6591
                }
6592
            }
6593
        } else {
6594
            /* Write */
6595
            if (ri->type & ARM_CP_CONST) {
6596
                /* If not forbidden by access permissions, treat as WI */
6597
                return 0;
6598
            }
6599

    
6600
            if (is64) {
6601
                TCGv_i32 tmplo, tmphi;
6602
                TCGv_i64 tmp64 = tcg_temp_new_i64();
6603
                tmplo = load_reg(s, rt);
6604
                tmphi = load_reg(s, rt2);
6605
                tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6606
                tcg_temp_free_i32(tmplo);
6607
                tcg_temp_free_i32(tmphi);
6608
                if (ri->writefn) {
6609
                    TCGv_ptr tmpptr = tcg_const_ptr(ri);
6610
                    gen_set_pc_im(s, s->pc);
6611
                    gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6612
                    tcg_temp_free_ptr(tmpptr);
6613
                } else {
6614
                    tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6615
                }
6616
                tcg_temp_free_i64(tmp64);
6617
            } else {
6618
                if (ri->writefn) {
6619
                    TCGv_i32 tmp;
6620
                    TCGv_ptr tmpptr;
6621
                    gen_set_pc_im(s, s->pc);
6622
                    tmp = load_reg(s, rt);
6623
                    tmpptr = tcg_const_ptr(ri);
6624
                    gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6625
                    tcg_temp_free_ptr(tmpptr);
6626
                    tcg_temp_free_i32(tmp);
6627
                } else {
6628
                    TCGv_i32 tmp = load_reg(s, rt);
6629
                    store_cpu_offset(tmp, ri->fieldoffset);
6630
                }
6631
            }
6632
        }
6633

    
6634
        if (use_icount && (ri->type & ARM_CP_IO)) {
6635
            /* I/O operations must end the TB here (whether read or write) */
6636
            gen_io_end();
6637
            gen_lookup_tb(s);
6638
        } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6639
            /* We default to ending the TB on a coprocessor register write,
6640
             * but allow this to be suppressed by the register definition
6641
             * (usually only necessary to work around guest bugs).
6642
             */
6643
            gen_lookup_tb(s);
6644
        }
6645

    
6646
        return 0;
6647
    }
6648

    
6649
    return 1;
6650
}
6651

    
6652

    
6653
/* Store a 64-bit value to a register pair.  Clobbers val.  */
6654
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6655
{
6656
    TCGv_i32 tmp;
6657
    tmp = tcg_temp_new_i32();
6658
    tcg_gen_trunc_i64_i32(tmp, val);
6659
    store_reg(s, rlow, tmp);
6660
    tmp = tcg_temp_new_i32();
6661
    tcg_gen_shri_i64(val, val, 32);
6662
    tcg_gen_trunc_i64_i32(tmp, val);
6663
    store_reg(s, rhigh, tmp);
6664
}
6665

    
6666
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
6667
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6668
{
6669
    TCGv_i64 tmp;
6670
    TCGv_i32 tmp2;
6671

    
6672
    /* Load value and extend to 64 bits.  */
6673
    tmp = tcg_temp_new_i64();
6674
    tmp2 = load_reg(s, rlow);
6675
    tcg_gen_extu_i32_i64(tmp, tmp2);
6676
    tcg_temp_free_i32(tmp2);
6677
    tcg_gen_add_i64(val, val, tmp);
6678
    tcg_temp_free_i64(tmp);
6679
}
6680

    
6681
/* load and add a 64-bit value from a register pair.  */
6682
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6683
{
6684
    TCGv_i64 tmp;
6685
    TCGv_i32 tmpl;
6686
    TCGv_i32 tmph;
6687

    
6688
    /* Load 64-bit value rd:rn.  */
6689
    tmpl = load_reg(s, rlow);
6690
    tmph = load_reg(s, rhigh);
6691
    tmp = tcg_temp_new_i64();
6692
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6693
    tcg_temp_free_i32(tmpl);
6694
    tcg_temp_free_i32(tmph);
6695
    tcg_gen_add_i64(val, val, tmp);
6696
    tcg_temp_free_i64(tmp);
6697
}
6698

    
6699
/* Set N and Z flags from hi|lo.  */
6700
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6701
{
6702
    tcg_gen_mov_i32(cpu_NF, hi);
6703
    tcg_gen_or_i32(cpu_ZF, lo, hi);
6704
}
6705

    
6706
/* Load/Store exclusive instructions are implemented by remembering
6707
   the value/address loaded, and seeing if these are the same
6708
   when the store is performed. This should be sufficient to implement
6709
   the architecturally mandated semantics, and avoids having to monitor
6710
   regular stores.
6711

6712
   In system emulation mode only one CPU will be running at once, so
6713
   this sequence is effectively atomic.  In user emulation mode we
6714
   throw an exception and handle the atomic operation elsewhere.  */
6715
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6716
                               TCGv_i32 addr, int size)
6717
{
6718
    TCGv_i32 tmp = tcg_temp_new_i32();
6719

    
6720
    switch (size) {
6721
    case 0:
6722
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
6723
        break;
6724
    case 1:
6725
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
6726
        break;
6727
    case 2:
6728
    case 3:
6729
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
6730
        break;
6731
    default:
6732
        abort();
6733
    }
6734
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6735
    store_reg(s, rt, tmp);
6736
    if (size == 3) {
6737
        TCGv_i32 tmp2 = tcg_temp_new_i32();
6738
        tcg_gen_addi_i32(tmp2, addr, 4);
6739
        tmp = tcg_temp_new_i32();
6740
        gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6741
        tcg_temp_free_i32(tmp2);
6742
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6743
        store_reg(s, rt2, tmp);
6744
    }
6745
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6746
}
6747

    
6748
static void gen_clrex(DisasContext *s)
6749
{
6750
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6751
}
6752

    
6753
#ifdef CONFIG_USER_ONLY
6754
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6755
                                TCGv_i32 addr, int size)
6756
{
6757
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
6758
    tcg_gen_movi_i32(cpu_exclusive_info,
6759
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
6760
    gen_exception_insn(s, 4, EXCP_STREX);
6761
}
6762
#else
6763
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6764
                                TCGv_i32 addr, int size)
6765
{
6766
    TCGv_i32 tmp;
6767
    int done_label;
6768
    int fail_label;
6769

    
6770
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6771
         [addr] = {Rt};
6772
         {Rd} = 0;
6773
       } else {
6774
         {Rd} = 1;
6775
       } */
6776
    fail_label = gen_new_label();
6777
    done_label = gen_new_label();
6778
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6779
    tmp = tcg_temp_new_i32();
6780
    switch (size) {
6781
    case 0:
6782
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
6783
        break;
6784
    case 1:
6785
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
6786
        break;
6787
    case 2:
6788
    case 3:
6789
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
6790
        break;
6791
    default:
6792
        abort();
6793
    }
6794
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6795
    tcg_temp_free_i32(tmp);
6796
    if (size == 3) {
6797
        TCGv_i32 tmp2 = tcg_temp_new_i32();
6798
        tcg_gen_addi_i32(tmp2, addr, 4);
6799
        tmp = tcg_temp_new_i32();
6800
        gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6801
        tcg_temp_free_i32(tmp2);
6802
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6803
        tcg_temp_free_i32(tmp);
6804
    }
6805
    tmp = load_reg(s, rt);
6806
    switch (size) {
6807
    case 0:
6808
        gen_aa32_st8(tmp, addr, IS_USER(s));
6809
        break;
6810
    case 1:
6811
        gen_aa32_st16(tmp, addr, IS_USER(s));
6812
        break;
6813
    case 2:
6814
    case 3:
6815
        gen_aa32_st32(tmp, addr, IS_USER(s));
6816
        break;
6817
    default:
6818
        abort();
6819
    }
6820
    tcg_temp_free_i32(tmp);
6821
    if (size == 3) {
6822
        tcg_gen_addi_i32(addr, addr, 4);
6823
        tmp = load_reg(s, rt2);
6824
        gen_aa32_st32(tmp, addr, IS_USER(s));
6825
        tcg_temp_free_i32(tmp);
6826
    }
6827
    tcg_gen_movi_i32(cpu_R[rd], 0);
6828
    tcg_gen_br(done_label);
6829
    gen_set_label(fail_label);
6830
    tcg_gen_movi_i32(cpu_R[rd], 1);
6831
    gen_set_label(done_label);
6832
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6833
}
6834
#endif
6835

    
6836
/* gen_srs:
6837
 * @env: CPUARMState
6838
 * @s: DisasContext
6839
 * @mode: mode field from insn (which stack to store to)
6840
 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6841
 * @writeback: true if writeback bit set
6842
 *
6843
 * Generate code for the SRS (Store Return State) insn.
6844
 */
6845
static void gen_srs(DisasContext *s,
6846
                    uint32_t mode, uint32_t amode, bool writeback)
6847
{
6848
    int32_t offset;
6849
    TCGv_i32 addr = tcg_temp_new_i32();
6850
    TCGv_i32 tmp = tcg_const_i32(mode);
6851
    gen_helper_get_r13_banked(addr, cpu_env, tmp);
6852
    tcg_temp_free_i32(tmp);
6853
    switch (amode) {
6854
    case 0: /* DA */
6855
        offset = -4;
6856
        break;
6857
    case 1: /* IA */
6858
        offset = 0;
6859
        break;
6860
    case 2: /* DB */
6861
        offset = -8;
6862
        break;
6863
    case 3: /* IB */
6864
        offset = 4;
6865
        break;
6866
    default:
6867
        abort();
6868
    }
6869
    tcg_gen_addi_i32(addr, addr, offset);
6870
    tmp = load_reg(s, 14);
6871
    gen_aa32_st32(tmp, addr, 0);
6872
    tcg_temp_free_i32(tmp);
6873
    tmp = load_cpu_field(spsr);
6874
    tcg_gen_addi_i32(addr, addr, 4);
6875
    gen_aa32_st32(tmp, addr, 0);
6876
    tcg_temp_free_i32(tmp);
6877
    if (writeback) {
6878
        switch (amode) {
6879
        case 0:
6880
            offset = -8;
6881
            break;
6882
        case 1:
6883
            offset = 4;
6884
            break;
6885
        case 2:
6886
            offset = -4;
6887
            break;
6888
        case 3:
6889
            offset = 0;
6890
            break;
6891
        default:
6892
            abort();
6893
        }
6894
        tcg_gen_addi_i32(addr, addr, offset);
6895
        tmp = tcg_const_i32(mode);
6896
        gen_helper_set_r13_banked(cpu_env, tmp, addr);
6897
        tcg_temp_free_i32(tmp);
6898
    }
6899
    tcg_temp_free_i32(addr);
6900
}
6901

    
6902
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6903
{
6904
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6905
    TCGv_i32 tmp;
6906
    TCGv_i32 tmp2;
6907
    TCGv_i32 tmp3;
6908
    TCGv_i32 addr;
6909
    TCGv_i64 tmp64;
6910

    
6911
    insn = arm_ldl_code(env, s->pc, s->bswap_code);
6912
    s->pc += 4;
6913

    
6914
    /* M variants do not implement ARM mode.  */
6915
    if (IS_M(env))
6916
        goto illegal_op;
6917
    cond = insn >> 28;
6918
    if (cond == 0xf){
6919
        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6920
         * choose to UNDEF. In ARMv5 and above the space is used
6921
         * for miscellaneous unconditional instructions.
6922
         */
6923
        ARCH(5);
6924

    
6925
        /* Unconditional instructions.  */
6926
        if (((insn >> 25) & 7) == 1) {
6927
            /* NEON Data processing.  */
6928
            if (!arm_feature(env, ARM_FEATURE_NEON))
6929
                goto illegal_op;
6930

    
6931
            if (disas_neon_data_insn(env, s, insn))
6932
                goto illegal_op;
6933
            return;
6934
        }
6935
        if ((insn & 0x0f100000) == 0x04000000) {
6936
            /* NEON load/store.  */
6937
            if (!arm_feature(env, ARM_FEATURE_NEON))
6938
                goto illegal_op;
6939

    
6940
            if (disas_neon_ls_insn(env, s, insn))
6941
                goto illegal_op;
6942
            return;
6943
        }
6944
        if ((insn & 0x0f000e10) == 0x0e000a00) {
6945
            /* VFP.  */
6946
            if (disas_vfp_insn(env, s, insn)) {
6947
                goto illegal_op;
6948
            }
6949
            return;
6950
        }
6951
        if (((insn & 0x0f30f000) == 0x0510f000) ||
6952
            ((insn & 0x0f30f010) == 0x0710f000)) {
6953
            if ((insn & (1 << 22)) == 0) {
6954
                /* PLDW; v7MP */
6955
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6956
                    goto illegal_op;
6957
                }
6958
            }
6959
            /* Otherwise PLD; v5TE+ */
6960
            ARCH(5TE);
6961
            return;
6962
        }
6963
        if (((insn & 0x0f70f000) == 0x0450f000) ||
6964
            ((insn & 0x0f70f010) == 0x0650f000)) {
6965
            ARCH(7);
6966
            return; /* PLI; V7 */
6967
        }
6968
        if (((insn & 0x0f700000) == 0x04100000) ||
6969
            ((insn & 0x0f700010) == 0x06100000)) {
6970
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6971
                goto illegal_op;
6972
            }
6973
            return; /* v7MP: Unallocated memory hint: must NOP */
6974
        }
6975

    
6976
        if ((insn & 0x0ffffdff) == 0x01010000) {
6977
            ARCH(6);
6978
            /* setend */
6979
            if (((insn >> 9) & 1) != s->bswap_code) {
6980
                /* Dynamic endianness switching not implemented. */
6981
                qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
6982
                goto illegal_op;
6983
            }
6984
            return;
6985
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6986
            switch ((insn >> 4) & 0xf) {
6987
            case 1: /* clrex */
6988
                ARCH(6K);
6989
                gen_clrex(s);
6990
                return;
6991
            case 4: /* dsb */
6992
            case 5: /* dmb */
6993
            case 6: /* isb */
6994
                ARCH(7);
6995
                /* We don't emulate caches so these are a no-op.  */
6996
                return;
6997
            default:
6998
                goto illegal_op;
6999
            }
7000
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7001
            /* srs */
7002
            if (IS_USER(s)) {
7003
                goto illegal_op;
7004
            }
7005
            ARCH(6);
7006
            gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7007
            return;
7008
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7009
            /* rfe */
7010
            int32_t offset;
7011
            if (IS_USER(s))
7012
                goto illegal_op;
7013
            ARCH(6);
7014
            rn = (insn >> 16) & 0xf;
7015
            addr = load_reg(s, rn);
7016
            i = (insn >> 23) & 3;
7017
            switch (i) {
7018
            case 0: offset = -4; break; /* DA */
7019
            case 1: offset = 0; break; /* IA */
7020
            case 2: offset = -8; break; /* DB */
7021
            case 3: offset = 4; break; /* IB */
7022
            default: abort();
7023
            }
7024
            if (offset)
7025
                tcg_gen_addi_i32(addr, addr, offset);
7026
            /* Load PC into tmp and CPSR into tmp2.  */
7027
            tmp = tcg_temp_new_i32();
7028
            gen_aa32_ld32u(tmp, addr, 0);
7029
            tcg_gen_addi_i32(addr, addr, 4);
7030
            tmp2 = tcg_temp_new_i32();
7031
            gen_aa32_ld32u(tmp2, addr, 0);
7032
            if (insn & (1 << 21)) {
7033
                /* Base writeback.  */
7034
                switch (i) {
7035
                case 0: offset = -8; break;
7036
                case 1: offset = 4; break;
7037
                case 2: offset = -4; break;
7038
                case 3: offset = 0; break;
7039
                default: abort();
7040
                }
7041
                if (offset)
7042
                    tcg_gen_addi_i32(addr, addr, offset);
7043
                store_reg(s, rn, addr);
7044
            } else {
7045
                tcg_temp_free_i32(addr);
7046
            }
7047
            gen_rfe(s, tmp, tmp2);
7048
            return;
7049
        } else if ((insn & 0x0e000000) == 0x0a000000) {
7050
            /* branch link and change to thumb (blx <offset>) */
7051
            int32_t offset;
7052

    
7053
            val = (uint32_t)s->pc;
7054
            tmp = tcg_temp_new_i32();
7055
            tcg_gen_movi_i32(tmp, val);
7056
            store_reg(s, 14, tmp);
7057
            /* Sign-extend the 24-bit offset */
7058
            offset = (((int32_t)insn) << 8) >> 8;
7059
            /* offset * 4 + bit24 * 2 + (thumb bit) */
7060
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
7061
            /* pipeline offset */
7062
            val += 4;
7063
            /* protected by ARCH(5); above, near the start of uncond block */
7064
            gen_bx_im(s, val);
7065
            return;
7066
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
7067
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7068
                /* iWMMXt register transfer.  */
7069
                if (env->cp15.c15_cpar & (1 << 1))
7070
                    if (!disas_iwmmxt_insn(env, s, insn))
7071
                        return;
7072
            }
7073
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
7074
            /* Coprocessor double register transfer.  */
7075
            ARCH(5TE);
7076
        } else if ((insn & 0x0f000010) == 0x0e000010) {
7077
            /* Additional coprocessor register transfer.  */
7078
        } else if ((insn & 0x0ff10020) == 0x01000000) {
7079
            uint32_t mask;
7080
            uint32_t val;
7081
            /* cps (privileged) */
7082
            if (IS_USER(s))
7083
                return;
7084
            mask = val = 0;
7085
            if (insn & (1 << 19)) {
7086
                if (insn & (1 << 8))
7087
                    mask |= CPSR_A;
7088
                if (insn & (1 << 7))
7089
                    mask |= CPSR_I;
7090
                if (insn & (1 << 6))
7091
                    mask |= CPSR_F;
7092
                if (insn & (1 << 18))
7093
                    val |= mask;
7094
            }
7095
            if (insn & (1 << 17)) {
7096
                mask |= CPSR_M;
7097
                val |= (insn & 0x1f);
7098
            }
7099
            if (mask) {
7100
                gen_set_psr_im(s, mask, 0, val);
7101
            }
7102
            return;
7103
        }
7104
        goto illegal_op;
7105
    }
7106
    if (cond != 0xe) {
7107
        /* if not always execute, we generate a conditional jump to
7108
           next instruction */
7109
        s->condlabel = gen_new_label();
7110
        gen_test_cc(cond ^ 1, s->condlabel);
7111
        s->condjmp = 1;
7112
    }
7113
    if ((insn & 0x0f900000) == 0x03000000) {
7114
        if ((insn & (1 << 21)) == 0) {
7115
            ARCH(6T2);
7116
            rd = (insn >> 12) & 0xf;
7117
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7118
            if ((insn & (1 << 22)) == 0) {
7119
                /* MOVW */
7120
                tmp = tcg_temp_new_i32();
7121
                tcg_gen_movi_i32(tmp, val);
7122
            } else {
7123
                /* MOVT */
7124
                tmp = load_reg(s, rd);
7125
                tcg_gen_ext16u_i32(tmp, tmp);
7126
                tcg_gen_ori_i32(tmp, tmp, val << 16);
7127
            }
7128
            store_reg(s, rd, tmp);
7129
        } else {
7130
            if (((insn >> 12) & 0xf) != 0xf)
7131
                goto illegal_op;
7132
            if (((insn >> 16) & 0xf) == 0) {
7133
                gen_nop_hint(s, insn & 0xff);
7134
            } else {
7135
                /* CPSR = immediate */
7136
                val = insn & 0xff;
7137
                shift = ((insn >> 8) & 0xf) * 2;
7138
                if (shift)
7139
                    val = (val >> shift) | (val << (32 - shift));
7140
                i = ((insn & (1 << 22)) != 0);
7141
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7142
                    goto illegal_op;
7143
            }
7144
        }
7145
    } else if ((insn & 0x0f900000) == 0x01000000
7146
               && (insn & 0x00000090) != 0x00000090) {
7147
        /* miscellaneous instructions */
7148
        op1 = (insn >> 21) & 3;
7149
        sh = (insn >> 4) & 0xf;
7150
        rm = insn & 0xf;
7151
        switch (sh) {
7152
        case 0x0: /* move program status register */
7153
            if (op1 & 1) {
7154
                /* PSR = reg */
7155
                tmp = load_reg(s, rm);
7156
                i = ((op1 & 2) != 0);
7157
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7158
                    goto illegal_op;
7159
            } else {
7160
                /* reg = PSR */
7161
                rd = (insn >> 12) & 0xf;
7162
                if (op1 & 2) {
7163
                    if (IS_USER(s))
7164
                        goto illegal_op;
7165
                    tmp = load_cpu_field(spsr);
7166
                } else {
7167
                    tmp = tcg_temp_new_i32();
7168
                    gen_helper_cpsr_read(tmp, cpu_env);
7169
                }
7170
                store_reg(s, rd, tmp);
7171
            }
7172
            break;
7173
        case 0x1:
7174
            if (op1 == 1) {
7175
                /* branch/exchange thumb (bx).  */
7176
                ARCH(4T);
7177
                tmp = load_reg(s, rm);
7178
                gen_bx(s, tmp);
7179
            } else if (op1 == 3) {
7180
                /* clz */
7181
                ARCH(5);
7182
                rd = (insn >> 12) & 0xf;
7183
                tmp = load_reg(s, rm);
7184
                gen_helper_clz(tmp, tmp);
7185
                store_reg(s, rd, tmp);
7186
            } else {
7187
                goto illegal_op;
7188
            }
7189
            break;
7190
        case 0x2:
7191
            if (op1 == 1) {
7192
                ARCH(5J); /* bxj */
7193
                /* Trivial implementation equivalent to bx.  */
7194
                tmp = load_reg(s, rm);
7195
                gen_bx(s, tmp);
7196
            } else {
7197
                goto illegal_op;
7198
            }
7199
            break;
7200
        case 0x3:
7201
            if (op1 != 1)
7202
              goto illegal_op;
7203

    
7204
            ARCH(5);
7205
            /* branch link/exchange thumb (blx) */
7206
            tmp = load_reg(s, rm);
7207
            tmp2 = tcg_temp_new_i32();
7208
            tcg_gen_movi_i32(tmp2, s->pc);
7209
            store_reg(s, 14, tmp2);
7210
            gen_bx(s, tmp);
7211
            break;
7212
        case 0x5: /* saturating add/subtract */
7213
            ARCH(5TE);
7214
            rd = (insn >> 12) & 0xf;
7215
            rn = (insn >> 16) & 0xf;
7216
            tmp = load_reg(s, rm);
7217
            tmp2 = load_reg(s, rn);
7218
            if (op1 & 2)
7219
                gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7220
            if (op1 & 1)
7221
                gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7222
            else
7223
                gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7224
            tcg_temp_free_i32(tmp2);
7225
            store_reg(s, rd, tmp);
7226
            break;
7227
        case 7:
7228
            /* SMC instruction (op1 == 3)
7229
               and undefined instructions (op1 == 0 || op1 == 2)
7230
               will trap */
7231
            if (op1 != 1) {
7232
                goto illegal_op;
7233
            }
7234
            /* bkpt */
7235
            ARCH(5);
7236
            gen_exception_insn(s, 4, EXCP_BKPT);
7237
            break;
7238
        case 0x8: /* signed multiply */
7239
        case 0xa:
7240
        case 0xc:
7241
        case 0xe:
7242
            ARCH(5TE);
7243
            rs = (insn >> 8) & 0xf;
7244
            rn = (insn >> 12) & 0xf;
7245
            rd = (insn >> 16) & 0xf;
7246
            if (op1 == 1) {
7247
                /* (32 * 16) >> 16 */
7248
                tmp = load_reg(s, rm);
7249
                tmp2 = load_reg(s, rs);
7250
                if (sh & 4)
7251
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7252
                else
7253
                    gen_sxth(tmp2);
7254
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7255
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7256
                tmp = tcg_temp_new_i32();
7257
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7258
                tcg_temp_free_i64(tmp64);
7259
                if ((sh & 2) == 0) {
7260
                    tmp2 = load_reg(s, rn);
7261
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7262
                    tcg_temp_free_i32(tmp2);
7263
                }
7264
                store_reg(s, rd, tmp);
7265
            } else {
7266
                /* 16 * 16 */
7267
                tmp = load_reg(s, rm);
7268
                tmp2 = load_reg(s, rs);
7269
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7270
                tcg_temp_free_i32(tmp2);
7271
                if (op1 == 2) {
7272
                    tmp64 = tcg_temp_new_i64();
7273
                    tcg_gen_ext_i32_i64(tmp64, tmp);
7274
                    tcg_temp_free_i32(tmp);
7275
                    gen_addq(s, tmp64, rn, rd);
7276
                    gen_storeq_reg(s, rn, rd, tmp64);
7277
                    tcg_temp_free_i64(tmp64);
7278
                } else {
7279
                    if (op1 == 0) {
7280
                        tmp2 = load_reg(s, rn);
7281
                        gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7282
                        tcg_temp_free_i32(tmp2);
7283
                    }
7284
                    store_reg(s, rd, tmp);
7285
                }
7286
            }
7287
            break;
7288
        default:
7289
            goto illegal_op;
7290
        }
7291
    } else if (((insn & 0x0e000000) == 0 &&
7292
                (insn & 0x00000090) != 0x90) ||
7293
               ((insn & 0x0e000000) == (1 << 25))) {
7294
        int set_cc, logic_cc, shiftop;
7295

    
7296
        op1 = (insn >> 21) & 0xf;
7297
        set_cc = (insn >> 20) & 1;
7298
        logic_cc = table_logic_cc[op1] & set_cc;
7299

    
7300
        /* data processing instruction */
7301
        if (insn & (1 << 25)) {
7302
            /* immediate operand */
7303
            val = insn & 0xff;
7304
            shift = ((insn >> 8) & 0xf) * 2;
7305
            if (shift) {
7306
                val = (val >> shift) | (val << (32 - shift));
7307
            }
7308
            tmp2 = tcg_temp_new_i32();
7309
            tcg_gen_movi_i32(tmp2, val);
7310
            if (logic_cc && shift) {
7311
                gen_set_CF_bit31(tmp2);
7312
            }
7313
        } else {
7314
            /* register */
7315
            rm = (insn) & 0xf;
7316
            tmp2 = load_reg(s, rm);
7317
            shiftop = (insn >> 5) & 3;
7318
            if (!(insn & (1 << 4))) {
7319
                shift = (insn >> 7) & 0x1f;
7320
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7321
            } else {
7322
                rs = (insn >> 8) & 0xf;
7323
                tmp = load_reg(s, rs);
7324
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7325
            }
7326
        }
7327
        if (op1 != 0x0f && op1 != 0x0d) {
7328
            rn = (insn >> 16) & 0xf;
7329
            tmp = load_reg(s, rn);
7330
        } else {
7331
            TCGV_UNUSED_I32(tmp);
7332
        }
7333
        rd = (insn >> 12) & 0xf;
7334
        switch(op1) {
7335
        case 0x00:
7336
            tcg_gen_and_i32(tmp, tmp, tmp2);
7337
            if (logic_cc) {
7338
                gen_logic_CC(tmp);
7339
            }
7340
            store_reg_bx(env, s, rd, tmp);
7341
            break;
7342
        case 0x01:
7343
            tcg_gen_xor_i32(tmp, tmp, tmp2);
7344
            if (logic_cc) {
7345
                gen_logic_CC(tmp);
7346
            }
7347
            store_reg_bx(env, s, rd, tmp);
7348
            break;
7349
        case 0x02:
7350
            if (set_cc && rd == 15) {
7351
                /* SUBS r15, ... is used for exception return.  */
7352
                if (IS_USER(s)) {
7353
                    goto illegal_op;
7354
                }
7355
                gen_sub_CC(tmp, tmp, tmp2);
7356
                gen_exception_return(s, tmp);
7357
            } else {
7358
                if (set_cc) {
7359
                    gen_sub_CC(tmp, tmp, tmp2);
7360
                } else {
7361
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7362
                }
7363
                store_reg_bx(env, s, rd, tmp);
7364
            }
7365
            break;
7366
        case 0x03:
7367
            if (set_cc) {
7368
                gen_sub_CC(tmp, tmp2, tmp);
7369
            } else {
7370
                tcg_gen_sub_i32(tmp, tmp2, tmp);
7371
            }
7372
            store_reg_bx(env, s, rd, tmp);
7373
            break;
7374
        case 0x04:
7375
            if (set_cc) {
7376
                gen_add_CC(tmp, tmp, tmp2);
7377
            } else {
7378
                tcg_gen_add_i32(tmp, tmp, tmp2);
7379
            }
7380
            store_reg_bx(env, s, rd, tmp);
7381
            break;
7382
        case 0x05:
7383
            if (set_cc) {
7384
                gen_adc_CC(tmp, tmp, tmp2);
7385
            } else {
7386
                gen_add_carry(tmp, tmp, tmp2);
7387
            }
7388
            store_reg_bx(env, s, rd, tmp);
7389
            break;
7390
        case 0x06:
7391
            if (set_cc) {
7392
                gen_sbc_CC(tmp, tmp, tmp2);
7393
            } else {
7394
                gen_sub_carry(tmp, tmp, tmp2);
7395
            }
7396
            store_reg_bx(env, s, rd, tmp);
7397
            break;
7398
        case 0x07:
7399
            if (set_cc) {
7400
                gen_sbc_CC(tmp, tmp2, tmp);
7401
            } else {
7402
                gen_sub_carry(tmp, tmp2, tmp);
7403
            }
7404
            store_reg_bx(env, s, rd, tmp);
7405
            break;
7406
        case 0x08:
7407
            if (set_cc) {
7408
                tcg_gen_and_i32(tmp, tmp, tmp2);
7409
                gen_logic_CC(tmp);
7410
            }
7411
            tcg_temp_free_i32(tmp);
7412
            break;
7413
        case 0x09:
7414
            if (set_cc) {
7415
                tcg_gen_xor_i32(tmp, tmp, tmp2);
7416
                gen_logic_CC(tmp);
7417
            }
7418
            tcg_temp_free_i32(tmp);
7419
            break;
7420
        case 0x0a:
7421
            if (set_cc) {
7422
                gen_sub_CC(tmp, tmp, tmp2);
7423
            }
7424
            tcg_temp_free_i32(tmp);
7425
            break;
7426
        case 0x0b:
7427
            if (set_cc) {
7428
                gen_add_CC(tmp, tmp, tmp2);
7429
            }
7430
            tcg_temp_free_i32(tmp);
7431
            break;
7432
        case 0x0c:
7433
            tcg_gen_or_i32(tmp, tmp, tmp2);
7434
            if (logic_cc) {
7435
                gen_logic_CC(tmp);
7436
            }
7437
            store_reg_bx(env, s, rd, tmp);
7438
            break;
7439
        case 0x0d:
7440
            if (logic_cc && rd == 15) {
7441
                /* MOVS r15, ... is used for exception return.  */
7442
                if (IS_USER(s)) {
7443
                    goto illegal_op;
7444
                }
7445
                gen_exception_return(s, tmp2);
7446
            } else {
7447
                if (logic_cc) {
7448
                    gen_logic_CC(tmp2);
7449
                }
7450
                store_reg_bx(env, s, rd, tmp2);
7451
            }
7452
            break;
7453
        case 0x0e:
7454
            tcg_gen_andc_i32(tmp, tmp, tmp2);
7455
            if (logic_cc) {
7456
                gen_logic_CC(tmp);
7457
            }
7458
            store_reg_bx(env, s, rd, tmp);
7459
            break;
7460
        default:
7461
        case 0x0f:
7462
            tcg_gen_not_i32(tmp2, tmp2);
7463
            if (logic_cc) {
7464
                gen_logic_CC(tmp2);
7465
            }
7466
            store_reg_bx(env, s, rd, tmp2);
7467
            break;
7468
        }
7469
        if (op1 != 0x0f && op1 != 0x0d) {
7470
            tcg_temp_free_i32(tmp2);
7471
        }
7472
    } else {
7473
        /* other instructions */
7474
        op1 = (insn >> 24) & 0xf;
7475
        switch(op1) {
7476
        case 0x0:
7477
        case 0x1:
7478
            /* multiplies, extra load/stores */
7479
            sh = (insn >> 5) & 3;
7480
            if (sh == 0) {
7481
                if (op1 == 0x0) {
7482
                    rd = (insn >> 16) & 0xf;
7483
                    rn = (insn >> 12) & 0xf;
7484
                    rs = (insn >> 8) & 0xf;
7485
                    rm = (insn) & 0xf;
7486
                    op1 = (insn >> 20) & 0xf;
7487
                    switch (op1) {
7488
                    case 0: case 1: case 2: case 3: case 6:
7489
                        /* 32 bit mul */
7490
                        tmp = load_reg(s, rs);
7491
                        tmp2 = load_reg(s, rm);
7492
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
7493
                        tcg_temp_free_i32(tmp2);
7494
                        if (insn & (1 << 22)) {
7495
                            /* Subtract (mls) */
7496
                            ARCH(6T2);
7497
                            tmp2 = load_reg(s, rn);
7498
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
7499
                            tcg_temp_free_i32(tmp2);
7500
                        } else if (insn & (1 << 21)) {
7501
                            /* Add */
7502
                            tmp2 = load_reg(s, rn);
7503
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7504
                            tcg_temp_free_i32(tmp2);
7505
                        }
7506
                        if (insn & (1 << 20))
7507
                            gen_logic_CC(tmp);
7508
                        store_reg(s, rd, tmp);
7509
                        break;
7510
                    case 4:
7511
                        /* 64 bit mul double accumulate (UMAAL) */
7512
                        ARCH(6);
7513
                        tmp = load_reg(s, rs);
7514
                        tmp2 = load_reg(s, rm);
7515
                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7516
                        gen_addq_lo(s, tmp64, rn);
7517
                        gen_addq_lo(s, tmp64, rd);
7518
                        gen_storeq_reg(s, rn, rd, tmp64);
7519
                        tcg_temp_free_i64(tmp64);
7520
                        break;
7521
                    case 8: case 9: case 10: case 11:
7522
                    case 12: case 13: case 14: case 15:
7523
                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7524
                        tmp = load_reg(s, rs);
7525
                        tmp2 = load_reg(s, rm);
7526
                        if (insn & (1 << 22)) {
7527
                            tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7528
                        } else {
7529
                            tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7530
                        }
7531
                        if (insn & (1 << 21)) { /* mult accumulate */
7532
                            TCGv_i32 al = load_reg(s, rn);
7533
                            TCGv_i32 ah = load_reg(s, rd);
7534
                            tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7535
                            tcg_temp_free_i32(al);
7536
                            tcg_temp_free_i32(ah);
7537
                        }
7538
                        if (insn & (1 << 20)) {
7539
                            gen_logicq_cc(tmp, tmp2);
7540
                        }
7541
                        store_reg(s, rn, tmp);
7542
                        store_reg(s, rd, tmp2);
7543
                        break;
7544
                    default:
7545
                        goto illegal_op;
7546
                    }
7547
                } else {
7548
                    rn = (insn >> 16) & 0xf;
7549
                    rd = (insn >> 12) & 0xf;
7550
                    if (insn & (1 << 23)) {
7551
                        /* load/store exclusive */
7552
                        int op2 = (insn >> 8) & 3;
7553
                        op1 = (insn >> 21) & 0x3;
7554

    
7555
                        switch (op2) {
7556
                        case 0: /* lda/stl */
7557
                            if (op1 == 1) {
7558
                                goto illegal_op;
7559
                            }
7560
                            ARCH(8);
7561
                            break;
7562
                        case 1: /* reserved */
7563
                            goto illegal_op;
7564
                        case 2: /* ldaex/stlex */
7565
                            ARCH(8);
7566
                            break;
7567
                        case 3: /* ldrex/strex */
7568
                            if (op1) {
7569
                                ARCH(6K);
7570
                            } else {
7571
                                ARCH(6);
7572
                            }
7573
                            break;
7574
                        }
7575

    
7576
                        addr = tcg_temp_local_new_i32();
7577
                        load_reg_var(s, addr, rn);
7578

    
7579
                        /* Since the emulation does not have barriers,
7580
                           the acquire/release semantics need no special
7581
                           handling */
7582
                        if (op2 == 0) {
7583
                            if (insn & (1 << 20)) {
7584
                                tmp = tcg_temp_new_i32();
7585
                                switch (op1) {
7586
                                case 0: /* lda */
7587
                                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
7588
                                    break;
7589
                                case 2: /* ldab */
7590
                                    gen_aa32_ld8u(tmp, addr, IS_USER(s));
7591
                                    break;
7592
                                case 3: /* ldah */
7593
                                    gen_aa32_ld16u(tmp, addr, IS_USER(s));
7594
                                    break;
7595
                                default:
7596
                                    abort();
7597
                                }
7598
                                store_reg(s, rd, tmp);
7599
                            } else {
7600
                                rm = insn & 0xf;
7601
                                tmp = load_reg(s, rm);
7602
                                switch (op1) {
7603
                                case 0: /* stl */
7604
                                    gen_aa32_st32(tmp, addr, IS_USER(s));
7605
                                    break;
7606
                                case 2: /* stlb */
7607
                                    gen_aa32_st8(tmp, addr, IS_USER(s));
7608
                                    break;
7609
                                case 3: /* stlh */
7610
                                    gen_aa32_st16(tmp, addr, IS_USER(s));
7611
                                    break;
7612
                                default:
7613
                                    abort();
7614
                                }
7615
                                tcg_temp_free_i32(tmp);
7616
                            }
7617
                        } else if (insn & (1 << 20)) {
7618
                            switch (op1) {
7619
                            case 0: /* ldrex */
7620
                                gen_load_exclusive(s, rd, 15, addr, 2);
7621
                                break;
7622
                            case 1: /* ldrexd */
7623
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
7624
                                break;
7625
                            case 2: /* ldrexb */
7626
                                gen_load_exclusive(s, rd, 15, addr, 0);
7627
                                break;
7628
                            case 3: /* ldrexh */
7629
                                gen_load_exclusive(s, rd, 15, addr, 1);
7630
                                break;
7631
                            default:
7632
                                abort();
7633
                            }
7634
                        } else {
7635
                            rm = insn & 0xf;
7636
                            switch (op1) {
7637
                            case 0:  /*  strex */
7638
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
7639
                                break;
7640
                            case 1: /*  strexd */
7641
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7642
                                break;
7643
                            case 2: /*  strexb */
7644
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
7645
                                break;
7646
                            case 3: /* strexh */
7647
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
7648
                                break;
7649
                            default:
7650
                                abort();
7651
                            }
7652
                        }
7653
                        tcg_temp_free_i32(addr);
7654
                    } else {
7655
                        /* SWP instruction */
7656
                        rm = (insn) & 0xf;
7657

    
7658
                        /* ??? This is not really atomic.  However we know
7659
                           we never have multiple CPUs running in parallel,
7660
                           so it is good enough.  */
7661
                        addr = load_reg(s, rn);
7662
                        tmp = load_reg(s, rm);
7663
                        tmp2 = tcg_temp_new_i32();
7664
                        if (insn & (1 << 22)) {
7665
                            gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7666
                            gen_aa32_st8(tmp, addr, IS_USER(s));
7667
                        } else {
7668
                            gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7669
                            gen_aa32_st32(tmp, addr, IS_USER(s));
7670
                        }
7671
                        tcg_temp_free_i32(tmp);
7672
                        tcg_temp_free_i32(addr);
7673
                        store_reg(s, rd, tmp2);
7674
                    }
7675
                }
7676
            } else {
7677
                int address_offset;
7678
                int load;
7679
                /* Misc load/store */
7680
                rn = (insn >> 16) & 0xf;
7681
                rd = (insn >> 12) & 0xf;
7682
                addr = load_reg(s, rn);
7683
                if (insn & (1 << 24))
7684
                    gen_add_datah_offset(s, insn, 0, addr);
7685
                address_offset = 0;
7686
                if (insn & (1 << 20)) {
7687
                    /* load */
7688
                    tmp = tcg_temp_new_i32();
7689
                    switch(sh) {
7690
                    case 1:
7691
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
7692
                        break;
7693
                    case 2:
7694
                        gen_aa32_ld8s(tmp, addr, IS_USER(s));
7695
                        break;
7696
                    default:
7697
                    case 3:
7698
                        gen_aa32_ld16s(tmp, addr, IS_USER(s));
7699
                        break;
7700
                    }
7701
                    load = 1;
7702
                } else if (sh & 2) {
7703
                    ARCH(5TE);
7704
                    /* doubleword */
7705
                    if (sh & 1) {
7706
                        /* store */
7707
                        tmp = load_reg(s, rd);
7708
                        gen_aa32_st32(tmp, addr, IS_USER(s));
7709
                        tcg_temp_free_i32(tmp);
7710
                        tcg_gen_addi_i32(addr, addr, 4);
7711
                        tmp = load_reg(s, rd + 1);
7712
                        gen_aa32_st32(tmp, addr, IS_USER(s));
7713
                        tcg_temp_free_i32(tmp);
7714
                        load = 0;
7715
                    } else {
7716
                        /* load */
7717
                        tmp = tcg_temp_new_i32();
7718
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
7719
                        store_reg(s, rd, tmp);
7720
                        tcg_gen_addi_i32(addr, addr, 4);
7721
                        tmp = tcg_temp_new_i32();
7722
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
7723
                        rd++;
7724
                        load = 1;
7725
                    }
7726
                    address_offset = -4;
7727
                } else {
7728
                    /* store */
7729
                    tmp = load_reg(s, rd);
7730
                    gen_aa32_st16(tmp, addr, IS_USER(s));
7731
                    tcg_temp_free_i32(tmp);
7732
                    load = 0;
7733
                }
7734
                /* Perform base writeback before the loaded value to
7735
                   ensure correct behavior with overlapping index registers.
7736
                   ldrd with base writeback is is undefined if the
7737
                   destination and index registers overlap.  */
7738
                if (!(insn & (1 << 24))) {
7739
                    gen_add_datah_offset(s, insn, address_offset, addr);
7740
                    store_reg(s, rn, addr);
7741
                } else if (insn & (1 << 21)) {
7742
                    if (address_offset)
7743
                        tcg_gen_addi_i32(addr, addr, address_offset);
7744
                    store_reg(s, rn, addr);
7745
                } else {
7746
                    tcg_temp_free_i32(addr);
7747
                }
7748
                if (load) {
7749
                    /* Complete the load.  */
7750
                    store_reg(s, rd, tmp);
7751
                }
7752
            }
7753
            break;
7754
        case 0x4:
7755
        case 0x5:
7756
            goto do_ldst;
7757
        case 0x6:
7758
        case 0x7:
7759
            if (insn & (1 << 4)) {
7760
                ARCH(6);
7761
                /* Armv6 Media instructions.  */
7762
                rm = insn & 0xf;
7763
                rn = (insn >> 16) & 0xf;
7764
                rd = (insn >> 12) & 0xf;
7765
                rs = (insn >> 8) & 0xf;
7766
                switch ((insn >> 23) & 3) {
7767
                case 0: /* Parallel add/subtract.  */
7768
                    op1 = (insn >> 20) & 7;
7769
                    tmp = load_reg(s, rn);
7770
                    tmp2 = load_reg(s, rm);
7771
                    sh = (insn >> 5) & 7;
7772
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7773
                        goto illegal_op;
7774
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7775
                    tcg_temp_free_i32(tmp2);
7776
                    store_reg(s, rd, tmp);
7777
                    break;
7778
                case 1:
7779
                    if ((insn & 0x00700020) == 0) {
7780
                        /* Halfword pack.  */
7781
                        tmp = load_reg(s, rn);
7782
                        tmp2 = load_reg(s, rm);
7783
                        shift = (insn >> 7) & 0x1f;
7784
                        if (insn & (1 << 6)) {
7785
                            /* pkhtb */
7786
                            if (shift == 0)
7787
                                shift = 31;
7788
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
7789
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7790
                            tcg_gen_ext16u_i32(tmp2, tmp2);
7791
                        } else {
7792
                            /* pkhbt */
7793
                            if (shift)
7794
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
7795
                            tcg_gen_ext16u_i32(tmp, tmp);
7796
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7797
                        }
7798
                        tcg_gen_or_i32(tmp, tmp, tmp2);
7799
                        tcg_temp_free_i32(tmp2);
7800
                        store_reg(s, rd, tmp);
7801
                    } else if ((insn & 0x00200020) == 0x00200000) {
7802
                        /* [us]sat */
7803
                        tmp = load_reg(s, rm);
7804
                        shift = (insn >> 7) & 0x1f;
7805
                        if (insn & (1 << 6)) {
7806
                            if (shift == 0)
7807
                                shift = 31;
7808
                            tcg_gen_sari_i32(tmp, tmp, shift);
7809
                        } else {
7810
                            tcg_gen_shli_i32(tmp, tmp, shift);
7811
                        }
7812
                        sh = (insn >> 16) & 0x1f;
7813
                        tmp2 = tcg_const_i32(sh);
7814
                        if (insn & (1 << 22))
7815
                          gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7816
                        else
7817
                          gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7818
                        tcg_temp_free_i32(tmp2);
7819
                        store_reg(s, rd, tmp);
7820
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
7821
                        /* [us]sat16 */
7822
                        tmp = load_reg(s, rm);
7823
                        sh = (insn >> 16) & 0x1f;
7824
                        tmp2 = tcg_const_i32(sh);
7825
                        if (insn & (1 << 22))
7826
                          gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7827
                        else
7828
                          gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7829
                        tcg_temp_free_i32(tmp2);
7830
                        store_reg(s, rd, tmp);
7831
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7832
                        /* Select bytes.  */
7833
                        tmp = load_reg(s, rn);
7834
                        tmp2 = load_reg(s, rm);
7835
                        tmp3 = tcg_temp_new_i32();
7836
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7837
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7838
                        tcg_temp_free_i32(tmp3);
7839
                        tcg_temp_free_i32(tmp2);
7840
                        store_reg(s, rd, tmp);
7841
                    } else if ((insn & 0x000003e0) == 0x00000060) {
7842
                        tmp = load_reg(s, rm);
7843
                        shift = (insn >> 10) & 3;
7844
                        /* ??? In many cases it's not necessary to do a
7845
                           rotate, a shift is sufficient.  */
7846
                        if (shift != 0)
7847
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7848
                        op1 = (insn >> 20) & 7;
7849
                        switch (op1) {
7850
                        case 0: gen_sxtb16(tmp);  break;
7851
                        case 2: gen_sxtb(tmp);    break;
7852
                        case 3: gen_sxth(tmp);    break;
7853
                        case 4: gen_uxtb16(tmp);  break;
7854
                        case 6: gen_uxtb(tmp);    break;
7855
                        case 7: gen_uxth(tmp);    break;
7856
                        default: goto illegal_op;
7857
                        }
7858
                        if (rn != 15) {
7859
                            tmp2 = load_reg(s, rn);
7860
                            if ((op1 & 3) == 0) {
7861
                                gen_add16(tmp, tmp2);
7862
                            } else {
7863
                                tcg_gen_add_i32(tmp, tmp, tmp2);
7864
                                tcg_temp_free_i32(tmp2);
7865
                            }
7866
                        }
7867
                        store_reg(s, rd, tmp);
7868
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7869
                        /* rev */
7870
                        tmp = load_reg(s, rm);
7871
                        if (insn & (1 << 22)) {
7872
                            if (insn & (1 << 7)) {
7873
                                gen_revsh(tmp);
7874
                            } else {
7875
                                ARCH(6T2);
7876
                                gen_helper_rbit(tmp, tmp);
7877
                            }
7878
                        } else {
7879
                            if (insn & (1 << 7))
7880
                                gen_rev16(tmp);
7881
                            else
7882
                                tcg_gen_bswap32_i32(tmp, tmp);
7883
                        }
7884
                        store_reg(s, rd, tmp);
7885
                    } else {
7886
                        goto illegal_op;
7887
                    }
7888
                    break;
7889
                case 2: /* Multiplies (Type 3).  */
7890
                    switch ((insn >> 20) & 0x7) {
7891
                    case 5:
7892
                        if (((insn >> 6) ^ (insn >> 7)) & 1) {
7893
                            /* op2 not 00x or 11x : UNDEF */
7894
                            goto illegal_op;
7895
                        }
7896
                        /* Signed multiply most significant [accumulate].
7897
                           (SMMUL, SMMLA, SMMLS) */
7898
                        tmp = load_reg(s, rm);
7899
                        tmp2 = load_reg(s, rs);
7900
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7901

    
7902
                        if (rd != 15) {
7903
                            tmp = load_reg(s, rd);
7904
                            if (insn & (1 << 6)) {
7905
                                tmp64 = gen_subq_msw(tmp64, tmp);
7906
                            } else {
7907
                                tmp64 = gen_addq_msw(tmp64, tmp);
7908
                            }
7909
                        }
7910
                        if (insn & (1 << 5)) {
7911
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7912
                        }
7913
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
7914
                        tmp = tcg_temp_new_i32();
7915
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
7916
                        tcg_temp_free_i64(tmp64);
7917
                        store_reg(s, rn, tmp);
7918
                        break;
7919
                    case 0:
7920
                    case 4:
7921
                        /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7922
                        if (insn & (1 << 7)) {
7923
                            goto illegal_op;
7924
                        }
7925
                        tmp = load_reg(s, rm);
7926
                        tmp2 = load_reg(s, rs);
7927
                        if (insn & (1 << 5))
7928
                            gen_swap_half(tmp2);
7929
                        gen_smul_dual(tmp, tmp2);
7930
                        if (insn & (1 << 6)) {
7931
                            /* This subtraction cannot overflow. */
7932
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
7933
                        } else {
7934
                            /* This addition cannot overflow 32 bits;
7935
                             * however it may overflow considered as a signed
7936
                             * operation, in which case we must set the Q flag.
7937
                             */
7938
                            gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7939
                        }
7940
                        tcg_temp_free_i32(tmp2);
7941
                        if (insn & (1 << 22)) {
7942
                            /* smlald, smlsld */
7943
                            tmp64 = tcg_temp_new_i64();
7944
                            tcg_gen_ext_i32_i64(tmp64, tmp);
7945
                            tcg_temp_free_i32(tmp);
7946
                            gen_addq(s, tmp64, rd, rn);
7947
                            gen_storeq_reg(s, rd, rn, tmp64);
7948
                            tcg_temp_free_i64(tmp64);
7949
                        } else {
7950
                            /* smuad, smusd, smlad, smlsd */
7951
                            if (rd != 15)
7952
                              {
7953
                                tmp2 = load_reg(s, rd);
7954
                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7955
                                tcg_temp_free_i32(tmp2);
7956
                              }
7957
                            store_reg(s, rn, tmp);
7958
                        }
7959
                        break;
7960
                    case 1:
7961
                    case 3:
7962
                        /* SDIV, UDIV */
7963
                        if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7964
                            goto illegal_op;
7965
                        }
7966
                        if (((insn >> 5) & 7) || (rd != 15)) {
7967
                            goto illegal_op;
7968
                        }
7969
                        tmp = load_reg(s, rm);
7970
                        tmp2 = load_reg(s, rs);
7971
                        if (insn & (1 << 21)) {
7972
                            gen_helper_udiv(tmp, tmp, tmp2);
7973
                        } else {
7974
                            gen_helper_sdiv(tmp, tmp, tmp2);
7975
                        }
7976
                        tcg_temp_free_i32(tmp2);
7977
                        store_reg(s, rn, tmp);
7978
                        break;
7979
                    default:
7980
                        goto illegal_op;
7981
                    }
7982
                    break;
7983
                case 3:
7984
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7985
                    switch (op1) {
7986
                    case 0: /* Unsigned sum of absolute differences.  */
7987
                        ARCH(6);
7988
                        tmp = load_reg(s, rm);
7989
                        tmp2 = load_reg(s, rs);
7990
                        gen_helper_usad8(tmp, tmp, tmp2);
7991
                        tcg_temp_free_i32(tmp2);
7992
                        if (rd != 15) {
7993
                            tmp2 = load_reg(s, rd);
7994
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7995
                            tcg_temp_free_i32(tmp2);
7996
                        }
7997
                        store_reg(s, rn, tmp);
7998
                        break;
7999
                    case 0x20: case 0x24: case 0x28: case 0x2c:
8000
                        /* Bitfield insert/clear.  */
8001
                        ARCH(6T2);
8002
                        shift = (insn >> 7) & 0x1f;
8003
                        i = (insn >> 16) & 0x1f;
8004
                        i = i + 1 - shift;
8005
                        if (rm == 15) {
8006
                            tmp = tcg_temp_new_i32();
8007
                            tcg_gen_movi_i32(tmp, 0);
8008
                        } else {
8009
                            tmp = load_reg(s, rm);
8010
                        }
8011
                        if (i != 32) {
8012
                            tmp2 = load_reg(s, rd);
8013
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8014
                            tcg_temp_free_i32(tmp2);
8015
                        }
8016
                        store_reg(s, rd, tmp);
8017
                        break;
8018
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8019
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8020
                        ARCH(6T2);
8021
                        tmp = load_reg(s, rm);
8022
                        shift = (insn >> 7) & 0x1f;
8023
                        i = ((insn >> 16) & 0x1f) + 1;
8024
                        if (shift + i > 32)
8025
                            goto illegal_op;
8026
                        if (i < 32) {
8027
                            if (op1 & 0x20) {
8028
                                gen_ubfx(tmp, shift, (1u << i) - 1);
8029
                            } else {
8030
                                gen_sbfx(tmp, shift, i);
8031
                            }
8032
                        }
8033
                        store_reg(s, rd, tmp);
8034
                        break;
8035
                    default:
8036
                        goto illegal_op;
8037
                    }
8038
                    break;
8039
                }
8040
                break;
8041
            }
8042
        do_ldst:
8043
            /* Check for undefined extension instructions
8044
             * per the ARM Bible IE:
8045
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
8046
             */
8047
            sh = (0xf << 20) | (0xf << 4);
8048
            if (op1 == 0x7 && ((insn & sh) == sh))
8049
            {
8050
                goto illegal_op;
8051
            }
8052
            /* load/store byte/word */
8053
            rn = (insn >> 16) & 0xf;
8054
            rd = (insn >> 12) & 0xf;
8055
            tmp2 = load_reg(s, rn);
8056
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8057
            if (insn & (1 << 24))
8058
                gen_add_data_offset(s, insn, tmp2);
8059
            if (insn & (1 << 20)) {
8060
                /* load */
8061
                tmp = tcg_temp_new_i32();
8062
                if (insn & (1 << 22)) {
8063
                    gen_aa32_ld8u(tmp, tmp2, i);
8064
                } else {
8065
                    gen_aa32_ld32u(tmp, tmp2, i);
8066
                }
8067
            } else {
8068
                /* store */
8069
                tmp = load_reg(s, rd);
8070
                if (insn & (1 << 22)) {
8071
                    gen_aa32_st8(tmp, tmp2, i);
8072
                } else {
8073
                    gen_aa32_st32(tmp, tmp2, i);
8074
                }
8075
                tcg_temp_free_i32(tmp);
8076
            }
8077
            if (!(insn & (1 << 24))) {
8078
                gen_add_data_offset(s, insn, tmp2);
8079
                store_reg(s, rn, tmp2);
8080
            } else if (insn & (1 << 21)) {
8081
                store_reg(s, rn, tmp2);
8082
            } else {
8083
                tcg_temp_free_i32(tmp2);
8084
            }
8085
            if (insn & (1 << 20)) {
8086
                /* Complete the load.  */
8087
                store_reg_from_load(env, s, rd, tmp);
8088
            }
8089
            break;
8090
        case 0x08:
8091
        case 0x09:
8092
            {
8093
                int j, n, user, loaded_base;
8094
                TCGv_i32 loaded_var;
8095
                /* load/store multiple words */
8096
                /* XXX: store correct base if write back */
8097
                user = 0;
8098
                if (insn & (1 << 22)) {
8099
                    if (IS_USER(s))
8100
                        goto illegal_op; /* only usable in supervisor mode */
8101

    
8102
                    if ((insn & (1 << 15)) == 0)
8103
                        user = 1;
8104
                }
8105
                rn = (insn >> 16) & 0xf;
8106
                addr = load_reg(s, rn);
8107

    
8108
                /* compute total size */
8109
                loaded_base = 0;
8110
                TCGV_UNUSED_I32(loaded_var);
8111
                n = 0;
8112
                for(i=0;i<16;i++) {
8113
                    if (insn & (1 << i))
8114
                        n++;
8115
                }
8116
                /* XXX: test invalid n == 0 case ? */
8117
                if (insn & (1 << 23)) {
8118
                    if (insn & (1 << 24)) {
8119
                        /* pre increment */
8120
                        tcg_gen_addi_i32(addr, addr, 4);
8121
                    } else {
8122
                        /* post increment */
8123
                    }
8124
                } else {
8125
                    if (insn & (1 << 24)) {
8126
                        /* pre decrement */
8127
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
8128
                    } else {
8129
                        /* post decrement */
8130
                        if (n != 1)
8131
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8132
                    }
8133
                }
8134
                j = 0;
8135
                for(i=0;i<16;i++) {
8136
                    if (insn & (1 << i)) {
8137
                        if (insn & (1 << 20)) {
8138
                            /* load */
8139
                            tmp = tcg_temp_new_i32();
8140
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
8141
                            if (user) {
8142
                                tmp2 = tcg_const_i32(i);
8143
                                gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8144
                                tcg_temp_free_i32(tmp2);
8145
                                tcg_temp_free_i32(tmp);
8146
                            } else if (i == rn) {
8147
                                loaded_var = tmp;
8148
                                loaded_base = 1;
8149
                            } else {
8150
                                store_reg_from_load(env, s, i, tmp);
8151
                            }
8152
                        } else {
8153
                            /* store */
8154
                            if (i == 15) {
8155
                                /* special case: r15 = PC + 8 */
8156
                                val = (long)s->pc + 4;
8157
                                tmp = tcg_temp_new_i32();
8158
                                tcg_gen_movi_i32(tmp, val);
8159
                            } else if (user) {
8160
                                tmp = tcg_temp_new_i32();
8161
                                tmp2 = tcg_const_i32(i);
8162
                                gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8163
                                tcg_temp_free_i32(tmp2);
8164
                            } else {
8165
                                tmp = load_reg(s, i);
8166
                            }
8167
                            gen_aa32_st32(tmp, addr, IS_USER(s));
8168
                            tcg_temp_free_i32(tmp);
8169
                        }
8170
                        j++;
8171
                        /* no need to add after the last transfer */
8172
                        if (j != n)
8173
                            tcg_gen_addi_i32(addr, addr, 4);
8174
                    }
8175
                }
8176
                if (insn & (1 << 21)) {
8177
                    /* write back */
8178
                    if (insn & (1 << 23)) {
8179
                        if (insn & (1 << 24)) {
8180
                            /* pre increment */
8181
                        } else {
8182
                            /* post increment */
8183
                            tcg_gen_addi_i32(addr, addr, 4);
8184
                        }
8185
                    } else {
8186
                        if (insn & (1 << 24)) {
8187
                            /* pre decrement */
8188
                            if (n != 1)
8189
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8190
                        } else {
8191
                            /* post decrement */
8192
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
8193
                        }
8194
                    }
8195
                    store_reg(s, rn, addr);
8196
                } else {
8197
                    tcg_temp_free_i32(addr);
8198
                }
8199
                if (loaded_base) {
8200
                    store_reg(s, rn, loaded_var);
8201
                }
8202
                if ((insn & (1 << 22)) && !user) {
8203
                    /* Restore CPSR from SPSR.  */
8204
                    tmp = load_cpu_field(spsr);
8205
                    gen_set_cpsr(tmp, 0xffffffff);
8206
                    tcg_temp_free_i32(tmp);
8207
                    s->is_jmp = DISAS_UPDATE;
8208
                }
8209
            }
8210
            break;
8211
        case 0xa:
8212
        case 0xb:
8213
            {
8214
                int32_t offset;
8215

    
8216
                /* branch (and link) */
8217
                val = (int32_t)s->pc;
8218
                if (insn & (1 << 24)) {
8219
                    tmp = tcg_temp_new_i32();
8220
                    tcg_gen_movi_i32(tmp, val);
8221
                    store_reg(s, 14, tmp);
8222
                }
8223
                offset = sextract32(insn << 2, 0, 26);
8224
                val += offset + 4;
8225
                gen_jmp(s, val);
8226
            }
8227
            break;
8228
        case 0xc:
8229
        case 0xd:
8230
        case 0xe:
8231
            if (((insn >> 8) & 0xe) == 10) {
8232
                /* VFP.  */
8233
                if (disas_vfp_insn(env, s, insn)) {
8234
                    goto illegal_op;
8235
                }
8236
            } else if (disas_coproc_insn(env, s, insn)) {
8237
                /* Coprocessor.  */
8238
                goto illegal_op;
8239
            }
8240
            break;
8241
        case 0xf:
8242
            /* swi */
8243
            gen_set_pc_im(s, s->pc);
8244
            s->is_jmp = DISAS_SWI;
8245
            break;
8246
        default:
8247
        illegal_op:
8248
            gen_exception_insn(s, 4, EXCP_UDEF);
8249
            break;
8250
        }
8251
    }
8252
}
8253

    
8254
/* Return true if this is a Thumb-2 logical op.  */
8255
static int
8256
thumb2_logic_op(int op)
8257
{
8258
    return (op < 8);
8259
}
8260

    
8261
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
8262
   then set condition code flags based on the result of the operation.
8263
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8264
   to the high bit of T1.
8265
   Returns zero if the opcode is valid.  */
8266

    
8267
static int
8268
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8269
                   TCGv_i32 t0, TCGv_i32 t1)
8270
{
8271
    int logic_cc;
8272

    
8273
    logic_cc = 0;
8274
    switch (op) {
8275
    case 0: /* and */
8276
        tcg_gen_and_i32(t0, t0, t1);
8277
        logic_cc = conds;
8278
        break;
8279
    case 1: /* bic */
8280
        tcg_gen_andc_i32(t0, t0, t1);
8281
        logic_cc = conds;
8282
        break;
8283
    case 2: /* orr */
8284
        tcg_gen_or_i32(t0, t0, t1);
8285
        logic_cc = conds;
8286
        break;
8287
    case 3: /* orn */
8288
        tcg_gen_orc_i32(t0, t0, t1);
8289
        logic_cc = conds;
8290
        break;
8291
    case 4: /* eor */
8292
        tcg_gen_xor_i32(t0, t0, t1);
8293
        logic_cc = conds;
8294
        break;
8295
    case 8: /* add */
8296
        if (conds)
8297
            gen_add_CC(t0, t0, t1);
8298
        else
8299
            tcg_gen_add_i32(t0, t0, t1);
8300
        break;
8301
    case 10: /* adc */
8302
        if (conds)
8303
            gen_adc_CC(t0, t0, t1);
8304
        else
8305
            gen_adc(t0, t1);
8306
        break;
8307
    case 11: /* sbc */
8308
        if (conds) {
8309
            gen_sbc_CC(t0, t0, t1);
8310
        } else {
8311
            gen_sub_carry(t0, t0, t1);
8312
        }
8313
        break;
8314
    case 13: /* sub */
8315
        if (conds)
8316
            gen_sub_CC(t0, t0, t1);
8317
        else
8318
            tcg_gen_sub_i32(t0, t0, t1);
8319
        break;
8320
    case 14: /* rsb */
8321
        if (conds)
8322
            gen_sub_CC(t0, t1, t0);
8323
        else
8324
            tcg_gen_sub_i32(t0, t1, t0);
8325
        break;
8326
    default: /* 5, 6, 7, 9, 12, 15. */
8327
        return 1;
8328
    }
8329
    if (logic_cc) {
8330
        gen_logic_CC(t0);
8331
        if (shifter_out)
8332
            gen_set_CF_bit31(t1);
8333
    }
8334
    return 0;
8335
}
8336

    
8337
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
8338
   is not legal.  */
8339
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8340
{
8341
    uint32_t insn, imm, shift, offset;
8342
    uint32_t rd, rn, rm, rs;
8343
    TCGv_i32 tmp;
8344
    TCGv_i32 tmp2;
8345
    TCGv_i32 tmp3;
8346
    TCGv_i32 addr;
8347
    TCGv_i64 tmp64;
8348
    int op;
8349
    int shiftop;
8350
    int conds;
8351
    int logic_cc;
8352

    
8353
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8354
          || arm_feature (env, ARM_FEATURE_M))) {
8355
        /* Thumb-1 cores may need to treat bl and blx as a pair of
8356
           16-bit instructions to get correct prefetch abort behavior.  */
8357
        insn = insn_hw1;
8358
        if ((insn & (1 << 12)) == 0) {
8359
            ARCH(5);
8360
            /* Second half of blx.  */
8361
            offset = ((insn & 0x7ff) << 1);
8362
            tmp = load_reg(s, 14);
8363
            tcg_gen_addi_i32(tmp, tmp, offset);
8364
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8365

    
8366
            tmp2 = tcg_temp_new_i32();
8367
            tcg_gen_movi_i32(tmp2, s->pc | 1);
8368
            store_reg(s, 14, tmp2);
8369
            gen_bx(s, tmp);
8370
            return 0;
8371
        }
8372
        if (insn & (1 << 11)) {
8373
            /* Second half of bl.  */
8374
            offset = ((insn & 0x7ff) << 1) | 1;
8375
            tmp = load_reg(s, 14);
8376
            tcg_gen_addi_i32(tmp, tmp, offset);
8377

    
8378
            tmp2 = tcg_temp_new_i32();
8379
            tcg_gen_movi_i32(tmp2, s->pc | 1);
8380
            store_reg(s, 14, tmp2);
8381
            gen_bx(s, tmp);
8382
            return 0;
8383
        }
8384
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8385
            /* Instruction spans a page boundary.  Implement it as two
8386
               16-bit instructions in case the second half causes an
8387
               prefetch abort.  */
8388
            offset = ((int32_t)insn << 21) >> 9;
8389
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8390
            return 0;
8391
        }
8392
        /* Fall through to 32-bit decode.  */
8393
    }
8394

    
8395
    insn = arm_lduw_code(env, s->pc, s->bswap_code);
8396
    s->pc += 2;
8397
    insn |= (uint32_t)insn_hw1 << 16;
8398

    
8399
    if ((insn & 0xf800e800) != 0xf000e800) {
8400
        ARCH(6T2);
8401
    }
8402

    
8403
    rn = (insn >> 16) & 0xf;
8404
    rs = (insn >> 12) & 0xf;
8405
    rd = (insn >> 8) & 0xf;
8406
    rm = insn & 0xf;
8407
    switch ((insn >> 25) & 0xf) {
8408
    case 0: case 1: case 2: case 3:
8409
        /* 16-bit instructions.  Should never happen.  */
8410
        abort();
8411
    case 4:
8412
        if (insn & (1 << 22)) {
8413
            /* Other load/store, table branch.  */
8414
            if (insn & 0x01200000) {
8415
                /* Load/store doubleword.  */
8416
                if (rn == 15) {
8417
                    addr = tcg_temp_new_i32();
8418
                    tcg_gen_movi_i32(addr, s->pc & ~3);
8419
                } else {
8420
                    addr = load_reg(s, rn);
8421
                }
8422
                offset = (insn & 0xff) * 4;
8423
                if ((insn & (1 << 23)) == 0)
8424
                    offset = -offset;
8425
                if (insn & (1 << 24)) {
8426
                    tcg_gen_addi_i32(addr, addr, offset);
8427
                    offset = 0;
8428
                }
8429
                if (insn & (1 << 20)) {
8430
                    /* ldrd */
8431
                    tmp = tcg_temp_new_i32();
8432
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
8433
                    store_reg(s, rs, tmp);
8434
                    tcg_gen_addi_i32(addr, addr, 4);
8435
                    tmp = tcg_temp_new_i32();
8436
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
8437
                    store_reg(s, rd, tmp);
8438
                } else {
8439
                    /* strd */
8440
                    tmp = load_reg(s, rs);
8441
                    gen_aa32_st32(tmp, addr, IS_USER(s));
8442
                    tcg_temp_free_i32(tmp);
8443
                    tcg_gen_addi_i32(addr, addr, 4);
8444
                    tmp = load_reg(s, rd);
8445
                    gen_aa32_st32(tmp, addr, IS_USER(s));
8446
                    tcg_temp_free_i32(tmp);
8447
                }
8448
                if (insn & (1 << 21)) {
8449
                    /* Base writeback.  */
8450
                    if (rn == 15)
8451
                        goto illegal_op;
8452
                    tcg_gen_addi_i32(addr, addr, offset - 4);
8453
                    store_reg(s, rn, addr);
8454
                } else {
8455
                    tcg_temp_free_i32(addr);
8456
                }
8457
            } else if ((insn & (1 << 23)) == 0) {
8458
                /* Load/store exclusive word.  */
8459
                addr = tcg_temp_local_new_i32();
8460
                load_reg_var(s, addr, rn);
8461
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8462
                if (insn & (1 << 20)) {
8463
                    gen_load_exclusive(s, rs, 15, addr, 2);
8464
                } else {
8465
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
8466
                }
8467
                tcg_temp_free_i32(addr);
8468
            } else if ((insn & (7 << 5)) == 0) {
8469
                /* Table Branch.  */
8470
                if (rn == 15) {
8471
                    addr = tcg_temp_new_i32();
8472
                    tcg_gen_movi_i32(addr, s->pc);
8473
                } else {
8474
                    addr = load_reg(s, rn);
8475
                }
8476
                tmp = load_reg(s, rm);
8477
                tcg_gen_add_i32(addr, addr, tmp);
8478
                if (insn & (1 << 4)) {
8479
                    /* tbh */
8480
                    tcg_gen_add_i32(addr, addr, tmp);
8481
                    tcg_temp_free_i32(tmp);
8482
                    tmp = tcg_temp_new_i32();
8483
                    gen_aa32_ld16u(tmp, addr, IS_USER(s));
8484
                } else { /* tbb */
8485
                    tcg_temp_free_i32(tmp);
8486
                    tmp = tcg_temp_new_i32();
8487
                    gen_aa32_ld8u(tmp, addr, IS_USER(s));
8488
                }
8489
                tcg_temp_free_i32(addr);
8490
                tcg_gen_shli_i32(tmp, tmp, 1);
8491
                tcg_gen_addi_i32(tmp, tmp, s->pc);
8492
                store_reg(s, 15, tmp);
8493
            } else {
8494
                int op2 = (insn >> 6) & 0x3;
8495
                op = (insn >> 4) & 0x3;
8496
                switch (op2) {
8497
                case 0:
8498
                    goto illegal_op;
8499
                case 1:
8500
                    /* Load/store exclusive byte/halfword/doubleword */
8501
                    if (op == 2) {
8502
                        goto illegal_op;
8503
                    }
8504
                    ARCH(7);
8505
                    break;
8506
                case 2:
8507
                    /* Load-acquire/store-release */
8508
                    if (op == 3) {
8509
                        goto illegal_op;
8510
                    }
8511
                    /* Fall through */
8512
                case 3:
8513
                    /* Load-acquire/store-release exclusive */
8514
                    ARCH(8);
8515
                    break;
8516
                }
8517
                addr = tcg_temp_local_new_i32();
8518
                load_reg_var(s, addr, rn);
8519
                if (!(op2 & 1)) {
8520
                    if (insn & (1 << 20)) {
8521
                        tmp = tcg_temp_new_i32();
8522
                        switch (op) {
8523
                        case 0: /* ldab */
8524
                            gen_aa32_ld8u(tmp, addr, IS_USER(s));
8525
                            break;
8526
                        case 1: /* ldah */
8527
                            gen_aa32_ld16u(tmp, addr, IS_USER(s));
8528
                            break;
8529
                        case 2: /* lda */
8530
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
8531
                            break;
8532
                        default:
8533
                            abort();
8534
                        }
8535
                        store_reg(s, rs, tmp);
8536
                    } else {
8537
                        tmp = load_reg(s, rs);
8538
                        switch (op) {
8539
                        case 0: /* stlb */
8540
                            gen_aa32_st8(tmp, addr, IS_USER(s));
8541
                            break;
8542
                        case 1: /* stlh */
8543
                            gen_aa32_st16(tmp, addr, IS_USER(s));
8544
                            break;
8545
                        case 2: /* stl */
8546
                            gen_aa32_st32(tmp, addr, IS_USER(s));
8547
                            break;
8548
                        default:
8549
                            abort();
8550
                        }
8551
                        tcg_temp_free_i32(tmp);
8552
                    }
8553
                } else if (insn & (1 << 20)) {
8554
                    gen_load_exclusive(s, rs, rd, addr, op);
8555
                } else {
8556
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
8557
                }
8558
                tcg_temp_free_i32(addr);
8559
            }
8560
        } else {
8561
            /* Load/store multiple, RFE, SRS.  */
8562
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8563
                /* RFE, SRS: not available in user mode or on M profile */
8564
                if (IS_USER(s) || IS_M(env)) {
8565
                    goto illegal_op;
8566
                }
8567
                if (insn & (1 << 20)) {
8568
                    /* rfe */
8569
                    addr = load_reg(s, rn);
8570
                    if ((insn & (1 << 24)) == 0)
8571
                        tcg_gen_addi_i32(addr, addr, -8);
8572
                    /* Load PC into tmp and CPSR into tmp2.  */
8573
                    tmp = tcg_temp_new_i32();
8574
                    gen_aa32_ld32u(tmp, addr, 0);
8575
                    tcg_gen_addi_i32(addr, addr, 4);
8576
                    tmp2 = tcg_temp_new_i32();
8577
                    gen_aa32_ld32u(tmp2, addr, 0);
8578
                    if (insn & (1 << 21)) {
8579
                        /* Base writeback.  */
8580
                        if (insn & (1 << 24)) {
8581
                            tcg_gen_addi_i32(addr, addr, 4);
8582
                        } else {
8583
                            tcg_gen_addi_i32(addr, addr, -4);
8584
                        }
8585
                        store_reg(s, rn, addr);
8586
                    } else {
8587
                        tcg_temp_free_i32(addr);
8588
                    }
8589
                    gen_rfe(s, tmp, tmp2);
8590
                } else {
8591
                    /* srs */
8592
                    gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8593
                            insn & (1 << 21));
8594
                }
8595
            } else {
8596
                int i, loaded_base = 0;
8597
                TCGv_i32 loaded_var;
8598
                /* Load/store multiple.  */
8599
                addr = load_reg(s, rn);
8600
                offset = 0;
8601
                for (i = 0; i < 16; i++) {
8602
                    if (insn & (1 << i))
8603
                        offset += 4;
8604
                }
8605
                if (insn & (1 << 24)) {
8606
                    tcg_gen_addi_i32(addr, addr, -offset);
8607
                }
8608

    
8609
                TCGV_UNUSED_I32(loaded_var);
8610
                for (i = 0; i < 16; i++) {
8611
                    if ((insn & (1 << i)) == 0)
8612
                        continue;
8613
                    if (insn & (1 << 20)) {
8614
                        /* Load.  */
8615
                        tmp = tcg_temp_new_i32();
8616
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
8617
                        if (i == 15) {
8618
                            gen_bx(s, tmp);
8619
                        } else if (i == rn) {
8620
                            loaded_var = tmp;
8621
                            loaded_base = 1;
8622
                        } else {
8623
                            store_reg(s, i, tmp);
8624
                        }
8625
                    } else {
8626
                        /* Store.  */
8627
                        tmp = load_reg(s, i);
8628
                        gen_aa32_st32(tmp, addr, IS_USER(s));
8629
                        tcg_temp_free_i32(tmp);
8630
                    }
8631
                    tcg_gen_addi_i32(addr, addr, 4);
8632
                }
8633
                if (loaded_base) {
8634
                    store_reg(s, rn, loaded_var);
8635
                }
8636
                if (insn & (1 << 21)) {
8637
                    /* Base register writeback.  */
8638
                    if (insn & (1 << 24)) {
8639
                        tcg_gen_addi_i32(addr, addr, -offset);
8640
                    }
8641
                    /* Fault if writeback register is in register list.  */
8642
                    if (insn & (1 << rn))
8643
                        goto illegal_op;
8644
                    store_reg(s, rn, addr);
8645
                } else {
8646
                    tcg_temp_free_i32(addr);
8647
                }
8648
            }
8649
        }
8650
        break;
8651
    case 5:
8652

    
8653
        op = (insn >> 21) & 0xf;
8654
        if (op == 6) {
8655
            /* Halfword pack.  */
8656
            tmp = load_reg(s, rn);
8657
            tmp2 = load_reg(s, rm);
8658
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8659
            if (insn & (1 << 5)) {
8660
                /* pkhtb */
8661
                if (shift == 0)
8662
                    shift = 31;
8663
                tcg_gen_sari_i32(tmp2, tmp2, shift);
8664
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8665
                tcg_gen_ext16u_i32(tmp2, tmp2);
8666
            } else {
8667
                /* pkhbt */
8668
                if (shift)
8669
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
8670
                tcg_gen_ext16u_i32(tmp, tmp);
8671
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8672
            }
8673
            tcg_gen_or_i32(tmp, tmp, tmp2);
8674
            tcg_temp_free_i32(tmp2);
8675
            store_reg(s, rd, tmp);
8676
        } else {
8677
            /* Data processing register constant shift.  */
8678
            if (rn == 15) {
8679
                tmp = tcg_temp_new_i32();
8680
                tcg_gen_movi_i32(tmp, 0);
8681
            } else {
8682
                tmp = load_reg(s, rn);
8683
            }
8684
            tmp2 = load_reg(s, rm);
8685

    
8686
            shiftop = (insn >> 4) & 3;
8687
            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8688
            conds = (insn & (1 << 20)) != 0;
8689
            logic_cc = (conds && thumb2_logic_op(op));
8690
            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8691
            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8692
                goto illegal_op;
8693
            tcg_temp_free_i32(tmp2);
8694
            if (rd != 15) {
8695
                store_reg(s, rd, tmp);
8696
            } else {
8697
                tcg_temp_free_i32(tmp);
8698
            }
8699
        }
8700
        break;
8701
    case 13: /* Misc data processing.  */
8702
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8703
        if (op < 4 && (insn & 0xf000) != 0xf000)
8704
            goto illegal_op;
8705
        switch (op) {
8706
        case 0: /* Register controlled shift.  */
8707
            tmp = load_reg(s, rn);
8708
            tmp2 = load_reg(s, rm);
8709
            if ((insn & 0x70) != 0)
8710
                goto illegal_op;
8711
            op = (insn >> 21) & 3;
8712
            logic_cc = (insn & (1 << 20)) != 0;
8713
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8714
            if (logic_cc)
8715
                gen_logic_CC(tmp);
8716
            store_reg_bx(env, s, rd, tmp);
8717
            break;
8718
        case 1: /* Sign/zero extend.  */
8719
            tmp = load_reg(s, rm);
8720
            shift = (insn >> 4) & 3;
8721
            /* ??? In many cases it's not necessary to do a
8722
               rotate, a shift is sufficient.  */
8723
            if (shift != 0)
8724
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8725
            op = (insn >> 20) & 7;
8726
            switch (op) {
8727
            case 0: gen_sxth(tmp);   break;
8728
            case 1: gen_uxth(tmp);   break;
8729
            case 2: gen_sxtb16(tmp); break;
8730
            case 3: gen_uxtb16(tmp); break;
8731
            case 4: gen_sxtb(tmp);   break;
8732
            case 5: gen_uxtb(tmp);   break;
8733
            default: goto illegal_op;
8734
            }
8735
            if (rn != 15) {
8736
                tmp2 = load_reg(s, rn);
8737
                if ((op >> 1) == 1) {
8738
                    gen_add16(tmp, tmp2);
8739
                } else {
8740
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8741
                    tcg_temp_free_i32(tmp2);
8742
                }
8743
            }
8744
            store_reg(s, rd, tmp);
8745
            break;
8746
        case 2: /* SIMD add/subtract.  */
8747
            op = (insn >> 20) & 7;
8748
            shift = (insn >> 4) & 7;
8749
            if ((op & 3) == 3 || (shift & 3) == 3)
8750
                goto illegal_op;
8751
            tmp = load_reg(s, rn);
8752
            tmp2 = load_reg(s, rm);
8753
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8754
            tcg_temp_free_i32(tmp2);
8755
            store_reg(s, rd, tmp);
8756
            break;
8757
        case 3: /* Other data processing.  */
8758
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8759
            if (op < 4) {
8760
                /* Saturating add/subtract.  */
8761
                tmp = load_reg(s, rn);
8762
                tmp2 = load_reg(s, rm);
8763
                if (op & 1)
8764
                    gen_helper_double_saturate(tmp, cpu_env, tmp);
8765
                if (op & 2)
8766
                    gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8767
                else
8768
                    gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8769
                tcg_temp_free_i32(tmp2);
8770
            } else {
8771
                tmp = load_reg(s, rn);
8772
                switch (op) {
8773
                case 0x0a: /* rbit */
8774
                    gen_helper_rbit(tmp, tmp);
8775
                    break;
8776
                case 0x08: /* rev */
8777
                    tcg_gen_bswap32_i32(tmp, tmp);
8778
                    break;
8779
                case 0x09: /* rev16 */
8780
                    gen_rev16(tmp);
8781
                    break;
8782
                case 0x0b: /* revsh */
8783
                    gen_revsh(tmp);
8784
                    break;
8785
                case 0x10: /* sel */
8786
                    tmp2 = load_reg(s, rm);
8787
                    tmp3 = tcg_temp_new_i32();
8788
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8789
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8790
                    tcg_temp_free_i32(tmp3);
8791
                    tcg_temp_free_i32(tmp2);
8792
                    break;
8793
                case 0x18: /* clz */
8794
                    gen_helper_clz(tmp, tmp);
8795
                    break;
8796
                default:
8797
                    goto illegal_op;
8798
                }
8799
            }
8800
            store_reg(s, rd, tmp);
8801
            break;
8802
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
8803
            op = (insn >> 4) & 0xf;
8804
            tmp = load_reg(s, rn);
8805
            tmp2 = load_reg(s, rm);
8806
            switch ((insn >> 20) & 7) {
8807
            case 0: /* 32 x 32 -> 32 */
8808
                tcg_gen_mul_i32(tmp, tmp, tmp2);
8809
                tcg_temp_free_i32(tmp2);
8810
                if (rs != 15) {
8811
                    tmp2 = load_reg(s, rs);
8812
                    if (op)
8813
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
8814
                    else
8815
                        tcg_gen_add_i32(tmp, tmp, tmp2);
8816
                    tcg_temp_free_i32(tmp2);
8817
                }
8818
                break;
8819
            case 1: /* 16 x 16 -> 32 */
8820
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
8821
                tcg_temp_free_i32(tmp2);
8822
                if (rs != 15) {
8823
                    tmp2 = load_reg(s, rs);
8824
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8825
                    tcg_temp_free_i32(tmp2);
8826
                }
8827
                break;
8828
            case 2: /* Dual multiply add.  */
8829
            case 4: /* Dual multiply subtract.  */
8830
                if (op)
8831
                    gen_swap_half(tmp2);
8832
                gen_smul_dual(tmp, tmp2);
8833
                if (insn & (1 << 22)) {
8834
                    /* This subtraction cannot overflow. */
8835
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8836
                } else {
8837
                    /* This addition cannot overflow 32 bits;
8838
                     * however it may overflow considered as a signed
8839
                     * operation, in which case we must set the Q flag.
8840
                     */
8841
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8842
                }
8843
                tcg_temp_free_i32(tmp2);
8844
                if (rs != 15)
8845
                  {
8846
                    tmp2 = load_reg(s, rs);
8847
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8848
                    tcg_temp_free_i32(tmp2);
8849
                  }
8850
                break;
8851
            case 3: /* 32 * 16 -> 32msb */
8852
                if (op)
8853
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
8854
                else
8855
                    gen_sxth(tmp2);
8856
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
8857
                tcg_gen_shri_i64(tmp64, tmp64, 16);
8858
                tmp = tcg_temp_new_i32();
8859
                tcg_gen_trunc_i64_i32(tmp, tmp64);
8860
                tcg_temp_free_i64(tmp64);
8861
                if (rs != 15)
8862
                  {
8863
                    tmp2 = load_reg(s, rs);
8864
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8865
                    tcg_temp_free_i32(tmp2);
8866
                  }
8867
                break;
8868
            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8869
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
8870
                if (rs != 15) {
8871
                    tmp = load_reg(s, rs);
8872
                    if (insn & (1 << 20)) {
8873
                        tmp64 = gen_addq_msw(tmp64, tmp);
8874
                    } else {
8875
                        tmp64 = gen_subq_msw(tmp64, tmp);
8876
                    }
8877
                }
8878
                if (insn & (1 << 4)) {
8879
                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8880
                }
8881
                tcg_gen_shri_i64(tmp64, tmp64, 32);
8882
                tmp = tcg_temp_new_i32();
8883
                tcg_gen_trunc_i64_i32(tmp, tmp64);
8884
                tcg_temp_free_i64(tmp64);
8885
                break;
8886
            case 7: /* Unsigned sum of absolute differences.  */
8887
                gen_helper_usad8(tmp, tmp, tmp2);
8888
                tcg_temp_free_i32(tmp2);
8889
                if (rs != 15) {
8890
                    tmp2 = load_reg(s, rs);
8891
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8892
                    tcg_temp_free_i32(tmp2);
8893
                }
8894
                break;
8895
            }
8896
            store_reg(s, rd, tmp);
8897
            break;
8898
        case 6: case 7: /* 64-bit multiply, Divide.  */
8899
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8900
            tmp = load_reg(s, rn);
8901
            tmp2 = load_reg(s, rm);
8902
            if ((op & 0x50) == 0x10) {
8903
                /* sdiv, udiv */
8904
                if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8905
                    goto illegal_op;
8906
                }
8907
                if (op & 0x20)
8908
                    gen_helper_udiv(tmp, tmp, tmp2);
8909
                else
8910
                    gen_helper_sdiv(tmp, tmp, tmp2);
8911
                tcg_temp_free_i32(tmp2);
8912
                store_reg(s, rd, tmp);
8913
            } else if ((op & 0xe) == 0xc) {
8914
                /* Dual multiply accumulate long.  */
8915
                if (op & 1)
8916
                    gen_swap_half(tmp2);
8917
                gen_smul_dual(tmp, tmp2);
8918
                if (op & 0x10) {
8919
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8920
                } else {
8921
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8922
                }
8923
                tcg_temp_free_i32(tmp2);
8924
                /* BUGFIX */
8925
                tmp64 = tcg_temp_new_i64();
8926
                tcg_gen_ext_i32_i64(tmp64, tmp);
8927
                tcg_temp_free_i32(tmp);
8928
                gen_addq(s, tmp64, rs, rd);
8929
                gen_storeq_reg(s, rs, rd, tmp64);
8930
                tcg_temp_free_i64(tmp64);
8931
            } else {
8932
                if (op & 0x20) {
8933
                    /* Unsigned 64-bit multiply  */
8934
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8935
                } else {
8936
                    if (op & 8) {
8937
                        /* smlalxy */
8938
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
8939
                        tcg_temp_free_i32(tmp2);
8940
                        tmp64 = tcg_temp_new_i64();
8941
                        tcg_gen_ext_i32_i64(tmp64, tmp);
8942
                        tcg_temp_free_i32(tmp);
8943
                    } else {
8944
                        /* Signed 64-bit multiply  */
8945
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
8946
                    }
8947
                }
8948
                if (op & 4) {
8949
                    /* umaal */
8950
                    gen_addq_lo(s, tmp64, rs);
8951
                    gen_addq_lo(s, tmp64, rd);
8952
                } else if (op & 0x40) {
8953
                    /* 64-bit accumulate.  */
8954
                    gen_addq(s, tmp64, rs, rd);
8955
                }
8956
                gen_storeq_reg(s, rs, rd, tmp64);
8957
                tcg_temp_free_i64(tmp64);
8958
            }
8959
            break;
8960
        }
8961
        break;
8962
    case 6: case 7: case 14: case 15:
8963
        /* Coprocessor.  */
8964
        if (((insn >> 24) & 3) == 3) {
8965
            /* Translate into the equivalent ARM encoding.  */
8966
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8967
            if (disas_neon_data_insn(env, s, insn))
8968
                goto illegal_op;
8969
        } else if (((insn >> 8) & 0xe) == 10) {
8970
            if (disas_vfp_insn(env, s, insn)) {
8971
                goto illegal_op;
8972
            }
8973
        } else {
8974
            if (insn & (1 << 28))
8975
                goto illegal_op;
8976
            if (disas_coproc_insn (env, s, insn))
8977
                goto illegal_op;
8978
        }
8979
        break;
8980
    case 8: case 9: case 10: case 11:
8981
        if (insn & (1 << 15)) {
8982
            /* Branches, misc control.  */
8983
            if (insn & 0x5000) {
8984
                /* Unconditional branch.  */
8985
                /* signextend(hw1[10:0]) -> offset[:12].  */
8986
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8987
                /* hw1[10:0] -> offset[11:1].  */
8988
                offset |= (insn & 0x7ff) << 1;
8989
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8990
                   offset[24:22] already have the same value because of the
8991
                   sign extension above.  */
8992
                offset ^= ((~insn) & (1 << 13)) << 10;
8993
                offset ^= ((~insn) & (1 << 11)) << 11;
8994

    
8995
                if (insn & (1 << 14)) {
8996
                    /* Branch and link.  */
8997
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8998
                }
8999

    
9000
                offset += s->pc;
9001
                if (insn & (1 << 12)) {
9002
                    /* b/bl */
9003
                    gen_jmp(s, offset);
9004
                } else {
9005
                    /* blx */
9006
                    offset &= ~(uint32_t)2;
9007
                    /* thumb2 bx, no need to check */
9008
                    gen_bx_im(s, offset);
9009
                }
9010
            } else if (((insn >> 23) & 7) == 7) {
9011
                /* Misc control */
9012
                if (insn & (1 << 13))
9013
                    goto illegal_op;
9014

    
9015
                if (insn & (1 << 26)) {
9016
                    /* Secure monitor call (v6Z) */
9017
                    qemu_log_mask(LOG_UNIMP,
9018
                                  "arm: unimplemented secure monitor call\n");
9019
                    goto illegal_op; /* not implemented.  */
9020
                } else {
9021
                    op = (insn >> 20) & 7;
9022
                    switch (op) {
9023
                    case 0: /* msr cpsr.  */
9024
                        if (IS_M(env)) {
9025
                            tmp = load_reg(s, rn);
9026
                            addr = tcg_const_i32(insn & 0xff);
9027
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
9028
                            tcg_temp_free_i32(addr);
9029
                            tcg_temp_free_i32(tmp);
9030
                            gen_lookup_tb(s);
9031
                            break;
9032
                        }
9033
                        /* fall through */
9034
                    case 1: /* msr spsr.  */
9035
                        if (IS_M(env))
9036
                            goto illegal_op;
9037
                        tmp = load_reg(s, rn);
9038
                        if (gen_set_psr(s,
9039
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9040
                              op == 1, tmp))
9041
                            goto illegal_op;
9042
                        break;
9043
                    case 2: /* cps, nop-hint.  */
9044
                        if (((insn >> 8) & 7) == 0) {
9045
                            gen_nop_hint(s, insn & 0xff);
9046
                        }
9047
                        /* Implemented as NOP in user mode.  */
9048
                        if (IS_USER(s))
9049
                            break;
9050
                        offset = 0;
9051
                        imm = 0;
9052
                        if (insn & (1 << 10)) {
9053
                            if (insn & (1 << 7))
9054
                                offset |= CPSR_A;
9055
                            if (insn & (1 << 6))
9056
                                offset |= CPSR_I;
9057
                            if (insn & (1 << 5))
9058
                                offset |= CPSR_F;
9059
                            if (insn & (1 << 9))
9060
                                imm = CPSR_A | CPSR_I | CPSR_F;
9061
                        }
9062
                        if (insn & (1 << 8)) {
9063
                            offset |= 0x1f;
9064
                            imm |= (insn & 0x1f);
9065
                        }
9066
                        if (offset) {
9067
                            gen_set_psr_im(s, offset, 0, imm);
9068
                        }
9069
                        break;
9070
                    case 3: /* Special control operations.  */
9071
                        ARCH(7);
9072
                        op = (insn >> 4) & 0xf;
9073
                        switch (op) {
9074
                        case 2: /* clrex */
9075
                            gen_clrex(s);
9076
                            break;
9077
                        case 4: /* dsb */
9078
                        case 5: /* dmb */
9079
                        case 6: /* isb */
9080
                            /* These execute as NOPs.  */
9081
                            break;
9082
                        default:
9083
                            goto illegal_op;
9084
                        }
9085
                        break;
9086
                    case 4: /* bxj */
9087
                        /* Trivial implementation equivalent to bx.  */
9088
                        tmp = load_reg(s, rn);
9089
                        gen_bx(s, tmp);
9090
                        break;
9091
                    case 5: /* Exception return.  */
9092
                        if (IS_USER(s)) {
9093
                            goto illegal_op;
9094
                        }
9095
                        if (rn != 14 || rd != 15) {
9096
                            goto illegal_op;
9097
                        }
9098
                        tmp = load_reg(s, rn);
9099
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9100
                        gen_exception_return(s, tmp);
9101
                        break;
9102
                    case 6: /* mrs cpsr.  */
9103
                        tmp = tcg_temp_new_i32();
9104
                        if (IS_M(env)) {
9105
                            addr = tcg_const_i32(insn & 0xff);
9106
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
9107
                            tcg_temp_free_i32(addr);
9108
                        } else {
9109
                            gen_helper_cpsr_read(tmp, cpu_env);
9110
                        }
9111
                        store_reg(s, rd, tmp);
9112
                        break;
9113
                    case 7: /* mrs spsr.  */
9114
                        /* Not accessible in user mode.  */
9115
                        if (IS_USER(s) || IS_M(env))
9116
                            goto illegal_op;
9117
                        tmp = load_cpu_field(spsr);
9118
                        store_reg(s, rd, tmp);
9119
                        break;
9120
                    }
9121
                }
9122
            } else {
9123
                /* Conditional branch.  */
9124
                op = (insn >> 22) & 0xf;
9125
                /* Generate a conditional jump to next instruction.  */
9126
                s->condlabel = gen_new_label();
9127
                gen_test_cc(op ^ 1, s->condlabel);
9128
                s->condjmp = 1;
9129

    
9130
                /* offset[11:1] = insn[10:0] */
9131
                offset = (insn & 0x7ff) << 1;
9132
                /* offset[17:12] = insn[21:16].  */
9133
                offset |= (insn & 0x003f0000) >> 4;
9134
                /* offset[31:20] = insn[26].  */
9135
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9136
                /* offset[18] = insn[13].  */
9137
                offset |= (insn & (1 << 13)) << 5;
9138
                /* offset[19] = insn[11].  */
9139
                offset |= (insn & (1 << 11)) << 8;
9140

    
9141
                /* jump to the offset */
9142
                gen_jmp(s, s->pc + offset);
9143
            }
9144
        } else {
9145
            /* Data processing immediate.  */
9146
            if (insn & (1 << 25)) {
9147
                if (insn & (1 << 24)) {
9148
                    if (insn & (1 << 20))
9149
                        goto illegal_op;
9150
                    /* Bitfield/Saturate.  */
9151
                    op = (insn >> 21) & 7;
9152
                    imm = insn & 0x1f;
9153
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9154
                    if (rn == 15) {
9155
                        tmp = tcg_temp_new_i32();
9156
                        tcg_gen_movi_i32(tmp, 0);
9157
                    } else {
9158
                        tmp = load_reg(s, rn);
9159
                    }
9160
                    switch (op) {
9161
                    case 2: /* Signed bitfield extract.  */
9162
                        imm++;
9163
                        if (shift + imm > 32)
9164
                            goto illegal_op;
9165
                        if (imm < 32)
9166
                            gen_sbfx(tmp, shift, imm);
9167
                        break;
9168
                    case 6: /* Unsigned bitfield extract.  */
9169
                        imm++;
9170
                        if (shift + imm > 32)
9171
                            goto illegal_op;
9172
                        if (imm < 32)
9173
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
9174
                        break;
9175
                    case 3: /* Bitfield insert/clear.  */
9176
                        if (imm < shift)
9177
                            goto illegal_op;
9178
                        imm = imm + 1 - shift;
9179
                        if (imm != 32) {
9180
                            tmp2 = load_reg(s, rd);
9181
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9182
                            tcg_temp_free_i32(tmp2);
9183
                        }
9184
                        break;
9185
                    case 7:
9186
                        goto illegal_op;
9187
                    default: /* Saturate.  */
9188
                        if (shift) {
9189
                            if (op & 1)
9190
                                tcg_gen_sari_i32(tmp, tmp, shift);
9191
                            else
9192
                                tcg_gen_shli_i32(tmp, tmp, shift);
9193
                        }
9194
                        tmp2 = tcg_const_i32(imm);
9195
                        if (op & 4) {
9196
                            /* Unsigned.  */
9197
                            if ((op & 1) && shift == 0)
9198
                                gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9199
                            else
9200
                                gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9201
                        } else {
9202
                            /* Signed.  */
9203
                            if ((op & 1) && shift == 0)
9204
                                gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9205
                            else
9206
                                gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9207
                        }
9208
                        tcg_temp_free_i32(tmp2);
9209
                        break;
9210
                    }
9211
                    store_reg(s, rd, tmp);
9212
                } else {
9213
                    imm = ((insn & 0x04000000) >> 15)
9214
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
9215
                    if (insn & (1 << 22)) {
9216
                        /* 16-bit immediate.  */
9217
                        imm |= (insn >> 4) & 0xf000;
9218
                        if (insn & (1 << 23)) {
9219
                            /* movt */
9220
                            tmp = load_reg(s, rd);
9221
                            tcg_gen_ext16u_i32(tmp, tmp);
9222
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
9223
                        } else {
9224
                            /* movw */
9225
                            tmp = tcg_temp_new_i32();
9226
                            tcg_gen_movi_i32(tmp, imm);
9227
                        }
9228
                    } else {
9229
                        /* Add/sub 12-bit immediate.  */
9230
                        if (rn == 15) {
9231
                            offset = s->pc & ~(uint32_t)3;
9232
                            if (insn & (1 << 23))
9233
                                offset -= imm;
9234
                            else
9235
                                offset += imm;
9236
                            tmp = tcg_temp_new_i32();
9237
                            tcg_gen_movi_i32(tmp, offset);
9238
                        } else {
9239
                            tmp = load_reg(s, rn);
9240
                            if (insn & (1 << 23))
9241
                                tcg_gen_subi_i32(tmp, tmp, imm);
9242
                            else
9243
                                tcg_gen_addi_i32(tmp, tmp, imm);
9244
                        }
9245
                    }
9246
                    store_reg(s, rd, tmp);
9247
                }
9248
            } else {
9249
                int shifter_out = 0;
9250
                /* modified 12-bit immediate.  */
9251
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9252
                imm = (insn & 0xff);
9253
                switch (shift) {
9254
                case 0: /* XY */
9255
                    /* Nothing to do.  */
9256
                    break;
9257
                case 1: /* 00XY00XY */
9258
                    imm |= imm << 16;
9259
                    break;
9260
                case 2: /* XY00XY00 */
9261
                    imm |= imm << 16;
9262
                    imm <<= 8;
9263
                    break;
9264
                case 3: /* XYXYXYXY */
9265
                    imm |= imm << 16;
9266
                    imm |= imm << 8;
9267
                    break;
9268
                default: /* Rotated constant.  */
9269
                    shift = (shift << 1) | (imm >> 7);
9270
                    imm |= 0x80;
9271
                    imm = imm << (32 - shift);
9272
                    shifter_out = 1;
9273
                    break;
9274
                }
9275
                tmp2 = tcg_temp_new_i32();
9276
                tcg_gen_movi_i32(tmp2, imm);
9277
                rn = (insn >> 16) & 0xf;
9278
                if (rn == 15) {
9279
                    tmp = tcg_temp_new_i32();
9280
                    tcg_gen_movi_i32(tmp, 0);
9281
                } else {
9282
                    tmp = load_reg(s, rn);
9283
                }
9284
                op = (insn >> 21) & 0xf;
9285
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9286
                                       shifter_out, tmp, tmp2))
9287
                    goto illegal_op;
9288
                tcg_temp_free_i32(tmp2);
9289
                rd = (insn >> 8) & 0xf;
9290
                if (rd != 15) {
9291
                    store_reg(s, rd, tmp);
9292
                } else {
9293
                    tcg_temp_free_i32(tmp);
9294
                }
9295
            }
9296
        }
9297
        break;
9298
    case 12: /* Load/store single data item.  */
9299
        {
9300
        int postinc = 0;
9301
        int writeback = 0;
9302
        int user;
9303
        if ((insn & 0x01100000) == 0x01000000) {
9304
            if (disas_neon_ls_insn(env, s, insn))
9305
                goto illegal_op;
9306
            break;
9307
        }
9308
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9309
        if (rs == 15) {
9310
            if (!(insn & (1 << 20))) {
9311
                goto illegal_op;
9312
            }
9313
            if (op != 2) {
9314
                /* Byte or halfword load space with dest == r15 : memory hints.
9315
                 * Catch them early so we don't emit pointless addressing code.
9316
                 * This space is a mix of:
9317
                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
9318
                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9319
                 *     cores)
9320
                 *  unallocated hints, which must be treated as NOPs
9321
                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
9322
                 *     which is easiest for the decoding logic
9323
                 *  Some space which must UNDEF
9324
                 */
9325
                int op1 = (insn >> 23) & 3;
9326
                int op2 = (insn >> 6) & 0x3f;
9327
                if (op & 2) {
9328
                    goto illegal_op;
9329
                }
9330
                if (rn == 15) {
9331
                    /* UNPREDICTABLE, unallocated hint or
9332
                     * PLD/PLDW/PLI (literal)
9333
                     */
9334
                    return 0;
9335
                }
9336
                if (op1 & 1) {
9337
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
9338
                }
9339
                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9340
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
9341
                }
9342
                /* UNDEF space, or an UNPREDICTABLE */
9343
                return 1;
9344
            }
9345
        }
9346
        user = IS_USER(s);
9347
        if (rn == 15) {
9348
            addr = tcg_temp_new_i32();
9349
            /* PC relative.  */
9350
            /* s->pc has already been incremented by 4.  */
9351
            imm = s->pc & 0xfffffffc;
9352
            if (insn & (1 << 23))
9353
                imm += insn & 0xfff;
9354
            else
9355
                imm -= insn & 0xfff;
9356
            tcg_gen_movi_i32(addr, imm);
9357
        } else {
9358
            addr = load_reg(s, rn);
9359
            if (insn & (1 << 23)) {
9360
                /* Positive offset.  */
9361
                imm = insn & 0xfff;
9362
                tcg_gen_addi_i32(addr, addr, imm);
9363
            } else {
9364
                imm = insn & 0xff;
9365
                switch ((insn >> 8) & 0xf) {
9366
                case 0x0: /* Shifted Register.  */
9367
                    shift = (insn >> 4) & 0xf;
9368
                    if (shift > 3) {
9369
                        tcg_temp_free_i32(addr);
9370
                        goto illegal_op;
9371
                    }
9372
                    tmp = load_reg(s, rm);
9373
                    if (shift)
9374
                        tcg_gen_shli_i32(tmp, tmp, shift);
9375
                    tcg_gen_add_i32(addr, addr, tmp);
9376
                    tcg_temp_free_i32(tmp);
9377
                    break;
9378
                case 0xc: /* Negative offset.  */
9379
                    tcg_gen_addi_i32(addr, addr, -imm);
9380
                    break;
9381
                case 0xe: /* User privilege.  */
9382
                    tcg_gen_addi_i32(addr, addr, imm);
9383
                    user = 1;
9384
                    break;
9385
                case 0x9: /* Post-decrement.  */
9386
                    imm = -imm;
9387
                    /* Fall through.  */
9388
                case 0xb: /* Post-increment.  */
9389
                    postinc = 1;
9390
                    writeback = 1;
9391
                    break;
9392
                case 0xd: /* Pre-decrement.  */
9393
                    imm = -imm;
9394
                    /* Fall through.  */
9395
                case 0xf: /* Pre-increment.  */
9396
                    tcg_gen_addi_i32(addr, addr, imm);
9397
                    writeback = 1;
9398
                    break;
9399
                default:
9400
                    tcg_temp_free_i32(addr);
9401
                    goto illegal_op;
9402
                }
9403
            }
9404
        }
9405
        if (insn & (1 << 20)) {
9406
            /* Load.  */
9407
            tmp = tcg_temp_new_i32();
9408
            switch (op) {
9409
            case 0:
9410
                gen_aa32_ld8u(tmp, addr, user);
9411
                break;
9412
            case 4:
9413
                gen_aa32_ld8s(tmp, addr, user);
9414
                break;
9415
            case 1:
9416
                gen_aa32_ld16u(tmp, addr, user);
9417
                break;
9418
            case 5:
9419
                gen_aa32_ld16s(tmp, addr, user);
9420
                break;
9421
            case 2:
9422
                gen_aa32_ld32u(tmp, addr, user);
9423
                break;
9424
            default:
9425
                tcg_temp_free_i32(tmp);
9426
                tcg_temp_free_i32(addr);
9427
                goto illegal_op;
9428
            }
9429
            if (rs == 15) {
9430
                gen_bx(s, tmp);
9431
            } else {
9432
                store_reg(s, rs, tmp);
9433
            }
9434
        } else {
9435
            /* Store.  */
9436
            tmp = load_reg(s, rs);
9437
            switch (op) {
9438
            case 0:
9439
                gen_aa32_st8(tmp, addr, user);
9440
                break;
9441
            case 1:
9442
                gen_aa32_st16(tmp, addr, user);
9443
                break;
9444
            case 2:
9445
                gen_aa32_st32(tmp, addr, user);
9446
                break;
9447
            default:
9448
                tcg_temp_free_i32(tmp);
9449
                tcg_temp_free_i32(addr);
9450
                goto illegal_op;
9451
            }
9452
            tcg_temp_free_i32(tmp);
9453
        }
9454
        if (postinc)
9455
            tcg_gen_addi_i32(addr, addr, imm);
9456
        if (writeback) {
9457
            store_reg(s, rn, addr);
9458
        } else {
9459
            tcg_temp_free_i32(addr);
9460
        }
9461
        }
9462
        break;
9463
    default:
9464
        goto illegal_op;
9465
    }
9466
    return 0;
9467
illegal_op:
9468
    return 1;
9469
}
9470

    
9471
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9472
{
9473
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
9474
    int32_t offset;
9475
    int i;
9476
    TCGv_i32 tmp;
9477
    TCGv_i32 tmp2;
9478
    TCGv_i32 addr;
9479

    
9480
    if (s->condexec_mask) {
9481
        cond = s->condexec_cond;
9482
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
9483
          s->condlabel = gen_new_label();
9484
          gen_test_cc(cond ^ 1, s->condlabel);
9485
          s->condjmp = 1;
9486
        }
9487
    }
9488

    
9489
    insn = arm_lduw_code(env, s->pc, s->bswap_code);
9490
    s->pc += 2;
9491

    
9492
    switch (insn >> 12) {
9493
    case 0: case 1:
9494

    
9495
        rd = insn & 7;
9496
        op = (insn >> 11) & 3;
9497
        if (op == 3) {
9498
            /* add/subtract */
9499
            rn = (insn >> 3) & 7;
9500
            tmp = load_reg(s, rn);
9501
            if (insn & (1 << 10)) {
9502
                /* immediate */
9503
                tmp2 = tcg_temp_new_i32();
9504
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9505
            } else {
9506
                /* reg */
9507
                rm = (insn >> 6) & 7;
9508
                tmp2 = load_reg(s, rm);
9509
            }
9510
            if (insn & (1 << 9)) {
9511
                if (s->condexec_mask)
9512
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9513
                else
9514
                    gen_sub_CC(tmp, tmp, tmp2);
9515
            } else {
9516
                if (s->condexec_mask)
9517
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9518
                else
9519
                    gen_add_CC(tmp, tmp, tmp2);
9520
            }
9521
            tcg_temp_free_i32(tmp2);
9522
            store_reg(s, rd, tmp);
9523
        } else {
9524
            /* shift immediate */
9525
            rm = (insn >> 3) & 7;
9526
            shift = (insn >> 6) & 0x1f;
9527
            tmp = load_reg(s, rm);
9528
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9529
            if (!s->condexec_mask)
9530
                gen_logic_CC(tmp);
9531
            store_reg(s, rd, tmp);
9532
        }
9533
        break;
9534
    case 2: case 3:
9535
        /* arithmetic large immediate */
9536
        op = (insn >> 11) & 3;
9537
        rd = (insn >> 8) & 0x7;
9538
        if (op == 0) { /* mov */
9539
            tmp = tcg_temp_new_i32();
9540
            tcg_gen_movi_i32(tmp, insn & 0xff);
9541
            if (!s->condexec_mask)
9542
                gen_logic_CC(tmp);
9543
            store_reg(s, rd, tmp);
9544
        } else {
9545
            tmp = load_reg(s, rd);
9546
            tmp2 = tcg_temp_new_i32();
9547
            tcg_gen_movi_i32(tmp2, insn & 0xff);
9548
            switch (op) {
9549
            case 1: /* cmp */
9550
                gen_sub_CC(tmp, tmp, tmp2);
9551
                tcg_temp_free_i32(tmp);
9552
                tcg_temp_free_i32(tmp2);
9553
                break;
9554
            case 2: /* add */
9555
                if (s->condexec_mask)
9556
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9557
                else
9558
                    gen_add_CC(tmp, tmp, tmp2);
9559
                tcg_temp_free_i32(tmp2);
9560
                store_reg(s, rd, tmp);
9561
                break;
9562
            case 3: /* sub */
9563
                if (s->condexec_mask)
9564
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9565
                else
9566
                    gen_sub_CC(tmp, tmp, tmp2);
9567
                tcg_temp_free_i32(tmp2);
9568
                store_reg(s, rd, tmp);
9569
                break;
9570
            }
9571
        }
9572
        break;
9573
    case 4:
9574
        if (insn & (1 << 11)) {
9575
            rd = (insn >> 8) & 7;
9576
            /* load pc-relative.  Bit 1 of PC is ignored.  */
9577
            val = s->pc + 2 + ((insn & 0xff) * 4);
9578
            val &= ~(uint32_t)2;
9579
            addr = tcg_temp_new_i32();
9580
            tcg_gen_movi_i32(addr, val);
9581
            tmp = tcg_temp_new_i32();
9582
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
9583
            tcg_temp_free_i32(addr);
9584
            store_reg(s, rd, tmp);
9585
            break;
9586
        }
9587
        if (insn & (1 << 10)) {
9588
            /* data processing extended or blx */
9589
            rd = (insn & 7) | ((insn >> 4) & 8);
9590
            rm = (insn >> 3) & 0xf;
9591
            op = (insn >> 8) & 3;
9592
            switch (op) {
9593
            case 0: /* add */
9594
                tmp = load_reg(s, rd);
9595
                tmp2 = load_reg(s, rm);
9596
                tcg_gen_add_i32(tmp, tmp, tmp2);
9597
                tcg_temp_free_i32(tmp2);
9598
                store_reg(s, rd, tmp);
9599
                break;
9600
            case 1: /* cmp */
9601
                tmp = load_reg(s, rd);
9602
                tmp2 = load_reg(s, rm);
9603
                gen_sub_CC(tmp, tmp, tmp2);
9604
                tcg_temp_free_i32(tmp2);
9605
                tcg_temp_free_i32(tmp);
9606
                break;
9607
            case 2: /* mov/cpy */
9608
                tmp = load_reg(s, rm);
9609
                store_reg(s, rd, tmp);
9610
                break;
9611
            case 3:/* branch [and link] exchange thumb register */
9612
                tmp = load_reg(s, rm);
9613
                if (insn & (1 << 7)) {
9614
                    ARCH(5);
9615
                    val = (uint32_t)s->pc | 1;
9616
                    tmp2 = tcg_temp_new_i32();
9617
                    tcg_gen_movi_i32(tmp2, val);
9618
                    store_reg(s, 14, tmp2);
9619
                }
9620
                /* already thumb, no need to check */
9621
                gen_bx(s, tmp);
9622
                break;
9623
            }
9624
            break;
9625
        }
9626

    
9627
        /* data processing register */
9628
        rd = insn & 7;
9629
        rm = (insn >> 3) & 7;
9630
        op = (insn >> 6) & 0xf;
9631
        if (op == 2 || op == 3 || op == 4 || op == 7) {
9632
            /* the shift/rotate ops want the operands backwards */
9633
            val = rm;
9634
            rm = rd;
9635
            rd = val;
9636
            val = 1;
9637
        } else {
9638
            val = 0;
9639
        }
9640

    
9641
        if (op == 9) { /* neg */
9642
            tmp = tcg_temp_new_i32();
9643
            tcg_gen_movi_i32(tmp, 0);
9644
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
9645
            tmp = load_reg(s, rd);
9646
        } else {
9647
            TCGV_UNUSED_I32(tmp);
9648
        }
9649

    
9650
        tmp2 = load_reg(s, rm);
9651
        switch (op) {
9652
        case 0x0: /* and */
9653
            tcg_gen_and_i32(tmp, tmp, tmp2);
9654
            if (!s->condexec_mask)
9655
                gen_logic_CC(tmp);
9656
            break;
9657
        case 0x1: /* eor */
9658
            tcg_gen_xor_i32(tmp, tmp, tmp2);
9659
            if (!s->condexec_mask)
9660
                gen_logic_CC(tmp);
9661
            break;
9662
        case 0x2: /* lsl */
9663
            if (s->condexec_mask) {
9664
                gen_shl(tmp2, tmp2, tmp);
9665
            } else {
9666
                gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9667
                gen_logic_CC(tmp2);
9668
            }
9669
            break;
9670
        case 0x3: /* lsr */
9671
            if (s->condexec_mask) {
9672
                gen_shr(tmp2, tmp2, tmp);
9673
            } else {
9674
                gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9675
                gen_logic_CC(tmp2);
9676
            }
9677
            break;
9678
        case 0x4: /* asr */
9679
            if (s->condexec_mask) {
9680
                gen_sar(tmp2, tmp2, tmp);
9681
            } else {
9682
                gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9683
                gen_logic_CC(tmp2);
9684
            }
9685
            break;
9686
        case 0x5: /* adc */
9687
            if (s->condexec_mask) {
9688
                gen_adc(tmp, tmp2);
9689
            } else {
9690
                gen_adc_CC(tmp, tmp, tmp2);
9691
            }
9692
            break;
9693
        case 0x6: /* sbc */
9694
            if (s->condexec_mask) {
9695
                gen_sub_carry(tmp, tmp, tmp2);
9696
            } else {
9697
                gen_sbc_CC(tmp, tmp, tmp2);
9698
            }
9699
            break;
9700
        case 0x7: /* ror */
9701
            if (s->condexec_mask) {
9702
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
9703
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9704
            } else {
9705
                gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9706
                gen_logic_CC(tmp2);
9707
            }
9708
            break;
9709
        case 0x8: /* tst */
9710
            tcg_gen_and_i32(tmp, tmp, tmp2);
9711
            gen_logic_CC(tmp);
9712
            rd = 16;
9713
            break;
9714
        case 0x9: /* neg */
9715
            if (s->condexec_mask)
9716
                tcg_gen_neg_i32(tmp, tmp2);
9717
            else
9718
                gen_sub_CC(tmp, tmp, tmp2);
9719
            break;
9720
        case 0xa: /* cmp */
9721
            gen_sub_CC(tmp, tmp, tmp2);
9722
            rd = 16;
9723
            break;
9724
        case 0xb: /* cmn */
9725
            gen_add_CC(tmp, tmp, tmp2);
9726
            rd = 16;
9727
            break;
9728
        case 0xc: /* orr */
9729
            tcg_gen_or_i32(tmp, tmp, tmp2);
9730
            if (!s->condexec_mask)
9731
                gen_logic_CC(tmp);
9732
            break;
9733
        case 0xd: /* mul */
9734
            tcg_gen_mul_i32(tmp, tmp, tmp2);
9735
            if (!s->condexec_mask)
9736
                gen_logic_CC(tmp);
9737
            break;
9738
        case 0xe: /* bic */
9739
            tcg_gen_andc_i32(tmp, tmp, tmp2);
9740
            if (!s->condexec_mask)
9741
                gen_logic_CC(tmp);
9742
            break;
9743
        case 0xf: /* mvn */
9744
            tcg_gen_not_i32(tmp2, tmp2);
9745
            if (!s->condexec_mask)
9746
                gen_logic_CC(tmp2);
9747
            val = 1;
9748
            rm = rd;
9749
            break;
9750
        }
9751
        if (rd != 16) {
9752
            if (val) {
9753
                store_reg(s, rm, tmp2);
9754
                if (op != 0xf)
9755
                    tcg_temp_free_i32(tmp);
9756
            } else {
9757
                store_reg(s, rd, tmp);
9758
                tcg_temp_free_i32(tmp2);
9759
            }
9760
        } else {
9761
            tcg_temp_free_i32(tmp);
9762
            tcg_temp_free_i32(tmp2);
9763
        }
9764
        break;
9765

    
9766
    case 5:
9767
        /* load/store register offset.  */
9768
        rd = insn & 7;
9769
        rn = (insn >> 3) & 7;
9770
        rm = (insn >> 6) & 7;
9771
        op = (insn >> 9) & 7;
9772
        addr = load_reg(s, rn);
9773
        tmp = load_reg(s, rm);
9774
        tcg_gen_add_i32(addr, addr, tmp);
9775
        tcg_temp_free_i32(tmp);
9776

    
9777
        if (op < 3) { /* store */
9778
            tmp = load_reg(s, rd);
9779
        } else {
9780
            tmp = tcg_temp_new_i32();
9781
        }
9782

    
9783
        switch (op) {
9784
        case 0: /* str */
9785
            gen_aa32_st32(tmp, addr, IS_USER(s));
9786
            break;
9787
        case 1: /* strh */
9788
            gen_aa32_st16(tmp, addr, IS_USER(s));
9789
            break;
9790
        case 2: /* strb */
9791
            gen_aa32_st8(tmp, addr, IS_USER(s));
9792
            break;
9793
        case 3: /* ldrsb */
9794
            gen_aa32_ld8s(tmp, addr, IS_USER(s));
9795
            break;
9796
        case 4: /* ldr */
9797
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
9798
            break;
9799
        case 5: /* ldrh */
9800
            gen_aa32_ld16u(tmp, addr, IS_USER(s));
9801
            break;
9802
        case 6: /* ldrb */
9803
            gen_aa32_ld8u(tmp, addr, IS_USER(s));
9804
            break;
9805
        case 7: /* ldrsh */
9806
            gen_aa32_ld16s(tmp, addr, IS_USER(s));
9807
            break;
9808
        }
9809
        if (op >= 3) { /* load */
9810
            store_reg(s, rd, tmp);
9811
        } else {
9812
            tcg_temp_free_i32(tmp);
9813
        }
9814
        tcg_temp_free_i32(addr);
9815
        break;
9816

    
9817
    case 6:
9818
        /* load/store word immediate offset */
9819
        rd = insn & 7;
9820
        rn = (insn >> 3) & 7;
9821
        addr = load_reg(s, rn);
9822
        val = (insn >> 4) & 0x7c;
9823
        tcg_gen_addi_i32(addr, addr, val);
9824

    
9825
        if (insn & (1 << 11)) {
9826
            /* load */
9827
            tmp = tcg_temp_new_i32();
9828
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
9829
            store_reg(s, rd, tmp);
9830
        } else {
9831
            /* store */
9832
            tmp = load_reg(s, rd);
9833
            gen_aa32_st32(tmp, addr, IS_USER(s));
9834
            tcg_temp_free_i32(tmp);
9835
        }
9836
        tcg_temp_free_i32(addr);
9837
        break;
9838

    
9839
    case 7:
9840
        /* load/store byte immediate offset */
9841
        rd = insn & 7;
9842
        rn = (insn >> 3) & 7;
9843
        addr = load_reg(s, rn);
9844
        val = (insn >> 6) & 0x1f;
9845
        tcg_gen_addi_i32(addr, addr, val);
9846

    
9847
        if (insn & (1 << 11)) {
9848
            /* load */
9849
            tmp = tcg_temp_new_i32();
9850
            gen_aa32_ld8u(tmp, addr, IS_USER(s));
9851
            store_reg(s, rd, tmp);
9852
        } else {
9853
            /* store */
9854
            tmp = load_reg(s, rd);
9855
            gen_aa32_st8(tmp, addr, IS_USER(s));
9856
            tcg_temp_free_i32(tmp);
9857
        }
9858
        tcg_temp_free_i32(addr);
9859
        break;
9860

    
9861
    case 8:
9862
        /* load/store halfword immediate offset */
9863
        rd = insn & 7;
9864
        rn = (insn >> 3) & 7;
9865
        addr = load_reg(s, rn);
9866
        val = (insn >> 5) & 0x3e;
9867
        tcg_gen_addi_i32(addr, addr, val);
9868

    
9869
        if (insn & (1 << 11)) {
9870
            /* load */
9871
            tmp = tcg_temp_new_i32();
9872
            gen_aa32_ld16u(tmp, addr, IS_USER(s));
9873
            store_reg(s, rd, tmp);
9874
        } else {
9875
            /* store */
9876
            tmp = load_reg(s, rd);
9877
            gen_aa32_st16(tmp, addr, IS_USER(s));
9878
            tcg_temp_free_i32(tmp);
9879
        }
9880
        tcg_temp_free_i32(addr);
9881
        break;
9882

    
9883
    case 9:
9884
        /* load/store from stack */
9885
        rd = (insn >> 8) & 7;
9886
        addr = load_reg(s, 13);
9887
        val = (insn & 0xff) * 4;
9888
        tcg_gen_addi_i32(addr, addr, val);
9889

    
9890
        if (insn & (1 << 11)) {
9891
            /* load */
9892
            tmp = tcg_temp_new_i32();
9893
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
9894
            store_reg(s, rd, tmp);
9895
        } else {
9896
            /* store */
9897
            tmp = load_reg(s, rd);
9898
            gen_aa32_st32(tmp, addr, IS_USER(s));
9899
            tcg_temp_free_i32(tmp);
9900
        }
9901
        tcg_temp_free_i32(addr);
9902
        break;
9903

    
9904
    case 10:
9905
        /* add to high reg */
9906
        rd = (insn >> 8) & 7;
9907
        if (insn & (1 << 11)) {
9908
            /* SP */
9909
            tmp = load_reg(s, 13);
9910
        } else {
9911
            /* PC. bit 1 is ignored.  */
9912
            tmp = tcg_temp_new_i32();
9913
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9914
        }
9915
        val = (insn & 0xff) * 4;
9916
        tcg_gen_addi_i32(tmp, tmp, val);
9917
        store_reg(s, rd, tmp);
9918
        break;
9919

    
9920
    case 11:
9921
        /* misc */
9922
        op = (insn >> 8) & 0xf;
9923
        switch (op) {
9924
        case 0:
9925
            /* adjust stack pointer */
9926
            tmp = load_reg(s, 13);
9927
            val = (insn & 0x7f) * 4;
9928
            if (insn & (1 << 7))
9929
                val = -(int32_t)val;
9930
            tcg_gen_addi_i32(tmp, tmp, val);
9931
            store_reg(s, 13, tmp);
9932
            break;
9933

    
9934
        case 2: /* sign/zero extend.  */
9935
            ARCH(6);
9936
            rd = insn & 7;
9937
            rm = (insn >> 3) & 7;
9938
            tmp = load_reg(s, rm);
9939
            switch ((insn >> 6) & 3) {
9940
            case 0: gen_sxth(tmp); break;
9941
            case 1: gen_sxtb(tmp); break;
9942
            case 2: gen_uxth(tmp); break;
9943
            case 3: gen_uxtb(tmp); break;
9944
            }
9945
            store_reg(s, rd, tmp);
9946
            break;
9947
        case 4: case 5: case 0xc: case 0xd:
9948
            /* push/pop */
9949
            addr = load_reg(s, 13);
9950
            if (insn & (1 << 8))
9951
                offset = 4;
9952
            else
9953
                offset = 0;
9954
            for (i = 0; i < 8; i++) {
9955
                if (insn & (1 << i))
9956
                    offset += 4;
9957
            }
9958
            if ((insn & (1 << 11)) == 0) {
9959
                tcg_gen_addi_i32(addr, addr, -offset);
9960
            }
9961
            for (i = 0; i < 8; i++) {
9962
                if (insn & (1 << i)) {
9963
                    if (insn & (1 << 11)) {
9964
                        /* pop */
9965
                        tmp = tcg_temp_new_i32();
9966
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
9967
                        store_reg(s, i, tmp);
9968
                    } else {
9969
                        /* push */
9970
                        tmp = load_reg(s, i);
9971
                        gen_aa32_st32(tmp, addr, IS_USER(s));
9972
                        tcg_temp_free_i32(tmp);
9973
                    }
9974
                    /* advance to the next address.  */
9975
                    tcg_gen_addi_i32(addr, addr, 4);
9976
                }
9977
            }
9978
            TCGV_UNUSED_I32(tmp);
9979
            if (insn & (1 << 8)) {
9980
                if (insn & (1 << 11)) {
9981
                    /* pop pc */
9982
                    tmp = tcg_temp_new_i32();
9983
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
9984
                    /* don't set the pc until the rest of the instruction
9985
                       has completed */
9986
                } else {
9987
                    /* push lr */
9988
                    tmp = load_reg(s, 14);
9989
                    gen_aa32_st32(tmp, addr, IS_USER(s));
9990
                    tcg_temp_free_i32(tmp);
9991
                }
9992
                tcg_gen_addi_i32(addr, addr, 4);
9993
            }
9994
            if ((insn & (1 << 11)) == 0) {
9995
                tcg_gen_addi_i32(addr, addr, -offset);
9996
            }
9997
            /* write back the new stack pointer */
9998
            store_reg(s, 13, addr);
9999
            /* set the new PC value */
10000
            if ((insn & 0x0900) == 0x0900) {
10001
                store_reg_from_load(env, s, 15, tmp);
10002
            }
10003
            break;
10004

    
10005
        case 1: case 3: case 9: case 11: /* czb */
10006
            rm = insn & 7;
10007
            tmp = load_reg(s, rm);
10008
            s->condlabel = gen_new_label();
10009
            s->condjmp = 1;
10010
            if (insn & (1 << 11))
10011
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10012
            else
10013
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10014
            tcg_temp_free_i32(tmp);
10015
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10016
            val = (uint32_t)s->pc + 2;
10017
            val += offset;
10018
            gen_jmp(s, val);
10019
            break;
10020

    
10021
        case 15: /* IT, nop-hint.  */
10022
            if ((insn & 0xf) == 0) {
10023
                gen_nop_hint(s, (insn >> 4) & 0xf);
10024
                break;
10025
            }
10026
            /* If Then.  */
10027
            s->condexec_cond = (insn >> 4) & 0xe;
10028
            s->condexec_mask = insn & 0x1f;
10029
            /* No actual code generated for this insn, just setup state.  */
10030
            break;
10031

    
10032
        case 0xe: /* bkpt */
10033
            ARCH(5);
10034
            gen_exception_insn(s, 2, EXCP_BKPT);
10035
            break;
10036

    
10037
        case 0xa: /* rev */
10038
            ARCH(6);
10039
            rn = (insn >> 3) & 0x7;
10040
            rd = insn & 0x7;
10041
            tmp = load_reg(s, rn);
10042
            switch ((insn >> 6) & 3) {
10043
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10044
            case 1: gen_rev16(tmp); break;
10045
            case 3: gen_revsh(tmp); break;
10046
            default: goto illegal_op;
10047
            }
10048
            store_reg(s, rd, tmp);
10049
            break;
10050

    
10051
        case 6:
10052
            switch ((insn >> 5) & 7) {
10053
            case 2:
10054
                /* setend */
10055
                ARCH(6);
10056
                if (((insn >> 3) & 1) != s->bswap_code) {
10057
                    /* Dynamic endianness switching not implemented. */
10058
                    qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10059
                    goto illegal_op;
10060
                }
10061
                break;
10062
            case 3:
10063
                /* cps */
10064
                ARCH(6);
10065
                if (IS_USER(s)) {
10066
                    break;
10067
                }
10068
                if (IS_M(env)) {
10069
                    tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10070
                    /* FAULTMASK */
10071
                    if (insn & 1) {
10072
                        addr = tcg_const_i32(19);
10073
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
10074
                        tcg_temp_free_i32(addr);
10075
                    }
10076
                    /* PRIMASK */
10077
                    if (insn & 2) {
10078
                        addr = tcg_const_i32(16);
10079
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
10080
                        tcg_temp_free_i32(addr);
10081
                    }
10082
                    tcg_temp_free_i32(tmp);
10083
                    gen_lookup_tb(s);
10084
                } else {
10085
                    if (insn & (1 << 4)) {
10086
                        shift = CPSR_A | CPSR_I | CPSR_F;
10087
                    } else {
10088
                        shift = 0;
10089
                    }
10090
                    gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10091
                }
10092
                break;
10093
            default:
10094
                goto undef;
10095
            }
10096
            break;
10097

    
10098
        default:
10099
            goto undef;
10100
        }
10101
        break;
10102

    
10103
    case 12:
10104
    {
10105
        /* load/store multiple */
10106
        TCGv_i32 loaded_var;
10107
        TCGV_UNUSED_I32(loaded_var);
10108
        rn = (insn >> 8) & 0x7;
10109
        addr = load_reg(s, rn);
10110
        for (i = 0; i < 8; i++) {
10111
            if (insn & (1 << i)) {
10112
                if (insn & (1 << 11)) {
10113
                    /* load */
10114
                    tmp = tcg_temp_new_i32();
10115
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
10116
                    if (i == rn) {
10117
                        loaded_var = tmp;
10118
                    } else {
10119
                        store_reg(s, i, tmp);
10120
                    }
10121
                } else {
10122
                    /* store */
10123
                    tmp = load_reg(s, i);
10124
                    gen_aa32_st32(tmp, addr, IS_USER(s));
10125
                    tcg_temp_free_i32(tmp);
10126
                }
10127
                /* advance to the next address */
10128
                tcg_gen_addi_i32(addr, addr, 4);
10129
            }
10130
        }
10131
        if ((insn & (1 << rn)) == 0) {
10132
            /* base reg not in list: base register writeback */
10133
            store_reg(s, rn, addr);
10134
        } else {
10135
            /* base reg in list: if load, complete it now */
10136
            if (insn & (1 << 11)) {
10137
                store_reg(s, rn, loaded_var);
10138
            }
10139
            tcg_temp_free_i32(addr);
10140
        }
10141
        break;
10142
    }
10143
    case 13:
10144
        /* conditional branch or swi */
10145
        cond = (insn >> 8) & 0xf;
10146
        if (cond == 0xe)
10147
            goto undef;
10148

    
10149
        if (cond == 0xf) {
10150
            /* swi */
10151
            gen_set_pc_im(s, s->pc);
10152
            s->is_jmp = DISAS_SWI;
10153
            break;
10154
        }
10155
        /* generate a conditional jump to next instruction */
10156
        s->condlabel = gen_new_label();
10157
        gen_test_cc(cond ^ 1, s->condlabel);
10158
        s->condjmp = 1;
10159

    
10160
        /* jump to the offset */
10161
        val = (uint32_t)s->pc + 2;
10162
        offset = ((int32_t)insn << 24) >> 24;
10163
        val += offset << 1;
10164
        gen_jmp(s, val);
10165
        break;
10166

    
10167
    case 14:
10168
        if (insn & (1 << 11)) {
10169
            if (disas_thumb2_insn(env, s, insn))
10170
              goto undef32;
10171
            break;
10172
        }
10173
        /* unconditional branch */
10174
        val = (uint32_t)s->pc;
10175
        offset = ((int32_t)insn << 21) >> 21;
10176
        val += (offset << 1) + 2;
10177
        gen_jmp(s, val);
10178
        break;
10179

    
10180
    case 15:
10181
        if (disas_thumb2_insn(env, s, insn))
10182
            goto undef32;
10183
        break;
10184
    }
10185
    return;
10186
undef32:
10187
    gen_exception_insn(s, 4, EXCP_UDEF);
10188
    return;
10189
illegal_op:
10190
undef:
10191
    gen_exception_insn(s, 2, EXCP_UDEF);
10192
}
10193

    
10194
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10195
   basic block 'tb'. If search_pc is TRUE, also generate PC
10196
   information for each intermediate instruction. */
10197
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10198
                                                  TranslationBlock *tb,
10199
                                                  bool search_pc)
10200
{
10201
    CPUState *cs = CPU(cpu);
10202
    CPUARMState *env = &cpu->env;
10203
    DisasContext dc1, *dc = &dc1;
10204
    CPUBreakpoint *bp;
10205
    uint16_t *gen_opc_end;
10206
    int j, lj;
10207
    target_ulong pc_start;
10208
    target_ulong next_page_start;
10209
    int num_insns;
10210
    int max_insns;
10211

    
10212
    /* generate intermediate code */
10213
    pc_start = tb->pc;
10214

    
10215
    dc->tb = tb;
10216

    
10217
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10218

    
10219
    dc->is_jmp = DISAS_NEXT;
10220
    dc->pc = pc_start;
10221
    dc->singlestep_enabled = cs->singlestep_enabled;
10222
    dc->condjmp = 0;
10223

    
10224
    if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10225
        dc->aarch64 = 1;
10226
        dc->thumb = 0;
10227
        dc->bswap_code = 0;
10228
        dc->condexec_mask = 0;
10229
        dc->condexec_cond = 0;
10230
#if !defined(CONFIG_USER_ONLY)
10231
        dc->user = 0;
10232
#endif
10233
        dc->vfp_enabled = 0;
10234
        dc->vec_len = 0;
10235
        dc->vec_stride = 0;
10236
    } else {
10237
        dc->aarch64 = 0;
10238
        dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10239
        dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10240
        dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10241
        dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10242
#if !defined(CONFIG_USER_ONLY)
10243
        dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10244
#endif
10245
        dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10246
        dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10247
        dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10248
    }
10249
    cpu_F0s = tcg_temp_new_i32();
10250
    cpu_F1s = tcg_temp_new_i32();
10251
    cpu_F0d = tcg_temp_new_i64();
10252
    cpu_F1d = tcg_temp_new_i64();
10253
    cpu_V0 = cpu_F0d;
10254
    cpu_V1 = cpu_F1d;
10255
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
10256
    cpu_M0 = tcg_temp_new_i64();
10257
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10258
    lj = -1;
10259
    num_insns = 0;
10260
    max_insns = tb->cflags & CF_COUNT_MASK;
10261
    if (max_insns == 0)
10262
        max_insns = CF_COUNT_MASK;
10263

    
10264
    gen_tb_start();
10265

    
10266
    tcg_clear_temp_count();
10267

    
10268
    /* A note on handling of the condexec (IT) bits:
10269
     *
10270
     * We want to avoid the overhead of having to write the updated condexec
10271
     * bits back to the CPUARMState for every instruction in an IT block. So:
10272
     * (1) if the condexec bits are not already zero then we write
10273
     * zero back into the CPUARMState now. This avoids complications trying
10274
     * to do it at the end of the block. (For example if we don't do this
10275
     * it's hard to identify whether we can safely skip writing condexec
10276
     * at the end of the TB, which we definitely want to do for the case
10277
     * where a TB doesn't do anything with the IT state at all.)
10278
     * (2) if we are going to leave the TB then we call gen_set_condexec()
10279
     * which will write the correct value into CPUARMState if zero is wrong.
10280
     * This is done both for leaving the TB at the end, and for leaving
10281
     * it because of an exception we know will happen, which is done in
10282
     * gen_exception_insn(). The latter is necessary because we need to
10283
     * leave the TB with the PC/IT state just prior to execution of the
10284
     * instruction which caused the exception.
10285
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10286
     * then the CPUARMState will be wrong and we need to reset it.
10287
     * This is handled in the same way as restoration of the
10288
     * PC in these situations: we will be called again with search_pc=1
10289
     * and generate a mapping of the condexec bits for each PC in
10290
     * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10291
     * this to restore the condexec bits.
10292
     *
10293
     * Note that there are no instructions which can read the condexec
10294
     * bits, and none which can write non-static values to them, so
10295
     * we don't need to care about whether CPUARMState is correct in the
10296
     * middle of a TB.
10297
     */
10298

    
10299
    /* Reset the conditional execution bits immediately. This avoids
10300
       complications trying to do it at the end of the block.  */
10301
    if (dc->condexec_mask || dc->condexec_cond)
10302
      {
10303
        TCGv_i32 tmp = tcg_temp_new_i32();
10304
        tcg_gen_movi_i32(tmp, 0);
10305
        store_cpu_field(tmp, condexec_bits);
10306
      }
10307
    do {
10308
#ifdef CONFIG_USER_ONLY
10309
        /* Intercept jump to the magic kernel page.  */
10310
        if (!dc->aarch64 && dc->pc >= 0xffff0000) {
10311
            /* We always get here via a jump, so know we are not in a
10312
               conditional execution block.  */
10313
            gen_exception(EXCP_KERNEL_TRAP);
10314
            dc->is_jmp = DISAS_UPDATE;
10315
            break;
10316
        }
10317
#else
10318
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10319
            /* We always get here via a jump, so know we are not in a
10320
               conditional execution block.  */
10321
            gen_exception(EXCP_EXCEPTION_EXIT);
10322
            dc->is_jmp = DISAS_UPDATE;
10323
            break;
10324
        }
10325
#endif
10326

    
10327
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10328
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10329
                if (bp->pc == dc->pc) {
10330
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
10331
                    /* Advance PC so that clearing the breakpoint will
10332
                       invalidate this TB.  */
10333
                    dc->pc += 2;
10334
                    goto done_generating;
10335
                }
10336
            }
10337
        }
10338
        if (search_pc) {
10339
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10340
            if (lj < j) {
10341
                lj++;
10342
                while (lj < j)
10343
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
10344
            }
10345
            tcg_ctx.gen_opc_pc[lj] = dc->pc;
10346
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10347
            tcg_ctx.gen_opc_instr_start[lj] = 1;
10348
            tcg_ctx.gen_opc_icount[lj] = num_insns;
10349
        }
10350

    
10351
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10352
            gen_io_start();
10353

    
10354
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10355
            tcg_gen_debug_insn_start(dc->pc);
10356
        }
10357

    
10358
        if (dc->aarch64) {
10359
            disas_a64_insn(env, dc);
10360
        } else if (dc->thumb) {
10361
            disas_thumb_insn(env, dc);
10362
            if (dc->condexec_mask) {
10363
                dc->condexec_cond = (dc->condexec_cond & 0xe)
10364
                                   | ((dc->condexec_mask >> 4) & 1);
10365
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10366
                if (dc->condexec_mask == 0) {
10367
                    dc->condexec_cond = 0;
10368
                }
10369
            }
10370
        } else {
10371
            disas_arm_insn(env, dc);
10372
        }
10373

    
10374
        if (dc->condjmp && !dc->is_jmp) {
10375
            gen_set_label(dc->condlabel);
10376
            dc->condjmp = 0;
10377
        }
10378

    
10379
        if (tcg_check_temp_count()) {
10380
            fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10381
                    dc->pc);
10382
        }
10383

    
10384
        /* Translation stops when a conditional branch is encountered.
10385
         * Otherwise the subsequent code could get translated several times.
10386
         * Also stop translation when a page boundary is reached.  This
10387
         * ensures prefetch aborts occur at the right place.  */
10388
        num_insns ++;
10389
    } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10390
             !cs->singlestep_enabled &&
10391
             !singlestep &&
10392
             dc->pc < next_page_start &&
10393
             num_insns < max_insns);
10394

    
10395
    if (tb->cflags & CF_LAST_IO) {
10396
        if (dc->condjmp) {
10397
            /* FIXME:  This can theoretically happen with self-modifying
10398
               code.  */
10399
            cpu_abort(env, "IO on conditional branch instruction");
10400
        }
10401
        gen_io_end();
10402
    }
10403

    
10404
    /* At this stage dc->condjmp will only be set when the skipped
10405
       instruction was a conditional branch or trap, and the PC has
10406
       already been written.  */
10407
    if (unlikely(cs->singlestep_enabled)) {
10408
        /* Make sure the pc is updated, and raise a debug exception.  */
10409
        if (dc->condjmp) {
10410
            gen_set_condexec(dc);
10411
            if (dc->is_jmp == DISAS_SWI) {
10412
                gen_exception(EXCP_SWI);
10413
            } else {
10414
                gen_exception(EXCP_DEBUG);
10415
            }
10416
            gen_set_label(dc->condlabel);
10417
        }
10418
        if (dc->condjmp || !dc->is_jmp) {
10419
            gen_set_pc_im(dc, dc->pc);
10420
            dc->condjmp = 0;
10421
        }
10422
        gen_set_condexec(dc);
10423
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10424
            gen_exception(EXCP_SWI);
10425
        } else {
10426
            /* FIXME: Single stepping a WFI insn will not halt
10427
               the CPU.  */
10428
            gen_exception(EXCP_DEBUG);
10429
        }
10430
    } else {
10431
        /* While branches must always occur at the end of an IT block,
10432
           there are a few other things that can cause us to terminate
10433
           the TB in the middle of an IT block:
10434
            - Exception generating instructions (bkpt, swi, undefined).
10435
            - Page boundaries.
10436
            - Hardware watchpoints.
10437
           Hardware breakpoints have already been handled and skip this code.
10438
         */
10439
        gen_set_condexec(dc);
10440
        switch(dc->is_jmp) {
10441
        case DISAS_NEXT:
10442
            gen_goto_tb(dc, 1, dc->pc);
10443
            break;
10444
        default:
10445
        case DISAS_JUMP:
10446
        case DISAS_UPDATE:
10447
            /* indicate that the hash table must be used to find the next TB */
10448
            tcg_gen_exit_tb(0);
10449
            break;
10450
        case DISAS_TB_JUMP:
10451
            /* nothing more to generate */
10452
            break;
10453
        case DISAS_WFI:
10454
            gen_helper_wfi(cpu_env);
10455
            break;
10456
        case DISAS_SWI:
10457
            gen_exception(EXCP_SWI);
10458
            break;
10459
        }
10460
        if (dc->condjmp) {
10461
            gen_set_label(dc->condlabel);
10462
            gen_set_condexec(dc);
10463
            gen_goto_tb(dc, 1, dc->pc);
10464
            dc->condjmp = 0;
10465
        }
10466
    }
10467

    
10468
done_generating:
10469
    gen_tb_end(tb, num_insns);
10470
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10471

    
10472
#ifdef DEBUG_DISAS
10473
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10474
        qemu_log("----------------\n");
10475
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
10476
        log_target_disas(env, pc_start, dc->pc - pc_start,
10477
                         dc->thumb | (dc->bswap_code << 1));
10478
        qemu_log("\n");
10479
    }
10480
#endif
10481
    if (search_pc) {
10482
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10483
        lj++;
10484
        while (lj <= j)
10485
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
10486
    } else {
10487
        tb->size = dc->pc - pc_start;
10488
        tb->icount = num_insns;
10489
    }
10490
}
10491

    
10492
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10493
{
10494
    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10495
}
10496

    
10497
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10498
{
10499
    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10500
}
10501

    
10502
static const char *cpu_mode_names[16] = {
10503
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10504
  "???", "???", "???", "und", "???", "???", "???", "sys"
10505
};
10506

    
10507
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10508
                        int flags)
10509
{
10510
    ARMCPU *cpu = ARM_CPU(cs);
10511
    CPUARMState *env = &cpu->env;
10512
    int i;
10513
    uint32_t psr;
10514

    
10515
    for(i=0;i<16;i++) {
10516
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10517
        if ((i % 4) == 3)
10518
            cpu_fprintf(f, "\n");
10519
        else
10520
            cpu_fprintf(f, " ");
10521
    }
10522
    psr = cpsr_read(env);
10523
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10524
                psr,
10525
                psr & (1 << 31) ? 'N' : '-',
10526
                psr & (1 << 30) ? 'Z' : '-',
10527
                psr & (1 << 29) ? 'C' : '-',
10528
                psr & (1 << 28) ? 'V' : '-',
10529
                psr & CPSR_T ? 'T' : 'A',
10530
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10531

    
10532
    if (flags & CPU_DUMP_FPU) {
10533
        int numvfpregs = 0;
10534
        if (arm_feature(env, ARM_FEATURE_VFP)) {
10535
            numvfpregs += 16;
10536
        }
10537
        if (arm_feature(env, ARM_FEATURE_VFP3)) {
10538
            numvfpregs += 16;
10539
        }
10540
        for (i = 0; i < numvfpregs; i++) {
10541
            uint64_t v = float64_val(env->vfp.regs[i]);
10542
            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10543
                        i * 2, (uint32_t)v,
10544
                        i * 2 + 1, (uint32_t)(v >> 32),
10545
                        i, v);
10546
        }
10547
        cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10548
    }
10549
}
10550

    
10551
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10552
{
10553
    if (is_a64(env)) {
10554
        env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10555
    } else {
10556
        env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10557
    }
10558
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
10559
}