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

« back to all changes in this revision

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