~ubuntu-branches/ubuntu/vivid/qemu/vivid

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-25 22:31:43 UTC
  • mfrom: (1.8.5)
  • Revision ID: package-import@ubuntu.com-20140225223143-odhqxfc60wxrjl15
Tags: 2.0.0~rc1+dfsg-0ubuntu1
* Merge 2.0.0-rc1
* debian/rules: consolidate ppc filter entries.
* Move qemu-system-arch64 into qemu-system-arm
* debian/patches/define-trusty-machine-type.patch: define a trusty machine
  type, currently the same as pc-i440fx-2.0, to put is in a better position
  to enable live migrations from trusty onward.  (LP: #1294823)
* debian/control: build-dep on libfdt >= 1.4.0  (LP: #1295072)
* Merge latest upstream git to commit dc9528f
* Debian/rules:
  - remove -enable-uname-release=2.6.32
  - don't make the aarch64 target Ubuntu-specific.
* Remove patches which are now upstream:
  - fix-smb-security-share.patch
  - slirp-smb-redirect-port-445-too.patch 
  - linux-user-Implement-sendmmsg-syscall.patch (better version is upstream)
  - signal-added-a-wrapper-for-sigprocmask-function.patch
  - ubuntu/signal-sigsegv-protection-on-do_sigprocmask.patch
  - ubuntu/Don-t-block-SIGSEGV-at-more-places.patch
  - ubuntu/ppc-force-cpu-threads-count-to-be-power-of-2.patch
* add link for /usr/share/qemu/bios-256k.bin
* Remove all linaro patches.
* Remove all arm64/ patches.  Many but not all are upstream.
* Remove CVE-2013-4377.patch which is upstream.
* debian/control-in: don't make qemu-system-aarch64 ubuntu-specific

Show diffs side-by-side

added added

removed removed

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