4
* Copyright (c) 2003 Fabrice Bellard
5
* Copyright (c) 2005-2007 CodeSourcery
6
* Copyright (c) 2007 OpenedHand, Ltd.
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.
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.
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/>.
28
#include "disas/disas.h"
31
#include "qemu/bitops.h"
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)
48
#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50
#include "translate.h"
51
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
53
/* These instructions trap after executing, so defer them until after the
54
conditional execution state has been updated. */
59
#if defined(CONFIG_USER_ONLY)
62
#define IS_USER(s) (s->user)
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;
77
/* FIXME: These should be removed. */
78
static TCGv_i32 cpu_F0s, cpu_F1s;
79
static TCGv_i64 cpu_F0d, cpu_F1d;
81
#include "exec/gen-icount.h"
83
static const char *regnames[] =
84
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
85
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
87
/* initialize TCG globals. */
88
void arm_translate_init(void)
92
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
94
for (i = 0; i < 16; i++) {
95
cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
96
offsetof(CPUARMState, regs[i]),
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");
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");
115
a64_translate_init();
118
static inline TCGv_i32 load_cpu_offset(int offset)
120
TCGv_i32 tmp = tcg_temp_new_i32();
121
tcg_gen_ld_i32(tmp, cpu_env, offset);
125
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
127
static inline void store_cpu_offset(TCGv_i32 var, int offset)
129
tcg_gen_st_i32(var, cpu_env, offset);
130
tcg_temp_free_i32(var);
133
#define store_cpu_field(var, name) \
134
store_cpu_offset(var, offsetof(CPUARMState, name))
136
/* Set a variable to the value of a CPU register. */
137
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
141
/* normally, since we updated PC, we need only to add one insn */
143
addr = (long)s->pc + 2;
145
addr = (long)s->pc + 4;
146
tcg_gen_movi_i32(var, addr);
148
tcg_gen_mov_i32(var, cpu_R[reg]);
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)
155
TCGv_i32 tmp = tcg_temp_new_i32();
156
load_reg_var(s, tmp, reg);
160
/* Set a CPU register. The source must be a temporary and will be
162
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
165
tcg_gen_andi_i32(var, var, ~1);
166
s->is_jmp = DISAS_JUMP;
168
tcg_gen_mov_i32(cpu_R[reg], var);
169
tcg_temp_free_i32(var);
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)
178
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
179
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
182
static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
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);
188
/* Set NZCV flags from the high 4 bits of var. */
189
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
191
static void gen_exception(int excp)
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);
199
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
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);
214
/* Byteswap each halfword. */
215
static void gen_rev16(TCGv_i32 var)
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);
226
/* Byteswap low halfword and sign extend. */
227
static void gen_revsh(TCGv_i32 var)
229
tcg_gen_ext16u_i32(var, var);
230
tcg_gen_bswap16_i32(var, var);
231
tcg_gen_ext16s_i32(var, var);
234
/* Unsigned bitfield extract. */
235
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
238
tcg_gen_shri_i32(var, var, shift);
239
tcg_gen_andi_i32(var, var, mask);
242
/* Signed bitfield extract. */
243
static void gen_sbfx(TCGv_i32 var, int shift, int width)
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);
257
/* Return (b << 32) + a. Mark inputs as dead */
258
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
260
TCGv_i64 tmp64 = tcg_temp_new_i64();
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);
267
tcg_temp_free_i64(tmp64);
271
/* Return (b << 32) - a. Mark inputs as dead. */
272
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
274
TCGv_i64 tmp64 = tcg_temp_new_i64();
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);
281
tcg_temp_free_i64(tmp64);
285
/* 32x32->64 multiply. Marks inputs as dead. */
286
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
288
TCGv_i32 lo = tcg_temp_new_i32();
289
TCGv_i32 hi = tcg_temp_new_i32();
292
tcg_gen_mulu2_i32(lo, hi, a, b);
293
tcg_temp_free_i32(a);
294
tcg_temp_free_i32(b);
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);
304
static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
306
TCGv_i32 lo = tcg_temp_new_i32();
307
TCGv_i32 hi = tcg_temp_new_i32();
310
tcg_gen_muls2_i32(lo, hi, a, b);
311
tcg_temp_free_i32(a);
312
tcg_temp_free_i32(b);
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);
322
/* Swap low and high halfwords. */
323
static void gen_swap_half(TCGv_i32 var)
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);
332
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
333
tmp = (t0 ^ t1) & 0x8000;
336
t0 = (t0 + t1) ^ tmp;
339
static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
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);
352
/* Set CF to the top bit of var. */
353
static void gen_set_CF_bit31(TCGv_i32 var)
355
tcg_gen_shri_i32(cpu_CF, var, 31);
358
/* Set N and Z flags from var. */
359
static inline void gen_logic_CC(TCGv_i32 var)
361
tcg_gen_mov_i32(cpu_NF, var);
362
tcg_gen_mov_i32(cpu_ZF, var);
366
static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
368
tcg_gen_add_i32(t0, t0, t1);
369
tcg_gen_add_i32(t0, t0, cpu_CF);
372
/* dest = T0 + T1 + CF. */
373
static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
375
tcg_gen_add_i32(dest, t0, t1);
376
tcg_gen_add_i32(dest, dest, cpu_CF);
379
/* dest = T0 - T1 + CF - 1. */
380
static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
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);
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)
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);
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)
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);
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);
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);
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)
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);
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)
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);
453
#define GEN_SHIFT(name) \
454
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
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); \
472
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
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);
484
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
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);
494
static void shifter_out_im(TCGv_i32 var, int shift)
497
tcg_gen_andi_i32(cpu_CF, var, 1);
499
tcg_gen_shri_i32(cpu_CF, var, shift);
501
tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
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)
514
shifter_out_im(var, 32 - shift);
515
tcg_gen_shli_i32(var, var, shift);
521
tcg_gen_shri_i32(cpu_CF, var, 31);
523
tcg_gen_movi_i32(var, 0);
526
shifter_out_im(var, shift - 1);
527
tcg_gen_shri_i32(var, var, shift);
534
shifter_out_im(var, shift - 1);
537
tcg_gen_sari_i32(var, var, shift);
539
case 3: /* ROR/RRX */
542
shifter_out_im(var, shift - 1);
543
tcg_gen_rotri_i32(var, var, shift); break;
545
TCGv_i32 tmp = tcg_temp_new_i32();
546
tcg_gen_shli_i32(tmp, cpu_CF, 31);
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);
556
static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
557
TCGv_i32 shift, int flags)
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;
569
gen_shl(var, var, shift);
572
gen_shr(var, var, shift);
575
gen_sar(var, var, shift);
577
case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
578
tcg_gen_rotr_i32(var, var, shift); break;
581
tcg_temp_free_i32(shift);
584
#define PAS_OP(pfx) \
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; \
593
static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
598
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
600
tmp = tcg_temp_new_ptr();
601
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
603
tcg_temp_free_ptr(tmp);
606
tmp = tcg_temp_new_ptr();
607
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
609
tcg_temp_free_ptr(tmp);
611
#undef gen_pas_helper
612
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
625
#undef gen_pas_helper
630
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
631
#define PAS_OP(pfx) \
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; \
640
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
645
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
647
tmp = tcg_temp_new_ptr();
648
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
650
tcg_temp_free_ptr(tmp);
653
tmp = tcg_temp_new_ptr();
654
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
656
tcg_temp_free_ptr(tmp);
658
#undef gen_pas_helper
659
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
672
#undef gen_pas_helper
678
* generate a conditional branch based on ARM condition code cc.
679
* This is common between ARM and Aarch64 targets.
681
void arm_gen_test_cc(int cc, int label)
688
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
691
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
694
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
697
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
700
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
703
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
706
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
709
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
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);
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);
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);
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);
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);
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);
750
fprintf(stderr, "Bad condition code 0x%x\n", cc);
755
static const uint8_t table_logic_cc[16] = {
774
/* Set PC and Thumb state from an immediate address. */
775
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
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);
786
tcg_gen_movi_i32(cpu_R[15], addr & ~1);
789
/* Set PC and Thumb state from var. var is marked as dead. */
790
static inline void gen_bx(DisasContext *s, TCGv_i32 var)
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);
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)
804
if (reg == 15 && ENABLE_ARCH_7) {
807
store_reg(s, reg, var);
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)
818
if (reg == 15 && ENABLE_ARCH_5) {
821
store_reg(s, reg, var);
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.
832
#if TARGET_LONG_BITS == 32
834
#define DO_GEN_LD(SUFF, OPC) \
835
static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
837
tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
840
#define DO_GEN_ST(SUFF, OPC) \
841
static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
843
tcg_gen_qemu_st_i32(val, addr, index, OPC); \
846
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
848
tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
851
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
853
tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
858
#define DO_GEN_LD(SUFF, OPC) \
859
static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
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); \
867
#define DO_GEN_ST(SUFF, OPC) \
868
static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
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); \
876
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
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);
884
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
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);
896
DO_GEN_LD(16s, MO_TESW)
897
DO_GEN_LD(16u, MO_TEUW)
898
DO_GEN_LD(32u, MO_TEUL)
900
DO_GEN_ST(16, MO_TEUW)
901
DO_GEN_ST(32, MO_TEUL)
903
static inline void gen_smc(CPUARMState *env, DisasContext *s)
905
tcg_gen_movi_i32(cpu_R[15], s->pc);
906
s->is_jmp = DISAS_SMC;
909
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
911
tcg_gen_movi_i32(cpu_R[15], val);
914
/* Force a TB lookup after an instruction that changes the CPU state. */
915
static inline void gen_lookup_tb(DisasContext *s)
917
tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
918
s->is_jmp = DISAS_UPDATE;
921
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
924
int val, rm, shift, shiftop;
927
if (!(insn & (1 << 25))) {
930
if (!(insn & (1 << 23)))
933
tcg_gen_addi_i32(var, var, val);
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);
944
tcg_gen_add_i32(var, var, offset);
945
tcg_temp_free_i32(offset);
949
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
950
int extra, TCGv_i32 var)
955
if (insn & (1 << 22)) {
957
val = (insn & 0xf) | ((insn >> 4) & 0xf0);
958
if (!(insn & (1 << 23)))
962
tcg_gen_addi_i32(var, var, val);
966
tcg_gen_addi_i32(var, var, extra);
968
offset = load_reg(s, rm);
969
if (!(insn & (1 << 23)))
970
tcg_gen_sub_i32(var, var, offset);
972
tcg_gen_add_i32(var, var, offset);
973
tcg_temp_free_i32(offset);
977
static TCGv_ptr get_fpstatus_ptr(int neon)
979
TCGv_ptr statusptr = tcg_temp_new_ptr();
982
offset = offsetof(CPUARMState, vfp.standard_fp_status);
984
offset = offsetof(CPUARMState, vfp.fp_status);
986
tcg_gen_addi_ptr(statusptr, cpu_env, offset);
990
#define VFP_OP2(name) \
991
static inline void gen_vfp_##name(int dp) \
993
TCGv_ptr fpst = get_fpstatus_ptr(0); \
995
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
997
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
999
tcg_temp_free_ptr(fpst); \
1009
static inline void gen_vfp_F1_mul(int dp)
1011
/* Like gen_vfp_mul() but put result in F1 */
1012
TCGv_ptr fpst = get_fpstatus_ptr(0);
1014
gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1016
gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1018
tcg_temp_free_ptr(fpst);
1021
static inline void gen_vfp_F1_neg(int dp)
1023
/* Like gen_vfp_neg() but put result in F1 */
1025
gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1027
gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1031
static inline void gen_vfp_abs(int dp)
1034
gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1036
gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1039
static inline void gen_vfp_neg(int dp)
1042
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1044
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1047
static inline void gen_vfp_sqrt(int dp)
1050
gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1052
gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1055
static inline void gen_vfp_cmp(int dp)
1058
gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1060
gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1063
static inline void gen_vfp_cmpe(int dp)
1066
gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1068
gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1071
static inline void gen_vfp_F1_ld0(int dp)
1074
tcg_gen_movi_i64(cpu_F1d, 0);
1076
tcg_gen_movi_i32(cpu_F1s, 0);
1079
#define VFP_GEN_ITOF(name) \
1080
static inline void gen_vfp_##name(int dp, int neon) \
1082
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1084
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1086
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1088
tcg_temp_free_ptr(statusptr); \
1095
#define VFP_GEN_FTOI(name) \
1096
static inline void gen_vfp_##name(int dp, int neon) \
1098
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1100
gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1102
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1104
tcg_temp_free_ptr(statusptr); \
1113
#define VFP_GEN_FIX(name) \
1114
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1116
TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1117
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1119
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1121
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1123
tcg_temp_free_i32(tmp_shift); \
1124
tcg_temp_free_ptr(statusptr); \
1136
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1139
gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1141
gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1145
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1148
gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1150
gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1155
vfp_reg_offset (int dp, int reg)
1158
return offsetof(CPUARMState, vfp.regs[reg]);
1160
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1161
+ offsetof(CPU_DoubleU, l.upper);
1163
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1164
+ offsetof(CPU_DoubleU, l.lower);
1168
/* Return the offset of a 32-bit piece of a NEON register.
1169
zero is the least significant end of the register. */
1171
neon_reg_offset (int reg, int n)
1175
return vfp_reg_offset(0, sreg);
1178
static TCGv_i32 neon_load_reg(int reg, int pass)
1180
TCGv_i32 tmp = tcg_temp_new_i32();
1181
tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1185
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1187
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1188
tcg_temp_free_i32(var);
1191
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1193
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1196
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1198
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1201
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1202
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1203
#define tcg_gen_st_f32 tcg_gen_st_i32
1204
#define tcg_gen_st_f64 tcg_gen_st_i64
1206
static inline void gen_mov_F0_vreg(int dp, int reg)
1209
tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1211
tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1214
static inline void gen_mov_F1_vreg(int dp, int reg)
1217
tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1219
tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1222
static inline void gen_mov_vreg_F0(int dp, int reg)
1225
tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1227
tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1230
#define ARM_CP_RW_BIT (1 << 20)
1232
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1234
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1237
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1239
tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1242
static inline TCGv_i32 iwmmxt_load_creg(int reg)
1244
TCGv_i32 var = tcg_temp_new_i32();
1245
tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1249
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1251
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1252
tcg_temp_free_i32(var);
1255
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1257
iwmmxt_store_reg(cpu_M0, rn);
1260
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1262
iwmmxt_load_reg(cpu_M0, rn);
1265
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1267
iwmmxt_load_reg(cpu_V1, rn);
1268
tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1271
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1273
iwmmxt_load_reg(cpu_V1, rn);
1274
tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1277
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1279
iwmmxt_load_reg(cpu_V1, rn);
1280
tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1283
#define IWMMXT_OP(name) \
1284
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1286
iwmmxt_load_reg(cpu_V1, rn); \
1287
gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1290
#define IWMMXT_OP_ENV(name) \
1291
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1293
iwmmxt_load_reg(cpu_V1, rn); \
1294
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1297
#define IWMMXT_OP_ENV_SIZE(name) \
1298
IWMMXT_OP_ENV(name##b) \
1299
IWMMXT_OP_ENV(name##w) \
1300
IWMMXT_OP_ENV(name##l)
1302
#define IWMMXT_OP_ENV1(name) \
1303
static inline void gen_op_iwmmxt_##name##_M0(void) \
1305
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1319
IWMMXT_OP_ENV_SIZE(unpackl)
1320
IWMMXT_OP_ENV_SIZE(unpackh)
1322
IWMMXT_OP_ENV1(unpacklub)
1323
IWMMXT_OP_ENV1(unpackluw)
1324
IWMMXT_OP_ENV1(unpacklul)
1325
IWMMXT_OP_ENV1(unpackhub)
1326
IWMMXT_OP_ENV1(unpackhuw)
1327
IWMMXT_OP_ENV1(unpackhul)
1328
IWMMXT_OP_ENV1(unpacklsb)
1329
IWMMXT_OP_ENV1(unpacklsw)
1330
IWMMXT_OP_ENV1(unpacklsl)
1331
IWMMXT_OP_ENV1(unpackhsb)
1332
IWMMXT_OP_ENV1(unpackhsw)
1333
IWMMXT_OP_ENV1(unpackhsl)
1335
IWMMXT_OP_ENV_SIZE(cmpeq)
1336
IWMMXT_OP_ENV_SIZE(cmpgtu)
1337
IWMMXT_OP_ENV_SIZE(cmpgts)
1339
IWMMXT_OP_ENV_SIZE(mins)
1340
IWMMXT_OP_ENV_SIZE(minu)
1341
IWMMXT_OP_ENV_SIZE(maxs)
1342
IWMMXT_OP_ENV_SIZE(maxu)
1344
IWMMXT_OP_ENV_SIZE(subn)
1345
IWMMXT_OP_ENV_SIZE(addn)
1346
IWMMXT_OP_ENV_SIZE(subu)
1347
IWMMXT_OP_ENV_SIZE(addu)
1348
IWMMXT_OP_ENV_SIZE(subs)
1349
IWMMXT_OP_ENV_SIZE(adds)
1351
IWMMXT_OP_ENV(avgb0)
1352
IWMMXT_OP_ENV(avgb1)
1353
IWMMXT_OP_ENV(avgw0)
1354
IWMMXT_OP_ENV(avgw1)
1358
IWMMXT_OP_ENV(packuw)
1359
IWMMXT_OP_ENV(packul)
1360
IWMMXT_OP_ENV(packuq)
1361
IWMMXT_OP_ENV(packsw)
1362
IWMMXT_OP_ENV(packsl)
1363
IWMMXT_OP_ENV(packsq)
1365
static void gen_op_iwmmxt_set_mup(void)
1368
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1369
tcg_gen_ori_i32(tmp, tmp, 2);
1370
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1373
static void gen_op_iwmmxt_set_cup(void)
1376
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1377
tcg_gen_ori_i32(tmp, tmp, 1);
1378
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1381
static void gen_op_iwmmxt_setpsr_nz(void)
1383
TCGv_i32 tmp = tcg_temp_new_i32();
1384
gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1385
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1388
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1390
iwmmxt_load_reg(cpu_V1, rn);
1391
tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1392
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1395
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1402
rd = (insn >> 16) & 0xf;
1403
tmp = load_reg(s, rd);
1405
offset = (insn & 0xff) << ((insn >> 7) & 2);
1406
if (insn & (1 << 24)) {
1408
if (insn & (1 << 23))
1409
tcg_gen_addi_i32(tmp, tmp, offset);
1411
tcg_gen_addi_i32(tmp, tmp, -offset);
1412
tcg_gen_mov_i32(dest, tmp);
1413
if (insn & (1 << 21))
1414
store_reg(s, rd, tmp);
1416
tcg_temp_free_i32(tmp);
1417
} else if (insn & (1 << 21)) {
1419
tcg_gen_mov_i32(dest, tmp);
1420
if (insn & (1 << 23))
1421
tcg_gen_addi_i32(tmp, tmp, offset);
1423
tcg_gen_addi_i32(tmp, tmp, -offset);
1424
store_reg(s, rd, tmp);
1425
} else if (!(insn & (1 << 23)))
1430
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1432
int rd = (insn >> 0) & 0xf;
1435
if (insn & (1 << 8)) {
1436
if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1439
tmp = iwmmxt_load_creg(rd);
1442
tmp = tcg_temp_new_i32();
1443
iwmmxt_load_reg(cpu_V0, rd);
1444
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1446
tcg_gen_andi_i32(tmp, tmp, mask);
1447
tcg_gen_mov_i32(dest, tmp);
1448
tcg_temp_free_i32(tmp);
1452
/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1453
(ie. an undefined instruction). */
1454
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1457
int rdhi, rdlo, rd0, rd1, i;
1459
TCGv_i32 tmp, tmp2, tmp3;
1461
if ((insn & 0x0e000e00) == 0x0c000000) {
1462
if ((insn & 0x0fe00ff0) == 0x0c400000) {
1464
rdlo = (insn >> 12) & 0xf;
1465
rdhi = (insn >> 16) & 0xf;
1466
if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1467
iwmmxt_load_reg(cpu_V0, wrd);
1468
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1469
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1470
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1471
} else { /* TMCRR */
1472
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1473
iwmmxt_store_reg(cpu_V0, wrd);
1474
gen_op_iwmmxt_set_mup();
1479
wrd = (insn >> 12) & 0xf;
1480
addr = tcg_temp_new_i32();
1481
if (gen_iwmmxt_address(s, insn, addr)) {
1482
tcg_temp_free_i32(addr);
1485
if (insn & ARM_CP_RW_BIT) {
1486
if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1487
tmp = tcg_temp_new_i32();
1488
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1489
iwmmxt_store_creg(wrd, tmp);
1492
if (insn & (1 << 8)) {
1493
if (insn & (1 << 22)) { /* WLDRD */
1494
gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1496
} else { /* WLDRW wRd */
1497
tmp = tcg_temp_new_i32();
1498
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1501
tmp = tcg_temp_new_i32();
1502
if (insn & (1 << 22)) { /* WLDRH */
1503
gen_aa32_ld16u(tmp, addr, IS_USER(s));
1504
} else { /* WLDRB */
1505
gen_aa32_ld8u(tmp, addr, IS_USER(s));
1509
tcg_gen_extu_i32_i64(cpu_M0, tmp);
1510
tcg_temp_free_i32(tmp);
1512
gen_op_iwmmxt_movq_wRn_M0(wrd);
1515
if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1516
tmp = iwmmxt_load_creg(wrd);
1517
gen_aa32_st32(tmp, addr, IS_USER(s));
1519
gen_op_iwmmxt_movq_M0_wRn(wrd);
1520
tmp = tcg_temp_new_i32();
1521
if (insn & (1 << 8)) {
1522
if (insn & (1 << 22)) { /* WSTRD */
1523
gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1524
} else { /* WSTRW wRd */
1525
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1526
gen_aa32_st32(tmp, addr, IS_USER(s));
1529
if (insn & (1 << 22)) { /* WSTRH */
1530
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1531
gen_aa32_st16(tmp, addr, IS_USER(s));
1532
} else { /* WSTRB */
1533
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1534
gen_aa32_st8(tmp, addr, IS_USER(s));
1538
tcg_temp_free_i32(tmp);
1540
tcg_temp_free_i32(addr);
1544
if ((insn & 0x0f000000) != 0x0e000000)
1547
switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1548
case 0x000: /* WOR */
1549
wrd = (insn >> 12) & 0xf;
1550
rd0 = (insn >> 0) & 0xf;
1551
rd1 = (insn >> 16) & 0xf;
1552
gen_op_iwmmxt_movq_M0_wRn(rd0);
1553
gen_op_iwmmxt_orq_M0_wRn(rd1);
1554
gen_op_iwmmxt_setpsr_nz();
1555
gen_op_iwmmxt_movq_wRn_M0(wrd);
1556
gen_op_iwmmxt_set_mup();
1557
gen_op_iwmmxt_set_cup();
1559
case 0x011: /* TMCR */
1562
rd = (insn >> 12) & 0xf;
1563
wrd = (insn >> 16) & 0xf;
1565
case ARM_IWMMXT_wCID:
1566
case ARM_IWMMXT_wCASF:
1568
case ARM_IWMMXT_wCon:
1569
gen_op_iwmmxt_set_cup();
1571
case ARM_IWMMXT_wCSSF:
1572
tmp = iwmmxt_load_creg(wrd);
1573
tmp2 = load_reg(s, rd);
1574
tcg_gen_andc_i32(tmp, tmp, tmp2);
1575
tcg_temp_free_i32(tmp2);
1576
iwmmxt_store_creg(wrd, tmp);
1578
case ARM_IWMMXT_wCGR0:
1579
case ARM_IWMMXT_wCGR1:
1580
case ARM_IWMMXT_wCGR2:
1581
case ARM_IWMMXT_wCGR3:
1582
gen_op_iwmmxt_set_cup();
1583
tmp = load_reg(s, rd);
1584
iwmmxt_store_creg(wrd, tmp);
1590
case 0x100: /* WXOR */
1591
wrd = (insn >> 12) & 0xf;
1592
rd0 = (insn >> 0) & 0xf;
1593
rd1 = (insn >> 16) & 0xf;
1594
gen_op_iwmmxt_movq_M0_wRn(rd0);
1595
gen_op_iwmmxt_xorq_M0_wRn(rd1);
1596
gen_op_iwmmxt_setpsr_nz();
1597
gen_op_iwmmxt_movq_wRn_M0(wrd);
1598
gen_op_iwmmxt_set_mup();
1599
gen_op_iwmmxt_set_cup();
1601
case 0x111: /* TMRC */
1604
rd = (insn >> 12) & 0xf;
1605
wrd = (insn >> 16) & 0xf;
1606
tmp = iwmmxt_load_creg(wrd);
1607
store_reg(s, rd, tmp);
1609
case 0x300: /* WANDN */
1610
wrd = (insn >> 12) & 0xf;
1611
rd0 = (insn >> 0) & 0xf;
1612
rd1 = (insn >> 16) & 0xf;
1613
gen_op_iwmmxt_movq_M0_wRn(rd0);
1614
tcg_gen_neg_i64(cpu_M0, cpu_M0);
1615
gen_op_iwmmxt_andq_M0_wRn(rd1);
1616
gen_op_iwmmxt_setpsr_nz();
1617
gen_op_iwmmxt_movq_wRn_M0(wrd);
1618
gen_op_iwmmxt_set_mup();
1619
gen_op_iwmmxt_set_cup();
1621
case 0x200: /* WAND */
1622
wrd = (insn >> 12) & 0xf;
1623
rd0 = (insn >> 0) & 0xf;
1624
rd1 = (insn >> 16) & 0xf;
1625
gen_op_iwmmxt_movq_M0_wRn(rd0);
1626
gen_op_iwmmxt_andq_M0_wRn(rd1);
1627
gen_op_iwmmxt_setpsr_nz();
1628
gen_op_iwmmxt_movq_wRn_M0(wrd);
1629
gen_op_iwmmxt_set_mup();
1630
gen_op_iwmmxt_set_cup();
1632
case 0x810: case 0xa10: /* WMADD */
1633
wrd = (insn >> 12) & 0xf;
1634
rd0 = (insn >> 0) & 0xf;
1635
rd1 = (insn >> 16) & 0xf;
1636
gen_op_iwmmxt_movq_M0_wRn(rd0);
1637
if (insn & (1 << 21))
1638
gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1640
gen_op_iwmmxt_madduq_M0_wRn(rd1);
1641
gen_op_iwmmxt_movq_wRn_M0(wrd);
1642
gen_op_iwmmxt_set_mup();
1644
case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1645
wrd = (insn >> 12) & 0xf;
1646
rd0 = (insn >> 16) & 0xf;
1647
rd1 = (insn >> 0) & 0xf;
1648
gen_op_iwmmxt_movq_M0_wRn(rd0);
1649
switch ((insn >> 22) & 3) {
1651
gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1654
gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1657
gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1662
gen_op_iwmmxt_movq_wRn_M0(wrd);
1663
gen_op_iwmmxt_set_mup();
1664
gen_op_iwmmxt_set_cup();
1666
case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1667
wrd = (insn >> 12) & 0xf;
1668
rd0 = (insn >> 16) & 0xf;
1669
rd1 = (insn >> 0) & 0xf;
1670
gen_op_iwmmxt_movq_M0_wRn(rd0);
1671
switch ((insn >> 22) & 3) {
1673
gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1676
gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1679
gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1684
gen_op_iwmmxt_movq_wRn_M0(wrd);
1685
gen_op_iwmmxt_set_mup();
1686
gen_op_iwmmxt_set_cup();
1688
case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1689
wrd = (insn >> 12) & 0xf;
1690
rd0 = (insn >> 16) & 0xf;
1691
rd1 = (insn >> 0) & 0xf;
1692
gen_op_iwmmxt_movq_M0_wRn(rd0);
1693
if (insn & (1 << 22))
1694
gen_op_iwmmxt_sadw_M0_wRn(rd1);
1696
gen_op_iwmmxt_sadb_M0_wRn(rd1);
1697
if (!(insn & (1 << 20)))
1698
gen_op_iwmmxt_addl_M0_wRn(wrd);
1699
gen_op_iwmmxt_movq_wRn_M0(wrd);
1700
gen_op_iwmmxt_set_mup();
1702
case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1703
wrd = (insn >> 12) & 0xf;
1704
rd0 = (insn >> 16) & 0xf;
1705
rd1 = (insn >> 0) & 0xf;
1706
gen_op_iwmmxt_movq_M0_wRn(rd0);
1707
if (insn & (1 << 21)) {
1708
if (insn & (1 << 20))
1709
gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1711
gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1713
if (insn & (1 << 20))
1714
gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1716
gen_op_iwmmxt_mululw_M0_wRn(rd1);
1718
gen_op_iwmmxt_movq_wRn_M0(wrd);
1719
gen_op_iwmmxt_set_mup();
1721
case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1722
wrd = (insn >> 12) & 0xf;
1723
rd0 = (insn >> 16) & 0xf;
1724
rd1 = (insn >> 0) & 0xf;
1725
gen_op_iwmmxt_movq_M0_wRn(rd0);
1726
if (insn & (1 << 21))
1727
gen_op_iwmmxt_macsw_M0_wRn(rd1);
1729
gen_op_iwmmxt_macuw_M0_wRn(rd1);
1730
if (!(insn & (1 << 20))) {
1731
iwmmxt_load_reg(cpu_V1, wrd);
1732
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1734
gen_op_iwmmxt_movq_wRn_M0(wrd);
1735
gen_op_iwmmxt_set_mup();
1737
case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1738
wrd = (insn >> 12) & 0xf;
1739
rd0 = (insn >> 16) & 0xf;
1740
rd1 = (insn >> 0) & 0xf;
1741
gen_op_iwmmxt_movq_M0_wRn(rd0);
1742
switch ((insn >> 22) & 3) {
1744
gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1747
gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1750
gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1755
gen_op_iwmmxt_movq_wRn_M0(wrd);
1756
gen_op_iwmmxt_set_mup();
1757
gen_op_iwmmxt_set_cup();
1759
case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1760
wrd = (insn >> 12) & 0xf;
1761
rd0 = (insn >> 16) & 0xf;
1762
rd1 = (insn >> 0) & 0xf;
1763
gen_op_iwmmxt_movq_M0_wRn(rd0);
1764
if (insn & (1 << 22)) {
1765
if (insn & (1 << 20))
1766
gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1768
gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1770
if (insn & (1 << 20))
1771
gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1773
gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1775
gen_op_iwmmxt_movq_wRn_M0(wrd);
1776
gen_op_iwmmxt_set_mup();
1777
gen_op_iwmmxt_set_cup();
1779
case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1780
wrd = (insn >> 12) & 0xf;
1781
rd0 = (insn >> 16) & 0xf;
1782
rd1 = (insn >> 0) & 0xf;
1783
gen_op_iwmmxt_movq_M0_wRn(rd0);
1784
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1785
tcg_gen_andi_i32(tmp, tmp, 7);
1786
iwmmxt_load_reg(cpu_V1, rd1);
1787
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1788
tcg_temp_free_i32(tmp);
1789
gen_op_iwmmxt_movq_wRn_M0(wrd);
1790
gen_op_iwmmxt_set_mup();
1792
case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1793
if (((insn >> 6) & 3) == 3)
1795
rd = (insn >> 12) & 0xf;
1796
wrd = (insn >> 16) & 0xf;
1797
tmp = load_reg(s, rd);
1798
gen_op_iwmmxt_movq_M0_wRn(wrd);
1799
switch ((insn >> 6) & 3) {
1801
tmp2 = tcg_const_i32(0xff);
1802
tmp3 = tcg_const_i32((insn & 7) << 3);
1805
tmp2 = tcg_const_i32(0xffff);
1806
tmp3 = tcg_const_i32((insn & 3) << 4);
1809
tmp2 = tcg_const_i32(0xffffffff);
1810
tmp3 = tcg_const_i32((insn & 1) << 5);
1813
TCGV_UNUSED_I32(tmp2);
1814
TCGV_UNUSED_I32(tmp3);
1816
gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1817
tcg_temp_free_i32(tmp3);
1818
tcg_temp_free_i32(tmp2);
1819
tcg_temp_free_i32(tmp);
1820
gen_op_iwmmxt_movq_wRn_M0(wrd);
1821
gen_op_iwmmxt_set_mup();
1823
case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1824
rd = (insn >> 12) & 0xf;
1825
wrd = (insn >> 16) & 0xf;
1826
if (rd == 15 || ((insn >> 22) & 3) == 3)
1828
gen_op_iwmmxt_movq_M0_wRn(wrd);
1829
tmp = tcg_temp_new_i32();
1830
switch ((insn >> 22) & 3) {
1832
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1833
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1835
tcg_gen_ext8s_i32(tmp, tmp);
1837
tcg_gen_andi_i32(tmp, tmp, 0xff);
1841
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1842
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1844
tcg_gen_ext16s_i32(tmp, tmp);
1846
tcg_gen_andi_i32(tmp, tmp, 0xffff);
1850
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1851
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1854
store_reg(s, rd, tmp);
1856
case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1857
if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1859
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1860
switch ((insn >> 22) & 3) {
1862
tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1865
tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1868
tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1871
tcg_gen_shli_i32(tmp, tmp, 28);
1873
tcg_temp_free_i32(tmp);
1875
case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1876
if (((insn >> 6) & 3) == 3)
1878
rd = (insn >> 12) & 0xf;
1879
wrd = (insn >> 16) & 0xf;
1880
tmp = load_reg(s, rd);
1881
switch ((insn >> 6) & 3) {
1883
gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1886
gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1889
gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1892
tcg_temp_free_i32(tmp);
1893
gen_op_iwmmxt_movq_wRn_M0(wrd);
1894
gen_op_iwmmxt_set_mup();
1896
case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1897
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1899
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1900
tmp2 = tcg_temp_new_i32();
1901
tcg_gen_mov_i32(tmp2, tmp);
1902
switch ((insn >> 22) & 3) {
1904
for (i = 0; i < 7; i ++) {
1905
tcg_gen_shli_i32(tmp2, tmp2, 4);
1906
tcg_gen_and_i32(tmp, tmp, tmp2);
1910
for (i = 0; i < 3; i ++) {
1911
tcg_gen_shli_i32(tmp2, tmp2, 8);
1912
tcg_gen_and_i32(tmp, tmp, tmp2);
1916
tcg_gen_shli_i32(tmp2, tmp2, 16);
1917
tcg_gen_and_i32(tmp, tmp, tmp2);
1921
tcg_temp_free_i32(tmp2);
1922
tcg_temp_free_i32(tmp);
1924
case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1925
wrd = (insn >> 12) & 0xf;
1926
rd0 = (insn >> 16) & 0xf;
1927
gen_op_iwmmxt_movq_M0_wRn(rd0);
1928
switch ((insn >> 22) & 3) {
1930
gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1933
gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1936
gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1941
gen_op_iwmmxt_movq_wRn_M0(wrd);
1942
gen_op_iwmmxt_set_mup();
1944
case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1945
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1947
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1948
tmp2 = tcg_temp_new_i32();
1949
tcg_gen_mov_i32(tmp2, tmp);
1950
switch ((insn >> 22) & 3) {
1952
for (i = 0; i < 7; i ++) {
1953
tcg_gen_shli_i32(tmp2, tmp2, 4);
1954
tcg_gen_or_i32(tmp, tmp, tmp2);
1958
for (i = 0; i < 3; i ++) {
1959
tcg_gen_shli_i32(tmp2, tmp2, 8);
1960
tcg_gen_or_i32(tmp, tmp, tmp2);
1964
tcg_gen_shli_i32(tmp2, tmp2, 16);
1965
tcg_gen_or_i32(tmp, tmp, tmp2);
1969
tcg_temp_free_i32(tmp2);
1970
tcg_temp_free_i32(tmp);
1972
case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1973
rd = (insn >> 12) & 0xf;
1974
rd0 = (insn >> 16) & 0xf;
1975
if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1977
gen_op_iwmmxt_movq_M0_wRn(rd0);
1978
tmp = tcg_temp_new_i32();
1979
switch ((insn >> 22) & 3) {
1981
gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1984
gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1987
gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1990
store_reg(s, rd, tmp);
1992
case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1993
case 0x906: case 0xb06: case 0xd06: case 0xf06:
1994
wrd = (insn >> 12) & 0xf;
1995
rd0 = (insn >> 16) & 0xf;
1996
rd1 = (insn >> 0) & 0xf;
1997
gen_op_iwmmxt_movq_M0_wRn(rd0);
1998
switch ((insn >> 22) & 3) {
2000
if (insn & (1 << 21))
2001
gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2003
gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2006
if (insn & (1 << 21))
2007
gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2009
gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2012
if (insn & (1 << 21))
2013
gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2015
gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2020
gen_op_iwmmxt_movq_wRn_M0(wrd);
2021
gen_op_iwmmxt_set_mup();
2022
gen_op_iwmmxt_set_cup();
2024
case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2025
case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2026
wrd = (insn >> 12) & 0xf;
2027
rd0 = (insn >> 16) & 0xf;
2028
gen_op_iwmmxt_movq_M0_wRn(rd0);
2029
switch ((insn >> 22) & 3) {
2031
if (insn & (1 << 21))
2032
gen_op_iwmmxt_unpacklsb_M0();
2034
gen_op_iwmmxt_unpacklub_M0();
2037
if (insn & (1 << 21))
2038
gen_op_iwmmxt_unpacklsw_M0();
2040
gen_op_iwmmxt_unpackluw_M0();
2043
if (insn & (1 << 21))
2044
gen_op_iwmmxt_unpacklsl_M0();
2046
gen_op_iwmmxt_unpacklul_M0();
2051
gen_op_iwmmxt_movq_wRn_M0(wrd);
2052
gen_op_iwmmxt_set_mup();
2053
gen_op_iwmmxt_set_cup();
2055
case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2056
case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2057
wrd = (insn >> 12) & 0xf;
2058
rd0 = (insn >> 16) & 0xf;
2059
gen_op_iwmmxt_movq_M0_wRn(rd0);
2060
switch ((insn >> 22) & 3) {
2062
if (insn & (1 << 21))
2063
gen_op_iwmmxt_unpackhsb_M0();
2065
gen_op_iwmmxt_unpackhub_M0();
2068
if (insn & (1 << 21))
2069
gen_op_iwmmxt_unpackhsw_M0();
2071
gen_op_iwmmxt_unpackhuw_M0();
2074
if (insn & (1 << 21))
2075
gen_op_iwmmxt_unpackhsl_M0();
2077
gen_op_iwmmxt_unpackhul_M0();
2082
gen_op_iwmmxt_movq_wRn_M0(wrd);
2083
gen_op_iwmmxt_set_mup();
2084
gen_op_iwmmxt_set_cup();
2086
case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2087
case 0x214: case 0x614: case 0xa14: case 0xe14:
2088
if (((insn >> 22) & 3) == 0)
2090
wrd = (insn >> 12) & 0xf;
2091
rd0 = (insn >> 16) & 0xf;
2092
gen_op_iwmmxt_movq_M0_wRn(rd0);
2093
tmp = tcg_temp_new_i32();
2094
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2095
tcg_temp_free_i32(tmp);
2098
switch ((insn >> 22) & 3) {
2100
gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2103
gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2106
gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2109
tcg_temp_free_i32(tmp);
2110
gen_op_iwmmxt_movq_wRn_M0(wrd);
2111
gen_op_iwmmxt_set_mup();
2112
gen_op_iwmmxt_set_cup();
2114
case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2115
case 0x014: case 0x414: case 0x814: case 0xc14:
2116
if (((insn >> 22) & 3) == 0)
2118
wrd = (insn >> 12) & 0xf;
2119
rd0 = (insn >> 16) & 0xf;
2120
gen_op_iwmmxt_movq_M0_wRn(rd0);
2121
tmp = tcg_temp_new_i32();
2122
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2123
tcg_temp_free_i32(tmp);
2126
switch ((insn >> 22) & 3) {
2128
gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2131
gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2134
gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2137
tcg_temp_free_i32(tmp);
2138
gen_op_iwmmxt_movq_wRn_M0(wrd);
2139
gen_op_iwmmxt_set_mup();
2140
gen_op_iwmmxt_set_cup();
2142
case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2143
case 0x114: case 0x514: case 0x914: case 0xd14:
2144
if (((insn >> 22) & 3) == 0)
2146
wrd = (insn >> 12) & 0xf;
2147
rd0 = (insn >> 16) & 0xf;
2148
gen_op_iwmmxt_movq_M0_wRn(rd0);
2149
tmp = tcg_temp_new_i32();
2150
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2151
tcg_temp_free_i32(tmp);
2154
switch ((insn >> 22) & 3) {
2156
gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2159
gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2162
gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2165
tcg_temp_free_i32(tmp);
2166
gen_op_iwmmxt_movq_wRn_M0(wrd);
2167
gen_op_iwmmxt_set_mup();
2168
gen_op_iwmmxt_set_cup();
2170
case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2171
case 0x314: case 0x714: case 0xb14: case 0xf14:
2172
if (((insn >> 22) & 3) == 0)
2174
wrd = (insn >> 12) & 0xf;
2175
rd0 = (insn >> 16) & 0xf;
2176
gen_op_iwmmxt_movq_M0_wRn(rd0);
2177
tmp = tcg_temp_new_i32();
2178
switch ((insn >> 22) & 3) {
2180
if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2181
tcg_temp_free_i32(tmp);
2184
gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2187
if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2188
tcg_temp_free_i32(tmp);
2191
gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2194
if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2195
tcg_temp_free_i32(tmp);
2198
gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2201
tcg_temp_free_i32(tmp);
2202
gen_op_iwmmxt_movq_wRn_M0(wrd);
2203
gen_op_iwmmxt_set_mup();
2204
gen_op_iwmmxt_set_cup();
2206
case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2207
case 0x916: case 0xb16: case 0xd16: case 0xf16:
2208
wrd = (insn >> 12) & 0xf;
2209
rd0 = (insn >> 16) & 0xf;
2210
rd1 = (insn >> 0) & 0xf;
2211
gen_op_iwmmxt_movq_M0_wRn(rd0);
2212
switch ((insn >> 22) & 3) {
2214
if (insn & (1 << 21))
2215
gen_op_iwmmxt_minsb_M0_wRn(rd1);
2217
gen_op_iwmmxt_minub_M0_wRn(rd1);
2220
if (insn & (1 << 21))
2221
gen_op_iwmmxt_minsw_M0_wRn(rd1);
2223
gen_op_iwmmxt_minuw_M0_wRn(rd1);
2226
if (insn & (1 << 21))
2227
gen_op_iwmmxt_minsl_M0_wRn(rd1);
2229
gen_op_iwmmxt_minul_M0_wRn(rd1);
2234
gen_op_iwmmxt_movq_wRn_M0(wrd);
2235
gen_op_iwmmxt_set_mup();
2237
case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2238
case 0x816: case 0xa16: case 0xc16: case 0xe16:
2239
wrd = (insn >> 12) & 0xf;
2240
rd0 = (insn >> 16) & 0xf;
2241
rd1 = (insn >> 0) & 0xf;
2242
gen_op_iwmmxt_movq_M0_wRn(rd0);
2243
switch ((insn >> 22) & 3) {
2245
if (insn & (1 << 21))
2246
gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2248
gen_op_iwmmxt_maxub_M0_wRn(rd1);
2251
if (insn & (1 << 21))
2252
gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2254
gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2257
if (insn & (1 << 21))
2258
gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2260
gen_op_iwmmxt_maxul_M0_wRn(rd1);
2265
gen_op_iwmmxt_movq_wRn_M0(wrd);
2266
gen_op_iwmmxt_set_mup();
2268
case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2269
case 0x402: case 0x502: case 0x602: case 0x702:
2270
wrd = (insn >> 12) & 0xf;
2271
rd0 = (insn >> 16) & 0xf;
2272
rd1 = (insn >> 0) & 0xf;
2273
gen_op_iwmmxt_movq_M0_wRn(rd0);
2274
tmp = tcg_const_i32((insn >> 20) & 3);
2275
iwmmxt_load_reg(cpu_V1, rd1);
2276
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2277
tcg_temp_free_i32(tmp);
2278
gen_op_iwmmxt_movq_wRn_M0(wrd);
2279
gen_op_iwmmxt_set_mup();
2281
case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2282
case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2283
case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2284
case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2285
wrd = (insn >> 12) & 0xf;
2286
rd0 = (insn >> 16) & 0xf;
2287
rd1 = (insn >> 0) & 0xf;
2288
gen_op_iwmmxt_movq_M0_wRn(rd0);
2289
switch ((insn >> 20) & 0xf) {
2291
gen_op_iwmmxt_subnb_M0_wRn(rd1);
2294
gen_op_iwmmxt_subub_M0_wRn(rd1);
2297
gen_op_iwmmxt_subsb_M0_wRn(rd1);
2300
gen_op_iwmmxt_subnw_M0_wRn(rd1);
2303
gen_op_iwmmxt_subuw_M0_wRn(rd1);
2306
gen_op_iwmmxt_subsw_M0_wRn(rd1);
2309
gen_op_iwmmxt_subnl_M0_wRn(rd1);
2312
gen_op_iwmmxt_subul_M0_wRn(rd1);
2315
gen_op_iwmmxt_subsl_M0_wRn(rd1);
2320
gen_op_iwmmxt_movq_wRn_M0(wrd);
2321
gen_op_iwmmxt_set_mup();
2322
gen_op_iwmmxt_set_cup();
2324
case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2325
case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2326
case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2327
case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2328
wrd = (insn >> 12) & 0xf;
2329
rd0 = (insn >> 16) & 0xf;
2330
gen_op_iwmmxt_movq_M0_wRn(rd0);
2331
tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2332
gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2333
tcg_temp_free_i32(tmp);
2334
gen_op_iwmmxt_movq_wRn_M0(wrd);
2335
gen_op_iwmmxt_set_mup();
2336
gen_op_iwmmxt_set_cup();
2338
case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2339
case 0x418: case 0x518: case 0x618: case 0x718:
2340
case 0x818: case 0x918: case 0xa18: case 0xb18:
2341
case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2342
wrd = (insn >> 12) & 0xf;
2343
rd0 = (insn >> 16) & 0xf;
2344
rd1 = (insn >> 0) & 0xf;
2345
gen_op_iwmmxt_movq_M0_wRn(rd0);
2346
switch ((insn >> 20) & 0xf) {
2348
gen_op_iwmmxt_addnb_M0_wRn(rd1);
2351
gen_op_iwmmxt_addub_M0_wRn(rd1);
2354
gen_op_iwmmxt_addsb_M0_wRn(rd1);
2357
gen_op_iwmmxt_addnw_M0_wRn(rd1);
2360
gen_op_iwmmxt_adduw_M0_wRn(rd1);
2363
gen_op_iwmmxt_addsw_M0_wRn(rd1);
2366
gen_op_iwmmxt_addnl_M0_wRn(rd1);
2369
gen_op_iwmmxt_addul_M0_wRn(rd1);
2372
gen_op_iwmmxt_addsl_M0_wRn(rd1);
2377
gen_op_iwmmxt_movq_wRn_M0(wrd);
2378
gen_op_iwmmxt_set_mup();
2379
gen_op_iwmmxt_set_cup();
2381
case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2382
case 0x408: case 0x508: case 0x608: case 0x708:
2383
case 0x808: case 0x908: case 0xa08: case 0xb08:
2384
case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2385
if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2387
wrd = (insn >> 12) & 0xf;
2388
rd0 = (insn >> 16) & 0xf;
2389
rd1 = (insn >> 0) & 0xf;
2390
gen_op_iwmmxt_movq_M0_wRn(rd0);
2391
switch ((insn >> 22) & 3) {
2393
if (insn & (1 << 21))
2394
gen_op_iwmmxt_packsw_M0_wRn(rd1);
2396
gen_op_iwmmxt_packuw_M0_wRn(rd1);
2399
if (insn & (1 << 21))
2400
gen_op_iwmmxt_packsl_M0_wRn(rd1);
2402
gen_op_iwmmxt_packul_M0_wRn(rd1);
2405
if (insn & (1 << 21))
2406
gen_op_iwmmxt_packsq_M0_wRn(rd1);
2408
gen_op_iwmmxt_packuq_M0_wRn(rd1);
2411
gen_op_iwmmxt_movq_wRn_M0(wrd);
2412
gen_op_iwmmxt_set_mup();
2413
gen_op_iwmmxt_set_cup();
2415
case 0x201: case 0x203: case 0x205: case 0x207:
2416
case 0x209: case 0x20b: case 0x20d: case 0x20f:
2417
case 0x211: case 0x213: case 0x215: case 0x217:
2418
case 0x219: case 0x21b: case 0x21d: case 0x21f:
2419
wrd = (insn >> 5) & 0xf;
2420
rd0 = (insn >> 12) & 0xf;
2421
rd1 = (insn >> 0) & 0xf;
2422
if (rd0 == 0xf || rd1 == 0xf)
2424
gen_op_iwmmxt_movq_M0_wRn(wrd);
2425
tmp = load_reg(s, rd0);
2426
tmp2 = load_reg(s, rd1);
2427
switch ((insn >> 16) & 0xf) {
2428
case 0x0: /* TMIA */
2429
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2431
case 0x8: /* TMIAPH */
2432
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2434
case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2435
if (insn & (1 << 16))
2436
tcg_gen_shri_i32(tmp, tmp, 16);
2437
if (insn & (1 << 17))
2438
tcg_gen_shri_i32(tmp2, tmp2, 16);
2439
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2442
tcg_temp_free_i32(tmp2);
2443
tcg_temp_free_i32(tmp);
2446
tcg_temp_free_i32(tmp2);
2447
tcg_temp_free_i32(tmp);
2448
gen_op_iwmmxt_movq_wRn_M0(wrd);
2449
gen_op_iwmmxt_set_mup();
2458
/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2459
(ie. an undefined instruction). */
2460
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2462
int acc, rd0, rd1, rdhi, rdlo;
2465
if ((insn & 0x0ff00f10) == 0x0e200010) {
2466
/* Multiply with Internal Accumulate Format */
2467
rd0 = (insn >> 12) & 0xf;
2469
acc = (insn >> 5) & 7;
2474
tmp = load_reg(s, rd0);
2475
tmp2 = load_reg(s, rd1);
2476
switch ((insn >> 16) & 0xf) {
2478
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2480
case 0x8: /* MIAPH */
2481
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2483
case 0xc: /* MIABB */
2484
case 0xd: /* MIABT */
2485
case 0xe: /* MIATB */
2486
case 0xf: /* MIATT */
2487
if (insn & (1 << 16))
2488
tcg_gen_shri_i32(tmp, tmp, 16);
2489
if (insn & (1 << 17))
2490
tcg_gen_shri_i32(tmp2, tmp2, 16);
2491
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2496
tcg_temp_free_i32(tmp2);
2497
tcg_temp_free_i32(tmp);
2499
gen_op_iwmmxt_movq_wRn_M0(acc);
2503
if ((insn & 0x0fe00ff8) == 0x0c400000) {
2504
/* Internal Accumulator Access Format */
2505
rdhi = (insn >> 16) & 0xf;
2506
rdlo = (insn >> 12) & 0xf;
2512
if (insn & ARM_CP_RW_BIT) { /* MRA */
2513
iwmmxt_load_reg(cpu_V0, acc);
2514
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2515
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2516
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2517
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2519
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2520
iwmmxt_store_reg(cpu_V0, acc);
2528
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2529
#define VFP_SREG(insn, bigbit, smallbit) \
2530
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2531
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2532
if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2533
reg = (((insn) >> (bigbit)) & 0x0f) \
2534
| (((insn) >> ((smallbit) - 4)) & 0x10); \
2536
if (insn & (1 << (smallbit))) \
2538
reg = ((insn) >> (bigbit)) & 0x0f; \
2541
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2542
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2543
#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2544
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2545
#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2546
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2548
/* Move between integer and VFP cores. */
2549
static TCGv_i32 gen_vfp_mrs(void)
2551
TCGv_i32 tmp = tcg_temp_new_i32();
2552
tcg_gen_mov_i32(tmp, cpu_F0s);
2556
static void gen_vfp_msr(TCGv_i32 tmp)
2558
tcg_gen_mov_i32(cpu_F0s, tmp);
2559
tcg_temp_free_i32(tmp);
2562
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2564
TCGv_i32 tmp = tcg_temp_new_i32();
2566
tcg_gen_shri_i32(var, var, shift);
2567
tcg_gen_ext8u_i32(var, var);
2568
tcg_gen_shli_i32(tmp, var, 8);
2569
tcg_gen_or_i32(var, var, tmp);
2570
tcg_gen_shli_i32(tmp, var, 16);
2571
tcg_gen_or_i32(var, var, tmp);
2572
tcg_temp_free_i32(tmp);
2575
static void gen_neon_dup_low16(TCGv_i32 var)
2577
TCGv_i32 tmp = tcg_temp_new_i32();
2578
tcg_gen_ext16u_i32(var, var);
2579
tcg_gen_shli_i32(tmp, var, 16);
2580
tcg_gen_or_i32(var, var, tmp);
2581
tcg_temp_free_i32(tmp);
2584
static void gen_neon_dup_high16(TCGv_i32 var)
2586
TCGv_i32 tmp = tcg_temp_new_i32();
2587
tcg_gen_andi_i32(var, var, 0xffff0000);
2588
tcg_gen_shri_i32(tmp, var, 16);
2589
tcg_gen_or_i32(var, var, tmp);
2590
tcg_temp_free_i32(tmp);
2593
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2595
/* Load a single Neon element and replicate into a 32 bit TCG reg */
2596
TCGv_i32 tmp = tcg_temp_new_i32();
2599
gen_aa32_ld8u(tmp, addr, IS_USER(s));
2600
gen_neon_dup_u8(tmp, 0);
2603
gen_aa32_ld16u(tmp, addr, IS_USER(s));
2604
gen_neon_dup_low16(tmp);
2607
gen_aa32_ld32u(tmp, addr, IS_USER(s));
2609
default: /* Avoid compiler warnings. */
2615
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2618
uint32_t cc = extract32(insn, 20, 2);
2621
TCGv_i64 frn, frm, dest;
2622
TCGv_i64 tmp, zero, zf, nf, vf;
2624
zero = tcg_const_i64(0);
2626
frn = tcg_temp_new_i64();
2627
frm = tcg_temp_new_i64();
2628
dest = tcg_temp_new_i64();
2630
zf = tcg_temp_new_i64();
2631
nf = tcg_temp_new_i64();
2632
vf = tcg_temp_new_i64();
2634
tcg_gen_extu_i32_i64(zf, cpu_ZF);
2635
tcg_gen_ext_i32_i64(nf, cpu_NF);
2636
tcg_gen_ext_i32_i64(vf, cpu_VF);
2638
tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2639
tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2642
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2646
tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2649
case 2: /* ge: N == V -> N ^ V == 0 */
2650
tmp = tcg_temp_new_i64();
2651
tcg_gen_xor_i64(tmp, vf, nf);
2652
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2654
tcg_temp_free_i64(tmp);
2656
case 3: /* gt: !Z && N == V */
2657
tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2659
tmp = tcg_temp_new_i64();
2660
tcg_gen_xor_i64(tmp, vf, nf);
2661
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2663
tcg_temp_free_i64(tmp);
2666
tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2667
tcg_temp_free_i64(frn);
2668
tcg_temp_free_i64(frm);
2669
tcg_temp_free_i64(dest);
2671
tcg_temp_free_i64(zf);
2672
tcg_temp_free_i64(nf);
2673
tcg_temp_free_i64(vf);
2675
tcg_temp_free_i64(zero);
2677
TCGv_i32 frn, frm, dest;
2680
zero = tcg_const_i32(0);
2682
frn = tcg_temp_new_i32();
2683
frm = tcg_temp_new_i32();
2684
dest = tcg_temp_new_i32();
2685
tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2686
tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2689
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2693
tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2696
case 2: /* ge: N == V -> N ^ V == 0 */
2697
tmp = tcg_temp_new_i32();
2698
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2699
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2701
tcg_temp_free_i32(tmp);
2703
case 3: /* gt: !Z && N == V */
2704
tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2706
tmp = tcg_temp_new_i32();
2707
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2708
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2710
tcg_temp_free_i32(tmp);
2713
tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2714
tcg_temp_free_i32(frn);
2715
tcg_temp_free_i32(frm);
2716
tcg_temp_free_i32(dest);
2718
tcg_temp_free_i32(zero);
2724
static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2725
uint32_t rm, uint32_t dp)
2727
uint32_t vmin = extract32(insn, 6, 1);
2728
TCGv_ptr fpst = get_fpstatus_ptr(0);
2731
TCGv_i64 frn, frm, dest;
2733
frn = tcg_temp_new_i64();
2734
frm = tcg_temp_new_i64();
2735
dest = tcg_temp_new_i64();
2737
tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2738
tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2740
gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2742
gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2744
tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2745
tcg_temp_free_i64(frn);
2746
tcg_temp_free_i64(frm);
2747
tcg_temp_free_i64(dest);
2749
TCGv_i32 frn, frm, dest;
2751
frn = tcg_temp_new_i32();
2752
frm = tcg_temp_new_i32();
2753
dest = tcg_temp_new_i32();
2755
tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2756
tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2758
gen_helper_vfp_minnums(dest, frn, frm, fpst);
2760
gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2762
tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2763
tcg_temp_free_i32(frn);
2764
tcg_temp_free_i32(frm);
2765
tcg_temp_free_i32(dest);
2768
tcg_temp_free_ptr(fpst);
2772
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2774
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2776
if (!arm_feature(env, ARM_FEATURE_V8)) {
2781
VFP_DREG_D(rd, insn);
2782
VFP_DREG_N(rn, insn);
2783
VFP_DREG_M(rm, insn);
2785
rd = VFP_SREG_D(insn);
2786
rn = VFP_SREG_N(insn);
2787
rm = VFP_SREG_M(insn);
2790
if ((insn & 0x0f800e50) == 0x0e000a00) {
2791
return handle_vsel(insn, rd, rn, rm, dp);
2792
} else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2793
return handle_vminmaxnm(insn, rd, rn, rm, dp);
2798
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2799
(ie. an undefined instruction). */
2800
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2802
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2808
if (!arm_feature(env, ARM_FEATURE_VFP))
2811
if (!s->vfp_enabled) {
2812
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2813
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2815
rn = (insn >> 16) & 0xf;
2816
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2817
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2821
if (extract32(insn, 28, 4) == 0xf) {
2822
/* Encodings with T=1 (Thumb) or unconditional (ARM):
2823
* only used in v8 and above.
2825
return disas_vfp_v8_insn(env, s, insn);
2828
dp = ((insn & 0xf00) == 0xb00);
2829
switch ((insn >> 24) & 0xf) {
2831
if (insn & (1 << 4)) {
2832
/* single register transfer */
2833
rd = (insn >> 12) & 0xf;
2838
VFP_DREG_N(rn, insn);
2841
if (insn & 0x00c00060
2842
&& !arm_feature(env, ARM_FEATURE_NEON))
2845
pass = (insn >> 21) & 1;
2846
if (insn & (1 << 22)) {
2848
offset = ((insn >> 5) & 3) * 8;
2849
} else if (insn & (1 << 5)) {
2851
offset = (insn & (1 << 6)) ? 16 : 0;
2856
if (insn & ARM_CP_RW_BIT) {
2858
tmp = neon_load_reg(rn, pass);
2862
tcg_gen_shri_i32(tmp, tmp, offset);
2863
if (insn & (1 << 23))
2869
if (insn & (1 << 23)) {
2871
tcg_gen_shri_i32(tmp, tmp, 16);
2877
tcg_gen_sari_i32(tmp, tmp, 16);
2886
store_reg(s, rd, tmp);
2889
tmp = load_reg(s, rd);
2890
if (insn & (1 << 23)) {
2893
gen_neon_dup_u8(tmp, 0);
2894
} else if (size == 1) {
2895
gen_neon_dup_low16(tmp);
2897
for (n = 0; n <= pass * 2; n++) {
2898
tmp2 = tcg_temp_new_i32();
2899
tcg_gen_mov_i32(tmp2, tmp);
2900
neon_store_reg(rn, n, tmp2);
2902
neon_store_reg(rn, n, tmp);
2907
tmp2 = neon_load_reg(rn, pass);
2908
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2909
tcg_temp_free_i32(tmp2);
2912
tmp2 = neon_load_reg(rn, pass);
2913
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2914
tcg_temp_free_i32(tmp2);
2919
neon_store_reg(rn, pass, tmp);
2923
if ((insn & 0x6f) != 0x00)
2925
rn = VFP_SREG_N(insn);
2926
if (insn & ARM_CP_RW_BIT) {
2928
if (insn & (1 << 21)) {
2929
/* system register */
2934
/* VFP2 allows access to FSID from userspace.
2935
VFP3 restricts all id registers to privileged
2938
&& arm_feature(env, ARM_FEATURE_VFP3))
2940
tmp = load_cpu_field(vfp.xregs[rn]);
2945
tmp = load_cpu_field(vfp.xregs[rn]);
2947
case ARM_VFP_FPINST:
2948
case ARM_VFP_FPINST2:
2949
/* Not present in VFP3. */
2951
|| arm_feature(env, ARM_FEATURE_VFP3))
2953
tmp = load_cpu_field(vfp.xregs[rn]);
2957
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2958
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2960
tmp = tcg_temp_new_i32();
2961
gen_helper_vfp_get_fpscr(tmp, cpu_env);
2967
|| !arm_feature(env, ARM_FEATURE_MVFR))
2969
tmp = load_cpu_field(vfp.xregs[rn]);
2975
gen_mov_F0_vreg(0, rn);
2976
tmp = gen_vfp_mrs();
2979
/* Set the 4 flag bits in the CPSR. */
2981
tcg_temp_free_i32(tmp);
2983
store_reg(s, rd, tmp);
2987
if (insn & (1 << 21)) {
2989
/* system register */
2994
/* Writes are ignored. */
2997
tmp = load_reg(s, rd);
2998
gen_helper_vfp_set_fpscr(cpu_env, tmp);
2999
tcg_temp_free_i32(tmp);
3005
/* TODO: VFP subarchitecture support.
3006
* For now, keep the EN bit only */
3007
tmp = load_reg(s, rd);
3008
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3009
store_cpu_field(tmp, vfp.xregs[rn]);
3012
case ARM_VFP_FPINST:
3013
case ARM_VFP_FPINST2:
3014
tmp = load_reg(s, rd);
3015
store_cpu_field(tmp, vfp.xregs[rn]);
3021
tmp = load_reg(s, rd);
3023
gen_mov_vreg_F0(0, rn);
3028
/* data processing */
3029
/* The opcode is in bits 23, 21, 20 and 6. */
3030
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3034
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3036
/* rn is register number */
3037
VFP_DREG_N(rn, insn);
3040
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3041
/* Integer or single precision destination. */
3042
rd = VFP_SREG_D(insn);
3044
VFP_DREG_D(rd, insn);
3047
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3048
/* VCVT from int is always from S reg regardless of dp bit.
3049
* VCVT with immediate frac_bits has same format as SREG_M
3051
rm = VFP_SREG_M(insn);
3053
VFP_DREG_M(rm, insn);
3056
rn = VFP_SREG_N(insn);
3057
if (op == 15 && rn == 15) {
3058
/* Double precision destination. */
3059
VFP_DREG_D(rd, insn);
3061
rd = VFP_SREG_D(insn);
3063
/* NB that we implicitly rely on the encoding for the frac_bits
3064
* in VCVT of fixed to float being the same as that of an SREG_M
3066
rm = VFP_SREG_M(insn);
3069
veclen = s->vec_len;
3070
if (op == 15 && rn > 3)
3073
/* Shut up compiler warnings. */
3084
/* Figure out what type of vector operation this is. */
3085
if ((rd & bank_mask) == 0) {
3090
delta_d = (s->vec_stride >> 1) + 1;
3092
delta_d = s->vec_stride + 1;
3094
if ((rm & bank_mask) == 0) {
3095
/* mixed scalar/vector */
3104
/* Load the initial operands. */
3109
/* Integer source */
3110
gen_mov_F0_vreg(0, rm);
3115
gen_mov_F0_vreg(dp, rd);
3116
gen_mov_F1_vreg(dp, rm);
3120
/* Compare with zero */
3121
gen_mov_F0_vreg(dp, rd);
3132
/* Source and destination the same. */
3133
gen_mov_F0_vreg(dp, rd);
3139
/* VCVTB, VCVTT: only present with the halfprec extension,
3140
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3142
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3145
/* Otherwise fall through */
3147
/* One source operand. */
3148
gen_mov_F0_vreg(dp, rm);
3152
/* Two source operands. */
3153
gen_mov_F0_vreg(dp, rn);
3154
gen_mov_F1_vreg(dp, rm);
3158
/* Perform the calculation. */
3160
case 0: /* VMLA: fd + (fn * fm) */
3161
/* Note that order of inputs to the add matters for NaNs */
3163
gen_mov_F0_vreg(dp, rd);
3166
case 1: /* VMLS: fd + -(fn * fm) */
3169
gen_mov_F0_vreg(dp, rd);
3172
case 2: /* VNMLS: -fd + (fn * fm) */
3173
/* Note that it isn't valid to replace (-A + B) with (B - A)
3174
* or similar plausible looking simplifications
3175
* because this will give wrong results for NaNs.
3178
gen_mov_F0_vreg(dp, rd);
3182
case 3: /* VNMLA: -fd + -(fn * fm) */
3185
gen_mov_F0_vreg(dp, rd);
3189
case 4: /* mul: fn * fm */
3192
case 5: /* nmul: -(fn * fm) */
3196
case 6: /* add: fn + fm */
3199
case 7: /* sub: fn - fm */
3202
case 8: /* div: fn / fm */
3205
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3206
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3207
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3208
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3209
/* These are fused multiply-add, and must be done as one
3210
* floating point operation with no rounding between the
3211
* multiplication and addition steps.
3212
* NB that doing the negations here as separate steps is
3213
* correct : an input NaN should come out with its sign bit
3214
* flipped if it is a negated-input.
3216
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3224
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3226
frd = tcg_temp_new_i64();
3227
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3230
gen_helper_vfp_negd(frd, frd);
3232
fpst = get_fpstatus_ptr(0);
3233
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3234
cpu_F1d, frd, fpst);
3235
tcg_temp_free_ptr(fpst);
3236
tcg_temp_free_i64(frd);
3242
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3244
frd = tcg_temp_new_i32();
3245
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3247
gen_helper_vfp_negs(frd, frd);
3249
fpst = get_fpstatus_ptr(0);
3250
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3251
cpu_F1s, frd, fpst);
3252
tcg_temp_free_ptr(fpst);
3253
tcg_temp_free_i32(frd);
3256
case 14: /* fconst */
3257
if (!arm_feature(env, ARM_FEATURE_VFP3))
3260
n = (insn << 12) & 0x80000000;
3261
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3268
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3275
tcg_gen_movi_i32(cpu_F0s, n);
3278
case 15: /* extension space */
3292
case 4: /* vcvtb.f32.f16 */
3293
tmp = gen_vfp_mrs();
3294
tcg_gen_ext16u_i32(tmp, tmp);
3295
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3296
tcg_temp_free_i32(tmp);
3298
case 5: /* vcvtt.f32.f16 */
3299
tmp = gen_vfp_mrs();
3300
tcg_gen_shri_i32(tmp, tmp, 16);
3301
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3302
tcg_temp_free_i32(tmp);
3304
case 6: /* vcvtb.f16.f32 */
3305
tmp = tcg_temp_new_i32();
3306
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3307
gen_mov_F0_vreg(0, rd);
3308
tmp2 = gen_vfp_mrs();
3309
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3310
tcg_gen_or_i32(tmp, tmp, tmp2);
3311
tcg_temp_free_i32(tmp2);
3314
case 7: /* vcvtt.f16.f32 */
3315
tmp = tcg_temp_new_i32();
3316
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3317
tcg_gen_shli_i32(tmp, tmp, 16);
3318
gen_mov_F0_vreg(0, rd);
3319
tmp2 = gen_vfp_mrs();
3320
tcg_gen_ext16u_i32(tmp2, tmp2);
3321
tcg_gen_or_i32(tmp, tmp, tmp2);
3322
tcg_temp_free_i32(tmp2);
3334
case 11: /* cmpez */
3338
case 15: /* single<->double conversion */
3340
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3342
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3344
case 16: /* fuito */
3345
gen_vfp_uito(dp, 0);
3347
case 17: /* fsito */
3348
gen_vfp_sito(dp, 0);
3350
case 20: /* fshto */
3351
if (!arm_feature(env, ARM_FEATURE_VFP3))
3353
gen_vfp_shto(dp, 16 - rm, 0);
3355
case 21: /* fslto */
3356
if (!arm_feature(env, ARM_FEATURE_VFP3))
3358
gen_vfp_slto(dp, 32 - rm, 0);
3360
case 22: /* fuhto */
3361
if (!arm_feature(env, ARM_FEATURE_VFP3))
3363
gen_vfp_uhto(dp, 16 - rm, 0);
3365
case 23: /* fulto */
3366
if (!arm_feature(env, ARM_FEATURE_VFP3))
3368
gen_vfp_ulto(dp, 32 - rm, 0);
3370
case 24: /* ftoui */
3371
gen_vfp_toui(dp, 0);
3373
case 25: /* ftouiz */
3374
gen_vfp_touiz(dp, 0);
3376
case 26: /* ftosi */
3377
gen_vfp_tosi(dp, 0);
3379
case 27: /* ftosiz */
3380
gen_vfp_tosiz(dp, 0);
3382
case 28: /* ftosh */
3383
if (!arm_feature(env, ARM_FEATURE_VFP3))
3385
gen_vfp_tosh(dp, 16 - rm, 0);
3387
case 29: /* ftosl */
3388
if (!arm_feature(env, ARM_FEATURE_VFP3))
3390
gen_vfp_tosl(dp, 32 - rm, 0);
3392
case 30: /* ftouh */
3393
if (!arm_feature(env, ARM_FEATURE_VFP3))
3395
gen_vfp_touh(dp, 16 - rm, 0);
3397
case 31: /* ftoul */
3398
if (!arm_feature(env, ARM_FEATURE_VFP3))
3400
gen_vfp_toul(dp, 32 - rm, 0);
3402
default: /* undefined */
3406
default: /* undefined */
3410
/* Write back the result. */
3411
if (op == 15 && (rn >= 8 && rn <= 11))
3412
; /* Comparison, do nothing. */
3413
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3414
/* VCVT double to int: always integer result. */
3415
gen_mov_vreg_F0(0, rd);
3416
else if (op == 15 && rn == 15)
3418
gen_mov_vreg_F0(!dp, rd);
3420
gen_mov_vreg_F0(dp, rd);
3422
/* break out of the loop if we have finished */
3426
if (op == 15 && delta_m == 0) {
3427
/* single source one-many */
3429
rd = ((rd + delta_d) & (bank_mask - 1))
3431
gen_mov_vreg_F0(dp, rd);
3435
/* Setup the next operands. */
3437
rd = ((rd + delta_d) & (bank_mask - 1))
3441
/* One source operand. */
3442
rm = ((rm + delta_m) & (bank_mask - 1))
3444
gen_mov_F0_vreg(dp, rm);
3446
/* Two source operands. */
3447
rn = ((rn + delta_d) & (bank_mask - 1))
3449
gen_mov_F0_vreg(dp, rn);
3451
rm = ((rm + delta_m) & (bank_mask - 1))
3453
gen_mov_F1_vreg(dp, rm);
3461
if ((insn & 0x03e00000) == 0x00400000) {
3462
/* two-register transfer */
3463
rn = (insn >> 16) & 0xf;
3464
rd = (insn >> 12) & 0xf;
3466
VFP_DREG_M(rm, insn);
3468
rm = VFP_SREG_M(insn);
3471
if (insn & ARM_CP_RW_BIT) {
3474
gen_mov_F0_vreg(0, rm * 2);
3475
tmp = gen_vfp_mrs();
3476
store_reg(s, rd, tmp);
3477
gen_mov_F0_vreg(0, rm * 2 + 1);
3478
tmp = gen_vfp_mrs();
3479
store_reg(s, rn, tmp);
3481
gen_mov_F0_vreg(0, rm);
3482
tmp = gen_vfp_mrs();
3483
store_reg(s, rd, tmp);
3484
gen_mov_F0_vreg(0, rm + 1);
3485
tmp = gen_vfp_mrs();
3486
store_reg(s, rn, tmp);
3491
tmp = load_reg(s, rd);
3493
gen_mov_vreg_F0(0, rm * 2);
3494
tmp = load_reg(s, rn);
3496
gen_mov_vreg_F0(0, rm * 2 + 1);
3498
tmp = load_reg(s, rd);
3500
gen_mov_vreg_F0(0, rm);
3501
tmp = load_reg(s, rn);
3503
gen_mov_vreg_F0(0, rm + 1);
3508
rn = (insn >> 16) & 0xf;
3510
VFP_DREG_D(rd, insn);
3512
rd = VFP_SREG_D(insn);
3513
if ((insn & 0x01200000) == 0x01000000) {
3514
/* Single load/store */
3515
offset = (insn & 0xff) << 2;
3516
if ((insn & (1 << 23)) == 0)
3518
if (s->thumb && rn == 15) {
3519
/* This is actually UNPREDICTABLE */
3520
addr = tcg_temp_new_i32();
3521
tcg_gen_movi_i32(addr, s->pc & ~2);
3523
addr = load_reg(s, rn);
3525
tcg_gen_addi_i32(addr, addr, offset);
3526
if (insn & (1 << 20)) {
3527
gen_vfp_ld(s, dp, addr);
3528
gen_mov_vreg_F0(dp, rd);
3530
gen_mov_F0_vreg(dp, rd);
3531
gen_vfp_st(s, dp, addr);
3533
tcg_temp_free_i32(addr);
3535
/* load/store multiple */
3536
int w = insn & (1 << 21);
3538
n = (insn >> 1) & 0x7f;
3542
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3543
/* P == U , W == 1 => UNDEF */
3546
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3547
/* UNPREDICTABLE cases for bad immediates: we choose to
3548
* UNDEF to avoid generating huge numbers of TCG ops
3552
if (rn == 15 && w) {
3553
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3557
if (s->thumb && rn == 15) {
3558
/* This is actually UNPREDICTABLE */
3559
addr = tcg_temp_new_i32();
3560
tcg_gen_movi_i32(addr, s->pc & ~2);
3562
addr = load_reg(s, rn);
3564
if (insn & (1 << 24)) /* pre-decrement */
3565
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3571
for (i = 0; i < n; i++) {
3572
if (insn & ARM_CP_RW_BIT) {
3574
gen_vfp_ld(s, dp, addr);
3575
gen_mov_vreg_F0(dp, rd + i);
3578
gen_mov_F0_vreg(dp, rd + i);
3579
gen_vfp_st(s, dp, addr);
3581
tcg_gen_addi_i32(addr, addr, offset);
3585
if (insn & (1 << 24))
3586
offset = -offset * n;
3587
else if (dp && (insn & 1))
3593
tcg_gen_addi_i32(addr, addr, offset);
3594
store_reg(s, rn, addr);
3596
tcg_temp_free_i32(addr);
3602
/* Should never happen. */
3608
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3610
TranslationBlock *tb;
3613
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3615
gen_set_pc_im(s, dest);
3616
tcg_gen_exit_tb((uintptr_t)tb + n);
3618
gen_set_pc_im(s, dest);
3623
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3625
if (unlikely(s->singlestep_enabled)) {
3626
/* An indirect jump so that we still trigger the debug exception. */
3631
gen_goto_tb(s, 0, dest);
3632
s->is_jmp = DISAS_TB_JUMP;
3636
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3639
tcg_gen_sari_i32(t0, t0, 16);
3643
tcg_gen_sari_i32(t1, t1, 16);
3646
tcg_gen_mul_i32(t0, t0, t1);
3649
/* Return the mask of PSR bits set by a MSR instruction. */
3650
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3654
if (flags & (1 << 0))
3656
if (flags & (1 << 1))
3658
if (flags & (1 << 2))
3660
if (flags & (1 << 3))
3663
/* Mask out undefined bits. */
3664
mask &= ~CPSR_RESERVED;
3665
if (!arm_feature(env, ARM_FEATURE_V4T))
3667
if (!arm_feature(env, ARM_FEATURE_V5))
3668
mask &= ~CPSR_Q; /* V5TE in reality*/
3669
if (!arm_feature(env, ARM_FEATURE_V6))
3670
mask &= ~(CPSR_E | CPSR_GE);
3671
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3673
/* Mask out execution state bits. */
3676
/* Mask out privileged bits. */
3682
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3683
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3687
/* ??? This is also undefined in system mode. */
3691
tmp = load_cpu_field(spsr);
3692
tcg_gen_andi_i32(tmp, tmp, ~mask);
3693
tcg_gen_andi_i32(t0, t0, mask);
3694
tcg_gen_or_i32(tmp, tmp, t0);
3695
store_cpu_field(tmp, spsr);
3697
gen_set_cpsr(t0, mask);
3699
tcg_temp_free_i32(t0);
3704
/* Returns nonzero if access to the PSR is not permitted. */
3705
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3708
tmp = tcg_temp_new_i32();
3709
tcg_gen_movi_i32(tmp, val);
3710
return gen_set_psr(s, mask, spsr, tmp);
3713
/* Generate an old-style exception return. Marks pc as dead. */
3714
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3717
store_reg(s, 15, pc);
3718
tmp = load_cpu_field(spsr);
3719
gen_set_cpsr(tmp, 0xffffffff);
3720
tcg_temp_free_i32(tmp);
3721
s->is_jmp = DISAS_UPDATE;
3724
/* Generate a v6 exception return. Marks both values as dead. */
3725
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3727
gen_set_cpsr(cpsr, 0xffffffff);
3728
tcg_temp_free_i32(cpsr);
3729
store_reg(s, 15, pc);
3730
s->is_jmp = DISAS_UPDATE;
3734
gen_set_condexec (DisasContext *s)
3736
if (s->condexec_mask) {
3737
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3738
TCGv_i32 tmp = tcg_temp_new_i32();
3739
tcg_gen_movi_i32(tmp, val);
3740
store_cpu_field(tmp, condexec_bits);
3744
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3746
gen_set_condexec(s);
3747
gen_set_pc_im(s, s->pc - offset);
3748
gen_exception(excp);
3749
s->is_jmp = DISAS_JUMP;
3752
static void gen_nop_hint(DisasContext *s, int val)
3756
gen_set_pc_im(s, s->pc);
3757
s->is_jmp = DISAS_WFI;
3762
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3768
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3770
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3773
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3774
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3775
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3780
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3783
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3784
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3785
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3790
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3791
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3792
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3793
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3794
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3796
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3797
switch ((size << 1) | u) { \
3799
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3802
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3805
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3808
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3811
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3814
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3816
default: return 1; \
3819
#define GEN_NEON_INTEGER_OP(name) do { \
3820
switch ((size << 1) | u) { \
3822
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3825
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3828
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3831
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3834
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3837
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3839
default: return 1; \
3842
static TCGv_i32 neon_load_scratch(int scratch)
3844
TCGv_i32 tmp = tcg_temp_new_i32();
3845
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3849
static void neon_store_scratch(int scratch, TCGv_i32 var)
3851
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3852
tcg_temp_free_i32(var);
3855
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3859
tmp = neon_load_reg(reg & 7, reg >> 4);
3861
gen_neon_dup_high16(tmp);
3863
gen_neon_dup_low16(tmp);
3866
tmp = neon_load_reg(reg & 15, reg >> 4);
3871
static int gen_neon_unzip(int rd, int rm, int size, int q)
3874
if (!q && size == 2) {
3877
tmp = tcg_const_i32(rd);
3878
tmp2 = tcg_const_i32(rm);
3882
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3885
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3888
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3896
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3899
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3905
tcg_temp_free_i32(tmp);
3906
tcg_temp_free_i32(tmp2);
3910
static int gen_neon_zip(int rd, int rm, int size, int q)
3913
if (!q && size == 2) {
3916
tmp = tcg_const_i32(rd);
3917
tmp2 = tcg_const_i32(rm);
3921
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3924
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3927
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3935
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3938
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3944
tcg_temp_free_i32(tmp);
3945
tcg_temp_free_i32(tmp2);
3949
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3953
rd = tcg_temp_new_i32();
3954
tmp = tcg_temp_new_i32();
3956
tcg_gen_shli_i32(rd, t0, 8);
3957
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3958
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3959
tcg_gen_or_i32(rd, rd, tmp);
3961
tcg_gen_shri_i32(t1, t1, 8);
3962
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3963
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3964
tcg_gen_or_i32(t1, t1, tmp);
3965
tcg_gen_mov_i32(t0, rd);
3967
tcg_temp_free_i32(tmp);
3968
tcg_temp_free_i32(rd);
3971
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3975
rd = tcg_temp_new_i32();
3976
tmp = tcg_temp_new_i32();
3978
tcg_gen_shli_i32(rd, t0, 16);
3979
tcg_gen_andi_i32(tmp, t1, 0xffff);
3980
tcg_gen_or_i32(rd, rd, tmp);
3981
tcg_gen_shri_i32(t1, t1, 16);
3982
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3983
tcg_gen_or_i32(t1, t1, tmp);
3984
tcg_gen_mov_i32(t0, rd);
3986
tcg_temp_free_i32(tmp);
3987
tcg_temp_free_i32(rd);
3995
} neon_ls_element_type[11] = {
4009
/* Translate a NEON load/store element instruction. Return nonzero if the
4010
instruction is invalid. */
4011
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4030
if (!s->vfp_enabled)
4032
VFP_DREG_D(rd, insn);
4033
rn = (insn >> 16) & 0xf;
4035
load = (insn & (1 << 21)) != 0;
4036
if ((insn & (1 << 23)) == 0) {
4037
/* Load store all elements. */
4038
op = (insn >> 8) & 0xf;
4039
size = (insn >> 6) & 3;
4042
/* Catch UNDEF cases for bad values of align field */
4045
if (((insn >> 5) & 1) == 1) {
4050
if (((insn >> 4) & 3) == 3) {
4057
nregs = neon_ls_element_type[op].nregs;
4058
interleave = neon_ls_element_type[op].interleave;
4059
spacing = neon_ls_element_type[op].spacing;
4060
if (size == 3 && (interleave | spacing) != 1)
4062
addr = tcg_temp_new_i32();
4063
load_reg_var(s, addr, rn);
4064
stride = (1 << size) * interleave;
4065
for (reg = 0; reg < nregs; reg++) {
4066
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4067
load_reg_var(s, addr, rn);
4068
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4069
} else if (interleave == 2 && nregs == 4 && reg == 2) {
4070
load_reg_var(s, addr, rn);
4071
tcg_gen_addi_i32(addr, addr, 1 << size);
4074
tmp64 = tcg_temp_new_i64();
4076
gen_aa32_ld64(tmp64, addr, IS_USER(s));
4077
neon_store_reg64(tmp64, rd);
4079
neon_load_reg64(tmp64, rd);
4080
gen_aa32_st64(tmp64, addr, IS_USER(s));
4082
tcg_temp_free_i64(tmp64);
4083
tcg_gen_addi_i32(addr, addr, stride);
4085
for (pass = 0; pass < 2; pass++) {
4088
tmp = tcg_temp_new_i32();
4089
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4090
neon_store_reg(rd, pass, tmp);
4092
tmp = neon_load_reg(rd, pass);
4093
gen_aa32_st32(tmp, addr, IS_USER(s));
4094
tcg_temp_free_i32(tmp);
4096
tcg_gen_addi_i32(addr, addr, stride);
4097
} else if (size == 1) {
4099
tmp = tcg_temp_new_i32();
4100
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4101
tcg_gen_addi_i32(addr, addr, stride);
4102
tmp2 = tcg_temp_new_i32();
4103
gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4104
tcg_gen_addi_i32(addr, addr, stride);
4105
tcg_gen_shli_i32(tmp2, tmp2, 16);
4106
tcg_gen_or_i32(tmp, tmp, tmp2);
4107
tcg_temp_free_i32(tmp2);
4108
neon_store_reg(rd, pass, tmp);
4110
tmp = neon_load_reg(rd, pass);
4111
tmp2 = tcg_temp_new_i32();
4112
tcg_gen_shri_i32(tmp2, tmp, 16);
4113
gen_aa32_st16(tmp, addr, IS_USER(s));
4114
tcg_temp_free_i32(tmp);
4115
tcg_gen_addi_i32(addr, addr, stride);
4116
gen_aa32_st16(tmp2, addr, IS_USER(s));
4117
tcg_temp_free_i32(tmp2);
4118
tcg_gen_addi_i32(addr, addr, stride);
4120
} else /* size == 0 */ {
4122
TCGV_UNUSED_I32(tmp2);
4123
for (n = 0; n < 4; n++) {
4124
tmp = tcg_temp_new_i32();
4125
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4126
tcg_gen_addi_i32(addr, addr, stride);
4130
tcg_gen_shli_i32(tmp, tmp, n * 8);
4131
tcg_gen_or_i32(tmp2, tmp2, tmp);
4132
tcg_temp_free_i32(tmp);
4135
neon_store_reg(rd, pass, tmp2);
4137
tmp2 = neon_load_reg(rd, pass);
4138
for (n = 0; n < 4; n++) {
4139
tmp = tcg_temp_new_i32();
4141
tcg_gen_mov_i32(tmp, tmp2);
4143
tcg_gen_shri_i32(tmp, tmp2, n * 8);
4145
gen_aa32_st8(tmp, addr, IS_USER(s));
4146
tcg_temp_free_i32(tmp);
4147
tcg_gen_addi_i32(addr, addr, stride);
4149
tcg_temp_free_i32(tmp2);
4156
tcg_temp_free_i32(addr);
4159
size = (insn >> 10) & 3;
4161
/* Load single element to all lanes. */
4162
int a = (insn >> 4) & 1;
4166
size = (insn >> 6) & 3;
4167
nregs = ((insn >> 8) & 3) + 1;
4170
if (nregs != 4 || a == 0) {
4173
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4176
if (nregs == 1 && a == 1 && size == 0) {
4179
if (nregs == 3 && a == 1) {
4182
addr = tcg_temp_new_i32();
4183
load_reg_var(s, addr, rn);
4185
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4186
tmp = gen_load_and_replicate(s, addr, size);
4187
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4188
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4189
if (insn & (1 << 5)) {
4190
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4191
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4193
tcg_temp_free_i32(tmp);
4195
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4196
stride = (insn & (1 << 5)) ? 2 : 1;
4197
for (reg = 0; reg < nregs; reg++) {
4198
tmp = gen_load_and_replicate(s, addr, size);
4199
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4200
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4201
tcg_temp_free_i32(tmp);
4202
tcg_gen_addi_i32(addr, addr, 1 << size);
4206
tcg_temp_free_i32(addr);
4207
stride = (1 << size) * nregs;
4209
/* Single element. */
4210
int idx = (insn >> 4) & 0xf;
4211
pass = (insn >> 7) & 1;
4214
shift = ((insn >> 5) & 3) * 8;
4218
shift = ((insn >> 6) & 1) * 16;
4219
stride = (insn & (1 << 5)) ? 2 : 1;
4223
stride = (insn & (1 << 6)) ? 2 : 1;
4228
nregs = ((insn >> 8) & 3) + 1;
4229
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
4232
if (((idx & (1 << size)) != 0) ||
4233
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4238
if ((idx & 1) != 0) {
4243
if (size == 2 && (idx & 2) != 0) {
4248
if ((size == 2) && ((idx & 3) == 3)) {
4255
if ((rd + stride * (nregs - 1)) > 31) {
4256
/* Attempts to write off the end of the register file
4257
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4258
* the neon_load_reg() would write off the end of the array.
4262
addr = tcg_temp_new_i32();
4263
load_reg_var(s, addr, rn);
4264
for (reg = 0; reg < nregs; reg++) {
4266
tmp = tcg_temp_new_i32();
4269
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4272
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4275
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4277
default: /* Avoid compiler warnings. */
4281
tmp2 = neon_load_reg(rd, pass);
4282
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4283
shift, size ? 16 : 8);
4284
tcg_temp_free_i32(tmp2);
4286
neon_store_reg(rd, pass, tmp);
4287
} else { /* Store */
4288
tmp = neon_load_reg(rd, pass);
4290
tcg_gen_shri_i32(tmp, tmp, shift);
4293
gen_aa32_st8(tmp, addr, IS_USER(s));
4296
gen_aa32_st16(tmp, addr, IS_USER(s));
4299
gen_aa32_st32(tmp, addr, IS_USER(s));
4302
tcg_temp_free_i32(tmp);
4305
tcg_gen_addi_i32(addr, addr, 1 << size);
4307
tcg_temp_free_i32(addr);
4308
stride = nregs * (1 << size);
4314
base = load_reg(s, rn);
4316
tcg_gen_addi_i32(base, base, stride);
4319
index = load_reg(s, rm);
4320
tcg_gen_add_i32(base, base, index);
4321
tcg_temp_free_i32(index);
4323
store_reg(s, rn, base);
4328
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4329
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4331
tcg_gen_and_i32(t, t, c);
4332
tcg_gen_andc_i32(f, f, c);
4333
tcg_gen_or_i32(dest, t, f);
4336
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4339
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4340
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4341
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4346
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4349
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4350
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4351
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4356
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4359
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4360
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4361
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4366
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4369
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4370
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4371
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4376
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4382
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4383
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4388
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4389
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4396
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4397
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4402
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4403
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4410
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4414
case 0: gen_helper_neon_widen_u8(dest, src); break;
4415
case 1: gen_helper_neon_widen_u16(dest, src); break;
4416
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4421
case 0: gen_helper_neon_widen_s8(dest, src); break;
4422
case 1: gen_helper_neon_widen_s16(dest, src); break;
4423
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4427
tcg_temp_free_i32(src);
4430
static inline void gen_neon_addl(int size)
4433
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4434
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4435
case 2: tcg_gen_add_i64(CPU_V001); break;
4440
static inline void gen_neon_subl(int size)
4443
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4444
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4445
case 2: tcg_gen_sub_i64(CPU_V001); break;
4450
static inline void gen_neon_negl(TCGv_i64 var, int size)
4453
case 0: gen_helper_neon_negl_u16(var, var); break;
4454
case 1: gen_helper_neon_negl_u32(var, var); break;
4456
tcg_gen_neg_i64(var, var);
4462
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4465
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4466
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4471
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4476
switch ((size << 1) | u) {
4477
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4478
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4479
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4480
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4482
tmp = gen_muls_i64_i32(a, b);
4483
tcg_gen_mov_i64(dest, tmp);
4484
tcg_temp_free_i64(tmp);
4487
tmp = gen_mulu_i64_i32(a, b);
4488
tcg_gen_mov_i64(dest, tmp);
4489
tcg_temp_free_i64(tmp);
4494
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4495
Don't forget to clean them now. */
4497
tcg_temp_free_i32(a);
4498
tcg_temp_free_i32(b);
4502
static void gen_neon_narrow_op(int op, int u, int size,
4503
TCGv_i32 dest, TCGv_i64 src)
4507
gen_neon_unarrow_sats(size, dest, src);
4509
gen_neon_narrow(size, dest, src);
4513
gen_neon_narrow_satu(size, dest, src);
4515
gen_neon_narrow_sats(size, dest, src);
4520
/* Symbolic constants for op fields for Neon 3-register same-length.
4521
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4524
#define NEON_3R_VHADD 0
4525
#define NEON_3R_VQADD 1
4526
#define NEON_3R_VRHADD 2
4527
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4528
#define NEON_3R_VHSUB 4
4529
#define NEON_3R_VQSUB 5
4530
#define NEON_3R_VCGT 6
4531
#define NEON_3R_VCGE 7
4532
#define NEON_3R_VSHL 8
4533
#define NEON_3R_VQSHL 9
4534
#define NEON_3R_VRSHL 10
4535
#define NEON_3R_VQRSHL 11
4536
#define NEON_3R_VMAX 12
4537
#define NEON_3R_VMIN 13
4538
#define NEON_3R_VABD 14
4539
#define NEON_3R_VABA 15
4540
#define NEON_3R_VADD_VSUB 16
4541
#define NEON_3R_VTST_VCEQ 17
4542
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4543
#define NEON_3R_VMUL 19
4544
#define NEON_3R_VPMAX 20
4545
#define NEON_3R_VPMIN 21
4546
#define NEON_3R_VQDMULH_VQRDMULH 22
4547
#define NEON_3R_VPADD 23
4548
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4549
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4550
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4551
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4552
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4553
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4554
#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4556
static const uint8_t neon_3r_sizes[] = {
4557
[NEON_3R_VHADD] = 0x7,
4558
[NEON_3R_VQADD] = 0xf,
4559
[NEON_3R_VRHADD] = 0x7,
4560
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4561
[NEON_3R_VHSUB] = 0x7,
4562
[NEON_3R_VQSUB] = 0xf,
4563
[NEON_3R_VCGT] = 0x7,
4564
[NEON_3R_VCGE] = 0x7,
4565
[NEON_3R_VSHL] = 0xf,
4566
[NEON_3R_VQSHL] = 0xf,
4567
[NEON_3R_VRSHL] = 0xf,
4568
[NEON_3R_VQRSHL] = 0xf,
4569
[NEON_3R_VMAX] = 0x7,
4570
[NEON_3R_VMIN] = 0x7,
4571
[NEON_3R_VABD] = 0x7,
4572
[NEON_3R_VABA] = 0x7,
4573
[NEON_3R_VADD_VSUB] = 0xf,
4574
[NEON_3R_VTST_VCEQ] = 0x7,
4575
[NEON_3R_VML] = 0x7,
4576
[NEON_3R_VMUL] = 0x7,
4577
[NEON_3R_VPMAX] = 0x7,
4578
[NEON_3R_VPMIN] = 0x7,
4579
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4580
[NEON_3R_VPADD] = 0x7,
4581
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4582
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4583
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4584
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4585
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4586
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4587
[NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4590
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4591
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4594
#define NEON_2RM_VREV64 0
4595
#define NEON_2RM_VREV32 1
4596
#define NEON_2RM_VREV16 2
4597
#define NEON_2RM_VPADDL 4
4598
#define NEON_2RM_VPADDL_U 5
4599
#define NEON_2RM_VCLS 8
4600
#define NEON_2RM_VCLZ 9
4601
#define NEON_2RM_VCNT 10
4602
#define NEON_2RM_VMVN 11
4603
#define NEON_2RM_VPADAL 12
4604
#define NEON_2RM_VPADAL_U 13
4605
#define NEON_2RM_VQABS 14
4606
#define NEON_2RM_VQNEG 15
4607
#define NEON_2RM_VCGT0 16
4608
#define NEON_2RM_VCGE0 17
4609
#define NEON_2RM_VCEQ0 18
4610
#define NEON_2RM_VCLE0 19
4611
#define NEON_2RM_VCLT0 20
4612
#define NEON_2RM_VABS 22
4613
#define NEON_2RM_VNEG 23
4614
#define NEON_2RM_VCGT0_F 24
4615
#define NEON_2RM_VCGE0_F 25
4616
#define NEON_2RM_VCEQ0_F 26
4617
#define NEON_2RM_VCLE0_F 27
4618
#define NEON_2RM_VCLT0_F 28
4619
#define NEON_2RM_VABS_F 30
4620
#define NEON_2RM_VNEG_F 31
4621
#define NEON_2RM_VSWP 32
4622
#define NEON_2RM_VTRN 33
4623
#define NEON_2RM_VUZP 34
4624
#define NEON_2RM_VZIP 35
4625
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4626
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4627
#define NEON_2RM_VSHLL 38
4628
#define NEON_2RM_VCVT_F16_F32 44
4629
#define NEON_2RM_VCVT_F32_F16 46
4630
#define NEON_2RM_VRECPE 56
4631
#define NEON_2RM_VRSQRTE 57
4632
#define NEON_2RM_VRECPE_F 58
4633
#define NEON_2RM_VRSQRTE_F 59
4634
#define NEON_2RM_VCVT_FS 60
4635
#define NEON_2RM_VCVT_FU 61
4636
#define NEON_2RM_VCVT_SF 62
4637
#define NEON_2RM_VCVT_UF 63
4639
static int neon_2rm_is_float_op(int op)
4641
/* Return true if this neon 2reg-misc op is float-to-float */
4642
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4643
op >= NEON_2RM_VRECPE_F);
4646
/* Each entry in this array has bit n set if the insn allows
4647
* size value n (otherwise it will UNDEF). Since unallocated
4648
* op values will have no bits set they always UNDEF.
4650
static const uint8_t neon_2rm_sizes[] = {
4651
[NEON_2RM_VREV64] = 0x7,
4652
[NEON_2RM_VREV32] = 0x3,
4653
[NEON_2RM_VREV16] = 0x1,
4654
[NEON_2RM_VPADDL] = 0x7,
4655
[NEON_2RM_VPADDL_U] = 0x7,
4656
[NEON_2RM_VCLS] = 0x7,
4657
[NEON_2RM_VCLZ] = 0x7,
4658
[NEON_2RM_VCNT] = 0x1,
4659
[NEON_2RM_VMVN] = 0x1,
4660
[NEON_2RM_VPADAL] = 0x7,
4661
[NEON_2RM_VPADAL_U] = 0x7,
4662
[NEON_2RM_VQABS] = 0x7,
4663
[NEON_2RM_VQNEG] = 0x7,
4664
[NEON_2RM_VCGT0] = 0x7,
4665
[NEON_2RM_VCGE0] = 0x7,
4666
[NEON_2RM_VCEQ0] = 0x7,
4667
[NEON_2RM_VCLE0] = 0x7,
4668
[NEON_2RM_VCLT0] = 0x7,
4669
[NEON_2RM_VABS] = 0x7,
4670
[NEON_2RM_VNEG] = 0x7,
4671
[NEON_2RM_VCGT0_F] = 0x4,
4672
[NEON_2RM_VCGE0_F] = 0x4,
4673
[NEON_2RM_VCEQ0_F] = 0x4,
4674
[NEON_2RM_VCLE0_F] = 0x4,
4675
[NEON_2RM_VCLT0_F] = 0x4,
4676
[NEON_2RM_VABS_F] = 0x4,
4677
[NEON_2RM_VNEG_F] = 0x4,
4678
[NEON_2RM_VSWP] = 0x1,
4679
[NEON_2RM_VTRN] = 0x7,
4680
[NEON_2RM_VUZP] = 0x7,
4681
[NEON_2RM_VZIP] = 0x7,
4682
[NEON_2RM_VMOVN] = 0x7,
4683
[NEON_2RM_VQMOVN] = 0x7,
4684
[NEON_2RM_VSHLL] = 0x7,
4685
[NEON_2RM_VCVT_F16_F32] = 0x2,
4686
[NEON_2RM_VCVT_F32_F16] = 0x2,
4687
[NEON_2RM_VRECPE] = 0x4,
4688
[NEON_2RM_VRSQRTE] = 0x4,
4689
[NEON_2RM_VRECPE_F] = 0x4,
4690
[NEON_2RM_VRSQRTE_F] = 0x4,
4691
[NEON_2RM_VCVT_FS] = 0x4,
4692
[NEON_2RM_VCVT_FU] = 0x4,
4693
[NEON_2RM_VCVT_SF] = 0x4,
4694
[NEON_2RM_VCVT_UF] = 0x4,
4697
/* Translate a NEON data processing instruction. Return nonzero if the
4698
instruction is invalid.
4699
We process data in a mixture of 32-bit and 64-bit chunks.
4700
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4702
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4714
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4717
if (!s->vfp_enabled)
4719
q = (insn & (1 << 6)) != 0;
4720
u = (insn >> 24) & 1;
4721
VFP_DREG_D(rd, insn);
4722
VFP_DREG_N(rn, insn);
4723
VFP_DREG_M(rm, insn);
4724
size = (insn >> 20) & 3;
4725
if ((insn & (1 << 23)) == 0) {
4726
/* Three register same length. */
4727
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4728
/* Catch invalid op and bad size combinations: UNDEF */
4729
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4732
/* All insns of this form UNDEF for either this condition or the
4733
* superset of cases "Q==1"; we catch the latter later.
4735
if (q && ((rd | rn | rm) & 1)) {
4738
if (size == 3 && op != NEON_3R_LOGIC) {
4739
/* 64-bit element instructions. */
4740
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4741
neon_load_reg64(cpu_V0, rn + pass);
4742
neon_load_reg64(cpu_V1, rm + pass);
4746
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4749
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4755
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4758
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4764
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4766
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4771
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4774
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4780
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4782
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4785
case NEON_3R_VQRSHL:
4787
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4790
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4794
case NEON_3R_VADD_VSUB:
4796
tcg_gen_sub_i64(CPU_V001);
4798
tcg_gen_add_i64(CPU_V001);
4804
neon_store_reg64(cpu_V0, rd + pass);
4813
case NEON_3R_VQRSHL:
4816
/* Shift instruction operands are reversed. */
4831
case NEON_3R_FLOAT_ARITH:
4832
pairwise = (u && size < 2); /* if VPADD (float) */
4834
case NEON_3R_FLOAT_MINMAX:
4835
pairwise = u; /* if VPMIN/VPMAX (float) */
4837
case NEON_3R_FLOAT_CMP:
4839
/* no encoding for U=0 C=1x */
4843
case NEON_3R_FLOAT_ACMP:
4848
case NEON_3R_FLOAT_MISC:
4849
/* VMAXNM/VMINNM in ARMv8 */
4850
if (u && !arm_feature(env, ARM_FEATURE_V8)) {
4855
if (u && (size != 0)) {
4856
/* UNDEF on invalid size for polynomial subcase */
4861
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4869
if (pairwise && q) {
4870
/* All the pairwise insns UNDEF if Q is set */
4874
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4879
tmp = neon_load_reg(rn, 0);
4880
tmp2 = neon_load_reg(rn, 1);
4882
tmp = neon_load_reg(rm, 0);
4883
tmp2 = neon_load_reg(rm, 1);
4887
tmp = neon_load_reg(rn, pass);
4888
tmp2 = neon_load_reg(rm, pass);
4892
GEN_NEON_INTEGER_OP(hadd);
4895
GEN_NEON_INTEGER_OP_ENV(qadd);
4897
case NEON_3R_VRHADD:
4898
GEN_NEON_INTEGER_OP(rhadd);
4900
case NEON_3R_LOGIC: /* Logic ops. */
4901
switch ((u << 2) | size) {
4903
tcg_gen_and_i32(tmp, tmp, tmp2);
4906
tcg_gen_andc_i32(tmp, tmp, tmp2);
4909
tcg_gen_or_i32(tmp, tmp, tmp2);
4912
tcg_gen_orc_i32(tmp, tmp, tmp2);
4915
tcg_gen_xor_i32(tmp, tmp, tmp2);
4918
tmp3 = neon_load_reg(rd, pass);
4919
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4920
tcg_temp_free_i32(tmp3);
4923
tmp3 = neon_load_reg(rd, pass);
4924
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4925
tcg_temp_free_i32(tmp3);
4928
tmp3 = neon_load_reg(rd, pass);
4929
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4930
tcg_temp_free_i32(tmp3);
4935
GEN_NEON_INTEGER_OP(hsub);
4938
GEN_NEON_INTEGER_OP_ENV(qsub);
4941
GEN_NEON_INTEGER_OP(cgt);
4944
GEN_NEON_INTEGER_OP(cge);
4947
GEN_NEON_INTEGER_OP(shl);
4950
GEN_NEON_INTEGER_OP_ENV(qshl);
4953
GEN_NEON_INTEGER_OP(rshl);
4955
case NEON_3R_VQRSHL:
4956
GEN_NEON_INTEGER_OP_ENV(qrshl);
4959
GEN_NEON_INTEGER_OP(max);
4962
GEN_NEON_INTEGER_OP(min);
4965
GEN_NEON_INTEGER_OP(abd);
4968
GEN_NEON_INTEGER_OP(abd);
4969
tcg_temp_free_i32(tmp2);
4970
tmp2 = neon_load_reg(rd, pass);
4971
gen_neon_add(size, tmp, tmp2);
4973
case NEON_3R_VADD_VSUB:
4974
if (!u) { /* VADD */
4975
gen_neon_add(size, tmp, tmp2);
4978
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4979
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4980
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4985
case NEON_3R_VTST_VCEQ:
4986
if (!u) { /* VTST */
4988
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4989
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4990
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4995
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4996
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4997
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5002
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5004
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5005
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5006
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5009
tcg_temp_free_i32(tmp2);
5010
tmp2 = neon_load_reg(rd, pass);
5012
gen_neon_rsb(size, tmp, tmp2);
5014
gen_neon_add(size, tmp, tmp2);
5018
if (u) { /* polynomial */
5019
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5020
} else { /* Integer */
5022
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5023
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5024
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5030
GEN_NEON_INTEGER_OP(pmax);
5033
GEN_NEON_INTEGER_OP(pmin);
5035
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5036
if (!u) { /* VQDMULH */
5039
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5042
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5046
} else { /* VQRDMULH */
5049
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5052
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5060
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5061
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5062
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5066
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5068
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5069
switch ((u << 2) | size) {
5072
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5075
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5078
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5083
tcg_temp_free_ptr(fpstatus);
5086
case NEON_3R_FLOAT_MULTIPLY:
5088
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5089
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5091
tcg_temp_free_i32(tmp2);
5092
tmp2 = neon_load_reg(rd, pass);
5094
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5096
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5099
tcg_temp_free_ptr(fpstatus);
5102
case NEON_3R_FLOAT_CMP:
5104
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5106
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5109
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5111
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5114
tcg_temp_free_ptr(fpstatus);
5117
case NEON_3R_FLOAT_ACMP:
5119
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5121
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5123
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5125
tcg_temp_free_ptr(fpstatus);
5128
case NEON_3R_FLOAT_MINMAX:
5130
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5132
gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5134
gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5136
tcg_temp_free_ptr(fpstatus);
5139
case NEON_3R_FLOAT_MISC:
5142
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5144
gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5146
gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5148
tcg_temp_free_ptr(fpstatus);
5151
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5153
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5159
/* VFMA, VFMS: fused multiply-add */
5160
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5161
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5164
gen_helper_vfp_negs(tmp, tmp);
5166
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5167
tcg_temp_free_i32(tmp3);
5168
tcg_temp_free_ptr(fpstatus);
5174
tcg_temp_free_i32(tmp2);
5176
/* Save the result. For elementwise operations we can put it
5177
straight into the destination register. For pairwise operations
5178
we have to be careful to avoid clobbering the source operands. */
5179
if (pairwise && rd == rm) {
5180
neon_store_scratch(pass, tmp);
5182
neon_store_reg(rd, pass, tmp);
5186
if (pairwise && rd == rm) {
5187
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5188
tmp = neon_load_scratch(pass);
5189
neon_store_reg(rd, pass, tmp);
5192
/* End of 3 register same size operations. */
5193
} else if (insn & (1 << 4)) {
5194
if ((insn & 0x00380080) != 0) {
5195
/* Two registers and shift. */
5196
op = (insn >> 8) & 0xf;
5197
if (insn & (1 << 7)) {
5205
while ((insn & (1 << (size + 19))) == 0)
5208
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5209
/* To avoid excessive duplication of ops we implement shift
5210
by immediate using the variable shift operations. */
5212
/* Shift by immediate:
5213
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5214
if (q && ((rd | rm) & 1)) {
5217
if (!u && (op == 4 || op == 6)) {
5220
/* Right shifts are encoded as N - shift, where N is the
5221
element size in bits. */
5223
shift = shift - (1 << (size + 3));
5231
imm = (uint8_t) shift;
5236
imm = (uint16_t) shift;
5247
for (pass = 0; pass < count; pass++) {
5249
neon_load_reg64(cpu_V0, rm + pass);
5250
tcg_gen_movi_i64(cpu_V1, imm);
5255
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5257
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5262
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5264
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5267
case 5: /* VSHL, VSLI */
5268
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5270
case 6: /* VQSHLU */
5271
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5276
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5279
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5284
if (op == 1 || op == 3) {
5286
neon_load_reg64(cpu_V1, rd + pass);
5287
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5288
} else if (op == 4 || (op == 5 && u)) {
5290
neon_load_reg64(cpu_V1, rd + pass);
5292
if (shift < -63 || shift > 63) {
5296
mask = 0xffffffffffffffffull >> -shift;
5298
mask = 0xffffffffffffffffull << shift;
5301
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5302
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5304
neon_store_reg64(cpu_V0, rd + pass);
5305
} else { /* size < 3 */
5306
/* Operands in T0 and T1. */
5307
tmp = neon_load_reg(rm, pass);
5308
tmp2 = tcg_temp_new_i32();
5309
tcg_gen_movi_i32(tmp2, imm);
5313
GEN_NEON_INTEGER_OP(shl);
5317
GEN_NEON_INTEGER_OP(rshl);
5320
case 5: /* VSHL, VSLI */
5322
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5323
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5324
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5328
case 6: /* VQSHLU */
5331
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5335
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5339
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5347
GEN_NEON_INTEGER_OP_ENV(qshl);
5350
tcg_temp_free_i32(tmp2);
5352
if (op == 1 || op == 3) {
5354
tmp2 = neon_load_reg(rd, pass);
5355
gen_neon_add(size, tmp, tmp2);
5356
tcg_temp_free_i32(tmp2);
5357
} else if (op == 4 || (op == 5 && u)) {
5362
mask = 0xff >> -shift;
5364
mask = (uint8_t)(0xff << shift);
5370
mask = 0xffff >> -shift;
5372
mask = (uint16_t)(0xffff << shift);
5376
if (shift < -31 || shift > 31) {
5380
mask = 0xffffffffu >> -shift;
5382
mask = 0xffffffffu << shift;
5388
tmp2 = neon_load_reg(rd, pass);
5389
tcg_gen_andi_i32(tmp, tmp, mask);
5390
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5391
tcg_gen_or_i32(tmp, tmp, tmp2);
5392
tcg_temp_free_i32(tmp2);
5394
neon_store_reg(rd, pass, tmp);
5397
} else if (op < 10) {
5398
/* Shift by immediate and narrow:
5399
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5400
int input_unsigned = (op == 8) ? !u : u;
5404
shift = shift - (1 << (size + 3));
5407
tmp64 = tcg_const_i64(shift);
5408
neon_load_reg64(cpu_V0, rm);
5409
neon_load_reg64(cpu_V1, rm + 1);
5410
for (pass = 0; pass < 2; pass++) {
5418
if (input_unsigned) {
5419
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5421
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5424
if (input_unsigned) {
5425
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5427
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5430
tmp = tcg_temp_new_i32();
5431
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5432
neon_store_reg(rd, pass, tmp);
5434
tcg_temp_free_i64(tmp64);
5437
imm = (uint16_t)shift;
5441
imm = (uint32_t)shift;
5443
tmp2 = tcg_const_i32(imm);
5444
tmp4 = neon_load_reg(rm + 1, 0);
5445
tmp5 = neon_load_reg(rm + 1, 1);
5446
for (pass = 0; pass < 2; pass++) {
5448
tmp = neon_load_reg(rm, 0);
5452
gen_neon_shift_narrow(size, tmp, tmp2, q,
5455
tmp3 = neon_load_reg(rm, 1);
5459
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5461
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5462
tcg_temp_free_i32(tmp);
5463
tcg_temp_free_i32(tmp3);
5464
tmp = tcg_temp_new_i32();
5465
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5466
neon_store_reg(rd, pass, tmp);
5468
tcg_temp_free_i32(tmp2);
5470
} else if (op == 10) {
5472
if (q || (rd & 1)) {
5475
tmp = neon_load_reg(rm, 0);
5476
tmp2 = neon_load_reg(rm, 1);
5477
for (pass = 0; pass < 2; pass++) {
5481
gen_neon_widen(cpu_V0, tmp, size, u);
5484
/* The shift is less than the width of the source
5485
type, so we can just shift the whole register. */
5486
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5487
/* Widen the result of shift: we need to clear
5488
* the potential overflow bits resulting from
5489
* left bits of the narrow input appearing as
5490
* right bits of left the neighbour narrow
5492
if (size < 2 || !u) {
5495
imm = (0xffu >> (8 - shift));
5497
} else if (size == 1) {
5498
imm = 0xffff >> (16 - shift);
5501
imm = 0xffffffff >> (32 - shift);
5504
imm64 = imm | (((uint64_t)imm) << 32);
5508
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5511
neon_store_reg64(cpu_V0, rd + pass);
5513
} else if (op >= 14) {
5514
/* VCVT fixed-point. */
5515
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5518
/* We have already masked out the must-be-1 top bit of imm6,
5519
* hence this 32-shift where the ARM ARM has 64-imm6.
5522
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5523
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5526
gen_vfp_ulto(0, shift, 1);
5528
gen_vfp_slto(0, shift, 1);
5531
gen_vfp_toul(0, shift, 1);
5533
gen_vfp_tosl(0, shift, 1);
5535
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5540
} else { /* (insn & 0x00380080) == 0 */
5542
if (q && (rd & 1)) {
5546
op = (insn >> 8) & 0xf;
5547
/* One register and immediate. */
5548
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5549
invert = (insn & (1 << 5)) != 0;
5550
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5551
* We choose to not special-case this and will behave as if a
5552
* valid constant encoding of 0 had been given.
5571
imm = (imm << 8) | (imm << 24);
5574
imm = (imm << 8) | 0xff;
5577
imm = (imm << 16) | 0xffff;
5580
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5588
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5589
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5595
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5596
if (op & 1 && op < 12) {
5597
tmp = neon_load_reg(rd, pass);
5599
/* The immediate value has already been inverted, so
5601
tcg_gen_andi_i32(tmp, tmp, imm);
5603
tcg_gen_ori_i32(tmp, tmp, imm);
5607
tmp = tcg_temp_new_i32();
5608
if (op == 14 && invert) {
5612
for (n = 0; n < 4; n++) {
5613
if (imm & (1 << (n + (pass & 1) * 4)))
5614
val |= 0xff << (n * 8);
5616
tcg_gen_movi_i32(tmp, val);
5618
tcg_gen_movi_i32(tmp, imm);
5621
neon_store_reg(rd, pass, tmp);
5624
} else { /* (insn & 0x00800010 == 0x00800000) */
5626
op = (insn >> 8) & 0xf;
5627
if ((insn & (1 << 6)) == 0) {
5628
/* Three registers of different lengths. */
5632
/* undefreq: bit 0 : UNDEF if size != 0
5633
* bit 1 : UNDEF if size == 0
5634
* bit 2 : UNDEF if U == 1
5635
* Note that [1:0] set implies 'always UNDEF'
5638
/* prewiden, src1_wide, src2_wide, undefreq */
5639
static const int neon_3reg_wide[16][4] = {
5640
{1, 0, 0, 0}, /* VADDL */
5641
{1, 1, 0, 0}, /* VADDW */
5642
{1, 0, 0, 0}, /* VSUBL */
5643
{1, 1, 0, 0}, /* VSUBW */
5644
{0, 1, 1, 0}, /* VADDHN */
5645
{0, 0, 0, 0}, /* VABAL */
5646
{0, 1, 1, 0}, /* VSUBHN */
5647
{0, 0, 0, 0}, /* VABDL */
5648
{0, 0, 0, 0}, /* VMLAL */
5649
{0, 0, 0, 6}, /* VQDMLAL */
5650
{0, 0, 0, 0}, /* VMLSL */
5651
{0, 0, 0, 6}, /* VQDMLSL */
5652
{0, 0, 0, 0}, /* Integer VMULL */
5653
{0, 0, 0, 2}, /* VQDMULL */
5654
{0, 0, 0, 5}, /* Polynomial VMULL */
5655
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5658
prewiden = neon_3reg_wide[op][0];
5659
src1_wide = neon_3reg_wide[op][1];
5660
src2_wide = neon_3reg_wide[op][2];
5661
undefreq = neon_3reg_wide[op][3];
5663
if (((undefreq & 1) && (size != 0)) ||
5664
((undefreq & 2) && (size == 0)) ||
5665
((undefreq & 4) && u)) {
5668
if ((src1_wide && (rn & 1)) ||
5669
(src2_wide && (rm & 1)) ||
5670
(!src2_wide && (rd & 1))) {
5674
/* Avoid overlapping operands. Wide source operands are
5675
always aligned so will never overlap with wide
5676
destinations in problematic ways. */
5677
if (rd == rm && !src2_wide) {
5678
tmp = neon_load_reg(rm, 1);
5679
neon_store_scratch(2, tmp);
5680
} else if (rd == rn && !src1_wide) {
5681
tmp = neon_load_reg(rn, 1);
5682
neon_store_scratch(2, tmp);
5684
TCGV_UNUSED_I32(tmp3);
5685
for (pass = 0; pass < 2; pass++) {
5687
neon_load_reg64(cpu_V0, rn + pass);
5688
TCGV_UNUSED_I32(tmp);
5690
if (pass == 1 && rd == rn) {
5691
tmp = neon_load_scratch(2);
5693
tmp = neon_load_reg(rn, pass);
5696
gen_neon_widen(cpu_V0, tmp, size, u);
5700
neon_load_reg64(cpu_V1, rm + pass);
5701
TCGV_UNUSED_I32(tmp2);
5703
if (pass == 1 && rd == rm) {
5704
tmp2 = neon_load_scratch(2);
5706
tmp2 = neon_load_reg(rm, pass);
5709
gen_neon_widen(cpu_V1, tmp2, size, u);
5713
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5714
gen_neon_addl(size);
5716
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5717
gen_neon_subl(size);
5719
case 5: case 7: /* VABAL, VABDL */
5720
switch ((size << 1) | u) {
5722
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5725
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5728
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5731
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5734
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5737
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5741
tcg_temp_free_i32(tmp2);
5742
tcg_temp_free_i32(tmp);
5744
case 8: case 9: case 10: case 11: case 12: case 13:
5745
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5746
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5748
case 14: /* Polynomial VMULL */
5749
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5750
tcg_temp_free_i32(tmp2);
5751
tcg_temp_free_i32(tmp);
5753
default: /* 15 is RESERVED: caught earlier */
5758
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5759
neon_store_reg64(cpu_V0, rd + pass);
5760
} else if (op == 5 || (op >= 8 && op <= 11)) {
5762
neon_load_reg64(cpu_V1, rd + pass);
5764
case 10: /* VMLSL */
5765
gen_neon_negl(cpu_V0, size);
5767
case 5: case 8: /* VABAL, VMLAL */
5768
gen_neon_addl(size);
5770
case 9: case 11: /* VQDMLAL, VQDMLSL */
5771
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5773
gen_neon_negl(cpu_V0, size);
5775
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5780
neon_store_reg64(cpu_V0, rd + pass);
5781
} else if (op == 4 || op == 6) {
5782
/* Narrowing operation. */
5783
tmp = tcg_temp_new_i32();
5787
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5790
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5793
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5794
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5801
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5804
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5807
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5808
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5809
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5817
neon_store_reg(rd, 0, tmp3);
5818
neon_store_reg(rd, 1, tmp);
5821
/* Write back the result. */
5822
neon_store_reg64(cpu_V0, rd + pass);
5826
/* Two registers and a scalar. NB that for ops of this form
5827
* the ARM ARM labels bit 24 as Q, but it is in our variable
5834
case 1: /* Float VMLA scalar */
5835
case 5: /* Floating point VMLS scalar */
5836
case 9: /* Floating point VMUL scalar */
5841
case 0: /* Integer VMLA scalar */
5842
case 4: /* Integer VMLS scalar */
5843
case 8: /* Integer VMUL scalar */
5844
case 12: /* VQDMULH scalar */
5845
case 13: /* VQRDMULH scalar */
5846
if (u && ((rd | rn) & 1)) {
5849
tmp = neon_get_scalar(size, rm);
5850
neon_store_scratch(0, tmp);
5851
for (pass = 0; pass < (u ? 4 : 2); pass++) {
5852
tmp = neon_load_scratch(0);
5853
tmp2 = neon_load_reg(rn, pass);
5856
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5858
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5860
} else if (op == 13) {
5862
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5864
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5866
} else if (op & 1) {
5867
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5868
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5869
tcg_temp_free_ptr(fpstatus);
5872
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5873
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5874
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5878
tcg_temp_free_i32(tmp2);
5881
tmp2 = neon_load_reg(rd, pass);
5884
gen_neon_add(size, tmp, tmp2);
5888
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5889
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5890
tcg_temp_free_ptr(fpstatus);
5894
gen_neon_rsb(size, tmp, tmp2);
5898
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5899
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5900
tcg_temp_free_ptr(fpstatus);
5906
tcg_temp_free_i32(tmp2);
5908
neon_store_reg(rd, pass, tmp);
5911
case 3: /* VQDMLAL scalar */
5912
case 7: /* VQDMLSL scalar */
5913
case 11: /* VQDMULL scalar */
5918
case 2: /* VMLAL sclar */
5919
case 6: /* VMLSL scalar */
5920
case 10: /* VMULL scalar */
5924
tmp2 = neon_get_scalar(size, rm);
5925
/* We need a copy of tmp2 because gen_neon_mull
5926
* deletes it during pass 0. */
5927
tmp4 = tcg_temp_new_i32();
5928
tcg_gen_mov_i32(tmp4, tmp2);
5929
tmp3 = neon_load_reg(rn, 1);
5931
for (pass = 0; pass < 2; pass++) {
5933
tmp = neon_load_reg(rn, 0);
5938
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5940
neon_load_reg64(cpu_V1, rd + pass);
5944
gen_neon_negl(cpu_V0, size);
5947
gen_neon_addl(size);
5950
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5952
gen_neon_negl(cpu_V0, size);
5954
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5960
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5965
neon_store_reg64(cpu_V0, rd + pass);
5970
default: /* 14 and 15 are RESERVED */
5974
} else { /* size == 3 */
5977
imm = (insn >> 8) & 0xf;
5982
if (q && ((rd | rn | rm) & 1)) {
5987
neon_load_reg64(cpu_V0, rn);
5989
neon_load_reg64(cpu_V1, rn + 1);
5991
} else if (imm == 8) {
5992
neon_load_reg64(cpu_V0, rn + 1);
5994
neon_load_reg64(cpu_V1, rm);
5997
tmp64 = tcg_temp_new_i64();
5999
neon_load_reg64(cpu_V0, rn);
6000
neon_load_reg64(tmp64, rn + 1);
6002
neon_load_reg64(cpu_V0, rn + 1);
6003
neon_load_reg64(tmp64, rm);
6005
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6006
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6007
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6009
neon_load_reg64(cpu_V1, rm);
6011
neon_load_reg64(cpu_V1, rm + 1);
6014
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6015
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6016
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6017
tcg_temp_free_i64(tmp64);
6020
neon_load_reg64(cpu_V0, rn);
6021
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6022
neon_load_reg64(cpu_V1, rm);
6023
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6024
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6026
neon_store_reg64(cpu_V0, rd);
6028
neon_store_reg64(cpu_V1, rd + 1);
6030
} else if ((insn & (1 << 11)) == 0) {
6031
/* Two register misc. */
6032
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6033
size = (insn >> 18) & 3;
6034
/* UNDEF for unknown op values and bad op-size combinations */
6035
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6038
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6039
q && ((rm | rd) & 1)) {
6043
case NEON_2RM_VREV64:
6044
for (pass = 0; pass < (q ? 2 : 1); pass++) {
6045
tmp = neon_load_reg(rm, pass * 2);
6046
tmp2 = neon_load_reg(rm, pass * 2 + 1);
6048
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6049
case 1: gen_swap_half(tmp); break;
6050
case 2: /* no-op */ break;
6053
neon_store_reg(rd, pass * 2 + 1, tmp);
6055
neon_store_reg(rd, pass * 2, tmp2);
6058
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6059
case 1: gen_swap_half(tmp2); break;
6062
neon_store_reg(rd, pass * 2, tmp2);
6066
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6067
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6068
for (pass = 0; pass < q + 1; pass++) {
6069
tmp = neon_load_reg(rm, pass * 2);
6070
gen_neon_widen(cpu_V0, tmp, size, op & 1);
6071
tmp = neon_load_reg(rm, pass * 2 + 1);
6072
gen_neon_widen(cpu_V1, tmp, size, op & 1);
6074
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6075
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6076
case 2: tcg_gen_add_i64(CPU_V001); break;
6079
if (op >= NEON_2RM_VPADAL) {
6081
neon_load_reg64(cpu_V1, rd + pass);
6082
gen_neon_addl(size);
6084
neon_store_reg64(cpu_V0, rd + pass);
6090
for (n = 0; n < (q ? 4 : 2); n += 2) {
6091
tmp = neon_load_reg(rm, n);
6092
tmp2 = neon_load_reg(rd, n + 1);
6093
neon_store_reg(rm, n, tmp2);
6094
neon_store_reg(rd, n + 1, tmp);
6101
if (gen_neon_unzip(rd, rm, size, q)) {
6106
if (gen_neon_zip(rd, rm, size, q)) {
6110
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6111
/* also VQMOVUN; op field and mnemonics don't line up */
6115
TCGV_UNUSED_I32(tmp2);
6116
for (pass = 0; pass < 2; pass++) {
6117
neon_load_reg64(cpu_V0, rm + pass);
6118
tmp = tcg_temp_new_i32();
6119
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6124
neon_store_reg(rd, 0, tmp2);
6125
neon_store_reg(rd, 1, tmp);
6129
case NEON_2RM_VSHLL:
6130
if (q || (rd & 1)) {
6133
tmp = neon_load_reg(rm, 0);
6134
tmp2 = neon_load_reg(rm, 1);
6135
for (pass = 0; pass < 2; pass++) {
6138
gen_neon_widen(cpu_V0, tmp, size, 1);
6139
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6140
neon_store_reg64(cpu_V0, rd + pass);
6143
case NEON_2RM_VCVT_F16_F32:
6144
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6148
tmp = tcg_temp_new_i32();
6149
tmp2 = tcg_temp_new_i32();
6150
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6151
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6152
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6153
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6154
tcg_gen_shli_i32(tmp2, tmp2, 16);
6155
tcg_gen_or_i32(tmp2, tmp2, tmp);
6156
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6157
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6158
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6159
neon_store_reg(rd, 0, tmp2);
6160
tmp2 = tcg_temp_new_i32();
6161
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6162
tcg_gen_shli_i32(tmp2, tmp2, 16);
6163
tcg_gen_or_i32(tmp2, tmp2, tmp);
6164
neon_store_reg(rd, 1, tmp2);
6165
tcg_temp_free_i32(tmp);
6167
case NEON_2RM_VCVT_F32_F16:
6168
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6172
tmp3 = tcg_temp_new_i32();
6173
tmp = neon_load_reg(rm, 0);
6174
tmp2 = neon_load_reg(rm, 1);
6175
tcg_gen_ext16u_i32(tmp3, tmp);
6176
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6177
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6178
tcg_gen_shri_i32(tmp3, tmp, 16);
6179
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6180
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6181
tcg_temp_free_i32(tmp);
6182
tcg_gen_ext16u_i32(tmp3, tmp2);
6183
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6184
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6185
tcg_gen_shri_i32(tmp3, tmp2, 16);
6186
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6187
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6188
tcg_temp_free_i32(tmp2);
6189
tcg_temp_free_i32(tmp3);
6193
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6194
if (neon_2rm_is_float_op(op)) {
6195
tcg_gen_ld_f32(cpu_F0s, cpu_env,
6196
neon_reg_offset(rm, pass));
6197
TCGV_UNUSED_I32(tmp);
6199
tmp = neon_load_reg(rm, pass);
6202
case NEON_2RM_VREV32:
6204
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6205
case 1: gen_swap_half(tmp); break;
6209
case NEON_2RM_VREV16:
6214
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6215
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6216
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6222
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6223
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6224
case 2: gen_helper_clz(tmp, tmp); break;
6229
gen_helper_neon_cnt_u8(tmp, tmp);
6232
tcg_gen_not_i32(tmp, tmp);
6234
case NEON_2RM_VQABS:
6237
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6240
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6243
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6248
case NEON_2RM_VQNEG:
6251
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6254
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6257
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6262
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6263
tmp2 = tcg_const_i32(0);
6265
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6266
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6267
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6270
tcg_temp_free_i32(tmp2);
6271
if (op == NEON_2RM_VCLE0) {
6272
tcg_gen_not_i32(tmp, tmp);
6275
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6276
tmp2 = tcg_const_i32(0);
6278
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6279
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6280
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6283
tcg_temp_free_i32(tmp2);
6284
if (op == NEON_2RM_VCLT0) {
6285
tcg_gen_not_i32(tmp, tmp);
6288
case NEON_2RM_VCEQ0:
6289
tmp2 = tcg_const_i32(0);
6291
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6292
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6293
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6296
tcg_temp_free_i32(tmp2);
6300
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6301
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6302
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6307
tmp2 = tcg_const_i32(0);
6308
gen_neon_rsb(size, tmp, tmp2);
6309
tcg_temp_free_i32(tmp2);
6311
case NEON_2RM_VCGT0_F:
6313
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6314
tmp2 = tcg_const_i32(0);
6315
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6316
tcg_temp_free_i32(tmp2);
6317
tcg_temp_free_ptr(fpstatus);
6320
case NEON_2RM_VCGE0_F:
6322
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6323
tmp2 = tcg_const_i32(0);
6324
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6325
tcg_temp_free_i32(tmp2);
6326
tcg_temp_free_ptr(fpstatus);
6329
case NEON_2RM_VCEQ0_F:
6331
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6332
tmp2 = tcg_const_i32(0);
6333
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6334
tcg_temp_free_i32(tmp2);
6335
tcg_temp_free_ptr(fpstatus);
6338
case NEON_2RM_VCLE0_F:
6340
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6341
tmp2 = tcg_const_i32(0);
6342
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6343
tcg_temp_free_i32(tmp2);
6344
tcg_temp_free_ptr(fpstatus);
6347
case NEON_2RM_VCLT0_F:
6349
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6350
tmp2 = tcg_const_i32(0);
6351
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6352
tcg_temp_free_i32(tmp2);
6353
tcg_temp_free_ptr(fpstatus);
6356
case NEON_2RM_VABS_F:
6359
case NEON_2RM_VNEG_F:
6363
tmp2 = neon_load_reg(rd, pass);
6364
neon_store_reg(rm, pass, tmp2);
6367
tmp2 = neon_load_reg(rd, pass);
6369
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6370
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6373
neon_store_reg(rm, pass, tmp2);
6375
case NEON_2RM_VRECPE:
6376
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6378
case NEON_2RM_VRSQRTE:
6379
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6381
case NEON_2RM_VRECPE_F:
6382
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6384
case NEON_2RM_VRSQRTE_F:
6385
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6387
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6390
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6393
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6394
gen_vfp_tosiz(0, 1);
6396
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6397
gen_vfp_touiz(0, 1);
6400
/* Reserved op values were caught by the
6401
* neon_2rm_sizes[] check earlier.
6405
if (neon_2rm_is_float_op(op)) {
6406
tcg_gen_st_f32(cpu_F0s, cpu_env,
6407
neon_reg_offset(rd, pass));
6409
neon_store_reg(rd, pass, tmp);
6414
} else if ((insn & (1 << 10)) == 0) {
6416
int n = ((insn >> 8) & 3) + 1;
6417
if ((rn + n) > 32) {
6418
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6419
* helper function running off the end of the register file.
6424
if (insn & (1 << 6)) {
6425
tmp = neon_load_reg(rd, 0);
6427
tmp = tcg_temp_new_i32();
6428
tcg_gen_movi_i32(tmp, 0);
6430
tmp2 = neon_load_reg(rm, 0);
6431
tmp4 = tcg_const_i32(rn);
6432
tmp5 = tcg_const_i32(n);
6433
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6434
tcg_temp_free_i32(tmp);
6435
if (insn & (1 << 6)) {
6436
tmp = neon_load_reg(rd, 1);
6438
tmp = tcg_temp_new_i32();
6439
tcg_gen_movi_i32(tmp, 0);
6441
tmp3 = neon_load_reg(rm, 1);
6442
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6443
tcg_temp_free_i32(tmp5);
6444
tcg_temp_free_i32(tmp4);
6445
neon_store_reg(rd, 0, tmp2);
6446
neon_store_reg(rd, 1, tmp3);
6447
tcg_temp_free_i32(tmp);
6448
} else if ((insn & 0x380) == 0) {
6450
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6453
if (insn & (1 << 19)) {
6454
tmp = neon_load_reg(rm, 1);
6456
tmp = neon_load_reg(rm, 0);
6458
if (insn & (1 << 16)) {
6459
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6460
} else if (insn & (1 << 17)) {
6461
if ((insn >> 18) & 1)
6462
gen_neon_dup_high16(tmp);
6464
gen_neon_dup_low16(tmp);
6466
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6467
tmp2 = tcg_temp_new_i32();
6468
tcg_gen_mov_i32(tmp2, tmp);
6469
neon_store_reg(rd, pass, tmp2);
6471
tcg_temp_free_i32(tmp);
6480
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6482
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6483
const ARMCPRegInfo *ri;
6485
cpnum = (insn >> 8) & 0xf;
6486
if (arm_feature(env, ARM_FEATURE_XSCALE)
6487
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6490
/* First check for coprocessor space used for actual instructions */
6494
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6495
return disas_iwmmxt_insn(env, s, insn);
6496
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6497
return disas_dsp_insn(env, s, insn);
6504
/* Otherwise treat as a generic register access */
6505
is64 = (insn & (1 << 25)) == 0;
6506
if (!is64 && ((insn & (1 << 4)) == 0)) {
6514
opc1 = (insn >> 4) & 0xf;
6516
rt2 = (insn >> 16) & 0xf;
6518
crn = (insn >> 16) & 0xf;
6519
opc1 = (insn >> 21) & 7;
6520
opc2 = (insn >> 5) & 7;
6523
isread = (insn >> 20) & 1;
6524
rt = (insn >> 12) & 0xf;
6526
ri = get_arm_cp_reginfo(s->cp_regs,
6527
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6529
/* Check access permissions */
6530
if (!cp_access_ok(s->current_pl, ri, isread)) {
6534
/* Handle special cases first */
6535
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6542
gen_set_pc_im(s, s->pc);
6543
s->is_jmp = DISAS_WFI;
6549
if (use_icount && (ri->type & ARM_CP_IO)) {
6558
if (ri->type & ARM_CP_CONST) {
6559
tmp64 = tcg_const_i64(ri->resetvalue);
6560
} else if (ri->readfn) {
6562
gen_set_pc_im(s, s->pc);
6563
tmp64 = tcg_temp_new_i64();
6564
tmpptr = tcg_const_ptr(ri);
6565
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6566
tcg_temp_free_ptr(tmpptr);
6568
tmp64 = tcg_temp_new_i64();
6569
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6571
tmp = tcg_temp_new_i32();
6572
tcg_gen_trunc_i64_i32(tmp, tmp64);
6573
store_reg(s, rt, tmp);
6574
tcg_gen_shri_i64(tmp64, tmp64, 32);
6575
tmp = tcg_temp_new_i32();
6576
tcg_gen_trunc_i64_i32(tmp, tmp64);
6577
tcg_temp_free_i64(tmp64);
6578
store_reg(s, rt2, tmp);
6581
if (ri->type & ARM_CP_CONST) {
6582
tmp = tcg_const_i32(ri->resetvalue);
6583
} else if (ri->readfn) {
6585
gen_set_pc_im(s, s->pc);
6586
tmp = tcg_temp_new_i32();
6587
tmpptr = tcg_const_ptr(ri);
6588
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6589
tcg_temp_free_ptr(tmpptr);
6591
tmp = load_cpu_offset(ri->fieldoffset);
6594
/* Destination register of r15 for 32 bit loads sets
6595
* the condition codes from the high 4 bits of the value
6598
tcg_temp_free_i32(tmp);
6600
store_reg(s, rt, tmp);
6605
if (ri->type & ARM_CP_CONST) {
6606
/* If not forbidden by access permissions, treat as WI */
6611
TCGv_i32 tmplo, tmphi;
6612
TCGv_i64 tmp64 = tcg_temp_new_i64();
6613
tmplo = load_reg(s, rt);
6614
tmphi = load_reg(s, rt2);
6615
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6616
tcg_temp_free_i32(tmplo);
6617
tcg_temp_free_i32(tmphi);
6619
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6620
gen_set_pc_im(s, s->pc);
6621
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6622
tcg_temp_free_ptr(tmpptr);
6624
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6626
tcg_temp_free_i64(tmp64);
6631
gen_set_pc_im(s, s->pc);
6632
tmp = load_reg(s, rt);
6633
tmpptr = tcg_const_ptr(ri);
6634
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6635
tcg_temp_free_ptr(tmpptr);
6636
tcg_temp_free_i32(tmp);
6638
TCGv_i32 tmp = load_reg(s, rt);
6639
store_cpu_offset(tmp, ri->fieldoffset);
6644
if (use_icount && (ri->type & ARM_CP_IO)) {
6645
/* I/O operations must end the TB here (whether read or write) */
6648
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6649
/* We default to ending the TB on a coprocessor register write,
6650
* but allow this to be suppressed by the register definition
6651
* (usually only necessary to work around guest bugs).
6663
/* Store a 64-bit value to a register pair. Clobbers val. */
6664
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6667
tmp = tcg_temp_new_i32();
6668
tcg_gen_trunc_i64_i32(tmp, val);
6669
store_reg(s, rlow, tmp);
6670
tmp = tcg_temp_new_i32();
6671
tcg_gen_shri_i64(val, val, 32);
6672
tcg_gen_trunc_i64_i32(tmp, val);
6673
store_reg(s, rhigh, tmp);
6676
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6677
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6682
/* Load value and extend to 64 bits. */
6683
tmp = tcg_temp_new_i64();
6684
tmp2 = load_reg(s, rlow);
6685
tcg_gen_extu_i32_i64(tmp, tmp2);
6686
tcg_temp_free_i32(tmp2);
6687
tcg_gen_add_i64(val, val, tmp);
6688
tcg_temp_free_i64(tmp);
6691
/* load and add a 64-bit value from a register pair. */
6692
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6698
/* Load 64-bit value rd:rn. */
6699
tmpl = load_reg(s, rlow);
6700
tmph = load_reg(s, rhigh);
6701
tmp = tcg_temp_new_i64();
6702
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6703
tcg_temp_free_i32(tmpl);
6704
tcg_temp_free_i32(tmph);
6705
tcg_gen_add_i64(val, val, tmp);
6706
tcg_temp_free_i64(tmp);
6709
/* Set N and Z flags from hi|lo. */
6710
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6712
tcg_gen_mov_i32(cpu_NF, hi);
6713
tcg_gen_or_i32(cpu_ZF, lo, hi);
6716
/* Load/Store exclusive instructions are implemented by remembering
6717
the value/address loaded, and seeing if these are the same
6718
when the store is performed. This should be sufficient to implement
6719
the architecturally mandated semantics, and avoids having to monitor
6722
In system emulation mode only one CPU will be running at once, so
6723
this sequence is effectively atomic. In user emulation mode we
6724
throw an exception and handle the atomic operation elsewhere. */
6725
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6726
TCGv_i32 addr, int size)
6728
TCGv_i32 tmp = tcg_temp_new_i32();
6732
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6735
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6739
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6746
TCGv_i32 tmp2 = tcg_temp_new_i32();
6747
TCGv_i32 tmp3 = tcg_temp_new_i32();
6749
tcg_gen_addi_i32(tmp2, addr, 4);
6750
gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6751
tcg_temp_free_i32(tmp2);
6752
tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
6753
store_reg(s, rt2, tmp3);
6755
tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
6758
store_reg(s, rt, tmp);
6759
tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
6762
static void gen_clrex(DisasContext *s)
6764
tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6767
#ifdef CONFIG_USER_ONLY
6768
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6769
TCGv_i32 addr, int size)
6771
tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
6772
tcg_gen_movi_i32(cpu_exclusive_info,
6773
size | (rd << 4) | (rt << 8) | (rt2 << 12));
6774
gen_exception_insn(s, 4, EXCP_STREX);
6777
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6778
TCGv_i32 addr, int size)
6781
TCGv_i64 val64, extaddr;
6785
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6791
fail_label = gen_new_label();
6792
done_label = gen_new_label();
6793
extaddr = tcg_temp_new_i64();
6794
tcg_gen_extu_i32_i64(extaddr, addr);
6795
tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
6796
tcg_temp_free_i64(extaddr);
6798
tmp = tcg_temp_new_i32();
6801
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6804
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6808
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6814
val64 = tcg_temp_new_i64();
6816
TCGv_i32 tmp2 = tcg_temp_new_i32();
6817
TCGv_i32 tmp3 = tcg_temp_new_i32();
6818
tcg_gen_addi_i32(tmp2, addr, 4);
6819
gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6820
tcg_temp_free_i32(tmp2);
6821
tcg_gen_concat_i32_i64(val64, tmp, tmp3);
6822
tcg_temp_free_i32(tmp3);
6824
tcg_gen_extu_i32_i64(val64, tmp);
6826
tcg_temp_free_i32(tmp);
6828
tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
6829
tcg_temp_free_i64(val64);
6831
tmp = load_reg(s, rt);
6834
gen_aa32_st8(tmp, addr, IS_USER(s));
6837
gen_aa32_st16(tmp, addr, IS_USER(s));
6841
gen_aa32_st32(tmp, addr, IS_USER(s));
6846
tcg_temp_free_i32(tmp);
6848
tcg_gen_addi_i32(addr, addr, 4);
6849
tmp = load_reg(s, rt2);
6850
gen_aa32_st32(tmp, addr, IS_USER(s));
6851
tcg_temp_free_i32(tmp);
6853
tcg_gen_movi_i32(cpu_R[rd], 0);
6854
tcg_gen_br(done_label);
6855
gen_set_label(fail_label);
6856
tcg_gen_movi_i32(cpu_R[rd], 1);
6857
gen_set_label(done_label);
6858
tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6865
* @mode: mode field from insn (which stack to store to)
6866
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6867
* @writeback: true if writeback bit set
6869
* Generate code for the SRS (Store Return State) insn.
6871
static void gen_srs(DisasContext *s,
6872
uint32_t mode, uint32_t amode, bool writeback)
6875
TCGv_i32 addr = tcg_temp_new_i32();
6876
TCGv_i32 tmp = tcg_const_i32(mode);
6877
gen_helper_get_r13_banked(addr, cpu_env, tmp);
6878
tcg_temp_free_i32(tmp);
6895
tcg_gen_addi_i32(addr, addr, offset);
6896
tmp = load_reg(s, 14);
6897
gen_aa32_st32(tmp, addr, 0);
6898
tcg_temp_free_i32(tmp);
6899
tmp = load_cpu_field(spsr);
6900
tcg_gen_addi_i32(addr, addr, 4);
6901
gen_aa32_st32(tmp, addr, 0);
6902
tcg_temp_free_i32(tmp);
6920
tcg_gen_addi_i32(addr, addr, offset);
6921
tmp = tcg_const_i32(mode);
6922
gen_helper_set_r13_banked(cpu_env, tmp, addr);
6923
tcg_temp_free_i32(tmp);
6925
tcg_temp_free_i32(addr);
6928
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6930
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6937
insn = arm_ldl_code(env, s->pc, s->bswap_code);
6940
/* M variants do not implement ARM mode. */
6945
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6946
* choose to UNDEF. In ARMv5 and above the space is used
6947
* for miscellaneous unconditional instructions.
6951
/* Unconditional instructions. */
6952
if (((insn >> 25) & 7) == 1) {
6953
/* NEON Data processing. */
6954
if (!arm_feature(env, ARM_FEATURE_NEON))
6957
if (disas_neon_data_insn(env, s, insn))
6961
if ((insn & 0x0f100000) == 0x04000000) {
6962
/* NEON load/store. */
6963
if (!arm_feature(env, ARM_FEATURE_NEON))
6966
if (disas_neon_ls_insn(env, s, insn))
6970
if ((insn & 0x0f000e10) == 0x0e000a00) {
6972
if (disas_vfp_insn(env, s, insn)) {
6977
if (((insn & 0x0f30f000) == 0x0510f000) ||
6978
((insn & 0x0f30f010) == 0x0710f000)) {
6979
if ((insn & (1 << 22)) == 0) {
6981
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6985
/* Otherwise PLD; v5TE+ */
6989
if (((insn & 0x0f70f000) == 0x0450f000) ||
6990
((insn & 0x0f70f010) == 0x0650f000)) {
6992
return; /* PLI; V7 */
6994
if (((insn & 0x0f700000) == 0x04100000) ||
6995
((insn & 0x0f700010) == 0x06100000)) {
6996
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6999
return; /* v7MP: Unallocated memory hint: must NOP */
7002
if ((insn & 0x0ffffdff) == 0x01010000) {
7005
if (((insn >> 9) & 1) != s->bswap_code) {
7006
/* Dynamic endianness switching not implemented. */
7007
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7011
} else if ((insn & 0x0fffff00) == 0x057ff000) {
7012
switch ((insn >> 4) & 0xf) {
7021
/* We don't emulate caches so these are a no-op. */
7026
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7032
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7034
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7040
rn = (insn >> 16) & 0xf;
7041
addr = load_reg(s, rn);
7042
i = (insn >> 23) & 3;
7044
case 0: offset = -4; break; /* DA */
7045
case 1: offset = 0; break; /* IA */
7046
case 2: offset = -8; break; /* DB */
7047
case 3: offset = 4; break; /* IB */
7051
tcg_gen_addi_i32(addr, addr, offset);
7052
/* Load PC into tmp and CPSR into tmp2. */
7053
tmp = tcg_temp_new_i32();
7054
gen_aa32_ld32u(tmp, addr, 0);
7055
tcg_gen_addi_i32(addr, addr, 4);
7056
tmp2 = tcg_temp_new_i32();
7057
gen_aa32_ld32u(tmp2, addr, 0);
7058
if (insn & (1 << 21)) {
7059
/* Base writeback. */
7061
case 0: offset = -8; break;
7062
case 1: offset = 4; break;
7063
case 2: offset = -4; break;
7064
case 3: offset = 0; break;
7068
tcg_gen_addi_i32(addr, addr, offset);
7069
store_reg(s, rn, addr);
7071
tcg_temp_free_i32(addr);
7073
gen_rfe(s, tmp, tmp2);
7075
} else if ((insn & 0x0e000000) == 0x0a000000) {
7076
/* branch link and change to thumb (blx <offset>) */
7079
val = (uint32_t)s->pc;
7080
tmp = tcg_temp_new_i32();
7081
tcg_gen_movi_i32(tmp, val);
7082
store_reg(s, 14, tmp);
7083
/* Sign-extend the 24-bit offset */
7084
offset = (((int32_t)insn) << 8) >> 8;
7085
/* offset * 4 + bit24 * 2 + (thumb bit) */
7086
val += (offset << 2) | ((insn >> 23) & 2) | 1;
7087
/* pipeline offset */
7089
/* protected by ARCH(5); above, near the start of uncond block */
7092
} else if ((insn & 0x0e000f00) == 0x0c000100) {
7093
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7094
/* iWMMXt register transfer. */
7095
if (env->cp15.c15_cpar & (1 << 1))
7096
if (!disas_iwmmxt_insn(env, s, insn))
7099
} else if ((insn & 0x0fe00000) == 0x0c400000) {
7100
/* Coprocessor double register transfer. */
7102
/* XXX doesn't belong in the trustzone patch: should just UNDEF? */
7103
cpu_abort(env, "unsupported coprocessor double register transfer\n");
7104
} else if ((insn & 0x0f000010) == 0x0e000010) {
7105
/* Additional coprocessor register transfer. */
7106
if (!disas_coproc_insn(env, s, insn)) {
7109
} else if ((insn & 0x0ff10020) == 0x01000000) {
7112
/* cps (privileged) */
7116
if (insn & (1 << 19)) {
7117
if (insn & (1 << 8))
7119
if (insn & (1 << 7))
7121
if (insn & (1 << 6))
7123
if (insn & (1 << 18))
7126
if (insn & (1 << 17)) {
7128
val |= (insn & 0x1f);
7131
gen_set_psr_im(s, mask, 0, val);
7138
/* if not always execute, we generate a conditional jump to
7140
s->condlabel = gen_new_label();
7141
arm_gen_test_cc(cond ^ 1, s->condlabel);
7144
if ((insn & 0x0f900000) == 0x03000000) {
7145
if ((insn & (1 << 21)) == 0) {
7147
rd = (insn >> 12) & 0xf;
7148
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7149
if ((insn & (1 << 22)) == 0) {
7151
tmp = tcg_temp_new_i32();
7152
tcg_gen_movi_i32(tmp, val);
7155
tmp = load_reg(s, rd);
7156
tcg_gen_ext16u_i32(tmp, tmp);
7157
tcg_gen_ori_i32(tmp, tmp, val << 16);
7159
store_reg(s, rd, tmp);
7161
if (((insn >> 12) & 0xf) != 0xf)
7163
if (((insn >> 16) & 0xf) == 0) {
7164
gen_nop_hint(s, insn & 0xff);
7166
/* CPSR = immediate */
7168
shift = ((insn >> 8) & 0xf) * 2;
7170
val = (val >> shift) | (val << (32 - shift));
7171
i = ((insn & (1 << 22)) != 0);
7172
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7176
} else if ((insn & 0x0f900000) == 0x01000000
7177
&& (insn & 0x00000090) != 0x00000090) {
7178
/* miscellaneous instructions */
7179
op1 = (insn >> 21) & 3;
7180
sh = (insn >> 4) & 0xf;
7183
case 0x0: /* move program status register */
7186
tmp = load_reg(s, rm);
7187
i = ((op1 & 2) != 0);
7188
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7192
rd = (insn >> 12) & 0xf;
7196
tmp = load_cpu_field(spsr);
7198
tmp = tcg_temp_new_i32();
7199
gen_helper_cpsr_read(tmp, cpu_env);
7201
store_reg(s, rd, tmp);
7206
/* branch/exchange thumb (bx). */
7208
tmp = load_reg(s, rm);
7210
} else if (op1 == 3) {
7213
rd = (insn >> 12) & 0xf;
7214
tmp = load_reg(s, rm);
7215
gen_helper_clz(tmp, tmp);
7216
store_reg(s, rd, tmp);
7224
/* Trivial implementation equivalent to bx. */
7225
tmp = load_reg(s, rm);
7236
/* branch link/exchange thumb (blx) */
7237
tmp = load_reg(s, rm);
7238
tmp2 = tcg_temp_new_i32();
7239
tcg_gen_movi_i32(tmp2, s->pc);
7240
store_reg(s, 14, tmp2);
7243
case 0x5: /* saturating add/subtract */
7245
rd = (insn >> 12) & 0xf;
7246
rn = (insn >> 16) & 0xf;
7247
tmp = load_reg(s, rm);
7248
tmp2 = load_reg(s, rn);
7250
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7252
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7254
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7255
tcg_temp_free_i32(tmp2);
7256
store_reg(s, rd, tmp);
7262
gen_exception_insn(s, 4, EXCP_BKPT);
7263
} else if (op1 == 3) {
7265
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
7273
case 0x8: /* signed multiply */
7278
rs = (insn >> 8) & 0xf;
7279
rn = (insn >> 12) & 0xf;
7280
rd = (insn >> 16) & 0xf;
7282
/* (32 * 16) >> 16 */
7283
tmp = load_reg(s, rm);
7284
tmp2 = load_reg(s, rs);
7286
tcg_gen_sari_i32(tmp2, tmp2, 16);
7289
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7290
tcg_gen_shri_i64(tmp64, tmp64, 16);
7291
tmp = tcg_temp_new_i32();
7292
tcg_gen_trunc_i64_i32(tmp, tmp64);
7293
tcg_temp_free_i64(tmp64);
7294
if ((sh & 2) == 0) {
7295
tmp2 = load_reg(s, rn);
7296
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7297
tcg_temp_free_i32(tmp2);
7299
store_reg(s, rd, tmp);
7302
tmp = load_reg(s, rm);
7303
tmp2 = load_reg(s, rs);
7304
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7305
tcg_temp_free_i32(tmp2);
7307
tmp64 = tcg_temp_new_i64();
7308
tcg_gen_ext_i32_i64(tmp64, tmp);
7309
tcg_temp_free_i32(tmp);
7310
gen_addq(s, tmp64, rn, rd);
7311
gen_storeq_reg(s, rn, rd, tmp64);
7312
tcg_temp_free_i64(tmp64);
7315
tmp2 = load_reg(s, rn);
7316
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7317
tcg_temp_free_i32(tmp2);
7319
store_reg(s, rd, tmp);
7326
} else if (((insn & 0x0e000000) == 0 &&
7327
(insn & 0x00000090) != 0x90) ||
7328
((insn & 0x0e000000) == (1 << 25))) {
7329
int set_cc, logic_cc, shiftop;
7331
op1 = (insn >> 21) & 0xf;
7332
set_cc = (insn >> 20) & 1;
7333
logic_cc = table_logic_cc[op1] & set_cc;
7335
/* data processing instruction */
7336
if (insn & (1 << 25)) {
7337
/* immediate operand */
7339
shift = ((insn >> 8) & 0xf) * 2;
7341
val = (val >> shift) | (val << (32 - shift));
7343
tmp2 = tcg_temp_new_i32();
7344
tcg_gen_movi_i32(tmp2, val);
7345
if (logic_cc && shift) {
7346
gen_set_CF_bit31(tmp2);
7351
tmp2 = load_reg(s, rm);
7352
shiftop = (insn >> 5) & 3;
7353
if (!(insn & (1 << 4))) {
7354
shift = (insn >> 7) & 0x1f;
7355
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7357
rs = (insn >> 8) & 0xf;
7358
tmp = load_reg(s, rs);
7359
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7362
if (op1 != 0x0f && op1 != 0x0d) {
7363
rn = (insn >> 16) & 0xf;
7364
tmp = load_reg(s, rn);
7366
TCGV_UNUSED_I32(tmp);
7368
rd = (insn >> 12) & 0xf;
7371
tcg_gen_and_i32(tmp, tmp, tmp2);
7375
store_reg_bx(env, s, rd, tmp);
7378
tcg_gen_xor_i32(tmp, tmp, tmp2);
7382
store_reg_bx(env, s, rd, tmp);
7385
if (set_cc && rd == 15) {
7386
/* SUBS r15, ... is used for exception return. */
7390
gen_sub_CC(tmp, tmp, tmp2);
7391
gen_exception_return(s, tmp);
7394
gen_sub_CC(tmp, tmp, tmp2);
7396
tcg_gen_sub_i32(tmp, tmp, tmp2);
7398
store_reg_bx(env, s, rd, tmp);
7403
gen_sub_CC(tmp, tmp2, tmp);
7405
tcg_gen_sub_i32(tmp, tmp2, tmp);
7407
store_reg_bx(env, s, rd, tmp);
7411
gen_add_CC(tmp, tmp, tmp2);
7413
tcg_gen_add_i32(tmp, tmp, tmp2);
7415
store_reg_bx(env, s, rd, tmp);
7419
gen_adc_CC(tmp, tmp, tmp2);
7421
gen_add_carry(tmp, tmp, tmp2);
7423
store_reg_bx(env, s, rd, tmp);
7427
gen_sbc_CC(tmp, tmp, tmp2);
7429
gen_sub_carry(tmp, tmp, tmp2);
7431
store_reg_bx(env, s, rd, tmp);
7435
gen_sbc_CC(tmp, tmp2, tmp);
7437
gen_sub_carry(tmp, tmp2, tmp);
7439
store_reg_bx(env, s, rd, tmp);
7443
tcg_gen_and_i32(tmp, tmp, tmp2);
7446
tcg_temp_free_i32(tmp);
7450
tcg_gen_xor_i32(tmp, tmp, tmp2);
7453
tcg_temp_free_i32(tmp);
7457
gen_sub_CC(tmp, tmp, tmp2);
7459
tcg_temp_free_i32(tmp);
7463
gen_add_CC(tmp, tmp, tmp2);
7465
tcg_temp_free_i32(tmp);
7468
tcg_gen_or_i32(tmp, tmp, tmp2);
7472
store_reg_bx(env, s, rd, tmp);
7475
if (logic_cc && rd == 15) {
7476
/* MOVS r15, ... is used for exception return. */
7480
gen_exception_return(s, tmp2);
7485
store_reg_bx(env, s, rd, tmp2);
7489
tcg_gen_andc_i32(tmp, tmp, tmp2);
7493
store_reg_bx(env, s, rd, tmp);
7497
tcg_gen_not_i32(tmp2, tmp2);
7501
store_reg_bx(env, s, rd, tmp2);
7504
if (op1 != 0x0f && op1 != 0x0d) {
7505
tcg_temp_free_i32(tmp2);
7508
/* other instructions */
7509
op1 = (insn >> 24) & 0xf;
7513
/* multiplies, extra load/stores */
7514
sh = (insn >> 5) & 3;
7517
rd = (insn >> 16) & 0xf;
7518
rn = (insn >> 12) & 0xf;
7519
rs = (insn >> 8) & 0xf;
7521
op1 = (insn >> 20) & 0xf;
7523
case 0: case 1: case 2: case 3: case 6:
7525
tmp = load_reg(s, rs);
7526
tmp2 = load_reg(s, rm);
7527
tcg_gen_mul_i32(tmp, tmp, tmp2);
7528
tcg_temp_free_i32(tmp2);
7529
if (insn & (1 << 22)) {
7530
/* Subtract (mls) */
7532
tmp2 = load_reg(s, rn);
7533
tcg_gen_sub_i32(tmp, tmp2, tmp);
7534
tcg_temp_free_i32(tmp2);
7535
} else if (insn & (1 << 21)) {
7537
tmp2 = load_reg(s, rn);
7538
tcg_gen_add_i32(tmp, tmp, tmp2);
7539
tcg_temp_free_i32(tmp2);
7541
if (insn & (1 << 20))
7543
store_reg(s, rd, tmp);
7546
/* 64 bit mul double accumulate (UMAAL) */
7548
tmp = load_reg(s, rs);
7549
tmp2 = load_reg(s, rm);
7550
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7551
gen_addq_lo(s, tmp64, rn);
7552
gen_addq_lo(s, tmp64, rd);
7553
gen_storeq_reg(s, rn, rd, tmp64);
7554
tcg_temp_free_i64(tmp64);
7556
case 8: case 9: case 10: case 11:
7557
case 12: case 13: case 14: case 15:
7558
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7559
tmp = load_reg(s, rs);
7560
tmp2 = load_reg(s, rm);
7561
if (insn & (1 << 22)) {
7562
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7564
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7566
if (insn & (1 << 21)) { /* mult accumulate */
7567
TCGv_i32 al = load_reg(s, rn);
7568
TCGv_i32 ah = load_reg(s, rd);
7569
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7570
tcg_temp_free_i32(al);
7571
tcg_temp_free_i32(ah);
7573
if (insn & (1 << 20)) {
7574
gen_logicq_cc(tmp, tmp2);
7576
store_reg(s, rn, tmp);
7577
store_reg(s, rd, tmp2);
7583
rn = (insn >> 16) & 0xf;
7584
rd = (insn >> 12) & 0xf;
7585
if (insn & (1 << 23)) {
7586
/* load/store exclusive */
7587
int op2 = (insn >> 8) & 3;
7588
op1 = (insn >> 21) & 0x3;
7591
case 0: /* lda/stl */
7597
case 1: /* reserved */
7599
case 2: /* ldaex/stlex */
7602
case 3: /* ldrex/strex */
7611
addr = tcg_temp_local_new_i32();
7612
load_reg_var(s, addr, rn);
7614
/* Since the emulation does not have barriers,
7615
the acquire/release semantics need no special
7618
if (insn & (1 << 20)) {
7619
tmp = tcg_temp_new_i32();
7622
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7625
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7628
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7633
store_reg(s, rd, tmp);
7636
tmp = load_reg(s, rm);
7639
gen_aa32_st32(tmp, addr, IS_USER(s));
7642
gen_aa32_st8(tmp, addr, IS_USER(s));
7645
gen_aa32_st16(tmp, addr, IS_USER(s));
7650
tcg_temp_free_i32(tmp);
7652
} else if (insn & (1 << 20)) {
7655
gen_load_exclusive(s, rd, 15, addr, 2);
7657
case 1: /* ldrexd */
7658
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7660
case 2: /* ldrexb */
7661
gen_load_exclusive(s, rd, 15, addr, 0);
7663
case 3: /* ldrexh */
7664
gen_load_exclusive(s, rd, 15, addr, 1);
7673
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7675
case 1: /* strexd */
7676
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7678
case 2: /* strexb */
7679
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7681
case 3: /* strexh */
7682
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7688
tcg_temp_free_i32(addr);
7690
/* SWP instruction */
7693
/* ??? This is not really atomic. However we know
7694
we never have multiple CPUs running in parallel,
7695
so it is good enough. */
7696
addr = load_reg(s, rn);
7697
tmp = load_reg(s, rm);
7698
tmp2 = tcg_temp_new_i32();
7699
if (insn & (1 << 22)) {
7700
gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7701
gen_aa32_st8(tmp, addr, IS_USER(s));
7703
gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7704
gen_aa32_st32(tmp, addr, IS_USER(s));
7706
tcg_temp_free_i32(tmp);
7707
tcg_temp_free_i32(addr);
7708
store_reg(s, rd, tmp2);
7714
/* Misc load/store */
7715
rn = (insn >> 16) & 0xf;
7716
rd = (insn >> 12) & 0xf;
7717
addr = load_reg(s, rn);
7718
if (insn & (1 << 24))
7719
gen_add_datah_offset(s, insn, 0, addr);
7721
if (insn & (1 << 20)) {
7723
tmp = tcg_temp_new_i32();
7726
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7729
gen_aa32_ld8s(tmp, addr, IS_USER(s));
7733
gen_aa32_ld16s(tmp, addr, IS_USER(s));
7737
} else if (sh & 2) {
7742
tmp = load_reg(s, rd);
7743
gen_aa32_st32(tmp, addr, IS_USER(s));
7744
tcg_temp_free_i32(tmp);
7745
tcg_gen_addi_i32(addr, addr, 4);
7746
tmp = load_reg(s, rd + 1);
7747
gen_aa32_st32(tmp, addr, IS_USER(s));
7748
tcg_temp_free_i32(tmp);
7752
tmp = tcg_temp_new_i32();
7753
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7754
store_reg(s, rd, tmp);
7755
tcg_gen_addi_i32(addr, addr, 4);
7756
tmp = tcg_temp_new_i32();
7757
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7761
address_offset = -4;
7764
tmp = load_reg(s, rd);
7765
gen_aa32_st16(tmp, addr, IS_USER(s));
7766
tcg_temp_free_i32(tmp);
7769
/* Perform base writeback before the loaded value to
7770
ensure correct behavior with overlapping index registers.
7771
ldrd with base writeback is is undefined if the
7772
destination and index registers overlap. */
7773
if (!(insn & (1 << 24))) {
7774
gen_add_datah_offset(s, insn, address_offset, addr);
7775
store_reg(s, rn, addr);
7776
} else if (insn & (1 << 21)) {
7778
tcg_gen_addi_i32(addr, addr, address_offset);
7779
store_reg(s, rn, addr);
7781
tcg_temp_free_i32(addr);
7784
/* Complete the load. */
7785
store_reg(s, rd, tmp);
7794
if (insn & (1 << 4)) {
7796
/* Armv6 Media instructions. */
7798
rn = (insn >> 16) & 0xf;
7799
rd = (insn >> 12) & 0xf;
7800
rs = (insn >> 8) & 0xf;
7801
switch ((insn >> 23) & 3) {
7802
case 0: /* Parallel add/subtract. */
7803
op1 = (insn >> 20) & 7;
7804
tmp = load_reg(s, rn);
7805
tmp2 = load_reg(s, rm);
7806
sh = (insn >> 5) & 7;
7807
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7809
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7810
tcg_temp_free_i32(tmp2);
7811
store_reg(s, rd, tmp);
7814
if ((insn & 0x00700020) == 0) {
7815
/* Halfword pack. */
7816
tmp = load_reg(s, rn);
7817
tmp2 = load_reg(s, rm);
7818
shift = (insn >> 7) & 0x1f;
7819
if (insn & (1 << 6)) {
7823
tcg_gen_sari_i32(tmp2, tmp2, shift);
7824
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7825
tcg_gen_ext16u_i32(tmp2, tmp2);
7829
tcg_gen_shli_i32(tmp2, tmp2, shift);
7830
tcg_gen_ext16u_i32(tmp, tmp);
7831
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7833
tcg_gen_or_i32(tmp, tmp, tmp2);
7834
tcg_temp_free_i32(tmp2);
7835
store_reg(s, rd, tmp);
7836
} else if ((insn & 0x00200020) == 0x00200000) {
7838
tmp = load_reg(s, rm);
7839
shift = (insn >> 7) & 0x1f;
7840
if (insn & (1 << 6)) {
7843
tcg_gen_sari_i32(tmp, tmp, shift);
7845
tcg_gen_shli_i32(tmp, tmp, shift);
7847
sh = (insn >> 16) & 0x1f;
7848
tmp2 = tcg_const_i32(sh);
7849
if (insn & (1 << 22))
7850
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7852
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7853
tcg_temp_free_i32(tmp2);
7854
store_reg(s, rd, tmp);
7855
} else if ((insn & 0x00300fe0) == 0x00200f20) {
7857
tmp = load_reg(s, rm);
7858
sh = (insn >> 16) & 0x1f;
7859
tmp2 = tcg_const_i32(sh);
7860
if (insn & (1 << 22))
7861
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7863
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7864
tcg_temp_free_i32(tmp2);
7865
store_reg(s, rd, tmp);
7866
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
7868
tmp = load_reg(s, rn);
7869
tmp2 = load_reg(s, rm);
7870
tmp3 = tcg_temp_new_i32();
7871
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7872
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7873
tcg_temp_free_i32(tmp3);
7874
tcg_temp_free_i32(tmp2);
7875
store_reg(s, rd, tmp);
7876
} else if ((insn & 0x000003e0) == 0x00000060) {
7877
tmp = load_reg(s, rm);
7878
shift = (insn >> 10) & 3;
7879
/* ??? In many cases it's not necessary to do a
7880
rotate, a shift is sufficient. */
7882
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7883
op1 = (insn >> 20) & 7;
7885
case 0: gen_sxtb16(tmp); break;
7886
case 2: gen_sxtb(tmp); break;
7887
case 3: gen_sxth(tmp); break;
7888
case 4: gen_uxtb16(tmp); break;
7889
case 6: gen_uxtb(tmp); break;
7890
case 7: gen_uxth(tmp); break;
7891
default: goto illegal_op;
7894
tmp2 = load_reg(s, rn);
7895
if ((op1 & 3) == 0) {
7896
gen_add16(tmp, tmp2);
7898
tcg_gen_add_i32(tmp, tmp, tmp2);
7899
tcg_temp_free_i32(tmp2);
7902
store_reg(s, rd, tmp);
7903
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
7905
tmp = load_reg(s, rm);
7906
if (insn & (1 << 22)) {
7907
if (insn & (1 << 7)) {
7911
gen_helper_rbit(tmp, tmp);
7914
if (insn & (1 << 7))
7917
tcg_gen_bswap32_i32(tmp, tmp);
7919
store_reg(s, rd, tmp);
7924
case 2: /* Multiplies (Type 3). */
7925
switch ((insn >> 20) & 0x7) {
7927
if (((insn >> 6) ^ (insn >> 7)) & 1) {
7928
/* op2 not 00x or 11x : UNDEF */
7931
/* Signed multiply most significant [accumulate].
7932
(SMMUL, SMMLA, SMMLS) */
7933
tmp = load_reg(s, rm);
7934
tmp2 = load_reg(s, rs);
7935
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7938
tmp = load_reg(s, rd);
7939
if (insn & (1 << 6)) {
7940
tmp64 = gen_subq_msw(tmp64, tmp);
7942
tmp64 = gen_addq_msw(tmp64, tmp);
7945
if (insn & (1 << 5)) {
7946
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7948
tcg_gen_shri_i64(tmp64, tmp64, 32);
7949
tmp = tcg_temp_new_i32();
7950
tcg_gen_trunc_i64_i32(tmp, tmp64);
7951
tcg_temp_free_i64(tmp64);
7952
store_reg(s, rn, tmp);
7956
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7957
if (insn & (1 << 7)) {
7960
tmp = load_reg(s, rm);
7961
tmp2 = load_reg(s, rs);
7962
if (insn & (1 << 5))
7963
gen_swap_half(tmp2);
7964
gen_smul_dual(tmp, tmp2);
7965
if (insn & (1 << 6)) {
7966
/* This subtraction cannot overflow. */
7967
tcg_gen_sub_i32(tmp, tmp, tmp2);
7969
/* This addition cannot overflow 32 bits;
7970
* however it may overflow considered as a signed
7971
* operation, in which case we must set the Q flag.
7973
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7975
tcg_temp_free_i32(tmp2);
7976
if (insn & (1 << 22)) {
7977
/* smlald, smlsld */
7978
tmp64 = tcg_temp_new_i64();
7979
tcg_gen_ext_i32_i64(tmp64, tmp);
7980
tcg_temp_free_i32(tmp);
7981
gen_addq(s, tmp64, rd, rn);
7982
gen_storeq_reg(s, rd, rn, tmp64);
7983
tcg_temp_free_i64(tmp64);
7985
/* smuad, smusd, smlad, smlsd */
7988
tmp2 = load_reg(s, rd);
7989
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7990
tcg_temp_free_i32(tmp2);
7992
store_reg(s, rn, tmp);
7998
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8001
if (((insn >> 5) & 7) || (rd != 15)) {
8004
tmp = load_reg(s, rm);
8005
tmp2 = load_reg(s, rs);
8006
if (insn & (1 << 21)) {
8007
gen_helper_udiv(tmp, tmp, tmp2);
8009
gen_helper_sdiv(tmp, tmp, tmp2);
8011
tcg_temp_free_i32(tmp2);
8012
store_reg(s, rn, tmp);
8019
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8021
case 0: /* Unsigned sum of absolute differences. */
8023
tmp = load_reg(s, rm);
8024
tmp2 = load_reg(s, rs);
8025
gen_helper_usad8(tmp, tmp, tmp2);
8026
tcg_temp_free_i32(tmp2);
8028
tmp2 = load_reg(s, rd);
8029
tcg_gen_add_i32(tmp, tmp, tmp2);
8030
tcg_temp_free_i32(tmp2);
8032
store_reg(s, rn, tmp);
8034
case 0x20: case 0x24: case 0x28: case 0x2c:
8035
/* Bitfield insert/clear. */
8037
shift = (insn >> 7) & 0x1f;
8038
i = (insn >> 16) & 0x1f;
8041
tmp = tcg_temp_new_i32();
8042
tcg_gen_movi_i32(tmp, 0);
8044
tmp = load_reg(s, rm);
8047
tmp2 = load_reg(s, rd);
8048
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8049
tcg_temp_free_i32(tmp2);
8051
store_reg(s, rd, tmp);
8053
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8054
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8056
tmp = load_reg(s, rm);
8057
shift = (insn >> 7) & 0x1f;
8058
i = ((insn >> 16) & 0x1f) + 1;
8063
gen_ubfx(tmp, shift, (1u << i) - 1);
8065
gen_sbfx(tmp, shift, i);
8068
store_reg(s, rd, tmp);
8078
/* Check for undefined extension instructions
8079
* per the ARM Bible IE:
8080
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8082
sh = (0xf << 20) | (0xf << 4);
8083
if (op1 == 0x7 && ((insn & sh) == sh))
8087
/* load/store byte/word */
8088
rn = (insn >> 16) & 0xf;
8089
rd = (insn >> 12) & 0xf;
8090
tmp2 = load_reg(s, rn);
8091
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8092
if (insn & (1 << 24))
8093
gen_add_data_offset(s, insn, tmp2);
8094
if (insn & (1 << 20)) {
8096
tmp = tcg_temp_new_i32();
8097
if (insn & (1 << 22)) {
8098
gen_aa32_ld8u(tmp, tmp2, i);
8100
gen_aa32_ld32u(tmp, tmp2, i);
8104
tmp = load_reg(s, rd);
8105
if (insn & (1 << 22)) {
8106
gen_aa32_st8(tmp, tmp2, i);
8108
gen_aa32_st32(tmp, tmp2, i);
8110
tcg_temp_free_i32(tmp);
8112
if (!(insn & (1 << 24))) {
8113
gen_add_data_offset(s, insn, tmp2);
8114
store_reg(s, rn, tmp2);
8115
} else if (insn & (1 << 21)) {
8116
store_reg(s, rn, tmp2);
8118
tcg_temp_free_i32(tmp2);
8120
if (insn & (1 << 20)) {
8121
/* Complete the load. */
8122
store_reg_from_load(env, s, rd, tmp);
8128
int j, n, user, loaded_base;
8129
TCGv_i32 loaded_var;
8130
/* load/store multiple words */
8131
/* XXX: store correct base if write back */
8133
if (insn & (1 << 22)) {
8135
goto illegal_op; /* only usable in supervisor mode */
8137
if ((insn & (1 << 15)) == 0)
8140
rn = (insn >> 16) & 0xf;
8141
addr = load_reg(s, rn);
8143
/* compute total size */
8145
TCGV_UNUSED_I32(loaded_var);
8148
if (insn & (1 << i))
8151
/* XXX: test invalid n == 0 case ? */
8152
if (insn & (1 << 23)) {
8153
if (insn & (1 << 24)) {
8155
tcg_gen_addi_i32(addr, addr, 4);
8157
/* post increment */
8160
if (insn & (1 << 24)) {
8162
tcg_gen_addi_i32(addr, addr, -(n * 4));
8164
/* post decrement */
8166
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8171
if (insn & (1 << i)) {
8172
if (insn & (1 << 20)) {
8174
tmp = tcg_temp_new_i32();
8175
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8177
tmp2 = tcg_const_i32(i);
8178
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8179
tcg_temp_free_i32(tmp2);
8180
tcg_temp_free_i32(tmp);
8181
} else if (i == rn) {
8185
store_reg_from_load(env, s, i, tmp);
8190
/* special case: r15 = PC + 8 */
8191
val = (long)s->pc + 4;
8192
tmp = tcg_temp_new_i32();
8193
tcg_gen_movi_i32(tmp, val);
8195
tmp = tcg_temp_new_i32();
8196
tmp2 = tcg_const_i32(i);
8197
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8198
tcg_temp_free_i32(tmp2);
8200
tmp = load_reg(s, i);
8202
gen_aa32_st32(tmp, addr, IS_USER(s));
8203
tcg_temp_free_i32(tmp);
8206
/* no need to add after the last transfer */
8208
tcg_gen_addi_i32(addr, addr, 4);
8211
if (insn & (1 << 21)) {
8213
if (insn & (1 << 23)) {
8214
if (insn & (1 << 24)) {
8217
/* post increment */
8218
tcg_gen_addi_i32(addr, addr, 4);
8221
if (insn & (1 << 24)) {
8224
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8226
/* post decrement */
8227
tcg_gen_addi_i32(addr, addr, -(n * 4));
8230
store_reg(s, rn, addr);
8232
tcg_temp_free_i32(addr);
8235
store_reg(s, rn, loaded_var);
8237
if ((insn & (1 << 22)) && !user) {
8238
/* Restore CPSR from SPSR. */
8239
tmp = load_cpu_field(spsr);
8240
gen_set_cpsr(tmp, 0xffffffff);
8241
tcg_temp_free_i32(tmp);
8242
s->is_jmp = DISAS_UPDATE;
8251
/* branch (and link) */
8252
val = (int32_t)s->pc;
8253
if (insn & (1 << 24)) {
8254
tmp = tcg_temp_new_i32();
8255
tcg_gen_movi_i32(tmp, val);
8256
store_reg(s, 14, tmp);
8258
offset = sextract32(insn << 2, 0, 26);
8266
if (((insn >> 8) & 0xe) == 10) {
8268
if (disas_vfp_insn(env, s, insn)) {
8271
} else if (disas_coproc_insn(env, s, insn)) {
8278
gen_set_pc_im(s, s->pc);
8279
s->is_jmp = DISAS_SWI;
8283
gen_exception_insn(s, 4, EXCP_UDEF);
8289
/* Return true if this is a Thumb-2 logical op. */
8291
thumb2_logic_op(int op)
8296
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8297
then set condition code flags based on the result of the operation.
8298
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8299
to the high bit of T1.
8300
Returns zero if the opcode is valid. */
8303
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8304
TCGv_i32 t0, TCGv_i32 t1)
8311
tcg_gen_and_i32(t0, t0, t1);
8315
tcg_gen_andc_i32(t0, t0, t1);
8319
tcg_gen_or_i32(t0, t0, t1);
8323
tcg_gen_orc_i32(t0, t0, t1);
8327
tcg_gen_xor_i32(t0, t0, t1);
8332
gen_add_CC(t0, t0, t1);
8334
tcg_gen_add_i32(t0, t0, t1);
8338
gen_adc_CC(t0, t0, t1);
8344
gen_sbc_CC(t0, t0, t1);
8346
gen_sub_carry(t0, t0, t1);
8351
gen_sub_CC(t0, t0, t1);
8353
tcg_gen_sub_i32(t0, t0, t1);
8357
gen_sub_CC(t0, t1, t0);
8359
tcg_gen_sub_i32(t0, t1, t0);
8361
default: /* 5, 6, 7, 9, 12, 15. */
8367
gen_set_CF_bit31(t1);
8372
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8374
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8376
uint32_t insn, imm, shift, offset;
8377
uint32_t rd, rn, rm, rs;
8388
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8389
|| arm_feature (env, ARM_FEATURE_M))) {
8390
/* Thumb-1 cores may need to treat bl and blx as a pair of
8391
16-bit instructions to get correct prefetch abort behavior. */
8393
if ((insn & (1 << 12)) == 0) {
8395
/* Second half of blx. */
8396
offset = ((insn & 0x7ff) << 1);
8397
tmp = load_reg(s, 14);
8398
tcg_gen_addi_i32(tmp, tmp, offset);
8399
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8401
tmp2 = tcg_temp_new_i32();
8402
tcg_gen_movi_i32(tmp2, s->pc | 1);
8403
store_reg(s, 14, tmp2);
8407
if (insn & (1 << 11)) {
8408
/* Second half of bl. */
8409
offset = ((insn & 0x7ff) << 1) | 1;
8410
tmp = load_reg(s, 14);
8411
tcg_gen_addi_i32(tmp, tmp, offset);
8413
tmp2 = tcg_temp_new_i32();
8414
tcg_gen_movi_i32(tmp2, s->pc | 1);
8415
store_reg(s, 14, tmp2);
8419
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8420
/* Instruction spans a page boundary. Implement it as two
8421
16-bit instructions in case the second half causes an
8423
offset = ((int32_t)insn << 21) >> 9;
8424
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8427
/* Fall through to 32-bit decode. */
8430
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8432
insn |= (uint32_t)insn_hw1 << 16;
8434
if ((insn & 0xf800e800) != 0xf000e800) {
8438
rn = (insn >> 16) & 0xf;
8439
rs = (insn >> 12) & 0xf;
8440
rd = (insn >> 8) & 0xf;
8442
switch ((insn >> 25) & 0xf) {
8443
case 0: case 1: case 2: case 3:
8444
/* 16-bit instructions. Should never happen. */
8447
if (insn & (1 << 22)) {
8448
/* Other load/store, table branch. */
8449
if (insn & 0x01200000) {
8450
/* Load/store doubleword. */
8452
addr = tcg_temp_new_i32();
8453
tcg_gen_movi_i32(addr, s->pc & ~3);
8455
addr = load_reg(s, rn);
8457
offset = (insn & 0xff) * 4;
8458
if ((insn & (1 << 23)) == 0)
8460
if (insn & (1 << 24)) {
8461
tcg_gen_addi_i32(addr, addr, offset);
8464
if (insn & (1 << 20)) {
8466
tmp = tcg_temp_new_i32();
8467
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8468
store_reg(s, rs, tmp);
8469
tcg_gen_addi_i32(addr, addr, 4);
8470
tmp = tcg_temp_new_i32();
8471
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8472
store_reg(s, rd, tmp);
8475
tmp = load_reg(s, rs);
8476
gen_aa32_st32(tmp, addr, IS_USER(s));
8477
tcg_temp_free_i32(tmp);
8478
tcg_gen_addi_i32(addr, addr, 4);
8479
tmp = load_reg(s, rd);
8480
gen_aa32_st32(tmp, addr, IS_USER(s));
8481
tcg_temp_free_i32(tmp);
8483
if (insn & (1 << 21)) {
8484
/* Base writeback. */
8487
tcg_gen_addi_i32(addr, addr, offset - 4);
8488
store_reg(s, rn, addr);
8490
tcg_temp_free_i32(addr);
8492
} else if ((insn & (1 << 23)) == 0) {
8493
/* Load/store exclusive word. */
8494
addr = tcg_temp_local_new_i32();
8495
load_reg_var(s, addr, rn);
8496
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8497
if (insn & (1 << 20)) {
8498
gen_load_exclusive(s, rs, 15, addr, 2);
8500
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8502
tcg_temp_free_i32(addr);
8503
} else if ((insn & (7 << 5)) == 0) {
8506
addr = tcg_temp_new_i32();
8507
tcg_gen_movi_i32(addr, s->pc);
8509
addr = load_reg(s, rn);
8511
tmp = load_reg(s, rm);
8512
tcg_gen_add_i32(addr, addr, tmp);
8513
if (insn & (1 << 4)) {
8515
tcg_gen_add_i32(addr, addr, tmp);
8516
tcg_temp_free_i32(tmp);
8517
tmp = tcg_temp_new_i32();
8518
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8520
tcg_temp_free_i32(tmp);
8521
tmp = tcg_temp_new_i32();
8522
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8524
tcg_temp_free_i32(addr);
8525
tcg_gen_shli_i32(tmp, tmp, 1);
8526
tcg_gen_addi_i32(tmp, tmp, s->pc);
8527
store_reg(s, 15, tmp);
8529
int op2 = (insn >> 6) & 0x3;
8530
op = (insn >> 4) & 0x3;
8535
/* Load/store exclusive byte/halfword/doubleword */
8542
/* Load-acquire/store-release */
8548
/* Load-acquire/store-release exclusive */
8552
addr = tcg_temp_local_new_i32();
8553
load_reg_var(s, addr, rn);
8555
if (insn & (1 << 20)) {
8556
tmp = tcg_temp_new_i32();
8559
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8562
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8565
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8570
store_reg(s, rs, tmp);
8572
tmp = load_reg(s, rs);
8575
gen_aa32_st8(tmp, addr, IS_USER(s));
8578
gen_aa32_st16(tmp, addr, IS_USER(s));
8581
gen_aa32_st32(tmp, addr, IS_USER(s));
8586
tcg_temp_free_i32(tmp);
8588
} else if (insn & (1 << 20)) {
8589
gen_load_exclusive(s, rs, rd, addr, op);
8591
gen_store_exclusive(s, rm, rs, rd, addr, op);
8593
tcg_temp_free_i32(addr);
8596
/* Load/store multiple, RFE, SRS. */
8597
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8598
/* RFE, SRS: not available in user mode or on M profile */
8599
if (IS_USER(s) || IS_M(env)) {
8602
if (insn & (1 << 20)) {
8604
addr = load_reg(s, rn);
8605
if ((insn & (1 << 24)) == 0)
8606
tcg_gen_addi_i32(addr, addr, -8);
8607
/* Load PC into tmp and CPSR into tmp2. */
8608
tmp = tcg_temp_new_i32();
8609
gen_aa32_ld32u(tmp, addr, 0);
8610
tcg_gen_addi_i32(addr, addr, 4);
8611
tmp2 = tcg_temp_new_i32();
8612
gen_aa32_ld32u(tmp2, addr, 0);
8613
if (insn & (1 << 21)) {
8614
/* Base writeback. */
8615
if (insn & (1 << 24)) {
8616
tcg_gen_addi_i32(addr, addr, 4);
8618
tcg_gen_addi_i32(addr, addr, -4);
8620
store_reg(s, rn, addr);
8622
tcg_temp_free_i32(addr);
8624
gen_rfe(s, tmp, tmp2);
8627
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8631
int i, loaded_base = 0;
8632
TCGv_i32 loaded_var;
8633
/* Load/store multiple. */
8634
addr = load_reg(s, rn);
8636
for (i = 0; i < 16; i++) {
8637
if (insn & (1 << i))
8640
if (insn & (1 << 24)) {
8641
tcg_gen_addi_i32(addr, addr, -offset);
8644
TCGV_UNUSED_I32(loaded_var);
8645
for (i = 0; i < 16; i++) {
8646
if ((insn & (1 << i)) == 0)
8648
if (insn & (1 << 20)) {
8650
tmp = tcg_temp_new_i32();
8651
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8654
} else if (i == rn) {
8658
store_reg(s, i, tmp);
8662
tmp = load_reg(s, i);
8663
gen_aa32_st32(tmp, addr, IS_USER(s));
8664
tcg_temp_free_i32(tmp);
8666
tcg_gen_addi_i32(addr, addr, 4);
8669
store_reg(s, rn, loaded_var);
8671
if (insn & (1 << 21)) {
8672
/* Base register writeback. */
8673
if (insn & (1 << 24)) {
8674
tcg_gen_addi_i32(addr, addr, -offset);
8676
/* Fault if writeback register is in register list. */
8677
if (insn & (1 << rn))
8679
store_reg(s, rn, addr);
8681
tcg_temp_free_i32(addr);
8688
op = (insn >> 21) & 0xf;
8690
/* Halfword pack. */
8691
tmp = load_reg(s, rn);
8692
tmp2 = load_reg(s, rm);
8693
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8694
if (insn & (1 << 5)) {
8698
tcg_gen_sari_i32(tmp2, tmp2, shift);
8699
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8700
tcg_gen_ext16u_i32(tmp2, tmp2);
8704
tcg_gen_shli_i32(tmp2, tmp2, shift);
8705
tcg_gen_ext16u_i32(tmp, tmp);
8706
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8708
tcg_gen_or_i32(tmp, tmp, tmp2);
8709
tcg_temp_free_i32(tmp2);
8710
store_reg(s, rd, tmp);
8712
/* Data processing register constant shift. */
8714
tmp = tcg_temp_new_i32();
8715
tcg_gen_movi_i32(tmp, 0);
8717
tmp = load_reg(s, rn);
8719
tmp2 = load_reg(s, rm);
8721
shiftop = (insn >> 4) & 3;
8722
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8723
conds = (insn & (1 << 20)) != 0;
8724
logic_cc = (conds && thumb2_logic_op(op));
8725
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8726
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8728
tcg_temp_free_i32(tmp2);
8730
store_reg(s, rd, tmp);
8732
tcg_temp_free_i32(tmp);
8736
case 13: /* Misc data processing. */
8737
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8738
if (op < 4 && (insn & 0xf000) != 0xf000)
8741
case 0: /* Register controlled shift. */
8742
tmp = load_reg(s, rn);
8743
tmp2 = load_reg(s, rm);
8744
if ((insn & 0x70) != 0)
8746
op = (insn >> 21) & 3;
8747
logic_cc = (insn & (1 << 20)) != 0;
8748
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8751
store_reg_bx(env, s, rd, tmp);
8753
case 1: /* Sign/zero extend. */
8754
tmp = load_reg(s, rm);
8755
shift = (insn >> 4) & 3;
8756
/* ??? In many cases it's not necessary to do a
8757
rotate, a shift is sufficient. */
8759
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8760
op = (insn >> 20) & 7;
8762
case 0: gen_sxth(tmp); break;
8763
case 1: gen_uxth(tmp); break;
8764
case 2: gen_sxtb16(tmp); break;
8765
case 3: gen_uxtb16(tmp); break;
8766
case 4: gen_sxtb(tmp); break;
8767
case 5: gen_uxtb(tmp); break;
8768
default: goto illegal_op;
8771
tmp2 = load_reg(s, rn);
8772
if ((op >> 1) == 1) {
8773
gen_add16(tmp, tmp2);
8775
tcg_gen_add_i32(tmp, tmp, tmp2);
8776
tcg_temp_free_i32(tmp2);
8779
store_reg(s, rd, tmp);
8781
case 2: /* SIMD add/subtract. */
8782
op = (insn >> 20) & 7;
8783
shift = (insn >> 4) & 7;
8784
if ((op & 3) == 3 || (shift & 3) == 3)
8786
tmp = load_reg(s, rn);
8787
tmp2 = load_reg(s, rm);
8788
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8789
tcg_temp_free_i32(tmp2);
8790
store_reg(s, rd, tmp);
8792
case 3: /* Other data processing. */
8793
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8795
/* Saturating add/subtract. */
8796
tmp = load_reg(s, rn);
8797
tmp2 = load_reg(s, rm);
8799
gen_helper_double_saturate(tmp, cpu_env, tmp);
8801
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8803
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8804
tcg_temp_free_i32(tmp2);
8806
tmp = load_reg(s, rn);
8808
case 0x0a: /* rbit */
8809
gen_helper_rbit(tmp, tmp);
8811
case 0x08: /* rev */
8812
tcg_gen_bswap32_i32(tmp, tmp);
8814
case 0x09: /* rev16 */
8817
case 0x0b: /* revsh */
8820
case 0x10: /* sel */
8821
tmp2 = load_reg(s, rm);
8822
tmp3 = tcg_temp_new_i32();
8823
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8824
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8825
tcg_temp_free_i32(tmp3);
8826
tcg_temp_free_i32(tmp2);
8828
case 0x18: /* clz */
8829
gen_helper_clz(tmp, tmp);
8835
store_reg(s, rd, tmp);
8837
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8838
op = (insn >> 4) & 0xf;
8839
tmp = load_reg(s, rn);
8840
tmp2 = load_reg(s, rm);
8841
switch ((insn >> 20) & 7) {
8842
case 0: /* 32 x 32 -> 32 */
8843
tcg_gen_mul_i32(tmp, tmp, tmp2);
8844
tcg_temp_free_i32(tmp2);
8846
tmp2 = load_reg(s, rs);
8848
tcg_gen_sub_i32(tmp, tmp2, tmp);
8850
tcg_gen_add_i32(tmp, tmp, tmp2);
8851
tcg_temp_free_i32(tmp2);
8854
case 1: /* 16 x 16 -> 32 */
8855
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8856
tcg_temp_free_i32(tmp2);
8858
tmp2 = load_reg(s, rs);
8859
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8860
tcg_temp_free_i32(tmp2);
8863
case 2: /* Dual multiply add. */
8864
case 4: /* Dual multiply subtract. */
8866
gen_swap_half(tmp2);
8867
gen_smul_dual(tmp, tmp2);
8868
if (insn & (1 << 22)) {
8869
/* This subtraction cannot overflow. */
8870
tcg_gen_sub_i32(tmp, tmp, tmp2);
8872
/* This addition cannot overflow 32 bits;
8873
* however it may overflow considered as a signed
8874
* operation, in which case we must set the Q flag.
8876
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8878
tcg_temp_free_i32(tmp2);
8881
tmp2 = load_reg(s, rs);
8882
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8883
tcg_temp_free_i32(tmp2);
8886
case 3: /* 32 * 16 -> 32msb */
8888
tcg_gen_sari_i32(tmp2, tmp2, 16);
8891
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8892
tcg_gen_shri_i64(tmp64, tmp64, 16);
8893
tmp = tcg_temp_new_i32();
8894
tcg_gen_trunc_i64_i32(tmp, tmp64);
8895
tcg_temp_free_i64(tmp64);
8898
tmp2 = load_reg(s, rs);
8899
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8900
tcg_temp_free_i32(tmp2);
8903
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8904
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8906
tmp = load_reg(s, rs);
8907
if (insn & (1 << 20)) {
8908
tmp64 = gen_addq_msw(tmp64, tmp);
8910
tmp64 = gen_subq_msw(tmp64, tmp);
8913
if (insn & (1 << 4)) {
8914
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8916
tcg_gen_shri_i64(tmp64, tmp64, 32);
8917
tmp = tcg_temp_new_i32();
8918
tcg_gen_trunc_i64_i32(tmp, tmp64);
8919
tcg_temp_free_i64(tmp64);
8921
case 7: /* Unsigned sum of absolute differences. */
8922
gen_helper_usad8(tmp, tmp, tmp2);
8923
tcg_temp_free_i32(tmp2);
8925
tmp2 = load_reg(s, rs);
8926
tcg_gen_add_i32(tmp, tmp, tmp2);
8927
tcg_temp_free_i32(tmp2);
8931
store_reg(s, rd, tmp);
8933
case 6: case 7: /* 64-bit multiply, Divide. */
8934
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8935
tmp = load_reg(s, rn);
8936
tmp2 = load_reg(s, rm);
8937
if ((op & 0x50) == 0x10) {
8939
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8943
gen_helper_udiv(tmp, tmp, tmp2);
8945
gen_helper_sdiv(tmp, tmp, tmp2);
8946
tcg_temp_free_i32(tmp2);
8947
store_reg(s, rd, tmp);
8948
} else if ((op & 0xe) == 0xc) {
8949
/* Dual multiply accumulate long. */
8951
gen_swap_half(tmp2);
8952
gen_smul_dual(tmp, tmp2);
8954
tcg_gen_sub_i32(tmp, tmp, tmp2);
8956
tcg_gen_add_i32(tmp, tmp, tmp2);
8958
tcg_temp_free_i32(tmp2);
8960
tmp64 = tcg_temp_new_i64();
8961
tcg_gen_ext_i32_i64(tmp64, tmp);
8962
tcg_temp_free_i32(tmp);
8963
gen_addq(s, tmp64, rs, rd);
8964
gen_storeq_reg(s, rs, rd, tmp64);
8965
tcg_temp_free_i64(tmp64);
8968
/* Unsigned 64-bit multiply */
8969
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8973
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8974
tcg_temp_free_i32(tmp2);
8975
tmp64 = tcg_temp_new_i64();
8976
tcg_gen_ext_i32_i64(tmp64, tmp);
8977
tcg_temp_free_i32(tmp);
8979
/* Signed 64-bit multiply */
8980
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8985
gen_addq_lo(s, tmp64, rs);
8986
gen_addq_lo(s, tmp64, rd);
8987
} else if (op & 0x40) {
8988
/* 64-bit accumulate. */
8989
gen_addq(s, tmp64, rs, rd);
8991
gen_storeq_reg(s, rs, rd, tmp64);
8992
tcg_temp_free_i64(tmp64);
8997
case 6: case 7: case 14: case 15:
8999
if (((insn >> 24) & 3) == 3) {
9000
/* Translate into the equivalent ARM encoding. */
9001
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9002
if (disas_neon_data_insn(env, s, insn))
9004
} else if (((insn >> 8) & 0xe) == 10) {
9005
if (disas_vfp_insn(env, s, insn)) {
9009
if (insn & (1 << 28))
9011
if (disas_coproc_insn (env, s, insn))
9015
case 8: case 9: case 10: case 11:
9016
if (insn & (1 << 15)) {
9017
/* Branches, misc control. */
9018
if (insn & 0x5000) {
9019
/* Unconditional branch. */
9020
/* signextend(hw1[10:0]) -> offset[:12]. */
9021
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9022
/* hw1[10:0] -> offset[11:1]. */
9023
offset |= (insn & 0x7ff) << 1;
9024
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9025
offset[24:22] already have the same value because of the
9026
sign extension above. */
9027
offset ^= ((~insn) & (1 << 13)) << 10;
9028
offset ^= ((~insn) & (1 << 11)) << 11;
9030
if (insn & (1 << 14)) {
9031
/* Branch and link. */
9032
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9036
if (insn & (1 << 12)) {
9041
offset &= ~(uint32_t)2;
9042
/* thumb2 bx, no need to check */
9043
gen_bx_im(s, offset);
9045
} else if (((insn >> 23) & 7) == 7) {
9047
if (insn & (1 << 13))
9050
if (insn & (1 << 26)) {
9051
/* Secure monitor call / smc (v6Z) */
9052
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
9058
op = (insn >> 20) & 7;
9060
case 0: /* msr cpsr. */
9062
tmp = load_reg(s, rn);
9063
addr = tcg_const_i32(insn & 0xff);
9064
gen_helper_v7m_msr(cpu_env, addr, tmp);
9065
tcg_temp_free_i32(addr);
9066
tcg_temp_free_i32(tmp);
9071
case 1: /* msr spsr. */
9074
tmp = load_reg(s, rn);
9076
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9080
case 2: /* cps, nop-hint. */
9081
if (((insn >> 8) & 7) == 0) {
9082
gen_nop_hint(s, insn & 0xff);
9084
/* Implemented as NOP in user mode. */
9089
if (insn & (1 << 10)) {
9090
if (insn & (1 << 7))
9092
if (insn & (1 << 6))
9094
if (insn & (1 << 5))
9096
if (insn & (1 << 9))
9097
imm = CPSR_A | CPSR_I | CPSR_F;
9099
if (insn & (1 << 8)) {
9101
imm |= (insn & 0x1f);
9104
gen_set_psr_im(s, offset, 0, imm);
9107
case 3: /* Special control operations. */
9109
op = (insn >> 4) & 0xf;
9117
/* These execute as NOPs. */
9124
/* Trivial implementation equivalent to bx. */
9125
tmp = load_reg(s, rn);
9128
case 5: /* Exception return. */
9132
if (rn != 14 || rd != 15) {
9135
tmp = load_reg(s, rn);
9136
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9137
gen_exception_return(s, tmp);
9139
case 6: /* mrs cpsr. */
9140
tmp = tcg_temp_new_i32();
9142
addr = tcg_const_i32(insn & 0xff);
9143
gen_helper_v7m_mrs(tmp, cpu_env, addr);
9144
tcg_temp_free_i32(addr);
9146
gen_helper_cpsr_read(tmp, cpu_env);
9148
store_reg(s, rd, tmp);
9150
case 7: /* mrs spsr. */
9151
/* Not accessible in user mode. */
9152
if (IS_USER(s) || IS_M(env))
9154
tmp = load_cpu_field(spsr);
9155
store_reg(s, rd, tmp);
9160
/* Conditional branch. */
9161
op = (insn >> 22) & 0xf;
9162
/* Generate a conditional jump to next instruction. */
9163
s->condlabel = gen_new_label();
9164
arm_gen_test_cc(op ^ 1, s->condlabel);
9167
/* offset[11:1] = insn[10:0] */
9168
offset = (insn & 0x7ff) << 1;
9169
/* offset[17:12] = insn[21:16]. */
9170
offset |= (insn & 0x003f0000) >> 4;
9171
/* offset[31:20] = insn[26]. */
9172
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9173
/* offset[18] = insn[13]. */
9174
offset |= (insn & (1 << 13)) << 5;
9175
/* offset[19] = insn[11]. */
9176
offset |= (insn & (1 << 11)) << 8;
9178
/* jump to the offset */
9179
gen_jmp(s, s->pc + offset);
9182
/* Data processing immediate. */
9183
if (insn & (1 << 25)) {
9184
if (insn & (1 << 24)) {
9185
if (insn & (1 << 20))
9187
/* Bitfield/Saturate. */
9188
op = (insn >> 21) & 7;
9190
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9192
tmp = tcg_temp_new_i32();
9193
tcg_gen_movi_i32(tmp, 0);
9195
tmp = load_reg(s, rn);
9198
case 2: /* Signed bitfield extract. */
9200
if (shift + imm > 32)
9203
gen_sbfx(tmp, shift, imm);
9205
case 6: /* Unsigned bitfield extract. */
9207
if (shift + imm > 32)
9210
gen_ubfx(tmp, shift, (1u << imm) - 1);
9212
case 3: /* Bitfield insert/clear. */
9215
imm = imm + 1 - shift;
9217
tmp2 = load_reg(s, rd);
9218
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9219
tcg_temp_free_i32(tmp2);
9224
default: /* Saturate. */
9227
tcg_gen_sari_i32(tmp, tmp, shift);
9229
tcg_gen_shli_i32(tmp, tmp, shift);
9231
tmp2 = tcg_const_i32(imm);
9234
if ((op & 1) && shift == 0)
9235
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9237
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9240
if ((op & 1) && shift == 0)
9241
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9243
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9245
tcg_temp_free_i32(tmp2);
9248
store_reg(s, rd, tmp);
9250
imm = ((insn & 0x04000000) >> 15)
9251
| ((insn & 0x7000) >> 4) | (insn & 0xff);
9252
if (insn & (1 << 22)) {
9253
/* 16-bit immediate. */
9254
imm |= (insn >> 4) & 0xf000;
9255
if (insn & (1 << 23)) {
9257
tmp = load_reg(s, rd);
9258
tcg_gen_ext16u_i32(tmp, tmp);
9259
tcg_gen_ori_i32(tmp, tmp, imm << 16);
9262
tmp = tcg_temp_new_i32();
9263
tcg_gen_movi_i32(tmp, imm);
9266
/* Add/sub 12-bit immediate. */
9268
offset = s->pc & ~(uint32_t)3;
9269
if (insn & (1 << 23))
9273
tmp = tcg_temp_new_i32();
9274
tcg_gen_movi_i32(tmp, offset);
9276
tmp = load_reg(s, rn);
9277
if (insn & (1 << 23))
9278
tcg_gen_subi_i32(tmp, tmp, imm);
9280
tcg_gen_addi_i32(tmp, tmp, imm);
9283
store_reg(s, rd, tmp);
9286
int shifter_out = 0;
9287
/* modified 12-bit immediate. */
9288
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9289
imm = (insn & 0xff);
9292
/* Nothing to do. */
9294
case 1: /* 00XY00XY */
9297
case 2: /* XY00XY00 */
9301
case 3: /* XYXYXYXY */
9305
default: /* Rotated constant. */
9306
shift = (shift << 1) | (imm >> 7);
9308
imm = imm << (32 - shift);
9312
tmp2 = tcg_temp_new_i32();
9313
tcg_gen_movi_i32(tmp2, imm);
9314
rn = (insn >> 16) & 0xf;
9316
tmp = tcg_temp_new_i32();
9317
tcg_gen_movi_i32(tmp, 0);
9319
tmp = load_reg(s, rn);
9321
op = (insn >> 21) & 0xf;
9322
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9323
shifter_out, tmp, tmp2))
9325
tcg_temp_free_i32(tmp2);
9326
rd = (insn >> 8) & 0xf;
9328
store_reg(s, rd, tmp);
9330
tcg_temp_free_i32(tmp);
9335
case 12: /* Load/store single data item. */
9340
if ((insn & 0x01100000) == 0x01000000) {
9341
if (disas_neon_ls_insn(env, s, insn))
9345
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9347
if (!(insn & (1 << 20))) {
9351
/* Byte or halfword load space with dest == r15 : memory hints.
9352
* Catch them early so we don't emit pointless addressing code.
9353
* This space is a mix of:
9354
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9355
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9357
* unallocated hints, which must be treated as NOPs
9358
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9359
* which is easiest for the decoding logic
9360
* Some space which must UNDEF
9362
int op1 = (insn >> 23) & 3;
9363
int op2 = (insn >> 6) & 0x3f;
9368
/* UNPREDICTABLE, unallocated hint or
9369
* PLD/PLDW/PLI (literal)
9374
return 0; /* PLD/PLDW/PLI or unallocated hint */
9376
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9377
return 0; /* PLD/PLDW/PLI or unallocated hint */
9379
/* UNDEF space, or an UNPREDICTABLE */
9385
addr = tcg_temp_new_i32();
9387
/* s->pc has already been incremented by 4. */
9388
imm = s->pc & 0xfffffffc;
9389
if (insn & (1 << 23))
9390
imm += insn & 0xfff;
9392
imm -= insn & 0xfff;
9393
tcg_gen_movi_i32(addr, imm);
9395
addr = load_reg(s, rn);
9396
if (insn & (1 << 23)) {
9397
/* Positive offset. */
9399
tcg_gen_addi_i32(addr, addr, imm);
9402
switch ((insn >> 8) & 0xf) {
9403
case 0x0: /* Shifted Register. */
9404
shift = (insn >> 4) & 0xf;
9406
tcg_temp_free_i32(addr);
9409
tmp = load_reg(s, rm);
9411
tcg_gen_shli_i32(tmp, tmp, shift);
9412
tcg_gen_add_i32(addr, addr, tmp);
9413
tcg_temp_free_i32(tmp);
9415
case 0xc: /* Negative offset. */
9416
tcg_gen_addi_i32(addr, addr, -imm);
9418
case 0xe: /* User privilege. */
9419
tcg_gen_addi_i32(addr, addr, imm);
9422
case 0x9: /* Post-decrement. */
9425
case 0xb: /* Post-increment. */
9429
case 0xd: /* Pre-decrement. */
9432
case 0xf: /* Pre-increment. */
9433
tcg_gen_addi_i32(addr, addr, imm);
9437
tcg_temp_free_i32(addr);
9442
if (insn & (1 << 20)) {
9444
tmp = tcg_temp_new_i32();
9447
gen_aa32_ld8u(tmp, addr, user);
9450
gen_aa32_ld8s(tmp, addr, user);
9453
gen_aa32_ld16u(tmp, addr, user);
9456
gen_aa32_ld16s(tmp, addr, user);
9459
gen_aa32_ld32u(tmp, addr, user);
9462
tcg_temp_free_i32(tmp);
9463
tcg_temp_free_i32(addr);
9469
store_reg(s, rs, tmp);
9473
tmp = load_reg(s, rs);
9476
gen_aa32_st8(tmp, addr, user);
9479
gen_aa32_st16(tmp, addr, user);
9482
gen_aa32_st32(tmp, addr, user);
9485
tcg_temp_free_i32(tmp);
9486
tcg_temp_free_i32(addr);
9489
tcg_temp_free_i32(tmp);
9492
tcg_gen_addi_i32(addr, addr, imm);
9494
store_reg(s, rn, addr);
9496
tcg_temp_free_i32(addr);
9508
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9510
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9517
if (s->condexec_mask) {
9518
cond = s->condexec_cond;
9519
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9520
s->condlabel = gen_new_label();
9521
arm_gen_test_cc(cond ^ 1, s->condlabel);
9526
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9529
switch (insn >> 12) {
9533
op = (insn >> 11) & 3;
9536
rn = (insn >> 3) & 7;
9537
tmp = load_reg(s, rn);
9538
if (insn & (1 << 10)) {
9540
tmp2 = tcg_temp_new_i32();
9541
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9544
rm = (insn >> 6) & 7;
9545
tmp2 = load_reg(s, rm);
9547
if (insn & (1 << 9)) {
9548
if (s->condexec_mask)
9549
tcg_gen_sub_i32(tmp, tmp, tmp2);
9551
gen_sub_CC(tmp, tmp, tmp2);
9553
if (s->condexec_mask)
9554
tcg_gen_add_i32(tmp, tmp, tmp2);
9556
gen_add_CC(tmp, tmp, tmp2);
9558
tcg_temp_free_i32(tmp2);
9559
store_reg(s, rd, tmp);
9561
/* shift immediate */
9562
rm = (insn >> 3) & 7;
9563
shift = (insn >> 6) & 0x1f;
9564
tmp = load_reg(s, rm);
9565
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9566
if (!s->condexec_mask)
9568
store_reg(s, rd, tmp);
9572
/* arithmetic large immediate */
9573
op = (insn >> 11) & 3;
9574
rd = (insn >> 8) & 0x7;
9575
if (op == 0) { /* mov */
9576
tmp = tcg_temp_new_i32();
9577
tcg_gen_movi_i32(tmp, insn & 0xff);
9578
if (!s->condexec_mask)
9580
store_reg(s, rd, tmp);
9582
tmp = load_reg(s, rd);
9583
tmp2 = tcg_temp_new_i32();
9584
tcg_gen_movi_i32(tmp2, insn & 0xff);
9587
gen_sub_CC(tmp, tmp, tmp2);
9588
tcg_temp_free_i32(tmp);
9589
tcg_temp_free_i32(tmp2);
9592
if (s->condexec_mask)
9593
tcg_gen_add_i32(tmp, tmp, tmp2);
9595
gen_add_CC(tmp, tmp, tmp2);
9596
tcg_temp_free_i32(tmp2);
9597
store_reg(s, rd, tmp);
9600
if (s->condexec_mask)
9601
tcg_gen_sub_i32(tmp, tmp, tmp2);
9603
gen_sub_CC(tmp, tmp, tmp2);
9604
tcg_temp_free_i32(tmp2);
9605
store_reg(s, rd, tmp);
9611
if (insn & (1 << 11)) {
9612
rd = (insn >> 8) & 7;
9613
/* load pc-relative. Bit 1 of PC is ignored. */
9614
val = s->pc + 2 + ((insn & 0xff) * 4);
9615
val &= ~(uint32_t)2;
9616
addr = tcg_temp_new_i32();
9617
tcg_gen_movi_i32(addr, val);
9618
tmp = tcg_temp_new_i32();
9619
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9620
tcg_temp_free_i32(addr);
9621
store_reg(s, rd, tmp);
9624
if (insn & (1 << 10)) {
9625
/* data processing extended or blx */
9626
rd = (insn & 7) | ((insn >> 4) & 8);
9627
rm = (insn >> 3) & 0xf;
9628
op = (insn >> 8) & 3;
9631
tmp = load_reg(s, rd);
9632
tmp2 = load_reg(s, rm);
9633
tcg_gen_add_i32(tmp, tmp, tmp2);
9634
tcg_temp_free_i32(tmp2);
9635
store_reg(s, rd, tmp);
9638
tmp = load_reg(s, rd);
9639
tmp2 = load_reg(s, rm);
9640
gen_sub_CC(tmp, tmp, tmp2);
9641
tcg_temp_free_i32(tmp2);
9642
tcg_temp_free_i32(tmp);
9644
case 2: /* mov/cpy */
9645
tmp = load_reg(s, rm);
9646
store_reg(s, rd, tmp);
9648
case 3:/* branch [and link] exchange thumb register */
9649
tmp = load_reg(s, rm);
9650
if (insn & (1 << 7)) {
9652
val = (uint32_t)s->pc | 1;
9653
tmp2 = tcg_temp_new_i32();
9654
tcg_gen_movi_i32(tmp2, val);
9655
store_reg(s, 14, tmp2);
9657
/* already thumb, no need to check */
9664
/* data processing register */
9666
rm = (insn >> 3) & 7;
9667
op = (insn >> 6) & 0xf;
9668
if (op == 2 || op == 3 || op == 4 || op == 7) {
9669
/* the shift/rotate ops want the operands backwards */
9678
if (op == 9) { /* neg */
9679
tmp = tcg_temp_new_i32();
9680
tcg_gen_movi_i32(tmp, 0);
9681
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9682
tmp = load_reg(s, rd);
9684
TCGV_UNUSED_I32(tmp);
9687
tmp2 = load_reg(s, rm);
9690
tcg_gen_and_i32(tmp, tmp, tmp2);
9691
if (!s->condexec_mask)
9695
tcg_gen_xor_i32(tmp, tmp, tmp2);
9696
if (!s->condexec_mask)
9700
if (s->condexec_mask) {
9701
gen_shl(tmp2, tmp2, tmp);
9703
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9708
if (s->condexec_mask) {
9709
gen_shr(tmp2, tmp2, tmp);
9711
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9716
if (s->condexec_mask) {
9717
gen_sar(tmp2, tmp2, tmp);
9719
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9724
if (s->condexec_mask) {
9727
gen_adc_CC(tmp, tmp, tmp2);
9731
if (s->condexec_mask) {
9732
gen_sub_carry(tmp, tmp, tmp2);
9734
gen_sbc_CC(tmp, tmp, tmp2);
9738
if (s->condexec_mask) {
9739
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9740
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9742
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9747
tcg_gen_and_i32(tmp, tmp, tmp2);
9752
if (s->condexec_mask)
9753
tcg_gen_neg_i32(tmp, tmp2);
9755
gen_sub_CC(tmp, tmp, tmp2);
9758
gen_sub_CC(tmp, tmp, tmp2);
9762
gen_add_CC(tmp, tmp, tmp2);
9766
tcg_gen_or_i32(tmp, tmp, tmp2);
9767
if (!s->condexec_mask)
9771
tcg_gen_mul_i32(tmp, tmp, tmp2);
9772
if (!s->condexec_mask)
9776
tcg_gen_andc_i32(tmp, tmp, tmp2);
9777
if (!s->condexec_mask)
9781
tcg_gen_not_i32(tmp2, tmp2);
9782
if (!s->condexec_mask)
9790
store_reg(s, rm, tmp2);
9792
tcg_temp_free_i32(tmp);
9794
store_reg(s, rd, tmp);
9795
tcg_temp_free_i32(tmp2);
9798
tcg_temp_free_i32(tmp);
9799
tcg_temp_free_i32(tmp2);
9804
/* load/store register offset. */
9806
rn = (insn >> 3) & 7;
9807
rm = (insn >> 6) & 7;
9808
op = (insn >> 9) & 7;
9809
addr = load_reg(s, rn);
9810
tmp = load_reg(s, rm);
9811
tcg_gen_add_i32(addr, addr, tmp);
9812
tcg_temp_free_i32(tmp);
9814
if (op < 3) { /* store */
9815
tmp = load_reg(s, rd);
9817
tmp = tcg_temp_new_i32();
9822
gen_aa32_st32(tmp, addr, IS_USER(s));
9825
gen_aa32_st16(tmp, addr, IS_USER(s));
9828
gen_aa32_st8(tmp, addr, IS_USER(s));
9831
gen_aa32_ld8s(tmp, addr, IS_USER(s));
9834
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9837
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9840
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9843
gen_aa32_ld16s(tmp, addr, IS_USER(s));
9846
if (op >= 3) { /* load */
9847
store_reg(s, rd, tmp);
9849
tcg_temp_free_i32(tmp);
9851
tcg_temp_free_i32(addr);
9855
/* load/store word immediate offset */
9857
rn = (insn >> 3) & 7;
9858
addr = load_reg(s, rn);
9859
val = (insn >> 4) & 0x7c;
9860
tcg_gen_addi_i32(addr, addr, val);
9862
if (insn & (1 << 11)) {
9864
tmp = tcg_temp_new_i32();
9865
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9866
store_reg(s, rd, tmp);
9869
tmp = load_reg(s, rd);
9870
gen_aa32_st32(tmp, addr, IS_USER(s));
9871
tcg_temp_free_i32(tmp);
9873
tcg_temp_free_i32(addr);
9877
/* load/store byte immediate offset */
9879
rn = (insn >> 3) & 7;
9880
addr = load_reg(s, rn);
9881
val = (insn >> 6) & 0x1f;
9882
tcg_gen_addi_i32(addr, addr, val);
9884
if (insn & (1 << 11)) {
9886
tmp = tcg_temp_new_i32();
9887
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9888
store_reg(s, rd, tmp);
9891
tmp = load_reg(s, rd);
9892
gen_aa32_st8(tmp, addr, IS_USER(s));
9893
tcg_temp_free_i32(tmp);
9895
tcg_temp_free_i32(addr);
9899
/* load/store halfword immediate offset */
9901
rn = (insn >> 3) & 7;
9902
addr = load_reg(s, rn);
9903
val = (insn >> 5) & 0x3e;
9904
tcg_gen_addi_i32(addr, addr, val);
9906
if (insn & (1 << 11)) {
9908
tmp = tcg_temp_new_i32();
9909
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9910
store_reg(s, rd, tmp);
9913
tmp = load_reg(s, rd);
9914
gen_aa32_st16(tmp, addr, IS_USER(s));
9915
tcg_temp_free_i32(tmp);
9917
tcg_temp_free_i32(addr);
9921
/* load/store from stack */
9922
rd = (insn >> 8) & 7;
9923
addr = load_reg(s, 13);
9924
val = (insn & 0xff) * 4;
9925
tcg_gen_addi_i32(addr, addr, val);
9927
if (insn & (1 << 11)) {
9929
tmp = tcg_temp_new_i32();
9930
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9931
store_reg(s, rd, tmp);
9934
tmp = load_reg(s, rd);
9935
gen_aa32_st32(tmp, addr, IS_USER(s));
9936
tcg_temp_free_i32(tmp);
9938
tcg_temp_free_i32(addr);
9942
/* add to high reg */
9943
rd = (insn >> 8) & 7;
9944
if (insn & (1 << 11)) {
9946
tmp = load_reg(s, 13);
9948
/* PC. bit 1 is ignored. */
9949
tmp = tcg_temp_new_i32();
9950
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9952
val = (insn & 0xff) * 4;
9953
tcg_gen_addi_i32(tmp, tmp, val);
9954
store_reg(s, rd, tmp);
9959
op = (insn >> 8) & 0xf;
9962
/* adjust stack pointer */
9963
tmp = load_reg(s, 13);
9964
val = (insn & 0x7f) * 4;
9965
if (insn & (1 << 7))
9966
val = -(int32_t)val;
9967
tcg_gen_addi_i32(tmp, tmp, val);
9968
store_reg(s, 13, tmp);
9971
case 2: /* sign/zero extend. */
9974
rm = (insn >> 3) & 7;
9975
tmp = load_reg(s, rm);
9976
switch ((insn >> 6) & 3) {
9977
case 0: gen_sxth(tmp); break;
9978
case 1: gen_sxtb(tmp); break;
9979
case 2: gen_uxth(tmp); break;
9980
case 3: gen_uxtb(tmp); break;
9982
store_reg(s, rd, tmp);
9984
case 4: case 5: case 0xc: case 0xd:
9986
addr = load_reg(s, 13);
9987
if (insn & (1 << 8))
9991
for (i = 0; i < 8; i++) {
9992
if (insn & (1 << i))
9995
if ((insn & (1 << 11)) == 0) {
9996
tcg_gen_addi_i32(addr, addr, -offset);
9998
for (i = 0; i < 8; i++) {
9999
if (insn & (1 << i)) {
10000
if (insn & (1 << 11)) {
10002
tmp = tcg_temp_new_i32();
10003
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10004
store_reg(s, i, tmp);
10007
tmp = load_reg(s, i);
10008
gen_aa32_st32(tmp, addr, IS_USER(s));
10009
tcg_temp_free_i32(tmp);
10011
/* advance to the next address. */
10012
tcg_gen_addi_i32(addr, addr, 4);
10015
TCGV_UNUSED_I32(tmp);
10016
if (insn & (1 << 8)) {
10017
if (insn & (1 << 11)) {
10019
tmp = tcg_temp_new_i32();
10020
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10021
/* don't set the pc until the rest of the instruction
10025
tmp = load_reg(s, 14);
10026
gen_aa32_st32(tmp, addr, IS_USER(s));
10027
tcg_temp_free_i32(tmp);
10029
tcg_gen_addi_i32(addr, addr, 4);
10031
if ((insn & (1 << 11)) == 0) {
10032
tcg_gen_addi_i32(addr, addr, -offset);
10034
/* write back the new stack pointer */
10035
store_reg(s, 13, addr);
10036
/* set the new PC value */
10037
if ((insn & 0x0900) == 0x0900) {
10038
store_reg_from_load(env, s, 15, tmp);
10042
case 1: case 3: case 9: case 11: /* czb */
10044
tmp = load_reg(s, rm);
10045
s->condlabel = gen_new_label();
10047
if (insn & (1 << 11))
10048
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10050
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10051
tcg_temp_free_i32(tmp);
10052
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10053
val = (uint32_t)s->pc + 2;
10058
case 15: /* IT, nop-hint. */
10059
if ((insn & 0xf) == 0) {
10060
gen_nop_hint(s, (insn >> 4) & 0xf);
10064
s->condexec_cond = (insn >> 4) & 0xe;
10065
s->condexec_mask = insn & 0x1f;
10066
/* No actual code generated for this insn, just setup state. */
10069
case 0xe: /* bkpt */
10071
gen_exception_insn(s, 2, EXCP_BKPT);
10074
case 0xa: /* rev */
10076
rn = (insn >> 3) & 0x7;
10078
tmp = load_reg(s, rn);
10079
switch ((insn >> 6) & 3) {
10080
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10081
case 1: gen_rev16(tmp); break;
10082
case 3: gen_revsh(tmp); break;
10083
default: goto illegal_op;
10085
store_reg(s, rd, tmp);
10089
switch ((insn >> 5) & 7) {
10093
if (((insn >> 3) & 1) != s->bswap_code) {
10094
/* Dynamic endianness switching not implemented. */
10095
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10106
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10109
addr = tcg_const_i32(19);
10110
gen_helper_v7m_msr(cpu_env, addr, tmp);
10111
tcg_temp_free_i32(addr);
10115
addr = tcg_const_i32(16);
10116
gen_helper_v7m_msr(cpu_env, addr, tmp);
10117
tcg_temp_free_i32(addr);
10119
tcg_temp_free_i32(tmp);
10122
if (insn & (1 << 4)) {
10123
shift = CPSR_A | CPSR_I | CPSR_F;
10127
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10142
/* load/store multiple */
10143
TCGv_i32 loaded_var;
10144
TCGV_UNUSED_I32(loaded_var);
10145
rn = (insn >> 8) & 0x7;
10146
addr = load_reg(s, rn);
10147
for (i = 0; i < 8; i++) {
10148
if (insn & (1 << i)) {
10149
if (insn & (1 << 11)) {
10151
tmp = tcg_temp_new_i32();
10152
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10156
store_reg(s, i, tmp);
10160
tmp = load_reg(s, i);
10161
gen_aa32_st32(tmp, addr, IS_USER(s));
10162
tcg_temp_free_i32(tmp);
10164
/* advance to the next address */
10165
tcg_gen_addi_i32(addr, addr, 4);
10168
if ((insn & (1 << rn)) == 0) {
10169
/* base reg not in list: base register writeback */
10170
store_reg(s, rn, addr);
10172
/* base reg in list: if load, complete it now */
10173
if (insn & (1 << 11)) {
10174
store_reg(s, rn, loaded_var);
10176
tcg_temp_free_i32(addr);
10181
/* conditional branch or swi */
10182
cond = (insn >> 8) & 0xf;
10188
gen_set_pc_im(s, s->pc);
10189
s->is_jmp = DISAS_SWI;
10192
/* generate a conditional jump to next instruction */
10193
s->condlabel = gen_new_label();
10194
arm_gen_test_cc(cond ^ 1, s->condlabel);
10197
/* jump to the offset */
10198
val = (uint32_t)s->pc + 2;
10199
offset = ((int32_t)insn << 24) >> 24;
10200
val += offset << 1;
10205
if (insn & (1 << 11)) {
10206
if (disas_thumb2_insn(env, s, insn))
10210
/* unconditional branch */
10211
val = (uint32_t)s->pc;
10212
offset = ((int32_t)insn << 21) >> 21;
10213
val += (offset << 1) + 2;
10218
if (disas_thumb2_insn(env, s, insn))
10224
gen_exception_insn(s, 4, EXCP_UDEF);
10228
gen_exception_insn(s, 2, EXCP_UDEF);
10231
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10232
basic block 'tb'. If search_pc is TRUE, also generate PC
10233
information for each intermediate instruction. */
10234
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10235
TranslationBlock *tb,
10238
CPUState *cs = CPU(cpu);
10239
CPUARMState *env = &cpu->env;
10240
DisasContext dc1, *dc = &dc1;
10242
uint16_t *gen_opc_end;
10244
target_ulong pc_start;
10245
target_ulong next_page_start;
10249
/* generate intermediate code */
10251
/* The A64 decoder has its own top level loop, because it doesn't need
10252
* the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10254
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10255
gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10263
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10265
dc->is_jmp = DISAS_NEXT;
10267
dc->singlestep_enabled = cs->singlestep_enabled;
10271
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10272
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10273
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10274
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10275
#if !defined(CONFIG_USER_ONLY)
10276
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10278
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10279
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10280
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10281
dc->cp_regs = cpu->cp_regs;
10282
dc->current_pl = arm_current_pl(env);
10284
cpu_F0s = tcg_temp_new_i32();
10285
cpu_F1s = tcg_temp_new_i32();
10286
cpu_F0d = tcg_temp_new_i64();
10287
cpu_F1d = tcg_temp_new_i64();
10290
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10291
cpu_M0 = tcg_temp_new_i64();
10292
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10295
max_insns = tb->cflags & CF_COUNT_MASK;
10296
if (max_insns == 0)
10297
max_insns = CF_COUNT_MASK;
10301
tcg_clear_temp_count();
10303
/* A note on handling of the condexec (IT) bits:
10305
* We want to avoid the overhead of having to write the updated condexec
10306
* bits back to the CPUARMState for every instruction in an IT block. So:
10307
* (1) if the condexec bits are not already zero then we write
10308
* zero back into the CPUARMState now. This avoids complications trying
10309
* to do it at the end of the block. (For example if we don't do this
10310
* it's hard to identify whether we can safely skip writing condexec
10311
* at the end of the TB, which we definitely want to do for the case
10312
* where a TB doesn't do anything with the IT state at all.)
10313
* (2) if we are going to leave the TB then we call gen_set_condexec()
10314
* which will write the correct value into CPUARMState if zero is wrong.
10315
* This is done both for leaving the TB at the end, and for leaving
10316
* it because of an exception we know will happen, which is done in
10317
* gen_exception_insn(). The latter is necessary because we need to
10318
* leave the TB with the PC/IT state just prior to execution of the
10319
* instruction which caused the exception.
10320
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10321
* then the CPUARMState will be wrong and we need to reset it.
10322
* This is handled in the same way as restoration of the
10323
* PC in these situations: we will be called again with search_pc=1
10324
* and generate a mapping of the condexec bits for each PC in
10325
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10326
* this to restore the condexec bits.
10328
* Note that there are no instructions which can read the condexec
10329
* bits, and none which can write non-static values to them, so
10330
* we don't need to care about whether CPUARMState is correct in the
10334
/* Reset the conditional execution bits immediately. This avoids
10335
complications trying to do it at the end of the block. */
10336
if (dc->condexec_mask || dc->condexec_cond)
10338
TCGv_i32 tmp = tcg_temp_new_i32();
10339
tcg_gen_movi_i32(tmp, 0);
10340
store_cpu_field(tmp, condexec_bits);
10343
#ifdef CONFIG_USER_ONLY
10344
/* Intercept jump to the magic kernel page. */
10345
if (dc->pc >= 0xffff0000) {
10346
/* We always get here via a jump, so know we are not in a
10347
conditional execution block. */
10348
gen_exception(EXCP_KERNEL_TRAP);
10349
dc->is_jmp = DISAS_UPDATE;
10353
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10354
/* We always get here via a jump, so know we are not in a
10355
conditional execution block. */
10356
gen_exception(EXCP_EXCEPTION_EXIT);
10357
dc->is_jmp = DISAS_UPDATE;
10362
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10363
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10364
if (bp->pc == dc->pc) {
10365
gen_exception_insn(dc, 0, EXCP_DEBUG);
10366
/* Advance PC so that clearing the breakpoint will
10367
invalidate this TB. */
10369
goto done_generating;
10374
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10378
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10380
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10381
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10382
tcg_ctx.gen_opc_instr_start[lj] = 1;
10383
tcg_ctx.gen_opc_icount[lj] = num_insns;
10386
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10389
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10390
tcg_gen_debug_insn_start(dc->pc);
10394
disas_thumb_insn(env, dc);
10395
if (dc->condexec_mask) {
10396
dc->condexec_cond = (dc->condexec_cond & 0xe)
10397
| ((dc->condexec_mask >> 4) & 1);
10398
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10399
if (dc->condexec_mask == 0) {
10400
dc->condexec_cond = 0;
10404
disas_arm_insn(env, dc);
10407
if (dc->condjmp && !dc->is_jmp) {
10408
gen_set_label(dc->condlabel);
10412
if (tcg_check_temp_count()) {
10413
fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10417
/* Translation stops when a conditional branch is encountered.
10418
* Otherwise the subsequent code could get translated several times.
10419
* Also stop translation when a page boundary is reached. This
10420
* ensures prefetch aborts occur at the right place. */
10422
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10423
!cs->singlestep_enabled &&
10425
dc->pc < next_page_start &&
10426
num_insns < max_insns);
10428
if (tb->cflags & CF_LAST_IO) {
10430
/* FIXME: This can theoretically happen with self-modifying
10432
cpu_abort(env, "IO on conditional branch instruction");
10437
/* At this stage dc->condjmp will only be set when the skipped
10438
instruction was a conditional branch or trap, and the PC has
10439
already been written. */
10440
if (unlikely(cs->singlestep_enabled)) {
10441
/* Make sure the pc is updated, and raise a debug exception. */
10443
gen_set_condexec(dc);
10444
if (dc->is_jmp == DISAS_SWI) {
10445
gen_exception(EXCP_SWI);
10446
} else if (dc->is_jmp == DISAS_SMC) {
10447
gen_exception(EXCP_SMC);
10449
gen_exception(EXCP_DEBUG);
10451
gen_set_label(dc->condlabel);
10453
if (dc->condjmp || !dc->is_jmp) {
10454
gen_set_pc_im(dc, dc->pc);
10457
gen_set_condexec(dc);
10458
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10459
gen_exception(EXCP_SWI);
10460
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10461
gen_exception(EXCP_SMC);
10463
/* FIXME: Single stepping a WFI insn will not halt
10465
gen_exception(EXCP_DEBUG);
10468
/* While branches must always occur at the end of an IT block,
10469
there are a few other things that can cause us to terminate
10470
the TB in the middle of an IT block:
10471
- Exception generating instructions (bkpt, swi, undefined).
10473
- Hardware watchpoints.
10474
Hardware breakpoints have already been handled and skip this code.
10476
gen_set_condexec(dc);
10477
switch(dc->is_jmp) {
10479
gen_goto_tb(dc, 1, dc->pc);
10484
/* indicate that the hash table must be used to find the next TB */
10485
tcg_gen_exit_tb(0);
10487
case DISAS_TB_JUMP:
10488
/* nothing more to generate */
10491
gen_helper_wfi(cpu_env);
10494
gen_exception(EXCP_SWI);
10497
gen_exception(EXCP_SMC);
10501
gen_set_label(dc->condlabel);
10502
gen_set_condexec(dc);
10503
gen_goto_tb(dc, 1, dc->pc);
10509
gen_tb_end(tb, num_insns);
10510
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10513
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10514
qemu_log("----------------\n");
10515
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10516
log_target_disas(env, pc_start, dc->pc - pc_start,
10517
dc->thumb | (dc->bswap_code << 1));
10522
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10525
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10527
tb->size = dc->pc - pc_start;
10528
tb->icount = num_insns;
10532
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10534
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10537
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10539
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10542
static const char *cpu_mode_names[16] = {
10543
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10544
"???", "???", "???", "und", "???", "???", "???", "sys"
10547
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10550
ARMCPU *cpu = ARM_CPU(cs);
10551
CPUARMState *env = &cpu->env;
10555
for(i=0;i<16;i++) {
10556
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10558
cpu_fprintf(f, "\n");
10560
cpu_fprintf(f, " ");
10562
psr = cpsr_read(env);
10563
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10565
psr & (1 << 31) ? 'N' : '-',
10566
psr & (1 << 30) ? 'Z' : '-',
10567
psr & (1 << 29) ? 'C' : '-',
10568
psr & (1 << 28) ? 'V' : '-',
10569
psr & CPSR_T ? 'T' : 'A',
10570
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10572
if (flags & CPU_DUMP_FPU) {
10573
int numvfpregs = 0;
10574
if (arm_feature(env, ARM_FEATURE_VFP)) {
10577
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10580
for (i = 0; i < numvfpregs; i++) {
10581
uint64_t v = float64_val(env->vfp.regs[i]);
10582
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10583
i * 2, (uint32_t)v,
10584
i * 2 + 1, (uint32_t)(v >> 32),
10587
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10591
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10594
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10595
env->condexec_bits = 0;
10597
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10598
env->condexec_bits = gen_opc_condexec_bits[pc_pos];