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

« back to all changes in this revision

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