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

« back to all changes in this revision

Viewing changes to .pc/arm64/0012-target-arm-Move-call-to-disas_vfp_insn-out-of-disas_.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
 
    dp = ((insn & 0xf00) == 0xb00);
2647
 
    switch ((insn >> 24) & 0xf) {
2648
 
    case 0xe:
2649
 
        if (insn & (1 << 4)) {
2650
 
            /* single register transfer */
2651
 
            rd = (insn >> 12) & 0xf;
2652
 
            if (dp) {
2653
 
                int size;
2654
 
                int pass;
2655
 
 
2656
 
                VFP_DREG_N(rn, insn);
2657
 
                if (insn & 0xf)
2658
 
                    return 1;
2659
 
                if (insn & 0x00c00060
2660
 
                    && !arm_feature(env, ARM_FEATURE_NEON))
2661
 
                    return 1;
2662
 
 
2663
 
                pass = (insn >> 21) & 1;
2664
 
                if (insn & (1 << 22)) {
2665
 
                    size = 0;
2666
 
                    offset = ((insn >> 5) & 3) * 8;
2667
 
                } else if (insn & (1 << 5)) {
2668
 
                    size = 1;
2669
 
                    offset = (insn & (1 << 6)) ? 16 : 0;
2670
 
                } else {
2671
 
                    size = 2;
2672
 
                    offset = 0;
2673
 
                }
2674
 
                if (insn & ARM_CP_RW_BIT) {
2675
 
                    /* vfp->arm */
2676
 
                    tmp = neon_load_reg(rn, pass);
2677
 
                    switch (size) {
2678
 
                    case 0:
2679
 
                        if (offset)
2680
 
                            tcg_gen_shri_i32(tmp, tmp, offset);
2681
 
                        if (insn & (1 << 23))
2682
 
                            gen_uxtb(tmp);
2683
 
                        else
2684
 
                            gen_sxtb(tmp);
2685
 
                        break;
2686
 
                    case 1:
2687
 
                        if (insn & (1 << 23)) {
2688
 
                            if (offset) {
2689
 
                                tcg_gen_shri_i32(tmp, tmp, 16);
2690
 
                            } else {
2691
 
                                gen_uxth(tmp);
2692
 
                            }
2693
 
                        } else {
2694
 
                            if (offset) {
2695
 
                                tcg_gen_sari_i32(tmp, tmp, 16);
2696
 
                            } else {
2697
 
                                gen_sxth(tmp);
2698
 
                            }
2699
 
                        }
2700
 
                        break;
2701
 
                    case 2:
2702
 
                        break;
2703
 
                    }
2704
 
                    store_reg(s, rd, tmp);
2705
 
                } else {
2706
 
                    /* arm->vfp */
2707
 
                    tmp = load_reg(s, rd);
2708
 
                    if (insn & (1 << 23)) {
2709
 
                        /* VDUP */
2710
 
                        if (size == 0) {
2711
 
                            gen_neon_dup_u8(tmp, 0);
2712
 
                        } else if (size == 1) {
2713
 
                            gen_neon_dup_low16(tmp);
2714
 
                        }
2715
 
                        for (n = 0; n <= pass * 2; n++) {
2716
 
                            tmp2 = tcg_temp_new_i32();
2717
 
                            tcg_gen_mov_i32(tmp2, tmp);
2718
 
                            neon_store_reg(rn, n, tmp2);
2719
 
                        }
2720
 
                        neon_store_reg(rn, n, tmp);
2721
 
                    } else {
2722
 
                        /* VMOV */
2723
 
                        switch (size) {
2724
 
                        case 0:
2725
 
                            tmp2 = neon_load_reg(rn, pass);
2726
 
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2727
 
                            tcg_temp_free_i32(tmp2);
2728
 
                            break;
2729
 
                        case 1:
2730
 
                            tmp2 = neon_load_reg(rn, pass);
2731
 
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2732
 
                            tcg_temp_free_i32(tmp2);
2733
 
                            break;
2734
 
                        case 2:
2735
 
                            break;
2736
 
                        }
2737
 
                        neon_store_reg(rn, pass, tmp);
2738
 
                    }
2739
 
                }
2740
 
            } else { /* !dp */
2741
 
                if ((insn & 0x6f) != 0x00)
2742
 
                    return 1;
2743
 
                rn = VFP_SREG_N(insn);
2744
 
                if (insn & ARM_CP_RW_BIT) {
2745
 
                    /* vfp->arm */
2746
 
                    if (insn & (1 << 21)) {
2747
 
                        /* system register */
2748
 
                        rn >>= 1;
2749
 
 
2750
 
                        switch (rn) {
2751
 
                        case ARM_VFP_FPSID:
2752
 
                            /* VFP2 allows access to FSID from userspace.
2753
 
                               VFP3 restricts all id registers to privileged
2754
 
                               accesses.  */
2755
 
                            if (IS_USER(s)
2756
 
                                && arm_feature(env, ARM_FEATURE_VFP3))
2757
 
                                return 1;
2758
 
                            tmp = load_cpu_field(vfp.xregs[rn]);
2759
 
                            break;
2760
 
                        case ARM_VFP_FPEXC:
2761
 
                            if (IS_USER(s))
2762
 
                                return 1;
2763
 
                            tmp = load_cpu_field(vfp.xregs[rn]);
2764
 
                            break;
2765
 
                        case ARM_VFP_FPINST:
2766
 
                        case ARM_VFP_FPINST2:
2767
 
                            /* Not present in VFP3.  */
2768
 
                            if (IS_USER(s)
2769
 
                                || arm_feature(env, ARM_FEATURE_VFP3))
2770
 
                                return 1;
2771
 
                            tmp = load_cpu_field(vfp.xregs[rn]);
2772
 
                            break;
2773
 
                        case ARM_VFP_FPSCR:
2774
 
                            if (rd == 15) {
2775
 
                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2776
 
                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2777
 
                            } else {
2778
 
                                tmp = tcg_temp_new_i32();
2779
 
                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
2780
 
                            }
2781
 
                            break;
2782
 
                        case ARM_VFP_MVFR0:
2783
 
                        case ARM_VFP_MVFR1:
2784
 
                            if (IS_USER(s)
2785
 
                                || !arm_feature(env, ARM_FEATURE_MVFR))
2786
 
                                return 1;
2787
 
                            tmp = load_cpu_field(vfp.xregs[rn]);
2788
 
                            break;
2789
 
                        default:
2790
 
                            return 1;
2791
 
                        }
2792
 
                    } else {
2793
 
                        gen_mov_F0_vreg(0, rn);
2794
 
                        tmp = gen_vfp_mrs();
2795
 
                    }
2796
 
                    if (rd == 15) {
2797
 
                        /* Set the 4 flag bits in the CPSR.  */
2798
 
                        gen_set_nzcv(tmp);
2799
 
                        tcg_temp_free_i32(tmp);
2800
 
                    } else {
2801
 
                        store_reg(s, rd, tmp);
2802
 
                    }
2803
 
                } else {
2804
 
                    /* arm->vfp */
2805
 
                    if (insn & (1 << 21)) {
2806
 
                        rn >>= 1;
2807
 
                        /* system register */
2808
 
                        switch (rn) {
2809
 
                        case ARM_VFP_FPSID:
2810
 
                        case ARM_VFP_MVFR0:
2811
 
                        case ARM_VFP_MVFR1:
2812
 
                            /* Writes are ignored.  */
2813
 
                            break;
2814
 
                        case ARM_VFP_FPSCR:
2815
 
                            tmp = load_reg(s, rd);
2816
 
                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
2817
 
                            tcg_temp_free_i32(tmp);
2818
 
                            gen_lookup_tb(s);
2819
 
                            break;
2820
 
                        case ARM_VFP_FPEXC:
2821
 
                            if (IS_USER(s))
2822
 
                                return 1;
2823
 
                            /* TODO: VFP subarchitecture support.
2824
 
                             * For now, keep the EN bit only */
2825
 
                            tmp = load_reg(s, rd);
2826
 
                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2827
 
                            store_cpu_field(tmp, vfp.xregs[rn]);
2828
 
                            gen_lookup_tb(s);
2829
 
                            break;
2830
 
                        case ARM_VFP_FPINST:
2831
 
                        case ARM_VFP_FPINST2:
2832
 
                            tmp = load_reg(s, rd);
2833
 
                            store_cpu_field(tmp, vfp.xregs[rn]);
2834
 
                            break;
2835
 
                        default:
2836
 
                            return 1;
2837
 
                        }
2838
 
                    } else {
2839
 
                        tmp = load_reg(s, rd);
2840
 
                        gen_vfp_msr(tmp);
2841
 
                        gen_mov_vreg_F0(0, rn);
2842
 
                    }
2843
 
                }
2844
 
            }
2845
 
        } else {
2846
 
            /* data processing */
2847
 
            /* The opcode is in bits 23, 21, 20 and 6.  */
2848
 
            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2849
 
            if (dp) {
2850
 
                if (op == 15) {
2851
 
                    /* rn is opcode */
2852
 
                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2853
 
                } else {
2854
 
                    /* rn is register number */
2855
 
                    VFP_DREG_N(rn, insn);
2856
 
                }
2857
 
 
2858
 
                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2859
 
                    /* Integer or single precision destination.  */
2860
 
                    rd = VFP_SREG_D(insn);
2861
 
                } else {
2862
 
                    VFP_DREG_D(rd, insn);
2863
 
                }
2864
 
                if (op == 15 &&
2865
 
                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2866
 
                    /* VCVT from int is always from S reg regardless of dp bit.
2867
 
                     * VCVT with immediate frac_bits has same format as SREG_M
2868
 
                     */
2869
 
                    rm = VFP_SREG_M(insn);
2870
 
                } else {
2871
 
                    VFP_DREG_M(rm, insn);
2872
 
                }
2873
 
            } else {
2874
 
                rn = VFP_SREG_N(insn);
2875
 
                if (op == 15 && rn == 15) {
2876
 
                    /* Double precision destination.  */
2877
 
                    VFP_DREG_D(rd, insn);
2878
 
                } else {
2879
 
                    rd = VFP_SREG_D(insn);
2880
 
                }
2881
 
                /* NB that we implicitly rely on the encoding for the frac_bits
2882
 
                 * in VCVT of fixed to float being the same as that of an SREG_M
2883
 
                 */
2884
 
                rm = VFP_SREG_M(insn);
2885
 
            }
2886
 
 
2887
 
            veclen = s->vec_len;
2888
 
            if (op == 15 && rn > 3)
2889
 
                veclen = 0;
2890
 
 
2891
 
            /* Shut up compiler warnings.  */
2892
 
            delta_m = 0;
2893
 
            delta_d = 0;
2894
 
            bank_mask = 0;
2895
 
 
2896
 
            if (veclen > 0) {
2897
 
                if (dp)
2898
 
                    bank_mask = 0xc;
2899
 
                else
2900
 
                    bank_mask = 0x18;
2901
 
 
2902
 
                /* Figure out what type of vector operation this is.  */
2903
 
                if ((rd & bank_mask) == 0) {
2904
 
                    /* scalar */
2905
 
                    veclen = 0;
2906
 
                } else {
2907
 
                    if (dp)
2908
 
                        delta_d = (s->vec_stride >> 1) + 1;
2909
 
                    else
2910
 
                        delta_d = s->vec_stride + 1;
2911
 
 
2912
 
                    if ((rm & bank_mask) == 0) {
2913
 
                        /* mixed scalar/vector */
2914
 
                        delta_m = 0;
2915
 
                    } else {
2916
 
                        /* vector */
2917
 
                        delta_m = delta_d;
2918
 
                    }
2919
 
                }
2920
 
            }
2921
 
 
2922
 
            /* Load the initial operands.  */
2923
 
            if (op == 15) {
2924
 
                switch (rn) {
2925
 
                case 16:
2926
 
                case 17:
2927
 
                    /* Integer source */
2928
 
                    gen_mov_F0_vreg(0, rm);
2929
 
                    break;
2930
 
                case 8:
2931
 
                case 9:
2932
 
                    /* Compare */
2933
 
                    gen_mov_F0_vreg(dp, rd);
2934
 
                    gen_mov_F1_vreg(dp, rm);
2935
 
                    break;
2936
 
                case 10:
2937
 
                case 11:
2938
 
                    /* Compare with zero */
2939
 
                    gen_mov_F0_vreg(dp, rd);
2940
 
                    gen_vfp_F1_ld0(dp);
2941
 
                    break;
2942
 
                case 20:
2943
 
                case 21:
2944
 
                case 22:
2945
 
                case 23:
2946
 
                case 28:
2947
 
                case 29:
2948
 
                case 30:
2949
 
                case 31:
2950
 
                    /* Source and destination the same.  */
2951
 
                    gen_mov_F0_vreg(dp, rd);
2952
 
                    break;
2953
 
                case 4:
2954
 
                case 5:
2955
 
                case 6:
2956
 
                case 7:
2957
 
                    /* VCVTB, VCVTT: only present with the halfprec extension,
2958
 
                     * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2959
 
                     */
2960
 
                    if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
2961
 
                        return 1;
2962
 
                    }
2963
 
                    /* Otherwise fall through */
2964
 
                default:
2965
 
                    /* One source operand.  */
2966
 
                    gen_mov_F0_vreg(dp, rm);
2967
 
                    break;
2968
 
                }
2969
 
            } else {
2970
 
                /* Two source operands.  */
2971
 
                gen_mov_F0_vreg(dp, rn);
2972
 
                gen_mov_F1_vreg(dp, rm);
2973
 
            }
2974
 
 
2975
 
            for (;;) {
2976
 
                /* Perform the calculation.  */
2977
 
                switch (op) {
2978
 
                case 0: /* VMLA: fd + (fn * fm) */
2979
 
                    /* Note that order of inputs to the add matters for NaNs */
2980
 
                    gen_vfp_F1_mul(dp);
2981
 
                    gen_mov_F0_vreg(dp, rd);
2982
 
                    gen_vfp_add(dp);
2983
 
                    break;
2984
 
                case 1: /* VMLS: fd + -(fn * fm) */
2985
 
                    gen_vfp_mul(dp);
2986
 
                    gen_vfp_F1_neg(dp);
2987
 
                    gen_mov_F0_vreg(dp, rd);
2988
 
                    gen_vfp_add(dp);
2989
 
                    break;
2990
 
                case 2: /* VNMLS: -fd + (fn * fm) */
2991
 
                    /* Note that it isn't valid to replace (-A + B) with (B - A)
2992
 
                     * or similar plausible looking simplifications
2993
 
                     * because this will give wrong results for NaNs.
2994
 
                     */
2995
 
                    gen_vfp_F1_mul(dp);
2996
 
                    gen_mov_F0_vreg(dp, rd);
2997
 
                    gen_vfp_neg(dp);
2998
 
                    gen_vfp_add(dp);
2999
 
                    break;
3000
 
                case 3: /* VNMLA: -fd + -(fn * fm) */
3001
 
                    gen_vfp_mul(dp);
3002
 
                    gen_vfp_F1_neg(dp);
3003
 
                    gen_mov_F0_vreg(dp, rd);
3004
 
                    gen_vfp_neg(dp);
3005
 
                    gen_vfp_add(dp);
3006
 
                    break;
3007
 
                case 4: /* mul: fn * fm */
3008
 
                    gen_vfp_mul(dp);
3009
 
                    break;
3010
 
                case 5: /* nmul: -(fn * fm) */
3011
 
                    gen_vfp_mul(dp);
3012
 
                    gen_vfp_neg(dp);
3013
 
                    break;
3014
 
                case 6: /* add: fn + fm */
3015
 
                    gen_vfp_add(dp);
3016
 
                    break;
3017
 
                case 7: /* sub: fn - fm */
3018
 
                    gen_vfp_sub(dp);
3019
 
                    break;
3020
 
                case 8: /* div: fn / fm */
3021
 
                    gen_vfp_div(dp);
3022
 
                    break;
3023
 
                case 10: /* VFNMA : fd = muladd(-fd,  fn, fm) */
3024
 
                case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3025
 
                case 12: /* VFMA  : fd = muladd( fd,  fn, fm) */
3026
 
                case 13: /* VFMS  : fd = muladd( fd, -fn, fm) */
3027
 
                    /* These are fused multiply-add, and must be done as one
3028
 
                     * floating point operation with no rounding between the
3029
 
                     * multiplication and addition steps.
3030
 
                     * NB that doing the negations here as separate steps is
3031
 
                     * correct : an input NaN should come out with its sign bit
3032
 
                     * flipped if it is a negated-input.
3033
 
                     */
3034
 
                    if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3035
 
                        return 1;
3036
 
                    }
3037
 
                    if (dp) {
3038
 
                        TCGv_ptr fpst;
3039
 
                        TCGv_i64 frd;
3040
 
                        if (op & 1) {
3041
 
                            /* VFNMS, VFMS */
3042
 
                            gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3043
 
                        }
3044
 
                        frd = tcg_temp_new_i64();
3045
 
                        tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3046
 
                        if (op & 2) {
3047
 
                            /* VFNMA, VFNMS */
3048
 
                            gen_helper_vfp_negd(frd, frd);
3049
 
                        }
3050
 
                        fpst = get_fpstatus_ptr(0);
3051
 
                        gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3052
 
                                               cpu_F1d, frd, fpst);
3053
 
                        tcg_temp_free_ptr(fpst);
3054
 
                        tcg_temp_free_i64(frd);
3055
 
                    } else {
3056
 
                        TCGv_ptr fpst;
3057
 
                        TCGv_i32 frd;
3058
 
                        if (op & 1) {
3059
 
                            /* VFNMS, VFMS */
3060
 
                            gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3061
 
                        }
3062
 
                        frd = tcg_temp_new_i32();
3063
 
                        tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3064
 
                        if (op & 2) {
3065
 
                            gen_helper_vfp_negs(frd, frd);
3066
 
                        }
3067
 
                        fpst = get_fpstatus_ptr(0);
3068
 
                        gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3069
 
                                               cpu_F1s, frd, fpst);
3070
 
                        tcg_temp_free_ptr(fpst);
3071
 
                        tcg_temp_free_i32(frd);
3072
 
                    }
3073
 
                    break;
3074
 
                case 14: /* fconst */
3075
 
                    if (!arm_feature(env, ARM_FEATURE_VFP3))
3076
 
                      return 1;
3077
 
 
3078
 
                    n = (insn << 12) & 0x80000000;
3079
 
                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3080
 
                    if (dp) {
3081
 
                        if (i & 0x40)
3082
 
                            i |= 0x3f80;
3083
 
                        else
3084
 
                            i |= 0x4000;
3085
 
                        n |= i << 16;
3086
 
                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3087
 
                    } else {
3088
 
                        if (i & 0x40)
3089
 
                            i |= 0x780;
3090
 
                        else
3091
 
                            i |= 0x800;
3092
 
                        n |= i << 19;
3093
 
                        tcg_gen_movi_i32(cpu_F0s, n);
3094
 
                    }
3095
 
                    break;
3096
 
                case 15: /* extension space */
3097
 
                    switch (rn) {
3098
 
                    case 0: /* cpy */
3099
 
                        /* no-op */
3100
 
                        break;
3101
 
                    case 1: /* abs */
3102
 
                        gen_vfp_abs(dp);
3103
 
                        break;
3104
 
                    case 2: /* neg */
3105
 
                        gen_vfp_neg(dp);
3106
 
                        break;
3107
 
                    case 3: /* sqrt */
3108
 
                        gen_vfp_sqrt(dp);
3109
 
                        break;
3110
 
                    case 4: /* vcvtb.f32.f16 */
3111
 
                        tmp = gen_vfp_mrs();
3112
 
                        tcg_gen_ext16u_i32(tmp, tmp);
3113
 
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3114
 
                        tcg_temp_free_i32(tmp);
3115
 
                        break;
3116
 
                    case 5: /* vcvtt.f32.f16 */
3117
 
                        tmp = gen_vfp_mrs();
3118
 
                        tcg_gen_shri_i32(tmp, tmp, 16);
3119
 
                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3120
 
                        tcg_temp_free_i32(tmp);
3121
 
                        break;
3122
 
                    case 6: /* vcvtb.f16.f32 */
3123
 
                        tmp = tcg_temp_new_i32();
3124
 
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3125
 
                        gen_mov_F0_vreg(0, rd);
3126
 
                        tmp2 = gen_vfp_mrs();
3127
 
                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3128
 
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3129
 
                        tcg_temp_free_i32(tmp2);
3130
 
                        gen_vfp_msr(tmp);
3131
 
                        break;
3132
 
                    case 7: /* vcvtt.f16.f32 */
3133
 
                        tmp = tcg_temp_new_i32();
3134
 
                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3135
 
                        tcg_gen_shli_i32(tmp, tmp, 16);
3136
 
                        gen_mov_F0_vreg(0, rd);
3137
 
                        tmp2 = gen_vfp_mrs();
3138
 
                        tcg_gen_ext16u_i32(tmp2, tmp2);
3139
 
                        tcg_gen_or_i32(tmp, tmp, tmp2);
3140
 
                        tcg_temp_free_i32(tmp2);
3141
 
                        gen_vfp_msr(tmp);
3142
 
                        break;
3143
 
                    case 8: /* cmp */
3144
 
                        gen_vfp_cmp(dp);
3145
 
                        break;
3146
 
                    case 9: /* cmpe */
3147
 
                        gen_vfp_cmpe(dp);
3148
 
                        break;
3149
 
                    case 10: /* cmpz */
3150
 
                        gen_vfp_cmp(dp);
3151
 
                        break;
3152
 
                    case 11: /* cmpez */
3153
 
                        gen_vfp_F1_ld0(dp);
3154
 
                        gen_vfp_cmpe(dp);
3155
 
                        break;
3156
 
                    case 15: /* single<->double conversion */
3157
 
                        if (dp)
3158
 
                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3159
 
                        else
3160
 
                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3161
 
                        break;
3162
 
                    case 16: /* fuito */
3163
 
                        gen_vfp_uito(dp, 0);
3164
 
                        break;
3165
 
                    case 17: /* fsito */
3166
 
                        gen_vfp_sito(dp, 0);
3167
 
                        break;
3168
 
                    case 20: /* fshto */
3169
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3170
 
                          return 1;
3171
 
                        gen_vfp_shto(dp, 16 - rm, 0);
3172
 
                        break;
3173
 
                    case 21: /* fslto */
3174
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3175
 
                          return 1;
3176
 
                        gen_vfp_slto(dp, 32 - rm, 0);
3177
 
                        break;
3178
 
                    case 22: /* fuhto */
3179
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3180
 
                          return 1;
3181
 
                        gen_vfp_uhto(dp, 16 - rm, 0);
3182
 
                        break;
3183
 
                    case 23: /* fulto */
3184
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3185
 
                          return 1;
3186
 
                        gen_vfp_ulto(dp, 32 - rm, 0);
3187
 
                        break;
3188
 
                    case 24: /* ftoui */
3189
 
                        gen_vfp_toui(dp, 0);
3190
 
                        break;
3191
 
                    case 25: /* ftouiz */
3192
 
                        gen_vfp_touiz(dp, 0);
3193
 
                        break;
3194
 
                    case 26: /* ftosi */
3195
 
                        gen_vfp_tosi(dp, 0);
3196
 
                        break;
3197
 
                    case 27: /* ftosiz */
3198
 
                        gen_vfp_tosiz(dp, 0);
3199
 
                        break;
3200
 
                    case 28: /* ftosh */
3201
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3202
 
                          return 1;
3203
 
                        gen_vfp_tosh(dp, 16 - rm, 0);
3204
 
                        break;
3205
 
                    case 29: /* ftosl */
3206
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3207
 
                          return 1;
3208
 
                        gen_vfp_tosl(dp, 32 - rm, 0);
3209
 
                        break;
3210
 
                    case 30: /* ftouh */
3211
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3212
 
                          return 1;
3213
 
                        gen_vfp_touh(dp, 16 - rm, 0);
3214
 
                        break;
3215
 
                    case 31: /* ftoul */
3216
 
                        if (!arm_feature(env, ARM_FEATURE_VFP3))
3217
 
                          return 1;
3218
 
                        gen_vfp_toul(dp, 32 - rm, 0);
3219
 
                        break;
3220
 
                    default: /* undefined */
3221
 
                        return 1;
3222
 
                    }
3223
 
                    break;
3224
 
                default: /* undefined */
3225
 
                    return 1;
3226
 
                }
3227
 
 
3228
 
                /* Write back the result.  */
3229
 
                if (op == 15 && (rn >= 8 && rn <= 11))
3230
 
                    ; /* Comparison, do nothing.  */
3231
 
                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3232
 
                    /* VCVT double to int: always integer result. */
3233
 
                    gen_mov_vreg_F0(0, rd);
3234
 
                else if (op == 15 && rn == 15)
3235
 
                    /* conversion */
3236
 
                    gen_mov_vreg_F0(!dp, rd);
3237
 
                else
3238
 
                    gen_mov_vreg_F0(dp, rd);
3239
 
 
3240
 
                /* break out of the loop if we have finished  */
3241
 
                if (veclen == 0)
3242
 
                    break;
3243
 
 
3244
 
                if (op == 15 && delta_m == 0) {
3245
 
                    /* single source one-many */
3246
 
                    while (veclen--) {
3247
 
                        rd = ((rd + delta_d) & (bank_mask - 1))
3248
 
                             | (rd & bank_mask);
3249
 
                        gen_mov_vreg_F0(dp, rd);
3250
 
                    }
3251
 
                    break;
3252
 
                }
3253
 
                /* Setup the next operands.  */
3254
 
                veclen--;
3255
 
                rd = ((rd + delta_d) & (bank_mask - 1))
3256
 
                     | (rd & bank_mask);
3257
 
 
3258
 
                if (op == 15) {
3259
 
                    /* One source operand.  */
3260
 
                    rm = ((rm + delta_m) & (bank_mask - 1))
3261
 
                         | (rm & bank_mask);
3262
 
                    gen_mov_F0_vreg(dp, rm);
3263
 
                } else {
3264
 
                    /* Two source operands.  */
3265
 
                    rn = ((rn + delta_d) & (bank_mask - 1))
3266
 
                         | (rn & bank_mask);
3267
 
                    gen_mov_F0_vreg(dp, rn);
3268
 
                    if (delta_m) {
3269
 
                        rm = ((rm + delta_m) & (bank_mask - 1))
3270
 
                             | (rm & bank_mask);
3271
 
                        gen_mov_F1_vreg(dp, rm);
3272
 
                    }
3273
 
                }
3274
 
            }
3275
 
        }
3276
 
        break;
3277
 
    case 0xc:
3278
 
    case 0xd:
3279
 
        if ((insn & 0x03e00000) == 0x00400000) {
3280
 
            /* two-register transfer */
3281
 
            rn = (insn >> 16) & 0xf;
3282
 
            rd = (insn >> 12) & 0xf;
3283
 
            if (dp) {
3284
 
                VFP_DREG_M(rm, insn);
3285
 
            } else {
3286
 
                rm = VFP_SREG_M(insn);
3287
 
            }
3288
 
 
3289
 
            if (insn & ARM_CP_RW_BIT) {
3290
 
                /* vfp->arm */
3291
 
                if (dp) {
3292
 
                    gen_mov_F0_vreg(0, rm * 2);
3293
 
                    tmp = gen_vfp_mrs();
3294
 
                    store_reg(s, rd, tmp);
3295
 
                    gen_mov_F0_vreg(0, rm * 2 + 1);
3296
 
                    tmp = gen_vfp_mrs();
3297
 
                    store_reg(s, rn, tmp);
3298
 
                } else {
3299
 
                    gen_mov_F0_vreg(0, rm);
3300
 
                    tmp = gen_vfp_mrs();
3301
 
                    store_reg(s, rd, tmp);
3302
 
                    gen_mov_F0_vreg(0, rm + 1);
3303
 
                    tmp = gen_vfp_mrs();
3304
 
                    store_reg(s, rn, tmp);
3305
 
                }
3306
 
            } else {
3307
 
                /* arm->vfp */
3308
 
                if (dp) {
3309
 
                    tmp = load_reg(s, rd);
3310
 
                    gen_vfp_msr(tmp);
3311
 
                    gen_mov_vreg_F0(0, rm * 2);
3312
 
                    tmp = load_reg(s, rn);
3313
 
                    gen_vfp_msr(tmp);
3314
 
                    gen_mov_vreg_F0(0, rm * 2 + 1);
3315
 
                } else {
3316
 
                    tmp = load_reg(s, rd);
3317
 
                    gen_vfp_msr(tmp);
3318
 
                    gen_mov_vreg_F0(0, rm);
3319
 
                    tmp = load_reg(s, rn);
3320
 
                    gen_vfp_msr(tmp);
3321
 
                    gen_mov_vreg_F0(0, rm + 1);
3322
 
                }
3323
 
            }
3324
 
        } else {
3325
 
            /* Load/store */
3326
 
            rn = (insn >> 16) & 0xf;
3327
 
            if (dp)
3328
 
                VFP_DREG_D(rd, insn);
3329
 
            else
3330
 
                rd = VFP_SREG_D(insn);
3331
 
            if ((insn & 0x01200000) == 0x01000000) {
3332
 
                /* Single load/store */
3333
 
                offset = (insn & 0xff) << 2;
3334
 
                if ((insn & (1 << 23)) == 0)
3335
 
                    offset = -offset;
3336
 
                if (s->thumb && rn == 15) {
3337
 
                    /* This is actually UNPREDICTABLE */
3338
 
                    addr = tcg_temp_new_i32();
3339
 
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3340
 
                } else {
3341
 
                    addr = load_reg(s, rn);
3342
 
                }
3343
 
                tcg_gen_addi_i32(addr, addr, offset);
3344
 
                if (insn & (1 << 20)) {
3345
 
                    gen_vfp_ld(s, dp, addr);
3346
 
                    gen_mov_vreg_F0(dp, rd);
3347
 
                } else {
3348
 
                    gen_mov_F0_vreg(dp, rd);
3349
 
                    gen_vfp_st(s, dp, addr);
3350
 
                }
3351
 
                tcg_temp_free_i32(addr);
3352
 
            } else {
3353
 
                /* load/store multiple */
3354
 
                int w = insn & (1 << 21);
3355
 
                if (dp)
3356
 
                    n = (insn >> 1) & 0x7f;
3357
 
                else
3358
 
                    n = insn & 0xff;
3359
 
 
3360
 
                if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3361
 
                    /* P == U , W == 1  => UNDEF */
3362
 
                    return 1;
3363
 
                }
3364
 
                if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3365
 
                    /* UNPREDICTABLE cases for bad immediates: we choose to
3366
 
                     * UNDEF to avoid generating huge numbers of TCG ops
3367
 
                     */
3368
 
                    return 1;
3369
 
                }
3370
 
                if (rn == 15 && w) {
3371
 
                    /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3372
 
                    return 1;
3373
 
                }
3374
 
 
3375
 
                if (s->thumb && rn == 15) {
3376
 
                    /* This is actually UNPREDICTABLE */
3377
 
                    addr = tcg_temp_new_i32();
3378
 
                    tcg_gen_movi_i32(addr, s->pc & ~2);
3379
 
                } else {
3380
 
                    addr = load_reg(s, rn);
3381
 
                }
3382
 
                if (insn & (1 << 24)) /* pre-decrement */
3383
 
                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3384
 
 
3385
 
                if (dp)
3386
 
                    offset = 8;
3387
 
                else
3388
 
                    offset = 4;
3389
 
                for (i = 0; i < n; i++) {
3390
 
                    if (insn & ARM_CP_RW_BIT) {
3391
 
                        /* load */
3392
 
                        gen_vfp_ld(s, dp, addr);
3393
 
                        gen_mov_vreg_F0(dp, rd + i);
3394
 
                    } else {
3395
 
                        /* store */
3396
 
                        gen_mov_F0_vreg(dp, rd + i);
3397
 
                        gen_vfp_st(s, dp, addr);
3398
 
                    }
3399
 
                    tcg_gen_addi_i32(addr, addr, offset);
3400
 
                }
3401
 
                if (w) {
3402
 
                    /* writeback */
3403
 
                    if (insn & (1 << 24))
3404
 
                        offset = -offset * n;
3405
 
                    else if (dp && (insn & 1))
3406
 
                        offset = 4;
3407
 
                    else
3408
 
                        offset = 0;
3409
 
 
3410
 
                    if (offset != 0)
3411
 
                        tcg_gen_addi_i32(addr, addr, offset);
3412
 
                    store_reg(s, rn, addr);
3413
 
                } else {
3414
 
                    tcg_temp_free_i32(addr);
3415
 
                }
3416
 
            }
3417
 
        }
3418
 
        break;
3419
 
    default:
3420
 
        /* Should never happen.  */
3421
 
        return 1;
3422
 
    }
3423
 
    return 0;
3424
 
}
3425
 
 
3426
 
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3427
 
{
3428
 
    TranslationBlock *tb;
3429
 
 
3430
 
    tb = s->tb;
3431
 
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3432
 
        tcg_gen_goto_tb(n);
3433
 
        gen_set_pc_im(s, dest);
3434
 
        tcg_gen_exit_tb((uintptr_t)tb + n);
3435
 
    } else {
3436
 
        gen_set_pc_im(s, dest);
3437
 
        tcg_gen_exit_tb(0);
3438
 
    }
3439
 
}
3440
 
 
3441
 
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3442
 
{
3443
 
    if (unlikely(s->singlestep_enabled)) {
3444
 
        /* An indirect jump so that we still trigger the debug exception.  */
3445
 
        if (s->thumb)
3446
 
            dest |= 1;
3447
 
        gen_bx_im(s, dest);
3448
 
    } else {
3449
 
        gen_goto_tb(s, 0, dest);
3450
 
        s->is_jmp = DISAS_TB_JUMP;
3451
 
    }
3452
 
}
3453
 
 
3454
 
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3455
 
{
3456
 
    if (x)
3457
 
        tcg_gen_sari_i32(t0, t0, 16);
3458
 
    else
3459
 
        gen_sxth(t0);
3460
 
    if (y)
3461
 
        tcg_gen_sari_i32(t1, t1, 16);
3462
 
    else
3463
 
        gen_sxth(t1);
3464
 
    tcg_gen_mul_i32(t0, t0, t1);
3465
 
}
3466
 
 
3467
 
/* Return the mask of PSR bits set by a MSR instruction.  */
3468
 
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3469
 
    uint32_t mask;
3470
 
 
3471
 
    mask = 0;
3472
 
    if (flags & (1 << 0))
3473
 
        mask |= 0xff;
3474
 
    if (flags & (1 << 1))
3475
 
        mask |= 0xff00;
3476
 
    if (flags & (1 << 2))
3477
 
        mask |= 0xff0000;
3478
 
    if (flags & (1 << 3))
3479
 
        mask |= 0xff000000;
3480
 
 
3481
 
    /* Mask out undefined bits.  */
3482
 
    mask &= ~CPSR_RESERVED;
3483
 
    if (!arm_feature(env, ARM_FEATURE_V4T))
3484
 
        mask &= ~CPSR_T;
3485
 
    if (!arm_feature(env, ARM_FEATURE_V5))
3486
 
        mask &= ~CPSR_Q; /* V5TE in reality*/
3487
 
    if (!arm_feature(env, ARM_FEATURE_V6))
3488
 
        mask &= ~(CPSR_E | CPSR_GE);
3489
 
    if (!arm_feature(env, ARM_FEATURE_THUMB2))
3490
 
        mask &= ~CPSR_IT;
3491
 
    /* Mask out execution state bits.  */
3492
 
    if (!spsr)
3493
 
        mask &= ~CPSR_EXEC;
3494
 
    /* Mask out privileged bits.  */
3495
 
    if (IS_USER(s))
3496
 
        mask &= CPSR_USER;
3497
 
    return mask;
3498
 
}
3499
 
 
3500
 
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3501
 
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3502
 
{
3503
 
    TCGv_i32 tmp;
3504
 
    if (spsr) {
3505
 
        /* ??? This is also undefined in system mode.  */
3506
 
        if (IS_USER(s))
3507
 
            return 1;
3508
 
 
3509
 
        tmp = load_cpu_field(spsr);
3510
 
        tcg_gen_andi_i32(tmp, tmp, ~mask);
3511
 
        tcg_gen_andi_i32(t0, t0, mask);
3512
 
        tcg_gen_or_i32(tmp, tmp, t0);
3513
 
        store_cpu_field(tmp, spsr);
3514
 
    } else {
3515
 
        gen_set_cpsr(t0, mask);
3516
 
    }
3517
 
    tcg_temp_free_i32(t0);
3518
 
    gen_lookup_tb(s);
3519
 
    return 0;
3520
 
}
3521
 
 
3522
 
/* Returns nonzero if access to the PSR is not permitted.  */
3523
 
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3524
 
{
3525
 
    TCGv_i32 tmp;
3526
 
    tmp = tcg_temp_new_i32();
3527
 
    tcg_gen_movi_i32(tmp, val);
3528
 
    return gen_set_psr(s, mask, spsr, tmp);
3529
 
}
3530
 
 
3531
 
/* Generate an old-style exception return. Marks pc as dead. */
3532
 
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3533
 
{
3534
 
    TCGv_i32 tmp;
3535
 
    store_reg(s, 15, pc);
3536
 
    tmp = load_cpu_field(spsr);
3537
 
    gen_set_cpsr(tmp, 0xffffffff);
3538
 
    tcg_temp_free_i32(tmp);
3539
 
    s->is_jmp = DISAS_UPDATE;
3540
 
}
3541
 
 
3542
 
/* Generate a v6 exception return.  Marks both values as dead.  */
3543
 
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3544
 
{
3545
 
    gen_set_cpsr(cpsr, 0xffffffff);
3546
 
    tcg_temp_free_i32(cpsr);
3547
 
    store_reg(s, 15, pc);
3548
 
    s->is_jmp = DISAS_UPDATE;
3549
 
}
3550
 
 
3551
 
static inline void
3552
 
gen_set_condexec (DisasContext *s)
3553
 
{
3554
 
    if (s->condexec_mask) {
3555
 
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3556
 
        TCGv_i32 tmp = tcg_temp_new_i32();
3557
 
        tcg_gen_movi_i32(tmp, val);
3558
 
        store_cpu_field(tmp, condexec_bits);
3559
 
    }
3560
 
}
3561
 
 
3562
 
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3563
 
{
3564
 
    gen_set_condexec(s);
3565
 
    gen_set_pc_im(s, s->pc - offset);
3566
 
    gen_exception(excp);
3567
 
    s->is_jmp = DISAS_JUMP;
3568
 
}
3569
 
 
3570
 
static void gen_nop_hint(DisasContext *s, int val)
3571
 
{
3572
 
    switch (val) {
3573
 
    case 3: /* wfi */
3574
 
        gen_set_pc_im(s, s->pc);
3575
 
        s->is_jmp = DISAS_WFI;
3576
 
        break;
3577
 
    case 2: /* wfe */
3578
 
    case 4: /* sev */
3579
 
    case 5: /* sevl */
3580
 
        /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */
3581
 
    default: /* nop */
3582
 
        break;
3583
 
    }
3584
 
}
3585
 
 
3586
 
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3587
 
 
3588
 
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3589
 
{
3590
 
    switch (size) {
3591
 
    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3592
 
    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3593
 
    case 2: tcg_gen_add_i32(t0, t0, t1); break;
3594
 
    default: abort();
3595
 
    }
3596
 
}
3597
 
 
3598
 
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3599
 
{
3600
 
    switch (size) {
3601
 
    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3602
 
    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3603
 
    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3604
 
    default: return;
3605
 
    }
3606
 
}
3607
 
 
3608
 
/* 32-bit pairwise ops end up the same as the elementwise versions.  */
3609
 
#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
3610
 
#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
3611
 
#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
3612
 
#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
3613
 
 
3614
 
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3615
 
    switch ((size << 1) | u) { \
3616
 
    case 0: \
3617
 
        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3618
 
        break; \
3619
 
    case 1: \
3620
 
        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3621
 
        break; \
3622
 
    case 2: \
3623
 
        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3624
 
        break; \
3625
 
    case 3: \
3626
 
        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3627
 
        break; \
3628
 
    case 4: \
3629
 
        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3630
 
        break; \
3631
 
    case 5: \
3632
 
        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3633
 
        break; \
3634
 
    default: return 1; \
3635
 
    }} while (0)
3636
 
 
3637
 
#define GEN_NEON_INTEGER_OP(name) do { \
3638
 
    switch ((size << 1) | u) { \
3639
 
    case 0: \
3640
 
        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3641
 
        break; \
3642
 
    case 1: \
3643
 
        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3644
 
        break; \
3645
 
    case 2: \
3646
 
        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3647
 
        break; \
3648
 
    case 3: \
3649
 
        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3650
 
        break; \
3651
 
    case 4: \
3652
 
        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3653
 
        break; \
3654
 
    case 5: \
3655
 
        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3656
 
        break; \
3657
 
    default: return 1; \
3658
 
    }} while (0)
3659
 
 
3660
 
static TCGv_i32 neon_load_scratch(int scratch)
3661
 
{
3662
 
    TCGv_i32 tmp = tcg_temp_new_i32();
3663
 
    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3664
 
    return tmp;
3665
 
}
3666
 
 
3667
 
static void neon_store_scratch(int scratch, TCGv_i32 var)
3668
 
{
3669
 
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3670
 
    tcg_temp_free_i32(var);
3671
 
}
3672
 
 
3673
 
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3674
 
{
3675
 
    TCGv_i32 tmp;
3676
 
    if (size == 1) {
3677
 
        tmp = neon_load_reg(reg & 7, reg >> 4);
3678
 
        if (reg & 8) {
3679
 
            gen_neon_dup_high16(tmp);
3680
 
        } else {
3681
 
            gen_neon_dup_low16(tmp);
3682
 
        }
3683
 
    } else {
3684
 
        tmp = neon_load_reg(reg & 15, reg >> 4);
3685
 
    }
3686
 
    return tmp;
3687
 
}
3688
 
 
3689
 
static int gen_neon_unzip(int rd, int rm, int size, int q)
3690
 
{
3691
 
    TCGv_i32 tmp, tmp2;
3692
 
    if (!q && size == 2) {
3693
 
        return 1;
3694
 
    }
3695
 
    tmp = tcg_const_i32(rd);
3696
 
    tmp2 = tcg_const_i32(rm);
3697
 
    if (q) {
3698
 
        switch (size) {
3699
 
        case 0:
3700
 
            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3701
 
            break;
3702
 
        case 1:
3703
 
            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3704
 
            break;
3705
 
        case 2:
3706
 
            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3707
 
            break;
3708
 
        default:
3709
 
            abort();
3710
 
        }
3711
 
    } else {
3712
 
        switch (size) {
3713
 
        case 0:
3714
 
            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3715
 
            break;
3716
 
        case 1:
3717
 
            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3718
 
            break;
3719
 
        default:
3720
 
            abort();
3721
 
        }
3722
 
    }
3723
 
    tcg_temp_free_i32(tmp);
3724
 
    tcg_temp_free_i32(tmp2);
3725
 
    return 0;
3726
 
}
3727
 
 
3728
 
static int gen_neon_zip(int rd, int rm, int size, int q)
3729
 
{
3730
 
    TCGv_i32 tmp, tmp2;
3731
 
    if (!q && size == 2) {
3732
 
        return 1;
3733
 
    }
3734
 
    tmp = tcg_const_i32(rd);
3735
 
    tmp2 = tcg_const_i32(rm);
3736
 
    if (q) {
3737
 
        switch (size) {
3738
 
        case 0:
3739
 
            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3740
 
            break;
3741
 
        case 1:
3742
 
            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3743
 
            break;
3744
 
        case 2:
3745
 
            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3746
 
            break;
3747
 
        default:
3748
 
            abort();
3749
 
        }
3750
 
    } else {
3751
 
        switch (size) {
3752
 
        case 0:
3753
 
            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3754
 
            break;
3755
 
        case 1:
3756
 
            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3757
 
            break;
3758
 
        default:
3759
 
            abort();
3760
 
        }
3761
 
    }
3762
 
    tcg_temp_free_i32(tmp);
3763
 
    tcg_temp_free_i32(tmp2);
3764
 
    return 0;
3765
 
}
3766
 
 
3767
 
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3768
 
{
3769
 
    TCGv_i32 rd, tmp;
3770
 
 
3771
 
    rd = tcg_temp_new_i32();
3772
 
    tmp = tcg_temp_new_i32();
3773
 
 
3774
 
    tcg_gen_shli_i32(rd, t0, 8);
3775
 
    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3776
 
    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3777
 
    tcg_gen_or_i32(rd, rd, tmp);
3778
 
 
3779
 
    tcg_gen_shri_i32(t1, t1, 8);
3780
 
    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3781
 
    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3782
 
    tcg_gen_or_i32(t1, t1, tmp);
3783
 
    tcg_gen_mov_i32(t0, rd);
3784
 
 
3785
 
    tcg_temp_free_i32(tmp);
3786
 
    tcg_temp_free_i32(rd);
3787
 
}
3788
 
 
3789
 
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3790
 
{
3791
 
    TCGv_i32 rd, tmp;
3792
 
 
3793
 
    rd = tcg_temp_new_i32();
3794
 
    tmp = tcg_temp_new_i32();
3795
 
 
3796
 
    tcg_gen_shli_i32(rd, t0, 16);
3797
 
    tcg_gen_andi_i32(tmp, t1, 0xffff);
3798
 
    tcg_gen_or_i32(rd, rd, tmp);
3799
 
    tcg_gen_shri_i32(t1, t1, 16);
3800
 
    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3801
 
    tcg_gen_or_i32(t1, t1, tmp);
3802
 
    tcg_gen_mov_i32(t0, rd);
3803
 
 
3804
 
    tcg_temp_free_i32(tmp);
3805
 
    tcg_temp_free_i32(rd);
3806
 
}
3807
 
 
3808
 
 
3809
 
static struct {
3810
 
    int nregs;
3811
 
    int interleave;
3812
 
    int spacing;
3813
 
} neon_ls_element_type[11] = {
3814
 
    {4, 4, 1},
3815
 
    {4, 4, 2},
3816
 
    {4, 1, 1},
3817
 
    {4, 2, 1},
3818
 
    {3, 3, 1},
3819
 
    {3, 3, 2},
3820
 
    {3, 1, 1},
3821
 
    {1, 1, 1},
3822
 
    {2, 2, 1},
3823
 
    {2, 2, 2},
3824
 
    {2, 1, 1}
3825
 
};
3826
 
 
3827
 
/* Translate a NEON load/store element instruction.  Return nonzero if the
3828
 
   instruction is invalid.  */
3829
 
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
3830
 
{
3831
 
    int rd, rn, rm;
3832
 
    int op;
3833
 
    int nregs;
3834
 
    int interleave;
3835
 
    int spacing;
3836
 
    int stride;
3837
 
    int size;
3838
 
    int reg;
3839
 
    int pass;
3840
 
    int load;
3841
 
    int shift;
3842
 
    int n;
3843
 
    TCGv_i32 addr;
3844
 
    TCGv_i32 tmp;
3845
 
    TCGv_i32 tmp2;
3846
 
    TCGv_i64 tmp64;
3847
 
 
3848
 
    if (!s->vfp_enabled)
3849
 
      return 1;
3850
 
    VFP_DREG_D(rd, insn);
3851
 
    rn = (insn >> 16) & 0xf;
3852
 
    rm = insn & 0xf;
3853
 
    load = (insn & (1 << 21)) != 0;
3854
 
    if ((insn & (1 << 23)) == 0) {
3855
 
        /* Load store all elements.  */
3856
 
        op = (insn >> 8) & 0xf;
3857
 
        size = (insn >> 6) & 3;
3858
 
        if (op > 10)
3859
 
            return 1;
3860
 
        /* Catch UNDEF cases for bad values of align field */
3861
 
        switch (op & 0xc) {
3862
 
        case 4:
3863
 
            if (((insn >> 5) & 1) == 1) {
3864
 
                return 1;
3865
 
            }
3866
 
            break;
3867
 
        case 8:
3868
 
            if (((insn >> 4) & 3) == 3) {
3869
 
                return 1;
3870
 
            }
3871
 
            break;
3872
 
        default:
3873
 
            break;
3874
 
        }
3875
 
        nregs = neon_ls_element_type[op].nregs;
3876
 
        interleave = neon_ls_element_type[op].interleave;
3877
 
        spacing = neon_ls_element_type[op].spacing;
3878
 
        if (size == 3 && (interleave | spacing) != 1)
3879
 
            return 1;
3880
 
        addr = tcg_temp_new_i32();
3881
 
        load_reg_var(s, addr, rn);
3882
 
        stride = (1 << size) * interleave;
3883
 
        for (reg = 0; reg < nregs; reg++) {
3884
 
            if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3885
 
                load_reg_var(s, addr, rn);
3886
 
                tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3887
 
            } else if (interleave == 2 && nregs == 4 && reg == 2) {
3888
 
                load_reg_var(s, addr, rn);
3889
 
                tcg_gen_addi_i32(addr, addr, 1 << size);
3890
 
            }
3891
 
            if (size == 3) {
3892
 
                tmp64 = tcg_temp_new_i64();
3893
 
                if (load) {
3894
 
                    gen_aa32_ld64(tmp64, addr, IS_USER(s));
3895
 
                    neon_store_reg64(tmp64, rd);
3896
 
                } else {
3897
 
                    neon_load_reg64(tmp64, rd);
3898
 
                    gen_aa32_st64(tmp64, addr, IS_USER(s));
3899
 
                }
3900
 
                tcg_temp_free_i64(tmp64);
3901
 
                tcg_gen_addi_i32(addr, addr, stride);
3902
 
            } else {
3903
 
                for (pass = 0; pass < 2; pass++) {
3904
 
                    if (size == 2) {
3905
 
                        if (load) {
3906
 
                            tmp = tcg_temp_new_i32();
3907
 
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
3908
 
                            neon_store_reg(rd, pass, tmp);
3909
 
                        } else {
3910
 
                            tmp = neon_load_reg(rd, pass);
3911
 
                            gen_aa32_st32(tmp, addr, IS_USER(s));
3912
 
                            tcg_temp_free_i32(tmp);
3913
 
                        }
3914
 
                        tcg_gen_addi_i32(addr, addr, stride);
3915
 
                    } else if (size == 1) {
3916
 
                        if (load) {
3917
 
                            tmp = tcg_temp_new_i32();
3918
 
                            gen_aa32_ld16u(tmp, addr, IS_USER(s));
3919
 
                            tcg_gen_addi_i32(addr, addr, stride);
3920
 
                            tmp2 = tcg_temp_new_i32();
3921
 
                            gen_aa32_ld16u(tmp2, addr, IS_USER(s));
3922
 
                            tcg_gen_addi_i32(addr, addr, stride);
3923
 
                            tcg_gen_shli_i32(tmp2, tmp2, 16);
3924
 
                            tcg_gen_or_i32(tmp, tmp, tmp2);
3925
 
                            tcg_temp_free_i32(tmp2);
3926
 
                            neon_store_reg(rd, pass, tmp);
3927
 
                        } else {
3928
 
                            tmp = neon_load_reg(rd, pass);
3929
 
                            tmp2 = tcg_temp_new_i32();
3930
 
                            tcg_gen_shri_i32(tmp2, tmp, 16);
3931
 
                            gen_aa32_st16(tmp, addr, IS_USER(s));
3932
 
                            tcg_temp_free_i32(tmp);
3933
 
                            tcg_gen_addi_i32(addr, addr, stride);
3934
 
                            gen_aa32_st16(tmp2, addr, IS_USER(s));
3935
 
                            tcg_temp_free_i32(tmp2);
3936
 
                            tcg_gen_addi_i32(addr, addr, stride);
3937
 
                        }
3938
 
                    } else /* size == 0 */ {
3939
 
                        if (load) {
3940
 
                            TCGV_UNUSED_I32(tmp2);
3941
 
                            for (n = 0; n < 4; n++) {
3942
 
                                tmp = tcg_temp_new_i32();
3943
 
                                gen_aa32_ld8u(tmp, addr, IS_USER(s));
3944
 
                                tcg_gen_addi_i32(addr, addr, stride);
3945
 
                                if (n == 0) {
3946
 
                                    tmp2 = tmp;
3947
 
                                } else {
3948
 
                                    tcg_gen_shli_i32(tmp, tmp, n * 8);
3949
 
                                    tcg_gen_or_i32(tmp2, tmp2, tmp);
3950
 
                                    tcg_temp_free_i32(tmp);
3951
 
                                }
3952
 
                            }
3953
 
                            neon_store_reg(rd, pass, tmp2);
3954
 
                        } else {
3955
 
                            tmp2 = neon_load_reg(rd, pass);
3956
 
                            for (n = 0; n < 4; n++) {
3957
 
                                tmp = tcg_temp_new_i32();
3958
 
                                if (n == 0) {
3959
 
                                    tcg_gen_mov_i32(tmp, tmp2);
3960
 
                                } else {
3961
 
                                    tcg_gen_shri_i32(tmp, tmp2, n * 8);
3962
 
                                }
3963
 
                                gen_aa32_st8(tmp, addr, IS_USER(s));
3964
 
                                tcg_temp_free_i32(tmp);
3965
 
                                tcg_gen_addi_i32(addr, addr, stride);
3966
 
                            }
3967
 
                            tcg_temp_free_i32(tmp2);
3968
 
                        }
3969
 
                    }
3970
 
                }
3971
 
            }
3972
 
            rd += spacing;
3973
 
        }
3974
 
        tcg_temp_free_i32(addr);
3975
 
        stride = nregs * 8;
3976
 
    } else {
3977
 
        size = (insn >> 10) & 3;
3978
 
        if (size == 3) {
3979
 
            /* Load single element to all lanes.  */
3980
 
            int a = (insn >> 4) & 1;
3981
 
            if (!load) {
3982
 
                return 1;
3983
 
            }
3984
 
            size = (insn >> 6) & 3;
3985
 
            nregs = ((insn >> 8) & 3) + 1;
3986
 
 
3987
 
            if (size == 3) {
3988
 
                if (nregs != 4 || a == 0) {
3989
 
                    return 1;
3990
 
                }
3991
 
                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3992
 
                size = 2;
3993
 
            }
3994
 
            if (nregs == 1 && a == 1 && size == 0) {
3995
 
                return 1;
3996
 
            }
3997
 
            if (nregs == 3 && a == 1) {
3998
 
                return 1;
3999
 
            }
4000
 
            addr = tcg_temp_new_i32();
4001
 
            load_reg_var(s, addr, rn);
4002
 
            if (nregs == 1) {
4003
 
                /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4004
 
                tmp = gen_load_and_replicate(s, addr, size);
4005
 
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4006
 
                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4007
 
                if (insn & (1 << 5)) {
4008
 
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4009
 
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4010
 
                }
4011
 
                tcg_temp_free_i32(tmp);
4012
 
            } else {
4013
 
                /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4014
 
                stride = (insn & (1 << 5)) ? 2 : 1;
4015
 
                for (reg = 0; reg < nregs; reg++) {
4016
 
                    tmp = gen_load_and_replicate(s, addr, size);
4017
 
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4018
 
                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4019
 
                    tcg_temp_free_i32(tmp);
4020
 
                    tcg_gen_addi_i32(addr, addr, 1 << size);
4021
 
                    rd += stride;
4022
 
                }
4023
 
            }
4024
 
            tcg_temp_free_i32(addr);
4025
 
            stride = (1 << size) * nregs;
4026
 
        } else {
4027
 
            /* Single element.  */
4028
 
            int idx = (insn >> 4) & 0xf;
4029
 
            pass = (insn >> 7) & 1;
4030
 
            switch (size) {
4031
 
            case 0:
4032
 
                shift = ((insn >> 5) & 3) * 8;
4033
 
                stride = 1;
4034
 
                break;
4035
 
            case 1:
4036
 
                shift = ((insn >> 6) & 1) * 16;
4037
 
                stride = (insn & (1 << 5)) ? 2 : 1;
4038
 
                break;
4039
 
            case 2:
4040
 
                shift = 0;
4041
 
                stride = (insn & (1 << 6)) ? 2 : 1;
4042
 
                break;
4043
 
            default:
4044
 
                abort();
4045
 
            }
4046
 
            nregs = ((insn >> 8) & 3) + 1;
4047
 
            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4048
 
            switch (nregs) {
4049
 
            case 1:
4050
 
                if (((idx & (1 << size)) != 0) ||
4051
 
                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4052
 
                    return 1;
4053
 
                }
4054
 
                break;
4055
 
            case 3:
4056
 
                if ((idx & 1) != 0) {
4057
 
                    return 1;
4058
 
                }
4059
 
                /* fall through */
4060
 
            case 2:
4061
 
                if (size == 2 && (idx & 2) != 0) {
4062
 
                    return 1;
4063
 
                }
4064
 
                break;
4065
 
            case 4:
4066
 
                if ((size == 2) && ((idx & 3) == 3)) {
4067
 
                    return 1;
4068
 
                }
4069
 
                break;
4070
 
            default:
4071
 
                abort();
4072
 
            }
4073
 
            if ((rd + stride * (nregs - 1)) > 31) {
4074
 
                /* Attempts to write off the end of the register file
4075
 
                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4076
 
                 * the neon_load_reg() would write off the end of the array.
4077
 
                 */
4078
 
                return 1;
4079
 
            }
4080
 
            addr = tcg_temp_new_i32();
4081
 
            load_reg_var(s, addr, rn);
4082
 
            for (reg = 0; reg < nregs; reg++) {
4083
 
                if (load) {
4084
 
                    tmp = tcg_temp_new_i32();
4085
 
                    switch (size) {
4086
 
                    case 0:
4087
 
                        gen_aa32_ld8u(tmp, addr, IS_USER(s));
4088
 
                        break;
4089
 
                    case 1:
4090
 
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
4091
 
                        break;
4092
 
                    case 2:
4093
 
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
4094
 
                        break;
4095
 
                    default: /* Avoid compiler warnings.  */
4096
 
                        abort();
4097
 
                    }
4098
 
                    if (size != 2) {
4099
 
                        tmp2 = neon_load_reg(rd, pass);
4100
 
                        tcg_gen_deposit_i32(tmp, tmp2, tmp,
4101
 
                                            shift, size ? 16 : 8);
4102
 
                        tcg_temp_free_i32(tmp2);
4103
 
                    }
4104
 
                    neon_store_reg(rd, pass, tmp);
4105
 
                } else { /* Store */
4106
 
                    tmp = neon_load_reg(rd, pass);
4107
 
                    if (shift)
4108
 
                        tcg_gen_shri_i32(tmp, tmp, shift);
4109
 
                    switch (size) {
4110
 
                    case 0:
4111
 
                        gen_aa32_st8(tmp, addr, IS_USER(s));
4112
 
                        break;
4113
 
                    case 1:
4114
 
                        gen_aa32_st16(tmp, addr, IS_USER(s));
4115
 
                        break;
4116
 
                    case 2:
4117
 
                        gen_aa32_st32(tmp, addr, IS_USER(s));
4118
 
                        break;
4119
 
                    }
4120
 
                    tcg_temp_free_i32(tmp);
4121
 
                }
4122
 
                rd += stride;
4123
 
                tcg_gen_addi_i32(addr, addr, 1 << size);
4124
 
            }
4125
 
            tcg_temp_free_i32(addr);
4126
 
            stride = nregs * (1 << size);
4127
 
        }
4128
 
    }
4129
 
    if (rm != 15) {
4130
 
        TCGv_i32 base;
4131
 
 
4132
 
        base = load_reg(s, rn);
4133
 
        if (rm == 13) {
4134
 
            tcg_gen_addi_i32(base, base, stride);
4135
 
        } else {
4136
 
            TCGv_i32 index;
4137
 
            index = load_reg(s, rm);
4138
 
            tcg_gen_add_i32(base, base, index);
4139
 
            tcg_temp_free_i32(index);
4140
 
        }
4141
 
        store_reg(s, rn, base);
4142
 
    }
4143
 
    return 0;
4144
 
}
4145
 
 
4146
 
/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
4147
 
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4148
 
{
4149
 
    tcg_gen_and_i32(t, t, c);
4150
 
    tcg_gen_andc_i32(f, f, c);
4151
 
    tcg_gen_or_i32(dest, t, f);
4152
 
}
4153
 
 
4154
 
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4155
 
{
4156
 
    switch (size) {
4157
 
    case 0: gen_helper_neon_narrow_u8(dest, src); break;
4158
 
    case 1: gen_helper_neon_narrow_u16(dest, src); break;
4159
 
    case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4160
 
    default: abort();
4161
 
    }
4162
 
}
4163
 
 
4164
 
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4165
 
{
4166
 
    switch (size) {
4167
 
    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4168
 
    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4169
 
    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4170
 
    default: abort();
4171
 
    }
4172
 
}
4173
 
 
4174
 
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4175
 
{
4176
 
    switch (size) {
4177
 
    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4178
 
    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4179
 
    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4180
 
    default: abort();
4181
 
    }
4182
 
}
4183
 
 
4184
 
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4185
 
{
4186
 
    switch (size) {
4187
 
    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4188
 
    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4189
 
    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4190
 
    default: abort();
4191
 
    }
4192
 
}
4193
 
 
4194
 
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4195
 
                                         int q, int u)
4196
 
{
4197
 
    if (q) {
4198
 
        if (u) {
4199
 
            switch (size) {
4200
 
            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4201
 
            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4202
 
            default: abort();
4203
 
            }
4204
 
        } else {
4205
 
            switch (size) {
4206
 
            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4207
 
            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4208
 
            default: abort();
4209
 
            }
4210
 
        }
4211
 
    } else {
4212
 
        if (u) {
4213
 
            switch (size) {
4214
 
            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4215
 
            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4216
 
            default: abort();
4217
 
            }
4218
 
        } else {
4219
 
            switch (size) {
4220
 
            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4221
 
            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4222
 
            default: abort();
4223
 
            }
4224
 
        }
4225
 
    }
4226
 
}
4227
 
 
4228
 
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4229
 
{
4230
 
    if (u) {
4231
 
        switch (size) {
4232
 
        case 0: gen_helper_neon_widen_u8(dest, src); break;
4233
 
        case 1: gen_helper_neon_widen_u16(dest, src); break;
4234
 
        case 2: tcg_gen_extu_i32_i64(dest, src); break;
4235
 
        default: abort();
4236
 
        }
4237
 
    } else {
4238
 
        switch (size) {
4239
 
        case 0: gen_helper_neon_widen_s8(dest, src); break;
4240
 
        case 1: gen_helper_neon_widen_s16(dest, src); break;
4241
 
        case 2: tcg_gen_ext_i32_i64(dest, src); break;
4242
 
        default: abort();
4243
 
        }
4244
 
    }
4245
 
    tcg_temp_free_i32(src);
4246
 
}
4247
 
 
4248
 
static inline void gen_neon_addl(int size)
4249
 
{
4250
 
    switch (size) {
4251
 
    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4252
 
    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4253
 
    case 2: tcg_gen_add_i64(CPU_V001); break;
4254
 
    default: abort();
4255
 
    }
4256
 
}
4257
 
 
4258
 
static inline void gen_neon_subl(int size)
4259
 
{
4260
 
    switch (size) {
4261
 
    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4262
 
    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4263
 
    case 2: tcg_gen_sub_i64(CPU_V001); break;
4264
 
    default: abort();
4265
 
    }
4266
 
}
4267
 
 
4268
 
static inline void gen_neon_negl(TCGv_i64 var, int size)
4269
 
{
4270
 
    switch (size) {
4271
 
    case 0: gen_helper_neon_negl_u16(var, var); break;
4272
 
    case 1: gen_helper_neon_negl_u32(var, var); break;
4273
 
    case 2:
4274
 
        tcg_gen_neg_i64(var, var);
4275
 
        break;
4276
 
    default: abort();
4277
 
    }
4278
 
}
4279
 
 
4280
 
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4281
 
{
4282
 
    switch (size) {
4283
 
    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4284
 
    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4285
 
    default: abort();
4286
 
    }
4287
 
}
4288
 
 
4289
 
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4290
 
                                 int size, int u)
4291
 
{
4292
 
    TCGv_i64 tmp;
4293
 
 
4294
 
    switch ((size << 1) | u) {
4295
 
    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4296
 
    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4297
 
    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4298
 
    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4299
 
    case 4:
4300
 
        tmp = gen_muls_i64_i32(a, b);
4301
 
        tcg_gen_mov_i64(dest, tmp);
4302
 
        tcg_temp_free_i64(tmp);
4303
 
        break;
4304
 
    case 5:
4305
 
        tmp = gen_mulu_i64_i32(a, b);
4306
 
        tcg_gen_mov_i64(dest, tmp);
4307
 
        tcg_temp_free_i64(tmp);
4308
 
        break;
4309
 
    default: abort();
4310
 
    }
4311
 
 
4312
 
    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4313
 
       Don't forget to clean them now.  */
4314
 
    if (size < 2) {
4315
 
        tcg_temp_free_i32(a);
4316
 
        tcg_temp_free_i32(b);
4317
 
    }
4318
 
}
4319
 
 
4320
 
static void gen_neon_narrow_op(int op, int u, int size,
4321
 
                               TCGv_i32 dest, TCGv_i64 src)
4322
 
{
4323
 
    if (op) {
4324
 
        if (u) {
4325
 
            gen_neon_unarrow_sats(size, dest, src);
4326
 
        } else {
4327
 
            gen_neon_narrow(size, dest, src);
4328
 
        }
4329
 
    } else {
4330
 
        if (u) {
4331
 
            gen_neon_narrow_satu(size, dest, src);
4332
 
        } else {
4333
 
            gen_neon_narrow_sats(size, dest, src);
4334
 
        }
4335
 
    }
4336
 
}
4337
 
 
4338
 
/* Symbolic constants for op fields for Neon 3-register same-length.
4339
 
 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4340
 
 * table A7-9.
4341
 
 */
4342
 
#define NEON_3R_VHADD 0
4343
 
#define NEON_3R_VQADD 1
4344
 
#define NEON_3R_VRHADD 2
4345
 
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4346
 
#define NEON_3R_VHSUB 4
4347
 
#define NEON_3R_VQSUB 5
4348
 
#define NEON_3R_VCGT 6
4349
 
#define NEON_3R_VCGE 7
4350
 
#define NEON_3R_VSHL 8
4351
 
#define NEON_3R_VQSHL 9
4352
 
#define NEON_3R_VRSHL 10
4353
 
#define NEON_3R_VQRSHL 11
4354
 
#define NEON_3R_VMAX 12
4355
 
#define NEON_3R_VMIN 13
4356
 
#define NEON_3R_VABD 14
4357
 
#define NEON_3R_VABA 15
4358
 
#define NEON_3R_VADD_VSUB 16
4359
 
#define NEON_3R_VTST_VCEQ 17
4360
 
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4361
 
#define NEON_3R_VMUL 19
4362
 
#define NEON_3R_VPMAX 20
4363
 
#define NEON_3R_VPMIN 21
4364
 
#define NEON_3R_VQDMULH_VQRDMULH 22
4365
 
#define NEON_3R_VPADD 23
4366
 
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4367
 
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4368
 
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4369
 
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4370
 
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4371
 
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4372
 
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4373
 
 
4374
 
static const uint8_t neon_3r_sizes[] = {
4375
 
    [NEON_3R_VHADD] = 0x7,
4376
 
    [NEON_3R_VQADD] = 0xf,
4377
 
    [NEON_3R_VRHADD] = 0x7,
4378
 
    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4379
 
    [NEON_3R_VHSUB] = 0x7,
4380
 
    [NEON_3R_VQSUB] = 0xf,
4381
 
    [NEON_3R_VCGT] = 0x7,
4382
 
    [NEON_3R_VCGE] = 0x7,
4383
 
    [NEON_3R_VSHL] = 0xf,
4384
 
    [NEON_3R_VQSHL] = 0xf,
4385
 
    [NEON_3R_VRSHL] = 0xf,
4386
 
    [NEON_3R_VQRSHL] = 0xf,
4387
 
    [NEON_3R_VMAX] = 0x7,
4388
 
    [NEON_3R_VMIN] = 0x7,
4389
 
    [NEON_3R_VABD] = 0x7,
4390
 
    [NEON_3R_VABA] = 0x7,
4391
 
    [NEON_3R_VADD_VSUB] = 0xf,
4392
 
    [NEON_3R_VTST_VCEQ] = 0x7,
4393
 
    [NEON_3R_VML] = 0x7,
4394
 
    [NEON_3R_VMUL] = 0x7,
4395
 
    [NEON_3R_VPMAX] = 0x7,
4396
 
    [NEON_3R_VPMIN] = 0x7,
4397
 
    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4398
 
    [NEON_3R_VPADD] = 0x7,
4399
 
    [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4400
 
    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4401
 
    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4402
 
    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4403
 
    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4404
 
    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4405
 
    [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4406
 
};
4407
 
 
4408
 
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4409
 
 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4410
 
 * table A7-13.
4411
 
 */
4412
 
#define NEON_2RM_VREV64 0
4413
 
#define NEON_2RM_VREV32 1
4414
 
#define NEON_2RM_VREV16 2
4415
 
#define NEON_2RM_VPADDL 4
4416
 
#define NEON_2RM_VPADDL_U 5
4417
 
#define NEON_2RM_VCLS 8
4418
 
#define NEON_2RM_VCLZ 9
4419
 
#define NEON_2RM_VCNT 10
4420
 
#define NEON_2RM_VMVN 11
4421
 
#define NEON_2RM_VPADAL 12
4422
 
#define NEON_2RM_VPADAL_U 13
4423
 
#define NEON_2RM_VQABS 14
4424
 
#define NEON_2RM_VQNEG 15
4425
 
#define NEON_2RM_VCGT0 16
4426
 
#define NEON_2RM_VCGE0 17
4427
 
#define NEON_2RM_VCEQ0 18
4428
 
#define NEON_2RM_VCLE0 19
4429
 
#define NEON_2RM_VCLT0 20
4430
 
#define NEON_2RM_VABS 22
4431
 
#define NEON_2RM_VNEG 23
4432
 
#define NEON_2RM_VCGT0_F 24
4433
 
#define NEON_2RM_VCGE0_F 25
4434
 
#define NEON_2RM_VCEQ0_F 26
4435
 
#define NEON_2RM_VCLE0_F 27
4436
 
#define NEON_2RM_VCLT0_F 28
4437
 
#define NEON_2RM_VABS_F 30
4438
 
#define NEON_2RM_VNEG_F 31
4439
 
#define NEON_2RM_VSWP 32
4440
 
#define NEON_2RM_VTRN 33
4441
 
#define NEON_2RM_VUZP 34
4442
 
#define NEON_2RM_VZIP 35
4443
 
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4444
 
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4445
 
#define NEON_2RM_VSHLL 38
4446
 
#define NEON_2RM_VCVT_F16_F32 44
4447
 
#define NEON_2RM_VCVT_F32_F16 46
4448
 
#define NEON_2RM_VRECPE 56
4449
 
#define NEON_2RM_VRSQRTE 57
4450
 
#define NEON_2RM_VRECPE_F 58
4451
 
#define NEON_2RM_VRSQRTE_F 59
4452
 
#define NEON_2RM_VCVT_FS 60
4453
 
#define NEON_2RM_VCVT_FU 61
4454
 
#define NEON_2RM_VCVT_SF 62
4455
 
#define NEON_2RM_VCVT_UF 63
4456
 
 
4457
 
static int neon_2rm_is_float_op(int op)
4458
 
{
4459
 
    /* Return true if this neon 2reg-misc op is float-to-float */
4460
 
    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4461
 
            op >= NEON_2RM_VRECPE_F);
4462
 
}
4463
 
 
4464
 
/* Each entry in this array has bit n set if the insn allows
4465
 
 * size value n (otherwise it will UNDEF). Since unallocated
4466
 
 * op values will have no bits set they always UNDEF.
4467
 
 */
4468
 
static const uint8_t neon_2rm_sizes[] = {
4469
 
    [NEON_2RM_VREV64] = 0x7,
4470
 
    [NEON_2RM_VREV32] = 0x3,
4471
 
    [NEON_2RM_VREV16] = 0x1,
4472
 
    [NEON_2RM_VPADDL] = 0x7,
4473
 
    [NEON_2RM_VPADDL_U] = 0x7,
4474
 
    [NEON_2RM_VCLS] = 0x7,
4475
 
    [NEON_2RM_VCLZ] = 0x7,
4476
 
    [NEON_2RM_VCNT] = 0x1,
4477
 
    [NEON_2RM_VMVN] = 0x1,
4478
 
    [NEON_2RM_VPADAL] = 0x7,
4479
 
    [NEON_2RM_VPADAL_U] = 0x7,
4480
 
    [NEON_2RM_VQABS] = 0x7,
4481
 
    [NEON_2RM_VQNEG] = 0x7,
4482
 
    [NEON_2RM_VCGT0] = 0x7,
4483
 
    [NEON_2RM_VCGE0] = 0x7,
4484
 
    [NEON_2RM_VCEQ0] = 0x7,
4485
 
    [NEON_2RM_VCLE0] = 0x7,
4486
 
    [NEON_2RM_VCLT0] = 0x7,
4487
 
    [NEON_2RM_VABS] = 0x7,
4488
 
    [NEON_2RM_VNEG] = 0x7,
4489
 
    [NEON_2RM_VCGT0_F] = 0x4,
4490
 
    [NEON_2RM_VCGE0_F] = 0x4,
4491
 
    [NEON_2RM_VCEQ0_F] = 0x4,
4492
 
    [NEON_2RM_VCLE0_F] = 0x4,
4493
 
    [NEON_2RM_VCLT0_F] = 0x4,
4494
 
    [NEON_2RM_VABS_F] = 0x4,
4495
 
    [NEON_2RM_VNEG_F] = 0x4,
4496
 
    [NEON_2RM_VSWP] = 0x1,
4497
 
    [NEON_2RM_VTRN] = 0x7,
4498
 
    [NEON_2RM_VUZP] = 0x7,
4499
 
    [NEON_2RM_VZIP] = 0x7,
4500
 
    [NEON_2RM_VMOVN] = 0x7,
4501
 
    [NEON_2RM_VQMOVN] = 0x7,
4502
 
    [NEON_2RM_VSHLL] = 0x7,
4503
 
    [NEON_2RM_VCVT_F16_F32] = 0x2,
4504
 
    [NEON_2RM_VCVT_F32_F16] = 0x2,
4505
 
    [NEON_2RM_VRECPE] = 0x4,
4506
 
    [NEON_2RM_VRSQRTE] = 0x4,
4507
 
    [NEON_2RM_VRECPE_F] = 0x4,
4508
 
    [NEON_2RM_VRSQRTE_F] = 0x4,
4509
 
    [NEON_2RM_VCVT_FS] = 0x4,
4510
 
    [NEON_2RM_VCVT_FU] = 0x4,
4511
 
    [NEON_2RM_VCVT_SF] = 0x4,
4512
 
    [NEON_2RM_VCVT_UF] = 0x4,
4513
 
};
4514
 
 
4515
 
/* Translate a NEON data processing instruction.  Return nonzero if the
4516
 
   instruction is invalid.
4517
 
   We process data in a mixture of 32-bit and 64-bit chunks.
4518
 
   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
4519
 
 
4520
 
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4521
 
{
4522
 
    int op;
4523
 
    int q;
4524
 
    int rd, rn, rm;
4525
 
    int size;
4526
 
    int shift;
4527
 
    int pass;
4528
 
    int count;
4529
 
    int pairwise;
4530
 
    int u;
4531
 
    uint32_t imm, mask;
4532
 
    TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4533
 
    TCGv_i64 tmp64;
4534
 
 
4535
 
    if (!s->vfp_enabled)
4536
 
      return 1;
4537
 
    q = (insn & (1 << 6)) != 0;
4538
 
    u = (insn >> 24) & 1;
4539
 
    VFP_DREG_D(rd, insn);
4540
 
    VFP_DREG_N(rn, insn);
4541
 
    VFP_DREG_M(rm, insn);
4542
 
    size = (insn >> 20) & 3;
4543
 
    if ((insn & (1 << 23)) == 0) {
4544
 
        /* Three register same length.  */
4545
 
        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4546
 
        /* Catch invalid op and bad size combinations: UNDEF */
4547
 
        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4548
 
            return 1;
4549
 
        }
4550
 
        /* All insns of this form UNDEF for either this condition or the
4551
 
         * superset of cases "Q==1"; we catch the latter later.
4552
 
         */
4553
 
        if (q && ((rd | rn | rm) & 1)) {
4554
 
            return 1;
4555
 
        }
4556
 
        if (size == 3 && op != NEON_3R_LOGIC) {
4557
 
            /* 64-bit element instructions. */
4558
 
            for (pass = 0; pass < (q ? 2 : 1); pass++) {
4559
 
                neon_load_reg64(cpu_V0, rn + pass);
4560
 
                neon_load_reg64(cpu_V1, rm + pass);
4561
 
                switch (op) {
4562
 
                case NEON_3R_VQADD:
4563
 
                    if (u) {
4564
 
                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4565
 
                                                 cpu_V0, cpu_V1);
4566
 
                    } else {
4567
 
                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4568
 
                                                 cpu_V0, cpu_V1);
4569
 
                    }
4570
 
                    break;
4571
 
                case NEON_3R_VQSUB:
4572
 
                    if (u) {
4573
 
                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4574
 
                                                 cpu_V0, cpu_V1);
4575
 
                    } else {
4576
 
                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4577
 
                                                 cpu_V0, cpu_V1);
4578
 
                    }
4579
 
                    break;
4580
 
                case NEON_3R_VSHL:
4581
 
                    if (u) {
4582
 
                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4583
 
                    } else {
4584
 
                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4585
 
                    }
4586
 
                    break;
4587
 
                case NEON_3R_VQSHL:
4588
 
                    if (u) {
4589
 
                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4590
 
                                                 cpu_V1, cpu_V0);
4591
 
                    } else {
4592
 
                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4593
 
                                                 cpu_V1, cpu_V0);
4594
 
                    }
4595
 
                    break;
4596
 
                case NEON_3R_VRSHL:
4597
 
                    if (u) {
4598
 
                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4599
 
                    } else {
4600
 
                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4601
 
                    }
4602
 
                    break;
4603
 
                case NEON_3R_VQRSHL:
4604
 
                    if (u) {
4605
 
                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4606
 
                                                  cpu_V1, cpu_V0);
4607
 
                    } else {
4608
 
                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4609
 
                                                  cpu_V1, cpu_V0);
4610
 
                    }
4611
 
                    break;
4612
 
                case NEON_3R_VADD_VSUB:
4613
 
                    if (u) {
4614
 
                        tcg_gen_sub_i64(CPU_V001);
4615
 
                    } else {
4616
 
                        tcg_gen_add_i64(CPU_V001);
4617
 
                    }
4618
 
                    break;
4619
 
                default:
4620
 
                    abort();
4621
 
                }
4622
 
                neon_store_reg64(cpu_V0, rd + pass);
4623
 
            }
4624
 
            return 0;
4625
 
        }
4626
 
        pairwise = 0;
4627
 
        switch (op) {
4628
 
        case NEON_3R_VSHL:
4629
 
        case NEON_3R_VQSHL:
4630
 
        case NEON_3R_VRSHL:
4631
 
        case NEON_3R_VQRSHL:
4632
 
            {
4633
 
                int rtmp;
4634
 
                /* Shift instruction operands are reversed.  */
4635
 
                rtmp = rn;
4636
 
                rn = rm;
4637
 
                rm = rtmp;
4638
 
            }
4639
 
            break;
4640
 
        case NEON_3R_VPADD:
4641
 
            if (u) {
4642
 
                return 1;
4643
 
            }
4644
 
            /* Fall through */
4645
 
        case NEON_3R_VPMAX:
4646
 
        case NEON_3R_VPMIN:
4647
 
            pairwise = 1;
4648
 
            break;
4649
 
        case NEON_3R_FLOAT_ARITH:
4650
 
            pairwise = (u && size < 2); /* if VPADD (float) */
4651
 
            break;
4652
 
        case NEON_3R_FLOAT_MINMAX:
4653
 
            pairwise = u; /* if VPMIN/VPMAX (float) */
4654
 
            break;
4655
 
        case NEON_3R_FLOAT_CMP:
4656
 
            if (!u && size) {
4657
 
                /* no encoding for U=0 C=1x */
4658
 
                return 1;
4659
 
            }
4660
 
            break;
4661
 
        case NEON_3R_FLOAT_ACMP:
4662
 
            if (!u) {
4663
 
                return 1;
4664
 
            }
4665
 
            break;
4666
 
        case NEON_3R_VRECPS_VRSQRTS:
4667
 
            if (u) {
4668
 
                return 1;
4669
 
            }
4670
 
            break;
4671
 
        case NEON_3R_VMUL:
4672
 
            if (u && (size != 0)) {
4673
 
                /* UNDEF on invalid size for polynomial subcase */
4674
 
                return 1;
4675
 
            }
4676
 
            break;
4677
 
        case NEON_3R_VFM:
4678
 
            if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4679
 
                return 1;
4680
 
            }
4681
 
            break;
4682
 
        default:
4683
 
            break;
4684
 
        }
4685
 
 
4686
 
        if (pairwise && q) {
4687
 
            /* All the pairwise insns UNDEF if Q is set */
4688
 
            return 1;
4689
 
        }
4690
 
 
4691
 
        for (pass = 0; pass < (q ? 4 : 2); pass++) {
4692
 
 
4693
 
        if (pairwise) {
4694
 
            /* Pairwise.  */
4695
 
            if (pass < 1) {
4696
 
                tmp = neon_load_reg(rn, 0);
4697
 
                tmp2 = neon_load_reg(rn, 1);
4698
 
            } else {
4699
 
                tmp = neon_load_reg(rm, 0);
4700
 
                tmp2 = neon_load_reg(rm, 1);
4701
 
            }
4702
 
        } else {
4703
 
            /* Elementwise.  */
4704
 
            tmp = neon_load_reg(rn, pass);
4705
 
            tmp2 = neon_load_reg(rm, pass);
4706
 
        }
4707
 
        switch (op) {
4708
 
        case NEON_3R_VHADD:
4709
 
            GEN_NEON_INTEGER_OP(hadd);
4710
 
            break;
4711
 
        case NEON_3R_VQADD:
4712
 
            GEN_NEON_INTEGER_OP_ENV(qadd);
4713
 
            break;
4714
 
        case NEON_3R_VRHADD:
4715
 
            GEN_NEON_INTEGER_OP(rhadd);
4716
 
            break;
4717
 
        case NEON_3R_LOGIC: /* Logic ops.  */
4718
 
            switch ((u << 2) | size) {
4719
 
            case 0: /* VAND */
4720
 
                tcg_gen_and_i32(tmp, tmp, tmp2);
4721
 
                break;
4722
 
            case 1: /* BIC */
4723
 
                tcg_gen_andc_i32(tmp, tmp, tmp2);
4724
 
                break;
4725
 
            case 2: /* VORR */
4726
 
                tcg_gen_or_i32(tmp, tmp, tmp2);
4727
 
                break;
4728
 
            case 3: /* VORN */
4729
 
                tcg_gen_orc_i32(tmp, tmp, tmp2);
4730
 
                break;
4731
 
            case 4: /* VEOR */
4732
 
                tcg_gen_xor_i32(tmp, tmp, tmp2);
4733
 
                break;
4734
 
            case 5: /* VBSL */
4735
 
                tmp3 = neon_load_reg(rd, pass);
4736
 
                gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4737
 
                tcg_temp_free_i32(tmp3);
4738
 
                break;
4739
 
            case 6: /* VBIT */
4740
 
                tmp3 = neon_load_reg(rd, pass);
4741
 
                gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4742
 
                tcg_temp_free_i32(tmp3);
4743
 
                break;
4744
 
            case 7: /* VBIF */
4745
 
                tmp3 = neon_load_reg(rd, pass);
4746
 
                gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4747
 
                tcg_temp_free_i32(tmp3);
4748
 
                break;
4749
 
            }
4750
 
            break;
4751
 
        case NEON_3R_VHSUB:
4752
 
            GEN_NEON_INTEGER_OP(hsub);
4753
 
            break;
4754
 
        case NEON_3R_VQSUB:
4755
 
            GEN_NEON_INTEGER_OP_ENV(qsub);
4756
 
            break;
4757
 
        case NEON_3R_VCGT:
4758
 
            GEN_NEON_INTEGER_OP(cgt);
4759
 
            break;
4760
 
        case NEON_3R_VCGE:
4761
 
            GEN_NEON_INTEGER_OP(cge);
4762
 
            break;
4763
 
        case NEON_3R_VSHL:
4764
 
            GEN_NEON_INTEGER_OP(shl);
4765
 
            break;
4766
 
        case NEON_3R_VQSHL:
4767
 
            GEN_NEON_INTEGER_OP_ENV(qshl);
4768
 
            break;
4769
 
        case NEON_3R_VRSHL:
4770
 
            GEN_NEON_INTEGER_OP(rshl);
4771
 
            break;
4772
 
        case NEON_3R_VQRSHL:
4773
 
            GEN_NEON_INTEGER_OP_ENV(qrshl);
4774
 
            break;
4775
 
        case NEON_3R_VMAX:
4776
 
            GEN_NEON_INTEGER_OP(max);
4777
 
            break;
4778
 
        case NEON_3R_VMIN:
4779
 
            GEN_NEON_INTEGER_OP(min);
4780
 
            break;
4781
 
        case NEON_3R_VABD:
4782
 
            GEN_NEON_INTEGER_OP(abd);
4783
 
            break;
4784
 
        case NEON_3R_VABA:
4785
 
            GEN_NEON_INTEGER_OP(abd);
4786
 
            tcg_temp_free_i32(tmp2);
4787
 
            tmp2 = neon_load_reg(rd, pass);
4788
 
            gen_neon_add(size, tmp, tmp2);
4789
 
            break;
4790
 
        case NEON_3R_VADD_VSUB:
4791
 
            if (!u) { /* VADD */
4792
 
                gen_neon_add(size, tmp, tmp2);
4793
 
            } else { /* VSUB */
4794
 
                switch (size) {
4795
 
                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4796
 
                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4797
 
                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4798
 
                default: abort();
4799
 
                }
4800
 
            }
4801
 
            break;
4802
 
        case NEON_3R_VTST_VCEQ:
4803
 
            if (!u) { /* VTST */
4804
 
                switch (size) {
4805
 
                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4806
 
                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4807
 
                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4808
 
                default: abort();
4809
 
                }
4810
 
            } else { /* VCEQ */
4811
 
                switch (size) {
4812
 
                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4813
 
                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4814
 
                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4815
 
                default: abort();
4816
 
                }
4817
 
            }
4818
 
            break;
4819
 
        case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4820
 
            switch (size) {
4821
 
            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4822
 
            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4823
 
            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4824
 
            default: abort();
4825
 
            }
4826
 
            tcg_temp_free_i32(tmp2);
4827
 
            tmp2 = neon_load_reg(rd, pass);
4828
 
            if (u) { /* VMLS */
4829
 
                gen_neon_rsb(size, tmp, tmp2);
4830
 
            } else { /* VMLA */
4831
 
                gen_neon_add(size, tmp, tmp2);
4832
 
            }
4833
 
            break;
4834
 
        case NEON_3R_VMUL:
4835
 
            if (u) { /* polynomial */
4836
 
                gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4837
 
            } else { /* Integer */
4838
 
                switch (size) {
4839
 
                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4840
 
                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4841
 
                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4842
 
                default: abort();
4843
 
                }
4844
 
            }
4845
 
            break;
4846
 
        case NEON_3R_VPMAX:
4847
 
            GEN_NEON_INTEGER_OP(pmax);
4848
 
            break;
4849
 
        case NEON_3R_VPMIN:
4850
 
            GEN_NEON_INTEGER_OP(pmin);
4851
 
            break;
4852
 
        case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
4853
 
            if (!u) { /* VQDMULH */
4854
 
                switch (size) {
4855
 
                case 1:
4856
 
                    gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
4857
 
                    break;
4858
 
                case 2:
4859
 
                    gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
4860
 
                    break;
4861
 
                default: abort();
4862
 
                }
4863
 
            } else { /* VQRDMULH */
4864
 
                switch (size) {
4865
 
                case 1:
4866
 
                    gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
4867
 
                    break;
4868
 
                case 2:
4869
 
                    gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
4870
 
                    break;
4871
 
                default: abort();
4872
 
                }
4873
 
            }
4874
 
            break;
4875
 
        case NEON_3R_VPADD:
4876
 
            switch (size) {
4877
 
            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4878
 
            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4879
 
            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4880
 
            default: abort();
4881
 
            }
4882
 
            break;
4883
 
        case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
4884
 
        {
4885
 
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4886
 
            switch ((u << 2) | size) {
4887
 
            case 0: /* VADD */
4888
 
            case 4: /* VPADD */
4889
 
                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4890
 
                break;
4891
 
            case 2: /* VSUB */
4892
 
                gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
4893
 
                break;
4894
 
            case 6: /* VABD */
4895
 
                gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
4896
 
                break;
4897
 
            default:
4898
 
                abort();
4899
 
            }
4900
 
            tcg_temp_free_ptr(fpstatus);
4901
 
            break;
4902
 
        }
4903
 
        case NEON_3R_FLOAT_MULTIPLY:
4904
 
        {
4905
 
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4906
 
            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
4907
 
            if (!u) {
4908
 
                tcg_temp_free_i32(tmp2);
4909
 
                tmp2 = neon_load_reg(rd, pass);
4910
 
                if (size == 0) {
4911
 
                    gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4912
 
                } else {
4913
 
                    gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
4914
 
                }
4915
 
            }
4916
 
            tcg_temp_free_ptr(fpstatus);
4917
 
            break;
4918
 
        }
4919
 
        case NEON_3R_FLOAT_CMP:
4920
 
        {
4921
 
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4922
 
            if (!u) {
4923
 
                gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
4924
 
            } else {
4925
 
                if (size == 0) {
4926
 
                    gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
4927
 
                } else {
4928
 
                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
4929
 
                }
4930
 
            }
4931
 
            tcg_temp_free_ptr(fpstatus);
4932
 
            break;
4933
 
        }
4934
 
        case NEON_3R_FLOAT_ACMP:
4935
 
        {
4936
 
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4937
 
            if (size == 0) {
4938
 
                gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
4939
 
            } else {
4940
 
                gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
4941
 
            }
4942
 
            tcg_temp_free_ptr(fpstatus);
4943
 
            break;
4944
 
        }
4945
 
        case NEON_3R_FLOAT_MINMAX:
4946
 
        {
4947
 
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4948
 
            if (size == 0) {
4949
 
                gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
4950
 
            } else {
4951
 
                gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
4952
 
            }
4953
 
            tcg_temp_free_ptr(fpstatus);
4954
 
            break;
4955
 
        }
4956
 
        case NEON_3R_VRECPS_VRSQRTS:
4957
 
            if (size == 0)
4958
 
                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4959
 
            else
4960
 
                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4961
 
            break;
4962
 
        case NEON_3R_VFM:
4963
 
        {
4964
 
            /* VFMA, VFMS: fused multiply-add */
4965
 
            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4966
 
            TCGv_i32 tmp3 = neon_load_reg(rd, pass);
4967
 
            if (size) {
4968
 
                /* VFMS */
4969
 
                gen_helper_vfp_negs(tmp, tmp);
4970
 
            }
4971
 
            gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
4972
 
            tcg_temp_free_i32(tmp3);
4973
 
            tcg_temp_free_ptr(fpstatus);
4974
 
            break;
4975
 
        }
4976
 
        default:
4977
 
            abort();
4978
 
        }
4979
 
        tcg_temp_free_i32(tmp2);
4980
 
 
4981
 
        /* Save the result.  For elementwise operations we can put it
4982
 
           straight into the destination register.  For pairwise operations
4983
 
           we have to be careful to avoid clobbering the source operands.  */
4984
 
        if (pairwise && rd == rm) {
4985
 
            neon_store_scratch(pass, tmp);
4986
 
        } else {
4987
 
            neon_store_reg(rd, pass, tmp);
4988
 
        }
4989
 
 
4990
 
        } /* for pass */
4991
 
        if (pairwise && rd == rm) {
4992
 
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
4993
 
                tmp = neon_load_scratch(pass);
4994
 
                neon_store_reg(rd, pass, tmp);
4995
 
            }
4996
 
        }
4997
 
        /* End of 3 register same size operations.  */
4998
 
    } else if (insn & (1 << 4)) {
4999
 
        if ((insn & 0x00380080) != 0) {
5000
 
            /* Two registers and shift.  */
5001
 
            op = (insn >> 8) & 0xf;
5002
 
            if (insn & (1 << 7)) {
5003
 
                /* 64-bit shift. */
5004
 
                if (op > 7) {
5005
 
                    return 1;
5006
 
                }
5007
 
                size = 3;
5008
 
            } else {
5009
 
                size = 2;
5010
 
                while ((insn & (1 << (size + 19))) == 0)
5011
 
                    size--;
5012
 
            }
5013
 
            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5014
 
            /* To avoid excessive duplication of ops we implement shift
5015
 
               by immediate using the variable shift operations.  */
5016
 
            if (op < 8) {
5017
 
                /* Shift by immediate:
5018
 
                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
5019
 
                if (q && ((rd | rm) & 1)) {
5020
 
                    return 1;
5021
 
                }
5022
 
                if (!u && (op == 4 || op == 6)) {
5023
 
                    return 1;
5024
 
                }
5025
 
                /* Right shifts are encoded as N - shift, where N is the
5026
 
                   element size in bits.  */
5027
 
                if (op <= 4)
5028
 
                    shift = shift - (1 << (size + 3));
5029
 
                if (size == 3) {
5030
 
                    count = q + 1;
5031
 
                } else {
5032
 
                    count = q ? 4: 2;
5033
 
                }
5034
 
                switch (size) {
5035
 
                case 0:
5036
 
                    imm = (uint8_t) shift;
5037
 
                    imm |= imm << 8;
5038
 
                    imm |= imm << 16;
5039
 
                    break;
5040
 
                case 1:
5041
 
                    imm = (uint16_t) shift;
5042
 
                    imm |= imm << 16;
5043
 
                    break;
5044
 
                case 2:
5045
 
                case 3:
5046
 
                    imm = shift;
5047
 
                    break;
5048
 
                default:
5049
 
                    abort();
5050
 
                }
5051
 
 
5052
 
                for (pass = 0; pass < count; pass++) {
5053
 
                    if (size == 3) {
5054
 
                        neon_load_reg64(cpu_V0, rm + pass);
5055
 
                        tcg_gen_movi_i64(cpu_V1, imm);
5056
 
                        switch (op) {
5057
 
                        case 0:  /* VSHR */
5058
 
                        case 1:  /* VSRA */
5059
 
                            if (u)
5060
 
                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5061
 
                            else
5062
 
                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5063
 
                            break;
5064
 
                        case 2: /* VRSHR */
5065
 
                        case 3: /* VRSRA */
5066
 
                            if (u)
5067
 
                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5068
 
                            else
5069
 
                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5070
 
                            break;
5071
 
                        case 4: /* VSRI */
5072
 
                        case 5: /* VSHL, VSLI */
5073
 
                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5074
 
                            break;
5075
 
                        case 6: /* VQSHLU */
5076
 
                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5077
 
                                                      cpu_V0, cpu_V1);
5078
 
                            break;
5079
 
                        case 7: /* VQSHL */
5080
 
                            if (u) {
5081
 
                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5082
 
                                                         cpu_V0, cpu_V1);
5083
 
                            } else {
5084
 
                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5085
 
                                                         cpu_V0, cpu_V1);
5086
 
                            }
5087
 
                            break;
5088
 
                        }
5089
 
                        if (op == 1 || op == 3) {
5090
 
                            /* Accumulate.  */
5091
 
                            neon_load_reg64(cpu_V1, rd + pass);
5092
 
                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5093
 
                        } else if (op == 4 || (op == 5 && u)) {
5094
 
                            /* Insert */
5095
 
                            neon_load_reg64(cpu_V1, rd + pass);
5096
 
                            uint64_t mask;
5097
 
                            if (shift < -63 || shift > 63) {
5098
 
                                mask = 0;
5099
 
                            } else {
5100
 
                                if (op == 4) {
5101
 
                                    mask = 0xffffffffffffffffull >> -shift;
5102
 
                                } else {
5103
 
                                    mask = 0xffffffffffffffffull << shift;
5104
 
                                }
5105
 
                            }
5106
 
                            tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5107
 
                            tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5108
 
                        }
5109
 
                        neon_store_reg64(cpu_V0, rd + pass);
5110
 
                    } else { /* size < 3 */
5111
 
                        /* Operands in T0 and T1.  */
5112
 
                        tmp = neon_load_reg(rm, pass);
5113
 
                        tmp2 = tcg_temp_new_i32();
5114
 
                        tcg_gen_movi_i32(tmp2, imm);
5115
 
                        switch (op) {
5116
 
                        case 0:  /* VSHR */
5117
 
                        case 1:  /* VSRA */
5118
 
                            GEN_NEON_INTEGER_OP(shl);
5119
 
                            break;
5120
 
                        case 2: /* VRSHR */
5121
 
                        case 3: /* VRSRA */
5122
 
                            GEN_NEON_INTEGER_OP(rshl);
5123
 
                            break;
5124
 
                        case 4: /* VSRI */
5125
 
                        case 5: /* VSHL, VSLI */
5126
 
                            switch (size) {
5127
 
                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5128
 
                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5129
 
                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5130
 
                            default: abort();
5131
 
                            }
5132
 
                            break;
5133
 
                        case 6: /* VQSHLU */
5134
 
                            switch (size) {
5135
 
                            case 0:
5136
 
                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
5137
 
                                                         tmp, tmp2);
5138
 
                                break;
5139
 
                            case 1:
5140
 
                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
5141
 
                                                          tmp, tmp2);
5142
 
                                break;
5143
 
                            case 2:
5144
 
                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
5145
 
                                                          tmp, tmp2);
5146
 
                                break;
5147
 
                            default:
5148
 
                                abort();
5149
 
                            }
5150
 
                            break;
5151
 
                        case 7: /* VQSHL */
5152
 
                            GEN_NEON_INTEGER_OP_ENV(qshl);
5153
 
                            break;
5154
 
                        }
5155
 
                        tcg_temp_free_i32(tmp2);
5156
 
 
5157
 
                        if (op == 1 || op == 3) {
5158
 
                            /* Accumulate.  */
5159
 
                            tmp2 = neon_load_reg(rd, pass);
5160
 
                            gen_neon_add(size, tmp, tmp2);
5161
 
                            tcg_temp_free_i32(tmp2);
5162
 
                        } else if (op == 4 || (op == 5 && u)) {
5163
 
                            /* Insert */
5164
 
                            switch (size) {
5165
 
                            case 0:
5166
 
                                if (op == 4)
5167
 
                                    mask = 0xff >> -shift;
5168
 
                                else
5169
 
                                    mask = (uint8_t)(0xff << shift);
5170
 
                                mask |= mask << 8;
5171
 
                                mask |= mask << 16;
5172
 
                                break;
5173
 
                            case 1:
5174
 
                                if (op == 4)
5175
 
                                    mask = 0xffff >> -shift;
5176
 
                                else
5177
 
                                    mask = (uint16_t)(0xffff << shift);
5178
 
                                mask |= mask << 16;
5179
 
                                break;
5180
 
                            case 2:
5181
 
                                if (shift < -31 || shift > 31) {
5182
 
                                    mask = 0;
5183
 
                                } else {
5184
 
                                    if (op == 4)
5185
 
                                        mask = 0xffffffffu >> -shift;
5186
 
                                    else
5187
 
                                        mask = 0xffffffffu << shift;
5188
 
                                }
5189
 
                                break;
5190
 
                            default:
5191
 
                                abort();
5192
 
                            }
5193
 
                            tmp2 = neon_load_reg(rd, pass);
5194
 
                            tcg_gen_andi_i32(tmp, tmp, mask);
5195
 
                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5196
 
                            tcg_gen_or_i32(tmp, tmp, tmp2);
5197
 
                            tcg_temp_free_i32(tmp2);
5198
 
                        }
5199
 
                        neon_store_reg(rd, pass, tmp);
5200
 
                    }
5201
 
                } /* for pass */
5202
 
            } else if (op < 10) {
5203
 
                /* Shift by immediate and narrow:
5204
 
                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
5205
 
                int input_unsigned = (op == 8) ? !u : u;
5206
 
                if (rm & 1) {
5207
 
                    return 1;
5208
 
                }
5209
 
                shift = shift - (1 << (size + 3));
5210
 
                size++;
5211
 
                if (size == 3) {
5212
 
                    tmp64 = tcg_const_i64(shift);
5213
 
                    neon_load_reg64(cpu_V0, rm);
5214
 
                    neon_load_reg64(cpu_V1, rm + 1);
5215
 
                    for (pass = 0; pass < 2; pass++) {
5216
 
                        TCGv_i64 in;
5217
 
                        if (pass == 0) {
5218
 
                            in = cpu_V0;
5219
 
                        } else {
5220
 
                            in = cpu_V1;
5221
 
                        }
5222
 
                        if (q) {
5223
 
                            if (input_unsigned) {
5224
 
                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5225
 
                            } else {
5226
 
                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5227
 
                            }
5228
 
                        } else {
5229
 
                            if (input_unsigned) {
5230
 
                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5231
 
                            } else {
5232
 
                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5233
 
                            }
5234
 
                        }
5235
 
                        tmp = tcg_temp_new_i32();
5236
 
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5237
 
                        neon_store_reg(rd, pass, tmp);
5238
 
                    } /* for pass */
5239
 
                    tcg_temp_free_i64(tmp64);
5240
 
                } else {
5241
 
                    if (size == 1) {
5242
 
                        imm = (uint16_t)shift;
5243
 
                        imm |= imm << 16;
5244
 
                    } else {
5245
 
                        /* size == 2 */
5246
 
                        imm = (uint32_t)shift;
5247
 
                    }
5248
 
                    tmp2 = tcg_const_i32(imm);
5249
 
                    tmp4 = neon_load_reg(rm + 1, 0);
5250
 
                    tmp5 = neon_load_reg(rm + 1, 1);
5251
 
                    for (pass = 0; pass < 2; pass++) {
5252
 
                        if (pass == 0) {
5253
 
                            tmp = neon_load_reg(rm, 0);
5254
 
                        } else {
5255
 
                            tmp = tmp4;
5256
 
                        }
5257
 
                        gen_neon_shift_narrow(size, tmp, tmp2, q,
5258
 
                                              input_unsigned);
5259
 
                        if (pass == 0) {
5260
 
                            tmp3 = neon_load_reg(rm, 1);
5261
 
                        } else {
5262
 
                            tmp3 = tmp5;
5263
 
                        }
5264
 
                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
5265
 
                                              input_unsigned);
5266
 
                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5267
 
                        tcg_temp_free_i32(tmp);
5268
 
                        tcg_temp_free_i32(tmp3);
5269
 
                        tmp = tcg_temp_new_i32();
5270
 
                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5271
 
                        neon_store_reg(rd, pass, tmp);
5272
 
                    } /* for pass */
5273
 
                    tcg_temp_free_i32(tmp2);
5274
 
                }
5275
 
            } else if (op == 10) {
5276
 
                /* VSHLL, VMOVL */
5277
 
                if (q || (rd & 1)) {
5278
 
                    return 1;
5279
 
                }
5280
 
                tmp = neon_load_reg(rm, 0);
5281
 
                tmp2 = neon_load_reg(rm, 1);
5282
 
                for (pass = 0; pass < 2; pass++) {
5283
 
                    if (pass == 1)
5284
 
                        tmp = tmp2;
5285
 
 
5286
 
                    gen_neon_widen(cpu_V0, tmp, size, u);
5287
 
 
5288
 
                    if (shift != 0) {
5289
 
                        /* The shift is less than the width of the source
5290
 
                           type, so we can just shift the whole register.  */
5291
 
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5292
 
                        /* Widen the result of shift: we need to clear
5293
 
                         * the potential overflow bits resulting from
5294
 
                         * left bits of the narrow input appearing as
5295
 
                         * right bits of left the neighbour narrow
5296
 
                         * input.  */
5297
 
                        if (size < 2 || !u) {
5298
 
                            uint64_t imm64;
5299
 
                            if (size == 0) {
5300
 
                                imm = (0xffu >> (8 - shift));
5301
 
                                imm |= imm << 16;
5302
 
                            } else if (size == 1) {
5303
 
                                imm = 0xffff >> (16 - shift);
5304
 
                            } else {
5305
 
                                /* size == 2 */
5306
 
                                imm = 0xffffffff >> (32 - shift);
5307
 
                            }
5308
 
                            if (size < 2) {
5309
 
                                imm64 = imm | (((uint64_t)imm) << 32);
5310
 
                            } else {
5311
 
                                imm64 = imm;
5312
 
                            }
5313
 
                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5314
 
                        }
5315
 
                    }
5316
 
                    neon_store_reg64(cpu_V0, rd + pass);
5317
 
                }
5318
 
            } else if (op >= 14) {
5319
 
                /* VCVT fixed-point.  */
5320
 
                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5321
 
                    return 1;
5322
 
                }
5323
 
                /* We have already masked out the must-be-1 top bit of imm6,
5324
 
                 * hence this 32-shift where the ARM ARM has 64-imm6.
5325
 
                 */
5326
 
                shift = 32 - shift;
5327
 
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
5328
 
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5329
 
                    if (!(op & 1)) {
5330
 
                        if (u)
5331
 
                            gen_vfp_ulto(0, shift, 1);
5332
 
                        else
5333
 
                            gen_vfp_slto(0, shift, 1);
5334
 
                    } else {
5335
 
                        if (u)
5336
 
                            gen_vfp_toul(0, shift, 1);
5337
 
                        else
5338
 
                            gen_vfp_tosl(0, shift, 1);
5339
 
                    }
5340
 
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5341
 
                }
5342
 
            } else {
5343
 
                return 1;
5344
 
            }
5345
 
        } else { /* (insn & 0x00380080) == 0 */
5346
 
            int invert;
5347
 
            if (q && (rd & 1)) {
5348
 
                return 1;
5349
 
            }
5350
 
 
5351
 
            op = (insn >> 8) & 0xf;
5352
 
            /* One register and immediate.  */
5353
 
            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5354
 
            invert = (insn & (1 << 5)) != 0;
5355
 
            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5356
 
             * We choose to not special-case this and will behave as if a
5357
 
             * valid constant encoding of 0 had been given.
5358
 
             */
5359
 
            switch (op) {
5360
 
            case 0: case 1:
5361
 
                /* no-op */
5362
 
                break;
5363
 
            case 2: case 3:
5364
 
                imm <<= 8;
5365
 
                break;
5366
 
            case 4: case 5:
5367
 
                imm <<= 16;
5368
 
                break;
5369
 
            case 6: case 7:
5370
 
                imm <<= 24;
5371
 
                break;
5372
 
            case 8: case 9:
5373
 
                imm |= imm << 16;
5374
 
                break;
5375
 
            case 10: case 11:
5376
 
                imm = (imm << 8) | (imm << 24);
5377
 
                break;
5378
 
            case 12:
5379
 
                imm = (imm << 8) | 0xff;
5380
 
                break;
5381
 
            case 13:
5382
 
                imm = (imm << 16) | 0xffff;
5383
 
                break;
5384
 
            case 14:
5385
 
                imm |= (imm << 8) | (imm << 16) | (imm << 24);
5386
 
                if (invert)
5387
 
                    imm = ~imm;
5388
 
                break;
5389
 
            case 15:
5390
 
                if (invert) {
5391
 
                    return 1;
5392
 
                }
5393
 
                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5394
 
                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5395
 
                break;
5396
 
            }
5397
 
            if (invert)
5398
 
                imm = ~imm;
5399
 
 
5400
 
            for (pass = 0; pass < (q ? 4 : 2); pass++) {
5401
 
                if (op & 1 && op < 12) {
5402
 
                    tmp = neon_load_reg(rd, pass);
5403
 
                    if (invert) {
5404
 
                        /* The immediate value has already been inverted, so
5405
 
                           BIC becomes AND.  */
5406
 
                        tcg_gen_andi_i32(tmp, tmp, imm);
5407
 
                    } else {
5408
 
                        tcg_gen_ori_i32(tmp, tmp, imm);
5409
 
                    }
5410
 
                } else {
5411
 
                    /* VMOV, VMVN.  */
5412
 
                    tmp = tcg_temp_new_i32();
5413
 
                    if (op == 14 && invert) {
5414
 
                        int n;
5415
 
                        uint32_t val;
5416
 
                        val = 0;
5417
 
                        for (n = 0; n < 4; n++) {
5418
 
                            if (imm & (1 << (n + (pass & 1) * 4)))
5419
 
                                val |= 0xff << (n * 8);
5420
 
                        }
5421
 
                        tcg_gen_movi_i32(tmp, val);
5422
 
                    } else {
5423
 
                        tcg_gen_movi_i32(tmp, imm);
5424
 
                    }
5425
 
                }
5426
 
                neon_store_reg(rd, pass, tmp);
5427
 
            }
5428
 
        }
5429
 
    } else { /* (insn & 0x00800010 == 0x00800000) */
5430
 
        if (size != 3) {
5431
 
            op = (insn >> 8) & 0xf;
5432
 
            if ((insn & (1 << 6)) == 0) {
5433
 
                /* Three registers of different lengths.  */
5434
 
                int src1_wide;
5435
 
                int src2_wide;
5436
 
                int prewiden;
5437
 
                /* undefreq: bit 0 : UNDEF if size != 0
5438
 
                 *           bit 1 : UNDEF if size == 0
5439
 
                 *           bit 2 : UNDEF if U == 1
5440
 
                 * Note that [1:0] set implies 'always UNDEF'
5441
 
                 */
5442
 
                int undefreq;
5443
 
                /* prewiden, src1_wide, src2_wide, undefreq */
5444
 
                static const int neon_3reg_wide[16][4] = {
5445
 
                    {1, 0, 0, 0}, /* VADDL */
5446
 
                    {1, 1, 0, 0}, /* VADDW */
5447
 
                    {1, 0, 0, 0}, /* VSUBL */
5448
 
                    {1, 1, 0, 0}, /* VSUBW */
5449
 
                    {0, 1, 1, 0}, /* VADDHN */
5450
 
                    {0, 0, 0, 0}, /* VABAL */
5451
 
                    {0, 1, 1, 0}, /* VSUBHN */
5452
 
                    {0, 0, 0, 0}, /* VABDL */
5453
 
                    {0, 0, 0, 0}, /* VMLAL */
5454
 
                    {0, 0, 0, 6}, /* VQDMLAL */
5455
 
                    {0, 0, 0, 0}, /* VMLSL */
5456
 
                    {0, 0, 0, 6}, /* VQDMLSL */
5457
 
                    {0, 0, 0, 0}, /* Integer VMULL */
5458
 
                    {0, 0, 0, 2}, /* VQDMULL */
5459
 
                    {0, 0, 0, 5}, /* Polynomial VMULL */
5460
 
                    {0, 0, 0, 3}, /* Reserved: always UNDEF */
5461
 
                };
5462
 
 
5463
 
                prewiden = neon_3reg_wide[op][0];
5464
 
                src1_wide = neon_3reg_wide[op][1];
5465
 
                src2_wide = neon_3reg_wide[op][2];
5466
 
                undefreq = neon_3reg_wide[op][3];
5467
 
 
5468
 
                if (((undefreq & 1) && (size != 0)) ||
5469
 
                    ((undefreq & 2) && (size == 0)) ||
5470
 
                    ((undefreq & 4) && u)) {
5471
 
                    return 1;
5472
 
                }
5473
 
                if ((src1_wide && (rn & 1)) ||
5474
 
                    (src2_wide && (rm & 1)) ||
5475
 
                    (!src2_wide && (rd & 1))) {
5476
 
                    return 1;
5477
 
                }
5478
 
 
5479
 
                /* Avoid overlapping operands.  Wide source operands are
5480
 
                   always aligned so will never overlap with wide
5481
 
                   destinations in problematic ways.  */
5482
 
                if (rd == rm && !src2_wide) {
5483
 
                    tmp = neon_load_reg(rm, 1);
5484
 
                    neon_store_scratch(2, tmp);
5485
 
                } else if (rd == rn && !src1_wide) {
5486
 
                    tmp = neon_load_reg(rn, 1);
5487
 
                    neon_store_scratch(2, tmp);
5488
 
                }
5489
 
                TCGV_UNUSED_I32(tmp3);
5490
 
                for (pass = 0; pass < 2; pass++) {
5491
 
                    if (src1_wide) {
5492
 
                        neon_load_reg64(cpu_V0, rn + pass);
5493
 
                        TCGV_UNUSED_I32(tmp);
5494
 
                    } else {
5495
 
                        if (pass == 1 && rd == rn) {
5496
 
                            tmp = neon_load_scratch(2);
5497
 
                        } else {
5498
 
                            tmp = neon_load_reg(rn, pass);
5499
 
                        }
5500
 
                        if (prewiden) {
5501
 
                            gen_neon_widen(cpu_V0, tmp, size, u);
5502
 
                        }
5503
 
                    }
5504
 
                    if (src2_wide) {
5505
 
                        neon_load_reg64(cpu_V1, rm + pass);
5506
 
                        TCGV_UNUSED_I32(tmp2);
5507
 
                    } else {
5508
 
                        if (pass == 1 && rd == rm) {
5509
 
                            tmp2 = neon_load_scratch(2);
5510
 
                        } else {
5511
 
                            tmp2 = neon_load_reg(rm, pass);
5512
 
                        }
5513
 
                        if (prewiden) {
5514
 
                            gen_neon_widen(cpu_V1, tmp2, size, u);
5515
 
                        }
5516
 
                    }
5517
 
                    switch (op) {
5518
 
                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5519
 
                        gen_neon_addl(size);
5520
 
                        break;
5521
 
                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5522
 
                        gen_neon_subl(size);
5523
 
                        break;
5524
 
                    case 5: case 7: /* VABAL, VABDL */
5525
 
                        switch ((size << 1) | u) {
5526
 
                        case 0:
5527
 
                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5528
 
                            break;
5529
 
                        case 1:
5530
 
                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5531
 
                            break;
5532
 
                        case 2:
5533
 
                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5534
 
                            break;
5535
 
                        case 3:
5536
 
                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5537
 
                            break;
5538
 
                        case 4:
5539
 
                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5540
 
                            break;
5541
 
                        case 5:
5542
 
                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5543
 
                            break;
5544
 
                        default: abort();
5545
 
                        }
5546
 
                        tcg_temp_free_i32(tmp2);
5547
 
                        tcg_temp_free_i32(tmp);
5548
 
                        break;
5549
 
                    case 8: case 9: case 10: case 11: case 12: case 13:
5550
 
                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5551
 
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5552
 
                        break;
5553
 
                    case 14: /* Polynomial VMULL */
5554
 
                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5555
 
                        tcg_temp_free_i32(tmp2);
5556
 
                        tcg_temp_free_i32(tmp);
5557
 
                        break;
5558
 
                    default: /* 15 is RESERVED: caught earlier  */
5559
 
                        abort();
5560
 
                    }
5561
 
                    if (op == 13) {
5562
 
                        /* VQDMULL */
5563
 
                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5564
 
                        neon_store_reg64(cpu_V0, rd + pass);
5565
 
                    } else if (op == 5 || (op >= 8 && op <= 11)) {
5566
 
                        /* Accumulate.  */
5567
 
                        neon_load_reg64(cpu_V1, rd + pass);
5568
 
                        switch (op) {
5569
 
                        case 10: /* VMLSL */
5570
 
                            gen_neon_negl(cpu_V0, size);
5571
 
                            /* Fall through */
5572
 
                        case 5: case 8: /* VABAL, VMLAL */
5573
 
                            gen_neon_addl(size);
5574
 
                            break;
5575
 
                        case 9: case 11: /* VQDMLAL, VQDMLSL */
5576
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5577
 
                            if (op == 11) {
5578
 
                                gen_neon_negl(cpu_V0, size);
5579
 
                            }
5580
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5581
 
                            break;
5582
 
                        default:
5583
 
                            abort();
5584
 
                        }
5585
 
                        neon_store_reg64(cpu_V0, rd + pass);
5586
 
                    } else if (op == 4 || op == 6) {
5587
 
                        /* Narrowing operation.  */
5588
 
                        tmp = tcg_temp_new_i32();
5589
 
                        if (!u) {
5590
 
                            switch (size) {
5591
 
                            case 0:
5592
 
                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5593
 
                                break;
5594
 
                            case 1:
5595
 
                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5596
 
                                break;
5597
 
                            case 2:
5598
 
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5599
 
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5600
 
                                break;
5601
 
                            default: abort();
5602
 
                            }
5603
 
                        } else {
5604
 
                            switch (size) {
5605
 
                            case 0:
5606
 
                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5607
 
                                break;
5608
 
                            case 1:
5609
 
                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5610
 
                                break;
5611
 
                            case 2:
5612
 
                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5613
 
                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5614
 
                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5615
 
                                break;
5616
 
                            default: abort();
5617
 
                            }
5618
 
                        }
5619
 
                        if (pass == 0) {
5620
 
                            tmp3 = tmp;
5621
 
                        } else {
5622
 
                            neon_store_reg(rd, 0, tmp3);
5623
 
                            neon_store_reg(rd, 1, tmp);
5624
 
                        }
5625
 
                    } else {
5626
 
                        /* Write back the result.  */
5627
 
                        neon_store_reg64(cpu_V0, rd + pass);
5628
 
                    }
5629
 
                }
5630
 
            } else {
5631
 
                /* Two registers and a scalar. NB that for ops of this form
5632
 
                 * the ARM ARM labels bit 24 as Q, but it is in our variable
5633
 
                 * 'u', not 'q'.
5634
 
                 */
5635
 
                if (size == 0) {
5636
 
                    return 1;
5637
 
                }
5638
 
                switch (op) {
5639
 
                case 1: /* Float VMLA scalar */
5640
 
                case 5: /* Floating point VMLS scalar */
5641
 
                case 9: /* Floating point VMUL scalar */
5642
 
                    if (size == 1) {
5643
 
                        return 1;
5644
 
                    }
5645
 
                    /* fall through */
5646
 
                case 0: /* Integer VMLA scalar */
5647
 
                case 4: /* Integer VMLS scalar */
5648
 
                case 8: /* Integer VMUL scalar */
5649
 
                case 12: /* VQDMULH scalar */
5650
 
                case 13: /* VQRDMULH scalar */
5651
 
                    if (u && ((rd | rn) & 1)) {
5652
 
                        return 1;
5653
 
                    }
5654
 
                    tmp = neon_get_scalar(size, rm);
5655
 
                    neon_store_scratch(0, tmp);
5656
 
                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
5657
 
                        tmp = neon_load_scratch(0);
5658
 
                        tmp2 = neon_load_reg(rn, pass);
5659
 
                        if (op == 12) {
5660
 
                            if (size == 1) {
5661
 
                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5662
 
                            } else {
5663
 
                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5664
 
                            }
5665
 
                        } else if (op == 13) {
5666
 
                            if (size == 1) {
5667
 
                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5668
 
                            } else {
5669
 
                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5670
 
                            }
5671
 
                        } else if (op & 1) {
5672
 
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5673
 
                            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5674
 
                            tcg_temp_free_ptr(fpstatus);
5675
 
                        } else {
5676
 
                            switch (size) {
5677
 
                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5678
 
                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5679
 
                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5680
 
                            default: abort();
5681
 
                            }
5682
 
                        }
5683
 
                        tcg_temp_free_i32(tmp2);
5684
 
                        if (op < 8) {
5685
 
                            /* Accumulate.  */
5686
 
                            tmp2 = neon_load_reg(rd, pass);
5687
 
                            switch (op) {
5688
 
                            case 0:
5689
 
                                gen_neon_add(size, tmp, tmp2);
5690
 
                                break;
5691
 
                            case 1:
5692
 
                            {
5693
 
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5694
 
                                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5695
 
                                tcg_temp_free_ptr(fpstatus);
5696
 
                                break;
5697
 
                            }
5698
 
                            case 4:
5699
 
                                gen_neon_rsb(size, tmp, tmp2);
5700
 
                                break;
5701
 
                            case 5:
5702
 
                            {
5703
 
                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5704
 
                                gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5705
 
                                tcg_temp_free_ptr(fpstatus);
5706
 
                                break;
5707
 
                            }
5708
 
                            default:
5709
 
                                abort();
5710
 
                            }
5711
 
                            tcg_temp_free_i32(tmp2);
5712
 
                        }
5713
 
                        neon_store_reg(rd, pass, tmp);
5714
 
                    }
5715
 
                    break;
5716
 
                case 3: /* VQDMLAL scalar */
5717
 
                case 7: /* VQDMLSL scalar */
5718
 
                case 11: /* VQDMULL scalar */
5719
 
                    if (u == 1) {
5720
 
                        return 1;
5721
 
                    }
5722
 
                    /* fall through */
5723
 
                case 2: /* VMLAL sclar */
5724
 
                case 6: /* VMLSL scalar */
5725
 
                case 10: /* VMULL scalar */
5726
 
                    if (rd & 1) {
5727
 
                        return 1;
5728
 
                    }
5729
 
                    tmp2 = neon_get_scalar(size, rm);
5730
 
                    /* We need a copy of tmp2 because gen_neon_mull
5731
 
                     * deletes it during pass 0.  */
5732
 
                    tmp4 = tcg_temp_new_i32();
5733
 
                    tcg_gen_mov_i32(tmp4, tmp2);
5734
 
                    tmp3 = neon_load_reg(rn, 1);
5735
 
 
5736
 
                    for (pass = 0; pass < 2; pass++) {
5737
 
                        if (pass == 0) {
5738
 
                            tmp = neon_load_reg(rn, 0);
5739
 
                        } else {
5740
 
                            tmp = tmp3;
5741
 
                            tmp2 = tmp4;
5742
 
                        }
5743
 
                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5744
 
                        if (op != 11) {
5745
 
                            neon_load_reg64(cpu_V1, rd + pass);
5746
 
                        }
5747
 
                        switch (op) {
5748
 
                        case 6:
5749
 
                            gen_neon_negl(cpu_V0, size);
5750
 
                            /* Fall through */
5751
 
                        case 2:
5752
 
                            gen_neon_addl(size);
5753
 
                            break;
5754
 
                        case 3: case 7:
5755
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5756
 
                            if (op == 7) {
5757
 
                                gen_neon_negl(cpu_V0, size);
5758
 
                            }
5759
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5760
 
                            break;
5761
 
                        case 10:
5762
 
                            /* no-op */
5763
 
                            break;
5764
 
                        case 11:
5765
 
                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5766
 
                            break;
5767
 
                        default:
5768
 
                            abort();
5769
 
                        }
5770
 
                        neon_store_reg64(cpu_V0, rd + pass);
5771
 
                    }
5772
 
 
5773
 
 
5774
 
                    break;
5775
 
                default: /* 14 and 15 are RESERVED */
5776
 
                    return 1;
5777
 
                }
5778
 
            }
5779
 
        } else { /* size == 3 */
5780
 
            if (!u) {
5781
 
                /* Extract.  */
5782
 
                imm = (insn >> 8) & 0xf;
5783
 
 
5784
 
                if (imm > 7 && !q)
5785
 
                    return 1;
5786
 
 
5787
 
                if (q && ((rd | rn | rm) & 1)) {
5788
 
                    return 1;
5789
 
                }
5790
 
 
5791
 
                if (imm == 0) {
5792
 
                    neon_load_reg64(cpu_V0, rn);
5793
 
                    if (q) {
5794
 
                        neon_load_reg64(cpu_V1, rn + 1);
5795
 
                    }
5796
 
                } else if (imm == 8) {
5797
 
                    neon_load_reg64(cpu_V0, rn + 1);
5798
 
                    if (q) {
5799
 
                        neon_load_reg64(cpu_V1, rm);
5800
 
                    }
5801
 
                } else if (q) {
5802
 
                    tmp64 = tcg_temp_new_i64();
5803
 
                    if (imm < 8) {
5804
 
                        neon_load_reg64(cpu_V0, rn);
5805
 
                        neon_load_reg64(tmp64, rn + 1);
5806
 
                    } else {
5807
 
                        neon_load_reg64(cpu_V0, rn + 1);
5808
 
                        neon_load_reg64(tmp64, rm);
5809
 
                    }
5810
 
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5811
 
                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5812
 
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5813
 
                    if (imm < 8) {
5814
 
                        neon_load_reg64(cpu_V1, rm);
5815
 
                    } else {
5816
 
                        neon_load_reg64(cpu_V1, rm + 1);
5817
 
                        imm -= 8;
5818
 
                    }
5819
 
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5820
 
                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5821
 
                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5822
 
                    tcg_temp_free_i64(tmp64);
5823
 
                } else {
5824
 
                    /* BUGFIX */
5825
 
                    neon_load_reg64(cpu_V0, rn);
5826
 
                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5827
 
                    neon_load_reg64(cpu_V1, rm);
5828
 
                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5829
 
                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5830
 
                }
5831
 
                neon_store_reg64(cpu_V0, rd);
5832
 
                if (q) {
5833
 
                    neon_store_reg64(cpu_V1, rd + 1);
5834
 
                }
5835
 
            } else if ((insn & (1 << 11)) == 0) {
5836
 
                /* Two register misc.  */
5837
 
                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5838
 
                size = (insn >> 18) & 3;
5839
 
                /* UNDEF for unknown op values and bad op-size combinations */
5840
 
                if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5841
 
                    return 1;
5842
 
                }
5843
 
                if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5844
 
                    q && ((rm | rd) & 1)) {
5845
 
                    return 1;
5846
 
                }
5847
 
                switch (op) {
5848
 
                case NEON_2RM_VREV64:
5849
 
                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
5850
 
                        tmp = neon_load_reg(rm, pass * 2);
5851
 
                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
5852
 
                        switch (size) {
5853
 
                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5854
 
                        case 1: gen_swap_half(tmp); break;
5855
 
                        case 2: /* no-op */ break;
5856
 
                        default: abort();
5857
 
                        }
5858
 
                        neon_store_reg(rd, pass * 2 + 1, tmp);
5859
 
                        if (size == 2) {
5860
 
                            neon_store_reg(rd, pass * 2, tmp2);
5861
 
                        } else {
5862
 
                            switch (size) {
5863
 
                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5864
 
                            case 1: gen_swap_half(tmp2); break;
5865
 
                            default: abort();
5866
 
                            }
5867
 
                            neon_store_reg(rd, pass * 2, tmp2);
5868
 
                        }
5869
 
                    }
5870
 
                    break;
5871
 
                case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5872
 
                case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5873
 
                    for (pass = 0; pass < q + 1; pass++) {
5874
 
                        tmp = neon_load_reg(rm, pass * 2);
5875
 
                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
5876
 
                        tmp = neon_load_reg(rm, pass * 2 + 1);
5877
 
                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
5878
 
                        switch (size) {
5879
 
                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5880
 
                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5881
 
                        case 2: tcg_gen_add_i64(CPU_V001); break;
5882
 
                        default: abort();
5883
 
                        }
5884
 
                        if (op >= NEON_2RM_VPADAL) {
5885
 
                            /* Accumulate.  */
5886
 
                            neon_load_reg64(cpu_V1, rd + pass);
5887
 
                            gen_neon_addl(size);
5888
 
                        }
5889
 
                        neon_store_reg64(cpu_V0, rd + pass);
5890
 
                    }
5891
 
                    break;
5892
 
                case NEON_2RM_VTRN:
5893
 
                    if (size == 2) {
5894
 
                        int n;
5895
 
                        for (n = 0; n < (q ? 4 : 2); n += 2) {
5896
 
                            tmp = neon_load_reg(rm, n);
5897
 
                            tmp2 = neon_load_reg(rd, n + 1);
5898
 
                            neon_store_reg(rm, n, tmp2);
5899
 
                            neon_store_reg(rd, n + 1, tmp);
5900
 
                        }
5901
 
                    } else {
5902
 
                        goto elementwise;
5903
 
                    }
5904
 
                    break;
5905
 
                case NEON_2RM_VUZP:
5906
 
                    if (gen_neon_unzip(rd, rm, size, q)) {
5907
 
                        return 1;
5908
 
                    }
5909
 
                    break;
5910
 
                case NEON_2RM_VZIP:
5911
 
                    if (gen_neon_zip(rd, rm, size, q)) {
5912
 
                        return 1;
5913
 
                    }
5914
 
                    break;
5915
 
                case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5916
 
                    /* also VQMOVUN; op field and mnemonics don't line up */
5917
 
                    if (rm & 1) {
5918
 
                        return 1;
5919
 
                    }
5920
 
                    TCGV_UNUSED_I32(tmp2);
5921
 
                    for (pass = 0; pass < 2; pass++) {
5922
 
                        neon_load_reg64(cpu_V0, rm + pass);
5923
 
                        tmp = tcg_temp_new_i32();
5924
 
                        gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5925
 
                                           tmp, cpu_V0);
5926
 
                        if (pass == 0) {
5927
 
                            tmp2 = tmp;
5928
 
                        } else {
5929
 
                            neon_store_reg(rd, 0, tmp2);
5930
 
                            neon_store_reg(rd, 1, tmp);
5931
 
                        }
5932
 
                    }
5933
 
                    break;
5934
 
                case NEON_2RM_VSHLL:
5935
 
                    if (q || (rd & 1)) {
5936
 
                        return 1;
5937
 
                    }
5938
 
                    tmp = neon_load_reg(rm, 0);
5939
 
                    tmp2 = neon_load_reg(rm, 1);
5940
 
                    for (pass = 0; pass < 2; pass++) {
5941
 
                        if (pass == 1)
5942
 
                            tmp = tmp2;
5943
 
                        gen_neon_widen(cpu_V0, tmp, size, 1);
5944
 
                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5945
 
                        neon_store_reg64(cpu_V0, rd + pass);
5946
 
                    }
5947
 
                    break;
5948
 
                case NEON_2RM_VCVT_F16_F32:
5949
 
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5950
 
                        q || (rm & 1)) {
5951
 
                        return 1;
5952
 
                    }
5953
 
                    tmp = tcg_temp_new_i32();
5954
 
                    tmp2 = tcg_temp_new_i32();
5955
 
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5956
 
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5957
 
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5958
 
                    gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5959
 
                    tcg_gen_shli_i32(tmp2, tmp2, 16);
5960
 
                    tcg_gen_or_i32(tmp2, tmp2, tmp);
5961
 
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5962
 
                    gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5963
 
                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5964
 
                    neon_store_reg(rd, 0, tmp2);
5965
 
                    tmp2 = tcg_temp_new_i32();
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
 
                    neon_store_reg(rd, 1, tmp2);
5970
 
                    tcg_temp_free_i32(tmp);
5971
 
                    break;
5972
 
                case NEON_2RM_VCVT_F32_F16:
5973
 
                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5974
 
                        q || (rd & 1)) {
5975
 
                        return 1;
5976
 
                    }
5977
 
                    tmp3 = tcg_temp_new_i32();
5978
 
                    tmp = neon_load_reg(rm, 0);
5979
 
                    tmp2 = neon_load_reg(rm, 1);
5980
 
                    tcg_gen_ext16u_i32(tmp3, tmp);
5981
 
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5982
 
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5983
 
                    tcg_gen_shri_i32(tmp3, tmp, 16);
5984
 
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5985
 
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5986
 
                    tcg_temp_free_i32(tmp);
5987
 
                    tcg_gen_ext16u_i32(tmp3, tmp2);
5988
 
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5989
 
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5990
 
                    tcg_gen_shri_i32(tmp3, tmp2, 16);
5991
 
                    gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5992
 
                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5993
 
                    tcg_temp_free_i32(tmp2);
5994
 
                    tcg_temp_free_i32(tmp3);
5995
 
                    break;
5996
 
                default:
5997
 
                elementwise:
5998
 
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
5999
 
                        if (neon_2rm_is_float_op(op)) {
6000
 
                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
6001
 
                                           neon_reg_offset(rm, pass));
6002
 
                            TCGV_UNUSED_I32(tmp);
6003
 
                        } else {
6004
 
                            tmp = neon_load_reg(rm, pass);
6005
 
                        }
6006
 
                        switch (op) {
6007
 
                        case NEON_2RM_VREV32:
6008
 
                            switch (size) {
6009
 
                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6010
 
                            case 1: gen_swap_half(tmp); break;
6011
 
                            default: abort();
6012
 
                            }
6013
 
                            break;
6014
 
                        case NEON_2RM_VREV16:
6015
 
                            gen_rev16(tmp);
6016
 
                            break;
6017
 
                        case NEON_2RM_VCLS:
6018
 
                            switch (size) {
6019
 
                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6020
 
                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6021
 
                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6022
 
                            default: abort();
6023
 
                            }
6024
 
                            break;
6025
 
                        case NEON_2RM_VCLZ:
6026
 
                            switch (size) {
6027
 
                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6028
 
                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6029
 
                            case 2: gen_helper_clz(tmp, tmp); break;
6030
 
                            default: abort();
6031
 
                            }
6032
 
                            break;
6033
 
                        case NEON_2RM_VCNT:
6034
 
                            gen_helper_neon_cnt_u8(tmp, tmp);
6035
 
                            break;
6036
 
                        case NEON_2RM_VMVN:
6037
 
                            tcg_gen_not_i32(tmp, tmp);
6038
 
                            break;
6039
 
                        case NEON_2RM_VQABS:
6040
 
                            switch (size) {
6041
 
                            case 0:
6042
 
                                gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6043
 
                                break;
6044
 
                            case 1:
6045
 
                                gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6046
 
                                break;
6047
 
                            case 2:
6048
 
                                gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6049
 
                                break;
6050
 
                            default: abort();
6051
 
                            }
6052
 
                            break;
6053
 
                        case NEON_2RM_VQNEG:
6054
 
                            switch (size) {
6055
 
                            case 0:
6056
 
                                gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6057
 
                                break;
6058
 
                            case 1:
6059
 
                                gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6060
 
                                break;
6061
 
                            case 2:
6062
 
                                gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6063
 
                                break;
6064
 
                            default: abort();
6065
 
                            }
6066
 
                            break;
6067
 
                        case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6068
 
                            tmp2 = tcg_const_i32(0);
6069
 
                            switch(size) {
6070
 
                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6071
 
                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6072
 
                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6073
 
                            default: abort();
6074
 
                            }
6075
 
                            tcg_temp_free_i32(tmp2);
6076
 
                            if (op == NEON_2RM_VCLE0) {
6077
 
                                tcg_gen_not_i32(tmp, tmp);
6078
 
                            }
6079
 
                            break;
6080
 
                        case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6081
 
                            tmp2 = tcg_const_i32(0);
6082
 
                            switch(size) {
6083
 
                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6084
 
                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6085
 
                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6086
 
                            default: abort();
6087
 
                            }
6088
 
                            tcg_temp_free_i32(tmp2);
6089
 
                            if (op == NEON_2RM_VCLT0) {
6090
 
                                tcg_gen_not_i32(tmp, tmp);
6091
 
                            }
6092
 
                            break;
6093
 
                        case NEON_2RM_VCEQ0:
6094
 
                            tmp2 = tcg_const_i32(0);
6095
 
                            switch(size) {
6096
 
                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6097
 
                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6098
 
                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6099
 
                            default: abort();
6100
 
                            }
6101
 
                            tcg_temp_free_i32(tmp2);
6102
 
                            break;
6103
 
                        case NEON_2RM_VABS:
6104
 
                            switch(size) {
6105
 
                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6106
 
                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6107
 
                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
6108
 
                            default: abort();
6109
 
                            }
6110
 
                            break;
6111
 
                        case NEON_2RM_VNEG:
6112
 
                            tmp2 = tcg_const_i32(0);
6113
 
                            gen_neon_rsb(size, tmp, tmp2);
6114
 
                            tcg_temp_free_i32(tmp2);
6115
 
                            break;
6116
 
                        case NEON_2RM_VCGT0_F:
6117
 
                        {
6118
 
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6119
 
                            tmp2 = tcg_const_i32(0);
6120
 
                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6121
 
                            tcg_temp_free_i32(tmp2);
6122
 
                            tcg_temp_free_ptr(fpstatus);
6123
 
                            break;
6124
 
                        }
6125
 
                        case NEON_2RM_VCGE0_F:
6126
 
                        {
6127
 
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6128
 
                            tmp2 = tcg_const_i32(0);
6129
 
                            gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6130
 
                            tcg_temp_free_i32(tmp2);
6131
 
                            tcg_temp_free_ptr(fpstatus);
6132
 
                            break;
6133
 
                        }
6134
 
                        case NEON_2RM_VCEQ0_F:
6135
 
                        {
6136
 
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6137
 
                            tmp2 = tcg_const_i32(0);
6138
 
                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6139
 
                            tcg_temp_free_i32(tmp2);
6140
 
                            tcg_temp_free_ptr(fpstatus);
6141
 
                            break;
6142
 
                        }
6143
 
                        case NEON_2RM_VCLE0_F:
6144
 
                        {
6145
 
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6146
 
                            tmp2 = tcg_const_i32(0);
6147
 
                            gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6148
 
                            tcg_temp_free_i32(tmp2);
6149
 
                            tcg_temp_free_ptr(fpstatus);
6150
 
                            break;
6151
 
                        }
6152
 
                        case NEON_2RM_VCLT0_F:
6153
 
                        {
6154
 
                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6155
 
                            tmp2 = tcg_const_i32(0);
6156
 
                            gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6157
 
                            tcg_temp_free_i32(tmp2);
6158
 
                            tcg_temp_free_ptr(fpstatus);
6159
 
                            break;
6160
 
                        }
6161
 
                        case NEON_2RM_VABS_F:
6162
 
                            gen_vfp_abs(0);
6163
 
                            break;
6164
 
                        case NEON_2RM_VNEG_F:
6165
 
                            gen_vfp_neg(0);
6166
 
                            break;
6167
 
                        case NEON_2RM_VSWP:
6168
 
                            tmp2 = neon_load_reg(rd, pass);
6169
 
                            neon_store_reg(rm, pass, tmp2);
6170
 
                            break;
6171
 
                        case NEON_2RM_VTRN:
6172
 
                            tmp2 = neon_load_reg(rd, pass);
6173
 
                            switch (size) {
6174
 
                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
6175
 
                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
6176
 
                            default: abort();
6177
 
                            }
6178
 
                            neon_store_reg(rm, pass, tmp2);
6179
 
                            break;
6180
 
                        case NEON_2RM_VRECPE:
6181
 
                            gen_helper_recpe_u32(tmp, tmp, cpu_env);
6182
 
                            break;
6183
 
                        case NEON_2RM_VRSQRTE:
6184
 
                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6185
 
                            break;
6186
 
                        case NEON_2RM_VRECPE_F:
6187
 
                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6188
 
                            break;
6189
 
                        case NEON_2RM_VRSQRTE_F:
6190
 
                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6191
 
                            break;
6192
 
                        case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6193
 
                            gen_vfp_sito(0, 1);
6194
 
                            break;
6195
 
                        case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6196
 
                            gen_vfp_uito(0, 1);
6197
 
                            break;
6198
 
                        case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6199
 
                            gen_vfp_tosiz(0, 1);
6200
 
                            break;
6201
 
                        case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6202
 
                            gen_vfp_touiz(0, 1);
6203
 
                            break;
6204
 
                        default:
6205
 
                            /* Reserved op values were caught by the
6206
 
                             * neon_2rm_sizes[] check earlier.
6207
 
                             */
6208
 
                            abort();
6209
 
                        }
6210
 
                        if (neon_2rm_is_float_op(op)) {
6211
 
                            tcg_gen_st_f32(cpu_F0s, cpu_env,
6212
 
                                           neon_reg_offset(rd, pass));
6213
 
                        } else {
6214
 
                            neon_store_reg(rd, pass, tmp);
6215
 
                        }
6216
 
                    }
6217
 
                    break;
6218
 
                }
6219
 
            } else if ((insn & (1 << 10)) == 0) {
6220
 
                /* VTBL, VTBX.  */
6221
 
                int n = ((insn >> 8) & 3) + 1;
6222
 
                if ((rn + n) > 32) {
6223
 
                    /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6224
 
                     * helper function running off the end of the register file.
6225
 
                     */
6226
 
                    return 1;
6227
 
                }
6228
 
                n <<= 3;
6229
 
                if (insn & (1 << 6)) {
6230
 
                    tmp = neon_load_reg(rd, 0);
6231
 
                } else {
6232
 
                    tmp = tcg_temp_new_i32();
6233
 
                    tcg_gen_movi_i32(tmp, 0);
6234
 
                }
6235
 
                tmp2 = neon_load_reg(rm, 0);
6236
 
                tmp4 = tcg_const_i32(rn);
6237
 
                tmp5 = tcg_const_i32(n);
6238
 
                gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6239
 
                tcg_temp_free_i32(tmp);
6240
 
                if (insn & (1 << 6)) {
6241
 
                    tmp = neon_load_reg(rd, 1);
6242
 
                } else {
6243
 
                    tmp = tcg_temp_new_i32();
6244
 
                    tcg_gen_movi_i32(tmp, 0);
6245
 
                }
6246
 
                tmp3 = neon_load_reg(rm, 1);
6247
 
                gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6248
 
                tcg_temp_free_i32(tmp5);
6249
 
                tcg_temp_free_i32(tmp4);
6250
 
                neon_store_reg(rd, 0, tmp2);
6251
 
                neon_store_reg(rd, 1, tmp3);
6252
 
                tcg_temp_free_i32(tmp);
6253
 
            } else if ((insn & 0x380) == 0) {
6254
 
                /* VDUP */
6255
 
                if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6256
 
                    return 1;
6257
 
                }
6258
 
                if (insn & (1 << 19)) {
6259
 
                    tmp = neon_load_reg(rm, 1);
6260
 
                } else {
6261
 
                    tmp = neon_load_reg(rm, 0);
6262
 
                }
6263
 
                if (insn & (1 << 16)) {
6264
 
                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6265
 
                } else if (insn & (1 << 17)) {
6266
 
                    if ((insn >> 18) & 1)
6267
 
                        gen_neon_dup_high16(tmp);
6268
 
                    else
6269
 
                        gen_neon_dup_low16(tmp);
6270
 
                }
6271
 
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
6272
 
                    tmp2 = tcg_temp_new_i32();
6273
 
                    tcg_gen_mov_i32(tmp2, tmp);
6274
 
                    neon_store_reg(rd, pass, tmp2);
6275
 
                }
6276
 
                tcg_temp_free_i32(tmp);
6277
 
            } else {
6278
 
                return 1;
6279
 
            }
6280
 
        }
6281
 
    }
6282
 
    return 0;
6283
 
}
6284
 
 
6285
 
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6286
 
{
6287
 
    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6288
 
    const ARMCPRegInfo *ri;
6289
 
    ARMCPU *cpu = arm_env_get_cpu(env);
6290
 
 
6291
 
    cpnum = (insn >> 8) & 0xf;
6292
 
    if (arm_feature(env, ARM_FEATURE_XSCALE)
6293
 
            && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6294
 
        return 1;
6295
 
 
6296
 
    /* First check for coprocessor space used for actual instructions */
6297
 
    switch (cpnum) {
6298
 
      case 0:
6299
 
      case 1:
6300
 
        if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6301
 
            return disas_iwmmxt_insn(env, s, insn);
6302
 
        } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6303
 
            return disas_dsp_insn(env, s, insn);
6304
 
        }
6305
 
        return 1;
6306
 
    case 10:
6307
 
    case 11:
6308
 
        return disas_vfp_insn (env, s, insn);
6309
 
    default:
6310
 
        break;
6311
 
    }
6312
 
 
6313
 
    /* Otherwise treat as a generic register access */
6314
 
    is64 = (insn & (1 << 25)) == 0;
6315
 
    if (!is64 && ((insn & (1 << 4)) == 0)) {
6316
 
        /* cdp */
6317
 
        return 1;
6318
 
    }
6319
 
 
6320
 
    crm = insn & 0xf;
6321
 
    if (is64) {
6322
 
        crn = 0;
6323
 
        opc1 = (insn >> 4) & 0xf;
6324
 
        opc2 = 0;
6325
 
        rt2 = (insn >> 16) & 0xf;
6326
 
    } else {
6327
 
        crn = (insn >> 16) & 0xf;
6328
 
        opc1 = (insn >> 21) & 7;
6329
 
        opc2 = (insn >> 5) & 7;
6330
 
        rt2 = 0;
6331
 
    }
6332
 
    isread = (insn >> 20) & 1;
6333
 
    rt = (insn >> 12) & 0xf;
6334
 
 
6335
 
    ri = get_arm_cp_reginfo(cpu,
6336
 
                            ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6337
 
    if (ri) {
6338
 
        /* Check access permissions */
6339
 
        if (!cp_access_ok(env, ri, isread)) {
6340
 
            return 1;
6341
 
        }
6342
 
 
6343
 
        /* Handle special cases first */
6344
 
        switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6345
 
        case ARM_CP_NOP:
6346
 
            return 0;
6347
 
        case ARM_CP_WFI:
6348
 
            if (isread) {
6349
 
                return 1;
6350
 
            }
6351
 
            gen_set_pc_im(s, s->pc);
6352
 
            s->is_jmp = DISAS_WFI;
6353
 
            return 0;
6354
 
        default:
6355
 
            break;
6356
 
        }
6357
 
 
6358
 
        if (use_icount && (ri->type & ARM_CP_IO)) {
6359
 
            gen_io_start();
6360
 
        }
6361
 
 
6362
 
        if (isread) {
6363
 
            /* Read */
6364
 
            if (is64) {
6365
 
                TCGv_i64 tmp64;
6366
 
                TCGv_i32 tmp;
6367
 
                if (ri->type & ARM_CP_CONST) {
6368
 
                    tmp64 = tcg_const_i64(ri->resetvalue);
6369
 
                } else if (ri->readfn) {
6370
 
                    TCGv_ptr tmpptr;
6371
 
                    gen_set_pc_im(s, s->pc);
6372
 
                    tmp64 = tcg_temp_new_i64();
6373
 
                    tmpptr = tcg_const_ptr(ri);
6374
 
                    gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6375
 
                    tcg_temp_free_ptr(tmpptr);
6376
 
                } else {
6377
 
                    tmp64 = tcg_temp_new_i64();
6378
 
                    tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6379
 
                }
6380
 
                tmp = tcg_temp_new_i32();
6381
 
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6382
 
                store_reg(s, rt, tmp);
6383
 
                tcg_gen_shri_i64(tmp64, tmp64, 32);
6384
 
                tmp = tcg_temp_new_i32();
6385
 
                tcg_gen_trunc_i64_i32(tmp, tmp64);
6386
 
                tcg_temp_free_i64(tmp64);
6387
 
                store_reg(s, rt2, tmp);
6388
 
            } else {
6389
 
                TCGv_i32 tmp;
6390
 
                if (ri->type & ARM_CP_CONST) {
6391
 
                    tmp = tcg_const_i32(ri->resetvalue);
6392
 
                } else if (ri->readfn) {
6393
 
                    TCGv_ptr tmpptr;
6394
 
                    gen_set_pc_im(s, s->pc);
6395
 
                    tmp = tcg_temp_new_i32();
6396
 
                    tmpptr = tcg_const_ptr(ri);
6397
 
                    gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6398
 
                    tcg_temp_free_ptr(tmpptr);
6399
 
                } else {
6400
 
                    tmp = load_cpu_offset(ri->fieldoffset);
6401
 
                }
6402
 
                if (rt == 15) {
6403
 
                    /* Destination register of r15 for 32 bit loads sets
6404
 
                     * the condition codes from the high 4 bits of the value
6405
 
                     */
6406
 
                    gen_set_nzcv(tmp);
6407
 
                    tcg_temp_free_i32(tmp);
6408
 
                } else {
6409
 
                    store_reg(s, rt, tmp);
6410
 
                }
6411
 
            }
6412
 
        } else {
6413
 
            /* Write */
6414
 
            if (ri->type & ARM_CP_CONST) {
6415
 
                /* If not forbidden by access permissions, treat as WI */
6416
 
                return 0;
6417
 
            }
6418
 
 
6419
 
            if (is64) {
6420
 
                TCGv_i32 tmplo, tmphi;
6421
 
                TCGv_i64 tmp64 = tcg_temp_new_i64();
6422
 
                tmplo = load_reg(s, rt);
6423
 
                tmphi = load_reg(s, rt2);
6424
 
                tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6425
 
                tcg_temp_free_i32(tmplo);
6426
 
                tcg_temp_free_i32(tmphi);
6427
 
                if (ri->writefn) {
6428
 
                    TCGv_ptr tmpptr = tcg_const_ptr(ri);
6429
 
                    gen_set_pc_im(s, s->pc);
6430
 
                    gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6431
 
                    tcg_temp_free_ptr(tmpptr);
6432
 
                } else {
6433
 
                    tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6434
 
                }
6435
 
                tcg_temp_free_i64(tmp64);
6436
 
            } else {
6437
 
                if (ri->writefn) {
6438
 
                    TCGv_i32 tmp;
6439
 
                    TCGv_ptr tmpptr;
6440
 
                    gen_set_pc_im(s, s->pc);
6441
 
                    tmp = load_reg(s, rt);
6442
 
                    tmpptr = tcg_const_ptr(ri);
6443
 
                    gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6444
 
                    tcg_temp_free_ptr(tmpptr);
6445
 
                    tcg_temp_free_i32(tmp);
6446
 
                } else {
6447
 
                    TCGv_i32 tmp = load_reg(s, rt);
6448
 
                    store_cpu_offset(tmp, ri->fieldoffset);
6449
 
                }
6450
 
            }
6451
 
        }
6452
 
 
6453
 
        if (use_icount && (ri->type & ARM_CP_IO)) {
6454
 
            /* I/O operations must end the TB here (whether read or write) */
6455
 
            gen_io_end();
6456
 
            gen_lookup_tb(s);
6457
 
        } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6458
 
            /* We default to ending the TB on a coprocessor register write,
6459
 
             * but allow this to be suppressed by the register definition
6460
 
             * (usually only necessary to work around guest bugs).
6461
 
             */
6462
 
            gen_lookup_tb(s);
6463
 
        }
6464
 
 
6465
 
        return 0;
6466
 
    }
6467
 
 
6468
 
    return 1;
6469
 
}
6470
 
 
6471
 
 
6472
 
/* Store a 64-bit value to a register pair.  Clobbers val.  */
6473
 
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6474
 
{
6475
 
    TCGv_i32 tmp;
6476
 
    tmp = tcg_temp_new_i32();
6477
 
    tcg_gen_trunc_i64_i32(tmp, val);
6478
 
    store_reg(s, rlow, tmp);
6479
 
    tmp = tcg_temp_new_i32();
6480
 
    tcg_gen_shri_i64(val, val, 32);
6481
 
    tcg_gen_trunc_i64_i32(tmp, val);
6482
 
    store_reg(s, rhigh, tmp);
6483
 
}
6484
 
 
6485
 
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
6486
 
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6487
 
{
6488
 
    TCGv_i64 tmp;
6489
 
    TCGv_i32 tmp2;
6490
 
 
6491
 
    /* Load value and extend to 64 bits.  */
6492
 
    tmp = tcg_temp_new_i64();
6493
 
    tmp2 = load_reg(s, rlow);
6494
 
    tcg_gen_extu_i32_i64(tmp, tmp2);
6495
 
    tcg_temp_free_i32(tmp2);
6496
 
    tcg_gen_add_i64(val, val, tmp);
6497
 
    tcg_temp_free_i64(tmp);
6498
 
}
6499
 
 
6500
 
/* load and add a 64-bit value from a register pair.  */
6501
 
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6502
 
{
6503
 
    TCGv_i64 tmp;
6504
 
    TCGv_i32 tmpl;
6505
 
    TCGv_i32 tmph;
6506
 
 
6507
 
    /* Load 64-bit value rd:rn.  */
6508
 
    tmpl = load_reg(s, rlow);
6509
 
    tmph = load_reg(s, rhigh);
6510
 
    tmp = tcg_temp_new_i64();
6511
 
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6512
 
    tcg_temp_free_i32(tmpl);
6513
 
    tcg_temp_free_i32(tmph);
6514
 
    tcg_gen_add_i64(val, val, tmp);
6515
 
    tcg_temp_free_i64(tmp);
6516
 
}
6517
 
 
6518
 
/* Set N and Z flags from hi|lo.  */
6519
 
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6520
 
{
6521
 
    tcg_gen_mov_i32(cpu_NF, hi);
6522
 
    tcg_gen_or_i32(cpu_ZF, lo, hi);
6523
 
}
6524
 
 
6525
 
/* Load/Store exclusive instructions are implemented by remembering
6526
 
   the value/address loaded, and seeing if these are the same
6527
 
   when the store is performed. This should be sufficient to implement
6528
 
   the architecturally mandated semantics, and avoids having to monitor
6529
 
   regular stores.
6530
 
 
6531
 
   In system emulation mode only one CPU will be running at once, so
6532
 
   this sequence is effectively atomic.  In user emulation mode we
6533
 
   throw an exception and handle the atomic operation elsewhere.  */
6534
 
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6535
 
                               TCGv_i32 addr, int size)
6536
 
{
6537
 
    TCGv_i32 tmp = tcg_temp_new_i32();
6538
 
 
6539
 
    switch (size) {
6540
 
    case 0:
6541
 
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
6542
 
        break;
6543
 
    case 1:
6544
 
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
6545
 
        break;
6546
 
    case 2:
6547
 
    case 3:
6548
 
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
6549
 
        break;
6550
 
    default:
6551
 
        abort();
6552
 
    }
6553
 
    tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6554
 
    store_reg(s, rt, tmp);
6555
 
    if (size == 3) {
6556
 
        TCGv_i32 tmp2 = tcg_temp_new_i32();
6557
 
        tcg_gen_addi_i32(tmp2, addr, 4);
6558
 
        tmp = tcg_temp_new_i32();
6559
 
        gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6560
 
        tcg_temp_free_i32(tmp2);
6561
 
        tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6562
 
        store_reg(s, rt2, tmp);
6563
 
    }
6564
 
    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6565
 
}
6566
 
 
6567
 
static void gen_clrex(DisasContext *s)
6568
 
{
6569
 
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6570
 
}
6571
 
 
6572
 
#ifdef CONFIG_USER_ONLY
6573
 
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6574
 
                                TCGv_i32 addr, int size)
6575
 
{
6576
 
    tcg_gen_mov_i32(cpu_exclusive_test, addr);
6577
 
    tcg_gen_movi_i32(cpu_exclusive_info,
6578
 
                     size | (rd << 4) | (rt << 8) | (rt2 << 12));
6579
 
    gen_exception_insn(s, 4, EXCP_STREX);
6580
 
}
6581
 
#else
6582
 
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6583
 
                                TCGv_i32 addr, int size)
6584
 
{
6585
 
    TCGv_i32 tmp;
6586
 
    int done_label;
6587
 
    int fail_label;
6588
 
 
6589
 
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6590
 
         [addr] = {Rt};
6591
 
         {Rd} = 0;
6592
 
       } else {
6593
 
         {Rd} = 1;
6594
 
       } */
6595
 
    fail_label = gen_new_label();
6596
 
    done_label = gen_new_label();
6597
 
    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6598
 
    tmp = tcg_temp_new_i32();
6599
 
    switch (size) {
6600
 
    case 0:
6601
 
        gen_aa32_ld8u(tmp, addr, IS_USER(s));
6602
 
        break;
6603
 
    case 1:
6604
 
        gen_aa32_ld16u(tmp, addr, IS_USER(s));
6605
 
        break;
6606
 
    case 2:
6607
 
    case 3:
6608
 
        gen_aa32_ld32u(tmp, addr, IS_USER(s));
6609
 
        break;
6610
 
    default:
6611
 
        abort();
6612
 
    }
6613
 
    tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6614
 
    tcg_temp_free_i32(tmp);
6615
 
    if (size == 3) {
6616
 
        TCGv_i32 tmp2 = tcg_temp_new_i32();
6617
 
        tcg_gen_addi_i32(tmp2, addr, 4);
6618
 
        tmp = tcg_temp_new_i32();
6619
 
        gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6620
 
        tcg_temp_free_i32(tmp2);
6621
 
        tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6622
 
        tcg_temp_free_i32(tmp);
6623
 
    }
6624
 
    tmp = load_reg(s, rt);
6625
 
    switch (size) {
6626
 
    case 0:
6627
 
        gen_aa32_st8(tmp, addr, IS_USER(s));
6628
 
        break;
6629
 
    case 1:
6630
 
        gen_aa32_st16(tmp, addr, IS_USER(s));
6631
 
        break;
6632
 
    case 2:
6633
 
    case 3:
6634
 
        gen_aa32_st32(tmp, addr, IS_USER(s));
6635
 
        break;
6636
 
    default:
6637
 
        abort();
6638
 
    }
6639
 
    tcg_temp_free_i32(tmp);
6640
 
    if (size == 3) {
6641
 
        tcg_gen_addi_i32(addr, addr, 4);
6642
 
        tmp = load_reg(s, rt2);
6643
 
        gen_aa32_st32(tmp, addr, IS_USER(s));
6644
 
        tcg_temp_free_i32(tmp);
6645
 
    }
6646
 
    tcg_gen_movi_i32(cpu_R[rd], 0);
6647
 
    tcg_gen_br(done_label);
6648
 
    gen_set_label(fail_label);
6649
 
    tcg_gen_movi_i32(cpu_R[rd], 1);
6650
 
    gen_set_label(done_label);
6651
 
    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6652
 
}
6653
 
#endif
6654
 
 
6655
 
/* gen_srs:
6656
 
 * @env: CPUARMState
6657
 
 * @s: DisasContext
6658
 
 * @mode: mode field from insn (which stack to store to)
6659
 
 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6660
 
 * @writeback: true if writeback bit set
6661
 
 *
6662
 
 * Generate code for the SRS (Store Return State) insn.
6663
 
 */
6664
 
static void gen_srs(DisasContext *s,
6665
 
                    uint32_t mode, uint32_t amode, bool writeback)
6666
 
{
6667
 
    int32_t offset;
6668
 
    TCGv_i32 addr = tcg_temp_new_i32();
6669
 
    TCGv_i32 tmp = tcg_const_i32(mode);
6670
 
    gen_helper_get_r13_banked(addr, cpu_env, tmp);
6671
 
    tcg_temp_free_i32(tmp);
6672
 
    switch (amode) {
6673
 
    case 0: /* DA */
6674
 
        offset = -4;
6675
 
        break;
6676
 
    case 1: /* IA */
6677
 
        offset = 0;
6678
 
        break;
6679
 
    case 2: /* DB */
6680
 
        offset = -8;
6681
 
        break;
6682
 
    case 3: /* IB */
6683
 
        offset = 4;
6684
 
        break;
6685
 
    default:
6686
 
        abort();
6687
 
    }
6688
 
    tcg_gen_addi_i32(addr, addr, offset);
6689
 
    tmp = load_reg(s, 14);
6690
 
    gen_aa32_st32(tmp, addr, 0);
6691
 
    tcg_temp_free_i32(tmp);
6692
 
    tmp = load_cpu_field(spsr);
6693
 
    tcg_gen_addi_i32(addr, addr, 4);
6694
 
    gen_aa32_st32(tmp, addr, 0);
6695
 
    tcg_temp_free_i32(tmp);
6696
 
    if (writeback) {
6697
 
        switch (amode) {
6698
 
        case 0:
6699
 
            offset = -8;
6700
 
            break;
6701
 
        case 1:
6702
 
            offset = 4;
6703
 
            break;
6704
 
        case 2:
6705
 
            offset = -4;
6706
 
            break;
6707
 
        case 3:
6708
 
            offset = 0;
6709
 
            break;
6710
 
        default:
6711
 
            abort();
6712
 
        }
6713
 
        tcg_gen_addi_i32(addr, addr, offset);
6714
 
        tmp = tcg_const_i32(mode);
6715
 
        gen_helper_set_r13_banked(cpu_env, tmp, addr);
6716
 
        tcg_temp_free_i32(tmp);
6717
 
    }
6718
 
    tcg_temp_free_i32(addr);
6719
 
}
6720
 
 
6721
 
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6722
 
{
6723
 
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6724
 
    TCGv_i32 tmp;
6725
 
    TCGv_i32 tmp2;
6726
 
    TCGv_i32 tmp3;
6727
 
    TCGv_i32 addr;
6728
 
    TCGv_i64 tmp64;
6729
 
 
6730
 
    insn = arm_ldl_code(env, s->pc, s->bswap_code);
6731
 
    s->pc += 4;
6732
 
 
6733
 
    /* M variants do not implement ARM mode.  */
6734
 
    if (IS_M(env))
6735
 
        goto illegal_op;
6736
 
    cond = insn >> 28;
6737
 
    if (cond == 0xf){
6738
 
        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6739
 
         * choose to UNDEF. In ARMv5 and above the space is used
6740
 
         * for miscellaneous unconditional instructions.
6741
 
         */
6742
 
        ARCH(5);
6743
 
 
6744
 
        /* Unconditional instructions.  */
6745
 
        if (((insn >> 25) & 7) == 1) {
6746
 
            /* NEON Data processing.  */
6747
 
            if (!arm_feature(env, ARM_FEATURE_NEON))
6748
 
                goto illegal_op;
6749
 
 
6750
 
            if (disas_neon_data_insn(env, s, insn))
6751
 
                goto illegal_op;
6752
 
            return;
6753
 
        }
6754
 
        if ((insn & 0x0f100000) == 0x04000000) {
6755
 
            /* NEON load/store.  */
6756
 
            if (!arm_feature(env, ARM_FEATURE_NEON))
6757
 
                goto illegal_op;
6758
 
 
6759
 
            if (disas_neon_ls_insn(env, s, insn))
6760
 
                goto illegal_op;
6761
 
            return;
6762
 
        }
6763
 
        if (((insn & 0x0f30f000) == 0x0510f000) ||
6764
 
            ((insn & 0x0f30f010) == 0x0710f000)) {
6765
 
            if ((insn & (1 << 22)) == 0) {
6766
 
                /* PLDW; v7MP */
6767
 
                if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6768
 
                    goto illegal_op;
6769
 
                }
6770
 
            }
6771
 
            /* Otherwise PLD; v5TE+ */
6772
 
            ARCH(5TE);
6773
 
            return;
6774
 
        }
6775
 
        if (((insn & 0x0f70f000) == 0x0450f000) ||
6776
 
            ((insn & 0x0f70f010) == 0x0650f000)) {
6777
 
            ARCH(7);
6778
 
            return; /* PLI; V7 */
6779
 
        }
6780
 
        if (((insn & 0x0f700000) == 0x04100000) ||
6781
 
            ((insn & 0x0f700010) == 0x06100000)) {
6782
 
            if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6783
 
                goto illegal_op;
6784
 
            }
6785
 
            return; /* v7MP: Unallocated memory hint: must NOP */
6786
 
        }
6787
 
 
6788
 
        if ((insn & 0x0ffffdff) == 0x01010000) {
6789
 
            ARCH(6);
6790
 
            /* setend */
6791
 
            if (((insn >> 9) & 1) != s->bswap_code) {
6792
 
                /* Dynamic endianness switching not implemented. */
6793
 
                qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
6794
 
                goto illegal_op;
6795
 
            }
6796
 
            return;
6797
 
        } else if ((insn & 0x0fffff00) == 0x057ff000) {
6798
 
            switch ((insn >> 4) & 0xf) {
6799
 
            case 1: /* clrex */
6800
 
                ARCH(6K);
6801
 
                gen_clrex(s);
6802
 
                return;
6803
 
            case 4: /* dsb */
6804
 
            case 5: /* dmb */
6805
 
            case 6: /* isb */
6806
 
                ARCH(7);
6807
 
                /* We don't emulate caches so these are a no-op.  */
6808
 
                return;
6809
 
            default:
6810
 
                goto illegal_op;
6811
 
            }
6812
 
        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6813
 
            /* srs */
6814
 
            if (IS_USER(s)) {
6815
 
                goto illegal_op;
6816
 
            }
6817
 
            ARCH(6);
6818
 
            gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
6819
 
            return;
6820
 
        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6821
 
            /* rfe */
6822
 
            int32_t offset;
6823
 
            if (IS_USER(s))
6824
 
                goto illegal_op;
6825
 
            ARCH(6);
6826
 
            rn = (insn >> 16) & 0xf;
6827
 
            addr = load_reg(s, rn);
6828
 
            i = (insn >> 23) & 3;
6829
 
            switch (i) {
6830
 
            case 0: offset = -4; break; /* DA */
6831
 
            case 1: offset = 0; break; /* IA */
6832
 
            case 2: offset = -8; break; /* DB */
6833
 
            case 3: offset = 4; break; /* IB */
6834
 
            default: abort();
6835
 
            }
6836
 
            if (offset)
6837
 
                tcg_gen_addi_i32(addr, addr, offset);
6838
 
            /* Load PC into tmp and CPSR into tmp2.  */
6839
 
            tmp = tcg_temp_new_i32();
6840
 
            gen_aa32_ld32u(tmp, addr, 0);
6841
 
            tcg_gen_addi_i32(addr, addr, 4);
6842
 
            tmp2 = tcg_temp_new_i32();
6843
 
            gen_aa32_ld32u(tmp2, addr, 0);
6844
 
            if (insn & (1 << 21)) {
6845
 
                /* Base writeback.  */
6846
 
                switch (i) {
6847
 
                case 0: offset = -8; break;
6848
 
                case 1: offset = 4; break;
6849
 
                case 2: offset = -4; break;
6850
 
                case 3: offset = 0; break;
6851
 
                default: abort();
6852
 
                }
6853
 
                if (offset)
6854
 
                    tcg_gen_addi_i32(addr, addr, offset);
6855
 
                store_reg(s, rn, addr);
6856
 
            } else {
6857
 
                tcg_temp_free_i32(addr);
6858
 
            }
6859
 
            gen_rfe(s, tmp, tmp2);
6860
 
            return;
6861
 
        } else if ((insn & 0x0e000000) == 0x0a000000) {
6862
 
            /* branch link and change to thumb (blx <offset>) */
6863
 
            int32_t offset;
6864
 
 
6865
 
            val = (uint32_t)s->pc;
6866
 
            tmp = tcg_temp_new_i32();
6867
 
            tcg_gen_movi_i32(tmp, val);
6868
 
            store_reg(s, 14, tmp);
6869
 
            /* Sign-extend the 24-bit offset */
6870
 
            offset = (((int32_t)insn) << 8) >> 8;
6871
 
            /* offset * 4 + bit24 * 2 + (thumb bit) */
6872
 
            val += (offset << 2) | ((insn >> 23) & 2) | 1;
6873
 
            /* pipeline offset */
6874
 
            val += 4;
6875
 
            /* protected by ARCH(5); above, near the start of uncond block */
6876
 
            gen_bx_im(s, val);
6877
 
            return;
6878
 
        } else if ((insn & 0x0e000f00) == 0x0c000100) {
6879
 
            if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6880
 
                /* iWMMXt register transfer.  */
6881
 
                if (env->cp15.c15_cpar & (1 << 1))
6882
 
                    if (!disas_iwmmxt_insn(env, s, insn))
6883
 
                        return;
6884
 
            }
6885
 
        } else if ((insn & 0x0fe00000) == 0x0c400000) {
6886
 
            /* Coprocessor double register transfer.  */
6887
 
            ARCH(5TE);
6888
 
            /* XXX doesn't belong in the trustzone patch: should just UNDEF? */
6889
 
            cpu_abort(env, "unsupported coprocessor double register transfer\n");
6890
 
        } else if ((insn & 0x0f000010) == 0x0e000010) {
6891
 
            /* Additional coprocessor register transfer.  */
6892
 
            if (!disas_coproc_insn(env, s, insn)) {
6893
 
                return;
6894
 
            }
6895
 
        } else if ((insn & 0x0ff10020) == 0x01000000) {
6896
 
            uint32_t mask;
6897
 
            uint32_t val;
6898
 
            /* cps (privileged) */
6899
 
            if (IS_USER(s))
6900
 
                return;
6901
 
            mask = val = 0;
6902
 
            if (insn & (1 << 19)) {
6903
 
                if (insn & (1 << 8))
6904
 
                    mask |= CPSR_A;
6905
 
                if (insn & (1 << 7))
6906
 
                    mask |= CPSR_I;
6907
 
                if (insn & (1 << 6))
6908
 
                    mask |= CPSR_F;
6909
 
                if (insn & (1 << 18))
6910
 
                    val |= mask;
6911
 
            }
6912
 
            if (insn & (1 << 17)) {
6913
 
                mask |= CPSR_M;
6914
 
                val |= (insn & 0x1f);
6915
 
            }
6916
 
            if (mask) {
6917
 
                gen_set_psr_im(s, mask, 0, val);
6918
 
            }
6919
 
            return;
6920
 
        }
6921
 
        goto illegal_op;
6922
 
    }
6923
 
    if (cond != 0xe) {
6924
 
        /* if not always execute, we generate a conditional jump to
6925
 
           next instruction */
6926
 
        s->condlabel = gen_new_label();
6927
 
        gen_test_cc(cond ^ 1, s->condlabel);
6928
 
        s->condjmp = 1;
6929
 
    }
6930
 
    if ((insn & 0x0f900000) == 0x03000000) {
6931
 
        if ((insn & (1 << 21)) == 0) {
6932
 
            ARCH(6T2);
6933
 
            rd = (insn >> 12) & 0xf;
6934
 
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6935
 
            if ((insn & (1 << 22)) == 0) {
6936
 
                /* MOVW */
6937
 
                tmp = tcg_temp_new_i32();
6938
 
                tcg_gen_movi_i32(tmp, val);
6939
 
            } else {
6940
 
                /* MOVT */
6941
 
                tmp = load_reg(s, rd);
6942
 
                tcg_gen_ext16u_i32(tmp, tmp);
6943
 
                tcg_gen_ori_i32(tmp, tmp, val << 16);
6944
 
            }
6945
 
            store_reg(s, rd, tmp);
6946
 
        } else {
6947
 
            if (((insn >> 12) & 0xf) != 0xf)
6948
 
                goto illegal_op;
6949
 
            if (((insn >> 16) & 0xf) == 0) {
6950
 
                gen_nop_hint(s, insn & 0xff);
6951
 
            } else {
6952
 
                /* CPSR = immediate */
6953
 
                val = insn & 0xff;
6954
 
                shift = ((insn >> 8) & 0xf) * 2;
6955
 
                if (shift)
6956
 
                    val = (val >> shift) | (val << (32 - shift));
6957
 
                i = ((insn & (1 << 22)) != 0);
6958
 
                if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6959
 
                    goto illegal_op;
6960
 
            }
6961
 
        }
6962
 
    } else if ((insn & 0x0f900000) == 0x01000000
6963
 
               && (insn & 0x00000090) != 0x00000090) {
6964
 
        /* miscellaneous instructions */
6965
 
        op1 = (insn >> 21) & 3;
6966
 
        sh = (insn >> 4) & 0xf;
6967
 
        rm = insn & 0xf;
6968
 
        switch (sh) {
6969
 
        case 0x0: /* move program status register */
6970
 
            if (op1 & 1) {
6971
 
                /* PSR = reg */
6972
 
                tmp = load_reg(s, rm);
6973
 
                i = ((op1 & 2) != 0);
6974
 
                if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6975
 
                    goto illegal_op;
6976
 
            } else {
6977
 
                /* reg = PSR */
6978
 
                rd = (insn >> 12) & 0xf;
6979
 
                if (op1 & 2) {
6980
 
                    if (IS_USER(s))
6981
 
                        goto illegal_op;
6982
 
                    tmp = load_cpu_field(spsr);
6983
 
                } else {
6984
 
                    tmp = tcg_temp_new_i32();
6985
 
                    gen_helper_cpsr_read(tmp, cpu_env);
6986
 
                }
6987
 
                store_reg(s, rd, tmp);
6988
 
            }
6989
 
            break;
6990
 
        case 0x1:
6991
 
            if (op1 == 1) {
6992
 
                /* branch/exchange thumb (bx).  */
6993
 
                ARCH(4T);
6994
 
                tmp = load_reg(s, rm);
6995
 
                gen_bx(s, tmp);
6996
 
            } else if (op1 == 3) {
6997
 
                /* clz */
6998
 
                ARCH(5);
6999
 
                rd = (insn >> 12) & 0xf;
7000
 
                tmp = load_reg(s, rm);
7001
 
                gen_helper_clz(tmp, tmp);
7002
 
                store_reg(s, rd, tmp);
7003
 
            } else {
7004
 
                goto illegal_op;
7005
 
            }
7006
 
            break;
7007
 
        case 0x2:
7008
 
            if (op1 == 1) {
7009
 
                ARCH(5J); /* bxj */
7010
 
                /* Trivial implementation equivalent to bx.  */
7011
 
                tmp = load_reg(s, rm);
7012
 
                gen_bx(s, tmp);
7013
 
            } else {
7014
 
                goto illegal_op;
7015
 
            }
7016
 
            break;
7017
 
        case 0x3:
7018
 
            if (op1 != 1)
7019
 
              goto illegal_op;
7020
 
 
7021
 
            ARCH(5);
7022
 
            /* branch link/exchange thumb (blx) */
7023
 
            tmp = load_reg(s, rm);
7024
 
            tmp2 = tcg_temp_new_i32();
7025
 
            tcg_gen_movi_i32(tmp2, s->pc);
7026
 
            store_reg(s, 14, tmp2);
7027
 
            gen_bx(s, tmp);
7028
 
            break;
7029
 
        case 0x5: /* saturating add/subtract */
7030
 
            ARCH(5TE);
7031
 
            rd = (insn >> 12) & 0xf;
7032
 
            rn = (insn >> 16) & 0xf;
7033
 
            tmp = load_reg(s, rm);
7034
 
            tmp2 = load_reg(s, rn);
7035
 
            if (op1 & 2)
7036
 
                gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7037
 
            if (op1 & 1)
7038
 
                gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7039
 
            else
7040
 
                gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7041
 
            tcg_temp_free_i32(tmp2);
7042
 
            store_reg(s, rd, tmp);
7043
 
            break;
7044
 
        case 7:
7045
 
            if (op1 == 1) {
7046
 
                /* bkpt */
7047
 
                ARCH(5);
7048
 
                gen_exception_insn(s, 4, EXCP_BKPT);
7049
 
            } else if (op1 == 3) {
7050
 
                /* smi/smc */
7051
 
                if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
7052
 
                    goto illegal_op;
7053
 
                }
7054
 
                gen_smc(env, s);
7055
 
            } else {
7056
 
                goto illegal_op;
7057
 
            }
7058
 
            break;
7059
 
        case 0x8: /* signed multiply */
7060
 
        case 0xa:
7061
 
        case 0xc:
7062
 
        case 0xe:
7063
 
            ARCH(5TE);
7064
 
            rs = (insn >> 8) & 0xf;
7065
 
            rn = (insn >> 12) & 0xf;
7066
 
            rd = (insn >> 16) & 0xf;
7067
 
            if (op1 == 1) {
7068
 
                /* (32 * 16) >> 16 */
7069
 
                tmp = load_reg(s, rm);
7070
 
                tmp2 = load_reg(s, rs);
7071
 
                if (sh & 4)
7072
 
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
7073
 
                else
7074
 
                    gen_sxth(tmp2);
7075
 
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
7076
 
                tcg_gen_shri_i64(tmp64, tmp64, 16);
7077
 
                tmp = tcg_temp_new_i32();
7078
 
                tcg_gen_trunc_i64_i32(tmp, tmp64);
7079
 
                tcg_temp_free_i64(tmp64);
7080
 
                if ((sh & 2) == 0) {
7081
 
                    tmp2 = load_reg(s, rn);
7082
 
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7083
 
                    tcg_temp_free_i32(tmp2);
7084
 
                }
7085
 
                store_reg(s, rd, tmp);
7086
 
            } else {
7087
 
                /* 16 * 16 */
7088
 
                tmp = load_reg(s, rm);
7089
 
                tmp2 = load_reg(s, rs);
7090
 
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7091
 
                tcg_temp_free_i32(tmp2);
7092
 
                if (op1 == 2) {
7093
 
                    tmp64 = tcg_temp_new_i64();
7094
 
                    tcg_gen_ext_i32_i64(tmp64, tmp);
7095
 
                    tcg_temp_free_i32(tmp);
7096
 
                    gen_addq(s, tmp64, rn, rd);
7097
 
                    gen_storeq_reg(s, rn, rd, tmp64);
7098
 
                    tcg_temp_free_i64(tmp64);
7099
 
                } else {
7100
 
                    if (op1 == 0) {
7101
 
                        tmp2 = load_reg(s, rn);
7102
 
                        gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7103
 
                        tcg_temp_free_i32(tmp2);
7104
 
                    }
7105
 
                    store_reg(s, rd, tmp);
7106
 
                }
7107
 
            }
7108
 
            break;
7109
 
        default:
7110
 
            goto illegal_op;
7111
 
        }
7112
 
    } else if (((insn & 0x0e000000) == 0 &&
7113
 
                (insn & 0x00000090) != 0x90) ||
7114
 
               ((insn & 0x0e000000) == (1 << 25))) {
7115
 
        int set_cc, logic_cc, shiftop;
7116
 
 
7117
 
        op1 = (insn >> 21) & 0xf;
7118
 
        set_cc = (insn >> 20) & 1;
7119
 
        logic_cc = table_logic_cc[op1] & set_cc;
7120
 
 
7121
 
        /* data processing instruction */
7122
 
        if (insn & (1 << 25)) {
7123
 
            /* immediate operand */
7124
 
            val = insn & 0xff;
7125
 
            shift = ((insn >> 8) & 0xf) * 2;
7126
 
            if (shift) {
7127
 
                val = (val >> shift) | (val << (32 - shift));
7128
 
            }
7129
 
            tmp2 = tcg_temp_new_i32();
7130
 
            tcg_gen_movi_i32(tmp2, val);
7131
 
            if (logic_cc && shift) {
7132
 
                gen_set_CF_bit31(tmp2);
7133
 
            }
7134
 
        } else {
7135
 
            /* register */
7136
 
            rm = (insn) & 0xf;
7137
 
            tmp2 = load_reg(s, rm);
7138
 
            shiftop = (insn >> 5) & 3;
7139
 
            if (!(insn & (1 << 4))) {
7140
 
                shift = (insn >> 7) & 0x1f;
7141
 
                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7142
 
            } else {
7143
 
                rs = (insn >> 8) & 0xf;
7144
 
                tmp = load_reg(s, rs);
7145
 
                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7146
 
            }
7147
 
        }
7148
 
        if (op1 != 0x0f && op1 != 0x0d) {
7149
 
            rn = (insn >> 16) & 0xf;
7150
 
            tmp = load_reg(s, rn);
7151
 
        } else {
7152
 
            TCGV_UNUSED_I32(tmp);
7153
 
        }
7154
 
        rd = (insn >> 12) & 0xf;
7155
 
        switch(op1) {
7156
 
        case 0x00:
7157
 
            tcg_gen_and_i32(tmp, tmp, tmp2);
7158
 
            if (logic_cc) {
7159
 
                gen_logic_CC(tmp);
7160
 
            }
7161
 
            store_reg_bx(env, s, rd, tmp);
7162
 
            break;
7163
 
        case 0x01:
7164
 
            tcg_gen_xor_i32(tmp, tmp, tmp2);
7165
 
            if (logic_cc) {
7166
 
                gen_logic_CC(tmp);
7167
 
            }
7168
 
            store_reg_bx(env, s, rd, tmp);
7169
 
            break;
7170
 
        case 0x02:
7171
 
            if (set_cc && rd == 15) {
7172
 
                /* SUBS r15, ... is used for exception return.  */
7173
 
                if (IS_USER(s)) {
7174
 
                    goto illegal_op;
7175
 
                }
7176
 
                gen_sub_CC(tmp, tmp, tmp2);
7177
 
                gen_exception_return(s, tmp);
7178
 
            } else {
7179
 
                if (set_cc) {
7180
 
                    gen_sub_CC(tmp, tmp, tmp2);
7181
 
                } else {
7182
 
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7183
 
                }
7184
 
                store_reg_bx(env, s, rd, tmp);
7185
 
            }
7186
 
            break;
7187
 
        case 0x03:
7188
 
            if (set_cc) {
7189
 
                gen_sub_CC(tmp, tmp2, tmp);
7190
 
            } else {
7191
 
                tcg_gen_sub_i32(tmp, tmp2, tmp);
7192
 
            }
7193
 
            store_reg_bx(env, s, rd, tmp);
7194
 
            break;
7195
 
        case 0x04:
7196
 
            if (set_cc) {
7197
 
                gen_add_CC(tmp, tmp, tmp2);
7198
 
            } else {
7199
 
                tcg_gen_add_i32(tmp, tmp, tmp2);
7200
 
            }
7201
 
            store_reg_bx(env, s, rd, tmp);
7202
 
            break;
7203
 
        case 0x05:
7204
 
            if (set_cc) {
7205
 
                gen_adc_CC(tmp, tmp, tmp2);
7206
 
            } else {
7207
 
                gen_add_carry(tmp, tmp, tmp2);
7208
 
            }
7209
 
            store_reg_bx(env, s, rd, tmp);
7210
 
            break;
7211
 
        case 0x06:
7212
 
            if (set_cc) {
7213
 
                gen_sbc_CC(tmp, tmp, tmp2);
7214
 
            } else {
7215
 
                gen_sub_carry(tmp, tmp, tmp2);
7216
 
            }
7217
 
            store_reg_bx(env, s, rd, tmp);
7218
 
            break;
7219
 
        case 0x07:
7220
 
            if (set_cc) {
7221
 
                gen_sbc_CC(tmp, tmp2, tmp);
7222
 
            } else {
7223
 
                gen_sub_carry(tmp, tmp2, tmp);
7224
 
            }
7225
 
            store_reg_bx(env, s, rd, tmp);
7226
 
            break;
7227
 
        case 0x08:
7228
 
            if (set_cc) {
7229
 
                tcg_gen_and_i32(tmp, tmp, tmp2);
7230
 
                gen_logic_CC(tmp);
7231
 
            }
7232
 
            tcg_temp_free_i32(tmp);
7233
 
            break;
7234
 
        case 0x09:
7235
 
            if (set_cc) {
7236
 
                tcg_gen_xor_i32(tmp, tmp, tmp2);
7237
 
                gen_logic_CC(tmp);
7238
 
            }
7239
 
            tcg_temp_free_i32(tmp);
7240
 
            break;
7241
 
        case 0x0a:
7242
 
            if (set_cc) {
7243
 
                gen_sub_CC(tmp, tmp, tmp2);
7244
 
            }
7245
 
            tcg_temp_free_i32(tmp);
7246
 
            break;
7247
 
        case 0x0b:
7248
 
            if (set_cc) {
7249
 
                gen_add_CC(tmp, tmp, tmp2);
7250
 
            }
7251
 
            tcg_temp_free_i32(tmp);
7252
 
            break;
7253
 
        case 0x0c:
7254
 
            tcg_gen_or_i32(tmp, tmp, tmp2);
7255
 
            if (logic_cc) {
7256
 
                gen_logic_CC(tmp);
7257
 
            }
7258
 
            store_reg_bx(env, s, rd, tmp);
7259
 
            break;
7260
 
        case 0x0d:
7261
 
            if (logic_cc && rd == 15) {
7262
 
                /* MOVS r15, ... is used for exception return.  */
7263
 
                if (IS_USER(s)) {
7264
 
                    goto illegal_op;
7265
 
                }
7266
 
                gen_exception_return(s, tmp2);
7267
 
            } else {
7268
 
                if (logic_cc) {
7269
 
                    gen_logic_CC(tmp2);
7270
 
                }
7271
 
                store_reg_bx(env, s, rd, tmp2);
7272
 
            }
7273
 
            break;
7274
 
        case 0x0e:
7275
 
            tcg_gen_andc_i32(tmp, tmp, tmp2);
7276
 
            if (logic_cc) {
7277
 
                gen_logic_CC(tmp);
7278
 
            }
7279
 
            store_reg_bx(env, s, rd, tmp);
7280
 
            break;
7281
 
        default:
7282
 
        case 0x0f:
7283
 
            tcg_gen_not_i32(tmp2, tmp2);
7284
 
            if (logic_cc) {
7285
 
                gen_logic_CC(tmp2);
7286
 
            }
7287
 
            store_reg_bx(env, s, rd, tmp2);
7288
 
            break;
7289
 
        }
7290
 
        if (op1 != 0x0f && op1 != 0x0d) {
7291
 
            tcg_temp_free_i32(tmp2);
7292
 
        }
7293
 
    } else {
7294
 
        /* other instructions */
7295
 
        op1 = (insn >> 24) & 0xf;
7296
 
        switch(op1) {
7297
 
        case 0x0:
7298
 
        case 0x1:
7299
 
            /* multiplies, extra load/stores */
7300
 
            sh = (insn >> 5) & 3;
7301
 
            if (sh == 0) {
7302
 
                if (op1 == 0x0) {
7303
 
                    rd = (insn >> 16) & 0xf;
7304
 
                    rn = (insn >> 12) & 0xf;
7305
 
                    rs = (insn >> 8) & 0xf;
7306
 
                    rm = (insn) & 0xf;
7307
 
                    op1 = (insn >> 20) & 0xf;
7308
 
                    switch (op1) {
7309
 
                    case 0: case 1: case 2: case 3: case 6:
7310
 
                        /* 32 bit mul */
7311
 
                        tmp = load_reg(s, rs);
7312
 
                        tmp2 = load_reg(s, rm);
7313
 
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
7314
 
                        tcg_temp_free_i32(tmp2);
7315
 
                        if (insn & (1 << 22)) {
7316
 
                            /* Subtract (mls) */
7317
 
                            ARCH(6T2);
7318
 
                            tmp2 = load_reg(s, rn);
7319
 
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
7320
 
                            tcg_temp_free_i32(tmp2);
7321
 
                        } else if (insn & (1 << 21)) {
7322
 
                            /* Add */
7323
 
                            tmp2 = load_reg(s, rn);
7324
 
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7325
 
                            tcg_temp_free_i32(tmp2);
7326
 
                        }
7327
 
                        if (insn & (1 << 20))
7328
 
                            gen_logic_CC(tmp);
7329
 
                        store_reg(s, rd, tmp);
7330
 
                        break;
7331
 
                    case 4:
7332
 
                        /* 64 bit mul double accumulate (UMAAL) */
7333
 
                        ARCH(6);
7334
 
                        tmp = load_reg(s, rs);
7335
 
                        tmp2 = load_reg(s, rm);
7336
 
                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7337
 
                        gen_addq_lo(s, tmp64, rn);
7338
 
                        gen_addq_lo(s, tmp64, rd);
7339
 
                        gen_storeq_reg(s, rn, rd, tmp64);
7340
 
                        tcg_temp_free_i64(tmp64);
7341
 
                        break;
7342
 
                    case 8: case 9: case 10: case 11:
7343
 
                    case 12: case 13: case 14: case 15:
7344
 
                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7345
 
                        tmp = load_reg(s, rs);
7346
 
                        tmp2 = load_reg(s, rm);
7347
 
                        if (insn & (1 << 22)) {
7348
 
                            tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7349
 
                        } else {
7350
 
                            tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7351
 
                        }
7352
 
                        if (insn & (1 << 21)) { /* mult accumulate */
7353
 
                            TCGv_i32 al = load_reg(s, rn);
7354
 
                            TCGv_i32 ah = load_reg(s, rd);
7355
 
                            tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7356
 
                            tcg_temp_free_i32(al);
7357
 
                            tcg_temp_free_i32(ah);
7358
 
                        }
7359
 
                        if (insn & (1 << 20)) {
7360
 
                            gen_logicq_cc(tmp, tmp2);
7361
 
                        }
7362
 
                        store_reg(s, rn, tmp);
7363
 
                        store_reg(s, rd, tmp2);
7364
 
                        break;
7365
 
                    default:
7366
 
                        goto illegal_op;
7367
 
                    }
7368
 
                } else {
7369
 
                    rn = (insn >> 16) & 0xf;
7370
 
                    rd = (insn >> 12) & 0xf;
7371
 
                    if (insn & (1 << 23)) {
7372
 
                        /* load/store exclusive */
7373
 
                        int op2 = (insn >> 8) & 3;
7374
 
                        op1 = (insn >> 21) & 0x3;
7375
 
 
7376
 
                        switch (op2) {
7377
 
                        case 0: /* lda/stl */
7378
 
                            if (op1 == 1) {
7379
 
                                goto illegal_op;
7380
 
                            }
7381
 
                            ARCH(8);
7382
 
                            break;
7383
 
                        case 1: /* reserved */
7384
 
                            goto illegal_op;
7385
 
                        case 2: /* ldaex/stlex */
7386
 
                            ARCH(8);
7387
 
                            break;
7388
 
                        case 3: /* ldrex/strex */
7389
 
                            if (op1) {
7390
 
                                ARCH(6K);
7391
 
                            } else {
7392
 
                                ARCH(6);
7393
 
                            }
7394
 
                            break;
7395
 
                        }
7396
 
 
7397
 
                        addr = tcg_temp_local_new_i32();
7398
 
                        load_reg_var(s, addr, rn);
7399
 
 
7400
 
                        /* Since the emulation does not have barriers,
7401
 
                           the acquire/release semantics need no special
7402
 
                           handling */
7403
 
                        if (op2 == 0) {
7404
 
                            if (insn & (1 << 20)) {
7405
 
                                tmp = tcg_temp_new_i32();
7406
 
                                switch (op1) {
7407
 
                                case 0: /* lda */
7408
 
                                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
7409
 
                                    break;
7410
 
                                case 2: /* ldab */
7411
 
                                    gen_aa32_ld8u(tmp, addr, IS_USER(s));
7412
 
                                    break;
7413
 
                                case 3: /* ldah */
7414
 
                                    gen_aa32_ld16u(tmp, addr, IS_USER(s));
7415
 
                                    break;
7416
 
                                default:
7417
 
                                    abort();
7418
 
                                }
7419
 
                                store_reg(s, rd, tmp);
7420
 
                            } else {
7421
 
                                rm = insn & 0xf;
7422
 
                                tmp = load_reg(s, rm);
7423
 
                                switch (op1) {
7424
 
                                case 0: /* stl */
7425
 
                                    gen_aa32_st32(tmp, addr, IS_USER(s));
7426
 
                                    break;
7427
 
                                case 2: /* stlb */
7428
 
                                    gen_aa32_st8(tmp, addr, IS_USER(s));
7429
 
                                    break;
7430
 
                                case 3: /* stlh */
7431
 
                                    gen_aa32_st16(tmp, addr, IS_USER(s));
7432
 
                                    break;
7433
 
                                default:
7434
 
                                    abort();
7435
 
                                }
7436
 
                                tcg_temp_free_i32(tmp);
7437
 
                            }
7438
 
                        } else if (insn & (1 << 20)) {
7439
 
                            switch (op1) {
7440
 
                            case 0: /* ldrex */
7441
 
                                gen_load_exclusive(s, rd, 15, addr, 2);
7442
 
                                break;
7443
 
                            case 1: /* ldrexd */
7444
 
                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
7445
 
                                break;
7446
 
                            case 2: /* ldrexb */
7447
 
                                gen_load_exclusive(s, rd, 15, addr, 0);
7448
 
                                break;
7449
 
                            case 3: /* ldrexh */
7450
 
                                gen_load_exclusive(s, rd, 15, addr, 1);
7451
 
                                break;
7452
 
                            default:
7453
 
                                abort();
7454
 
                            }
7455
 
                        } else {
7456
 
                            rm = insn & 0xf;
7457
 
                            switch (op1) {
7458
 
                            case 0:  /*  strex */
7459
 
                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
7460
 
                                break;
7461
 
                            case 1: /*  strexd */
7462
 
                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7463
 
                                break;
7464
 
                            case 2: /*  strexb */
7465
 
                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
7466
 
                                break;
7467
 
                            case 3: /* strexh */
7468
 
                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
7469
 
                                break;
7470
 
                            default:
7471
 
                                abort();
7472
 
                            }
7473
 
                        }
7474
 
                        tcg_temp_free_i32(addr);
7475
 
                    } else {
7476
 
                        /* SWP instruction */
7477
 
                        rm = (insn) & 0xf;
7478
 
 
7479
 
                        /* ??? This is not really atomic.  However we know
7480
 
                           we never have multiple CPUs running in parallel,
7481
 
                           so it is good enough.  */
7482
 
                        addr = load_reg(s, rn);
7483
 
                        tmp = load_reg(s, rm);
7484
 
                        tmp2 = tcg_temp_new_i32();
7485
 
                        if (insn & (1 << 22)) {
7486
 
                            gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7487
 
                            gen_aa32_st8(tmp, addr, IS_USER(s));
7488
 
                        } else {
7489
 
                            gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7490
 
                            gen_aa32_st32(tmp, addr, IS_USER(s));
7491
 
                        }
7492
 
                        tcg_temp_free_i32(tmp);
7493
 
                        tcg_temp_free_i32(addr);
7494
 
                        store_reg(s, rd, tmp2);
7495
 
                    }
7496
 
                }
7497
 
            } else {
7498
 
                int address_offset;
7499
 
                int load;
7500
 
                /* Misc load/store */
7501
 
                rn = (insn >> 16) & 0xf;
7502
 
                rd = (insn >> 12) & 0xf;
7503
 
                addr = load_reg(s, rn);
7504
 
                if (insn & (1 << 24))
7505
 
                    gen_add_datah_offset(s, insn, 0, addr);
7506
 
                address_offset = 0;
7507
 
                if (insn & (1 << 20)) {
7508
 
                    /* load */
7509
 
                    tmp = tcg_temp_new_i32();
7510
 
                    switch(sh) {
7511
 
                    case 1:
7512
 
                        gen_aa32_ld16u(tmp, addr, IS_USER(s));
7513
 
                        break;
7514
 
                    case 2:
7515
 
                        gen_aa32_ld8s(tmp, addr, IS_USER(s));
7516
 
                        break;
7517
 
                    default:
7518
 
                    case 3:
7519
 
                        gen_aa32_ld16s(tmp, addr, IS_USER(s));
7520
 
                        break;
7521
 
                    }
7522
 
                    load = 1;
7523
 
                } else if (sh & 2) {
7524
 
                    ARCH(5TE);
7525
 
                    /* doubleword */
7526
 
                    if (sh & 1) {
7527
 
                        /* store */
7528
 
                        tmp = load_reg(s, rd);
7529
 
                        gen_aa32_st32(tmp, addr, IS_USER(s));
7530
 
                        tcg_temp_free_i32(tmp);
7531
 
                        tcg_gen_addi_i32(addr, addr, 4);
7532
 
                        tmp = load_reg(s, rd + 1);
7533
 
                        gen_aa32_st32(tmp, addr, IS_USER(s));
7534
 
                        tcg_temp_free_i32(tmp);
7535
 
                        load = 0;
7536
 
                    } else {
7537
 
                        /* load */
7538
 
                        tmp = tcg_temp_new_i32();
7539
 
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
7540
 
                        store_reg(s, rd, tmp);
7541
 
                        tcg_gen_addi_i32(addr, addr, 4);
7542
 
                        tmp = tcg_temp_new_i32();
7543
 
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
7544
 
                        rd++;
7545
 
                        load = 1;
7546
 
                    }
7547
 
                    address_offset = -4;
7548
 
                } else {
7549
 
                    /* store */
7550
 
                    tmp = load_reg(s, rd);
7551
 
                    gen_aa32_st16(tmp, addr, IS_USER(s));
7552
 
                    tcg_temp_free_i32(tmp);
7553
 
                    load = 0;
7554
 
                }
7555
 
                /* Perform base writeback before the loaded value to
7556
 
                   ensure correct behavior with overlapping index registers.
7557
 
                   ldrd with base writeback is is undefined if the
7558
 
                   destination and index registers overlap.  */
7559
 
                if (!(insn & (1 << 24))) {
7560
 
                    gen_add_datah_offset(s, insn, address_offset, addr);
7561
 
                    store_reg(s, rn, addr);
7562
 
                } else if (insn & (1 << 21)) {
7563
 
                    if (address_offset)
7564
 
                        tcg_gen_addi_i32(addr, addr, address_offset);
7565
 
                    store_reg(s, rn, addr);
7566
 
                } else {
7567
 
                    tcg_temp_free_i32(addr);
7568
 
                }
7569
 
                if (load) {
7570
 
                    /* Complete the load.  */
7571
 
                    store_reg(s, rd, tmp);
7572
 
                }
7573
 
            }
7574
 
            break;
7575
 
        case 0x4:
7576
 
        case 0x5:
7577
 
            goto do_ldst;
7578
 
        case 0x6:
7579
 
        case 0x7:
7580
 
            if (insn & (1 << 4)) {
7581
 
                ARCH(6);
7582
 
                /* Armv6 Media instructions.  */
7583
 
                rm = insn & 0xf;
7584
 
                rn = (insn >> 16) & 0xf;
7585
 
                rd = (insn >> 12) & 0xf;
7586
 
                rs = (insn >> 8) & 0xf;
7587
 
                switch ((insn >> 23) & 3) {
7588
 
                case 0: /* Parallel add/subtract.  */
7589
 
                    op1 = (insn >> 20) & 7;
7590
 
                    tmp = load_reg(s, rn);
7591
 
                    tmp2 = load_reg(s, rm);
7592
 
                    sh = (insn >> 5) & 7;
7593
 
                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7594
 
                        goto illegal_op;
7595
 
                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7596
 
                    tcg_temp_free_i32(tmp2);
7597
 
                    store_reg(s, rd, tmp);
7598
 
                    break;
7599
 
                case 1:
7600
 
                    if ((insn & 0x00700020) == 0) {
7601
 
                        /* Halfword pack.  */
7602
 
                        tmp = load_reg(s, rn);
7603
 
                        tmp2 = load_reg(s, rm);
7604
 
                        shift = (insn >> 7) & 0x1f;
7605
 
                        if (insn & (1 << 6)) {
7606
 
                            /* pkhtb */
7607
 
                            if (shift == 0)
7608
 
                                shift = 31;
7609
 
                            tcg_gen_sari_i32(tmp2, tmp2, shift);
7610
 
                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7611
 
                            tcg_gen_ext16u_i32(tmp2, tmp2);
7612
 
                        } else {
7613
 
                            /* pkhbt */
7614
 
                            if (shift)
7615
 
                                tcg_gen_shli_i32(tmp2, tmp2, shift);
7616
 
                            tcg_gen_ext16u_i32(tmp, tmp);
7617
 
                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7618
 
                        }
7619
 
                        tcg_gen_or_i32(tmp, tmp, tmp2);
7620
 
                        tcg_temp_free_i32(tmp2);
7621
 
                        store_reg(s, rd, tmp);
7622
 
                    } else if ((insn & 0x00200020) == 0x00200000) {
7623
 
                        /* [us]sat */
7624
 
                        tmp = load_reg(s, rm);
7625
 
                        shift = (insn >> 7) & 0x1f;
7626
 
                        if (insn & (1 << 6)) {
7627
 
                            if (shift == 0)
7628
 
                                shift = 31;
7629
 
                            tcg_gen_sari_i32(tmp, tmp, shift);
7630
 
                        } else {
7631
 
                            tcg_gen_shli_i32(tmp, tmp, shift);
7632
 
                        }
7633
 
                        sh = (insn >> 16) & 0x1f;
7634
 
                        tmp2 = tcg_const_i32(sh);
7635
 
                        if (insn & (1 << 22))
7636
 
                          gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7637
 
                        else
7638
 
                          gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7639
 
                        tcg_temp_free_i32(tmp2);
7640
 
                        store_reg(s, rd, tmp);
7641
 
                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
7642
 
                        /* [us]sat16 */
7643
 
                        tmp = load_reg(s, rm);
7644
 
                        sh = (insn >> 16) & 0x1f;
7645
 
                        tmp2 = tcg_const_i32(sh);
7646
 
                        if (insn & (1 << 22))
7647
 
                          gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7648
 
                        else
7649
 
                          gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7650
 
                        tcg_temp_free_i32(tmp2);
7651
 
                        store_reg(s, rd, tmp);
7652
 
                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7653
 
                        /* Select bytes.  */
7654
 
                        tmp = load_reg(s, rn);
7655
 
                        tmp2 = load_reg(s, rm);
7656
 
                        tmp3 = tcg_temp_new_i32();
7657
 
                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7658
 
                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7659
 
                        tcg_temp_free_i32(tmp3);
7660
 
                        tcg_temp_free_i32(tmp2);
7661
 
                        store_reg(s, rd, tmp);
7662
 
                    } else if ((insn & 0x000003e0) == 0x00000060) {
7663
 
                        tmp = load_reg(s, rm);
7664
 
                        shift = (insn >> 10) & 3;
7665
 
                        /* ??? In many cases it's not necessary to do a
7666
 
                           rotate, a shift is sufficient.  */
7667
 
                        if (shift != 0)
7668
 
                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7669
 
                        op1 = (insn >> 20) & 7;
7670
 
                        switch (op1) {
7671
 
                        case 0: gen_sxtb16(tmp);  break;
7672
 
                        case 2: gen_sxtb(tmp);    break;
7673
 
                        case 3: gen_sxth(tmp);    break;
7674
 
                        case 4: gen_uxtb16(tmp);  break;
7675
 
                        case 6: gen_uxtb(tmp);    break;
7676
 
                        case 7: gen_uxth(tmp);    break;
7677
 
                        default: goto illegal_op;
7678
 
                        }
7679
 
                        if (rn != 15) {
7680
 
                            tmp2 = load_reg(s, rn);
7681
 
                            if ((op1 & 3) == 0) {
7682
 
                                gen_add16(tmp, tmp2);
7683
 
                            } else {
7684
 
                                tcg_gen_add_i32(tmp, tmp, tmp2);
7685
 
                                tcg_temp_free_i32(tmp2);
7686
 
                            }
7687
 
                        }
7688
 
                        store_reg(s, rd, tmp);
7689
 
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7690
 
                        /* rev */
7691
 
                        tmp = load_reg(s, rm);
7692
 
                        if (insn & (1 << 22)) {
7693
 
                            if (insn & (1 << 7)) {
7694
 
                                gen_revsh(tmp);
7695
 
                            } else {
7696
 
                                ARCH(6T2);
7697
 
                                gen_helper_rbit(tmp, tmp);
7698
 
                            }
7699
 
                        } else {
7700
 
                            if (insn & (1 << 7))
7701
 
                                gen_rev16(tmp);
7702
 
                            else
7703
 
                                tcg_gen_bswap32_i32(tmp, tmp);
7704
 
                        }
7705
 
                        store_reg(s, rd, tmp);
7706
 
                    } else {
7707
 
                        goto illegal_op;
7708
 
                    }
7709
 
                    break;
7710
 
                case 2: /* Multiplies (Type 3).  */
7711
 
                    switch ((insn >> 20) & 0x7) {
7712
 
                    case 5:
7713
 
                        if (((insn >> 6) ^ (insn >> 7)) & 1) {
7714
 
                            /* op2 not 00x or 11x : UNDEF */
7715
 
                            goto illegal_op;
7716
 
                        }
7717
 
                        /* Signed multiply most significant [accumulate].
7718
 
                           (SMMUL, SMMLA, SMMLS) */
7719
 
                        tmp = load_reg(s, rm);
7720
 
                        tmp2 = load_reg(s, rs);
7721
 
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
7722
 
 
7723
 
                        if (rd != 15) {
7724
 
                            tmp = load_reg(s, rd);
7725
 
                            if (insn & (1 << 6)) {
7726
 
                                tmp64 = gen_subq_msw(tmp64, tmp);
7727
 
                            } else {
7728
 
                                tmp64 = gen_addq_msw(tmp64, tmp);
7729
 
                            }
7730
 
                        }
7731
 
                        if (insn & (1 << 5)) {
7732
 
                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7733
 
                        }
7734
 
                        tcg_gen_shri_i64(tmp64, tmp64, 32);
7735
 
                        tmp = tcg_temp_new_i32();
7736
 
                        tcg_gen_trunc_i64_i32(tmp, tmp64);
7737
 
                        tcg_temp_free_i64(tmp64);
7738
 
                        store_reg(s, rn, tmp);
7739
 
                        break;
7740
 
                    case 0:
7741
 
                    case 4:
7742
 
                        /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7743
 
                        if (insn & (1 << 7)) {
7744
 
                            goto illegal_op;
7745
 
                        }
7746
 
                        tmp = load_reg(s, rm);
7747
 
                        tmp2 = load_reg(s, rs);
7748
 
                        if (insn & (1 << 5))
7749
 
                            gen_swap_half(tmp2);
7750
 
                        gen_smul_dual(tmp, tmp2);
7751
 
                        if (insn & (1 << 6)) {
7752
 
                            /* This subtraction cannot overflow. */
7753
 
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
7754
 
                        } else {
7755
 
                            /* This addition cannot overflow 32 bits;
7756
 
                             * however it may overflow considered as a signed
7757
 
                             * operation, in which case we must set the Q flag.
7758
 
                             */
7759
 
                            gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7760
 
                        }
7761
 
                        tcg_temp_free_i32(tmp2);
7762
 
                        if (insn & (1 << 22)) {
7763
 
                            /* smlald, smlsld */
7764
 
                            tmp64 = tcg_temp_new_i64();
7765
 
                            tcg_gen_ext_i32_i64(tmp64, tmp);
7766
 
                            tcg_temp_free_i32(tmp);
7767
 
                            gen_addq(s, tmp64, rd, rn);
7768
 
                            gen_storeq_reg(s, rd, rn, tmp64);
7769
 
                            tcg_temp_free_i64(tmp64);
7770
 
                        } else {
7771
 
                            /* smuad, smusd, smlad, smlsd */
7772
 
                            if (rd != 15)
7773
 
                              {
7774
 
                                tmp2 = load_reg(s, rd);
7775
 
                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7776
 
                                tcg_temp_free_i32(tmp2);
7777
 
                              }
7778
 
                            store_reg(s, rn, tmp);
7779
 
                        }
7780
 
                        break;
7781
 
                    case 1:
7782
 
                    case 3:
7783
 
                        /* SDIV, UDIV */
7784
 
                        if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7785
 
                            goto illegal_op;
7786
 
                        }
7787
 
                        if (((insn >> 5) & 7) || (rd != 15)) {
7788
 
                            goto illegal_op;
7789
 
                        }
7790
 
                        tmp = load_reg(s, rm);
7791
 
                        tmp2 = load_reg(s, rs);
7792
 
                        if (insn & (1 << 21)) {
7793
 
                            gen_helper_udiv(tmp, tmp, tmp2);
7794
 
                        } else {
7795
 
                            gen_helper_sdiv(tmp, tmp, tmp2);
7796
 
                        }
7797
 
                        tcg_temp_free_i32(tmp2);
7798
 
                        store_reg(s, rn, tmp);
7799
 
                        break;
7800
 
                    default:
7801
 
                        goto illegal_op;
7802
 
                    }
7803
 
                    break;
7804
 
                case 3:
7805
 
                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7806
 
                    switch (op1) {
7807
 
                    case 0: /* Unsigned sum of absolute differences.  */
7808
 
                        ARCH(6);
7809
 
                        tmp = load_reg(s, rm);
7810
 
                        tmp2 = load_reg(s, rs);
7811
 
                        gen_helper_usad8(tmp, tmp, tmp2);
7812
 
                        tcg_temp_free_i32(tmp2);
7813
 
                        if (rd != 15) {
7814
 
                            tmp2 = load_reg(s, rd);
7815
 
                            tcg_gen_add_i32(tmp, tmp, tmp2);
7816
 
                            tcg_temp_free_i32(tmp2);
7817
 
                        }
7818
 
                        store_reg(s, rn, tmp);
7819
 
                        break;
7820
 
                    case 0x20: case 0x24: case 0x28: case 0x2c:
7821
 
                        /* Bitfield insert/clear.  */
7822
 
                        ARCH(6T2);
7823
 
                        shift = (insn >> 7) & 0x1f;
7824
 
                        i = (insn >> 16) & 0x1f;
7825
 
                        i = i + 1 - shift;
7826
 
                        if (rm == 15) {
7827
 
                            tmp = tcg_temp_new_i32();
7828
 
                            tcg_gen_movi_i32(tmp, 0);
7829
 
                        } else {
7830
 
                            tmp = load_reg(s, rm);
7831
 
                        }
7832
 
                        if (i != 32) {
7833
 
                            tmp2 = load_reg(s, rd);
7834
 
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
7835
 
                            tcg_temp_free_i32(tmp2);
7836
 
                        }
7837
 
                        store_reg(s, rd, tmp);
7838
 
                        break;
7839
 
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7840
 
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7841
 
                        ARCH(6T2);
7842
 
                        tmp = load_reg(s, rm);
7843
 
                        shift = (insn >> 7) & 0x1f;
7844
 
                        i = ((insn >> 16) & 0x1f) + 1;
7845
 
                        if (shift + i > 32)
7846
 
                            goto illegal_op;
7847
 
                        if (i < 32) {
7848
 
                            if (op1 & 0x20) {
7849
 
                                gen_ubfx(tmp, shift, (1u << i) - 1);
7850
 
                            } else {
7851
 
                                gen_sbfx(tmp, shift, i);
7852
 
                            }
7853
 
                        }
7854
 
                        store_reg(s, rd, tmp);
7855
 
                        break;
7856
 
                    default:
7857
 
                        goto illegal_op;
7858
 
                    }
7859
 
                    break;
7860
 
                }
7861
 
                break;
7862
 
            }
7863
 
        do_ldst:
7864
 
            /* Check for undefined extension instructions
7865
 
             * per the ARM Bible IE:
7866
 
             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
7867
 
             */
7868
 
            sh = (0xf << 20) | (0xf << 4);
7869
 
            if (op1 == 0x7 && ((insn & sh) == sh))
7870
 
            {
7871
 
                goto illegal_op;
7872
 
            }
7873
 
            /* load/store byte/word */
7874
 
            rn = (insn >> 16) & 0xf;
7875
 
            rd = (insn >> 12) & 0xf;
7876
 
            tmp2 = load_reg(s, rn);
7877
 
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7878
 
            if (insn & (1 << 24))
7879
 
                gen_add_data_offset(s, insn, tmp2);
7880
 
            if (insn & (1 << 20)) {
7881
 
                /* load */
7882
 
                tmp = tcg_temp_new_i32();
7883
 
                if (insn & (1 << 22)) {
7884
 
                    gen_aa32_ld8u(tmp, tmp2, i);
7885
 
                } else {
7886
 
                    gen_aa32_ld32u(tmp, tmp2, i);
7887
 
                }
7888
 
            } else {
7889
 
                /* store */
7890
 
                tmp = load_reg(s, rd);
7891
 
                if (insn & (1 << 22)) {
7892
 
                    gen_aa32_st8(tmp, tmp2, i);
7893
 
                } else {
7894
 
                    gen_aa32_st32(tmp, tmp2, i);
7895
 
                }
7896
 
                tcg_temp_free_i32(tmp);
7897
 
            }
7898
 
            if (!(insn & (1 << 24))) {
7899
 
                gen_add_data_offset(s, insn, tmp2);
7900
 
                store_reg(s, rn, tmp2);
7901
 
            } else if (insn & (1 << 21)) {
7902
 
                store_reg(s, rn, tmp2);
7903
 
            } else {
7904
 
                tcg_temp_free_i32(tmp2);
7905
 
            }
7906
 
            if (insn & (1 << 20)) {
7907
 
                /* Complete the load.  */
7908
 
                store_reg_from_load(env, s, rd, tmp);
7909
 
            }
7910
 
            break;
7911
 
        case 0x08:
7912
 
        case 0x09:
7913
 
            {
7914
 
                int j, n, user, loaded_base;
7915
 
                TCGv_i32 loaded_var;
7916
 
                /* load/store multiple words */
7917
 
                /* XXX: store correct base if write back */
7918
 
                user = 0;
7919
 
                if (insn & (1 << 22)) {
7920
 
                    if (IS_USER(s))
7921
 
                        goto illegal_op; /* only usable in supervisor mode */
7922
 
 
7923
 
                    if ((insn & (1 << 15)) == 0)
7924
 
                        user = 1;
7925
 
                }
7926
 
                rn = (insn >> 16) & 0xf;
7927
 
                addr = load_reg(s, rn);
7928
 
 
7929
 
                /* compute total size */
7930
 
                loaded_base = 0;
7931
 
                TCGV_UNUSED_I32(loaded_var);
7932
 
                n = 0;
7933
 
                for(i=0;i<16;i++) {
7934
 
                    if (insn & (1 << i))
7935
 
                        n++;
7936
 
                }
7937
 
                /* XXX: test invalid n == 0 case ? */
7938
 
                if (insn & (1 << 23)) {
7939
 
                    if (insn & (1 << 24)) {
7940
 
                        /* pre increment */
7941
 
                        tcg_gen_addi_i32(addr, addr, 4);
7942
 
                    } else {
7943
 
                        /* post increment */
7944
 
                    }
7945
 
                } else {
7946
 
                    if (insn & (1 << 24)) {
7947
 
                        /* pre decrement */
7948
 
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
7949
 
                    } else {
7950
 
                        /* post decrement */
7951
 
                        if (n != 1)
7952
 
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7953
 
                    }
7954
 
                }
7955
 
                j = 0;
7956
 
                for(i=0;i<16;i++) {
7957
 
                    if (insn & (1 << i)) {
7958
 
                        if (insn & (1 << 20)) {
7959
 
                            /* load */
7960
 
                            tmp = tcg_temp_new_i32();
7961
 
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
7962
 
                            if (user) {
7963
 
                                tmp2 = tcg_const_i32(i);
7964
 
                                gen_helper_set_user_reg(cpu_env, tmp2, tmp);
7965
 
                                tcg_temp_free_i32(tmp2);
7966
 
                                tcg_temp_free_i32(tmp);
7967
 
                            } else if (i == rn) {
7968
 
                                loaded_var = tmp;
7969
 
                                loaded_base = 1;
7970
 
                            } else {
7971
 
                                store_reg_from_load(env, s, i, tmp);
7972
 
                            }
7973
 
                        } else {
7974
 
                            /* store */
7975
 
                            if (i == 15) {
7976
 
                                /* special case: r15 = PC + 8 */
7977
 
                                val = (long)s->pc + 4;
7978
 
                                tmp = tcg_temp_new_i32();
7979
 
                                tcg_gen_movi_i32(tmp, val);
7980
 
                            } else if (user) {
7981
 
                                tmp = tcg_temp_new_i32();
7982
 
                                tmp2 = tcg_const_i32(i);
7983
 
                                gen_helper_get_user_reg(tmp, cpu_env, tmp2);
7984
 
                                tcg_temp_free_i32(tmp2);
7985
 
                            } else {
7986
 
                                tmp = load_reg(s, i);
7987
 
                            }
7988
 
                            gen_aa32_st32(tmp, addr, IS_USER(s));
7989
 
                            tcg_temp_free_i32(tmp);
7990
 
                        }
7991
 
                        j++;
7992
 
                        /* no need to add after the last transfer */
7993
 
                        if (j != n)
7994
 
                            tcg_gen_addi_i32(addr, addr, 4);
7995
 
                    }
7996
 
                }
7997
 
                if (insn & (1 << 21)) {
7998
 
                    /* write back */
7999
 
                    if (insn & (1 << 23)) {
8000
 
                        if (insn & (1 << 24)) {
8001
 
                            /* pre increment */
8002
 
                        } else {
8003
 
                            /* post increment */
8004
 
                            tcg_gen_addi_i32(addr, addr, 4);
8005
 
                        }
8006
 
                    } else {
8007
 
                        if (insn & (1 << 24)) {
8008
 
                            /* pre decrement */
8009
 
                            if (n != 1)
8010
 
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8011
 
                        } else {
8012
 
                            /* post decrement */
8013
 
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
8014
 
                        }
8015
 
                    }
8016
 
                    store_reg(s, rn, addr);
8017
 
                } else {
8018
 
                    tcg_temp_free_i32(addr);
8019
 
                }
8020
 
                if (loaded_base) {
8021
 
                    store_reg(s, rn, loaded_var);
8022
 
                }
8023
 
                if ((insn & (1 << 22)) && !user) {
8024
 
                    /* Restore CPSR from SPSR.  */
8025
 
                    tmp = load_cpu_field(spsr);
8026
 
                    gen_set_cpsr(tmp, 0xffffffff);
8027
 
                    tcg_temp_free_i32(tmp);
8028
 
                    s->is_jmp = DISAS_UPDATE;
8029
 
                }
8030
 
            }
8031
 
            break;
8032
 
        case 0xa:
8033
 
        case 0xb:
8034
 
            {
8035
 
                int32_t offset;
8036
 
 
8037
 
                /* branch (and link) */
8038
 
                val = (int32_t)s->pc;
8039
 
                if (insn & (1 << 24)) {
8040
 
                    tmp = tcg_temp_new_i32();
8041
 
                    tcg_gen_movi_i32(tmp, val);
8042
 
                    store_reg(s, 14, tmp);
8043
 
                }
8044
 
                offset = sextract32(insn << 2, 0, 26);
8045
 
                val += offset + 4;
8046
 
                gen_jmp(s, val);
8047
 
            }
8048
 
            break;
8049
 
        case 0xc:
8050
 
        case 0xd:
8051
 
        case 0xe:
8052
 
            /* Coprocessor.  */
8053
 
            if (disas_coproc_insn(env, s, insn))
8054
 
                goto illegal_op;
8055
 
            break;
8056
 
        case 0xf:
8057
 
            /* swi */
8058
 
            gen_set_pc_im(s, s->pc);
8059
 
            s->is_jmp = DISAS_SWI;
8060
 
            break;
8061
 
        default:
8062
 
        illegal_op:
8063
 
            gen_exception_insn(s, 4, EXCP_UDEF);
8064
 
            break;
8065
 
        }
8066
 
    }
8067
 
}
8068
 
 
8069
 
/* Return true if this is a Thumb-2 logical op.  */
8070
 
static int
8071
 
thumb2_logic_op(int op)
8072
 
{
8073
 
    return (op < 8);
8074
 
}
8075
 
 
8076
 
/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
8077
 
   then set condition code flags based on the result of the operation.
8078
 
   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8079
 
   to the high bit of T1.
8080
 
   Returns zero if the opcode is valid.  */
8081
 
 
8082
 
static int
8083
 
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8084
 
                   TCGv_i32 t0, TCGv_i32 t1)
8085
 
{
8086
 
    int logic_cc;
8087
 
 
8088
 
    logic_cc = 0;
8089
 
    switch (op) {
8090
 
    case 0: /* and */
8091
 
        tcg_gen_and_i32(t0, t0, t1);
8092
 
        logic_cc = conds;
8093
 
        break;
8094
 
    case 1: /* bic */
8095
 
        tcg_gen_andc_i32(t0, t0, t1);
8096
 
        logic_cc = conds;
8097
 
        break;
8098
 
    case 2: /* orr */
8099
 
        tcg_gen_or_i32(t0, t0, t1);
8100
 
        logic_cc = conds;
8101
 
        break;
8102
 
    case 3: /* orn */
8103
 
        tcg_gen_orc_i32(t0, t0, t1);
8104
 
        logic_cc = conds;
8105
 
        break;
8106
 
    case 4: /* eor */
8107
 
        tcg_gen_xor_i32(t0, t0, t1);
8108
 
        logic_cc = conds;
8109
 
        break;
8110
 
    case 8: /* add */
8111
 
        if (conds)
8112
 
            gen_add_CC(t0, t0, t1);
8113
 
        else
8114
 
            tcg_gen_add_i32(t0, t0, t1);
8115
 
        break;
8116
 
    case 10: /* adc */
8117
 
        if (conds)
8118
 
            gen_adc_CC(t0, t0, t1);
8119
 
        else
8120
 
            gen_adc(t0, t1);
8121
 
        break;
8122
 
    case 11: /* sbc */
8123
 
        if (conds) {
8124
 
            gen_sbc_CC(t0, t0, t1);
8125
 
        } else {
8126
 
            gen_sub_carry(t0, t0, t1);
8127
 
        }
8128
 
        break;
8129
 
    case 13: /* sub */
8130
 
        if (conds)
8131
 
            gen_sub_CC(t0, t0, t1);
8132
 
        else
8133
 
            tcg_gen_sub_i32(t0, t0, t1);
8134
 
        break;
8135
 
    case 14: /* rsb */
8136
 
        if (conds)
8137
 
            gen_sub_CC(t0, t1, t0);
8138
 
        else
8139
 
            tcg_gen_sub_i32(t0, t1, t0);
8140
 
        break;
8141
 
    default: /* 5, 6, 7, 9, 12, 15. */
8142
 
        return 1;
8143
 
    }
8144
 
    if (logic_cc) {
8145
 
        gen_logic_CC(t0);
8146
 
        if (shifter_out)
8147
 
            gen_set_CF_bit31(t1);
8148
 
    }
8149
 
    return 0;
8150
 
}
8151
 
 
8152
 
/* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
8153
 
   is not legal.  */
8154
 
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8155
 
{
8156
 
    uint32_t insn, imm, shift, offset;
8157
 
    uint32_t rd, rn, rm, rs;
8158
 
    TCGv_i32 tmp;
8159
 
    TCGv_i32 tmp2;
8160
 
    TCGv_i32 tmp3;
8161
 
    TCGv_i32 addr;
8162
 
    TCGv_i64 tmp64;
8163
 
    int op;
8164
 
    int shiftop;
8165
 
    int conds;
8166
 
    int logic_cc;
8167
 
 
8168
 
    if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8169
 
          || arm_feature (env, ARM_FEATURE_M))) {
8170
 
        /* Thumb-1 cores may need to treat bl and blx as a pair of
8171
 
           16-bit instructions to get correct prefetch abort behavior.  */
8172
 
        insn = insn_hw1;
8173
 
        if ((insn & (1 << 12)) == 0) {
8174
 
            ARCH(5);
8175
 
            /* Second half of blx.  */
8176
 
            offset = ((insn & 0x7ff) << 1);
8177
 
            tmp = load_reg(s, 14);
8178
 
            tcg_gen_addi_i32(tmp, tmp, offset);
8179
 
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8180
 
 
8181
 
            tmp2 = tcg_temp_new_i32();
8182
 
            tcg_gen_movi_i32(tmp2, s->pc | 1);
8183
 
            store_reg(s, 14, tmp2);
8184
 
            gen_bx(s, tmp);
8185
 
            return 0;
8186
 
        }
8187
 
        if (insn & (1 << 11)) {
8188
 
            /* Second half of bl.  */
8189
 
            offset = ((insn & 0x7ff) << 1) | 1;
8190
 
            tmp = load_reg(s, 14);
8191
 
            tcg_gen_addi_i32(tmp, tmp, offset);
8192
 
 
8193
 
            tmp2 = tcg_temp_new_i32();
8194
 
            tcg_gen_movi_i32(tmp2, s->pc | 1);
8195
 
            store_reg(s, 14, tmp2);
8196
 
            gen_bx(s, tmp);
8197
 
            return 0;
8198
 
        }
8199
 
        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8200
 
            /* Instruction spans a page boundary.  Implement it as two
8201
 
               16-bit instructions in case the second half causes an
8202
 
               prefetch abort.  */
8203
 
            offset = ((int32_t)insn << 21) >> 9;
8204
 
            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8205
 
            return 0;
8206
 
        }
8207
 
        /* Fall through to 32-bit decode.  */
8208
 
    }
8209
 
 
8210
 
    insn = arm_lduw_code(env, s->pc, s->bswap_code);
8211
 
    s->pc += 2;
8212
 
    insn |= (uint32_t)insn_hw1 << 16;
8213
 
 
8214
 
    if ((insn & 0xf800e800) != 0xf000e800) {
8215
 
        ARCH(6T2);
8216
 
    }
8217
 
 
8218
 
    rn = (insn >> 16) & 0xf;
8219
 
    rs = (insn >> 12) & 0xf;
8220
 
    rd = (insn >> 8) & 0xf;
8221
 
    rm = insn & 0xf;
8222
 
    switch ((insn >> 25) & 0xf) {
8223
 
    case 0: case 1: case 2: case 3:
8224
 
        /* 16-bit instructions.  Should never happen.  */
8225
 
        abort();
8226
 
    case 4:
8227
 
        if (insn & (1 << 22)) {
8228
 
            /* Other load/store, table branch.  */
8229
 
            if (insn & 0x01200000) {
8230
 
                /* Load/store doubleword.  */
8231
 
                if (rn == 15) {
8232
 
                    addr = tcg_temp_new_i32();
8233
 
                    tcg_gen_movi_i32(addr, s->pc & ~3);
8234
 
                } else {
8235
 
                    addr = load_reg(s, rn);
8236
 
                }
8237
 
                offset = (insn & 0xff) * 4;
8238
 
                if ((insn & (1 << 23)) == 0)
8239
 
                    offset = -offset;
8240
 
                if (insn & (1 << 24)) {
8241
 
                    tcg_gen_addi_i32(addr, addr, offset);
8242
 
                    offset = 0;
8243
 
                }
8244
 
                if (insn & (1 << 20)) {
8245
 
                    /* ldrd */
8246
 
                    tmp = tcg_temp_new_i32();
8247
 
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
8248
 
                    store_reg(s, rs, tmp);
8249
 
                    tcg_gen_addi_i32(addr, addr, 4);
8250
 
                    tmp = tcg_temp_new_i32();
8251
 
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
8252
 
                    store_reg(s, rd, tmp);
8253
 
                } else {
8254
 
                    /* strd */
8255
 
                    tmp = load_reg(s, rs);
8256
 
                    gen_aa32_st32(tmp, addr, IS_USER(s));
8257
 
                    tcg_temp_free_i32(tmp);
8258
 
                    tcg_gen_addi_i32(addr, addr, 4);
8259
 
                    tmp = load_reg(s, rd);
8260
 
                    gen_aa32_st32(tmp, addr, IS_USER(s));
8261
 
                    tcg_temp_free_i32(tmp);
8262
 
                }
8263
 
                if (insn & (1 << 21)) {
8264
 
                    /* Base writeback.  */
8265
 
                    if (rn == 15)
8266
 
                        goto illegal_op;
8267
 
                    tcg_gen_addi_i32(addr, addr, offset - 4);
8268
 
                    store_reg(s, rn, addr);
8269
 
                } else {
8270
 
                    tcg_temp_free_i32(addr);
8271
 
                }
8272
 
            } else if ((insn & (1 << 23)) == 0) {
8273
 
                /* Load/store exclusive word.  */
8274
 
                addr = tcg_temp_local_new_i32();
8275
 
                load_reg_var(s, addr, rn);
8276
 
                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8277
 
                if (insn & (1 << 20)) {
8278
 
                    gen_load_exclusive(s, rs, 15, addr, 2);
8279
 
                } else {
8280
 
                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
8281
 
                }
8282
 
                tcg_temp_free_i32(addr);
8283
 
            } else if ((insn & (7 << 5)) == 0) {
8284
 
                /* Table Branch.  */
8285
 
                if (rn == 15) {
8286
 
                    addr = tcg_temp_new_i32();
8287
 
                    tcg_gen_movi_i32(addr, s->pc);
8288
 
                } else {
8289
 
                    addr = load_reg(s, rn);
8290
 
                }
8291
 
                tmp = load_reg(s, rm);
8292
 
                tcg_gen_add_i32(addr, addr, tmp);
8293
 
                if (insn & (1 << 4)) {
8294
 
                    /* tbh */
8295
 
                    tcg_gen_add_i32(addr, addr, tmp);
8296
 
                    tcg_temp_free_i32(tmp);
8297
 
                    tmp = tcg_temp_new_i32();
8298
 
                    gen_aa32_ld16u(tmp, addr, IS_USER(s));
8299
 
                } else { /* tbb */
8300
 
                    tcg_temp_free_i32(tmp);
8301
 
                    tmp = tcg_temp_new_i32();
8302
 
                    gen_aa32_ld8u(tmp, addr, IS_USER(s));
8303
 
                }
8304
 
                tcg_temp_free_i32(addr);
8305
 
                tcg_gen_shli_i32(tmp, tmp, 1);
8306
 
                tcg_gen_addi_i32(tmp, tmp, s->pc);
8307
 
                store_reg(s, 15, tmp);
8308
 
            } else {
8309
 
                int op2 = (insn >> 6) & 0x3;
8310
 
                op = (insn >> 4) & 0x3;
8311
 
                switch (op2) {
8312
 
                case 0:
8313
 
                    goto illegal_op;
8314
 
                case 1:
8315
 
                    /* Load/store exclusive byte/halfword/doubleword */
8316
 
                    if (op == 2) {
8317
 
                        goto illegal_op;
8318
 
                    }
8319
 
                    ARCH(7);
8320
 
                    break;
8321
 
                case 2:
8322
 
                    /* Load-acquire/store-release */
8323
 
                    if (op == 3) {
8324
 
                        goto illegal_op;
8325
 
                    }
8326
 
                    /* Fall through */
8327
 
                case 3:
8328
 
                    /* Load-acquire/store-release exclusive */
8329
 
                    ARCH(8);
8330
 
                    break;
8331
 
                }
8332
 
                addr = tcg_temp_local_new_i32();
8333
 
                load_reg_var(s, addr, rn);
8334
 
                if (!(op2 & 1)) {
8335
 
                    if (insn & (1 << 20)) {
8336
 
                        tmp = tcg_temp_new_i32();
8337
 
                        switch (op) {
8338
 
                        case 0: /* ldab */
8339
 
                            gen_aa32_ld8u(tmp, addr, IS_USER(s));
8340
 
                            break;
8341
 
                        case 1: /* ldah */
8342
 
                            gen_aa32_ld16u(tmp, addr, IS_USER(s));
8343
 
                            break;
8344
 
                        case 2: /* lda */
8345
 
                            gen_aa32_ld32u(tmp, addr, IS_USER(s));
8346
 
                            break;
8347
 
                        default:
8348
 
                            abort();
8349
 
                        }
8350
 
                        store_reg(s, rs, tmp);
8351
 
                    } else {
8352
 
                        tmp = load_reg(s, rs);
8353
 
                        switch (op) {
8354
 
                        case 0: /* stlb */
8355
 
                            gen_aa32_st8(tmp, addr, IS_USER(s));
8356
 
                            break;
8357
 
                        case 1: /* stlh */
8358
 
                            gen_aa32_st16(tmp, addr, IS_USER(s));
8359
 
                            break;
8360
 
                        case 2: /* stl */
8361
 
                            gen_aa32_st32(tmp, addr, IS_USER(s));
8362
 
                            break;
8363
 
                        default:
8364
 
                            abort();
8365
 
                        }
8366
 
                        tcg_temp_free_i32(tmp);
8367
 
                    }
8368
 
                } else if (insn & (1 << 20)) {
8369
 
                    gen_load_exclusive(s, rs, rd, addr, op);
8370
 
                } else {
8371
 
                    gen_store_exclusive(s, rm, rs, rd, addr, op);
8372
 
                }
8373
 
                tcg_temp_free_i32(addr);
8374
 
            }
8375
 
        } else {
8376
 
            /* Load/store multiple, RFE, SRS.  */
8377
 
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8378
 
                /* RFE, SRS: not available in user mode or on M profile */
8379
 
                if (IS_USER(s) || IS_M(env)) {
8380
 
                    goto illegal_op;
8381
 
                }
8382
 
                if (insn & (1 << 20)) {
8383
 
                    /* rfe */
8384
 
                    addr = load_reg(s, rn);
8385
 
                    if ((insn & (1 << 24)) == 0)
8386
 
                        tcg_gen_addi_i32(addr, addr, -8);
8387
 
                    /* Load PC into tmp and CPSR into tmp2.  */
8388
 
                    tmp = tcg_temp_new_i32();
8389
 
                    gen_aa32_ld32u(tmp, addr, 0);
8390
 
                    tcg_gen_addi_i32(addr, addr, 4);
8391
 
                    tmp2 = tcg_temp_new_i32();
8392
 
                    gen_aa32_ld32u(tmp2, addr, 0);
8393
 
                    if (insn & (1 << 21)) {
8394
 
                        /* Base writeback.  */
8395
 
                        if (insn & (1 << 24)) {
8396
 
                            tcg_gen_addi_i32(addr, addr, 4);
8397
 
                        } else {
8398
 
                            tcg_gen_addi_i32(addr, addr, -4);
8399
 
                        }
8400
 
                        store_reg(s, rn, addr);
8401
 
                    } else {
8402
 
                        tcg_temp_free_i32(addr);
8403
 
                    }
8404
 
                    gen_rfe(s, tmp, tmp2);
8405
 
                } else {
8406
 
                    /* srs */
8407
 
                    gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8408
 
                            insn & (1 << 21));
8409
 
                }
8410
 
            } else {
8411
 
                int i, loaded_base = 0;
8412
 
                TCGv_i32 loaded_var;
8413
 
                /* Load/store multiple.  */
8414
 
                addr = load_reg(s, rn);
8415
 
                offset = 0;
8416
 
                for (i = 0; i < 16; i++) {
8417
 
                    if (insn & (1 << i))
8418
 
                        offset += 4;
8419
 
                }
8420
 
                if (insn & (1 << 24)) {
8421
 
                    tcg_gen_addi_i32(addr, addr, -offset);
8422
 
                }
8423
 
 
8424
 
                TCGV_UNUSED_I32(loaded_var);
8425
 
                for (i = 0; i < 16; i++) {
8426
 
                    if ((insn & (1 << i)) == 0)
8427
 
                        continue;
8428
 
                    if (insn & (1 << 20)) {
8429
 
                        /* Load.  */
8430
 
                        tmp = tcg_temp_new_i32();
8431
 
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
8432
 
                        if (i == 15) {
8433
 
                            gen_bx(s, tmp);
8434
 
                        } else if (i == rn) {
8435
 
                            loaded_var = tmp;
8436
 
                            loaded_base = 1;
8437
 
                        } else {
8438
 
                            store_reg(s, i, tmp);
8439
 
                        }
8440
 
                    } else {
8441
 
                        /* Store.  */
8442
 
                        tmp = load_reg(s, i);
8443
 
                        gen_aa32_st32(tmp, addr, IS_USER(s));
8444
 
                        tcg_temp_free_i32(tmp);
8445
 
                    }
8446
 
                    tcg_gen_addi_i32(addr, addr, 4);
8447
 
                }
8448
 
                if (loaded_base) {
8449
 
                    store_reg(s, rn, loaded_var);
8450
 
                }
8451
 
                if (insn & (1 << 21)) {
8452
 
                    /* Base register writeback.  */
8453
 
                    if (insn & (1 << 24)) {
8454
 
                        tcg_gen_addi_i32(addr, addr, -offset);
8455
 
                    }
8456
 
                    /* Fault if writeback register is in register list.  */
8457
 
                    if (insn & (1 << rn))
8458
 
                        goto illegal_op;
8459
 
                    store_reg(s, rn, addr);
8460
 
                } else {
8461
 
                    tcg_temp_free_i32(addr);
8462
 
                }
8463
 
            }
8464
 
        }
8465
 
        break;
8466
 
    case 5:
8467
 
 
8468
 
        op = (insn >> 21) & 0xf;
8469
 
        if (op == 6) {
8470
 
            /* Halfword pack.  */
8471
 
            tmp = load_reg(s, rn);
8472
 
            tmp2 = load_reg(s, rm);
8473
 
            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8474
 
            if (insn & (1 << 5)) {
8475
 
                /* pkhtb */
8476
 
                if (shift == 0)
8477
 
                    shift = 31;
8478
 
                tcg_gen_sari_i32(tmp2, tmp2, shift);
8479
 
                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8480
 
                tcg_gen_ext16u_i32(tmp2, tmp2);
8481
 
            } else {
8482
 
                /* pkhbt */
8483
 
                if (shift)
8484
 
                    tcg_gen_shli_i32(tmp2, tmp2, shift);
8485
 
                tcg_gen_ext16u_i32(tmp, tmp);
8486
 
                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8487
 
            }
8488
 
            tcg_gen_or_i32(tmp, tmp, tmp2);
8489
 
            tcg_temp_free_i32(tmp2);
8490
 
            store_reg(s, rd, tmp);
8491
 
        } else {
8492
 
            /* Data processing register constant shift.  */
8493
 
            if (rn == 15) {
8494
 
                tmp = tcg_temp_new_i32();
8495
 
                tcg_gen_movi_i32(tmp, 0);
8496
 
            } else {
8497
 
                tmp = load_reg(s, rn);
8498
 
            }
8499
 
            tmp2 = load_reg(s, rm);
8500
 
 
8501
 
            shiftop = (insn >> 4) & 3;
8502
 
            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8503
 
            conds = (insn & (1 << 20)) != 0;
8504
 
            logic_cc = (conds && thumb2_logic_op(op));
8505
 
            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8506
 
            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8507
 
                goto illegal_op;
8508
 
            tcg_temp_free_i32(tmp2);
8509
 
            if (rd != 15) {
8510
 
                store_reg(s, rd, tmp);
8511
 
            } else {
8512
 
                tcg_temp_free_i32(tmp);
8513
 
            }
8514
 
        }
8515
 
        break;
8516
 
    case 13: /* Misc data processing.  */
8517
 
        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8518
 
        if (op < 4 && (insn & 0xf000) != 0xf000)
8519
 
            goto illegal_op;
8520
 
        switch (op) {
8521
 
        case 0: /* Register controlled shift.  */
8522
 
            tmp = load_reg(s, rn);
8523
 
            tmp2 = load_reg(s, rm);
8524
 
            if ((insn & 0x70) != 0)
8525
 
                goto illegal_op;
8526
 
            op = (insn >> 21) & 3;
8527
 
            logic_cc = (insn & (1 << 20)) != 0;
8528
 
            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8529
 
            if (logic_cc)
8530
 
                gen_logic_CC(tmp);
8531
 
            store_reg_bx(env, s, rd, tmp);
8532
 
            break;
8533
 
        case 1: /* Sign/zero extend.  */
8534
 
            tmp = load_reg(s, rm);
8535
 
            shift = (insn >> 4) & 3;
8536
 
            /* ??? In many cases it's not necessary to do a
8537
 
               rotate, a shift is sufficient.  */
8538
 
            if (shift != 0)
8539
 
                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8540
 
            op = (insn >> 20) & 7;
8541
 
            switch (op) {
8542
 
            case 0: gen_sxth(tmp);   break;
8543
 
            case 1: gen_uxth(tmp);   break;
8544
 
            case 2: gen_sxtb16(tmp); break;
8545
 
            case 3: gen_uxtb16(tmp); break;
8546
 
            case 4: gen_sxtb(tmp);   break;
8547
 
            case 5: gen_uxtb(tmp);   break;
8548
 
            default: goto illegal_op;
8549
 
            }
8550
 
            if (rn != 15) {
8551
 
                tmp2 = load_reg(s, rn);
8552
 
                if ((op >> 1) == 1) {
8553
 
                    gen_add16(tmp, tmp2);
8554
 
                } else {
8555
 
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8556
 
                    tcg_temp_free_i32(tmp2);
8557
 
                }
8558
 
            }
8559
 
            store_reg(s, rd, tmp);
8560
 
            break;
8561
 
        case 2: /* SIMD add/subtract.  */
8562
 
            op = (insn >> 20) & 7;
8563
 
            shift = (insn >> 4) & 7;
8564
 
            if ((op & 3) == 3 || (shift & 3) == 3)
8565
 
                goto illegal_op;
8566
 
            tmp = load_reg(s, rn);
8567
 
            tmp2 = load_reg(s, rm);
8568
 
            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8569
 
            tcg_temp_free_i32(tmp2);
8570
 
            store_reg(s, rd, tmp);
8571
 
            break;
8572
 
        case 3: /* Other data processing.  */
8573
 
            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8574
 
            if (op < 4) {
8575
 
                /* Saturating add/subtract.  */
8576
 
                tmp = load_reg(s, rn);
8577
 
                tmp2 = load_reg(s, rm);
8578
 
                if (op & 1)
8579
 
                    gen_helper_double_saturate(tmp, cpu_env, tmp);
8580
 
                if (op & 2)
8581
 
                    gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8582
 
                else
8583
 
                    gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8584
 
                tcg_temp_free_i32(tmp2);
8585
 
            } else {
8586
 
                tmp = load_reg(s, rn);
8587
 
                switch (op) {
8588
 
                case 0x0a: /* rbit */
8589
 
                    gen_helper_rbit(tmp, tmp);
8590
 
                    break;
8591
 
                case 0x08: /* rev */
8592
 
                    tcg_gen_bswap32_i32(tmp, tmp);
8593
 
                    break;
8594
 
                case 0x09: /* rev16 */
8595
 
                    gen_rev16(tmp);
8596
 
                    break;
8597
 
                case 0x0b: /* revsh */
8598
 
                    gen_revsh(tmp);
8599
 
                    break;
8600
 
                case 0x10: /* sel */
8601
 
                    tmp2 = load_reg(s, rm);
8602
 
                    tmp3 = tcg_temp_new_i32();
8603
 
                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8604
 
                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8605
 
                    tcg_temp_free_i32(tmp3);
8606
 
                    tcg_temp_free_i32(tmp2);
8607
 
                    break;
8608
 
                case 0x18: /* clz */
8609
 
                    gen_helper_clz(tmp, tmp);
8610
 
                    break;
8611
 
                default:
8612
 
                    goto illegal_op;
8613
 
                }
8614
 
            }
8615
 
            store_reg(s, rd, tmp);
8616
 
            break;
8617
 
        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
8618
 
            op = (insn >> 4) & 0xf;
8619
 
            tmp = load_reg(s, rn);
8620
 
            tmp2 = load_reg(s, rm);
8621
 
            switch ((insn >> 20) & 7) {
8622
 
            case 0: /* 32 x 32 -> 32 */
8623
 
                tcg_gen_mul_i32(tmp, tmp, tmp2);
8624
 
                tcg_temp_free_i32(tmp2);
8625
 
                if (rs != 15) {
8626
 
                    tmp2 = load_reg(s, rs);
8627
 
                    if (op)
8628
 
                        tcg_gen_sub_i32(tmp, tmp2, tmp);
8629
 
                    else
8630
 
                        tcg_gen_add_i32(tmp, tmp, tmp2);
8631
 
                    tcg_temp_free_i32(tmp2);
8632
 
                }
8633
 
                break;
8634
 
            case 1: /* 16 x 16 -> 32 */
8635
 
                gen_mulxy(tmp, tmp2, op & 2, op & 1);
8636
 
                tcg_temp_free_i32(tmp2);
8637
 
                if (rs != 15) {
8638
 
                    tmp2 = load_reg(s, rs);
8639
 
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8640
 
                    tcg_temp_free_i32(tmp2);
8641
 
                }
8642
 
                break;
8643
 
            case 2: /* Dual multiply add.  */
8644
 
            case 4: /* Dual multiply subtract.  */
8645
 
                if (op)
8646
 
                    gen_swap_half(tmp2);
8647
 
                gen_smul_dual(tmp, tmp2);
8648
 
                if (insn & (1 << 22)) {
8649
 
                    /* This subtraction cannot overflow. */
8650
 
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8651
 
                } else {
8652
 
                    /* This addition cannot overflow 32 bits;
8653
 
                     * however it may overflow considered as a signed
8654
 
                     * operation, in which case we must set the Q flag.
8655
 
                     */
8656
 
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8657
 
                }
8658
 
                tcg_temp_free_i32(tmp2);
8659
 
                if (rs != 15)
8660
 
                  {
8661
 
                    tmp2 = load_reg(s, rs);
8662
 
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8663
 
                    tcg_temp_free_i32(tmp2);
8664
 
                  }
8665
 
                break;
8666
 
            case 3: /* 32 * 16 -> 32msb */
8667
 
                if (op)
8668
 
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
8669
 
                else
8670
 
                    gen_sxth(tmp2);
8671
 
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
8672
 
                tcg_gen_shri_i64(tmp64, tmp64, 16);
8673
 
                tmp = tcg_temp_new_i32();
8674
 
                tcg_gen_trunc_i64_i32(tmp, tmp64);
8675
 
                tcg_temp_free_i64(tmp64);
8676
 
                if (rs != 15)
8677
 
                  {
8678
 
                    tmp2 = load_reg(s, rs);
8679
 
                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8680
 
                    tcg_temp_free_i32(tmp2);
8681
 
                  }
8682
 
                break;
8683
 
            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8684
 
                tmp64 = gen_muls_i64_i32(tmp, tmp2);
8685
 
                if (rs != 15) {
8686
 
                    tmp = load_reg(s, rs);
8687
 
                    if (insn & (1 << 20)) {
8688
 
                        tmp64 = gen_addq_msw(tmp64, tmp);
8689
 
                    } else {
8690
 
                        tmp64 = gen_subq_msw(tmp64, tmp);
8691
 
                    }
8692
 
                }
8693
 
                if (insn & (1 << 4)) {
8694
 
                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8695
 
                }
8696
 
                tcg_gen_shri_i64(tmp64, tmp64, 32);
8697
 
                tmp = tcg_temp_new_i32();
8698
 
                tcg_gen_trunc_i64_i32(tmp, tmp64);
8699
 
                tcg_temp_free_i64(tmp64);
8700
 
                break;
8701
 
            case 7: /* Unsigned sum of absolute differences.  */
8702
 
                gen_helper_usad8(tmp, tmp, tmp2);
8703
 
                tcg_temp_free_i32(tmp2);
8704
 
                if (rs != 15) {
8705
 
                    tmp2 = load_reg(s, rs);
8706
 
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8707
 
                    tcg_temp_free_i32(tmp2);
8708
 
                }
8709
 
                break;
8710
 
            }
8711
 
            store_reg(s, rd, tmp);
8712
 
            break;
8713
 
        case 6: case 7: /* 64-bit multiply, Divide.  */
8714
 
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8715
 
            tmp = load_reg(s, rn);
8716
 
            tmp2 = load_reg(s, rm);
8717
 
            if ((op & 0x50) == 0x10) {
8718
 
                /* sdiv, udiv */
8719
 
                if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8720
 
                    goto illegal_op;
8721
 
                }
8722
 
                if (op & 0x20)
8723
 
                    gen_helper_udiv(tmp, tmp, tmp2);
8724
 
                else
8725
 
                    gen_helper_sdiv(tmp, tmp, tmp2);
8726
 
                tcg_temp_free_i32(tmp2);
8727
 
                store_reg(s, rd, tmp);
8728
 
            } else if ((op & 0xe) == 0xc) {
8729
 
                /* Dual multiply accumulate long.  */
8730
 
                if (op & 1)
8731
 
                    gen_swap_half(tmp2);
8732
 
                gen_smul_dual(tmp, tmp2);
8733
 
                if (op & 0x10) {
8734
 
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
8735
 
                } else {
8736
 
                    tcg_gen_add_i32(tmp, tmp, tmp2);
8737
 
                }
8738
 
                tcg_temp_free_i32(tmp2);
8739
 
                /* BUGFIX */
8740
 
                tmp64 = tcg_temp_new_i64();
8741
 
                tcg_gen_ext_i32_i64(tmp64, tmp);
8742
 
                tcg_temp_free_i32(tmp);
8743
 
                gen_addq(s, tmp64, rs, rd);
8744
 
                gen_storeq_reg(s, rs, rd, tmp64);
8745
 
                tcg_temp_free_i64(tmp64);
8746
 
            } else {
8747
 
                if (op & 0x20) {
8748
 
                    /* Unsigned 64-bit multiply  */
8749
 
                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8750
 
                } else {
8751
 
                    if (op & 8) {
8752
 
                        /* smlalxy */
8753
 
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
8754
 
                        tcg_temp_free_i32(tmp2);
8755
 
                        tmp64 = tcg_temp_new_i64();
8756
 
                        tcg_gen_ext_i32_i64(tmp64, tmp);
8757
 
                        tcg_temp_free_i32(tmp);
8758
 
                    } else {
8759
 
                        /* Signed 64-bit multiply  */
8760
 
                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
8761
 
                    }
8762
 
                }
8763
 
                if (op & 4) {
8764
 
                    /* umaal */
8765
 
                    gen_addq_lo(s, tmp64, rs);
8766
 
                    gen_addq_lo(s, tmp64, rd);
8767
 
                } else if (op & 0x40) {
8768
 
                    /* 64-bit accumulate.  */
8769
 
                    gen_addq(s, tmp64, rs, rd);
8770
 
                }
8771
 
                gen_storeq_reg(s, rs, rd, tmp64);
8772
 
                tcg_temp_free_i64(tmp64);
8773
 
            }
8774
 
            break;
8775
 
        }
8776
 
        break;
8777
 
    case 6: case 7: case 14: case 15:
8778
 
        /* Coprocessor.  */
8779
 
        if (((insn >> 24) & 3) == 3) {
8780
 
            /* Translate into the equivalent ARM encoding.  */
8781
 
            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8782
 
            if (disas_neon_data_insn(env, s, insn))
8783
 
                goto illegal_op;
8784
 
        } else {
8785
 
            if (insn & (1 << 28))
8786
 
                goto illegal_op;
8787
 
            if (disas_coproc_insn (env, s, insn))
8788
 
                goto illegal_op;
8789
 
        }
8790
 
        break;
8791
 
    case 8: case 9: case 10: case 11:
8792
 
        if (insn & (1 << 15)) {
8793
 
            /* Branches, misc control.  */
8794
 
            if (insn & 0x5000) {
8795
 
                /* Unconditional branch.  */
8796
 
                /* signextend(hw1[10:0]) -> offset[:12].  */
8797
 
                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8798
 
                /* hw1[10:0] -> offset[11:1].  */
8799
 
                offset |= (insn & 0x7ff) << 1;
8800
 
                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8801
 
                   offset[24:22] already have the same value because of the
8802
 
                   sign extension above.  */
8803
 
                offset ^= ((~insn) & (1 << 13)) << 10;
8804
 
                offset ^= ((~insn) & (1 << 11)) << 11;
8805
 
 
8806
 
                if (insn & (1 << 14)) {
8807
 
                    /* Branch and link.  */
8808
 
                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8809
 
                }
8810
 
 
8811
 
                offset += s->pc;
8812
 
                if (insn & (1 << 12)) {
8813
 
                    /* b/bl */
8814
 
                    gen_jmp(s, offset);
8815
 
                } else {
8816
 
                    /* blx */
8817
 
                    offset &= ~(uint32_t)2;
8818
 
                    /* thumb2 bx, no need to check */
8819
 
                    gen_bx_im(s, offset);
8820
 
                }
8821
 
            } else if (((insn >> 23) & 7) == 7) {
8822
 
                /* Misc control */
8823
 
                if (insn & (1 << 13))
8824
 
                    goto illegal_op;
8825
 
 
8826
 
                if (insn & (1 << 26)) {
8827
 
                    /* Secure monitor call / smc (v6Z) */
8828
 
                    if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
8829
 
                        || IS_USER(s)) {
8830
 
                        goto illegal_op;
8831
 
                    }
8832
 
                    gen_smc(env, s);
8833
 
                } else {
8834
 
                    op = (insn >> 20) & 7;
8835
 
                    switch (op) {
8836
 
                    case 0: /* msr cpsr.  */
8837
 
                        if (IS_M(env)) {
8838
 
                            tmp = load_reg(s, rn);
8839
 
                            addr = tcg_const_i32(insn & 0xff);
8840
 
                            gen_helper_v7m_msr(cpu_env, addr, tmp);
8841
 
                            tcg_temp_free_i32(addr);
8842
 
                            tcg_temp_free_i32(tmp);
8843
 
                            gen_lookup_tb(s);
8844
 
                            break;
8845
 
                        }
8846
 
                        /* fall through */
8847
 
                    case 1: /* msr spsr.  */
8848
 
                        if (IS_M(env))
8849
 
                            goto illegal_op;
8850
 
                        tmp = load_reg(s, rn);
8851
 
                        if (gen_set_psr(s,
8852
 
                              msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8853
 
                              op == 1, tmp))
8854
 
                            goto illegal_op;
8855
 
                        break;
8856
 
                    case 2: /* cps, nop-hint.  */
8857
 
                        if (((insn >> 8) & 7) == 0) {
8858
 
                            gen_nop_hint(s, insn & 0xff);
8859
 
                        }
8860
 
                        /* Implemented as NOP in user mode.  */
8861
 
                        if (IS_USER(s))
8862
 
                            break;
8863
 
                        offset = 0;
8864
 
                        imm = 0;
8865
 
                        if (insn & (1 << 10)) {
8866
 
                            if (insn & (1 << 7))
8867
 
                                offset |= CPSR_A;
8868
 
                            if (insn & (1 << 6))
8869
 
                                offset |= CPSR_I;
8870
 
                            if (insn & (1 << 5))
8871
 
                                offset |= CPSR_F;
8872
 
                            if (insn & (1 << 9))
8873
 
                                imm = CPSR_A | CPSR_I | CPSR_F;
8874
 
                        }
8875
 
                        if (insn & (1 << 8)) {
8876
 
                            offset |= 0x1f;
8877
 
                            imm |= (insn & 0x1f);
8878
 
                        }
8879
 
                        if (offset) {
8880
 
                            gen_set_psr_im(s, offset, 0, imm);
8881
 
                        }
8882
 
                        break;
8883
 
                    case 3: /* Special control operations.  */
8884
 
                        ARCH(7);
8885
 
                        op = (insn >> 4) & 0xf;
8886
 
                        switch (op) {
8887
 
                        case 2: /* clrex */
8888
 
                            gen_clrex(s);
8889
 
                            break;
8890
 
                        case 4: /* dsb */
8891
 
                        case 5: /* dmb */
8892
 
                        case 6: /* isb */
8893
 
                            /* These execute as NOPs.  */
8894
 
                            break;
8895
 
                        default:
8896
 
                            goto illegal_op;
8897
 
                        }
8898
 
                        break;
8899
 
                    case 4: /* bxj */
8900
 
                        /* Trivial implementation equivalent to bx.  */
8901
 
                        tmp = load_reg(s, rn);
8902
 
                        gen_bx(s, tmp);
8903
 
                        break;
8904
 
                    case 5: /* Exception return.  */
8905
 
                        if (IS_USER(s)) {
8906
 
                            goto illegal_op;
8907
 
                        }
8908
 
                        if (rn != 14 || rd != 15) {
8909
 
                            goto illegal_op;
8910
 
                        }
8911
 
                        tmp = load_reg(s, rn);
8912
 
                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8913
 
                        gen_exception_return(s, tmp);
8914
 
                        break;
8915
 
                    case 6: /* mrs cpsr.  */
8916
 
                        tmp = tcg_temp_new_i32();
8917
 
                        if (IS_M(env)) {
8918
 
                            addr = tcg_const_i32(insn & 0xff);
8919
 
                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
8920
 
                            tcg_temp_free_i32(addr);
8921
 
                        } else {
8922
 
                            gen_helper_cpsr_read(tmp, cpu_env);
8923
 
                        }
8924
 
                        store_reg(s, rd, tmp);
8925
 
                        break;
8926
 
                    case 7: /* mrs spsr.  */
8927
 
                        /* Not accessible in user mode.  */
8928
 
                        if (IS_USER(s) || IS_M(env))
8929
 
                            goto illegal_op;
8930
 
                        tmp = load_cpu_field(spsr);
8931
 
                        store_reg(s, rd, tmp);
8932
 
                        break;
8933
 
                    }
8934
 
                }
8935
 
            } else {
8936
 
                /* Conditional branch.  */
8937
 
                op = (insn >> 22) & 0xf;
8938
 
                /* Generate a conditional jump to next instruction.  */
8939
 
                s->condlabel = gen_new_label();
8940
 
                gen_test_cc(op ^ 1, s->condlabel);
8941
 
                s->condjmp = 1;
8942
 
 
8943
 
                /* offset[11:1] = insn[10:0] */
8944
 
                offset = (insn & 0x7ff) << 1;
8945
 
                /* offset[17:12] = insn[21:16].  */
8946
 
                offset |= (insn & 0x003f0000) >> 4;
8947
 
                /* offset[31:20] = insn[26].  */
8948
 
                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8949
 
                /* offset[18] = insn[13].  */
8950
 
                offset |= (insn & (1 << 13)) << 5;
8951
 
                /* offset[19] = insn[11].  */
8952
 
                offset |= (insn & (1 << 11)) << 8;
8953
 
 
8954
 
                /* jump to the offset */
8955
 
                gen_jmp(s, s->pc + offset);
8956
 
            }
8957
 
        } else {
8958
 
            /* Data processing immediate.  */
8959
 
            if (insn & (1 << 25)) {
8960
 
                if (insn & (1 << 24)) {
8961
 
                    if (insn & (1 << 20))
8962
 
                        goto illegal_op;
8963
 
                    /* Bitfield/Saturate.  */
8964
 
                    op = (insn >> 21) & 7;
8965
 
                    imm = insn & 0x1f;
8966
 
                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8967
 
                    if (rn == 15) {
8968
 
                        tmp = tcg_temp_new_i32();
8969
 
                        tcg_gen_movi_i32(tmp, 0);
8970
 
                    } else {
8971
 
                        tmp = load_reg(s, rn);
8972
 
                    }
8973
 
                    switch (op) {
8974
 
                    case 2: /* Signed bitfield extract.  */
8975
 
                        imm++;
8976
 
                        if (shift + imm > 32)
8977
 
                            goto illegal_op;
8978
 
                        if (imm < 32)
8979
 
                            gen_sbfx(tmp, shift, imm);
8980
 
                        break;
8981
 
                    case 6: /* Unsigned bitfield extract.  */
8982
 
                        imm++;
8983
 
                        if (shift + imm > 32)
8984
 
                            goto illegal_op;
8985
 
                        if (imm < 32)
8986
 
                            gen_ubfx(tmp, shift, (1u << imm) - 1);
8987
 
                        break;
8988
 
                    case 3: /* Bitfield insert/clear.  */
8989
 
                        if (imm < shift)
8990
 
                            goto illegal_op;
8991
 
                        imm = imm + 1 - shift;
8992
 
                        if (imm != 32) {
8993
 
                            tmp2 = load_reg(s, rd);
8994
 
                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
8995
 
                            tcg_temp_free_i32(tmp2);
8996
 
                        }
8997
 
                        break;
8998
 
                    case 7:
8999
 
                        goto illegal_op;
9000
 
                    default: /* Saturate.  */
9001
 
                        if (shift) {
9002
 
                            if (op & 1)
9003
 
                                tcg_gen_sari_i32(tmp, tmp, shift);
9004
 
                            else
9005
 
                                tcg_gen_shli_i32(tmp, tmp, shift);
9006
 
                        }
9007
 
                        tmp2 = tcg_const_i32(imm);
9008
 
                        if (op & 4) {
9009
 
                            /* Unsigned.  */
9010
 
                            if ((op & 1) && shift == 0)
9011
 
                                gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9012
 
                            else
9013
 
                                gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9014
 
                        } else {
9015
 
                            /* Signed.  */
9016
 
                            if ((op & 1) && shift == 0)
9017
 
                                gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9018
 
                            else
9019
 
                                gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9020
 
                        }
9021
 
                        tcg_temp_free_i32(tmp2);
9022
 
                        break;
9023
 
                    }
9024
 
                    store_reg(s, rd, tmp);
9025
 
                } else {
9026
 
                    imm = ((insn & 0x04000000) >> 15)
9027
 
                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
9028
 
                    if (insn & (1 << 22)) {
9029
 
                        /* 16-bit immediate.  */
9030
 
                        imm |= (insn >> 4) & 0xf000;
9031
 
                        if (insn & (1 << 23)) {
9032
 
                            /* movt */
9033
 
                            tmp = load_reg(s, rd);
9034
 
                            tcg_gen_ext16u_i32(tmp, tmp);
9035
 
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
9036
 
                        } else {
9037
 
                            /* movw */
9038
 
                            tmp = tcg_temp_new_i32();
9039
 
                            tcg_gen_movi_i32(tmp, imm);
9040
 
                        }
9041
 
                    } else {
9042
 
                        /* Add/sub 12-bit immediate.  */
9043
 
                        if (rn == 15) {
9044
 
                            offset = s->pc & ~(uint32_t)3;
9045
 
                            if (insn & (1 << 23))
9046
 
                                offset -= imm;
9047
 
                            else
9048
 
                                offset += imm;
9049
 
                            tmp = tcg_temp_new_i32();
9050
 
                            tcg_gen_movi_i32(tmp, offset);
9051
 
                        } else {
9052
 
                            tmp = load_reg(s, rn);
9053
 
                            if (insn & (1 << 23))
9054
 
                                tcg_gen_subi_i32(tmp, tmp, imm);
9055
 
                            else
9056
 
                                tcg_gen_addi_i32(tmp, tmp, imm);
9057
 
                        }
9058
 
                    }
9059
 
                    store_reg(s, rd, tmp);
9060
 
                }
9061
 
            } else {
9062
 
                int shifter_out = 0;
9063
 
                /* modified 12-bit immediate.  */
9064
 
                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9065
 
                imm = (insn & 0xff);
9066
 
                switch (shift) {
9067
 
                case 0: /* XY */
9068
 
                    /* Nothing to do.  */
9069
 
                    break;
9070
 
                case 1: /* 00XY00XY */
9071
 
                    imm |= imm << 16;
9072
 
                    break;
9073
 
                case 2: /* XY00XY00 */
9074
 
                    imm |= imm << 16;
9075
 
                    imm <<= 8;
9076
 
                    break;
9077
 
                case 3: /* XYXYXYXY */
9078
 
                    imm |= imm << 16;
9079
 
                    imm |= imm << 8;
9080
 
                    break;
9081
 
                default: /* Rotated constant.  */
9082
 
                    shift = (shift << 1) | (imm >> 7);
9083
 
                    imm |= 0x80;
9084
 
                    imm = imm << (32 - shift);
9085
 
                    shifter_out = 1;
9086
 
                    break;
9087
 
                }
9088
 
                tmp2 = tcg_temp_new_i32();
9089
 
                tcg_gen_movi_i32(tmp2, imm);
9090
 
                rn = (insn >> 16) & 0xf;
9091
 
                if (rn == 15) {
9092
 
                    tmp = tcg_temp_new_i32();
9093
 
                    tcg_gen_movi_i32(tmp, 0);
9094
 
                } else {
9095
 
                    tmp = load_reg(s, rn);
9096
 
                }
9097
 
                op = (insn >> 21) & 0xf;
9098
 
                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9099
 
                                       shifter_out, tmp, tmp2))
9100
 
                    goto illegal_op;
9101
 
                tcg_temp_free_i32(tmp2);
9102
 
                rd = (insn >> 8) & 0xf;
9103
 
                if (rd != 15) {
9104
 
                    store_reg(s, rd, tmp);
9105
 
                } else {
9106
 
                    tcg_temp_free_i32(tmp);
9107
 
                }
9108
 
            }
9109
 
        }
9110
 
        break;
9111
 
    case 12: /* Load/store single data item.  */
9112
 
        {
9113
 
        int postinc = 0;
9114
 
        int writeback = 0;
9115
 
        int user;
9116
 
        if ((insn & 0x01100000) == 0x01000000) {
9117
 
            if (disas_neon_ls_insn(env, s, insn))
9118
 
                goto illegal_op;
9119
 
            break;
9120
 
        }
9121
 
        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9122
 
        if (rs == 15) {
9123
 
            if (!(insn & (1 << 20))) {
9124
 
                goto illegal_op;
9125
 
            }
9126
 
            if (op != 2) {
9127
 
                /* Byte or halfword load space with dest == r15 : memory hints.
9128
 
                 * Catch them early so we don't emit pointless addressing code.
9129
 
                 * This space is a mix of:
9130
 
                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
9131
 
                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9132
 
                 *     cores)
9133
 
                 *  unallocated hints, which must be treated as NOPs
9134
 
                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
9135
 
                 *     which is easiest for the decoding logic
9136
 
                 *  Some space which must UNDEF
9137
 
                 */
9138
 
                int op1 = (insn >> 23) & 3;
9139
 
                int op2 = (insn >> 6) & 0x3f;
9140
 
                if (op & 2) {
9141
 
                    goto illegal_op;
9142
 
                }
9143
 
                if (rn == 15) {
9144
 
                    /* UNPREDICTABLE, unallocated hint or
9145
 
                     * PLD/PLDW/PLI (literal)
9146
 
                     */
9147
 
                    return 0;
9148
 
                }
9149
 
                if (op1 & 1) {
9150
 
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
9151
 
                }
9152
 
                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9153
 
                    return 0; /* PLD/PLDW/PLI or unallocated hint */
9154
 
                }
9155
 
                /* UNDEF space, or an UNPREDICTABLE */
9156
 
                return 1;
9157
 
            }
9158
 
        }
9159
 
        user = IS_USER(s);
9160
 
        if (rn == 15) {
9161
 
            addr = tcg_temp_new_i32();
9162
 
            /* PC relative.  */
9163
 
            /* s->pc has already been incremented by 4.  */
9164
 
            imm = s->pc & 0xfffffffc;
9165
 
            if (insn & (1 << 23))
9166
 
                imm += insn & 0xfff;
9167
 
            else
9168
 
                imm -= insn & 0xfff;
9169
 
            tcg_gen_movi_i32(addr, imm);
9170
 
        } else {
9171
 
            addr = load_reg(s, rn);
9172
 
            if (insn & (1 << 23)) {
9173
 
                /* Positive offset.  */
9174
 
                imm = insn & 0xfff;
9175
 
                tcg_gen_addi_i32(addr, addr, imm);
9176
 
            } else {
9177
 
                imm = insn & 0xff;
9178
 
                switch ((insn >> 8) & 0xf) {
9179
 
                case 0x0: /* Shifted Register.  */
9180
 
                    shift = (insn >> 4) & 0xf;
9181
 
                    if (shift > 3) {
9182
 
                        tcg_temp_free_i32(addr);
9183
 
                        goto illegal_op;
9184
 
                    }
9185
 
                    tmp = load_reg(s, rm);
9186
 
                    if (shift)
9187
 
                        tcg_gen_shli_i32(tmp, tmp, shift);
9188
 
                    tcg_gen_add_i32(addr, addr, tmp);
9189
 
                    tcg_temp_free_i32(tmp);
9190
 
                    break;
9191
 
                case 0xc: /* Negative offset.  */
9192
 
                    tcg_gen_addi_i32(addr, addr, -imm);
9193
 
                    break;
9194
 
                case 0xe: /* User privilege.  */
9195
 
                    tcg_gen_addi_i32(addr, addr, imm);
9196
 
                    user = 1;
9197
 
                    break;
9198
 
                case 0x9: /* Post-decrement.  */
9199
 
                    imm = -imm;
9200
 
                    /* Fall through.  */
9201
 
                case 0xb: /* Post-increment.  */
9202
 
                    postinc = 1;
9203
 
                    writeback = 1;
9204
 
                    break;
9205
 
                case 0xd: /* Pre-decrement.  */
9206
 
                    imm = -imm;
9207
 
                    /* Fall through.  */
9208
 
                case 0xf: /* Pre-increment.  */
9209
 
                    tcg_gen_addi_i32(addr, addr, imm);
9210
 
                    writeback = 1;
9211
 
                    break;
9212
 
                default:
9213
 
                    tcg_temp_free_i32(addr);
9214
 
                    goto illegal_op;
9215
 
                }
9216
 
            }
9217
 
        }
9218
 
        if (insn & (1 << 20)) {
9219
 
            /* Load.  */
9220
 
            tmp = tcg_temp_new_i32();
9221
 
            switch (op) {
9222
 
            case 0:
9223
 
                gen_aa32_ld8u(tmp, addr, user);
9224
 
                break;
9225
 
            case 4:
9226
 
                gen_aa32_ld8s(tmp, addr, user);
9227
 
                break;
9228
 
            case 1:
9229
 
                gen_aa32_ld16u(tmp, addr, user);
9230
 
                break;
9231
 
            case 5:
9232
 
                gen_aa32_ld16s(tmp, addr, user);
9233
 
                break;
9234
 
            case 2:
9235
 
                gen_aa32_ld32u(tmp, addr, user);
9236
 
                break;
9237
 
            default:
9238
 
                tcg_temp_free_i32(tmp);
9239
 
                tcg_temp_free_i32(addr);
9240
 
                goto illegal_op;
9241
 
            }
9242
 
            if (rs == 15) {
9243
 
                gen_bx(s, tmp);
9244
 
            } else {
9245
 
                store_reg(s, rs, tmp);
9246
 
            }
9247
 
        } else {
9248
 
            /* Store.  */
9249
 
            tmp = load_reg(s, rs);
9250
 
            switch (op) {
9251
 
            case 0:
9252
 
                gen_aa32_st8(tmp, addr, user);
9253
 
                break;
9254
 
            case 1:
9255
 
                gen_aa32_st16(tmp, addr, user);
9256
 
                break;
9257
 
            case 2:
9258
 
                gen_aa32_st32(tmp, addr, user);
9259
 
                break;
9260
 
            default:
9261
 
                tcg_temp_free_i32(tmp);
9262
 
                tcg_temp_free_i32(addr);
9263
 
                goto illegal_op;
9264
 
            }
9265
 
            tcg_temp_free_i32(tmp);
9266
 
        }
9267
 
        if (postinc)
9268
 
            tcg_gen_addi_i32(addr, addr, imm);
9269
 
        if (writeback) {
9270
 
            store_reg(s, rn, addr);
9271
 
        } else {
9272
 
            tcg_temp_free_i32(addr);
9273
 
        }
9274
 
        }
9275
 
        break;
9276
 
    default:
9277
 
        goto illegal_op;
9278
 
    }
9279
 
    return 0;
9280
 
illegal_op:
9281
 
    return 1;
9282
 
}
9283
 
 
9284
 
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9285
 
{
9286
 
    uint32_t val, insn, op, rm, rn, rd, shift, cond;
9287
 
    int32_t offset;
9288
 
    int i;
9289
 
    TCGv_i32 tmp;
9290
 
    TCGv_i32 tmp2;
9291
 
    TCGv_i32 addr;
9292
 
 
9293
 
    if (s->condexec_mask) {
9294
 
        cond = s->condexec_cond;
9295
 
        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
9296
 
          s->condlabel = gen_new_label();
9297
 
          gen_test_cc(cond ^ 1, s->condlabel);
9298
 
          s->condjmp = 1;
9299
 
        }
9300
 
    }
9301
 
 
9302
 
    insn = arm_lduw_code(env, s->pc, s->bswap_code);
9303
 
    s->pc += 2;
9304
 
 
9305
 
    switch (insn >> 12) {
9306
 
    case 0: case 1:
9307
 
 
9308
 
        rd = insn & 7;
9309
 
        op = (insn >> 11) & 3;
9310
 
        if (op == 3) {
9311
 
            /* add/subtract */
9312
 
            rn = (insn >> 3) & 7;
9313
 
            tmp = load_reg(s, rn);
9314
 
            if (insn & (1 << 10)) {
9315
 
                /* immediate */
9316
 
                tmp2 = tcg_temp_new_i32();
9317
 
                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9318
 
            } else {
9319
 
                /* reg */
9320
 
                rm = (insn >> 6) & 7;
9321
 
                tmp2 = load_reg(s, rm);
9322
 
            }
9323
 
            if (insn & (1 << 9)) {
9324
 
                if (s->condexec_mask)
9325
 
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9326
 
                else
9327
 
                    gen_sub_CC(tmp, tmp, tmp2);
9328
 
            } else {
9329
 
                if (s->condexec_mask)
9330
 
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9331
 
                else
9332
 
                    gen_add_CC(tmp, tmp, tmp2);
9333
 
            }
9334
 
            tcg_temp_free_i32(tmp2);
9335
 
            store_reg(s, rd, tmp);
9336
 
        } else {
9337
 
            /* shift immediate */
9338
 
            rm = (insn >> 3) & 7;
9339
 
            shift = (insn >> 6) & 0x1f;
9340
 
            tmp = load_reg(s, rm);
9341
 
            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9342
 
            if (!s->condexec_mask)
9343
 
                gen_logic_CC(tmp);
9344
 
            store_reg(s, rd, tmp);
9345
 
        }
9346
 
        break;
9347
 
    case 2: case 3:
9348
 
        /* arithmetic large immediate */
9349
 
        op = (insn >> 11) & 3;
9350
 
        rd = (insn >> 8) & 0x7;
9351
 
        if (op == 0) { /* mov */
9352
 
            tmp = tcg_temp_new_i32();
9353
 
            tcg_gen_movi_i32(tmp, insn & 0xff);
9354
 
            if (!s->condexec_mask)
9355
 
                gen_logic_CC(tmp);
9356
 
            store_reg(s, rd, tmp);
9357
 
        } else {
9358
 
            tmp = load_reg(s, rd);
9359
 
            tmp2 = tcg_temp_new_i32();
9360
 
            tcg_gen_movi_i32(tmp2, insn & 0xff);
9361
 
            switch (op) {
9362
 
            case 1: /* cmp */
9363
 
                gen_sub_CC(tmp, tmp, tmp2);
9364
 
                tcg_temp_free_i32(tmp);
9365
 
                tcg_temp_free_i32(tmp2);
9366
 
                break;
9367
 
            case 2: /* add */
9368
 
                if (s->condexec_mask)
9369
 
                    tcg_gen_add_i32(tmp, tmp, tmp2);
9370
 
                else
9371
 
                    gen_add_CC(tmp, tmp, tmp2);
9372
 
                tcg_temp_free_i32(tmp2);
9373
 
                store_reg(s, rd, tmp);
9374
 
                break;
9375
 
            case 3: /* sub */
9376
 
                if (s->condexec_mask)
9377
 
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9378
 
                else
9379
 
                    gen_sub_CC(tmp, tmp, tmp2);
9380
 
                tcg_temp_free_i32(tmp2);
9381
 
                store_reg(s, rd, tmp);
9382
 
                break;
9383
 
            }
9384
 
        }
9385
 
        break;
9386
 
    case 4:
9387
 
        if (insn & (1 << 11)) {
9388
 
            rd = (insn >> 8) & 7;
9389
 
            /* load pc-relative.  Bit 1 of PC is ignored.  */
9390
 
            val = s->pc + 2 + ((insn & 0xff) * 4);
9391
 
            val &= ~(uint32_t)2;
9392
 
            addr = tcg_temp_new_i32();
9393
 
            tcg_gen_movi_i32(addr, val);
9394
 
            tmp = tcg_temp_new_i32();
9395
 
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
9396
 
            tcg_temp_free_i32(addr);
9397
 
            store_reg(s, rd, tmp);
9398
 
            break;
9399
 
        }
9400
 
        if (insn & (1 << 10)) {
9401
 
            /* data processing extended or blx */
9402
 
            rd = (insn & 7) | ((insn >> 4) & 8);
9403
 
            rm = (insn >> 3) & 0xf;
9404
 
            op = (insn >> 8) & 3;
9405
 
            switch (op) {
9406
 
            case 0: /* add */
9407
 
                tmp = load_reg(s, rd);
9408
 
                tmp2 = load_reg(s, rm);
9409
 
                tcg_gen_add_i32(tmp, tmp, tmp2);
9410
 
                tcg_temp_free_i32(tmp2);
9411
 
                store_reg(s, rd, tmp);
9412
 
                break;
9413
 
            case 1: /* cmp */
9414
 
                tmp = load_reg(s, rd);
9415
 
                tmp2 = load_reg(s, rm);
9416
 
                gen_sub_CC(tmp, tmp, tmp2);
9417
 
                tcg_temp_free_i32(tmp2);
9418
 
                tcg_temp_free_i32(tmp);
9419
 
                break;
9420
 
            case 2: /* mov/cpy */
9421
 
                tmp = load_reg(s, rm);
9422
 
                store_reg(s, rd, tmp);
9423
 
                break;
9424
 
            case 3:/* branch [and link] exchange thumb register */
9425
 
                tmp = load_reg(s, rm);
9426
 
                if (insn & (1 << 7)) {
9427
 
                    ARCH(5);
9428
 
                    val = (uint32_t)s->pc | 1;
9429
 
                    tmp2 = tcg_temp_new_i32();
9430
 
                    tcg_gen_movi_i32(tmp2, val);
9431
 
                    store_reg(s, 14, tmp2);
9432
 
                }
9433
 
                /* already thumb, no need to check */
9434
 
                gen_bx(s, tmp);
9435
 
                break;
9436
 
            }
9437
 
            break;
9438
 
        }
9439
 
 
9440
 
        /* data processing register */
9441
 
        rd = insn & 7;
9442
 
        rm = (insn >> 3) & 7;
9443
 
        op = (insn >> 6) & 0xf;
9444
 
        if (op == 2 || op == 3 || op == 4 || op == 7) {
9445
 
            /* the shift/rotate ops want the operands backwards */
9446
 
            val = rm;
9447
 
            rm = rd;
9448
 
            rd = val;
9449
 
            val = 1;
9450
 
        } else {
9451
 
            val = 0;
9452
 
        }
9453
 
 
9454
 
        if (op == 9) { /* neg */
9455
 
            tmp = tcg_temp_new_i32();
9456
 
            tcg_gen_movi_i32(tmp, 0);
9457
 
        } else if (op != 0xf) { /* mvn doesn't read its first operand */
9458
 
            tmp = load_reg(s, rd);
9459
 
        } else {
9460
 
            TCGV_UNUSED_I32(tmp);
9461
 
        }
9462
 
 
9463
 
        tmp2 = load_reg(s, rm);
9464
 
        switch (op) {
9465
 
        case 0x0: /* and */
9466
 
            tcg_gen_and_i32(tmp, tmp, tmp2);
9467
 
            if (!s->condexec_mask)
9468
 
                gen_logic_CC(tmp);
9469
 
            break;
9470
 
        case 0x1: /* eor */
9471
 
            tcg_gen_xor_i32(tmp, tmp, tmp2);
9472
 
            if (!s->condexec_mask)
9473
 
                gen_logic_CC(tmp);
9474
 
            break;
9475
 
        case 0x2: /* lsl */
9476
 
            if (s->condexec_mask) {
9477
 
                gen_shl(tmp2, tmp2, tmp);
9478
 
            } else {
9479
 
                gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9480
 
                gen_logic_CC(tmp2);
9481
 
            }
9482
 
            break;
9483
 
        case 0x3: /* lsr */
9484
 
            if (s->condexec_mask) {
9485
 
                gen_shr(tmp2, tmp2, tmp);
9486
 
            } else {
9487
 
                gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9488
 
                gen_logic_CC(tmp2);
9489
 
            }
9490
 
            break;
9491
 
        case 0x4: /* asr */
9492
 
            if (s->condexec_mask) {
9493
 
                gen_sar(tmp2, tmp2, tmp);
9494
 
            } else {
9495
 
                gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9496
 
                gen_logic_CC(tmp2);
9497
 
            }
9498
 
            break;
9499
 
        case 0x5: /* adc */
9500
 
            if (s->condexec_mask) {
9501
 
                gen_adc(tmp, tmp2);
9502
 
            } else {
9503
 
                gen_adc_CC(tmp, tmp, tmp2);
9504
 
            }
9505
 
            break;
9506
 
        case 0x6: /* sbc */
9507
 
            if (s->condexec_mask) {
9508
 
                gen_sub_carry(tmp, tmp, tmp2);
9509
 
            } else {
9510
 
                gen_sbc_CC(tmp, tmp, tmp2);
9511
 
            }
9512
 
            break;
9513
 
        case 0x7: /* ror */
9514
 
            if (s->condexec_mask) {
9515
 
                tcg_gen_andi_i32(tmp, tmp, 0x1f);
9516
 
                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9517
 
            } else {
9518
 
                gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9519
 
                gen_logic_CC(tmp2);
9520
 
            }
9521
 
            break;
9522
 
        case 0x8: /* tst */
9523
 
            tcg_gen_and_i32(tmp, tmp, tmp2);
9524
 
            gen_logic_CC(tmp);
9525
 
            rd = 16;
9526
 
            break;
9527
 
        case 0x9: /* neg */
9528
 
            if (s->condexec_mask)
9529
 
                tcg_gen_neg_i32(tmp, tmp2);
9530
 
            else
9531
 
                gen_sub_CC(tmp, tmp, tmp2);
9532
 
            break;
9533
 
        case 0xa: /* cmp */
9534
 
            gen_sub_CC(tmp, tmp, tmp2);
9535
 
            rd = 16;
9536
 
            break;
9537
 
        case 0xb: /* cmn */
9538
 
            gen_add_CC(tmp, tmp, tmp2);
9539
 
            rd = 16;
9540
 
            break;
9541
 
        case 0xc: /* orr */
9542
 
            tcg_gen_or_i32(tmp, tmp, tmp2);
9543
 
            if (!s->condexec_mask)
9544
 
                gen_logic_CC(tmp);
9545
 
            break;
9546
 
        case 0xd: /* mul */
9547
 
            tcg_gen_mul_i32(tmp, tmp, tmp2);
9548
 
            if (!s->condexec_mask)
9549
 
                gen_logic_CC(tmp);
9550
 
            break;
9551
 
        case 0xe: /* bic */
9552
 
            tcg_gen_andc_i32(tmp, tmp, tmp2);
9553
 
            if (!s->condexec_mask)
9554
 
                gen_logic_CC(tmp);
9555
 
            break;
9556
 
        case 0xf: /* mvn */
9557
 
            tcg_gen_not_i32(tmp2, tmp2);
9558
 
            if (!s->condexec_mask)
9559
 
                gen_logic_CC(tmp2);
9560
 
            val = 1;
9561
 
            rm = rd;
9562
 
            break;
9563
 
        }
9564
 
        if (rd != 16) {
9565
 
            if (val) {
9566
 
                store_reg(s, rm, tmp2);
9567
 
                if (op != 0xf)
9568
 
                    tcg_temp_free_i32(tmp);
9569
 
            } else {
9570
 
                store_reg(s, rd, tmp);
9571
 
                tcg_temp_free_i32(tmp2);
9572
 
            }
9573
 
        } else {
9574
 
            tcg_temp_free_i32(tmp);
9575
 
            tcg_temp_free_i32(tmp2);
9576
 
        }
9577
 
        break;
9578
 
 
9579
 
    case 5:
9580
 
        /* load/store register offset.  */
9581
 
        rd = insn & 7;
9582
 
        rn = (insn >> 3) & 7;
9583
 
        rm = (insn >> 6) & 7;
9584
 
        op = (insn >> 9) & 7;
9585
 
        addr = load_reg(s, rn);
9586
 
        tmp = load_reg(s, rm);
9587
 
        tcg_gen_add_i32(addr, addr, tmp);
9588
 
        tcg_temp_free_i32(tmp);
9589
 
 
9590
 
        if (op < 3) { /* store */
9591
 
            tmp = load_reg(s, rd);
9592
 
        } else {
9593
 
            tmp = tcg_temp_new_i32();
9594
 
        }
9595
 
 
9596
 
        switch (op) {
9597
 
        case 0: /* str */
9598
 
            gen_aa32_st32(tmp, addr, IS_USER(s));
9599
 
            break;
9600
 
        case 1: /* strh */
9601
 
            gen_aa32_st16(tmp, addr, IS_USER(s));
9602
 
            break;
9603
 
        case 2: /* strb */
9604
 
            gen_aa32_st8(tmp, addr, IS_USER(s));
9605
 
            break;
9606
 
        case 3: /* ldrsb */
9607
 
            gen_aa32_ld8s(tmp, addr, IS_USER(s));
9608
 
            break;
9609
 
        case 4: /* ldr */
9610
 
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
9611
 
            break;
9612
 
        case 5: /* ldrh */
9613
 
            gen_aa32_ld16u(tmp, addr, IS_USER(s));
9614
 
            break;
9615
 
        case 6: /* ldrb */
9616
 
            gen_aa32_ld8u(tmp, addr, IS_USER(s));
9617
 
            break;
9618
 
        case 7: /* ldrsh */
9619
 
            gen_aa32_ld16s(tmp, addr, IS_USER(s));
9620
 
            break;
9621
 
        }
9622
 
        if (op >= 3) { /* load */
9623
 
            store_reg(s, rd, tmp);
9624
 
        } else {
9625
 
            tcg_temp_free_i32(tmp);
9626
 
        }
9627
 
        tcg_temp_free_i32(addr);
9628
 
        break;
9629
 
 
9630
 
    case 6:
9631
 
        /* load/store word immediate offset */
9632
 
        rd = insn & 7;
9633
 
        rn = (insn >> 3) & 7;
9634
 
        addr = load_reg(s, rn);
9635
 
        val = (insn >> 4) & 0x7c;
9636
 
        tcg_gen_addi_i32(addr, addr, val);
9637
 
 
9638
 
        if (insn & (1 << 11)) {
9639
 
            /* load */
9640
 
            tmp = tcg_temp_new_i32();
9641
 
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
9642
 
            store_reg(s, rd, tmp);
9643
 
        } else {
9644
 
            /* store */
9645
 
            tmp = load_reg(s, rd);
9646
 
            gen_aa32_st32(tmp, addr, IS_USER(s));
9647
 
            tcg_temp_free_i32(tmp);
9648
 
        }
9649
 
        tcg_temp_free_i32(addr);
9650
 
        break;
9651
 
 
9652
 
    case 7:
9653
 
        /* load/store byte immediate offset */
9654
 
        rd = insn & 7;
9655
 
        rn = (insn >> 3) & 7;
9656
 
        addr = load_reg(s, rn);
9657
 
        val = (insn >> 6) & 0x1f;
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_ld8u(tmp, addr, IS_USER(s));
9664
 
            store_reg(s, rd, tmp);
9665
 
        } else {
9666
 
            /* store */
9667
 
            tmp = load_reg(s, rd);
9668
 
            gen_aa32_st8(tmp, addr, IS_USER(s));
9669
 
            tcg_temp_free_i32(tmp);
9670
 
        }
9671
 
        tcg_temp_free_i32(addr);
9672
 
        break;
9673
 
 
9674
 
    case 8:
9675
 
        /* load/store halfword immediate offset */
9676
 
        rd = insn & 7;
9677
 
        rn = (insn >> 3) & 7;
9678
 
        addr = load_reg(s, rn);
9679
 
        val = (insn >> 5) & 0x3e;
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_ld16u(tmp, addr, IS_USER(s));
9686
 
            store_reg(s, rd, tmp);
9687
 
        } else {
9688
 
            /* store */
9689
 
            tmp = load_reg(s, rd);
9690
 
            gen_aa32_st16(tmp, addr, IS_USER(s));
9691
 
            tcg_temp_free_i32(tmp);
9692
 
        }
9693
 
        tcg_temp_free_i32(addr);
9694
 
        break;
9695
 
 
9696
 
    case 9:
9697
 
        /* load/store from stack */
9698
 
        rd = (insn >> 8) & 7;
9699
 
        addr = load_reg(s, 13);
9700
 
        val = (insn & 0xff) * 4;
9701
 
        tcg_gen_addi_i32(addr, addr, val);
9702
 
 
9703
 
        if (insn & (1 << 11)) {
9704
 
            /* load */
9705
 
            tmp = tcg_temp_new_i32();
9706
 
            gen_aa32_ld32u(tmp, addr, IS_USER(s));
9707
 
            store_reg(s, rd, tmp);
9708
 
        } else {
9709
 
            /* store */
9710
 
            tmp = load_reg(s, rd);
9711
 
            gen_aa32_st32(tmp, addr, IS_USER(s));
9712
 
            tcg_temp_free_i32(tmp);
9713
 
        }
9714
 
        tcg_temp_free_i32(addr);
9715
 
        break;
9716
 
 
9717
 
    case 10:
9718
 
        /* add to high reg */
9719
 
        rd = (insn >> 8) & 7;
9720
 
        if (insn & (1 << 11)) {
9721
 
            /* SP */
9722
 
            tmp = load_reg(s, 13);
9723
 
        } else {
9724
 
            /* PC. bit 1 is ignored.  */
9725
 
            tmp = tcg_temp_new_i32();
9726
 
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9727
 
        }
9728
 
        val = (insn & 0xff) * 4;
9729
 
        tcg_gen_addi_i32(tmp, tmp, val);
9730
 
        store_reg(s, rd, tmp);
9731
 
        break;
9732
 
 
9733
 
    case 11:
9734
 
        /* misc */
9735
 
        op = (insn >> 8) & 0xf;
9736
 
        switch (op) {
9737
 
        case 0:
9738
 
            /* adjust stack pointer */
9739
 
            tmp = load_reg(s, 13);
9740
 
            val = (insn & 0x7f) * 4;
9741
 
            if (insn & (1 << 7))
9742
 
                val = -(int32_t)val;
9743
 
            tcg_gen_addi_i32(tmp, tmp, val);
9744
 
            store_reg(s, 13, tmp);
9745
 
            break;
9746
 
 
9747
 
        case 2: /* sign/zero extend.  */
9748
 
            ARCH(6);
9749
 
            rd = insn & 7;
9750
 
            rm = (insn >> 3) & 7;
9751
 
            tmp = load_reg(s, rm);
9752
 
            switch ((insn >> 6) & 3) {
9753
 
            case 0: gen_sxth(tmp); break;
9754
 
            case 1: gen_sxtb(tmp); break;
9755
 
            case 2: gen_uxth(tmp); break;
9756
 
            case 3: gen_uxtb(tmp); break;
9757
 
            }
9758
 
            store_reg(s, rd, tmp);
9759
 
            break;
9760
 
        case 4: case 5: case 0xc: case 0xd:
9761
 
            /* push/pop */
9762
 
            addr = load_reg(s, 13);
9763
 
            if (insn & (1 << 8))
9764
 
                offset = 4;
9765
 
            else
9766
 
                offset = 0;
9767
 
            for (i = 0; i < 8; i++) {
9768
 
                if (insn & (1 << i))
9769
 
                    offset += 4;
9770
 
            }
9771
 
            if ((insn & (1 << 11)) == 0) {
9772
 
                tcg_gen_addi_i32(addr, addr, -offset);
9773
 
            }
9774
 
            for (i = 0; i < 8; i++) {
9775
 
                if (insn & (1 << i)) {
9776
 
                    if (insn & (1 << 11)) {
9777
 
                        /* pop */
9778
 
                        tmp = tcg_temp_new_i32();
9779
 
                        gen_aa32_ld32u(tmp, addr, IS_USER(s));
9780
 
                        store_reg(s, i, tmp);
9781
 
                    } else {
9782
 
                        /* push */
9783
 
                        tmp = load_reg(s, i);
9784
 
                        gen_aa32_st32(tmp, addr, IS_USER(s));
9785
 
                        tcg_temp_free_i32(tmp);
9786
 
                    }
9787
 
                    /* advance to the next address.  */
9788
 
                    tcg_gen_addi_i32(addr, addr, 4);
9789
 
                }
9790
 
            }
9791
 
            TCGV_UNUSED_I32(tmp);
9792
 
            if (insn & (1 << 8)) {
9793
 
                if (insn & (1 << 11)) {
9794
 
                    /* pop pc */
9795
 
                    tmp = tcg_temp_new_i32();
9796
 
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
9797
 
                    /* don't set the pc until the rest of the instruction
9798
 
                       has completed */
9799
 
                } else {
9800
 
                    /* push lr */
9801
 
                    tmp = load_reg(s, 14);
9802
 
                    gen_aa32_st32(tmp, addr, IS_USER(s));
9803
 
                    tcg_temp_free_i32(tmp);
9804
 
                }
9805
 
                tcg_gen_addi_i32(addr, addr, 4);
9806
 
            }
9807
 
            if ((insn & (1 << 11)) == 0) {
9808
 
                tcg_gen_addi_i32(addr, addr, -offset);
9809
 
            }
9810
 
            /* write back the new stack pointer */
9811
 
            store_reg(s, 13, addr);
9812
 
            /* set the new PC value */
9813
 
            if ((insn & 0x0900) == 0x0900) {
9814
 
                store_reg_from_load(env, s, 15, tmp);
9815
 
            }
9816
 
            break;
9817
 
 
9818
 
        case 1: case 3: case 9: case 11: /* czb */
9819
 
            rm = insn & 7;
9820
 
            tmp = load_reg(s, rm);
9821
 
            s->condlabel = gen_new_label();
9822
 
            s->condjmp = 1;
9823
 
            if (insn & (1 << 11))
9824
 
                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9825
 
            else
9826
 
                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9827
 
            tcg_temp_free_i32(tmp);
9828
 
            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9829
 
            val = (uint32_t)s->pc + 2;
9830
 
            val += offset;
9831
 
            gen_jmp(s, val);
9832
 
            break;
9833
 
 
9834
 
        case 15: /* IT, nop-hint.  */
9835
 
            if ((insn & 0xf) == 0) {
9836
 
                gen_nop_hint(s, (insn >> 4) & 0xf);
9837
 
                break;
9838
 
            }
9839
 
            /* If Then.  */
9840
 
            s->condexec_cond = (insn >> 4) & 0xe;
9841
 
            s->condexec_mask = insn & 0x1f;
9842
 
            /* No actual code generated for this insn, just setup state.  */
9843
 
            break;
9844
 
 
9845
 
        case 0xe: /* bkpt */
9846
 
            ARCH(5);
9847
 
            gen_exception_insn(s, 2, EXCP_BKPT);
9848
 
            break;
9849
 
 
9850
 
        case 0xa: /* rev */
9851
 
            ARCH(6);
9852
 
            rn = (insn >> 3) & 0x7;
9853
 
            rd = insn & 0x7;
9854
 
            tmp = load_reg(s, rn);
9855
 
            switch ((insn >> 6) & 3) {
9856
 
            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9857
 
            case 1: gen_rev16(tmp); break;
9858
 
            case 3: gen_revsh(tmp); break;
9859
 
            default: goto illegal_op;
9860
 
            }
9861
 
            store_reg(s, rd, tmp);
9862
 
            break;
9863
 
 
9864
 
        case 6:
9865
 
            switch ((insn >> 5) & 7) {
9866
 
            case 2:
9867
 
                /* setend */
9868
 
                ARCH(6);
9869
 
                if (((insn >> 3) & 1) != s->bswap_code) {
9870
 
                    /* Dynamic endianness switching not implemented. */
9871
 
                    qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
9872
 
                    goto illegal_op;
9873
 
                }
9874
 
                break;
9875
 
            case 3:
9876
 
                /* cps */
9877
 
                ARCH(6);
9878
 
                if (IS_USER(s)) {
9879
 
                    break;
9880
 
                }
9881
 
                if (IS_M(env)) {
9882
 
                    tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9883
 
                    /* FAULTMASK */
9884
 
                    if (insn & 1) {
9885
 
                        addr = tcg_const_i32(19);
9886
 
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
9887
 
                        tcg_temp_free_i32(addr);
9888
 
                    }
9889
 
                    /* PRIMASK */
9890
 
                    if (insn & 2) {
9891
 
                        addr = tcg_const_i32(16);
9892
 
                        gen_helper_v7m_msr(cpu_env, addr, tmp);
9893
 
                        tcg_temp_free_i32(addr);
9894
 
                    }
9895
 
                    tcg_temp_free_i32(tmp);
9896
 
                    gen_lookup_tb(s);
9897
 
                } else {
9898
 
                    if (insn & (1 << 4)) {
9899
 
                        shift = CPSR_A | CPSR_I | CPSR_F;
9900
 
                    } else {
9901
 
                        shift = 0;
9902
 
                    }
9903
 
                    gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9904
 
                }
9905
 
                break;
9906
 
            default:
9907
 
                goto undef;
9908
 
            }
9909
 
            break;
9910
 
 
9911
 
        default:
9912
 
            goto undef;
9913
 
        }
9914
 
        break;
9915
 
 
9916
 
    case 12:
9917
 
    {
9918
 
        /* load/store multiple */
9919
 
        TCGv_i32 loaded_var;
9920
 
        TCGV_UNUSED_I32(loaded_var);
9921
 
        rn = (insn >> 8) & 0x7;
9922
 
        addr = load_reg(s, rn);
9923
 
        for (i = 0; i < 8; i++) {
9924
 
            if (insn & (1 << i)) {
9925
 
                if (insn & (1 << 11)) {
9926
 
                    /* load */
9927
 
                    tmp = tcg_temp_new_i32();
9928
 
                    gen_aa32_ld32u(tmp, addr, IS_USER(s));
9929
 
                    if (i == rn) {
9930
 
                        loaded_var = tmp;
9931
 
                    } else {
9932
 
                        store_reg(s, i, tmp);
9933
 
                    }
9934
 
                } else {
9935
 
                    /* store */
9936
 
                    tmp = load_reg(s, i);
9937
 
                    gen_aa32_st32(tmp, addr, IS_USER(s));
9938
 
                    tcg_temp_free_i32(tmp);
9939
 
                }
9940
 
                /* advance to the next address */
9941
 
                tcg_gen_addi_i32(addr, addr, 4);
9942
 
            }
9943
 
        }
9944
 
        if ((insn & (1 << rn)) == 0) {
9945
 
            /* base reg not in list: base register writeback */
9946
 
            store_reg(s, rn, addr);
9947
 
        } else {
9948
 
            /* base reg in list: if load, complete it now */
9949
 
            if (insn & (1 << 11)) {
9950
 
                store_reg(s, rn, loaded_var);
9951
 
            }
9952
 
            tcg_temp_free_i32(addr);
9953
 
        }
9954
 
        break;
9955
 
    }
9956
 
    case 13:
9957
 
        /* conditional branch or swi */
9958
 
        cond = (insn >> 8) & 0xf;
9959
 
        if (cond == 0xe)
9960
 
            goto undef;
9961
 
 
9962
 
        if (cond == 0xf) {
9963
 
            /* swi */
9964
 
            gen_set_pc_im(s, s->pc);
9965
 
            s->is_jmp = DISAS_SWI;
9966
 
            break;
9967
 
        }
9968
 
        /* generate a conditional jump to next instruction */
9969
 
        s->condlabel = gen_new_label();
9970
 
        gen_test_cc(cond ^ 1, s->condlabel);
9971
 
        s->condjmp = 1;
9972
 
 
9973
 
        /* jump to the offset */
9974
 
        val = (uint32_t)s->pc + 2;
9975
 
        offset = ((int32_t)insn << 24) >> 24;
9976
 
        val += offset << 1;
9977
 
        gen_jmp(s, val);
9978
 
        break;
9979
 
 
9980
 
    case 14:
9981
 
        if (insn & (1 << 11)) {
9982
 
            if (disas_thumb2_insn(env, s, insn))
9983
 
              goto undef32;
9984
 
            break;
9985
 
        }
9986
 
        /* unconditional branch */
9987
 
        val = (uint32_t)s->pc;
9988
 
        offset = ((int32_t)insn << 21) >> 21;
9989
 
        val += (offset << 1) + 2;
9990
 
        gen_jmp(s, val);
9991
 
        break;
9992
 
 
9993
 
    case 15:
9994
 
        if (disas_thumb2_insn(env, s, insn))
9995
 
            goto undef32;
9996
 
        break;
9997
 
    }
9998
 
    return;
9999
 
undef32:
10000
 
    gen_exception_insn(s, 4, EXCP_UDEF);
10001
 
    return;
10002
 
illegal_op:
10003
 
undef:
10004
 
    gen_exception_insn(s, 2, EXCP_UDEF);
10005
 
}
10006
 
 
10007
 
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10008
 
   basic block 'tb'. If search_pc is TRUE, also generate PC
10009
 
   information for each intermediate instruction. */
10010
 
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10011
 
                                                  TranslationBlock *tb,
10012
 
                                                  bool search_pc)
10013
 
{
10014
 
    CPUState *cs = CPU(cpu);
10015
 
    CPUARMState *env = &cpu->env;
10016
 
    DisasContext dc1, *dc = &dc1;
10017
 
    CPUBreakpoint *bp;
10018
 
    uint16_t *gen_opc_end;
10019
 
    int j, lj;
10020
 
    target_ulong pc_start;
10021
 
    target_ulong next_page_start;
10022
 
    int num_insns;
10023
 
    int max_insns;
10024
 
 
10025
 
    /* generate intermediate code */
10026
 
    pc_start = tb->pc;
10027
 
 
10028
 
    dc->tb = tb;
10029
 
 
10030
 
    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10031
 
 
10032
 
    dc->is_jmp = DISAS_NEXT;
10033
 
    dc->pc = pc_start;
10034
 
    dc->singlestep_enabled = cs->singlestep_enabled;
10035
 
    dc->condjmp = 0;
10036
 
 
10037
 
    if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10038
 
        dc->aarch64 = 1;
10039
 
        dc->thumb = 0;
10040
 
        dc->bswap_code = 0;
10041
 
        dc->condexec_mask = 0;
10042
 
        dc->condexec_cond = 0;
10043
 
#if !defined(CONFIG_USER_ONLY)
10044
 
        dc->user = 0;
10045
 
#endif
10046
 
        dc->vfp_enabled = 0;
10047
 
        dc->vec_len = 0;
10048
 
        dc->vec_stride = 0;
10049
 
    } else {
10050
 
        dc->aarch64 = 0;
10051
 
        dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10052
 
        dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10053
 
        dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10054
 
        dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10055
 
#if !defined(CONFIG_USER_ONLY)
10056
 
        dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10057
 
#endif
10058
 
        dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10059
 
        dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10060
 
        dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10061
 
    }
10062
 
    cpu_F0s = tcg_temp_new_i32();
10063
 
    cpu_F1s = tcg_temp_new_i32();
10064
 
    cpu_F0d = tcg_temp_new_i64();
10065
 
    cpu_F1d = tcg_temp_new_i64();
10066
 
    cpu_V0 = cpu_F0d;
10067
 
    cpu_V1 = cpu_F1d;
10068
 
    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
10069
 
    cpu_M0 = tcg_temp_new_i64();
10070
 
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10071
 
    lj = -1;
10072
 
    num_insns = 0;
10073
 
    max_insns = tb->cflags & CF_COUNT_MASK;
10074
 
    if (max_insns == 0)
10075
 
        max_insns = CF_COUNT_MASK;
10076
 
 
10077
 
    gen_tb_start();
10078
 
 
10079
 
    tcg_clear_temp_count();
10080
 
 
10081
 
    /* A note on handling of the condexec (IT) bits:
10082
 
     *
10083
 
     * We want to avoid the overhead of having to write the updated condexec
10084
 
     * bits back to the CPUARMState for every instruction in an IT block. So:
10085
 
     * (1) if the condexec bits are not already zero then we write
10086
 
     * zero back into the CPUARMState now. This avoids complications trying
10087
 
     * to do it at the end of the block. (For example if we don't do this
10088
 
     * it's hard to identify whether we can safely skip writing condexec
10089
 
     * at the end of the TB, which we definitely want to do for the case
10090
 
     * where a TB doesn't do anything with the IT state at all.)
10091
 
     * (2) if we are going to leave the TB then we call gen_set_condexec()
10092
 
     * which will write the correct value into CPUARMState if zero is wrong.
10093
 
     * This is done both for leaving the TB at the end, and for leaving
10094
 
     * it because of an exception we know will happen, which is done in
10095
 
     * gen_exception_insn(). The latter is necessary because we need to
10096
 
     * leave the TB with the PC/IT state just prior to execution of the
10097
 
     * instruction which caused the exception.
10098
 
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10099
 
     * then the CPUARMState will be wrong and we need to reset it.
10100
 
     * This is handled in the same way as restoration of the
10101
 
     * PC in these situations: we will be called again with search_pc=1
10102
 
     * and generate a mapping of the condexec bits for each PC in
10103
 
     * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10104
 
     * this to restore the condexec bits.
10105
 
     *
10106
 
     * Note that there are no instructions which can read the condexec
10107
 
     * bits, and none which can write non-static values to them, so
10108
 
     * we don't need to care about whether CPUARMState is correct in the
10109
 
     * middle of a TB.
10110
 
     */
10111
 
 
10112
 
    /* Reset the conditional execution bits immediately. This avoids
10113
 
       complications trying to do it at the end of the block.  */
10114
 
    if (dc->condexec_mask || dc->condexec_cond)
10115
 
      {
10116
 
        TCGv_i32 tmp = tcg_temp_new_i32();
10117
 
        tcg_gen_movi_i32(tmp, 0);
10118
 
        store_cpu_field(tmp, condexec_bits);
10119
 
      }
10120
 
    do {
10121
 
#ifdef CONFIG_USER_ONLY
10122
 
        /* Intercept jump to the magic kernel page.  */
10123
 
        if (!dc->aarch64 && dc->pc >= 0xffff0000) {
10124
 
            /* We always get here via a jump, so know we are not in a
10125
 
               conditional execution block.  */
10126
 
            gen_exception(EXCP_KERNEL_TRAP);
10127
 
            dc->is_jmp = DISAS_UPDATE;
10128
 
            break;
10129
 
        }
10130
 
#else
10131
 
        if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10132
 
            /* We always get here via a jump, so know we are not in a
10133
 
               conditional execution block.  */
10134
 
            gen_exception(EXCP_EXCEPTION_EXIT);
10135
 
            dc->is_jmp = DISAS_UPDATE;
10136
 
            break;
10137
 
        }
10138
 
#endif
10139
 
 
10140
 
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10141
 
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10142
 
                if (bp->pc == dc->pc) {
10143
 
                    gen_exception_insn(dc, 0, EXCP_DEBUG);
10144
 
                    /* Advance PC so that clearing the breakpoint will
10145
 
                       invalidate this TB.  */
10146
 
                    dc->pc += 2;
10147
 
                    goto done_generating;
10148
 
                }
10149
 
            }
10150
 
        }
10151
 
        if (search_pc) {
10152
 
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10153
 
            if (lj < j) {
10154
 
                lj++;
10155
 
                while (lj < j)
10156
 
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
10157
 
            }
10158
 
            tcg_ctx.gen_opc_pc[lj] = dc->pc;
10159
 
            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10160
 
            tcg_ctx.gen_opc_instr_start[lj] = 1;
10161
 
            tcg_ctx.gen_opc_icount[lj] = num_insns;
10162
 
        }
10163
 
 
10164
 
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10165
 
            gen_io_start();
10166
 
 
10167
 
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10168
 
            tcg_gen_debug_insn_start(dc->pc);
10169
 
        }
10170
 
 
10171
 
        if (dc->aarch64) {
10172
 
            disas_a64_insn(env, dc);
10173
 
        } else if (dc->thumb) {
10174
 
            disas_thumb_insn(env, dc);
10175
 
            if (dc->condexec_mask) {
10176
 
                dc->condexec_cond = (dc->condexec_cond & 0xe)
10177
 
                                   | ((dc->condexec_mask >> 4) & 1);
10178
 
                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10179
 
                if (dc->condexec_mask == 0) {
10180
 
                    dc->condexec_cond = 0;
10181
 
                }
10182
 
            }
10183
 
        } else {
10184
 
            disas_arm_insn(env, dc);
10185
 
        }
10186
 
 
10187
 
        if (dc->condjmp && !dc->is_jmp) {
10188
 
            gen_set_label(dc->condlabel);
10189
 
            dc->condjmp = 0;
10190
 
        }
10191
 
 
10192
 
        if (tcg_check_temp_count()) {
10193
 
            fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10194
 
                    dc->pc);
10195
 
        }
10196
 
 
10197
 
        /* Translation stops when a conditional branch is encountered.
10198
 
         * Otherwise the subsequent code could get translated several times.
10199
 
         * Also stop translation when a page boundary is reached.  This
10200
 
         * ensures prefetch aborts occur at the right place.  */
10201
 
        num_insns ++;
10202
 
    } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10203
 
             !cs->singlestep_enabled &&
10204
 
             !singlestep &&
10205
 
             dc->pc < next_page_start &&
10206
 
             num_insns < max_insns);
10207
 
 
10208
 
    if (tb->cflags & CF_LAST_IO) {
10209
 
        if (dc->condjmp) {
10210
 
            /* FIXME:  This can theoretically happen with self-modifying
10211
 
               code.  */
10212
 
            cpu_abort(env, "IO on conditional branch instruction");
10213
 
        }
10214
 
        gen_io_end();
10215
 
    }
10216
 
 
10217
 
    /* At this stage dc->condjmp will only be set when the skipped
10218
 
       instruction was a conditional branch or trap, and the PC has
10219
 
       already been written.  */
10220
 
    if (unlikely(cs->singlestep_enabled)) {
10221
 
        /* Make sure the pc is updated, and raise a debug exception.  */
10222
 
        if (dc->condjmp) {
10223
 
            gen_set_condexec(dc);
10224
 
            if (dc->is_jmp == DISAS_SWI) {
10225
 
                gen_exception(EXCP_SWI);
10226
 
            } else if (dc->is_jmp == DISAS_SMC) {
10227
 
                gen_exception(EXCP_SMC);
10228
 
            } else {
10229
 
                gen_exception(EXCP_DEBUG);
10230
 
            }
10231
 
            gen_set_label(dc->condlabel);
10232
 
        }
10233
 
        if (dc->condjmp || !dc->is_jmp) {
10234
 
            gen_set_pc_im(dc, dc->pc);
10235
 
            dc->condjmp = 0;
10236
 
        }
10237
 
        gen_set_condexec(dc);
10238
 
        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10239
 
            gen_exception(EXCP_SWI);
10240
 
        } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10241
 
            gen_exception(EXCP_SMC);
10242
 
        } else {
10243
 
            /* FIXME: Single stepping a WFI insn will not halt
10244
 
               the CPU.  */
10245
 
            gen_exception(EXCP_DEBUG);
10246
 
        }
10247
 
    } else {
10248
 
        /* While branches must always occur at the end of an IT block,
10249
 
           there are a few other things that can cause us to terminate
10250
 
           the TB in the middle of an IT block:
10251
 
            - Exception generating instructions (bkpt, swi, undefined).
10252
 
            - Page boundaries.
10253
 
            - Hardware watchpoints.
10254
 
           Hardware breakpoints have already been handled and skip this code.
10255
 
         */
10256
 
        gen_set_condexec(dc);
10257
 
        switch(dc->is_jmp) {
10258
 
        case DISAS_NEXT:
10259
 
            gen_goto_tb(dc, 1, dc->pc);
10260
 
            break;
10261
 
        default:
10262
 
        case DISAS_JUMP:
10263
 
        case DISAS_UPDATE:
10264
 
            /* indicate that the hash table must be used to find the next TB */
10265
 
            tcg_gen_exit_tb(0);
10266
 
            break;
10267
 
        case DISAS_TB_JUMP:
10268
 
            /* nothing more to generate */
10269
 
            break;
10270
 
        case DISAS_WFI:
10271
 
            gen_helper_wfi(cpu_env);
10272
 
            break;
10273
 
        case DISAS_SWI:
10274
 
            gen_exception(EXCP_SWI);
10275
 
            break;
10276
 
        case DISAS_SMC:
10277
 
            gen_exception(EXCP_SMC);
10278
 
            break;
10279
 
        }
10280
 
        if (dc->condjmp) {
10281
 
            gen_set_label(dc->condlabel);
10282
 
            gen_set_condexec(dc);
10283
 
            gen_goto_tb(dc, 1, dc->pc);
10284
 
            dc->condjmp = 0;
10285
 
        }
10286
 
    }
10287
 
 
10288
 
done_generating:
10289
 
    gen_tb_end(tb, num_insns);
10290
 
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10291
 
 
10292
 
#ifdef DEBUG_DISAS
10293
 
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10294
 
        qemu_log("----------------\n");
10295
 
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
10296
 
        log_target_disas(env, pc_start, dc->pc - pc_start,
10297
 
                         dc->thumb | (dc->bswap_code << 1));
10298
 
        qemu_log("\n");
10299
 
    }
10300
 
#endif
10301
 
    if (search_pc) {
10302
 
        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10303
 
        lj++;
10304
 
        while (lj <= j)
10305
 
            tcg_ctx.gen_opc_instr_start[lj++] = 0;
10306
 
    } else {
10307
 
        tb->size = dc->pc - pc_start;
10308
 
        tb->icount = num_insns;
10309
 
    }
10310
 
}
10311
 
 
10312
 
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10313
 
{
10314
 
    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10315
 
}
10316
 
 
10317
 
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10318
 
{
10319
 
    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10320
 
}
10321
 
 
10322
 
static const char *cpu_mode_names[16] = {
10323
 
  "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10324
 
  "???", "???", "???", "und", "???", "???", "???", "sys"
10325
 
};
10326
 
 
10327
 
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10328
 
                        int flags)
10329
 
{
10330
 
    ARMCPU *cpu = ARM_CPU(cs);
10331
 
    CPUARMState *env = &cpu->env;
10332
 
    int i;
10333
 
    uint32_t psr;
10334
 
 
10335
 
    for(i=0;i<16;i++) {
10336
 
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10337
 
        if ((i % 4) == 3)
10338
 
            cpu_fprintf(f, "\n");
10339
 
        else
10340
 
            cpu_fprintf(f, " ");
10341
 
    }
10342
 
    psr = cpsr_read(env);
10343
 
    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10344
 
                psr,
10345
 
                psr & (1 << 31) ? 'N' : '-',
10346
 
                psr & (1 << 30) ? 'Z' : '-',
10347
 
                psr & (1 << 29) ? 'C' : '-',
10348
 
                psr & (1 << 28) ? 'V' : '-',
10349
 
                psr & CPSR_T ? 'T' : 'A',
10350
 
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10351
 
 
10352
 
    if (flags & CPU_DUMP_FPU) {
10353
 
        int numvfpregs = 0;
10354
 
        if (arm_feature(env, ARM_FEATURE_VFP)) {
10355
 
            numvfpregs += 16;
10356
 
        }
10357
 
        if (arm_feature(env, ARM_FEATURE_VFP3)) {
10358
 
            numvfpregs += 16;
10359
 
        }
10360
 
        for (i = 0; i < numvfpregs; i++) {
10361
 
            uint64_t v = float64_val(env->vfp.regs[i]);
10362
 
            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10363
 
                        i * 2, (uint32_t)v,
10364
 
                        i * 2 + 1, (uint32_t)(v >> 32),
10365
 
                        i, v);
10366
 
        }
10367
 
        cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10368
 
    }
10369
 
}
10370
 
 
10371
 
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10372
 
{
10373
 
    if (is_a64(env)) {
10374
 
        env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10375
 
    } else {
10376
 
        env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10377
 
    }
10378
 
    env->condexec_bits = gen_opc_condexec_bits[pc_pos];
10379
 
}