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

« back to all changes in this revision

Viewing changes to .pc/arm-virt/0005-target-arm-support-coprocessor-registers-which-do-io/target-arm/translate.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

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