Statistics
| Branch: | Revision:

root / target-arm / translate.c @ ea4571eb

History | View | Annotate | Download (378.5 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
TCGv_ptr cpu_env;
60
/* We reuse the same 64-bit temporaries for efficiency.  */
61
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
62
static TCGv_i32 cpu_R[16];
63
static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
64
static TCGv_i64 cpu_exclusive_addr;
65
static TCGv_i64 cpu_exclusive_val;
66
#ifdef CONFIG_USER_ONLY
67
static TCGv_i64 cpu_exclusive_test;
68
static TCGv_i32 cpu_exclusive_info;
69
#endif
70

    
71
/* FIXME:  These should be removed.  */
72
static TCGv_i32 cpu_F0s, cpu_F1s;
73
static TCGv_i64 cpu_F0d, cpu_F1d;
74

    
75
#include "exec/gen-icount.h"
76

    
77
static const char *regnames[] =
78
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
80

    
81
/* initialize TCG globals.  */
82
void arm_translate_init(void)
83
{
84
    int i;
85

    
86
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
87

    
88
    for (i = 0; i < 16; i++) {
89
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
90
                                          offsetof(CPUARMState, regs[i]),
91
                                          regnames[i]);
92
    }
93
    cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
94
    cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
95
    cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
96
    cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
97

    
98
    cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
99
        offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100
    cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
101
        offsetof(CPUARMState, exclusive_val), "exclusive_val");
102
#ifdef CONFIG_USER_ONLY
103
    cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
104
        offsetof(CPUARMState, exclusive_test), "exclusive_test");
105
    cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
106
        offsetof(CPUARMState, exclusive_info), "exclusive_info");
107
#endif
108

    
109
    a64_translate_init();
110
}
111

    
112
static inline TCGv_i32 load_cpu_offset(int offset)
113
{
114
    TCGv_i32 tmp = tcg_temp_new_i32();
115
    tcg_gen_ld_i32(tmp, cpu_env, offset);
116
    return tmp;
117
}
118

    
119
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
120

    
121
static inline void store_cpu_offset(TCGv_i32 var, int offset)
122
{
123
    tcg_gen_st_i32(var, cpu_env, offset);
124
    tcg_temp_free_i32(var);
125
}
126

    
127
#define store_cpu_field(var, name) \
128
    store_cpu_offset(var, offsetof(CPUARMState, name))
129

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

    
146
/* Create a new temporary and set it to the value of a CPU register.  */
147
static inline TCGv_i32 load_reg(DisasContext *s, int reg)
148
{
149
    TCGv_i32 tmp = tcg_temp_new_i32();
150
    load_reg_var(s, tmp, reg);
151
    return tmp;
152
}
153

    
154
/* Set a CPU register.  The source must be a temporary and will be
155
   marked as dead.  */
156
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
157
{
158
    if (reg == 15) {
159
        tcg_gen_andi_i32(var, var, ~1);
160
        s->is_jmp = DISAS_JUMP;
161
    }
162
    tcg_gen_mov_i32(cpu_R[reg], var);
163
    tcg_temp_free_i32(var);
164
}
165

    
166
/* Value extensions.  */
167
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
168
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
169
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
170
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
171

    
172
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
173
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
174

    
175

    
176
static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
177
{
178
    TCGv_i32 tmp_mask = tcg_const_i32(mask);
179
    gen_helper_cpsr_write(cpu_env, var, tmp_mask);
180
    tcg_temp_free_i32(tmp_mask);
181
}
182
/* Set NZCV flags from the high 4 bits of var.  */
183
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
184

    
185
static void gen_exception(int excp)
186
{
187
    TCGv_i32 tmp = tcg_temp_new_i32();
188
    tcg_gen_movi_i32(tmp, excp);
189
    gen_helper_exception(cpu_env, tmp);
190
    tcg_temp_free_i32(tmp);
191
}
192

    
193
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
194
{
195
    TCGv_i32 tmp1 = tcg_temp_new_i32();
196
    TCGv_i32 tmp2 = tcg_temp_new_i32();
197
    tcg_gen_ext16s_i32(tmp1, a);
198
    tcg_gen_ext16s_i32(tmp2, b);
199
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
200
    tcg_temp_free_i32(tmp2);
201
    tcg_gen_sari_i32(a, a, 16);
202
    tcg_gen_sari_i32(b, b, 16);
203
    tcg_gen_mul_i32(b, b, a);
204
    tcg_gen_mov_i32(a, tmp1);
205
    tcg_temp_free_i32(tmp1);
206
}
207

    
208
/* Byteswap each halfword.  */
209
static void gen_rev16(TCGv_i32 var)
210
{
211
    TCGv_i32 tmp = tcg_temp_new_i32();
212
    tcg_gen_shri_i32(tmp, var, 8);
213
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
214
    tcg_gen_shli_i32(var, var, 8);
215
    tcg_gen_andi_i32(var, var, 0xff00ff00);
216
    tcg_gen_or_i32(var, var, tmp);
217
    tcg_temp_free_i32(tmp);
218
}
219

    
220
/* Byteswap low halfword and sign extend.  */
221
static void gen_revsh(TCGv_i32 var)
222
{
223
    tcg_gen_ext16u_i32(var, var);
224
    tcg_gen_bswap16_i32(var, var);
225
    tcg_gen_ext16s_i32(var, var);
226
}
227

    
228
/* Unsigned bitfield extract.  */
229
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
230
{
231
    if (shift)
232
        tcg_gen_shri_i32(var, var, shift);
233
    tcg_gen_andi_i32(var, var, mask);
234
}
235

    
236
/* Signed bitfield extract.  */
237
static void gen_sbfx(TCGv_i32 var, int shift, int width)
238
{
239
    uint32_t signbit;
240

    
241
    if (shift)
242
        tcg_gen_sari_i32(var, var, shift);
243
    if (shift + width < 32) {
244
        signbit = 1u << (width - 1);
245
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
246
        tcg_gen_xori_i32(var, var, signbit);
247
        tcg_gen_subi_i32(var, var, signbit);
248
    }
249
}
250

    
251
/* Return (b << 32) + a. Mark inputs as dead */
252
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
253
{
254
    TCGv_i64 tmp64 = tcg_temp_new_i64();
255

    
256
    tcg_gen_extu_i32_i64(tmp64, b);
257
    tcg_temp_free_i32(b);
258
    tcg_gen_shli_i64(tmp64, tmp64, 32);
259
    tcg_gen_add_i64(a, tmp64, a);
260

    
261
    tcg_temp_free_i64(tmp64);
262
    return a;
263
}
264

    
265
/* Return (b << 32) - a. Mark inputs as dead. */
266
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
267
{
268
    TCGv_i64 tmp64 = tcg_temp_new_i64();
269

    
270
    tcg_gen_extu_i32_i64(tmp64, b);
271
    tcg_temp_free_i32(b);
272
    tcg_gen_shli_i64(tmp64, tmp64, 32);
273
    tcg_gen_sub_i64(a, tmp64, a);
274

    
275
    tcg_temp_free_i64(tmp64);
276
    return a;
277
}
278

    
279
/* 32x32->64 multiply.  Marks inputs as dead.  */
280
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
281
{
282
    TCGv_i32 lo = tcg_temp_new_i32();
283
    TCGv_i32 hi = tcg_temp_new_i32();
284
    TCGv_i64 ret;
285

    
286
    tcg_gen_mulu2_i32(lo, hi, a, b);
287
    tcg_temp_free_i32(a);
288
    tcg_temp_free_i32(b);
289

    
290
    ret = tcg_temp_new_i64();
291
    tcg_gen_concat_i32_i64(ret, lo, hi);
292
    tcg_temp_free_i32(lo);
293
    tcg_temp_free_i32(hi);
294

    
295
    return ret;
296
}
297

    
298
static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
299
{
300
    TCGv_i32 lo = tcg_temp_new_i32();
301
    TCGv_i32 hi = tcg_temp_new_i32();
302
    TCGv_i64 ret;
303

    
304
    tcg_gen_muls2_i32(lo, hi, a, b);
305
    tcg_temp_free_i32(a);
306
    tcg_temp_free_i32(b);
307

    
308
    ret = tcg_temp_new_i64();
309
    tcg_gen_concat_i32_i64(ret, lo, hi);
310
    tcg_temp_free_i32(lo);
311
    tcg_temp_free_i32(hi);
312

    
313
    return ret;
314
}
315

    
316
/* Swap low and high halfwords.  */
317
static void gen_swap_half(TCGv_i32 var)
318
{
319
    TCGv_i32 tmp = tcg_temp_new_i32();
320
    tcg_gen_shri_i32(tmp, var, 16);
321
    tcg_gen_shli_i32(var, var, 16);
322
    tcg_gen_or_i32(var, var, tmp);
323
    tcg_temp_free_i32(tmp);
324
}
325

    
326
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
327
    tmp = (t0 ^ t1) & 0x8000;
328
    t0 &= ~0x8000;
329
    t1 &= ~0x8000;
330
    t0 = (t0 + t1) ^ tmp;
331
 */
332

    
333
static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
334
{
335
    TCGv_i32 tmp = tcg_temp_new_i32();
336
    tcg_gen_xor_i32(tmp, t0, t1);
337
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
338
    tcg_gen_andi_i32(t0, t0, ~0x8000);
339
    tcg_gen_andi_i32(t1, t1, ~0x8000);
340
    tcg_gen_add_i32(t0, t0, t1);
341
    tcg_gen_xor_i32(t0, t0, tmp);
342
    tcg_temp_free_i32(tmp);
343
    tcg_temp_free_i32(t1);
344
}
345

    
346
/* Set CF to the top bit of var.  */
347
static void gen_set_CF_bit31(TCGv_i32 var)
348
{
349
    tcg_gen_shri_i32(cpu_CF, var, 31);
350
}
351

    
352
/* Set N and Z flags from var.  */
353
static inline void gen_logic_CC(TCGv_i32 var)
354
{
355
    tcg_gen_mov_i32(cpu_NF, var);
356
    tcg_gen_mov_i32(cpu_ZF, var);
357
}
358

    
359
/* T0 += T1 + CF.  */
360
static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
361
{
362
    tcg_gen_add_i32(t0, t0, t1);
363
    tcg_gen_add_i32(t0, t0, cpu_CF);
364
}
365

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

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

    
381
/* dest = T0 + T1. Compute C, N, V and Z flags */
382
static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
383
{
384
    TCGv_i32 tmp = tcg_temp_new_i32();
385
    tcg_gen_movi_i32(tmp, 0);
386
    tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
387
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
388
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
389
    tcg_gen_xor_i32(tmp, t0, t1);
390
    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
391
    tcg_temp_free_i32(tmp);
392
    tcg_gen_mov_i32(dest, cpu_NF);
393
}
394

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

    
423
/* dest = T0 - T1. Compute C, N, V and Z flags */
424
static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
425
{
426
    TCGv_i32 tmp;
427
    tcg_gen_sub_i32(cpu_NF, t0, t1);
428
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
429
    tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
430
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
431
    tmp = tcg_temp_new_i32();
432
    tcg_gen_xor_i32(tmp, t0, t1);
433
    tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
434
    tcg_temp_free_i32(tmp);
435
    tcg_gen_mov_i32(dest, cpu_NF);
436
}
437

    
438
/* dest = T0 + ~T1 + CF.  Compute C, N, V and Z flags */
439
static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
440
{
441
    TCGv_i32 tmp = tcg_temp_new_i32();
442
    tcg_gen_not_i32(tmp, t1);
443
    gen_adc_CC(dest, t0, tmp);
444
    tcg_temp_free_i32(tmp);
445
}
446

    
447
#define GEN_SHIFT(name)                                               \
448
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)       \
449
{                                                                     \
450
    TCGv_i32 tmp1, tmp2, tmp3;                                        \
451
    tmp1 = tcg_temp_new_i32();                                        \
452
    tcg_gen_andi_i32(tmp1, t1, 0xff);                                 \
453
    tmp2 = tcg_const_i32(0);                                          \
454
    tmp3 = tcg_const_i32(0x1f);                                       \
455
    tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0);    \
456
    tcg_temp_free_i32(tmp3);                                          \
457
    tcg_gen_andi_i32(tmp1, tmp1, 0x1f);                               \
458
    tcg_gen_##name##_i32(dest, tmp2, tmp1);                           \
459
    tcg_temp_free_i32(tmp2);                                          \
460
    tcg_temp_free_i32(tmp1);                                          \
461
}
462
GEN_SHIFT(shl)
463
GEN_SHIFT(shr)
464
#undef GEN_SHIFT
465

    
466
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
467
{
468
    TCGv_i32 tmp1, tmp2;
469
    tmp1 = tcg_temp_new_i32();
470
    tcg_gen_andi_i32(tmp1, t1, 0xff);
471
    tmp2 = tcg_const_i32(0x1f);
472
    tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
473
    tcg_temp_free_i32(tmp2);
474
    tcg_gen_sar_i32(dest, t0, tmp1);
475
    tcg_temp_free_i32(tmp1);
476
}
477

    
478
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
479
{
480
    TCGv_i32 c0 = tcg_const_i32(0);
481
    TCGv_i32 tmp = tcg_temp_new_i32();
482
    tcg_gen_neg_i32(tmp, src);
483
    tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
484
    tcg_temp_free_i32(c0);
485
    tcg_temp_free_i32(tmp);
486
}
487

    
488
static void shifter_out_im(TCGv_i32 var, int shift)
489
{
490
    if (shift == 0) {
491
        tcg_gen_andi_i32(cpu_CF, var, 1);
492
    } else {
493
        tcg_gen_shri_i32(cpu_CF, var, shift);
494
        if (shift != 31) {
495
            tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
496
        }
497
    }
498
}
499

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

    
550
static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
551
                                     TCGv_i32 shift, int flags)
552
{
553
    if (flags) {
554
        switch (shiftop) {
555
        case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
556
        case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
557
        case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
558
        case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
559
        }
560
    } else {
561
        switch (shiftop) {
562
        case 0:
563
            gen_shl(var, var, shift);
564
            break;
565
        case 1:
566
            gen_shr(var, var, shift);
567
            break;
568
        case 2:
569
            gen_sar(var, var, shift);
570
            break;
571
        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
572
                tcg_gen_rotr_i32(var, var, shift); break;
573
        }
574
    }
575
    tcg_temp_free_i32(shift);
576
}
577

    
578
#define PAS_OP(pfx) \
579
    switch (op2) {  \
580
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
581
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
582
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
583
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
584
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
585
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
586
    }
587
static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
588
{
589
    TCGv_ptr tmp;
590

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

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

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

    
671
/*
672
 * generate a conditional branch based on ARM condition code cc.
673
 * This is common between ARM and Aarch64 targets.
674
 */
675
void arm_gen_test_cc(int cc, int label)
676
{
677
    TCGv_i32 tmp;
678
    int inv;
679

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

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

    
768
/* Set PC and Thumb state from an immediate address.  */
769
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
770
{
771
    TCGv_i32 tmp;
772

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

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

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

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

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

    
828
#define DO_GEN_LD(SUFF, OPC)                                             \
829
static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
830
{                                                                        \
831
    tcg_gen_qemu_ld_i32(val, addr, index, OPC);                          \
832
}
833

    
834
#define DO_GEN_ST(SUFF, OPC)                                             \
835
static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
836
{                                                                        \
837
    tcg_gen_qemu_st_i32(val, addr, index, OPC);                          \
838
}
839

    
840
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
841
{
842
    tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
843
}
844

    
845
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
846
{
847
    tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
848
}
849

    
850
#else
851

    
852
#define DO_GEN_LD(SUFF, OPC)                                             \
853
static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
854
{                                                                        \
855
    TCGv addr64 = tcg_temp_new();                                        \
856
    tcg_gen_extu_i32_i64(addr64, addr);                                  \
857
    tcg_gen_qemu_ld_i32(val, addr64, index, OPC);                        \
858
    tcg_temp_free(addr64);                                               \
859
}
860

    
861
#define DO_GEN_ST(SUFF, OPC)                                             \
862
static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
863
{                                                                        \
864
    TCGv addr64 = tcg_temp_new();                                        \
865
    tcg_gen_extu_i32_i64(addr64, addr);                                  \
866
    tcg_gen_qemu_st_i32(val, addr64, index, OPC);                        \
867
    tcg_temp_free(addr64);                                               \
868
}
869

    
870
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
871
{
872
    TCGv addr64 = tcg_temp_new();
873
    tcg_gen_extu_i32_i64(addr64, addr);
874
    tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
875
    tcg_temp_free(addr64);
876
}
877

    
878
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
879
{
880
    TCGv addr64 = tcg_temp_new();
881
    tcg_gen_extu_i32_i64(addr64, addr);
882
    tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
883
    tcg_temp_free(addr64);
884
}
885

    
886
#endif
887

    
888
DO_GEN_LD(8s, MO_SB)
889
DO_GEN_LD(8u, MO_UB)
890
DO_GEN_LD(16s, MO_TESW)
891
DO_GEN_LD(16u, MO_TEUW)
892
DO_GEN_LD(32u, MO_TEUL)
893
DO_GEN_ST(8, MO_UB)
894
DO_GEN_ST(16, MO_TEUW)
895
DO_GEN_ST(32, MO_TEUL)
896

    
897
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
898
{
899
    tcg_gen_movi_i32(cpu_R[15], val);
900
}
901

    
902
/* Force a TB lookup after an instruction that changes the CPU state.  */
903
static inline void gen_lookup_tb(DisasContext *s)
904
{
905
    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
906
    s->is_jmp = DISAS_UPDATE;
907
}
908

    
909
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
910
                                       TCGv_i32 var)
911
{
912
    int val, rm, shift, shiftop;
913
    TCGv_i32 offset;
914

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

    
937
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
938
                                        int extra, TCGv_i32 var)
939
{
940
    int val, rm;
941
    TCGv_i32 offset;
942

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

    
965
static TCGv_ptr get_fpstatus_ptr(int neon)
966
{
967
    TCGv_ptr statusptr = tcg_temp_new_ptr();
968
    int offset;
969
    if (neon) {
970
        offset = offsetof(CPUARMState, vfp.standard_fp_status);
971
    } else {
972
        offset = offsetof(CPUARMState, vfp.fp_status);
973
    }
974
    tcg_gen_addi_ptr(statusptr, cpu_env, offset);
975
    return statusptr;
976
}
977

    
978
#define VFP_OP2(name)                                                 \
979
static inline void gen_vfp_##name(int dp)                             \
980
{                                                                     \
981
    TCGv_ptr fpst = get_fpstatus_ptr(0);                              \
982
    if (dp) {                                                         \
983
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst);    \
984
    } else {                                                          \
985
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst);    \
986
    }                                                                 \
987
    tcg_temp_free_ptr(fpst);                                          \
988
}
989

    
990
VFP_OP2(add)
991
VFP_OP2(sub)
992
VFP_OP2(mul)
993
VFP_OP2(div)
994

    
995
#undef VFP_OP2
996

    
997
static inline void gen_vfp_F1_mul(int dp)
998
{
999
    /* Like gen_vfp_mul() but put result in F1 */
1000
    TCGv_ptr fpst = get_fpstatus_ptr(0);
1001
    if (dp) {
1002
        gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1003
    } else {
1004
        gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1005
    }
1006
    tcg_temp_free_ptr(fpst);
1007
}
1008

    
1009
static inline void gen_vfp_F1_neg(int dp)
1010
{
1011
    /* Like gen_vfp_neg() but put result in F1 */
1012
    if (dp) {
1013
        gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1014
    } else {
1015
        gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1016
    }
1017
}
1018

    
1019
static inline void gen_vfp_abs(int dp)
1020
{
1021
    if (dp)
1022
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1023
    else
1024
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1025
}
1026

    
1027
static inline void gen_vfp_neg(int dp)
1028
{
1029
    if (dp)
1030
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1031
    else
1032
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1033
}
1034

    
1035
static inline void gen_vfp_sqrt(int dp)
1036
{
1037
    if (dp)
1038
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1039
    else
1040
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1041
}
1042

    
1043
static inline void gen_vfp_cmp(int dp)
1044
{
1045
    if (dp)
1046
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1047
    else
1048
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1049
}
1050

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

    
1059
static inline void gen_vfp_F1_ld0(int dp)
1060
{
1061
    if (dp)
1062
        tcg_gen_movi_i64(cpu_F1d, 0);
1063
    else
1064
        tcg_gen_movi_i32(cpu_F1s, 0);
1065
}
1066

    
1067
#define VFP_GEN_ITOF(name) \
1068
static inline void gen_vfp_##name(int dp, int neon) \
1069
{ \
1070
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1071
    if (dp) { \
1072
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1073
    } else { \
1074
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1075
    } \
1076
    tcg_temp_free_ptr(statusptr); \
1077
}
1078

    
1079
VFP_GEN_ITOF(uito)
1080
VFP_GEN_ITOF(sito)
1081
#undef VFP_GEN_ITOF
1082

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

    
1095
VFP_GEN_FTOI(toui)
1096
VFP_GEN_FTOI(touiz)
1097
VFP_GEN_FTOI(tosi)
1098
VFP_GEN_FTOI(tosiz)
1099
#undef VFP_GEN_FTOI
1100

    
1101
#define VFP_GEN_FIX(name, round) \
1102
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1103
{ \
1104
    TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1105
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1106
    if (dp) { \
1107
        gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1108
                                        statusptr); \
1109
    } else { \
1110
        gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1111
                                        statusptr); \
1112
    } \
1113
    tcg_temp_free_i32(tmp_shift); \
1114
    tcg_temp_free_ptr(statusptr); \
1115
}
1116
VFP_GEN_FIX(tosh, _round_to_zero)
1117
VFP_GEN_FIX(tosl, _round_to_zero)
1118
VFP_GEN_FIX(touh, _round_to_zero)
1119
VFP_GEN_FIX(toul, _round_to_zero)
1120
VFP_GEN_FIX(shto, )
1121
VFP_GEN_FIX(slto, )
1122
VFP_GEN_FIX(uhto, )
1123
VFP_GEN_FIX(ulto, )
1124
#undef VFP_GEN_FIX
1125

    
1126
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1127
{
1128
    if (dp) {
1129
        gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1130
    } else {
1131
        gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1132
    }
1133
}
1134

    
1135
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1136
{
1137
    if (dp) {
1138
        gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1139
    } else {
1140
        gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1141
    }
1142
}
1143

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

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

    
1168
static TCGv_i32 neon_load_reg(int reg, int pass)
1169
{
1170
    TCGv_i32 tmp = tcg_temp_new_i32();
1171
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1172
    return tmp;
1173
}
1174

    
1175
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1176
{
1177
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1178
    tcg_temp_free_i32(var);
1179
}
1180

    
1181
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1182
{
1183
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1184
}
1185

    
1186
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1187
{
1188
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1189
}
1190

    
1191
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1192
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1193
#define tcg_gen_st_f32 tcg_gen_st_i32
1194
#define tcg_gen_st_f64 tcg_gen_st_i64
1195

    
1196
static inline void gen_mov_F0_vreg(int dp, int reg)
1197
{
1198
    if (dp)
1199
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1200
    else
1201
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1202
}
1203

    
1204
static inline void gen_mov_F1_vreg(int dp, int reg)
1205
{
1206
    if (dp)
1207
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1208
    else
1209
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1210
}
1211

    
1212
static inline void gen_mov_vreg_F0(int dp, int reg)
1213
{
1214
    if (dp)
1215
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1216
    else
1217
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1218
}
1219

    
1220
#define ARM_CP_RW_BIT        (1 << 20)
1221

    
1222
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1223
{
1224
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1225
}
1226

    
1227
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1228
{
1229
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1230
}
1231

    
1232
static inline TCGv_i32 iwmmxt_load_creg(int reg)
1233
{
1234
    TCGv_i32 var = tcg_temp_new_i32();
1235
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1236
    return var;
1237
}
1238

    
1239
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1240
{
1241
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1242
    tcg_temp_free_i32(var);
1243
}
1244

    
1245
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1246
{
1247
    iwmmxt_store_reg(cpu_M0, rn);
1248
}
1249

    
1250
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1251
{
1252
    iwmmxt_load_reg(cpu_M0, rn);
1253
}
1254

    
1255
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1256
{
1257
    iwmmxt_load_reg(cpu_V1, rn);
1258
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1259
}
1260

    
1261
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1262
{
1263
    iwmmxt_load_reg(cpu_V1, rn);
1264
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1265
}
1266

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

    
1273
#define IWMMXT_OP(name) \
1274
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1275
{ \
1276
    iwmmxt_load_reg(cpu_V1, rn); \
1277
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1278
}
1279

    
1280
#define IWMMXT_OP_ENV(name) \
1281
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1282
{ \
1283
    iwmmxt_load_reg(cpu_V1, rn); \
1284
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1285
}
1286

    
1287
#define IWMMXT_OP_ENV_SIZE(name) \
1288
IWMMXT_OP_ENV(name##b) \
1289
IWMMXT_OP_ENV(name##w) \
1290
IWMMXT_OP_ENV(name##l)
1291

    
1292
#define IWMMXT_OP_ENV1(name) \
1293
static inline void gen_op_iwmmxt_##name##_M0(void) \
1294
{ \
1295
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1296
}
1297

    
1298
IWMMXT_OP(maddsq)
1299
IWMMXT_OP(madduq)
1300
IWMMXT_OP(sadb)
1301
IWMMXT_OP(sadw)
1302
IWMMXT_OP(mulslw)
1303
IWMMXT_OP(mulshw)
1304
IWMMXT_OP(mululw)
1305
IWMMXT_OP(muluhw)
1306
IWMMXT_OP(macsw)
1307
IWMMXT_OP(macuw)
1308

    
1309
IWMMXT_OP_ENV_SIZE(unpackl)
1310
IWMMXT_OP_ENV_SIZE(unpackh)
1311

    
1312
IWMMXT_OP_ENV1(unpacklub)
1313
IWMMXT_OP_ENV1(unpackluw)
1314
IWMMXT_OP_ENV1(unpacklul)
1315
IWMMXT_OP_ENV1(unpackhub)
1316
IWMMXT_OP_ENV1(unpackhuw)
1317
IWMMXT_OP_ENV1(unpackhul)
1318
IWMMXT_OP_ENV1(unpacklsb)
1319
IWMMXT_OP_ENV1(unpacklsw)
1320
IWMMXT_OP_ENV1(unpacklsl)
1321
IWMMXT_OP_ENV1(unpackhsb)
1322
IWMMXT_OP_ENV1(unpackhsw)
1323
IWMMXT_OP_ENV1(unpackhsl)
1324

    
1325
IWMMXT_OP_ENV_SIZE(cmpeq)
1326
IWMMXT_OP_ENV_SIZE(cmpgtu)
1327
IWMMXT_OP_ENV_SIZE(cmpgts)
1328

    
1329
IWMMXT_OP_ENV_SIZE(mins)
1330
IWMMXT_OP_ENV_SIZE(minu)
1331
IWMMXT_OP_ENV_SIZE(maxs)
1332
IWMMXT_OP_ENV_SIZE(maxu)
1333

    
1334
IWMMXT_OP_ENV_SIZE(subn)
1335
IWMMXT_OP_ENV_SIZE(addn)
1336
IWMMXT_OP_ENV_SIZE(subu)
1337
IWMMXT_OP_ENV_SIZE(addu)
1338
IWMMXT_OP_ENV_SIZE(subs)
1339
IWMMXT_OP_ENV_SIZE(adds)
1340

    
1341
IWMMXT_OP_ENV(avgb0)
1342
IWMMXT_OP_ENV(avgb1)
1343
IWMMXT_OP_ENV(avgw0)
1344
IWMMXT_OP_ENV(avgw1)
1345

    
1346
IWMMXT_OP(msadb)
1347

    
1348
IWMMXT_OP_ENV(packuw)
1349
IWMMXT_OP_ENV(packul)
1350
IWMMXT_OP_ENV(packuq)
1351
IWMMXT_OP_ENV(packsw)
1352
IWMMXT_OP_ENV(packsl)
1353
IWMMXT_OP_ENV(packsq)
1354

    
1355
static void gen_op_iwmmxt_set_mup(void)
1356
{
1357
    TCGv_i32 tmp;
1358
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1359
    tcg_gen_ori_i32(tmp, tmp, 2);
1360
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1361
}
1362

    
1363
static void gen_op_iwmmxt_set_cup(void)
1364
{
1365
    TCGv_i32 tmp;
1366
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1367
    tcg_gen_ori_i32(tmp, tmp, 1);
1368
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1369
}
1370

    
1371
static void gen_op_iwmmxt_setpsr_nz(void)
1372
{
1373
    TCGv_i32 tmp = tcg_temp_new_i32();
1374
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1375
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1376
}
1377

    
1378
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1379
{
1380
    iwmmxt_load_reg(cpu_V1, rn);
1381
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1382
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1383
}
1384

    
1385
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1386
                                     TCGv_i32 dest)
1387
{
1388
    int rd;
1389
    uint32_t offset;
1390
    TCGv_i32 tmp;
1391

    
1392
    rd = (insn >> 16) & 0xf;
1393
    tmp = load_reg(s, rd);
1394

    
1395
    offset = (insn & 0xff) << ((insn >> 7) & 2);
1396
    if (insn & (1 << 24)) {
1397
        /* Pre indexed */
1398
        if (insn & (1 << 23))
1399
            tcg_gen_addi_i32(tmp, tmp, offset);
1400
        else
1401
            tcg_gen_addi_i32(tmp, tmp, -offset);
1402
        tcg_gen_mov_i32(dest, tmp);
1403
        if (insn & (1 << 21))
1404
            store_reg(s, rd, tmp);
1405
        else
1406
            tcg_temp_free_i32(tmp);
1407
    } else if (insn & (1 << 21)) {
1408
        /* Post indexed */
1409
        tcg_gen_mov_i32(dest, tmp);
1410
        if (insn & (1 << 23))
1411
            tcg_gen_addi_i32(tmp, tmp, offset);
1412
        else
1413
            tcg_gen_addi_i32(tmp, tmp, -offset);
1414
        store_reg(s, rd, tmp);
1415
    } else if (!(insn & (1 << 23)))
1416
        return 1;
1417
    return 0;
1418
}
1419

    
1420
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1421
{
1422
    int rd = (insn >> 0) & 0xf;
1423
    TCGv_i32 tmp;
1424

    
1425
    if (insn & (1 << 8)) {
1426
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1427
            return 1;
1428
        } else {
1429
            tmp = iwmmxt_load_creg(rd);
1430
        }
1431
    } else {
1432
        tmp = tcg_temp_new_i32();
1433
        iwmmxt_load_reg(cpu_V0, rd);
1434
        tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1435
    }
1436
    tcg_gen_andi_i32(tmp, tmp, mask);
1437
    tcg_gen_mov_i32(dest, tmp);
1438
    tcg_temp_free_i32(tmp);
1439
    return 0;
1440
}
1441

    
1442
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occurred
1443
   (ie. an undefined instruction).  */
1444
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1445
{
1446
    int rd, wrd;
1447
    int rdhi, rdlo, rd0, rd1, i;
1448
    TCGv_i32 addr;
1449
    TCGv_i32 tmp, tmp2, tmp3;
1450

    
1451
    if ((insn & 0x0e000e00) == 0x0c000000) {
1452
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1453
            wrd = insn & 0xf;
1454
            rdlo = (insn >> 12) & 0xf;
1455
            rdhi = (insn >> 16) & 0xf;
1456
            if (insn & ARM_CP_RW_BIT) {                        /* TMRRC */
1457
                iwmmxt_load_reg(cpu_V0, wrd);
1458
                tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1459
                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1460
                tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1461
            } else {                                        /* TMCRR */
1462
                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1463
                iwmmxt_store_reg(cpu_V0, wrd);
1464
                gen_op_iwmmxt_set_mup();
1465
            }
1466
            return 0;
1467
        }
1468

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

    
1534
    if ((insn & 0x0f000000) != 0x0e000000)
1535
        return 1;
1536

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

    
2445
    return 0;
2446
}
2447

    
2448
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occurred
2449
   (ie. an undefined instruction).  */
2450
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2451
{
2452
    int acc, rd0, rd1, rdhi, rdlo;
2453
    TCGv_i32 tmp, tmp2;
2454

    
2455
    if ((insn & 0x0ff00f10) == 0x0e200010) {
2456
        /* Multiply with Internal Accumulate Format */
2457
        rd0 = (insn >> 12) & 0xf;
2458
        rd1 = insn & 0xf;
2459
        acc = (insn >> 5) & 7;
2460

    
2461
        if (acc != 0)
2462
            return 1;
2463

    
2464
        tmp = load_reg(s, rd0);
2465
        tmp2 = load_reg(s, rd1);
2466
        switch ((insn >> 16) & 0xf) {
2467
        case 0x0:                                        /* MIA */
2468
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2469
            break;
2470
        case 0x8:                                        /* MIAPH */
2471
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2472
            break;
2473
        case 0xc:                                        /* MIABB */
2474
        case 0xd:                                        /* MIABT */
2475
        case 0xe:                                        /* MIATB */
2476
        case 0xf:                                        /* MIATT */
2477
            if (insn & (1 << 16))
2478
                tcg_gen_shri_i32(tmp, tmp, 16);
2479
            if (insn & (1 << 17))
2480
                tcg_gen_shri_i32(tmp2, tmp2, 16);
2481
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2482
            break;
2483
        default:
2484
            return 1;
2485
        }
2486
        tcg_temp_free_i32(tmp2);
2487
        tcg_temp_free_i32(tmp);
2488

    
2489
        gen_op_iwmmxt_movq_wRn_M0(acc);
2490
        return 0;
2491
    }
2492

    
2493
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
2494
        /* Internal Accumulator Access Format */
2495
        rdhi = (insn >> 16) & 0xf;
2496
        rdlo = (insn >> 12) & 0xf;
2497
        acc = insn & 7;
2498

    
2499
        if (acc != 0)
2500
            return 1;
2501

    
2502
        if (insn & ARM_CP_RW_BIT) {                        /* MRA */
2503
            iwmmxt_load_reg(cpu_V0, acc);
2504
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2505
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2506
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2507
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2508
        } else {                                        /* MAR */
2509
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2510
            iwmmxt_store_reg(cpu_V0, acc);
2511
        }
2512
        return 0;
2513
    }
2514

    
2515
    return 1;
2516
}
2517

    
2518
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2519
#define VFP_SREG(insn, bigbit, smallbit) \
2520
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2521
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2522
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2523
        reg = (((insn) >> (bigbit)) & 0x0f) \
2524
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
2525
    } else { \
2526
        if (insn & (1 << (smallbit))) \
2527
            return 1; \
2528
        reg = ((insn) >> (bigbit)) & 0x0f; \
2529
    }} while (0)
2530

    
2531
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2532
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2533
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
2534
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
2535
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
2536
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
2537

    
2538
/* Move between integer and VFP cores.  */
2539
static TCGv_i32 gen_vfp_mrs(void)
2540
{
2541
    TCGv_i32 tmp = tcg_temp_new_i32();
2542
    tcg_gen_mov_i32(tmp, cpu_F0s);
2543
    return tmp;
2544
}
2545

    
2546
static void gen_vfp_msr(TCGv_i32 tmp)
2547
{
2548
    tcg_gen_mov_i32(cpu_F0s, tmp);
2549
    tcg_temp_free_i32(tmp);
2550
}
2551

    
2552
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2553
{
2554
    TCGv_i32 tmp = tcg_temp_new_i32();
2555
    if (shift)
2556
        tcg_gen_shri_i32(var, var, shift);
2557
    tcg_gen_ext8u_i32(var, var);
2558
    tcg_gen_shli_i32(tmp, var, 8);
2559
    tcg_gen_or_i32(var, var, tmp);
2560
    tcg_gen_shli_i32(tmp, var, 16);
2561
    tcg_gen_or_i32(var, var, tmp);
2562
    tcg_temp_free_i32(tmp);
2563
}
2564

    
2565
static void gen_neon_dup_low16(TCGv_i32 var)
2566
{
2567
    TCGv_i32 tmp = tcg_temp_new_i32();
2568
    tcg_gen_ext16u_i32(var, var);
2569
    tcg_gen_shli_i32(tmp, var, 16);
2570
    tcg_gen_or_i32(var, var, tmp);
2571
    tcg_temp_free_i32(tmp);
2572
}
2573

    
2574
static void gen_neon_dup_high16(TCGv_i32 var)
2575
{
2576
    TCGv_i32 tmp = tcg_temp_new_i32();
2577
    tcg_gen_andi_i32(var, var, 0xffff0000);
2578
    tcg_gen_shri_i32(tmp, var, 16);
2579
    tcg_gen_or_i32(var, var, tmp);
2580
    tcg_temp_free_i32(tmp);
2581
}
2582

    
2583
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2584
{
2585
    /* Load a single Neon element and replicate into a 32 bit TCG reg */
2586
    TCGv_i32 tmp = tcg_temp_new_i32();
2587
    switch (size) {
2588
    case 0:
2589
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
2590
        gen_neon_dup_u8(tmp, 0);
2591
        break;
2592
    case 1:
2593
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
2594
        gen_neon_dup_low16(tmp);
2595
        break;
2596
    case 2:
2597
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
2598
        break;
2599
    default: /* Avoid compiler warnings.  */
2600
        abort();
2601
    }
2602
    return tmp;
2603
}
2604

    
2605
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2606
                       uint32_t dp)
2607
{
2608
    uint32_t cc = extract32(insn, 20, 2);
2609

    
2610
    if (dp) {
2611
        TCGv_i64 frn, frm, dest;
2612
        TCGv_i64 tmp, zero, zf, nf, vf;
2613

    
2614
        zero = tcg_const_i64(0);
2615

    
2616
        frn = tcg_temp_new_i64();
2617
        frm = tcg_temp_new_i64();
2618
        dest = tcg_temp_new_i64();
2619

    
2620
        zf = tcg_temp_new_i64();
2621
        nf = tcg_temp_new_i64();
2622
        vf = tcg_temp_new_i64();
2623

    
2624
        tcg_gen_extu_i32_i64(zf, cpu_ZF);
2625
        tcg_gen_ext_i32_i64(nf, cpu_NF);
2626
        tcg_gen_ext_i32_i64(vf, cpu_VF);
2627

    
2628
        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2629
        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2630
        switch (cc) {
2631
        case 0: /* eq: Z */
2632
            tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2633
                                frn, frm);
2634
            break;
2635
        case 1: /* vs: V */
2636
            tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2637
                                frn, frm);
2638
            break;
2639
        case 2: /* ge: N == V -> N ^ V == 0 */
2640
            tmp = tcg_temp_new_i64();
2641
            tcg_gen_xor_i64(tmp, vf, nf);
2642
            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2643
                                frn, frm);
2644
            tcg_temp_free_i64(tmp);
2645
            break;
2646
        case 3: /* gt: !Z && N == V */
2647
            tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2648
                                frn, frm);
2649
            tmp = tcg_temp_new_i64();
2650
            tcg_gen_xor_i64(tmp, vf, nf);
2651
            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2652
                                dest, frm);
2653
            tcg_temp_free_i64(tmp);
2654
            break;
2655
        }
2656
        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2657
        tcg_temp_free_i64(frn);
2658
        tcg_temp_free_i64(frm);
2659
        tcg_temp_free_i64(dest);
2660

    
2661
        tcg_temp_free_i64(zf);
2662
        tcg_temp_free_i64(nf);
2663
        tcg_temp_free_i64(vf);
2664

    
2665
        tcg_temp_free_i64(zero);
2666
    } else {
2667
        TCGv_i32 frn, frm, dest;
2668
        TCGv_i32 tmp, zero;
2669

    
2670
        zero = tcg_const_i32(0);
2671

    
2672
        frn = tcg_temp_new_i32();
2673
        frm = tcg_temp_new_i32();
2674
        dest = tcg_temp_new_i32();
2675
        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2676
        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2677
        switch (cc) {
2678
        case 0: /* eq: Z */
2679
            tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2680
                                frn, frm);
2681
            break;
2682
        case 1: /* vs: V */
2683
            tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2684
                                frn, frm);
2685
            break;
2686
        case 2: /* ge: N == V -> N ^ V == 0 */
2687
            tmp = tcg_temp_new_i32();
2688
            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2689
            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2690
                                frn, frm);
2691
            tcg_temp_free_i32(tmp);
2692
            break;
2693
        case 3: /* gt: !Z && N == V */
2694
            tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2695
                                frn, frm);
2696
            tmp = tcg_temp_new_i32();
2697
            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2698
            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2699
                                dest, frm);
2700
            tcg_temp_free_i32(tmp);
2701
            break;
2702
        }
2703
        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2704
        tcg_temp_free_i32(frn);
2705
        tcg_temp_free_i32(frm);
2706
        tcg_temp_free_i32(dest);
2707

    
2708
        tcg_temp_free_i32(zero);
2709
    }
2710

    
2711
    return 0;
2712
}
2713

    
2714
static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2715
                            uint32_t rm, uint32_t dp)
2716
{
2717
    uint32_t vmin = extract32(insn, 6, 1);
2718
    TCGv_ptr fpst = get_fpstatus_ptr(0);
2719

    
2720
    if (dp) {
2721
        TCGv_i64 frn, frm, dest;
2722

    
2723
        frn = tcg_temp_new_i64();
2724
        frm = tcg_temp_new_i64();
2725
        dest = tcg_temp_new_i64();
2726

    
2727
        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2728
        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2729
        if (vmin) {
2730
            gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2731
        } else {
2732
            gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2733
        }
2734
        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2735
        tcg_temp_free_i64(frn);
2736
        tcg_temp_free_i64(frm);
2737
        tcg_temp_free_i64(dest);
2738
    } else {
2739
        TCGv_i32 frn, frm, dest;
2740

    
2741
        frn = tcg_temp_new_i32();
2742
        frm = tcg_temp_new_i32();
2743
        dest = tcg_temp_new_i32();
2744

    
2745
        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2746
        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2747
        if (vmin) {
2748
            gen_helper_vfp_minnums(dest, frn, frm, fpst);
2749
        } else {
2750
            gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2751
        }
2752
        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2753
        tcg_temp_free_i32(frn);
2754
        tcg_temp_free_i32(frm);
2755
        tcg_temp_free_i32(dest);
2756
    }
2757

    
2758
    tcg_temp_free_ptr(fpst);
2759
    return 0;
2760
}
2761

    
2762
static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2763
                        int rounding)
2764
{
2765
    TCGv_ptr fpst = get_fpstatus_ptr(0);
2766
    TCGv_i32 tcg_rmode;
2767

    
2768
    tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2769
    gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2770

    
2771
    if (dp) {
2772
        TCGv_i64 tcg_op;
2773
        TCGv_i64 tcg_res;
2774
        tcg_op = tcg_temp_new_i64();
2775
        tcg_res = tcg_temp_new_i64();
2776
        tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2777
        gen_helper_rintd(tcg_res, tcg_op, fpst);
2778
        tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2779
        tcg_temp_free_i64(tcg_op);
2780
        tcg_temp_free_i64(tcg_res);
2781
    } else {
2782
        TCGv_i32 tcg_op;
2783
        TCGv_i32 tcg_res;
2784
        tcg_op = tcg_temp_new_i32();
2785
        tcg_res = tcg_temp_new_i32();
2786
        tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2787
        gen_helper_rints(tcg_res, tcg_op, fpst);
2788
        tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2789
        tcg_temp_free_i32(tcg_op);
2790
        tcg_temp_free_i32(tcg_res);
2791
    }
2792

    
2793
    gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2794
    tcg_temp_free_i32(tcg_rmode);
2795

    
2796
    tcg_temp_free_ptr(fpst);
2797
    return 0;
2798
}
2799

    
2800
static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2801
                       int rounding)
2802
{
2803
    bool is_signed = extract32(insn, 7, 1);
2804
    TCGv_ptr fpst = get_fpstatus_ptr(0);
2805
    TCGv_i32 tcg_rmode, tcg_shift;
2806

    
2807
    tcg_shift = tcg_const_i32(0);
2808

    
2809
    tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2810
    gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2811

    
2812
    if (dp) {
2813
        TCGv_i64 tcg_double, tcg_res;
2814
        TCGv_i32 tcg_tmp;
2815
        /* Rd is encoded as a single precision register even when the source
2816
         * is double precision.
2817
         */
2818
        rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2819
        tcg_double = tcg_temp_new_i64();
2820
        tcg_res = tcg_temp_new_i64();
2821
        tcg_tmp = tcg_temp_new_i32();
2822
        tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2823
        if (is_signed) {
2824
            gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2825
        } else {
2826
            gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2827
        }
2828
        tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res);
2829
        tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2830
        tcg_temp_free_i32(tcg_tmp);
2831
        tcg_temp_free_i64(tcg_res);
2832
        tcg_temp_free_i64(tcg_double);
2833
    } else {
2834
        TCGv_i32 tcg_single, tcg_res;
2835
        tcg_single = tcg_temp_new_i32();
2836
        tcg_res = tcg_temp_new_i32();
2837
        tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2838
        if (is_signed) {
2839
            gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2840
        } else {
2841
            gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
2842
        }
2843
        tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
2844
        tcg_temp_free_i32(tcg_res);
2845
        tcg_temp_free_i32(tcg_single);
2846
    }
2847

    
2848
    gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2849
    tcg_temp_free_i32(tcg_rmode);
2850

    
2851
    tcg_temp_free_i32(tcg_shift);
2852

    
2853
    tcg_temp_free_ptr(fpst);
2854

    
2855
    return 0;
2856
}
2857

    
2858
/* Table for converting the most common AArch32 encoding of
2859
 * rounding mode to arm_fprounding order (which matches the
2860
 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2861
 */
2862
static const uint8_t fp_decode_rm[] = {
2863
    FPROUNDING_TIEAWAY,
2864
    FPROUNDING_TIEEVEN,
2865
    FPROUNDING_POSINF,
2866
    FPROUNDING_NEGINF,
2867
};
2868

    
2869
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2870
{
2871
    uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2872

    
2873
    if (!arm_feature(env, ARM_FEATURE_V8)) {
2874
        return 1;
2875
    }
2876

    
2877
    if (dp) {
2878
        VFP_DREG_D(rd, insn);
2879
        VFP_DREG_N(rn, insn);
2880
        VFP_DREG_M(rm, insn);
2881
    } else {
2882
        rd = VFP_SREG_D(insn);
2883
        rn = VFP_SREG_N(insn);
2884
        rm = VFP_SREG_M(insn);
2885
    }
2886

    
2887
    if ((insn & 0x0f800e50) == 0x0e000a00) {
2888
        return handle_vsel(insn, rd, rn, rm, dp);
2889
    } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2890
        return handle_vminmaxnm(insn, rd, rn, rm, dp);
2891
    } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
2892
        /* VRINTA, VRINTN, VRINTP, VRINTM */
2893
        int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2894
        return handle_vrint(insn, rd, rm, dp, rounding);
2895
    } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
2896
        /* VCVTA, VCVTN, VCVTP, VCVTM */
2897
        int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2898
        return handle_vcvt(insn, rd, rm, dp, rounding);
2899
    }
2900
    return 1;
2901
}
2902

    
2903
/* Disassemble a VFP instruction.  Returns nonzero if an error occurred
2904
   (ie. an undefined instruction).  */
2905
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2906
{
2907
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2908
    int dp, veclen;
2909
    TCGv_i32 addr;
2910
    TCGv_i32 tmp;
2911
    TCGv_i32 tmp2;
2912

    
2913
    if (!arm_feature(env, ARM_FEATURE_VFP))
2914
        return 1;
2915

    
2916
    if (!s->vfp_enabled) {
2917
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
2918
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
2919
            return 1;
2920
        rn = (insn >> 16) & 0xf;
2921
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2922
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2923
            return 1;
2924
    }
2925

    
2926
    if (extract32(insn, 28, 4) == 0xf) {
2927
        /* Encodings with T=1 (Thumb) or unconditional (ARM):
2928
         * only used in v8 and above.
2929
         */
2930
        return disas_vfp_v8_insn(env, s, insn);
2931
    }
2932

    
2933
    dp = ((insn & 0xf00) == 0xb00);
2934
    switch ((insn >> 24) & 0xf) {
2935
    case 0xe:
2936
        if (insn & (1 << 4)) {
2937
            /* single register transfer */
2938
            rd = (insn >> 12) & 0xf;
2939
            if (dp) {
2940
                int size;
2941
                int pass;
2942

    
2943
                VFP_DREG_N(rn, insn);
2944
                if (insn & 0xf)
2945
                    return 1;
2946
                if (insn & 0x00c00060
2947
                    && !arm_feature(env, ARM_FEATURE_NEON))
2948
                    return 1;
2949

    
2950
                pass = (insn >> 21) & 1;
2951
                if (insn & (1 << 22)) {
2952
                    size = 0;
2953
                    offset = ((insn >> 5) & 3) * 8;
2954
                } else if (insn & (1 << 5)) {
2955
                    size = 1;
2956
                    offset = (insn & (1 << 6)) ? 16 : 0;
2957
                } else {
2958
                    size = 2;
2959
                    offset = 0;
2960
                }
2961
                if (insn & ARM_CP_RW_BIT) {
2962
                    /* vfp->arm */
2963
                    tmp = neon_load_reg(rn, pass);
2964
                    switch (size) {
2965
                    case 0:
2966
                        if (offset)
2967
                            tcg_gen_shri_i32(tmp, tmp, offset);
2968
                        if (insn & (1 << 23))
2969
                            gen_uxtb(tmp);
2970
                        else
2971
                            gen_sxtb(tmp);
2972
                        break;
2973
                    case 1:
2974
                        if (insn & (1 << 23)) {
2975
                            if (offset) {
2976
                                tcg_gen_shri_i32(tmp, tmp, 16);
2977
                            } else {
2978
                                gen_uxth(tmp);
2979
                            }
2980
                        } else {
2981
                            if (offset) {
2982
                                tcg_gen_sari_i32(tmp, tmp, 16);
2983
                            } else {
2984
                                gen_sxth(tmp);
2985
                            }
2986
                        }
2987
                        break;
2988
                    case 2:
2989
                        break;
2990
                    }
2991
                    store_reg(s, rd, tmp);
2992
                } else {
2993
                    /* arm->vfp */
2994
                    tmp = load_reg(s, rd);
2995
                    if (insn & (1 << 23)) {
2996
                        /* VDUP */
2997
                        if (size == 0) {
2998
                            gen_neon_dup_u8(tmp, 0);
2999
                        } else if (size == 1) {
3000
                            gen_neon_dup_low16(tmp);
3001
                        }
3002
                        for (n = 0; n <= pass * 2; n++) {
3003
                            tmp2 = tcg_temp_new_i32();
3004
                            tcg_gen_mov_i32(tmp2, tmp);
3005
                            neon_store_reg(rn, n, tmp2);
3006
                        }
3007
                        neon_store_reg(rn, n, tmp);
3008
                    } else {
3009
                        /* VMOV */
3010
                        switch (size) {
3011
                        case 0:
3012
                            tmp2 = neon_load_reg(rn, pass);
3013
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3014
                            tcg_temp_free_i32(tmp2);
3015
                            break;
3016
                        case 1:
3017
                            tmp2 = neon_load_reg(rn, pass);
3018
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3019
                            tcg_temp_free_i32(tmp2);
3020
                            break;
3021
                        case 2:
3022
                            break;
3023
                        }
3024
                        neon_store_reg(rn, pass, tmp);
3025
                    }
3026
                }
3027
            } else { /* !dp */
3028
                if ((insn & 0x6f) != 0x00)
3029
                    return 1;
3030
                rn = VFP_SREG_N(insn);
3031
                if (insn & ARM_CP_RW_BIT) {
3032
                    /* vfp->arm */
3033
                    if (insn & (1 << 21)) {
3034
                        /* system register */
3035
                        rn >>= 1;
3036

    
3037
                        switch (rn) {
3038
                        case ARM_VFP_FPSID:
3039
                            /* VFP2 allows access to FSID from userspace.
3040
                               VFP3 restricts all id registers to privileged
3041
                               accesses.  */
3042
                            if (IS_USER(s)
3043
                                && arm_feature(env, ARM_FEATURE_VFP3))
3044
                                return 1;
3045
                            tmp = load_cpu_field(vfp.xregs[rn]);
3046
                            break;
3047
                        case ARM_VFP_FPEXC:
3048
                            if (IS_USER(s))
3049
                                return 1;
3050
                            tmp = load_cpu_field(vfp.xregs[rn]);
3051
                            break;
3052
                        case ARM_VFP_FPINST:
3053
                        case ARM_VFP_FPINST2:
3054
                            /* Not present in VFP3.  */
3055
                            if (IS_USER(s)
3056
                                || arm_feature(env, ARM_FEATURE_VFP3))
3057
                                return 1;
3058
                            tmp = load_cpu_field(vfp.xregs[rn]);
3059
                            break;
3060
                        case ARM_VFP_FPSCR:
3061
                            if (rd == 15) {
3062
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3063
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3064
                            } else {
3065
                                tmp = tcg_temp_new_i32();
3066
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
3067
                            }
3068
                            break;
3069
                        case ARM_VFP_MVFR0:
3070
                        case ARM_VFP_MVFR1:
3071
                            if (IS_USER(s)
3072
                                || !arm_feature(env, ARM_FEATURE_MVFR))
3073
                                return 1;
3074
                            tmp = load_cpu_field(vfp.xregs[rn]);
3075
                            break;
3076
                        default:
3077
                            return 1;
3078
                        }
3079
                    } else {
3080
                        gen_mov_F0_vreg(0, rn);
3081
                        tmp = gen_vfp_mrs();
3082
                    }
3083
                    if (rd == 15) {
3084
                        /* Set the 4 flag bits in the CPSR.  */
3085
                        gen_set_nzcv(tmp);
3086
                        tcg_temp_free_i32(tmp);
3087
                    } else {
3088
                        store_reg(s, rd, tmp);
3089
                    }
3090
                } else {
3091
                    /* arm->vfp */
3092
                    if (insn & (1 << 21)) {
3093
                        rn >>= 1;
3094
                        /* system register */
3095
                        switch (rn) {
3096
                        case ARM_VFP_FPSID:
3097
                        case ARM_VFP_MVFR0:
3098
                        case ARM_VFP_MVFR1:
3099
                            /* Writes are ignored.  */
3100
                            break;
3101
                        case ARM_VFP_FPSCR:
3102
                            tmp = load_reg(s, rd);
3103
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
3104
                            tcg_temp_free_i32(tmp);
3105
                            gen_lookup_tb(s);
3106
                            break;
3107
                        case ARM_VFP_FPEXC:
3108
                            if (IS_USER(s))
3109
                                return 1;
3110
                            /* TODO: VFP subarchitecture support.
3111
                             * For now, keep the EN bit only */
3112
                            tmp = load_reg(s, rd);
3113
                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3114
                            store_cpu_field(tmp, vfp.xregs[rn]);
3115
                            gen_lookup_tb(s);
3116
                            break;
3117
                        case ARM_VFP_FPINST:
3118
                        case ARM_VFP_FPINST2:
3119
                            tmp = load_reg(s, rd);
3120
                            store_cpu_field(tmp, vfp.xregs[rn]);
3121
                            break;
3122
                        default:
3123
                            return 1;
3124
                        }
3125
                    } else {
3126
                        tmp = load_reg(s, rd);
3127
                        gen_vfp_msr(tmp);
3128
                        gen_mov_vreg_F0(0, rn);
3129
                    }
3130
                }
3131
            }
3132
        } else {
3133
            /* data processing */
3134
            /* The opcode is in bits 23, 21, 20 and 6.  */
3135
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3136
            if (dp) {
3137
                if (op == 15) {
3138
                    /* rn is opcode */
3139
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3140
                } else {
3141
                    /* rn is register number */
3142
                    VFP_DREG_N(rn, insn);
3143
                }
3144

    
3145
                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3146
                                 ((rn & 0x1e) == 0x6))) {
3147
                    /* Integer or single/half precision destination.  */
3148
                    rd = VFP_SREG_D(insn);
3149
                } else {
3150
                    VFP_DREG_D(rd, insn);
3151
                }
3152
                if (op == 15 &&
3153
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3154
                     ((rn & 0x1e) == 0x4))) {
3155
                    /* VCVT from int or half precision is always from S reg
3156
                     * regardless of dp bit. VCVT with immediate frac_bits
3157
                     * has same format as SREG_M.
3158
                     */
3159
                    rm = VFP_SREG_M(insn);
3160
                } else {
3161
                    VFP_DREG_M(rm, insn);
3162
                }
3163
            } else {
3164
                rn = VFP_SREG_N(insn);
3165
                if (op == 15 && rn == 15) {
3166
                    /* Double precision destination.  */
3167
                    VFP_DREG_D(rd, insn);
3168
                } else {
3169
                    rd = VFP_SREG_D(insn);
3170
                }
3171
                /* NB that we implicitly rely on the encoding for the frac_bits
3172
                 * in VCVT of fixed to float being the same as that of an SREG_M
3173
                 */
3174
                rm = VFP_SREG_M(insn);
3175
            }
3176

    
3177
            veclen = s->vec_len;
3178
            if (op == 15 && rn > 3)
3179
                veclen = 0;
3180

    
3181
            /* Shut up compiler warnings.  */
3182
            delta_m = 0;
3183
            delta_d = 0;
3184
            bank_mask = 0;
3185

    
3186
            if (veclen > 0) {
3187
                if (dp)
3188
                    bank_mask = 0xc;
3189
                else
3190
                    bank_mask = 0x18;
3191

    
3192
                /* Figure out what type of vector operation this is.  */
3193
                if ((rd & bank_mask) == 0) {
3194
                    /* scalar */
3195
                    veclen = 0;
3196
                } else {
3197
                    if (dp)
3198
                        delta_d = (s->vec_stride >> 1) + 1;
3199
                    else
3200
                        delta_d = s->vec_stride + 1;
3201

    
3202
                    if ((rm & bank_mask) == 0) {
3203
                        /* mixed scalar/vector */
3204
                        delta_m = 0;
3205
                    } else {
3206
                        /* vector */
3207
                        delta_m = delta_d;
3208
                    }
3209
                }
3210
            }
3211

    
3212
            /* Load the initial operands.  */
3213
            if (op == 15) {
3214
                switch (rn) {
3215
                case 16:
3216
                case 17:
3217
                    /* Integer source */
3218
                    gen_mov_F0_vreg(0, rm);
3219
                    break;
3220
                case 8:
3221
                case 9:
3222
                    /* Compare */
3223
                    gen_mov_F0_vreg(dp, rd);
3224
                    gen_mov_F1_vreg(dp, rm);
3225
                    break;
3226
                case 10:
3227
                case 11:
3228
                    /* Compare with zero */
3229
                    gen_mov_F0_vreg(dp, rd);
3230
                    gen_vfp_F1_ld0(dp);
3231
                    break;
3232
                case 20:
3233
                case 21:
3234
                case 22:
3235
                case 23:
3236
                case 28:
3237
                case 29:
3238
                case 30:
3239
                case 31:
3240
                    /* Source and destination the same.  */
3241
                    gen_mov_F0_vreg(dp, rd);
3242
                    break;
3243
                case 4:
3244
                case 5:
3245
                case 6:
3246
                case 7:
3247
                    /* VCVTB, VCVTT: only present with the halfprec extension
3248
                     * UNPREDICTABLE if bit 8 is set prior to ARMv8
3249
                     * (we choose to UNDEF)
3250
                     */
3251
                    if ((dp && !arm_feature(env, ARM_FEATURE_V8)) ||
3252
                        !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3253
                        return 1;
3254
                    }
3255
                    if (!extract32(rn, 1, 1)) {
3256
                        /* Half precision source.  */
3257
                        gen_mov_F0_vreg(0, rm);
3258
                        break;
3259
                    }
3260
                    /* Otherwise fall through */
3261
                default:
3262
                    /* One source operand.  */
3263
                    gen_mov_F0_vreg(dp, rm);
3264
                    break;
3265
                }
3266
            } else {
3267
                /* Two source operands.  */
3268
                gen_mov_F0_vreg(dp, rn);
3269
                gen_mov_F1_vreg(dp, rm);
3270
            }
3271

    
3272
            for (;;) {
3273
                /* Perform the calculation.  */
3274
                switch (op) {
3275
                case 0: /* VMLA: fd + (fn * fm) */
3276
                    /* Note that order of inputs to the add matters for NaNs */
3277
                    gen_vfp_F1_mul(dp);
3278
                    gen_mov_F0_vreg(dp, rd);
3279
                    gen_vfp_add(dp);
3280
                    break;
3281
                case 1: /* VMLS: fd + -(fn * fm) */
3282
                    gen_vfp_mul(dp);
3283
                    gen_vfp_F1_neg(dp);
3284
                    gen_mov_F0_vreg(dp, rd);
3285
                    gen_vfp_add(dp);
3286
                    break;
3287
                case 2: /* VNMLS: -fd + (fn * fm) */
3288
                    /* Note that it isn't valid to replace (-A + B) with (B - A)
3289
                     * or similar plausible looking simplifications
3290
                     * because this will give wrong results for NaNs.
3291
                     */
3292
                    gen_vfp_F1_mul(dp);
3293
                    gen_mov_F0_vreg(dp, rd);
3294
                    gen_vfp_neg(dp);
3295
                    gen_vfp_add(dp);
3296
                    break;
3297
                case 3: /* VNMLA: -fd + -(fn * fm) */
3298
                    gen_vfp_mul(dp);
3299
                    gen_vfp_F1_neg(dp);
3300
                    gen_mov_F0_vreg(dp, rd);
3301
                    gen_vfp_neg(dp);
3302
                    gen_vfp_add(dp);
3303
                    break;
3304
                case 4: /* mul: fn * fm */
3305
                    gen_vfp_mul(dp);
3306
                    break;
3307
                case 5: /* nmul: -(fn * fm) */
3308
                    gen_vfp_mul(dp);
3309
                    gen_vfp_neg(dp);
3310
                    break;
3311
                case 6: /* add: fn + fm */
3312
                    gen_vfp_add(dp);
3313
                    break;
3314
                case 7: /* sub: fn - fm */
3315
                    gen_vfp_sub(dp);
3316
                    break;
3317
                case 8: /* div: fn / fm */
3318
                    gen_vfp_div(dp);
3319
                    break;
3320
                case 10: /* VFNMA : fd = muladd(-fd,  fn, fm) */
3321
                case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3322
                case 12: /* VFMA  : fd = muladd( fd,  fn, fm) */
3323
                case 13: /* VFMS  : fd = muladd( fd, -fn, fm) */
3324
                    /* These are fused multiply-add, and must be done as one
3325
                     * floating point operation with no rounding between the
3326
                     * multiplication and addition steps.
3327
                     * NB that doing the negations here as separate steps is
3328
                     * correct : an input NaN should come out with its sign bit
3329
                     * flipped if it is a negated-input.
3330
                     */
3331
                    if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3332
                        return 1;
3333
                    }
3334
                    if (dp) {
3335
                        TCGv_ptr fpst;
3336
                        TCGv_i64 frd;
3337
                        if (op & 1) {
3338
                            /* VFNMS, VFMS */
3339
                            gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3340
                        }
3341
                        frd = tcg_temp_new_i64();
3342
                        tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3343
                        if (op & 2) {
3344
                            /* VFNMA, VFNMS */
3345
                            gen_helper_vfp_negd(frd, frd);
3346
                        }
3347
                        fpst = get_fpstatus_ptr(0);
3348
                        gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3349
                                               cpu_F1d, frd, fpst);
3350
                        tcg_temp_free_ptr(fpst);
3351
                        tcg_temp_free_i64(frd);
3352
                    } else {
3353
                        TCGv_ptr fpst;
3354
                        TCGv_i32 frd;
3355
                        if (op & 1) {
3356
                            /* VFNMS, VFMS */
3357
                            gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3358
                        }
3359
                        frd = tcg_temp_new_i32();
3360
                        tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3361
                        if (op & 2) {
3362
                            gen_helper_vfp_negs(frd, frd);
3363
                        }
3364
                        fpst = get_fpstatus_ptr(0);
3365
                        gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3366
                                               cpu_F1s, frd, fpst);
3367
                        tcg_temp_free_ptr(fpst);
3368
                        tcg_temp_free_i32(frd);
3369
                    }
3370
                    break;
3371
                case 14: /* fconst */
3372
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3373
                      return 1;
3374

    
3375
                    n = (insn << 12) & 0x80000000;
3376
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3377
                    if (dp) {
3378
                        if (i & 0x40)
3379
                            i |= 0x3f80;
3380
                        else
3381
                            i |= 0x4000;
3382
                        n |= i << 16;
3383
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3384
                    } else {
3385
                        if (i & 0x40)
3386
                            i |= 0x780;
3387
                        else
3388
                            i |= 0x800;
3389
                        n |= i << 19;
3390
                        tcg_gen_movi_i32(cpu_F0s, n);
3391
                    }
3392
                    break;
3393
                case 15: /* extension space */
3394
                    switch (rn) {
3395
                    case 0: /* cpy */
3396
                        /* no-op */
3397
                        break;
3398
                    case 1: /* abs */
3399
                        gen_vfp_abs(dp);
3400
                        break;
3401
                    case 2: /* neg */
3402
                        gen_vfp_neg(dp);
3403
                        break;
3404
                    case 3: /* sqrt */
3405
                        gen_vfp_sqrt(dp);
3406
                        break;
3407
                    case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3408
                        tmp = gen_vfp_mrs();
3409
                        tcg_gen_ext16u_i32(tmp, tmp);
3410
                        if (dp) {
3411
                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3412
                                                           cpu_env);
3413
                        } else {
3414
                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3415
                                                           cpu_env);
3416
                        }
3417
                        tcg_temp_free_i32(tmp);
3418
                        break;
3419
                    case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3420
                        tmp = gen_vfp_mrs();
3421
                        tcg_gen_shri_i32(tmp, tmp, 16);
3422
                        if (dp) {
3423
                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3424
                                                           cpu_env);
3425
                        } else {
3426
                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3427
                                                           cpu_env);
3428
                        }
3429
                        tcg_temp_free_i32(tmp);
3430
                        break;
3431
                    case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3432
                        tmp = tcg_temp_new_i32();
3433
                        if (dp) {
3434
                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3435
                                                           cpu_env);
3436
                        } else {
3437
                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3438
                                                           cpu_env);
3439
                        }
3440
                        gen_mov_F0_vreg(0, rd);
3441
                        tmp2 = gen_vfp_mrs();
3442
                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3443
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3444
                        tcg_temp_free_i32(tmp2);
3445
                        gen_vfp_msr(tmp);
3446
                        break;
3447
                    case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3448
                        tmp = tcg_temp_new_i32();
3449
                        if (dp) {
3450
                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3451
                                                           cpu_env);
3452
                        } else {
3453
                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3454
                                                           cpu_env);
3455
                        }
3456
                        tcg_gen_shli_i32(tmp, tmp, 16);
3457
                        gen_mov_F0_vreg(0, rd);
3458
                        tmp2 = gen_vfp_mrs();
3459
                        tcg_gen_ext16u_i32(tmp2, tmp2);
3460
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3461
                        tcg_temp_free_i32(tmp2);
3462
                        gen_vfp_msr(tmp);
3463
                        break;
3464
                    case 8: /* cmp */
3465
                        gen_vfp_cmp(dp);
3466
                        break;
3467
                    case 9: /* cmpe */
3468
                        gen_vfp_cmpe(dp);
3469
                        break;
3470
                    case 10: /* cmpz */
3471
                        gen_vfp_cmp(dp);
3472
                        break;
3473
                    case 11: /* cmpez */
3474
                        gen_vfp_F1_ld0(dp);
3475
                        gen_vfp_cmpe(dp);
3476
                        break;
3477
                    case 12: /* vrintr */
3478
                    {
3479
                        TCGv_ptr fpst = get_fpstatus_ptr(0);
3480
                        if (dp) {
3481
                            gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3482
                        } else {
3483
                            gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3484
                        }
3485
                        tcg_temp_free_ptr(fpst);
3486
                        break;
3487
                    }
3488
                    case 13: /* vrintz */
3489
                    {
3490
                        TCGv_ptr fpst = get_fpstatus_ptr(0);
3491
                        TCGv_i32 tcg_rmode;
3492
                        tcg_rmode = tcg_const_i32(float_round_to_zero);
3493
                        gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3494
                        if (dp) {
3495
                            gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3496
                        } else {
3497
                            gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3498
                        }
3499
                        gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3500
                        tcg_temp_free_i32(tcg_rmode);
3501
                        tcg_temp_free_ptr(fpst);
3502
                        break;
3503
                    }
3504
                    case 14: /* vrintx */
3505
                    {
3506
                        TCGv_ptr fpst = get_fpstatus_ptr(0);
3507
                        if (dp) {
3508
                            gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3509
                        } else {
3510
                            gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3511
                        }
3512
                        tcg_temp_free_ptr(fpst);
3513
                        break;
3514
                    }
3515
                    case 15: /* single<->double conversion */
3516
                        if (dp)
3517
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3518
                        else
3519
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3520
                        break;
3521
                    case 16: /* fuito */
3522
                        gen_vfp_uito(dp, 0);
3523
                        break;
3524
                    case 17: /* fsito */
3525
                        gen_vfp_sito(dp, 0);
3526
                        break;
3527
                    case 20: /* fshto */
3528
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3529
                          return 1;
3530
                        gen_vfp_shto(dp, 16 - rm, 0);
3531
                        break;
3532
                    case 21: /* fslto */
3533
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3534
                          return 1;
3535
                        gen_vfp_slto(dp, 32 - rm, 0);
3536
                        break;
3537
                    case 22: /* fuhto */
3538
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3539
                          return 1;
3540
                        gen_vfp_uhto(dp, 16 - rm, 0);
3541
                        break;
3542
                    case 23: /* fulto */
3543
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3544
                          return 1;
3545
                        gen_vfp_ulto(dp, 32 - rm, 0);
3546
                        break;
3547
                    case 24: /* ftoui */
3548
                        gen_vfp_toui(dp, 0);
3549
                        break;
3550
                    case 25: /* ftouiz */
3551
                        gen_vfp_touiz(dp, 0);
3552
                        break;
3553
                    case 26: /* ftosi */
3554
                        gen_vfp_tosi(dp, 0);
3555
                        break;
3556
                    case 27: /* ftosiz */
3557
                        gen_vfp_tosiz(dp, 0);
3558
                        break;
3559
                    case 28: /* ftosh */
3560
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3561
                          return 1;
3562
                        gen_vfp_tosh(dp, 16 - rm, 0);
3563
                        break;
3564
                    case 29: /* ftosl */
3565
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3566
                          return 1;
3567
                        gen_vfp_tosl(dp, 32 - rm, 0);
3568
                        break;
3569
                    case 30: /* ftouh */
3570
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3571
                          return 1;
3572
                        gen_vfp_touh(dp, 16 - rm, 0);
3573
                        break;
3574
                    case 31: /* ftoul */
3575
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3576
                          return 1;
3577
                        gen_vfp_toul(dp, 32 - rm, 0);
3578
                        break;
3579
                    default: /* undefined */
3580
                        return 1;
3581
                    }
3582
                    break;
3583
                default: /* undefined */
3584
                    return 1;
3585
                }
3586

    
3587
                /* Write back the result.  */
3588
                if (op == 15 && (rn >= 8 && rn <= 11)) {
3589
                    /* Comparison, do nothing.  */
3590
                } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3591
                                              (rn & 0x1e) == 0x6)) {
3592
                    /* VCVT double to int: always integer result.
3593
                     * VCVT double to half precision is always a single
3594
                     * precision result.
3595
                     */
3596
                    gen_mov_vreg_F0(0, rd);
3597
                } else if (op == 15 && rn == 15) {
3598
                    /* conversion */
3599
                    gen_mov_vreg_F0(!dp, rd);
3600
                } else {
3601
                    gen_mov_vreg_F0(dp, rd);
3602
                }
3603

    
3604
                /* break out of the loop if we have finished  */
3605
                if (veclen == 0)
3606
                    break;
3607

    
3608
                if (op == 15 && delta_m == 0) {
3609
                    /* single source one-many */
3610
                    while (veclen--) {
3611
                        rd = ((rd + delta_d) & (bank_mask - 1))
3612
                             | (rd & bank_mask);
3613
                        gen_mov_vreg_F0(dp, rd);
3614
                    }
3615
                    break;
3616
                }
3617
                /* Setup the next operands.  */
3618
                veclen--;
3619
                rd = ((rd + delta_d) & (bank_mask - 1))
3620
                     | (rd & bank_mask);
3621

    
3622
                if (op == 15) {
3623
                    /* One source operand.  */
3624
                    rm = ((rm + delta_m) & (bank_mask - 1))
3625
                         | (rm & bank_mask);
3626
                    gen_mov_F0_vreg(dp, rm);
3627
                } else {
3628
                    /* Two source operands.  */
3629
                    rn = ((rn + delta_d) & (bank_mask - 1))
3630
                         | (rn & bank_mask);
3631
                    gen_mov_F0_vreg(dp, rn);
3632
                    if (delta_m) {
3633
                        rm = ((rm + delta_m) & (bank_mask - 1))
3634
                             | (rm & bank_mask);
3635
                        gen_mov_F1_vreg(dp, rm);
3636
                    }
3637
                }
3638
            }
3639
        }
3640
        break;
3641
    case 0xc:
3642
    case 0xd:
3643
        if ((insn & 0x03e00000) == 0x00400000) {
3644
            /* two-register transfer */
3645
            rn = (insn >> 16) & 0xf;
3646
            rd = (insn >> 12) & 0xf;
3647
            if (dp) {
3648
                VFP_DREG_M(rm, insn);
3649
            } else {
3650
                rm = VFP_SREG_M(insn);
3651
            }
3652

    
3653
            if (insn & ARM_CP_RW_BIT) {
3654
                /* vfp->arm */
3655
                if (dp) {
3656
                    gen_mov_F0_vreg(0, rm * 2);
3657
                    tmp = gen_vfp_mrs();
3658
                    store_reg(s, rd, tmp);
3659
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3660
                    tmp = gen_vfp_mrs();
3661
                    store_reg(s, rn, tmp);
3662
                } else {
3663
                    gen_mov_F0_vreg(0, rm);
3664
                    tmp = gen_vfp_mrs();
3665
                    store_reg(s, rd, tmp);
3666
                    gen_mov_F0_vreg(0, rm + 1);
3667
                    tmp = gen_vfp_mrs();
3668
                    store_reg(s, rn, tmp);
3669
                }
3670
            } else {
3671
                /* arm->vfp */
3672
                if (dp) {
3673
                    tmp = load_reg(s, rd);
3674
                    gen_vfp_msr(tmp);
3675
                    gen_mov_vreg_F0(0, rm * 2);
3676
                    tmp = load_reg(s, rn);
3677
                    gen_vfp_msr(tmp);
3678
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3679
                } else {
3680
                    tmp = load_reg(s, rd);
3681
                    gen_vfp_msr(tmp);
3682
                    gen_mov_vreg_F0(0, rm);
3683
                    tmp = load_reg(s, rn);
3684
                    gen_vfp_msr(tmp);
3685
                    gen_mov_vreg_F0(0, rm + 1);
3686
                }
3687
            }
3688
        } else {
3689
            /* Load/store */
3690
            rn = (insn >> 16) & 0xf;
3691
            if (dp)
3692
                VFP_DREG_D(rd, insn);
3693
            else
3694
                rd = VFP_SREG_D(insn);
3695
            if ((insn & 0x01200000) == 0x01000000) {
3696
                /* Single load/store */
3697
                offset = (insn & 0xff) << 2;
3698
                if ((insn & (1 << 23)) == 0)
3699
                    offset = -offset;
3700
                if (s->thumb && rn == 15) {
3701
                    /* This is actually UNPREDICTABLE */
3702
                    addr = tcg_temp_new_i32();
3703
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3704
                } else {
3705
                    addr = load_reg(s, rn);
3706
                }
3707
                tcg_gen_addi_i32(addr, addr, offset);
3708
                if (insn & (1 << 20)) {
3709
                    gen_vfp_ld(s, dp, addr);
3710
                    gen_mov_vreg_F0(dp, rd);
3711
                } else {
3712
                    gen_mov_F0_vreg(dp, rd);
3713
                    gen_vfp_st(s, dp, addr);
3714
                }
3715
                tcg_temp_free_i32(addr);
3716
            } else {
3717
                /* load/store multiple */
3718
                int w = insn & (1 << 21);
3719
                if (dp)
3720
                    n = (insn >> 1) & 0x7f;
3721
                else
3722
                    n = insn & 0xff;
3723

    
3724
                if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3725
                    /* P == U , W == 1  => UNDEF */
3726
                    return 1;
3727
                }
3728
                if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3729
                    /* UNPREDICTABLE cases for bad immediates: we choose to
3730
                     * UNDEF to avoid generating huge numbers of TCG ops
3731
                     */
3732
                    return 1;
3733
                }
3734
                if (rn == 15 && w) {
3735
                    /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3736
                    return 1;
3737
                }
3738

    
3739
                if (s->thumb && rn == 15) {
3740
                    /* This is actually UNPREDICTABLE */
3741
                    addr = tcg_temp_new_i32();
3742
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3743
                } else {
3744
                    addr = load_reg(s, rn);
3745
                }
3746
                if (insn & (1 << 24)) /* pre-decrement */
3747
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3748

    
3749
                if (dp)
3750
                    offset = 8;
3751
                else
3752
                    offset = 4;
3753
                for (i = 0; i < n; i++) {
3754
                    if (insn & ARM_CP_RW_BIT) {
3755
                        /* load */
3756
                        gen_vfp_ld(s, dp, addr);
3757
                        gen_mov_vreg_F0(dp, rd + i);
3758
                    } else {
3759
                        /* store */
3760
                        gen_mov_F0_vreg(dp, rd + i);
3761
                        gen_vfp_st(s, dp, addr);
3762
                    }
3763
                    tcg_gen_addi_i32(addr, addr, offset);
3764
                }
3765
                if (w) {
3766
                    /* writeback */
3767
                    if (insn & (1 << 24))
3768
                        offset = -offset * n;
3769
                    else if (dp && (insn & 1))
3770
                        offset = 4;
3771
                    else
3772
                        offset = 0;
3773

    
3774
                    if (offset != 0)
3775
                        tcg_gen_addi_i32(addr, addr, offset);
3776
                    store_reg(s, rn, addr);
3777
                } else {
3778
                    tcg_temp_free_i32(addr);
3779
                }
3780
            }
3781
        }
3782
        break;
3783
    default:
3784
        /* Should never happen.  */
3785
        return 1;
3786
    }
3787
    return 0;
3788
}
3789

    
3790
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3791
{
3792
    TranslationBlock *tb;
3793

    
3794
    tb = s->tb;
3795
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3796
        tcg_gen_goto_tb(n);
3797
        gen_set_pc_im(s, dest);
3798
        tcg_gen_exit_tb((uintptr_t)tb + n);
3799
    } else {
3800
        gen_set_pc_im(s, dest);
3801
        tcg_gen_exit_tb(0);
3802
    }
3803
}
3804

    
3805
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3806
{
3807
    if (unlikely(s->singlestep_enabled)) {
3808
        /* An indirect jump so that we still trigger the debug exception.  */
3809
        if (s->thumb)
3810
            dest |= 1;
3811
        gen_bx_im(s, dest);
3812
    } else {
3813
        gen_goto_tb(s, 0, dest);
3814
        s->is_jmp = DISAS_TB_JUMP;
3815
    }
3816
}
3817

    
3818
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3819
{
3820
    if (x)
3821
        tcg_gen_sari_i32(t0, t0, 16);
3822
    else
3823
        gen_sxth(t0);
3824
    if (y)
3825
        tcg_gen_sari_i32(t1, t1, 16);
3826
    else
3827
        gen_sxth(t1);
3828
    tcg_gen_mul_i32(t0, t0, t1);
3829
}
3830

    
3831
/* Return the mask of PSR bits set by a MSR instruction.  */
3832
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3833
    uint32_t mask;
3834

    
3835
    mask = 0;
3836
    if (flags & (1 << 0))
3837
        mask |= 0xff;
3838
    if (flags & (1 << 1))
3839
        mask |= 0xff00;
3840
    if (flags & (1 << 2))
3841
        mask |= 0xff0000;
3842
    if (flags & (1 << 3))
3843
        mask |= 0xff000000;
3844

    
3845
    /* Mask out undefined bits.  */
3846
    mask &= ~CPSR_RESERVED;
3847
    if (!arm_feature(env, ARM_FEATURE_V4T))
3848
        mask &= ~CPSR_T;
3849
    if (!arm_feature(env, ARM_FEATURE_V5))
3850
        mask &= ~CPSR_Q; /* V5TE in reality*/
3851
    if (!arm_feature(env, ARM_FEATURE_V6))
3852
        mask &= ~(CPSR_E | CPSR_GE);
3853
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3854
        mask &= ~CPSR_IT;
3855
    /* Mask out execution state bits.  */
3856
    if (!spsr)
3857
        mask &= ~CPSR_EXEC;
3858
    /* Mask out privileged bits.  */
3859
    if (IS_USER(s))
3860
        mask &= CPSR_USER;
3861
    return mask;
3862
}
3863

    
3864
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3865
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3866
{
3867
    TCGv_i32 tmp;
3868
    if (spsr) {
3869
        /* ??? This is also undefined in system mode.  */
3870
        if (IS_USER(s))
3871
            return 1;
3872

    
3873
        tmp = load_cpu_field(spsr);
3874
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3875
        tcg_gen_andi_i32(t0, t0, mask);
3876
        tcg_gen_or_i32(tmp, tmp, t0);
3877
        store_cpu_field(tmp, spsr);
3878
    } else {
3879
        gen_set_cpsr(t0, mask);
3880
    }
3881
    tcg_temp_free_i32(t0);
3882
    gen_lookup_tb(s);
3883
    return 0;
3884
}
3885

    
3886
/* Returns nonzero if access to the PSR is not permitted.  */
3887
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3888
{
3889
    TCGv_i32 tmp;
3890
    tmp = tcg_temp_new_i32();
3891
    tcg_gen_movi_i32(tmp, val);
3892
    return gen_set_psr(s, mask, spsr, tmp);
3893
}
3894

    
3895
/* Generate an old-style exception return. Marks pc as dead. */
3896
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3897
{
3898
    TCGv_i32 tmp;
3899
    store_reg(s, 15, pc);
3900
    tmp = load_cpu_field(spsr);
3901
    gen_set_cpsr(tmp, 0xffffffff);
3902
    tcg_temp_free_i32(tmp);
3903
    s->is_jmp = DISAS_UPDATE;
3904
}
3905

    
3906
/* Generate a v6 exception return.  Marks both values as dead.  */
3907
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3908
{
3909
    gen_set_cpsr(cpsr, 0xffffffff);
3910
    tcg_temp_free_i32(cpsr);
3911
    store_reg(s, 15, pc);
3912
    s->is_jmp = DISAS_UPDATE;
3913
}
3914

    
3915
static inline void
3916
gen_set_condexec (DisasContext *s)
3917
{
3918
    if (s->condexec_mask) {
3919
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3920
        TCGv_i32 tmp = tcg_temp_new_i32();
3921
        tcg_gen_movi_i32(tmp, val);
3922
        store_cpu_field(tmp, condexec_bits);
3923
    }
3924
}
3925

    
3926
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3927
{
3928
    gen_set_condexec(s);
3929
    gen_set_pc_im(s, s->pc - offset);
3930
    gen_exception(excp);
3931
    s->is_jmp = DISAS_JUMP;
3932
}
3933

    
3934
static void gen_nop_hint(DisasContext *s, int val)
3935
{
3936
    switch (val) {
3937
    case 3: /* wfi */
3938
        gen_set_pc_im(s, s->pc);
3939
        s->is_jmp = DISAS_WFI;
3940
        break;
3941
    case 2: /* wfe */
3942
    case 4: /* sev */
3943
    case 5: /* sevl */
3944
        /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */
3945
    default: /* nop */
3946
        break;
3947
    }
3948
}
3949

    
3950
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3951

    
3952
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3953
{
3954
    switch (size) {
3955
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3956
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3957
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3958
    default: abort();
3959
    }
3960
}
3961

    
3962
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3963
{
3964
    switch (size) {
3965
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3966
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3967
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3968
    default: return;
3969
    }
3970
}
3971

    
3972
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3973
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3974
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3975
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3976
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3977

    
3978
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3979
    switch ((size << 1) | u) { \
3980
    case 0: \
3981
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3982
        break; \
3983
    case 1: \
3984
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3985
        break; \
3986
    case 2: \
3987
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3988
        break; \
3989
    case 3: \
3990
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3991
        break; \
3992
    case 4: \
3993
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3994
        break; \
3995
    case 5: \
3996
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3997
        break; \
3998
    default: return 1; \
3999
    }} while (0)
4000

    
4001
#define GEN_NEON_INTEGER_OP(name) do { \
4002
    switch ((size << 1) | u) { \
4003
    case 0: \
4004
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4005
        break; \
4006
    case 1: \
4007
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4008
        break; \
4009
    case 2: \
4010
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4011
        break; \
4012
    case 3: \
4013
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4014
        break; \
4015
    case 4: \
4016
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4017
        break; \
4018
    case 5: \
4019
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4020
        break; \
4021
    default: return 1; \
4022
    }} while (0)
4023

    
4024
static TCGv_i32 neon_load_scratch(int scratch)
4025
{
4026
    TCGv_i32 tmp = tcg_temp_new_i32();
4027
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4028
    return tmp;
4029
}
4030

    
4031
static void neon_store_scratch(int scratch, TCGv_i32 var)
4032
{
4033
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4034
    tcg_temp_free_i32(var);
4035
}
4036

    
4037
static inline TCGv_i32 neon_get_scalar(int size, int reg)
4038
{
4039
    TCGv_i32 tmp;
4040
    if (size == 1) {
4041
        tmp = neon_load_reg(reg & 7, reg >> 4);
4042
        if (reg & 8) {
4043
            gen_neon_dup_high16(tmp);
4044
        } else {
4045
            gen_neon_dup_low16(tmp);
4046
        }
4047
    } else {
4048
        tmp = neon_load_reg(reg & 15, reg >> 4);
4049
    }
4050
    return tmp;
4051
}
4052

    
4053
static int gen_neon_unzip(int rd, int rm, int size, int q)
4054
{
4055
    TCGv_i32 tmp, tmp2;
4056
    if (!q && size == 2) {
4057
        return 1;
4058
    }
4059
    tmp = tcg_const_i32(rd);
4060
    tmp2 = tcg_const_i32(rm);
4061
    if (q) {
4062
        switch (size) {
4063
        case 0:
4064
            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4065
            break;
4066
        case 1:
4067
            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4068
            break;
4069
        case 2:
4070
            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4071
            break;
4072
        default:
4073
            abort();
4074
        }
4075
    } else {
4076
        switch (size) {
4077
        case 0:
4078
            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4079
            break;
4080
        case 1:
4081
            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4082
            break;
4083
        default:
4084
            abort();
4085
        }
4086
    }
4087
    tcg_temp_free_i32(tmp);
4088
    tcg_temp_free_i32(tmp2);
4089
    return 0;
4090
}
4091

    
4092
static int gen_neon_zip(int rd, int rm, int size, int q)
4093
{
4094
    TCGv_i32 tmp, tmp2;
4095
    if (!q && size == 2) {
4096
        return 1;
4097
    }
4098
    tmp = tcg_const_i32(rd);
4099
    tmp2 = tcg_const_i32(rm);
4100
    if (q) {
4101
        switch (size) {
4102
        case 0:
4103
            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4104
            break;
4105
        case 1:
4106
            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4107
            break;
4108
        case 2:
4109
            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4110
            break;
4111
        default:
4112
            abort();
4113
        }
4114
    } else {
4115
        switch (size) {
4116
        case 0:
4117
            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4118
            break;
4119
        case 1:
4120
            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4121
            break;
4122
        default:
4123
            abort();
4124
        }
4125
    }
4126
    tcg_temp_free_i32(tmp);
4127
    tcg_temp_free_i32(tmp2);
4128
    return 0;
4129
}
4130

    
4131
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4132
{
4133
    TCGv_i32 rd, tmp;
4134

    
4135
    rd = tcg_temp_new_i32();
4136
    tmp = tcg_temp_new_i32();
4137

    
4138
    tcg_gen_shli_i32(rd, t0, 8);
4139
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4140
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4141
    tcg_gen_or_i32(rd, rd, tmp);
4142

    
4143
    tcg_gen_shri_i32(t1, t1, 8);
4144
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4145
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4146
    tcg_gen_or_i32(t1, t1, tmp);
4147
    tcg_gen_mov_i32(t0, rd);
4148

    
4149
    tcg_temp_free_i32(tmp);
4150
    tcg_temp_free_i32(rd);
4151
}
4152

    
4153
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4154
{
4155
    TCGv_i32 rd, tmp;
4156

    
4157
    rd = tcg_temp_new_i32();
4158
    tmp = tcg_temp_new_i32();
4159

    
4160
    tcg_gen_shli_i32(rd, t0, 16);
4161
    tcg_gen_andi_i32(tmp, t1, 0xffff);
4162
    tcg_gen_or_i32(rd, rd, tmp);
4163
    tcg_gen_shri_i32(t1, t1, 16);
4164
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4165
    tcg_gen_or_i32(t1, t1, tmp);
4166
    tcg_gen_mov_i32(t0, rd);
4167

    
4168
    tcg_temp_free_i32(tmp);
4169
    tcg_temp_free_i32(rd);
4170
}
4171

    
4172

    
4173
static struct {
4174
    int nregs;
4175
    int interleave;
4176
    int spacing;
4177
} neon_ls_element_type[11] = {
4178
    {4, 4, 1},
4179
    {4, 4, 2},
4180
    {4, 1, 1},
4181
    {4, 2, 1},
4182
    {3, 3, 1},
4183
    {3, 3, 2},
4184
    {3, 1, 1},
4185
    {1, 1, 1},
4186
    {2, 2, 1},
4187
    {2, 2, 2},
4188
    {2, 1, 1}
4189
};
4190

    
4191
/* Translate a NEON load/store element instruction.  Return nonzero if the
4192
   instruction is invalid.  */
4193
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4194
{
4195
    int rd, rn, rm;
4196
    int op;
4197
    int nregs;
4198
    int interleave;
4199
    int spacing;
4200
    int stride;
4201
    int size;
4202
    int reg;
4203
    int pass;
4204
    int load;
4205
    int shift;
4206
    int n;
4207
    TCGv_i32 addr;
4208
    TCGv_i32 tmp;
4209
    TCGv_i32 tmp2;
4210
    TCGv_i64 tmp64;
4211

    
4212
    if (!s->vfp_enabled)
4213
      return 1;
4214
    VFP_DREG_D(rd, insn);
4215
    rn = (insn >> 16) & 0xf;
4216
    rm = insn & 0xf;
4217
    load = (insn & (1 << 21)) != 0;
4218
    if ((insn & (1 << 23)) == 0) {
4219
        /* Load store all elements.  */
4220
        op = (insn >> 8) & 0xf;
4221
        size = (insn >> 6) & 3;
4222
        if (op > 10)
4223
            return 1;
4224
        /* Catch UNDEF cases for bad values of align field */
4225
        switch (op & 0xc) {
4226
        case 4:
4227
            if (((insn >> 5) & 1) == 1) {
4228
                return 1;
4229
            }
4230
            break;
4231
        case 8:
4232
            if (((insn >> 4) & 3) == 3) {
4233
                return 1;
4234
            }
4235
            break;
4236
        default:
4237
            break;
4238
        }
4239
        nregs = neon_ls_element_type[op].nregs;
4240
        interleave = neon_ls_element_type[op].interleave;
4241
        spacing = neon_ls_element_type[op].spacing;
4242
        if (size == 3 && (interleave | spacing) != 1)
4243
            return 1;
4244
        addr = tcg_temp_new_i32();
4245
        load_reg_var(s, addr, rn);
4246
        stride = (1 << size) * interleave;
4247
        for (reg = 0; reg < nregs; reg++) {
4248
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4249
                load_reg_var(s, addr, rn);
4250
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4251
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
4252
                load_reg_var(s, addr, rn);
4253
                tcg_gen_addi_i32(addr, addr, 1 << size);
4254
            }
4255
            if (size == 3) {
4256
                tmp64 = tcg_temp_new_i64();
4257
                if (load) {
4258
                    gen_aa32_ld64(tmp64, addr, IS_USER(s));
4259
                    neon_store_reg64(tmp64, rd);
4260
                } else {
4261
                    neon_load_reg64(tmp64, rd);
4262
                    gen_aa32_st64(tmp64, addr, IS_USER(s));
4263
                }
4264
                tcg_temp_free_i64(tmp64);
4265
                tcg_gen_addi_i32(addr, addr, stride);
4266
            } else {
4267
                for (pass = 0; pass < 2; pass++) {
4268
                    if (size == 2) {
4269
                        if (load) {
4270
                            tmp = tcg_temp_new_i32();
4271
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
4272
                            neon_store_reg(rd, pass, tmp);
4273
                        } else {
4274
                            tmp = neon_load_reg(rd, pass);
4275
                            gen_aa32_st32(tmp, addr, IS_USER(s));
4276
                            tcg_temp_free_i32(tmp);
4277
                        }
4278
                        tcg_gen_addi_i32(addr, addr, stride);
4279
                    } else if (size == 1) {
4280
                        if (load) {
4281
                            tmp = tcg_temp_new_i32();
4282
                            gen_aa32_ld16u(tmp, addr, IS_USER(s));
4283
                            tcg_gen_addi_i32(addr, addr, stride);
4284
                            tmp2 = tcg_temp_new_i32();
4285
                            gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4286
                            tcg_gen_addi_i32(addr, addr, stride);
4287
                            tcg_gen_shli_i32(tmp2, tmp2, 16);
4288
                            tcg_gen_or_i32(tmp, tmp, tmp2);
4289
                            tcg_temp_free_i32(tmp2);
4290
                            neon_store_reg(rd, pass, tmp);
4291
                        } else {
4292
                            tmp = neon_load_reg(rd, pass);
4293
                            tmp2 = tcg_temp_new_i32();
4294
                            tcg_gen_shri_i32(tmp2, tmp, 16);
4295
                            gen_aa32_st16(tmp, addr, IS_USER(s));
4296
                            tcg_temp_free_i32(tmp);
4297
                            tcg_gen_addi_i32(addr, addr, stride);
4298
                            gen_aa32_st16(tmp2, addr, IS_USER(s));
4299
                            tcg_temp_free_i32(tmp2);
4300
                            tcg_gen_addi_i32(addr, addr, stride);
4301
                        }
4302
                    } else /* size == 0 */ {
4303
                        if (load) {
4304
                            TCGV_UNUSED_I32(tmp2);
4305
                            for (n = 0; n < 4; n++) {
4306
                                tmp = tcg_temp_new_i32();
4307
                                gen_aa32_ld8u(tmp, addr, IS_USER(s));
4308
                                tcg_gen_addi_i32(addr, addr, stride);
4309
                                if (n == 0) {
4310
                                    tmp2 = tmp;
4311
                                } else {
4312
                                    tcg_gen_shli_i32(tmp, tmp, n * 8);
4313
                                    tcg_gen_or_i32(tmp2, tmp2, tmp);
4314
                                    tcg_temp_free_i32(tmp);
4315
                                }
4316
                            }
4317
                            neon_store_reg(rd, pass, tmp2);
4318
                        } else {
4319
                            tmp2 = neon_load_reg(rd, pass);
4320
                            for (n = 0; n < 4; n++) {
4321
                                tmp = tcg_temp_new_i32();
4322
                                if (n == 0) {
4323
                                    tcg_gen_mov_i32(tmp, tmp2);
4324
                                } else {
4325
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
4326
                                }
4327
                                gen_aa32_st8(tmp, addr, IS_USER(s));
4328
                                tcg_temp_free_i32(tmp);
4329
                                tcg_gen_addi_i32(addr, addr, stride);
4330
                            }
4331
                            tcg_temp_free_i32(tmp2);
4332
                        }
4333
                    }
4334
                }
4335
            }
4336
            rd += spacing;
4337
        }
4338
        tcg_temp_free_i32(addr);
4339
        stride = nregs * 8;
4340
    } else {
4341
        size = (insn >> 10) & 3;
4342
        if (size == 3) {
4343
            /* Load single element to all lanes.  */
4344
            int a = (insn >> 4) & 1;
4345
            if (!load) {
4346
                return 1;
4347
            }
4348
            size = (insn >> 6) & 3;
4349
            nregs = ((insn >> 8) & 3) + 1;
4350

    
4351
            if (size == 3) {
4352
                if (nregs != 4 || a == 0) {
4353
                    return 1;
4354
                }
4355
                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4356
                size = 2;
4357
            }
4358
            if (nregs == 1 && a == 1 && size == 0) {
4359
                return 1;
4360
            }
4361
            if (nregs == 3 && a == 1) {
4362
                return 1;
4363
            }
4364
            addr = tcg_temp_new_i32();
4365
            load_reg_var(s, addr, rn);
4366
            if (nregs == 1) {
4367
                /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4368
                tmp = gen_load_and_replicate(s, addr, size);
4369
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4370
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4371
                if (insn & (1 << 5)) {
4372
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4373
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4374
                }
4375
                tcg_temp_free_i32(tmp);
4376
            } else {
4377
                /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4378
                stride = (insn & (1 << 5)) ? 2 : 1;
4379
                for (reg = 0; reg < nregs; reg++) {
4380
                    tmp = gen_load_and_replicate(s, addr, size);
4381
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4382
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4383
                    tcg_temp_free_i32(tmp);
4384
                    tcg_gen_addi_i32(addr, addr, 1 << size);
4385
                    rd += stride;
4386
                }
4387
            }
4388
            tcg_temp_free_i32(addr);
4389
            stride = (1 << size) * nregs;
4390
        } else {
4391
            /* Single element.  */
4392
            int idx = (insn >> 4) & 0xf;
4393
            pass = (insn >> 7) & 1;
4394
            switch (size) {
4395
            case 0:
4396
                shift = ((insn >> 5) & 3) * 8;
4397
                stride = 1;
4398
                break;
4399
            case 1:
4400
                shift = ((insn >> 6) & 1) * 16;
4401
                stride = (insn & (1 << 5)) ? 2 : 1;
4402
                break;
4403
            case 2:
4404
                shift = 0;
4405
                stride = (insn & (1 << 6)) ? 2 : 1;
4406
                break;
4407
            default:
4408
                abort();
4409
            }
4410
            nregs = ((insn >> 8) & 3) + 1;
4411
            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4412
            switch (nregs) {
4413
            case 1:
4414
                if (((idx & (1 << size)) != 0) ||
4415
                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4416
                    return 1;
4417
                }
4418
                break;
4419
            case 3:
4420
                if ((idx & 1) != 0) {
4421
                    return 1;
4422
                }
4423
                /* fall through */
4424
            case 2:
4425
                if (size == 2 && (idx & 2) != 0) {
4426
                    return 1;
4427
                }
4428
                break;
4429
            case 4:
4430
                if ((size == 2) && ((idx & 3) == 3)) {
4431
                    return 1;
4432
                }
4433
                break;
4434
            default:
4435
                abort();
4436
            }
4437
            if ((rd + stride * (nregs - 1)) > 31) {
4438
                /* Attempts to write off the end of the register file
4439
                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4440
                 * the neon_load_reg() would write off the end of the array.
4441
                 */
4442
                return 1;
4443
            }
4444
            addr = tcg_temp_new_i32();
4445
            load_reg_var(s, addr, rn);
4446
            for (reg = 0; reg < nregs; reg++) {
4447
                if (load) {
4448
                    tmp = tcg_temp_new_i32();
4449
                    switch (size) {
4450
                    case 0:
4451
                        gen_aa32_ld8u(tmp, addr, IS_USER(s));
4452
                        break;
4453
                    case 1:
4454
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
4455
                        break;
4456
                    case 2:
4457
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
4458
                        break;
4459
                    default: /* Avoid compiler warnings.  */
4460
                        abort();
4461
                    }
4462
                    if (size != 2) {
4463
                        tmp2 = neon_load_reg(rd, pass);
4464
                        tcg_gen_deposit_i32(tmp, tmp2, tmp,
4465
                                            shift, size ? 16 : 8);
4466
                        tcg_temp_free_i32(tmp2);
4467
                    }
4468
                    neon_store_reg(rd, pass, tmp);
4469
                } else { /* Store */
4470
                    tmp = neon_load_reg(rd, pass);
4471
                    if (shift)
4472
                        tcg_gen_shri_i32(tmp, tmp, shift);
4473
                    switch (size) {
4474
                    case 0:
4475
                        gen_aa32_st8(tmp, addr, IS_USER(s));
4476
                        break;
4477
                    case 1:
4478
                        gen_aa32_st16(tmp, addr, IS_USER(s));
4479
                        break;
4480
                    case 2:
4481
                        gen_aa32_st32(tmp, addr, IS_USER(s));
4482
                        break;
4483
                    }
4484
                    tcg_temp_free_i32(tmp);
4485
                }
4486
                rd += stride;
4487
                tcg_gen_addi_i32(addr, addr, 1 << size);
4488
            }
4489
            tcg_temp_free_i32(addr);
4490
            stride = nregs * (1 << size);
4491
        }
4492
    }
4493
    if (rm != 15) {
4494
        TCGv_i32 base;
4495

    
4496
        base = load_reg(s, rn);
4497
        if (rm == 13) {
4498
            tcg_gen_addi_i32(base, base, stride);
4499
        } else {
4500
            TCGv_i32 index;
4501
            index = load_reg(s, rm);
4502
            tcg_gen_add_i32(base, base, index);
4503
            tcg_temp_free_i32(index);
4504
        }
4505
        store_reg(s, rn, base);
4506
    }
4507
    return 0;
4508
}
4509

    
4510
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4511
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4512
{
4513
    tcg_gen_and_i32(t, t, c);
4514
    tcg_gen_andc_i32(f, f, c);
4515
    tcg_gen_or_i32(dest, t, f);
4516
}
4517

    
4518
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4519
{
4520
    switch (size) {
4521
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4522
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4523
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4524
    default: abort();
4525
    }
4526
}
4527

    
4528
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4529
{
4530
    switch (size) {
4531
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4532
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4533
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4534
    default: abort();
4535
    }
4536
}
4537

    
4538
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4539
{
4540
    switch (size) {
4541
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4542
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4543
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4544
    default: abort();
4545
    }
4546
}
4547

    
4548
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4549
{
4550
    switch (size) {
4551
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4552
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4553
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4554
    default: abort();
4555
    }
4556
}
4557

    
4558
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4559
                                         int q, int u)
4560
{
4561
    if (q) {
4562
        if (u) {
4563
            switch (size) {
4564
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4565
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4566
            default: abort();
4567
            }
4568
        } else {
4569
            switch (size) {
4570
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4571
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4572
            default: abort();
4573
            }
4574
        }
4575
    } else {
4576
        if (u) {
4577
            switch (size) {
4578
            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4579
            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4580
            default: abort();
4581
            }
4582
        } else {
4583
            switch (size) {
4584
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4585
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4586
            default: abort();
4587
            }
4588
        }
4589
    }
4590
}
4591

    
4592
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4593
{
4594
    if (u) {
4595
        switch (size) {
4596
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4597
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4598
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4599
        default: abort();
4600
        }
4601
    } else {
4602
        switch (size) {
4603
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4604
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4605
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4606
        default: abort();
4607
        }
4608
    }
4609
    tcg_temp_free_i32(src);
4610
}
4611

    
4612
static inline void gen_neon_addl(int size)
4613
{
4614
    switch (size) {
4615
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4616
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4617
    case 2: tcg_gen_add_i64(CPU_V001); break;
4618
    default: abort();
4619
    }
4620
}
4621

    
4622
static inline void gen_neon_subl(int size)
4623
{
4624
    switch (size) {
4625
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4626
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4627
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4628
    default: abort();
4629
    }
4630
}
4631

    
4632
static inline void gen_neon_negl(TCGv_i64 var, int size)
4633
{
4634
    switch (size) {
4635
    case 0: gen_helper_neon_negl_u16(var, var); break;
4636
    case 1: gen_helper_neon_negl_u32(var, var); break;
4637
    case 2:
4638
        tcg_gen_neg_i64(var, var);
4639
        break;
4640
    default: abort();
4641
    }
4642
}
4643

    
4644
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4645
{
4646
    switch (size) {
4647
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4648
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4649
    default: abort();
4650
    }
4651
}
4652

    
4653
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4654
                                 int size, int u)
4655
{
4656
    TCGv_i64 tmp;
4657

    
4658
    switch ((size << 1) | u) {
4659
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4660
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4661
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4662
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4663
    case 4:
4664
        tmp = gen_muls_i64_i32(a, b);
4665
        tcg_gen_mov_i64(dest, tmp);
4666
        tcg_temp_free_i64(tmp);
4667
        break;
4668
    case 5:
4669
        tmp = gen_mulu_i64_i32(a, b);
4670
        tcg_gen_mov_i64(dest, tmp);
4671
        tcg_temp_free_i64(tmp);
4672
        break;
4673
    default: abort();
4674
    }
4675

    
4676
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4677
       Don't forget to clean them now.  */
4678
    if (size < 2) {
4679
        tcg_temp_free_i32(a);
4680
        tcg_temp_free_i32(b);
4681
    }
4682
}
4683

    
4684
static void gen_neon_narrow_op(int op, int u, int size,
4685
                               TCGv_i32 dest, TCGv_i64 src)
4686
{
4687
    if (op) {
4688
        if (u) {
4689
            gen_neon_unarrow_sats(size, dest, src);
4690
        } else {
4691
            gen_neon_narrow(size, dest, src);
4692
        }
4693
    } else {
4694
        if (u) {
4695
            gen_neon_narrow_satu(size, dest, src);
4696
        } else {
4697
            gen_neon_narrow_sats(size, dest, src);
4698
        }
4699
    }
4700
}
4701

    
4702
/* Symbolic constants for op fields for Neon 3-register same-length.
4703
 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4704
 * table A7-9.
4705
 */
4706
#define NEON_3R_VHADD 0
4707
#define NEON_3R_VQADD 1
4708
#define NEON_3R_VRHADD 2
4709
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4710
#define NEON_3R_VHSUB 4
4711
#define NEON_3R_VQSUB 5
4712
#define NEON_3R_VCGT 6
4713
#define NEON_3R_VCGE 7
4714
#define NEON_3R_VSHL 8
4715
#define NEON_3R_VQSHL 9
4716
#define NEON_3R_VRSHL 10
4717
#define NEON_3R_VQRSHL 11
4718
#define NEON_3R_VMAX 12
4719
#define NEON_3R_VMIN 13
4720
#define NEON_3R_VABD 14
4721
#define NEON_3R_VABA 15
4722
#define NEON_3R_VADD_VSUB 16
4723
#define NEON_3R_VTST_VCEQ 17
4724
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4725
#define NEON_3R_VMUL 19
4726
#define NEON_3R_VPMAX 20
4727
#define NEON_3R_VPMIN 21
4728
#define NEON_3R_VQDMULH_VQRDMULH 22
4729
#define NEON_3R_VPADD 23
4730
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4731
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4732
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4733
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4734
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4735
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4736
#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4737

    
4738
static const uint8_t neon_3r_sizes[] = {
4739
    [NEON_3R_VHADD] = 0x7,
4740
    [NEON_3R_VQADD] = 0xf,
4741
    [NEON_3R_VRHADD] = 0x7,
4742
    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4743
    [NEON_3R_VHSUB] = 0x7,
4744
    [NEON_3R_VQSUB] = 0xf,
4745
    [NEON_3R_VCGT] = 0x7,
4746
    [NEON_3R_VCGE] = 0x7,
4747
    [NEON_3R_VSHL] = 0xf,
4748
    [NEON_3R_VQSHL] = 0xf,
4749
    [NEON_3R_VRSHL] = 0xf,
4750
    [NEON_3R_VQRSHL] = 0xf,
4751
    [NEON_3R_VMAX] = 0x7,
4752
    [NEON_3R_VMIN] = 0x7,
4753
    [NEON_3R_VABD] = 0x7,
4754
    [NEON_3R_VABA] = 0x7,
4755
    [NEON_3R_VADD_VSUB] = 0xf,
4756
    [NEON_3R_VTST_VCEQ] = 0x7,
4757
    [NEON_3R_VML] = 0x7,
4758
    [NEON_3R_VMUL] = 0x7,
4759
    [NEON_3R_VPMAX] = 0x7,
4760
    [NEON_3R_VPMIN] = 0x7,
4761
    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4762
    [NEON_3R_VPADD] = 0x7,
4763
    [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4764
    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4765
    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4766
    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4767
    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4768
    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4769
    [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4770
};
4771

    
4772
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4773
 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4774
 * table A7-13.
4775
 */
4776
#define NEON_2RM_VREV64 0
4777
#define NEON_2RM_VREV32 1
4778
#define NEON_2RM_VREV16 2
4779
#define NEON_2RM_VPADDL 4
4780
#define NEON_2RM_VPADDL_U 5
4781
#define NEON_2RM_AESE 6 /* Includes AESD */
4782
#define NEON_2RM_AESMC 7 /* Includes AESIMC */
4783
#define NEON_2RM_VCLS 8
4784
#define NEON_2RM_VCLZ 9
4785
#define NEON_2RM_VCNT 10
4786
#define NEON_2RM_VMVN 11
4787
#define NEON_2RM_VPADAL 12
4788
#define NEON_2RM_VPADAL_U 13
4789
#define NEON_2RM_VQABS 14
4790
#define NEON_2RM_VQNEG 15
4791
#define NEON_2RM_VCGT0 16
4792
#define NEON_2RM_VCGE0 17
4793
#define NEON_2RM_VCEQ0 18
4794
#define NEON_2RM_VCLE0 19
4795
#define NEON_2RM_VCLT0 20
4796
#define NEON_2RM_VABS 22
4797
#define NEON_2RM_VNEG 23
4798
#define NEON_2RM_VCGT0_F 24
4799
#define NEON_2RM_VCGE0_F 25
4800
#define NEON_2RM_VCEQ0_F 26
4801
#define NEON_2RM_VCLE0_F 27
4802
#define NEON_2RM_VCLT0_F 28
4803
#define NEON_2RM_VABS_F 30
4804
#define NEON_2RM_VNEG_F 31
4805
#define NEON_2RM_VSWP 32
4806
#define NEON_2RM_VTRN 33
4807
#define NEON_2RM_VUZP 34
4808
#define NEON_2RM_VZIP 35
4809
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4810
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4811
#define NEON_2RM_VSHLL 38
4812
#define NEON_2RM_VRINTN 40
4813
#define NEON_2RM_VRINTX 41
4814
#define NEON_2RM_VRINTA 42
4815
#define NEON_2RM_VRINTZ 43
4816
#define NEON_2RM_VCVT_F16_F32 44
4817
#define NEON_2RM_VRINTM 45
4818
#define NEON_2RM_VCVT_F32_F16 46
4819
#define NEON_2RM_VRINTP 47
4820
#define NEON_2RM_VCVTAU 48
4821
#define NEON_2RM_VCVTAS 49
4822
#define NEON_2RM_VCVTNU 50
4823
#define NEON_2RM_VCVTNS 51
4824
#define NEON_2RM_VCVTPU 52
4825
#define NEON_2RM_VCVTPS 53
4826
#define NEON_2RM_VCVTMU 54
4827
#define NEON_2RM_VCVTMS 55
4828
#define NEON_2RM_VRECPE 56
4829
#define NEON_2RM_VRSQRTE 57
4830
#define NEON_2RM_VRECPE_F 58
4831
#define NEON_2RM_VRSQRTE_F 59
4832
#define NEON_2RM_VCVT_FS 60
4833
#define NEON_2RM_VCVT_FU 61
4834
#define NEON_2RM_VCVT_SF 62
4835
#define NEON_2RM_VCVT_UF 63
4836

    
4837
static int neon_2rm_is_float_op(int op)
4838
{
4839
    /* Return true if this neon 2reg-misc op is float-to-float */
4840
    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4841
            (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4842
            op == NEON_2RM_VRINTM ||
4843
            (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4844
            op >= NEON_2RM_VRECPE_F);
4845
}
4846

    
4847
/* Each entry in this array has bit n set if the insn allows
4848
 * size value n (otherwise it will UNDEF). Since unallocated
4849
 * op values will have no bits set they always UNDEF.
4850
 */
4851
static const uint8_t neon_2rm_sizes[] = {
4852
    [NEON_2RM_VREV64] = 0x7,
4853
    [NEON_2RM_VREV32] = 0x3,
4854
    [NEON_2RM_VREV16] = 0x1,
4855
    [NEON_2RM_VPADDL] = 0x7,
4856
    [NEON_2RM_VPADDL_U] = 0x7,
4857
    [NEON_2RM_AESE] = 0x1,
4858
    [NEON_2RM_AESMC] = 0x1,
4859
    [NEON_2RM_VCLS] = 0x7,
4860
    [NEON_2RM_VCLZ] = 0x7,
4861
    [NEON_2RM_VCNT] = 0x1,
4862
    [NEON_2RM_VMVN] = 0x1,
4863
    [NEON_2RM_VPADAL] = 0x7,
4864
    [NEON_2RM_VPADAL_U] = 0x7,
4865
    [NEON_2RM_VQABS] = 0x7,
4866
    [NEON_2RM_VQNEG] = 0x7,
4867
    [NEON_2RM_VCGT0] = 0x7,
4868
    [NEON_2RM_VCGE0] = 0x7,
4869
    [NEON_2RM_VCEQ0] = 0x7,
4870
    [NEON_2RM_VCLE0] = 0x7,
4871
    [NEON_2RM_VCLT0] = 0x7,
4872
    [NEON_2RM_VABS] = 0x7,
4873
    [NEON_2RM_VNEG] = 0x7,
4874
    [NEON_2RM_VCGT0_F] = 0x4,
4875
    [NEON_2RM_VCGE0_F] = 0x4,
4876
    [NEON_2RM_VCEQ0_F] = 0x4,
4877
    [NEON_2RM_VCLE0_F] = 0x4,
4878
    [NEON_2RM_VCLT0_F] = 0x4,
4879
    [NEON_2RM_VABS_F] = 0x4,
4880
    [NEON_2RM_VNEG_F] = 0x4,
4881
    [NEON_2RM_VSWP] = 0x1,
4882
    [NEON_2RM_VTRN] = 0x7,
4883
    [NEON_2RM_VUZP] = 0x7,
4884
    [NEON_2RM_VZIP] = 0x7,
4885
    [NEON_2RM_VMOVN] = 0x7,
4886
    [NEON_2RM_VQMOVN] = 0x7,
4887
    [NEON_2RM_VSHLL] = 0x7,
4888
    [NEON_2RM_VRINTN] = 0x4,
4889
    [NEON_2RM_VRINTX] = 0x4,
4890
    [NEON_2RM_VRINTA] = 0x4,
4891
    [NEON_2RM_VRINTZ] = 0x4,
4892
    [NEON_2RM_VCVT_F16_F32] = 0x2,
4893
    [NEON_2RM_VRINTM] = 0x4,
4894
    [NEON_2RM_VCVT_F32_F16] = 0x2,
4895
    [NEON_2RM_VRINTP] = 0x4,
4896
    [NEON_2RM_VCVTAU] = 0x4,
4897
    [NEON_2RM_VCVTAS] = 0x4,
4898
    [NEON_2RM_VCVTNU] = 0x4,
4899
    [NEON_2RM_VCVTNS] = 0x4,
4900
    [NEON_2RM_VCVTPU] = 0x4,
4901
    [NEON_2RM_VCVTPS] = 0x4,
4902
    [NEON_2RM_VCVTMU] = 0x4,
4903
    [NEON_2RM_VCVTMS] = 0x4,
4904
    [NEON_2RM_VRECPE] = 0x4,
4905
    [NEON_2RM_VRSQRTE] = 0x4,
4906
    [NEON_2RM_VRECPE_F] = 0x4,
4907
    [NEON_2RM_VRSQRTE_F] = 0x4,
4908
    [NEON_2RM_VCVT_FS] = 0x4,
4909
    [NEON_2RM_VCVT_FU] = 0x4,
4910
    [NEON_2RM_VCVT_SF] = 0x4,
4911
    [NEON_2RM_VCVT_UF] = 0x4,
4912
};
4913

    
4914
/* Translate a NEON data processing instruction.  Return nonzero if the
4915
   instruction is invalid.
4916
   We process data in a mixture of 32-bit and 64-bit chunks.
4917
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4918

    
4919
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4920
{
4921
    int op;
4922
    int q;
4923
    int rd, rn, rm;
4924
    int size;
4925
    int shift;
4926
    int pass;
4927
    int count;
4928
    int pairwise;
4929
    int u;
4930
    uint32_t imm, mask;
4931
    TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4932
    TCGv_i64 tmp64;
4933

    
4934
    if (!s->vfp_enabled)
4935
      return 1;
4936
    q = (insn & (1 << 6)) != 0;
4937
    u = (insn >> 24) & 1;
4938
    VFP_DREG_D(rd, insn);
4939
    VFP_DREG_N(rn, insn);
4940
    VFP_DREG_M(rm, insn);
4941
    size = (insn >> 20) & 3;
4942
    if ((insn & (1 << 23)) == 0) {
4943
        /* Three register same length.  */
4944
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4945
        /* Catch invalid op and bad size combinations: UNDEF */
4946
        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4947
            return 1;
4948
        }
4949
        /* All insns of this form UNDEF for either this condition or the
4950
         * superset of cases "Q==1"; we catch the latter later.
4951
         */
4952
        if (q && ((rd | rn | rm) & 1)) {
4953
            return 1;
4954
        }
4955
        if (size == 3 && op != NEON_3R_LOGIC) {
4956
            /* 64-bit element instructions. */
4957
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4958
                neon_load_reg64(cpu_V0, rn + pass);
4959
                neon_load_reg64(cpu_V1, rm + pass);
4960
                switch (op) {
4961
                case NEON_3R_VQADD:
4962
                    if (u) {
4963
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4964
                                                 cpu_V0, cpu_V1);
4965
                    } else {
4966
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4967
                                                 cpu_V0, cpu_V1);
4968
                    }
4969
                    break;
4970
                case NEON_3R_VQSUB:
4971
                    if (u) {
4972
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4973
                                                 cpu_V0, cpu_V1);
4974
                    } else {
4975
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4976
                                                 cpu_V0, cpu_V1);
4977
                    }
4978
                    break;
4979
                case NEON_3R_VSHL:
4980
                    if (u) {
4981
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4982
                    } else {
4983
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4984
                    }
4985
                    break;
4986
                case NEON_3R_VQSHL:
4987
                    if (u) {
4988
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4989
                                                 cpu_V1, cpu_V0);
4990
                    } else {
4991
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4992
                                                 cpu_V1, cpu_V0);
4993
                    }
4994
                    break;
4995
                case NEON_3R_VRSHL:
4996
                    if (u) {
4997
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4998
                    } else {
4999
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5000
                    }
5001
                    break;
5002
                case NEON_3R_VQRSHL:
5003
                    if (u) {
5004
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5005
                                                  cpu_V1, cpu_V0);
5006
                    } else {
5007
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5008
                                                  cpu_V1, cpu_V0);
5009
                    }
5010
                    break;
5011
                case NEON_3R_VADD_VSUB:
5012
                    if (u) {
5013
                        tcg_gen_sub_i64(CPU_V001);
5014
                    } else {
5015
                        tcg_gen_add_i64(CPU_V001);
5016
                    }
5017
                    break;
5018
                default:
5019
                    abort();
5020
                }
5021
                neon_store_reg64(cpu_V0, rd + pass);
5022
            }
5023
            return 0;
5024
        }
5025
        pairwise = 0;
5026
        switch (op) {
5027
        case NEON_3R_VSHL:
5028
        case NEON_3R_VQSHL:
5029
        case NEON_3R_VRSHL:
5030
        case NEON_3R_VQRSHL:
5031
            {
5032
                int rtmp;
5033
                /* Shift instruction operands are reversed.  */
5034
                rtmp = rn;
5035
                rn = rm;
5036
                rm = rtmp;
5037
            }
5038
            break;
5039
        case NEON_3R_VPADD:
5040
            if (u) {
5041
                return 1;
5042
            }
5043
            /* Fall through */
5044
        case NEON_3R_VPMAX:
5045
        case NEON_3R_VPMIN:
5046
            pairwise = 1;
5047
            break;
5048
        case NEON_3R_FLOAT_ARITH:
5049
            pairwise = (u && size < 2); /* if VPADD (float) */
5050
            break;
5051
        case NEON_3R_FLOAT_MINMAX:
5052
            pairwise = u; /* if VPMIN/VPMAX (float) */
5053
            break;
5054
        case NEON_3R_FLOAT_CMP:
5055
            if (!u && size) {
5056
                /* no encoding for U=0 C=1x */
5057
                return 1;
5058
            }
5059
            break;
5060
        case NEON_3R_FLOAT_ACMP:
5061
            if (!u) {
5062
                return 1;
5063
            }
5064
            break;
5065
        case NEON_3R_FLOAT_MISC:
5066
            /* VMAXNM/VMINNM in ARMv8 */
5067
            if (u && !arm_feature(env, ARM_FEATURE_V8)) {
5068
                return 1;
5069
            }
5070
            break;
5071
        case NEON_3R_VMUL:
5072
            if (u && (size != 0)) {
5073
                /* UNDEF on invalid size for polynomial subcase */
5074
                return 1;
5075
            }
5076
            break;
5077
        case NEON_3R_VFM:
5078
            if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
5079
                return 1;
5080
            }
5081
            break;
5082
        default:
5083
            break;
5084
        }
5085

    
5086
        if (pairwise && q) {
5087
            /* All the pairwise insns UNDEF if Q is set */
5088
            return 1;
5089
        }
5090

    
5091
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
5092

    
5093
        if (pairwise) {
5094
            /* Pairwise.  */
5095
            if (pass < 1) {
5096
                tmp = neon_load_reg(rn, 0);
5097
                tmp2 = neon_load_reg(rn, 1);
5098
            } else {
5099
                tmp = neon_load_reg(rm, 0);
5100
                tmp2 = neon_load_reg(rm, 1);
5101
            }
5102
        } else {
5103
            /* Elementwise.  */
5104
            tmp = neon_load_reg(rn, pass);
5105
            tmp2 = neon_load_reg(rm, pass);
5106
        }
5107
        switch (op) {
5108
        case NEON_3R_VHADD:
5109
            GEN_NEON_INTEGER_OP(hadd);
5110
            break;
5111
        case NEON_3R_VQADD:
5112
            GEN_NEON_INTEGER_OP_ENV(qadd);
5113
            break;
5114
        case NEON_3R_VRHADD:
5115
            GEN_NEON_INTEGER_OP(rhadd);
5116
            break;
5117
        case NEON_3R_LOGIC: /* Logic ops.  */
5118
            switch ((u << 2) | size) {
5119
            case 0: /* VAND */
5120
                tcg_gen_and_i32(tmp, tmp, tmp2);
5121
                break;
5122
            case 1: /* BIC */
5123
                tcg_gen_andc_i32(tmp, tmp, tmp2);
5124
                break;
5125
            case 2: /* VORR */
5126
                tcg_gen_or_i32(tmp, tmp, tmp2);
5127
                break;
5128
            case 3: /* VORN */
5129
                tcg_gen_orc_i32(tmp, tmp, tmp2);
5130
                break;
5131
            case 4: /* VEOR */
5132
                tcg_gen_xor_i32(tmp, tmp, tmp2);
5133
                break;
5134
            case 5: /* VBSL */
5135
                tmp3 = neon_load_reg(rd, pass);
5136
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5137
                tcg_temp_free_i32(tmp3);
5138
                break;
5139
            case 6: /* VBIT */
5140
                tmp3 = neon_load_reg(rd, pass);
5141
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5142
                tcg_temp_free_i32(tmp3);
5143
                break;
5144
            case 7: /* VBIF */
5145
                tmp3 = neon_load_reg(rd, pass);
5146
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5147
                tcg_temp_free_i32(tmp3);
5148
                break;
5149
            }
5150
            break;
5151
        case NEON_3R_VHSUB:
5152
            GEN_NEON_INTEGER_OP(hsub);
5153
            break;
5154
        case NEON_3R_VQSUB:
5155
            GEN_NEON_INTEGER_OP_ENV(qsub);
5156
            break;
5157
        case NEON_3R_VCGT:
5158
            GEN_NEON_INTEGER_OP(cgt);
5159
            break;
5160
        case NEON_3R_VCGE:
5161
            GEN_NEON_INTEGER_OP(cge);
5162
            break;
5163
        case NEON_3R_VSHL:
5164
            GEN_NEON_INTEGER_OP(shl);
5165
            break;
5166
        case NEON_3R_VQSHL:
5167
            GEN_NEON_INTEGER_OP_ENV(qshl);
5168
            break;
5169
        case NEON_3R_VRSHL:
5170
            GEN_NEON_INTEGER_OP(rshl);
5171
            break;
5172
        case NEON_3R_VQRSHL:
5173
            GEN_NEON_INTEGER_OP_ENV(qrshl);
5174
            break;
5175
        case NEON_3R_VMAX:
5176
            GEN_NEON_INTEGER_OP(max);
5177
            break;
5178
        case NEON_3R_VMIN:
5179
            GEN_NEON_INTEGER_OP(min);
5180
            break;
5181
        case NEON_3R_VABD:
5182
            GEN_NEON_INTEGER_OP(abd);
5183
            break;
5184
        case NEON_3R_VABA:
5185
            GEN_NEON_INTEGER_OP(abd);
5186
            tcg_temp_free_i32(tmp2);
5187
            tmp2 = neon_load_reg(rd, pass);
5188
            gen_neon_add(size, tmp, tmp2);
5189
            break;
5190
        case NEON_3R_VADD_VSUB:
5191
            if (!u) { /* VADD */
5192
                gen_neon_add(size, tmp, tmp2);
5193
            } else { /* VSUB */
5194
                switch (size) {
5195
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5196
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5197
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5198
                default: abort();
5199
                }
5200
            }
5201
            break;
5202
        case NEON_3R_VTST_VCEQ:
5203
            if (!u) { /* VTST */
5204
                switch (size) {
5205
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5206
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5207
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5208
                default: abort();
5209
                }
5210
            } else { /* VCEQ */
5211
                switch (size) {
5212
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5213
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5214
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5215
                default: abort();
5216
                }
5217
            }
5218
            break;
5219
        case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5220
            switch (size) {
5221
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5222
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5223
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5224
            default: abort();
5225
            }
5226
            tcg_temp_free_i32(tmp2);
5227
            tmp2 = neon_load_reg(rd, pass);
5228
            if (u) { /* VMLS */
5229
                gen_neon_rsb(size, tmp, tmp2);
5230
            } else { /* VMLA */
5231
                gen_neon_add(size, tmp, tmp2);
5232
            }
5233
            break;
5234
        case NEON_3R_VMUL:
5235
            if (u) { /* polynomial */
5236
                gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5237
            } else { /* Integer */
5238
                switch (size) {
5239
                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5240
                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5241
                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5242
                default: abort();
5243
                }
5244
            }
5245
            break;
5246
        case NEON_3R_VPMAX:
5247
            GEN_NEON_INTEGER_OP(pmax);
5248
            break;
5249
        case NEON_3R_VPMIN:
5250
            GEN_NEON_INTEGER_OP(pmin);
5251
            break;
5252
        case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
5253
            if (!u) { /* VQDMULH */
5254
                switch (size) {
5255
                case 1:
5256
                    gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5257
                    break;
5258
                case 2:
5259
                    gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5260
                    break;
5261
                default: abort();
5262
                }
5263
            } else { /* VQRDMULH */
5264
                switch (size) {
5265
                case 1:
5266
                    gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5267
                    break;
5268
                case 2:
5269
                    gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5270
                    break;
5271
                default: abort();
5272
                }
5273
            }
5274
            break;
5275
        case NEON_3R_VPADD:
5276
            switch (size) {
5277
            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5278
            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5279
            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5280
            default: abort();
5281
            }
5282
            break;
5283
        case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5284
        {
5285
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5286
            switch ((u << 2) | size) {
5287
            case 0: /* VADD */
5288
            case 4: /* VPADD */
5289
                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5290
                break;
5291
            case 2: /* VSUB */
5292
                gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5293
                break;
5294
            case 6: /* VABD */
5295
                gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5296
                break;
5297
            default:
5298
                abort();
5299
            }
5300
            tcg_temp_free_ptr(fpstatus);
5301
            break;
5302
        }
5303
        case NEON_3R_FLOAT_MULTIPLY:
5304
        {
5305
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5306
            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5307
            if (!u) {
5308
                tcg_temp_free_i32(tmp2);
5309
                tmp2 = neon_load_reg(rd, pass);
5310
                if (size == 0) {
5311
                    gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5312
                } else {
5313
                    gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5314
                }
5315
            }
5316
            tcg_temp_free_ptr(fpstatus);
5317
            break;
5318
        }
5319
        case NEON_3R_FLOAT_CMP:
5320
        {
5321
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5322
            if (!u) {
5323
                gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5324
            } else {
5325
                if (size == 0) {
5326
                    gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5327
                } else {
5328
                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5329
                }
5330
            }
5331
            tcg_temp_free_ptr(fpstatus);
5332
            break;
5333
        }
5334
        case NEON_3R_FLOAT_ACMP:
5335
        {
5336
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5337
            if (size == 0) {
5338
                gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5339
            } else {
5340
                gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5341
            }
5342
            tcg_temp_free_ptr(fpstatus);
5343
            break;
5344
        }
5345
        case NEON_3R_FLOAT_MINMAX:
5346
        {
5347
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5348
            if (size == 0) {
5349
                gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5350
            } else {
5351
                gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5352
            }
5353
            tcg_temp_free_ptr(fpstatus);
5354
            break;
5355
        }
5356
        case NEON_3R_FLOAT_MISC:
5357
            if (u) {
5358
                /* VMAXNM/VMINNM */
5359
                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5360
                if (size == 0) {
5361
                    gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5362
                } else {
5363
                    gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5364
                }
5365
                tcg_temp_free_ptr(fpstatus);
5366
            } else {
5367
                if (size == 0) {
5368
                    gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5369
                } else {
5370
                    gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5371
              }
5372
            }
5373
            break;
5374
        case NEON_3R_VFM:
5375
        {
5376
            /* VFMA, VFMS: fused multiply-add */
5377
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5378
            TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5379
            if (size) {
5380
                /* VFMS */
5381
                gen_helper_vfp_negs(tmp, tmp);
5382
            }
5383
            gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5384
            tcg_temp_free_i32(tmp3);
5385
            tcg_temp_free_ptr(fpstatus);
5386
            break;
5387
        }
5388
        default:
5389
            abort();
5390
        }
5391
        tcg_temp_free_i32(tmp2);
5392

    
5393
        /* Save the result.  For elementwise operations we can put it
5394
           straight into the destination register.  For pairwise operations
5395
           we have to be careful to avoid clobbering the source operands.  */
5396
        if (pairwise && rd == rm) {
5397
            neon_store_scratch(pass, tmp);
5398
        } else {
5399
            neon_store_reg(rd, pass, tmp);
5400
        }
5401

    
5402
        } /* for pass */
5403
        if (pairwise && rd == rm) {
5404
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5405
                tmp = neon_load_scratch(pass);
5406
                neon_store_reg(rd, pass, tmp);
5407
            }
5408
        }
5409
        /* End of 3 register same size operations.  */
5410
    } else if (insn & (1 << 4)) {
5411
        if ((insn & 0x00380080) != 0) {
5412
            /* Two registers and shift.  */
5413
            op = (insn >> 8) & 0xf;
5414
            if (insn & (1 << 7)) {
5415
                /* 64-bit shift. */
5416
                if (op > 7) {
5417
                    return 1;
5418
                }
5419
                size = 3;
5420
            } else {
5421
                size = 2;
5422
                while ((insn & (1 << (size + 19))) == 0)
5423
                    size--;
5424
            }
5425
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5426
            /* To avoid excessive duplication of ops we implement shift
5427
               by immediate using the variable shift operations.  */
5428
            if (op < 8) {
5429
                /* Shift by immediate:
5430
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
5431
                if (q && ((rd | rm) & 1)) {
5432
                    return 1;
5433
                }
5434
                if (!u && (op == 4 || op == 6)) {
5435
                    return 1;
5436
                }
5437
                /* Right shifts are encoded as N - shift, where N is the
5438
                   element size in bits.  */
5439
                if (op <= 4)
5440
                    shift = shift - (1 << (size + 3));
5441
                if (size == 3) {
5442
                    count = q + 1;
5443
                } else {
5444
                    count = q ? 4: 2;
5445
                }
5446
                switch (size) {
5447
                case 0:
5448
                    imm = (uint8_t) shift;
5449
                    imm |= imm << 8;
5450
                    imm |= imm << 16;
5451
                    break;
5452
                case 1:
5453
                    imm = (uint16_t) shift;
5454
                    imm |= imm << 16;
5455
                    break;
5456
                case 2:
5457
                case 3:
5458
                    imm = shift;
5459
                    break;
5460
                default:
5461
                    abort();
5462
                }
5463

    
5464
                for (pass = 0; pass < count; pass++) {
5465
                    if (size == 3) {
5466
                        neon_load_reg64(cpu_V0, rm + pass);
5467
                        tcg_gen_movi_i64(cpu_V1, imm);
5468
                        switch (op) {
5469
                        case 0:  /* VSHR */
5470
                        case 1:  /* VSRA */
5471
                            if (u)
5472
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5473
                            else
5474
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5475
                            break;
5476
                        case 2: /* VRSHR */
5477
                        case 3: /* VRSRA */
5478
                            if (u)
5479
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5480
                            else
5481
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5482
                            break;
5483
                        case 4: /* VSRI */
5484
                        case 5: /* VSHL, VSLI */
5485
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5486
                            break;
5487
                        case 6: /* VQSHLU */
5488
                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5489
                                                      cpu_V0, cpu_V1);
5490
                            break;
5491
                        case 7: /* VQSHL */
5492
                            if (u) {
5493
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5494
                                                         cpu_V0, cpu_V1);
5495
                            } else {
5496
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5497
                                                         cpu_V0, cpu_V1);
5498
                            }
5499
                            break;
5500
                        }
5501
                        if (op == 1 || op == 3) {
5502
                            /* Accumulate.  */
5503
                            neon_load_reg64(cpu_V1, rd + pass);
5504
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5505
                        } else if (op == 4 || (op == 5 && u)) {
5506
                            /* Insert */
5507
                            neon_load_reg64(cpu_V1, rd + pass);
5508
                            uint64_t mask;
5509
                            if (shift < -63 || shift > 63) {
5510
                                mask = 0;
5511
                            } else {
5512
                                if (op == 4) {
5513
                                    mask = 0xffffffffffffffffull >> -shift;
5514
                                } else {
5515
                                    mask = 0xffffffffffffffffull << shift;
5516
                                }
5517
                            }
5518
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5519
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5520
                        }
5521
                        neon_store_reg64(cpu_V0, rd + pass);
5522
                    } else { /* size < 3 */
5523
                        /* Operands in T0 and T1.  */
5524
                        tmp = neon_load_reg(rm, pass);
5525
                        tmp2 = tcg_temp_new_i32();
5526
                        tcg_gen_movi_i32(tmp2, imm);
5527
                        switch (op) {
5528
                        case 0:  /* VSHR */
5529
                        case 1:  /* VSRA */
5530
                            GEN_NEON_INTEGER_OP(shl);
5531
                            break;
5532
                        case 2: /* VRSHR */
5533
                        case 3: /* VRSRA */
5534
                            GEN_NEON_INTEGER_OP(rshl);
5535
                            break;
5536
                        case 4: /* VSRI */
5537
                        case 5: /* VSHL, VSLI */
5538
                            switch (size) {
5539
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5540
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5541
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5542
                            default: abort();
5543
                            }
5544
                            break;
5545
                        case 6: /* VQSHLU */
5546
                            switch (size) {
5547
                            case 0:
5548
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
5549
                                                         tmp, tmp2);
5550
                                break;
5551
                            case 1:
5552
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
5553
                                                          tmp, tmp2);
5554
                                break;
5555
                            case 2:
5556
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
5557
                                                          tmp, tmp2);
5558
                                break;
5559
                            default:
5560
                                abort();
5561
                            }
5562
                            break;
5563
                        case 7: /* VQSHL */
5564
                            GEN_NEON_INTEGER_OP_ENV(qshl);
5565
                            break;
5566
                        }
5567
                        tcg_temp_free_i32(tmp2);
5568

    
5569
                        if (op == 1 || op == 3) {
5570
                            /* Accumulate.  */
5571
                            tmp2 = neon_load_reg(rd, pass);
5572
                            gen_neon_add(size, tmp, tmp2);
5573
                            tcg_temp_free_i32(tmp2);
5574
                        } else if (op == 4 || (op == 5 && u)) {
5575
                            /* Insert */
5576
                            switch (size) {
5577
                            case 0:
5578
                                if (op == 4)
5579
                                    mask = 0xff >> -shift;
5580
                                else
5581
                                    mask = (uint8_t)(0xff << shift);
5582
                                mask |= mask << 8;
5583
                                mask |= mask << 16;
5584
                                break;
5585
                            case 1:
5586
                                if (op == 4)
5587
                                    mask = 0xffff >> -shift;
5588
                                else
5589
                                    mask = (uint16_t)(0xffff << shift);
5590
                                mask |= mask << 16;
5591
                                break;
5592
                            case 2:
5593
                                if (shift < -31 || shift > 31) {
5594
                                    mask = 0;
5595
                                } else {
5596
                                    if (op == 4)
5597
                                        mask = 0xffffffffu >> -shift;
5598
                                    else
5599
                                        mask = 0xffffffffu << shift;
5600
                                }
5601
                                break;
5602
                            default:
5603
                                abort();
5604
                            }
5605
                            tmp2 = neon_load_reg(rd, pass);
5606
                            tcg_gen_andi_i32(tmp, tmp, mask);
5607
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5608
                            tcg_gen_or_i32(tmp, tmp, tmp2);
5609
                            tcg_temp_free_i32(tmp2);
5610
                        }
5611
                        neon_store_reg(rd, pass, tmp);
5612
                    }
5613
                } /* for pass */
5614
            } else if (op < 10) {
5615
                /* Shift by immediate and narrow:
5616
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
5617
                int input_unsigned = (op == 8) ? !u : u;
5618
                if (rm & 1) {
5619
                    return 1;
5620
                }
5621
                shift = shift - (1 << (size + 3));
5622
                size++;
5623
                if (size == 3) {
5624
                    tmp64 = tcg_const_i64(shift);
5625
                    neon_load_reg64(cpu_V0, rm);
5626
                    neon_load_reg64(cpu_V1, rm + 1);
5627
                    for (pass = 0; pass < 2; pass++) {
5628
                        TCGv_i64 in;
5629
                        if (pass == 0) {
5630
                            in = cpu_V0;
5631
                        } else {
5632
                            in = cpu_V1;
5633
                        }
5634
                        if (q) {
5635
                            if (input_unsigned) {
5636
                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5637
                            } else {
5638
                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5639
                            }
5640
                        } else {
5641
                            if (input_unsigned) {
5642
                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5643
                            } else {
5644
                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5645
                            }
5646
                        }
5647
                        tmp = tcg_temp_new_i32();
5648
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5649
                        neon_store_reg(rd, pass, tmp);
5650
                    } /* for pass */
5651
                    tcg_temp_free_i64(tmp64);
5652
                } else {
5653
                    if (size == 1) {
5654
                        imm = (uint16_t)shift;
5655
                        imm |= imm << 16;
5656
                    } else {
5657
                        /* size == 2 */
5658
                        imm = (uint32_t)shift;
5659
                    }
5660
                    tmp2 = tcg_const_i32(imm);
5661
                    tmp4 = neon_load_reg(rm + 1, 0);
5662
                    tmp5 = neon_load_reg(rm + 1, 1);
5663
                    for (pass = 0; pass < 2; pass++) {
5664
                        if (pass == 0) {
5665
                            tmp = neon_load_reg(rm, 0);
5666
                        } else {
5667
                            tmp = tmp4;
5668
                        }
5669
                        gen_neon_shift_narrow(size, tmp, tmp2, q,
5670
                                              input_unsigned);
5671
                        if (pass == 0) {
5672
                            tmp3 = neon_load_reg(rm, 1);
5673
                        } else {
5674
                            tmp3 = tmp5;
5675
                        }
5676
                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
5677
                                              input_unsigned);
5678
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5679
                        tcg_temp_free_i32(tmp);
5680
                        tcg_temp_free_i32(tmp3);
5681
                        tmp = tcg_temp_new_i32();
5682
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5683
                        neon_store_reg(rd, pass, tmp);
5684
                    } /* for pass */
5685
                    tcg_temp_free_i32(tmp2);
5686
                }
5687
            } else if (op == 10) {
5688
                /* VSHLL, VMOVL */
5689
                if (q || (rd & 1)) {
5690
                    return 1;
5691
                }
5692
                tmp = neon_load_reg(rm, 0);
5693
                tmp2 = neon_load_reg(rm, 1);
5694
                for (pass = 0; pass < 2; pass++) {
5695
                    if (pass == 1)
5696
                        tmp = tmp2;
5697

    
5698
                    gen_neon_widen(cpu_V0, tmp, size, u);
5699

    
5700
                    if (shift != 0) {
5701
                        /* The shift is less than the width of the source
5702
                           type, so we can just shift the whole register.  */
5703
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5704
                        /* Widen the result of shift: we need to clear
5705
                         * the potential overflow bits resulting from
5706
                         * left bits of the narrow input appearing as
5707
                         * right bits of left the neighbour narrow
5708
                         * input.  */
5709
                        if (size < 2 || !u) {
5710
                            uint64_t imm64;
5711
                            if (size == 0) {
5712
                                imm = (0xffu >> (8 - shift));
5713
                                imm |= imm << 16;
5714
                            } else if (size == 1) {
5715
                                imm = 0xffff >> (16 - shift);
5716
                            } else {
5717
                                /* size == 2 */
5718
                                imm = 0xffffffff >> (32 - shift);
5719
                            }
5720
                            if (size < 2) {
5721
                                imm64 = imm | (((uint64_t)imm) << 32);
5722
                            } else {
5723
                                imm64 = imm;
5724
                            }
5725
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5726
                        }
5727
                    }
5728
                    neon_store_reg64(cpu_V0, rd + pass);
5729
                }
5730
            } else if (op >= 14) {
5731
                /* VCVT fixed-point.  */
5732
                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5733
                    return 1;
5734
                }
5735
                /* We have already masked out the must-be-1 top bit of imm6,
5736
                 * hence this 32-shift where the ARM ARM has 64-imm6.
5737
                 */
5738
                shift = 32 - shift;
5739
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5740
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5741
                    if (!(op & 1)) {
5742
                        if (u)
5743
                            gen_vfp_ulto(0, shift, 1);
5744
                        else
5745
                            gen_vfp_slto(0, shift, 1);
5746
                    } else {
5747
                        if (u)
5748
                            gen_vfp_toul(0, shift, 1);
5749
                        else
5750
                            gen_vfp_tosl(0, shift, 1);
5751
                    }
5752
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5753
                }
5754
            } else {
5755
                return 1;
5756
            }
5757
        } else { /* (insn & 0x00380080) == 0 */
5758
            int invert;
5759
            if (q && (rd & 1)) {
5760
                return 1;
5761
            }
5762

    
5763
            op = (insn >> 8) & 0xf;
5764
            /* One register and immediate.  */
5765
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5766
            invert = (insn & (1 << 5)) != 0;
5767
            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5768
             * We choose to not special-case this and will behave as if a
5769
             * valid constant encoding of 0 had been given.
5770
             */
5771
            switch (op) {
5772
            case 0: case 1:
5773
                /* no-op */
5774
                break;
5775
            case 2: case 3:
5776
                imm <<= 8;
5777
                break;
5778
            case 4: case 5:
5779
                imm <<= 16;
5780
                break;
5781
            case 6: case 7:
5782
                imm <<= 24;
5783
                break;
5784
            case 8: case 9:
5785
                imm |= imm << 16;
5786
                break;
5787
            case 10: case 11:
5788
                imm = (imm << 8) | (imm << 24);
5789
                break;
5790
            case 12:
5791
                imm = (imm << 8) | 0xff;
5792
                break;
5793
            case 13:
5794
                imm = (imm << 16) | 0xffff;
5795
                break;
5796
            case 14:
5797
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
5798
                if (invert)
5799
                    imm = ~imm;
5800
                break;
5801
            case 15:
5802
                if (invert) {
5803
                    return 1;
5804
                }
5805
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5806
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5807
                break;
5808
            }
5809
            if (invert)
5810
                imm = ~imm;
5811

    
5812
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5813
                if (op & 1 && op < 12) {
5814
                    tmp = neon_load_reg(rd, pass);
5815
                    if (invert) {
5816
                        /* The immediate value has already been inverted, so
5817
                           BIC becomes AND.  */
5818
                        tcg_gen_andi_i32(tmp, tmp, imm);
5819
                    } else {
5820
                        tcg_gen_ori_i32(tmp, tmp, imm);
5821
                    }
5822
                } else {
5823
                    /* VMOV, VMVN.  */
5824
                    tmp = tcg_temp_new_i32();
5825
                    if (op == 14 && invert) {
5826
                        int n;
5827
                        uint32_t val;
5828
                        val = 0;
5829
                        for (n = 0; n < 4; n++) {
5830
                            if (imm & (1 << (n + (pass & 1) * 4)))
5831
                                val |= 0xff << (n * 8);
5832
                        }
5833
                        tcg_gen_movi_i32(tmp, val);
5834
                    } else {
5835
                        tcg_gen_movi_i32(tmp, imm);
5836
                    }
5837
                }
5838
                neon_store_reg(rd, pass, tmp);
5839
            }
5840
        }
5841
    } else { /* (insn & 0x00800010 == 0x00800000) */
5842
        if (size != 3) {
5843
            op = (insn >> 8) & 0xf;
5844
            if ((insn & (1 << 6)) == 0) {
5845
                /* Three registers of different lengths.  */
5846
                int src1_wide;
5847
                int src2_wide;
5848
                int prewiden;
5849
                /* undefreq: bit 0 : UNDEF if size != 0
5850
                 *           bit 1 : UNDEF if size == 0
5851
                 *           bit 2 : UNDEF if U == 1
5852
                 * Note that [1:0] set implies 'always UNDEF'
5853
                 */
5854
                int undefreq;
5855
                /* prewiden, src1_wide, src2_wide, undefreq */
5856
                static const int neon_3reg_wide[16][4] = {
5857
                    {1, 0, 0, 0}, /* VADDL */
5858
                    {1, 1, 0, 0}, /* VADDW */
5859
                    {1, 0, 0, 0}, /* VSUBL */
5860
                    {1, 1, 0, 0}, /* VSUBW */
5861
                    {0, 1, 1, 0}, /* VADDHN */
5862
                    {0, 0, 0, 0}, /* VABAL */
5863
                    {0, 1, 1, 0}, /* VSUBHN */
5864
                    {0, 0, 0, 0}, /* VABDL */
5865
                    {0, 0, 0, 0}, /* VMLAL */
5866
                    {0, 0, 0, 6}, /* VQDMLAL */
5867
                    {0, 0, 0, 0}, /* VMLSL */
5868
                    {0, 0, 0, 6}, /* VQDMLSL */
5869
                    {0, 0, 0, 0}, /* Integer VMULL */
5870
                    {0, 0, 0, 2}, /* VQDMULL */
5871
                    {0, 0, 0, 5}, /* Polynomial VMULL */
5872
                    {0, 0, 0, 3}, /* Reserved: always UNDEF */
5873
                };
5874

    
5875
                prewiden = neon_3reg_wide[op][0];
5876
                src1_wide = neon_3reg_wide[op][1];
5877
                src2_wide = neon_3reg_wide[op][2];
5878
                undefreq = neon_3reg_wide[op][3];
5879

    
5880
                if (((undefreq & 1) && (size != 0)) ||
5881
                    ((undefreq & 2) && (size == 0)) ||
5882
                    ((undefreq & 4) && u)) {
5883
                    return 1;
5884
                }
5885
                if ((src1_wide && (rn & 1)) ||
5886
                    (src2_wide && (rm & 1)) ||
5887
                    (!src2_wide && (rd & 1))) {
5888
                    return 1;
5889
                }
5890

    
5891
                /* Avoid overlapping operands.  Wide source operands are
5892
                   always aligned so will never overlap with wide
5893
                   destinations in problematic ways.  */
5894
                if (rd == rm && !src2_wide) {
5895
                    tmp = neon_load_reg(rm, 1);
5896
                    neon_store_scratch(2, tmp);
5897
                } else if (rd == rn && !src1_wide) {
5898
                    tmp = neon_load_reg(rn, 1);
5899
                    neon_store_scratch(2, tmp);
5900
                }
5901
                TCGV_UNUSED_I32(tmp3);
5902
                for (pass = 0; pass < 2; pass++) {
5903
                    if (src1_wide) {
5904
                        neon_load_reg64(cpu_V0, rn + pass);
5905
                        TCGV_UNUSED_I32(tmp);
5906
                    } else {
5907
                        if (pass == 1 && rd == rn) {
5908
                            tmp = neon_load_scratch(2);
5909
                        } else {
5910
                            tmp = neon_load_reg(rn, pass);
5911
                        }
5912
                        if (prewiden) {
5913
                            gen_neon_widen(cpu_V0, tmp, size, u);
5914
                        }
5915
                    }
5916
                    if (src2_wide) {
5917
                        neon_load_reg64(cpu_V1, rm + pass);
5918
                        TCGV_UNUSED_I32(tmp2);
5919
                    } else {
5920
                        if (pass == 1 && rd == rm) {
5921
                            tmp2 = neon_load_scratch(2);
5922
                        } else {
5923
                            tmp2 = neon_load_reg(rm, pass);
5924
                        }
5925
                        if (prewiden) {
5926
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5927
                        }
5928
                    }
5929
                    switch (op) {
5930
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5931
                        gen_neon_addl(size);
5932
                        break;
5933
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5934
                        gen_neon_subl(size);
5935
                        break;
5936
                    case 5: case 7: /* VABAL, VABDL */
5937
                        switch ((size << 1) | u) {
5938
                        case 0:
5939
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5940
                            break;
5941
                        case 1:
5942
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5943
                            break;
5944
                        case 2:
5945
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5946
                            break;
5947
                        case 3:
5948
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5949
                            break;
5950
                        case 4:
5951
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5952
                            break;
5953
                        case 5:
5954
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5955
                            break;
5956
                        default: abort();
5957
                        }
5958
                        tcg_temp_free_i32(tmp2);
5959
                        tcg_temp_free_i32(tmp);
5960
                        break;
5961
                    case 8: case 9: case 10: case 11: case 12: case 13:
5962
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5963
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5964
                        break;
5965
                    case 14: /* Polynomial VMULL */
5966
                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5967
                        tcg_temp_free_i32(tmp2);
5968
                        tcg_temp_free_i32(tmp);
5969
                        break;
5970
                    default: /* 15 is RESERVED: caught earlier  */
5971
                        abort();
5972
                    }
5973
                    if (op == 13) {
5974
                        /* VQDMULL */
5975
                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5976
                        neon_store_reg64(cpu_V0, rd + pass);
5977
                    } else if (op == 5 || (op >= 8 && op <= 11)) {
5978
                        /* Accumulate.  */
5979
                        neon_load_reg64(cpu_V1, rd + pass);
5980
                        switch (op) {
5981
                        case 10: /* VMLSL */
5982
                            gen_neon_negl(cpu_V0, size);
5983
                            /* Fall through */
5984
                        case 5: case 8: /* VABAL, VMLAL */
5985
                            gen_neon_addl(size);
5986
                            break;
5987
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5988
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5989
                            if (op == 11) {
5990
                                gen_neon_negl(cpu_V0, size);
5991
                            }
5992
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5993
                            break;
5994
                        default:
5995
                            abort();
5996
                        }
5997
                        neon_store_reg64(cpu_V0, rd + pass);
5998
                    } else if (op == 4 || op == 6) {
5999
                        /* Narrowing operation.  */
6000
                        tmp = tcg_temp_new_i32();
6001
                        if (!u) {
6002
                            switch (size) {
6003
                            case 0:
6004
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6005
                                break;
6006
                            case 1:
6007
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6008
                                break;
6009
                            case 2:
6010
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6011
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6012
                                break;
6013
                            default: abort();
6014
                            }
6015
                        } else {
6016
                            switch (size) {
6017
                            case 0:
6018
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6019
                                break;
6020
                            case 1:
6021
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6022
                                break;
6023
                            case 2:
6024
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6025
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6026
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6027
                                break;
6028
                            default: abort();
6029
                            }
6030
                        }
6031
                        if (pass == 0) {
6032
                            tmp3 = tmp;
6033
                        } else {
6034
                            neon_store_reg(rd, 0, tmp3);
6035
                            neon_store_reg(rd, 1, tmp);
6036
                        }
6037
                    } else {
6038
                        /* Write back the result.  */
6039
                        neon_store_reg64(cpu_V0, rd + pass);
6040
                    }
6041
                }
6042
            } else {
6043
                /* Two registers and a scalar. NB that for ops of this form
6044
                 * the ARM ARM labels bit 24 as Q, but it is in our variable
6045
                 * 'u', not 'q'.
6046
                 */
6047
                if (size == 0) {
6048
                    return 1;
6049
                }
6050
                switch (op) {
6051
                case 1: /* Float VMLA scalar */
6052
                case 5: /* Floating point VMLS scalar */
6053
                case 9: /* Floating point VMUL scalar */
6054
                    if (size == 1) {
6055
                        return 1;
6056
                    }
6057
                    /* fall through */
6058
                case 0: /* Integer VMLA scalar */
6059
                case 4: /* Integer VMLS scalar */
6060
                case 8: /* Integer VMUL scalar */
6061
                case 12: /* VQDMULH scalar */
6062
                case 13: /* VQRDMULH scalar */
6063
                    if (u && ((rd | rn) & 1)) {
6064
                        return 1;
6065
                    }
6066
                    tmp = neon_get_scalar(size, rm);
6067
                    neon_store_scratch(0, tmp);
6068
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
6069
                        tmp = neon_load_scratch(0);
6070
                        tmp2 = neon_load_reg(rn, pass);
6071
                        if (op == 12) {
6072
                            if (size == 1) {
6073
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6074
                            } else {
6075
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6076
                            }
6077
                        } else if (op == 13) {
6078
                            if (size == 1) {
6079
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6080
                            } else {
6081
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6082
                            }
6083
                        } else if (op & 1) {
6084
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6085
                            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6086
                            tcg_temp_free_ptr(fpstatus);
6087
                        } else {
6088
                            switch (size) {
6089
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6090
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6091
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6092
                            default: abort();
6093
                            }
6094
                        }
6095
                        tcg_temp_free_i32(tmp2);
6096
                        if (op < 8) {
6097
                            /* Accumulate.  */
6098
                            tmp2 = neon_load_reg(rd, pass);
6099
                            switch (op) {
6100
                            case 0:
6101
                                gen_neon_add(size, tmp, tmp2);
6102
                                break;
6103
                            case 1:
6104
                            {
6105
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6106
                                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6107
                                tcg_temp_free_ptr(fpstatus);
6108
                                break;
6109
                            }
6110
                            case 4:
6111
                                gen_neon_rsb(size, tmp, tmp2);
6112
                                break;
6113
                            case 5:
6114
                            {
6115
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6116
                                gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6117
                                tcg_temp_free_ptr(fpstatus);
6118
                                break;
6119
                            }
6120
                            default:
6121
                                abort();
6122
                            }
6123
                            tcg_temp_free_i32(tmp2);
6124
                        }
6125
                        neon_store_reg(rd, pass, tmp);
6126
                    }
6127
                    break;
6128
                case 3: /* VQDMLAL scalar */
6129
                case 7: /* VQDMLSL scalar */
6130
                case 11: /* VQDMULL scalar */
6131
                    if (u == 1) {
6132
                        return 1;
6133
                    }
6134
                    /* fall through */
6135
                case 2: /* VMLAL sclar */
6136
                case 6: /* VMLSL scalar */
6137
                case 10: /* VMULL scalar */
6138
                    if (rd & 1) {
6139
                        return 1;
6140
                    }
6141
                    tmp2 = neon_get_scalar(size, rm);
6142
                    /* We need a copy of tmp2 because gen_neon_mull
6143
                     * deletes it during pass 0.  */
6144
                    tmp4 = tcg_temp_new_i32();
6145
                    tcg_gen_mov_i32(tmp4, tmp2);
6146
                    tmp3 = neon_load_reg(rn, 1);
6147

    
6148
                    for (pass = 0; pass < 2; pass++) {
6149
                        if (pass == 0) {
6150
                            tmp = neon_load_reg(rn, 0);
6151
                        } else {
6152
                            tmp = tmp3;
6153
                            tmp2 = tmp4;
6154
                        }
6155
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6156
                        if (op != 11) {
6157
                            neon_load_reg64(cpu_V1, rd + pass);
6158
                        }
6159
                        switch (op) {
6160
                        case 6:
6161
                            gen_neon_negl(cpu_V0, size);
6162
                            /* Fall through */
6163
                        case 2:
6164
                            gen_neon_addl(size);
6165
                            break;
6166
                        case 3: case 7:
6167
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6168
                            if (op == 7) {
6169
                                gen_neon_negl(cpu_V0, size);
6170
                            }
6171
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6172
                            break;
6173
                        case 10:
6174
                            /* no-op */
6175
                            break;
6176
                        case 11:
6177
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6178
                            break;
6179
                        default:
6180
                            abort();
6181
                        }
6182
                        neon_store_reg64(cpu_V0, rd + pass);
6183
                    }
6184

    
6185

    
6186
                    break;
6187
                default: /* 14 and 15 are RESERVED */
6188
                    return 1;
6189
                }
6190
            }
6191
        } else { /* size == 3 */
6192
            if (!u) {
6193
                /* Extract.  */
6194
                imm = (insn >> 8) & 0xf;
6195

    
6196
                if (imm > 7 && !q)
6197
                    return 1;
6198

    
6199
                if (q && ((rd | rn | rm) & 1)) {
6200
                    return 1;
6201
                }
6202

    
6203
                if (imm == 0) {
6204
                    neon_load_reg64(cpu_V0, rn);
6205
                    if (q) {
6206
                        neon_load_reg64(cpu_V1, rn + 1);
6207
                    }
6208
                } else if (imm == 8) {
6209
                    neon_load_reg64(cpu_V0, rn + 1);
6210
                    if (q) {
6211
                        neon_load_reg64(cpu_V1, rm);
6212
                    }
6213
                } else if (q) {
6214
                    tmp64 = tcg_temp_new_i64();
6215
                    if (imm < 8) {
6216
                        neon_load_reg64(cpu_V0, rn);
6217
                        neon_load_reg64(tmp64, rn + 1);
6218
                    } else {
6219
                        neon_load_reg64(cpu_V0, rn + 1);
6220
                        neon_load_reg64(tmp64, rm);
6221
                    }
6222
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6223
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6224
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6225
                    if (imm < 8) {
6226
                        neon_load_reg64(cpu_V1, rm);
6227
                    } else {
6228
                        neon_load_reg64(cpu_V1, rm + 1);
6229
                        imm -= 8;
6230
                    }
6231
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6232
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6233
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6234
                    tcg_temp_free_i64(tmp64);
6235
                } else {
6236
                    /* BUGFIX */
6237
                    neon_load_reg64(cpu_V0, rn);
6238
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6239
                    neon_load_reg64(cpu_V1, rm);
6240
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6241
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6242
                }
6243
                neon_store_reg64(cpu_V0, rd);
6244
                if (q) {
6245
                    neon_store_reg64(cpu_V1, rd + 1);
6246
                }
6247
            } else if ((insn & (1 << 11)) == 0) {
6248
                /* Two register misc.  */
6249
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6250
                size = (insn >> 18) & 3;
6251
                /* UNDEF for unknown op values and bad op-size combinations */
6252
                if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6253
                    return 1;
6254
                }
6255
                if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6256
                    q && ((rm | rd) & 1)) {
6257
                    return 1;
6258
                }
6259
                switch (op) {
6260
                case NEON_2RM_VREV64:
6261
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
6262
                        tmp = neon_load_reg(rm, pass * 2);
6263
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
6264
                        switch (size) {
6265
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6266
                        case 1: gen_swap_half(tmp); break;
6267
                        case 2: /* no-op */ break;
6268
                        default: abort();
6269
                        }
6270
                        neon_store_reg(rd, pass * 2 + 1, tmp);
6271
                        if (size == 2) {
6272
                            neon_store_reg(rd, pass * 2, tmp2);
6273
                        } else {
6274
                            switch (size) {
6275
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6276
                            case 1: gen_swap_half(tmp2); break;
6277
                            default: abort();
6278
                            }
6279
                            neon_store_reg(rd, pass * 2, tmp2);
6280
                        }
6281
                    }
6282
                    break;
6283
                case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6284
                case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6285
                    for (pass = 0; pass < q + 1; pass++) {
6286
                        tmp = neon_load_reg(rm, pass * 2);
6287
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
6288
                        tmp = neon_load_reg(rm, pass * 2 + 1);
6289
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
6290
                        switch (size) {
6291
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6292
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6293
                        case 2: tcg_gen_add_i64(CPU_V001); break;
6294
                        default: abort();
6295
                        }
6296
                        if (op >= NEON_2RM_VPADAL) {
6297
                            /* Accumulate.  */
6298
                            neon_load_reg64(cpu_V1, rd + pass);
6299
                            gen_neon_addl(size);
6300
                        }
6301
                        neon_store_reg64(cpu_V0, rd + pass);
6302
                    }
6303
                    break;
6304
                case NEON_2RM_VTRN:
6305
                    if (size == 2) {
6306
                        int n;
6307
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
6308
                            tmp = neon_load_reg(rm, n);
6309
                            tmp2 = neon_load_reg(rd, n + 1);
6310
                            neon_store_reg(rm, n, tmp2);
6311
                            neon_store_reg(rd, n + 1, tmp);
6312
                        }
6313
                    } else {
6314
                        goto elementwise;
6315
                    }
6316
                    break;
6317
                case NEON_2RM_VUZP:
6318
                    if (gen_neon_unzip(rd, rm, size, q)) {
6319
                        return 1;
6320
                    }
6321
                    break;
6322
                case NEON_2RM_VZIP:
6323
                    if (gen_neon_zip(rd, rm, size, q)) {
6324
                        return 1;
6325
                    }
6326
                    break;
6327
                case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6328
                    /* also VQMOVUN; op field and mnemonics don't line up */
6329
                    if (rm & 1) {
6330
                        return 1;
6331
                    }
6332
                    TCGV_UNUSED_I32(tmp2);
6333
                    for (pass = 0; pass < 2; pass++) {
6334
                        neon_load_reg64(cpu_V0, rm + pass);
6335
                        tmp = tcg_temp_new_i32();
6336
                        gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6337
                                           tmp, cpu_V0);
6338
                        if (pass == 0) {
6339
                            tmp2 = tmp;
6340
                        } else {
6341
                            neon_store_reg(rd, 0, tmp2);
6342
                            neon_store_reg(rd, 1, tmp);
6343
                        }
6344
                    }
6345
                    break;
6346
                case NEON_2RM_VSHLL:
6347
                    if (q || (rd & 1)) {
6348
                        return 1;
6349
                    }
6350
                    tmp = neon_load_reg(rm, 0);
6351
                    tmp2 = neon_load_reg(rm, 1);
6352
                    for (pass = 0; pass < 2; pass++) {
6353
                        if (pass == 1)
6354
                            tmp = tmp2;
6355
                        gen_neon_widen(cpu_V0, tmp, size, 1);
6356
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6357
                        neon_store_reg64(cpu_V0, rd + pass);
6358
                    }
6359
                    break;
6360
                case NEON_2RM_VCVT_F16_F32:
6361
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6362
                        q || (rm & 1)) {
6363
                        return 1;
6364
                    }
6365
                    tmp = tcg_temp_new_i32();
6366
                    tmp2 = tcg_temp_new_i32();
6367
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6368
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6369
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6370
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6371
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
6372
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
6373
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6374
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6375
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6376
                    neon_store_reg(rd, 0, tmp2);
6377
                    tmp2 = tcg_temp_new_i32();
6378
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6379
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
6380
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
6381
                    neon_store_reg(rd, 1, tmp2);
6382
                    tcg_temp_free_i32(tmp);
6383
                    break;
6384
                case NEON_2RM_VCVT_F32_F16:
6385
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6386
                        q || (rd & 1)) {
6387
                        return 1;
6388
                    }
6389
                    tmp3 = tcg_temp_new_i32();
6390
                    tmp = neon_load_reg(rm, 0);
6391
                    tmp2 = neon_load_reg(rm, 1);
6392
                    tcg_gen_ext16u_i32(tmp3, tmp);
6393
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6394
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6395
                    tcg_gen_shri_i32(tmp3, tmp, 16);
6396
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6397
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6398
                    tcg_temp_free_i32(tmp);
6399
                    tcg_gen_ext16u_i32(tmp3, tmp2);
6400
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6401
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6402
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
6403
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6404
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6405
                    tcg_temp_free_i32(tmp2);
6406
                    tcg_temp_free_i32(tmp3);
6407
                    break;
6408
                case NEON_2RM_AESE: case NEON_2RM_AESMC:
6409
                    if (!arm_feature(env, ARM_FEATURE_V8_AES)
6410
                        || ((rm | rd) & 1)) {
6411
                        return 1;
6412
                    }
6413
                    tmp = tcg_const_i32(rd);
6414
                    tmp2 = tcg_const_i32(rm);
6415

    
6416
                     /* Bit 6 is the lowest opcode bit; it distinguishes between
6417
                      * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6418
                      */
6419
                    tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6420

    
6421
                    if (op == NEON_2RM_AESE) {
6422
                        gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6423
                    } else {
6424
                        gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6425
                    }
6426
                    tcg_temp_free_i32(tmp);
6427
                    tcg_temp_free_i32(tmp2);
6428
                    tcg_temp_free_i32(tmp3);
6429
                    break;
6430
                default:
6431
                elementwise:
6432
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
6433
                        if (neon_2rm_is_float_op(op)) {
6434
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
6435
                                           neon_reg_offset(rm, pass));
6436
                            TCGV_UNUSED_I32(tmp);
6437
                        } else {
6438
                            tmp = neon_load_reg(rm, pass);
6439
                        }
6440
                        switch (op) {
6441
                        case NEON_2RM_VREV32:
6442
                            switch (size) {
6443
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6444
                            case 1: gen_swap_half(tmp); break;
6445
                            default: abort();
6446
                            }
6447
                            break;
6448
                        case NEON_2RM_VREV16:
6449
                            gen_rev16(tmp);
6450
                            break;
6451
                        case NEON_2RM_VCLS:
6452
                            switch (size) {
6453
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6454
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6455
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6456
                            default: abort();
6457
                            }
6458
                            break;
6459
                        case NEON_2RM_VCLZ:
6460
                            switch (size) {
6461
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6462
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6463
                            case 2: gen_helper_clz(tmp, tmp); break;
6464
                            default: abort();
6465
                            }
6466
                            break;
6467
                        case NEON_2RM_VCNT:
6468
                            gen_helper_neon_cnt_u8(tmp, tmp);
6469
                            break;
6470
                        case NEON_2RM_VMVN:
6471
                            tcg_gen_not_i32(tmp, tmp);
6472
                            break;
6473
                        case NEON_2RM_VQABS:
6474
                            switch (size) {
6475
                            case 0:
6476
                                gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6477
                                break;
6478
                            case 1:
6479
                                gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6480
                                break;
6481
                            case 2:
6482
                                gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6483
                                break;
6484
                            default: abort();
6485
                            }
6486
                            break;
6487
                        case NEON_2RM_VQNEG:
6488
                            switch (size) {
6489
                            case 0:
6490
                                gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6491
                                break;
6492
                            case 1:
6493
                                gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6494
                                break;
6495
                            case 2:
6496
                                gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6497
                                break;
6498
                            default: abort();
6499
                            }
6500
                            break;
6501
                        case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6502
                            tmp2 = tcg_const_i32(0);
6503
                            switch(size) {
6504
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6505
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6506
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6507
                            default: abort();
6508
                            }
6509
                            tcg_temp_free_i32(tmp2);
6510
                            if (op == NEON_2RM_VCLE0) {
6511
                                tcg_gen_not_i32(tmp, tmp);
6512
                            }
6513
                            break;
6514
                        case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6515
                            tmp2 = tcg_const_i32(0);
6516
                            switch(size) {
6517
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6518
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6519
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6520
                            default: abort();
6521
                            }
6522
                            tcg_temp_free_i32(tmp2);
6523
                            if (op == NEON_2RM_VCLT0) {
6524
                                tcg_gen_not_i32(tmp, tmp);
6525
                            }
6526
                            break;
6527
                        case NEON_2RM_VCEQ0:
6528
                            tmp2 = tcg_const_i32(0);
6529
                            switch(size) {
6530
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6531
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6532
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6533
                            default: abort();
6534
                            }
6535
                            tcg_temp_free_i32(tmp2);
6536
                            break;
6537
                        case NEON_2RM_VABS:
6538
                            switch(size) {
6539
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6540
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6541
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
6542
                            default: abort();
6543
                            }
6544
                            break;
6545
                        case NEON_2RM_VNEG:
6546
                            tmp2 = tcg_const_i32(0);
6547
                            gen_neon_rsb(size, tmp, tmp2);
6548
                            tcg_temp_free_i32(tmp2);
6549
                            break;
6550
                        case NEON_2RM_VCGT0_F:
6551
                        {
6552
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6553
                            tmp2 = tcg_const_i32(0);
6554
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6555
                            tcg_temp_free_i32(tmp2);
6556
                            tcg_temp_free_ptr(fpstatus);
6557
                            break;
6558
                        }
6559
                        case NEON_2RM_VCGE0_F:
6560
                        {
6561
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6562
                            tmp2 = tcg_const_i32(0);
6563
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6564
                            tcg_temp_free_i32(tmp2);
6565
                            tcg_temp_free_ptr(fpstatus);
6566
                            break;
6567
                        }
6568
                        case NEON_2RM_VCEQ0_F:
6569
                        {
6570
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6571
                            tmp2 = tcg_const_i32(0);
6572
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6573
                            tcg_temp_free_i32(tmp2);
6574
                            tcg_temp_free_ptr(fpstatus);
6575
                            break;
6576
                        }
6577
                        case NEON_2RM_VCLE0_F:
6578
                        {
6579
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6580
                            tmp2 = tcg_const_i32(0);
6581
                            gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6582
                            tcg_temp_free_i32(tmp2);
6583
                            tcg_temp_free_ptr(fpstatus);
6584
                            break;
6585
                        }
6586
                        case NEON_2RM_VCLT0_F:
6587
                        {
6588
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6589
                            tmp2 = tcg_const_i32(0);
6590
                            gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6591
                            tcg_temp_free_i32(tmp2);
6592
                            tcg_temp_free_ptr(fpstatus);
6593
                            break;
6594
                        }
6595
                        case NEON_2RM_VABS_F:
6596
                            gen_vfp_abs(0);
6597
                            break;
6598
                        case NEON_2RM_VNEG_F:
6599
                            gen_vfp_neg(0);
6600
                            break;
6601
                        case NEON_2RM_VSWP:
6602
                            tmp2 = neon_load_reg(rd, pass);
6603
                            neon_store_reg(rm, pass, tmp2);
6604
                            break;
6605
                        case NEON_2RM_VTRN:
6606
                            tmp2 = neon_load_reg(rd, pass);
6607
                            switch (size) {
6608
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
6609
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
6610
                            default: abort();
6611
                            }
6612
                            neon_store_reg(rm, pass, tmp2);
6613
                            break;
6614
                        case NEON_2RM_VRINTN:
6615
                        case NEON_2RM_VRINTA:
6616
                        case NEON_2RM_VRINTM:
6617
                        case NEON_2RM_VRINTP:
6618
                        case NEON_2RM_VRINTZ:
6619
                        {
6620
                            TCGv_i32 tcg_rmode;
6621
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6622
                            int rmode;
6623

    
6624
                            if (op == NEON_2RM_VRINTZ) {
6625
                                rmode = FPROUNDING_ZERO;
6626
                            } else {
6627
                                rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6628
                            }
6629

    
6630
                            tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6631
                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6632
                                                      cpu_env);
6633
                            gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6634
                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6635
                                                      cpu_env);
6636
                            tcg_temp_free_ptr(fpstatus);
6637
                            tcg_temp_free_i32(tcg_rmode);
6638
                            break;
6639
                        }
6640
                        case NEON_2RM_VRINTX:
6641
                        {
6642
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6643
                            gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6644
                            tcg_temp_free_ptr(fpstatus);
6645
                            break;
6646
                        }
6647
                        case NEON_2RM_VCVTAU:
6648
                        case NEON_2RM_VCVTAS:
6649
                        case NEON_2RM_VCVTNU:
6650
                        case NEON_2RM_VCVTNS:
6651
                        case NEON_2RM_VCVTPU:
6652
                        case NEON_2RM_VCVTPS:
6653
                        case NEON_2RM_VCVTMU:
6654
                        case NEON_2RM_VCVTMS:
6655
                        {
6656
                            bool is_signed = !extract32(insn, 7, 1);
6657
                            TCGv_ptr fpst = get_fpstatus_ptr(1);
6658
                            TCGv_i32 tcg_rmode, tcg_shift;
6659
                            int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6660

    
6661
                            tcg_shift = tcg_const_i32(0);
6662
                            tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6663
                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6664
                                                      cpu_env);
6665

    
6666
                            if (is_signed) {
6667
                                gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6668
                                                     tcg_shift, fpst);
6669
                            } else {
6670
                                gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6671
                                                     tcg_shift, fpst);
6672
                            }
6673

    
6674
                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6675
                                                      cpu_env);
6676
                            tcg_temp_free_i32(tcg_rmode);
6677
                            tcg_temp_free_i32(tcg_shift);
6678
                            tcg_temp_free_ptr(fpst);
6679
                            break;
6680
                        }
6681
                        case NEON_2RM_VRECPE:
6682
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
6683
                            break;
6684
                        case NEON_2RM_VRSQRTE:
6685
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6686
                            break;
6687
                        case NEON_2RM_VRECPE_F:
6688
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6689
                            break;
6690
                        case NEON_2RM_VRSQRTE_F:
6691
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6692
                            break;
6693
                        case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6694
                            gen_vfp_sito(0, 1);
6695
                            break;
6696
                        case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6697
                            gen_vfp_uito(0, 1);
6698
                            break;
6699
                        case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6700
                            gen_vfp_tosiz(0, 1);
6701
                            break;
6702
                        case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6703
                            gen_vfp_touiz(0, 1);
6704
                            break;
6705
                        default:
6706
                            /* Reserved op values were caught by the
6707
                             * neon_2rm_sizes[] check earlier.
6708
                             */
6709
                            abort();
6710
                        }
6711
                        if (neon_2rm_is_float_op(op)) {
6712
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
6713
                                           neon_reg_offset(rd, pass));
6714
                        } else {
6715
                            neon_store_reg(rd, pass, tmp);
6716
                        }
6717
                    }
6718
                    break;
6719
                }
6720
            } else if ((insn & (1 << 10)) == 0) {
6721
                /* VTBL, VTBX.  */
6722
                int n = ((insn >> 8) & 3) + 1;
6723
                if ((rn + n) > 32) {
6724
                    /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6725
                     * helper function running off the end of the register file.
6726
                     */
6727
                    return 1;
6728
                }
6729
                n <<= 3;
6730
                if (insn & (1 << 6)) {
6731
                    tmp = neon_load_reg(rd, 0);
6732
                } else {
6733
                    tmp = tcg_temp_new_i32();
6734
                    tcg_gen_movi_i32(tmp, 0);
6735
                }
6736
                tmp2 = neon_load_reg(rm, 0);
6737
                tmp4 = tcg_const_i32(rn);
6738
                tmp5 = tcg_const_i32(n);
6739
                gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6740
                tcg_temp_free_i32(tmp);
6741
                if (insn & (1 << 6)) {
6742
                    tmp = neon_load_reg(rd, 1);
6743
                } else {
6744
                    tmp = tcg_temp_new_i32();
6745
                    tcg_gen_movi_i32(tmp, 0);
6746
                }
6747
                tmp3 = neon_load_reg(rm, 1);
6748
                gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6749
                tcg_temp_free_i32(tmp5);
6750
                tcg_temp_free_i32(tmp4);
6751
                neon_store_reg(rd, 0, tmp2);
6752
                neon_store_reg(rd, 1, tmp3);
6753
                tcg_temp_free_i32(tmp);
6754
            } else if ((insn & 0x380) == 0) {
6755
                /* VDUP */
6756
                if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6757
                    return 1;
6758
                }
6759
                if (insn & (1 << 19)) {
6760
                    tmp = neon_load_reg(rm, 1);
6761
                } else {
6762
                    tmp = neon_load_reg(rm, 0);
6763
                }
6764
                if (insn & (1 << 16)) {
6765
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6766
                } else if (insn & (1 << 17)) {
6767
                    if ((insn >> 18) & 1)
6768
                        gen_neon_dup_high16(tmp);
6769
                    else
6770
                        gen_neon_dup_low16(tmp);
6771
                }
6772
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
6773
                    tmp2 = tcg_temp_new_i32();
6774
                    tcg_gen_mov_i32(tmp2, tmp);
6775
                    neon_store_reg(rd, pass, tmp2);
6776
                }
6777
                tcg_temp_free_i32(tmp);
6778
            } else {
6779
                return 1;
6780
            }
6781
        }
6782
    }
6783
    return 0;
6784
}
6785

    
6786
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6787
{
6788
    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6789
    const ARMCPRegInfo *ri;
6790

    
6791
    cpnum = (insn >> 8) & 0xf;
6792
    if (arm_feature(env, ARM_FEATURE_XSCALE)
6793
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6794
        return 1;
6795

    
6796
    /* First check for coprocessor space used for actual instructions */
6797
    switch (cpnum) {
6798
      case 0:
6799
      case 1:
6800
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6801
            return disas_iwmmxt_insn(env, s, insn);
6802
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6803
            return disas_dsp_insn(env, s, insn);
6804
        }
6805
        return 1;
6806
    default:
6807
        break;
6808
    }
6809

    
6810
    /* Otherwise treat as a generic register access */
6811
    is64 = (insn & (1 << 25)) == 0;
6812
    if (!is64 && ((insn & (1 << 4)) == 0)) {
6813
        /* cdp */
6814
        return 1;
6815
    }
6816

    
6817
    crm = insn & 0xf;
6818
    if (is64) {
6819
        crn = 0;
6820
        opc1 = (insn >> 4) & 0xf;
6821
        opc2 = 0;
6822
        rt2 = (insn >> 16) & 0xf;
6823
    } else {
6824
        crn = (insn >> 16) & 0xf;
6825
        opc1 = (insn >> 21) & 7;
6826
        opc2 = (insn >> 5) & 7;
6827
        rt2 = 0;
6828
    }
6829
    isread = (insn >> 20) & 1;
6830
    rt = (insn >> 12) & 0xf;
6831

    
6832
    ri = get_arm_cp_reginfo(s->cp_regs,
6833
                            ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6834
    if (ri) {
6835
        /* Check access permissions */
6836
        if (!cp_access_ok(s->current_pl, ri, isread)) {
6837
            return 1;
6838
        }
6839

    
6840
        if (ri->accessfn) {
6841
            /* Emit code to perform further access permissions checks at
6842
             * runtime; this may result in an exception.
6843
             */
6844
            TCGv_ptr tmpptr;
6845
            gen_set_pc_im(s, s->pc);
6846
            tmpptr = tcg_const_ptr(ri);
6847
            gen_helper_access_check_cp_reg(cpu_env, tmpptr);
6848
            tcg_temp_free_ptr(tmpptr);
6849
        }
6850

    
6851
        /* Handle special cases first */
6852
        switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6853
        case ARM_CP_NOP:
6854
            return 0;
6855
        case ARM_CP_WFI:
6856
            if (isread) {
6857
                return 1;
6858
            }
6859
            gen_set_pc_im(s, s->pc);
6860
            s->is_jmp = DISAS_WFI;
6861
            return 0;
6862
        default:
6863
            break;
6864
        }
6865

    
6866
        if (use_icount && (ri->type & ARM_CP_IO)) {
6867
            gen_io_start();
6868
        }
6869

    
6870
        if (isread) {
6871
            /* Read */
6872
            if (is64) {
6873
                TCGv_i64 tmp64;
6874
                TCGv_i32 tmp;
6875
                if (ri->type & ARM_CP_CONST) {
6876
                    tmp64 = tcg_const_i64(ri->resetvalue);
6877
                } else if (ri->readfn) {
6878
                    TCGv_ptr tmpptr;
6879
                    tmp64 = tcg_temp_new_i64();
6880
                    tmpptr = tcg_const_ptr(ri);
6881
                    gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6882
                    tcg_temp_free_ptr(tmpptr);
6883
                } else {
6884
                    tmp64 = tcg_temp_new_i64();
6885
                    tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6886
                }
6887
                tmp = tcg_temp_new_i32();
6888
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6889
                store_reg(s, rt, tmp);
6890
                tcg_gen_shri_i64(tmp64, tmp64, 32);
6891
                tmp = tcg_temp_new_i32();
6892
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6893
                tcg_temp_free_i64(tmp64);
6894
                store_reg(s, rt2, tmp);
6895
            } else {
6896
                TCGv_i32 tmp;
6897
                if (ri->type & ARM_CP_CONST) {
6898
                    tmp = tcg_const_i32(ri->resetvalue);
6899
                } else if (ri->readfn) {
6900
                    TCGv_ptr tmpptr;
6901
                    tmp = tcg_temp_new_i32();
6902
                    tmpptr = tcg_const_ptr(ri);
6903
                    gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6904
                    tcg_temp_free_ptr(tmpptr);
6905
                } else {
6906
                    tmp = load_cpu_offset(ri->fieldoffset);
6907
                }
6908
                if (rt == 15) {
6909
                    /* Destination register of r15 for 32 bit loads sets
6910
                     * the condition codes from the high 4 bits of the value
6911
                     */
6912
                    gen_set_nzcv(tmp);
6913
                    tcg_temp_free_i32(tmp);
6914
                } else {
6915
                    store_reg(s, rt, tmp);
6916
                }
6917
            }
6918
        } else {
6919
            /* Write */
6920
            if (ri->type & ARM_CP_CONST) {
6921
                /* If not forbidden by access permissions, treat as WI */
6922
                return 0;
6923
            }
6924

    
6925
            if (is64) {
6926
                TCGv_i32 tmplo, tmphi;
6927
                TCGv_i64 tmp64 = tcg_temp_new_i64();
6928
                tmplo = load_reg(s, rt);
6929
                tmphi = load_reg(s, rt2);
6930
                tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6931
                tcg_temp_free_i32(tmplo);
6932
                tcg_temp_free_i32(tmphi);
6933
                if (ri->writefn) {
6934
                    TCGv_ptr tmpptr = tcg_const_ptr(ri);
6935
                    gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6936
                    tcg_temp_free_ptr(tmpptr);
6937
                } else {
6938
                    tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6939
                }
6940
                tcg_temp_free_i64(tmp64);
6941
            } else {
6942
                if (ri->writefn) {
6943
                    TCGv_i32 tmp;
6944
                    TCGv_ptr tmpptr;
6945
                    tmp = load_reg(s, rt);
6946
                    tmpptr = tcg_const_ptr(ri);
6947
                    gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6948
                    tcg_temp_free_ptr(tmpptr);
6949
                    tcg_temp_free_i32(tmp);
6950
                } else {
6951
                    TCGv_i32 tmp = load_reg(s, rt);
6952
                    store_cpu_offset(tmp, ri->fieldoffset);
6953
                }
6954
            }
6955
        }
6956

    
6957
        if (use_icount && (ri->type & ARM_CP_IO)) {
6958
            /* I/O operations must end the TB here (whether read or write) */
6959
            gen_io_end();
6960
            gen_lookup_tb(s);
6961
        } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6962
            /* We default to ending the TB on a coprocessor register write,
6963
             * but allow this to be suppressed by the register definition
6964
             * (usually only necessary to work around guest bugs).
6965
             */
6966
            gen_lookup_tb(s);
6967
        }
6968

    
6969
        return 0;
6970
    }
6971

    
6972
    /* Unknown register; this might be a guest error or a QEMU
6973
     * unimplemented feature.
6974
     */
6975
    if (is64) {
6976
        qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
6977
                      "64 bit system register cp:%d opc1: %d crm:%d\n",
6978
                      isread ? "read" : "write", cpnum, opc1, crm);
6979
    } else {
6980
        qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
6981
                      "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
6982
                      isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
6983
    }
6984

    
6985
    return 1;
6986
}
6987

    
6988

    
6989
/* Store a 64-bit value to a register pair.  Clobbers val.  */
6990
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6991
{
6992
    TCGv_i32 tmp;
6993
    tmp = tcg_temp_new_i32();
6994
    tcg_gen_trunc_i64_i32(tmp, val);
6995
    store_reg(s, rlow, tmp);
6996
    tmp = tcg_temp_new_i32();
6997
    tcg_gen_shri_i64(val, val, 32);
6998
    tcg_gen_trunc_i64_i32(tmp, val);
6999
    store_reg(s, rhigh, tmp);
7000
}
7001

    
7002
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
7003
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7004
{
7005
    TCGv_i64 tmp;
7006
    TCGv_i32 tmp2;
7007

    
7008
    /* Load value and extend to 64 bits.  */
7009
    tmp = tcg_temp_new_i64();
7010
    tmp2 = load_reg(s, rlow);
7011
    tcg_gen_extu_i32_i64(tmp, tmp2);
7012
    tcg_temp_free_i32(tmp2);
7013
    tcg_gen_add_i64(val, val, tmp);
7014
    tcg_temp_free_i64(tmp);
7015
}
7016

    
7017
/* load and add a 64-bit value from a register pair.  */
7018
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7019
{
7020
    TCGv_i64 tmp;
7021
    TCGv_i32 tmpl;
7022
    TCGv_i32 tmph;
7023

    
7024
    /* Load 64-bit value rd:rn.  */
7025
    tmpl = load_reg(s, rlow);
7026
    tmph = load_reg(s, rhigh);
7027
    tmp = tcg_temp_new_i64();
7028
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7029
    tcg_temp_free_i32(tmpl);
7030
    tcg_temp_free_i32(tmph);
7031
    tcg_gen_add_i64(val, val, tmp);
7032
    tcg_temp_free_i64(tmp);
7033
}
7034

    
7035
/* Set N and Z flags from hi|lo.  */
7036
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7037
{
7038
    tcg_gen_mov_i32(cpu_NF, hi);
7039
    tcg_gen_or_i32(cpu_ZF, lo, hi);
7040
}
7041

    
7042
/* Load/Store exclusive instructions are implemented by remembering
7043
   the value/address loaded, and seeing if these are the same
7044
   when the store is performed. This should be sufficient to implement
7045
   the architecturally mandated semantics, and avoids having to monitor
7046
   regular stores.
7047

7048
   In system emulation mode only one CPU will be running at once, so
7049
   this sequence is effectively atomic.  In user emulation mode we
7050
   throw an exception and handle the atomic operation elsewhere.  */
7051
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7052
                               TCGv_i32 addr, int size)
7053
{
7054
    TCGv_i32 tmp = tcg_temp_new_i32();
7055

    
7056
    switch (size) {
7057
    case 0:
7058
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
7059
        break;
7060
    case 1:
7061
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
7062
        break;
7063
    case 2:
7064
    case 3:
7065
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
7066
        break;
7067
    default:
7068
        abort();
7069
    }
7070

    
7071
    if (size == 3) {
7072
        TCGv_i32 tmp2 = tcg_temp_new_i32();
7073
        TCGv_i32 tmp3 = tcg_temp_new_i32();
7074

    
7075
        tcg_gen_addi_i32(tmp2, addr, 4);
7076
        gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7077
        tcg_temp_free_i32(tmp2);
7078
        tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7079
        store_reg(s, rt2, tmp3);
7080
    } else {
7081
        tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7082
    }
7083

    
7084
    store_reg(s, rt, tmp);
7085
    tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7086
}
7087

    
7088
static void gen_clrex(DisasContext *s)
7089
{
7090
    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7091
}
7092

    
7093
#ifdef CONFIG_USER_ONLY
7094
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7095
                                TCGv_i32 addr, int size)
7096
{
7097
    tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7098
    tcg_gen_movi_i32(cpu_exclusive_info,
7099
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
7100
    gen_exception_insn(s, 4, EXCP_STREX);
7101
}
7102
#else
7103
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7104
                                TCGv_i32 addr, int size)
7105
{
7106
    TCGv_i32 tmp;
7107
    TCGv_i64 val64, extaddr;
7108
    int done_label;
7109
    int fail_label;
7110

    
7111
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7112
         [addr] = {Rt};
7113
         {Rd} = 0;
7114
       } else {
7115
         {Rd} = 1;
7116
       } */
7117
    fail_label = gen_new_label();
7118
    done_label = gen_new_label();
7119
    extaddr = tcg_temp_new_i64();
7120
    tcg_gen_extu_i32_i64(extaddr, addr);
7121
    tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7122
    tcg_temp_free_i64(extaddr);
7123

    
7124
    tmp = tcg_temp_new_i32();
7125
    switch (size) {
7126
    case 0:
7127
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
7128
        break;
7129
    case 1:
7130
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
7131
        break;
7132
    case 2:
7133
    case 3:
7134
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
7135
        break;
7136
    default:
7137
        abort();
7138
    }
7139

    
7140
    val64 = tcg_temp_new_i64();
7141
    if (size == 3) {
7142
        TCGv_i32 tmp2 = tcg_temp_new_i32();
7143
        TCGv_i32 tmp3 = tcg_temp_new_i32();
7144
        tcg_gen_addi_i32(tmp2, addr, 4);
7145
        gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7146
        tcg_temp_free_i32(tmp2);
7147
        tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7148
        tcg_temp_free_i32(tmp3);
7149
    } else {
7150
        tcg_gen_extu_i32_i64(val64, tmp);
7151
    }
7152
    tcg_temp_free_i32(tmp);
7153

    
7154
    tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7155
    tcg_temp_free_i64(val64);
7156

    
7157
    tmp = load_reg(s, rt);
7158
    switch (size) {
7159
    case 0:
7160
        gen_aa32_st8(tmp, addr, IS_USER(s));
7161
        break;
7162
    case 1:
7163
        gen_aa32_st16(tmp, addr, IS_USER(s));
7164
        break;
7165
    case 2:
7166
    case 3:
7167
        gen_aa32_st32(tmp, addr, IS_USER(s));
7168
        break;
7169
    default:
7170
        abort();
7171
    }
7172
    tcg_temp_free_i32(tmp);
7173
    if (size == 3) {
7174
        tcg_gen_addi_i32(addr, addr, 4);
7175
        tmp = load_reg(s, rt2);
7176
        gen_aa32_st32(tmp, addr, IS_USER(s));
7177
        tcg_temp_free_i32(tmp);
7178
    }
7179
    tcg_gen_movi_i32(cpu_R[rd], 0);
7180
    tcg_gen_br(done_label);
7181
    gen_set_label(fail_label);
7182
    tcg_gen_movi_i32(cpu_R[rd], 1);
7183
    gen_set_label(done_label);
7184
    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7185
}
7186
#endif
7187

    
7188
/* gen_srs:
7189
 * @env: CPUARMState
7190
 * @s: DisasContext
7191
 * @mode: mode field from insn (which stack to store to)
7192
 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7193
 * @writeback: true if writeback bit set
7194
 *
7195
 * Generate code for the SRS (Store Return State) insn.
7196
 */
7197
static void gen_srs(DisasContext *s,
7198
                    uint32_t mode, uint32_t amode, bool writeback)
7199
{
7200
    int32_t offset;
7201
    TCGv_i32 addr = tcg_temp_new_i32();
7202
    TCGv_i32 tmp = tcg_const_i32(mode);
7203
    gen_helper_get_r13_banked(addr, cpu_env, tmp);
7204
    tcg_temp_free_i32(tmp);
7205
    switch (amode) {
7206
    case 0: /* DA */
7207
        offset = -4;
7208
        break;
7209
    case 1: /* IA */
7210
        offset = 0;
7211
        break;
7212
    case 2: /* DB */
7213
        offset = -8;
7214
        break;
7215
    case 3: /* IB */
7216
        offset = 4;
7217
        break;
7218
    default:
7219
        abort();
7220
    }
7221
    tcg_gen_addi_i32(addr, addr, offset);
7222
    tmp = load_reg(s, 14);
7223
    gen_aa32_st32(tmp, addr, 0);
7224
    tcg_temp_free_i32(tmp);
7225
    tmp = load_cpu_field(spsr);
7226
    tcg_gen_addi_i32(addr, addr, 4);
7227
    gen_aa32_st32(tmp, addr, 0);
7228
    tcg_temp_free_i32(tmp);
7229
    if (writeback) {
7230
        switch (amode) {
7231
        case 0:
7232
            offset = -8;
7233
            break;
7234
        case 1:
7235
            offset = 4;
7236
            break;
7237
        case 2:
7238
            offset = -4;
7239
            break;
7240
        case 3:
7241
            offset = 0;
7242
            break;
7243
        default:
7244
            abort();
7245
        }
7246
        tcg_gen_addi_i32(addr, addr, offset);
7247
        tmp = tcg_const_i32(mode);
7248
        gen_helper_set_r13_banked(cpu_env, tmp, addr);
7249
        tcg_temp_free_i32(tmp);
7250
    }
7251
    tcg_temp_free_i32(addr);
7252
}
7253

    
7254
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
7255
{
7256
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7257
    TCGv_i32 tmp;
7258
    TCGv_i32 tmp2;
7259
    TCGv_i32 tmp3;
7260
    TCGv_i32 addr;
7261
    TCGv_i64 tmp64;
7262

    
7263
    insn = arm_ldl_code(env, s->pc, s->bswap_code);
7264
    s->pc += 4;
7265

    
7266
    /* M variants do not implement ARM mode.  */
7267
    if (IS_M(env))
7268
        goto illegal_op;
7269
    cond = insn >> 28;
7270
    if (cond == 0xf){
7271
        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7272
         * choose to UNDEF. In ARMv5 and above the space is used
7273
         * for miscellaneous unconditional instructions.
7274
         */
7275
        ARCH(5);
7276

    
7277
        /* Unconditional instructions.  */
7278
        if (((insn >> 25) & 7) == 1) {
7279
            /* NEON Data processing.  */
7280
            if (!arm_feature(env, ARM_FEATURE_NEON))
7281
                goto illegal_op;
7282

    
7283
            if (disas_neon_data_insn(env, s, insn))
7284
                goto illegal_op;
7285
            return;
7286
        }
7287
        if ((insn & 0x0f100000) == 0x04000000) {
7288
            /* NEON load/store.  */
7289
            if (!arm_feature(env, ARM_FEATURE_NEON))
7290
                goto illegal_op;
7291

    
7292
            if (disas_neon_ls_insn(env, s, insn))
7293
                goto illegal_op;
7294
            return;
7295
        }
7296
        if ((insn & 0x0f000e10) == 0x0e000a00) {
7297
            /* VFP.  */
7298
            if (disas_vfp_insn(env, s, insn)) {
7299
                goto illegal_op;
7300
            }
7301
            return;
7302
        }
7303
        if (((insn & 0x0f30f000) == 0x0510f000) ||
7304
            ((insn & 0x0f30f010) == 0x0710f000)) {
7305
            if ((insn & (1 << 22)) == 0) {
7306
                /* PLDW; v7MP */
7307
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7308
                    goto illegal_op;
7309
                }
7310
            }
7311
            /* Otherwise PLD; v5TE+ */
7312
            ARCH(5TE);
7313
            return;
7314
        }
7315
        if (((insn & 0x0f70f000) == 0x0450f000) ||
7316
            ((insn & 0x0f70f010) == 0x0650f000)) {
7317
            ARCH(7);
7318
            return; /* PLI; V7 */
7319
        }
7320
        if (((insn & 0x0f700000) == 0x04100000) ||
7321
            ((insn & 0x0f700010) == 0x06100000)) {
7322
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7323
                goto illegal_op;
7324
            }
7325
            return; /* v7MP: Unallocated memory hint: must NOP */
7326
        }
7327

    
7328
        if ((insn & 0x0ffffdff) == 0x01010000) {
7329
            ARCH(6);
7330
            /* setend */
7331
            if (((insn >> 9) & 1) != s->bswap_code) {
7332
                /* Dynamic endianness switching not implemented. */
7333
                qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7334
                goto illegal_op;
7335
            }
7336
            return;
7337
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
7338
            switch ((insn >> 4) & 0xf) {
7339
            case 1: /* clrex */
7340
                ARCH(6K);
7341
                gen_clrex(s);
7342
                return;
7343
            case 4: /* dsb */
7344
            case 5: /* dmb */
7345
            case 6: /* isb */
7346
                ARCH(7);
7347
                /* We don't emulate caches so these are a no-op.  */
7348
                return;
7349
            default:
7350
                goto illegal_op;
7351
            }
7352
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7353
            /* srs */
7354
            if (IS_USER(s)) {
7355
                goto illegal_op;
7356
            }
7357
            ARCH(6);
7358
            gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7359
            return;
7360
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7361
            /* rfe */
7362
            int32_t offset;
7363
            if (IS_USER(s))
7364
                goto illegal_op;
7365
            ARCH(6);
7366
            rn = (insn >> 16) & 0xf;
7367
            addr = load_reg(s, rn);
7368
            i = (insn >> 23) & 3;
7369
            switch (i) {
7370
            case 0: offset = -4; break; /* DA */
7371
            case 1: offset = 0; break; /* IA */
7372
            case 2: offset = -8; break; /* DB */
7373
            case 3: offset = 4; break; /* IB */
7374
            default: abort();
7375
            }
7376
            if (offset)
7377
                tcg_gen_addi_i32(addr, addr, offset);
7378
            /* Load PC into tmp and CPSR into tmp2.  */
7379
            tmp = tcg_temp_new_i32();
7380
            gen_aa32_ld32u(tmp, addr, 0);
7381
            tcg_gen_addi_i32(addr, addr, 4);
7382
            tmp2 = tcg_temp_new_i32();
7383
            gen_aa32_ld32u(tmp2, addr, 0);
7384
            if (insn & (1 << 21)) {
7385
                /* Base writeback.  */
7386
                switch (i) {
7387
                case 0: offset = -8; break;
7388
                case 1: offset = 4; break;
7389
                case 2: offset = -4; break;
7390
                case 3: offset = 0; break;
7391
                default: abort();
7392
                }
7393
                if (offset)
7394
                    tcg_gen_addi_i32(addr, addr, offset);
7395
                store_reg(s, rn, addr);
7396
            } else {
7397
                tcg_temp_free_i32(addr);
7398
            }
7399
            gen_rfe(s, tmp, tmp2);
7400
            return;
7401
        } else if ((insn & 0x0e000000) == 0x0a000000) {
7402
            /* branch link and change to thumb (blx <offset>) */
7403
            int32_t offset;
7404

    
7405
            val = (uint32_t)s->pc;
7406
            tmp = tcg_temp_new_i32();
7407
            tcg_gen_movi_i32(tmp, val);
7408
            store_reg(s, 14, tmp);
7409
            /* Sign-extend the 24-bit offset */
7410
            offset = (((int32_t)insn) << 8) >> 8;
7411
            /* offset * 4 + bit24 * 2 + (thumb bit) */
7412
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
7413
            /* pipeline offset */
7414
            val += 4;
7415
            /* protected by ARCH(5); above, near the start of uncond block */
7416
            gen_bx_im(s, val);
7417
            return;
7418
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
7419
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7420
                /* iWMMXt register transfer.  */
7421
                if (env->cp15.c15_cpar & (1 << 1))
7422
                    if (!disas_iwmmxt_insn(env, s, insn))
7423
                        return;
7424
            }
7425
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
7426
            /* Coprocessor double register transfer.  */
7427
            ARCH(5TE);
7428
        } else if ((insn & 0x0f000010) == 0x0e000010) {
7429
            /* Additional coprocessor register transfer.  */
7430
        } else if ((insn & 0x0ff10020) == 0x01000000) {
7431
            uint32_t mask;
7432
            uint32_t val;
7433
            /* cps (privileged) */
7434
            if (IS_USER(s))
7435
                return;
7436
            mask = val = 0;
7437
            if (insn & (1 << 19)) {
7438
                if (insn & (1 << 8))
7439
                    mask |= CPSR_A;
7440
                if (insn & (1 << 7))
7441
                    mask |= CPSR_I;
7442
                if (insn & (1 << 6))
7443
                    mask |= CPSR_F;
7444
                if (insn & (1 << 18))
7445
                    val |= mask;
7446
            }
7447
            if (insn & (1 << 17)) {
7448
                mask |= CPSR_M;
7449
                val |= (insn & 0x1f);
7450
            }
7451
            if (mask) {
7452
                gen_set_psr_im(s, mask, 0, val);
7453
            }
7454
            return;
7455
        }
7456
        goto illegal_op;
7457
    }
7458
    if (cond != 0xe) {
7459
        /* if not always execute, we generate a conditional jump to
7460
           next instruction */
7461
        s->condlabel = gen_new_label();
7462
        arm_gen_test_cc(cond ^ 1, s->condlabel);
7463
        s->condjmp = 1;
7464
    }
7465
    if ((insn & 0x0f900000) == 0x03000000) {
7466
        if ((insn & (1 << 21)) == 0) {
7467
            ARCH(6T2);
7468
            rd = (insn >> 12) & 0xf;
7469
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7470
            if ((insn & (1 << 22)) == 0) {
7471
                /* MOVW */
7472
                tmp = tcg_temp_new_i32();
7473
                tcg_gen_movi_i32(tmp, val);
7474
            } else {
7475
                /* MOVT */
7476
                tmp = load_reg(s, rd);
7477
                tcg_gen_ext16u_i32(tmp, tmp);
7478
                tcg_gen_ori_i32(tmp, tmp, val << 16);
7479
            }
7480
            store_reg(s, rd, tmp);
7481
        } else {
7482
            if (((insn >> 12) & 0xf) != 0xf)
7483
                goto illegal_op;
7484
            if (((insn >> 16) & 0xf) == 0) {
7485
                gen_nop_hint(s, insn & 0xff);
7486
            } else {
7487
                /* CPSR = immediate */
7488
                val = insn & 0xff;
7489
                shift = ((insn >> 8) & 0xf) * 2;
7490
                if (shift)
7491
                    val = (val >> shift) | (val << (32 - shift));
7492
                i = ((insn & (1 << 22)) != 0);
7493
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7494
                    goto illegal_op;
7495
            }
7496
        }
7497
    } else if ((insn & 0x0f900000) == 0x01000000
7498
               && (insn & 0x00000090) != 0x00000090) {
7499
        /* miscellaneous instructions */
7500
        op1 = (insn >> 21) & 3;
7501
        sh = (insn >> 4) & 0xf;
7502
        rm = insn & 0xf;
7503
        switch (sh) {
7504
        case 0x0: /* move program status register */
7505
            if (op1 & 1) {
7506
                /* PSR = reg */
7507
                tmp = load_reg(s, rm);
7508
                i = ((op1 & 2) != 0);
7509
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7510
                    goto illegal_op;
7511
            } else {
7512
                /* reg = PSR */
7513
                rd = (insn >> 12) & 0xf;
7514
                if (op1 & 2) {
7515
                    if (IS_USER(s))
7516
                        goto illegal_op;
7517
                    tmp = load_cpu_field(spsr);
7518
                } else {
7519
                    tmp = tcg_temp_new_i32();
7520
                    gen_helper_cpsr_read(tmp, cpu_env);
7521
                }
7522
                store_reg(s, rd, tmp);
7523
            }
7524
            break;
7525
        case 0x1:
7526
            if (op1 == 1) {
7527
                /* branch/exchange thumb (bx).  */
7528
                ARCH(4T);
7529
                tmp = load_reg(s, rm);
7530
                gen_bx(s, tmp);
7531
            } else if (op1 == 3) {
7532
                /* clz */
7533
                ARCH(5);
7534
                rd = (insn >> 12) & 0xf;
7535
                tmp = load_reg(s, rm);
7536
                gen_helper_clz(tmp, tmp);
7537
                store_reg(s, rd, tmp);
7538
            } else {
7539
                goto illegal_op;
7540
            }
7541
            break;
7542
        case 0x2:
7543
            if (op1 == 1) {
7544
                ARCH(5J); /* bxj */
7545
                /* Trivial implementation equivalent to bx.  */
7546
                tmp = load_reg(s, rm);
7547
                gen_bx(s, tmp);
7548
            } else {
7549
                goto illegal_op;
7550
            }
7551
            break;
7552
        case 0x3:
7553
            if (op1 != 1)
7554
              goto illegal_op;
7555

    
7556
            ARCH(5);
7557
            /* branch link/exchange thumb (blx) */
7558
            tmp = load_reg(s, rm);
7559
            tmp2 = tcg_temp_new_i32();
7560
            tcg_gen_movi_i32(tmp2, s->pc);
7561
            store_reg(s, 14, tmp2);
7562
            gen_bx(s, tmp);
7563
            break;
7564
        case 0x5: /* saturating add/subtract */
7565
            ARCH(5TE);
7566
            rd = (insn >> 12) & 0xf;
7567
            rn = (insn >> 16) & 0xf;
7568
            tmp = load_reg(s, rm);
7569
            tmp2 = load_reg(s, rn);
7570
            if (op1 & 2)
7571
                gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7572
            if (op1 & 1)
7573
                gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7574
            else
7575
                gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7576
            tcg_temp_free_i32(tmp2);
7577
            store_reg(s, rd, tmp);
7578
            break;
7579
        case 7:
7580
            /* SMC instruction (op1 == 3)
7581
               and undefined instructions (op1 == 0 || op1 == 2)
7582
               will trap */
7583
            if (op1 != 1) {
7584
                goto illegal_op;
7585
            }
7586
            /* bkpt */
7587
            ARCH(5);
7588
            gen_exception_insn(s, 4, EXCP_BKPT);
7589
            break;
7590
        case 0x8: /* signed multiply */
7591
        case 0xa:
7592
        case 0xc:
7593
        case 0xe:
7594
            ARCH(5TE);
7595
            rs = (insn >> 8) & 0xf;
7596
            rn = (insn >> 12) & 0xf;
7597
            rd = (insn >> 16) & 0xf;
7598
            if (op1 == 1) {
7599
                /* (32 * 16) >> 16 */
7600
                tmp = load_reg(s, rm);
7601
                tmp2 = load_reg(s, rs);
7602
                if (sh & 4)
7603
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7604
                else
7605
                    gen_sxth(tmp2);
7606
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7607
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7608
                tmp = tcg_temp_new_i32();
7609
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7610
                tcg_temp_free_i64(tmp64);
7611
                if ((sh & 2) == 0) {
7612
                    tmp2 = load_reg(s, rn);
7613
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7614
                    tcg_temp_free_i32(tmp2);
7615
                }
7616
                store_reg(s, rd, tmp);
7617
            } else {
7618
                /* 16 * 16 */
7619
                tmp = load_reg(s, rm);
7620
                tmp2 = load_reg(s, rs);
7621
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7622
                tcg_temp_free_i32(tmp2);
7623
                if (op1 == 2) {
7624
                    tmp64 = tcg_temp_new_i64();
7625
                    tcg_gen_ext_i32_i64(tmp64, tmp);
7626
                    tcg_temp_free_i32(tmp);
7627
                    gen_addq(s, tmp64, rn, rd);
7628
                    gen_storeq_reg(s, rn, rd, tmp64);
7629
                    tcg_temp_free_i64(tmp64);
7630
                } else {
7631
                    if (op1 == 0) {
7632
                        tmp2 = load_reg(s, rn);
7633
                        gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7634
                        tcg_temp_free_i32(tmp2);
7635
                    }
7636
                    store_reg(s, rd, tmp);
7637
                }
7638
            }
7639
            break;
7640
        default:
7641
            goto illegal_op;
7642
        }
7643
    } else if (((insn & 0x0e000000) == 0 &&
7644
                (insn & 0x00000090) != 0x90) ||
7645
               ((insn & 0x0e000000) == (1 << 25))) {
7646
        int set_cc, logic_cc, shiftop;
7647

    
7648
        op1 = (insn >> 21) & 0xf;
7649
        set_cc = (insn >> 20) & 1;
7650
        logic_cc = table_logic_cc[op1] & set_cc;
7651

    
7652
        /* data processing instruction */
7653
        if (insn & (1 << 25)) {
7654
            /* immediate operand */
7655
            val = insn & 0xff;
7656
            shift = ((insn >> 8) & 0xf) * 2;
7657
            if (shift) {
7658
                val = (val >> shift) | (val << (32 - shift));
7659
            }
7660
            tmp2 = tcg_temp_new_i32();
7661
            tcg_gen_movi_i32(tmp2, val);
7662
            if (logic_cc && shift) {
7663
                gen_set_CF_bit31(tmp2);
7664
            }
7665
        } else {
7666
            /* register */
7667
            rm = (insn) & 0xf;
7668
            tmp2 = load_reg(s, rm);
7669
            shiftop = (insn >> 5) & 3;
7670
            if (!(insn & (1 << 4))) {
7671
                shift = (insn >> 7) & 0x1f;
7672
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7673
            } else {
7674
                rs = (insn >> 8) & 0xf;
7675
                tmp = load_reg(s, rs);
7676
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7677
            }
7678
        }
7679
        if (op1 != 0x0f && op1 != 0x0d) {
7680
            rn = (insn >> 16) & 0xf;
7681
            tmp = load_reg(s, rn);
7682
        } else {
7683
            TCGV_UNUSED_I32(tmp);
7684
        }
7685
        rd = (insn >> 12) & 0xf;
7686
        switch(op1) {
7687
        case 0x00:
7688
            tcg_gen_and_i32(tmp, tmp, tmp2);
7689
            if (logic_cc) {
7690
                gen_logic_CC(tmp);
7691
            }
7692
            store_reg_bx(env, s, rd, tmp);
7693
            break;
7694
        case 0x01:
7695
            tcg_gen_xor_i32(tmp, tmp, tmp2);
7696
            if (logic_cc) {
7697
                gen_logic_CC(tmp);
7698
            }
7699
            store_reg_bx(env, s, rd, tmp);
7700
            break;
7701
        case 0x02:
7702
            if (set_cc && rd == 15) {
7703
                /* SUBS r15, ... is used for exception return.  */
7704
                if (IS_USER(s)) {
7705
                    goto illegal_op;
7706
                }
7707
                gen_sub_CC(tmp, tmp, tmp2);
7708
                gen_exception_return(s, tmp);
7709
            } else {
7710
                if (set_cc) {
7711
                    gen_sub_CC(tmp, tmp, tmp2);
7712
                } else {
7713
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7714
                }
7715
                store_reg_bx(env, s, rd, tmp);
7716
            }
7717
            break;
7718
        case 0x03:
7719
            if (set_cc) {
7720
                gen_sub_CC(tmp, tmp2, tmp);
7721
            } else {
7722
                tcg_gen_sub_i32(tmp, tmp2, tmp);
7723
            }
7724
            store_reg_bx(env, s, rd, tmp);
7725
            break;
7726
        case 0x04:
7727
            if (set_cc) {
7728
                gen_add_CC(tmp, tmp, tmp2);
7729
            } else {
7730
                tcg_gen_add_i32(tmp, tmp, tmp2);
7731
            }
7732
            store_reg_bx(env, s, rd, tmp);
7733
            break;
7734
        case 0x05:
7735
            if (set_cc) {
7736
                gen_adc_CC(tmp, tmp, tmp2);
7737
            } else {
7738
                gen_add_carry(tmp, tmp, tmp2);
7739
            }
7740
            store_reg_bx(env, s, rd, tmp);
7741
            break;
7742
        case 0x06:
7743
            if (set_cc) {
7744
                gen_sbc_CC(tmp, tmp, tmp2);
7745
            } else {
7746
                gen_sub_carry(tmp, tmp, tmp2);
7747
            }
7748
            store_reg_bx(env, s, rd, tmp);
7749
            break;
7750
        case 0x07:
7751
            if (set_cc) {
7752
                gen_sbc_CC(tmp, tmp2, tmp);
7753
            } else {
7754
                gen_sub_carry(tmp, tmp2, tmp);
7755
            }
7756
            store_reg_bx(env, s, rd, tmp);
7757
            break;
7758
        case 0x08:
7759
            if (set_cc) {
7760
                tcg_gen_and_i32(tmp, tmp, tmp2);
7761
                gen_logic_CC(tmp);
7762
            }
7763
            tcg_temp_free_i32(tmp);
7764
            break;
7765
        case 0x09:
7766
            if (set_cc) {
7767
                tcg_gen_xor_i32(tmp, tmp, tmp2);
7768
                gen_logic_CC(tmp);
7769
            }
7770
            tcg_temp_free_i32(tmp);
7771
            break;
7772
        case 0x0a:
7773
            if (set_cc) {
7774
                gen_sub_CC(tmp, tmp, tmp2);
7775
            }
7776
            tcg_temp_free_i32(tmp);
7777
            break;
7778
        case 0x0b:
7779
            if (set_cc) {
7780
                gen_add_CC(tmp, tmp, tmp2);
7781
            }
7782
            tcg_temp_free_i32(tmp);
7783
            break;
7784
        case 0x0c:
7785
            tcg_gen_or_i32(tmp, tmp, tmp2);
7786
            if (logic_cc) {
7787
                gen_logic_CC(tmp);
7788
            }
7789
            store_reg_bx(env, s, rd, tmp);
7790
            break;
7791
        case 0x0d:
7792
            if (logic_cc && rd == 15) {
7793
                /* MOVS r15, ... is used for exception return.  */
7794
                if (IS_USER(s)) {
7795
                    goto illegal_op;
7796
                }
7797
                gen_exception_return(s, tmp2);
7798
            } else {
7799
                if (logic_cc) {
7800
                    gen_logic_CC(tmp2);
7801
                }
7802
                store_reg_bx(env, s, rd, tmp2);
7803
            }
7804
            break;
7805
        case 0x0e:
7806
            tcg_gen_andc_i32(tmp, tmp, tmp2);
7807
            if (logic_cc) {
7808
                gen_logic_CC(tmp);
7809
            }
7810
            store_reg_bx(env, s, rd, tmp);
7811
            break;
7812
        default:
7813
        case 0x0f:
7814
            tcg_gen_not_i32(tmp2, tmp2);
7815
            if (logic_cc) {
7816
                gen_logic_CC(tmp2);
7817
            }
7818
            store_reg_bx(env, s, rd, tmp2);
7819
            break;
7820
        }
7821
        if (op1 != 0x0f && op1 != 0x0d) {
7822
            tcg_temp_free_i32(tmp2);
7823
        }
7824
    } else {
7825
        /* other instructions */
7826
        op1 = (insn >> 24) & 0xf;
7827
        switch(op1) {
7828
        case 0x0:
7829
        case 0x1:
7830
            /* multiplies, extra load/stores */
7831
            sh = (insn >> 5) & 3;
7832
            if (sh == 0) {
7833
                if (op1 == 0x0) {
7834
                    rd = (insn >> 16) & 0xf;
7835
                    rn = (insn >> 12) & 0xf;
7836
                    rs = (insn >> 8) & 0xf;
7837
                    rm = (insn) & 0xf;
7838
                    op1 = (insn >> 20) & 0xf;
7839
                    switch (op1) {
7840
                    case 0: case 1: case 2: case 3: case 6:
7841
                        /* 32 bit mul */
7842
                        tmp = load_reg(s, rs);
7843
                        tmp2 = load_reg(s, rm);
7844
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
7845
                        tcg_temp_free_i32(tmp2);
7846
                        if (insn & (1 << 22)) {
7847
                            /* Subtract (mls) */
7848
                            ARCH(6T2);
7849
                            tmp2 = load_reg(s, rn);
7850
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
7851
                            tcg_temp_free_i32(tmp2);
7852
                        } else if (insn & (1 << 21)) {
7853
                            /* Add */
7854
                            tmp2 = load_reg(s, rn);
7855
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7856
                            tcg_temp_free_i32(tmp2);
7857
                        }
7858
                        if (insn & (1 << 20))
7859
                            gen_logic_CC(tmp);
7860
                        store_reg(s, rd, tmp);
7861
                        break;
7862
                    case 4:
7863
                        /* 64 bit mul double accumulate (UMAAL) */
7864
                        ARCH(6);
7865
                        tmp = load_reg(s, rs);
7866
                        tmp2 = load_reg(s, rm);
7867
                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7868
                        gen_addq_lo(s, tmp64, rn);
7869
                        gen_addq_lo(s, tmp64, rd);
7870
                        gen_storeq_reg(s, rn, rd, tmp64);
7871
                        tcg_temp_free_i64(tmp64);
7872
                        break;
7873
                    case 8: case 9: case 10: case 11:
7874
                    case 12: case 13: case 14: case 15:
7875
                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7876
                        tmp = load_reg(s, rs);
7877
                        tmp2 = load_reg(s, rm);
7878
                        if (insn & (1 << 22)) {
7879
                            tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7880
                        } else {
7881
                            tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7882
                        }
7883
                        if (insn & (1 << 21)) { /* mult accumulate */
7884
                            TCGv_i32 al = load_reg(s, rn);
7885
                            TCGv_i32 ah = load_reg(s, rd);
7886
                            tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7887
                            tcg_temp_free_i32(al);
7888
                            tcg_temp_free_i32(ah);
7889
                        }
7890
                        if (insn & (1 << 20)) {
7891
                            gen_logicq_cc(tmp, tmp2);
7892
                        }
7893
                        store_reg(s, rn, tmp);
7894
                        store_reg(s, rd, tmp2);
7895
                        break;
7896
                    default:
7897
                        goto illegal_op;
7898
                    }
7899
                } else {
7900
                    rn = (insn >> 16) & 0xf;
7901
                    rd = (insn >> 12) & 0xf;
7902
                    if (insn & (1 << 23)) {
7903
                        /* load/store exclusive */
7904
                        int op2 = (insn >> 8) & 3;
7905
                        op1 = (insn >> 21) & 0x3;
7906

    
7907
                        switch (op2) {
7908
                        case 0: /* lda/stl */
7909
                            if (op1 == 1) {
7910
                                goto illegal_op;
7911
                            }
7912
                            ARCH(8);
7913
                            break;
7914
                        case 1: /* reserved */
7915
                            goto illegal_op;
7916
                        case 2: /* ldaex/stlex */
7917
                            ARCH(8);
7918
                            break;
7919
                        case 3: /* ldrex/strex */
7920
                            if (op1) {
7921
                                ARCH(6K);
7922
                            } else {
7923
                                ARCH(6);
7924
                            }
7925
                            break;
7926
                        }
7927

    
7928
                        addr = tcg_temp_local_new_i32();
7929
                        load_reg_var(s, addr, rn);
7930

    
7931
                        /* Since the emulation does not have barriers,
7932
                           the acquire/release semantics need no special
7933
                           handling */
7934
                        if (op2 == 0) {
7935
                            if (insn & (1 << 20)) {
7936
                                tmp = tcg_temp_new_i32();
7937
                                switch (op1) {
7938
                                case 0: /* lda */
7939
                                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
7940
                                    break;
7941
                                case 2: /* ldab */
7942
                                    gen_aa32_ld8u(tmp, addr, IS_USER(s));
7943
                                    break;
7944
                                case 3: /* ldah */
7945
                                    gen_aa32_ld16u(tmp, addr, IS_USER(s));
7946
                                    break;
7947
                                default:
7948
                                    abort();
7949
                                }
7950
                                store_reg(s, rd, tmp);
7951
                            } else {
7952
                                rm = insn & 0xf;
7953
                                tmp = load_reg(s, rm);
7954
                                switch (op1) {
7955
                                case 0: /* stl */
7956
                                    gen_aa32_st32(tmp, addr, IS_USER(s));
7957
                                    break;
7958
                                case 2: /* stlb */
7959
                                    gen_aa32_st8(tmp, addr, IS_USER(s));
7960
                                    break;
7961
                                case 3: /* stlh */
7962
                                    gen_aa32_st16(tmp, addr, IS_USER(s));
7963
                                    break;
7964
                                default:
7965
                                    abort();
7966
                                }
7967
                                tcg_temp_free_i32(tmp);
7968
                            }
7969
                        } else if (insn & (1 << 20)) {
7970
                            switch (op1) {
7971
                            case 0: /* ldrex */
7972
                                gen_load_exclusive(s, rd, 15, addr, 2);
7973
                                break;
7974
                            case 1: /* ldrexd */
7975
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
7976
                                break;
7977
                            case 2: /* ldrexb */
7978
                                gen_load_exclusive(s, rd, 15, addr, 0);
7979
                                break;
7980
                            case 3: /* ldrexh */
7981
                                gen_load_exclusive(s, rd, 15, addr, 1);
7982
                                break;
7983
                            default:
7984
                                abort();
7985
                            }
7986
                        } else {
7987
                            rm = insn & 0xf;
7988
                            switch (op1) {
7989
                            case 0:  /*  strex */
7990
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
7991
                                break;
7992
                            case 1: /*  strexd */
7993
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7994
                                break;
7995
                            case 2: /*  strexb */
7996
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
7997
                                break;
7998
                            case 3: /* strexh */
7999
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
8000
                                break;
8001
                            default:
8002
                                abort();
8003
                            }
8004
                        }
8005
                        tcg_temp_free_i32(addr);
8006
                    } else {
8007
                        /* SWP instruction */
8008
                        rm = (insn) & 0xf;
8009

    
8010
                        /* ??? This is not really atomic.  However we know
8011
                           we never have multiple CPUs running in parallel,
8012
                           so it is good enough.  */
8013
                        addr = load_reg(s, rn);
8014
                        tmp = load_reg(s, rm);
8015
                        tmp2 = tcg_temp_new_i32();
8016
                        if (insn & (1 << 22)) {
8017
                            gen_aa32_ld8u(tmp2, addr, IS_USER(s));
8018
                            gen_aa32_st8(tmp, addr, IS_USER(s));
8019
                        } else {
8020
                            gen_aa32_ld32u(tmp2, addr, IS_USER(s));
8021
                            gen_aa32_st32(tmp, addr, IS_USER(s));
8022
                        }
8023
                        tcg_temp_free_i32(tmp);
8024
                        tcg_temp_free_i32(addr);
8025
                        store_reg(s, rd, tmp2);
8026
                    }
8027
                }
8028
            } else {
8029
                int address_offset;
8030
                int load;
8031
                /* Misc load/store */
8032
                rn = (insn >> 16) & 0xf;
8033
                rd = (insn >> 12) & 0xf;
8034
                addr = load_reg(s, rn);
8035
                if (insn & (1 << 24))
8036
                    gen_add_datah_offset(s, insn, 0, addr);
8037
                address_offset = 0;
8038
                if (insn & (1 << 20)) {
8039
                    /* load */
8040
                    tmp = tcg_temp_new_i32();
8041
                    switch(sh) {
8042
                    case 1:
8043
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
8044
                        break;
8045
                    case 2:
8046
                        gen_aa32_ld8s(tmp, addr, IS_USER(s));
8047
                        break;
8048
                    default:
8049
                    case 3:
8050
                        gen_aa32_ld16s(tmp, addr, IS_USER(s));
8051
                        break;
8052
                    }
8053
                    load = 1;
8054
                } else if (sh & 2) {
8055
                    ARCH(5TE);
8056
                    /* doubleword */
8057
                    if (sh & 1) {
8058
                        /* store */
8059
                        tmp = load_reg(s, rd);
8060
                        gen_aa32_st32(tmp, addr, IS_USER(s));
8061
                        tcg_temp_free_i32(tmp);
8062
                        tcg_gen_addi_i32(addr, addr, 4);
8063
                        tmp = load_reg(s, rd + 1);
8064
                        gen_aa32_st32(tmp, addr, IS_USER(s));
8065
                        tcg_temp_free_i32(tmp);
8066
                        load = 0;
8067
                    } else {
8068
                        /* load */
8069
                        tmp = tcg_temp_new_i32();
8070
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
8071
                        store_reg(s, rd, tmp);
8072
                        tcg_gen_addi_i32(addr, addr, 4);
8073
                        tmp = tcg_temp_new_i32();
8074
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
8075
                        rd++;
8076
                        load = 1;
8077
                    }
8078
                    address_offset = -4;
8079
                } else {
8080
                    /* store */
8081
                    tmp = load_reg(s, rd);
8082
                    gen_aa32_st16(tmp, addr, IS_USER(s));
8083
                    tcg_temp_free_i32(tmp);
8084
                    load = 0;
8085
                }
8086
                /* Perform base writeback before the loaded value to
8087
                   ensure correct behavior with overlapping index registers.
8088
                   ldrd with base writeback is is undefined if the
8089
                   destination and index registers overlap.  */
8090
                if (!(insn & (1 << 24))) {
8091
                    gen_add_datah_offset(s, insn, address_offset, addr);
8092
                    store_reg(s, rn, addr);
8093
                } else if (insn & (1 << 21)) {
8094
                    if (address_offset)
8095
                        tcg_gen_addi_i32(addr, addr, address_offset);
8096
                    store_reg(s, rn, addr);
8097
                } else {
8098
                    tcg_temp_free_i32(addr);
8099
                }
8100
                if (load) {
8101
                    /* Complete the load.  */
8102
                    store_reg(s, rd, tmp);
8103
                }
8104
            }
8105
            break;
8106
        case 0x4:
8107
        case 0x5:
8108
            goto do_ldst;
8109
        case 0x6:
8110
        case 0x7:
8111
            if (insn & (1 << 4)) {
8112
                ARCH(6);
8113
                /* Armv6 Media instructions.  */
8114
                rm = insn & 0xf;
8115
                rn = (insn >> 16) & 0xf;
8116
                rd = (insn >> 12) & 0xf;
8117
                rs = (insn >> 8) & 0xf;
8118
                switch ((insn >> 23) & 3) {
8119
                case 0: /* Parallel add/subtract.  */
8120
                    op1 = (insn >> 20) & 7;
8121
                    tmp = load_reg(s, rn);
8122
                    tmp2 = load_reg(s, rm);
8123
                    sh = (insn >> 5) & 7;
8124
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8125
                        goto illegal_op;
8126
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8127
                    tcg_temp_free_i32(tmp2);
8128
                    store_reg(s, rd, tmp);
8129
                    break;
8130
                case 1:
8131
                    if ((insn & 0x00700020) == 0) {
8132
                        /* Halfword pack.  */
8133
                        tmp = load_reg(s, rn);
8134
                        tmp2 = load_reg(s, rm);
8135
                        shift = (insn >> 7) & 0x1f;
8136
                        if (insn & (1 << 6)) {
8137
                            /* pkhtb */
8138
                            if (shift == 0)
8139
                                shift = 31;
8140
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
8141
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8142
                            tcg_gen_ext16u_i32(tmp2, tmp2);
8143
                        } else {
8144
                            /* pkhbt */
8145
                            if (shift)
8146
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
8147
                            tcg_gen_ext16u_i32(tmp, tmp);
8148
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8149
                        }
8150
                        tcg_gen_or_i32(tmp, tmp, tmp2);
8151
                        tcg_temp_free_i32(tmp2);
8152
                        store_reg(s, rd, tmp);
8153
                    } else if ((insn & 0x00200020) == 0x00200000) {
8154
                        /* [us]sat */
8155
                        tmp = load_reg(s, rm);
8156
                        shift = (insn >> 7) & 0x1f;
8157
                        if (insn & (1 << 6)) {
8158
                            if (shift == 0)
8159
                                shift = 31;
8160
                            tcg_gen_sari_i32(tmp, tmp, shift);
8161
                        } else {
8162
                            tcg_gen_shli_i32(tmp, tmp, shift);
8163
                        }
8164
                        sh = (insn >> 16) & 0x1f;
8165
                        tmp2 = tcg_const_i32(sh);
8166
                        if (insn & (1 << 22))
8167
                          gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8168
                        else
8169
                          gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8170
                        tcg_temp_free_i32(tmp2);
8171
                        store_reg(s, rd, tmp);
8172
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
8173
                        /* [us]sat16 */
8174
                        tmp = load_reg(s, rm);
8175
                        sh = (insn >> 16) & 0x1f;
8176
                        tmp2 = tcg_const_i32(sh);
8177
                        if (insn & (1 << 22))
8178
                          gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8179
                        else
8180
                          gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8181
                        tcg_temp_free_i32(tmp2);
8182
                        store_reg(s, rd, tmp);
8183
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8184
                        /* Select bytes.  */
8185
                        tmp = load_reg(s, rn);
8186
                        tmp2 = load_reg(s, rm);
8187
                        tmp3 = tcg_temp_new_i32();
8188
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8189
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8190
                        tcg_temp_free_i32(tmp3);
8191
                        tcg_temp_free_i32(tmp2);
8192
                        store_reg(s, rd, tmp);
8193
                    } else if ((insn & 0x000003e0) == 0x00000060) {
8194
                        tmp = load_reg(s, rm);
8195
                        shift = (insn >> 10) & 3;
8196
                        /* ??? In many cases it's not necessary to do a
8197
                           rotate, a shift is sufficient.  */
8198
                        if (shift != 0)
8199
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8200
                        op1 = (insn >> 20) & 7;
8201
                        switch (op1) {
8202
                        case 0: gen_sxtb16(tmp);  break;
8203
                        case 2: gen_sxtb(tmp);    break;
8204
                        case 3: gen_sxth(tmp);    break;
8205
                        case 4: gen_uxtb16(tmp);  break;
8206
                        case 6: gen_uxtb(tmp);    break;
8207
                        case 7: gen_uxth(tmp);    break;
8208
                        default: goto illegal_op;
8209
                        }
8210
                        if (rn != 15) {
8211
                            tmp2 = load_reg(s, rn);
8212
                            if ((op1 & 3) == 0) {
8213
                                gen_add16(tmp, tmp2);
8214
                            } else {
8215
                                tcg_gen_add_i32(tmp, tmp, tmp2);
8216
                                tcg_temp_free_i32(tmp2);
8217
                            }
8218
                        }
8219
                        store_reg(s, rd, tmp);
8220
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8221
                        /* rev */
8222
                        tmp = load_reg(s, rm);
8223
                        if (insn & (1 << 22)) {
8224
                            if (insn & (1 << 7)) {
8225
                                gen_revsh(tmp);
8226
                            } else {
8227
                                ARCH(6T2);
8228
                                gen_helper_rbit(tmp, tmp);
8229
                            }
8230
                        } else {
8231
                            if (insn & (1 << 7))
8232
                                gen_rev16(tmp);
8233
                            else
8234
                                tcg_gen_bswap32_i32(tmp, tmp);
8235
                        }
8236
                        store_reg(s, rd, tmp);
8237
                    } else {
8238
                        goto illegal_op;
8239
                    }
8240
                    break;
8241
                case 2: /* Multiplies (Type 3).  */
8242
                    switch ((insn >> 20) & 0x7) {
8243
                    case 5:
8244
                        if (((insn >> 6) ^ (insn >> 7)) & 1) {
8245
                            /* op2 not 00x or 11x : UNDEF */
8246
                            goto illegal_op;
8247
                        }
8248
                        /* Signed multiply most significant [accumulate].
8249
                           (SMMUL, SMMLA, SMMLS) */
8250
                        tmp = load_reg(s, rm);
8251
                        tmp2 = load_reg(s, rs);
8252
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
8253

    
8254
                        if (rd != 15) {
8255
                            tmp = load_reg(s, rd);
8256
                            if (insn & (1 << 6)) {
8257
                                tmp64 = gen_subq_msw(tmp64, tmp);
8258
                            } else {
8259
                                tmp64 = gen_addq_msw(tmp64, tmp);
8260
                            }
8261
                        }
8262
                        if (insn & (1 << 5)) {
8263
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8264
                        }
8265
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
8266
                        tmp = tcg_temp_new_i32();
8267
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
8268
                        tcg_temp_free_i64(tmp64);
8269
                        store_reg(s, rn, tmp);
8270
                        break;
8271
                    case 0:
8272
                    case 4:
8273
                        /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8274
                        if (insn & (1 << 7)) {
8275
                            goto illegal_op;
8276
                        }
8277
                        tmp = load_reg(s, rm);
8278
                        tmp2 = load_reg(s, rs);
8279
                        if (insn & (1 << 5))
8280
                            gen_swap_half(tmp2);
8281
                        gen_smul_dual(tmp, tmp2);
8282
                        if (insn & (1 << 6)) {
8283
                            /* This subtraction cannot overflow. */
8284
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
8285
                        } else {
8286
                            /* This addition cannot overflow 32 bits;
8287
                             * however it may overflow considered as a signed
8288
                             * operation, in which case we must set the Q flag.
8289
                             */
8290
                            gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8291
                        }
8292
                        tcg_temp_free_i32(tmp2);
8293
                        if (insn & (1 << 22)) {
8294
                            /* smlald, smlsld */
8295
                            tmp64 = tcg_temp_new_i64();
8296
                            tcg_gen_ext_i32_i64(tmp64, tmp);
8297
                            tcg_temp_free_i32(tmp);
8298
                            gen_addq(s, tmp64, rd, rn);
8299
                            gen_storeq_reg(s, rd, rn, tmp64);
8300
                            tcg_temp_free_i64(tmp64);
8301
                        } else {
8302
                            /* smuad, smusd, smlad, smlsd */
8303
                            if (rd != 15)
8304
                              {
8305
                                tmp2 = load_reg(s, rd);
8306
                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8307
                                tcg_temp_free_i32(tmp2);
8308
                              }
8309
                            store_reg(s, rn, tmp);
8310
                        }
8311
                        break;
8312
                    case 1:
8313
                    case 3:
8314
                        /* SDIV, UDIV */
8315
                        if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8316
                            goto illegal_op;
8317
                        }
8318
                        if (((insn >> 5) & 7) || (rd != 15)) {
8319
                            goto illegal_op;
8320
                        }
8321
                        tmp = load_reg(s, rm);
8322
                        tmp2 = load_reg(s, rs);
8323
                        if (insn & (1 << 21)) {
8324
                            gen_helper_udiv(tmp, tmp, tmp2);
8325
                        } else {
8326
                            gen_helper_sdiv(tmp, tmp, tmp2);
8327
                        }
8328
                        tcg_temp_free_i32(tmp2);
8329
                        store_reg(s, rn, tmp);
8330
                        break;
8331
                    default:
8332
                        goto illegal_op;
8333
                    }
8334
                    break;
8335
                case 3:
8336
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8337
                    switch (op1) {
8338
                    case 0: /* Unsigned sum of absolute differences.  */
8339
                        ARCH(6);
8340
                        tmp = load_reg(s, rm);
8341
                        tmp2 = load_reg(s, rs);
8342
                        gen_helper_usad8(tmp, tmp, tmp2);
8343
                        tcg_temp_free_i32(tmp2);
8344
                        if (rd != 15) {
8345
                            tmp2 = load_reg(s, rd);
8346
                            tcg_gen_add_i32(tmp, tmp, tmp2);
8347
                            tcg_temp_free_i32(tmp2);
8348
                        }
8349
                        store_reg(s, rn, tmp);
8350
                        break;
8351
                    case 0x20: case 0x24: case 0x28: case 0x2c:
8352
                        /* Bitfield insert/clear.  */
8353
                        ARCH(6T2);
8354
                        shift = (insn >> 7) & 0x1f;
8355
                        i = (insn >> 16) & 0x1f;
8356
                        i = i + 1 - shift;
8357
                        if (rm == 15) {
8358
                            tmp = tcg_temp_new_i32();
8359
                            tcg_gen_movi_i32(tmp, 0);
8360
                        } else {
8361
                            tmp = load_reg(s, rm);
8362
                        }
8363
                        if (i != 32) {
8364
                            tmp2 = load_reg(s, rd);
8365
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8366
                            tcg_temp_free_i32(tmp2);
8367
                        }
8368
                        store_reg(s, rd, tmp);
8369
                        break;
8370
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8371
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8372
                        ARCH(6T2);
8373
                        tmp = load_reg(s, rm);
8374
                        shift = (insn >> 7) & 0x1f;
8375
                        i = ((insn >> 16) & 0x1f) + 1;
8376
                        if (shift + i > 32)
8377
                            goto illegal_op;
8378
                        if (i < 32) {
8379
                            if (op1 & 0x20) {
8380
                                gen_ubfx(tmp, shift, (1u << i) - 1);
8381
                            } else {
8382
                                gen_sbfx(tmp, shift, i);
8383
                            }
8384
                        }
8385
                        store_reg(s, rd, tmp);
8386
                        break;
8387
                    default:
8388
                        goto illegal_op;
8389
                    }
8390
                    break;
8391
                }
8392
                break;
8393
            }
8394
        do_ldst:
8395
            /* Check for undefined extension instructions
8396
             * per the ARM Bible IE:
8397
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
8398
             */
8399
            sh = (0xf << 20) | (0xf << 4);
8400
            if (op1 == 0x7 && ((insn & sh) == sh))
8401
            {
8402
                goto illegal_op;
8403
            }
8404
            /* load/store byte/word */
8405
            rn = (insn >> 16) & 0xf;
8406
            rd = (insn >> 12) & 0xf;
8407
            tmp2 = load_reg(s, rn);
8408
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8409
            if (insn & (1 << 24))
8410
                gen_add_data_offset(s, insn, tmp2);
8411
            if (insn & (1 << 20)) {
8412
                /* load */
8413
                tmp = tcg_temp_new_i32();
8414
                if (insn & (1 << 22)) {
8415
                    gen_aa32_ld8u(tmp, tmp2, i);
8416
                } else {
8417
                    gen_aa32_ld32u(tmp, tmp2, i);
8418
                }
8419
            } else {
8420
                /* store */
8421
                tmp = load_reg(s, rd);
8422
                if (insn & (1 << 22)) {
8423
                    gen_aa32_st8(tmp, tmp2, i);
8424
                } else {
8425
                    gen_aa32_st32(tmp, tmp2, i);
8426
                }
8427
                tcg_temp_free_i32(tmp);
8428
            }
8429
            if (!(insn & (1 << 24))) {
8430
                gen_add_data_offset(s, insn, tmp2);
8431
                store_reg(s, rn, tmp2);
8432
            } else if (insn & (1 << 21)) {
8433
                store_reg(s, rn, tmp2);
8434
            } else {
8435
                tcg_temp_free_i32(tmp2);
8436
            }
8437
            if (insn & (1 << 20)) {
8438
                /* Complete the load.  */
8439
                store_reg_from_load(env, s, rd, tmp);
8440
            }
8441
            break;
8442
        case 0x08:
8443
        case 0x09:
8444
            {
8445
                int j, n, user, loaded_base;
8446
                TCGv_i32 loaded_var;
8447
                /* load/store multiple words */
8448
                /* XXX: store correct base if write back */
8449
                user = 0;
8450
                if (insn & (1 << 22)) {
8451
                    if (IS_USER(s))
8452
                        goto illegal_op; /* only usable in supervisor mode */
8453

    
8454
                    if ((insn & (1 << 15)) == 0)
8455
                        user = 1;
8456
                }
8457
                rn = (insn >> 16) & 0xf;
8458
                addr = load_reg(s, rn);
8459

    
8460
                /* compute total size */
8461
                loaded_base = 0;
8462
                TCGV_UNUSED_I32(loaded_var);
8463
                n = 0;
8464
                for(i=0;i<16;i++) {
8465
                    if (insn & (1 << i))
8466
                        n++;
8467
                }
8468
                /* XXX: test invalid n == 0 case ? */
8469
                if (insn & (1 << 23)) {
8470
                    if (insn & (1 << 24)) {
8471
                        /* pre increment */
8472
                        tcg_gen_addi_i32(addr, addr, 4);
8473
                    } else {
8474
                        /* post increment */
8475
                    }
8476
                } else {
8477
                    if (insn & (1 << 24)) {
8478
                        /* pre decrement */
8479
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
8480
                    } else {
8481
                        /* post decrement */
8482
                        if (n != 1)
8483
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8484
                    }
8485
                }
8486
                j = 0;
8487
                for(i=0;i<16;i++) {
8488
                    if (insn & (1 << i)) {
8489
                        if (insn & (1 << 20)) {
8490
                            /* load */
8491
                            tmp = tcg_temp_new_i32();
8492
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
8493
                            if (user) {
8494
                                tmp2 = tcg_const_i32(i);
8495
                                gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8496
                                tcg_temp_free_i32(tmp2);
8497
                                tcg_temp_free_i32(tmp);
8498
                            } else if (i == rn) {
8499
                                loaded_var = tmp;
8500
                                loaded_base = 1;
8501
                            } else {
8502
                                store_reg_from_load(env, s, i, tmp);
8503
                            }
8504
                        } else {
8505
                            /* store */
8506
                            if (i == 15) {
8507
                                /* special case: r15 = PC + 8 */
8508
                                val = (long)s->pc + 4;
8509
                                tmp = tcg_temp_new_i32();
8510
                                tcg_gen_movi_i32(tmp, val);
8511
                            } else if (user) {
8512
                                tmp = tcg_temp_new_i32();
8513
                                tmp2 = tcg_const_i32(i);
8514
                                gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8515
                                tcg_temp_free_i32(tmp2);
8516
                            } else {
8517
                                tmp = load_reg(s, i);
8518
                            }
8519
                            gen_aa32_st32(tmp, addr, IS_USER(s));
8520
                            tcg_temp_free_i32(tmp);
8521
                        }
8522
                        j++;
8523
                        /* no need to add after the last transfer */
8524
                        if (j != n)
8525
                            tcg_gen_addi_i32(addr, addr, 4);
8526
                    }
8527
                }
8528
                if (insn & (1 << 21)) {
8529
                    /* write back */
8530
                    if (insn & (1 << 23)) {
8531
                        if (insn & (1 << 24)) {
8532
                            /* pre increment */
8533
                        } else {
8534
                            /* post increment */
8535
                            tcg_gen_addi_i32(addr, addr, 4);
8536
                        }
8537
                    } else {
8538
                        if (insn & (1 << 24)) {
8539
                            /* pre decrement */
8540
                            if (n != 1)
8541
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8542
                        } else {
8543
                            /* post decrement */
8544
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
8545
                        }
8546
                    }
8547
                    store_reg(s, rn, addr);
8548
                } else {
8549
                    tcg_temp_free_i32(addr);
8550
                }
8551
                if (loaded_base) {
8552
                    store_reg(s, rn, loaded_var);
8553
                }
8554
                if ((insn & (1 << 22)) && !user) {
8555
                    /* Restore CPSR from SPSR.  */
8556
                    tmp = load_cpu_field(spsr);
8557
                    gen_set_cpsr(tmp, 0xffffffff);
8558
                    tcg_temp_free_i32(tmp);
8559
                    s->is_jmp = DISAS_UPDATE;
8560
                }
8561
            }
8562
            break;
8563
        case 0xa:
8564
        case 0xb:
8565
            {
8566
                int32_t offset;
8567

    
8568
                /* branch (and link) */
8569
                val = (int32_t)s->pc;
8570
                if (insn & (1 << 24)) {
8571
                    tmp = tcg_temp_new_i32();
8572
                    tcg_gen_movi_i32(tmp, val);
8573
                    store_reg(s, 14, tmp);
8574
                }
8575
                offset = sextract32(insn << 2, 0, 26);
8576
                val += offset + 4;
8577
                gen_jmp(s, val);
8578
            }
8579
            break;
8580
        case 0xc:
8581
        case 0xd:
8582
        case 0xe:
8583
            if (((insn >> 8) & 0xe) == 10) {
8584
                /* VFP.  */
8585
                if (disas_vfp_insn(env, s, insn)) {
8586
                    goto illegal_op;
8587
                }
8588
            } else if (disas_coproc_insn(env, s, insn)) {
8589
                /* Coprocessor.  */
8590
                goto illegal_op;
8591
            }
8592
            break;
8593
        case 0xf:
8594
            /* swi */
8595
            gen_set_pc_im(s, s->pc);
8596
            s->is_jmp = DISAS_SWI;
8597
            break;
8598
        default:
8599
        illegal_op:
8600
            gen_exception_insn(s, 4, EXCP_UDEF);
8601
            break;
8602
        }
8603
    }
8604
}
8605

    
8606
/* Return true if this is a Thumb-2 logical op.  */
8607
static int
8608
thumb2_logic_op(int op)
8609
{
8610
    return (op < 8);
8611
}
8612

    
8613
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
8614
   then set condition code flags based on the result of the operation.
8615
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8616
   to the high bit of T1.
8617
   Returns zero if the opcode is valid.  */
8618

    
8619
static int
8620
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8621
                   TCGv_i32 t0, TCGv_i32 t1)
8622
{
8623
    int logic_cc;
8624

    
8625
    logic_cc = 0;
8626
    switch (op) {
8627
    case 0: /* and */
8628
        tcg_gen_and_i32(t0, t0, t1);
8629
        logic_cc = conds;
8630
        break;
8631
    case 1: /* bic */
8632
        tcg_gen_andc_i32(t0, t0, t1);
8633
        logic_cc = conds;
8634
        break;
8635
    case 2: /* orr */
8636
        tcg_gen_or_i32(t0, t0, t1);
8637
        logic_cc = conds;
8638
        break;
8639
    case 3: /* orn */
8640
        tcg_gen_orc_i32(t0, t0, t1);
8641
        logic_cc = conds;
8642
        break;
8643
    case 4: /* eor */
8644
        tcg_gen_xor_i32(t0, t0, t1);
8645
        logic_cc = conds;
8646
        break;
8647
    case 8: /* add */
8648
        if (conds)
8649
            gen_add_CC(t0, t0, t1);
8650
        else
8651
            tcg_gen_add_i32(t0, t0, t1);
8652
        break;
8653
    case 10: /* adc */
8654
        if (conds)
8655
            gen_adc_CC(t0, t0, t1);
8656
        else
8657
            gen_adc(t0, t1);
8658
        break;
8659
    case 11: /* sbc */
8660
        if (conds) {
8661
            gen_sbc_CC(t0, t0, t1);
8662
        } else {
8663
            gen_sub_carry(t0, t0, t1);
8664
        }
8665
        break;
8666
    case 13: /* sub */
8667
        if (conds)
8668
            gen_sub_CC(t0, t0, t1);
8669
        else
8670
            tcg_gen_sub_i32(t0, t0, t1);
8671
        break;
8672
    case 14: /* rsb */
8673
        if (conds)
8674
            gen_sub_CC(t0, t1, t0);
8675
        else
8676
            tcg_gen_sub_i32(t0, t1, t0);
8677
        break;
8678
    default: /* 5, 6, 7, 9, 12, 15. */
8679
        return 1;
8680
    }
8681
    if (logic_cc) {
8682
        gen_logic_CC(t0);
8683
        if (shifter_out)
8684
            gen_set_CF_bit31(t1);
8685
    }
8686
    return 0;
8687
}
8688

    
8689
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
8690
   is not legal.  */
8691
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8692
{
8693
    uint32_t insn, imm, shift, offset;
8694
    uint32_t rd, rn, rm, rs;
8695
    TCGv_i32 tmp;
8696
    TCGv_i32 tmp2;
8697
    TCGv_i32 tmp3;
8698
    TCGv_i32 addr;
8699
    TCGv_i64 tmp64;
8700
    int op;
8701
    int shiftop;
8702
    int conds;
8703
    int logic_cc;
8704

    
8705
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8706
          || arm_feature (env, ARM_FEATURE_M))) {
8707
        /* Thumb-1 cores may need to treat bl and blx as a pair of
8708
           16-bit instructions to get correct prefetch abort behavior.  */
8709
        insn = insn_hw1;
8710
        if ((insn & (1 << 12)) == 0) {
8711
            ARCH(5);
8712
            /* Second half of blx.  */
8713
            offset = ((insn & 0x7ff) << 1);
8714
            tmp = load_reg(s, 14);
8715
            tcg_gen_addi_i32(tmp, tmp, offset);
8716
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8717

    
8718
            tmp2 = tcg_temp_new_i32();
8719
            tcg_gen_movi_i32(tmp2, s->pc | 1);
8720
            store_reg(s, 14, tmp2);
8721
            gen_bx(s, tmp);
8722
            return 0;
8723
        }
8724
        if (insn & (1 << 11)) {
8725
            /* Second half of bl.  */
8726
            offset = ((insn & 0x7ff) << 1) | 1;
8727
            tmp = load_reg(s, 14);
8728
            tcg_gen_addi_i32(tmp, tmp, offset);
8729

    
8730
            tmp2 = tcg_temp_new_i32();
8731
            tcg_gen_movi_i32(tmp2, s->pc | 1);
8732
            store_reg(s, 14, tmp2);
8733
            gen_bx(s, tmp);
8734
            return 0;
8735
        }
8736
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8737
            /* Instruction spans a page boundary.  Implement it as two
8738
               16-bit instructions in case the second half causes an
8739
               prefetch abort.  */
8740
            offset = ((int32_t)insn << 21) >> 9;
8741
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8742
            return 0;
8743
        }
8744
        /* Fall through to 32-bit decode.  */
8745
    }
8746

    
8747
    insn = arm_lduw_code(env, s->pc, s->bswap_code);
8748
    s->pc += 2;
8749
    insn |= (uint32_t)insn_hw1 << 16;
8750

    
8751
    if ((insn & 0xf800e800) != 0xf000e800) {
8752
        ARCH(6T2);
8753
    }
8754

    
8755
    rn = (insn >> 16) & 0xf;
8756
    rs = (insn >> 12) & 0xf;
8757
    rd = (insn >> 8) & 0xf;
8758
    rm = insn & 0xf;
8759
    switch ((insn >> 25) & 0xf) {
8760
    case 0: case 1: case 2: case 3:
8761
        /* 16-bit instructions.  Should never happen.  */
8762
        abort();
8763
    case 4:
8764
        if (insn & (1 << 22)) {
8765
            /* Other load/store, table branch.  */
8766
            if (insn & 0x01200000) {
8767
                /* Load/store doubleword.  */
8768
                if (rn == 15) {
8769
                    addr = tcg_temp_new_i32();
8770
                    tcg_gen_movi_i32(addr, s->pc & ~3);
8771
                } else {
8772
                    addr = load_reg(s, rn);
8773
                }
8774
                offset = (insn & 0xff) * 4;
8775
                if ((insn & (1 << 23)) == 0)
8776
                    offset = -offset;
8777
                if (insn & (1 << 24)) {
8778
                    tcg_gen_addi_i32(addr, addr, offset);
8779
                    offset = 0;
8780
                }
8781
                if (insn & (1 << 20)) {
8782
                    /* ldrd */
8783
                    tmp = tcg_temp_new_i32();
8784
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
8785
                    store_reg(s, rs, tmp);
8786
                    tcg_gen_addi_i32(addr, addr, 4);
8787
                    tmp = tcg_temp_new_i32();
8788
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
8789
                    store_reg(s, rd, tmp);
8790
                } else {
8791
                    /* strd */
8792
                    tmp = load_reg(s, rs);
8793
                    gen_aa32_st32(tmp, addr, IS_USER(s));
8794
                    tcg_temp_free_i32(tmp);
8795
                    tcg_gen_addi_i32(addr, addr, 4);
8796
                    tmp = load_reg(s, rd);
8797
                    gen_aa32_st32(tmp, addr, IS_USER(s));
8798
                    tcg_temp_free_i32(tmp);
8799
                }
8800
                if (insn & (1 << 21)) {
8801
                    /* Base writeback.  */
8802
                    if (rn == 15)
8803
                        goto illegal_op;
8804
                    tcg_gen_addi_i32(addr, addr, offset - 4);
8805
                    store_reg(s, rn, addr);
8806
                } else {
8807
                    tcg_temp_free_i32(addr);
8808
                }
8809
            } else if ((insn & (1 << 23)) == 0) {
8810
                /* Load/store exclusive word.  */
8811
                addr = tcg_temp_local_new_i32();
8812
                load_reg_var(s, addr, rn);
8813
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8814
                if (insn & (1 << 20)) {
8815
                    gen_load_exclusive(s, rs, 15, addr, 2);
8816
                } else {
8817
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
8818
                }
8819
                tcg_temp_free_i32(addr);
8820
            } else if ((insn & (7 << 5)) == 0) {
8821
                /* Table Branch.  */
8822
                if (rn == 15) {
8823
                    addr = tcg_temp_new_i32();
8824
                    tcg_gen_movi_i32(addr, s->pc);
8825
                } else {
8826
                    addr = load_reg(s, rn);
8827
                }
8828
                tmp = load_reg(s, rm);
8829
                tcg_gen_add_i32(addr, addr, tmp);
8830
                if (insn & (1 << 4)) {
8831
                    /* tbh */
8832
                    tcg_gen_add_i32(addr, addr, tmp);
8833
                    tcg_temp_free_i32(tmp);
8834
                    tmp = tcg_temp_new_i32();
8835
                    gen_aa32_ld16u(tmp, addr, IS_USER(s));
8836
                } else { /* tbb */
8837
                    tcg_temp_free_i32(tmp);
8838
                    tmp = tcg_temp_new_i32();
8839
                    gen_aa32_ld8u(tmp, addr, IS_USER(s));
8840
                }
8841
                tcg_temp_free_i32(addr);
8842
                tcg_gen_shli_i32(tmp, tmp, 1);
8843
                tcg_gen_addi_i32(tmp, tmp, s->pc);
8844
                store_reg(s, 15, tmp);
8845
            } else {
8846
                int op2 = (insn >> 6) & 0x3;
8847
                op = (insn >> 4) & 0x3;
8848
                switch (op2) {
8849
                case 0:
8850
                    goto illegal_op;
8851
                case 1:
8852
                    /* Load/store exclusive byte/halfword/doubleword */
8853
                    if (op == 2) {
8854
                        goto illegal_op;
8855
                    }
8856
                    ARCH(7);
8857
                    break;
8858
                case 2:
8859
                    /* Load-acquire/store-release */
8860
                    if (op == 3) {
8861
                        goto illegal_op;
8862
                    }
8863
                    /* Fall through */
8864
                case 3:
8865
                    /* Load-acquire/store-release exclusive */
8866
                    ARCH(8);
8867
                    break;
8868
                }
8869
                addr = tcg_temp_local_new_i32();
8870
                load_reg_var(s, addr, rn);
8871
                if (!(op2 & 1)) {
8872
                    if (insn & (1 << 20)) {
8873
                        tmp = tcg_temp_new_i32();
8874
                        switch (op) {
8875
                        case 0: /* ldab */
8876
                            gen_aa32_ld8u(tmp, addr, IS_USER(s));
8877
                            break;
8878
                        case 1: /* ldah */
8879
                            gen_aa32_ld16u(tmp, addr, IS_USER(s));
8880
                            break;
8881
                        case 2: /* lda */
8882
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
8883
                            break;
8884
                        default:
8885
                            abort();
8886
                        }
8887
                        store_reg(s, rs, tmp);
8888
                    } else {
8889
                        tmp = load_reg(s, rs);
8890
                        switch (op) {
8891
                        case 0: /* stlb */
8892
                            gen_aa32_st8(tmp, addr, IS_USER(s));
8893
                            break;
8894
                        case 1: /* stlh */
8895
                            gen_aa32_st16(tmp, addr, IS_USER(s));
8896
                            break;
8897
                        case 2: /* stl */
8898
                            gen_aa32_st32(tmp, addr, IS_USER(s));
8899
                            break;
8900
                        default:
8901
                            abort();
8902
                        }
8903
                        tcg_temp_free_i32(tmp);
8904
                    }
8905
                } else if (insn & (1 << 20)) {
8906
                    gen_load_exclusive(s, rs, rd, addr, op);
8907
                } else {
8908
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
8909
                }
8910
                tcg_temp_free_i32(addr);
8911
            }
8912
        } else {
8913
            /* Load/store multiple, RFE, SRS.  */
8914
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8915
                /* RFE, SRS: not available in user mode or on M profile */
8916
                if (IS_USER(s) || IS_M(env)) {
8917
                    goto illegal_op;
8918
                }
8919
                if (insn & (1 << 20)) {
8920
                    /* rfe */
8921
                    addr = load_reg(s, rn);
8922
                    if ((insn & (1 << 24)) == 0)
8923
                        tcg_gen_addi_i32(addr, addr, -8);
8924
                    /* Load PC into tmp and CPSR into tmp2.  */
8925
                    tmp = tcg_temp_new_i32();
8926
                    gen_aa32_ld32u(tmp, addr, 0);
8927
                    tcg_gen_addi_i32(addr, addr, 4);
8928
                    tmp2 = tcg_temp_new_i32();
8929
                    gen_aa32_ld32u(tmp2, addr, 0);
8930
                    if (insn & (1 << 21)) {
8931
                        /* Base writeback.  */
8932
                        if (insn & (1 << 24)) {
8933
                            tcg_gen_addi_i32(addr, addr, 4);
8934
                        } else {
8935
                            tcg_gen_addi_i32(addr, addr, -4);
8936
                        }
8937
                        store_reg(s, rn, addr);
8938
                    } else {
8939
                        tcg_temp_free_i32(addr);
8940
                    }
8941
                    gen_rfe(s, tmp, tmp2);
8942
                } else {
8943
                    /* srs */
8944
                    gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8945
                            insn & (1 << 21));
8946
                }
8947
            } else {
8948
                int i, loaded_base = 0;
8949
                TCGv_i32 loaded_var;
8950
                /* Load/store multiple.  */
8951
                addr = load_reg(s, rn);
8952
                offset = 0;
8953
                for (i = 0; i < 16; i++) {
8954
                    if (insn & (1 << i))
8955
                        offset += 4;
8956
                }
8957
                if (insn & (1 << 24)) {
8958
                    tcg_gen_addi_i32(addr, addr, -offset);
8959
                }
8960

    
8961
                TCGV_UNUSED_I32(loaded_var);
8962
                for (i = 0; i < 16; i++) {
8963
                    if ((insn & (1 << i)) == 0)
8964
                        continue;
8965
                    if (insn & (1 << 20)) {
8966
                        /* Load.  */
8967
                        tmp = tcg_temp_new_i32();
8968
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
8969
                        if (i == 15) {
8970
                            gen_bx(s, tmp);
8971
                        } else if (i == rn) {
8972
                            loaded_var = tmp;
8973
                            loaded_base = 1;
8974
                        } else {
8975
                            store_reg(s, i, tmp);
8976
                        }
8977
                    } else {
8978
                        /* Store.  */
8979
                        tmp = load_reg(s, i);
8980
                        gen_aa32_st32(tmp, addr, IS_USER(s));
8981
                        tcg_temp_free_i32(tmp);
8982
                    }
8983
                    tcg_gen_addi_i32(addr, addr, 4);
8984
                }
8985
                if (loaded_base) {
8986
                    store_reg(s, rn, loaded_var);
8987
                }
8988
                if (insn & (1 << 21)) {
8989
                    /* Base register writeback.  */
8990
                    if (insn & (1 << 24)) {
8991
                        tcg_gen_addi_i32(addr, addr, -offset);
8992
                    }
8993
                    /* Fault if writeback register is in register list.  */
8994
                    if (insn & (1 << rn))
8995
                        goto illegal_op;
8996
                    store_reg(s, rn, addr);
8997
                } else {
8998
                    tcg_temp_free_i32(addr);
8999
                }
9000
            }
9001
        }
9002
        break;
9003
    case 5:
9004

    
9005
        op = (insn >> 21) & 0xf;
9006
        if (op == 6) {
9007
            /* Halfword pack.  */
9008
            tmp = load_reg(s, rn);
9009
            tmp2 = load_reg(s, rm);
9010
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9011
            if (insn & (1 << 5)) {
9012
                /* pkhtb */
9013
                if (shift == 0)
9014
                    shift = 31;
9015
                tcg_gen_sari_i32(tmp2, tmp2, shift);
9016
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9017
                tcg_gen_ext16u_i32(tmp2, tmp2);
9018
            } else {
9019
                /* pkhbt */
9020
                if (shift)
9021
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
9022
                tcg_gen_ext16u_i32(tmp, tmp);
9023
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9024
            }
9025
            tcg_gen_or_i32(tmp, tmp, tmp2);
9026
            tcg_temp_free_i32(tmp2);
9027
            store_reg(s, rd, tmp);
9028
        } else {
9029
            /* Data processing register constant shift.  */
9030
            if (rn == 15) {
9031
                tmp = tcg_temp_new_i32();
9032
                tcg_gen_movi_i32(tmp, 0);
9033
            } else {
9034
                tmp = load_reg(s, rn);
9035
            }
9036
            tmp2 = load_reg(s, rm);
9037

    
9038
            shiftop = (insn >> 4) & 3;
9039
            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9040
            conds = (insn & (1 << 20)) != 0;
9041
            logic_cc = (conds && thumb2_logic_op(op));
9042
            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9043
            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9044
                goto illegal_op;
9045
            tcg_temp_free_i32(tmp2);
9046
            if (rd != 15) {
9047
                store_reg(s, rd, tmp);
9048
            } else {
9049
                tcg_temp_free_i32(tmp);
9050
            }
9051
        }
9052
        break;
9053
    case 13: /* Misc data processing.  */
9054
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9055
        if (op < 4 && (insn & 0xf000) != 0xf000)
9056
            goto illegal_op;
9057
        switch (op) {
9058
        case 0: /* Register controlled shift.  */
9059
            tmp = load_reg(s, rn);
9060
            tmp2 = load_reg(s, rm);
9061
            if ((insn & 0x70) != 0)
9062
                goto illegal_op;
9063
            op = (insn >> 21) & 3;
9064
            logic_cc = (insn & (1 << 20)) != 0;
9065
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9066
            if (logic_cc)
9067
                gen_logic_CC(tmp);
9068
            store_reg_bx(env, s, rd, tmp);
9069
            break;
9070
        case 1: /* Sign/zero extend.  */
9071
            tmp = load_reg(s, rm);
9072
            shift = (insn >> 4) & 3;
9073
            /* ??? In many cases it's not necessary to do a
9074
               rotate, a shift is sufficient.  */
9075
            if (shift != 0)
9076
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9077
            op = (insn >> 20) & 7;
9078
            switch (op) {
9079
            case 0: gen_sxth(tmp);   break;
9080
            case 1: gen_uxth(tmp);   break;
9081
            case 2: gen_sxtb16(tmp); break;
9082
            case 3: gen_uxtb16(tmp); break;
9083
            case 4: gen_sxtb(tmp);   break;
9084
            case 5: gen_uxtb(tmp);   break;
9085
            default: goto illegal_op;
9086
            }
9087
            if (rn != 15) {
9088
                tmp2 = load_reg(s, rn);
9089
                if ((op >> 1) == 1) {
9090
                    gen_add16(tmp, tmp2);
9091
                } else {
9092
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9093
                    tcg_temp_free_i32(tmp2);
9094
                }
9095
            }
9096
            store_reg(s, rd, tmp);
9097
            break;
9098
        case 2: /* SIMD add/subtract.  */
9099
            op = (insn >> 20) & 7;
9100
            shift = (insn >> 4) & 7;
9101
            if ((op & 3) == 3 || (shift & 3) == 3)
9102
                goto illegal_op;
9103
            tmp = load_reg(s, rn);
9104
            tmp2 = load_reg(s, rm);
9105
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9106
            tcg_temp_free_i32(tmp2);
9107
            store_reg(s, rd, tmp);
9108
            break;
9109
        case 3: /* Other data processing.  */
9110
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9111
            if (op < 4) {
9112
                /* Saturating add/subtract.  */
9113
                tmp = load_reg(s, rn);
9114
                tmp2 = load_reg(s, rm);
9115
                if (op & 1)
9116
                    gen_helper_double_saturate(tmp, cpu_env, tmp);
9117
                if (op & 2)
9118
                    gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9119
                else
9120
                    gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9121
                tcg_temp_free_i32(tmp2);
9122
            } else {
9123
                tmp = load_reg(s, rn);
9124
                switch (op) {
9125
                case 0x0a: /* rbit */
9126
                    gen_helper_rbit(tmp, tmp);
9127
                    break;
9128
                case 0x08: /* rev */
9129
                    tcg_gen_bswap32_i32(tmp, tmp);
9130
                    break;
9131
                case 0x09: /* rev16 */
9132
                    gen_rev16(tmp);
9133
                    break;
9134
                case 0x0b: /* revsh */
9135
                    gen_revsh(tmp);
9136
                    break;
9137
                case 0x10: /* sel */
9138
                    tmp2 = load_reg(s, rm);
9139
                    tmp3 = tcg_temp_new_i32();
9140
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9141
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9142
                    tcg_temp_free_i32(tmp3);
9143
                    tcg_temp_free_i32(tmp2);
9144
                    break;
9145
                case 0x18: /* clz */
9146
                    gen_helper_clz(tmp, tmp);
9147
                    break;
9148
                default:
9149
                    goto illegal_op;
9150
                }
9151
            }
9152
            store_reg(s, rd, tmp);
9153
            break;
9154
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
9155
            op = (insn >> 4) & 0xf;
9156
            tmp = load_reg(s, rn);
9157
            tmp2 = load_reg(s, rm);
9158
            switch ((insn >> 20) & 7) {
9159
            case 0: /* 32 x 32 -> 32 */
9160
                tcg_gen_mul_i32(tmp, tmp, tmp2);
9161
                tcg_temp_free_i32(tmp2);
9162
                if (rs != 15) {
9163
                    tmp2 = load_reg(s, rs);
9164
                    if (op)
9165
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
9166
                    else
9167
                        tcg_gen_add_i32(tmp, tmp, tmp2);
9168
                    tcg_temp_free_i32(tmp2);
9169
                }
9170
                break;
9171
            case 1: /* 16 x 16 -> 32 */
9172
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
9173
                tcg_temp_free_i32(tmp2);
9174
                if (rs != 15) {
9175
                    tmp2 = load_reg(s, rs);
9176
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9177
                    tcg_temp_free_i32(tmp2);
9178
                }
9179
                break;
9180
            case 2: /* Dual multiply add.  */
9181
            case 4: /* Dual multiply subtract.  */
9182
                if (op)
9183
                    gen_swap_half(tmp2);
9184
                gen_smul_dual(tmp, tmp2);
9185
                if (insn & (1 << 22)) {
9186
                    /* This subtraction cannot overflow. */
9187
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9188
                } else {
9189
                    /* This addition cannot overflow 32 bits;
9190
                     * however it may overflow considered as a signed
9191
                     * operation, in which case we must set the Q flag.
9192
                     */
9193
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9194
                }
9195
                tcg_temp_free_i32(tmp2);
9196
                if (rs != 15)
9197
                  {
9198
                    tmp2 = load_reg(s, rs);
9199
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9200
                    tcg_temp_free_i32(tmp2);
9201
                  }
9202
                break;
9203
            case 3: /* 32 * 16 -> 32msb */
9204
                if (op)
9205
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
9206
                else
9207
                    gen_sxth(tmp2);
9208
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
9209
                tcg_gen_shri_i64(tmp64, tmp64, 16);
9210
                tmp = tcg_temp_new_i32();
9211
                tcg_gen_trunc_i64_i32(tmp, tmp64);
9212
                tcg_temp_free_i64(tmp64);
9213
                if (rs != 15)
9214
                  {
9215
                    tmp2 = load_reg(s, rs);
9216
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9217
                    tcg_temp_free_i32(tmp2);
9218
                  }
9219
                break;
9220
            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9221
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
9222
                if (rs != 15) {
9223
                    tmp = load_reg(s, rs);
9224
                    if (insn & (1 << 20)) {
9225
                        tmp64 = gen_addq_msw(tmp64, tmp);
9226
                    } else {
9227
                        tmp64 = gen_subq_msw(tmp64, tmp);
9228
                    }
9229
                }
9230
                if (insn & (1 << 4)) {
9231
                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9232
                }
9233
                tcg_gen_shri_i64(tmp64, tmp64, 32);
9234
                tmp = tcg_temp_new_i32();
9235
                tcg_gen_trunc_i64_i32(tmp, tmp64);
9236
                tcg_temp_free_i64(tmp64);
9237
                break;
9238
            case 7: /* Unsigned sum of absolute differences.  */
9239
                gen_helper_usad8(tmp, tmp, tmp2);
9240
                tcg_temp_free_i32(tmp2);
9241
                if (rs != 15) {
9242
                    tmp2 = load_reg(s, rs);
9243
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9244
                    tcg_temp_free_i32(tmp2);
9245
                }
9246
                break;
9247
            }
9248
            store_reg(s, rd, tmp);
9249
            break;
9250
        case 6: case 7: /* 64-bit multiply, Divide.  */
9251
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9252
            tmp = load_reg(s, rn);
9253
            tmp2 = load_reg(s, rm);
9254
            if ((op & 0x50) == 0x10) {
9255
                /* sdiv, udiv */
9256
                if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9257
                    goto illegal_op;
9258
                }
9259
                if (op & 0x20)
9260
                    gen_helper_udiv(tmp, tmp, tmp2);
9261
                else
9262
                    gen_helper_sdiv(tmp, tmp, tmp2);
9263
                tcg_temp_free_i32(tmp2);
9264
                store_reg(s, rd, tmp);
9265
            } else if ((op & 0xe) == 0xc) {
9266
                /* Dual multiply accumulate long.  */
9267
                if (op & 1)
9268
                    gen_swap_half(tmp2);
9269
                gen_smul_dual(tmp, tmp2);
9270
                if (op & 0x10) {
9271
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9272
                } else {
9273
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9274
                }
9275
                tcg_temp_free_i32(tmp2);
9276
                /* BUGFIX */
9277
                tmp64 = tcg_temp_new_i64();
9278
                tcg_gen_ext_i32_i64(tmp64, tmp);
9279
                tcg_temp_free_i32(tmp);
9280
                gen_addq(s, tmp64, rs, rd);
9281
                gen_storeq_reg(s, rs, rd, tmp64);
9282
                tcg_temp_free_i64(tmp64);
9283
            } else {
9284
                if (op & 0x20) {
9285
                    /* Unsigned 64-bit multiply  */
9286
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9287
                } else {
9288
                    if (op & 8) {
9289
                        /* smlalxy */
9290
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
9291
                        tcg_temp_free_i32(tmp2);
9292
                        tmp64 = tcg_temp_new_i64();
9293
                        tcg_gen_ext_i32_i64(tmp64, tmp);
9294
                        tcg_temp_free_i32(tmp);
9295
                    } else {
9296
                        /* Signed 64-bit multiply  */
9297
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
9298
                    }
9299
                }
9300
                if (op & 4) {
9301
                    /* umaal */
9302
                    gen_addq_lo(s, tmp64, rs);
9303
                    gen_addq_lo(s, tmp64, rd);
9304
                } else if (op & 0x40) {
9305
                    /* 64-bit accumulate.  */
9306
                    gen_addq(s, tmp64, rs, rd);
9307
                }
9308
                gen_storeq_reg(s, rs, rd, tmp64);
9309
                tcg_temp_free_i64(tmp64);
9310
            }
9311
            break;
9312
        }
9313
        break;
9314
    case 6: case 7: case 14: case 15:
9315
        /* Coprocessor.  */
9316
        if (((insn >> 24) & 3) == 3) {
9317
            /* Translate into the equivalent ARM encoding.  */
9318
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9319
            if (disas_neon_data_insn(env, s, insn))
9320
                goto illegal_op;
9321
        } else if (((insn >> 8) & 0xe) == 10) {
9322
            if (disas_vfp_insn(env, s, insn)) {
9323
                goto illegal_op;
9324
            }
9325
        } else {
9326
            if (insn & (1 << 28))
9327
                goto illegal_op;
9328
            if (disas_coproc_insn (env, s, insn))
9329
                goto illegal_op;
9330
        }
9331
        break;
9332
    case 8: case 9: case 10: case 11:
9333
        if (insn & (1 << 15)) {
9334
            /* Branches, misc control.  */
9335
            if (insn & 0x5000) {
9336
                /* Unconditional branch.  */
9337
                /* signextend(hw1[10:0]) -> offset[:12].  */
9338
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9339
                /* hw1[10:0] -> offset[11:1].  */
9340
                offset |= (insn & 0x7ff) << 1;
9341
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9342
                   offset[24:22] already have the same value because of the
9343
                   sign extension above.  */
9344
                offset ^= ((~insn) & (1 << 13)) << 10;
9345
                offset ^= ((~insn) & (1 << 11)) << 11;
9346

    
9347
                if (insn & (1 << 14)) {
9348
                    /* Branch and link.  */
9349
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9350
                }
9351

    
9352
                offset += s->pc;
9353
                if (insn & (1 << 12)) {
9354
                    /* b/bl */
9355
                    gen_jmp(s, offset);
9356
                } else {
9357
                    /* blx */
9358
                    offset &= ~(uint32_t)2;
9359
                    /* thumb2 bx, no need to check */
9360
                    gen_bx_im(s, offset);
9361
                }
9362
            } else if (((insn >> 23) & 7) == 7) {
9363
                /* Misc control */
9364
                if (insn & (1 << 13))
9365
                    goto illegal_op;
9366

    
9367
                if (insn & (1 << 26)) {
9368
                    /* Secure monitor call (v6Z) */
9369
                    qemu_log_mask(LOG_UNIMP,
9370
                                  "arm: unimplemented secure monitor call\n");
9371
                    goto illegal_op; /* not implemented.  */
9372
                } else {
9373
                    op = (insn >> 20) & 7;
9374
                    switch (op) {
9375
                    case 0: /* msr cpsr.  */
9376
                        if (IS_M(env)) {
9377
                            tmp = load_reg(s, rn);
9378
                            addr = tcg_const_i32(insn & 0xff);
9379
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
9380
                            tcg_temp_free_i32(addr);
9381
                            tcg_temp_free_i32(tmp);
9382
                            gen_lookup_tb(s);
9383
                            break;
9384
                        }
9385
                        /* fall through */
9386
                    case 1: /* msr spsr.  */
9387
                        if (IS_M(env))
9388
                            goto illegal_op;
9389
                        tmp = load_reg(s, rn);
9390
                        if (gen_set_psr(s,
9391
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9392
                              op == 1, tmp))
9393
                            goto illegal_op;
9394
                        break;
9395
                    case 2: /* cps, nop-hint.  */
9396
                        if (((insn >> 8) & 7) == 0) {
9397
                            gen_nop_hint(s, insn & 0xff);
9398
                        }
9399
                        /* Implemented as NOP in user mode.  */
9400
                        if (IS_USER(s))
9401
                            break;
9402
                        offset = 0;
9403
                        imm = 0;
9404
                        if (insn & (1 << 10)) {
9405
                            if (insn & (1 << 7))
9406
                                offset |= CPSR_A;
9407
                            if (insn & (1 << 6))
9408
                                offset |= CPSR_I;
9409
                            if (insn & (1 << 5))
9410
                                offset |= CPSR_F;
9411
                            if (insn & (1 << 9))
9412
                                imm = CPSR_A | CPSR_I | CPSR_F;
9413
                        }
9414
                        if (insn & (1 << 8)) {
9415
                            offset |= 0x1f;
9416
                            imm |= (insn & 0x1f);
9417
                        }
9418
                        if (offset) {
9419
                            gen_set_psr_im(s, offset, 0, imm);
9420
                        }
9421
                        break;
9422
                    case 3: /* Special control operations.  */
9423
                        ARCH(7);
9424
                        op = (insn >> 4) & 0xf;
9425
                        switch (op) {
9426
                        case 2: /* clrex */
9427
                            gen_clrex(s);
9428
                            break;
9429
                        case 4: /* dsb */
9430
                        case 5: /* dmb */
9431
                        case 6: /* isb */
9432
                            /* These execute as NOPs.  */
9433
                            break;
9434
                        default:
9435
                            goto illegal_op;
9436
                        }
9437
                        break;
9438
                    case 4: /* bxj */
9439
                        /* Trivial implementation equivalent to bx.  */
9440
                        tmp = load_reg(s, rn);
9441
                        gen_bx(s, tmp);
9442
                        break;
9443
                    case 5: /* Exception return.  */
9444
                        if (IS_USER(s)) {
9445
                            goto illegal_op;
9446
                        }
9447
                        if (rn != 14 || rd != 15) {
9448
                            goto illegal_op;
9449
                        }
9450
                        tmp = load_reg(s, rn);
9451
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9452
                        gen_exception_return(s, tmp);
9453
                        break;
9454
                    case 6: /* mrs cpsr.  */
9455
                        tmp = tcg_temp_new_i32();
9456
                        if (IS_M(env)) {
9457
                            addr = tcg_const_i32(insn & 0xff);
9458
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
9459
                            tcg_temp_free_i32(addr);
9460
                        } else {
9461
                            gen_helper_cpsr_read(tmp, cpu_env);
9462
                        }
9463
                        store_reg(s, rd, tmp);
9464
                        break;
9465
                    case 7: /* mrs spsr.  */
9466
                        /* Not accessible in user mode.  */
9467
                        if (IS_USER(s) || IS_M(env))
9468
                            goto illegal_op;
9469
                        tmp = load_cpu_field(spsr);
9470
                        store_reg(s, rd, tmp);
9471
                        break;
9472
                    }
9473
                }
9474
            } else {
9475
                /* Conditional branch.  */
9476
                op = (insn >> 22) & 0xf;
9477
                /* Generate a conditional jump to next instruction.  */
9478
                s->condlabel = gen_new_label();
9479
                arm_gen_test_cc(op ^ 1, s->condlabel);
9480
                s->condjmp = 1;
9481

    
9482
                /* offset[11:1] = insn[10:0] */
9483
                offset = (insn & 0x7ff) << 1;
9484
                /* offset[17:12] = insn[21:16].  */
9485
                offset |= (insn & 0x003f0000) >> 4;
9486
                /* offset[31:20] = insn[26].  */
9487
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9488
                /* offset[18] = insn[13].  */
9489
                offset |= (insn & (1 << 13)) << 5;
9490
                /* offset[19] = insn[11].  */
9491
                offset |= (insn & (1 << 11)) << 8;
9492

    
9493
                /* jump to the offset */
9494
                gen_jmp(s, s->pc + offset);
9495
            }
9496
        } else {
9497
            /* Data processing immediate.  */
9498
            if (insn & (1 << 25)) {
9499
                if (insn & (1 << 24)) {
9500
                    if (insn & (1 << 20))
9501
                        goto illegal_op;
9502
                    /* Bitfield/Saturate.  */
9503
                    op = (insn >> 21) & 7;
9504
                    imm = insn & 0x1f;
9505
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9506
                    if (rn == 15) {
9507
                        tmp = tcg_temp_new_i32();
9508
                        tcg_gen_movi_i32(tmp, 0);
9509
                    } else {
9510
                        tmp = load_reg(s, rn);
9511
                    }
9512
                    switch (op) {
9513
                    case 2: /* Signed bitfield extract.  */
9514
                        imm++;
9515
                        if (shift + imm > 32)
9516
                            goto illegal_op;
9517
                        if (imm < 32)
9518
                            gen_sbfx(tmp, shift, imm);
9519
                        break;
9520
                    case 6: /* Unsigned bitfield extract.  */
9521
                        imm++;
9522
                        if (shift + imm > 32)
9523
                            goto illegal_op;
9524
                        if (imm < 32)
9525
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
9526
                        break;
9527
                    case 3: /* Bitfield insert/clear.  */
9528
                        if (imm < shift)
9529
                            goto illegal_op;
9530
                        imm = imm + 1 - shift;
9531
                        if (imm != 32) {
9532
                            tmp2 = load_reg(s, rd);
9533
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9534
                            tcg_temp_free_i32(tmp2);
9535
                        }
9536
                        break;
9537
                    case 7:
9538
                        goto illegal_op;
9539
                    default: /* Saturate.  */
9540
                        if (shift) {
9541
                            if (op & 1)
9542
                                tcg_gen_sari_i32(tmp, tmp, shift);
9543
                            else
9544
                                tcg_gen_shli_i32(tmp, tmp, shift);
9545
                        }
9546
                        tmp2 = tcg_const_i32(imm);
9547
                        if (op & 4) {
9548
                            /* Unsigned.  */
9549
                            if ((op & 1) && shift == 0)
9550
                                gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9551
                            else
9552
                                gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9553
                        } else {
9554
                            /* Signed.  */
9555
                            if ((op & 1) && shift == 0)
9556
                                gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9557
                            else
9558
                                gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9559
                        }
9560
                        tcg_temp_free_i32(tmp2);
9561
                        break;
9562
                    }
9563
                    store_reg(s, rd, tmp);
9564
                } else {
9565
                    imm = ((insn & 0x04000000) >> 15)
9566
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
9567
                    if (insn & (1 << 22)) {
9568
                        /* 16-bit immediate.  */
9569
                        imm |= (insn >> 4) & 0xf000;
9570
                        if (insn & (1 << 23)) {
9571
                            /* movt */
9572
                            tmp = load_reg(s, rd);
9573
                            tcg_gen_ext16u_i32(tmp, tmp);
9574
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
9575
                        } else {
9576
                            /* movw */
9577
                            tmp = tcg_temp_new_i32();
9578
                            tcg_gen_movi_i32(tmp, imm);
9579
                        }
9580
                    } else {
9581
                        /* Add/sub 12-bit immediate.  */
9582
                        if (rn == 15) {
9583
                            offset = s->pc & ~(uint32_t)3;
9584
                            if (insn & (1 << 23))
9585
                                offset -= imm;
9586
                            else
9587
                                offset += imm;
9588
                            tmp = tcg_temp_new_i32();
9589
                            tcg_gen_movi_i32(tmp, offset);
9590
                        } else {
9591
                            tmp = load_reg(s, rn);
9592
                            if (insn & (1 << 23))
9593
                                tcg_gen_subi_i32(tmp, tmp, imm);
9594
                            else
9595
                                tcg_gen_addi_i32(tmp, tmp, imm);
9596
                        }
9597
                    }
9598
                    store_reg(s, rd, tmp);
9599
                }
9600
            } else {
9601
                int shifter_out = 0;
9602
                /* modified 12-bit immediate.  */
9603
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9604
                imm = (insn & 0xff);
9605
                switch (shift) {
9606
                case 0: /* XY */
9607
                    /* Nothing to do.  */
9608
                    break;
9609
                case 1: /* 00XY00XY */
9610
                    imm |= imm << 16;
9611
                    break;
9612
                case 2: /* XY00XY00 */
9613
                    imm |= imm << 16;
9614
                    imm <<= 8;
9615
                    break;
9616
                case 3: /* XYXYXYXY */
9617
                    imm |= imm << 16;
9618
                    imm |= imm << 8;
9619
                    break;
9620
                default: /* Rotated constant.  */
9621
                    shift = (shift << 1) | (imm >> 7);
9622
                    imm |= 0x80;
9623
                    imm = imm << (32 - shift);
9624
                    shifter_out = 1;
9625
                    break;
9626
                }
9627
                tmp2 = tcg_temp_new_i32();
9628
                tcg_gen_movi_i32(tmp2, imm);
9629
                rn = (insn >> 16) & 0xf;
9630
                if (rn == 15) {
9631
                    tmp = tcg_temp_new_i32();
9632
                    tcg_gen_movi_i32(tmp, 0);
9633
                } else {
9634
                    tmp = load_reg(s, rn);
9635
                }
9636
                op = (insn >> 21) & 0xf;
9637
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9638
                                       shifter_out, tmp, tmp2))
9639
                    goto illegal_op;
9640
                tcg_temp_free_i32(tmp2);
9641
                rd = (insn >> 8) & 0xf;
9642
                if (rd != 15) {
9643
                    store_reg(s, rd, tmp);
9644
                } else {
9645
                    tcg_temp_free_i32(tmp);
9646
                }
9647
            }
9648
        }
9649
        break;
9650
    case 12: /* Load/store single data item.  */
9651
        {
9652
        int postinc = 0;
9653
        int writeback = 0;
9654
        int user;
9655
        if ((insn & 0x01100000) == 0x01000000) {
9656
            if (disas_neon_ls_insn(env, s, insn))
9657
                goto illegal_op;
9658
            break;
9659
        }
9660
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9661
        if (rs == 15) {
9662
            if (!(insn & (1 << 20))) {
9663
                goto illegal_op;
9664
            }
9665
            if (op != 2) {
9666
                /* Byte or halfword load space with dest == r15 : memory hints.
9667
                 * Catch them early so we don't emit pointless addressing code.
9668
                 * This space is a mix of:
9669
                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
9670
                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9671
                 *     cores)
9672
                 *  unallocated hints, which must be treated as NOPs
9673
                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
9674
                 *     which is easiest for the decoding logic
9675
                 *  Some space which must UNDEF
9676
                 */
9677
                int op1 = (insn >> 23) & 3;
9678
                int op2 = (insn >> 6) & 0x3f;
9679
                if (op & 2) {
9680
                    goto illegal_op;
9681
                }
9682
                if (rn == 15) {
9683
                    /* UNPREDICTABLE, unallocated hint or
9684
                     * PLD/PLDW/PLI (literal)
9685
                     */
9686
                    return 0;
9687
                }
9688
                if (op1 & 1) {
9689
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
9690
                }
9691
                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9692
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
9693
                }
9694
                /* UNDEF space, or an UNPREDICTABLE */
9695
                return 1;
9696
            }
9697
        }
9698
        user = IS_USER(s);
9699
        if (rn == 15) {
9700
            addr = tcg_temp_new_i32();
9701
            /* PC relative.  */
9702
            /* s->pc has already been incremented by 4.  */
9703
            imm = s->pc & 0xfffffffc;
9704
            if (insn & (1 << 23))
9705
                imm += insn & 0xfff;
9706
            else
9707
                imm -= insn & 0xfff;
9708
            tcg_gen_movi_i32(addr, imm);
9709
        } else {
9710
            addr = load_reg(s, rn);
9711
            if (insn & (1 << 23)) {
9712
                /* Positive offset.  */
9713
                imm = insn & 0xfff;
9714
                tcg_gen_addi_i32(addr, addr, imm);
9715
            } else {
9716
                imm = insn & 0xff;
9717
                switch ((insn >> 8) & 0xf) {
9718
                case 0x0: /* Shifted Register.  */
9719
                    shift = (insn >> 4) & 0xf;
9720
                    if (shift > 3) {
9721
                        tcg_temp_free_i32(addr);
9722
                        goto illegal_op;
9723
                    }
9724
                    tmp = load_reg(s, rm);
9725
                    if (shift)
9726
                        tcg_gen_shli_i32(tmp, tmp, shift);
9727
                    tcg_gen_add_i32(addr, addr, tmp);
9728
                    tcg_temp_free_i32(tmp);
9729
                    break;
9730
                case 0xc: /* Negative offset.  */
9731
                    tcg_gen_addi_i32(addr, addr, -imm);
9732
                    break;
9733
                case 0xe: /* User privilege.  */
9734
                    tcg_gen_addi_i32(addr, addr, imm);
9735
                    user = 1;
9736
                    break;
9737
                case 0x9: /* Post-decrement.  */
9738
                    imm = -imm;
9739
                    /* Fall through.  */
9740
                case 0xb: /* Post-increment.  */
9741
                    postinc = 1;
9742
                    writeback = 1;
9743
                    break;
9744
                case 0xd: /* Pre-decrement.  */
9745
                    imm = -imm;
9746
                    /* Fall through.  */
9747
                case 0xf: /* Pre-increment.  */
9748
                    tcg_gen_addi_i32(addr, addr, imm);
9749
                    writeback = 1;
9750
                    break;
9751
                default:
9752
                    tcg_temp_free_i32(addr);
9753
                    goto illegal_op;
9754
                }
9755
            }
9756
        }
9757
        if (insn & (1 << 20)) {
9758
            /* Load.  */
9759
            tmp = tcg_temp_new_i32();
9760
            switch (op) {
9761
            case 0:
9762
                gen_aa32_ld8u(tmp, addr, user);
9763
                break;
9764
            case 4:
9765
                gen_aa32_ld8s(tmp, addr, user);
9766
                break;
9767
            case 1:
9768
                gen_aa32_ld16u(tmp, addr, user);
9769
                break;
9770
            case 5:
9771
                gen_aa32_ld16s(tmp, addr, user);
9772
                break;
9773
            case 2:
9774
                gen_aa32_ld32u(tmp, addr, user);
9775
                break;
9776
            default:
9777
                tcg_temp_free_i32(tmp);
9778
                tcg_temp_free_i32(addr);
9779
                goto illegal_op;
9780
            }
9781
            if (rs == 15) {
9782
                gen_bx(s, tmp);
9783
            } else {
9784
                store_reg(s, rs, tmp);
9785
            }
9786
        } else {
9787
            /* Store.  */
9788
            tmp = load_reg(s, rs);
9789
            switch (op) {
9790
            case 0:
9791
                gen_aa32_st8(tmp, addr, user);
9792
                break;
9793
            case 1:
9794
                gen_aa32_st16(tmp, addr, user);
9795
                break;
9796
            case 2:
9797
                gen_aa32_st32(tmp, addr, user);
9798
                break;
9799
            default:
9800
                tcg_temp_free_i32(tmp);
9801
                tcg_temp_free_i32(addr);
9802
                goto illegal_op;
9803
            }
9804
            tcg_temp_free_i32(tmp);
9805
        }
9806
        if (postinc)
9807
            tcg_gen_addi_i32(addr, addr, imm);
9808
        if (writeback) {
9809
            store_reg(s, rn, addr);
9810
        } else {
9811
            tcg_temp_free_i32(addr);
9812
        }
9813
        }
9814
        break;
9815
    default:
9816
        goto illegal_op;
9817
    }
9818
    return 0;
9819
illegal_op:
9820
    return 1;
9821
}
9822

    
9823
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9824
{
9825
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
9826
    int32_t offset;
9827
    int i;
9828
    TCGv_i32 tmp;
9829
    TCGv_i32 tmp2;
9830
    TCGv_i32 addr;
9831

    
9832
    if (s->condexec_mask) {
9833
        cond = s->condexec_cond;
9834
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
9835
          s->condlabel = gen_new_label();
9836
          arm_gen_test_cc(cond ^ 1, s->condlabel);
9837
          s->condjmp = 1;
9838
        }
9839
    }
9840

    
9841
    insn = arm_lduw_code(env, s->pc, s->bswap_code);
9842
    s->pc += 2;
9843

    
9844
    switch (insn >> 12) {
9845
    case 0: case 1:
9846

    
9847
        rd = insn & 7;
9848
        op = (insn >> 11) & 3;
9849
        if (op == 3) {
9850
            /* add/subtract */
9851
            rn = (insn >> 3) & 7;
9852
            tmp = load_reg(s, rn);
9853
            if (insn & (1 << 10)) {
9854
                /* immediate */
9855
                tmp2 = tcg_temp_new_i32();
9856
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9857
            } else {
9858
                /* reg */
9859
                rm = (insn >> 6) & 7;
9860
                tmp2 = load_reg(s, rm);
9861
            }
9862
            if (insn & (1 << 9)) {
9863
                if (s->condexec_mask)
9864
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9865
                else
9866
                    gen_sub_CC(tmp, tmp, tmp2);
9867
            } else {
9868
                if (s->condexec_mask)
9869
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9870
                else
9871
                    gen_add_CC(tmp, tmp, tmp2);
9872
            }
9873
            tcg_temp_free_i32(tmp2);
9874
            store_reg(s, rd, tmp);
9875
        } else {
9876
            /* shift immediate */
9877
            rm = (insn >> 3) & 7;
9878
            shift = (insn >> 6) & 0x1f;
9879
            tmp = load_reg(s, rm);
9880
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9881
            if (!s->condexec_mask)
9882
                gen_logic_CC(tmp);
9883
            store_reg(s, rd, tmp);
9884
        }
9885
        break;
9886
    case 2: case 3:
9887
        /* arithmetic large immediate */
9888
        op = (insn >> 11) & 3;
9889
        rd = (insn >> 8) & 0x7;
9890
        if (op == 0) { /* mov */
9891
            tmp = tcg_temp_new_i32();
9892
            tcg_gen_movi_i32(tmp, insn & 0xff);
9893
            if (!s->condexec_mask)
9894
                gen_logic_CC(tmp);
9895
            store_reg(s, rd, tmp);
9896
        } else {
9897
            tmp = load_reg(s, rd);
9898
            tmp2 = tcg_temp_new_i32();
9899
            tcg_gen_movi_i32(tmp2, insn & 0xff);
9900
            switch (op) {
9901
            case 1: /* cmp */
9902
                gen_sub_CC(tmp, tmp, tmp2);
9903
                tcg_temp_free_i32(tmp);
9904
                tcg_temp_free_i32(tmp2);
9905
                break;
9906
            case 2: /* add */
9907
                if (s->condexec_mask)
9908
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9909
                else
9910
                    gen_add_CC(tmp, tmp, tmp2);
9911
                tcg_temp_free_i32(tmp2);
9912
                store_reg(s, rd, tmp);
9913
                break;
9914
            case 3: /* sub */
9915
                if (s->condexec_mask)
9916
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9917
                else
9918
                    gen_sub_CC(tmp, tmp, tmp2);
9919
                tcg_temp_free_i32(tmp2);
9920
                store_reg(s, rd, tmp);
9921
                break;
9922
            }
9923
        }
9924
        break;
9925
    case 4:
9926
        if (insn & (1 << 11)) {
9927
            rd = (insn >> 8) & 7;
9928
            /* load pc-relative.  Bit 1 of PC is ignored.  */
9929
            val = s->pc + 2 + ((insn & 0xff) * 4);
9930
            val &= ~(uint32_t)2;
9931
            addr = tcg_temp_new_i32();
9932
            tcg_gen_movi_i32(addr, val);
9933
            tmp = tcg_temp_new_i32();
9934
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
9935
            tcg_temp_free_i32(addr);
9936
            store_reg(s, rd, tmp);
9937
            break;
9938
        }
9939
        if (insn & (1 << 10)) {
9940
            /* data processing extended or blx */
9941
            rd = (insn & 7) | ((insn >> 4) & 8);
9942
            rm = (insn >> 3) & 0xf;
9943
            op = (insn >> 8) & 3;
9944
            switch (op) {
9945
            case 0: /* add */
9946
                tmp = load_reg(s, rd);
9947
                tmp2 = load_reg(s, rm);
9948
                tcg_gen_add_i32(tmp, tmp, tmp2);
9949
                tcg_temp_free_i32(tmp2);
9950
                store_reg(s, rd, tmp);
9951
                break;
9952
            case 1: /* cmp */
9953
                tmp = load_reg(s, rd);
9954
                tmp2 = load_reg(s, rm);
9955
                gen_sub_CC(tmp, tmp, tmp2);
9956
                tcg_temp_free_i32(tmp2);
9957
                tcg_temp_free_i32(tmp);
9958
                break;
9959
            case 2: /* mov/cpy */
9960
                tmp = load_reg(s, rm);
9961
                store_reg(s, rd, tmp);
9962
                break;
9963
            case 3:/* branch [and link] exchange thumb register */
9964
                tmp = load_reg(s, rm);
9965
                if (insn & (1 << 7)) {
9966
                    ARCH(5);
9967
                    val = (uint32_t)s->pc | 1;
9968
                    tmp2 = tcg_temp_new_i32();
9969
                    tcg_gen_movi_i32(tmp2, val);
9970
                    store_reg(s, 14, tmp2);
9971
                }
9972
                /* already thumb, no need to check */
9973
                gen_bx(s, tmp);
9974
                break;
9975
            }
9976
            break;
9977
        }
9978

    
9979
        /* data processing register */
9980
        rd = insn & 7;
9981
        rm = (insn >> 3) & 7;
9982
        op = (insn >> 6) & 0xf;
9983
        if (op == 2 || op == 3 || op == 4 || op == 7) {
9984
            /* the shift/rotate ops want the operands backwards */
9985
            val = rm;
9986
            rm = rd;
9987
            rd = val;
9988
            val = 1;
9989
        } else {
9990
            val = 0;
9991
        }
9992

    
9993
        if (op == 9) { /* neg */
9994
            tmp = tcg_temp_new_i32();
9995
            tcg_gen_movi_i32(tmp, 0);
9996
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
9997
            tmp = load_reg(s, rd);
9998
        } else {
9999
            TCGV_UNUSED_I32(tmp);
10000
        }
10001

    
10002
        tmp2 = load_reg(s, rm);
10003
        switch (op) {
10004
        case 0x0: /* and */
10005
            tcg_gen_and_i32(tmp, tmp, tmp2);
10006
            if (!s->condexec_mask)
10007
                gen_logic_CC(tmp);
10008
            break;
10009
        case 0x1: /* eor */
10010
            tcg_gen_xor_i32(tmp, tmp, tmp2);
10011
            if (!s->condexec_mask)
10012
                gen_logic_CC(tmp);
10013
            break;
10014
        case 0x2: /* lsl */
10015
            if (s->condexec_mask) {
10016
                gen_shl(tmp2, tmp2, tmp);
10017
            } else {
10018
                gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10019
                gen_logic_CC(tmp2);
10020
            }
10021
            break;
10022
        case 0x3: /* lsr */
10023
            if (s->condexec_mask) {
10024
                gen_shr(tmp2, tmp2, tmp);
10025
            } else {
10026
                gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10027
                gen_logic_CC(tmp2);
10028
            }
10029
            break;
10030
        case 0x4: /* asr */
10031
            if (s->condexec_mask) {
10032
                gen_sar(tmp2, tmp2, tmp);
10033
            } else {
10034
                gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10035
                gen_logic_CC(tmp2);
10036
            }
10037
            break;
10038
        case 0x5: /* adc */
10039
            if (s->condexec_mask) {
10040
                gen_adc(tmp, tmp2);
10041
            } else {
10042
                gen_adc_CC(tmp, tmp, tmp2);
10043
            }
10044
            break;
10045
        case 0x6: /* sbc */
10046
            if (s->condexec_mask) {
10047
                gen_sub_carry(tmp, tmp, tmp2);
10048
            } else {
10049
                gen_sbc_CC(tmp, tmp, tmp2);
10050
            }
10051
            break;
10052
        case 0x7: /* ror */
10053
            if (s->condexec_mask) {
10054
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
10055
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10056
            } else {
10057
                gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10058
                gen_logic_CC(tmp2);
10059
            }
10060
            break;
10061
        case 0x8: /* tst */
10062
            tcg_gen_and_i32(tmp, tmp, tmp2);
10063
            gen_logic_CC(tmp);
10064
            rd = 16;
10065
            break;
10066
        case 0x9: /* neg */
10067
            if (s->condexec_mask)
10068
                tcg_gen_neg_i32(tmp, tmp2);
10069
            else
10070
                gen_sub_CC(tmp, tmp, tmp2);
10071
            break;
10072
        case 0xa: /* cmp */
10073
            gen_sub_CC(tmp, tmp, tmp2);
10074
            rd = 16;
10075
            break;
10076
        case 0xb: /* cmn */
10077
            gen_add_CC(tmp, tmp, tmp2);
10078
            rd = 16;
10079
            break;
10080
        case 0xc: /* orr */
10081
            tcg_gen_or_i32(tmp, tmp, tmp2);
10082
            if (!s->condexec_mask)
10083
                gen_logic_CC(tmp);
10084
            break;
10085
        case 0xd: /* mul */
10086
            tcg_gen_mul_i32(tmp, tmp, tmp2);
10087
            if (!s->condexec_mask)
10088
                gen_logic_CC(tmp);
10089
            break;
10090
        case 0xe: /* bic */
10091
            tcg_gen_andc_i32(tmp, tmp, tmp2);
10092
            if (!s->condexec_mask)
10093
                gen_logic_CC(tmp);
10094
            break;
10095
        case 0xf: /* mvn */
10096
            tcg_gen_not_i32(tmp2, tmp2);
10097
            if (!s->condexec_mask)
10098
                gen_logic_CC(tmp2);
10099
            val = 1;
10100
            rm = rd;
10101
            break;
10102
        }
10103
        if (rd != 16) {
10104
            if (val) {
10105
                store_reg(s, rm, tmp2);
10106
                if (op != 0xf)
10107
                    tcg_temp_free_i32(tmp);
10108
            } else {
10109
                store_reg(s, rd, tmp);
10110
                tcg_temp_free_i32(tmp2);
10111
            }
10112
        } else {
10113
            tcg_temp_free_i32(tmp);
10114
            tcg_temp_free_i32(tmp2);
10115
        }
10116
        break;
10117

    
10118
    case 5:
10119
        /* load/store register offset.  */
10120
        rd = insn & 7;
10121
        rn = (insn >> 3) & 7;
10122
        rm = (insn >> 6) & 7;
10123
        op = (insn >> 9) & 7;
10124
        addr = load_reg(s, rn);
10125
        tmp = load_reg(s, rm);
10126
        tcg_gen_add_i32(addr, addr, tmp);
10127
        tcg_temp_free_i32(tmp);
10128

    
10129
        if (op < 3) { /* store */
10130
            tmp = load_reg(s, rd);
10131
        } else {
10132
            tmp = tcg_temp_new_i32();
10133
        }
10134

    
10135
        switch (op) {
10136
        case 0: /* str */
10137
            gen_aa32_st32(tmp, addr, IS_USER(s));
10138
            break;
10139
        case 1: /* strh */
10140
            gen_aa32_st16(tmp, addr, IS_USER(s));
10141
            break;
10142
        case 2: /* strb */
10143
            gen_aa32_st8(tmp, addr, IS_USER(s));
10144
            break;
10145
        case 3: /* ldrsb */
10146
            gen_aa32_ld8s(tmp, addr, IS_USER(s));
10147
            break;
10148
        case 4: /* ldr */
10149
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
10150
            break;
10151
        case 5: /* ldrh */
10152
            gen_aa32_ld16u(tmp, addr, IS_USER(s));
10153
            break;
10154
        case 6: /* ldrb */
10155
            gen_aa32_ld8u(tmp, addr, IS_USER(s));
10156
            break;
10157
        case 7: /* ldrsh */
10158
            gen_aa32_ld16s(tmp, addr, IS_USER(s));
10159
            break;
10160
        }
10161
        if (op >= 3) { /* load */
10162
            store_reg(s, rd, tmp);
10163
        } else {
10164
            tcg_temp_free_i32(tmp);
10165
        }
10166
        tcg_temp_free_i32(addr);
10167
        break;
10168

    
10169
    case 6:
10170
        /* load/store word immediate offset */
10171
        rd = insn & 7;
10172
        rn = (insn >> 3) & 7;
10173
        addr = load_reg(s, rn);
10174
        val = (insn >> 4) & 0x7c;
10175
        tcg_gen_addi_i32(addr, addr, val);
10176

    
10177
        if (insn & (1 << 11)) {
10178
            /* load */
10179
            tmp = tcg_temp_new_i32();
10180
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
10181
            store_reg(s, rd, tmp);
10182
        } else {
10183
            /* store */
10184
            tmp = load_reg(s, rd);
10185
            gen_aa32_st32(tmp, addr, IS_USER(s));
10186
            tcg_temp_free_i32(tmp);
10187
        }
10188
        tcg_temp_free_i32(addr);
10189
        break;
10190

    
10191
    case 7:
10192
        /* load/store byte immediate offset */
10193
        rd = insn & 7;
10194
        rn = (insn >> 3) & 7;
10195
        addr = load_reg(s, rn);
10196
        val = (insn >> 6) & 0x1f;
10197
        tcg_gen_addi_i32(addr, addr, val);
10198

    
10199
        if (insn & (1 << 11)) {
10200
            /* load */
10201
            tmp = tcg_temp_new_i32();
10202
            gen_aa32_ld8u(tmp, addr, IS_USER(s));
10203
            store_reg(s, rd, tmp);
10204
        } else {
10205
            /* store */
10206
            tmp = load_reg(s, rd);
10207
            gen_aa32_st8(tmp, addr, IS_USER(s));
10208
            tcg_temp_free_i32(tmp);
10209
        }
10210
        tcg_temp_free_i32(addr);
10211
        break;
10212

    
10213
    case 8:
10214
        /* load/store halfword immediate offset */
10215
        rd = insn & 7;
10216
        rn = (insn >> 3) & 7;
10217
        addr = load_reg(s, rn);
10218
        val = (insn >> 5) & 0x3e;
10219
        tcg_gen_addi_i32(addr, addr, val);
10220

    
10221
        if (insn & (1 << 11)) {
10222
            /* load */
10223
            tmp = tcg_temp_new_i32();
10224
            gen_aa32_ld16u(tmp, addr, IS_USER(s));
10225
            store_reg(s, rd, tmp);
10226
        } else {
10227
            /* store */
10228
            tmp = load_reg(s, rd);
10229
            gen_aa32_st16(tmp, addr, IS_USER(s));
10230
            tcg_temp_free_i32(tmp);
10231
        }
10232
        tcg_temp_free_i32(addr);
10233
        break;
10234

    
10235
    case 9:
10236
        /* load/store from stack */
10237
        rd = (insn >> 8) & 7;
10238
        addr = load_reg(s, 13);
10239
        val = (insn & 0xff) * 4;
10240
        tcg_gen_addi_i32(addr, addr, val);
10241

    
10242
        if (insn & (1 << 11)) {
10243
            /* load */
10244
            tmp = tcg_temp_new_i32();
10245
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
10246
            store_reg(s, rd, tmp);
10247
        } else {
10248
            /* store */
10249
            tmp = load_reg(s, rd);
10250
            gen_aa32_st32(tmp, addr, IS_USER(s));
10251
            tcg_temp_free_i32(tmp);
10252
        }
10253
        tcg_temp_free_i32(addr);
10254
        break;
10255

    
10256
    case 10:
10257
        /* add to high reg */
10258
        rd = (insn >> 8) & 7;
10259
        if (insn & (1 << 11)) {
10260
            /* SP */
10261
            tmp = load_reg(s, 13);
10262
        } else {
10263
            /* PC. bit 1 is ignored.  */
10264
            tmp = tcg_temp_new_i32();
10265
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10266
        }
10267
        val = (insn & 0xff) * 4;
10268
        tcg_gen_addi_i32(tmp, tmp, val);
10269
        store_reg(s, rd, tmp);
10270
        break;
10271

    
10272
    case 11:
10273
        /* misc */
10274
        op = (insn >> 8) & 0xf;
10275
        switch (op) {
10276
        case 0:
10277
            /* adjust stack pointer */
10278
            tmp = load_reg(s, 13);
10279
            val = (insn & 0x7f) * 4;
10280
            if (insn & (1 << 7))
10281
                val = -(int32_t)val;
10282
            tcg_gen_addi_i32(tmp, tmp, val);
10283
            store_reg(s, 13, tmp);
10284
            break;
10285

    
10286
        case 2: /* sign/zero extend.  */
10287
            ARCH(6);
10288
            rd = insn & 7;
10289
            rm = (insn >> 3) & 7;
10290
            tmp = load_reg(s, rm);
10291
            switch ((insn >> 6) & 3) {
10292
            case 0: gen_sxth(tmp); break;
10293
            case 1: gen_sxtb(tmp); break;
10294
            case 2: gen_uxth(tmp); break;
10295
            case 3: gen_uxtb(tmp); break;
10296
            }
10297
            store_reg(s, rd, tmp);
10298
            break;
10299
        case 4: case 5: case 0xc: case 0xd:
10300
            /* push/pop */
10301
            addr = load_reg(s, 13);
10302
            if (insn & (1 << 8))
10303
                offset = 4;
10304
            else
10305
                offset = 0;
10306
            for (i = 0; i < 8; i++) {
10307
                if (insn & (1 << i))
10308
                    offset += 4;
10309
            }
10310
            if ((insn & (1 << 11)) == 0) {
10311
                tcg_gen_addi_i32(addr, addr, -offset);
10312
            }
10313
            for (i = 0; i < 8; i++) {
10314
                if (insn & (1 << i)) {
10315
                    if (insn & (1 << 11)) {
10316
                        /* pop */
10317
                        tmp = tcg_temp_new_i32();
10318
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
10319
                        store_reg(s, i, tmp);
10320
                    } else {
10321
                        /* push */
10322
                        tmp = load_reg(s, i);
10323
                        gen_aa32_st32(tmp, addr, IS_USER(s));
10324
                        tcg_temp_free_i32(tmp);
10325
                    }
10326
                    /* advance to the next address.  */
10327
                    tcg_gen_addi_i32(addr, addr, 4);
10328
                }
10329
            }
10330
            TCGV_UNUSED_I32(tmp);
10331
            if (insn & (1 << 8)) {
10332
                if (insn & (1 << 11)) {
10333
                    /* pop pc */
10334
                    tmp = tcg_temp_new_i32();
10335
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
10336
                    /* don't set the pc until the rest of the instruction
10337
                       has completed */
10338
                } else {
10339
                    /* push lr */
10340
                    tmp = load_reg(s, 14);
10341
                    gen_aa32_st32(tmp, addr, IS_USER(s));
10342
                    tcg_temp_free_i32(tmp);
10343
                }
10344
                tcg_gen_addi_i32(addr, addr, 4);
10345
            }
10346
            if ((insn & (1 << 11)) == 0) {
10347
                tcg_gen_addi_i32(addr, addr, -offset);
10348
            }
10349
            /* write back the new stack pointer */
10350
            store_reg(s, 13, addr);
10351
            /* set the new PC value */
10352
            if ((insn & 0x0900) == 0x0900) {
10353
                store_reg_from_load(env, s, 15, tmp);
10354
            }
10355
            break;
10356

    
10357
        case 1: case 3: case 9: case 11: /* czb */
10358
            rm = insn & 7;
10359
            tmp = load_reg(s, rm);
10360
            s->condlabel = gen_new_label();
10361
            s->condjmp = 1;
10362
            if (insn & (1 << 11))
10363
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10364
            else
10365
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10366
            tcg_temp_free_i32(tmp);
10367
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10368
            val = (uint32_t)s->pc + 2;
10369
            val += offset;
10370
            gen_jmp(s, val);
10371
            break;
10372

    
10373
        case 15: /* IT, nop-hint.  */
10374
            if ((insn & 0xf) == 0) {
10375
                gen_nop_hint(s, (insn >> 4) & 0xf);
10376
                break;
10377
            }
10378
            /* If Then.  */
10379
            s->condexec_cond = (insn >> 4) & 0xe;
10380
            s->condexec_mask = insn & 0x1f;
10381
            /* No actual code generated for this insn, just setup state.  */
10382
            break;
10383

    
10384
        case 0xe: /* bkpt */
10385
            ARCH(5);
10386
            gen_exception_insn(s, 2, EXCP_BKPT);
10387
            break;
10388

    
10389
        case 0xa: /* rev */
10390
            ARCH(6);
10391
            rn = (insn >> 3) & 0x7;
10392
            rd = insn & 0x7;
10393
            tmp = load_reg(s, rn);
10394
            switch ((insn >> 6) & 3) {
10395
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10396
            case 1: gen_rev16(tmp); break;
10397
            case 3: gen_revsh(tmp); break;
10398
            default: goto illegal_op;
10399
            }
10400
            store_reg(s, rd, tmp);
10401
            break;
10402

    
10403
        case 6:
10404
            switch ((insn >> 5) & 7) {
10405
            case 2:
10406
                /* setend */
10407
                ARCH(6);
10408
                if (((insn >> 3) & 1) != s->bswap_code) {
10409
                    /* Dynamic endianness switching not implemented. */
10410
                    qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10411
                    goto illegal_op;
10412
                }
10413
                break;
10414
            case 3:
10415
                /* cps */
10416
                ARCH(6);
10417
                if (IS_USER(s)) {
10418
                    break;
10419
                }
10420
                if (IS_M(env)) {
10421
                    tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10422
                    /* FAULTMASK */
10423
                    if (insn & 1) {
10424
                        addr = tcg_const_i32(19);
10425
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
10426
                        tcg_temp_free_i32(addr);
10427
                    }
10428
                    /* PRIMASK */
10429
                    if (insn & 2) {
10430
                        addr = tcg_const_i32(16);
10431
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
10432
                        tcg_temp_free_i32(addr);
10433
                    }
10434
                    tcg_temp_free_i32(tmp);
10435
                    gen_lookup_tb(s);
10436
                } else {
10437
                    if (insn & (1 << 4)) {
10438
                        shift = CPSR_A | CPSR_I | CPSR_F;
10439
                    } else {
10440
                        shift = 0;
10441
                    }
10442
                    gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10443
                }
10444
                break;
10445
            default:
10446
                goto undef;
10447
            }
10448
            break;
10449

    
10450
        default:
10451
            goto undef;
10452
        }
10453
        break;
10454

    
10455
    case 12:
10456
    {
10457
        /* load/store multiple */
10458
        TCGv_i32 loaded_var;
10459
        TCGV_UNUSED_I32(loaded_var);
10460
        rn = (insn >> 8) & 0x7;
10461
        addr = load_reg(s, rn);
10462
        for (i = 0; i < 8; i++) {
10463
            if (insn & (1 << i)) {
10464
                if (insn & (1 << 11)) {
10465
                    /* load */
10466
                    tmp = tcg_temp_new_i32();
10467
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
10468
                    if (i == rn) {
10469
                        loaded_var = tmp;
10470
                    } else {
10471
                        store_reg(s, i, tmp);
10472
                    }
10473
                } else {
10474
                    /* store */
10475
                    tmp = load_reg(s, i);
10476
                    gen_aa32_st32(tmp, addr, IS_USER(s));
10477
                    tcg_temp_free_i32(tmp);
10478
                }
10479
                /* advance to the next address */
10480
                tcg_gen_addi_i32(addr, addr, 4);
10481
            }
10482
        }
10483
        if ((insn & (1 << rn)) == 0) {
10484
            /* base reg not in list: base register writeback */
10485
            store_reg(s, rn, addr);
10486
        } else {
10487
            /* base reg in list: if load, complete it now */
10488
            if (insn & (1 << 11)) {
10489
                store_reg(s, rn, loaded_var);
10490
            }
10491
            tcg_temp_free_i32(addr);
10492
        }
10493
        break;
10494
    }
10495
    case 13:
10496
        /* conditional branch or swi */
10497
        cond = (insn >> 8) & 0xf;
10498
        if (cond == 0xe)
10499
            goto undef;
10500

    
10501
        if (cond == 0xf) {
10502
            /* swi */
10503
            gen_set_pc_im(s, s->pc);
10504
            s->is_jmp = DISAS_SWI;
10505
            break;
10506
        }
10507
        /* generate a conditional jump to next instruction */
10508
        s->condlabel = gen_new_label();
10509
        arm_gen_test_cc(cond ^ 1, s->condlabel);
10510
        s->condjmp = 1;
10511

    
10512
        /* jump to the offset */
10513
        val = (uint32_t)s->pc + 2;
10514
        offset = ((int32_t)insn << 24) >> 24;
10515
        val += offset << 1;
10516
        gen_jmp(s, val);
10517
        break;
10518

    
10519
    case 14:
10520
        if (insn & (1 << 11)) {
10521
            if (disas_thumb2_insn(env, s, insn))
10522
              goto undef32;
10523
            break;
10524
        }
10525
        /* unconditional branch */
10526
        val = (uint32_t)s->pc;
10527
        offset = ((int32_t)insn << 21) >> 21;
10528
        val += (offset << 1) + 2;
10529
        gen_jmp(s, val);
10530
        break;
10531

    
10532
    case 15:
10533
        if (disas_thumb2_insn(env, s, insn))
10534
            goto undef32;
10535
        break;
10536
    }
10537
    return;
10538
undef32:
10539
    gen_exception_insn(s, 4, EXCP_UDEF);
10540
    return;
10541
illegal_op:
10542
undef:
10543
    gen_exception_insn(s, 2, EXCP_UDEF);
10544
}
10545

    
10546
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10547
   basic block 'tb'. If search_pc is TRUE, also generate PC
10548
   information for each intermediate instruction. */
10549
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10550
                                                  TranslationBlock *tb,
10551
                                                  bool search_pc)
10552
{
10553
    CPUState *cs = CPU(cpu);
10554
    CPUARMState *env = &cpu->env;
10555
    DisasContext dc1, *dc = &dc1;
10556
    CPUBreakpoint *bp;
10557
    uint16_t *gen_opc_end;
10558
    int j, lj;
10559
    target_ulong pc_start;
10560
    target_ulong next_page_start;
10561
    int num_insns;
10562
    int max_insns;
10563

    
10564
    /* generate intermediate code */
10565

    
10566
    /* The A64 decoder has its own top level loop, because it doesn't need
10567
     * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10568
     */
10569
    if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10570
        gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10571
        return;
10572
    }
10573

    
10574
    pc_start = tb->pc;
10575

    
10576
    dc->tb = tb;
10577

    
10578
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10579

    
10580
    dc->is_jmp = DISAS_NEXT;
10581
    dc->pc = pc_start;
10582
    dc->singlestep_enabled = cs->singlestep_enabled;
10583
    dc->condjmp = 0;
10584

    
10585
    dc->aarch64 = 0;
10586
    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10587
    dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10588
    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10589
    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10590
#if !defined(CONFIG_USER_ONLY)
10591
    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10592
#endif
10593
    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10594
    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10595
    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10596
    dc->cp_regs = cpu->cp_regs;
10597
    dc->current_pl = arm_current_pl(env);
10598

    
10599
    cpu_F0s = tcg_temp_new_i32();
10600
    cpu_F1s = tcg_temp_new_i32();
10601
    cpu_F0d = tcg_temp_new_i64();
10602
    cpu_F1d = tcg_temp_new_i64();
10603
    cpu_V0 = cpu_F0d;
10604
    cpu_V1 = cpu_F1d;
10605
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
10606
    cpu_M0 = tcg_temp_new_i64();
10607
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10608
    lj = -1;
10609
    num_insns = 0;
10610
    max_insns = tb->cflags & CF_COUNT_MASK;
10611
    if (max_insns == 0)
10612
        max_insns = CF_COUNT_MASK;
10613

    
10614
    gen_tb_start();
10615

    
10616
    tcg_clear_temp_count();
10617

    
10618
    /* A note on handling of the condexec (IT) bits:
10619
     *
10620
     * We want to avoid the overhead of having to write the updated condexec
10621
     * bits back to the CPUARMState for every instruction in an IT block. So:
10622
     * (1) if the condexec bits are not already zero then we write
10623
     * zero back into the CPUARMState now. This avoids complications trying
10624
     * to do it at the end of the block. (For example if we don't do this
10625
     * it's hard to identify whether we can safely skip writing condexec
10626
     * at the end of the TB, which we definitely want to do for the case
10627
     * where a TB doesn't do anything with the IT state at all.)
10628
     * (2) if we are going to leave the TB then we call gen_set_condexec()
10629
     * which will write the correct value into CPUARMState if zero is wrong.
10630
     * This is done both for leaving the TB at the end, and for leaving
10631
     * it because of an exception we know will happen, which is done in
10632
     * gen_exception_insn(). The latter is necessary because we need to
10633
     * leave the TB with the PC/IT state just prior to execution of the
10634
     * instruction which caused the exception.
10635
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10636
     * then the CPUARMState will be wrong and we need to reset it.
10637
     * This is handled in the same way as restoration of the
10638
     * PC in these situations: we will be called again with search_pc=1
10639
     * and generate a mapping of the condexec bits for each PC in
10640
     * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10641
     * this to restore the condexec bits.
10642
     *
10643
     * Note that there are no instructions which can read the condexec
10644
     * bits, and none which can write non-static values to them, so
10645
     * we don't need to care about whether CPUARMState is correct in the
10646
     * middle of a TB.
10647
     */
10648

    
10649
    /* Reset the conditional execution bits immediately. This avoids
10650
       complications trying to do it at the end of the block.  */
10651
    if (dc->condexec_mask || dc->condexec_cond)
10652
      {
10653
        TCGv_i32 tmp = tcg_temp_new_i32();
10654
        tcg_gen_movi_i32(tmp, 0);
10655
        store_cpu_field(tmp, condexec_bits);
10656
      }
10657
    do {
10658
#ifdef CONFIG_USER_ONLY
10659
        /* Intercept jump to the magic kernel page.  */
10660
        if (dc->pc >= 0xffff0000) {
10661
            /* We always get here via a jump, so know we are not in a
10662
               conditional execution block.  */
10663
            gen_exception(EXCP_KERNEL_TRAP);
10664
            dc->is_jmp = DISAS_UPDATE;
10665
            break;
10666
        }
10667
#else
10668
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10669
            /* We always get here via a jump, so know we are not in a
10670
               conditional execution block.  */
10671
            gen_exception(EXCP_EXCEPTION_EXIT);
10672
            dc->is_jmp = DISAS_UPDATE;
10673
            break;
10674
        }
10675
#endif
10676

    
10677
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10678
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10679
                if (bp->pc == dc->pc) {
10680
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
10681
                    /* Advance PC so that clearing the breakpoint will
10682
                       invalidate this TB.  */
10683
                    dc->pc += 2;
10684
                    goto done_generating;
10685
                }
10686
            }
10687
        }
10688
        if (search_pc) {
10689
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10690
            if (lj < j) {
10691
                lj++;
10692
                while (lj < j)
10693
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
10694
            }
10695
            tcg_ctx.gen_opc_pc[lj] = dc->pc;
10696
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10697
            tcg_ctx.gen_opc_instr_start[lj] = 1;
10698
            tcg_ctx.gen_opc_icount[lj] = num_insns;
10699
        }
10700

    
10701
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10702
            gen_io_start();
10703

    
10704
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10705
            tcg_gen_debug_insn_start(dc->pc);
10706
        }
10707

    
10708
        if (dc->thumb) {
10709
            disas_thumb_insn(env, dc);
10710
            if (dc->condexec_mask) {
10711
                dc->condexec_cond = (dc->condexec_cond & 0xe)
10712
                                   | ((dc->condexec_mask >> 4) & 1);
10713
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10714
                if (dc->condexec_mask == 0) {
10715
                    dc->condexec_cond = 0;
10716
                }
10717
            }
10718
        } else {
10719
            disas_arm_insn(env, dc);
10720
        }
10721

    
10722
        if (dc->condjmp && !dc->is_jmp) {
10723
            gen_set_label(dc->condlabel);
10724
            dc->condjmp = 0;
10725
        }
10726

    
10727
        if (tcg_check_temp_count()) {
10728
            fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10729
                    dc->pc);
10730
        }
10731

    
10732
        /* Translation stops when a conditional branch is encountered.
10733
         * Otherwise the subsequent code could get translated several times.
10734
         * Also stop translation when a page boundary is reached.  This
10735
         * ensures prefetch aborts occur at the right place.  */
10736
        num_insns ++;
10737
    } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10738
             !cs->singlestep_enabled &&
10739
             !singlestep &&
10740
             dc->pc < next_page_start &&
10741
             num_insns < max_insns);
10742

    
10743
    if (tb->cflags & CF_LAST_IO) {
10744
        if (dc->condjmp) {
10745
            /* FIXME:  This can theoretically happen with self-modifying
10746
               code.  */
10747
            cpu_abort(env, "IO on conditional branch instruction");
10748
        }
10749
        gen_io_end();
10750
    }
10751

    
10752
    /* At this stage dc->condjmp will only be set when the skipped
10753
       instruction was a conditional branch or trap, and the PC has
10754
       already been written.  */
10755
    if (unlikely(cs->singlestep_enabled)) {
10756
        /* Make sure the pc is updated, and raise a debug exception.  */
10757
        if (dc->condjmp) {
10758
            gen_set_condexec(dc);
10759
            if (dc->is_jmp == DISAS_SWI) {
10760
                gen_exception(EXCP_SWI);
10761
            } else {
10762
                gen_exception(EXCP_DEBUG);
10763
            }
10764
            gen_set_label(dc->condlabel);
10765
        }
10766
        if (dc->condjmp || !dc->is_jmp) {
10767
            gen_set_pc_im(dc, dc->pc);
10768
            dc->condjmp = 0;
10769
        }
10770
        gen_set_condexec(dc);
10771
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10772
            gen_exception(EXCP_SWI);
10773
        } else {
10774
            /* FIXME: Single stepping a WFI insn will not halt
10775
               the CPU.  */
10776
            gen_exception(EXCP_DEBUG);
10777
        }
10778
    } else {
10779
        /* While branches must always occur at the end of an IT block,
10780
           there are a few other things that can cause us to terminate
10781
           the TB in the middle of an IT block:
10782
            - Exception generating instructions (bkpt, swi, undefined).
10783
            - Page boundaries.
10784
            - Hardware watchpoints.
10785
           Hardware breakpoints have already been handled and skip this code.
10786
         */
10787
        gen_set_condexec(dc);
10788
        switch(dc->is_jmp) {
10789
        case DISAS_NEXT:
10790
            gen_goto_tb(dc, 1, dc->pc);
10791
            break;
10792
        default:
10793
        case DISAS_JUMP:
10794
        case DISAS_UPDATE:
10795
            /* indicate that the hash table must be used to find the next TB */
10796
            tcg_gen_exit_tb(0);
10797
            break;
10798
        case DISAS_TB_JUMP:
10799
            /* nothing more to generate */
10800
            break;
10801
        case DISAS_WFI:
10802
            gen_helper_wfi(cpu_env);
10803
            break;
10804
        case DISAS_SWI:
10805
            gen_exception(EXCP_SWI);
10806
            break;
10807
        }
10808
        if (dc->condjmp) {
10809
            gen_set_label(dc->condlabel);
10810
            gen_set_condexec(dc);
10811
            gen_goto_tb(dc, 1, dc->pc);
10812
            dc->condjmp = 0;
10813
        }
10814
    }
10815

    
10816
done_generating:
10817
    gen_tb_end(tb, num_insns);
10818
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10819

    
10820
#ifdef DEBUG_DISAS
10821
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10822
        qemu_log("----------------\n");
10823
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
10824
        log_target_disas(env, pc_start, dc->pc - pc_start,
10825
                         dc->thumb | (dc->bswap_code << 1));
10826
        qemu_log("\n");
10827
    }
10828
#endif
10829
    if (search_pc) {
10830
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10831
        lj++;
10832
        while (lj <= j)
10833
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
10834
    } else {
10835
        tb->size = dc->pc - pc_start;
10836
        tb->icount = num_insns;
10837
    }
10838
}
10839

    
10840
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10841
{
10842
    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10843
}
10844

    
10845
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10846
{
10847
    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10848
}
10849

    
10850
static const char *cpu_mode_names[16] = {
10851
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10852
  "???", "???", "???", "und", "???", "???", "???", "sys"
10853
};
10854

    
10855
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10856
                        int flags)
10857
{
10858
    ARMCPU *cpu = ARM_CPU(cs);
10859
    CPUARMState *env = &cpu->env;
10860
    int i;
10861
    uint32_t psr;
10862

    
10863
    for(i=0;i<16;i++) {
10864
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10865
        if ((i % 4) == 3)
10866
            cpu_fprintf(f, "\n");
10867
        else
10868
            cpu_fprintf(f, " ");
10869
    }
10870
    psr = cpsr_read(env);
10871
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10872
                psr,
10873
                psr & (1 << 31) ? 'N' : '-',
10874
                psr & (1 << 30) ? 'Z' : '-',
10875
                psr & (1 << 29) ? 'C' : '-',
10876
                psr & (1 << 28) ? 'V' : '-',
10877
                psr & CPSR_T ? 'T' : 'A',
10878
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10879

    
10880
    if (flags & CPU_DUMP_FPU) {
10881
        int numvfpregs = 0;
10882
        if (arm_feature(env, ARM_FEATURE_VFP)) {
10883
            numvfpregs += 16;
10884
        }
10885
        if (arm_feature(env, ARM_FEATURE_VFP3)) {
10886
            numvfpregs += 16;
10887
        }
10888
        for (i = 0; i < numvfpregs; i++) {
10889
            uint64_t v = float64_val(env->vfp.regs[i]);
10890
            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10891
                        i * 2, (uint32_t)v,
10892
                        i * 2 + 1, (uint32_t)(v >> 32),
10893
                        i, v);
10894
        }
10895
        cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10896
    }
10897
}
10898

    
10899
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10900
{
10901
    if (is_a64(env)) {
10902
        env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10903
        env->condexec_bits = 0;
10904
    } else {
10905
        env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10906
        env->condexec_bits = gen_opc_condexec_bits[pc_pos];
10907
    }
10908
}