~ubuntu-branches/ubuntu/utopic/qemu/utopic

« back to all changes in this revision

Viewing changes to .pc/arm64/0014-target-arm-Implement-ARMv8-FP-VMAXNM-and-VMINNM-inst.patch/target-arm/translate.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn, Serge Hallyn, dann frazier
  • Date: 2014-01-10 12:19:08 UTC
  • Revision ID: package-import@ubuntu.com-20140110121908-6lsn06rypqbokbaf
Tags: 1.7.0+dfsg-2ubuntu6
[ Serge Hallyn ]
* add arm64 patchset from upstream.  The three arm virt patches previously
  pushed are in that set, so drop them.

[ dann frazier ]
* Add packaging for qemu-system-aarch64. This package is currently only
  available for arm64, as full software emulation is not yet supported.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  ARM translation
 
3
 *
 
4
 *  Copyright (c) 2003 Fabrice Bellard
 
5
 *  Copyright (c) 2005-2007 CodeSourcery
 
6
 *  Copyright (c) 2007 OpenedHand, Ltd.
 
7
 *
 
8
 * This library is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU Lesser General Public
 
10
 * License as published by the Free Software Foundation; either
 
11
 * version 2 of the License, or (at your option) any later version.
 
12
 *
 
13
 * This library is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * Lesser General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU Lesser General Public
 
19
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 
20
 */
 
21
#include <stdarg.h>
 
22
#include <stdlib.h>
 
23
#include <stdio.h>
 
24
#include <string.h>
 
25
#include <inttypes.h>
 
26
 
 
27
#include "cpu.h"
 
28
#include "disas/disas.h"
 
29
#include "tcg-op.h"
 
30
#include "qemu/log.h"
 
31
#include "qemu/bitops.h"
 
32
 
 
33
#include "helper.h"
 
34
#define GEN_HELPER 1
 
35
#include "helper.h"
 
36
 
 
37
#define ENABLE_ARCH_4T    arm_feature(env, ARM_FEATURE_V4T)
 
38
#define ENABLE_ARCH_5     arm_feature(env, ARM_FEATURE_V5)
 
39
/* currently all emulated v5 cores are also v5TE, so don't bother */
 
40
#define ENABLE_ARCH_5TE   arm_feature(env, ARM_FEATURE_V5)
 
41
#define ENABLE_ARCH_5J    0
 
42
#define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
 
43
#define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
 
44
#define ENABLE_ARCH_6T2   arm_feature(env, ARM_FEATURE_THUMB2)
 
45
#define ENABLE_ARCH_7     arm_feature(env, ARM_FEATURE_V7)
 
46
#define ENABLE_ARCH_8     arm_feature(env, ARM_FEATURE_V8)
 
47
 
 
48
#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
 
49
 
 
50
#include "translate.h"
 
51
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
 
52
 
 
53
#if defined(CONFIG_USER_ONLY)
 
54
#define IS_USER(s) 1
 
55
#else
 
56
#define IS_USER(s) (s->user)
 
57
#endif
 
58
 
 
59
/* These instructions trap after executing, so defer them until after the
 
60
   conditional execution state has been updated.  */
 
61
#define DISAS_WFI 4
 
62
#define DISAS_SWI 5
 
63
#define DISAS_SMC 6
 
64
 
 
65
TCGv_ptr cpu_env;
 
66
/* We reuse the same 64-bit temporaries for efficiency.  */
 
67
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
 
68
static TCGv_i32 cpu_R[16];
 
69
static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
 
70
static TCGv_i32 cpu_exclusive_addr;
 
71
static TCGv_i32 cpu_exclusive_val;
 
72
static TCGv_i32 cpu_exclusive_high;
 
73
#ifdef CONFIG_USER_ONLY
 
74
static TCGv_i32 cpu_exclusive_test;
 
75
static TCGv_i32 cpu_exclusive_info;
 
76
#endif
 
77
 
 
78
/* FIXME:  These should be removed.  */
 
79
static TCGv_i32 cpu_F0s, cpu_F1s;
 
80
static TCGv_i64 cpu_F0d, cpu_F1d;
 
81
 
 
82
#include "exec/gen-icount.h"
 
83
 
 
84
static const char *regnames[] =
 
85
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
 
86
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
 
87
 
 
88
/* initialize TCG globals.  */
 
89
void arm_translate_init(void)
 
90
{
 
91
    int i;
 
92
 
 
93
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 
94
 
 
95
    for (i = 0; i < 16; i++) {
 
96
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
 
97
                                          offsetof(CPUARMState, regs[i]),
 
98
                                          regnames[i]);
 
99
    }
 
100
    cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
 
101
    cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
 
102
    cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
 
103
    cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
 
104
 
 
105
    cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
 
106
        offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
 
107
    cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
 
108
        offsetof(CPUARMState, exclusive_val), "exclusive_val");
 
109
    cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
 
110
        offsetof(CPUARMState, exclusive_high), "exclusive_high");
 
111
#ifdef CONFIG_USER_ONLY
 
112
    cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
 
113
        offsetof(CPUARMState, exclusive_test), "exclusive_test");
 
114
    cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
 
115
        offsetof(CPUARMState, exclusive_info), "exclusive_info");
 
116
#endif
 
117
 
 
118
    a64_translate_init();
 
119
}
 
120
 
 
121
static inline TCGv_i32 load_cpu_offset(int offset)
 
122
{
 
123
    TCGv_i32 tmp = tcg_temp_new_i32();
 
124
    tcg_gen_ld_i32(tmp, cpu_env, offset);
 
125
    return tmp;
 
126
}
 
127
 
 
128
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
 
129
 
 
130
static inline void store_cpu_offset(TCGv_i32 var, int offset)
 
131
{
 
132
    tcg_gen_st_i32(var, cpu_env, offset);
 
133
    tcg_temp_free_i32(var);
 
134
}
 
135
 
 
136
#define store_cpu_field(var, name) \
 
137
    store_cpu_offset(var, offsetof(CPUARMState, name))
 
138
 
 
139
/* Set a variable to the value of a CPU register.  */
 
140
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
 
141
{
 
142
    if (reg == 15) {
 
143
        uint32_t addr;
 
144
        /* normally, since we updated PC, we need only to add one insn */
 
145
        if (s->thumb)
 
146
            addr = (long)s->pc + 2;
 
147
        else
 
148
            addr = (long)s->pc + 4;
 
149
        tcg_gen_movi_i32(var, addr);
 
150
    } else {
 
151
        tcg_gen_mov_i32(var, cpu_R[reg]);
 
152
    }
 
153
}
 
154
 
 
155
/* Create a new temporary and set it to the value of a CPU register.  */
 
156
static inline TCGv_i32 load_reg(DisasContext *s, int reg)
 
157
{
 
158
    TCGv_i32 tmp = tcg_temp_new_i32();
 
159
    load_reg_var(s, tmp, reg);
 
160
    return tmp;
 
161
}
 
162
 
 
163
/* Set a CPU register.  The source must be a temporary and will be
 
164
   marked as dead.  */
 
165
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
 
166
{
 
167
    if (reg == 15) {
 
168
        tcg_gen_andi_i32(var, var, ~1);
 
169
        s->is_jmp = DISAS_JUMP;
 
170
    }
 
171
    tcg_gen_mov_i32(cpu_R[reg], var);
 
172
    tcg_temp_free_i32(var);
 
173
}
 
174
 
 
175
/* Value extensions.  */
 
176
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
 
177
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
 
178
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
 
179
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
 
180
 
 
181
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
 
182
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
 
183
 
 
184
 
 
185
static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
 
186
{
 
187
    TCGv_i32 tmp_mask = tcg_const_i32(mask);
 
188
    gen_helper_cpsr_write(cpu_env, var, tmp_mask);
 
189
    tcg_temp_free_i32(tmp_mask);
 
190
}
 
191
/* Set NZCV flags from the high 4 bits of var.  */
 
192
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
 
193
 
 
194
static void gen_exception(int excp)
 
195
{
 
196
    TCGv_i32 tmp = tcg_temp_new_i32();
 
197
    tcg_gen_movi_i32(tmp, excp);
 
198
    gen_helper_exception(cpu_env, tmp);
 
199
    tcg_temp_free_i32(tmp);
 
200
}
 
201
 
 
202
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
 
203
{
 
204
    TCGv_i32 tmp1 = tcg_temp_new_i32();
 
205
    TCGv_i32 tmp2 = tcg_temp_new_i32();
 
206
    tcg_gen_ext16s_i32(tmp1, a);
 
207
    tcg_gen_ext16s_i32(tmp2, b);
 
208
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
 
209
    tcg_temp_free_i32(tmp2);
 
210
    tcg_gen_sari_i32(a, a, 16);
 
211
    tcg_gen_sari_i32(b, b, 16);
 
212
    tcg_gen_mul_i32(b, b, a);
 
213
    tcg_gen_mov_i32(a, tmp1);
 
214
    tcg_temp_free_i32(tmp1);
 
215
}
 
216
 
 
217
/* Byteswap each halfword.  */
 
218
static void gen_rev16(TCGv_i32 var)
 
219
{
 
220
    TCGv_i32 tmp = tcg_temp_new_i32();
 
221
    tcg_gen_shri_i32(tmp, var, 8);
 
222
    tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
 
223
    tcg_gen_shli_i32(var, var, 8);
 
224
    tcg_gen_andi_i32(var, var, 0xff00ff00);
 
225
    tcg_gen_or_i32(var, var, tmp);
 
226
    tcg_temp_free_i32(tmp);
 
227
}
 
228
 
 
229
/* Byteswap low halfword and sign extend.  */
 
230
static void gen_revsh(TCGv_i32 var)
 
231
{
 
232
    tcg_gen_ext16u_i32(var, var);
 
233
    tcg_gen_bswap16_i32(var, var);
 
234
    tcg_gen_ext16s_i32(var, var);
 
235
}
 
236
 
 
237
/* Unsigned bitfield extract.  */
 
238
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
 
239
{
 
240
    if (shift)
 
241
        tcg_gen_shri_i32(var, var, shift);
 
242
    tcg_gen_andi_i32(var, var, mask);
 
243
}
 
244
 
 
245
/* Signed bitfield extract.  */
 
246
static void gen_sbfx(TCGv_i32 var, int shift, int width)
 
247
{
 
248
    uint32_t signbit;
 
249
 
 
250
    if (shift)
 
251
        tcg_gen_sari_i32(var, var, shift);
 
252
    if (shift + width < 32) {
 
253
        signbit = 1u << (width - 1);
 
254
        tcg_gen_andi_i32(var, var, (1u << width) - 1);
 
255
        tcg_gen_xori_i32(var, var, signbit);
 
256
        tcg_gen_subi_i32(var, var, signbit);
 
257
    }
 
258
}
 
259
 
 
260
/* Return (b << 32) + a. Mark inputs as dead */
 
261
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
 
262
{
 
263
    TCGv_i64 tmp64 = tcg_temp_new_i64();
 
264
 
 
265
    tcg_gen_extu_i32_i64(tmp64, b);
 
266
    tcg_temp_free_i32(b);
 
267
    tcg_gen_shli_i64(tmp64, tmp64, 32);
 
268
    tcg_gen_add_i64(a, tmp64, a);
 
269
 
 
270
    tcg_temp_free_i64(tmp64);
 
271
    return a;
 
272
}
 
273
 
 
274
/* Return (b << 32) - a. Mark inputs as dead. */
 
275
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
 
276
{
 
277
    TCGv_i64 tmp64 = tcg_temp_new_i64();
 
278
 
 
279
    tcg_gen_extu_i32_i64(tmp64, b);
 
280
    tcg_temp_free_i32(b);
 
281
    tcg_gen_shli_i64(tmp64, tmp64, 32);
 
282
    tcg_gen_sub_i64(a, tmp64, a);
 
283
 
 
284
    tcg_temp_free_i64(tmp64);
 
285
    return a;
 
286
}
 
287
 
 
288
/* 32x32->64 multiply.  Marks inputs as dead.  */
 
289
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
 
290
{
 
291
    TCGv_i32 lo = tcg_temp_new_i32();
 
292
    TCGv_i32 hi = tcg_temp_new_i32();
 
293
    TCGv_i64 ret;
 
294
 
 
295
    tcg_gen_mulu2_i32(lo, hi, a, b);
 
296
    tcg_temp_free_i32(a);
 
297
    tcg_temp_free_i32(b);
 
298
 
 
299
    ret = tcg_temp_new_i64();
 
300
    tcg_gen_concat_i32_i64(ret, lo, hi);
 
301
    tcg_temp_free_i32(lo);
 
302
    tcg_temp_free_i32(hi);
 
303
 
 
304
    return ret;
 
305
}
 
306
 
 
307
static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
 
308
{
 
309
    TCGv_i32 lo = tcg_temp_new_i32();
 
310
    TCGv_i32 hi = tcg_temp_new_i32();
 
311
    TCGv_i64 ret;
 
312
 
 
313
    tcg_gen_muls2_i32(lo, hi, a, b);
 
314
    tcg_temp_free_i32(a);
 
315
    tcg_temp_free_i32(b);
 
316
 
 
317
    ret = tcg_temp_new_i64();
 
318
    tcg_gen_concat_i32_i64(ret, lo, hi);
 
319
    tcg_temp_free_i32(lo);
 
320
    tcg_temp_free_i32(hi);
 
321
 
 
322
    return ret;
 
323
}
 
324
 
 
325
/* Swap low and high halfwords.  */
 
326
static void gen_swap_half(TCGv_i32 var)
 
327
{
 
328
    TCGv_i32 tmp = tcg_temp_new_i32();
 
329
    tcg_gen_shri_i32(tmp, var, 16);
 
330
    tcg_gen_shli_i32(var, var, 16);
 
331
    tcg_gen_or_i32(var, var, tmp);
 
332
    tcg_temp_free_i32(tmp);
 
333
}
 
334
 
 
335
/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
 
336
    tmp = (t0 ^ t1) & 0x8000;
 
337
    t0 &= ~0x8000;
 
338
    t1 &= ~0x8000;
 
339
    t0 = (t0 + t1) ^ tmp;
 
340
 */
 
341
 
 
342
static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
 
343
{
 
344
    TCGv_i32 tmp = tcg_temp_new_i32();
 
345
    tcg_gen_xor_i32(tmp, t0, t1);
 
346
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
 
347
    tcg_gen_andi_i32(t0, t0, ~0x8000);
 
348
    tcg_gen_andi_i32(t1, t1, ~0x8000);
 
349
    tcg_gen_add_i32(t0, t0, t1);
 
350
    tcg_gen_xor_i32(t0, t0, tmp);
 
351
    tcg_temp_free_i32(tmp);
 
352
    tcg_temp_free_i32(t1);
 
353
}
 
354
 
 
355
/* Set CF to the top bit of var.  */
 
356
static void gen_set_CF_bit31(TCGv_i32 var)
 
357
{
 
358
    tcg_gen_shri_i32(cpu_CF, var, 31);
 
359
}
 
360
 
 
361
/* Set N and Z flags from var.  */
 
362
static inline void gen_logic_CC(TCGv_i32 var)
 
363
{
 
364
    tcg_gen_mov_i32(cpu_NF, var);
 
365
    tcg_gen_mov_i32(cpu_ZF, var);
 
366
}
 
367
 
 
368
/* T0 += T1 + CF.  */
 
369
static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
 
370
{
 
371
    tcg_gen_add_i32(t0, t0, t1);
 
372
    tcg_gen_add_i32(t0, t0, cpu_CF);
 
373
}
 
374
 
 
375
/* dest = T0 + T1 + CF. */
 
376
static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 
377
{
 
378
    tcg_gen_add_i32(dest, t0, t1);
 
379
    tcg_gen_add_i32(dest, dest, cpu_CF);
 
380
}
 
381
 
 
382
/* dest = T0 - T1 + CF - 1.  */
 
383
static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 
384
{
 
385
    tcg_gen_sub_i32(dest, t0, t1);
 
386
    tcg_gen_add_i32(dest, dest, cpu_CF);
 
387
    tcg_gen_subi_i32(dest, dest, 1);
 
388
}
 
389
 
 
390
/* dest = T0 + T1. Compute C, N, V and Z flags */
 
391
static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 
392
{
 
393
    TCGv_i32 tmp = tcg_temp_new_i32();
 
394
    tcg_gen_movi_i32(tmp, 0);
 
395
    tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
 
396
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
 
397
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
 
398
    tcg_gen_xor_i32(tmp, t0, t1);
 
399
    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
 
400
    tcg_temp_free_i32(tmp);
 
401
    tcg_gen_mov_i32(dest, cpu_NF);
 
402
}
 
403
 
 
404
/* dest = T0 + T1 + CF.  Compute C, N, V and Z flags */
 
405
static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 
406
{
 
407
    TCGv_i32 tmp = tcg_temp_new_i32();
 
408
    if (TCG_TARGET_HAS_add2_i32) {
 
409
        tcg_gen_movi_i32(tmp, 0);
 
410
        tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
 
411
        tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
 
412
    } else {
 
413
        TCGv_i64 q0 = tcg_temp_new_i64();
 
414
        TCGv_i64 q1 = tcg_temp_new_i64();
 
415
        tcg_gen_extu_i32_i64(q0, t0);
 
416
        tcg_gen_extu_i32_i64(q1, t1);
 
417
        tcg_gen_add_i64(q0, q0, q1);
 
418
        tcg_gen_extu_i32_i64(q1, cpu_CF);
 
419
        tcg_gen_add_i64(q0, q0, q1);
 
420
        tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
 
421
        tcg_temp_free_i64(q0);
 
422
        tcg_temp_free_i64(q1);
 
423
    }
 
424
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
 
425
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
 
426
    tcg_gen_xor_i32(tmp, t0, t1);
 
427
    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
 
428
    tcg_temp_free_i32(tmp);
 
429
    tcg_gen_mov_i32(dest, cpu_NF);
 
430
}
 
431
 
 
432
/* dest = T0 - T1. Compute C, N, V and Z flags */
 
433
static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 
434
{
 
435
    TCGv_i32 tmp;
 
436
    tcg_gen_sub_i32(cpu_NF, t0, t1);
 
437
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
 
438
    tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
 
439
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
 
440
    tmp = tcg_temp_new_i32();
 
441
    tcg_gen_xor_i32(tmp, t0, t1);
 
442
    tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
 
443
    tcg_temp_free_i32(tmp);
 
444
    tcg_gen_mov_i32(dest, cpu_NF);
 
445
}
 
446
 
 
447
/* dest = T0 + ~T1 + CF.  Compute C, N, V and Z flags */
 
448
static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 
449
{
 
450
    TCGv_i32 tmp = tcg_temp_new_i32();
 
451
    tcg_gen_not_i32(tmp, t1);
 
452
    gen_adc_CC(dest, t0, tmp);
 
453
    tcg_temp_free_i32(tmp);
 
454
}
 
455
 
 
456
#define GEN_SHIFT(name)                                               \
 
457
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)       \
 
458
{                                                                     \
 
459
    TCGv_i32 tmp1, tmp2, tmp3;                                        \
 
460
    tmp1 = tcg_temp_new_i32();                                        \
 
461
    tcg_gen_andi_i32(tmp1, t1, 0xff);                                 \
 
462
    tmp2 = tcg_const_i32(0);                                          \
 
463
    tmp3 = tcg_const_i32(0x1f);                                       \
 
464
    tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0);    \
 
465
    tcg_temp_free_i32(tmp3);                                          \
 
466
    tcg_gen_andi_i32(tmp1, tmp1, 0x1f);                               \
 
467
    tcg_gen_##name##_i32(dest, tmp2, tmp1);                           \
 
468
    tcg_temp_free_i32(tmp2);                                          \
 
469
    tcg_temp_free_i32(tmp1);                                          \
 
470
}
 
471
GEN_SHIFT(shl)
 
472
GEN_SHIFT(shr)
 
473
#undef GEN_SHIFT
 
474
 
 
475
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 
476
{
 
477
    TCGv_i32 tmp1, tmp2;
 
478
    tmp1 = tcg_temp_new_i32();
 
479
    tcg_gen_andi_i32(tmp1, t1, 0xff);
 
480
    tmp2 = tcg_const_i32(0x1f);
 
481
    tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
 
482
    tcg_temp_free_i32(tmp2);
 
483
    tcg_gen_sar_i32(dest, t0, tmp1);
 
484
    tcg_temp_free_i32(tmp1);
 
485
}
 
486
 
 
487
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
 
488
{
 
489
    TCGv_i32 c0 = tcg_const_i32(0);
 
490
    TCGv_i32 tmp = tcg_temp_new_i32();
 
491
    tcg_gen_neg_i32(tmp, src);
 
492
    tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
 
493
    tcg_temp_free_i32(c0);
 
494
    tcg_temp_free_i32(tmp);
 
495
}
 
496
 
 
497
static void shifter_out_im(TCGv_i32 var, int shift)
 
498
{
 
499
    if (shift == 0) {
 
500
        tcg_gen_andi_i32(cpu_CF, var, 1);
 
501
    } else {
 
502
        tcg_gen_shri_i32(cpu_CF, var, shift);
 
503
        if (shift != 31) {
 
504
            tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
 
505
        }
 
506
    }
 
507
}
 
508
 
 
509
/* Shift by immediate.  Includes special handling for shift == 0.  */
 
510
static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
 
511
                                    int shift, int flags)
 
512
{
 
513
    switch (shiftop) {
 
514
    case 0: /* LSL */
 
515
        if (shift != 0) {
 
516
            if (flags)
 
517
                shifter_out_im(var, 32 - shift);
 
518
            tcg_gen_shli_i32(var, var, shift);
 
519
        }
 
520
        break;
 
521
    case 1: /* LSR */
 
522
        if (shift == 0) {
 
523
            if (flags) {
 
524
                tcg_gen_shri_i32(cpu_CF, var, 31);
 
525
            }
 
526
            tcg_gen_movi_i32(var, 0);
 
527
        } else {
 
528
            if (flags)
 
529
                shifter_out_im(var, shift - 1);
 
530
            tcg_gen_shri_i32(var, var, shift);
 
531
        }
 
532
        break;
 
533
    case 2: /* ASR */
 
534
        if (shift == 0)
 
535
            shift = 32;
 
536
        if (flags)
 
537
            shifter_out_im(var, shift - 1);
 
538
        if (shift == 32)
 
539
          shift = 31;
 
540
        tcg_gen_sari_i32(var, var, shift);
 
541
        break;
 
542
    case 3: /* ROR/RRX */
 
543
        if (shift != 0) {
 
544
            if (flags)
 
545
                shifter_out_im(var, shift - 1);
 
546
            tcg_gen_rotri_i32(var, var, shift); break;
 
547
        } else {
 
548
            TCGv_i32 tmp = tcg_temp_new_i32();
 
549
            tcg_gen_shli_i32(tmp, cpu_CF, 31);
 
550
            if (flags)
 
551
                shifter_out_im(var, 0);
 
552
            tcg_gen_shri_i32(var, var, 1);
 
553
            tcg_gen_or_i32(var, var, tmp);
 
554
            tcg_temp_free_i32(tmp);
 
555
        }
 
556
    }
 
557
};
 
558
 
 
559
static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
 
560
                                     TCGv_i32 shift, int flags)
 
561
{
 
562
    if (flags) {
 
563
        switch (shiftop) {
 
564
        case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
 
565
        case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
 
566
        case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
 
567
        case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
 
568
        }
 
569
    } else {
 
570
        switch (shiftop) {
 
571
        case 0:
 
572
            gen_shl(var, var, shift);
 
573
            break;
 
574
        case 1:
 
575
            gen_shr(var, var, shift);
 
576
            break;
 
577
        case 2:
 
578
            gen_sar(var, var, shift);
 
579
            break;
 
580
        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
 
581
                tcg_gen_rotr_i32(var, var, shift); break;
 
582
        }
 
583
    }
 
584
    tcg_temp_free_i32(shift);
 
585
}
 
586
 
 
587
#define PAS_OP(pfx) \
 
588
    switch (op2) {  \
 
589
    case 0: gen_pas_helper(glue(pfx,add16)); break; \
 
590
    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
 
591
    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
 
592
    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
 
593
    case 4: gen_pas_helper(glue(pfx,add8)); break; \
 
594
    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
 
595
    }
 
596
static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
 
597
{
 
598
    TCGv_ptr tmp;
 
599
 
 
600
    switch (op1) {
 
601
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
 
602
    case 1:
 
603
        tmp = tcg_temp_new_ptr();
 
604
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 
605
        PAS_OP(s)
 
606
        tcg_temp_free_ptr(tmp);
 
607
        break;
 
608
    case 5:
 
609
        tmp = tcg_temp_new_ptr();
 
610
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 
611
        PAS_OP(u)
 
612
        tcg_temp_free_ptr(tmp);
 
613
        break;
 
614
#undef gen_pas_helper
 
615
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
 
616
    case 2:
 
617
        PAS_OP(q);
 
618
        break;
 
619
    case 3:
 
620
        PAS_OP(sh);
 
621
        break;
 
622
    case 6:
 
623
        PAS_OP(uq);
 
624
        break;
 
625
    case 7:
 
626
        PAS_OP(uh);
 
627
        break;
 
628
#undef gen_pas_helper
 
629
    }
 
630
}
 
631
#undef PAS_OP
 
632
 
 
633
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
 
634
#define PAS_OP(pfx) \
 
635
    switch (op1) {  \
 
636
    case 0: gen_pas_helper(glue(pfx,add8)); break; \
 
637
    case 1: gen_pas_helper(glue(pfx,add16)); break; \
 
638
    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
 
639
    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
 
640
    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
 
641
    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
 
642
    }
 
643
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
 
644
{
 
645
    TCGv_ptr tmp;
 
646
 
 
647
    switch (op2) {
 
648
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
 
649
    case 0:
 
650
        tmp = tcg_temp_new_ptr();
 
651
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 
652
        PAS_OP(s)
 
653
        tcg_temp_free_ptr(tmp);
 
654
        break;
 
655
    case 4:
 
656
        tmp = tcg_temp_new_ptr();
 
657
        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 
658
        PAS_OP(u)
 
659
        tcg_temp_free_ptr(tmp);
 
660
        break;
 
661
#undef gen_pas_helper
 
662
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
 
663
    case 1:
 
664
        PAS_OP(q);
 
665
        break;
 
666
    case 2:
 
667
        PAS_OP(sh);
 
668
        break;
 
669
    case 5:
 
670
        PAS_OP(uq);
 
671
        break;
 
672
    case 6:
 
673
        PAS_OP(uh);
 
674
        break;
 
675
#undef gen_pas_helper
 
676
    }
 
677
}
 
678
#undef PAS_OP
 
679
 
 
680
static void gen_test_cc(int cc, int label)
 
681
{
 
682
    TCGv_i32 tmp;
 
683
    int inv;
 
684
 
 
685
    switch (cc) {
 
686
    case 0: /* eq: Z */
 
687
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
 
688
        break;
 
689
    case 1: /* ne: !Z */
 
690
        tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
 
691
        break;
 
692
    case 2: /* cs: C */
 
693
        tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
 
694
        break;
 
695
    case 3: /* cc: !C */
 
696
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
 
697
        break;
 
698
    case 4: /* mi: N */
 
699
        tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
 
700
        break;
 
701
    case 5: /* pl: !N */
 
702
        tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
 
703
        break;
 
704
    case 6: /* vs: V */
 
705
        tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
 
706
        break;
 
707
    case 7: /* vc: !V */
 
708
        tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
 
709
        break;
 
710
    case 8: /* hi: C && !Z */
 
711
        inv = gen_new_label();
 
712
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
 
713
        tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
 
714
        gen_set_label(inv);
 
715
        break;
 
716
    case 9: /* ls: !C || Z */
 
717
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
 
718
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
 
719
        break;
 
720
    case 10: /* ge: N == V -> N ^ V == 0 */
 
721
        tmp = tcg_temp_new_i32();
 
722
        tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
 
723
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
 
724
        tcg_temp_free_i32(tmp);
 
725
        break;
 
726
    case 11: /* lt: N != V -> N ^ V != 0 */
 
727
        tmp = tcg_temp_new_i32();
 
728
        tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
 
729
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
 
730
        tcg_temp_free_i32(tmp);
 
731
        break;
 
732
    case 12: /* gt: !Z && N == V */
 
733
        inv = gen_new_label();
 
734
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
 
735
        tmp = tcg_temp_new_i32();
 
736
        tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
 
737
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
 
738
        tcg_temp_free_i32(tmp);
 
739
        gen_set_label(inv);
 
740
        break;
 
741
    case 13: /* le: Z || N != V */
 
742
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
 
743
        tmp = tcg_temp_new_i32();
 
744
        tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
 
745
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
 
746
        tcg_temp_free_i32(tmp);
 
747
        break;
 
748
    default:
 
749
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
 
750
        abort();
 
751
    }
 
752
}
 
753
 
 
754
static const uint8_t table_logic_cc[16] = {
 
755
    1, /* and */
 
756
    1, /* xor */
 
757
    0, /* sub */
 
758
    0, /* rsb */
 
759
    0, /* add */
 
760
    0, /* adc */
 
761
    0, /* sbc */
 
762
    0, /* rsc */
 
763
    1, /* andl */
 
764
    1, /* xorl */
 
765
    0, /* cmp */
 
766
    0, /* cmn */
 
767
    1, /* orr */
 
768
    1, /* mov */
 
769
    1, /* bic */
 
770
    1, /* mvn */
 
771
};
 
772
 
 
773
/* Set PC and Thumb state from an immediate address.  */
 
774
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
 
775
{
 
776
    TCGv_i32 tmp;
 
777
 
 
778
    s->is_jmp = DISAS_UPDATE;
 
779
    if (s->thumb != (addr & 1)) {
 
780
        tmp = tcg_temp_new_i32();
 
781
        tcg_gen_movi_i32(tmp, addr & 1);
 
782
        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
 
783
        tcg_temp_free_i32(tmp);
 
784
    }
 
785
    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
 
786
}
 
787
 
 
788
/* Set PC and Thumb state from var.  var is marked as dead.  */
 
789
static inline void gen_bx(DisasContext *s, TCGv_i32 var)
 
790
{
 
791
    s->is_jmp = DISAS_UPDATE;
 
792
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
 
793
    tcg_gen_andi_i32(var, var, 1);
 
794
    store_cpu_field(var, thumb);
 
795
}
 
796
 
 
797
/* Variant of store_reg which uses branch&exchange logic when storing
 
798
   to r15 in ARM architecture v7 and above. The source must be a temporary
 
799
   and will be marked as dead. */
 
800
static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
 
801
                                int reg, TCGv_i32 var)
 
802
{
 
803
    if (reg == 15 && ENABLE_ARCH_7) {
 
804
        gen_bx(s, var);
 
805
    } else {
 
806
        store_reg(s, reg, var);
 
807
    }
 
808
}
 
809
 
 
810
/* Variant of store_reg which uses branch&exchange logic when storing
 
811
 * to r15 in ARM architecture v5T and above. This is used for storing
 
812
 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
 
813
 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
 
814
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
 
815
                                       int reg, TCGv_i32 var)
 
816
{
 
817
    if (reg == 15 && ENABLE_ARCH_5) {
 
818
        gen_bx(s, var);
 
819
    } else {
 
820
        store_reg(s, reg, var);
 
821
    }
 
822
}
 
823
 
 
824
/* Abstractions of "generate code to do a guest load/store for
 
825
 * AArch32", where a vaddr is always 32 bits (and is zero
 
826
 * extended if we're a 64 bit core) and  data is also
 
827
 * 32 bits unless specifically doing a 64 bit access.
 
828
 * These functions work like tcg_gen_qemu_{ld,st}* except
 
829
 * that their arguments are TCGv_i32 rather than TCGv.
 
830
 */
 
831
#if TARGET_LONG_BITS == 32
 
832
 
 
833
#define DO_GEN_LD(OP)                                                    \
 
834
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
 
835
{                                                                        \
 
836
    tcg_gen_qemu_##OP(val, addr, index);                                 \
 
837
}
 
838
 
 
839
#define DO_GEN_ST(OP)                                                    \
 
840
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
 
841
{                                                                        \
 
842
    tcg_gen_qemu_##OP(val, addr, index);                                 \
 
843
}
 
844
 
 
845
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
 
846
{
 
847
    tcg_gen_qemu_ld64(val, addr, index);
 
848
}
 
849
 
 
850
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
 
851
{
 
852
    tcg_gen_qemu_st64(val, addr, index);
 
853
}
 
854
 
 
855
#else
 
856
 
 
857
#define DO_GEN_LD(OP)                                                    \
 
858
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
 
859
{                                                                        \
 
860
    TCGv addr64 = tcg_temp_new();                                        \
 
861
    TCGv val64 = tcg_temp_new();                                         \
 
862
    tcg_gen_extu_i32_i64(addr64, addr);                                  \
 
863
    tcg_gen_qemu_##OP(val64, addr64, index);                             \
 
864
    tcg_temp_free(addr64);                                               \
 
865
    tcg_gen_trunc_i64_i32(val, val64);                                   \
 
866
    tcg_temp_free(val64);                                                \
 
867
}
 
868
 
 
869
#define DO_GEN_ST(OP)                                                    \
 
870
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
 
871
{                                                                        \
 
872
    TCGv addr64 = tcg_temp_new();                                        \
 
873
    TCGv val64 = tcg_temp_new();                                         \
 
874
    tcg_gen_extu_i32_i64(addr64, addr);                                  \
 
875
    tcg_gen_extu_i32_i64(val64, val);                                    \
 
876
    tcg_gen_qemu_##OP(val64, addr64, index);                             \
 
877
    tcg_temp_free(addr64);                                               \
 
878
    tcg_temp_free(val64);                                                \
 
879
}
 
880
 
 
881
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
 
882
{
 
883
    TCGv addr64 = tcg_temp_new();
 
884
    tcg_gen_extu_i32_i64(addr64, addr);
 
885
    tcg_gen_qemu_ld64(val, addr64, index);
 
886
    tcg_temp_free(addr64);
 
887
}
 
888
 
 
889
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
 
890
{
 
891
    TCGv addr64 = tcg_temp_new();
 
892
    tcg_gen_extu_i32_i64(addr64, addr);
 
893
    tcg_gen_qemu_st64(val, addr64, index);
 
894
    tcg_temp_free(addr64);
 
895
}
 
896
 
 
897
#endif
 
898
 
 
899
DO_GEN_LD(ld8s)
 
900
DO_GEN_LD(ld8u)
 
901
DO_GEN_LD(ld16s)
 
902
DO_GEN_LD(ld16u)
 
903
DO_GEN_LD(ld32u)
 
904
DO_GEN_ST(st8)
 
905
DO_GEN_ST(st16)
 
906
DO_GEN_ST(st32)
 
907
 
 
908
static inline void gen_smc(CPUARMState *env, DisasContext *s)
 
909
{
 
910
    tcg_gen_movi_i32(cpu_R[15], s->pc);
 
911
    s->is_jmp = DISAS_SMC;
 
912
}
 
913
 
 
914
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
 
915
{
 
916
    if (s->aarch64) {
 
917
        gen_a64_set_pc_im(val);
 
918
    } else {
 
919
        tcg_gen_movi_i32(cpu_R[15], val);
 
920
    }
 
921
}
 
922
 
 
923
/* Force a TB lookup after an instruction that changes the CPU state.  */
 
924
static inline void gen_lookup_tb(DisasContext *s)
 
925
{
 
926
    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
 
927
    s->is_jmp = DISAS_UPDATE;
 
928
}
 
929
 
 
930
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
 
931
                                       TCGv_i32 var)
 
932
{
 
933
    int val, rm, shift, shiftop;
 
934
    TCGv_i32 offset;
 
935
 
 
936
    if (!(insn & (1 << 25))) {
 
937
        /* immediate */
 
938
        val = insn & 0xfff;
 
939
        if (!(insn & (1 << 23)))
 
940
            val = -val;
 
941
        if (val != 0)
 
942
            tcg_gen_addi_i32(var, var, val);
 
943
    } else {
 
944
        /* shift/register */
 
945
        rm = (insn) & 0xf;
 
946
        shift = (insn >> 7) & 0x1f;
 
947
        shiftop = (insn >> 5) & 3;
 
948
        offset = load_reg(s, rm);
 
949
        gen_arm_shift_im(offset, shiftop, shift, 0);
 
950
        if (!(insn & (1 << 23)))
 
951
            tcg_gen_sub_i32(var, var, offset);
 
952
        else
 
953
            tcg_gen_add_i32(var, var, offset);
 
954
        tcg_temp_free_i32(offset);
 
955
    }
 
956
}
 
957
 
 
958
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
 
959
                                        int extra, TCGv_i32 var)
 
960
{
 
961
    int val, rm;
 
962
    TCGv_i32 offset;
 
963
 
 
964
    if (insn & (1 << 22)) {
 
965
        /* immediate */
 
966
        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
 
967
        if (!(insn & (1 << 23)))
 
968
            val = -val;
 
969
        val += extra;
 
970
        if (val != 0)
 
971
            tcg_gen_addi_i32(var, var, val);
 
972
    } else {
 
973
        /* register */
 
974
        if (extra)
 
975
            tcg_gen_addi_i32(var, var, extra);
 
976
        rm = (insn) & 0xf;
 
977
        offset = load_reg(s, rm);
 
978
        if (!(insn & (1 << 23)))
 
979
            tcg_gen_sub_i32(var, var, offset);
 
980
        else
 
981
            tcg_gen_add_i32(var, var, offset);
 
982
        tcg_temp_free_i32(offset);
 
983
    }
 
984
}
 
985
 
 
986
static TCGv_ptr get_fpstatus_ptr(int neon)
 
987
{
 
988
    TCGv_ptr statusptr = tcg_temp_new_ptr();
 
989
    int offset;
 
990
    if (neon) {
 
991
        offset = offsetof(CPUARMState, vfp.standard_fp_status);
 
992
    } else {
 
993
        offset = offsetof(CPUARMState, vfp.fp_status);
 
994
    }
 
995
    tcg_gen_addi_ptr(statusptr, cpu_env, offset);
 
996
    return statusptr;
 
997
}
 
998
 
 
999
#define VFP_OP2(name)                                                 \
 
1000
static inline void gen_vfp_##name(int dp)                             \
 
1001
{                                                                     \
 
1002
    TCGv_ptr fpst = get_fpstatus_ptr(0);                              \
 
1003
    if (dp) {                                                         \
 
1004
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst);    \
 
1005
    } else {                                                          \
 
1006
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst);    \
 
1007
    }                                                                 \
 
1008
    tcg_temp_free_ptr(fpst);                                          \
 
1009
}
 
1010
 
 
1011
VFP_OP2(add)
 
1012
VFP_OP2(sub)
 
1013
VFP_OP2(mul)
 
1014
VFP_OP2(div)
 
1015
 
 
1016
#undef VFP_OP2
 
1017
 
 
1018
static inline void gen_vfp_F1_mul(int dp)
 
1019
{
 
1020
    /* Like gen_vfp_mul() but put result in F1 */
 
1021
    TCGv_ptr fpst = get_fpstatus_ptr(0);
 
1022
    if (dp) {
 
1023
        gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
 
1024
    } else {
 
1025
        gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
 
1026
    }
 
1027
    tcg_temp_free_ptr(fpst);
 
1028
}
 
1029
 
 
1030
static inline void gen_vfp_F1_neg(int dp)
 
1031
{
 
1032
    /* Like gen_vfp_neg() but put result in F1 */
 
1033
    if (dp) {
 
1034
        gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
 
1035
    } else {
 
1036
        gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
 
1037
    }
 
1038
}
 
1039
 
 
1040
static inline void gen_vfp_abs(int dp)
 
1041
{
 
1042
    if (dp)
 
1043
        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
 
1044
    else
 
1045
        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
 
1046
}
 
1047
 
 
1048
static inline void gen_vfp_neg(int dp)
 
1049
{
 
1050
    if (dp)
 
1051
        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
 
1052
    else
 
1053
        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
 
1054
}
 
1055
 
 
1056
static inline void gen_vfp_sqrt(int dp)
 
1057
{
 
1058
    if (dp)
 
1059
        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
 
1060
    else
 
1061
        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
 
1062
}
 
1063
 
 
1064
static inline void gen_vfp_cmp(int dp)
 
1065
{
 
1066
    if (dp)
 
1067
        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
 
1068
    else
 
1069
        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
 
1070
}
 
1071
 
 
1072
static inline void gen_vfp_cmpe(int dp)
 
1073
{
 
1074
    if (dp)
 
1075
        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
 
1076
    else
 
1077
        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
 
1078
}
 
1079
 
 
1080
static inline void gen_vfp_F1_ld0(int dp)
 
1081
{
 
1082
    if (dp)
 
1083
        tcg_gen_movi_i64(cpu_F1d, 0);
 
1084
    else
 
1085
        tcg_gen_movi_i32(cpu_F1s, 0);
 
1086
}
 
1087
 
 
1088
#define VFP_GEN_ITOF(name) \
 
1089
static inline void gen_vfp_##name(int dp, int neon) \
 
1090
{ \
 
1091
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
 
1092
    if (dp) { \
 
1093
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
 
1094
    } else { \
 
1095
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
 
1096
    } \
 
1097
    tcg_temp_free_ptr(statusptr); \
 
1098
}
 
1099
 
 
1100
VFP_GEN_ITOF(uito)
 
1101
VFP_GEN_ITOF(sito)
 
1102
#undef VFP_GEN_ITOF
 
1103
 
 
1104
#define VFP_GEN_FTOI(name) \
 
1105
static inline void gen_vfp_##name(int dp, int neon) \
 
1106
{ \
 
1107
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
 
1108
    if (dp) { \
 
1109
        gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
 
1110
    } else { \
 
1111
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
 
1112
    } \
 
1113
    tcg_temp_free_ptr(statusptr); \
 
1114
}
 
1115
 
 
1116
VFP_GEN_FTOI(toui)
 
1117
VFP_GEN_FTOI(touiz)
 
1118
VFP_GEN_FTOI(tosi)
 
1119
VFP_GEN_FTOI(tosiz)
 
1120
#undef VFP_GEN_FTOI
 
1121
 
 
1122
#define VFP_GEN_FIX(name) \
 
1123
static inline void gen_vfp_##name(int dp, int shift, int neon) \
 
1124
{ \
 
1125
    TCGv_i32 tmp_shift = tcg_const_i32(shift); \
 
1126
    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
 
1127
    if (dp) { \
 
1128
        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
 
1129
    } else { \
 
1130
        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
 
1131
    } \
 
1132
    tcg_temp_free_i32(tmp_shift); \
 
1133
    tcg_temp_free_ptr(statusptr); \
 
1134
}
 
1135
VFP_GEN_FIX(tosh)
 
1136
VFP_GEN_FIX(tosl)
 
1137
VFP_GEN_FIX(touh)
 
1138
VFP_GEN_FIX(toul)
 
1139
VFP_GEN_FIX(shto)
 
1140
VFP_GEN_FIX(slto)
 
1141
VFP_GEN_FIX(uhto)
 
1142
VFP_GEN_FIX(ulto)
 
1143
#undef VFP_GEN_FIX
 
1144
 
 
1145
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
 
1146
{
 
1147
    if (dp) {
 
1148
        gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
 
1149
    } else {
 
1150
        gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
 
1151
    }
 
1152
}
 
1153
 
 
1154
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
 
1155
{
 
1156
    if (dp) {
 
1157
        gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
 
1158
    } else {
 
1159
        gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
 
1160
    }
 
1161
}
 
1162
 
 
1163
static inline long
 
1164
vfp_reg_offset (int dp, int reg)
 
1165
{
 
1166
    if (dp)
 
1167
        return offsetof(CPUARMState, vfp.regs[reg]);
 
1168
    else if (reg & 1) {
 
1169
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
 
1170
          + offsetof(CPU_DoubleU, l.upper);
 
1171
    } else {
 
1172
        return offsetof(CPUARMState, vfp.regs[reg >> 1])
 
1173
          + offsetof(CPU_DoubleU, l.lower);
 
1174
    }
 
1175
}
 
1176
 
 
1177
/* Return the offset of a 32-bit piece of a NEON register.
 
1178
   zero is the least significant end of the register.  */
 
1179
static inline long
 
1180
neon_reg_offset (int reg, int n)
 
1181
{
 
1182
    int sreg;
 
1183
    sreg = reg * 2 + n;
 
1184
    return vfp_reg_offset(0, sreg);
 
1185
}
 
1186
 
 
1187
static TCGv_i32 neon_load_reg(int reg, int pass)
 
1188
{
 
1189
    TCGv_i32 tmp = tcg_temp_new_i32();
 
1190
    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
 
1191
    return tmp;
 
1192
}
 
1193
 
 
1194
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
 
1195
{
 
1196
    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
 
1197
    tcg_temp_free_i32(var);
 
1198
}
 
1199
 
 
1200
static inline void neon_load_reg64(TCGv_i64 var, int reg)
 
1201
{
 
1202
    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
 
1203
}
 
1204
 
 
1205
static inline void neon_store_reg64(TCGv_i64 var, int reg)
 
1206
{
 
1207
    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
 
1208
}
 
1209
 
 
1210
#define tcg_gen_ld_f32 tcg_gen_ld_i32
 
1211
#define tcg_gen_ld_f64 tcg_gen_ld_i64
 
1212
#define tcg_gen_st_f32 tcg_gen_st_i32
 
1213
#define tcg_gen_st_f64 tcg_gen_st_i64
 
1214
 
 
1215
static inline void gen_mov_F0_vreg(int dp, int reg)
 
1216
{
 
1217
    if (dp)
 
1218
        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
 
1219
    else
 
1220
        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
 
1221
}
 
1222
 
 
1223
static inline void gen_mov_F1_vreg(int dp, int reg)
 
1224
{
 
1225
    if (dp)
 
1226
        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
 
1227
    else
 
1228
        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
 
1229
}
 
1230
 
 
1231
static inline void gen_mov_vreg_F0(int dp, int reg)
 
1232
{
 
1233
    if (dp)
 
1234
        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
 
1235
    else
 
1236
        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
 
1237
}
 
1238
 
 
1239
#define ARM_CP_RW_BIT   (1 << 20)
 
1240
 
 
1241
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
 
1242
{
 
1243
    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
 
1244
}
 
1245
 
 
1246
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
 
1247
{
 
1248
    tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
 
1249
}
 
1250
 
 
1251
static inline TCGv_i32 iwmmxt_load_creg(int reg)
 
1252
{
 
1253
    TCGv_i32 var = tcg_temp_new_i32();
 
1254
    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
 
1255
    return var;
 
1256
}
 
1257
 
 
1258
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
 
1259
{
 
1260
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
 
1261
    tcg_temp_free_i32(var);
 
1262
}
 
1263
 
 
1264
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
 
1265
{
 
1266
    iwmmxt_store_reg(cpu_M0, rn);
 
1267
}
 
1268
 
 
1269
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
 
1270
{
 
1271
    iwmmxt_load_reg(cpu_M0, rn);
 
1272
}
 
1273
 
 
1274
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
 
1275
{
 
1276
    iwmmxt_load_reg(cpu_V1, rn);
 
1277
    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
 
1278
}
 
1279
 
 
1280
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
 
1281
{
 
1282
    iwmmxt_load_reg(cpu_V1, rn);
 
1283
    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
 
1284
}
 
1285
 
 
1286
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
 
1287
{
 
1288
    iwmmxt_load_reg(cpu_V1, rn);
 
1289
    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
 
1290
}
 
1291
 
 
1292
#define IWMMXT_OP(name) \
 
1293
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
 
1294
{ \
 
1295
    iwmmxt_load_reg(cpu_V1, rn); \
 
1296
    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
 
1297
}
 
1298
 
 
1299
#define IWMMXT_OP_ENV(name) \
 
1300
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
 
1301
{ \
 
1302
    iwmmxt_load_reg(cpu_V1, rn); \
 
1303
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
 
1304
}
 
1305
 
 
1306
#define IWMMXT_OP_ENV_SIZE(name) \
 
1307
IWMMXT_OP_ENV(name##b) \
 
1308
IWMMXT_OP_ENV(name##w) \
 
1309
IWMMXT_OP_ENV(name##l)
 
1310
 
 
1311
#define IWMMXT_OP_ENV1(name) \
 
1312
static inline void gen_op_iwmmxt_##name##_M0(void) \
 
1313
{ \
 
1314
    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
 
1315
}
 
1316
 
 
1317
IWMMXT_OP(maddsq)
 
1318
IWMMXT_OP(madduq)
 
1319
IWMMXT_OP(sadb)
 
1320
IWMMXT_OP(sadw)
 
1321
IWMMXT_OP(mulslw)
 
1322
IWMMXT_OP(mulshw)
 
1323
IWMMXT_OP(mululw)
 
1324
IWMMXT_OP(muluhw)
 
1325
IWMMXT_OP(macsw)
 
1326
IWMMXT_OP(macuw)
 
1327
 
 
1328
IWMMXT_OP_ENV_SIZE(unpackl)
 
1329
IWMMXT_OP_ENV_SIZE(unpackh)
 
1330
 
 
1331
IWMMXT_OP_ENV1(unpacklub)
 
1332
IWMMXT_OP_ENV1(unpackluw)
 
1333
IWMMXT_OP_ENV1(unpacklul)
 
1334
IWMMXT_OP_ENV1(unpackhub)
 
1335
IWMMXT_OP_ENV1(unpackhuw)
 
1336
IWMMXT_OP_ENV1(unpackhul)
 
1337
IWMMXT_OP_ENV1(unpacklsb)
 
1338
IWMMXT_OP_ENV1(unpacklsw)
 
1339
IWMMXT_OP_ENV1(unpacklsl)
 
1340
IWMMXT_OP_ENV1(unpackhsb)
 
1341
IWMMXT_OP_ENV1(unpackhsw)
 
1342
IWMMXT_OP_ENV1(unpackhsl)
 
1343
 
 
1344
IWMMXT_OP_ENV_SIZE(cmpeq)
 
1345
IWMMXT_OP_ENV_SIZE(cmpgtu)
 
1346
IWMMXT_OP_ENV_SIZE(cmpgts)
 
1347
 
 
1348
IWMMXT_OP_ENV_SIZE(mins)
 
1349
IWMMXT_OP_ENV_SIZE(minu)
 
1350
IWMMXT_OP_ENV_SIZE(maxs)
 
1351
IWMMXT_OP_ENV_SIZE(maxu)
 
1352
 
 
1353
IWMMXT_OP_ENV_SIZE(subn)
 
1354
IWMMXT_OP_ENV_SIZE(addn)
 
1355
IWMMXT_OP_ENV_SIZE(subu)
 
1356
IWMMXT_OP_ENV_SIZE(addu)
 
1357
IWMMXT_OP_ENV_SIZE(subs)
 
1358
IWMMXT_OP_ENV_SIZE(adds)
 
1359
 
 
1360
IWMMXT_OP_ENV(avgb0)
 
1361
IWMMXT_OP_ENV(avgb1)
 
1362
IWMMXT_OP_ENV(avgw0)
 
1363
IWMMXT_OP_ENV(avgw1)
 
1364
 
 
1365
IWMMXT_OP(msadb)
 
1366
 
 
1367
IWMMXT_OP_ENV(packuw)
 
1368
IWMMXT_OP_ENV(packul)
 
1369
IWMMXT_OP_ENV(packuq)
 
1370
IWMMXT_OP_ENV(packsw)
 
1371
IWMMXT_OP_ENV(packsl)
 
1372
IWMMXT_OP_ENV(packsq)
 
1373
 
 
1374
static void gen_op_iwmmxt_set_mup(void)
 
1375
{
 
1376
    TCGv_i32 tmp;
 
1377
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
 
1378
    tcg_gen_ori_i32(tmp, tmp, 2);
 
1379
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
 
1380
}
 
1381
 
 
1382
static void gen_op_iwmmxt_set_cup(void)
 
1383
{
 
1384
    TCGv_i32 tmp;
 
1385
    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
 
1386
    tcg_gen_ori_i32(tmp, tmp, 1);
 
1387
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
 
1388
}
 
1389
 
 
1390
static void gen_op_iwmmxt_setpsr_nz(void)
 
1391
{
 
1392
    TCGv_i32 tmp = tcg_temp_new_i32();
 
1393
    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
 
1394
    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
 
1395
}
 
1396
 
 
1397
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
 
1398
{
 
1399
    iwmmxt_load_reg(cpu_V1, rn);
 
1400
    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
 
1401
    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
 
1402
}
 
1403
 
 
1404
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
 
1405
                                     TCGv_i32 dest)
 
1406
{
 
1407
    int rd;
 
1408
    uint32_t offset;
 
1409
    TCGv_i32 tmp;
 
1410
 
 
1411
    rd = (insn >> 16) & 0xf;
 
1412
    tmp = load_reg(s, rd);
 
1413
 
 
1414
    offset = (insn & 0xff) << ((insn >> 7) & 2);
 
1415
    if (insn & (1 << 24)) {
 
1416
        /* Pre indexed */
 
1417
        if (insn & (1 << 23))
 
1418
            tcg_gen_addi_i32(tmp, tmp, offset);
 
1419
        else
 
1420
            tcg_gen_addi_i32(tmp, tmp, -offset);
 
1421
        tcg_gen_mov_i32(dest, tmp);
 
1422
        if (insn & (1 << 21))
 
1423
            store_reg(s, rd, tmp);
 
1424
        else
 
1425
            tcg_temp_free_i32(tmp);
 
1426
    } else if (insn & (1 << 21)) {
 
1427
        /* Post indexed */
 
1428
        tcg_gen_mov_i32(dest, tmp);
 
1429
        if (insn & (1 << 23))
 
1430
            tcg_gen_addi_i32(tmp, tmp, offset);
 
1431
        else
 
1432
            tcg_gen_addi_i32(tmp, tmp, -offset);
 
1433
        store_reg(s, rd, tmp);
 
1434
    } else if (!(insn & (1 << 23)))
 
1435
        return 1;
 
1436
    return 0;
 
1437
}
 
1438
 
 
1439
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
 
1440
{
 
1441
    int rd = (insn >> 0) & 0xf;
 
1442
    TCGv_i32 tmp;
 
1443
 
 
1444
    if (insn & (1 << 8)) {
 
1445
        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
 
1446
            return 1;
 
1447
        } else {
 
1448
            tmp = iwmmxt_load_creg(rd);
 
1449
        }
 
1450
    } else {
 
1451
        tmp = tcg_temp_new_i32();
 
1452
        iwmmxt_load_reg(cpu_V0, rd);
 
1453
        tcg_gen_trunc_i64_i32(tmp, cpu_V0);
 
1454
    }
 
1455
    tcg_gen_andi_i32(tmp, tmp, mask);
 
1456
    tcg_gen_mov_i32(dest, tmp);
 
1457
    tcg_temp_free_i32(tmp);
 
1458
    return 0;
 
1459
}
 
1460
 
 
1461
/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occurred
 
1462
   (ie. an undefined instruction).  */
 
1463
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 
1464
{
 
1465
    int rd, wrd;
 
1466
    int rdhi, rdlo, rd0, rd1, i;
 
1467
    TCGv_i32 addr;
 
1468
    TCGv_i32 tmp, tmp2, tmp3;
 
1469
 
 
1470
    if ((insn & 0x0e000e00) == 0x0c000000) {
 
1471
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
 
1472
            wrd = insn & 0xf;
 
1473
            rdlo = (insn >> 12) & 0xf;
 
1474
            rdhi = (insn >> 16) & 0xf;
 
1475
            if (insn & ARM_CP_RW_BIT) {                 /* TMRRC */
 
1476
                iwmmxt_load_reg(cpu_V0, wrd);
 
1477
                tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
 
1478
                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
 
1479
                tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
 
1480
            } else {                                    /* TMCRR */
 
1481
                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
 
1482
                iwmmxt_store_reg(cpu_V0, wrd);
 
1483
                gen_op_iwmmxt_set_mup();
 
1484
            }
 
1485
            return 0;
 
1486
        }
 
1487
 
 
1488
        wrd = (insn >> 12) & 0xf;
 
1489
        addr = tcg_temp_new_i32();
 
1490
        if (gen_iwmmxt_address(s, insn, addr)) {
 
1491
            tcg_temp_free_i32(addr);
 
1492
            return 1;
 
1493
        }
 
1494
        if (insn & ARM_CP_RW_BIT) {
 
1495
            if ((insn >> 28) == 0xf) {                  /* WLDRW wCx */
 
1496
                tmp = tcg_temp_new_i32();
 
1497
                gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
1498
                iwmmxt_store_creg(wrd, tmp);
 
1499
            } else {
 
1500
                i = 1;
 
1501
                if (insn & (1 << 8)) {
 
1502
                    if (insn & (1 << 22)) {             /* WLDRD */
 
1503
                        gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
 
1504
                        i = 0;
 
1505
                    } else {                            /* WLDRW wRd */
 
1506
                        tmp = tcg_temp_new_i32();
 
1507
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
1508
                    }
 
1509
                } else {
 
1510
                    tmp = tcg_temp_new_i32();
 
1511
                    if (insn & (1 << 22)) {             /* WLDRH */
 
1512
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
1513
                    } else {                            /* WLDRB */
 
1514
                        gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
1515
                    }
 
1516
                }
 
1517
                if (i) {
 
1518
                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
 
1519
                    tcg_temp_free_i32(tmp);
 
1520
                }
 
1521
                gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1522
            }
 
1523
        } else {
 
1524
            if ((insn >> 28) == 0xf) {                  /* WSTRW wCx */
 
1525
                tmp = iwmmxt_load_creg(wrd);
 
1526
                gen_aa32_st32(tmp, addr, IS_USER(s));
 
1527
            } else {
 
1528
                gen_op_iwmmxt_movq_M0_wRn(wrd);
 
1529
                tmp = tcg_temp_new_i32();
 
1530
                if (insn & (1 << 8)) {
 
1531
                    if (insn & (1 << 22)) {             /* WSTRD */
 
1532
                        gen_aa32_st64(cpu_M0, addr, IS_USER(s));
 
1533
                    } else {                            /* WSTRW wRd */
 
1534
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
 
1535
                        gen_aa32_st32(tmp, addr, IS_USER(s));
 
1536
                    }
 
1537
                } else {
 
1538
                    if (insn & (1 << 22)) {             /* WSTRH */
 
1539
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
 
1540
                        gen_aa32_st16(tmp, addr, IS_USER(s));
 
1541
                    } else {                            /* WSTRB */
 
1542
                        tcg_gen_trunc_i64_i32(tmp, cpu_M0);
 
1543
                        gen_aa32_st8(tmp, addr, IS_USER(s));
 
1544
                    }
 
1545
                }
 
1546
            }
 
1547
            tcg_temp_free_i32(tmp);
 
1548
        }
 
1549
        tcg_temp_free_i32(addr);
 
1550
        return 0;
 
1551
    }
 
1552
 
 
1553
    if ((insn & 0x0f000000) != 0x0e000000)
 
1554
        return 1;
 
1555
 
 
1556
    switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
 
1557
    case 0x000:                                         /* WOR */
 
1558
        wrd = (insn >> 12) & 0xf;
 
1559
        rd0 = (insn >> 0) & 0xf;
 
1560
        rd1 = (insn >> 16) & 0xf;
 
1561
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1562
        gen_op_iwmmxt_orq_M0_wRn(rd1);
 
1563
        gen_op_iwmmxt_setpsr_nz();
 
1564
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1565
        gen_op_iwmmxt_set_mup();
 
1566
        gen_op_iwmmxt_set_cup();
 
1567
        break;
 
1568
    case 0x011:                                         /* TMCR */
 
1569
        if (insn & 0xf)
 
1570
            return 1;
 
1571
        rd = (insn >> 12) & 0xf;
 
1572
        wrd = (insn >> 16) & 0xf;
 
1573
        switch (wrd) {
 
1574
        case ARM_IWMMXT_wCID:
 
1575
        case ARM_IWMMXT_wCASF:
 
1576
            break;
 
1577
        case ARM_IWMMXT_wCon:
 
1578
            gen_op_iwmmxt_set_cup();
 
1579
            /* Fall through.  */
 
1580
        case ARM_IWMMXT_wCSSF:
 
1581
            tmp = iwmmxt_load_creg(wrd);
 
1582
            tmp2 = load_reg(s, rd);
 
1583
            tcg_gen_andc_i32(tmp, tmp, tmp2);
 
1584
            tcg_temp_free_i32(tmp2);
 
1585
            iwmmxt_store_creg(wrd, tmp);
 
1586
            break;
 
1587
        case ARM_IWMMXT_wCGR0:
 
1588
        case ARM_IWMMXT_wCGR1:
 
1589
        case ARM_IWMMXT_wCGR2:
 
1590
        case ARM_IWMMXT_wCGR3:
 
1591
            gen_op_iwmmxt_set_cup();
 
1592
            tmp = load_reg(s, rd);
 
1593
            iwmmxt_store_creg(wrd, tmp);
 
1594
            break;
 
1595
        default:
 
1596
            return 1;
 
1597
        }
 
1598
        break;
 
1599
    case 0x100:                                         /* WXOR */
 
1600
        wrd = (insn >> 12) & 0xf;
 
1601
        rd0 = (insn >> 0) & 0xf;
 
1602
        rd1 = (insn >> 16) & 0xf;
 
1603
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1604
        gen_op_iwmmxt_xorq_M0_wRn(rd1);
 
1605
        gen_op_iwmmxt_setpsr_nz();
 
1606
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1607
        gen_op_iwmmxt_set_mup();
 
1608
        gen_op_iwmmxt_set_cup();
 
1609
        break;
 
1610
    case 0x111:                                         /* TMRC */
 
1611
        if (insn & 0xf)
 
1612
            return 1;
 
1613
        rd = (insn >> 12) & 0xf;
 
1614
        wrd = (insn >> 16) & 0xf;
 
1615
        tmp = iwmmxt_load_creg(wrd);
 
1616
        store_reg(s, rd, tmp);
 
1617
        break;
 
1618
    case 0x300:                                         /* WANDN */
 
1619
        wrd = (insn >> 12) & 0xf;
 
1620
        rd0 = (insn >> 0) & 0xf;
 
1621
        rd1 = (insn >> 16) & 0xf;
 
1622
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1623
        tcg_gen_neg_i64(cpu_M0, cpu_M0);
 
1624
        gen_op_iwmmxt_andq_M0_wRn(rd1);
 
1625
        gen_op_iwmmxt_setpsr_nz();
 
1626
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1627
        gen_op_iwmmxt_set_mup();
 
1628
        gen_op_iwmmxt_set_cup();
 
1629
        break;
 
1630
    case 0x200:                                         /* WAND */
 
1631
        wrd = (insn >> 12) & 0xf;
 
1632
        rd0 = (insn >> 0) & 0xf;
 
1633
        rd1 = (insn >> 16) & 0xf;
 
1634
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1635
        gen_op_iwmmxt_andq_M0_wRn(rd1);
 
1636
        gen_op_iwmmxt_setpsr_nz();
 
1637
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1638
        gen_op_iwmmxt_set_mup();
 
1639
        gen_op_iwmmxt_set_cup();
 
1640
        break;
 
1641
    case 0x810: case 0xa10:                             /* WMADD */
 
1642
        wrd = (insn >> 12) & 0xf;
 
1643
        rd0 = (insn >> 0) & 0xf;
 
1644
        rd1 = (insn >> 16) & 0xf;
 
1645
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1646
        if (insn & (1 << 21))
 
1647
            gen_op_iwmmxt_maddsq_M0_wRn(rd1);
 
1648
        else
 
1649
            gen_op_iwmmxt_madduq_M0_wRn(rd1);
 
1650
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1651
        gen_op_iwmmxt_set_mup();
 
1652
        break;
 
1653
    case 0x10e: case 0x50e: case 0x90e: case 0xd0e:     /* WUNPCKIL */
 
1654
        wrd = (insn >> 12) & 0xf;
 
1655
        rd0 = (insn >> 16) & 0xf;
 
1656
        rd1 = (insn >> 0) & 0xf;
 
1657
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1658
        switch ((insn >> 22) & 3) {
 
1659
        case 0:
 
1660
            gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
 
1661
            break;
 
1662
        case 1:
 
1663
            gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
 
1664
            break;
 
1665
        case 2:
 
1666
            gen_op_iwmmxt_unpackll_M0_wRn(rd1);
 
1667
            break;
 
1668
        case 3:
 
1669
            return 1;
 
1670
        }
 
1671
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1672
        gen_op_iwmmxt_set_mup();
 
1673
        gen_op_iwmmxt_set_cup();
 
1674
        break;
 
1675
    case 0x10c: case 0x50c: case 0x90c: case 0xd0c:     /* WUNPCKIH */
 
1676
        wrd = (insn >> 12) & 0xf;
 
1677
        rd0 = (insn >> 16) & 0xf;
 
1678
        rd1 = (insn >> 0) & 0xf;
 
1679
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1680
        switch ((insn >> 22) & 3) {
 
1681
        case 0:
 
1682
            gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
 
1683
            break;
 
1684
        case 1:
 
1685
            gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
 
1686
            break;
 
1687
        case 2:
 
1688
            gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
 
1689
            break;
 
1690
        case 3:
 
1691
            return 1;
 
1692
        }
 
1693
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1694
        gen_op_iwmmxt_set_mup();
 
1695
        gen_op_iwmmxt_set_cup();
 
1696
        break;
 
1697
    case 0x012: case 0x112: case 0x412: case 0x512:     /* WSAD */
 
1698
        wrd = (insn >> 12) & 0xf;
 
1699
        rd0 = (insn >> 16) & 0xf;
 
1700
        rd1 = (insn >> 0) & 0xf;
 
1701
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1702
        if (insn & (1 << 22))
 
1703
            gen_op_iwmmxt_sadw_M0_wRn(rd1);
 
1704
        else
 
1705
            gen_op_iwmmxt_sadb_M0_wRn(rd1);
 
1706
        if (!(insn & (1 << 20)))
 
1707
            gen_op_iwmmxt_addl_M0_wRn(wrd);
 
1708
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1709
        gen_op_iwmmxt_set_mup();
 
1710
        break;
 
1711
    case 0x010: case 0x110: case 0x210: case 0x310:     /* WMUL */
 
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
            if (insn & (1 << 20))
 
1718
                gen_op_iwmmxt_mulshw_M0_wRn(rd1);
 
1719
            else
 
1720
                gen_op_iwmmxt_mulslw_M0_wRn(rd1);
 
1721
        } else {
 
1722
            if (insn & (1 << 20))
 
1723
                gen_op_iwmmxt_muluhw_M0_wRn(rd1);
 
1724
            else
 
1725
                gen_op_iwmmxt_mululw_M0_wRn(rd1);
 
1726
        }
 
1727
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1728
        gen_op_iwmmxt_set_mup();
 
1729
        break;
 
1730
    case 0x410: case 0x510: case 0x610: case 0x710:     /* WMAC */
 
1731
        wrd = (insn >> 12) & 0xf;
 
1732
        rd0 = (insn >> 16) & 0xf;
 
1733
        rd1 = (insn >> 0) & 0xf;
 
1734
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1735
        if (insn & (1 << 21))
 
1736
            gen_op_iwmmxt_macsw_M0_wRn(rd1);
 
1737
        else
 
1738
            gen_op_iwmmxt_macuw_M0_wRn(rd1);
 
1739
        if (!(insn & (1 << 20))) {
 
1740
            iwmmxt_load_reg(cpu_V1, wrd);
 
1741
            tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
 
1742
        }
 
1743
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1744
        gen_op_iwmmxt_set_mup();
 
1745
        break;
 
1746
    case 0x006: case 0x406: case 0x806: case 0xc06:     /* WCMPEQ */
 
1747
        wrd = (insn >> 12) & 0xf;
 
1748
        rd0 = (insn >> 16) & 0xf;
 
1749
        rd1 = (insn >> 0) & 0xf;
 
1750
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1751
        switch ((insn >> 22) & 3) {
 
1752
        case 0:
 
1753
            gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
 
1754
            break;
 
1755
        case 1:
 
1756
            gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
 
1757
            break;
 
1758
        case 2:
 
1759
            gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
 
1760
            break;
 
1761
        case 3:
 
1762
            return 1;
 
1763
        }
 
1764
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1765
        gen_op_iwmmxt_set_mup();
 
1766
        gen_op_iwmmxt_set_cup();
 
1767
        break;
 
1768
    case 0x800: case 0x900: case 0xc00: case 0xd00:     /* WAVG2 */
 
1769
        wrd = (insn >> 12) & 0xf;
 
1770
        rd0 = (insn >> 16) & 0xf;
 
1771
        rd1 = (insn >> 0) & 0xf;
 
1772
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1773
        if (insn & (1 << 22)) {
 
1774
            if (insn & (1 << 20))
 
1775
                gen_op_iwmmxt_avgw1_M0_wRn(rd1);
 
1776
            else
 
1777
                gen_op_iwmmxt_avgw0_M0_wRn(rd1);
 
1778
        } else {
 
1779
            if (insn & (1 << 20))
 
1780
                gen_op_iwmmxt_avgb1_M0_wRn(rd1);
 
1781
            else
 
1782
                gen_op_iwmmxt_avgb0_M0_wRn(rd1);
 
1783
        }
 
1784
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1785
        gen_op_iwmmxt_set_mup();
 
1786
        gen_op_iwmmxt_set_cup();
 
1787
        break;
 
1788
    case 0x802: case 0x902: case 0xa02: case 0xb02:     /* WALIGNR */
 
1789
        wrd = (insn >> 12) & 0xf;
 
1790
        rd0 = (insn >> 16) & 0xf;
 
1791
        rd1 = (insn >> 0) & 0xf;
 
1792
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1793
        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
 
1794
        tcg_gen_andi_i32(tmp, tmp, 7);
 
1795
        iwmmxt_load_reg(cpu_V1, rd1);
 
1796
        gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
 
1797
        tcg_temp_free_i32(tmp);
 
1798
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1799
        gen_op_iwmmxt_set_mup();
 
1800
        break;
 
1801
    case 0x601: case 0x605: case 0x609: case 0x60d:     /* TINSR */
 
1802
        if (((insn >> 6) & 3) == 3)
 
1803
            return 1;
 
1804
        rd = (insn >> 12) & 0xf;
 
1805
        wrd = (insn >> 16) & 0xf;
 
1806
        tmp = load_reg(s, rd);
 
1807
        gen_op_iwmmxt_movq_M0_wRn(wrd);
 
1808
        switch ((insn >> 6) & 3) {
 
1809
        case 0:
 
1810
            tmp2 = tcg_const_i32(0xff);
 
1811
            tmp3 = tcg_const_i32((insn & 7) << 3);
 
1812
            break;
 
1813
        case 1:
 
1814
            tmp2 = tcg_const_i32(0xffff);
 
1815
            tmp3 = tcg_const_i32((insn & 3) << 4);
 
1816
            break;
 
1817
        case 2:
 
1818
            tmp2 = tcg_const_i32(0xffffffff);
 
1819
            tmp3 = tcg_const_i32((insn & 1) << 5);
 
1820
            break;
 
1821
        default:
 
1822
            TCGV_UNUSED_I32(tmp2);
 
1823
            TCGV_UNUSED_I32(tmp3);
 
1824
        }
 
1825
        gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
 
1826
        tcg_temp_free_i32(tmp3);
 
1827
        tcg_temp_free_i32(tmp2);
 
1828
        tcg_temp_free_i32(tmp);
 
1829
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1830
        gen_op_iwmmxt_set_mup();
 
1831
        break;
 
1832
    case 0x107: case 0x507: case 0x907: case 0xd07:     /* TEXTRM */
 
1833
        rd = (insn >> 12) & 0xf;
 
1834
        wrd = (insn >> 16) & 0xf;
 
1835
        if (rd == 15 || ((insn >> 22) & 3) == 3)
 
1836
            return 1;
 
1837
        gen_op_iwmmxt_movq_M0_wRn(wrd);
 
1838
        tmp = tcg_temp_new_i32();
 
1839
        switch ((insn >> 22) & 3) {
 
1840
        case 0:
 
1841
            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
 
1842
            tcg_gen_trunc_i64_i32(tmp, cpu_M0);
 
1843
            if (insn & 8) {
 
1844
                tcg_gen_ext8s_i32(tmp, tmp);
 
1845
            } else {
 
1846
                tcg_gen_andi_i32(tmp, tmp, 0xff);
 
1847
            }
 
1848
            break;
 
1849
        case 1:
 
1850
            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
 
1851
            tcg_gen_trunc_i64_i32(tmp, cpu_M0);
 
1852
            if (insn & 8) {
 
1853
                tcg_gen_ext16s_i32(tmp, tmp);
 
1854
            } else {
 
1855
                tcg_gen_andi_i32(tmp, tmp, 0xffff);
 
1856
            }
 
1857
            break;
 
1858
        case 2:
 
1859
            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
 
1860
            tcg_gen_trunc_i64_i32(tmp, cpu_M0);
 
1861
            break;
 
1862
        }
 
1863
        store_reg(s, rd, tmp);
 
1864
        break;
 
1865
    case 0x117: case 0x517: case 0x917: case 0xd17:     /* TEXTRC */
 
1866
        if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
 
1867
            return 1;
 
1868
        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
 
1869
        switch ((insn >> 22) & 3) {
 
1870
        case 0:
 
1871
            tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
 
1872
            break;
 
1873
        case 1:
 
1874
            tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
 
1875
            break;
 
1876
        case 2:
 
1877
            tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
 
1878
            break;
 
1879
        }
 
1880
        tcg_gen_shli_i32(tmp, tmp, 28);
 
1881
        gen_set_nzcv(tmp);
 
1882
        tcg_temp_free_i32(tmp);
 
1883
        break;
 
1884
    case 0x401: case 0x405: case 0x409: case 0x40d:     /* TBCST */
 
1885
        if (((insn >> 6) & 3) == 3)
 
1886
            return 1;
 
1887
        rd = (insn >> 12) & 0xf;
 
1888
        wrd = (insn >> 16) & 0xf;
 
1889
        tmp = load_reg(s, rd);
 
1890
        switch ((insn >> 6) & 3) {
 
1891
        case 0:
 
1892
            gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
 
1893
            break;
 
1894
        case 1:
 
1895
            gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
 
1896
            break;
 
1897
        case 2:
 
1898
            gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
 
1899
            break;
 
1900
        }
 
1901
        tcg_temp_free_i32(tmp);
 
1902
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1903
        gen_op_iwmmxt_set_mup();
 
1904
        break;
 
1905
    case 0x113: case 0x513: case 0x913: case 0xd13:     /* TANDC */
 
1906
        if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
 
1907
            return 1;
 
1908
        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
 
1909
        tmp2 = tcg_temp_new_i32();
 
1910
        tcg_gen_mov_i32(tmp2, tmp);
 
1911
        switch ((insn >> 22) & 3) {
 
1912
        case 0:
 
1913
            for (i = 0; i < 7; i ++) {
 
1914
                tcg_gen_shli_i32(tmp2, tmp2, 4);
 
1915
                tcg_gen_and_i32(tmp, tmp, tmp2);
 
1916
            }
 
1917
            break;
 
1918
        case 1:
 
1919
            for (i = 0; i < 3; i ++) {
 
1920
                tcg_gen_shli_i32(tmp2, tmp2, 8);
 
1921
                tcg_gen_and_i32(tmp, tmp, tmp2);
 
1922
            }
 
1923
            break;
 
1924
        case 2:
 
1925
            tcg_gen_shli_i32(tmp2, tmp2, 16);
 
1926
            tcg_gen_and_i32(tmp, tmp, tmp2);
 
1927
            break;
 
1928
        }
 
1929
        gen_set_nzcv(tmp);
 
1930
        tcg_temp_free_i32(tmp2);
 
1931
        tcg_temp_free_i32(tmp);
 
1932
        break;
 
1933
    case 0x01c: case 0x41c: case 0x81c: case 0xc1c:     /* WACC */
 
1934
        wrd = (insn >> 12) & 0xf;
 
1935
        rd0 = (insn >> 16) & 0xf;
 
1936
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1937
        switch ((insn >> 22) & 3) {
 
1938
        case 0:
 
1939
            gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
 
1940
            break;
 
1941
        case 1:
 
1942
            gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
 
1943
            break;
 
1944
        case 2:
 
1945
            gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
 
1946
            break;
 
1947
        case 3:
 
1948
            return 1;
 
1949
        }
 
1950
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
1951
        gen_op_iwmmxt_set_mup();
 
1952
        break;
 
1953
    case 0x115: case 0x515: case 0x915: case 0xd15:     /* TORC */
 
1954
        if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
 
1955
            return 1;
 
1956
        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
 
1957
        tmp2 = tcg_temp_new_i32();
 
1958
        tcg_gen_mov_i32(tmp2, tmp);
 
1959
        switch ((insn >> 22) & 3) {
 
1960
        case 0:
 
1961
            for (i = 0; i < 7; i ++) {
 
1962
                tcg_gen_shli_i32(tmp2, tmp2, 4);
 
1963
                tcg_gen_or_i32(tmp, tmp, tmp2);
 
1964
            }
 
1965
            break;
 
1966
        case 1:
 
1967
            for (i = 0; i < 3; i ++) {
 
1968
                tcg_gen_shli_i32(tmp2, tmp2, 8);
 
1969
                tcg_gen_or_i32(tmp, tmp, tmp2);
 
1970
            }
 
1971
            break;
 
1972
        case 2:
 
1973
            tcg_gen_shli_i32(tmp2, tmp2, 16);
 
1974
            tcg_gen_or_i32(tmp, tmp, tmp2);
 
1975
            break;
 
1976
        }
 
1977
        gen_set_nzcv(tmp);
 
1978
        tcg_temp_free_i32(tmp2);
 
1979
        tcg_temp_free_i32(tmp);
 
1980
        break;
 
1981
    case 0x103: case 0x503: case 0x903: case 0xd03:     /* TMOVMSK */
 
1982
        rd = (insn >> 12) & 0xf;
 
1983
        rd0 = (insn >> 16) & 0xf;
 
1984
        if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
 
1985
            return 1;
 
1986
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
1987
        tmp = tcg_temp_new_i32();
 
1988
        switch ((insn >> 22) & 3) {
 
1989
        case 0:
 
1990
            gen_helper_iwmmxt_msbb(tmp, cpu_M0);
 
1991
            break;
 
1992
        case 1:
 
1993
            gen_helper_iwmmxt_msbw(tmp, cpu_M0);
 
1994
            break;
 
1995
        case 2:
 
1996
            gen_helper_iwmmxt_msbl(tmp, cpu_M0);
 
1997
            break;
 
1998
        }
 
1999
        store_reg(s, rd, tmp);
 
2000
        break;
 
2001
    case 0x106: case 0x306: case 0x506: case 0x706:     /* WCMPGT */
 
2002
    case 0x906: case 0xb06: case 0xd06: case 0xf06:
 
2003
        wrd = (insn >> 12) & 0xf;
 
2004
        rd0 = (insn >> 16) & 0xf;
 
2005
        rd1 = (insn >> 0) & 0xf;
 
2006
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2007
        switch ((insn >> 22) & 3) {
 
2008
        case 0:
 
2009
            if (insn & (1 << 21))
 
2010
                gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
 
2011
            else
 
2012
                gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
 
2013
            break;
 
2014
        case 1:
 
2015
            if (insn & (1 << 21))
 
2016
                gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
 
2017
            else
 
2018
                gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
 
2019
            break;
 
2020
        case 2:
 
2021
            if (insn & (1 << 21))
 
2022
                gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
 
2023
            else
 
2024
                gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
 
2025
            break;
 
2026
        case 3:
 
2027
            return 1;
 
2028
        }
 
2029
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2030
        gen_op_iwmmxt_set_mup();
 
2031
        gen_op_iwmmxt_set_cup();
 
2032
        break;
 
2033
    case 0x00e: case 0x20e: case 0x40e: case 0x60e:     /* WUNPCKEL */
 
2034
    case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
 
2035
        wrd = (insn >> 12) & 0xf;
 
2036
        rd0 = (insn >> 16) & 0xf;
 
2037
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2038
        switch ((insn >> 22) & 3) {
 
2039
        case 0:
 
2040
            if (insn & (1 << 21))
 
2041
                gen_op_iwmmxt_unpacklsb_M0();
 
2042
            else
 
2043
                gen_op_iwmmxt_unpacklub_M0();
 
2044
            break;
 
2045
        case 1:
 
2046
            if (insn & (1 << 21))
 
2047
                gen_op_iwmmxt_unpacklsw_M0();
 
2048
            else
 
2049
                gen_op_iwmmxt_unpackluw_M0();
 
2050
            break;
 
2051
        case 2:
 
2052
            if (insn & (1 << 21))
 
2053
                gen_op_iwmmxt_unpacklsl_M0();
 
2054
            else
 
2055
                gen_op_iwmmxt_unpacklul_M0();
 
2056
            break;
 
2057
        case 3:
 
2058
            return 1;
 
2059
        }
 
2060
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2061
        gen_op_iwmmxt_set_mup();
 
2062
        gen_op_iwmmxt_set_cup();
 
2063
        break;
 
2064
    case 0x00c: case 0x20c: case 0x40c: case 0x60c:     /* WUNPCKEH */
 
2065
    case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
 
2066
        wrd = (insn >> 12) & 0xf;
 
2067
        rd0 = (insn >> 16) & 0xf;
 
2068
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2069
        switch ((insn >> 22) & 3) {
 
2070
        case 0:
 
2071
            if (insn & (1 << 21))
 
2072
                gen_op_iwmmxt_unpackhsb_M0();
 
2073
            else
 
2074
                gen_op_iwmmxt_unpackhub_M0();
 
2075
            break;
 
2076
        case 1:
 
2077
            if (insn & (1 << 21))
 
2078
                gen_op_iwmmxt_unpackhsw_M0();
 
2079
            else
 
2080
                gen_op_iwmmxt_unpackhuw_M0();
 
2081
            break;
 
2082
        case 2:
 
2083
            if (insn & (1 << 21))
 
2084
                gen_op_iwmmxt_unpackhsl_M0();
 
2085
            else
 
2086
                gen_op_iwmmxt_unpackhul_M0();
 
2087
            break;
 
2088
        case 3:
 
2089
            return 1;
 
2090
        }
 
2091
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2092
        gen_op_iwmmxt_set_mup();
 
2093
        gen_op_iwmmxt_set_cup();
 
2094
        break;
 
2095
    case 0x204: case 0x604: case 0xa04: case 0xe04:     /* WSRL */
 
2096
    case 0x214: case 0x614: case 0xa14: case 0xe14:
 
2097
        if (((insn >> 22) & 3) == 0)
 
2098
            return 1;
 
2099
        wrd = (insn >> 12) & 0xf;
 
2100
        rd0 = (insn >> 16) & 0xf;
 
2101
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2102
        tmp = tcg_temp_new_i32();
 
2103
        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
 
2104
            tcg_temp_free_i32(tmp);
 
2105
            return 1;
 
2106
        }
 
2107
        switch ((insn >> 22) & 3) {
 
2108
        case 1:
 
2109
            gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
 
2110
            break;
 
2111
        case 2:
 
2112
            gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
 
2113
            break;
 
2114
        case 3:
 
2115
            gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
 
2116
            break;
 
2117
        }
 
2118
        tcg_temp_free_i32(tmp);
 
2119
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2120
        gen_op_iwmmxt_set_mup();
 
2121
        gen_op_iwmmxt_set_cup();
 
2122
        break;
 
2123
    case 0x004: case 0x404: case 0x804: case 0xc04:     /* WSRA */
 
2124
    case 0x014: case 0x414: case 0x814: case 0xc14:
 
2125
        if (((insn >> 22) & 3) == 0)
 
2126
            return 1;
 
2127
        wrd = (insn >> 12) & 0xf;
 
2128
        rd0 = (insn >> 16) & 0xf;
 
2129
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2130
        tmp = tcg_temp_new_i32();
 
2131
        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
 
2132
            tcg_temp_free_i32(tmp);
 
2133
            return 1;
 
2134
        }
 
2135
        switch ((insn >> 22) & 3) {
 
2136
        case 1:
 
2137
            gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
 
2138
            break;
 
2139
        case 2:
 
2140
            gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
 
2141
            break;
 
2142
        case 3:
 
2143
            gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
 
2144
            break;
 
2145
        }
 
2146
        tcg_temp_free_i32(tmp);
 
2147
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2148
        gen_op_iwmmxt_set_mup();
 
2149
        gen_op_iwmmxt_set_cup();
 
2150
        break;
 
2151
    case 0x104: case 0x504: case 0x904: case 0xd04:     /* WSLL */
 
2152
    case 0x114: case 0x514: case 0x914: case 0xd14:
 
2153
        if (((insn >> 22) & 3) == 0)
 
2154
            return 1;
 
2155
        wrd = (insn >> 12) & 0xf;
 
2156
        rd0 = (insn >> 16) & 0xf;
 
2157
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2158
        tmp = tcg_temp_new_i32();
 
2159
        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
 
2160
            tcg_temp_free_i32(tmp);
 
2161
            return 1;
 
2162
        }
 
2163
        switch ((insn >> 22) & 3) {
 
2164
        case 1:
 
2165
            gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
 
2166
            break;
 
2167
        case 2:
 
2168
            gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
 
2169
            break;
 
2170
        case 3:
 
2171
            gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
 
2172
            break;
 
2173
        }
 
2174
        tcg_temp_free_i32(tmp);
 
2175
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2176
        gen_op_iwmmxt_set_mup();
 
2177
        gen_op_iwmmxt_set_cup();
 
2178
        break;
 
2179
    case 0x304: case 0x704: case 0xb04: case 0xf04:     /* WROR */
 
2180
    case 0x314: case 0x714: case 0xb14: case 0xf14:
 
2181
        if (((insn >> 22) & 3) == 0)
 
2182
            return 1;
 
2183
        wrd = (insn >> 12) & 0xf;
 
2184
        rd0 = (insn >> 16) & 0xf;
 
2185
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2186
        tmp = tcg_temp_new_i32();
 
2187
        switch ((insn >> 22) & 3) {
 
2188
        case 1:
 
2189
            if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
 
2190
                tcg_temp_free_i32(tmp);
 
2191
                return 1;
 
2192
            }
 
2193
            gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
 
2194
            break;
 
2195
        case 2:
 
2196
            if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
 
2197
                tcg_temp_free_i32(tmp);
 
2198
                return 1;
 
2199
            }
 
2200
            gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
 
2201
            break;
 
2202
        case 3:
 
2203
            if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
 
2204
                tcg_temp_free_i32(tmp);
 
2205
                return 1;
 
2206
            }
 
2207
            gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
 
2208
            break;
 
2209
        }
 
2210
        tcg_temp_free_i32(tmp);
 
2211
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2212
        gen_op_iwmmxt_set_mup();
 
2213
        gen_op_iwmmxt_set_cup();
 
2214
        break;
 
2215
    case 0x116: case 0x316: case 0x516: case 0x716:     /* WMIN */
 
2216
    case 0x916: case 0xb16: case 0xd16: case 0xf16:
 
2217
        wrd = (insn >> 12) & 0xf;
 
2218
        rd0 = (insn >> 16) & 0xf;
 
2219
        rd1 = (insn >> 0) & 0xf;
 
2220
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2221
        switch ((insn >> 22) & 3) {
 
2222
        case 0:
 
2223
            if (insn & (1 << 21))
 
2224
                gen_op_iwmmxt_minsb_M0_wRn(rd1);
 
2225
            else
 
2226
                gen_op_iwmmxt_minub_M0_wRn(rd1);
 
2227
            break;
 
2228
        case 1:
 
2229
            if (insn & (1 << 21))
 
2230
                gen_op_iwmmxt_minsw_M0_wRn(rd1);
 
2231
            else
 
2232
                gen_op_iwmmxt_minuw_M0_wRn(rd1);
 
2233
            break;
 
2234
        case 2:
 
2235
            if (insn & (1 << 21))
 
2236
                gen_op_iwmmxt_minsl_M0_wRn(rd1);
 
2237
            else
 
2238
                gen_op_iwmmxt_minul_M0_wRn(rd1);
 
2239
            break;
 
2240
        case 3:
 
2241
            return 1;
 
2242
        }
 
2243
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2244
        gen_op_iwmmxt_set_mup();
 
2245
        break;
 
2246
    case 0x016: case 0x216: case 0x416: case 0x616:     /* WMAX */
 
2247
    case 0x816: case 0xa16: case 0xc16: case 0xe16:
 
2248
        wrd = (insn >> 12) & 0xf;
 
2249
        rd0 = (insn >> 16) & 0xf;
 
2250
        rd1 = (insn >> 0) & 0xf;
 
2251
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2252
        switch ((insn >> 22) & 3) {
 
2253
        case 0:
 
2254
            if (insn & (1 << 21))
 
2255
                gen_op_iwmmxt_maxsb_M0_wRn(rd1);
 
2256
            else
 
2257
                gen_op_iwmmxt_maxub_M0_wRn(rd1);
 
2258
            break;
 
2259
        case 1:
 
2260
            if (insn & (1 << 21))
 
2261
                gen_op_iwmmxt_maxsw_M0_wRn(rd1);
 
2262
            else
 
2263
                gen_op_iwmmxt_maxuw_M0_wRn(rd1);
 
2264
            break;
 
2265
        case 2:
 
2266
            if (insn & (1 << 21))
 
2267
                gen_op_iwmmxt_maxsl_M0_wRn(rd1);
 
2268
            else
 
2269
                gen_op_iwmmxt_maxul_M0_wRn(rd1);
 
2270
            break;
 
2271
        case 3:
 
2272
            return 1;
 
2273
        }
 
2274
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2275
        gen_op_iwmmxt_set_mup();
 
2276
        break;
 
2277
    case 0x002: case 0x102: case 0x202: case 0x302:     /* WALIGNI */
 
2278
    case 0x402: case 0x502: case 0x602: case 0x702:
 
2279
        wrd = (insn >> 12) & 0xf;
 
2280
        rd0 = (insn >> 16) & 0xf;
 
2281
        rd1 = (insn >> 0) & 0xf;
 
2282
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2283
        tmp = tcg_const_i32((insn >> 20) & 3);
 
2284
        iwmmxt_load_reg(cpu_V1, rd1);
 
2285
        gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
 
2286
        tcg_temp_free_i32(tmp);
 
2287
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2288
        gen_op_iwmmxt_set_mup();
 
2289
        break;
 
2290
    case 0x01a: case 0x11a: case 0x21a: case 0x31a:     /* WSUB */
 
2291
    case 0x41a: case 0x51a: case 0x61a: case 0x71a:
 
2292
    case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
 
2293
    case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
 
2294
        wrd = (insn >> 12) & 0xf;
 
2295
        rd0 = (insn >> 16) & 0xf;
 
2296
        rd1 = (insn >> 0) & 0xf;
 
2297
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2298
        switch ((insn >> 20) & 0xf) {
 
2299
        case 0x0:
 
2300
            gen_op_iwmmxt_subnb_M0_wRn(rd1);
 
2301
            break;
 
2302
        case 0x1:
 
2303
            gen_op_iwmmxt_subub_M0_wRn(rd1);
 
2304
            break;
 
2305
        case 0x3:
 
2306
            gen_op_iwmmxt_subsb_M0_wRn(rd1);
 
2307
            break;
 
2308
        case 0x4:
 
2309
            gen_op_iwmmxt_subnw_M0_wRn(rd1);
 
2310
            break;
 
2311
        case 0x5:
 
2312
            gen_op_iwmmxt_subuw_M0_wRn(rd1);
 
2313
            break;
 
2314
        case 0x7:
 
2315
            gen_op_iwmmxt_subsw_M0_wRn(rd1);
 
2316
            break;
 
2317
        case 0x8:
 
2318
            gen_op_iwmmxt_subnl_M0_wRn(rd1);
 
2319
            break;
 
2320
        case 0x9:
 
2321
            gen_op_iwmmxt_subul_M0_wRn(rd1);
 
2322
            break;
 
2323
        case 0xb:
 
2324
            gen_op_iwmmxt_subsl_M0_wRn(rd1);
 
2325
            break;
 
2326
        default:
 
2327
            return 1;
 
2328
        }
 
2329
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2330
        gen_op_iwmmxt_set_mup();
 
2331
        gen_op_iwmmxt_set_cup();
 
2332
        break;
 
2333
    case 0x01e: case 0x11e: case 0x21e: case 0x31e:     /* WSHUFH */
 
2334
    case 0x41e: case 0x51e: case 0x61e: case 0x71e:
 
2335
    case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
 
2336
    case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
 
2337
        wrd = (insn >> 12) & 0xf;
 
2338
        rd0 = (insn >> 16) & 0xf;
 
2339
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2340
        tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
 
2341
        gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
 
2342
        tcg_temp_free_i32(tmp);
 
2343
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2344
        gen_op_iwmmxt_set_mup();
 
2345
        gen_op_iwmmxt_set_cup();
 
2346
        break;
 
2347
    case 0x018: case 0x118: case 0x218: case 0x318:     /* WADD */
 
2348
    case 0x418: case 0x518: case 0x618: case 0x718:
 
2349
    case 0x818: case 0x918: case 0xa18: case 0xb18:
 
2350
    case 0xc18: case 0xd18: case 0xe18: case 0xf18:
 
2351
        wrd = (insn >> 12) & 0xf;
 
2352
        rd0 = (insn >> 16) & 0xf;
 
2353
        rd1 = (insn >> 0) & 0xf;
 
2354
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2355
        switch ((insn >> 20) & 0xf) {
 
2356
        case 0x0:
 
2357
            gen_op_iwmmxt_addnb_M0_wRn(rd1);
 
2358
            break;
 
2359
        case 0x1:
 
2360
            gen_op_iwmmxt_addub_M0_wRn(rd1);
 
2361
            break;
 
2362
        case 0x3:
 
2363
            gen_op_iwmmxt_addsb_M0_wRn(rd1);
 
2364
            break;
 
2365
        case 0x4:
 
2366
            gen_op_iwmmxt_addnw_M0_wRn(rd1);
 
2367
            break;
 
2368
        case 0x5:
 
2369
            gen_op_iwmmxt_adduw_M0_wRn(rd1);
 
2370
            break;
 
2371
        case 0x7:
 
2372
            gen_op_iwmmxt_addsw_M0_wRn(rd1);
 
2373
            break;
 
2374
        case 0x8:
 
2375
            gen_op_iwmmxt_addnl_M0_wRn(rd1);
 
2376
            break;
 
2377
        case 0x9:
 
2378
            gen_op_iwmmxt_addul_M0_wRn(rd1);
 
2379
            break;
 
2380
        case 0xb:
 
2381
            gen_op_iwmmxt_addsl_M0_wRn(rd1);
 
2382
            break;
 
2383
        default:
 
2384
            return 1;
 
2385
        }
 
2386
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2387
        gen_op_iwmmxt_set_mup();
 
2388
        gen_op_iwmmxt_set_cup();
 
2389
        break;
 
2390
    case 0x008: case 0x108: case 0x208: case 0x308:     /* WPACK */
 
2391
    case 0x408: case 0x508: case 0x608: case 0x708:
 
2392
    case 0x808: case 0x908: case 0xa08: case 0xb08:
 
2393
    case 0xc08: case 0xd08: case 0xe08: case 0xf08:
 
2394
        if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
 
2395
            return 1;
 
2396
        wrd = (insn >> 12) & 0xf;
 
2397
        rd0 = (insn >> 16) & 0xf;
 
2398
        rd1 = (insn >> 0) & 0xf;
 
2399
        gen_op_iwmmxt_movq_M0_wRn(rd0);
 
2400
        switch ((insn >> 22) & 3) {
 
2401
        case 1:
 
2402
            if (insn & (1 << 21))
 
2403
                gen_op_iwmmxt_packsw_M0_wRn(rd1);
 
2404
            else
 
2405
                gen_op_iwmmxt_packuw_M0_wRn(rd1);
 
2406
            break;
 
2407
        case 2:
 
2408
            if (insn & (1 << 21))
 
2409
                gen_op_iwmmxt_packsl_M0_wRn(rd1);
 
2410
            else
 
2411
                gen_op_iwmmxt_packul_M0_wRn(rd1);
 
2412
            break;
 
2413
        case 3:
 
2414
            if (insn & (1 << 21))
 
2415
                gen_op_iwmmxt_packsq_M0_wRn(rd1);
 
2416
            else
 
2417
                gen_op_iwmmxt_packuq_M0_wRn(rd1);
 
2418
            break;
 
2419
        }
 
2420
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2421
        gen_op_iwmmxt_set_mup();
 
2422
        gen_op_iwmmxt_set_cup();
 
2423
        break;
 
2424
    case 0x201: case 0x203: case 0x205: case 0x207:
 
2425
    case 0x209: case 0x20b: case 0x20d: case 0x20f:
 
2426
    case 0x211: case 0x213: case 0x215: case 0x217:
 
2427
    case 0x219: case 0x21b: case 0x21d: case 0x21f:
 
2428
        wrd = (insn >> 5) & 0xf;
 
2429
        rd0 = (insn >> 12) & 0xf;
 
2430
        rd1 = (insn >> 0) & 0xf;
 
2431
        if (rd0 == 0xf || rd1 == 0xf)
 
2432
            return 1;
 
2433
        gen_op_iwmmxt_movq_M0_wRn(wrd);
 
2434
        tmp = load_reg(s, rd0);
 
2435
        tmp2 = load_reg(s, rd1);
 
2436
        switch ((insn >> 16) & 0xf) {
 
2437
        case 0x0:                                       /* TMIA */
 
2438
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
 
2439
            break;
 
2440
        case 0x8:                                       /* TMIAPH */
 
2441
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
 
2442
            break;
 
2443
        case 0xc: case 0xd: case 0xe: case 0xf:         /* TMIAxy */
 
2444
            if (insn & (1 << 16))
 
2445
                tcg_gen_shri_i32(tmp, tmp, 16);
 
2446
            if (insn & (1 << 17))
 
2447
                tcg_gen_shri_i32(tmp2, tmp2, 16);
 
2448
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
 
2449
            break;
 
2450
        default:
 
2451
            tcg_temp_free_i32(tmp2);
 
2452
            tcg_temp_free_i32(tmp);
 
2453
            return 1;
 
2454
        }
 
2455
        tcg_temp_free_i32(tmp2);
 
2456
        tcg_temp_free_i32(tmp);
 
2457
        gen_op_iwmmxt_movq_wRn_M0(wrd);
 
2458
        gen_op_iwmmxt_set_mup();
 
2459
        break;
 
2460
    default:
 
2461
        return 1;
 
2462
    }
 
2463
 
 
2464
    return 0;
 
2465
}
 
2466
 
 
2467
/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occurred
 
2468
   (ie. an undefined instruction).  */
 
2469
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 
2470
{
 
2471
    int acc, rd0, rd1, rdhi, rdlo;
 
2472
    TCGv_i32 tmp, tmp2;
 
2473
 
 
2474
    if ((insn & 0x0ff00f10) == 0x0e200010) {
 
2475
        /* Multiply with Internal Accumulate Format */
 
2476
        rd0 = (insn >> 12) & 0xf;
 
2477
        rd1 = insn & 0xf;
 
2478
        acc = (insn >> 5) & 7;
 
2479
 
 
2480
        if (acc != 0)
 
2481
            return 1;
 
2482
 
 
2483
        tmp = load_reg(s, rd0);
 
2484
        tmp2 = load_reg(s, rd1);
 
2485
        switch ((insn >> 16) & 0xf) {
 
2486
        case 0x0:                                       /* MIA */
 
2487
            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
 
2488
            break;
 
2489
        case 0x8:                                       /* MIAPH */
 
2490
            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
 
2491
            break;
 
2492
        case 0xc:                                       /* MIABB */
 
2493
        case 0xd:                                       /* MIABT */
 
2494
        case 0xe:                                       /* MIATB */
 
2495
        case 0xf:                                       /* MIATT */
 
2496
            if (insn & (1 << 16))
 
2497
                tcg_gen_shri_i32(tmp, tmp, 16);
 
2498
            if (insn & (1 << 17))
 
2499
                tcg_gen_shri_i32(tmp2, tmp2, 16);
 
2500
            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
 
2501
            break;
 
2502
        default:
 
2503
            return 1;
 
2504
        }
 
2505
        tcg_temp_free_i32(tmp2);
 
2506
        tcg_temp_free_i32(tmp);
 
2507
 
 
2508
        gen_op_iwmmxt_movq_wRn_M0(acc);
 
2509
        return 0;
 
2510
    }
 
2511
 
 
2512
    if ((insn & 0x0fe00ff8) == 0x0c400000) {
 
2513
        /* Internal Accumulator Access Format */
 
2514
        rdhi = (insn >> 16) & 0xf;
 
2515
        rdlo = (insn >> 12) & 0xf;
 
2516
        acc = insn & 7;
 
2517
 
 
2518
        if (acc != 0)
 
2519
            return 1;
 
2520
 
 
2521
        if (insn & ARM_CP_RW_BIT) {                     /* MRA */
 
2522
            iwmmxt_load_reg(cpu_V0, acc);
 
2523
            tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
 
2524
            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
 
2525
            tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
 
2526
            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
 
2527
        } else {                                        /* MAR */
 
2528
            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
 
2529
            iwmmxt_store_reg(cpu_V0, acc);
 
2530
        }
 
2531
        return 0;
 
2532
    }
 
2533
 
 
2534
    return 1;
 
2535
}
 
2536
 
 
2537
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
 
2538
#define VFP_SREG(insn, bigbit, smallbit) \
 
2539
  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
 
2540
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
 
2541
    if (arm_feature(env, ARM_FEATURE_VFP3)) { \
 
2542
        reg = (((insn) >> (bigbit)) & 0x0f) \
 
2543
              | (((insn) >> ((smallbit) - 4)) & 0x10); \
 
2544
    } else { \
 
2545
        if (insn & (1 << (smallbit))) \
 
2546
            return 1; \
 
2547
        reg = ((insn) >> (bigbit)) & 0x0f; \
 
2548
    }} while (0)
 
2549
 
 
2550
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
 
2551
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
 
2552
#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
 
2553
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
 
2554
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
 
2555
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
 
2556
 
 
2557
/* Move between integer and VFP cores.  */
 
2558
static TCGv_i32 gen_vfp_mrs(void)
 
2559
{
 
2560
    TCGv_i32 tmp = tcg_temp_new_i32();
 
2561
    tcg_gen_mov_i32(tmp, cpu_F0s);
 
2562
    return tmp;
 
2563
}
 
2564
 
 
2565
static void gen_vfp_msr(TCGv_i32 tmp)
 
2566
{
 
2567
    tcg_gen_mov_i32(cpu_F0s, tmp);
 
2568
    tcg_temp_free_i32(tmp);
 
2569
}
 
2570
 
 
2571
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
 
2572
{
 
2573
    TCGv_i32 tmp = tcg_temp_new_i32();
 
2574
    if (shift)
 
2575
        tcg_gen_shri_i32(var, var, shift);
 
2576
    tcg_gen_ext8u_i32(var, var);
 
2577
    tcg_gen_shli_i32(tmp, var, 8);
 
2578
    tcg_gen_or_i32(var, var, tmp);
 
2579
    tcg_gen_shli_i32(tmp, var, 16);
 
2580
    tcg_gen_or_i32(var, var, tmp);
 
2581
    tcg_temp_free_i32(tmp);
 
2582
}
 
2583
 
 
2584
static void gen_neon_dup_low16(TCGv_i32 var)
 
2585
{
 
2586
    TCGv_i32 tmp = tcg_temp_new_i32();
 
2587
    tcg_gen_ext16u_i32(var, var);
 
2588
    tcg_gen_shli_i32(tmp, var, 16);
 
2589
    tcg_gen_or_i32(var, var, tmp);
 
2590
    tcg_temp_free_i32(tmp);
 
2591
}
 
2592
 
 
2593
static void gen_neon_dup_high16(TCGv_i32 var)
 
2594
{
 
2595
    TCGv_i32 tmp = tcg_temp_new_i32();
 
2596
    tcg_gen_andi_i32(var, var, 0xffff0000);
 
2597
    tcg_gen_shri_i32(tmp, var, 16);
 
2598
    tcg_gen_or_i32(var, var, tmp);
 
2599
    tcg_temp_free_i32(tmp);
 
2600
}
 
2601
 
 
2602
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
 
2603
{
 
2604
    /* Load a single Neon element and replicate into a 32 bit TCG reg */
 
2605
    TCGv_i32 tmp = tcg_temp_new_i32();
 
2606
    switch (size) {
 
2607
    case 0:
 
2608
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
2609
        gen_neon_dup_u8(tmp, 0);
 
2610
        break;
 
2611
    case 1:
 
2612
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
2613
        gen_neon_dup_low16(tmp);
 
2614
        break;
 
2615
    case 2:
 
2616
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
2617
        break;
 
2618
    default: /* Avoid compiler warnings.  */
 
2619
        abort();
 
2620
    }
 
2621
    return tmp;
 
2622
}
 
2623
 
 
2624
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
 
2625
                       uint32_t dp)
 
2626
{
 
2627
    uint32_t cc = extract32(insn, 20, 2);
 
2628
 
 
2629
    if (dp) {
 
2630
        TCGv_i64 frn, frm, dest;
 
2631
        TCGv_i64 tmp, zero, zf, nf, vf;
 
2632
 
 
2633
        zero = tcg_const_i64(0);
 
2634
 
 
2635
        frn = tcg_temp_new_i64();
 
2636
        frm = tcg_temp_new_i64();
 
2637
        dest = tcg_temp_new_i64();
 
2638
 
 
2639
        zf = tcg_temp_new_i64();
 
2640
        nf = tcg_temp_new_i64();
 
2641
        vf = tcg_temp_new_i64();
 
2642
 
 
2643
        tcg_gen_extu_i32_i64(zf, cpu_ZF);
 
2644
        tcg_gen_ext_i32_i64(nf, cpu_NF);
 
2645
        tcg_gen_ext_i32_i64(vf, cpu_VF);
 
2646
 
 
2647
        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
 
2648
        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
 
2649
        switch (cc) {
 
2650
        case 0: /* eq: Z */
 
2651
            tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
 
2652
                                frn, frm);
 
2653
            break;
 
2654
        case 1: /* vs: V */
 
2655
            tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
 
2656
                                frn, frm);
 
2657
            break;
 
2658
        case 2: /* ge: N == V -> N ^ V == 0 */
 
2659
            tmp = tcg_temp_new_i64();
 
2660
            tcg_gen_xor_i64(tmp, vf, nf);
 
2661
            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
 
2662
                                frn, frm);
 
2663
            tcg_temp_free_i64(tmp);
 
2664
            break;
 
2665
        case 3: /* gt: !Z && N == V */
 
2666
            tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
 
2667
                                frn, frm);
 
2668
            tmp = tcg_temp_new_i64();
 
2669
            tcg_gen_xor_i64(tmp, vf, nf);
 
2670
            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
 
2671
                                dest, frm);
 
2672
            tcg_temp_free_i64(tmp);
 
2673
            break;
 
2674
        }
 
2675
        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
 
2676
        tcg_temp_free_i64(frn);
 
2677
        tcg_temp_free_i64(frm);
 
2678
        tcg_temp_free_i64(dest);
 
2679
 
 
2680
        tcg_temp_free_i64(zf);
 
2681
        tcg_temp_free_i64(nf);
 
2682
        tcg_temp_free_i64(vf);
 
2683
 
 
2684
        tcg_temp_free_i64(zero);
 
2685
    } else {
 
2686
        TCGv_i32 frn, frm, dest;
 
2687
        TCGv_i32 tmp, zero;
 
2688
 
 
2689
        zero = tcg_const_i32(0);
 
2690
 
 
2691
        frn = tcg_temp_new_i32();
 
2692
        frm = tcg_temp_new_i32();
 
2693
        dest = tcg_temp_new_i32();
 
2694
        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
 
2695
        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
 
2696
        switch (cc) {
 
2697
        case 0: /* eq: Z */
 
2698
            tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
 
2699
                                frn, frm);
 
2700
            break;
 
2701
        case 1: /* vs: V */
 
2702
            tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
 
2703
                                frn, frm);
 
2704
            break;
 
2705
        case 2: /* ge: N == V -> N ^ V == 0 */
 
2706
            tmp = tcg_temp_new_i32();
 
2707
            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
 
2708
            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
 
2709
                                frn, frm);
 
2710
            tcg_temp_free_i32(tmp);
 
2711
            break;
 
2712
        case 3: /* gt: !Z && N == V */
 
2713
            tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
 
2714
                                frn, frm);
 
2715
            tmp = tcg_temp_new_i32();
 
2716
            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
 
2717
            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
 
2718
                                dest, frm);
 
2719
            tcg_temp_free_i32(tmp);
 
2720
            break;
 
2721
        }
 
2722
        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
 
2723
        tcg_temp_free_i32(frn);
 
2724
        tcg_temp_free_i32(frm);
 
2725
        tcg_temp_free_i32(dest);
 
2726
 
 
2727
        tcg_temp_free_i32(zero);
 
2728
    }
 
2729
 
 
2730
    return 0;
 
2731
}
 
2732
 
 
2733
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 
2734
{
 
2735
    uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
 
2736
 
 
2737
    if (!arm_feature(env, ARM_FEATURE_V8)) {
 
2738
        return 1;
 
2739
    }
 
2740
 
 
2741
    if (dp) {
 
2742
        VFP_DREG_D(rd, insn);
 
2743
        VFP_DREG_N(rn, insn);
 
2744
        VFP_DREG_M(rm, insn);
 
2745
    } else {
 
2746
        rd = VFP_SREG_D(insn);
 
2747
        rn = VFP_SREG_N(insn);
 
2748
        rm = VFP_SREG_M(insn);
 
2749
    }
 
2750
 
 
2751
    if ((insn & 0x0f800e50) == 0x0e000a00) {
 
2752
        return handle_vsel(insn, rd, rn, rm, dp);
 
2753
    }
 
2754
    return 1;
 
2755
}
 
2756
 
 
2757
/* Disassemble a VFP instruction.  Returns nonzero if an error occurred
 
2758
   (ie. an undefined instruction).  */
 
2759
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 
2760
{
 
2761
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
 
2762
    int dp, veclen;
 
2763
    TCGv_i32 addr;
 
2764
    TCGv_i32 tmp;
 
2765
    TCGv_i32 tmp2;
 
2766
 
 
2767
    if (!arm_feature(env, ARM_FEATURE_VFP))
 
2768
        return 1;
 
2769
 
 
2770
    if (!s->vfp_enabled) {
 
2771
        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
 
2772
        if ((insn & 0x0fe00fff) != 0x0ee00a10)
 
2773
            return 1;
 
2774
        rn = (insn >> 16) & 0xf;
 
2775
        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
 
2776
            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
 
2777
            return 1;
 
2778
    }
 
2779
 
 
2780
    if (extract32(insn, 28, 4) == 0xf) {
 
2781
        /* Encodings with T=1 (Thumb) or unconditional (ARM):
 
2782
         * only used in v8 and above.
 
2783
         */
 
2784
        return disas_vfp_v8_insn(env, s, insn);
 
2785
    }
 
2786
 
 
2787
    dp = ((insn & 0xf00) == 0xb00);
 
2788
    switch ((insn >> 24) & 0xf) {
 
2789
    case 0xe:
 
2790
        if (insn & (1 << 4)) {
 
2791
            /* single register transfer */
 
2792
            rd = (insn >> 12) & 0xf;
 
2793
            if (dp) {
 
2794
                int size;
 
2795
                int pass;
 
2796
 
 
2797
                VFP_DREG_N(rn, insn);
 
2798
                if (insn & 0xf)
 
2799
                    return 1;
 
2800
                if (insn & 0x00c00060
 
2801
                    && !arm_feature(env, ARM_FEATURE_NEON))
 
2802
                    return 1;
 
2803
 
 
2804
                pass = (insn >> 21) & 1;
 
2805
                if (insn & (1 << 22)) {
 
2806
                    size = 0;
 
2807
                    offset = ((insn >> 5) & 3) * 8;
 
2808
                } else if (insn & (1 << 5)) {
 
2809
                    size = 1;
 
2810
                    offset = (insn & (1 << 6)) ? 16 : 0;
 
2811
                } else {
 
2812
                    size = 2;
 
2813
                    offset = 0;
 
2814
                }
 
2815
                if (insn & ARM_CP_RW_BIT) {
 
2816
                    /* vfp->arm */
 
2817
                    tmp = neon_load_reg(rn, pass);
 
2818
                    switch (size) {
 
2819
                    case 0:
 
2820
                        if (offset)
 
2821
                            tcg_gen_shri_i32(tmp, tmp, offset);
 
2822
                        if (insn & (1 << 23))
 
2823
                            gen_uxtb(tmp);
 
2824
                        else
 
2825
                            gen_sxtb(tmp);
 
2826
                        break;
 
2827
                    case 1:
 
2828
                        if (insn & (1 << 23)) {
 
2829
                            if (offset) {
 
2830
                                tcg_gen_shri_i32(tmp, tmp, 16);
 
2831
                            } else {
 
2832
                                gen_uxth(tmp);
 
2833
                            }
 
2834
                        } else {
 
2835
                            if (offset) {
 
2836
                                tcg_gen_sari_i32(tmp, tmp, 16);
 
2837
                            } else {
 
2838
                                gen_sxth(tmp);
 
2839
                            }
 
2840
                        }
 
2841
                        break;
 
2842
                    case 2:
 
2843
                        break;
 
2844
                    }
 
2845
                    store_reg(s, rd, tmp);
 
2846
                } else {
 
2847
                    /* arm->vfp */
 
2848
                    tmp = load_reg(s, rd);
 
2849
                    if (insn & (1 << 23)) {
 
2850
                        /* VDUP */
 
2851
                        if (size == 0) {
 
2852
                            gen_neon_dup_u8(tmp, 0);
 
2853
                        } else if (size == 1) {
 
2854
                            gen_neon_dup_low16(tmp);
 
2855
                        }
 
2856
                        for (n = 0; n <= pass * 2; n++) {
 
2857
                            tmp2 = tcg_temp_new_i32();
 
2858
                            tcg_gen_mov_i32(tmp2, tmp);
 
2859
                            neon_store_reg(rn, n, tmp2);
 
2860
                        }
 
2861
                        neon_store_reg(rn, n, tmp);
 
2862
                    } else {
 
2863
                        /* VMOV */
 
2864
                        switch (size) {
 
2865
                        case 0:
 
2866
                            tmp2 = neon_load_reg(rn, pass);
 
2867
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
 
2868
                            tcg_temp_free_i32(tmp2);
 
2869
                            break;
 
2870
                        case 1:
 
2871
                            tmp2 = neon_load_reg(rn, pass);
 
2872
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
 
2873
                            tcg_temp_free_i32(tmp2);
 
2874
                            break;
 
2875
                        case 2:
 
2876
                            break;
 
2877
                        }
 
2878
                        neon_store_reg(rn, pass, tmp);
 
2879
                    }
 
2880
                }
 
2881
            } else { /* !dp */
 
2882
                if ((insn & 0x6f) != 0x00)
 
2883
                    return 1;
 
2884
                rn = VFP_SREG_N(insn);
 
2885
                if (insn & ARM_CP_RW_BIT) {
 
2886
                    /* vfp->arm */
 
2887
                    if (insn & (1 << 21)) {
 
2888
                        /* system register */
 
2889
                        rn >>= 1;
 
2890
 
 
2891
                        switch (rn) {
 
2892
                        case ARM_VFP_FPSID:
 
2893
                            /* VFP2 allows access to FSID from userspace.
 
2894
                               VFP3 restricts all id registers to privileged
 
2895
                               accesses.  */
 
2896
                            if (IS_USER(s)
 
2897
                                && arm_feature(env, ARM_FEATURE_VFP3))
 
2898
                                return 1;
 
2899
                            tmp = load_cpu_field(vfp.xregs[rn]);
 
2900
                            break;
 
2901
                        case ARM_VFP_FPEXC:
 
2902
                            if (IS_USER(s))
 
2903
                                return 1;
 
2904
                            tmp = load_cpu_field(vfp.xregs[rn]);
 
2905
                            break;
 
2906
                        case ARM_VFP_FPINST:
 
2907
                        case ARM_VFP_FPINST2:
 
2908
                            /* Not present in VFP3.  */
 
2909
                            if (IS_USER(s)
 
2910
                                || arm_feature(env, ARM_FEATURE_VFP3))
 
2911
                                return 1;
 
2912
                            tmp = load_cpu_field(vfp.xregs[rn]);
 
2913
                            break;
 
2914
                        case ARM_VFP_FPSCR:
 
2915
                            if (rd == 15) {
 
2916
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
 
2917
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
 
2918
                            } else {
 
2919
                                tmp = tcg_temp_new_i32();
 
2920
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
 
2921
                            }
 
2922
                            break;
 
2923
                        case ARM_VFP_MVFR0:
 
2924
                        case ARM_VFP_MVFR1:
 
2925
                            if (IS_USER(s)
 
2926
                                || !arm_feature(env, ARM_FEATURE_MVFR))
 
2927
                                return 1;
 
2928
                            tmp = load_cpu_field(vfp.xregs[rn]);
 
2929
                            break;
 
2930
                        default:
 
2931
                            return 1;
 
2932
                        }
 
2933
                    } else {
 
2934
                        gen_mov_F0_vreg(0, rn);
 
2935
                        tmp = gen_vfp_mrs();
 
2936
                    }
 
2937
                    if (rd == 15) {
 
2938
                        /* Set the 4 flag bits in the CPSR.  */
 
2939
                        gen_set_nzcv(tmp);
 
2940
                        tcg_temp_free_i32(tmp);
 
2941
                    } else {
 
2942
                        store_reg(s, rd, tmp);
 
2943
                    }
 
2944
                } else {
 
2945
                    /* arm->vfp */
 
2946
                    if (insn & (1 << 21)) {
 
2947
                        rn >>= 1;
 
2948
                        /* system register */
 
2949
                        switch (rn) {
 
2950
                        case ARM_VFP_FPSID:
 
2951
                        case ARM_VFP_MVFR0:
 
2952
                        case ARM_VFP_MVFR1:
 
2953
                            /* Writes are ignored.  */
 
2954
                            break;
 
2955
                        case ARM_VFP_FPSCR:
 
2956
                            tmp = load_reg(s, rd);
 
2957
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
 
2958
                            tcg_temp_free_i32(tmp);
 
2959
                            gen_lookup_tb(s);
 
2960
                            break;
 
2961
                        case ARM_VFP_FPEXC:
 
2962
                            if (IS_USER(s))
 
2963
                                return 1;
 
2964
                            /* TODO: VFP subarchitecture support.
 
2965
                             * For now, keep the EN bit only */
 
2966
                            tmp = load_reg(s, rd);
 
2967
                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
 
2968
                            store_cpu_field(tmp, vfp.xregs[rn]);
 
2969
                            gen_lookup_tb(s);
 
2970
                            break;
 
2971
                        case ARM_VFP_FPINST:
 
2972
                        case ARM_VFP_FPINST2:
 
2973
                            tmp = load_reg(s, rd);
 
2974
                            store_cpu_field(tmp, vfp.xregs[rn]);
 
2975
                            break;
 
2976
                        default:
 
2977
                            return 1;
 
2978
                        }
 
2979
                    } else {
 
2980
                        tmp = load_reg(s, rd);
 
2981
                        gen_vfp_msr(tmp);
 
2982
                        gen_mov_vreg_F0(0, rn);
 
2983
                    }
 
2984
                }
 
2985
            }
 
2986
        } else {
 
2987
            /* data processing */
 
2988
            /* The opcode is in bits 23, 21, 20 and 6.  */
 
2989
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
 
2990
            if (dp) {
 
2991
                if (op == 15) {
 
2992
                    /* rn is opcode */
 
2993
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
 
2994
                } else {
 
2995
                    /* rn is register number */
 
2996
                    VFP_DREG_N(rn, insn);
 
2997
                }
 
2998
 
 
2999
                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
 
3000
                    /* Integer or single precision destination.  */
 
3001
                    rd = VFP_SREG_D(insn);
 
3002
                } else {
 
3003
                    VFP_DREG_D(rd, insn);
 
3004
                }
 
3005
                if (op == 15 &&
 
3006
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
 
3007
                    /* VCVT from int is always from S reg regardless of dp bit.
 
3008
                     * VCVT with immediate frac_bits has same format as SREG_M
 
3009
                     */
 
3010
                    rm = VFP_SREG_M(insn);
 
3011
                } else {
 
3012
                    VFP_DREG_M(rm, insn);
 
3013
                }
 
3014
            } else {
 
3015
                rn = VFP_SREG_N(insn);
 
3016
                if (op == 15 && rn == 15) {
 
3017
                    /* Double precision destination.  */
 
3018
                    VFP_DREG_D(rd, insn);
 
3019
                } else {
 
3020
                    rd = VFP_SREG_D(insn);
 
3021
                }
 
3022
                /* NB that we implicitly rely on the encoding for the frac_bits
 
3023
                 * in VCVT of fixed to float being the same as that of an SREG_M
 
3024
                 */
 
3025
                rm = VFP_SREG_M(insn);
 
3026
            }
 
3027
 
 
3028
            veclen = s->vec_len;
 
3029
            if (op == 15 && rn > 3)
 
3030
                veclen = 0;
 
3031
 
 
3032
            /* Shut up compiler warnings.  */
 
3033
            delta_m = 0;
 
3034
            delta_d = 0;
 
3035
            bank_mask = 0;
 
3036
 
 
3037
            if (veclen > 0) {
 
3038
                if (dp)
 
3039
                    bank_mask = 0xc;
 
3040
                else
 
3041
                    bank_mask = 0x18;
 
3042
 
 
3043
                /* Figure out what type of vector operation this is.  */
 
3044
                if ((rd & bank_mask) == 0) {
 
3045
                    /* scalar */
 
3046
                    veclen = 0;
 
3047
                } else {
 
3048
                    if (dp)
 
3049
                        delta_d = (s->vec_stride >> 1) + 1;
 
3050
                    else
 
3051
                        delta_d = s->vec_stride + 1;
 
3052
 
 
3053
                    if ((rm & bank_mask) == 0) {
 
3054
                        /* mixed scalar/vector */
 
3055
                        delta_m = 0;
 
3056
                    } else {
 
3057
                        /* vector */
 
3058
                        delta_m = delta_d;
 
3059
                    }
 
3060
                }
 
3061
            }
 
3062
 
 
3063
            /* Load the initial operands.  */
 
3064
            if (op == 15) {
 
3065
                switch (rn) {
 
3066
                case 16:
 
3067
                case 17:
 
3068
                    /* Integer source */
 
3069
                    gen_mov_F0_vreg(0, rm);
 
3070
                    break;
 
3071
                case 8:
 
3072
                case 9:
 
3073
                    /* Compare */
 
3074
                    gen_mov_F0_vreg(dp, rd);
 
3075
                    gen_mov_F1_vreg(dp, rm);
 
3076
                    break;
 
3077
                case 10:
 
3078
                case 11:
 
3079
                    /* Compare with zero */
 
3080
                    gen_mov_F0_vreg(dp, rd);
 
3081
                    gen_vfp_F1_ld0(dp);
 
3082
                    break;
 
3083
                case 20:
 
3084
                case 21:
 
3085
                case 22:
 
3086
                case 23:
 
3087
                case 28:
 
3088
                case 29:
 
3089
                case 30:
 
3090
                case 31:
 
3091
                    /* Source and destination the same.  */
 
3092
                    gen_mov_F0_vreg(dp, rd);
 
3093
                    break;
 
3094
                case 4:
 
3095
                case 5:
 
3096
                case 6:
 
3097
                case 7:
 
3098
                    /* VCVTB, VCVTT: only present with the halfprec extension,
 
3099
                     * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
 
3100
                     */
 
3101
                    if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
 
3102
                        return 1;
 
3103
                    }
 
3104
                    /* Otherwise fall through */
 
3105
                default:
 
3106
                    /* One source operand.  */
 
3107
                    gen_mov_F0_vreg(dp, rm);
 
3108
                    break;
 
3109
                }
 
3110
            } else {
 
3111
                /* Two source operands.  */
 
3112
                gen_mov_F0_vreg(dp, rn);
 
3113
                gen_mov_F1_vreg(dp, rm);
 
3114
            }
 
3115
 
 
3116
            for (;;) {
 
3117
                /* Perform the calculation.  */
 
3118
                switch (op) {
 
3119
                case 0: /* VMLA: fd + (fn * fm) */
 
3120
                    /* Note that order of inputs to the add matters for NaNs */
 
3121
                    gen_vfp_F1_mul(dp);
 
3122
                    gen_mov_F0_vreg(dp, rd);
 
3123
                    gen_vfp_add(dp);
 
3124
                    break;
 
3125
                case 1: /* VMLS: fd + -(fn * fm) */
 
3126
                    gen_vfp_mul(dp);
 
3127
                    gen_vfp_F1_neg(dp);
 
3128
                    gen_mov_F0_vreg(dp, rd);
 
3129
                    gen_vfp_add(dp);
 
3130
                    break;
 
3131
                case 2: /* VNMLS: -fd + (fn * fm) */
 
3132
                    /* Note that it isn't valid to replace (-A + B) with (B - A)
 
3133
                     * or similar plausible looking simplifications
 
3134
                     * because this will give wrong results for NaNs.
 
3135
                     */
 
3136
                    gen_vfp_F1_mul(dp);
 
3137
                    gen_mov_F0_vreg(dp, rd);
 
3138
                    gen_vfp_neg(dp);
 
3139
                    gen_vfp_add(dp);
 
3140
                    break;
 
3141
                case 3: /* VNMLA: -fd + -(fn * fm) */
 
3142
                    gen_vfp_mul(dp);
 
3143
                    gen_vfp_F1_neg(dp);
 
3144
                    gen_mov_F0_vreg(dp, rd);
 
3145
                    gen_vfp_neg(dp);
 
3146
                    gen_vfp_add(dp);
 
3147
                    break;
 
3148
                case 4: /* mul: fn * fm */
 
3149
                    gen_vfp_mul(dp);
 
3150
                    break;
 
3151
                case 5: /* nmul: -(fn * fm) */
 
3152
                    gen_vfp_mul(dp);
 
3153
                    gen_vfp_neg(dp);
 
3154
                    break;
 
3155
                case 6: /* add: fn + fm */
 
3156
                    gen_vfp_add(dp);
 
3157
                    break;
 
3158
                case 7: /* sub: fn - fm */
 
3159
                    gen_vfp_sub(dp);
 
3160
                    break;
 
3161
                case 8: /* div: fn / fm */
 
3162
                    gen_vfp_div(dp);
 
3163
                    break;
 
3164
                case 10: /* VFNMA : fd = muladd(-fd,  fn, fm) */
 
3165
                case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
 
3166
                case 12: /* VFMA  : fd = muladd( fd,  fn, fm) */
 
3167
                case 13: /* VFMS  : fd = muladd( fd, -fn, fm) */
 
3168
                    /* These are fused multiply-add, and must be done as one
 
3169
                     * floating point operation with no rounding between the
 
3170
                     * multiplication and addition steps.
 
3171
                     * NB that doing the negations here as separate steps is
 
3172
                     * correct : an input NaN should come out with its sign bit
 
3173
                     * flipped if it is a negated-input.
 
3174
                     */
 
3175
                    if (!arm_feature(env, ARM_FEATURE_VFP4)) {
 
3176
                        return 1;
 
3177
                    }
 
3178
                    if (dp) {
 
3179
                        TCGv_ptr fpst;
 
3180
                        TCGv_i64 frd;
 
3181
                        if (op & 1) {
 
3182
                            /* VFNMS, VFMS */
 
3183
                            gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
 
3184
                        }
 
3185
                        frd = tcg_temp_new_i64();
 
3186
                        tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
 
3187
                        if (op & 2) {
 
3188
                            /* VFNMA, VFNMS */
 
3189
                            gen_helper_vfp_negd(frd, frd);
 
3190
                        }
 
3191
                        fpst = get_fpstatus_ptr(0);
 
3192
                        gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
 
3193
                                               cpu_F1d, frd, fpst);
 
3194
                        tcg_temp_free_ptr(fpst);
 
3195
                        tcg_temp_free_i64(frd);
 
3196
                    } else {
 
3197
                        TCGv_ptr fpst;
 
3198
                        TCGv_i32 frd;
 
3199
                        if (op & 1) {
 
3200
                            /* VFNMS, VFMS */
 
3201
                            gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
 
3202
                        }
 
3203
                        frd = tcg_temp_new_i32();
 
3204
                        tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
 
3205
                        if (op & 2) {
 
3206
                            gen_helper_vfp_negs(frd, frd);
 
3207
                        }
 
3208
                        fpst = get_fpstatus_ptr(0);
 
3209
                        gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
 
3210
                                               cpu_F1s, frd, fpst);
 
3211
                        tcg_temp_free_ptr(fpst);
 
3212
                        tcg_temp_free_i32(frd);
 
3213
                    }
 
3214
                    break;
 
3215
                case 14: /* fconst */
 
3216
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
 
3217
                      return 1;
 
3218
 
 
3219
                    n = (insn << 12) & 0x80000000;
 
3220
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
 
3221
                    if (dp) {
 
3222
                        if (i & 0x40)
 
3223
                            i |= 0x3f80;
 
3224
                        else
 
3225
                            i |= 0x4000;
 
3226
                        n |= i << 16;
 
3227
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
 
3228
                    } else {
 
3229
                        if (i & 0x40)
 
3230
                            i |= 0x780;
 
3231
                        else
 
3232
                            i |= 0x800;
 
3233
                        n |= i << 19;
 
3234
                        tcg_gen_movi_i32(cpu_F0s, n);
 
3235
                    }
 
3236
                    break;
 
3237
                case 15: /* extension space */
 
3238
                    switch (rn) {
 
3239
                    case 0: /* cpy */
 
3240
                        /* no-op */
 
3241
                        break;
 
3242
                    case 1: /* abs */
 
3243
                        gen_vfp_abs(dp);
 
3244
                        break;
 
3245
                    case 2: /* neg */
 
3246
                        gen_vfp_neg(dp);
 
3247
                        break;
 
3248
                    case 3: /* sqrt */
 
3249
                        gen_vfp_sqrt(dp);
 
3250
                        break;
 
3251
                    case 4: /* vcvtb.f32.f16 */
 
3252
                        tmp = gen_vfp_mrs();
 
3253
                        tcg_gen_ext16u_i32(tmp, tmp);
 
3254
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
 
3255
                        tcg_temp_free_i32(tmp);
 
3256
                        break;
 
3257
                    case 5: /* vcvtt.f32.f16 */
 
3258
                        tmp = gen_vfp_mrs();
 
3259
                        tcg_gen_shri_i32(tmp, tmp, 16);
 
3260
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
 
3261
                        tcg_temp_free_i32(tmp);
 
3262
                        break;
 
3263
                    case 6: /* vcvtb.f16.f32 */
 
3264
                        tmp = tcg_temp_new_i32();
 
3265
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
 
3266
                        gen_mov_F0_vreg(0, rd);
 
3267
                        tmp2 = gen_vfp_mrs();
 
3268
                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
 
3269
                        tcg_gen_or_i32(tmp, tmp, tmp2);
 
3270
                        tcg_temp_free_i32(tmp2);
 
3271
                        gen_vfp_msr(tmp);
 
3272
                        break;
 
3273
                    case 7: /* vcvtt.f16.f32 */
 
3274
                        tmp = tcg_temp_new_i32();
 
3275
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
 
3276
                        tcg_gen_shli_i32(tmp, tmp, 16);
 
3277
                        gen_mov_F0_vreg(0, rd);
 
3278
                        tmp2 = gen_vfp_mrs();
 
3279
                        tcg_gen_ext16u_i32(tmp2, tmp2);
 
3280
                        tcg_gen_or_i32(tmp, tmp, tmp2);
 
3281
                        tcg_temp_free_i32(tmp2);
 
3282
                        gen_vfp_msr(tmp);
 
3283
                        break;
 
3284
                    case 8: /* cmp */
 
3285
                        gen_vfp_cmp(dp);
 
3286
                        break;
 
3287
                    case 9: /* cmpe */
 
3288
                        gen_vfp_cmpe(dp);
 
3289
                        break;
 
3290
                    case 10: /* cmpz */
 
3291
                        gen_vfp_cmp(dp);
 
3292
                        break;
 
3293
                    case 11: /* cmpez */
 
3294
                        gen_vfp_F1_ld0(dp);
 
3295
                        gen_vfp_cmpe(dp);
 
3296
                        break;
 
3297
                    case 15: /* single<->double conversion */
 
3298
                        if (dp)
 
3299
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
 
3300
                        else
 
3301
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
 
3302
                        break;
 
3303
                    case 16: /* fuito */
 
3304
                        gen_vfp_uito(dp, 0);
 
3305
                        break;
 
3306
                    case 17: /* fsito */
 
3307
                        gen_vfp_sito(dp, 0);
 
3308
                        break;
 
3309
                    case 20: /* fshto */
 
3310
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
 
3311
                          return 1;
 
3312
                        gen_vfp_shto(dp, 16 - rm, 0);
 
3313
                        break;
 
3314
                    case 21: /* fslto */
 
3315
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
 
3316
                          return 1;
 
3317
                        gen_vfp_slto(dp, 32 - rm, 0);
 
3318
                        break;
 
3319
                    case 22: /* fuhto */
 
3320
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
 
3321
                          return 1;
 
3322
                        gen_vfp_uhto(dp, 16 - rm, 0);
 
3323
                        break;
 
3324
                    case 23: /* fulto */
 
3325
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
 
3326
                          return 1;
 
3327
                        gen_vfp_ulto(dp, 32 - rm, 0);
 
3328
                        break;
 
3329
                    case 24: /* ftoui */
 
3330
                        gen_vfp_toui(dp, 0);
 
3331
                        break;
 
3332
                    case 25: /* ftouiz */
 
3333
                        gen_vfp_touiz(dp, 0);
 
3334
                        break;
 
3335
                    case 26: /* ftosi */
 
3336
                        gen_vfp_tosi(dp, 0);
 
3337
                        break;
 
3338
                    case 27: /* ftosiz */
 
3339
                        gen_vfp_tosiz(dp, 0);
 
3340
                        break;
 
3341
                    case 28: /* ftosh */
 
3342
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
 
3343
                          return 1;
 
3344
                        gen_vfp_tosh(dp, 16 - rm, 0);
 
3345
                        break;
 
3346
                    case 29: /* ftosl */
 
3347
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
 
3348
                          return 1;
 
3349
                        gen_vfp_tosl(dp, 32 - rm, 0);
 
3350
                        break;
 
3351
                    case 30: /* ftouh */
 
3352
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
 
3353
                          return 1;
 
3354
                        gen_vfp_touh(dp, 16 - rm, 0);
 
3355
                        break;
 
3356
                    case 31: /* ftoul */
 
3357
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
 
3358
                          return 1;
 
3359
                        gen_vfp_toul(dp, 32 - rm, 0);
 
3360
                        break;
 
3361
                    default: /* undefined */
 
3362
                        return 1;
 
3363
                    }
 
3364
                    break;
 
3365
                default: /* undefined */
 
3366
                    return 1;
 
3367
                }
 
3368
 
 
3369
                /* Write back the result.  */
 
3370
                if (op == 15 && (rn >= 8 && rn <= 11))
 
3371
                    ; /* Comparison, do nothing.  */
 
3372
                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
 
3373
                    /* VCVT double to int: always integer result. */
 
3374
                    gen_mov_vreg_F0(0, rd);
 
3375
                else if (op == 15 && rn == 15)
 
3376
                    /* conversion */
 
3377
                    gen_mov_vreg_F0(!dp, rd);
 
3378
                else
 
3379
                    gen_mov_vreg_F0(dp, rd);
 
3380
 
 
3381
                /* break out of the loop if we have finished  */
 
3382
                if (veclen == 0)
 
3383
                    break;
 
3384
 
 
3385
                if (op == 15 && delta_m == 0) {
 
3386
                    /* single source one-many */
 
3387
                    while (veclen--) {
 
3388
                        rd = ((rd + delta_d) & (bank_mask - 1))
 
3389
                             | (rd & bank_mask);
 
3390
                        gen_mov_vreg_F0(dp, rd);
 
3391
                    }
 
3392
                    break;
 
3393
                }
 
3394
                /* Setup the next operands.  */
 
3395
                veclen--;
 
3396
                rd = ((rd + delta_d) & (bank_mask - 1))
 
3397
                     | (rd & bank_mask);
 
3398
 
 
3399
                if (op == 15) {
 
3400
                    /* One source operand.  */
 
3401
                    rm = ((rm + delta_m) & (bank_mask - 1))
 
3402
                         | (rm & bank_mask);
 
3403
                    gen_mov_F0_vreg(dp, rm);
 
3404
                } else {
 
3405
                    /* Two source operands.  */
 
3406
                    rn = ((rn + delta_d) & (bank_mask - 1))
 
3407
                         | (rn & bank_mask);
 
3408
                    gen_mov_F0_vreg(dp, rn);
 
3409
                    if (delta_m) {
 
3410
                        rm = ((rm + delta_m) & (bank_mask - 1))
 
3411
                             | (rm & bank_mask);
 
3412
                        gen_mov_F1_vreg(dp, rm);
 
3413
                    }
 
3414
                }
 
3415
            }
 
3416
        }
 
3417
        break;
 
3418
    case 0xc:
 
3419
    case 0xd:
 
3420
        if ((insn & 0x03e00000) == 0x00400000) {
 
3421
            /* two-register transfer */
 
3422
            rn = (insn >> 16) & 0xf;
 
3423
            rd = (insn >> 12) & 0xf;
 
3424
            if (dp) {
 
3425
                VFP_DREG_M(rm, insn);
 
3426
            } else {
 
3427
                rm = VFP_SREG_M(insn);
 
3428
            }
 
3429
 
 
3430
            if (insn & ARM_CP_RW_BIT) {
 
3431
                /* vfp->arm */
 
3432
                if (dp) {
 
3433
                    gen_mov_F0_vreg(0, rm * 2);
 
3434
                    tmp = gen_vfp_mrs();
 
3435
                    store_reg(s, rd, tmp);
 
3436
                    gen_mov_F0_vreg(0, rm * 2 + 1);
 
3437
                    tmp = gen_vfp_mrs();
 
3438
                    store_reg(s, rn, tmp);
 
3439
                } else {
 
3440
                    gen_mov_F0_vreg(0, rm);
 
3441
                    tmp = gen_vfp_mrs();
 
3442
                    store_reg(s, rd, tmp);
 
3443
                    gen_mov_F0_vreg(0, rm + 1);
 
3444
                    tmp = gen_vfp_mrs();
 
3445
                    store_reg(s, rn, tmp);
 
3446
                }
 
3447
            } else {
 
3448
                /* arm->vfp */
 
3449
                if (dp) {
 
3450
                    tmp = load_reg(s, rd);
 
3451
                    gen_vfp_msr(tmp);
 
3452
                    gen_mov_vreg_F0(0, rm * 2);
 
3453
                    tmp = load_reg(s, rn);
 
3454
                    gen_vfp_msr(tmp);
 
3455
                    gen_mov_vreg_F0(0, rm * 2 + 1);
 
3456
                } else {
 
3457
                    tmp = load_reg(s, rd);
 
3458
                    gen_vfp_msr(tmp);
 
3459
                    gen_mov_vreg_F0(0, rm);
 
3460
                    tmp = load_reg(s, rn);
 
3461
                    gen_vfp_msr(tmp);
 
3462
                    gen_mov_vreg_F0(0, rm + 1);
 
3463
                }
 
3464
            }
 
3465
        } else {
 
3466
            /* Load/store */
 
3467
            rn = (insn >> 16) & 0xf;
 
3468
            if (dp)
 
3469
                VFP_DREG_D(rd, insn);
 
3470
            else
 
3471
                rd = VFP_SREG_D(insn);
 
3472
            if ((insn & 0x01200000) == 0x01000000) {
 
3473
                /* Single load/store */
 
3474
                offset = (insn & 0xff) << 2;
 
3475
                if ((insn & (1 << 23)) == 0)
 
3476
                    offset = -offset;
 
3477
                if (s->thumb && rn == 15) {
 
3478
                    /* This is actually UNPREDICTABLE */
 
3479
                    addr = tcg_temp_new_i32();
 
3480
                    tcg_gen_movi_i32(addr, s->pc & ~2);
 
3481
                } else {
 
3482
                    addr = load_reg(s, rn);
 
3483
                }
 
3484
                tcg_gen_addi_i32(addr, addr, offset);
 
3485
                if (insn & (1 << 20)) {
 
3486
                    gen_vfp_ld(s, dp, addr);
 
3487
                    gen_mov_vreg_F0(dp, rd);
 
3488
                } else {
 
3489
                    gen_mov_F0_vreg(dp, rd);
 
3490
                    gen_vfp_st(s, dp, addr);
 
3491
                }
 
3492
                tcg_temp_free_i32(addr);
 
3493
            } else {
 
3494
                /* load/store multiple */
 
3495
                int w = insn & (1 << 21);
 
3496
                if (dp)
 
3497
                    n = (insn >> 1) & 0x7f;
 
3498
                else
 
3499
                    n = insn & 0xff;
 
3500
 
 
3501
                if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
 
3502
                    /* P == U , W == 1  => UNDEF */
 
3503
                    return 1;
 
3504
                }
 
3505
                if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
 
3506
                    /* UNPREDICTABLE cases for bad immediates: we choose to
 
3507
                     * UNDEF to avoid generating huge numbers of TCG ops
 
3508
                     */
 
3509
                    return 1;
 
3510
                }
 
3511
                if (rn == 15 && w) {
 
3512
                    /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
 
3513
                    return 1;
 
3514
                }
 
3515
 
 
3516
                if (s->thumb && rn == 15) {
 
3517
                    /* This is actually UNPREDICTABLE */
 
3518
                    addr = tcg_temp_new_i32();
 
3519
                    tcg_gen_movi_i32(addr, s->pc & ~2);
 
3520
                } else {
 
3521
                    addr = load_reg(s, rn);
 
3522
                }
 
3523
                if (insn & (1 << 24)) /* pre-decrement */
 
3524
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
 
3525
 
 
3526
                if (dp)
 
3527
                    offset = 8;
 
3528
                else
 
3529
                    offset = 4;
 
3530
                for (i = 0; i < n; i++) {
 
3531
                    if (insn & ARM_CP_RW_BIT) {
 
3532
                        /* load */
 
3533
                        gen_vfp_ld(s, dp, addr);
 
3534
                        gen_mov_vreg_F0(dp, rd + i);
 
3535
                    } else {
 
3536
                        /* store */
 
3537
                        gen_mov_F0_vreg(dp, rd + i);
 
3538
                        gen_vfp_st(s, dp, addr);
 
3539
                    }
 
3540
                    tcg_gen_addi_i32(addr, addr, offset);
 
3541
                }
 
3542
                if (w) {
 
3543
                    /* writeback */
 
3544
                    if (insn & (1 << 24))
 
3545
                        offset = -offset * n;
 
3546
                    else if (dp && (insn & 1))
 
3547
                        offset = 4;
 
3548
                    else
 
3549
                        offset = 0;
 
3550
 
 
3551
                    if (offset != 0)
 
3552
                        tcg_gen_addi_i32(addr, addr, offset);
 
3553
                    store_reg(s, rn, addr);
 
3554
                } else {
 
3555
                    tcg_temp_free_i32(addr);
 
3556
                }
 
3557
            }
 
3558
        }
 
3559
        break;
 
3560
    default:
 
3561
        /* Should never happen.  */
 
3562
        return 1;
 
3563
    }
 
3564
    return 0;
 
3565
}
 
3566
 
 
3567
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
 
3568
{
 
3569
    TranslationBlock *tb;
 
3570
 
 
3571
    tb = s->tb;
 
3572
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
 
3573
        tcg_gen_goto_tb(n);
 
3574
        gen_set_pc_im(s, dest);
 
3575
        tcg_gen_exit_tb((uintptr_t)tb + n);
 
3576
    } else {
 
3577
        gen_set_pc_im(s, dest);
 
3578
        tcg_gen_exit_tb(0);
 
3579
    }
 
3580
}
 
3581
 
 
3582
static inline void gen_jmp (DisasContext *s, uint32_t dest)
 
3583
{
 
3584
    if (unlikely(s->singlestep_enabled)) {
 
3585
        /* An indirect jump so that we still trigger the debug exception.  */
 
3586
        if (s->thumb)
 
3587
            dest |= 1;
 
3588
        gen_bx_im(s, dest);
 
3589
    } else {
 
3590
        gen_goto_tb(s, 0, dest);
 
3591
        s->is_jmp = DISAS_TB_JUMP;
 
3592
    }
 
3593
}
 
3594
 
 
3595
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
 
3596
{
 
3597
    if (x)
 
3598
        tcg_gen_sari_i32(t0, t0, 16);
 
3599
    else
 
3600
        gen_sxth(t0);
 
3601
    if (y)
 
3602
        tcg_gen_sari_i32(t1, t1, 16);
 
3603
    else
 
3604
        gen_sxth(t1);
 
3605
    tcg_gen_mul_i32(t0, t0, t1);
 
3606
}
 
3607
 
 
3608
/* Return the mask of PSR bits set by a MSR instruction.  */
 
3609
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
 
3610
    uint32_t mask;
 
3611
 
 
3612
    mask = 0;
 
3613
    if (flags & (1 << 0))
 
3614
        mask |= 0xff;
 
3615
    if (flags & (1 << 1))
 
3616
        mask |= 0xff00;
 
3617
    if (flags & (1 << 2))
 
3618
        mask |= 0xff0000;
 
3619
    if (flags & (1 << 3))
 
3620
        mask |= 0xff000000;
 
3621
 
 
3622
    /* Mask out undefined bits.  */
 
3623
    mask &= ~CPSR_RESERVED;
 
3624
    if (!arm_feature(env, ARM_FEATURE_V4T))
 
3625
        mask &= ~CPSR_T;
 
3626
    if (!arm_feature(env, ARM_FEATURE_V5))
 
3627
        mask &= ~CPSR_Q; /* V5TE in reality*/
 
3628
    if (!arm_feature(env, ARM_FEATURE_V6))
 
3629
        mask &= ~(CPSR_E | CPSR_GE);
 
3630
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
 
3631
        mask &= ~CPSR_IT;
 
3632
    /* Mask out execution state bits.  */
 
3633
    if (!spsr)
 
3634
        mask &= ~CPSR_EXEC;
 
3635
    /* Mask out privileged bits.  */
 
3636
    if (IS_USER(s))
 
3637
        mask &= CPSR_USER;
 
3638
    return mask;
 
3639
}
 
3640
 
 
3641
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
 
3642
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
 
3643
{
 
3644
    TCGv_i32 tmp;
 
3645
    if (spsr) {
 
3646
        /* ??? This is also undefined in system mode.  */
 
3647
        if (IS_USER(s))
 
3648
            return 1;
 
3649
 
 
3650
        tmp = load_cpu_field(spsr);
 
3651
        tcg_gen_andi_i32(tmp, tmp, ~mask);
 
3652
        tcg_gen_andi_i32(t0, t0, mask);
 
3653
        tcg_gen_or_i32(tmp, tmp, t0);
 
3654
        store_cpu_field(tmp, spsr);
 
3655
    } else {
 
3656
        gen_set_cpsr(t0, mask);
 
3657
    }
 
3658
    tcg_temp_free_i32(t0);
 
3659
    gen_lookup_tb(s);
 
3660
    return 0;
 
3661
}
 
3662
 
 
3663
/* Returns nonzero if access to the PSR is not permitted.  */
 
3664
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
 
3665
{
 
3666
    TCGv_i32 tmp;
 
3667
    tmp = tcg_temp_new_i32();
 
3668
    tcg_gen_movi_i32(tmp, val);
 
3669
    return gen_set_psr(s, mask, spsr, tmp);
 
3670
}
 
3671
 
 
3672
/* Generate an old-style exception return. Marks pc as dead. */
 
3673
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
 
3674
{
 
3675
    TCGv_i32 tmp;
 
3676
    store_reg(s, 15, pc);
 
3677
    tmp = load_cpu_field(spsr);
 
3678
    gen_set_cpsr(tmp, 0xffffffff);
 
3679
    tcg_temp_free_i32(tmp);
 
3680
    s->is_jmp = DISAS_UPDATE;
 
3681
}
 
3682
 
 
3683
/* Generate a v6 exception return.  Marks both values as dead.  */
 
3684
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
 
3685
{
 
3686
    gen_set_cpsr(cpsr, 0xffffffff);
 
3687
    tcg_temp_free_i32(cpsr);
 
3688
    store_reg(s, 15, pc);
 
3689
    s->is_jmp = DISAS_UPDATE;
 
3690
}
 
3691
 
 
3692
static inline void
 
3693
gen_set_condexec (DisasContext *s)
 
3694
{
 
3695
    if (s->condexec_mask) {
 
3696
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
 
3697
        TCGv_i32 tmp = tcg_temp_new_i32();
 
3698
        tcg_gen_movi_i32(tmp, val);
 
3699
        store_cpu_field(tmp, condexec_bits);
 
3700
    }
 
3701
}
 
3702
 
 
3703
static void gen_exception_insn(DisasContext *s, int offset, int excp)
 
3704
{
 
3705
    gen_set_condexec(s);
 
3706
    gen_set_pc_im(s, s->pc - offset);
 
3707
    gen_exception(excp);
 
3708
    s->is_jmp = DISAS_JUMP;
 
3709
}
 
3710
 
 
3711
static void gen_nop_hint(DisasContext *s, int val)
 
3712
{
 
3713
    switch (val) {
 
3714
    case 3: /* wfi */
 
3715
        gen_set_pc_im(s, s->pc);
 
3716
        s->is_jmp = DISAS_WFI;
 
3717
        break;
 
3718
    case 2: /* wfe */
 
3719
    case 4: /* sev */
 
3720
    case 5: /* sevl */
 
3721
        /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */
 
3722
    default: /* nop */
 
3723
        break;
 
3724
    }
 
3725
}
 
3726
 
 
3727
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
 
3728
 
 
3729
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
 
3730
{
 
3731
    switch (size) {
 
3732
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
 
3733
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
 
3734
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
 
3735
    default: abort();
 
3736
    }
 
3737
}
 
3738
 
 
3739
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
 
3740
{
 
3741
    switch (size) {
 
3742
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
 
3743
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
 
3744
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
 
3745
    default: return;
 
3746
    }
 
3747
}
 
3748
 
 
3749
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
 
3750
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
 
3751
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
 
3752
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
 
3753
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
 
3754
 
 
3755
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
 
3756
    switch ((size << 1) | u) { \
 
3757
    case 0: \
 
3758
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
 
3759
        break; \
 
3760
    case 1: \
 
3761
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
 
3762
        break; \
 
3763
    case 2: \
 
3764
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
 
3765
        break; \
 
3766
    case 3: \
 
3767
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
 
3768
        break; \
 
3769
    case 4: \
 
3770
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
 
3771
        break; \
 
3772
    case 5: \
 
3773
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
 
3774
        break; \
 
3775
    default: return 1; \
 
3776
    }} while (0)
 
3777
 
 
3778
#define GEN_NEON_INTEGER_OP(name) do { \
 
3779
    switch ((size << 1) | u) { \
 
3780
    case 0: \
 
3781
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
 
3782
        break; \
 
3783
    case 1: \
 
3784
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
 
3785
        break; \
 
3786
    case 2: \
 
3787
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
 
3788
        break; \
 
3789
    case 3: \
 
3790
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
 
3791
        break; \
 
3792
    case 4: \
 
3793
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
 
3794
        break; \
 
3795
    case 5: \
 
3796
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
 
3797
        break; \
 
3798
    default: return 1; \
 
3799
    }} while (0)
 
3800
 
 
3801
static TCGv_i32 neon_load_scratch(int scratch)
 
3802
{
 
3803
    TCGv_i32 tmp = tcg_temp_new_i32();
 
3804
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
 
3805
    return tmp;
 
3806
}
 
3807
 
 
3808
static void neon_store_scratch(int scratch, TCGv_i32 var)
 
3809
{
 
3810
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
 
3811
    tcg_temp_free_i32(var);
 
3812
}
 
3813
 
 
3814
static inline TCGv_i32 neon_get_scalar(int size, int reg)
 
3815
{
 
3816
    TCGv_i32 tmp;
 
3817
    if (size == 1) {
 
3818
        tmp = neon_load_reg(reg & 7, reg >> 4);
 
3819
        if (reg & 8) {
 
3820
            gen_neon_dup_high16(tmp);
 
3821
        } else {
 
3822
            gen_neon_dup_low16(tmp);
 
3823
        }
 
3824
    } else {
 
3825
        tmp = neon_load_reg(reg & 15, reg >> 4);
 
3826
    }
 
3827
    return tmp;
 
3828
}
 
3829
 
 
3830
static int gen_neon_unzip(int rd, int rm, int size, int q)
 
3831
{
 
3832
    TCGv_i32 tmp, tmp2;
 
3833
    if (!q && size == 2) {
 
3834
        return 1;
 
3835
    }
 
3836
    tmp = tcg_const_i32(rd);
 
3837
    tmp2 = tcg_const_i32(rm);
 
3838
    if (q) {
 
3839
        switch (size) {
 
3840
        case 0:
 
3841
            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
 
3842
            break;
 
3843
        case 1:
 
3844
            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
 
3845
            break;
 
3846
        case 2:
 
3847
            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
 
3848
            break;
 
3849
        default:
 
3850
            abort();
 
3851
        }
 
3852
    } else {
 
3853
        switch (size) {
 
3854
        case 0:
 
3855
            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
 
3856
            break;
 
3857
        case 1:
 
3858
            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
 
3859
            break;
 
3860
        default:
 
3861
            abort();
 
3862
        }
 
3863
    }
 
3864
    tcg_temp_free_i32(tmp);
 
3865
    tcg_temp_free_i32(tmp2);
 
3866
    return 0;
 
3867
}
 
3868
 
 
3869
static int gen_neon_zip(int rd, int rm, int size, int q)
 
3870
{
 
3871
    TCGv_i32 tmp, tmp2;
 
3872
    if (!q && size == 2) {
 
3873
        return 1;
 
3874
    }
 
3875
    tmp = tcg_const_i32(rd);
 
3876
    tmp2 = tcg_const_i32(rm);
 
3877
    if (q) {
 
3878
        switch (size) {
 
3879
        case 0:
 
3880
            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
 
3881
            break;
 
3882
        case 1:
 
3883
            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
 
3884
            break;
 
3885
        case 2:
 
3886
            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
 
3887
            break;
 
3888
        default:
 
3889
            abort();
 
3890
        }
 
3891
    } else {
 
3892
        switch (size) {
 
3893
        case 0:
 
3894
            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
 
3895
            break;
 
3896
        case 1:
 
3897
            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
 
3898
            break;
 
3899
        default:
 
3900
            abort();
 
3901
        }
 
3902
    }
 
3903
    tcg_temp_free_i32(tmp);
 
3904
    tcg_temp_free_i32(tmp2);
 
3905
    return 0;
 
3906
}
 
3907
 
 
3908
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
 
3909
{
 
3910
    TCGv_i32 rd, tmp;
 
3911
 
 
3912
    rd = tcg_temp_new_i32();
 
3913
    tmp = tcg_temp_new_i32();
 
3914
 
 
3915
    tcg_gen_shli_i32(rd, t0, 8);
 
3916
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
 
3917
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
 
3918
    tcg_gen_or_i32(rd, rd, tmp);
 
3919
 
 
3920
    tcg_gen_shri_i32(t1, t1, 8);
 
3921
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
 
3922
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
 
3923
    tcg_gen_or_i32(t1, t1, tmp);
 
3924
    tcg_gen_mov_i32(t0, rd);
 
3925
 
 
3926
    tcg_temp_free_i32(tmp);
 
3927
    tcg_temp_free_i32(rd);
 
3928
}
 
3929
 
 
3930
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
 
3931
{
 
3932
    TCGv_i32 rd, tmp;
 
3933
 
 
3934
    rd = tcg_temp_new_i32();
 
3935
    tmp = tcg_temp_new_i32();
 
3936
 
 
3937
    tcg_gen_shli_i32(rd, t0, 16);
 
3938
    tcg_gen_andi_i32(tmp, t1, 0xffff);
 
3939
    tcg_gen_or_i32(rd, rd, tmp);
 
3940
    tcg_gen_shri_i32(t1, t1, 16);
 
3941
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
 
3942
    tcg_gen_or_i32(t1, t1, tmp);
 
3943
    tcg_gen_mov_i32(t0, rd);
 
3944
 
 
3945
    tcg_temp_free_i32(tmp);
 
3946
    tcg_temp_free_i32(rd);
 
3947
}
 
3948
 
 
3949
 
 
3950
static struct {
 
3951
    int nregs;
 
3952
    int interleave;
 
3953
    int spacing;
 
3954
} neon_ls_element_type[11] = {
 
3955
    {4, 4, 1},
 
3956
    {4, 4, 2},
 
3957
    {4, 1, 1},
 
3958
    {4, 2, 1},
 
3959
    {3, 3, 1},
 
3960
    {3, 3, 2},
 
3961
    {3, 1, 1},
 
3962
    {1, 1, 1},
 
3963
    {2, 2, 1},
 
3964
    {2, 2, 2},
 
3965
    {2, 1, 1}
 
3966
};
 
3967
 
 
3968
/* Translate a NEON load/store element instruction.  Return nonzero if the
 
3969
   instruction is invalid.  */
 
3970
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 
3971
{
 
3972
    int rd, rn, rm;
 
3973
    int op;
 
3974
    int nregs;
 
3975
    int interleave;
 
3976
    int spacing;
 
3977
    int stride;
 
3978
    int size;
 
3979
    int reg;
 
3980
    int pass;
 
3981
    int load;
 
3982
    int shift;
 
3983
    int n;
 
3984
    TCGv_i32 addr;
 
3985
    TCGv_i32 tmp;
 
3986
    TCGv_i32 tmp2;
 
3987
    TCGv_i64 tmp64;
 
3988
 
 
3989
    if (!s->vfp_enabled)
 
3990
      return 1;
 
3991
    VFP_DREG_D(rd, insn);
 
3992
    rn = (insn >> 16) & 0xf;
 
3993
    rm = insn & 0xf;
 
3994
    load = (insn & (1 << 21)) != 0;
 
3995
    if ((insn & (1 << 23)) == 0) {
 
3996
        /* Load store all elements.  */
 
3997
        op = (insn >> 8) & 0xf;
 
3998
        size = (insn >> 6) & 3;
 
3999
        if (op > 10)
 
4000
            return 1;
 
4001
        /* Catch UNDEF cases for bad values of align field */
 
4002
        switch (op & 0xc) {
 
4003
        case 4:
 
4004
            if (((insn >> 5) & 1) == 1) {
 
4005
                return 1;
 
4006
            }
 
4007
            break;
 
4008
        case 8:
 
4009
            if (((insn >> 4) & 3) == 3) {
 
4010
                return 1;
 
4011
            }
 
4012
            break;
 
4013
        default:
 
4014
            break;
 
4015
        }
 
4016
        nregs = neon_ls_element_type[op].nregs;
 
4017
        interleave = neon_ls_element_type[op].interleave;
 
4018
        spacing = neon_ls_element_type[op].spacing;
 
4019
        if (size == 3 && (interleave | spacing) != 1)
 
4020
            return 1;
 
4021
        addr = tcg_temp_new_i32();
 
4022
        load_reg_var(s, addr, rn);
 
4023
        stride = (1 << size) * interleave;
 
4024
        for (reg = 0; reg < nregs; reg++) {
 
4025
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
 
4026
                load_reg_var(s, addr, rn);
 
4027
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
 
4028
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
 
4029
                load_reg_var(s, addr, rn);
 
4030
                tcg_gen_addi_i32(addr, addr, 1 << size);
 
4031
            }
 
4032
            if (size == 3) {
 
4033
                tmp64 = tcg_temp_new_i64();
 
4034
                if (load) {
 
4035
                    gen_aa32_ld64(tmp64, addr, IS_USER(s));
 
4036
                    neon_store_reg64(tmp64, rd);
 
4037
                } else {
 
4038
                    neon_load_reg64(tmp64, rd);
 
4039
                    gen_aa32_st64(tmp64, addr, IS_USER(s));
 
4040
                }
 
4041
                tcg_temp_free_i64(tmp64);
 
4042
                tcg_gen_addi_i32(addr, addr, stride);
 
4043
            } else {
 
4044
                for (pass = 0; pass < 2; pass++) {
 
4045
                    if (size == 2) {
 
4046
                        if (load) {
 
4047
                            tmp = tcg_temp_new_i32();
 
4048
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
4049
                            neon_store_reg(rd, pass, tmp);
 
4050
                        } else {
 
4051
                            tmp = neon_load_reg(rd, pass);
 
4052
                            gen_aa32_st32(tmp, addr, IS_USER(s));
 
4053
                            tcg_temp_free_i32(tmp);
 
4054
                        }
 
4055
                        tcg_gen_addi_i32(addr, addr, stride);
 
4056
                    } else if (size == 1) {
 
4057
                        if (load) {
 
4058
                            tmp = tcg_temp_new_i32();
 
4059
                            gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
4060
                            tcg_gen_addi_i32(addr, addr, stride);
 
4061
                            tmp2 = tcg_temp_new_i32();
 
4062
                            gen_aa32_ld16u(tmp2, addr, IS_USER(s));
 
4063
                            tcg_gen_addi_i32(addr, addr, stride);
 
4064
                            tcg_gen_shli_i32(tmp2, tmp2, 16);
 
4065
                            tcg_gen_or_i32(tmp, tmp, tmp2);
 
4066
                            tcg_temp_free_i32(tmp2);
 
4067
                            neon_store_reg(rd, pass, tmp);
 
4068
                        } else {
 
4069
                            tmp = neon_load_reg(rd, pass);
 
4070
                            tmp2 = tcg_temp_new_i32();
 
4071
                            tcg_gen_shri_i32(tmp2, tmp, 16);
 
4072
                            gen_aa32_st16(tmp, addr, IS_USER(s));
 
4073
                            tcg_temp_free_i32(tmp);
 
4074
                            tcg_gen_addi_i32(addr, addr, stride);
 
4075
                            gen_aa32_st16(tmp2, addr, IS_USER(s));
 
4076
                            tcg_temp_free_i32(tmp2);
 
4077
                            tcg_gen_addi_i32(addr, addr, stride);
 
4078
                        }
 
4079
                    } else /* size == 0 */ {
 
4080
                        if (load) {
 
4081
                            TCGV_UNUSED_I32(tmp2);
 
4082
                            for (n = 0; n < 4; n++) {
 
4083
                                tmp = tcg_temp_new_i32();
 
4084
                                gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
4085
                                tcg_gen_addi_i32(addr, addr, stride);
 
4086
                                if (n == 0) {
 
4087
                                    tmp2 = tmp;
 
4088
                                } else {
 
4089
                                    tcg_gen_shli_i32(tmp, tmp, n * 8);
 
4090
                                    tcg_gen_or_i32(tmp2, tmp2, tmp);
 
4091
                                    tcg_temp_free_i32(tmp);
 
4092
                                }
 
4093
                            }
 
4094
                            neon_store_reg(rd, pass, tmp2);
 
4095
                        } else {
 
4096
                            tmp2 = neon_load_reg(rd, pass);
 
4097
                            for (n = 0; n < 4; n++) {
 
4098
                                tmp = tcg_temp_new_i32();
 
4099
                                if (n == 0) {
 
4100
                                    tcg_gen_mov_i32(tmp, tmp2);
 
4101
                                } else {
 
4102
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
 
4103
                                }
 
4104
                                gen_aa32_st8(tmp, addr, IS_USER(s));
 
4105
                                tcg_temp_free_i32(tmp);
 
4106
                                tcg_gen_addi_i32(addr, addr, stride);
 
4107
                            }
 
4108
                            tcg_temp_free_i32(tmp2);
 
4109
                        }
 
4110
                    }
 
4111
                }
 
4112
            }
 
4113
            rd += spacing;
 
4114
        }
 
4115
        tcg_temp_free_i32(addr);
 
4116
        stride = nregs * 8;
 
4117
    } else {
 
4118
        size = (insn >> 10) & 3;
 
4119
        if (size == 3) {
 
4120
            /* Load single element to all lanes.  */
 
4121
            int a = (insn >> 4) & 1;
 
4122
            if (!load) {
 
4123
                return 1;
 
4124
            }
 
4125
            size = (insn >> 6) & 3;
 
4126
            nregs = ((insn >> 8) & 3) + 1;
 
4127
 
 
4128
            if (size == 3) {
 
4129
                if (nregs != 4 || a == 0) {
 
4130
                    return 1;
 
4131
                }
 
4132
                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
 
4133
                size = 2;
 
4134
            }
 
4135
            if (nregs == 1 && a == 1 && size == 0) {
 
4136
                return 1;
 
4137
            }
 
4138
            if (nregs == 3 && a == 1) {
 
4139
                return 1;
 
4140
            }
 
4141
            addr = tcg_temp_new_i32();
 
4142
            load_reg_var(s, addr, rn);
 
4143
            if (nregs == 1) {
 
4144
                /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
 
4145
                tmp = gen_load_and_replicate(s, addr, size);
 
4146
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
 
4147
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
 
4148
                if (insn & (1 << 5)) {
 
4149
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
 
4150
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
 
4151
                }
 
4152
                tcg_temp_free_i32(tmp);
 
4153
            } else {
 
4154
                /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
 
4155
                stride = (insn & (1 << 5)) ? 2 : 1;
 
4156
                for (reg = 0; reg < nregs; reg++) {
 
4157
                    tmp = gen_load_and_replicate(s, addr, size);
 
4158
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
 
4159
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
 
4160
                    tcg_temp_free_i32(tmp);
 
4161
                    tcg_gen_addi_i32(addr, addr, 1 << size);
 
4162
                    rd += stride;
 
4163
                }
 
4164
            }
 
4165
            tcg_temp_free_i32(addr);
 
4166
            stride = (1 << size) * nregs;
 
4167
        } else {
 
4168
            /* Single element.  */
 
4169
            int idx = (insn >> 4) & 0xf;
 
4170
            pass = (insn >> 7) & 1;
 
4171
            switch (size) {
 
4172
            case 0:
 
4173
                shift = ((insn >> 5) & 3) * 8;
 
4174
                stride = 1;
 
4175
                break;
 
4176
            case 1:
 
4177
                shift = ((insn >> 6) & 1) * 16;
 
4178
                stride = (insn & (1 << 5)) ? 2 : 1;
 
4179
                break;
 
4180
            case 2:
 
4181
                shift = 0;
 
4182
                stride = (insn & (1 << 6)) ? 2 : 1;
 
4183
                break;
 
4184
            default:
 
4185
                abort();
 
4186
            }
 
4187
            nregs = ((insn >> 8) & 3) + 1;
 
4188
            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
 
4189
            switch (nregs) {
 
4190
            case 1:
 
4191
                if (((idx & (1 << size)) != 0) ||
 
4192
                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
 
4193
                    return 1;
 
4194
                }
 
4195
                break;
 
4196
            case 3:
 
4197
                if ((idx & 1) != 0) {
 
4198
                    return 1;
 
4199
                }
 
4200
                /* fall through */
 
4201
            case 2:
 
4202
                if (size == 2 && (idx & 2) != 0) {
 
4203
                    return 1;
 
4204
                }
 
4205
                break;
 
4206
            case 4:
 
4207
                if ((size == 2) && ((idx & 3) == 3)) {
 
4208
                    return 1;
 
4209
                }
 
4210
                break;
 
4211
            default:
 
4212
                abort();
 
4213
            }
 
4214
            if ((rd + stride * (nregs - 1)) > 31) {
 
4215
                /* Attempts to write off the end of the register file
 
4216
                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
 
4217
                 * the neon_load_reg() would write off the end of the array.
 
4218
                 */
 
4219
                return 1;
 
4220
            }
 
4221
            addr = tcg_temp_new_i32();
 
4222
            load_reg_var(s, addr, rn);
 
4223
            for (reg = 0; reg < nregs; reg++) {
 
4224
                if (load) {
 
4225
                    tmp = tcg_temp_new_i32();
 
4226
                    switch (size) {
 
4227
                    case 0:
 
4228
                        gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
4229
                        break;
 
4230
                    case 1:
 
4231
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
4232
                        break;
 
4233
                    case 2:
 
4234
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
4235
                        break;
 
4236
                    default: /* Avoid compiler warnings.  */
 
4237
                        abort();
 
4238
                    }
 
4239
                    if (size != 2) {
 
4240
                        tmp2 = neon_load_reg(rd, pass);
 
4241
                        tcg_gen_deposit_i32(tmp, tmp2, tmp,
 
4242
                                            shift, size ? 16 : 8);
 
4243
                        tcg_temp_free_i32(tmp2);
 
4244
                    }
 
4245
                    neon_store_reg(rd, pass, tmp);
 
4246
                } else { /* Store */
 
4247
                    tmp = neon_load_reg(rd, pass);
 
4248
                    if (shift)
 
4249
                        tcg_gen_shri_i32(tmp, tmp, shift);
 
4250
                    switch (size) {
 
4251
                    case 0:
 
4252
                        gen_aa32_st8(tmp, addr, IS_USER(s));
 
4253
                        break;
 
4254
                    case 1:
 
4255
                        gen_aa32_st16(tmp, addr, IS_USER(s));
 
4256
                        break;
 
4257
                    case 2:
 
4258
                        gen_aa32_st32(tmp, addr, IS_USER(s));
 
4259
                        break;
 
4260
                    }
 
4261
                    tcg_temp_free_i32(tmp);
 
4262
                }
 
4263
                rd += stride;
 
4264
                tcg_gen_addi_i32(addr, addr, 1 << size);
 
4265
            }
 
4266
            tcg_temp_free_i32(addr);
 
4267
            stride = nregs * (1 << size);
 
4268
        }
 
4269
    }
 
4270
    if (rm != 15) {
 
4271
        TCGv_i32 base;
 
4272
 
 
4273
        base = load_reg(s, rn);
 
4274
        if (rm == 13) {
 
4275
            tcg_gen_addi_i32(base, base, stride);
 
4276
        } else {
 
4277
            TCGv_i32 index;
 
4278
            index = load_reg(s, rm);
 
4279
            tcg_gen_add_i32(base, base, index);
 
4280
            tcg_temp_free_i32(index);
 
4281
        }
 
4282
        store_reg(s, rn, base);
 
4283
    }
 
4284
    return 0;
 
4285
}
 
4286
 
 
4287
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
 
4288
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
 
4289
{
 
4290
    tcg_gen_and_i32(t, t, c);
 
4291
    tcg_gen_andc_i32(f, f, c);
 
4292
    tcg_gen_or_i32(dest, t, f);
 
4293
}
 
4294
 
 
4295
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
 
4296
{
 
4297
    switch (size) {
 
4298
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
 
4299
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
 
4300
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
 
4301
    default: abort();
 
4302
    }
 
4303
}
 
4304
 
 
4305
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
 
4306
{
 
4307
    switch (size) {
 
4308
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
 
4309
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
 
4310
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
 
4311
    default: abort();
 
4312
    }
 
4313
}
 
4314
 
 
4315
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
 
4316
{
 
4317
    switch (size) {
 
4318
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
 
4319
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
 
4320
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
 
4321
    default: abort();
 
4322
    }
 
4323
}
 
4324
 
 
4325
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
 
4326
{
 
4327
    switch (size) {
 
4328
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
 
4329
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
 
4330
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
 
4331
    default: abort();
 
4332
    }
 
4333
}
 
4334
 
 
4335
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
 
4336
                                         int q, int u)
 
4337
{
 
4338
    if (q) {
 
4339
        if (u) {
 
4340
            switch (size) {
 
4341
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
 
4342
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
 
4343
            default: abort();
 
4344
            }
 
4345
        } else {
 
4346
            switch (size) {
 
4347
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
 
4348
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
 
4349
            default: abort();
 
4350
            }
 
4351
        }
 
4352
    } else {
 
4353
        if (u) {
 
4354
            switch (size) {
 
4355
            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
 
4356
            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
 
4357
            default: abort();
 
4358
            }
 
4359
        } else {
 
4360
            switch (size) {
 
4361
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
 
4362
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
 
4363
            default: abort();
 
4364
            }
 
4365
        }
 
4366
    }
 
4367
}
 
4368
 
 
4369
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
 
4370
{
 
4371
    if (u) {
 
4372
        switch (size) {
 
4373
        case 0: gen_helper_neon_widen_u8(dest, src); break;
 
4374
        case 1: gen_helper_neon_widen_u16(dest, src); break;
 
4375
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
 
4376
        default: abort();
 
4377
        }
 
4378
    } else {
 
4379
        switch (size) {
 
4380
        case 0: gen_helper_neon_widen_s8(dest, src); break;
 
4381
        case 1: gen_helper_neon_widen_s16(dest, src); break;
 
4382
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
 
4383
        default: abort();
 
4384
        }
 
4385
    }
 
4386
    tcg_temp_free_i32(src);
 
4387
}
 
4388
 
 
4389
static inline void gen_neon_addl(int size)
 
4390
{
 
4391
    switch (size) {
 
4392
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
 
4393
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
 
4394
    case 2: tcg_gen_add_i64(CPU_V001); break;
 
4395
    default: abort();
 
4396
    }
 
4397
}
 
4398
 
 
4399
static inline void gen_neon_subl(int size)
 
4400
{
 
4401
    switch (size) {
 
4402
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
 
4403
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
 
4404
    case 2: tcg_gen_sub_i64(CPU_V001); break;
 
4405
    default: abort();
 
4406
    }
 
4407
}
 
4408
 
 
4409
static inline void gen_neon_negl(TCGv_i64 var, int size)
 
4410
{
 
4411
    switch (size) {
 
4412
    case 0: gen_helper_neon_negl_u16(var, var); break;
 
4413
    case 1: gen_helper_neon_negl_u32(var, var); break;
 
4414
    case 2:
 
4415
        tcg_gen_neg_i64(var, var);
 
4416
        break;
 
4417
    default: abort();
 
4418
    }
 
4419
}
 
4420
 
 
4421
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
 
4422
{
 
4423
    switch (size) {
 
4424
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
 
4425
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
 
4426
    default: abort();
 
4427
    }
 
4428
}
 
4429
 
 
4430
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
 
4431
                                 int size, int u)
 
4432
{
 
4433
    TCGv_i64 tmp;
 
4434
 
 
4435
    switch ((size << 1) | u) {
 
4436
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
 
4437
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
 
4438
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
 
4439
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
 
4440
    case 4:
 
4441
        tmp = gen_muls_i64_i32(a, b);
 
4442
        tcg_gen_mov_i64(dest, tmp);
 
4443
        tcg_temp_free_i64(tmp);
 
4444
        break;
 
4445
    case 5:
 
4446
        tmp = gen_mulu_i64_i32(a, b);
 
4447
        tcg_gen_mov_i64(dest, tmp);
 
4448
        tcg_temp_free_i64(tmp);
 
4449
        break;
 
4450
    default: abort();
 
4451
    }
 
4452
 
 
4453
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
 
4454
       Don't forget to clean them now.  */
 
4455
    if (size < 2) {
 
4456
        tcg_temp_free_i32(a);
 
4457
        tcg_temp_free_i32(b);
 
4458
    }
 
4459
}
 
4460
 
 
4461
static void gen_neon_narrow_op(int op, int u, int size,
 
4462
                               TCGv_i32 dest, TCGv_i64 src)
 
4463
{
 
4464
    if (op) {
 
4465
        if (u) {
 
4466
            gen_neon_unarrow_sats(size, dest, src);
 
4467
        } else {
 
4468
            gen_neon_narrow(size, dest, src);
 
4469
        }
 
4470
    } else {
 
4471
        if (u) {
 
4472
            gen_neon_narrow_satu(size, dest, src);
 
4473
        } else {
 
4474
            gen_neon_narrow_sats(size, dest, src);
 
4475
        }
 
4476
    }
 
4477
}
 
4478
 
 
4479
/* Symbolic constants for op fields for Neon 3-register same-length.
 
4480
 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
 
4481
 * table A7-9.
 
4482
 */
 
4483
#define NEON_3R_VHADD 0
 
4484
#define NEON_3R_VQADD 1
 
4485
#define NEON_3R_VRHADD 2
 
4486
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
 
4487
#define NEON_3R_VHSUB 4
 
4488
#define NEON_3R_VQSUB 5
 
4489
#define NEON_3R_VCGT 6
 
4490
#define NEON_3R_VCGE 7
 
4491
#define NEON_3R_VSHL 8
 
4492
#define NEON_3R_VQSHL 9
 
4493
#define NEON_3R_VRSHL 10
 
4494
#define NEON_3R_VQRSHL 11
 
4495
#define NEON_3R_VMAX 12
 
4496
#define NEON_3R_VMIN 13
 
4497
#define NEON_3R_VABD 14
 
4498
#define NEON_3R_VABA 15
 
4499
#define NEON_3R_VADD_VSUB 16
 
4500
#define NEON_3R_VTST_VCEQ 17
 
4501
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
 
4502
#define NEON_3R_VMUL 19
 
4503
#define NEON_3R_VPMAX 20
 
4504
#define NEON_3R_VPMIN 21
 
4505
#define NEON_3R_VQDMULH_VQRDMULH 22
 
4506
#define NEON_3R_VPADD 23
 
4507
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
 
4508
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
 
4509
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
 
4510
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
 
4511
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
 
4512
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
 
4513
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
 
4514
 
 
4515
static const uint8_t neon_3r_sizes[] = {
 
4516
    [NEON_3R_VHADD] = 0x7,
 
4517
    [NEON_3R_VQADD] = 0xf,
 
4518
    [NEON_3R_VRHADD] = 0x7,
 
4519
    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
 
4520
    [NEON_3R_VHSUB] = 0x7,
 
4521
    [NEON_3R_VQSUB] = 0xf,
 
4522
    [NEON_3R_VCGT] = 0x7,
 
4523
    [NEON_3R_VCGE] = 0x7,
 
4524
    [NEON_3R_VSHL] = 0xf,
 
4525
    [NEON_3R_VQSHL] = 0xf,
 
4526
    [NEON_3R_VRSHL] = 0xf,
 
4527
    [NEON_3R_VQRSHL] = 0xf,
 
4528
    [NEON_3R_VMAX] = 0x7,
 
4529
    [NEON_3R_VMIN] = 0x7,
 
4530
    [NEON_3R_VABD] = 0x7,
 
4531
    [NEON_3R_VABA] = 0x7,
 
4532
    [NEON_3R_VADD_VSUB] = 0xf,
 
4533
    [NEON_3R_VTST_VCEQ] = 0x7,
 
4534
    [NEON_3R_VML] = 0x7,
 
4535
    [NEON_3R_VMUL] = 0x7,
 
4536
    [NEON_3R_VPMAX] = 0x7,
 
4537
    [NEON_3R_VPMIN] = 0x7,
 
4538
    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
 
4539
    [NEON_3R_VPADD] = 0x7,
 
4540
    [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
 
4541
    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
 
4542
    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
 
4543
    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
 
4544
    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
 
4545
    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
 
4546
    [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
 
4547
};
 
4548
 
 
4549
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
 
4550
 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
 
4551
 * table A7-13.
 
4552
 */
 
4553
#define NEON_2RM_VREV64 0
 
4554
#define NEON_2RM_VREV32 1
 
4555
#define NEON_2RM_VREV16 2
 
4556
#define NEON_2RM_VPADDL 4
 
4557
#define NEON_2RM_VPADDL_U 5
 
4558
#define NEON_2RM_VCLS 8
 
4559
#define NEON_2RM_VCLZ 9
 
4560
#define NEON_2RM_VCNT 10
 
4561
#define NEON_2RM_VMVN 11
 
4562
#define NEON_2RM_VPADAL 12
 
4563
#define NEON_2RM_VPADAL_U 13
 
4564
#define NEON_2RM_VQABS 14
 
4565
#define NEON_2RM_VQNEG 15
 
4566
#define NEON_2RM_VCGT0 16
 
4567
#define NEON_2RM_VCGE0 17
 
4568
#define NEON_2RM_VCEQ0 18
 
4569
#define NEON_2RM_VCLE0 19
 
4570
#define NEON_2RM_VCLT0 20
 
4571
#define NEON_2RM_VABS 22
 
4572
#define NEON_2RM_VNEG 23
 
4573
#define NEON_2RM_VCGT0_F 24
 
4574
#define NEON_2RM_VCGE0_F 25
 
4575
#define NEON_2RM_VCEQ0_F 26
 
4576
#define NEON_2RM_VCLE0_F 27
 
4577
#define NEON_2RM_VCLT0_F 28
 
4578
#define NEON_2RM_VABS_F 30
 
4579
#define NEON_2RM_VNEG_F 31
 
4580
#define NEON_2RM_VSWP 32
 
4581
#define NEON_2RM_VTRN 33
 
4582
#define NEON_2RM_VUZP 34
 
4583
#define NEON_2RM_VZIP 35
 
4584
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
 
4585
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
 
4586
#define NEON_2RM_VSHLL 38
 
4587
#define NEON_2RM_VCVT_F16_F32 44
 
4588
#define NEON_2RM_VCVT_F32_F16 46
 
4589
#define NEON_2RM_VRECPE 56
 
4590
#define NEON_2RM_VRSQRTE 57
 
4591
#define NEON_2RM_VRECPE_F 58
 
4592
#define NEON_2RM_VRSQRTE_F 59
 
4593
#define NEON_2RM_VCVT_FS 60
 
4594
#define NEON_2RM_VCVT_FU 61
 
4595
#define NEON_2RM_VCVT_SF 62
 
4596
#define NEON_2RM_VCVT_UF 63
 
4597
 
 
4598
static int neon_2rm_is_float_op(int op)
 
4599
{
 
4600
    /* Return true if this neon 2reg-misc op is float-to-float */
 
4601
    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
 
4602
            op >= NEON_2RM_VRECPE_F);
 
4603
}
 
4604
 
 
4605
/* Each entry in this array has bit n set if the insn allows
 
4606
 * size value n (otherwise it will UNDEF). Since unallocated
 
4607
 * op values will have no bits set they always UNDEF.
 
4608
 */
 
4609
static const uint8_t neon_2rm_sizes[] = {
 
4610
    [NEON_2RM_VREV64] = 0x7,
 
4611
    [NEON_2RM_VREV32] = 0x3,
 
4612
    [NEON_2RM_VREV16] = 0x1,
 
4613
    [NEON_2RM_VPADDL] = 0x7,
 
4614
    [NEON_2RM_VPADDL_U] = 0x7,
 
4615
    [NEON_2RM_VCLS] = 0x7,
 
4616
    [NEON_2RM_VCLZ] = 0x7,
 
4617
    [NEON_2RM_VCNT] = 0x1,
 
4618
    [NEON_2RM_VMVN] = 0x1,
 
4619
    [NEON_2RM_VPADAL] = 0x7,
 
4620
    [NEON_2RM_VPADAL_U] = 0x7,
 
4621
    [NEON_2RM_VQABS] = 0x7,
 
4622
    [NEON_2RM_VQNEG] = 0x7,
 
4623
    [NEON_2RM_VCGT0] = 0x7,
 
4624
    [NEON_2RM_VCGE0] = 0x7,
 
4625
    [NEON_2RM_VCEQ0] = 0x7,
 
4626
    [NEON_2RM_VCLE0] = 0x7,
 
4627
    [NEON_2RM_VCLT0] = 0x7,
 
4628
    [NEON_2RM_VABS] = 0x7,
 
4629
    [NEON_2RM_VNEG] = 0x7,
 
4630
    [NEON_2RM_VCGT0_F] = 0x4,
 
4631
    [NEON_2RM_VCGE0_F] = 0x4,
 
4632
    [NEON_2RM_VCEQ0_F] = 0x4,
 
4633
    [NEON_2RM_VCLE0_F] = 0x4,
 
4634
    [NEON_2RM_VCLT0_F] = 0x4,
 
4635
    [NEON_2RM_VABS_F] = 0x4,
 
4636
    [NEON_2RM_VNEG_F] = 0x4,
 
4637
    [NEON_2RM_VSWP] = 0x1,
 
4638
    [NEON_2RM_VTRN] = 0x7,
 
4639
    [NEON_2RM_VUZP] = 0x7,
 
4640
    [NEON_2RM_VZIP] = 0x7,
 
4641
    [NEON_2RM_VMOVN] = 0x7,
 
4642
    [NEON_2RM_VQMOVN] = 0x7,
 
4643
    [NEON_2RM_VSHLL] = 0x7,
 
4644
    [NEON_2RM_VCVT_F16_F32] = 0x2,
 
4645
    [NEON_2RM_VCVT_F32_F16] = 0x2,
 
4646
    [NEON_2RM_VRECPE] = 0x4,
 
4647
    [NEON_2RM_VRSQRTE] = 0x4,
 
4648
    [NEON_2RM_VRECPE_F] = 0x4,
 
4649
    [NEON_2RM_VRSQRTE_F] = 0x4,
 
4650
    [NEON_2RM_VCVT_FS] = 0x4,
 
4651
    [NEON_2RM_VCVT_FU] = 0x4,
 
4652
    [NEON_2RM_VCVT_SF] = 0x4,
 
4653
    [NEON_2RM_VCVT_UF] = 0x4,
 
4654
};
 
4655
 
 
4656
/* Translate a NEON data processing instruction.  Return nonzero if the
 
4657
   instruction is invalid.
 
4658
   We process data in a mixture of 32-bit and 64-bit chunks.
 
4659
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
 
4660
 
 
4661
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 
4662
{
 
4663
    int op;
 
4664
    int q;
 
4665
    int rd, rn, rm;
 
4666
    int size;
 
4667
    int shift;
 
4668
    int pass;
 
4669
    int count;
 
4670
    int pairwise;
 
4671
    int u;
 
4672
    uint32_t imm, mask;
 
4673
    TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
 
4674
    TCGv_i64 tmp64;
 
4675
 
 
4676
    if (!s->vfp_enabled)
 
4677
      return 1;
 
4678
    q = (insn & (1 << 6)) != 0;
 
4679
    u = (insn >> 24) & 1;
 
4680
    VFP_DREG_D(rd, insn);
 
4681
    VFP_DREG_N(rn, insn);
 
4682
    VFP_DREG_M(rm, insn);
 
4683
    size = (insn >> 20) & 3;
 
4684
    if ((insn & (1 << 23)) == 0) {
 
4685
        /* Three register same length.  */
 
4686
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
 
4687
        /* Catch invalid op and bad size combinations: UNDEF */
 
4688
        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
 
4689
            return 1;
 
4690
        }
 
4691
        /* All insns of this form UNDEF for either this condition or the
 
4692
         * superset of cases "Q==1"; we catch the latter later.
 
4693
         */
 
4694
        if (q && ((rd | rn | rm) & 1)) {
 
4695
            return 1;
 
4696
        }
 
4697
        if (size == 3 && op != NEON_3R_LOGIC) {
 
4698
            /* 64-bit element instructions. */
 
4699
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
 
4700
                neon_load_reg64(cpu_V0, rn + pass);
 
4701
                neon_load_reg64(cpu_V1, rm + pass);
 
4702
                switch (op) {
 
4703
                case NEON_3R_VQADD:
 
4704
                    if (u) {
 
4705
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
 
4706
                                                 cpu_V0, cpu_V1);
 
4707
                    } else {
 
4708
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
 
4709
                                                 cpu_V0, cpu_V1);
 
4710
                    }
 
4711
                    break;
 
4712
                case NEON_3R_VQSUB:
 
4713
                    if (u) {
 
4714
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
 
4715
                                                 cpu_V0, cpu_V1);
 
4716
                    } else {
 
4717
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
 
4718
                                                 cpu_V0, cpu_V1);
 
4719
                    }
 
4720
                    break;
 
4721
                case NEON_3R_VSHL:
 
4722
                    if (u) {
 
4723
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
 
4724
                    } else {
 
4725
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
 
4726
                    }
 
4727
                    break;
 
4728
                case NEON_3R_VQSHL:
 
4729
                    if (u) {
 
4730
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
 
4731
                                                 cpu_V1, cpu_V0);
 
4732
                    } else {
 
4733
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
 
4734
                                                 cpu_V1, cpu_V0);
 
4735
                    }
 
4736
                    break;
 
4737
                case NEON_3R_VRSHL:
 
4738
                    if (u) {
 
4739
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
 
4740
                    } else {
 
4741
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
 
4742
                    }
 
4743
                    break;
 
4744
                case NEON_3R_VQRSHL:
 
4745
                    if (u) {
 
4746
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
 
4747
                                                  cpu_V1, cpu_V0);
 
4748
                    } else {
 
4749
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
 
4750
                                                  cpu_V1, cpu_V0);
 
4751
                    }
 
4752
                    break;
 
4753
                case NEON_3R_VADD_VSUB:
 
4754
                    if (u) {
 
4755
                        tcg_gen_sub_i64(CPU_V001);
 
4756
                    } else {
 
4757
                        tcg_gen_add_i64(CPU_V001);
 
4758
                    }
 
4759
                    break;
 
4760
                default:
 
4761
                    abort();
 
4762
                }
 
4763
                neon_store_reg64(cpu_V0, rd + pass);
 
4764
            }
 
4765
            return 0;
 
4766
        }
 
4767
        pairwise = 0;
 
4768
        switch (op) {
 
4769
        case NEON_3R_VSHL:
 
4770
        case NEON_3R_VQSHL:
 
4771
        case NEON_3R_VRSHL:
 
4772
        case NEON_3R_VQRSHL:
 
4773
            {
 
4774
                int rtmp;
 
4775
                /* Shift instruction operands are reversed.  */
 
4776
                rtmp = rn;
 
4777
                rn = rm;
 
4778
                rm = rtmp;
 
4779
            }
 
4780
            break;
 
4781
        case NEON_3R_VPADD:
 
4782
            if (u) {
 
4783
                return 1;
 
4784
            }
 
4785
            /* Fall through */
 
4786
        case NEON_3R_VPMAX:
 
4787
        case NEON_3R_VPMIN:
 
4788
            pairwise = 1;
 
4789
            break;
 
4790
        case NEON_3R_FLOAT_ARITH:
 
4791
            pairwise = (u && size < 2); /* if VPADD (float) */
 
4792
            break;
 
4793
        case NEON_3R_FLOAT_MINMAX:
 
4794
            pairwise = u; /* if VPMIN/VPMAX (float) */
 
4795
            break;
 
4796
        case NEON_3R_FLOAT_CMP:
 
4797
            if (!u && size) {
 
4798
                /* no encoding for U=0 C=1x */
 
4799
                return 1;
 
4800
            }
 
4801
            break;
 
4802
        case NEON_3R_FLOAT_ACMP:
 
4803
            if (!u) {
 
4804
                return 1;
 
4805
            }
 
4806
            break;
 
4807
        case NEON_3R_VRECPS_VRSQRTS:
 
4808
            if (u) {
 
4809
                return 1;
 
4810
            }
 
4811
            break;
 
4812
        case NEON_3R_VMUL:
 
4813
            if (u && (size != 0)) {
 
4814
                /* UNDEF on invalid size for polynomial subcase */
 
4815
                return 1;
 
4816
            }
 
4817
            break;
 
4818
        case NEON_3R_VFM:
 
4819
            if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
 
4820
                return 1;
 
4821
            }
 
4822
            break;
 
4823
        default:
 
4824
            break;
 
4825
        }
 
4826
 
 
4827
        if (pairwise && q) {
 
4828
            /* All the pairwise insns UNDEF if Q is set */
 
4829
            return 1;
 
4830
        }
 
4831
 
 
4832
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
 
4833
 
 
4834
        if (pairwise) {
 
4835
            /* Pairwise.  */
 
4836
            if (pass < 1) {
 
4837
                tmp = neon_load_reg(rn, 0);
 
4838
                tmp2 = neon_load_reg(rn, 1);
 
4839
            } else {
 
4840
                tmp = neon_load_reg(rm, 0);
 
4841
                tmp2 = neon_load_reg(rm, 1);
 
4842
            }
 
4843
        } else {
 
4844
            /* Elementwise.  */
 
4845
            tmp = neon_load_reg(rn, pass);
 
4846
            tmp2 = neon_load_reg(rm, pass);
 
4847
        }
 
4848
        switch (op) {
 
4849
        case NEON_3R_VHADD:
 
4850
            GEN_NEON_INTEGER_OP(hadd);
 
4851
            break;
 
4852
        case NEON_3R_VQADD:
 
4853
            GEN_NEON_INTEGER_OP_ENV(qadd);
 
4854
            break;
 
4855
        case NEON_3R_VRHADD:
 
4856
            GEN_NEON_INTEGER_OP(rhadd);
 
4857
            break;
 
4858
        case NEON_3R_LOGIC: /* Logic ops.  */
 
4859
            switch ((u << 2) | size) {
 
4860
            case 0: /* VAND */
 
4861
                tcg_gen_and_i32(tmp, tmp, tmp2);
 
4862
                break;
 
4863
            case 1: /* BIC */
 
4864
                tcg_gen_andc_i32(tmp, tmp, tmp2);
 
4865
                break;
 
4866
            case 2: /* VORR */
 
4867
                tcg_gen_or_i32(tmp, tmp, tmp2);
 
4868
                break;
 
4869
            case 3: /* VORN */
 
4870
                tcg_gen_orc_i32(tmp, tmp, tmp2);
 
4871
                break;
 
4872
            case 4: /* VEOR */
 
4873
                tcg_gen_xor_i32(tmp, tmp, tmp2);
 
4874
                break;
 
4875
            case 5: /* VBSL */
 
4876
                tmp3 = neon_load_reg(rd, pass);
 
4877
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
 
4878
                tcg_temp_free_i32(tmp3);
 
4879
                break;
 
4880
            case 6: /* VBIT */
 
4881
                tmp3 = neon_load_reg(rd, pass);
 
4882
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
 
4883
                tcg_temp_free_i32(tmp3);
 
4884
                break;
 
4885
            case 7: /* VBIF */
 
4886
                tmp3 = neon_load_reg(rd, pass);
 
4887
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
 
4888
                tcg_temp_free_i32(tmp3);
 
4889
                break;
 
4890
            }
 
4891
            break;
 
4892
        case NEON_3R_VHSUB:
 
4893
            GEN_NEON_INTEGER_OP(hsub);
 
4894
            break;
 
4895
        case NEON_3R_VQSUB:
 
4896
            GEN_NEON_INTEGER_OP_ENV(qsub);
 
4897
            break;
 
4898
        case NEON_3R_VCGT:
 
4899
            GEN_NEON_INTEGER_OP(cgt);
 
4900
            break;
 
4901
        case NEON_3R_VCGE:
 
4902
            GEN_NEON_INTEGER_OP(cge);
 
4903
            break;
 
4904
        case NEON_3R_VSHL:
 
4905
            GEN_NEON_INTEGER_OP(shl);
 
4906
            break;
 
4907
        case NEON_3R_VQSHL:
 
4908
            GEN_NEON_INTEGER_OP_ENV(qshl);
 
4909
            break;
 
4910
        case NEON_3R_VRSHL:
 
4911
            GEN_NEON_INTEGER_OP(rshl);
 
4912
            break;
 
4913
        case NEON_3R_VQRSHL:
 
4914
            GEN_NEON_INTEGER_OP_ENV(qrshl);
 
4915
            break;
 
4916
        case NEON_3R_VMAX:
 
4917
            GEN_NEON_INTEGER_OP(max);
 
4918
            break;
 
4919
        case NEON_3R_VMIN:
 
4920
            GEN_NEON_INTEGER_OP(min);
 
4921
            break;
 
4922
        case NEON_3R_VABD:
 
4923
            GEN_NEON_INTEGER_OP(abd);
 
4924
            break;
 
4925
        case NEON_3R_VABA:
 
4926
            GEN_NEON_INTEGER_OP(abd);
 
4927
            tcg_temp_free_i32(tmp2);
 
4928
            tmp2 = neon_load_reg(rd, pass);
 
4929
            gen_neon_add(size, tmp, tmp2);
 
4930
            break;
 
4931
        case NEON_3R_VADD_VSUB:
 
4932
            if (!u) { /* VADD */
 
4933
                gen_neon_add(size, tmp, tmp2);
 
4934
            } else { /* VSUB */
 
4935
                switch (size) {
 
4936
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
 
4937
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
 
4938
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
 
4939
                default: abort();
 
4940
                }
 
4941
            }
 
4942
            break;
 
4943
        case NEON_3R_VTST_VCEQ:
 
4944
            if (!u) { /* VTST */
 
4945
                switch (size) {
 
4946
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
 
4947
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
 
4948
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
 
4949
                default: abort();
 
4950
                }
 
4951
            } else { /* VCEQ */
 
4952
                switch (size) {
 
4953
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
 
4954
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
 
4955
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
 
4956
                default: abort();
 
4957
                }
 
4958
            }
 
4959
            break;
 
4960
        case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
 
4961
            switch (size) {
 
4962
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
 
4963
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
 
4964
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
 
4965
            default: abort();
 
4966
            }
 
4967
            tcg_temp_free_i32(tmp2);
 
4968
            tmp2 = neon_load_reg(rd, pass);
 
4969
            if (u) { /* VMLS */
 
4970
                gen_neon_rsb(size, tmp, tmp2);
 
4971
            } else { /* VMLA */
 
4972
                gen_neon_add(size, tmp, tmp2);
 
4973
            }
 
4974
            break;
 
4975
        case NEON_3R_VMUL:
 
4976
            if (u) { /* polynomial */
 
4977
                gen_helper_neon_mul_p8(tmp, tmp, tmp2);
 
4978
            } else { /* Integer */
 
4979
                switch (size) {
 
4980
                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
 
4981
                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
 
4982
                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
 
4983
                default: abort();
 
4984
                }
 
4985
            }
 
4986
            break;
 
4987
        case NEON_3R_VPMAX:
 
4988
            GEN_NEON_INTEGER_OP(pmax);
 
4989
            break;
 
4990
        case NEON_3R_VPMIN:
 
4991
            GEN_NEON_INTEGER_OP(pmin);
 
4992
            break;
 
4993
        case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
 
4994
            if (!u) { /* VQDMULH */
 
4995
                switch (size) {
 
4996
                case 1:
 
4997
                    gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
 
4998
                    break;
 
4999
                case 2:
 
5000
                    gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
 
5001
                    break;
 
5002
                default: abort();
 
5003
                }
 
5004
            } else { /* VQRDMULH */
 
5005
                switch (size) {
 
5006
                case 1:
 
5007
                    gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
 
5008
                    break;
 
5009
                case 2:
 
5010
                    gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
 
5011
                    break;
 
5012
                default: abort();
 
5013
                }
 
5014
            }
 
5015
            break;
 
5016
        case NEON_3R_VPADD:
 
5017
            switch (size) {
 
5018
            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
 
5019
            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
 
5020
            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
 
5021
            default: abort();
 
5022
            }
 
5023
            break;
 
5024
        case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
 
5025
        {
 
5026
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
5027
            switch ((u << 2) | size) {
 
5028
            case 0: /* VADD */
 
5029
            case 4: /* VPADD */
 
5030
                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
 
5031
                break;
 
5032
            case 2: /* VSUB */
 
5033
                gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
 
5034
                break;
 
5035
            case 6: /* VABD */
 
5036
                gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
 
5037
                break;
 
5038
            default:
 
5039
                abort();
 
5040
            }
 
5041
            tcg_temp_free_ptr(fpstatus);
 
5042
            break;
 
5043
        }
 
5044
        case NEON_3R_FLOAT_MULTIPLY:
 
5045
        {
 
5046
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
5047
            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
 
5048
            if (!u) {
 
5049
                tcg_temp_free_i32(tmp2);
 
5050
                tmp2 = neon_load_reg(rd, pass);
 
5051
                if (size == 0) {
 
5052
                    gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
 
5053
                } else {
 
5054
                    gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
 
5055
                }
 
5056
            }
 
5057
            tcg_temp_free_ptr(fpstatus);
 
5058
            break;
 
5059
        }
 
5060
        case NEON_3R_FLOAT_CMP:
 
5061
        {
 
5062
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
5063
            if (!u) {
 
5064
                gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
 
5065
            } else {
 
5066
                if (size == 0) {
 
5067
                    gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
 
5068
                } else {
 
5069
                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
 
5070
                }
 
5071
            }
 
5072
            tcg_temp_free_ptr(fpstatus);
 
5073
            break;
 
5074
        }
 
5075
        case NEON_3R_FLOAT_ACMP:
 
5076
        {
 
5077
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
5078
            if (size == 0) {
 
5079
                gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
 
5080
            } else {
 
5081
                gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
 
5082
            }
 
5083
            tcg_temp_free_ptr(fpstatus);
 
5084
            break;
 
5085
        }
 
5086
        case NEON_3R_FLOAT_MINMAX:
 
5087
        {
 
5088
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
5089
            if (size == 0) {
 
5090
                gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
 
5091
            } else {
 
5092
                gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
 
5093
            }
 
5094
            tcg_temp_free_ptr(fpstatus);
 
5095
            break;
 
5096
        }
 
5097
        case NEON_3R_VRECPS_VRSQRTS:
 
5098
            if (size == 0)
 
5099
                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
 
5100
            else
 
5101
                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
 
5102
            break;
 
5103
        case NEON_3R_VFM:
 
5104
        {
 
5105
            /* VFMA, VFMS: fused multiply-add */
 
5106
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
5107
            TCGv_i32 tmp3 = neon_load_reg(rd, pass);
 
5108
            if (size) {
 
5109
                /* VFMS */
 
5110
                gen_helper_vfp_negs(tmp, tmp);
 
5111
            }
 
5112
            gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
 
5113
            tcg_temp_free_i32(tmp3);
 
5114
            tcg_temp_free_ptr(fpstatus);
 
5115
            break;
 
5116
        }
 
5117
        default:
 
5118
            abort();
 
5119
        }
 
5120
        tcg_temp_free_i32(tmp2);
 
5121
 
 
5122
        /* Save the result.  For elementwise operations we can put it
 
5123
           straight into the destination register.  For pairwise operations
 
5124
           we have to be careful to avoid clobbering the source operands.  */
 
5125
        if (pairwise && rd == rm) {
 
5126
            neon_store_scratch(pass, tmp);
 
5127
        } else {
 
5128
            neon_store_reg(rd, pass, tmp);
 
5129
        }
 
5130
 
 
5131
        } /* for pass */
 
5132
        if (pairwise && rd == rm) {
 
5133
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
 
5134
                tmp = neon_load_scratch(pass);
 
5135
                neon_store_reg(rd, pass, tmp);
 
5136
            }
 
5137
        }
 
5138
        /* End of 3 register same size operations.  */
 
5139
    } else if (insn & (1 << 4)) {
 
5140
        if ((insn & 0x00380080) != 0) {
 
5141
            /* Two registers and shift.  */
 
5142
            op = (insn >> 8) & 0xf;
 
5143
            if (insn & (1 << 7)) {
 
5144
                /* 64-bit shift. */
 
5145
                if (op > 7) {
 
5146
                    return 1;
 
5147
                }
 
5148
                size = 3;
 
5149
            } else {
 
5150
                size = 2;
 
5151
                while ((insn & (1 << (size + 19))) == 0)
 
5152
                    size--;
 
5153
            }
 
5154
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
 
5155
            /* To avoid excessive duplication of ops we implement shift
 
5156
               by immediate using the variable shift operations.  */
 
5157
            if (op < 8) {
 
5158
                /* Shift by immediate:
 
5159
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
 
5160
                if (q && ((rd | rm) & 1)) {
 
5161
                    return 1;
 
5162
                }
 
5163
                if (!u && (op == 4 || op == 6)) {
 
5164
                    return 1;
 
5165
                }
 
5166
                /* Right shifts are encoded as N - shift, where N is the
 
5167
                   element size in bits.  */
 
5168
                if (op <= 4)
 
5169
                    shift = shift - (1 << (size + 3));
 
5170
                if (size == 3) {
 
5171
                    count = q + 1;
 
5172
                } else {
 
5173
                    count = q ? 4: 2;
 
5174
                }
 
5175
                switch (size) {
 
5176
                case 0:
 
5177
                    imm = (uint8_t) shift;
 
5178
                    imm |= imm << 8;
 
5179
                    imm |= imm << 16;
 
5180
                    break;
 
5181
                case 1:
 
5182
                    imm = (uint16_t) shift;
 
5183
                    imm |= imm << 16;
 
5184
                    break;
 
5185
                case 2:
 
5186
                case 3:
 
5187
                    imm = shift;
 
5188
                    break;
 
5189
                default:
 
5190
                    abort();
 
5191
                }
 
5192
 
 
5193
                for (pass = 0; pass < count; pass++) {
 
5194
                    if (size == 3) {
 
5195
                        neon_load_reg64(cpu_V0, rm + pass);
 
5196
                        tcg_gen_movi_i64(cpu_V1, imm);
 
5197
                        switch (op) {
 
5198
                        case 0:  /* VSHR */
 
5199
                        case 1:  /* VSRA */
 
5200
                            if (u)
 
5201
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
 
5202
                            else
 
5203
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
 
5204
                            break;
 
5205
                        case 2: /* VRSHR */
 
5206
                        case 3: /* VRSRA */
 
5207
                            if (u)
 
5208
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
 
5209
                            else
 
5210
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
 
5211
                            break;
 
5212
                        case 4: /* VSRI */
 
5213
                        case 5: /* VSHL, VSLI */
 
5214
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
 
5215
                            break;
 
5216
                        case 6: /* VQSHLU */
 
5217
                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
 
5218
                                                      cpu_V0, cpu_V1);
 
5219
                            break;
 
5220
                        case 7: /* VQSHL */
 
5221
                            if (u) {
 
5222
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
 
5223
                                                         cpu_V0, cpu_V1);
 
5224
                            } else {
 
5225
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
 
5226
                                                         cpu_V0, cpu_V1);
 
5227
                            }
 
5228
                            break;
 
5229
                        }
 
5230
                        if (op == 1 || op == 3) {
 
5231
                            /* Accumulate.  */
 
5232
                            neon_load_reg64(cpu_V1, rd + pass);
 
5233
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
 
5234
                        } else if (op == 4 || (op == 5 && u)) {
 
5235
                            /* Insert */
 
5236
                            neon_load_reg64(cpu_V1, rd + pass);
 
5237
                            uint64_t mask;
 
5238
                            if (shift < -63 || shift > 63) {
 
5239
                                mask = 0;
 
5240
                            } else {
 
5241
                                if (op == 4) {
 
5242
                                    mask = 0xffffffffffffffffull >> -shift;
 
5243
                                } else {
 
5244
                                    mask = 0xffffffffffffffffull << shift;
 
5245
                                }
 
5246
                            }
 
5247
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
 
5248
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
 
5249
                        }
 
5250
                        neon_store_reg64(cpu_V0, rd + pass);
 
5251
                    } else { /* size < 3 */
 
5252
                        /* Operands in T0 and T1.  */
 
5253
                        tmp = neon_load_reg(rm, pass);
 
5254
                        tmp2 = tcg_temp_new_i32();
 
5255
                        tcg_gen_movi_i32(tmp2, imm);
 
5256
                        switch (op) {
 
5257
                        case 0:  /* VSHR */
 
5258
                        case 1:  /* VSRA */
 
5259
                            GEN_NEON_INTEGER_OP(shl);
 
5260
                            break;
 
5261
                        case 2: /* VRSHR */
 
5262
                        case 3: /* VRSRA */
 
5263
                            GEN_NEON_INTEGER_OP(rshl);
 
5264
                            break;
 
5265
                        case 4: /* VSRI */
 
5266
                        case 5: /* VSHL, VSLI */
 
5267
                            switch (size) {
 
5268
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
 
5269
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
 
5270
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
 
5271
                            default: abort();
 
5272
                            }
 
5273
                            break;
 
5274
                        case 6: /* VQSHLU */
 
5275
                            switch (size) {
 
5276
                            case 0:
 
5277
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
 
5278
                                                         tmp, tmp2);
 
5279
                                break;
 
5280
                            case 1:
 
5281
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
 
5282
                                                          tmp, tmp2);
 
5283
                                break;
 
5284
                            case 2:
 
5285
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
 
5286
                                                          tmp, tmp2);
 
5287
                                break;
 
5288
                            default:
 
5289
                                abort();
 
5290
                            }
 
5291
                            break;
 
5292
                        case 7: /* VQSHL */
 
5293
                            GEN_NEON_INTEGER_OP_ENV(qshl);
 
5294
                            break;
 
5295
                        }
 
5296
                        tcg_temp_free_i32(tmp2);
 
5297
 
 
5298
                        if (op == 1 || op == 3) {
 
5299
                            /* Accumulate.  */
 
5300
                            tmp2 = neon_load_reg(rd, pass);
 
5301
                            gen_neon_add(size, tmp, tmp2);
 
5302
                            tcg_temp_free_i32(tmp2);
 
5303
                        } else if (op == 4 || (op == 5 && u)) {
 
5304
                            /* Insert */
 
5305
                            switch (size) {
 
5306
                            case 0:
 
5307
                                if (op == 4)
 
5308
                                    mask = 0xff >> -shift;
 
5309
                                else
 
5310
                                    mask = (uint8_t)(0xff << shift);
 
5311
                                mask |= mask << 8;
 
5312
                                mask |= mask << 16;
 
5313
                                break;
 
5314
                            case 1:
 
5315
                                if (op == 4)
 
5316
                                    mask = 0xffff >> -shift;
 
5317
                                else
 
5318
                                    mask = (uint16_t)(0xffff << shift);
 
5319
                                mask |= mask << 16;
 
5320
                                break;
 
5321
                            case 2:
 
5322
                                if (shift < -31 || shift > 31) {
 
5323
                                    mask = 0;
 
5324
                                } else {
 
5325
                                    if (op == 4)
 
5326
                                        mask = 0xffffffffu >> -shift;
 
5327
                                    else
 
5328
                                        mask = 0xffffffffu << shift;
 
5329
                                }
 
5330
                                break;
 
5331
                            default:
 
5332
                                abort();
 
5333
                            }
 
5334
                            tmp2 = neon_load_reg(rd, pass);
 
5335
                            tcg_gen_andi_i32(tmp, tmp, mask);
 
5336
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
 
5337
                            tcg_gen_or_i32(tmp, tmp, tmp2);
 
5338
                            tcg_temp_free_i32(tmp2);
 
5339
                        }
 
5340
                        neon_store_reg(rd, pass, tmp);
 
5341
                    }
 
5342
                } /* for pass */
 
5343
            } else if (op < 10) {
 
5344
                /* Shift by immediate and narrow:
 
5345
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
 
5346
                int input_unsigned = (op == 8) ? !u : u;
 
5347
                if (rm & 1) {
 
5348
                    return 1;
 
5349
                }
 
5350
                shift = shift - (1 << (size + 3));
 
5351
                size++;
 
5352
                if (size == 3) {
 
5353
                    tmp64 = tcg_const_i64(shift);
 
5354
                    neon_load_reg64(cpu_V0, rm);
 
5355
                    neon_load_reg64(cpu_V1, rm + 1);
 
5356
                    for (pass = 0; pass < 2; pass++) {
 
5357
                        TCGv_i64 in;
 
5358
                        if (pass == 0) {
 
5359
                            in = cpu_V0;
 
5360
                        } else {
 
5361
                            in = cpu_V1;
 
5362
                        }
 
5363
                        if (q) {
 
5364
                            if (input_unsigned) {
 
5365
                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
 
5366
                            } else {
 
5367
                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
 
5368
                            }
 
5369
                        } else {
 
5370
                            if (input_unsigned) {
 
5371
                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
 
5372
                            } else {
 
5373
                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
 
5374
                            }
 
5375
                        }
 
5376
                        tmp = tcg_temp_new_i32();
 
5377
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
 
5378
                        neon_store_reg(rd, pass, tmp);
 
5379
                    } /* for pass */
 
5380
                    tcg_temp_free_i64(tmp64);
 
5381
                } else {
 
5382
                    if (size == 1) {
 
5383
                        imm = (uint16_t)shift;
 
5384
                        imm |= imm << 16;
 
5385
                    } else {
 
5386
                        /* size == 2 */
 
5387
                        imm = (uint32_t)shift;
 
5388
                    }
 
5389
                    tmp2 = tcg_const_i32(imm);
 
5390
                    tmp4 = neon_load_reg(rm + 1, 0);
 
5391
                    tmp5 = neon_load_reg(rm + 1, 1);
 
5392
                    for (pass = 0; pass < 2; pass++) {
 
5393
                        if (pass == 0) {
 
5394
                            tmp = neon_load_reg(rm, 0);
 
5395
                        } else {
 
5396
                            tmp = tmp4;
 
5397
                        }
 
5398
                        gen_neon_shift_narrow(size, tmp, tmp2, q,
 
5399
                                              input_unsigned);
 
5400
                        if (pass == 0) {
 
5401
                            tmp3 = neon_load_reg(rm, 1);
 
5402
                        } else {
 
5403
                            tmp3 = tmp5;
 
5404
                        }
 
5405
                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
 
5406
                                              input_unsigned);
 
5407
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
 
5408
                        tcg_temp_free_i32(tmp);
 
5409
                        tcg_temp_free_i32(tmp3);
 
5410
                        tmp = tcg_temp_new_i32();
 
5411
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
 
5412
                        neon_store_reg(rd, pass, tmp);
 
5413
                    } /* for pass */
 
5414
                    tcg_temp_free_i32(tmp2);
 
5415
                }
 
5416
            } else if (op == 10) {
 
5417
                /* VSHLL, VMOVL */
 
5418
                if (q || (rd & 1)) {
 
5419
                    return 1;
 
5420
                }
 
5421
                tmp = neon_load_reg(rm, 0);
 
5422
                tmp2 = neon_load_reg(rm, 1);
 
5423
                for (pass = 0; pass < 2; pass++) {
 
5424
                    if (pass == 1)
 
5425
                        tmp = tmp2;
 
5426
 
 
5427
                    gen_neon_widen(cpu_V0, tmp, size, u);
 
5428
 
 
5429
                    if (shift != 0) {
 
5430
                        /* The shift is less than the width of the source
 
5431
                           type, so we can just shift the whole register.  */
 
5432
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
 
5433
                        /* Widen the result of shift: we need to clear
 
5434
                         * the potential overflow bits resulting from
 
5435
                         * left bits of the narrow input appearing as
 
5436
                         * right bits of left the neighbour narrow
 
5437
                         * input.  */
 
5438
                        if (size < 2 || !u) {
 
5439
                            uint64_t imm64;
 
5440
                            if (size == 0) {
 
5441
                                imm = (0xffu >> (8 - shift));
 
5442
                                imm |= imm << 16;
 
5443
                            } else if (size == 1) {
 
5444
                                imm = 0xffff >> (16 - shift);
 
5445
                            } else {
 
5446
                                /* size == 2 */
 
5447
                                imm = 0xffffffff >> (32 - shift);
 
5448
                            }
 
5449
                            if (size < 2) {
 
5450
                                imm64 = imm | (((uint64_t)imm) << 32);
 
5451
                            } else {
 
5452
                                imm64 = imm;
 
5453
                            }
 
5454
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
 
5455
                        }
 
5456
                    }
 
5457
                    neon_store_reg64(cpu_V0, rd + pass);
 
5458
                }
 
5459
            } else if (op >= 14) {
 
5460
                /* VCVT fixed-point.  */
 
5461
                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
 
5462
                    return 1;
 
5463
                }
 
5464
                /* We have already masked out the must-be-1 top bit of imm6,
 
5465
                 * hence this 32-shift where the ARM ARM has 64-imm6.
 
5466
                 */
 
5467
                shift = 32 - shift;
 
5468
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
 
5469
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
 
5470
                    if (!(op & 1)) {
 
5471
                        if (u)
 
5472
                            gen_vfp_ulto(0, shift, 1);
 
5473
                        else
 
5474
                            gen_vfp_slto(0, shift, 1);
 
5475
                    } else {
 
5476
                        if (u)
 
5477
                            gen_vfp_toul(0, shift, 1);
 
5478
                        else
 
5479
                            gen_vfp_tosl(0, shift, 1);
 
5480
                    }
 
5481
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
 
5482
                }
 
5483
            } else {
 
5484
                return 1;
 
5485
            }
 
5486
        } else { /* (insn & 0x00380080) == 0 */
 
5487
            int invert;
 
5488
            if (q && (rd & 1)) {
 
5489
                return 1;
 
5490
            }
 
5491
 
 
5492
            op = (insn >> 8) & 0xf;
 
5493
            /* One register and immediate.  */
 
5494
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
 
5495
            invert = (insn & (1 << 5)) != 0;
 
5496
            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
 
5497
             * We choose to not special-case this and will behave as if a
 
5498
             * valid constant encoding of 0 had been given.
 
5499
             */
 
5500
            switch (op) {
 
5501
            case 0: case 1:
 
5502
                /* no-op */
 
5503
                break;
 
5504
            case 2: case 3:
 
5505
                imm <<= 8;
 
5506
                break;
 
5507
            case 4: case 5:
 
5508
                imm <<= 16;
 
5509
                break;
 
5510
            case 6: case 7:
 
5511
                imm <<= 24;
 
5512
                break;
 
5513
            case 8: case 9:
 
5514
                imm |= imm << 16;
 
5515
                break;
 
5516
            case 10: case 11:
 
5517
                imm = (imm << 8) | (imm << 24);
 
5518
                break;
 
5519
            case 12:
 
5520
                imm = (imm << 8) | 0xff;
 
5521
                break;
 
5522
            case 13:
 
5523
                imm = (imm << 16) | 0xffff;
 
5524
                break;
 
5525
            case 14:
 
5526
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
 
5527
                if (invert)
 
5528
                    imm = ~imm;
 
5529
                break;
 
5530
            case 15:
 
5531
                if (invert) {
 
5532
                    return 1;
 
5533
                }
 
5534
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
 
5535
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
 
5536
                break;
 
5537
            }
 
5538
            if (invert)
 
5539
                imm = ~imm;
 
5540
 
 
5541
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
 
5542
                if (op & 1 && op < 12) {
 
5543
                    tmp = neon_load_reg(rd, pass);
 
5544
                    if (invert) {
 
5545
                        /* The immediate value has already been inverted, so
 
5546
                           BIC becomes AND.  */
 
5547
                        tcg_gen_andi_i32(tmp, tmp, imm);
 
5548
                    } else {
 
5549
                        tcg_gen_ori_i32(tmp, tmp, imm);
 
5550
                    }
 
5551
                } else {
 
5552
                    /* VMOV, VMVN.  */
 
5553
                    tmp = tcg_temp_new_i32();
 
5554
                    if (op == 14 && invert) {
 
5555
                        int n;
 
5556
                        uint32_t val;
 
5557
                        val = 0;
 
5558
                        for (n = 0; n < 4; n++) {
 
5559
                            if (imm & (1 << (n + (pass & 1) * 4)))
 
5560
                                val |= 0xff << (n * 8);
 
5561
                        }
 
5562
                        tcg_gen_movi_i32(tmp, val);
 
5563
                    } else {
 
5564
                        tcg_gen_movi_i32(tmp, imm);
 
5565
                    }
 
5566
                }
 
5567
                neon_store_reg(rd, pass, tmp);
 
5568
            }
 
5569
        }
 
5570
    } else { /* (insn & 0x00800010 == 0x00800000) */
 
5571
        if (size != 3) {
 
5572
            op = (insn >> 8) & 0xf;
 
5573
            if ((insn & (1 << 6)) == 0) {
 
5574
                /* Three registers of different lengths.  */
 
5575
                int src1_wide;
 
5576
                int src2_wide;
 
5577
                int prewiden;
 
5578
                /* undefreq: bit 0 : UNDEF if size != 0
 
5579
                 *           bit 1 : UNDEF if size == 0
 
5580
                 *           bit 2 : UNDEF if U == 1
 
5581
                 * Note that [1:0] set implies 'always UNDEF'
 
5582
                 */
 
5583
                int undefreq;
 
5584
                /* prewiden, src1_wide, src2_wide, undefreq */
 
5585
                static const int neon_3reg_wide[16][4] = {
 
5586
                    {1, 0, 0, 0}, /* VADDL */
 
5587
                    {1, 1, 0, 0}, /* VADDW */
 
5588
                    {1, 0, 0, 0}, /* VSUBL */
 
5589
                    {1, 1, 0, 0}, /* VSUBW */
 
5590
                    {0, 1, 1, 0}, /* VADDHN */
 
5591
                    {0, 0, 0, 0}, /* VABAL */
 
5592
                    {0, 1, 1, 0}, /* VSUBHN */
 
5593
                    {0, 0, 0, 0}, /* VABDL */
 
5594
                    {0, 0, 0, 0}, /* VMLAL */
 
5595
                    {0, 0, 0, 6}, /* VQDMLAL */
 
5596
                    {0, 0, 0, 0}, /* VMLSL */
 
5597
                    {0, 0, 0, 6}, /* VQDMLSL */
 
5598
                    {0, 0, 0, 0}, /* Integer VMULL */
 
5599
                    {0, 0, 0, 2}, /* VQDMULL */
 
5600
                    {0, 0, 0, 5}, /* Polynomial VMULL */
 
5601
                    {0, 0, 0, 3}, /* Reserved: always UNDEF */
 
5602
                };
 
5603
 
 
5604
                prewiden = neon_3reg_wide[op][0];
 
5605
                src1_wide = neon_3reg_wide[op][1];
 
5606
                src2_wide = neon_3reg_wide[op][2];
 
5607
                undefreq = neon_3reg_wide[op][3];
 
5608
 
 
5609
                if (((undefreq & 1) && (size != 0)) ||
 
5610
                    ((undefreq & 2) && (size == 0)) ||
 
5611
                    ((undefreq & 4) && u)) {
 
5612
                    return 1;
 
5613
                }
 
5614
                if ((src1_wide && (rn & 1)) ||
 
5615
                    (src2_wide && (rm & 1)) ||
 
5616
                    (!src2_wide && (rd & 1))) {
 
5617
                    return 1;
 
5618
                }
 
5619
 
 
5620
                /* Avoid overlapping operands.  Wide source operands are
 
5621
                   always aligned so will never overlap with wide
 
5622
                   destinations in problematic ways.  */
 
5623
                if (rd == rm && !src2_wide) {
 
5624
                    tmp = neon_load_reg(rm, 1);
 
5625
                    neon_store_scratch(2, tmp);
 
5626
                } else if (rd == rn && !src1_wide) {
 
5627
                    tmp = neon_load_reg(rn, 1);
 
5628
                    neon_store_scratch(2, tmp);
 
5629
                }
 
5630
                TCGV_UNUSED_I32(tmp3);
 
5631
                for (pass = 0; pass < 2; pass++) {
 
5632
                    if (src1_wide) {
 
5633
                        neon_load_reg64(cpu_V0, rn + pass);
 
5634
                        TCGV_UNUSED_I32(tmp);
 
5635
                    } else {
 
5636
                        if (pass == 1 && rd == rn) {
 
5637
                            tmp = neon_load_scratch(2);
 
5638
                        } else {
 
5639
                            tmp = neon_load_reg(rn, pass);
 
5640
                        }
 
5641
                        if (prewiden) {
 
5642
                            gen_neon_widen(cpu_V0, tmp, size, u);
 
5643
                        }
 
5644
                    }
 
5645
                    if (src2_wide) {
 
5646
                        neon_load_reg64(cpu_V1, rm + pass);
 
5647
                        TCGV_UNUSED_I32(tmp2);
 
5648
                    } else {
 
5649
                        if (pass == 1 && rd == rm) {
 
5650
                            tmp2 = neon_load_scratch(2);
 
5651
                        } else {
 
5652
                            tmp2 = neon_load_reg(rm, pass);
 
5653
                        }
 
5654
                        if (prewiden) {
 
5655
                            gen_neon_widen(cpu_V1, tmp2, size, u);
 
5656
                        }
 
5657
                    }
 
5658
                    switch (op) {
 
5659
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
 
5660
                        gen_neon_addl(size);
 
5661
                        break;
 
5662
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
 
5663
                        gen_neon_subl(size);
 
5664
                        break;
 
5665
                    case 5: case 7: /* VABAL, VABDL */
 
5666
                        switch ((size << 1) | u) {
 
5667
                        case 0:
 
5668
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
 
5669
                            break;
 
5670
                        case 1:
 
5671
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
 
5672
                            break;
 
5673
                        case 2:
 
5674
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
 
5675
                            break;
 
5676
                        case 3:
 
5677
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
 
5678
                            break;
 
5679
                        case 4:
 
5680
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
 
5681
                            break;
 
5682
                        case 5:
 
5683
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
 
5684
                            break;
 
5685
                        default: abort();
 
5686
                        }
 
5687
                        tcg_temp_free_i32(tmp2);
 
5688
                        tcg_temp_free_i32(tmp);
 
5689
                        break;
 
5690
                    case 8: case 9: case 10: case 11: case 12: case 13:
 
5691
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
 
5692
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
 
5693
                        break;
 
5694
                    case 14: /* Polynomial VMULL */
 
5695
                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
 
5696
                        tcg_temp_free_i32(tmp2);
 
5697
                        tcg_temp_free_i32(tmp);
 
5698
                        break;
 
5699
                    default: /* 15 is RESERVED: caught earlier  */
 
5700
                        abort();
 
5701
                    }
 
5702
                    if (op == 13) {
 
5703
                        /* VQDMULL */
 
5704
                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
 
5705
                        neon_store_reg64(cpu_V0, rd + pass);
 
5706
                    } else if (op == 5 || (op >= 8 && op <= 11)) {
 
5707
                        /* Accumulate.  */
 
5708
                        neon_load_reg64(cpu_V1, rd + pass);
 
5709
                        switch (op) {
 
5710
                        case 10: /* VMLSL */
 
5711
                            gen_neon_negl(cpu_V0, size);
 
5712
                            /* Fall through */
 
5713
                        case 5: case 8: /* VABAL, VMLAL */
 
5714
                            gen_neon_addl(size);
 
5715
                            break;
 
5716
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
 
5717
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
 
5718
                            if (op == 11) {
 
5719
                                gen_neon_negl(cpu_V0, size);
 
5720
                            }
 
5721
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
 
5722
                            break;
 
5723
                        default:
 
5724
                            abort();
 
5725
                        }
 
5726
                        neon_store_reg64(cpu_V0, rd + pass);
 
5727
                    } else if (op == 4 || op == 6) {
 
5728
                        /* Narrowing operation.  */
 
5729
                        tmp = tcg_temp_new_i32();
 
5730
                        if (!u) {
 
5731
                            switch (size) {
 
5732
                            case 0:
 
5733
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
 
5734
                                break;
 
5735
                            case 1:
 
5736
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
 
5737
                                break;
 
5738
                            case 2:
 
5739
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
 
5740
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
 
5741
                                break;
 
5742
                            default: abort();
 
5743
                            }
 
5744
                        } else {
 
5745
                            switch (size) {
 
5746
                            case 0:
 
5747
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
 
5748
                                break;
 
5749
                            case 1:
 
5750
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
 
5751
                                break;
 
5752
                            case 2:
 
5753
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
 
5754
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
 
5755
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
 
5756
                                break;
 
5757
                            default: abort();
 
5758
                            }
 
5759
                        }
 
5760
                        if (pass == 0) {
 
5761
                            tmp3 = tmp;
 
5762
                        } else {
 
5763
                            neon_store_reg(rd, 0, tmp3);
 
5764
                            neon_store_reg(rd, 1, tmp);
 
5765
                        }
 
5766
                    } else {
 
5767
                        /* Write back the result.  */
 
5768
                        neon_store_reg64(cpu_V0, rd + pass);
 
5769
                    }
 
5770
                }
 
5771
            } else {
 
5772
                /* Two registers and a scalar. NB that for ops of this form
 
5773
                 * the ARM ARM labels bit 24 as Q, but it is in our variable
 
5774
                 * 'u', not 'q'.
 
5775
                 */
 
5776
                if (size == 0) {
 
5777
                    return 1;
 
5778
                }
 
5779
                switch (op) {
 
5780
                case 1: /* Float VMLA scalar */
 
5781
                case 5: /* Floating point VMLS scalar */
 
5782
                case 9: /* Floating point VMUL scalar */
 
5783
                    if (size == 1) {
 
5784
                        return 1;
 
5785
                    }
 
5786
                    /* fall through */
 
5787
                case 0: /* Integer VMLA scalar */
 
5788
                case 4: /* Integer VMLS scalar */
 
5789
                case 8: /* Integer VMUL scalar */
 
5790
                case 12: /* VQDMULH scalar */
 
5791
                case 13: /* VQRDMULH scalar */
 
5792
                    if (u && ((rd | rn) & 1)) {
 
5793
                        return 1;
 
5794
                    }
 
5795
                    tmp = neon_get_scalar(size, rm);
 
5796
                    neon_store_scratch(0, tmp);
 
5797
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
 
5798
                        tmp = neon_load_scratch(0);
 
5799
                        tmp2 = neon_load_reg(rn, pass);
 
5800
                        if (op == 12) {
 
5801
                            if (size == 1) {
 
5802
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
 
5803
                            } else {
 
5804
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
 
5805
                            }
 
5806
                        } else if (op == 13) {
 
5807
                            if (size == 1) {
 
5808
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
 
5809
                            } else {
 
5810
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
 
5811
                            }
 
5812
                        } else if (op & 1) {
 
5813
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
5814
                            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
 
5815
                            tcg_temp_free_ptr(fpstatus);
 
5816
                        } else {
 
5817
                            switch (size) {
 
5818
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
 
5819
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
 
5820
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
 
5821
                            default: abort();
 
5822
                            }
 
5823
                        }
 
5824
                        tcg_temp_free_i32(tmp2);
 
5825
                        if (op < 8) {
 
5826
                            /* Accumulate.  */
 
5827
                            tmp2 = neon_load_reg(rd, pass);
 
5828
                            switch (op) {
 
5829
                            case 0:
 
5830
                                gen_neon_add(size, tmp, tmp2);
 
5831
                                break;
 
5832
                            case 1:
 
5833
                            {
 
5834
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
5835
                                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
 
5836
                                tcg_temp_free_ptr(fpstatus);
 
5837
                                break;
 
5838
                            }
 
5839
                            case 4:
 
5840
                                gen_neon_rsb(size, tmp, tmp2);
 
5841
                                break;
 
5842
                            case 5:
 
5843
                            {
 
5844
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
5845
                                gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
 
5846
                                tcg_temp_free_ptr(fpstatus);
 
5847
                                break;
 
5848
                            }
 
5849
                            default:
 
5850
                                abort();
 
5851
                            }
 
5852
                            tcg_temp_free_i32(tmp2);
 
5853
                        }
 
5854
                        neon_store_reg(rd, pass, tmp);
 
5855
                    }
 
5856
                    break;
 
5857
                case 3: /* VQDMLAL scalar */
 
5858
                case 7: /* VQDMLSL scalar */
 
5859
                case 11: /* VQDMULL scalar */
 
5860
                    if (u == 1) {
 
5861
                        return 1;
 
5862
                    }
 
5863
                    /* fall through */
 
5864
                case 2: /* VMLAL sclar */
 
5865
                case 6: /* VMLSL scalar */
 
5866
                case 10: /* VMULL scalar */
 
5867
                    if (rd & 1) {
 
5868
                        return 1;
 
5869
                    }
 
5870
                    tmp2 = neon_get_scalar(size, rm);
 
5871
                    /* We need a copy of tmp2 because gen_neon_mull
 
5872
                     * deletes it during pass 0.  */
 
5873
                    tmp4 = tcg_temp_new_i32();
 
5874
                    tcg_gen_mov_i32(tmp4, tmp2);
 
5875
                    tmp3 = neon_load_reg(rn, 1);
 
5876
 
 
5877
                    for (pass = 0; pass < 2; pass++) {
 
5878
                        if (pass == 0) {
 
5879
                            tmp = neon_load_reg(rn, 0);
 
5880
                        } else {
 
5881
                            tmp = tmp3;
 
5882
                            tmp2 = tmp4;
 
5883
                        }
 
5884
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
 
5885
                        if (op != 11) {
 
5886
                            neon_load_reg64(cpu_V1, rd + pass);
 
5887
                        }
 
5888
                        switch (op) {
 
5889
                        case 6:
 
5890
                            gen_neon_negl(cpu_V0, size);
 
5891
                            /* Fall through */
 
5892
                        case 2:
 
5893
                            gen_neon_addl(size);
 
5894
                            break;
 
5895
                        case 3: case 7:
 
5896
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
 
5897
                            if (op == 7) {
 
5898
                                gen_neon_negl(cpu_V0, size);
 
5899
                            }
 
5900
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
 
5901
                            break;
 
5902
                        case 10:
 
5903
                            /* no-op */
 
5904
                            break;
 
5905
                        case 11:
 
5906
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
 
5907
                            break;
 
5908
                        default:
 
5909
                            abort();
 
5910
                        }
 
5911
                        neon_store_reg64(cpu_V0, rd + pass);
 
5912
                    }
 
5913
 
 
5914
 
 
5915
                    break;
 
5916
                default: /* 14 and 15 are RESERVED */
 
5917
                    return 1;
 
5918
                }
 
5919
            }
 
5920
        } else { /* size == 3 */
 
5921
            if (!u) {
 
5922
                /* Extract.  */
 
5923
                imm = (insn >> 8) & 0xf;
 
5924
 
 
5925
                if (imm > 7 && !q)
 
5926
                    return 1;
 
5927
 
 
5928
                if (q && ((rd | rn | rm) & 1)) {
 
5929
                    return 1;
 
5930
                }
 
5931
 
 
5932
                if (imm == 0) {
 
5933
                    neon_load_reg64(cpu_V0, rn);
 
5934
                    if (q) {
 
5935
                        neon_load_reg64(cpu_V1, rn + 1);
 
5936
                    }
 
5937
                } else if (imm == 8) {
 
5938
                    neon_load_reg64(cpu_V0, rn + 1);
 
5939
                    if (q) {
 
5940
                        neon_load_reg64(cpu_V1, rm);
 
5941
                    }
 
5942
                } else if (q) {
 
5943
                    tmp64 = tcg_temp_new_i64();
 
5944
                    if (imm < 8) {
 
5945
                        neon_load_reg64(cpu_V0, rn);
 
5946
                        neon_load_reg64(tmp64, rn + 1);
 
5947
                    } else {
 
5948
                        neon_load_reg64(cpu_V0, rn + 1);
 
5949
                        neon_load_reg64(tmp64, rm);
 
5950
                    }
 
5951
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
 
5952
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
 
5953
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
 
5954
                    if (imm < 8) {
 
5955
                        neon_load_reg64(cpu_V1, rm);
 
5956
                    } else {
 
5957
                        neon_load_reg64(cpu_V1, rm + 1);
 
5958
                        imm -= 8;
 
5959
                    }
 
5960
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
 
5961
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
 
5962
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
 
5963
                    tcg_temp_free_i64(tmp64);
 
5964
                } else {
 
5965
                    /* BUGFIX */
 
5966
                    neon_load_reg64(cpu_V0, rn);
 
5967
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
 
5968
                    neon_load_reg64(cpu_V1, rm);
 
5969
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
 
5970
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
 
5971
                }
 
5972
                neon_store_reg64(cpu_V0, rd);
 
5973
                if (q) {
 
5974
                    neon_store_reg64(cpu_V1, rd + 1);
 
5975
                }
 
5976
            } else if ((insn & (1 << 11)) == 0) {
 
5977
                /* Two register misc.  */
 
5978
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
 
5979
                size = (insn >> 18) & 3;
 
5980
                /* UNDEF for unknown op values and bad op-size combinations */
 
5981
                if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
 
5982
                    return 1;
 
5983
                }
 
5984
                if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
 
5985
                    q && ((rm | rd) & 1)) {
 
5986
                    return 1;
 
5987
                }
 
5988
                switch (op) {
 
5989
                case NEON_2RM_VREV64:
 
5990
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
 
5991
                        tmp = neon_load_reg(rm, pass * 2);
 
5992
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
 
5993
                        switch (size) {
 
5994
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
 
5995
                        case 1: gen_swap_half(tmp); break;
 
5996
                        case 2: /* no-op */ break;
 
5997
                        default: abort();
 
5998
                        }
 
5999
                        neon_store_reg(rd, pass * 2 + 1, tmp);
 
6000
                        if (size == 2) {
 
6001
                            neon_store_reg(rd, pass * 2, tmp2);
 
6002
                        } else {
 
6003
                            switch (size) {
 
6004
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
 
6005
                            case 1: gen_swap_half(tmp2); break;
 
6006
                            default: abort();
 
6007
                            }
 
6008
                            neon_store_reg(rd, pass * 2, tmp2);
 
6009
                        }
 
6010
                    }
 
6011
                    break;
 
6012
                case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
 
6013
                case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
 
6014
                    for (pass = 0; pass < q + 1; pass++) {
 
6015
                        tmp = neon_load_reg(rm, pass * 2);
 
6016
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
 
6017
                        tmp = neon_load_reg(rm, pass * 2 + 1);
 
6018
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
 
6019
                        switch (size) {
 
6020
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
 
6021
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
 
6022
                        case 2: tcg_gen_add_i64(CPU_V001); break;
 
6023
                        default: abort();
 
6024
                        }
 
6025
                        if (op >= NEON_2RM_VPADAL) {
 
6026
                            /* Accumulate.  */
 
6027
                            neon_load_reg64(cpu_V1, rd + pass);
 
6028
                            gen_neon_addl(size);
 
6029
                        }
 
6030
                        neon_store_reg64(cpu_V0, rd + pass);
 
6031
                    }
 
6032
                    break;
 
6033
                case NEON_2RM_VTRN:
 
6034
                    if (size == 2) {
 
6035
                        int n;
 
6036
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
 
6037
                            tmp = neon_load_reg(rm, n);
 
6038
                            tmp2 = neon_load_reg(rd, n + 1);
 
6039
                            neon_store_reg(rm, n, tmp2);
 
6040
                            neon_store_reg(rd, n + 1, tmp);
 
6041
                        }
 
6042
                    } else {
 
6043
                        goto elementwise;
 
6044
                    }
 
6045
                    break;
 
6046
                case NEON_2RM_VUZP:
 
6047
                    if (gen_neon_unzip(rd, rm, size, q)) {
 
6048
                        return 1;
 
6049
                    }
 
6050
                    break;
 
6051
                case NEON_2RM_VZIP:
 
6052
                    if (gen_neon_zip(rd, rm, size, q)) {
 
6053
                        return 1;
 
6054
                    }
 
6055
                    break;
 
6056
                case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
 
6057
                    /* also VQMOVUN; op field and mnemonics don't line up */
 
6058
                    if (rm & 1) {
 
6059
                        return 1;
 
6060
                    }
 
6061
                    TCGV_UNUSED_I32(tmp2);
 
6062
                    for (pass = 0; pass < 2; pass++) {
 
6063
                        neon_load_reg64(cpu_V0, rm + pass);
 
6064
                        tmp = tcg_temp_new_i32();
 
6065
                        gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
 
6066
                                           tmp, cpu_V0);
 
6067
                        if (pass == 0) {
 
6068
                            tmp2 = tmp;
 
6069
                        } else {
 
6070
                            neon_store_reg(rd, 0, tmp2);
 
6071
                            neon_store_reg(rd, 1, tmp);
 
6072
                        }
 
6073
                    }
 
6074
                    break;
 
6075
                case NEON_2RM_VSHLL:
 
6076
                    if (q || (rd & 1)) {
 
6077
                        return 1;
 
6078
                    }
 
6079
                    tmp = neon_load_reg(rm, 0);
 
6080
                    tmp2 = neon_load_reg(rm, 1);
 
6081
                    for (pass = 0; pass < 2; pass++) {
 
6082
                        if (pass == 1)
 
6083
                            tmp = tmp2;
 
6084
                        gen_neon_widen(cpu_V0, tmp, size, 1);
 
6085
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
 
6086
                        neon_store_reg64(cpu_V0, rd + pass);
 
6087
                    }
 
6088
                    break;
 
6089
                case NEON_2RM_VCVT_F16_F32:
 
6090
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
 
6091
                        q || (rm & 1)) {
 
6092
                        return 1;
 
6093
                    }
 
6094
                    tmp = tcg_temp_new_i32();
 
6095
                    tmp2 = tcg_temp_new_i32();
 
6096
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
 
6097
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
 
6098
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
 
6099
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
 
6100
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
 
6101
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
 
6102
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
 
6103
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
 
6104
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
 
6105
                    neon_store_reg(rd, 0, tmp2);
 
6106
                    tmp2 = tcg_temp_new_i32();
 
6107
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
 
6108
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
 
6109
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
 
6110
                    neon_store_reg(rd, 1, tmp2);
 
6111
                    tcg_temp_free_i32(tmp);
 
6112
                    break;
 
6113
                case NEON_2RM_VCVT_F32_F16:
 
6114
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
 
6115
                        q || (rd & 1)) {
 
6116
                        return 1;
 
6117
                    }
 
6118
                    tmp3 = tcg_temp_new_i32();
 
6119
                    tmp = neon_load_reg(rm, 0);
 
6120
                    tmp2 = neon_load_reg(rm, 1);
 
6121
                    tcg_gen_ext16u_i32(tmp3, tmp);
 
6122
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
 
6123
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
 
6124
                    tcg_gen_shri_i32(tmp3, tmp, 16);
 
6125
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
 
6126
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
 
6127
                    tcg_temp_free_i32(tmp);
 
6128
                    tcg_gen_ext16u_i32(tmp3, tmp2);
 
6129
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
 
6130
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
 
6131
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
 
6132
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
 
6133
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
 
6134
                    tcg_temp_free_i32(tmp2);
 
6135
                    tcg_temp_free_i32(tmp3);
 
6136
                    break;
 
6137
                default:
 
6138
                elementwise:
 
6139
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
 
6140
                        if (neon_2rm_is_float_op(op)) {
 
6141
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
 
6142
                                           neon_reg_offset(rm, pass));
 
6143
                            TCGV_UNUSED_I32(tmp);
 
6144
                        } else {
 
6145
                            tmp = neon_load_reg(rm, pass);
 
6146
                        }
 
6147
                        switch (op) {
 
6148
                        case NEON_2RM_VREV32:
 
6149
                            switch (size) {
 
6150
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
 
6151
                            case 1: gen_swap_half(tmp); break;
 
6152
                            default: abort();
 
6153
                            }
 
6154
                            break;
 
6155
                        case NEON_2RM_VREV16:
 
6156
                            gen_rev16(tmp);
 
6157
                            break;
 
6158
                        case NEON_2RM_VCLS:
 
6159
                            switch (size) {
 
6160
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
 
6161
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
 
6162
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
 
6163
                            default: abort();
 
6164
                            }
 
6165
                            break;
 
6166
                        case NEON_2RM_VCLZ:
 
6167
                            switch (size) {
 
6168
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
 
6169
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
 
6170
                            case 2: gen_helper_clz(tmp, tmp); break;
 
6171
                            default: abort();
 
6172
                            }
 
6173
                            break;
 
6174
                        case NEON_2RM_VCNT:
 
6175
                            gen_helper_neon_cnt_u8(tmp, tmp);
 
6176
                            break;
 
6177
                        case NEON_2RM_VMVN:
 
6178
                            tcg_gen_not_i32(tmp, tmp);
 
6179
                            break;
 
6180
                        case NEON_2RM_VQABS:
 
6181
                            switch (size) {
 
6182
                            case 0:
 
6183
                                gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
 
6184
                                break;
 
6185
                            case 1:
 
6186
                                gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
 
6187
                                break;
 
6188
                            case 2:
 
6189
                                gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
 
6190
                                break;
 
6191
                            default: abort();
 
6192
                            }
 
6193
                            break;
 
6194
                        case NEON_2RM_VQNEG:
 
6195
                            switch (size) {
 
6196
                            case 0:
 
6197
                                gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
 
6198
                                break;
 
6199
                            case 1:
 
6200
                                gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
 
6201
                                break;
 
6202
                            case 2:
 
6203
                                gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
 
6204
                                break;
 
6205
                            default: abort();
 
6206
                            }
 
6207
                            break;
 
6208
                        case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
 
6209
                            tmp2 = tcg_const_i32(0);
 
6210
                            switch(size) {
 
6211
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
 
6212
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
 
6213
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
 
6214
                            default: abort();
 
6215
                            }
 
6216
                            tcg_temp_free_i32(tmp2);
 
6217
                            if (op == NEON_2RM_VCLE0) {
 
6218
                                tcg_gen_not_i32(tmp, tmp);
 
6219
                            }
 
6220
                            break;
 
6221
                        case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
 
6222
                            tmp2 = tcg_const_i32(0);
 
6223
                            switch(size) {
 
6224
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
 
6225
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
 
6226
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
 
6227
                            default: abort();
 
6228
                            }
 
6229
                            tcg_temp_free_i32(tmp2);
 
6230
                            if (op == NEON_2RM_VCLT0) {
 
6231
                                tcg_gen_not_i32(tmp, tmp);
 
6232
                            }
 
6233
                            break;
 
6234
                        case NEON_2RM_VCEQ0:
 
6235
                            tmp2 = tcg_const_i32(0);
 
6236
                            switch(size) {
 
6237
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
 
6238
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
 
6239
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
 
6240
                            default: abort();
 
6241
                            }
 
6242
                            tcg_temp_free_i32(tmp2);
 
6243
                            break;
 
6244
                        case NEON_2RM_VABS:
 
6245
                            switch(size) {
 
6246
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
 
6247
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
 
6248
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
 
6249
                            default: abort();
 
6250
                            }
 
6251
                            break;
 
6252
                        case NEON_2RM_VNEG:
 
6253
                            tmp2 = tcg_const_i32(0);
 
6254
                            gen_neon_rsb(size, tmp, tmp2);
 
6255
                            tcg_temp_free_i32(tmp2);
 
6256
                            break;
 
6257
                        case NEON_2RM_VCGT0_F:
 
6258
                        {
 
6259
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
6260
                            tmp2 = tcg_const_i32(0);
 
6261
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
 
6262
                            tcg_temp_free_i32(tmp2);
 
6263
                            tcg_temp_free_ptr(fpstatus);
 
6264
                            break;
 
6265
                        }
 
6266
                        case NEON_2RM_VCGE0_F:
 
6267
                        {
 
6268
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
6269
                            tmp2 = tcg_const_i32(0);
 
6270
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
 
6271
                            tcg_temp_free_i32(tmp2);
 
6272
                            tcg_temp_free_ptr(fpstatus);
 
6273
                            break;
 
6274
                        }
 
6275
                        case NEON_2RM_VCEQ0_F:
 
6276
                        {
 
6277
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
6278
                            tmp2 = tcg_const_i32(0);
 
6279
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
 
6280
                            tcg_temp_free_i32(tmp2);
 
6281
                            tcg_temp_free_ptr(fpstatus);
 
6282
                            break;
 
6283
                        }
 
6284
                        case NEON_2RM_VCLE0_F:
 
6285
                        {
 
6286
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
6287
                            tmp2 = tcg_const_i32(0);
 
6288
                            gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
 
6289
                            tcg_temp_free_i32(tmp2);
 
6290
                            tcg_temp_free_ptr(fpstatus);
 
6291
                            break;
 
6292
                        }
 
6293
                        case NEON_2RM_VCLT0_F:
 
6294
                        {
 
6295
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
 
6296
                            tmp2 = tcg_const_i32(0);
 
6297
                            gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
 
6298
                            tcg_temp_free_i32(tmp2);
 
6299
                            tcg_temp_free_ptr(fpstatus);
 
6300
                            break;
 
6301
                        }
 
6302
                        case NEON_2RM_VABS_F:
 
6303
                            gen_vfp_abs(0);
 
6304
                            break;
 
6305
                        case NEON_2RM_VNEG_F:
 
6306
                            gen_vfp_neg(0);
 
6307
                            break;
 
6308
                        case NEON_2RM_VSWP:
 
6309
                            tmp2 = neon_load_reg(rd, pass);
 
6310
                            neon_store_reg(rm, pass, tmp2);
 
6311
                            break;
 
6312
                        case NEON_2RM_VTRN:
 
6313
                            tmp2 = neon_load_reg(rd, pass);
 
6314
                            switch (size) {
 
6315
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
 
6316
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
 
6317
                            default: abort();
 
6318
                            }
 
6319
                            neon_store_reg(rm, pass, tmp2);
 
6320
                            break;
 
6321
                        case NEON_2RM_VRECPE:
 
6322
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
 
6323
                            break;
 
6324
                        case NEON_2RM_VRSQRTE:
 
6325
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
 
6326
                            break;
 
6327
                        case NEON_2RM_VRECPE_F:
 
6328
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
 
6329
                            break;
 
6330
                        case NEON_2RM_VRSQRTE_F:
 
6331
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
 
6332
                            break;
 
6333
                        case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
 
6334
                            gen_vfp_sito(0, 1);
 
6335
                            break;
 
6336
                        case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
 
6337
                            gen_vfp_uito(0, 1);
 
6338
                            break;
 
6339
                        case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
 
6340
                            gen_vfp_tosiz(0, 1);
 
6341
                            break;
 
6342
                        case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
 
6343
                            gen_vfp_touiz(0, 1);
 
6344
                            break;
 
6345
                        default:
 
6346
                            /* Reserved op values were caught by the
 
6347
                             * neon_2rm_sizes[] check earlier.
 
6348
                             */
 
6349
                            abort();
 
6350
                        }
 
6351
                        if (neon_2rm_is_float_op(op)) {
 
6352
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
 
6353
                                           neon_reg_offset(rd, pass));
 
6354
                        } else {
 
6355
                            neon_store_reg(rd, pass, tmp);
 
6356
                        }
 
6357
                    }
 
6358
                    break;
 
6359
                }
 
6360
            } else if ((insn & (1 << 10)) == 0) {
 
6361
                /* VTBL, VTBX.  */
 
6362
                int n = ((insn >> 8) & 3) + 1;
 
6363
                if ((rn + n) > 32) {
 
6364
                    /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
 
6365
                     * helper function running off the end of the register file.
 
6366
                     */
 
6367
                    return 1;
 
6368
                }
 
6369
                n <<= 3;
 
6370
                if (insn & (1 << 6)) {
 
6371
                    tmp = neon_load_reg(rd, 0);
 
6372
                } else {
 
6373
                    tmp = tcg_temp_new_i32();
 
6374
                    tcg_gen_movi_i32(tmp, 0);
 
6375
                }
 
6376
                tmp2 = neon_load_reg(rm, 0);
 
6377
                tmp4 = tcg_const_i32(rn);
 
6378
                tmp5 = tcg_const_i32(n);
 
6379
                gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
 
6380
                tcg_temp_free_i32(tmp);
 
6381
                if (insn & (1 << 6)) {
 
6382
                    tmp = neon_load_reg(rd, 1);
 
6383
                } else {
 
6384
                    tmp = tcg_temp_new_i32();
 
6385
                    tcg_gen_movi_i32(tmp, 0);
 
6386
                }
 
6387
                tmp3 = neon_load_reg(rm, 1);
 
6388
                gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
 
6389
                tcg_temp_free_i32(tmp5);
 
6390
                tcg_temp_free_i32(tmp4);
 
6391
                neon_store_reg(rd, 0, tmp2);
 
6392
                neon_store_reg(rd, 1, tmp3);
 
6393
                tcg_temp_free_i32(tmp);
 
6394
            } else if ((insn & 0x380) == 0) {
 
6395
                /* VDUP */
 
6396
                if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
 
6397
                    return 1;
 
6398
                }
 
6399
                if (insn & (1 << 19)) {
 
6400
                    tmp = neon_load_reg(rm, 1);
 
6401
                } else {
 
6402
                    tmp = neon_load_reg(rm, 0);
 
6403
                }
 
6404
                if (insn & (1 << 16)) {
 
6405
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
 
6406
                } else if (insn & (1 << 17)) {
 
6407
                    if ((insn >> 18) & 1)
 
6408
                        gen_neon_dup_high16(tmp);
 
6409
                    else
 
6410
                        gen_neon_dup_low16(tmp);
 
6411
                }
 
6412
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
 
6413
                    tmp2 = tcg_temp_new_i32();
 
6414
                    tcg_gen_mov_i32(tmp2, tmp);
 
6415
                    neon_store_reg(rd, pass, tmp2);
 
6416
                }
 
6417
                tcg_temp_free_i32(tmp);
 
6418
            } else {
 
6419
                return 1;
 
6420
            }
 
6421
        }
 
6422
    }
 
6423
    return 0;
 
6424
}
 
6425
 
 
6426
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 
6427
{
 
6428
    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
 
6429
    const ARMCPRegInfo *ri;
 
6430
    ARMCPU *cpu = arm_env_get_cpu(env);
 
6431
 
 
6432
    cpnum = (insn >> 8) & 0xf;
 
6433
    if (arm_feature(env, ARM_FEATURE_XSCALE)
 
6434
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
 
6435
        return 1;
 
6436
 
 
6437
    /* First check for coprocessor space used for actual instructions */
 
6438
    switch (cpnum) {
 
6439
      case 0:
 
6440
      case 1:
 
6441
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
 
6442
            return disas_iwmmxt_insn(env, s, insn);
 
6443
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
 
6444
            return disas_dsp_insn(env, s, insn);
 
6445
        }
 
6446
        return 1;
 
6447
    default:
 
6448
        break;
 
6449
    }
 
6450
 
 
6451
    /* Otherwise treat as a generic register access */
 
6452
    is64 = (insn & (1 << 25)) == 0;
 
6453
    if (!is64 && ((insn & (1 << 4)) == 0)) {
 
6454
        /* cdp */
 
6455
        return 1;
 
6456
    }
 
6457
 
 
6458
    crm = insn & 0xf;
 
6459
    if (is64) {
 
6460
        crn = 0;
 
6461
        opc1 = (insn >> 4) & 0xf;
 
6462
        opc2 = 0;
 
6463
        rt2 = (insn >> 16) & 0xf;
 
6464
    } else {
 
6465
        crn = (insn >> 16) & 0xf;
 
6466
        opc1 = (insn >> 21) & 7;
 
6467
        opc2 = (insn >> 5) & 7;
 
6468
        rt2 = 0;
 
6469
    }
 
6470
    isread = (insn >> 20) & 1;
 
6471
    rt = (insn >> 12) & 0xf;
 
6472
 
 
6473
    ri = get_arm_cp_reginfo(cpu,
 
6474
                            ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
 
6475
    if (ri) {
 
6476
        /* Check access permissions */
 
6477
        if (!cp_access_ok(env, ri, isread)) {
 
6478
            return 1;
 
6479
        }
 
6480
 
 
6481
        /* Handle special cases first */
 
6482
        switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
 
6483
        case ARM_CP_NOP:
 
6484
            return 0;
 
6485
        case ARM_CP_WFI:
 
6486
            if (isread) {
 
6487
                return 1;
 
6488
            }
 
6489
            gen_set_pc_im(s, s->pc);
 
6490
            s->is_jmp = DISAS_WFI;
 
6491
            return 0;
 
6492
        default:
 
6493
            break;
 
6494
        }
 
6495
 
 
6496
        if (use_icount && (ri->type & ARM_CP_IO)) {
 
6497
            gen_io_start();
 
6498
        }
 
6499
 
 
6500
        if (isread) {
 
6501
            /* Read */
 
6502
            if (is64) {
 
6503
                TCGv_i64 tmp64;
 
6504
                TCGv_i32 tmp;
 
6505
                if (ri->type & ARM_CP_CONST) {
 
6506
                    tmp64 = tcg_const_i64(ri->resetvalue);
 
6507
                } else if (ri->readfn) {
 
6508
                    TCGv_ptr tmpptr;
 
6509
                    gen_set_pc_im(s, s->pc);
 
6510
                    tmp64 = tcg_temp_new_i64();
 
6511
                    tmpptr = tcg_const_ptr(ri);
 
6512
                    gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
 
6513
                    tcg_temp_free_ptr(tmpptr);
 
6514
                } else {
 
6515
                    tmp64 = tcg_temp_new_i64();
 
6516
                    tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
 
6517
                }
 
6518
                tmp = tcg_temp_new_i32();
 
6519
                tcg_gen_trunc_i64_i32(tmp, tmp64);
 
6520
                store_reg(s, rt, tmp);
 
6521
                tcg_gen_shri_i64(tmp64, tmp64, 32);
 
6522
                tmp = tcg_temp_new_i32();
 
6523
                tcg_gen_trunc_i64_i32(tmp, tmp64);
 
6524
                tcg_temp_free_i64(tmp64);
 
6525
                store_reg(s, rt2, tmp);
 
6526
            } else {
 
6527
                TCGv_i32 tmp;
 
6528
                if (ri->type & ARM_CP_CONST) {
 
6529
                    tmp = tcg_const_i32(ri->resetvalue);
 
6530
                } else if (ri->readfn) {
 
6531
                    TCGv_ptr tmpptr;
 
6532
                    gen_set_pc_im(s, s->pc);
 
6533
                    tmp = tcg_temp_new_i32();
 
6534
                    tmpptr = tcg_const_ptr(ri);
 
6535
                    gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
 
6536
                    tcg_temp_free_ptr(tmpptr);
 
6537
                } else {
 
6538
                    tmp = load_cpu_offset(ri->fieldoffset);
 
6539
                }
 
6540
                if (rt == 15) {
 
6541
                    /* Destination register of r15 for 32 bit loads sets
 
6542
                     * the condition codes from the high 4 bits of the value
 
6543
                     */
 
6544
                    gen_set_nzcv(tmp);
 
6545
                    tcg_temp_free_i32(tmp);
 
6546
                } else {
 
6547
                    store_reg(s, rt, tmp);
 
6548
                }
 
6549
            }
 
6550
        } else {
 
6551
            /* Write */
 
6552
            if (ri->type & ARM_CP_CONST) {
 
6553
                /* If not forbidden by access permissions, treat as WI */
 
6554
                return 0;
 
6555
            }
 
6556
 
 
6557
            if (is64) {
 
6558
                TCGv_i32 tmplo, tmphi;
 
6559
                TCGv_i64 tmp64 = tcg_temp_new_i64();
 
6560
                tmplo = load_reg(s, rt);
 
6561
                tmphi = load_reg(s, rt2);
 
6562
                tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
 
6563
                tcg_temp_free_i32(tmplo);
 
6564
                tcg_temp_free_i32(tmphi);
 
6565
                if (ri->writefn) {
 
6566
                    TCGv_ptr tmpptr = tcg_const_ptr(ri);
 
6567
                    gen_set_pc_im(s, s->pc);
 
6568
                    gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
 
6569
                    tcg_temp_free_ptr(tmpptr);
 
6570
                } else {
 
6571
                    tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
 
6572
                }
 
6573
                tcg_temp_free_i64(tmp64);
 
6574
            } else {
 
6575
                if (ri->writefn) {
 
6576
                    TCGv_i32 tmp;
 
6577
                    TCGv_ptr tmpptr;
 
6578
                    gen_set_pc_im(s, s->pc);
 
6579
                    tmp = load_reg(s, rt);
 
6580
                    tmpptr = tcg_const_ptr(ri);
 
6581
                    gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
 
6582
                    tcg_temp_free_ptr(tmpptr);
 
6583
                    tcg_temp_free_i32(tmp);
 
6584
                } else {
 
6585
                    TCGv_i32 tmp = load_reg(s, rt);
 
6586
                    store_cpu_offset(tmp, ri->fieldoffset);
 
6587
                }
 
6588
            }
 
6589
        }
 
6590
 
 
6591
        if (use_icount && (ri->type & ARM_CP_IO)) {
 
6592
            /* I/O operations must end the TB here (whether read or write) */
 
6593
            gen_io_end();
 
6594
            gen_lookup_tb(s);
 
6595
        } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
 
6596
            /* We default to ending the TB on a coprocessor register write,
 
6597
             * but allow this to be suppressed by the register definition
 
6598
             * (usually only necessary to work around guest bugs).
 
6599
             */
 
6600
            gen_lookup_tb(s);
 
6601
        }
 
6602
 
 
6603
        return 0;
 
6604
    }
 
6605
 
 
6606
    return 1;
 
6607
}
 
6608
 
 
6609
 
 
6610
/* Store a 64-bit value to a register pair.  Clobbers val.  */
 
6611
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
 
6612
{
 
6613
    TCGv_i32 tmp;
 
6614
    tmp = tcg_temp_new_i32();
 
6615
    tcg_gen_trunc_i64_i32(tmp, val);
 
6616
    store_reg(s, rlow, tmp);
 
6617
    tmp = tcg_temp_new_i32();
 
6618
    tcg_gen_shri_i64(val, val, 32);
 
6619
    tcg_gen_trunc_i64_i32(tmp, val);
 
6620
    store_reg(s, rhigh, tmp);
 
6621
}
 
6622
 
 
6623
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
 
6624
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
 
6625
{
 
6626
    TCGv_i64 tmp;
 
6627
    TCGv_i32 tmp2;
 
6628
 
 
6629
    /* Load value and extend to 64 bits.  */
 
6630
    tmp = tcg_temp_new_i64();
 
6631
    tmp2 = load_reg(s, rlow);
 
6632
    tcg_gen_extu_i32_i64(tmp, tmp2);
 
6633
    tcg_temp_free_i32(tmp2);
 
6634
    tcg_gen_add_i64(val, val, tmp);
 
6635
    tcg_temp_free_i64(tmp);
 
6636
}
 
6637
 
 
6638
/* load and add a 64-bit value from a register pair.  */
 
6639
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
 
6640
{
 
6641
    TCGv_i64 tmp;
 
6642
    TCGv_i32 tmpl;
 
6643
    TCGv_i32 tmph;
 
6644
 
 
6645
    /* Load 64-bit value rd:rn.  */
 
6646
    tmpl = load_reg(s, rlow);
 
6647
    tmph = load_reg(s, rhigh);
 
6648
    tmp = tcg_temp_new_i64();
 
6649
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
 
6650
    tcg_temp_free_i32(tmpl);
 
6651
    tcg_temp_free_i32(tmph);
 
6652
    tcg_gen_add_i64(val, val, tmp);
 
6653
    tcg_temp_free_i64(tmp);
 
6654
}
 
6655
 
 
6656
/* Set N and Z flags from hi|lo.  */
 
6657
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
 
6658
{
 
6659
    tcg_gen_mov_i32(cpu_NF, hi);
 
6660
    tcg_gen_or_i32(cpu_ZF, lo, hi);
 
6661
}
 
6662
 
 
6663
/* Load/Store exclusive instructions are implemented by remembering
 
6664
   the value/address loaded, and seeing if these are the same
 
6665
   when the store is performed. This should be sufficient to implement
 
6666
   the architecturally mandated semantics, and avoids having to monitor
 
6667
   regular stores.
 
6668
 
 
6669
   In system emulation mode only one CPU will be running at once, so
 
6670
   this sequence is effectively atomic.  In user emulation mode we
 
6671
   throw an exception and handle the atomic operation elsewhere.  */
 
6672
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
 
6673
                               TCGv_i32 addr, int size)
 
6674
{
 
6675
    TCGv_i32 tmp = tcg_temp_new_i32();
 
6676
 
 
6677
    switch (size) {
 
6678
    case 0:
 
6679
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
6680
        break;
 
6681
    case 1:
 
6682
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
6683
        break;
 
6684
    case 2:
 
6685
    case 3:
 
6686
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
6687
        break;
 
6688
    default:
 
6689
        abort();
 
6690
    }
 
6691
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
 
6692
    store_reg(s, rt, tmp);
 
6693
    if (size == 3) {
 
6694
        TCGv_i32 tmp2 = tcg_temp_new_i32();
 
6695
        tcg_gen_addi_i32(tmp2, addr, 4);
 
6696
        tmp = tcg_temp_new_i32();
 
6697
        gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
 
6698
        tcg_temp_free_i32(tmp2);
 
6699
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
 
6700
        store_reg(s, rt2, tmp);
 
6701
    }
 
6702
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
 
6703
}
 
6704
 
 
6705
static void gen_clrex(DisasContext *s)
 
6706
{
 
6707
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
 
6708
}
 
6709
 
 
6710
#ifdef CONFIG_USER_ONLY
 
6711
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
 
6712
                                TCGv_i32 addr, int size)
 
6713
{
 
6714
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
 
6715
    tcg_gen_movi_i32(cpu_exclusive_info,
 
6716
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
 
6717
    gen_exception_insn(s, 4, EXCP_STREX);
 
6718
}
 
6719
#else
 
6720
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
 
6721
                                TCGv_i32 addr, int size)
 
6722
{
 
6723
    TCGv_i32 tmp;
 
6724
    int done_label;
 
6725
    int fail_label;
 
6726
 
 
6727
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
 
6728
         [addr] = {Rt};
 
6729
         {Rd} = 0;
 
6730
       } else {
 
6731
         {Rd} = 1;
 
6732
       } */
 
6733
    fail_label = gen_new_label();
 
6734
    done_label = gen_new_label();
 
6735
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
 
6736
    tmp = tcg_temp_new_i32();
 
6737
    switch (size) {
 
6738
    case 0:
 
6739
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
6740
        break;
 
6741
    case 1:
 
6742
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
6743
        break;
 
6744
    case 2:
 
6745
    case 3:
 
6746
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
6747
        break;
 
6748
    default:
 
6749
        abort();
 
6750
    }
 
6751
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
 
6752
    tcg_temp_free_i32(tmp);
 
6753
    if (size == 3) {
 
6754
        TCGv_i32 tmp2 = tcg_temp_new_i32();
 
6755
        tcg_gen_addi_i32(tmp2, addr, 4);
 
6756
        tmp = tcg_temp_new_i32();
 
6757
        gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
 
6758
        tcg_temp_free_i32(tmp2);
 
6759
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
 
6760
        tcg_temp_free_i32(tmp);
 
6761
    }
 
6762
    tmp = load_reg(s, rt);
 
6763
    switch (size) {
 
6764
    case 0:
 
6765
        gen_aa32_st8(tmp, addr, IS_USER(s));
 
6766
        break;
 
6767
    case 1:
 
6768
        gen_aa32_st16(tmp, addr, IS_USER(s));
 
6769
        break;
 
6770
    case 2:
 
6771
    case 3:
 
6772
        gen_aa32_st32(tmp, addr, IS_USER(s));
 
6773
        break;
 
6774
    default:
 
6775
        abort();
 
6776
    }
 
6777
    tcg_temp_free_i32(tmp);
 
6778
    if (size == 3) {
 
6779
        tcg_gen_addi_i32(addr, addr, 4);
 
6780
        tmp = load_reg(s, rt2);
 
6781
        gen_aa32_st32(tmp, addr, IS_USER(s));
 
6782
        tcg_temp_free_i32(tmp);
 
6783
    }
 
6784
    tcg_gen_movi_i32(cpu_R[rd], 0);
 
6785
    tcg_gen_br(done_label);
 
6786
    gen_set_label(fail_label);
 
6787
    tcg_gen_movi_i32(cpu_R[rd], 1);
 
6788
    gen_set_label(done_label);
 
6789
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
 
6790
}
 
6791
#endif
 
6792
 
 
6793
/* gen_srs:
 
6794
 * @env: CPUARMState
 
6795
 * @s: DisasContext
 
6796
 * @mode: mode field from insn (which stack to store to)
 
6797
 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
 
6798
 * @writeback: true if writeback bit set
 
6799
 *
 
6800
 * Generate code for the SRS (Store Return State) insn.
 
6801
 */
 
6802
static void gen_srs(DisasContext *s,
 
6803
                    uint32_t mode, uint32_t amode, bool writeback)
 
6804
{
 
6805
    int32_t offset;
 
6806
    TCGv_i32 addr = tcg_temp_new_i32();
 
6807
    TCGv_i32 tmp = tcg_const_i32(mode);
 
6808
    gen_helper_get_r13_banked(addr, cpu_env, tmp);
 
6809
    tcg_temp_free_i32(tmp);
 
6810
    switch (amode) {
 
6811
    case 0: /* DA */
 
6812
        offset = -4;
 
6813
        break;
 
6814
    case 1: /* IA */
 
6815
        offset = 0;
 
6816
        break;
 
6817
    case 2: /* DB */
 
6818
        offset = -8;
 
6819
        break;
 
6820
    case 3: /* IB */
 
6821
        offset = 4;
 
6822
        break;
 
6823
    default:
 
6824
        abort();
 
6825
    }
 
6826
    tcg_gen_addi_i32(addr, addr, offset);
 
6827
    tmp = load_reg(s, 14);
 
6828
    gen_aa32_st32(tmp, addr, 0);
 
6829
    tcg_temp_free_i32(tmp);
 
6830
    tmp = load_cpu_field(spsr);
 
6831
    tcg_gen_addi_i32(addr, addr, 4);
 
6832
    gen_aa32_st32(tmp, addr, 0);
 
6833
    tcg_temp_free_i32(tmp);
 
6834
    if (writeback) {
 
6835
        switch (amode) {
 
6836
        case 0:
 
6837
            offset = -8;
 
6838
            break;
 
6839
        case 1:
 
6840
            offset = 4;
 
6841
            break;
 
6842
        case 2:
 
6843
            offset = -4;
 
6844
            break;
 
6845
        case 3:
 
6846
            offset = 0;
 
6847
            break;
 
6848
        default:
 
6849
            abort();
 
6850
        }
 
6851
        tcg_gen_addi_i32(addr, addr, offset);
 
6852
        tmp = tcg_const_i32(mode);
 
6853
        gen_helper_set_r13_banked(cpu_env, tmp, addr);
 
6854
        tcg_temp_free_i32(tmp);
 
6855
    }
 
6856
    tcg_temp_free_i32(addr);
 
6857
}
 
6858
 
 
6859
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
 
6860
{
 
6861
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
 
6862
    TCGv_i32 tmp;
 
6863
    TCGv_i32 tmp2;
 
6864
    TCGv_i32 tmp3;
 
6865
    TCGv_i32 addr;
 
6866
    TCGv_i64 tmp64;
 
6867
 
 
6868
    insn = arm_ldl_code(env, s->pc, s->bswap_code);
 
6869
    s->pc += 4;
 
6870
 
 
6871
    /* M variants do not implement ARM mode.  */
 
6872
    if (IS_M(env))
 
6873
        goto illegal_op;
 
6874
    cond = insn >> 28;
 
6875
    if (cond == 0xf){
 
6876
        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
 
6877
         * choose to UNDEF. In ARMv5 and above the space is used
 
6878
         * for miscellaneous unconditional instructions.
 
6879
         */
 
6880
        ARCH(5);
 
6881
 
 
6882
        /* Unconditional instructions.  */
 
6883
        if (((insn >> 25) & 7) == 1) {
 
6884
            /* NEON Data processing.  */
 
6885
            if (!arm_feature(env, ARM_FEATURE_NEON))
 
6886
                goto illegal_op;
 
6887
 
 
6888
            if (disas_neon_data_insn(env, s, insn))
 
6889
                goto illegal_op;
 
6890
            return;
 
6891
        }
 
6892
        if ((insn & 0x0f100000) == 0x04000000) {
 
6893
            /* NEON load/store.  */
 
6894
            if (!arm_feature(env, ARM_FEATURE_NEON))
 
6895
                goto illegal_op;
 
6896
 
 
6897
            if (disas_neon_ls_insn(env, s, insn))
 
6898
                goto illegal_op;
 
6899
            return;
 
6900
        }
 
6901
        if ((insn & 0x0f000e10) == 0x0e000a00) {
 
6902
            /* VFP.  */
 
6903
            if (disas_vfp_insn(env, s, insn)) {
 
6904
                goto illegal_op;
 
6905
            }
 
6906
            return;
 
6907
        }
 
6908
        if (((insn & 0x0f30f000) == 0x0510f000) ||
 
6909
            ((insn & 0x0f30f010) == 0x0710f000)) {
 
6910
            if ((insn & (1 << 22)) == 0) {
 
6911
                /* PLDW; v7MP */
 
6912
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
 
6913
                    goto illegal_op;
 
6914
                }
 
6915
            }
 
6916
            /* Otherwise PLD; v5TE+ */
 
6917
            ARCH(5TE);
 
6918
            return;
 
6919
        }
 
6920
        if (((insn & 0x0f70f000) == 0x0450f000) ||
 
6921
            ((insn & 0x0f70f010) == 0x0650f000)) {
 
6922
            ARCH(7);
 
6923
            return; /* PLI; V7 */
 
6924
        }
 
6925
        if (((insn & 0x0f700000) == 0x04100000) ||
 
6926
            ((insn & 0x0f700010) == 0x06100000)) {
 
6927
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
 
6928
                goto illegal_op;
 
6929
            }
 
6930
            return; /* v7MP: Unallocated memory hint: must NOP */
 
6931
        }
 
6932
 
 
6933
        if ((insn & 0x0ffffdff) == 0x01010000) {
 
6934
            ARCH(6);
 
6935
            /* setend */
 
6936
            if (((insn >> 9) & 1) != s->bswap_code) {
 
6937
                /* Dynamic endianness switching not implemented. */
 
6938
                qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
 
6939
                goto illegal_op;
 
6940
            }
 
6941
            return;
 
6942
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
 
6943
            switch ((insn >> 4) & 0xf) {
 
6944
            case 1: /* clrex */
 
6945
                ARCH(6K);
 
6946
                gen_clrex(s);
 
6947
                return;
 
6948
            case 4: /* dsb */
 
6949
            case 5: /* dmb */
 
6950
            case 6: /* isb */
 
6951
                ARCH(7);
 
6952
                /* We don't emulate caches so these are a no-op.  */
 
6953
                return;
 
6954
            default:
 
6955
                goto illegal_op;
 
6956
            }
 
6957
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
 
6958
            /* srs */
 
6959
            if (IS_USER(s)) {
 
6960
                goto illegal_op;
 
6961
            }
 
6962
            ARCH(6);
 
6963
            gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
 
6964
            return;
 
6965
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
 
6966
            /* rfe */
 
6967
            int32_t offset;
 
6968
            if (IS_USER(s))
 
6969
                goto illegal_op;
 
6970
            ARCH(6);
 
6971
            rn = (insn >> 16) & 0xf;
 
6972
            addr = load_reg(s, rn);
 
6973
            i = (insn >> 23) & 3;
 
6974
            switch (i) {
 
6975
            case 0: offset = -4; break; /* DA */
 
6976
            case 1: offset = 0; break; /* IA */
 
6977
            case 2: offset = -8; break; /* DB */
 
6978
            case 3: offset = 4; break; /* IB */
 
6979
            default: abort();
 
6980
            }
 
6981
            if (offset)
 
6982
                tcg_gen_addi_i32(addr, addr, offset);
 
6983
            /* Load PC into tmp and CPSR into tmp2.  */
 
6984
            tmp = tcg_temp_new_i32();
 
6985
            gen_aa32_ld32u(tmp, addr, 0);
 
6986
            tcg_gen_addi_i32(addr, addr, 4);
 
6987
            tmp2 = tcg_temp_new_i32();
 
6988
            gen_aa32_ld32u(tmp2, addr, 0);
 
6989
            if (insn & (1 << 21)) {
 
6990
                /* Base writeback.  */
 
6991
                switch (i) {
 
6992
                case 0: offset = -8; break;
 
6993
                case 1: offset = 4; break;
 
6994
                case 2: offset = -4; break;
 
6995
                case 3: offset = 0; break;
 
6996
                default: abort();
 
6997
                }
 
6998
                if (offset)
 
6999
                    tcg_gen_addi_i32(addr, addr, offset);
 
7000
                store_reg(s, rn, addr);
 
7001
            } else {
 
7002
                tcg_temp_free_i32(addr);
 
7003
            }
 
7004
            gen_rfe(s, tmp, tmp2);
 
7005
            return;
 
7006
        } else if ((insn & 0x0e000000) == 0x0a000000) {
 
7007
            /* branch link and change to thumb (blx <offset>) */
 
7008
            int32_t offset;
 
7009
 
 
7010
            val = (uint32_t)s->pc;
 
7011
            tmp = tcg_temp_new_i32();
 
7012
            tcg_gen_movi_i32(tmp, val);
 
7013
            store_reg(s, 14, tmp);
 
7014
            /* Sign-extend the 24-bit offset */
 
7015
            offset = (((int32_t)insn) << 8) >> 8;
 
7016
            /* offset * 4 + bit24 * 2 + (thumb bit) */
 
7017
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
 
7018
            /* pipeline offset */
 
7019
            val += 4;
 
7020
            /* protected by ARCH(5); above, near the start of uncond block */
 
7021
            gen_bx_im(s, val);
 
7022
            return;
 
7023
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
 
7024
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
 
7025
                /* iWMMXt register transfer.  */
 
7026
                if (env->cp15.c15_cpar & (1 << 1))
 
7027
                    if (!disas_iwmmxt_insn(env, s, insn))
 
7028
                        return;
 
7029
            }
 
7030
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
 
7031
            /* Coprocessor double register transfer.  */
 
7032
            ARCH(5TE);
 
7033
            /* XXX doesn't belong in the trustzone patch: should just UNDEF? */
 
7034
            cpu_abort(env, "unsupported coprocessor double register transfer\n");
 
7035
        } else if ((insn & 0x0f000010) == 0x0e000010) {
 
7036
            /* Additional coprocessor register transfer.  */
 
7037
            if (!disas_coproc_insn(env, s, insn)) {
 
7038
                return;
 
7039
            }
 
7040
        } else if ((insn & 0x0ff10020) == 0x01000000) {
 
7041
            uint32_t mask;
 
7042
            uint32_t val;
 
7043
            /* cps (privileged) */
 
7044
            if (IS_USER(s))
 
7045
                return;
 
7046
            mask = val = 0;
 
7047
            if (insn & (1 << 19)) {
 
7048
                if (insn & (1 << 8))
 
7049
                    mask |= CPSR_A;
 
7050
                if (insn & (1 << 7))
 
7051
                    mask |= CPSR_I;
 
7052
                if (insn & (1 << 6))
 
7053
                    mask |= CPSR_F;
 
7054
                if (insn & (1 << 18))
 
7055
                    val |= mask;
 
7056
            }
 
7057
            if (insn & (1 << 17)) {
 
7058
                mask |= CPSR_M;
 
7059
                val |= (insn & 0x1f);
 
7060
            }
 
7061
            if (mask) {
 
7062
                gen_set_psr_im(s, mask, 0, val);
 
7063
            }
 
7064
            return;
 
7065
        }
 
7066
        goto illegal_op;
 
7067
    }
 
7068
    if (cond != 0xe) {
 
7069
        /* if not always execute, we generate a conditional jump to
 
7070
           next instruction */
 
7071
        s->condlabel = gen_new_label();
 
7072
        gen_test_cc(cond ^ 1, s->condlabel);
 
7073
        s->condjmp = 1;
 
7074
    }
 
7075
    if ((insn & 0x0f900000) == 0x03000000) {
 
7076
        if ((insn & (1 << 21)) == 0) {
 
7077
            ARCH(6T2);
 
7078
            rd = (insn >> 12) & 0xf;
 
7079
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
 
7080
            if ((insn & (1 << 22)) == 0) {
 
7081
                /* MOVW */
 
7082
                tmp = tcg_temp_new_i32();
 
7083
                tcg_gen_movi_i32(tmp, val);
 
7084
            } else {
 
7085
                /* MOVT */
 
7086
                tmp = load_reg(s, rd);
 
7087
                tcg_gen_ext16u_i32(tmp, tmp);
 
7088
                tcg_gen_ori_i32(tmp, tmp, val << 16);
 
7089
            }
 
7090
            store_reg(s, rd, tmp);
 
7091
        } else {
 
7092
            if (((insn >> 12) & 0xf) != 0xf)
 
7093
                goto illegal_op;
 
7094
            if (((insn >> 16) & 0xf) == 0) {
 
7095
                gen_nop_hint(s, insn & 0xff);
 
7096
            } else {
 
7097
                /* CPSR = immediate */
 
7098
                val = insn & 0xff;
 
7099
                shift = ((insn >> 8) & 0xf) * 2;
 
7100
                if (shift)
 
7101
                    val = (val >> shift) | (val << (32 - shift));
 
7102
                i = ((insn & (1 << 22)) != 0);
 
7103
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
 
7104
                    goto illegal_op;
 
7105
            }
 
7106
        }
 
7107
    } else if ((insn & 0x0f900000) == 0x01000000
 
7108
               && (insn & 0x00000090) != 0x00000090) {
 
7109
        /* miscellaneous instructions */
 
7110
        op1 = (insn >> 21) & 3;
 
7111
        sh = (insn >> 4) & 0xf;
 
7112
        rm = insn & 0xf;
 
7113
        switch (sh) {
 
7114
        case 0x0: /* move program status register */
 
7115
            if (op1 & 1) {
 
7116
                /* PSR = reg */
 
7117
                tmp = load_reg(s, rm);
 
7118
                i = ((op1 & 2) != 0);
 
7119
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
 
7120
                    goto illegal_op;
 
7121
            } else {
 
7122
                /* reg = PSR */
 
7123
                rd = (insn >> 12) & 0xf;
 
7124
                if (op1 & 2) {
 
7125
                    if (IS_USER(s))
 
7126
                        goto illegal_op;
 
7127
                    tmp = load_cpu_field(spsr);
 
7128
                } else {
 
7129
                    tmp = tcg_temp_new_i32();
 
7130
                    gen_helper_cpsr_read(tmp, cpu_env);
 
7131
                }
 
7132
                store_reg(s, rd, tmp);
 
7133
            }
 
7134
            break;
 
7135
        case 0x1:
 
7136
            if (op1 == 1) {
 
7137
                /* branch/exchange thumb (bx).  */
 
7138
                ARCH(4T);
 
7139
                tmp = load_reg(s, rm);
 
7140
                gen_bx(s, tmp);
 
7141
            } else if (op1 == 3) {
 
7142
                /* clz */
 
7143
                ARCH(5);
 
7144
                rd = (insn >> 12) & 0xf;
 
7145
                tmp = load_reg(s, rm);
 
7146
                gen_helper_clz(tmp, tmp);
 
7147
                store_reg(s, rd, tmp);
 
7148
            } else {
 
7149
                goto illegal_op;
 
7150
            }
 
7151
            break;
 
7152
        case 0x2:
 
7153
            if (op1 == 1) {
 
7154
                ARCH(5J); /* bxj */
 
7155
                /* Trivial implementation equivalent to bx.  */
 
7156
                tmp = load_reg(s, rm);
 
7157
                gen_bx(s, tmp);
 
7158
            } else {
 
7159
                goto illegal_op;
 
7160
            }
 
7161
            break;
 
7162
        case 0x3:
 
7163
            if (op1 != 1)
 
7164
              goto illegal_op;
 
7165
 
 
7166
            ARCH(5);
 
7167
            /* branch link/exchange thumb (blx) */
 
7168
            tmp = load_reg(s, rm);
 
7169
            tmp2 = tcg_temp_new_i32();
 
7170
            tcg_gen_movi_i32(tmp2, s->pc);
 
7171
            store_reg(s, 14, tmp2);
 
7172
            gen_bx(s, tmp);
 
7173
            break;
 
7174
        case 0x5: /* saturating add/subtract */
 
7175
            ARCH(5TE);
 
7176
            rd = (insn >> 12) & 0xf;
 
7177
            rn = (insn >> 16) & 0xf;
 
7178
            tmp = load_reg(s, rm);
 
7179
            tmp2 = load_reg(s, rn);
 
7180
            if (op1 & 2)
 
7181
                gen_helper_double_saturate(tmp2, cpu_env, tmp2);
 
7182
            if (op1 & 1)
 
7183
                gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
 
7184
            else
 
7185
                gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
 
7186
            tcg_temp_free_i32(tmp2);
 
7187
            store_reg(s, rd, tmp);
 
7188
            break;
 
7189
        case 7:
 
7190
            if (op1 == 1) {
 
7191
                /* bkpt */
 
7192
                ARCH(5);
 
7193
                gen_exception_insn(s, 4, EXCP_BKPT);
 
7194
            } else if (op1 == 3) {
 
7195
                /* smi/smc */
 
7196
                if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
 
7197
                    goto illegal_op;
 
7198
                }
 
7199
                gen_smc(env, s);
 
7200
            } else {
 
7201
                goto illegal_op;
 
7202
            }
 
7203
            break;
 
7204
        case 0x8: /* signed multiply */
 
7205
        case 0xa:
 
7206
        case 0xc:
 
7207
        case 0xe:
 
7208
            ARCH(5TE);
 
7209
            rs = (insn >> 8) & 0xf;
 
7210
            rn = (insn >> 12) & 0xf;
 
7211
            rd = (insn >> 16) & 0xf;
 
7212
            if (op1 == 1) {
 
7213
                /* (32 * 16) >> 16 */
 
7214
                tmp = load_reg(s, rm);
 
7215
                tmp2 = load_reg(s, rs);
 
7216
                if (sh & 4)
 
7217
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
 
7218
                else
 
7219
                    gen_sxth(tmp2);
 
7220
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
 
7221
                tcg_gen_shri_i64(tmp64, tmp64, 16);
 
7222
                tmp = tcg_temp_new_i32();
 
7223
                tcg_gen_trunc_i64_i32(tmp, tmp64);
 
7224
                tcg_temp_free_i64(tmp64);
 
7225
                if ((sh & 2) == 0) {
 
7226
                    tmp2 = load_reg(s, rn);
 
7227
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 
7228
                    tcg_temp_free_i32(tmp2);
 
7229
                }
 
7230
                store_reg(s, rd, tmp);
 
7231
            } else {
 
7232
                /* 16 * 16 */
 
7233
                tmp = load_reg(s, rm);
 
7234
                tmp2 = load_reg(s, rs);
 
7235
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
 
7236
                tcg_temp_free_i32(tmp2);
 
7237
                if (op1 == 2) {
 
7238
                    tmp64 = tcg_temp_new_i64();
 
7239
                    tcg_gen_ext_i32_i64(tmp64, tmp);
 
7240
                    tcg_temp_free_i32(tmp);
 
7241
                    gen_addq(s, tmp64, rn, rd);
 
7242
                    gen_storeq_reg(s, rn, rd, tmp64);
 
7243
                    tcg_temp_free_i64(tmp64);
 
7244
                } else {
 
7245
                    if (op1 == 0) {
 
7246
                        tmp2 = load_reg(s, rn);
 
7247
                        gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 
7248
                        tcg_temp_free_i32(tmp2);
 
7249
                    }
 
7250
                    store_reg(s, rd, tmp);
 
7251
                }
 
7252
            }
 
7253
            break;
 
7254
        default:
 
7255
            goto illegal_op;
 
7256
        }
 
7257
    } else if (((insn & 0x0e000000) == 0 &&
 
7258
                (insn & 0x00000090) != 0x90) ||
 
7259
               ((insn & 0x0e000000) == (1 << 25))) {
 
7260
        int set_cc, logic_cc, shiftop;
 
7261
 
 
7262
        op1 = (insn >> 21) & 0xf;
 
7263
        set_cc = (insn >> 20) & 1;
 
7264
        logic_cc = table_logic_cc[op1] & set_cc;
 
7265
 
 
7266
        /* data processing instruction */
 
7267
        if (insn & (1 << 25)) {
 
7268
            /* immediate operand */
 
7269
            val = insn & 0xff;
 
7270
            shift = ((insn >> 8) & 0xf) * 2;
 
7271
            if (shift) {
 
7272
                val = (val >> shift) | (val << (32 - shift));
 
7273
            }
 
7274
            tmp2 = tcg_temp_new_i32();
 
7275
            tcg_gen_movi_i32(tmp2, val);
 
7276
            if (logic_cc && shift) {
 
7277
                gen_set_CF_bit31(tmp2);
 
7278
            }
 
7279
        } else {
 
7280
            /* register */
 
7281
            rm = (insn) & 0xf;
 
7282
            tmp2 = load_reg(s, rm);
 
7283
            shiftop = (insn >> 5) & 3;
 
7284
            if (!(insn & (1 << 4))) {
 
7285
                shift = (insn >> 7) & 0x1f;
 
7286
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
 
7287
            } else {
 
7288
                rs = (insn >> 8) & 0xf;
 
7289
                tmp = load_reg(s, rs);
 
7290
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
 
7291
            }
 
7292
        }
 
7293
        if (op1 != 0x0f && op1 != 0x0d) {
 
7294
            rn = (insn >> 16) & 0xf;
 
7295
            tmp = load_reg(s, rn);
 
7296
        } else {
 
7297
            TCGV_UNUSED_I32(tmp);
 
7298
        }
 
7299
        rd = (insn >> 12) & 0xf;
 
7300
        switch(op1) {
 
7301
        case 0x00:
 
7302
            tcg_gen_and_i32(tmp, tmp, tmp2);
 
7303
            if (logic_cc) {
 
7304
                gen_logic_CC(tmp);
 
7305
            }
 
7306
            store_reg_bx(env, s, rd, tmp);
 
7307
            break;
 
7308
        case 0x01:
 
7309
            tcg_gen_xor_i32(tmp, tmp, tmp2);
 
7310
            if (logic_cc) {
 
7311
                gen_logic_CC(tmp);
 
7312
            }
 
7313
            store_reg_bx(env, s, rd, tmp);
 
7314
            break;
 
7315
        case 0x02:
 
7316
            if (set_cc && rd == 15) {
 
7317
                /* SUBS r15, ... is used for exception return.  */
 
7318
                if (IS_USER(s)) {
 
7319
                    goto illegal_op;
 
7320
                }
 
7321
                gen_sub_CC(tmp, tmp, tmp2);
 
7322
                gen_exception_return(s, tmp);
 
7323
            } else {
 
7324
                if (set_cc) {
 
7325
                    gen_sub_CC(tmp, tmp, tmp2);
 
7326
                } else {
 
7327
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
 
7328
                }
 
7329
                store_reg_bx(env, s, rd, tmp);
 
7330
            }
 
7331
            break;
 
7332
        case 0x03:
 
7333
            if (set_cc) {
 
7334
                gen_sub_CC(tmp, tmp2, tmp);
 
7335
            } else {
 
7336
                tcg_gen_sub_i32(tmp, tmp2, tmp);
 
7337
            }
 
7338
            store_reg_bx(env, s, rd, tmp);
 
7339
            break;
 
7340
        case 0x04:
 
7341
            if (set_cc) {
 
7342
                gen_add_CC(tmp, tmp, tmp2);
 
7343
            } else {
 
7344
                tcg_gen_add_i32(tmp, tmp, tmp2);
 
7345
            }
 
7346
            store_reg_bx(env, s, rd, tmp);
 
7347
            break;
 
7348
        case 0x05:
 
7349
            if (set_cc) {
 
7350
                gen_adc_CC(tmp, tmp, tmp2);
 
7351
            } else {
 
7352
                gen_add_carry(tmp, tmp, tmp2);
 
7353
            }
 
7354
            store_reg_bx(env, s, rd, tmp);
 
7355
            break;
 
7356
        case 0x06:
 
7357
            if (set_cc) {
 
7358
                gen_sbc_CC(tmp, tmp, tmp2);
 
7359
            } else {
 
7360
                gen_sub_carry(tmp, tmp, tmp2);
 
7361
            }
 
7362
            store_reg_bx(env, s, rd, tmp);
 
7363
            break;
 
7364
        case 0x07:
 
7365
            if (set_cc) {
 
7366
                gen_sbc_CC(tmp, tmp2, tmp);
 
7367
            } else {
 
7368
                gen_sub_carry(tmp, tmp2, tmp);
 
7369
            }
 
7370
            store_reg_bx(env, s, rd, tmp);
 
7371
            break;
 
7372
        case 0x08:
 
7373
            if (set_cc) {
 
7374
                tcg_gen_and_i32(tmp, tmp, tmp2);
 
7375
                gen_logic_CC(tmp);
 
7376
            }
 
7377
            tcg_temp_free_i32(tmp);
 
7378
            break;
 
7379
        case 0x09:
 
7380
            if (set_cc) {
 
7381
                tcg_gen_xor_i32(tmp, tmp, tmp2);
 
7382
                gen_logic_CC(tmp);
 
7383
            }
 
7384
            tcg_temp_free_i32(tmp);
 
7385
            break;
 
7386
        case 0x0a:
 
7387
            if (set_cc) {
 
7388
                gen_sub_CC(tmp, tmp, tmp2);
 
7389
            }
 
7390
            tcg_temp_free_i32(tmp);
 
7391
            break;
 
7392
        case 0x0b:
 
7393
            if (set_cc) {
 
7394
                gen_add_CC(tmp, tmp, tmp2);
 
7395
            }
 
7396
            tcg_temp_free_i32(tmp);
 
7397
            break;
 
7398
        case 0x0c:
 
7399
            tcg_gen_or_i32(tmp, tmp, tmp2);
 
7400
            if (logic_cc) {
 
7401
                gen_logic_CC(tmp);
 
7402
            }
 
7403
            store_reg_bx(env, s, rd, tmp);
 
7404
            break;
 
7405
        case 0x0d:
 
7406
            if (logic_cc && rd == 15) {
 
7407
                /* MOVS r15, ... is used for exception return.  */
 
7408
                if (IS_USER(s)) {
 
7409
                    goto illegal_op;
 
7410
                }
 
7411
                gen_exception_return(s, tmp2);
 
7412
            } else {
 
7413
                if (logic_cc) {
 
7414
                    gen_logic_CC(tmp2);
 
7415
                }
 
7416
                store_reg_bx(env, s, rd, tmp2);
 
7417
            }
 
7418
            break;
 
7419
        case 0x0e:
 
7420
            tcg_gen_andc_i32(tmp, tmp, tmp2);
 
7421
            if (logic_cc) {
 
7422
                gen_logic_CC(tmp);
 
7423
            }
 
7424
            store_reg_bx(env, s, rd, tmp);
 
7425
            break;
 
7426
        default:
 
7427
        case 0x0f:
 
7428
            tcg_gen_not_i32(tmp2, tmp2);
 
7429
            if (logic_cc) {
 
7430
                gen_logic_CC(tmp2);
 
7431
            }
 
7432
            store_reg_bx(env, s, rd, tmp2);
 
7433
            break;
 
7434
        }
 
7435
        if (op1 != 0x0f && op1 != 0x0d) {
 
7436
            tcg_temp_free_i32(tmp2);
 
7437
        }
 
7438
    } else {
 
7439
        /* other instructions */
 
7440
        op1 = (insn >> 24) & 0xf;
 
7441
        switch(op1) {
 
7442
        case 0x0:
 
7443
        case 0x1:
 
7444
            /* multiplies, extra load/stores */
 
7445
            sh = (insn >> 5) & 3;
 
7446
            if (sh == 0) {
 
7447
                if (op1 == 0x0) {
 
7448
                    rd = (insn >> 16) & 0xf;
 
7449
                    rn = (insn >> 12) & 0xf;
 
7450
                    rs = (insn >> 8) & 0xf;
 
7451
                    rm = (insn) & 0xf;
 
7452
                    op1 = (insn >> 20) & 0xf;
 
7453
                    switch (op1) {
 
7454
                    case 0: case 1: case 2: case 3: case 6:
 
7455
                        /* 32 bit mul */
 
7456
                        tmp = load_reg(s, rs);
 
7457
                        tmp2 = load_reg(s, rm);
 
7458
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
 
7459
                        tcg_temp_free_i32(tmp2);
 
7460
                        if (insn & (1 << 22)) {
 
7461
                            /* Subtract (mls) */
 
7462
                            ARCH(6T2);
 
7463
                            tmp2 = load_reg(s, rn);
 
7464
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
 
7465
                            tcg_temp_free_i32(tmp2);
 
7466
                        } else if (insn & (1 << 21)) {
 
7467
                            /* Add */
 
7468
                            tmp2 = load_reg(s, rn);
 
7469
                            tcg_gen_add_i32(tmp, tmp, tmp2);
 
7470
                            tcg_temp_free_i32(tmp2);
 
7471
                        }
 
7472
                        if (insn & (1 << 20))
 
7473
                            gen_logic_CC(tmp);
 
7474
                        store_reg(s, rd, tmp);
 
7475
                        break;
 
7476
                    case 4:
 
7477
                        /* 64 bit mul double accumulate (UMAAL) */
 
7478
                        ARCH(6);
 
7479
                        tmp = load_reg(s, rs);
 
7480
                        tmp2 = load_reg(s, rm);
 
7481
                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
 
7482
                        gen_addq_lo(s, tmp64, rn);
 
7483
                        gen_addq_lo(s, tmp64, rd);
 
7484
                        gen_storeq_reg(s, rn, rd, tmp64);
 
7485
                        tcg_temp_free_i64(tmp64);
 
7486
                        break;
 
7487
                    case 8: case 9: case 10: case 11:
 
7488
                    case 12: case 13: case 14: case 15:
 
7489
                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
 
7490
                        tmp = load_reg(s, rs);
 
7491
                        tmp2 = load_reg(s, rm);
 
7492
                        if (insn & (1 << 22)) {
 
7493
                            tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
 
7494
                        } else {
 
7495
                            tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
 
7496
                        }
 
7497
                        if (insn & (1 << 21)) { /* mult accumulate */
 
7498
                            TCGv_i32 al = load_reg(s, rn);
 
7499
                            TCGv_i32 ah = load_reg(s, rd);
 
7500
                            tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
 
7501
                            tcg_temp_free_i32(al);
 
7502
                            tcg_temp_free_i32(ah);
 
7503
                        }
 
7504
                        if (insn & (1 << 20)) {
 
7505
                            gen_logicq_cc(tmp, tmp2);
 
7506
                        }
 
7507
                        store_reg(s, rn, tmp);
 
7508
                        store_reg(s, rd, tmp2);
 
7509
                        break;
 
7510
                    default:
 
7511
                        goto illegal_op;
 
7512
                    }
 
7513
                } else {
 
7514
                    rn = (insn >> 16) & 0xf;
 
7515
                    rd = (insn >> 12) & 0xf;
 
7516
                    if (insn & (1 << 23)) {
 
7517
                        /* load/store exclusive */
 
7518
                        int op2 = (insn >> 8) & 3;
 
7519
                        op1 = (insn >> 21) & 0x3;
 
7520
 
 
7521
                        switch (op2) {
 
7522
                        case 0: /* lda/stl */
 
7523
                            if (op1 == 1) {
 
7524
                                goto illegal_op;
 
7525
                            }
 
7526
                            ARCH(8);
 
7527
                            break;
 
7528
                        case 1: /* reserved */
 
7529
                            goto illegal_op;
 
7530
                        case 2: /* ldaex/stlex */
 
7531
                            ARCH(8);
 
7532
                            break;
 
7533
                        case 3: /* ldrex/strex */
 
7534
                            if (op1) {
 
7535
                                ARCH(6K);
 
7536
                            } else {
 
7537
                                ARCH(6);
 
7538
                            }
 
7539
                            break;
 
7540
                        }
 
7541
 
 
7542
                        addr = tcg_temp_local_new_i32();
 
7543
                        load_reg_var(s, addr, rn);
 
7544
 
 
7545
                        /* Since the emulation does not have barriers,
 
7546
                           the acquire/release semantics need no special
 
7547
                           handling */
 
7548
                        if (op2 == 0) {
 
7549
                            if (insn & (1 << 20)) {
 
7550
                                tmp = tcg_temp_new_i32();
 
7551
                                switch (op1) {
 
7552
                                case 0: /* lda */
 
7553
                                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
7554
                                    break;
 
7555
                                case 2: /* ldab */
 
7556
                                    gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
7557
                                    break;
 
7558
                                case 3: /* ldah */
 
7559
                                    gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
7560
                                    break;
 
7561
                                default:
 
7562
                                    abort();
 
7563
                                }
 
7564
                                store_reg(s, rd, tmp);
 
7565
                            } else {
 
7566
                                rm = insn & 0xf;
 
7567
                                tmp = load_reg(s, rm);
 
7568
                                switch (op1) {
 
7569
                                case 0: /* stl */
 
7570
                                    gen_aa32_st32(tmp, addr, IS_USER(s));
 
7571
                                    break;
 
7572
                                case 2: /* stlb */
 
7573
                                    gen_aa32_st8(tmp, addr, IS_USER(s));
 
7574
                                    break;
 
7575
                                case 3: /* stlh */
 
7576
                                    gen_aa32_st16(tmp, addr, IS_USER(s));
 
7577
                                    break;
 
7578
                                default:
 
7579
                                    abort();
 
7580
                                }
 
7581
                                tcg_temp_free_i32(tmp);
 
7582
                            }
 
7583
                        } else if (insn & (1 << 20)) {
 
7584
                            switch (op1) {
 
7585
                            case 0: /* ldrex */
 
7586
                                gen_load_exclusive(s, rd, 15, addr, 2);
 
7587
                                break;
 
7588
                            case 1: /* ldrexd */
 
7589
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
 
7590
                                break;
 
7591
                            case 2: /* ldrexb */
 
7592
                                gen_load_exclusive(s, rd, 15, addr, 0);
 
7593
                                break;
 
7594
                            case 3: /* ldrexh */
 
7595
                                gen_load_exclusive(s, rd, 15, addr, 1);
 
7596
                                break;
 
7597
                            default:
 
7598
                                abort();
 
7599
                            }
 
7600
                        } else {
 
7601
                            rm = insn & 0xf;
 
7602
                            switch (op1) {
 
7603
                            case 0:  /*  strex */
 
7604
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
 
7605
                                break;
 
7606
                            case 1: /*  strexd */
 
7607
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
 
7608
                                break;
 
7609
                            case 2: /*  strexb */
 
7610
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
 
7611
                                break;
 
7612
                            case 3: /* strexh */
 
7613
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
 
7614
                                break;
 
7615
                            default:
 
7616
                                abort();
 
7617
                            }
 
7618
                        }
 
7619
                        tcg_temp_free_i32(addr);
 
7620
                    } else {
 
7621
                        /* SWP instruction */
 
7622
                        rm = (insn) & 0xf;
 
7623
 
 
7624
                        /* ??? This is not really atomic.  However we know
 
7625
                           we never have multiple CPUs running in parallel,
 
7626
                           so it is good enough.  */
 
7627
                        addr = load_reg(s, rn);
 
7628
                        tmp = load_reg(s, rm);
 
7629
                        tmp2 = tcg_temp_new_i32();
 
7630
                        if (insn & (1 << 22)) {
 
7631
                            gen_aa32_ld8u(tmp2, addr, IS_USER(s));
 
7632
                            gen_aa32_st8(tmp, addr, IS_USER(s));
 
7633
                        } else {
 
7634
                            gen_aa32_ld32u(tmp2, addr, IS_USER(s));
 
7635
                            gen_aa32_st32(tmp, addr, IS_USER(s));
 
7636
                        }
 
7637
                        tcg_temp_free_i32(tmp);
 
7638
                        tcg_temp_free_i32(addr);
 
7639
                        store_reg(s, rd, tmp2);
 
7640
                    }
 
7641
                }
 
7642
            } else {
 
7643
                int address_offset;
 
7644
                int load;
 
7645
                /* Misc load/store */
 
7646
                rn = (insn >> 16) & 0xf;
 
7647
                rd = (insn >> 12) & 0xf;
 
7648
                addr = load_reg(s, rn);
 
7649
                if (insn & (1 << 24))
 
7650
                    gen_add_datah_offset(s, insn, 0, addr);
 
7651
                address_offset = 0;
 
7652
                if (insn & (1 << 20)) {
 
7653
                    /* load */
 
7654
                    tmp = tcg_temp_new_i32();
 
7655
                    switch(sh) {
 
7656
                    case 1:
 
7657
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
7658
                        break;
 
7659
                    case 2:
 
7660
                        gen_aa32_ld8s(tmp, addr, IS_USER(s));
 
7661
                        break;
 
7662
                    default:
 
7663
                    case 3:
 
7664
                        gen_aa32_ld16s(tmp, addr, IS_USER(s));
 
7665
                        break;
 
7666
                    }
 
7667
                    load = 1;
 
7668
                } else if (sh & 2) {
 
7669
                    ARCH(5TE);
 
7670
                    /* doubleword */
 
7671
                    if (sh & 1) {
 
7672
                        /* store */
 
7673
                        tmp = load_reg(s, rd);
 
7674
                        gen_aa32_st32(tmp, addr, IS_USER(s));
 
7675
                        tcg_temp_free_i32(tmp);
 
7676
                        tcg_gen_addi_i32(addr, addr, 4);
 
7677
                        tmp = load_reg(s, rd + 1);
 
7678
                        gen_aa32_st32(tmp, addr, IS_USER(s));
 
7679
                        tcg_temp_free_i32(tmp);
 
7680
                        load = 0;
 
7681
                    } else {
 
7682
                        /* load */
 
7683
                        tmp = tcg_temp_new_i32();
 
7684
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
7685
                        store_reg(s, rd, tmp);
 
7686
                        tcg_gen_addi_i32(addr, addr, 4);
 
7687
                        tmp = tcg_temp_new_i32();
 
7688
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
7689
                        rd++;
 
7690
                        load = 1;
 
7691
                    }
 
7692
                    address_offset = -4;
 
7693
                } else {
 
7694
                    /* store */
 
7695
                    tmp = load_reg(s, rd);
 
7696
                    gen_aa32_st16(tmp, addr, IS_USER(s));
 
7697
                    tcg_temp_free_i32(tmp);
 
7698
                    load = 0;
 
7699
                }
 
7700
                /* Perform base writeback before the loaded value to
 
7701
                   ensure correct behavior with overlapping index registers.
 
7702
                   ldrd with base writeback is is undefined if the
 
7703
                   destination and index registers overlap.  */
 
7704
                if (!(insn & (1 << 24))) {
 
7705
                    gen_add_datah_offset(s, insn, address_offset, addr);
 
7706
                    store_reg(s, rn, addr);
 
7707
                } else if (insn & (1 << 21)) {
 
7708
                    if (address_offset)
 
7709
                        tcg_gen_addi_i32(addr, addr, address_offset);
 
7710
                    store_reg(s, rn, addr);
 
7711
                } else {
 
7712
                    tcg_temp_free_i32(addr);
 
7713
                }
 
7714
                if (load) {
 
7715
                    /* Complete the load.  */
 
7716
                    store_reg(s, rd, tmp);
 
7717
                }
 
7718
            }
 
7719
            break;
 
7720
        case 0x4:
 
7721
        case 0x5:
 
7722
            goto do_ldst;
 
7723
        case 0x6:
 
7724
        case 0x7:
 
7725
            if (insn & (1 << 4)) {
 
7726
                ARCH(6);
 
7727
                /* Armv6 Media instructions.  */
 
7728
                rm = insn & 0xf;
 
7729
                rn = (insn >> 16) & 0xf;
 
7730
                rd = (insn >> 12) & 0xf;
 
7731
                rs = (insn >> 8) & 0xf;
 
7732
                switch ((insn >> 23) & 3) {
 
7733
                case 0: /* Parallel add/subtract.  */
 
7734
                    op1 = (insn >> 20) & 7;
 
7735
                    tmp = load_reg(s, rn);
 
7736
                    tmp2 = load_reg(s, rm);
 
7737
                    sh = (insn >> 5) & 7;
 
7738
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
 
7739
                        goto illegal_op;
 
7740
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
 
7741
                    tcg_temp_free_i32(tmp2);
 
7742
                    store_reg(s, rd, tmp);
 
7743
                    break;
 
7744
                case 1:
 
7745
                    if ((insn & 0x00700020) == 0) {
 
7746
                        /* Halfword pack.  */
 
7747
                        tmp = load_reg(s, rn);
 
7748
                        tmp2 = load_reg(s, rm);
 
7749
                        shift = (insn >> 7) & 0x1f;
 
7750
                        if (insn & (1 << 6)) {
 
7751
                            /* pkhtb */
 
7752
                            if (shift == 0)
 
7753
                                shift = 31;
 
7754
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
 
7755
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
 
7756
                            tcg_gen_ext16u_i32(tmp2, tmp2);
 
7757
                        } else {
 
7758
                            /* pkhbt */
 
7759
                            if (shift)
 
7760
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
 
7761
                            tcg_gen_ext16u_i32(tmp, tmp);
 
7762
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
 
7763
                        }
 
7764
                        tcg_gen_or_i32(tmp, tmp, tmp2);
 
7765
                        tcg_temp_free_i32(tmp2);
 
7766
                        store_reg(s, rd, tmp);
 
7767
                    } else if ((insn & 0x00200020) == 0x00200000) {
 
7768
                        /* [us]sat */
 
7769
                        tmp = load_reg(s, rm);
 
7770
                        shift = (insn >> 7) & 0x1f;
 
7771
                        if (insn & (1 << 6)) {
 
7772
                            if (shift == 0)
 
7773
                                shift = 31;
 
7774
                            tcg_gen_sari_i32(tmp, tmp, shift);
 
7775
                        } else {
 
7776
                            tcg_gen_shli_i32(tmp, tmp, shift);
 
7777
                        }
 
7778
                        sh = (insn >> 16) & 0x1f;
 
7779
                        tmp2 = tcg_const_i32(sh);
 
7780
                        if (insn & (1 << 22))
 
7781
                          gen_helper_usat(tmp, cpu_env, tmp, tmp2);
 
7782
                        else
 
7783
                          gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
 
7784
                        tcg_temp_free_i32(tmp2);
 
7785
                        store_reg(s, rd, tmp);
 
7786
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
 
7787
                        /* [us]sat16 */
 
7788
                        tmp = load_reg(s, rm);
 
7789
                        sh = (insn >> 16) & 0x1f;
 
7790
                        tmp2 = tcg_const_i32(sh);
 
7791
                        if (insn & (1 << 22))
 
7792
                          gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
 
7793
                        else
 
7794
                          gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
 
7795
                        tcg_temp_free_i32(tmp2);
 
7796
                        store_reg(s, rd, tmp);
 
7797
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
 
7798
                        /* Select bytes.  */
 
7799
                        tmp = load_reg(s, rn);
 
7800
                        tmp2 = load_reg(s, rm);
 
7801
                        tmp3 = tcg_temp_new_i32();
 
7802
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
 
7803
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
 
7804
                        tcg_temp_free_i32(tmp3);
 
7805
                        tcg_temp_free_i32(tmp2);
 
7806
                        store_reg(s, rd, tmp);
 
7807
                    } else if ((insn & 0x000003e0) == 0x00000060) {
 
7808
                        tmp = load_reg(s, rm);
 
7809
                        shift = (insn >> 10) & 3;
 
7810
                        /* ??? In many cases it's not necessary to do a
 
7811
                           rotate, a shift is sufficient.  */
 
7812
                        if (shift != 0)
 
7813
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
 
7814
                        op1 = (insn >> 20) & 7;
 
7815
                        switch (op1) {
 
7816
                        case 0: gen_sxtb16(tmp);  break;
 
7817
                        case 2: gen_sxtb(tmp);    break;
 
7818
                        case 3: gen_sxth(tmp);    break;
 
7819
                        case 4: gen_uxtb16(tmp);  break;
 
7820
                        case 6: gen_uxtb(tmp);    break;
 
7821
                        case 7: gen_uxth(tmp);    break;
 
7822
                        default: goto illegal_op;
 
7823
                        }
 
7824
                        if (rn != 15) {
 
7825
                            tmp2 = load_reg(s, rn);
 
7826
                            if ((op1 & 3) == 0) {
 
7827
                                gen_add16(tmp, tmp2);
 
7828
                            } else {
 
7829
                                tcg_gen_add_i32(tmp, tmp, tmp2);
 
7830
                                tcg_temp_free_i32(tmp2);
 
7831
                            }
 
7832
                        }
 
7833
                        store_reg(s, rd, tmp);
 
7834
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
 
7835
                        /* rev */
 
7836
                        tmp = load_reg(s, rm);
 
7837
                        if (insn & (1 << 22)) {
 
7838
                            if (insn & (1 << 7)) {
 
7839
                                gen_revsh(tmp);
 
7840
                            } else {
 
7841
                                ARCH(6T2);
 
7842
                                gen_helper_rbit(tmp, tmp);
 
7843
                            }
 
7844
                        } else {
 
7845
                            if (insn & (1 << 7))
 
7846
                                gen_rev16(tmp);
 
7847
                            else
 
7848
                                tcg_gen_bswap32_i32(tmp, tmp);
 
7849
                        }
 
7850
                        store_reg(s, rd, tmp);
 
7851
                    } else {
 
7852
                        goto illegal_op;
 
7853
                    }
 
7854
                    break;
 
7855
                case 2: /* Multiplies (Type 3).  */
 
7856
                    switch ((insn >> 20) & 0x7) {
 
7857
                    case 5:
 
7858
                        if (((insn >> 6) ^ (insn >> 7)) & 1) {
 
7859
                            /* op2 not 00x or 11x : UNDEF */
 
7860
                            goto illegal_op;
 
7861
                        }
 
7862
                        /* Signed multiply most significant [accumulate].
 
7863
                           (SMMUL, SMMLA, SMMLS) */
 
7864
                        tmp = load_reg(s, rm);
 
7865
                        tmp2 = load_reg(s, rs);
 
7866
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
 
7867
 
 
7868
                        if (rd != 15) {
 
7869
                            tmp = load_reg(s, rd);
 
7870
                            if (insn & (1 << 6)) {
 
7871
                                tmp64 = gen_subq_msw(tmp64, tmp);
 
7872
                            } else {
 
7873
                                tmp64 = gen_addq_msw(tmp64, tmp);
 
7874
                            }
 
7875
                        }
 
7876
                        if (insn & (1 << 5)) {
 
7877
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
 
7878
                        }
 
7879
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
 
7880
                        tmp = tcg_temp_new_i32();
 
7881
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
 
7882
                        tcg_temp_free_i64(tmp64);
 
7883
                        store_reg(s, rn, tmp);
 
7884
                        break;
 
7885
                    case 0:
 
7886
                    case 4:
 
7887
                        /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
 
7888
                        if (insn & (1 << 7)) {
 
7889
                            goto illegal_op;
 
7890
                        }
 
7891
                        tmp = load_reg(s, rm);
 
7892
                        tmp2 = load_reg(s, rs);
 
7893
                        if (insn & (1 << 5))
 
7894
                            gen_swap_half(tmp2);
 
7895
                        gen_smul_dual(tmp, tmp2);
 
7896
                        if (insn & (1 << 6)) {
 
7897
                            /* This subtraction cannot overflow. */
 
7898
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
 
7899
                        } else {
 
7900
                            /* This addition cannot overflow 32 bits;
 
7901
                             * however it may overflow considered as a signed
 
7902
                             * operation, in which case we must set the Q flag.
 
7903
                             */
 
7904
                            gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 
7905
                        }
 
7906
                        tcg_temp_free_i32(tmp2);
 
7907
                        if (insn & (1 << 22)) {
 
7908
                            /* smlald, smlsld */
 
7909
                            tmp64 = tcg_temp_new_i64();
 
7910
                            tcg_gen_ext_i32_i64(tmp64, tmp);
 
7911
                            tcg_temp_free_i32(tmp);
 
7912
                            gen_addq(s, tmp64, rd, rn);
 
7913
                            gen_storeq_reg(s, rd, rn, tmp64);
 
7914
                            tcg_temp_free_i64(tmp64);
 
7915
                        } else {
 
7916
                            /* smuad, smusd, smlad, smlsd */
 
7917
                            if (rd != 15)
 
7918
                              {
 
7919
                                tmp2 = load_reg(s, rd);
 
7920
                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 
7921
                                tcg_temp_free_i32(tmp2);
 
7922
                              }
 
7923
                            store_reg(s, rn, tmp);
 
7924
                        }
 
7925
                        break;
 
7926
                    case 1:
 
7927
                    case 3:
 
7928
                        /* SDIV, UDIV */
 
7929
                        if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
 
7930
                            goto illegal_op;
 
7931
                        }
 
7932
                        if (((insn >> 5) & 7) || (rd != 15)) {
 
7933
                            goto illegal_op;
 
7934
                        }
 
7935
                        tmp = load_reg(s, rm);
 
7936
                        tmp2 = load_reg(s, rs);
 
7937
                        if (insn & (1 << 21)) {
 
7938
                            gen_helper_udiv(tmp, tmp, tmp2);
 
7939
                        } else {
 
7940
                            gen_helper_sdiv(tmp, tmp, tmp2);
 
7941
                        }
 
7942
                        tcg_temp_free_i32(tmp2);
 
7943
                        store_reg(s, rn, tmp);
 
7944
                        break;
 
7945
                    default:
 
7946
                        goto illegal_op;
 
7947
                    }
 
7948
                    break;
 
7949
                case 3:
 
7950
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
 
7951
                    switch (op1) {
 
7952
                    case 0: /* Unsigned sum of absolute differences.  */
 
7953
                        ARCH(6);
 
7954
                        tmp = load_reg(s, rm);
 
7955
                        tmp2 = load_reg(s, rs);
 
7956
                        gen_helper_usad8(tmp, tmp, tmp2);
 
7957
                        tcg_temp_free_i32(tmp2);
 
7958
                        if (rd != 15) {
 
7959
                            tmp2 = load_reg(s, rd);
 
7960
                            tcg_gen_add_i32(tmp, tmp, tmp2);
 
7961
                            tcg_temp_free_i32(tmp2);
 
7962
                        }
 
7963
                        store_reg(s, rn, tmp);
 
7964
                        break;
 
7965
                    case 0x20: case 0x24: case 0x28: case 0x2c:
 
7966
                        /* Bitfield insert/clear.  */
 
7967
                        ARCH(6T2);
 
7968
                        shift = (insn >> 7) & 0x1f;
 
7969
                        i = (insn >> 16) & 0x1f;
 
7970
                        i = i + 1 - shift;
 
7971
                        if (rm == 15) {
 
7972
                            tmp = tcg_temp_new_i32();
 
7973
                            tcg_gen_movi_i32(tmp, 0);
 
7974
                        } else {
 
7975
                            tmp = load_reg(s, rm);
 
7976
                        }
 
7977
                        if (i != 32) {
 
7978
                            tmp2 = load_reg(s, rd);
 
7979
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
 
7980
                            tcg_temp_free_i32(tmp2);
 
7981
                        }
 
7982
                        store_reg(s, rd, tmp);
 
7983
                        break;
 
7984
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
 
7985
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
 
7986
                        ARCH(6T2);
 
7987
                        tmp = load_reg(s, rm);
 
7988
                        shift = (insn >> 7) & 0x1f;
 
7989
                        i = ((insn >> 16) & 0x1f) + 1;
 
7990
                        if (shift + i > 32)
 
7991
                            goto illegal_op;
 
7992
                        if (i < 32) {
 
7993
                            if (op1 & 0x20) {
 
7994
                                gen_ubfx(tmp, shift, (1u << i) - 1);
 
7995
                            } else {
 
7996
                                gen_sbfx(tmp, shift, i);
 
7997
                            }
 
7998
                        }
 
7999
                        store_reg(s, rd, tmp);
 
8000
                        break;
 
8001
                    default:
 
8002
                        goto illegal_op;
 
8003
                    }
 
8004
                    break;
 
8005
                }
 
8006
                break;
 
8007
            }
 
8008
        do_ldst:
 
8009
            /* Check for undefined extension instructions
 
8010
             * per the ARM Bible IE:
 
8011
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
 
8012
             */
 
8013
            sh = (0xf << 20) | (0xf << 4);
 
8014
            if (op1 == 0x7 && ((insn & sh) == sh))
 
8015
            {
 
8016
                goto illegal_op;
 
8017
            }
 
8018
            /* load/store byte/word */
 
8019
            rn = (insn >> 16) & 0xf;
 
8020
            rd = (insn >> 12) & 0xf;
 
8021
            tmp2 = load_reg(s, rn);
 
8022
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
 
8023
            if (insn & (1 << 24))
 
8024
                gen_add_data_offset(s, insn, tmp2);
 
8025
            if (insn & (1 << 20)) {
 
8026
                /* load */
 
8027
                tmp = tcg_temp_new_i32();
 
8028
                if (insn & (1 << 22)) {
 
8029
                    gen_aa32_ld8u(tmp, tmp2, i);
 
8030
                } else {
 
8031
                    gen_aa32_ld32u(tmp, tmp2, i);
 
8032
                }
 
8033
            } else {
 
8034
                /* store */
 
8035
                tmp = load_reg(s, rd);
 
8036
                if (insn & (1 << 22)) {
 
8037
                    gen_aa32_st8(tmp, tmp2, i);
 
8038
                } else {
 
8039
                    gen_aa32_st32(tmp, tmp2, i);
 
8040
                }
 
8041
                tcg_temp_free_i32(tmp);
 
8042
            }
 
8043
            if (!(insn & (1 << 24))) {
 
8044
                gen_add_data_offset(s, insn, tmp2);
 
8045
                store_reg(s, rn, tmp2);
 
8046
            } else if (insn & (1 << 21)) {
 
8047
                store_reg(s, rn, tmp2);
 
8048
            } else {
 
8049
                tcg_temp_free_i32(tmp2);
 
8050
            }
 
8051
            if (insn & (1 << 20)) {
 
8052
                /* Complete the load.  */
 
8053
                store_reg_from_load(env, s, rd, tmp);
 
8054
            }
 
8055
            break;
 
8056
        case 0x08:
 
8057
        case 0x09:
 
8058
            {
 
8059
                int j, n, user, loaded_base;
 
8060
                TCGv_i32 loaded_var;
 
8061
                /* load/store multiple words */
 
8062
                /* XXX: store correct base if write back */
 
8063
                user = 0;
 
8064
                if (insn & (1 << 22)) {
 
8065
                    if (IS_USER(s))
 
8066
                        goto illegal_op; /* only usable in supervisor mode */
 
8067
 
 
8068
                    if ((insn & (1 << 15)) == 0)
 
8069
                        user = 1;
 
8070
                }
 
8071
                rn = (insn >> 16) & 0xf;
 
8072
                addr = load_reg(s, rn);
 
8073
 
 
8074
                /* compute total size */
 
8075
                loaded_base = 0;
 
8076
                TCGV_UNUSED_I32(loaded_var);
 
8077
                n = 0;
 
8078
                for(i=0;i<16;i++) {
 
8079
                    if (insn & (1 << i))
 
8080
                        n++;
 
8081
                }
 
8082
                /* XXX: test invalid n == 0 case ? */
 
8083
                if (insn & (1 << 23)) {
 
8084
                    if (insn & (1 << 24)) {
 
8085
                        /* pre increment */
 
8086
                        tcg_gen_addi_i32(addr, addr, 4);
 
8087
                    } else {
 
8088
                        /* post increment */
 
8089
                    }
 
8090
                } else {
 
8091
                    if (insn & (1 << 24)) {
 
8092
                        /* pre decrement */
 
8093
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
 
8094
                    } else {
 
8095
                        /* post decrement */
 
8096
                        if (n != 1)
 
8097
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
 
8098
                    }
 
8099
                }
 
8100
                j = 0;
 
8101
                for(i=0;i<16;i++) {
 
8102
                    if (insn & (1 << i)) {
 
8103
                        if (insn & (1 << 20)) {
 
8104
                            /* load */
 
8105
                            tmp = tcg_temp_new_i32();
 
8106
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
8107
                            if (user) {
 
8108
                                tmp2 = tcg_const_i32(i);
 
8109
                                gen_helper_set_user_reg(cpu_env, tmp2, tmp);
 
8110
                                tcg_temp_free_i32(tmp2);
 
8111
                                tcg_temp_free_i32(tmp);
 
8112
                            } else if (i == rn) {
 
8113
                                loaded_var = tmp;
 
8114
                                loaded_base = 1;
 
8115
                            } else {
 
8116
                                store_reg_from_load(env, s, i, tmp);
 
8117
                            }
 
8118
                        } else {
 
8119
                            /* store */
 
8120
                            if (i == 15) {
 
8121
                                /* special case: r15 = PC + 8 */
 
8122
                                val = (long)s->pc + 4;
 
8123
                                tmp = tcg_temp_new_i32();
 
8124
                                tcg_gen_movi_i32(tmp, val);
 
8125
                            } else if (user) {
 
8126
                                tmp = tcg_temp_new_i32();
 
8127
                                tmp2 = tcg_const_i32(i);
 
8128
                                gen_helper_get_user_reg(tmp, cpu_env, tmp2);
 
8129
                                tcg_temp_free_i32(tmp2);
 
8130
                            } else {
 
8131
                                tmp = load_reg(s, i);
 
8132
                            }
 
8133
                            gen_aa32_st32(tmp, addr, IS_USER(s));
 
8134
                            tcg_temp_free_i32(tmp);
 
8135
                        }
 
8136
                        j++;
 
8137
                        /* no need to add after the last transfer */
 
8138
                        if (j != n)
 
8139
                            tcg_gen_addi_i32(addr, addr, 4);
 
8140
                    }
 
8141
                }
 
8142
                if (insn & (1 << 21)) {
 
8143
                    /* write back */
 
8144
                    if (insn & (1 << 23)) {
 
8145
                        if (insn & (1 << 24)) {
 
8146
                            /* pre increment */
 
8147
                        } else {
 
8148
                            /* post increment */
 
8149
                            tcg_gen_addi_i32(addr, addr, 4);
 
8150
                        }
 
8151
                    } else {
 
8152
                        if (insn & (1 << 24)) {
 
8153
                            /* pre decrement */
 
8154
                            if (n != 1)
 
8155
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
 
8156
                        } else {
 
8157
                            /* post decrement */
 
8158
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
 
8159
                        }
 
8160
                    }
 
8161
                    store_reg(s, rn, addr);
 
8162
                } else {
 
8163
                    tcg_temp_free_i32(addr);
 
8164
                }
 
8165
                if (loaded_base) {
 
8166
                    store_reg(s, rn, loaded_var);
 
8167
                }
 
8168
                if ((insn & (1 << 22)) && !user) {
 
8169
                    /* Restore CPSR from SPSR.  */
 
8170
                    tmp = load_cpu_field(spsr);
 
8171
                    gen_set_cpsr(tmp, 0xffffffff);
 
8172
                    tcg_temp_free_i32(tmp);
 
8173
                    s->is_jmp = DISAS_UPDATE;
 
8174
                }
 
8175
            }
 
8176
            break;
 
8177
        case 0xa:
 
8178
        case 0xb:
 
8179
            {
 
8180
                int32_t offset;
 
8181
 
 
8182
                /* branch (and link) */
 
8183
                val = (int32_t)s->pc;
 
8184
                if (insn & (1 << 24)) {
 
8185
                    tmp = tcg_temp_new_i32();
 
8186
                    tcg_gen_movi_i32(tmp, val);
 
8187
                    store_reg(s, 14, tmp);
 
8188
                }
 
8189
                offset = sextract32(insn << 2, 0, 26);
 
8190
                val += offset + 4;
 
8191
                gen_jmp(s, val);
 
8192
            }
 
8193
            break;
 
8194
        case 0xc:
 
8195
        case 0xd:
 
8196
        case 0xe:
 
8197
            if (((insn >> 8) & 0xe) == 10) {
 
8198
                /* VFP.  */
 
8199
                if (disas_vfp_insn(env, s, insn)) {
 
8200
                    goto illegal_op;
 
8201
                }
 
8202
            } else if (disas_coproc_insn(env, s, insn)) {
 
8203
                /* Coprocessor.  */
 
8204
                goto illegal_op;
 
8205
            }
 
8206
            break;
 
8207
        case 0xf:
 
8208
            /* swi */
 
8209
            gen_set_pc_im(s, s->pc);
 
8210
            s->is_jmp = DISAS_SWI;
 
8211
            break;
 
8212
        default:
 
8213
        illegal_op:
 
8214
            gen_exception_insn(s, 4, EXCP_UDEF);
 
8215
            break;
 
8216
        }
 
8217
    }
 
8218
}
 
8219
 
 
8220
/* Return true if this is a Thumb-2 logical op.  */
 
8221
static int
 
8222
thumb2_logic_op(int op)
 
8223
{
 
8224
    return (op < 8);
 
8225
}
 
8226
 
 
8227
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
 
8228
   then set condition code flags based on the result of the operation.
 
8229
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
 
8230
   to the high bit of T1.
 
8231
   Returns zero if the opcode is valid.  */
 
8232
 
 
8233
static int
 
8234
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
 
8235
                   TCGv_i32 t0, TCGv_i32 t1)
 
8236
{
 
8237
    int logic_cc;
 
8238
 
 
8239
    logic_cc = 0;
 
8240
    switch (op) {
 
8241
    case 0: /* and */
 
8242
        tcg_gen_and_i32(t0, t0, t1);
 
8243
        logic_cc = conds;
 
8244
        break;
 
8245
    case 1: /* bic */
 
8246
        tcg_gen_andc_i32(t0, t0, t1);
 
8247
        logic_cc = conds;
 
8248
        break;
 
8249
    case 2: /* orr */
 
8250
        tcg_gen_or_i32(t0, t0, t1);
 
8251
        logic_cc = conds;
 
8252
        break;
 
8253
    case 3: /* orn */
 
8254
        tcg_gen_orc_i32(t0, t0, t1);
 
8255
        logic_cc = conds;
 
8256
        break;
 
8257
    case 4: /* eor */
 
8258
        tcg_gen_xor_i32(t0, t0, t1);
 
8259
        logic_cc = conds;
 
8260
        break;
 
8261
    case 8: /* add */
 
8262
        if (conds)
 
8263
            gen_add_CC(t0, t0, t1);
 
8264
        else
 
8265
            tcg_gen_add_i32(t0, t0, t1);
 
8266
        break;
 
8267
    case 10: /* adc */
 
8268
        if (conds)
 
8269
            gen_adc_CC(t0, t0, t1);
 
8270
        else
 
8271
            gen_adc(t0, t1);
 
8272
        break;
 
8273
    case 11: /* sbc */
 
8274
        if (conds) {
 
8275
            gen_sbc_CC(t0, t0, t1);
 
8276
        } else {
 
8277
            gen_sub_carry(t0, t0, t1);
 
8278
        }
 
8279
        break;
 
8280
    case 13: /* sub */
 
8281
        if (conds)
 
8282
            gen_sub_CC(t0, t0, t1);
 
8283
        else
 
8284
            tcg_gen_sub_i32(t0, t0, t1);
 
8285
        break;
 
8286
    case 14: /* rsb */
 
8287
        if (conds)
 
8288
            gen_sub_CC(t0, t1, t0);
 
8289
        else
 
8290
            tcg_gen_sub_i32(t0, t1, t0);
 
8291
        break;
 
8292
    default: /* 5, 6, 7, 9, 12, 15. */
 
8293
        return 1;
 
8294
    }
 
8295
    if (logic_cc) {
 
8296
        gen_logic_CC(t0);
 
8297
        if (shifter_out)
 
8298
            gen_set_CF_bit31(t1);
 
8299
    }
 
8300
    return 0;
 
8301
}
 
8302
 
 
8303
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
 
8304
   is not legal.  */
 
8305
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
 
8306
{
 
8307
    uint32_t insn, imm, shift, offset;
 
8308
    uint32_t rd, rn, rm, rs;
 
8309
    TCGv_i32 tmp;
 
8310
    TCGv_i32 tmp2;
 
8311
    TCGv_i32 tmp3;
 
8312
    TCGv_i32 addr;
 
8313
    TCGv_i64 tmp64;
 
8314
    int op;
 
8315
    int shiftop;
 
8316
    int conds;
 
8317
    int logic_cc;
 
8318
 
 
8319
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
 
8320
          || arm_feature (env, ARM_FEATURE_M))) {
 
8321
        /* Thumb-1 cores may need to treat bl and blx as a pair of
 
8322
           16-bit instructions to get correct prefetch abort behavior.  */
 
8323
        insn = insn_hw1;
 
8324
        if ((insn & (1 << 12)) == 0) {
 
8325
            ARCH(5);
 
8326
            /* Second half of blx.  */
 
8327
            offset = ((insn & 0x7ff) << 1);
 
8328
            tmp = load_reg(s, 14);
 
8329
            tcg_gen_addi_i32(tmp, tmp, offset);
 
8330
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
 
8331
 
 
8332
            tmp2 = tcg_temp_new_i32();
 
8333
            tcg_gen_movi_i32(tmp2, s->pc | 1);
 
8334
            store_reg(s, 14, tmp2);
 
8335
            gen_bx(s, tmp);
 
8336
            return 0;
 
8337
        }
 
8338
        if (insn & (1 << 11)) {
 
8339
            /* Second half of bl.  */
 
8340
            offset = ((insn & 0x7ff) << 1) | 1;
 
8341
            tmp = load_reg(s, 14);
 
8342
            tcg_gen_addi_i32(tmp, tmp, offset);
 
8343
 
 
8344
            tmp2 = tcg_temp_new_i32();
 
8345
            tcg_gen_movi_i32(tmp2, s->pc | 1);
 
8346
            store_reg(s, 14, tmp2);
 
8347
            gen_bx(s, tmp);
 
8348
            return 0;
 
8349
        }
 
8350
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
 
8351
            /* Instruction spans a page boundary.  Implement it as two
 
8352
               16-bit instructions in case the second half causes an
 
8353
               prefetch abort.  */
 
8354
            offset = ((int32_t)insn << 21) >> 9;
 
8355
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
 
8356
            return 0;
 
8357
        }
 
8358
        /* Fall through to 32-bit decode.  */
 
8359
    }
 
8360
 
 
8361
    insn = arm_lduw_code(env, s->pc, s->bswap_code);
 
8362
    s->pc += 2;
 
8363
    insn |= (uint32_t)insn_hw1 << 16;
 
8364
 
 
8365
    if ((insn & 0xf800e800) != 0xf000e800) {
 
8366
        ARCH(6T2);
 
8367
    }
 
8368
 
 
8369
    rn = (insn >> 16) & 0xf;
 
8370
    rs = (insn >> 12) & 0xf;
 
8371
    rd = (insn >> 8) & 0xf;
 
8372
    rm = insn & 0xf;
 
8373
    switch ((insn >> 25) & 0xf) {
 
8374
    case 0: case 1: case 2: case 3:
 
8375
        /* 16-bit instructions.  Should never happen.  */
 
8376
        abort();
 
8377
    case 4:
 
8378
        if (insn & (1 << 22)) {
 
8379
            /* Other load/store, table branch.  */
 
8380
            if (insn & 0x01200000) {
 
8381
                /* Load/store doubleword.  */
 
8382
                if (rn == 15) {
 
8383
                    addr = tcg_temp_new_i32();
 
8384
                    tcg_gen_movi_i32(addr, s->pc & ~3);
 
8385
                } else {
 
8386
                    addr = load_reg(s, rn);
 
8387
                }
 
8388
                offset = (insn & 0xff) * 4;
 
8389
                if ((insn & (1 << 23)) == 0)
 
8390
                    offset = -offset;
 
8391
                if (insn & (1 << 24)) {
 
8392
                    tcg_gen_addi_i32(addr, addr, offset);
 
8393
                    offset = 0;
 
8394
                }
 
8395
                if (insn & (1 << 20)) {
 
8396
                    /* ldrd */
 
8397
                    tmp = tcg_temp_new_i32();
 
8398
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
8399
                    store_reg(s, rs, tmp);
 
8400
                    tcg_gen_addi_i32(addr, addr, 4);
 
8401
                    tmp = tcg_temp_new_i32();
 
8402
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
8403
                    store_reg(s, rd, tmp);
 
8404
                } else {
 
8405
                    /* strd */
 
8406
                    tmp = load_reg(s, rs);
 
8407
                    gen_aa32_st32(tmp, addr, IS_USER(s));
 
8408
                    tcg_temp_free_i32(tmp);
 
8409
                    tcg_gen_addi_i32(addr, addr, 4);
 
8410
                    tmp = load_reg(s, rd);
 
8411
                    gen_aa32_st32(tmp, addr, IS_USER(s));
 
8412
                    tcg_temp_free_i32(tmp);
 
8413
                }
 
8414
                if (insn & (1 << 21)) {
 
8415
                    /* Base writeback.  */
 
8416
                    if (rn == 15)
 
8417
                        goto illegal_op;
 
8418
                    tcg_gen_addi_i32(addr, addr, offset - 4);
 
8419
                    store_reg(s, rn, addr);
 
8420
                } else {
 
8421
                    tcg_temp_free_i32(addr);
 
8422
                }
 
8423
            } else if ((insn & (1 << 23)) == 0) {
 
8424
                /* Load/store exclusive word.  */
 
8425
                addr = tcg_temp_local_new_i32();
 
8426
                load_reg_var(s, addr, rn);
 
8427
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
 
8428
                if (insn & (1 << 20)) {
 
8429
                    gen_load_exclusive(s, rs, 15, addr, 2);
 
8430
                } else {
 
8431
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
 
8432
                }
 
8433
                tcg_temp_free_i32(addr);
 
8434
            } else if ((insn & (7 << 5)) == 0) {
 
8435
                /* Table Branch.  */
 
8436
                if (rn == 15) {
 
8437
                    addr = tcg_temp_new_i32();
 
8438
                    tcg_gen_movi_i32(addr, s->pc);
 
8439
                } else {
 
8440
                    addr = load_reg(s, rn);
 
8441
                }
 
8442
                tmp = load_reg(s, rm);
 
8443
                tcg_gen_add_i32(addr, addr, tmp);
 
8444
                if (insn & (1 << 4)) {
 
8445
                    /* tbh */
 
8446
                    tcg_gen_add_i32(addr, addr, tmp);
 
8447
                    tcg_temp_free_i32(tmp);
 
8448
                    tmp = tcg_temp_new_i32();
 
8449
                    gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
8450
                } else { /* tbb */
 
8451
                    tcg_temp_free_i32(tmp);
 
8452
                    tmp = tcg_temp_new_i32();
 
8453
                    gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
8454
                }
 
8455
                tcg_temp_free_i32(addr);
 
8456
                tcg_gen_shli_i32(tmp, tmp, 1);
 
8457
                tcg_gen_addi_i32(tmp, tmp, s->pc);
 
8458
                store_reg(s, 15, tmp);
 
8459
            } else {
 
8460
                int op2 = (insn >> 6) & 0x3;
 
8461
                op = (insn >> 4) & 0x3;
 
8462
                switch (op2) {
 
8463
                case 0:
 
8464
                    goto illegal_op;
 
8465
                case 1:
 
8466
                    /* Load/store exclusive byte/halfword/doubleword */
 
8467
                    if (op == 2) {
 
8468
                        goto illegal_op;
 
8469
                    }
 
8470
                    ARCH(7);
 
8471
                    break;
 
8472
                case 2:
 
8473
                    /* Load-acquire/store-release */
 
8474
                    if (op == 3) {
 
8475
                        goto illegal_op;
 
8476
                    }
 
8477
                    /* Fall through */
 
8478
                case 3:
 
8479
                    /* Load-acquire/store-release exclusive */
 
8480
                    ARCH(8);
 
8481
                    break;
 
8482
                }
 
8483
                addr = tcg_temp_local_new_i32();
 
8484
                load_reg_var(s, addr, rn);
 
8485
                if (!(op2 & 1)) {
 
8486
                    if (insn & (1 << 20)) {
 
8487
                        tmp = tcg_temp_new_i32();
 
8488
                        switch (op) {
 
8489
                        case 0: /* ldab */
 
8490
                            gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
8491
                            break;
 
8492
                        case 1: /* ldah */
 
8493
                            gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
8494
                            break;
 
8495
                        case 2: /* lda */
 
8496
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
8497
                            break;
 
8498
                        default:
 
8499
                            abort();
 
8500
                        }
 
8501
                        store_reg(s, rs, tmp);
 
8502
                    } else {
 
8503
                        tmp = load_reg(s, rs);
 
8504
                        switch (op) {
 
8505
                        case 0: /* stlb */
 
8506
                            gen_aa32_st8(tmp, addr, IS_USER(s));
 
8507
                            break;
 
8508
                        case 1: /* stlh */
 
8509
                            gen_aa32_st16(tmp, addr, IS_USER(s));
 
8510
                            break;
 
8511
                        case 2: /* stl */
 
8512
                            gen_aa32_st32(tmp, addr, IS_USER(s));
 
8513
                            break;
 
8514
                        default:
 
8515
                            abort();
 
8516
                        }
 
8517
                        tcg_temp_free_i32(tmp);
 
8518
                    }
 
8519
                } else if (insn & (1 << 20)) {
 
8520
                    gen_load_exclusive(s, rs, rd, addr, op);
 
8521
                } else {
 
8522
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
 
8523
                }
 
8524
                tcg_temp_free_i32(addr);
 
8525
            }
 
8526
        } else {
 
8527
            /* Load/store multiple, RFE, SRS.  */
 
8528
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
 
8529
                /* RFE, SRS: not available in user mode or on M profile */
 
8530
                if (IS_USER(s) || IS_M(env)) {
 
8531
                    goto illegal_op;
 
8532
                }
 
8533
                if (insn & (1 << 20)) {
 
8534
                    /* rfe */
 
8535
                    addr = load_reg(s, rn);
 
8536
                    if ((insn & (1 << 24)) == 0)
 
8537
                        tcg_gen_addi_i32(addr, addr, -8);
 
8538
                    /* Load PC into tmp and CPSR into tmp2.  */
 
8539
                    tmp = tcg_temp_new_i32();
 
8540
                    gen_aa32_ld32u(tmp, addr, 0);
 
8541
                    tcg_gen_addi_i32(addr, addr, 4);
 
8542
                    tmp2 = tcg_temp_new_i32();
 
8543
                    gen_aa32_ld32u(tmp2, addr, 0);
 
8544
                    if (insn & (1 << 21)) {
 
8545
                        /* Base writeback.  */
 
8546
                        if (insn & (1 << 24)) {
 
8547
                            tcg_gen_addi_i32(addr, addr, 4);
 
8548
                        } else {
 
8549
                            tcg_gen_addi_i32(addr, addr, -4);
 
8550
                        }
 
8551
                        store_reg(s, rn, addr);
 
8552
                    } else {
 
8553
                        tcg_temp_free_i32(addr);
 
8554
                    }
 
8555
                    gen_rfe(s, tmp, tmp2);
 
8556
                } else {
 
8557
                    /* srs */
 
8558
                    gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
 
8559
                            insn & (1 << 21));
 
8560
                }
 
8561
            } else {
 
8562
                int i, loaded_base = 0;
 
8563
                TCGv_i32 loaded_var;
 
8564
                /* Load/store multiple.  */
 
8565
                addr = load_reg(s, rn);
 
8566
                offset = 0;
 
8567
                for (i = 0; i < 16; i++) {
 
8568
                    if (insn & (1 << i))
 
8569
                        offset += 4;
 
8570
                }
 
8571
                if (insn & (1 << 24)) {
 
8572
                    tcg_gen_addi_i32(addr, addr, -offset);
 
8573
                }
 
8574
 
 
8575
                TCGV_UNUSED_I32(loaded_var);
 
8576
                for (i = 0; i < 16; i++) {
 
8577
                    if ((insn & (1 << i)) == 0)
 
8578
                        continue;
 
8579
                    if (insn & (1 << 20)) {
 
8580
                        /* Load.  */
 
8581
                        tmp = tcg_temp_new_i32();
 
8582
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
8583
                        if (i == 15) {
 
8584
                            gen_bx(s, tmp);
 
8585
                        } else if (i == rn) {
 
8586
                            loaded_var = tmp;
 
8587
                            loaded_base = 1;
 
8588
                        } else {
 
8589
                            store_reg(s, i, tmp);
 
8590
                        }
 
8591
                    } else {
 
8592
                        /* Store.  */
 
8593
                        tmp = load_reg(s, i);
 
8594
                        gen_aa32_st32(tmp, addr, IS_USER(s));
 
8595
                        tcg_temp_free_i32(tmp);
 
8596
                    }
 
8597
                    tcg_gen_addi_i32(addr, addr, 4);
 
8598
                }
 
8599
                if (loaded_base) {
 
8600
                    store_reg(s, rn, loaded_var);
 
8601
                }
 
8602
                if (insn & (1 << 21)) {
 
8603
                    /* Base register writeback.  */
 
8604
                    if (insn & (1 << 24)) {
 
8605
                        tcg_gen_addi_i32(addr, addr, -offset);
 
8606
                    }
 
8607
                    /* Fault if writeback register is in register list.  */
 
8608
                    if (insn & (1 << rn))
 
8609
                        goto illegal_op;
 
8610
                    store_reg(s, rn, addr);
 
8611
                } else {
 
8612
                    tcg_temp_free_i32(addr);
 
8613
                }
 
8614
            }
 
8615
        }
 
8616
        break;
 
8617
    case 5:
 
8618
 
 
8619
        op = (insn >> 21) & 0xf;
 
8620
        if (op == 6) {
 
8621
            /* Halfword pack.  */
 
8622
            tmp = load_reg(s, rn);
 
8623
            tmp2 = load_reg(s, rm);
 
8624
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
 
8625
            if (insn & (1 << 5)) {
 
8626
                /* pkhtb */
 
8627
                if (shift == 0)
 
8628
                    shift = 31;
 
8629
                tcg_gen_sari_i32(tmp2, tmp2, shift);
 
8630
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
 
8631
                tcg_gen_ext16u_i32(tmp2, tmp2);
 
8632
            } else {
 
8633
                /* pkhbt */
 
8634
                if (shift)
 
8635
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
 
8636
                tcg_gen_ext16u_i32(tmp, tmp);
 
8637
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
 
8638
            }
 
8639
            tcg_gen_or_i32(tmp, tmp, tmp2);
 
8640
            tcg_temp_free_i32(tmp2);
 
8641
            store_reg(s, rd, tmp);
 
8642
        } else {
 
8643
            /* Data processing register constant shift.  */
 
8644
            if (rn == 15) {
 
8645
                tmp = tcg_temp_new_i32();
 
8646
                tcg_gen_movi_i32(tmp, 0);
 
8647
            } else {
 
8648
                tmp = load_reg(s, rn);
 
8649
            }
 
8650
            tmp2 = load_reg(s, rm);
 
8651
 
 
8652
            shiftop = (insn >> 4) & 3;
 
8653
            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
 
8654
            conds = (insn & (1 << 20)) != 0;
 
8655
            logic_cc = (conds && thumb2_logic_op(op));
 
8656
            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
 
8657
            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
 
8658
                goto illegal_op;
 
8659
            tcg_temp_free_i32(tmp2);
 
8660
            if (rd != 15) {
 
8661
                store_reg(s, rd, tmp);
 
8662
            } else {
 
8663
                tcg_temp_free_i32(tmp);
 
8664
            }
 
8665
        }
 
8666
        break;
 
8667
    case 13: /* Misc data processing.  */
 
8668
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
 
8669
        if (op < 4 && (insn & 0xf000) != 0xf000)
 
8670
            goto illegal_op;
 
8671
        switch (op) {
 
8672
        case 0: /* Register controlled shift.  */
 
8673
            tmp = load_reg(s, rn);
 
8674
            tmp2 = load_reg(s, rm);
 
8675
            if ((insn & 0x70) != 0)
 
8676
                goto illegal_op;
 
8677
            op = (insn >> 21) & 3;
 
8678
            logic_cc = (insn & (1 << 20)) != 0;
 
8679
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
 
8680
            if (logic_cc)
 
8681
                gen_logic_CC(tmp);
 
8682
            store_reg_bx(env, s, rd, tmp);
 
8683
            break;
 
8684
        case 1: /* Sign/zero extend.  */
 
8685
            tmp = load_reg(s, rm);
 
8686
            shift = (insn >> 4) & 3;
 
8687
            /* ??? In many cases it's not necessary to do a
 
8688
               rotate, a shift is sufficient.  */
 
8689
            if (shift != 0)
 
8690
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
 
8691
            op = (insn >> 20) & 7;
 
8692
            switch (op) {
 
8693
            case 0: gen_sxth(tmp);   break;
 
8694
            case 1: gen_uxth(tmp);   break;
 
8695
            case 2: gen_sxtb16(tmp); break;
 
8696
            case 3: gen_uxtb16(tmp); break;
 
8697
            case 4: gen_sxtb(tmp);   break;
 
8698
            case 5: gen_uxtb(tmp);   break;
 
8699
            default: goto illegal_op;
 
8700
            }
 
8701
            if (rn != 15) {
 
8702
                tmp2 = load_reg(s, rn);
 
8703
                if ((op >> 1) == 1) {
 
8704
                    gen_add16(tmp, tmp2);
 
8705
                } else {
 
8706
                    tcg_gen_add_i32(tmp, tmp, tmp2);
 
8707
                    tcg_temp_free_i32(tmp2);
 
8708
                }
 
8709
            }
 
8710
            store_reg(s, rd, tmp);
 
8711
            break;
 
8712
        case 2: /* SIMD add/subtract.  */
 
8713
            op = (insn >> 20) & 7;
 
8714
            shift = (insn >> 4) & 7;
 
8715
            if ((op & 3) == 3 || (shift & 3) == 3)
 
8716
                goto illegal_op;
 
8717
            tmp = load_reg(s, rn);
 
8718
            tmp2 = load_reg(s, rm);
 
8719
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
 
8720
            tcg_temp_free_i32(tmp2);
 
8721
            store_reg(s, rd, tmp);
 
8722
            break;
 
8723
        case 3: /* Other data processing.  */
 
8724
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
 
8725
            if (op < 4) {
 
8726
                /* Saturating add/subtract.  */
 
8727
                tmp = load_reg(s, rn);
 
8728
                tmp2 = load_reg(s, rm);
 
8729
                if (op & 1)
 
8730
                    gen_helper_double_saturate(tmp, cpu_env, tmp);
 
8731
                if (op & 2)
 
8732
                    gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
 
8733
                else
 
8734
                    gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
 
8735
                tcg_temp_free_i32(tmp2);
 
8736
            } else {
 
8737
                tmp = load_reg(s, rn);
 
8738
                switch (op) {
 
8739
                case 0x0a: /* rbit */
 
8740
                    gen_helper_rbit(tmp, tmp);
 
8741
                    break;
 
8742
                case 0x08: /* rev */
 
8743
                    tcg_gen_bswap32_i32(tmp, tmp);
 
8744
                    break;
 
8745
                case 0x09: /* rev16 */
 
8746
                    gen_rev16(tmp);
 
8747
                    break;
 
8748
                case 0x0b: /* revsh */
 
8749
                    gen_revsh(tmp);
 
8750
                    break;
 
8751
                case 0x10: /* sel */
 
8752
                    tmp2 = load_reg(s, rm);
 
8753
                    tmp3 = tcg_temp_new_i32();
 
8754
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
 
8755
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
 
8756
                    tcg_temp_free_i32(tmp3);
 
8757
                    tcg_temp_free_i32(tmp2);
 
8758
                    break;
 
8759
                case 0x18: /* clz */
 
8760
                    gen_helper_clz(tmp, tmp);
 
8761
                    break;
 
8762
                default:
 
8763
                    goto illegal_op;
 
8764
                }
 
8765
            }
 
8766
            store_reg(s, rd, tmp);
 
8767
            break;
 
8768
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
 
8769
            op = (insn >> 4) & 0xf;
 
8770
            tmp = load_reg(s, rn);
 
8771
            tmp2 = load_reg(s, rm);
 
8772
            switch ((insn >> 20) & 7) {
 
8773
            case 0: /* 32 x 32 -> 32 */
 
8774
                tcg_gen_mul_i32(tmp, tmp, tmp2);
 
8775
                tcg_temp_free_i32(tmp2);
 
8776
                if (rs != 15) {
 
8777
                    tmp2 = load_reg(s, rs);
 
8778
                    if (op)
 
8779
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
 
8780
                    else
 
8781
                        tcg_gen_add_i32(tmp, tmp, tmp2);
 
8782
                    tcg_temp_free_i32(tmp2);
 
8783
                }
 
8784
                break;
 
8785
            case 1: /* 16 x 16 -> 32 */
 
8786
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
 
8787
                tcg_temp_free_i32(tmp2);
 
8788
                if (rs != 15) {
 
8789
                    tmp2 = load_reg(s, rs);
 
8790
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 
8791
                    tcg_temp_free_i32(tmp2);
 
8792
                }
 
8793
                break;
 
8794
            case 2: /* Dual multiply add.  */
 
8795
            case 4: /* Dual multiply subtract.  */
 
8796
                if (op)
 
8797
                    gen_swap_half(tmp2);
 
8798
                gen_smul_dual(tmp, tmp2);
 
8799
                if (insn & (1 << 22)) {
 
8800
                    /* This subtraction cannot overflow. */
 
8801
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
 
8802
                } else {
 
8803
                    /* This addition cannot overflow 32 bits;
 
8804
                     * however it may overflow considered as a signed
 
8805
                     * operation, in which case we must set the Q flag.
 
8806
                     */
 
8807
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 
8808
                }
 
8809
                tcg_temp_free_i32(tmp2);
 
8810
                if (rs != 15)
 
8811
                  {
 
8812
                    tmp2 = load_reg(s, rs);
 
8813
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 
8814
                    tcg_temp_free_i32(tmp2);
 
8815
                  }
 
8816
                break;
 
8817
            case 3: /* 32 * 16 -> 32msb */
 
8818
                if (op)
 
8819
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
 
8820
                else
 
8821
                    gen_sxth(tmp2);
 
8822
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
 
8823
                tcg_gen_shri_i64(tmp64, tmp64, 16);
 
8824
                tmp = tcg_temp_new_i32();
 
8825
                tcg_gen_trunc_i64_i32(tmp, tmp64);
 
8826
                tcg_temp_free_i64(tmp64);
 
8827
                if (rs != 15)
 
8828
                  {
 
8829
                    tmp2 = load_reg(s, rs);
 
8830
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
 
8831
                    tcg_temp_free_i32(tmp2);
 
8832
                  }
 
8833
                break;
 
8834
            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
 
8835
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
 
8836
                if (rs != 15) {
 
8837
                    tmp = load_reg(s, rs);
 
8838
                    if (insn & (1 << 20)) {
 
8839
                        tmp64 = gen_addq_msw(tmp64, tmp);
 
8840
                    } else {
 
8841
                        tmp64 = gen_subq_msw(tmp64, tmp);
 
8842
                    }
 
8843
                }
 
8844
                if (insn & (1 << 4)) {
 
8845
                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
 
8846
                }
 
8847
                tcg_gen_shri_i64(tmp64, tmp64, 32);
 
8848
                tmp = tcg_temp_new_i32();
 
8849
                tcg_gen_trunc_i64_i32(tmp, tmp64);
 
8850
                tcg_temp_free_i64(tmp64);
 
8851
                break;
 
8852
            case 7: /* Unsigned sum of absolute differences.  */
 
8853
                gen_helper_usad8(tmp, tmp, tmp2);
 
8854
                tcg_temp_free_i32(tmp2);
 
8855
                if (rs != 15) {
 
8856
                    tmp2 = load_reg(s, rs);
 
8857
                    tcg_gen_add_i32(tmp, tmp, tmp2);
 
8858
                    tcg_temp_free_i32(tmp2);
 
8859
                }
 
8860
                break;
 
8861
            }
 
8862
            store_reg(s, rd, tmp);
 
8863
            break;
 
8864
        case 6: case 7: /* 64-bit multiply, Divide.  */
 
8865
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
 
8866
            tmp = load_reg(s, rn);
 
8867
            tmp2 = load_reg(s, rm);
 
8868
            if ((op & 0x50) == 0x10) {
 
8869
                /* sdiv, udiv */
 
8870
                if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
 
8871
                    goto illegal_op;
 
8872
                }
 
8873
                if (op & 0x20)
 
8874
                    gen_helper_udiv(tmp, tmp, tmp2);
 
8875
                else
 
8876
                    gen_helper_sdiv(tmp, tmp, tmp2);
 
8877
                tcg_temp_free_i32(tmp2);
 
8878
                store_reg(s, rd, tmp);
 
8879
            } else if ((op & 0xe) == 0xc) {
 
8880
                /* Dual multiply accumulate long.  */
 
8881
                if (op & 1)
 
8882
                    gen_swap_half(tmp2);
 
8883
                gen_smul_dual(tmp, tmp2);
 
8884
                if (op & 0x10) {
 
8885
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
 
8886
                } else {
 
8887
                    tcg_gen_add_i32(tmp, tmp, tmp2);
 
8888
                }
 
8889
                tcg_temp_free_i32(tmp2);
 
8890
                /* BUGFIX */
 
8891
                tmp64 = tcg_temp_new_i64();
 
8892
                tcg_gen_ext_i32_i64(tmp64, tmp);
 
8893
                tcg_temp_free_i32(tmp);
 
8894
                gen_addq(s, tmp64, rs, rd);
 
8895
                gen_storeq_reg(s, rs, rd, tmp64);
 
8896
                tcg_temp_free_i64(tmp64);
 
8897
            } else {
 
8898
                if (op & 0x20) {
 
8899
                    /* Unsigned 64-bit multiply  */
 
8900
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
 
8901
                } else {
 
8902
                    if (op & 8) {
 
8903
                        /* smlalxy */
 
8904
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
 
8905
                        tcg_temp_free_i32(tmp2);
 
8906
                        tmp64 = tcg_temp_new_i64();
 
8907
                        tcg_gen_ext_i32_i64(tmp64, tmp);
 
8908
                        tcg_temp_free_i32(tmp);
 
8909
                    } else {
 
8910
                        /* Signed 64-bit multiply  */
 
8911
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
 
8912
                    }
 
8913
                }
 
8914
                if (op & 4) {
 
8915
                    /* umaal */
 
8916
                    gen_addq_lo(s, tmp64, rs);
 
8917
                    gen_addq_lo(s, tmp64, rd);
 
8918
                } else if (op & 0x40) {
 
8919
                    /* 64-bit accumulate.  */
 
8920
                    gen_addq(s, tmp64, rs, rd);
 
8921
                }
 
8922
                gen_storeq_reg(s, rs, rd, tmp64);
 
8923
                tcg_temp_free_i64(tmp64);
 
8924
            }
 
8925
            break;
 
8926
        }
 
8927
        break;
 
8928
    case 6: case 7: case 14: case 15:
 
8929
        /* Coprocessor.  */
 
8930
        if (((insn >> 24) & 3) == 3) {
 
8931
            /* Translate into the equivalent ARM encoding.  */
 
8932
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
 
8933
            if (disas_neon_data_insn(env, s, insn))
 
8934
                goto illegal_op;
 
8935
        } else if (((insn >> 8) & 0xe) == 10) {
 
8936
            if (disas_vfp_insn(env, s, insn)) {
 
8937
                goto illegal_op;
 
8938
            }
 
8939
        } else {
 
8940
            if (insn & (1 << 28))
 
8941
                goto illegal_op;
 
8942
            if (disas_coproc_insn (env, s, insn))
 
8943
                goto illegal_op;
 
8944
        }
 
8945
        break;
 
8946
    case 8: case 9: case 10: case 11:
 
8947
        if (insn & (1 << 15)) {
 
8948
            /* Branches, misc control.  */
 
8949
            if (insn & 0x5000) {
 
8950
                /* Unconditional branch.  */
 
8951
                /* signextend(hw1[10:0]) -> offset[:12].  */
 
8952
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
 
8953
                /* hw1[10:0] -> offset[11:1].  */
 
8954
                offset |= (insn & 0x7ff) << 1;
 
8955
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
 
8956
                   offset[24:22] already have the same value because of the
 
8957
                   sign extension above.  */
 
8958
                offset ^= ((~insn) & (1 << 13)) << 10;
 
8959
                offset ^= ((~insn) & (1 << 11)) << 11;
 
8960
 
 
8961
                if (insn & (1 << 14)) {
 
8962
                    /* Branch and link.  */
 
8963
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
 
8964
                }
 
8965
 
 
8966
                offset += s->pc;
 
8967
                if (insn & (1 << 12)) {
 
8968
                    /* b/bl */
 
8969
                    gen_jmp(s, offset);
 
8970
                } else {
 
8971
                    /* blx */
 
8972
                    offset &= ~(uint32_t)2;
 
8973
                    /* thumb2 bx, no need to check */
 
8974
                    gen_bx_im(s, offset);
 
8975
                }
 
8976
            } else if (((insn >> 23) & 7) == 7) {
 
8977
                /* Misc control */
 
8978
                if (insn & (1 << 13))
 
8979
                    goto illegal_op;
 
8980
 
 
8981
                if (insn & (1 << 26)) {
 
8982
                    /* Secure monitor call / smc (v6Z) */
 
8983
                    if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
 
8984
                        || IS_USER(s)) {
 
8985
                        goto illegal_op;
 
8986
                    }
 
8987
                    gen_smc(env, s);
 
8988
                } else {
 
8989
                    op = (insn >> 20) & 7;
 
8990
                    switch (op) {
 
8991
                    case 0: /* msr cpsr.  */
 
8992
                        if (IS_M(env)) {
 
8993
                            tmp = load_reg(s, rn);
 
8994
                            addr = tcg_const_i32(insn & 0xff);
 
8995
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
 
8996
                            tcg_temp_free_i32(addr);
 
8997
                            tcg_temp_free_i32(tmp);
 
8998
                            gen_lookup_tb(s);
 
8999
                            break;
 
9000
                        }
 
9001
                        /* fall through */
 
9002
                    case 1: /* msr spsr.  */
 
9003
                        if (IS_M(env))
 
9004
                            goto illegal_op;
 
9005
                        tmp = load_reg(s, rn);
 
9006
                        if (gen_set_psr(s,
 
9007
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
 
9008
                              op == 1, tmp))
 
9009
                            goto illegal_op;
 
9010
                        break;
 
9011
                    case 2: /* cps, nop-hint.  */
 
9012
                        if (((insn >> 8) & 7) == 0) {
 
9013
                            gen_nop_hint(s, insn & 0xff);
 
9014
                        }
 
9015
                        /* Implemented as NOP in user mode.  */
 
9016
                        if (IS_USER(s))
 
9017
                            break;
 
9018
                        offset = 0;
 
9019
                        imm = 0;
 
9020
                        if (insn & (1 << 10)) {
 
9021
                            if (insn & (1 << 7))
 
9022
                                offset |= CPSR_A;
 
9023
                            if (insn & (1 << 6))
 
9024
                                offset |= CPSR_I;
 
9025
                            if (insn & (1 << 5))
 
9026
                                offset |= CPSR_F;
 
9027
                            if (insn & (1 << 9))
 
9028
                                imm = CPSR_A | CPSR_I | CPSR_F;
 
9029
                        }
 
9030
                        if (insn & (1 << 8)) {
 
9031
                            offset |= 0x1f;
 
9032
                            imm |= (insn & 0x1f);
 
9033
                        }
 
9034
                        if (offset) {
 
9035
                            gen_set_psr_im(s, offset, 0, imm);
 
9036
                        }
 
9037
                        break;
 
9038
                    case 3: /* Special control operations.  */
 
9039
                        ARCH(7);
 
9040
                        op = (insn >> 4) & 0xf;
 
9041
                        switch (op) {
 
9042
                        case 2: /* clrex */
 
9043
                            gen_clrex(s);
 
9044
                            break;
 
9045
                        case 4: /* dsb */
 
9046
                        case 5: /* dmb */
 
9047
                        case 6: /* isb */
 
9048
                            /* These execute as NOPs.  */
 
9049
                            break;
 
9050
                        default:
 
9051
                            goto illegal_op;
 
9052
                        }
 
9053
                        break;
 
9054
                    case 4: /* bxj */
 
9055
                        /* Trivial implementation equivalent to bx.  */
 
9056
                        tmp = load_reg(s, rn);
 
9057
                        gen_bx(s, tmp);
 
9058
                        break;
 
9059
                    case 5: /* Exception return.  */
 
9060
                        if (IS_USER(s)) {
 
9061
                            goto illegal_op;
 
9062
                        }
 
9063
                        if (rn != 14 || rd != 15) {
 
9064
                            goto illegal_op;
 
9065
                        }
 
9066
                        tmp = load_reg(s, rn);
 
9067
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
 
9068
                        gen_exception_return(s, tmp);
 
9069
                        break;
 
9070
                    case 6: /* mrs cpsr.  */
 
9071
                        tmp = tcg_temp_new_i32();
 
9072
                        if (IS_M(env)) {
 
9073
                            addr = tcg_const_i32(insn & 0xff);
 
9074
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
 
9075
                            tcg_temp_free_i32(addr);
 
9076
                        } else {
 
9077
                            gen_helper_cpsr_read(tmp, cpu_env);
 
9078
                        }
 
9079
                        store_reg(s, rd, tmp);
 
9080
                        break;
 
9081
                    case 7: /* mrs spsr.  */
 
9082
                        /* Not accessible in user mode.  */
 
9083
                        if (IS_USER(s) || IS_M(env))
 
9084
                            goto illegal_op;
 
9085
                        tmp = load_cpu_field(spsr);
 
9086
                        store_reg(s, rd, tmp);
 
9087
                        break;
 
9088
                    }
 
9089
                }
 
9090
            } else {
 
9091
                /* Conditional branch.  */
 
9092
                op = (insn >> 22) & 0xf;
 
9093
                /* Generate a conditional jump to next instruction.  */
 
9094
                s->condlabel = gen_new_label();
 
9095
                gen_test_cc(op ^ 1, s->condlabel);
 
9096
                s->condjmp = 1;
 
9097
 
 
9098
                /* offset[11:1] = insn[10:0] */
 
9099
                offset = (insn & 0x7ff) << 1;
 
9100
                /* offset[17:12] = insn[21:16].  */
 
9101
                offset |= (insn & 0x003f0000) >> 4;
 
9102
                /* offset[31:20] = insn[26].  */
 
9103
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
 
9104
                /* offset[18] = insn[13].  */
 
9105
                offset |= (insn & (1 << 13)) << 5;
 
9106
                /* offset[19] = insn[11].  */
 
9107
                offset |= (insn & (1 << 11)) << 8;
 
9108
 
 
9109
                /* jump to the offset */
 
9110
                gen_jmp(s, s->pc + offset);
 
9111
            }
 
9112
        } else {
 
9113
            /* Data processing immediate.  */
 
9114
            if (insn & (1 << 25)) {
 
9115
                if (insn & (1 << 24)) {
 
9116
                    if (insn & (1 << 20))
 
9117
                        goto illegal_op;
 
9118
                    /* Bitfield/Saturate.  */
 
9119
                    op = (insn >> 21) & 7;
 
9120
                    imm = insn & 0x1f;
 
9121
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
 
9122
                    if (rn == 15) {
 
9123
                        tmp = tcg_temp_new_i32();
 
9124
                        tcg_gen_movi_i32(tmp, 0);
 
9125
                    } else {
 
9126
                        tmp = load_reg(s, rn);
 
9127
                    }
 
9128
                    switch (op) {
 
9129
                    case 2: /* Signed bitfield extract.  */
 
9130
                        imm++;
 
9131
                        if (shift + imm > 32)
 
9132
                            goto illegal_op;
 
9133
                        if (imm < 32)
 
9134
                            gen_sbfx(tmp, shift, imm);
 
9135
                        break;
 
9136
                    case 6: /* Unsigned bitfield extract.  */
 
9137
                        imm++;
 
9138
                        if (shift + imm > 32)
 
9139
                            goto illegal_op;
 
9140
                        if (imm < 32)
 
9141
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
 
9142
                        break;
 
9143
                    case 3: /* Bitfield insert/clear.  */
 
9144
                        if (imm < shift)
 
9145
                            goto illegal_op;
 
9146
                        imm = imm + 1 - shift;
 
9147
                        if (imm != 32) {
 
9148
                            tmp2 = load_reg(s, rd);
 
9149
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
 
9150
                            tcg_temp_free_i32(tmp2);
 
9151
                        }
 
9152
                        break;
 
9153
                    case 7:
 
9154
                        goto illegal_op;
 
9155
                    default: /* Saturate.  */
 
9156
                        if (shift) {
 
9157
                            if (op & 1)
 
9158
                                tcg_gen_sari_i32(tmp, tmp, shift);
 
9159
                            else
 
9160
                                tcg_gen_shli_i32(tmp, tmp, shift);
 
9161
                        }
 
9162
                        tmp2 = tcg_const_i32(imm);
 
9163
                        if (op & 4) {
 
9164
                            /* Unsigned.  */
 
9165
                            if ((op & 1) && shift == 0)
 
9166
                                gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
 
9167
                            else
 
9168
                                gen_helper_usat(tmp, cpu_env, tmp, tmp2);
 
9169
                        } else {
 
9170
                            /* Signed.  */
 
9171
                            if ((op & 1) && shift == 0)
 
9172
                                gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
 
9173
                            else
 
9174
                                gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
 
9175
                        }
 
9176
                        tcg_temp_free_i32(tmp2);
 
9177
                        break;
 
9178
                    }
 
9179
                    store_reg(s, rd, tmp);
 
9180
                } else {
 
9181
                    imm = ((insn & 0x04000000) >> 15)
 
9182
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
 
9183
                    if (insn & (1 << 22)) {
 
9184
                        /* 16-bit immediate.  */
 
9185
                        imm |= (insn >> 4) & 0xf000;
 
9186
                        if (insn & (1 << 23)) {
 
9187
                            /* movt */
 
9188
                            tmp = load_reg(s, rd);
 
9189
                            tcg_gen_ext16u_i32(tmp, tmp);
 
9190
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
 
9191
                        } else {
 
9192
                            /* movw */
 
9193
                            tmp = tcg_temp_new_i32();
 
9194
                            tcg_gen_movi_i32(tmp, imm);
 
9195
                        }
 
9196
                    } else {
 
9197
                        /* Add/sub 12-bit immediate.  */
 
9198
                        if (rn == 15) {
 
9199
                            offset = s->pc & ~(uint32_t)3;
 
9200
                            if (insn & (1 << 23))
 
9201
                                offset -= imm;
 
9202
                            else
 
9203
                                offset += imm;
 
9204
                            tmp = tcg_temp_new_i32();
 
9205
                            tcg_gen_movi_i32(tmp, offset);
 
9206
                        } else {
 
9207
                            tmp = load_reg(s, rn);
 
9208
                            if (insn & (1 << 23))
 
9209
                                tcg_gen_subi_i32(tmp, tmp, imm);
 
9210
                            else
 
9211
                                tcg_gen_addi_i32(tmp, tmp, imm);
 
9212
                        }
 
9213
                    }
 
9214
                    store_reg(s, rd, tmp);
 
9215
                }
 
9216
            } else {
 
9217
                int shifter_out = 0;
 
9218
                /* modified 12-bit immediate.  */
 
9219
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
 
9220
                imm = (insn & 0xff);
 
9221
                switch (shift) {
 
9222
                case 0: /* XY */
 
9223
                    /* Nothing to do.  */
 
9224
                    break;
 
9225
                case 1: /* 00XY00XY */
 
9226
                    imm |= imm << 16;
 
9227
                    break;
 
9228
                case 2: /* XY00XY00 */
 
9229
                    imm |= imm << 16;
 
9230
                    imm <<= 8;
 
9231
                    break;
 
9232
                case 3: /* XYXYXYXY */
 
9233
                    imm |= imm << 16;
 
9234
                    imm |= imm << 8;
 
9235
                    break;
 
9236
                default: /* Rotated constant.  */
 
9237
                    shift = (shift << 1) | (imm >> 7);
 
9238
                    imm |= 0x80;
 
9239
                    imm = imm << (32 - shift);
 
9240
                    shifter_out = 1;
 
9241
                    break;
 
9242
                }
 
9243
                tmp2 = tcg_temp_new_i32();
 
9244
                tcg_gen_movi_i32(tmp2, imm);
 
9245
                rn = (insn >> 16) & 0xf;
 
9246
                if (rn == 15) {
 
9247
                    tmp = tcg_temp_new_i32();
 
9248
                    tcg_gen_movi_i32(tmp, 0);
 
9249
                } else {
 
9250
                    tmp = load_reg(s, rn);
 
9251
                }
 
9252
                op = (insn >> 21) & 0xf;
 
9253
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
 
9254
                                       shifter_out, tmp, tmp2))
 
9255
                    goto illegal_op;
 
9256
                tcg_temp_free_i32(tmp2);
 
9257
                rd = (insn >> 8) & 0xf;
 
9258
                if (rd != 15) {
 
9259
                    store_reg(s, rd, tmp);
 
9260
                } else {
 
9261
                    tcg_temp_free_i32(tmp);
 
9262
                }
 
9263
            }
 
9264
        }
 
9265
        break;
 
9266
    case 12: /* Load/store single data item.  */
 
9267
        {
 
9268
        int postinc = 0;
 
9269
        int writeback = 0;
 
9270
        int user;
 
9271
        if ((insn & 0x01100000) == 0x01000000) {
 
9272
            if (disas_neon_ls_insn(env, s, insn))
 
9273
                goto illegal_op;
 
9274
            break;
 
9275
        }
 
9276
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
 
9277
        if (rs == 15) {
 
9278
            if (!(insn & (1 << 20))) {
 
9279
                goto illegal_op;
 
9280
            }
 
9281
            if (op != 2) {
 
9282
                /* Byte or halfword load space with dest == r15 : memory hints.
 
9283
                 * Catch them early so we don't emit pointless addressing code.
 
9284
                 * This space is a mix of:
 
9285
                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
 
9286
                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
 
9287
                 *     cores)
 
9288
                 *  unallocated hints, which must be treated as NOPs
 
9289
                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
 
9290
                 *     which is easiest for the decoding logic
 
9291
                 *  Some space which must UNDEF
 
9292
                 */
 
9293
                int op1 = (insn >> 23) & 3;
 
9294
                int op2 = (insn >> 6) & 0x3f;
 
9295
                if (op & 2) {
 
9296
                    goto illegal_op;
 
9297
                }
 
9298
                if (rn == 15) {
 
9299
                    /* UNPREDICTABLE, unallocated hint or
 
9300
                     * PLD/PLDW/PLI (literal)
 
9301
                     */
 
9302
                    return 0;
 
9303
                }
 
9304
                if (op1 & 1) {
 
9305
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
 
9306
                }
 
9307
                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
 
9308
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
 
9309
                }
 
9310
                /* UNDEF space, or an UNPREDICTABLE */
 
9311
                return 1;
 
9312
            }
 
9313
        }
 
9314
        user = IS_USER(s);
 
9315
        if (rn == 15) {
 
9316
            addr = tcg_temp_new_i32();
 
9317
            /* PC relative.  */
 
9318
            /* s->pc has already been incremented by 4.  */
 
9319
            imm = s->pc & 0xfffffffc;
 
9320
            if (insn & (1 << 23))
 
9321
                imm += insn & 0xfff;
 
9322
            else
 
9323
                imm -= insn & 0xfff;
 
9324
            tcg_gen_movi_i32(addr, imm);
 
9325
        } else {
 
9326
            addr = load_reg(s, rn);
 
9327
            if (insn & (1 << 23)) {
 
9328
                /* Positive offset.  */
 
9329
                imm = insn & 0xfff;
 
9330
                tcg_gen_addi_i32(addr, addr, imm);
 
9331
            } else {
 
9332
                imm = insn & 0xff;
 
9333
                switch ((insn >> 8) & 0xf) {
 
9334
                case 0x0: /* Shifted Register.  */
 
9335
                    shift = (insn >> 4) & 0xf;
 
9336
                    if (shift > 3) {
 
9337
                        tcg_temp_free_i32(addr);
 
9338
                        goto illegal_op;
 
9339
                    }
 
9340
                    tmp = load_reg(s, rm);
 
9341
                    if (shift)
 
9342
                        tcg_gen_shli_i32(tmp, tmp, shift);
 
9343
                    tcg_gen_add_i32(addr, addr, tmp);
 
9344
                    tcg_temp_free_i32(tmp);
 
9345
                    break;
 
9346
                case 0xc: /* Negative offset.  */
 
9347
                    tcg_gen_addi_i32(addr, addr, -imm);
 
9348
                    break;
 
9349
                case 0xe: /* User privilege.  */
 
9350
                    tcg_gen_addi_i32(addr, addr, imm);
 
9351
                    user = 1;
 
9352
                    break;
 
9353
                case 0x9: /* Post-decrement.  */
 
9354
                    imm = -imm;
 
9355
                    /* Fall through.  */
 
9356
                case 0xb: /* Post-increment.  */
 
9357
                    postinc = 1;
 
9358
                    writeback = 1;
 
9359
                    break;
 
9360
                case 0xd: /* Pre-decrement.  */
 
9361
                    imm = -imm;
 
9362
                    /* Fall through.  */
 
9363
                case 0xf: /* Pre-increment.  */
 
9364
                    tcg_gen_addi_i32(addr, addr, imm);
 
9365
                    writeback = 1;
 
9366
                    break;
 
9367
                default:
 
9368
                    tcg_temp_free_i32(addr);
 
9369
                    goto illegal_op;
 
9370
                }
 
9371
            }
 
9372
        }
 
9373
        if (insn & (1 << 20)) {
 
9374
            /* Load.  */
 
9375
            tmp = tcg_temp_new_i32();
 
9376
            switch (op) {
 
9377
            case 0:
 
9378
                gen_aa32_ld8u(tmp, addr, user);
 
9379
                break;
 
9380
            case 4:
 
9381
                gen_aa32_ld8s(tmp, addr, user);
 
9382
                break;
 
9383
            case 1:
 
9384
                gen_aa32_ld16u(tmp, addr, user);
 
9385
                break;
 
9386
            case 5:
 
9387
                gen_aa32_ld16s(tmp, addr, user);
 
9388
                break;
 
9389
            case 2:
 
9390
                gen_aa32_ld32u(tmp, addr, user);
 
9391
                break;
 
9392
            default:
 
9393
                tcg_temp_free_i32(tmp);
 
9394
                tcg_temp_free_i32(addr);
 
9395
                goto illegal_op;
 
9396
            }
 
9397
            if (rs == 15) {
 
9398
                gen_bx(s, tmp);
 
9399
            } else {
 
9400
                store_reg(s, rs, tmp);
 
9401
            }
 
9402
        } else {
 
9403
            /* Store.  */
 
9404
            tmp = load_reg(s, rs);
 
9405
            switch (op) {
 
9406
            case 0:
 
9407
                gen_aa32_st8(tmp, addr, user);
 
9408
                break;
 
9409
            case 1:
 
9410
                gen_aa32_st16(tmp, addr, user);
 
9411
                break;
 
9412
            case 2:
 
9413
                gen_aa32_st32(tmp, addr, user);
 
9414
                break;
 
9415
            default:
 
9416
                tcg_temp_free_i32(tmp);
 
9417
                tcg_temp_free_i32(addr);
 
9418
                goto illegal_op;
 
9419
            }
 
9420
            tcg_temp_free_i32(tmp);
 
9421
        }
 
9422
        if (postinc)
 
9423
            tcg_gen_addi_i32(addr, addr, imm);
 
9424
        if (writeback) {
 
9425
            store_reg(s, rn, addr);
 
9426
        } else {
 
9427
            tcg_temp_free_i32(addr);
 
9428
        }
 
9429
        }
 
9430
        break;
 
9431
    default:
 
9432
        goto illegal_op;
 
9433
    }
 
9434
    return 0;
 
9435
illegal_op:
 
9436
    return 1;
 
9437
}
 
9438
 
 
9439
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 
9440
{
 
9441
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
 
9442
    int32_t offset;
 
9443
    int i;
 
9444
    TCGv_i32 tmp;
 
9445
    TCGv_i32 tmp2;
 
9446
    TCGv_i32 addr;
 
9447
 
 
9448
    if (s->condexec_mask) {
 
9449
        cond = s->condexec_cond;
 
9450
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
 
9451
          s->condlabel = gen_new_label();
 
9452
          gen_test_cc(cond ^ 1, s->condlabel);
 
9453
          s->condjmp = 1;
 
9454
        }
 
9455
    }
 
9456
 
 
9457
    insn = arm_lduw_code(env, s->pc, s->bswap_code);
 
9458
    s->pc += 2;
 
9459
 
 
9460
    switch (insn >> 12) {
 
9461
    case 0: case 1:
 
9462
 
 
9463
        rd = insn & 7;
 
9464
        op = (insn >> 11) & 3;
 
9465
        if (op == 3) {
 
9466
            /* add/subtract */
 
9467
            rn = (insn >> 3) & 7;
 
9468
            tmp = load_reg(s, rn);
 
9469
            if (insn & (1 << 10)) {
 
9470
                /* immediate */
 
9471
                tmp2 = tcg_temp_new_i32();
 
9472
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
 
9473
            } else {
 
9474
                /* reg */
 
9475
                rm = (insn >> 6) & 7;
 
9476
                tmp2 = load_reg(s, rm);
 
9477
            }
 
9478
            if (insn & (1 << 9)) {
 
9479
                if (s->condexec_mask)
 
9480
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
 
9481
                else
 
9482
                    gen_sub_CC(tmp, tmp, tmp2);
 
9483
            } else {
 
9484
                if (s->condexec_mask)
 
9485
                    tcg_gen_add_i32(tmp, tmp, tmp2);
 
9486
                else
 
9487
                    gen_add_CC(tmp, tmp, tmp2);
 
9488
            }
 
9489
            tcg_temp_free_i32(tmp2);
 
9490
            store_reg(s, rd, tmp);
 
9491
        } else {
 
9492
            /* shift immediate */
 
9493
            rm = (insn >> 3) & 7;
 
9494
            shift = (insn >> 6) & 0x1f;
 
9495
            tmp = load_reg(s, rm);
 
9496
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
 
9497
            if (!s->condexec_mask)
 
9498
                gen_logic_CC(tmp);
 
9499
            store_reg(s, rd, tmp);
 
9500
        }
 
9501
        break;
 
9502
    case 2: case 3:
 
9503
        /* arithmetic large immediate */
 
9504
        op = (insn >> 11) & 3;
 
9505
        rd = (insn >> 8) & 0x7;
 
9506
        if (op == 0) { /* mov */
 
9507
            tmp = tcg_temp_new_i32();
 
9508
            tcg_gen_movi_i32(tmp, insn & 0xff);
 
9509
            if (!s->condexec_mask)
 
9510
                gen_logic_CC(tmp);
 
9511
            store_reg(s, rd, tmp);
 
9512
        } else {
 
9513
            tmp = load_reg(s, rd);
 
9514
            tmp2 = tcg_temp_new_i32();
 
9515
            tcg_gen_movi_i32(tmp2, insn & 0xff);
 
9516
            switch (op) {
 
9517
            case 1: /* cmp */
 
9518
                gen_sub_CC(tmp, tmp, tmp2);
 
9519
                tcg_temp_free_i32(tmp);
 
9520
                tcg_temp_free_i32(tmp2);
 
9521
                break;
 
9522
            case 2: /* add */
 
9523
                if (s->condexec_mask)
 
9524
                    tcg_gen_add_i32(tmp, tmp, tmp2);
 
9525
                else
 
9526
                    gen_add_CC(tmp, tmp, tmp2);
 
9527
                tcg_temp_free_i32(tmp2);
 
9528
                store_reg(s, rd, tmp);
 
9529
                break;
 
9530
            case 3: /* sub */
 
9531
                if (s->condexec_mask)
 
9532
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
 
9533
                else
 
9534
                    gen_sub_CC(tmp, tmp, tmp2);
 
9535
                tcg_temp_free_i32(tmp2);
 
9536
                store_reg(s, rd, tmp);
 
9537
                break;
 
9538
            }
 
9539
        }
 
9540
        break;
 
9541
    case 4:
 
9542
        if (insn & (1 << 11)) {
 
9543
            rd = (insn >> 8) & 7;
 
9544
            /* load pc-relative.  Bit 1 of PC is ignored.  */
 
9545
            val = s->pc + 2 + ((insn & 0xff) * 4);
 
9546
            val &= ~(uint32_t)2;
 
9547
            addr = tcg_temp_new_i32();
 
9548
            tcg_gen_movi_i32(addr, val);
 
9549
            tmp = tcg_temp_new_i32();
 
9550
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
9551
            tcg_temp_free_i32(addr);
 
9552
            store_reg(s, rd, tmp);
 
9553
            break;
 
9554
        }
 
9555
        if (insn & (1 << 10)) {
 
9556
            /* data processing extended or blx */
 
9557
            rd = (insn & 7) | ((insn >> 4) & 8);
 
9558
            rm = (insn >> 3) & 0xf;
 
9559
            op = (insn >> 8) & 3;
 
9560
            switch (op) {
 
9561
            case 0: /* add */
 
9562
                tmp = load_reg(s, rd);
 
9563
                tmp2 = load_reg(s, rm);
 
9564
                tcg_gen_add_i32(tmp, tmp, tmp2);
 
9565
                tcg_temp_free_i32(tmp2);
 
9566
                store_reg(s, rd, tmp);
 
9567
                break;
 
9568
            case 1: /* cmp */
 
9569
                tmp = load_reg(s, rd);
 
9570
                tmp2 = load_reg(s, rm);
 
9571
                gen_sub_CC(tmp, tmp, tmp2);
 
9572
                tcg_temp_free_i32(tmp2);
 
9573
                tcg_temp_free_i32(tmp);
 
9574
                break;
 
9575
            case 2: /* mov/cpy */
 
9576
                tmp = load_reg(s, rm);
 
9577
                store_reg(s, rd, tmp);
 
9578
                break;
 
9579
            case 3:/* branch [and link] exchange thumb register */
 
9580
                tmp = load_reg(s, rm);
 
9581
                if (insn & (1 << 7)) {
 
9582
                    ARCH(5);
 
9583
                    val = (uint32_t)s->pc | 1;
 
9584
                    tmp2 = tcg_temp_new_i32();
 
9585
                    tcg_gen_movi_i32(tmp2, val);
 
9586
                    store_reg(s, 14, tmp2);
 
9587
                }
 
9588
                /* already thumb, no need to check */
 
9589
                gen_bx(s, tmp);
 
9590
                break;
 
9591
            }
 
9592
            break;
 
9593
        }
 
9594
 
 
9595
        /* data processing register */
 
9596
        rd = insn & 7;
 
9597
        rm = (insn >> 3) & 7;
 
9598
        op = (insn >> 6) & 0xf;
 
9599
        if (op == 2 || op == 3 || op == 4 || op == 7) {
 
9600
            /* the shift/rotate ops want the operands backwards */
 
9601
            val = rm;
 
9602
            rm = rd;
 
9603
            rd = val;
 
9604
            val = 1;
 
9605
        } else {
 
9606
            val = 0;
 
9607
        }
 
9608
 
 
9609
        if (op == 9) { /* neg */
 
9610
            tmp = tcg_temp_new_i32();
 
9611
            tcg_gen_movi_i32(tmp, 0);
 
9612
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
 
9613
            tmp = load_reg(s, rd);
 
9614
        } else {
 
9615
            TCGV_UNUSED_I32(tmp);
 
9616
        }
 
9617
 
 
9618
        tmp2 = load_reg(s, rm);
 
9619
        switch (op) {
 
9620
        case 0x0: /* and */
 
9621
            tcg_gen_and_i32(tmp, tmp, tmp2);
 
9622
            if (!s->condexec_mask)
 
9623
                gen_logic_CC(tmp);
 
9624
            break;
 
9625
        case 0x1: /* eor */
 
9626
            tcg_gen_xor_i32(tmp, tmp, tmp2);
 
9627
            if (!s->condexec_mask)
 
9628
                gen_logic_CC(tmp);
 
9629
            break;
 
9630
        case 0x2: /* lsl */
 
9631
            if (s->condexec_mask) {
 
9632
                gen_shl(tmp2, tmp2, tmp);
 
9633
            } else {
 
9634
                gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
 
9635
                gen_logic_CC(tmp2);
 
9636
            }
 
9637
            break;
 
9638
        case 0x3: /* lsr */
 
9639
            if (s->condexec_mask) {
 
9640
                gen_shr(tmp2, tmp2, tmp);
 
9641
            } else {
 
9642
                gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
 
9643
                gen_logic_CC(tmp2);
 
9644
            }
 
9645
            break;
 
9646
        case 0x4: /* asr */
 
9647
            if (s->condexec_mask) {
 
9648
                gen_sar(tmp2, tmp2, tmp);
 
9649
            } else {
 
9650
                gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
 
9651
                gen_logic_CC(tmp2);
 
9652
            }
 
9653
            break;
 
9654
        case 0x5: /* adc */
 
9655
            if (s->condexec_mask) {
 
9656
                gen_adc(tmp, tmp2);
 
9657
            } else {
 
9658
                gen_adc_CC(tmp, tmp, tmp2);
 
9659
            }
 
9660
            break;
 
9661
        case 0x6: /* sbc */
 
9662
            if (s->condexec_mask) {
 
9663
                gen_sub_carry(tmp, tmp, tmp2);
 
9664
            } else {
 
9665
                gen_sbc_CC(tmp, tmp, tmp2);
 
9666
            }
 
9667
            break;
 
9668
        case 0x7: /* ror */
 
9669
            if (s->condexec_mask) {
 
9670
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
 
9671
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
 
9672
            } else {
 
9673
                gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
 
9674
                gen_logic_CC(tmp2);
 
9675
            }
 
9676
            break;
 
9677
        case 0x8: /* tst */
 
9678
            tcg_gen_and_i32(tmp, tmp, tmp2);
 
9679
            gen_logic_CC(tmp);
 
9680
            rd = 16;
 
9681
            break;
 
9682
        case 0x9: /* neg */
 
9683
            if (s->condexec_mask)
 
9684
                tcg_gen_neg_i32(tmp, tmp2);
 
9685
            else
 
9686
                gen_sub_CC(tmp, tmp, tmp2);
 
9687
            break;
 
9688
        case 0xa: /* cmp */
 
9689
            gen_sub_CC(tmp, tmp, tmp2);
 
9690
            rd = 16;
 
9691
            break;
 
9692
        case 0xb: /* cmn */
 
9693
            gen_add_CC(tmp, tmp, tmp2);
 
9694
            rd = 16;
 
9695
            break;
 
9696
        case 0xc: /* orr */
 
9697
            tcg_gen_or_i32(tmp, tmp, tmp2);
 
9698
            if (!s->condexec_mask)
 
9699
                gen_logic_CC(tmp);
 
9700
            break;
 
9701
        case 0xd: /* mul */
 
9702
            tcg_gen_mul_i32(tmp, tmp, tmp2);
 
9703
            if (!s->condexec_mask)
 
9704
                gen_logic_CC(tmp);
 
9705
            break;
 
9706
        case 0xe: /* bic */
 
9707
            tcg_gen_andc_i32(tmp, tmp, tmp2);
 
9708
            if (!s->condexec_mask)
 
9709
                gen_logic_CC(tmp);
 
9710
            break;
 
9711
        case 0xf: /* mvn */
 
9712
            tcg_gen_not_i32(tmp2, tmp2);
 
9713
            if (!s->condexec_mask)
 
9714
                gen_logic_CC(tmp2);
 
9715
            val = 1;
 
9716
            rm = rd;
 
9717
            break;
 
9718
        }
 
9719
        if (rd != 16) {
 
9720
            if (val) {
 
9721
                store_reg(s, rm, tmp2);
 
9722
                if (op != 0xf)
 
9723
                    tcg_temp_free_i32(tmp);
 
9724
            } else {
 
9725
                store_reg(s, rd, tmp);
 
9726
                tcg_temp_free_i32(tmp2);
 
9727
            }
 
9728
        } else {
 
9729
            tcg_temp_free_i32(tmp);
 
9730
            tcg_temp_free_i32(tmp2);
 
9731
        }
 
9732
        break;
 
9733
 
 
9734
    case 5:
 
9735
        /* load/store register offset.  */
 
9736
        rd = insn & 7;
 
9737
        rn = (insn >> 3) & 7;
 
9738
        rm = (insn >> 6) & 7;
 
9739
        op = (insn >> 9) & 7;
 
9740
        addr = load_reg(s, rn);
 
9741
        tmp = load_reg(s, rm);
 
9742
        tcg_gen_add_i32(addr, addr, tmp);
 
9743
        tcg_temp_free_i32(tmp);
 
9744
 
 
9745
        if (op < 3) { /* store */
 
9746
            tmp = load_reg(s, rd);
 
9747
        } else {
 
9748
            tmp = tcg_temp_new_i32();
 
9749
        }
 
9750
 
 
9751
        switch (op) {
 
9752
        case 0: /* str */
 
9753
            gen_aa32_st32(tmp, addr, IS_USER(s));
 
9754
            break;
 
9755
        case 1: /* strh */
 
9756
            gen_aa32_st16(tmp, addr, IS_USER(s));
 
9757
            break;
 
9758
        case 2: /* strb */
 
9759
            gen_aa32_st8(tmp, addr, IS_USER(s));
 
9760
            break;
 
9761
        case 3: /* ldrsb */
 
9762
            gen_aa32_ld8s(tmp, addr, IS_USER(s));
 
9763
            break;
 
9764
        case 4: /* ldr */
 
9765
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
9766
            break;
 
9767
        case 5: /* ldrh */
 
9768
            gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
9769
            break;
 
9770
        case 6: /* ldrb */
 
9771
            gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
9772
            break;
 
9773
        case 7: /* ldrsh */
 
9774
            gen_aa32_ld16s(tmp, addr, IS_USER(s));
 
9775
            break;
 
9776
        }
 
9777
        if (op >= 3) { /* load */
 
9778
            store_reg(s, rd, tmp);
 
9779
        } else {
 
9780
            tcg_temp_free_i32(tmp);
 
9781
        }
 
9782
        tcg_temp_free_i32(addr);
 
9783
        break;
 
9784
 
 
9785
    case 6:
 
9786
        /* load/store word immediate offset */
 
9787
        rd = insn & 7;
 
9788
        rn = (insn >> 3) & 7;
 
9789
        addr = load_reg(s, rn);
 
9790
        val = (insn >> 4) & 0x7c;
 
9791
        tcg_gen_addi_i32(addr, addr, val);
 
9792
 
 
9793
        if (insn & (1 << 11)) {
 
9794
            /* load */
 
9795
            tmp = tcg_temp_new_i32();
 
9796
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
9797
            store_reg(s, rd, tmp);
 
9798
        } else {
 
9799
            /* store */
 
9800
            tmp = load_reg(s, rd);
 
9801
            gen_aa32_st32(tmp, addr, IS_USER(s));
 
9802
            tcg_temp_free_i32(tmp);
 
9803
        }
 
9804
        tcg_temp_free_i32(addr);
 
9805
        break;
 
9806
 
 
9807
    case 7:
 
9808
        /* load/store byte immediate offset */
 
9809
        rd = insn & 7;
 
9810
        rn = (insn >> 3) & 7;
 
9811
        addr = load_reg(s, rn);
 
9812
        val = (insn >> 6) & 0x1f;
 
9813
        tcg_gen_addi_i32(addr, addr, val);
 
9814
 
 
9815
        if (insn & (1 << 11)) {
 
9816
            /* load */
 
9817
            tmp = tcg_temp_new_i32();
 
9818
            gen_aa32_ld8u(tmp, addr, IS_USER(s));
 
9819
            store_reg(s, rd, tmp);
 
9820
        } else {
 
9821
            /* store */
 
9822
            tmp = load_reg(s, rd);
 
9823
            gen_aa32_st8(tmp, addr, IS_USER(s));
 
9824
            tcg_temp_free_i32(tmp);
 
9825
        }
 
9826
        tcg_temp_free_i32(addr);
 
9827
        break;
 
9828
 
 
9829
    case 8:
 
9830
        /* load/store halfword immediate offset */
 
9831
        rd = insn & 7;
 
9832
        rn = (insn >> 3) & 7;
 
9833
        addr = load_reg(s, rn);
 
9834
        val = (insn >> 5) & 0x3e;
 
9835
        tcg_gen_addi_i32(addr, addr, val);
 
9836
 
 
9837
        if (insn & (1 << 11)) {
 
9838
            /* load */
 
9839
            tmp = tcg_temp_new_i32();
 
9840
            gen_aa32_ld16u(tmp, addr, IS_USER(s));
 
9841
            store_reg(s, rd, tmp);
 
9842
        } else {
 
9843
            /* store */
 
9844
            tmp = load_reg(s, rd);
 
9845
            gen_aa32_st16(tmp, addr, IS_USER(s));
 
9846
            tcg_temp_free_i32(tmp);
 
9847
        }
 
9848
        tcg_temp_free_i32(addr);
 
9849
        break;
 
9850
 
 
9851
    case 9:
 
9852
        /* load/store from stack */
 
9853
        rd = (insn >> 8) & 7;
 
9854
        addr = load_reg(s, 13);
 
9855
        val = (insn & 0xff) * 4;
 
9856
        tcg_gen_addi_i32(addr, addr, val);
 
9857
 
 
9858
        if (insn & (1 << 11)) {
 
9859
            /* load */
 
9860
            tmp = tcg_temp_new_i32();
 
9861
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
9862
            store_reg(s, rd, tmp);
 
9863
        } else {
 
9864
            /* store */
 
9865
            tmp = load_reg(s, rd);
 
9866
            gen_aa32_st32(tmp, addr, IS_USER(s));
 
9867
            tcg_temp_free_i32(tmp);
 
9868
        }
 
9869
        tcg_temp_free_i32(addr);
 
9870
        break;
 
9871
 
 
9872
    case 10:
 
9873
        /* add to high reg */
 
9874
        rd = (insn >> 8) & 7;
 
9875
        if (insn & (1 << 11)) {
 
9876
            /* SP */
 
9877
            tmp = load_reg(s, 13);
 
9878
        } else {
 
9879
            /* PC. bit 1 is ignored.  */
 
9880
            tmp = tcg_temp_new_i32();
 
9881
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
 
9882
        }
 
9883
        val = (insn & 0xff) * 4;
 
9884
        tcg_gen_addi_i32(tmp, tmp, val);
 
9885
        store_reg(s, rd, tmp);
 
9886
        break;
 
9887
 
 
9888
    case 11:
 
9889
        /* misc */
 
9890
        op = (insn >> 8) & 0xf;
 
9891
        switch (op) {
 
9892
        case 0:
 
9893
            /* adjust stack pointer */
 
9894
            tmp = load_reg(s, 13);
 
9895
            val = (insn & 0x7f) * 4;
 
9896
            if (insn & (1 << 7))
 
9897
                val = -(int32_t)val;
 
9898
            tcg_gen_addi_i32(tmp, tmp, val);
 
9899
            store_reg(s, 13, tmp);
 
9900
            break;
 
9901
 
 
9902
        case 2: /* sign/zero extend.  */
 
9903
            ARCH(6);
 
9904
            rd = insn & 7;
 
9905
            rm = (insn >> 3) & 7;
 
9906
            tmp = load_reg(s, rm);
 
9907
            switch ((insn >> 6) & 3) {
 
9908
            case 0: gen_sxth(tmp); break;
 
9909
            case 1: gen_sxtb(tmp); break;
 
9910
            case 2: gen_uxth(tmp); break;
 
9911
            case 3: gen_uxtb(tmp); break;
 
9912
            }
 
9913
            store_reg(s, rd, tmp);
 
9914
            break;
 
9915
        case 4: case 5: case 0xc: case 0xd:
 
9916
            /* push/pop */
 
9917
            addr = load_reg(s, 13);
 
9918
            if (insn & (1 << 8))
 
9919
                offset = 4;
 
9920
            else
 
9921
                offset = 0;
 
9922
            for (i = 0; i < 8; i++) {
 
9923
                if (insn & (1 << i))
 
9924
                    offset += 4;
 
9925
            }
 
9926
            if ((insn & (1 << 11)) == 0) {
 
9927
                tcg_gen_addi_i32(addr, addr, -offset);
 
9928
            }
 
9929
            for (i = 0; i < 8; i++) {
 
9930
                if (insn & (1 << i)) {
 
9931
                    if (insn & (1 << 11)) {
 
9932
                        /* pop */
 
9933
                        tmp = tcg_temp_new_i32();
 
9934
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
9935
                        store_reg(s, i, tmp);
 
9936
                    } else {
 
9937
                        /* push */
 
9938
                        tmp = load_reg(s, i);
 
9939
                        gen_aa32_st32(tmp, addr, IS_USER(s));
 
9940
                        tcg_temp_free_i32(tmp);
 
9941
                    }
 
9942
                    /* advance to the next address.  */
 
9943
                    tcg_gen_addi_i32(addr, addr, 4);
 
9944
                }
 
9945
            }
 
9946
            TCGV_UNUSED_I32(tmp);
 
9947
            if (insn & (1 << 8)) {
 
9948
                if (insn & (1 << 11)) {
 
9949
                    /* pop pc */
 
9950
                    tmp = tcg_temp_new_i32();
 
9951
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
9952
                    /* don't set the pc until the rest of the instruction
 
9953
                       has completed */
 
9954
                } else {
 
9955
                    /* push lr */
 
9956
                    tmp = load_reg(s, 14);
 
9957
                    gen_aa32_st32(tmp, addr, IS_USER(s));
 
9958
                    tcg_temp_free_i32(tmp);
 
9959
                }
 
9960
                tcg_gen_addi_i32(addr, addr, 4);
 
9961
            }
 
9962
            if ((insn & (1 << 11)) == 0) {
 
9963
                tcg_gen_addi_i32(addr, addr, -offset);
 
9964
            }
 
9965
            /* write back the new stack pointer */
 
9966
            store_reg(s, 13, addr);
 
9967
            /* set the new PC value */
 
9968
            if ((insn & 0x0900) == 0x0900) {
 
9969
                store_reg_from_load(env, s, 15, tmp);
 
9970
            }
 
9971
            break;
 
9972
 
 
9973
        case 1: case 3: case 9: case 11: /* czb */
 
9974
            rm = insn & 7;
 
9975
            tmp = load_reg(s, rm);
 
9976
            s->condlabel = gen_new_label();
 
9977
            s->condjmp = 1;
 
9978
            if (insn & (1 << 11))
 
9979
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
 
9980
            else
 
9981
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
 
9982
            tcg_temp_free_i32(tmp);
 
9983
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
 
9984
            val = (uint32_t)s->pc + 2;
 
9985
            val += offset;
 
9986
            gen_jmp(s, val);
 
9987
            break;
 
9988
 
 
9989
        case 15: /* IT, nop-hint.  */
 
9990
            if ((insn & 0xf) == 0) {
 
9991
                gen_nop_hint(s, (insn >> 4) & 0xf);
 
9992
                break;
 
9993
            }
 
9994
            /* If Then.  */
 
9995
            s->condexec_cond = (insn >> 4) & 0xe;
 
9996
            s->condexec_mask = insn & 0x1f;
 
9997
            /* No actual code generated for this insn, just setup state.  */
 
9998
            break;
 
9999
 
 
10000
        case 0xe: /* bkpt */
 
10001
            ARCH(5);
 
10002
            gen_exception_insn(s, 2, EXCP_BKPT);
 
10003
            break;
 
10004
 
 
10005
        case 0xa: /* rev */
 
10006
            ARCH(6);
 
10007
            rn = (insn >> 3) & 0x7;
 
10008
            rd = insn & 0x7;
 
10009
            tmp = load_reg(s, rn);
 
10010
            switch ((insn >> 6) & 3) {
 
10011
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
 
10012
            case 1: gen_rev16(tmp); break;
 
10013
            case 3: gen_revsh(tmp); break;
 
10014
            default: goto illegal_op;
 
10015
            }
 
10016
            store_reg(s, rd, tmp);
 
10017
            break;
 
10018
 
 
10019
        case 6:
 
10020
            switch ((insn >> 5) & 7) {
 
10021
            case 2:
 
10022
                /* setend */
 
10023
                ARCH(6);
 
10024
                if (((insn >> 3) & 1) != s->bswap_code) {
 
10025
                    /* Dynamic endianness switching not implemented. */
 
10026
                    qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
 
10027
                    goto illegal_op;
 
10028
                }
 
10029
                break;
 
10030
            case 3:
 
10031
                /* cps */
 
10032
                ARCH(6);
 
10033
                if (IS_USER(s)) {
 
10034
                    break;
 
10035
                }
 
10036
                if (IS_M(env)) {
 
10037
                    tmp = tcg_const_i32((insn & (1 << 4)) != 0);
 
10038
                    /* FAULTMASK */
 
10039
                    if (insn & 1) {
 
10040
                        addr = tcg_const_i32(19);
 
10041
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
 
10042
                        tcg_temp_free_i32(addr);
 
10043
                    }
 
10044
                    /* PRIMASK */
 
10045
                    if (insn & 2) {
 
10046
                        addr = tcg_const_i32(16);
 
10047
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
 
10048
                        tcg_temp_free_i32(addr);
 
10049
                    }
 
10050
                    tcg_temp_free_i32(tmp);
 
10051
                    gen_lookup_tb(s);
 
10052
                } else {
 
10053
                    if (insn & (1 << 4)) {
 
10054
                        shift = CPSR_A | CPSR_I | CPSR_F;
 
10055
                    } else {
 
10056
                        shift = 0;
 
10057
                    }
 
10058
                    gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
 
10059
                }
 
10060
                break;
 
10061
            default:
 
10062
                goto undef;
 
10063
            }
 
10064
            break;
 
10065
 
 
10066
        default:
 
10067
            goto undef;
 
10068
        }
 
10069
        break;
 
10070
 
 
10071
    case 12:
 
10072
    {
 
10073
        /* load/store multiple */
 
10074
        TCGv_i32 loaded_var;
 
10075
        TCGV_UNUSED_I32(loaded_var);
 
10076
        rn = (insn >> 8) & 0x7;
 
10077
        addr = load_reg(s, rn);
 
10078
        for (i = 0; i < 8; i++) {
 
10079
            if (insn & (1 << i)) {
 
10080
                if (insn & (1 << 11)) {
 
10081
                    /* load */
 
10082
                    tmp = tcg_temp_new_i32();
 
10083
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
 
10084
                    if (i == rn) {
 
10085
                        loaded_var = tmp;
 
10086
                    } else {
 
10087
                        store_reg(s, i, tmp);
 
10088
                    }
 
10089
                } else {
 
10090
                    /* store */
 
10091
                    tmp = load_reg(s, i);
 
10092
                    gen_aa32_st32(tmp, addr, IS_USER(s));
 
10093
                    tcg_temp_free_i32(tmp);
 
10094
                }
 
10095
                /* advance to the next address */
 
10096
                tcg_gen_addi_i32(addr, addr, 4);
 
10097
            }
 
10098
        }
 
10099
        if ((insn & (1 << rn)) == 0) {
 
10100
            /* base reg not in list: base register writeback */
 
10101
            store_reg(s, rn, addr);
 
10102
        } else {
 
10103
            /* base reg in list: if load, complete it now */
 
10104
            if (insn & (1 << 11)) {
 
10105
                store_reg(s, rn, loaded_var);
 
10106
            }
 
10107
            tcg_temp_free_i32(addr);
 
10108
        }
 
10109
        break;
 
10110
    }
 
10111
    case 13:
 
10112
        /* conditional branch or swi */
 
10113
        cond = (insn >> 8) & 0xf;
 
10114
        if (cond == 0xe)
 
10115
            goto undef;
 
10116
 
 
10117
        if (cond == 0xf) {
 
10118
            /* swi */
 
10119
            gen_set_pc_im(s, s->pc);
 
10120
            s->is_jmp = DISAS_SWI;
 
10121
            break;
 
10122
        }
 
10123
        /* generate a conditional jump to next instruction */
 
10124
        s->condlabel = gen_new_label();
 
10125
        gen_test_cc(cond ^ 1, s->condlabel);
 
10126
        s->condjmp = 1;
 
10127
 
 
10128
        /* jump to the offset */
 
10129
        val = (uint32_t)s->pc + 2;
 
10130
        offset = ((int32_t)insn << 24) >> 24;
 
10131
        val += offset << 1;
 
10132
        gen_jmp(s, val);
 
10133
        break;
 
10134
 
 
10135
    case 14:
 
10136
        if (insn & (1 << 11)) {
 
10137
            if (disas_thumb2_insn(env, s, insn))
 
10138
              goto undef32;
 
10139
            break;
 
10140
        }
 
10141
        /* unconditional branch */
 
10142
        val = (uint32_t)s->pc;
 
10143
        offset = ((int32_t)insn << 21) >> 21;
 
10144
        val += (offset << 1) + 2;
 
10145
        gen_jmp(s, val);
 
10146
        break;
 
10147
 
 
10148
    case 15:
 
10149
        if (disas_thumb2_insn(env, s, insn))
 
10150
            goto undef32;
 
10151
        break;
 
10152
    }
 
10153
    return;
 
10154
undef32:
 
10155
    gen_exception_insn(s, 4, EXCP_UDEF);
 
10156
    return;
 
10157
illegal_op:
 
10158
undef:
 
10159
    gen_exception_insn(s, 2, EXCP_UDEF);
 
10160
}
 
10161
 
 
10162
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
 
10163
   basic block 'tb'. If search_pc is TRUE, also generate PC
 
10164
   information for each intermediate instruction. */
 
10165
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
 
10166
                                                  TranslationBlock *tb,
 
10167
                                                  bool search_pc)
 
10168
{
 
10169
    CPUState *cs = CPU(cpu);
 
10170
    CPUARMState *env = &cpu->env;
 
10171
    DisasContext dc1, *dc = &dc1;
 
10172
    CPUBreakpoint *bp;
 
10173
    uint16_t *gen_opc_end;
 
10174
    int j, lj;
 
10175
    target_ulong pc_start;
 
10176
    target_ulong next_page_start;
 
10177
    int num_insns;
 
10178
    int max_insns;
 
10179
 
 
10180
    /* generate intermediate code */
 
10181
    pc_start = tb->pc;
 
10182
 
 
10183
    dc->tb = tb;
 
10184
 
 
10185
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 
10186
 
 
10187
    dc->is_jmp = DISAS_NEXT;
 
10188
    dc->pc = pc_start;
 
10189
    dc->singlestep_enabled = cs->singlestep_enabled;
 
10190
    dc->condjmp = 0;
 
10191
 
 
10192
    if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
 
10193
        dc->aarch64 = 1;
 
10194
        dc->thumb = 0;
 
10195
        dc->bswap_code = 0;
 
10196
        dc->condexec_mask = 0;
 
10197
        dc->condexec_cond = 0;
 
10198
#if !defined(CONFIG_USER_ONLY)
 
10199
        dc->user = 0;
 
10200
#endif
 
10201
        dc->vfp_enabled = 0;
 
10202
        dc->vec_len = 0;
 
10203
        dc->vec_stride = 0;
 
10204
    } else {
 
10205
        dc->aarch64 = 0;
 
10206
        dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
 
10207
        dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
 
10208
        dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
 
10209
        dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
 
10210
#if !defined(CONFIG_USER_ONLY)
 
10211
        dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
 
10212
#endif
 
10213
        dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
 
10214
        dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
 
10215
        dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
 
10216
    }
 
10217
    cpu_F0s = tcg_temp_new_i32();
 
10218
    cpu_F1s = tcg_temp_new_i32();
 
10219
    cpu_F0d = tcg_temp_new_i64();
 
10220
    cpu_F1d = tcg_temp_new_i64();
 
10221
    cpu_V0 = cpu_F0d;
 
10222
    cpu_V1 = cpu_F1d;
 
10223
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
 
10224
    cpu_M0 = tcg_temp_new_i64();
 
10225
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 
10226
    lj = -1;
 
10227
    num_insns = 0;
 
10228
    max_insns = tb->cflags & CF_COUNT_MASK;
 
10229
    if (max_insns == 0)
 
10230
        max_insns = CF_COUNT_MASK;
 
10231
 
 
10232
    gen_tb_start();
 
10233
 
 
10234
    tcg_clear_temp_count();
 
10235
 
 
10236
    /* A note on handling of the condexec (IT) bits:
 
10237
     *
 
10238
     * We want to avoid the overhead of having to write the updated condexec
 
10239
     * bits back to the CPUARMState for every instruction in an IT block. So:
 
10240
     * (1) if the condexec bits are not already zero then we write
 
10241
     * zero back into the CPUARMState now. This avoids complications trying
 
10242
     * to do it at the end of the block. (For example if we don't do this
 
10243
     * it's hard to identify whether we can safely skip writing condexec
 
10244
     * at the end of the TB, which we definitely want to do for the case
 
10245
     * where a TB doesn't do anything with the IT state at all.)
 
10246
     * (2) if we are going to leave the TB then we call gen_set_condexec()
 
10247
     * which will write the correct value into CPUARMState if zero is wrong.
 
10248
     * This is done both for leaving the TB at the end, and for leaving
 
10249
     * it because of an exception we know will happen, which is done in
 
10250
     * gen_exception_insn(). The latter is necessary because we need to
 
10251
     * leave the TB with the PC/IT state just prior to execution of the
 
10252
     * instruction which caused the exception.
 
10253
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
 
10254
     * then the CPUARMState will be wrong and we need to reset it.
 
10255
     * This is handled in the same way as restoration of the
 
10256
     * PC in these situations: we will be called again with search_pc=1
 
10257
     * and generate a mapping of the condexec bits for each PC in
 
10258
     * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
 
10259
     * this to restore the condexec bits.
 
10260
     *
 
10261
     * Note that there are no instructions which can read the condexec
 
10262
     * bits, and none which can write non-static values to them, so
 
10263
     * we don't need to care about whether CPUARMState is correct in the
 
10264
     * middle of a TB.
 
10265
     */
 
10266
 
 
10267
    /* Reset the conditional execution bits immediately. This avoids
 
10268
       complications trying to do it at the end of the block.  */
 
10269
    if (dc->condexec_mask || dc->condexec_cond)
 
10270
      {
 
10271
        TCGv_i32 tmp = tcg_temp_new_i32();
 
10272
        tcg_gen_movi_i32(tmp, 0);
 
10273
        store_cpu_field(tmp, condexec_bits);
 
10274
      }
 
10275
    do {
 
10276
#ifdef CONFIG_USER_ONLY
 
10277
        /* Intercept jump to the magic kernel page.  */
 
10278
        if (!dc->aarch64 && dc->pc >= 0xffff0000) {
 
10279
            /* We always get here via a jump, so know we are not in a
 
10280
               conditional execution block.  */
 
10281
            gen_exception(EXCP_KERNEL_TRAP);
 
10282
            dc->is_jmp = DISAS_UPDATE;
 
10283
            break;
 
10284
        }
 
10285
#else
 
10286
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
 
10287
            /* We always get here via a jump, so know we are not in a
 
10288
               conditional execution block.  */
 
10289
            gen_exception(EXCP_EXCEPTION_EXIT);
 
10290
            dc->is_jmp = DISAS_UPDATE;
 
10291
            break;
 
10292
        }
 
10293
#endif
 
10294
 
 
10295
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
 
10296
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
 
10297
                if (bp->pc == dc->pc) {
 
10298
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
 
10299
                    /* Advance PC so that clearing the breakpoint will
 
10300
                       invalidate this TB.  */
 
10301
                    dc->pc += 2;
 
10302
                    goto done_generating;
 
10303
                }
 
10304
            }
 
10305
        }
 
10306
        if (search_pc) {
 
10307
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
 
10308
            if (lj < j) {
 
10309
                lj++;
 
10310
                while (lj < j)
 
10311
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
 
10312
            }
 
10313
            tcg_ctx.gen_opc_pc[lj] = dc->pc;
 
10314
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
 
10315
            tcg_ctx.gen_opc_instr_start[lj] = 1;
 
10316
            tcg_ctx.gen_opc_icount[lj] = num_insns;
 
10317
        }
 
10318
 
 
10319
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
 
10320
            gen_io_start();
 
10321
 
 
10322
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
 
10323
            tcg_gen_debug_insn_start(dc->pc);
 
10324
        }
 
10325
 
 
10326
        if (dc->aarch64) {
 
10327
            disas_a64_insn(env, dc);
 
10328
        } else if (dc->thumb) {
 
10329
            disas_thumb_insn(env, dc);
 
10330
            if (dc->condexec_mask) {
 
10331
                dc->condexec_cond = (dc->condexec_cond & 0xe)
 
10332
                                   | ((dc->condexec_mask >> 4) & 1);
 
10333
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
 
10334
                if (dc->condexec_mask == 0) {
 
10335
                    dc->condexec_cond = 0;
 
10336
                }
 
10337
            }
 
10338
        } else {
 
10339
            disas_arm_insn(env, dc);
 
10340
        }
 
10341
 
 
10342
        if (dc->condjmp && !dc->is_jmp) {
 
10343
            gen_set_label(dc->condlabel);
 
10344
            dc->condjmp = 0;
 
10345
        }
 
10346
 
 
10347
        if (tcg_check_temp_count()) {
 
10348
            fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
 
10349
                    dc->pc);
 
10350
        }
 
10351
 
 
10352
        /* Translation stops when a conditional branch is encountered.
 
10353
         * Otherwise the subsequent code could get translated several times.
 
10354
         * Also stop translation when a page boundary is reached.  This
 
10355
         * ensures prefetch aborts occur at the right place.  */
 
10356
        num_insns ++;
 
10357
    } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
 
10358
             !cs->singlestep_enabled &&
 
10359
             !singlestep &&
 
10360
             dc->pc < next_page_start &&
 
10361
             num_insns < max_insns);
 
10362
 
 
10363
    if (tb->cflags & CF_LAST_IO) {
 
10364
        if (dc->condjmp) {
 
10365
            /* FIXME:  This can theoretically happen with self-modifying
 
10366
               code.  */
 
10367
            cpu_abort(env, "IO on conditional branch instruction");
 
10368
        }
 
10369
        gen_io_end();
 
10370
    }
 
10371
 
 
10372
    /* At this stage dc->condjmp will only be set when the skipped
 
10373
       instruction was a conditional branch or trap, and the PC has
 
10374
       already been written.  */
 
10375
    if (unlikely(cs->singlestep_enabled)) {
 
10376
        /* Make sure the pc is updated, and raise a debug exception.  */
 
10377
        if (dc->condjmp) {
 
10378
            gen_set_condexec(dc);
 
10379
            if (dc->is_jmp == DISAS_SWI) {
 
10380
                gen_exception(EXCP_SWI);
 
10381
            } else if (dc->is_jmp == DISAS_SMC) {
 
10382
                gen_exception(EXCP_SMC);
 
10383
            } else {
 
10384
                gen_exception(EXCP_DEBUG);
 
10385
            }
 
10386
            gen_set_label(dc->condlabel);
 
10387
        }
 
10388
        if (dc->condjmp || !dc->is_jmp) {
 
10389
            gen_set_pc_im(dc, dc->pc);
 
10390
            dc->condjmp = 0;
 
10391
        }
 
10392
        gen_set_condexec(dc);
 
10393
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
 
10394
            gen_exception(EXCP_SWI);
 
10395
        } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
 
10396
            gen_exception(EXCP_SMC);
 
10397
        } else {
 
10398
            /* FIXME: Single stepping a WFI insn will not halt
 
10399
               the CPU.  */
 
10400
            gen_exception(EXCP_DEBUG);
 
10401
        }
 
10402
    } else {
 
10403
        /* While branches must always occur at the end of an IT block,
 
10404
           there are a few other things that can cause us to terminate
 
10405
           the TB in the middle of an IT block:
 
10406
            - Exception generating instructions (bkpt, swi, undefined).
 
10407
            - Page boundaries.
 
10408
            - Hardware watchpoints.
 
10409
           Hardware breakpoints have already been handled and skip this code.
 
10410
         */
 
10411
        gen_set_condexec(dc);
 
10412
        switch(dc->is_jmp) {
 
10413
        case DISAS_NEXT:
 
10414
            gen_goto_tb(dc, 1, dc->pc);
 
10415
            break;
 
10416
        default:
 
10417
        case DISAS_JUMP:
 
10418
        case DISAS_UPDATE:
 
10419
            /* indicate that the hash table must be used to find the next TB */
 
10420
            tcg_gen_exit_tb(0);
 
10421
            break;
 
10422
        case DISAS_TB_JUMP:
 
10423
            /* nothing more to generate */
 
10424
            break;
 
10425
        case DISAS_WFI:
 
10426
            gen_helper_wfi(cpu_env);
 
10427
            break;
 
10428
        case DISAS_SWI:
 
10429
            gen_exception(EXCP_SWI);
 
10430
            break;
 
10431
        case DISAS_SMC:
 
10432
            gen_exception(EXCP_SMC);
 
10433
            break;
 
10434
        }
 
10435
        if (dc->condjmp) {
 
10436
            gen_set_label(dc->condlabel);
 
10437
            gen_set_condexec(dc);
 
10438
            gen_goto_tb(dc, 1, dc->pc);
 
10439
            dc->condjmp = 0;
 
10440
        }
 
10441
    }
 
10442
 
 
10443
done_generating:
 
10444
    gen_tb_end(tb, num_insns);
 
10445
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
 
10446
 
 
10447
#ifdef DEBUG_DISAS
 
10448
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
 
10449
        qemu_log("----------------\n");
 
10450
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
 
10451
        log_target_disas(env, pc_start, dc->pc - pc_start,
 
10452
                         dc->thumb | (dc->bswap_code << 1));
 
10453
        qemu_log("\n");
 
10454
    }
 
10455
#endif
 
10456
    if (search_pc) {
 
10457
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
 
10458
        lj++;
 
10459
        while (lj <= j)
 
10460
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
 
10461
    } else {
 
10462
        tb->size = dc->pc - pc_start;
 
10463
        tb->icount = num_insns;
 
10464
    }
 
10465
}
 
10466
 
 
10467
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
 
10468
{
 
10469
    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
 
10470
}
 
10471
 
 
10472
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
 
10473
{
 
10474
    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
 
10475
}
 
10476
 
 
10477
static const char *cpu_mode_names[16] = {
 
10478
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
 
10479
  "???", "???", "???", "und", "???", "???", "???", "sys"
 
10480
};
 
10481
 
 
10482
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 
10483
                        int flags)
 
10484
{
 
10485
    ARMCPU *cpu = ARM_CPU(cs);
 
10486
    CPUARMState *env = &cpu->env;
 
10487
    int i;
 
10488
    uint32_t psr;
 
10489
 
 
10490
    for(i=0;i<16;i++) {
 
10491
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
 
10492
        if ((i % 4) == 3)
 
10493
            cpu_fprintf(f, "\n");
 
10494
        else
 
10495
            cpu_fprintf(f, " ");
 
10496
    }
 
10497
    psr = cpsr_read(env);
 
10498
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
 
10499
                psr,
 
10500
                psr & (1 << 31) ? 'N' : '-',
 
10501
                psr & (1 << 30) ? 'Z' : '-',
 
10502
                psr & (1 << 29) ? 'C' : '-',
 
10503
                psr & (1 << 28) ? 'V' : '-',
 
10504
                psr & CPSR_T ? 'T' : 'A',
 
10505
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
 
10506
 
 
10507
    if (flags & CPU_DUMP_FPU) {
 
10508
        int numvfpregs = 0;
 
10509
        if (arm_feature(env, ARM_FEATURE_VFP)) {
 
10510
            numvfpregs += 16;
 
10511
        }
 
10512
        if (arm_feature(env, ARM_FEATURE_VFP3)) {
 
10513
            numvfpregs += 16;
 
10514
        }
 
10515
        for (i = 0; i < numvfpregs; i++) {
 
10516
            uint64_t v = float64_val(env->vfp.regs[i]);
 
10517
            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
 
10518
                        i * 2, (uint32_t)v,
 
10519
                        i * 2 + 1, (uint32_t)(v >> 32),
 
10520
                        i, v);
 
10521
        }
 
10522
        cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
 
10523
    }
 
10524
}
 
10525
 
 
10526
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
 
10527
{
 
10528
    if (is_a64(env)) {
 
10529
        env->pc = tcg_ctx.gen_opc_pc[pc_pos];
 
10530
    } else {
 
10531
        env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
 
10532
    }
 
10533
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
 
10534
}