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

« back to all changes in this revision

Viewing changes to .pc/ubuntu/arm64/0103-target-arm-Rename-A32-VFP-conversion-helpers.patch/target-arm/translate.c

  • Committer: Package Import Robot
  • Author(s): dann frazier
  • Date: 2014-02-11 15:41:53 UTC
  • Revision ID: package-import@ubuntu.com-20140211154153-2d001tf0ium08u81
Tags: 1.7.0+dfsg-3ubuntu2
* Backport changes to enable qemu-user-static support for aarch64
* debian/control: add ppc64el to Architectures
* debian/rules: only install qemu-system-aarch64 on arm64.
  Fixes a FTBFS  when built twice in a row on non-arm64 due to a stale
  debian/qemu-system-aarch64 directory

Show diffs side-by-side

added added

removed removed

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