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

« back to all changes in this revision

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