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

« back to all changes in this revision

Viewing changes to .pc/ubuntu/arm64/0013-target-arm-Implement-ARMv8-VSEL-instruction.patch/target-arm/translate.c

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

Show diffs side-by-side

added added

removed removed

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