~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/ubuntu/arm64/0024-target-arm-Split-A64-from-A32-T32-gen_intermediate_c.patch/target-arm/translate.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-04 12:13:08 UTC
  • mfrom: (10.1.45 sid)
  • Revision ID: package-import@ubuntu.com-20140204121308-1xq92lrfs75agw2g
Tags: 1.7.0+dfsg-3ubuntu1~ppa1
* Merge 1.7.0+dfsg-3 from debian.  Remaining changes:
  - debian/patches/ubuntu:
    * expose-vmx_qemu64cpu.patch
    * linaro (omap3) and arm64 patches
    * ubuntu/target-ppc-add-stubs-for-kvm-breakpoints: fix FTBFS
      on ppc
    * ubuntu/CVE-2013-4377.patch: fix denial of service via virtio
  - debian/qemu-system-x86.modprobe: set kvm_intel nested=1 options
  - debian/control:
    * add arm64 to Architectures
    * add qemu-common and qemu-system-aarch64 packages
  - debian/qemu-system-common.install: add debian/tmp/usr/lib
  - debian/qemu-system-common.preinst: add kvm group
  - debian/qemu-system-common.postinst: remove acl placed by udev,
    and add udevadm trigger.
  - qemu-system-x86.links: add eepro100.rom, remove pxe-virtio,
    pxe-e1000 and pxe-rtl8139.
  - add qemu-system-x86.qemu-kvm.upstart and .default
  - qemu-user-static.postinst-in: remove arm64 binfmt
  - debian/rules:
    * allow parallel build
    * add aarch64 to system_targets and sys_systems
    * add qemu-kvm-spice links
    * install qemu-system-x86.modprobe
  - add debian/qemu-system-common.links for OVMF.fd link
* Remove kvm-img, kvm-nbd, kvm-ifup and kvm-ifdown symlinks.

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