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, round) \
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##round(cpu_F0d, cpu_F0d, tmp_shift, \
1122
gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1125
tcg_temp_free_i32(tmp_shift); \
1126
tcg_temp_free_ptr(statusptr); \
1128
VFP_GEN_FIX(tosh, _round_to_zero)
1129
VFP_GEN_FIX(tosl, _round_to_zero)
1130
VFP_GEN_FIX(touh, _round_to_zero)
1131
VFP_GEN_FIX(toul, _round_to_zero)
1138
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1141
gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1143
gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1147
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1150
gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1152
gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1157
vfp_reg_offset (int dp, int reg)
1160
return offsetof(CPUARMState, vfp.regs[reg]);
1162
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1163
+ offsetof(CPU_DoubleU, l.upper);
1165
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1166
+ offsetof(CPU_DoubleU, l.lower);
1170
/* Return the offset of a 32-bit piece of a NEON register.
1171
zero is the least significant end of the register. */
1173
neon_reg_offset (int reg, int n)
1177
return vfp_reg_offset(0, sreg);
1180
static TCGv_i32 neon_load_reg(int reg, int pass)
1182
TCGv_i32 tmp = tcg_temp_new_i32();
1183
tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1187
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1189
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1190
tcg_temp_free_i32(var);
1193
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1195
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1198
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1200
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1203
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1204
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1205
#define tcg_gen_st_f32 tcg_gen_st_i32
1206
#define tcg_gen_st_f64 tcg_gen_st_i64
1208
static inline void gen_mov_F0_vreg(int dp, int reg)
1211
tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1213
tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1216
static inline void gen_mov_F1_vreg(int dp, int reg)
1219
tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1221
tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1224
static inline void gen_mov_vreg_F0(int dp, int reg)
1227
tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1229
tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1232
#define ARM_CP_RW_BIT (1 << 20)
1234
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1236
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1239
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1241
tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1244
static inline TCGv_i32 iwmmxt_load_creg(int reg)
1246
TCGv_i32 var = tcg_temp_new_i32();
1247
tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1251
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1253
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1254
tcg_temp_free_i32(var);
1257
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1259
iwmmxt_store_reg(cpu_M0, rn);
1262
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1264
iwmmxt_load_reg(cpu_M0, rn);
1267
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1269
iwmmxt_load_reg(cpu_V1, rn);
1270
tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1273
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1275
iwmmxt_load_reg(cpu_V1, rn);
1276
tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1279
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1281
iwmmxt_load_reg(cpu_V1, rn);
1282
tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1285
#define IWMMXT_OP(name) \
1286
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1288
iwmmxt_load_reg(cpu_V1, rn); \
1289
gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1292
#define IWMMXT_OP_ENV(name) \
1293
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1295
iwmmxt_load_reg(cpu_V1, rn); \
1296
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1299
#define IWMMXT_OP_ENV_SIZE(name) \
1300
IWMMXT_OP_ENV(name##b) \
1301
IWMMXT_OP_ENV(name##w) \
1302
IWMMXT_OP_ENV(name##l)
1304
#define IWMMXT_OP_ENV1(name) \
1305
static inline void gen_op_iwmmxt_##name##_M0(void) \
1307
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1321
IWMMXT_OP_ENV_SIZE(unpackl)
1322
IWMMXT_OP_ENV_SIZE(unpackh)
1324
IWMMXT_OP_ENV1(unpacklub)
1325
IWMMXT_OP_ENV1(unpackluw)
1326
IWMMXT_OP_ENV1(unpacklul)
1327
IWMMXT_OP_ENV1(unpackhub)
1328
IWMMXT_OP_ENV1(unpackhuw)
1329
IWMMXT_OP_ENV1(unpackhul)
1330
IWMMXT_OP_ENV1(unpacklsb)
1331
IWMMXT_OP_ENV1(unpacklsw)
1332
IWMMXT_OP_ENV1(unpacklsl)
1333
IWMMXT_OP_ENV1(unpackhsb)
1334
IWMMXT_OP_ENV1(unpackhsw)
1335
IWMMXT_OP_ENV1(unpackhsl)
1337
IWMMXT_OP_ENV_SIZE(cmpeq)
1338
IWMMXT_OP_ENV_SIZE(cmpgtu)
1339
IWMMXT_OP_ENV_SIZE(cmpgts)
1341
IWMMXT_OP_ENV_SIZE(mins)
1342
IWMMXT_OP_ENV_SIZE(minu)
1343
IWMMXT_OP_ENV_SIZE(maxs)
1344
IWMMXT_OP_ENV_SIZE(maxu)
1346
IWMMXT_OP_ENV_SIZE(subn)
1347
IWMMXT_OP_ENV_SIZE(addn)
1348
IWMMXT_OP_ENV_SIZE(subu)
1349
IWMMXT_OP_ENV_SIZE(addu)
1350
IWMMXT_OP_ENV_SIZE(subs)
1351
IWMMXT_OP_ENV_SIZE(adds)
1353
IWMMXT_OP_ENV(avgb0)
1354
IWMMXT_OP_ENV(avgb1)
1355
IWMMXT_OP_ENV(avgw0)
1356
IWMMXT_OP_ENV(avgw1)
1360
IWMMXT_OP_ENV(packuw)
1361
IWMMXT_OP_ENV(packul)
1362
IWMMXT_OP_ENV(packuq)
1363
IWMMXT_OP_ENV(packsw)
1364
IWMMXT_OP_ENV(packsl)
1365
IWMMXT_OP_ENV(packsq)
1367
static void gen_op_iwmmxt_set_mup(void)
1370
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1371
tcg_gen_ori_i32(tmp, tmp, 2);
1372
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1375
static void gen_op_iwmmxt_set_cup(void)
1378
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1379
tcg_gen_ori_i32(tmp, tmp, 1);
1380
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1383
static void gen_op_iwmmxt_setpsr_nz(void)
1385
TCGv_i32 tmp = tcg_temp_new_i32();
1386
gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1387
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1390
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1392
iwmmxt_load_reg(cpu_V1, rn);
1393
tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1394
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1397
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1404
rd = (insn >> 16) & 0xf;
1405
tmp = load_reg(s, rd);
1407
offset = (insn & 0xff) << ((insn >> 7) & 2);
1408
if (insn & (1 << 24)) {
1410
if (insn & (1 << 23))
1411
tcg_gen_addi_i32(tmp, tmp, offset);
1413
tcg_gen_addi_i32(tmp, tmp, -offset);
1414
tcg_gen_mov_i32(dest, tmp);
1415
if (insn & (1 << 21))
1416
store_reg(s, rd, tmp);
1418
tcg_temp_free_i32(tmp);
1419
} else if (insn & (1 << 21)) {
1421
tcg_gen_mov_i32(dest, tmp);
1422
if (insn & (1 << 23))
1423
tcg_gen_addi_i32(tmp, tmp, offset);
1425
tcg_gen_addi_i32(tmp, tmp, -offset);
1426
store_reg(s, rd, tmp);
1427
} else if (!(insn & (1 << 23)))
1432
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1434
int rd = (insn >> 0) & 0xf;
1437
if (insn & (1 << 8)) {
1438
if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1441
tmp = iwmmxt_load_creg(rd);
1444
tmp = tcg_temp_new_i32();
1445
iwmmxt_load_reg(cpu_V0, rd);
1446
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1448
tcg_gen_andi_i32(tmp, tmp, mask);
1449
tcg_gen_mov_i32(dest, tmp);
1450
tcg_temp_free_i32(tmp);
1454
/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1455
(ie. an undefined instruction). */
1456
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1459
int rdhi, rdlo, rd0, rd1, i;
1461
TCGv_i32 tmp, tmp2, tmp3;
1463
if ((insn & 0x0e000e00) == 0x0c000000) {
1464
if ((insn & 0x0fe00ff0) == 0x0c400000) {
1466
rdlo = (insn >> 12) & 0xf;
1467
rdhi = (insn >> 16) & 0xf;
1468
if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1469
iwmmxt_load_reg(cpu_V0, wrd);
1470
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1471
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1472
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1473
} else { /* TMCRR */
1474
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1475
iwmmxt_store_reg(cpu_V0, wrd);
1476
gen_op_iwmmxt_set_mup();
1481
wrd = (insn >> 12) & 0xf;
1482
addr = tcg_temp_new_i32();
1483
if (gen_iwmmxt_address(s, insn, addr)) {
1484
tcg_temp_free_i32(addr);
1487
if (insn & ARM_CP_RW_BIT) {
1488
if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1489
tmp = tcg_temp_new_i32();
1490
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1491
iwmmxt_store_creg(wrd, tmp);
1494
if (insn & (1 << 8)) {
1495
if (insn & (1 << 22)) { /* WLDRD */
1496
gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1498
} else { /* WLDRW wRd */
1499
tmp = tcg_temp_new_i32();
1500
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1503
tmp = tcg_temp_new_i32();
1504
if (insn & (1 << 22)) { /* WLDRH */
1505
gen_aa32_ld16u(tmp, addr, IS_USER(s));
1506
} else { /* WLDRB */
1507
gen_aa32_ld8u(tmp, addr, IS_USER(s));
1511
tcg_gen_extu_i32_i64(cpu_M0, tmp);
1512
tcg_temp_free_i32(tmp);
1514
gen_op_iwmmxt_movq_wRn_M0(wrd);
1517
if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1518
tmp = iwmmxt_load_creg(wrd);
1519
gen_aa32_st32(tmp, addr, IS_USER(s));
1521
gen_op_iwmmxt_movq_M0_wRn(wrd);
1522
tmp = tcg_temp_new_i32();
1523
if (insn & (1 << 8)) {
1524
if (insn & (1 << 22)) { /* WSTRD */
1525
gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1526
} else { /* WSTRW wRd */
1527
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1528
gen_aa32_st32(tmp, addr, IS_USER(s));
1531
if (insn & (1 << 22)) { /* WSTRH */
1532
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1533
gen_aa32_st16(tmp, addr, IS_USER(s));
1534
} else { /* WSTRB */
1535
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1536
gen_aa32_st8(tmp, addr, IS_USER(s));
1540
tcg_temp_free_i32(tmp);
1542
tcg_temp_free_i32(addr);
1546
if ((insn & 0x0f000000) != 0x0e000000)
1549
switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1550
case 0x000: /* WOR */
1551
wrd = (insn >> 12) & 0xf;
1552
rd0 = (insn >> 0) & 0xf;
1553
rd1 = (insn >> 16) & 0xf;
1554
gen_op_iwmmxt_movq_M0_wRn(rd0);
1555
gen_op_iwmmxt_orq_M0_wRn(rd1);
1556
gen_op_iwmmxt_setpsr_nz();
1557
gen_op_iwmmxt_movq_wRn_M0(wrd);
1558
gen_op_iwmmxt_set_mup();
1559
gen_op_iwmmxt_set_cup();
1561
case 0x011: /* TMCR */
1564
rd = (insn >> 12) & 0xf;
1565
wrd = (insn >> 16) & 0xf;
1567
case ARM_IWMMXT_wCID:
1568
case ARM_IWMMXT_wCASF:
1570
case ARM_IWMMXT_wCon:
1571
gen_op_iwmmxt_set_cup();
1573
case ARM_IWMMXT_wCSSF:
1574
tmp = iwmmxt_load_creg(wrd);
1575
tmp2 = load_reg(s, rd);
1576
tcg_gen_andc_i32(tmp, tmp, tmp2);
1577
tcg_temp_free_i32(tmp2);
1578
iwmmxt_store_creg(wrd, tmp);
1580
case ARM_IWMMXT_wCGR0:
1581
case ARM_IWMMXT_wCGR1:
1582
case ARM_IWMMXT_wCGR2:
1583
case ARM_IWMMXT_wCGR3:
1584
gen_op_iwmmxt_set_cup();
1585
tmp = load_reg(s, rd);
1586
iwmmxt_store_creg(wrd, tmp);
1592
case 0x100: /* WXOR */
1593
wrd = (insn >> 12) & 0xf;
1594
rd0 = (insn >> 0) & 0xf;
1595
rd1 = (insn >> 16) & 0xf;
1596
gen_op_iwmmxt_movq_M0_wRn(rd0);
1597
gen_op_iwmmxt_xorq_M0_wRn(rd1);
1598
gen_op_iwmmxt_setpsr_nz();
1599
gen_op_iwmmxt_movq_wRn_M0(wrd);
1600
gen_op_iwmmxt_set_mup();
1601
gen_op_iwmmxt_set_cup();
1603
case 0x111: /* TMRC */
1606
rd = (insn >> 12) & 0xf;
1607
wrd = (insn >> 16) & 0xf;
1608
tmp = iwmmxt_load_creg(wrd);
1609
store_reg(s, rd, tmp);
1611
case 0x300: /* WANDN */
1612
wrd = (insn >> 12) & 0xf;
1613
rd0 = (insn >> 0) & 0xf;
1614
rd1 = (insn >> 16) & 0xf;
1615
gen_op_iwmmxt_movq_M0_wRn(rd0);
1616
tcg_gen_neg_i64(cpu_M0, cpu_M0);
1617
gen_op_iwmmxt_andq_M0_wRn(rd1);
1618
gen_op_iwmmxt_setpsr_nz();
1619
gen_op_iwmmxt_movq_wRn_M0(wrd);
1620
gen_op_iwmmxt_set_mup();
1621
gen_op_iwmmxt_set_cup();
1623
case 0x200: /* WAND */
1624
wrd = (insn >> 12) & 0xf;
1625
rd0 = (insn >> 0) & 0xf;
1626
rd1 = (insn >> 16) & 0xf;
1627
gen_op_iwmmxt_movq_M0_wRn(rd0);
1628
gen_op_iwmmxt_andq_M0_wRn(rd1);
1629
gen_op_iwmmxt_setpsr_nz();
1630
gen_op_iwmmxt_movq_wRn_M0(wrd);
1631
gen_op_iwmmxt_set_mup();
1632
gen_op_iwmmxt_set_cup();
1634
case 0x810: case 0xa10: /* WMADD */
1635
wrd = (insn >> 12) & 0xf;
1636
rd0 = (insn >> 0) & 0xf;
1637
rd1 = (insn >> 16) & 0xf;
1638
gen_op_iwmmxt_movq_M0_wRn(rd0);
1639
if (insn & (1 << 21))
1640
gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1642
gen_op_iwmmxt_madduq_M0_wRn(rd1);
1643
gen_op_iwmmxt_movq_wRn_M0(wrd);
1644
gen_op_iwmmxt_set_mup();
1646
case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1647
wrd = (insn >> 12) & 0xf;
1648
rd0 = (insn >> 16) & 0xf;
1649
rd1 = (insn >> 0) & 0xf;
1650
gen_op_iwmmxt_movq_M0_wRn(rd0);
1651
switch ((insn >> 22) & 3) {
1653
gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1656
gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1659
gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1664
gen_op_iwmmxt_movq_wRn_M0(wrd);
1665
gen_op_iwmmxt_set_mup();
1666
gen_op_iwmmxt_set_cup();
1668
case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1669
wrd = (insn >> 12) & 0xf;
1670
rd0 = (insn >> 16) & 0xf;
1671
rd1 = (insn >> 0) & 0xf;
1672
gen_op_iwmmxt_movq_M0_wRn(rd0);
1673
switch ((insn >> 22) & 3) {
1675
gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1678
gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1681
gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1686
gen_op_iwmmxt_movq_wRn_M0(wrd);
1687
gen_op_iwmmxt_set_mup();
1688
gen_op_iwmmxt_set_cup();
1690
case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1691
wrd = (insn >> 12) & 0xf;
1692
rd0 = (insn >> 16) & 0xf;
1693
rd1 = (insn >> 0) & 0xf;
1694
gen_op_iwmmxt_movq_M0_wRn(rd0);
1695
if (insn & (1 << 22))
1696
gen_op_iwmmxt_sadw_M0_wRn(rd1);
1698
gen_op_iwmmxt_sadb_M0_wRn(rd1);
1699
if (!(insn & (1 << 20)))
1700
gen_op_iwmmxt_addl_M0_wRn(wrd);
1701
gen_op_iwmmxt_movq_wRn_M0(wrd);
1702
gen_op_iwmmxt_set_mup();
1704
case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1705
wrd = (insn >> 12) & 0xf;
1706
rd0 = (insn >> 16) & 0xf;
1707
rd1 = (insn >> 0) & 0xf;
1708
gen_op_iwmmxt_movq_M0_wRn(rd0);
1709
if (insn & (1 << 21)) {
1710
if (insn & (1 << 20))
1711
gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1713
gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1715
if (insn & (1 << 20))
1716
gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1718
gen_op_iwmmxt_mululw_M0_wRn(rd1);
1720
gen_op_iwmmxt_movq_wRn_M0(wrd);
1721
gen_op_iwmmxt_set_mup();
1723
case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1724
wrd = (insn >> 12) & 0xf;
1725
rd0 = (insn >> 16) & 0xf;
1726
rd1 = (insn >> 0) & 0xf;
1727
gen_op_iwmmxt_movq_M0_wRn(rd0);
1728
if (insn & (1 << 21))
1729
gen_op_iwmmxt_macsw_M0_wRn(rd1);
1731
gen_op_iwmmxt_macuw_M0_wRn(rd1);
1732
if (!(insn & (1 << 20))) {
1733
iwmmxt_load_reg(cpu_V1, wrd);
1734
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1736
gen_op_iwmmxt_movq_wRn_M0(wrd);
1737
gen_op_iwmmxt_set_mup();
1739
case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1740
wrd = (insn >> 12) & 0xf;
1741
rd0 = (insn >> 16) & 0xf;
1742
rd1 = (insn >> 0) & 0xf;
1743
gen_op_iwmmxt_movq_M0_wRn(rd0);
1744
switch ((insn >> 22) & 3) {
1746
gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1749
gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1752
gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1757
gen_op_iwmmxt_movq_wRn_M0(wrd);
1758
gen_op_iwmmxt_set_mup();
1759
gen_op_iwmmxt_set_cup();
1761
case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1762
wrd = (insn >> 12) & 0xf;
1763
rd0 = (insn >> 16) & 0xf;
1764
rd1 = (insn >> 0) & 0xf;
1765
gen_op_iwmmxt_movq_M0_wRn(rd0);
1766
if (insn & (1 << 22)) {
1767
if (insn & (1 << 20))
1768
gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1770
gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1772
if (insn & (1 << 20))
1773
gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1775
gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1777
gen_op_iwmmxt_movq_wRn_M0(wrd);
1778
gen_op_iwmmxt_set_mup();
1779
gen_op_iwmmxt_set_cup();
1781
case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1782
wrd = (insn >> 12) & 0xf;
1783
rd0 = (insn >> 16) & 0xf;
1784
rd1 = (insn >> 0) & 0xf;
1785
gen_op_iwmmxt_movq_M0_wRn(rd0);
1786
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1787
tcg_gen_andi_i32(tmp, tmp, 7);
1788
iwmmxt_load_reg(cpu_V1, rd1);
1789
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1790
tcg_temp_free_i32(tmp);
1791
gen_op_iwmmxt_movq_wRn_M0(wrd);
1792
gen_op_iwmmxt_set_mup();
1794
case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1795
if (((insn >> 6) & 3) == 3)
1797
rd = (insn >> 12) & 0xf;
1798
wrd = (insn >> 16) & 0xf;
1799
tmp = load_reg(s, rd);
1800
gen_op_iwmmxt_movq_M0_wRn(wrd);
1801
switch ((insn >> 6) & 3) {
1803
tmp2 = tcg_const_i32(0xff);
1804
tmp3 = tcg_const_i32((insn & 7) << 3);
1807
tmp2 = tcg_const_i32(0xffff);
1808
tmp3 = tcg_const_i32((insn & 3) << 4);
1811
tmp2 = tcg_const_i32(0xffffffff);
1812
tmp3 = tcg_const_i32((insn & 1) << 5);
1815
TCGV_UNUSED_I32(tmp2);
1816
TCGV_UNUSED_I32(tmp3);
1818
gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1819
tcg_temp_free_i32(tmp3);
1820
tcg_temp_free_i32(tmp2);
1821
tcg_temp_free_i32(tmp);
1822
gen_op_iwmmxt_movq_wRn_M0(wrd);
1823
gen_op_iwmmxt_set_mup();
1825
case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1826
rd = (insn >> 12) & 0xf;
1827
wrd = (insn >> 16) & 0xf;
1828
if (rd == 15 || ((insn >> 22) & 3) == 3)
1830
gen_op_iwmmxt_movq_M0_wRn(wrd);
1831
tmp = tcg_temp_new_i32();
1832
switch ((insn >> 22) & 3) {
1834
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1835
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1837
tcg_gen_ext8s_i32(tmp, tmp);
1839
tcg_gen_andi_i32(tmp, tmp, 0xff);
1843
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1844
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1846
tcg_gen_ext16s_i32(tmp, tmp);
1848
tcg_gen_andi_i32(tmp, tmp, 0xffff);
1852
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1853
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1856
store_reg(s, rd, tmp);
1858
case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1859
if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1861
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1862
switch ((insn >> 22) & 3) {
1864
tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1867
tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1870
tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1873
tcg_gen_shli_i32(tmp, tmp, 28);
1875
tcg_temp_free_i32(tmp);
1877
case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1878
if (((insn >> 6) & 3) == 3)
1880
rd = (insn >> 12) & 0xf;
1881
wrd = (insn >> 16) & 0xf;
1882
tmp = load_reg(s, rd);
1883
switch ((insn >> 6) & 3) {
1885
gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1888
gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1891
gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1894
tcg_temp_free_i32(tmp);
1895
gen_op_iwmmxt_movq_wRn_M0(wrd);
1896
gen_op_iwmmxt_set_mup();
1898
case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1899
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1901
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1902
tmp2 = tcg_temp_new_i32();
1903
tcg_gen_mov_i32(tmp2, tmp);
1904
switch ((insn >> 22) & 3) {
1906
for (i = 0; i < 7; i ++) {
1907
tcg_gen_shli_i32(tmp2, tmp2, 4);
1908
tcg_gen_and_i32(tmp, tmp, tmp2);
1912
for (i = 0; i < 3; i ++) {
1913
tcg_gen_shli_i32(tmp2, tmp2, 8);
1914
tcg_gen_and_i32(tmp, tmp, tmp2);
1918
tcg_gen_shli_i32(tmp2, tmp2, 16);
1919
tcg_gen_and_i32(tmp, tmp, tmp2);
1923
tcg_temp_free_i32(tmp2);
1924
tcg_temp_free_i32(tmp);
1926
case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1927
wrd = (insn >> 12) & 0xf;
1928
rd0 = (insn >> 16) & 0xf;
1929
gen_op_iwmmxt_movq_M0_wRn(rd0);
1930
switch ((insn >> 22) & 3) {
1932
gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1935
gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1938
gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1943
gen_op_iwmmxt_movq_wRn_M0(wrd);
1944
gen_op_iwmmxt_set_mup();
1946
case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1947
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1949
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1950
tmp2 = tcg_temp_new_i32();
1951
tcg_gen_mov_i32(tmp2, tmp);
1952
switch ((insn >> 22) & 3) {
1954
for (i = 0; i < 7; i ++) {
1955
tcg_gen_shli_i32(tmp2, tmp2, 4);
1956
tcg_gen_or_i32(tmp, tmp, tmp2);
1960
for (i = 0; i < 3; i ++) {
1961
tcg_gen_shli_i32(tmp2, tmp2, 8);
1962
tcg_gen_or_i32(tmp, tmp, tmp2);
1966
tcg_gen_shli_i32(tmp2, tmp2, 16);
1967
tcg_gen_or_i32(tmp, tmp, tmp2);
1971
tcg_temp_free_i32(tmp2);
1972
tcg_temp_free_i32(tmp);
1974
case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1975
rd = (insn >> 12) & 0xf;
1976
rd0 = (insn >> 16) & 0xf;
1977
if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1979
gen_op_iwmmxt_movq_M0_wRn(rd0);
1980
tmp = tcg_temp_new_i32();
1981
switch ((insn >> 22) & 3) {
1983
gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1986
gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1989
gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1992
store_reg(s, rd, tmp);
1994
case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1995
case 0x906: case 0xb06: case 0xd06: case 0xf06:
1996
wrd = (insn >> 12) & 0xf;
1997
rd0 = (insn >> 16) & 0xf;
1998
rd1 = (insn >> 0) & 0xf;
1999
gen_op_iwmmxt_movq_M0_wRn(rd0);
2000
switch ((insn >> 22) & 3) {
2002
if (insn & (1 << 21))
2003
gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2005
gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2008
if (insn & (1 << 21))
2009
gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2011
gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2014
if (insn & (1 << 21))
2015
gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2017
gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2022
gen_op_iwmmxt_movq_wRn_M0(wrd);
2023
gen_op_iwmmxt_set_mup();
2024
gen_op_iwmmxt_set_cup();
2026
case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2027
case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2028
wrd = (insn >> 12) & 0xf;
2029
rd0 = (insn >> 16) & 0xf;
2030
gen_op_iwmmxt_movq_M0_wRn(rd0);
2031
switch ((insn >> 22) & 3) {
2033
if (insn & (1 << 21))
2034
gen_op_iwmmxt_unpacklsb_M0();
2036
gen_op_iwmmxt_unpacklub_M0();
2039
if (insn & (1 << 21))
2040
gen_op_iwmmxt_unpacklsw_M0();
2042
gen_op_iwmmxt_unpackluw_M0();
2045
if (insn & (1 << 21))
2046
gen_op_iwmmxt_unpacklsl_M0();
2048
gen_op_iwmmxt_unpacklul_M0();
2053
gen_op_iwmmxt_movq_wRn_M0(wrd);
2054
gen_op_iwmmxt_set_mup();
2055
gen_op_iwmmxt_set_cup();
2057
case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2058
case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2059
wrd = (insn >> 12) & 0xf;
2060
rd0 = (insn >> 16) & 0xf;
2061
gen_op_iwmmxt_movq_M0_wRn(rd0);
2062
switch ((insn >> 22) & 3) {
2064
if (insn & (1 << 21))
2065
gen_op_iwmmxt_unpackhsb_M0();
2067
gen_op_iwmmxt_unpackhub_M0();
2070
if (insn & (1 << 21))
2071
gen_op_iwmmxt_unpackhsw_M0();
2073
gen_op_iwmmxt_unpackhuw_M0();
2076
if (insn & (1 << 21))
2077
gen_op_iwmmxt_unpackhsl_M0();
2079
gen_op_iwmmxt_unpackhul_M0();
2084
gen_op_iwmmxt_movq_wRn_M0(wrd);
2085
gen_op_iwmmxt_set_mup();
2086
gen_op_iwmmxt_set_cup();
2088
case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2089
case 0x214: case 0x614: case 0xa14: case 0xe14:
2090
if (((insn >> 22) & 3) == 0)
2092
wrd = (insn >> 12) & 0xf;
2093
rd0 = (insn >> 16) & 0xf;
2094
gen_op_iwmmxt_movq_M0_wRn(rd0);
2095
tmp = tcg_temp_new_i32();
2096
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2097
tcg_temp_free_i32(tmp);
2100
switch ((insn >> 22) & 3) {
2102
gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2105
gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2108
gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2111
tcg_temp_free_i32(tmp);
2112
gen_op_iwmmxt_movq_wRn_M0(wrd);
2113
gen_op_iwmmxt_set_mup();
2114
gen_op_iwmmxt_set_cup();
2116
case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2117
case 0x014: case 0x414: case 0x814: case 0xc14:
2118
if (((insn >> 22) & 3) == 0)
2120
wrd = (insn >> 12) & 0xf;
2121
rd0 = (insn >> 16) & 0xf;
2122
gen_op_iwmmxt_movq_M0_wRn(rd0);
2123
tmp = tcg_temp_new_i32();
2124
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2125
tcg_temp_free_i32(tmp);
2128
switch ((insn >> 22) & 3) {
2130
gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2133
gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2136
gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2139
tcg_temp_free_i32(tmp);
2140
gen_op_iwmmxt_movq_wRn_M0(wrd);
2141
gen_op_iwmmxt_set_mup();
2142
gen_op_iwmmxt_set_cup();
2144
case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2145
case 0x114: case 0x514: case 0x914: case 0xd14:
2146
if (((insn >> 22) & 3) == 0)
2148
wrd = (insn >> 12) & 0xf;
2149
rd0 = (insn >> 16) & 0xf;
2150
gen_op_iwmmxt_movq_M0_wRn(rd0);
2151
tmp = tcg_temp_new_i32();
2152
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2153
tcg_temp_free_i32(tmp);
2156
switch ((insn >> 22) & 3) {
2158
gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2161
gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2164
gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2167
tcg_temp_free_i32(tmp);
2168
gen_op_iwmmxt_movq_wRn_M0(wrd);
2169
gen_op_iwmmxt_set_mup();
2170
gen_op_iwmmxt_set_cup();
2172
case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2173
case 0x314: case 0x714: case 0xb14: case 0xf14:
2174
if (((insn >> 22) & 3) == 0)
2176
wrd = (insn >> 12) & 0xf;
2177
rd0 = (insn >> 16) & 0xf;
2178
gen_op_iwmmxt_movq_M0_wRn(rd0);
2179
tmp = tcg_temp_new_i32();
2180
switch ((insn >> 22) & 3) {
2182
if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2183
tcg_temp_free_i32(tmp);
2186
gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2189
if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2190
tcg_temp_free_i32(tmp);
2193
gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2196
if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2197
tcg_temp_free_i32(tmp);
2200
gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2203
tcg_temp_free_i32(tmp);
2204
gen_op_iwmmxt_movq_wRn_M0(wrd);
2205
gen_op_iwmmxt_set_mup();
2206
gen_op_iwmmxt_set_cup();
2208
case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2209
case 0x916: case 0xb16: case 0xd16: case 0xf16:
2210
wrd = (insn >> 12) & 0xf;
2211
rd0 = (insn >> 16) & 0xf;
2212
rd1 = (insn >> 0) & 0xf;
2213
gen_op_iwmmxt_movq_M0_wRn(rd0);
2214
switch ((insn >> 22) & 3) {
2216
if (insn & (1 << 21))
2217
gen_op_iwmmxt_minsb_M0_wRn(rd1);
2219
gen_op_iwmmxt_minub_M0_wRn(rd1);
2222
if (insn & (1 << 21))
2223
gen_op_iwmmxt_minsw_M0_wRn(rd1);
2225
gen_op_iwmmxt_minuw_M0_wRn(rd1);
2228
if (insn & (1 << 21))
2229
gen_op_iwmmxt_minsl_M0_wRn(rd1);
2231
gen_op_iwmmxt_minul_M0_wRn(rd1);
2236
gen_op_iwmmxt_movq_wRn_M0(wrd);
2237
gen_op_iwmmxt_set_mup();
2239
case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2240
case 0x816: case 0xa16: case 0xc16: case 0xe16:
2241
wrd = (insn >> 12) & 0xf;
2242
rd0 = (insn >> 16) & 0xf;
2243
rd1 = (insn >> 0) & 0xf;
2244
gen_op_iwmmxt_movq_M0_wRn(rd0);
2245
switch ((insn >> 22) & 3) {
2247
if (insn & (1 << 21))
2248
gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2250
gen_op_iwmmxt_maxub_M0_wRn(rd1);
2253
if (insn & (1 << 21))
2254
gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2256
gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2259
if (insn & (1 << 21))
2260
gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2262
gen_op_iwmmxt_maxul_M0_wRn(rd1);
2267
gen_op_iwmmxt_movq_wRn_M0(wrd);
2268
gen_op_iwmmxt_set_mup();
2270
case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2271
case 0x402: case 0x502: case 0x602: case 0x702:
2272
wrd = (insn >> 12) & 0xf;
2273
rd0 = (insn >> 16) & 0xf;
2274
rd1 = (insn >> 0) & 0xf;
2275
gen_op_iwmmxt_movq_M0_wRn(rd0);
2276
tmp = tcg_const_i32((insn >> 20) & 3);
2277
iwmmxt_load_reg(cpu_V1, rd1);
2278
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2279
tcg_temp_free_i32(tmp);
2280
gen_op_iwmmxt_movq_wRn_M0(wrd);
2281
gen_op_iwmmxt_set_mup();
2283
case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2284
case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2285
case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2286
case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2287
wrd = (insn >> 12) & 0xf;
2288
rd0 = (insn >> 16) & 0xf;
2289
rd1 = (insn >> 0) & 0xf;
2290
gen_op_iwmmxt_movq_M0_wRn(rd0);
2291
switch ((insn >> 20) & 0xf) {
2293
gen_op_iwmmxt_subnb_M0_wRn(rd1);
2296
gen_op_iwmmxt_subub_M0_wRn(rd1);
2299
gen_op_iwmmxt_subsb_M0_wRn(rd1);
2302
gen_op_iwmmxt_subnw_M0_wRn(rd1);
2305
gen_op_iwmmxt_subuw_M0_wRn(rd1);
2308
gen_op_iwmmxt_subsw_M0_wRn(rd1);
2311
gen_op_iwmmxt_subnl_M0_wRn(rd1);
2314
gen_op_iwmmxt_subul_M0_wRn(rd1);
2317
gen_op_iwmmxt_subsl_M0_wRn(rd1);
2322
gen_op_iwmmxt_movq_wRn_M0(wrd);
2323
gen_op_iwmmxt_set_mup();
2324
gen_op_iwmmxt_set_cup();
2326
case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2327
case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2328
case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2329
case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2330
wrd = (insn >> 12) & 0xf;
2331
rd0 = (insn >> 16) & 0xf;
2332
gen_op_iwmmxt_movq_M0_wRn(rd0);
2333
tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2334
gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2335
tcg_temp_free_i32(tmp);
2336
gen_op_iwmmxt_movq_wRn_M0(wrd);
2337
gen_op_iwmmxt_set_mup();
2338
gen_op_iwmmxt_set_cup();
2340
case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2341
case 0x418: case 0x518: case 0x618: case 0x718:
2342
case 0x818: case 0x918: case 0xa18: case 0xb18:
2343
case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2344
wrd = (insn >> 12) & 0xf;
2345
rd0 = (insn >> 16) & 0xf;
2346
rd1 = (insn >> 0) & 0xf;
2347
gen_op_iwmmxt_movq_M0_wRn(rd0);
2348
switch ((insn >> 20) & 0xf) {
2350
gen_op_iwmmxt_addnb_M0_wRn(rd1);
2353
gen_op_iwmmxt_addub_M0_wRn(rd1);
2356
gen_op_iwmmxt_addsb_M0_wRn(rd1);
2359
gen_op_iwmmxt_addnw_M0_wRn(rd1);
2362
gen_op_iwmmxt_adduw_M0_wRn(rd1);
2365
gen_op_iwmmxt_addsw_M0_wRn(rd1);
2368
gen_op_iwmmxt_addnl_M0_wRn(rd1);
2371
gen_op_iwmmxt_addul_M0_wRn(rd1);
2374
gen_op_iwmmxt_addsl_M0_wRn(rd1);
2379
gen_op_iwmmxt_movq_wRn_M0(wrd);
2380
gen_op_iwmmxt_set_mup();
2381
gen_op_iwmmxt_set_cup();
2383
case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2384
case 0x408: case 0x508: case 0x608: case 0x708:
2385
case 0x808: case 0x908: case 0xa08: case 0xb08:
2386
case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2387
if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2389
wrd = (insn >> 12) & 0xf;
2390
rd0 = (insn >> 16) & 0xf;
2391
rd1 = (insn >> 0) & 0xf;
2392
gen_op_iwmmxt_movq_M0_wRn(rd0);
2393
switch ((insn >> 22) & 3) {
2395
if (insn & (1 << 21))
2396
gen_op_iwmmxt_packsw_M0_wRn(rd1);
2398
gen_op_iwmmxt_packuw_M0_wRn(rd1);
2401
if (insn & (1 << 21))
2402
gen_op_iwmmxt_packsl_M0_wRn(rd1);
2404
gen_op_iwmmxt_packul_M0_wRn(rd1);
2407
if (insn & (1 << 21))
2408
gen_op_iwmmxt_packsq_M0_wRn(rd1);
2410
gen_op_iwmmxt_packuq_M0_wRn(rd1);
2413
gen_op_iwmmxt_movq_wRn_M0(wrd);
2414
gen_op_iwmmxt_set_mup();
2415
gen_op_iwmmxt_set_cup();
2417
case 0x201: case 0x203: case 0x205: case 0x207:
2418
case 0x209: case 0x20b: case 0x20d: case 0x20f:
2419
case 0x211: case 0x213: case 0x215: case 0x217:
2420
case 0x219: case 0x21b: case 0x21d: case 0x21f:
2421
wrd = (insn >> 5) & 0xf;
2422
rd0 = (insn >> 12) & 0xf;
2423
rd1 = (insn >> 0) & 0xf;
2424
if (rd0 == 0xf || rd1 == 0xf)
2426
gen_op_iwmmxt_movq_M0_wRn(wrd);
2427
tmp = load_reg(s, rd0);
2428
tmp2 = load_reg(s, rd1);
2429
switch ((insn >> 16) & 0xf) {
2430
case 0x0: /* TMIA */
2431
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2433
case 0x8: /* TMIAPH */
2434
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2436
case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2437
if (insn & (1 << 16))
2438
tcg_gen_shri_i32(tmp, tmp, 16);
2439
if (insn & (1 << 17))
2440
tcg_gen_shri_i32(tmp2, tmp2, 16);
2441
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2444
tcg_temp_free_i32(tmp2);
2445
tcg_temp_free_i32(tmp);
2448
tcg_temp_free_i32(tmp2);
2449
tcg_temp_free_i32(tmp);
2450
gen_op_iwmmxt_movq_wRn_M0(wrd);
2451
gen_op_iwmmxt_set_mup();
2460
/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2461
(ie. an undefined instruction). */
2462
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2464
int acc, rd0, rd1, rdhi, rdlo;
2467
if ((insn & 0x0ff00f10) == 0x0e200010) {
2468
/* Multiply with Internal Accumulate Format */
2469
rd0 = (insn >> 12) & 0xf;
2471
acc = (insn >> 5) & 7;
2476
tmp = load_reg(s, rd0);
2477
tmp2 = load_reg(s, rd1);
2478
switch ((insn >> 16) & 0xf) {
2480
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2482
case 0x8: /* MIAPH */
2483
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2485
case 0xc: /* MIABB */
2486
case 0xd: /* MIABT */
2487
case 0xe: /* MIATB */
2488
case 0xf: /* MIATT */
2489
if (insn & (1 << 16))
2490
tcg_gen_shri_i32(tmp, tmp, 16);
2491
if (insn & (1 << 17))
2492
tcg_gen_shri_i32(tmp2, tmp2, 16);
2493
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2498
tcg_temp_free_i32(tmp2);
2499
tcg_temp_free_i32(tmp);
2501
gen_op_iwmmxt_movq_wRn_M0(acc);
2505
if ((insn & 0x0fe00ff8) == 0x0c400000) {
2506
/* Internal Accumulator Access Format */
2507
rdhi = (insn >> 16) & 0xf;
2508
rdlo = (insn >> 12) & 0xf;
2514
if (insn & ARM_CP_RW_BIT) { /* MRA */
2515
iwmmxt_load_reg(cpu_V0, acc);
2516
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2517
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2518
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2519
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2521
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2522
iwmmxt_store_reg(cpu_V0, acc);
2530
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2531
#define VFP_SREG(insn, bigbit, smallbit) \
2532
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2533
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2534
if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2535
reg = (((insn) >> (bigbit)) & 0x0f) \
2536
| (((insn) >> ((smallbit) - 4)) & 0x10); \
2538
if (insn & (1 << (smallbit))) \
2540
reg = ((insn) >> (bigbit)) & 0x0f; \
2543
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2544
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2545
#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2546
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2547
#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2548
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2550
/* Move between integer and VFP cores. */
2551
static TCGv_i32 gen_vfp_mrs(void)
2553
TCGv_i32 tmp = tcg_temp_new_i32();
2554
tcg_gen_mov_i32(tmp, cpu_F0s);
2558
static void gen_vfp_msr(TCGv_i32 tmp)
2560
tcg_gen_mov_i32(cpu_F0s, tmp);
2561
tcg_temp_free_i32(tmp);
2564
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2566
TCGv_i32 tmp = tcg_temp_new_i32();
2568
tcg_gen_shri_i32(var, var, shift);
2569
tcg_gen_ext8u_i32(var, var);
2570
tcg_gen_shli_i32(tmp, var, 8);
2571
tcg_gen_or_i32(var, var, tmp);
2572
tcg_gen_shli_i32(tmp, var, 16);
2573
tcg_gen_or_i32(var, var, tmp);
2574
tcg_temp_free_i32(tmp);
2577
static void gen_neon_dup_low16(TCGv_i32 var)
2579
TCGv_i32 tmp = tcg_temp_new_i32();
2580
tcg_gen_ext16u_i32(var, var);
2581
tcg_gen_shli_i32(tmp, var, 16);
2582
tcg_gen_or_i32(var, var, tmp);
2583
tcg_temp_free_i32(tmp);
2586
static void gen_neon_dup_high16(TCGv_i32 var)
2588
TCGv_i32 tmp = tcg_temp_new_i32();
2589
tcg_gen_andi_i32(var, var, 0xffff0000);
2590
tcg_gen_shri_i32(tmp, var, 16);
2591
tcg_gen_or_i32(var, var, tmp);
2592
tcg_temp_free_i32(tmp);
2595
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2597
/* Load a single Neon element and replicate into a 32 bit TCG reg */
2598
TCGv_i32 tmp = tcg_temp_new_i32();
2601
gen_aa32_ld8u(tmp, addr, IS_USER(s));
2602
gen_neon_dup_u8(tmp, 0);
2605
gen_aa32_ld16u(tmp, addr, IS_USER(s));
2606
gen_neon_dup_low16(tmp);
2609
gen_aa32_ld32u(tmp, addr, IS_USER(s));
2611
default: /* Avoid compiler warnings. */
2617
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2620
uint32_t cc = extract32(insn, 20, 2);
2623
TCGv_i64 frn, frm, dest;
2624
TCGv_i64 tmp, zero, zf, nf, vf;
2626
zero = tcg_const_i64(0);
2628
frn = tcg_temp_new_i64();
2629
frm = tcg_temp_new_i64();
2630
dest = tcg_temp_new_i64();
2632
zf = tcg_temp_new_i64();
2633
nf = tcg_temp_new_i64();
2634
vf = tcg_temp_new_i64();
2636
tcg_gen_extu_i32_i64(zf, cpu_ZF);
2637
tcg_gen_ext_i32_i64(nf, cpu_NF);
2638
tcg_gen_ext_i32_i64(vf, cpu_VF);
2640
tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2641
tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2644
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2648
tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2651
case 2: /* ge: N == V -> N ^ V == 0 */
2652
tmp = tcg_temp_new_i64();
2653
tcg_gen_xor_i64(tmp, vf, nf);
2654
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2656
tcg_temp_free_i64(tmp);
2658
case 3: /* gt: !Z && N == V */
2659
tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2661
tmp = tcg_temp_new_i64();
2662
tcg_gen_xor_i64(tmp, vf, nf);
2663
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2665
tcg_temp_free_i64(tmp);
2668
tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2669
tcg_temp_free_i64(frn);
2670
tcg_temp_free_i64(frm);
2671
tcg_temp_free_i64(dest);
2673
tcg_temp_free_i64(zf);
2674
tcg_temp_free_i64(nf);
2675
tcg_temp_free_i64(vf);
2677
tcg_temp_free_i64(zero);
2679
TCGv_i32 frn, frm, dest;
2682
zero = tcg_const_i32(0);
2684
frn = tcg_temp_new_i32();
2685
frm = tcg_temp_new_i32();
2686
dest = tcg_temp_new_i32();
2687
tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2688
tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2691
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2695
tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2698
case 2: /* ge: N == V -> N ^ V == 0 */
2699
tmp = tcg_temp_new_i32();
2700
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2701
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2703
tcg_temp_free_i32(tmp);
2705
case 3: /* gt: !Z && N == V */
2706
tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2708
tmp = tcg_temp_new_i32();
2709
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2710
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2712
tcg_temp_free_i32(tmp);
2715
tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2716
tcg_temp_free_i32(frn);
2717
tcg_temp_free_i32(frm);
2718
tcg_temp_free_i32(dest);
2720
tcg_temp_free_i32(zero);
2726
static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2727
uint32_t rm, uint32_t dp)
2729
uint32_t vmin = extract32(insn, 6, 1);
2730
TCGv_ptr fpst = get_fpstatus_ptr(0);
2733
TCGv_i64 frn, frm, dest;
2735
frn = tcg_temp_new_i64();
2736
frm = tcg_temp_new_i64();
2737
dest = tcg_temp_new_i64();
2739
tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2740
tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2742
gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2744
gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2746
tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2747
tcg_temp_free_i64(frn);
2748
tcg_temp_free_i64(frm);
2749
tcg_temp_free_i64(dest);
2751
TCGv_i32 frn, frm, dest;
2753
frn = tcg_temp_new_i32();
2754
frm = tcg_temp_new_i32();
2755
dest = tcg_temp_new_i32();
2757
tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2758
tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2760
gen_helper_vfp_minnums(dest, frn, frm, fpst);
2762
gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2764
tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2765
tcg_temp_free_i32(frn);
2766
tcg_temp_free_i32(frm);
2767
tcg_temp_free_i32(dest);
2770
tcg_temp_free_ptr(fpst);
2774
static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2777
TCGv_ptr fpst = get_fpstatus_ptr(0);
2780
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2781
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2786
tcg_op = tcg_temp_new_i64();
2787
tcg_res = tcg_temp_new_i64();
2788
tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2789
gen_helper_rintd(tcg_res, tcg_op, fpst);
2790
tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2791
tcg_temp_free_i64(tcg_op);
2792
tcg_temp_free_i64(tcg_res);
2796
tcg_op = tcg_temp_new_i32();
2797
tcg_res = tcg_temp_new_i32();
2798
tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2799
gen_helper_rints(tcg_res, tcg_op, fpst);
2800
tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2801
tcg_temp_free_i32(tcg_op);
2802
tcg_temp_free_i32(tcg_res);
2805
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2806
tcg_temp_free_i32(tcg_rmode);
2808
tcg_temp_free_ptr(fpst);
2813
/* Table for converting the most common AArch32 encoding of
2814
* rounding mode to arm_fprounding order (which matches the
2815
* common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2817
static const uint8_t fp_decode_rm[] = {
2824
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2826
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2828
if (!arm_feature(env, ARM_FEATURE_V8)) {
2833
VFP_DREG_D(rd, insn);
2834
VFP_DREG_N(rn, insn);
2835
VFP_DREG_M(rm, insn);
2837
rd = VFP_SREG_D(insn);
2838
rn = VFP_SREG_N(insn);
2839
rm = VFP_SREG_M(insn);
2842
if ((insn & 0x0f800e50) == 0x0e000a00) {
2843
return handle_vsel(insn, rd, rn, rm, dp);
2844
} else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2845
return handle_vminmaxnm(insn, rd, rn, rm, dp);
2846
} else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
2847
/* VRINTA, VRINTN, VRINTP, VRINTM */
2848
int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2849
return handle_vrint(insn, rd, rm, dp, rounding);
2854
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2855
(ie. an undefined instruction). */
2856
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2858
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2864
if (!arm_feature(env, ARM_FEATURE_VFP))
2867
if (!s->vfp_enabled) {
2868
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2869
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2871
rn = (insn >> 16) & 0xf;
2872
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2873
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2877
if (extract32(insn, 28, 4) == 0xf) {
2878
/* Encodings with T=1 (Thumb) or unconditional (ARM):
2879
* only used in v8 and above.
2881
return disas_vfp_v8_insn(env, s, insn);
2884
dp = ((insn & 0xf00) == 0xb00);
2885
switch ((insn >> 24) & 0xf) {
2887
if (insn & (1 << 4)) {
2888
/* single register transfer */
2889
rd = (insn >> 12) & 0xf;
2894
VFP_DREG_N(rn, insn);
2897
if (insn & 0x00c00060
2898
&& !arm_feature(env, ARM_FEATURE_NEON))
2901
pass = (insn >> 21) & 1;
2902
if (insn & (1 << 22)) {
2904
offset = ((insn >> 5) & 3) * 8;
2905
} else if (insn & (1 << 5)) {
2907
offset = (insn & (1 << 6)) ? 16 : 0;
2912
if (insn & ARM_CP_RW_BIT) {
2914
tmp = neon_load_reg(rn, pass);
2918
tcg_gen_shri_i32(tmp, tmp, offset);
2919
if (insn & (1 << 23))
2925
if (insn & (1 << 23)) {
2927
tcg_gen_shri_i32(tmp, tmp, 16);
2933
tcg_gen_sari_i32(tmp, tmp, 16);
2942
store_reg(s, rd, tmp);
2945
tmp = load_reg(s, rd);
2946
if (insn & (1 << 23)) {
2949
gen_neon_dup_u8(tmp, 0);
2950
} else if (size == 1) {
2951
gen_neon_dup_low16(tmp);
2953
for (n = 0; n <= pass * 2; n++) {
2954
tmp2 = tcg_temp_new_i32();
2955
tcg_gen_mov_i32(tmp2, tmp);
2956
neon_store_reg(rn, n, tmp2);
2958
neon_store_reg(rn, n, tmp);
2963
tmp2 = neon_load_reg(rn, pass);
2964
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2965
tcg_temp_free_i32(tmp2);
2968
tmp2 = neon_load_reg(rn, pass);
2969
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2970
tcg_temp_free_i32(tmp2);
2975
neon_store_reg(rn, pass, tmp);
2979
if ((insn & 0x6f) != 0x00)
2981
rn = VFP_SREG_N(insn);
2982
if (insn & ARM_CP_RW_BIT) {
2984
if (insn & (1 << 21)) {
2985
/* system register */
2990
/* VFP2 allows access to FSID from userspace.
2991
VFP3 restricts all id registers to privileged
2994
&& arm_feature(env, ARM_FEATURE_VFP3))
2996
tmp = load_cpu_field(vfp.xregs[rn]);
3001
tmp = load_cpu_field(vfp.xregs[rn]);
3003
case ARM_VFP_FPINST:
3004
case ARM_VFP_FPINST2:
3005
/* Not present in VFP3. */
3007
|| arm_feature(env, ARM_FEATURE_VFP3))
3009
tmp = load_cpu_field(vfp.xregs[rn]);
3013
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3014
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3016
tmp = tcg_temp_new_i32();
3017
gen_helper_vfp_get_fpscr(tmp, cpu_env);
3023
|| !arm_feature(env, ARM_FEATURE_MVFR))
3025
tmp = load_cpu_field(vfp.xregs[rn]);
3031
gen_mov_F0_vreg(0, rn);
3032
tmp = gen_vfp_mrs();
3035
/* Set the 4 flag bits in the CPSR. */
3037
tcg_temp_free_i32(tmp);
3039
store_reg(s, rd, tmp);
3043
if (insn & (1 << 21)) {
3045
/* system register */
3050
/* Writes are ignored. */
3053
tmp = load_reg(s, rd);
3054
gen_helper_vfp_set_fpscr(cpu_env, tmp);
3055
tcg_temp_free_i32(tmp);
3061
/* TODO: VFP subarchitecture support.
3062
* For now, keep the EN bit only */
3063
tmp = load_reg(s, rd);
3064
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3065
store_cpu_field(tmp, vfp.xregs[rn]);
3068
case ARM_VFP_FPINST:
3069
case ARM_VFP_FPINST2:
3070
tmp = load_reg(s, rd);
3071
store_cpu_field(tmp, vfp.xregs[rn]);
3077
tmp = load_reg(s, rd);
3079
gen_mov_vreg_F0(0, rn);
3084
/* data processing */
3085
/* The opcode is in bits 23, 21, 20 and 6. */
3086
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3090
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3092
/* rn is register number */
3093
VFP_DREG_N(rn, insn);
3096
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3097
/* Integer or single precision destination. */
3098
rd = VFP_SREG_D(insn);
3100
VFP_DREG_D(rd, insn);
3103
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3104
/* VCVT from int is always from S reg regardless of dp bit.
3105
* VCVT with immediate frac_bits has same format as SREG_M
3107
rm = VFP_SREG_M(insn);
3109
VFP_DREG_M(rm, insn);
3112
rn = VFP_SREG_N(insn);
3113
if (op == 15 && rn == 15) {
3114
/* Double precision destination. */
3115
VFP_DREG_D(rd, insn);
3117
rd = VFP_SREG_D(insn);
3119
/* NB that we implicitly rely on the encoding for the frac_bits
3120
* in VCVT of fixed to float being the same as that of an SREG_M
3122
rm = VFP_SREG_M(insn);
3125
veclen = s->vec_len;
3126
if (op == 15 && rn > 3)
3129
/* Shut up compiler warnings. */
3140
/* Figure out what type of vector operation this is. */
3141
if ((rd & bank_mask) == 0) {
3146
delta_d = (s->vec_stride >> 1) + 1;
3148
delta_d = s->vec_stride + 1;
3150
if ((rm & bank_mask) == 0) {
3151
/* mixed scalar/vector */
3160
/* Load the initial operands. */
3165
/* Integer source */
3166
gen_mov_F0_vreg(0, rm);
3171
gen_mov_F0_vreg(dp, rd);
3172
gen_mov_F1_vreg(dp, rm);
3176
/* Compare with zero */
3177
gen_mov_F0_vreg(dp, rd);
3188
/* Source and destination the same. */
3189
gen_mov_F0_vreg(dp, rd);
3195
/* VCVTB, VCVTT: only present with the halfprec extension,
3196
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3198
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3201
/* Otherwise fall through */
3203
/* One source operand. */
3204
gen_mov_F0_vreg(dp, rm);
3208
/* Two source operands. */
3209
gen_mov_F0_vreg(dp, rn);
3210
gen_mov_F1_vreg(dp, rm);
3214
/* Perform the calculation. */
3216
case 0: /* VMLA: fd + (fn * fm) */
3217
/* Note that order of inputs to the add matters for NaNs */
3219
gen_mov_F0_vreg(dp, rd);
3222
case 1: /* VMLS: fd + -(fn * fm) */
3225
gen_mov_F0_vreg(dp, rd);
3228
case 2: /* VNMLS: -fd + (fn * fm) */
3229
/* Note that it isn't valid to replace (-A + B) with (B - A)
3230
* or similar plausible looking simplifications
3231
* because this will give wrong results for NaNs.
3234
gen_mov_F0_vreg(dp, rd);
3238
case 3: /* VNMLA: -fd + -(fn * fm) */
3241
gen_mov_F0_vreg(dp, rd);
3245
case 4: /* mul: fn * fm */
3248
case 5: /* nmul: -(fn * fm) */
3252
case 6: /* add: fn + fm */
3255
case 7: /* sub: fn - fm */
3258
case 8: /* div: fn / fm */
3261
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3262
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3263
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3264
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3265
/* These are fused multiply-add, and must be done as one
3266
* floating point operation with no rounding between the
3267
* multiplication and addition steps.
3268
* NB that doing the negations here as separate steps is
3269
* correct : an input NaN should come out with its sign bit
3270
* flipped if it is a negated-input.
3272
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3280
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3282
frd = tcg_temp_new_i64();
3283
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3286
gen_helper_vfp_negd(frd, frd);
3288
fpst = get_fpstatus_ptr(0);
3289
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3290
cpu_F1d, frd, fpst);
3291
tcg_temp_free_ptr(fpst);
3292
tcg_temp_free_i64(frd);
3298
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3300
frd = tcg_temp_new_i32();
3301
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3303
gen_helper_vfp_negs(frd, frd);
3305
fpst = get_fpstatus_ptr(0);
3306
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3307
cpu_F1s, frd, fpst);
3308
tcg_temp_free_ptr(fpst);
3309
tcg_temp_free_i32(frd);
3312
case 14: /* fconst */
3313
if (!arm_feature(env, ARM_FEATURE_VFP3))
3316
n = (insn << 12) & 0x80000000;
3317
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3324
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3331
tcg_gen_movi_i32(cpu_F0s, n);
3334
case 15: /* extension space */
3348
case 4: /* vcvtb.f32.f16 */
3349
tmp = gen_vfp_mrs();
3350
tcg_gen_ext16u_i32(tmp, tmp);
3351
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3352
tcg_temp_free_i32(tmp);
3354
case 5: /* vcvtt.f32.f16 */
3355
tmp = gen_vfp_mrs();
3356
tcg_gen_shri_i32(tmp, tmp, 16);
3357
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3358
tcg_temp_free_i32(tmp);
3360
case 6: /* vcvtb.f16.f32 */
3361
tmp = tcg_temp_new_i32();
3362
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3363
gen_mov_F0_vreg(0, rd);
3364
tmp2 = gen_vfp_mrs();
3365
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3366
tcg_gen_or_i32(tmp, tmp, tmp2);
3367
tcg_temp_free_i32(tmp2);
3370
case 7: /* vcvtt.f16.f32 */
3371
tmp = tcg_temp_new_i32();
3372
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3373
tcg_gen_shli_i32(tmp, tmp, 16);
3374
gen_mov_F0_vreg(0, rd);
3375
tmp2 = gen_vfp_mrs();
3376
tcg_gen_ext16u_i32(tmp2, tmp2);
3377
tcg_gen_or_i32(tmp, tmp, tmp2);
3378
tcg_temp_free_i32(tmp2);
3390
case 11: /* cmpez */
3394
case 12: /* vrintr */
3396
TCGv_ptr fpst = get_fpstatus_ptr(0);
3398
gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3400
gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3402
tcg_temp_free_ptr(fpst);
3405
case 15: /* single<->double conversion */
3407
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3409
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3411
case 16: /* fuito */
3412
gen_vfp_uito(dp, 0);
3414
case 17: /* fsito */
3415
gen_vfp_sito(dp, 0);
3417
case 20: /* fshto */
3418
if (!arm_feature(env, ARM_FEATURE_VFP3))
3420
gen_vfp_shto(dp, 16 - rm, 0);
3422
case 21: /* fslto */
3423
if (!arm_feature(env, ARM_FEATURE_VFP3))
3425
gen_vfp_slto(dp, 32 - rm, 0);
3427
case 22: /* fuhto */
3428
if (!arm_feature(env, ARM_FEATURE_VFP3))
3430
gen_vfp_uhto(dp, 16 - rm, 0);
3432
case 23: /* fulto */
3433
if (!arm_feature(env, ARM_FEATURE_VFP3))
3435
gen_vfp_ulto(dp, 32 - rm, 0);
3437
case 24: /* ftoui */
3438
gen_vfp_toui(dp, 0);
3440
case 25: /* ftouiz */
3441
gen_vfp_touiz(dp, 0);
3443
case 26: /* ftosi */
3444
gen_vfp_tosi(dp, 0);
3446
case 27: /* ftosiz */
3447
gen_vfp_tosiz(dp, 0);
3449
case 28: /* ftosh */
3450
if (!arm_feature(env, ARM_FEATURE_VFP3))
3452
gen_vfp_tosh(dp, 16 - rm, 0);
3454
case 29: /* ftosl */
3455
if (!arm_feature(env, ARM_FEATURE_VFP3))
3457
gen_vfp_tosl(dp, 32 - rm, 0);
3459
case 30: /* ftouh */
3460
if (!arm_feature(env, ARM_FEATURE_VFP3))
3462
gen_vfp_touh(dp, 16 - rm, 0);
3464
case 31: /* ftoul */
3465
if (!arm_feature(env, ARM_FEATURE_VFP3))
3467
gen_vfp_toul(dp, 32 - rm, 0);
3469
default: /* undefined */
3473
default: /* undefined */
3477
/* Write back the result. */
3478
if (op == 15 && (rn >= 8 && rn <= 11))
3479
; /* Comparison, do nothing. */
3480
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3481
/* VCVT double to int: always integer result. */
3482
gen_mov_vreg_F0(0, rd);
3483
else if (op == 15 && rn == 15)
3485
gen_mov_vreg_F0(!dp, rd);
3487
gen_mov_vreg_F0(dp, rd);
3489
/* break out of the loop if we have finished */
3493
if (op == 15 && delta_m == 0) {
3494
/* single source one-many */
3496
rd = ((rd + delta_d) & (bank_mask - 1))
3498
gen_mov_vreg_F0(dp, rd);
3502
/* Setup the next operands. */
3504
rd = ((rd + delta_d) & (bank_mask - 1))
3508
/* One source operand. */
3509
rm = ((rm + delta_m) & (bank_mask - 1))
3511
gen_mov_F0_vreg(dp, rm);
3513
/* Two source operands. */
3514
rn = ((rn + delta_d) & (bank_mask - 1))
3516
gen_mov_F0_vreg(dp, rn);
3518
rm = ((rm + delta_m) & (bank_mask - 1))
3520
gen_mov_F1_vreg(dp, rm);
3528
if ((insn & 0x03e00000) == 0x00400000) {
3529
/* two-register transfer */
3530
rn = (insn >> 16) & 0xf;
3531
rd = (insn >> 12) & 0xf;
3533
VFP_DREG_M(rm, insn);
3535
rm = VFP_SREG_M(insn);
3538
if (insn & ARM_CP_RW_BIT) {
3541
gen_mov_F0_vreg(0, rm * 2);
3542
tmp = gen_vfp_mrs();
3543
store_reg(s, rd, tmp);
3544
gen_mov_F0_vreg(0, rm * 2 + 1);
3545
tmp = gen_vfp_mrs();
3546
store_reg(s, rn, tmp);
3548
gen_mov_F0_vreg(0, rm);
3549
tmp = gen_vfp_mrs();
3550
store_reg(s, rd, tmp);
3551
gen_mov_F0_vreg(0, rm + 1);
3552
tmp = gen_vfp_mrs();
3553
store_reg(s, rn, tmp);
3558
tmp = load_reg(s, rd);
3560
gen_mov_vreg_F0(0, rm * 2);
3561
tmp = load_reg(s, rn);
3563
gen_mov_vreg_F0(0, rm * 2 + 1);
3565
tmp = load_reg(s, rd);
3567
gen_mov_vreg_F0(0, rm);
3568
tmp = load_reg(s, rn);
3570
gen_mov_vreg_F0(0, rm + 1);
3575
rn = (insn >> 16) & 0xf;
3577
VFP_DREG_D(rd, insn);
3579
rd = VFP_SREG_D(insn);
3580
if ((insn & 0x01200000) == 0x01000000) {
3581
/* Single load/store */
3582
offset = (insn & 0xff) << 2;
3583
if ((insn & (1 << 23)) == 0)
3585
if (s->thumb && rn == 15) {
3586
/* This is actually UNPREDICTABLE */
3587
addr = tcg_temp_new_i32();
3588
tcg_gen_movi_i32(addr, s->pc & ~2);
3590
addr = load_reg(s, rn);
3592
tcg_gen_addi_i32(addr, addr, offset);
3593
if (insn & (1 << 20)) {
3594
gen_vfp_ld(s, dp, addr);
3595
gen_mov_vreg_F0(dp, rd);
3597
gen_mov_F0_vreg(dp, rd);
3598
gen_vfp_st(s, dp, addr);
3600
tcg_temp_free_i32(addr);
3602
/* load/store multiple */
3603
int w = insn & (1 << 21);
3605
n = (insn >> 1) & 0x7f;
3609
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3610
/* P == U , W == 1 => UNDEF */
3613
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3614
/* UNPREDICTABLE cases for bad immediates: we choose to
3615
* UNDEF to avoid generating huge numbers of TCG ops
3619
if (rn == 15 && w) {
3620
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3624
if (s->thumb && rn == 15) {
3625
/* This is actually UNPREDICTABLE */
3626
addr = tcg_temp_new_i32();
3627
tcg_gen_movi_i32(addr, s->pc & ~2);
3629
addr = load_reg(s, rn);
3631
if (insn & (1 << 24)) /* pre-decrement */
3632
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3638
for (i = 0; i < n; i++) {
3639
if (insn & ARM_CP_RW_BIT) {
3641
gen_vfp_ld(s, dp, addr);
3642
gen_mov_vreg_F0(dp, rd + i);
3645
gen_mov_F0_vreg(dp, rd + i);
3646
gen_vfp_st(s, dp, addr);
3648
tcg_gen_addi_i32(addr, addr, offset);
3652
if (insn & (1 << 24))
3653
offset = -offset * n;
3654
else if (dp && (insn & 1))
3660
tcg_gen_addi_i32(addr, addr, offset);
3661
store_reg(s, rn, addr);
3663
tcg_temp_free_i32(addr);
3669
/* Should never happen. */
3675
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3677
TranslationBlock *tb;
3680
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3682
gen_set_pc_im(s, dest);
3683
tcg_gen_exit_tb((uintptr_t)tb + n);
3685
gen_set_pc_im(s, dest);
3690
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3692
if (unlikely(s->singlestep_enabled)) {
3693
/* An indirect jump so that we still trigger the debug exception. */
3698
gen_goto_tb(s, 0, dest);
3699
s->is_jmp = DISAS_TB_JUMP;
3703
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3706
tcg_gen_sari_i32(t0, t0, 16);
3710
tcg_gen_sari_i32(t1, t1, 16);
3713
tcg_gen_mul_i32(t0, t0, t1);
3716
/* Return the mask of PSR bits set by a MSR instruction. */
3717
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3721
if (flags & (1 << 0))
3723
if (flags & (1 << 1))
3725
if (flags & (1 << 2))
3727
if (flags & (1 << 3))
3730
/* Mask out undefined bits. */
3731
mask &= ~CPSR_RESERVED;
3732
if (!arm_feature(env, ARM_FEATURE_V4T))
3734
if (!arm_feature(env, ARM_FEATURE_V5))
3735
mask &= ~CPSR_Q; /* V5TE in reality*/
3736
if (!arm_feature(env, ARM_FEATURE_V6))
3737
mask &= ~(CPSR_E | CPSR_GE);
3738
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3740
/* Mask out execution state bits. */
3743
/* Mask out privileged bits. */
3749
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3750
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3754
/* ??? This is also undefined in system mode. */
3758
tmp = load_cpu_field(spsr);
3759
tcg_gen_andi_i32(tmp, tmp, ~mask);
3760
tcg_gen_andi_i32(t0, t0, mask);
3761
tcg_gen_or_i32(tmp, tmp, t0);
3762
store_cpu_field(tmp, spsr);
3764
gen_set_cpsr(t0, mask);
3766
tcg_temp_free_i32(t0);
3771
/* Returns nonzero if access to the PSR is not permitted. */
3772
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3775
tmp = tcg_temp_new_i32();
3776
tcg_gen_movi_i32(tmp, val);
3777
return gen_set_psr(s, mask, spsr, tmp);
3780
/* Generate an old-style exception return. Marks pc as dead. */
3781
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3784
store_reg(s, 15, pc);
3785
tmp = load_cpu_field(spsr);
3786
gen_set_cpsr(tmp, 0xffffffff);
3787
tcg_temp_free_i32(tmp);
3788
s->is_jmp = DISAS_UPDATE;
3791
/* Generate a v6 exception return. Marks both values as dead. */
3792
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3794
gen_set_cpsr(cpsr, 0xffffffff);
3795
tcg_temp_free_i32(cpsr);
3796
store_reg(s, 15, pc);
3797
s->is_jmp = DISAS_UPDATE;
3801
gen_set_condexec (DisasContext *s)
3803
if (s->condexec_mask) {
3804
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3805
TCGv_i32 tmp = tcg_temp_new_i32();
3806
tcg_gen_movi_i32(tmp, val);
3807
store_cpu_field(tmp, condexec_bits);
3811
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3813
gen_set_condexec(s);
3814
gen_set_pc_im(s, s->pc - offset);
3815
gen_exception(excp);
3816
s->is_jmp = DISAS_JUMP;
3819
static void gen_nop_hint(DisasContext *s, int val)
3823
gen_set_pc_im(s, s->pc);
3824
s->is_jmp = DISAS_WFI;
3829
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3835
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3837
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3840
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3841
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3842
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3847
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3850
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3851
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3852
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3857
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3858
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3859
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3860
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3861
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3863
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3864
switch ((size << 1) | u) { \
3866
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3869
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3872
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3875
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3878
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3881
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3883
default: return 1; \
3886
#define GEN_NEON_INTEGER_OP(name) do { \
3887
switch ((size << 1) | u) { \
3889
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3892
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3895
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3898
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3901
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3904
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3906
default: return 1; \
3909
static TCGv_i32 neon_load_scratch(int scratch)
3911
TCGv_i32 tmp = tcg_temp_new_i32();
3912
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3916
static void neon_store_scratch(int scratch, TCGv_i32 var)
3918
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3919
tcg_temp_free_i32(var);
3922
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3926
tmp = neon_load_reg(reg & 7, reg >> 4);
3928
gen_neon_dup_high16(tmp);
3930
gen_neon_dup_low16(tmp);
3933
tmp = neon_load_reg(reg & 15, reg >> 4);
3938
static int gen_neon_unzip(int rd, int rm, int size, int q)
3941
if (!q && size == 2) {
3944
tmp = tcg_const_i32(rd);
3945
tmp2 = tcg_const_i32(rm);
3949
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3952
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3955
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3963
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3966
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3972
tcg_temp_free_i32(tmp);
3973
tcg_temp_free_i32(tmp2);
3977
static int gen_neon_zip(int rd, int rm, int size, int q)
3980
if (!q && size == 2) {
3983
tmp = tcg_const_i32(rd);
3984
tmp2 = tcg_const_i32(rm);
3988
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3991
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3994
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4002
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4005
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4011
tcg_temp_free_i32(tmp);
4012
tcg_temp_free_i32(tmp2);
4016
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4020
rd = tcg_temp_new_i32();
4021
tmp = tcg_temp_new_i32();
4023
tcg_gen_shli_i32(rd, t0, 8);
4024
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4025
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4026
tcg_gen_or_i32(rd, rd, tmp);
4028
tcg_gen_shri_i32(t1, t1, 8);
4029
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4030
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4031
tcg_gen_or_i32(t1, t1, tmp);
4032
tcg_gen_mov_i32(t0, rd);
4034
tcg_temp_free_i32(tmp);
4035
tcg_temp_free_i32(rd);
4038
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4042
rd = tcg_temp_new_i32();
4043
tmp = tcg_temp_new_i32();
4045
tcg_gen_shli_i32(rd, t0, 16);
4046
tcg_gen_andi_i32(tmp, t1, 0xffff);
4047
tcg_gen_or_i32(rd, rd, tmp);
4048
tcg_gen_shri_i32(t1, t1, 16);
4049
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4050
tcg_gen_or_i32(t1, t1, tmp);
4051
tcg_gen_mov_i32(t0, rd);
4053
tcg_temp_free_i32(tmp);
4054
tcg_temp_free_i32(rd);
4062
} neon_ls_element_type[11] = {
4076
/* Translate a NEON load/store element instruction. Return nonzero if the
4077
instruction is invalid. */
4078
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4097
if (!s->vfp_enabled)
4099
VFP_DREG_D(rd, insn);
4100
rn = (insn >> 16) & 0xf;
4102
load = (insn & (1 << 21)) != 0;
4103
if ((insn & (1 << 23)) == 0) {
4104
/* Load store all elements. */
4105
op = (insn >> 8) & 0xf;
4106
size = (insn >> 6) & 3;
4109
/* Catch UNDEF cases for bad values of align field */
4112
if (((insn >> 5) & 1) == 1) {
4117
if (((insn >> 4) & 3) == 3) {
4124
nregs = neon_ls_element_type[op].nregs;
4125
interleave = neon_ls_element_type[op].interleave;
4126
spacing = neon_ls_element_type[op].spacing;
4127
if (size == 3 && (interleave | spacing) != 1)
4129
addr = tcg_temp_new_i32();
4130
load_reg_var(s, addr, rn);
4131
stride = (1 << size) * interleave;
4132
for (reg = 0; reg < nregs; reg++) {
4133
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4134
load_reg_var(s, addr, rn);
4135
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4136
} else if (interleave == 2 && nregs == 4 && reg == 2) {
4137
load_reg_var(s, addr, rn);
4138
tcg_gen_addi_i32(addr, addr, 1 << size);
4141
tmp64 = tcg_temp_new_i64();
4143
gen_aa32_ld64(tmp64, addr, IS_USER(s));
4144
neon_store_reg64(tmp64, rd);
4146
neon_load_reg64(tmp64, rd);
4147
gen_aa32_st64(tmp64, addr, IS_USER(s));
4149
tcg_temp_free_i64(tmp64);
4150
tcg_gen_addi_i32(addr, addr, stride);
4152
for (pass = 0; pass < 2; pass++) {
4155
tmp = tcg_temp_new_i32();
4156
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4157
neon_store_reg(rd, pass, tmp);
4159
tmp = neon_load_reg(rd, pass);
4160
gen_aa32_st32(tmp, addr, IS_USER(s));
4161
tcg_temp_free_i32(tmp);
4163
tcg_gen_addi_i32(addr, addr, stride);
4164
} else if (size == 1) {
4166
tmp = tcg_temp_new_i32();
4167
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4168
tcg_gen_addi_i32(addr, addr, stride);
4169
tmp2 = tcg_temp_new_i32();
4170
gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4171
tcg_gen_addi_i32(addr, addr, stride);
4172
tcg_gen_shli_i32(tmp2, tmp2, 16);
4173
tcg_gen_or_i32(tmp, tmp, tmp2);
4174
tcg_temp_free_i32(tmp2);
4175
neon_store_reg(rd, pass, tmp);
4177
tmp = neon_load_reg(rd, pass);
4178
tmp2 = tcg_temp_new_i32();
4179
tcg_gen_shri_i32(tmp2, tmp, 16);
4180
gen_aa32_st16(tmp, addr, IS_USER(s));
4181
tcg_temp_free_i32(tmp);
4182
tcg_gen_addi_i32(addr, addr, stride);
4183
gen_aa32_st16(tmp2, addr, IS_USER(s));
4184
tcg_temp_free_i32(tmp2);
4185
tcg_gen_addi_i32(addr, addr, stride);
4187
} else /* size == 0 */ {
4189
TCGV_UNUSED_I32(tmp2);
4190
for (n = 0; n < 4; n++) {
4191
tmp = tcg_temp_new_i32();
4192
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4193
tcg_gen_addi_i32(addr, addr, stride);
4197
tcg_gen_shli_i32(tmp, tmp, n * 8);
4198
tcg_gen_or_i32(tmp2, tmp2, tmp);
4199
tcg_temp_free_i32(tmp);
4202
neon_store_reg(rd, pass, tmp2);
4204
tmp2 = neon_load_reg(rd, pass);
4205
for (n = 0; n < 4; n++) {
4206
tmp = tcg_temp_new_i32();
4208
tcg_gen_mov_i32(tmp, tmp2);
4210
tcg_gen_shri_i32(tmp, tmp2, n * 8);
4212
gen_aa32_st8(tmp, addr, IS_USER(s));
4213
tcg_temp_free_i32(tmp);
4214
tcg_gen_addi_i32(addr, addr, stride);
4216
tcg_temp_free_i32(tmp2);
4223
tcg_temp_free_i32(addr);
4226
size = (insn >> 10) & 3;
4228
/* Load single element to all lanes. */
4229
int a = (insn >> 4) & 1;
4233
size = (insn >> 6) & 3;
4234
nregs = ((insn >> 8) & 3) + 1;
4237
if (nregs != 4 || a == 0) {
4240
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4243
if (nregs == 1 && a == 1 && size == 0) {
4246
if (nregs == 3 && a == 1) {
4249
addr = tcg_temp_new_i32();
4250
load_reg_var(s, addr, rn);
4252
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4253
tmp = gen_load_and_replicate(s, addr, size);
4254
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4255
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4256
if (insn & (1 << 5)) {
4257
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4258
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4260
tcg_temp_free_i32(tmp);
4262
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4263
stride = (insn & (1 << 5)) ? 2 : 1;
4264
for (reg = 0; reg < nregs; reg++) {
4265
tmp = gen_load_and_replicate(s, addr, size);
4266
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4267
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4268
tcg_temp_free_i32(tmp);
4269
tcg_gen_addi_i32(addr, addr, 1 << size);
4273
tcg_temp_free_i32(addr);
4274
stride = (1 << size) * nregs;
4276
/* Single element. */
4277
int idx = (insn >> 4) & 0xf;
4278
pass = (insn >> 7) & 1;
4281
shift = ((insn >> 5) & 3) * 8;
4285
shift = ((insn >> 6) & 1) * 16;
4286
stride = (insn & (1 << 5)) ? 2 : 1;
4290
stride = (insn & (1 << 6)) ? 2 : 1;
4295
nregs = ((insn >> 8) & 3) + 1;
4296
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
4299
if (((idx & (1 << size)) != 0) ||
4300
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4305
if ((idx & 1) != 0) {
4310
if (size == 2 && (idx & 2) != 0) {
4315
if ((size == 2) && ((idx & 3) == 3)) {
4322
if ((rd + stride * (nregs - 1)) > 31) {
4323
/* Attempts to write off the end of the register file
4324
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4325
* the neon_load_reg() would write off the end of the array.
4329
addr = tcg_temp_new_i32();
4330
load_reg_var(s, addr, rn);
4331
for (reg = 0; reg < nregs; reg++) {
4333
tmp = tcg_temp_new_i32();
4336
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4339
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4342
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4344
default: /* Avoid compiler warnings. */
4348
tmp2 = neon_load_reg(rd, pass);
4349
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4350
shift, size ? 16 : 8);
4351
tcg_temp_free_i32(tmp2);
4353
neon_store_reg(rd, pass, tmp);
4354
} else { /* Store */
4355
tmp = neon_load_reg(rd, pass);
4357
tcg_gen_shri_i32(tmp, tmp, shift);
4360
gen_aa32_st8(tmp, addr, IS_USER(s));
4363
gen_aa32_st16(tmp, addr, IS_USER(s));
4366
gen_aa32_st32(tmp, addr, IS_USER(s));
4369
tcg_temp_free_i32(tmp);
4372
tcg_gen_addi_i32(addr, addr, 1 << size);
4374
tcg_temp_free_i32(addr);
4375
stride = nregs * (1 << size);
4381
base = load_reg(s, rn);
4383
tcg_gen_addi_i32(base, base, stride);
4386
index = load_reg(s, rm);
4387
tcg_gen_add_i32(base, base, index);
4388
tcg_temp_free_i32(index);
4390
store_reg(s, rn, base);
4395
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4396
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4398
tcg_gen_and_i32(t, t, c);
4399
tcg_gen_andc_i32(f, f, c);
4400
tcg_gen_or_i32(dest, t, f);
4403
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4406
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4407
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4408
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4413
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4416
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4417
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4418
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4423
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4426
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4427
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4428
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4433
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4436
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4437
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4438
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4443
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4449
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4450
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4455
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4456
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4463
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4464
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4469
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4470
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4477
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4481
case 0: gen_helper_neon_widen_u8(dest, src); break;
4482
case 1: gen_helper_neon_widen_u16(dest, src); break;
4483
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4488
case 0: gen_helper_neon_widen_s8(dest, src); break;
4489
case 1: gen_helper_neon_widen_s16(dest, src); break;
4490
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4494
tcg_temp_free_i32(src);
4497
static inline void gen_neon_addl(int size)
4500
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4501
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4502
case 2: tcg_gen_add_i64(CPU_V001); break;
4507
static inline void gen_neon_subl(int size)
4510
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4511
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4512
case 2: tcg_gen_sub_i64(CPU_V001); break;
4517
static inline void gen_neon_negl(TCGv_i64 var, int size)
4520
case 0: gen_helper_neon_negl_u16(var, var); break;
4521
case 1: gen_helper_neon_negl_u32(var, var); break;
4523
tcg_gen_neg_i64(var, var);
4529
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4532
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4533
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4538
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4543
switch ((size << 1) | u) {
4544
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4545
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4546
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4547
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4549
tmp = gen_muls_i64_i32(a, b);
4550
tcg_gen_mov_i64(dest, tmp);
4551
tcg_temp_free_i64(tmp);
4554
tmp = gen_mulu_i64_i32(a, b);
4555
tcg_gen_mov_i64(dest, tmp);
4556
tcg_temp_free_i64(tmp);
4561
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4562
Don't forget to clean them now. */
4564
tcg_temp_free_i32(a);
4565
tcg_temp_free_i32(b);
4569
static void gen_neon_narrow_op(int op, int u, int size,
4570
TCGv_i32 dest, TCGv_i64 src)
4574
gen_neon_unarrow_sats(size, dest, src);
4576
gen_neon_narrow(size, dest, src);
4580
gen_neon_narrow_satu(size, dest, src);
4582
gen_neon_narrow_sats(size, dest, src);
4587
/* Symbolic constants for op fields for Neon 3-register same-length.
4588
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4591
#define NEON_3R_VHADD 0
4592
#define NEON_3R_VQADD 1
4593
#define NEON_3R_VRHADD 2
4594
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4595
#define NEON_3R_VHSUB 4
4596
#define NEON_3R_VQSUB 5
4597
#define NEON_3R_VCGT 6
4598
#define NEON_3R_VCGE 7
4599
#define NEON_3R_VSHL 8
4600
#define NEON_3R_VQSHL 9
4601
#define NEON_3R_VRSHL 10
4602
#define NEON_3R_VQRSHL 11
4603
#define NEON_3R_VMAX 12
4604
#define NEON_3R_VMIN 13
4605
#define NEON_3R_VABD 14
4606
#define NEON_3R_VABA 15
4607
#define NEON_3R_VADD_VSUB 16
4608
#define NEON_3R_VTST_VCEQ 17
4609
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4610
#define NEON_3R_VMUL 19
4611
#define NEON_3R_VPMAX 20
4612
#define NEON_3R_VPMIN 21
4613
#define NEON_3R_VQDMULH_VQRDMULH 22
4614
#define NEON_3R_VPADD 23
4615
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4616
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4617
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4618
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4619
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4620
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4621
#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4623
static const uint8_t neon_3r_sizes[] = {
4624
[NEON_3R_VHADD] = 0x7,
4625
[NEON_3R_VQADD] = 0xf,
4626
[NEON_3R_VRHADD] = 0x7,
4627
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4628
[NEON_3R_VHSUB] = 0x7,
4629
[NEON_3R_VQSUB] = 0xf,
4630
[NEON_3R_VCGT] = 0x7,
4631
[NEON_3R_VCGE] = 0x7,
4632
[NEON_3R_VSHL] = 0xf,
4633
[NEON_3R_VQSHL] = 0xf,
4634
[NEON_3R_VRSHL] = 0xf,
4635
[NEON_3R_VQRSHL] = 0xf,
4636
[NEON_3R_VMAX] = 0x7,
4637
[NEON_3R_VMIN] = 0x7,
4638
[NEON_3R_VABD] = 0x7,
4639
[NEON_3R_VABA] = 0x7,
4640
[NEON_3R_VADD_VSUB] = 0xf,
4641
[NEON_3R_VTST_VCEQ] = 0x7,
4642
[NEON_3R_VML] = 0x7,
4643
[NEON_3R_VMUL] = 0x7,
4644
[NEON_3R_VPMAX] = 0x7,
4645
[NEON_3R_VPMIN] = 0x7,
4646
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4647
[NEON_3R_VPADD] = 0x7,
4648
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4649
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4650
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4651
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4652
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4653
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4654
[NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4657
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4658
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4661
#define NEON_2RM_VREV64 0
4662
#define NEON_2RM_VREV32 1
4663
#define NEON_2RM_VREV16 2
4664
#define NEON_2RM_VPADDL 4
4665
#define NEON_2RM_VPADDL_U 5
4666
#define NEON_2RM_VCLS 8
4667
#define NEON_2RM_VCLZ 9
4668
#define NEON_2RM_VCNT 10
4669
#define NEON_2RM_VMVN 11
4670
#define NEON_2RM_VPADAL 12
4671
#define NEON_2RM_VPADAL_U 13
4672
#define NEON_2RM_VQABS 14
4673
#define NEON_2RM_VQNEG 15
4674
#define NEON_2RM_VCGT0 16
4675
#define NEON_2RM_VCGE0 17
4676
#define NEON_2RM_VCEQ0 18
4677
#define NEON_2RM_VCLE0 19
4678
#define NEON_2RM_VCLT0 20
4679
#define NEON_2RM_VABS 22
4680
#define NEON_2RM_VNEG 23
4681
#define NEON_2RM_VCGT0_F 24
4682
#define NEON_2RM_VCGE0_F 25
4683
#define NEON_2RM_VCEQ0_F 26
4684
#define NEON_2RM_VCLE0_F 27
4685
#define NEON_2RM_VCLT0_F 28
4686
#define NEON_2RM_VABS_F 30
4687
#define NEON_2RM_VNEG_F 31
4688
#define NEON_2RM_VSWP 32
4689
#define NEON_2RM_VTRN 33
4690
#define NEON_2RM_VUZP 34
4691
#define NEON_2RM_VZIP 35
4692
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4693
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4694
#define NEON_2RM_VSHLL 38
4695
#define NEON_2RM_VCVT_F16_F32 44
4696
#define NEON_2RM_VCVT_F32_F16 46
4697
#define NEON_2RM_VRECPE 56
4698
#define NEON_2RM_VRSQRTE 57
4699
#define NEON_2RM_VRECPE_F 58
4700
#define NEON_2RM_VRSQRTE_F 59
4701
#define NEON_2RM_VCVT_FS 60
4702
#define NEON_2RM_VCVT_FU 61
4703
#define NEON_2RM_VCVT_SF 62
4704
#define NEON_2RM_VCVT_UF 63
4706
static int neon_2rm_is_float_op(int op)
4708
/* Return true if this neon 2reg-misc op is float-to-float */
4709
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4710
op >= NEON_2RM_VRECPE_F);
4713
/* Each entry in this array has bit n set if the insn allows
4714
* size value n (otherwise it will UNDEF). Since unallocated
4715
* op values will have no bits set they always UNDEF.
4717
static const uint8_t neon_2rm_sizes[] = {
4718
[NEON_2RM_VREV64] = 0x7,
4719
[NEON_2RM_VREV32] = 0x3,
4720
[NEON_2RM_VREV16] = 0x1,
4721
[NEON_2RM_VPADDL] = 0x7,
4722
[NEON_2RM_VPADDL_U] = 0x7,
4723
[NEON_2RM_VCLS] = 0x7,
4724
[NEON_2RM_VCLZ] = 0x7,
4725
[NEON_2RM_VCNT] = 0x1,
4726
[NEON_2RM_VMVN] = 0x1,
4727
[NEON_2RM_VPADAL] = 0x7,
4728
[NEON_2RM_VPADAL_U] = 0x7,
4729
[NEON_2RM_VQABS] = 0x7,
4730
[NEON_2RM_VQNEG] = 0x7,
4731
[NEON_2RM_VCGT0] = 0x7,
4732
[NEON_2RM_VCGE0] = 0x7,
4733
[NEON_2RM_VCEQ0] = 0x7,
4734
[NEON_2RM_VCLE0] = 0x7,
4735
[NEON_2RM_VCLT0] = 0x7,
4736
[NEON_2RM_VABS] = 0x7,
4737
[NEON_2RM_VNEG] = 0x7,
4738
[NEON_2RM_VCGT0_F] = 0x4,
4739
[NEON_2RM_VCGE0_F] = 0x4,
4740
[NEON_2RM_VCEQ0_F] = 0x4,
4741
[NEON_2RM_VCLE0_F] = 0x4,
4742
[NEON_2RM_VCLT0_F] = 0x4,
4743
[NEON_2RM_VABS_F] = 0x4,
4744
[NEON_2RM_VNEG_F] = 0x4,
4745
[NEON_2RM_VSWP] = 0x1,
4746
[NEON_2RM_VTRN] = 0x7,
4747
[NEON_2RM_VUZP] = 0x7,
4748
[NEON_2RM_VZIP] = 0x7,
4749
[NEON_2RM_VMOVN] = 0x7,
4750
[NEON_2RM_VQMOVN] = 0x7,
4751
[NEON_2RM_VSHLL] = 0x7,
4752
[NEON_2RM_VCVT_F16_F32] = 0x2,
4753
[NEON_2RM_VCVT_F32_F16] = 0x2,
4754
[NEON_2RM_VRECPE] = 0x4,
4755
[NEON_2RM_VRSQRTE] = 0x4,
4756
[NEON_2RM_VRECPE_F] = 0x4,
4757
[NEON_2RM_VRSQRTE_F] = 0x4,
4758
[NEON_2RM_VCVT_FS] = 0x4,
4759
[NEON_2RM_VCVT_FU] = 0x4,
4760
[NEON_2RM_VCVT_SF] = 0x4,
4761
[NEON_2RM_VCVT_UF] = 0x4,
4764
/* Translate a NEON data processing instruction. Return nonzero if the
4765
instruction is invalid.
4766
We process data in a mixture of 32-bit and 64-bit chunks.
4767
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4769
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4781
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4784
if (!s->vfp_enabled)
4786
q = (insn & (1 << 6)) != 0;
4787
u = (insn >> 24) & 1;
4788
VFP_DREG_D(rd, insn);
4789
VFP_DREG_N(rn, insn);
4790
VFP_DREG_M(rm, insn);
4791
size = (insn >> 20) & 3;
4792
if ((insn & (1 << 23)) == 0) {
4793
/* Three register same length. */
4794
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4795
/* Catch invalid op and bad size combinations: UNDEF */
4796
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4799
/* All insns of this form UNDEF for either this condition or the
4800
* superset of cases "Q==1"; we catch the latter later.
4802
if (q && ((rd | rn | rm) & 1)) {
4805
if (size == 3 && op != NEON_3R_LOGIC) {
4806
/* 64-bit element instructions. */
4807
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4808
neon_load_reg64(cpu_V0, rn + pass);
4809
neon_load_reg64(cpu_V1, rm + pass);
4813
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4816
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4822
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4825
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4831
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4833
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4838
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4841
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4847
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4849
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4852
case NEON_3R_VQRSHL:
4854
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4857
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4861
case NEON_3R_VADD_VSUB:
4863
tcg_gen_sub_i64(CPU_V001);
4865
tcg_gen_add_i64(CPU_V001);
4871
neon_store_reg64(cpu_V0, rd + pass);
4880
case NEON_3R_VQRSHL:
4883
/* Shift instruction operands are reversed. */
4898
case NEON_3R_FLOAT_ARITH:
4899
pairwise = (u && size < 2); /* if VPADD (float) */
4901
case NEON_3R_FLOAT_MINMAX:
4902
pairwise = u; /* if VPMIN/VPMAX (float) */
4904
case NEON_3R_FLOAT_CMP:
4906
/* no encoding for U=0 C=1x */
4910
case NEON_3R_FLOAT_ACMP:
4915
case NEON_3R_FLOAT_MISC:
4916
/* VMAXNM/VMINNM in ARMv8 */
4917
if (u && !arm_feature(env, ARM_FEATURE_V8)) {
4922
if (u && (size != 0)) {
4923
/* UNDEF on invalid size for polynomial subcase */
4928
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4936
if (pairwise && q) {
4937
/* All the pairwise insns UNDEF if Q is set */
4941
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4946
tmp = neon_load_reg(rn, 0);
4947
tmp2 = neon_load_reg(rn, 1);
4949
tmp = neon_load_reg(rm, 0);
4950
tmp2 = neon_load_reg(rm, 1);
4954
tmp = neon_load_reg(rn, pass);
4955
tmp2 = neon_load_reg(rm, pass);
4959
GEN_NEON_INTEGER_OP(hadd);
4962
GEN_NEON_INTEGER_OP_ENV(qadd);
4964
case NEON_3R_VRHADD:
4965
GEN_NEON_INTEGER_OP(rhadd);
4967
case NEON_3R_LOGIC: /* Logic ops. */
4968
switch ((u << 2) | size) {
4970
tcg_gen_and_i32(tmp, tmp, tmp2);
4973
tcg_gen_andc_i32(tmp, tmp, tmp2);
4976
tcg_gen_or_i32(tmp, tmp, tmp2);
4979
tcg_gen_orc_i32(tmp, tmp, tmp2);
4982
tcg_gen_xor_i32(tmp, tmp, tmp2);
4985
tmp3 = neon_load_reg(rd, pass);
4986
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4987
tcg_temp_free_i32(tmp3);
4990
tmp3 = neon_load_reg(rd, pass);
4991
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4992
tcg_temp_free_i32(tmp3);
4995
tmp3 = neon_load_reg(rd, pass);
4996
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4997
tcg_temp_free_i32(tmp3);
5002
GEN_NEON_INTEGER_OP(hsub);
5005
GEN_NEON_INTEGER_OP_ENV(qsub);
5008
GEN_NEON_INTEGER_OP(cgt);
5011
GEN_NEON_INTEGER_OP(cge);
5014
GEN_NEON_INTEGER_OP(shl);
5017
GEN_NEON_INTEGER_OP_ENV(qshl);
5020
GEN_NEON_INTEGER_OP(rshl);
5022
case NEON_3R_VQRSHL:
5023
GEN_NEON_INTEGER_OP_ENV(qrshl);
5026
GEN_NEON_INTEGER_OP(max);
5029
GEN_NEON_INTEGER_OP(min);
5032
GEN_NEON_INTEGER_OP(abd);
5035
GEN_NEON_INTEGER_OP(abd);
5036
tcg_temp_free_i32(tmp2);
5037
tmp2 = neon_load_reg(rd, pass);
5038
gen_neon_add(size, tmp, tmp2);
5040
case NEON_3R_VADD_VSUB:
5041
if (!u) { /* VADD */
5042
gen_neon_add(size, tmp, tmp2);
5045
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5046
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5047
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5052
case NEON_3R_VTST_VCEQ:
5053
if (!u) { /* VTST */
5055
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5056
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5057
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5062
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5063
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5064
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5069
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5071
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5072
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5073
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5076
tcg_temp_free_i32(tmp2);
5077
tmp2 = neon_load_reg(rd, pass);
5079
gen_neon_rsb(size, tmp, tmp2);
5081
gen_neon_add(size, tmp, tmp2);
5085
if (u) { /* polynomial */
5086
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5087
} else { /* Integer */
5089
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5090
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5091
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5097
GEN_NEON_INTEGER_OP(pmax);
5100
GEN_NEON_INTEGER_OP(pmin);
5102
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5103
if (!u) { /* VQDMULH */
5106
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5109
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5113
} else { /* VQRDMULH */
5116
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5119
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5127
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5128
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5129
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5133
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5135
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5136
switch ((u << 2) | size) {
5139
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5142
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5145
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5150
tcg_temp_free_ptr(fpstatus);
5153
case NEON_3R_FLOAT_MULTIPLY:
5155
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5156
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5158
tcg_temp_free_i32(tmp2);
5159
tmp2 = neon_load_reg(rd, pass);
5161
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5163
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5166
tcg_temp_free_ptr(fpstatus);
5169
case NEON_3R_FLOAT_CMP:
5171
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5173
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5176
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5178
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5181
tcg_temp_free_ptr(fpstatus);
5184
case NEON_3R_FLOAT_ACMP:
5186
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5188
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5190
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5192
tcg_temp_free_ptr(fpstatus);
5195
case NEON_3R_FLOAT_MINMAX:
5197
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5199
gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5201
gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5203
tcg_temp_free_ptr(fpstatus);
5206
case NEON_3R_FLOAT_MISC:
5209
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5211
gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5213
gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5215
tcg_temp_free_ptr(fpstatus);
5218
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5220
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5226
/* VFMA, VFMS: fused multiply-add */
5227
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5228
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5231
gen_helper_vfp_negs(tmp, tmp);
5233
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5234
tcg_temp_free_i32(tmp3);
5235
tcg_temp_free_ptr(fpstatus);
5241
tcg_temp_free_i32(tmp2);
5243
/* Save the result. For elementwise operations we can put it
5244
straight into the destination register. For pairwise operations
5245
we have to be careful to avoid clobbering the source operands. */
5246
if (pairwise && rd == rm) {
5247
neon_store_scratch(pass, tmp);
5249
neon_store_reg(rd, pass, tmp);
5253
if (pairwise && rd == rm) {
5254
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5255
tmp = neon_load_scratch(pass);
5256
neon_store_reg(rd, pass, tmp);
5259
/* End of 3 register same size operations. */
5260
} else if (insn & (1 << 4)) {
5261
if ((insn & 0x00380080) != 0) {
5262
/* Two registers and shift. */
5263
op = (insn >> 8) & 0xf;
5264
if (insn & (1 << 7)) {
5272
while ((insn & (1 << (size + 19))) == 0)
5275
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5276
/* To avoid excessive duplication of ops we implement shift
5277
by immediate using the variable shift operations. */
5279
/* Shift by immediate:
5280
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5281
if (q && ((rd | rm) & 1)) {
5284
if (!u && (op == 4 || op == 6)) {
5287
/* Right shifts are encoded as N - shift, where N is the
5288
element size in bits. */
5290
shift = shift - (1 << (size + 3));
5298
imm = (uint8_t) shift;
5303
imm = (uint16_t) shift;
5314
for (pass = 0; pass < count; pass++) {
5316
neon_load_reg64(cpu_V0, rm + pass);
5317
tcg_gen_movi_i64(cpu_V1, imm);
5322
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5324
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5329
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5331
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5334
case 5: /* VSHL, VSLI */
5335
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5337
case 6: /* VQSHLU */
5338
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5343
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5346
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5351
if (op == 1 || op == 3) {
5353
neon_load_reg64(cpu_V1, rd + pass);
5354
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5355
} else if (op == 4 || (op == 5 && u)) {
5357
neon_load_reg64(cpu_V1, rd + pass);
5359
if (shift < -63 || shift > 63) {
5363
mask = 0xffffffffffffffffull >> -shift;
5365
mask = 0xffffffffffffffffull << shift;
5368
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5369
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5371
neon_store_reg64(cpu_V0, rd + pass);
5372
} else { /* size < 3 */
5373
/* Operands in T0 and T1. */
5374
tmp = neon_load_reg(rm, pass);
5375
tmp2 = tcg_temp_new_i32();
5376
tcg_gen_movi_i32(tmp2, imm);
5380
GEN_NEON_INTEGER_OP(shl);
5384
GEN_NEON_INTEGER_OP(rshl);
5387
case 5: /* VSHL, VSLI */
5389
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5390
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5391
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5395
case 6: /* VQSHLU */
5398
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5402
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5406
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5414
GEN_NEON_INTEGER_OP_ENV(qshl);
5417
tcg_temp_free_i32(tmp2);
5419
if (op == 1 || op == 3) {
5421
tmp2 = neon_load_reg(rd, pass);
5422
gen_neon_add(size, tmp, tmp2);
5423
tcg_temp_free_i32(tmp2);
5424
} else if (op == 4 || (op == 5 && u)) {
5429
mask = 0xff >> -shift;
5431
mask = (uint8_t)(0xff << shift);
5437
mask = 0xffff >> -shift;
5439
mask = (uint16_t)(0xffff << shift);
5443
if (shift < -31 || shift > 31) {
5447
mask = 0xffffffffu >> -shift;
5449
mask = 0xffffffffu << shift;
5455
tmp2 = neon_load_reg(rd, pass);
5456
tcg_gen_andi_i32(tmp, tmp, mask);
5457
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5458
tcg_gen_or_i32(tmp, tmp, tmp2);
5459
tcg_temp_free_i32(tmp2);
5461
neon_store_reg(rd, pass, tmp);
5464
} else if (op < 10) {
5465
/* Shift by immediate and narrow:
5466
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5467
int input_unsigned = (op == 8) ? !u : u;
5471
shift = shift - (1 << (size + 3));
5474
tmp64 = tcg_const_i64(shift);
5475
neon_load_reg64(cpu_V0, rm);
5476
neon_load_reg64(cpu_V1, rm + 1);
5477
for (pass = 0; pass < 2; pass++) {
5485
if (input_unsigned) {
5486
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5488
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5491
if (input_unsigned) {
5492
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5494
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5497
tmp = tcg_temp_new_i32();
5498
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5499
neon_store_reg(rd, pass, tmp);
5501
tcg_temp_free_i64(tmp64);
5504
imm = (uint16_t)shift;
5508
imm = (uint32_t)shift;
5510
tmp2 = tcg_const_i32(imm);
5511
tmp4 = neon_load_reg(rm + 1, 0);
5512
tmp5 = neon_load_reg(rm + 1, 1);
5513
for (pass = 0; pass < 2; pass++) {
5515
tmp = neon_load_reg(rm, 0);
5519
gen_neon_shift_narrow(size, tmp, tmp2, q,
5522
tmp3 = neon_load_reg(rm, 1);
5526
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5528
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5529
tcg_temp_free_i32(tmp);
5530
tcg_temp_free_i32(tmp3);
5531
tmp = tcg_temp_new_i32();
5532
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5533
neon_store_reg(rd, pass, tmp);
5535
tcg_temp_free_i32(tmp2);
5537
} else if (op == 10) {
5539
if (q || (rd & 1)) {
5542
tmp = neon_load_reg(rm, 0);
5543
tmp2 = neon_load_reg(rm, 1);
5544
for (pass = 0; pass < 2; pass++) {
5548
gen_neon_widen(cpu_V0, tmp, size, u);
5551
/* The shift is less than the width of the source
5552
type, so we can just shift the whole register. */
5553
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5554
/* Widen the result of shift: we need to clear
5555
* the potential overflow bits resulting from
5556
* left bits of the narrow input appearing as
5557
* right bits of left the neighbour narrow
5559
if (size < 2 || !u) {
5562
imm = (0xffu >> (8 - shift));
5564
} else if (size == 1) {
5565
imm = 0xffff >> (16 - shift);
5568
imm = 0xffffffff >> (32 - shift);
5571
imm64 = imm | (((uint64_t)imm) << 32);
5575
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5578
neon_store_reg64(cpu_V0, rd + pass);
5580
} else if (op >= 14) {
5581
/* VCVT fixed-point. */
5582
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5585
/* We have already masked out the must-be-1 top bit of imm6,
5586
* hence this 32-shift where the ARM ARM has 64-imm6.
5589
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5590
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5593
gen_vfp_ulto(0, shift, 1);
5595
gen_vfp_slto(0, shift, 1);
5598
gen_vfp_toul(0, shift, 1);
5600
gen_vfp_tosl(0, shift, 1);
5602
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5607
} else { /* (insn & 0x00380080) == 0 */
5609
if (q && (rd & 1)) {
5613
op = (insn >> 8) & 0xf;
5614
/* One register and immediate. */
5615
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5616
invert = (insn & (1 << 5)) != 0;
5617
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5618
* We choose to not special-case this and will behave as if a
5619
* valid constant encoding of 0 had been given.
5638
imm = (imm << 8) | (imm << 24);
5641
imm = (imm << 8) | 0xff;
5644
imm = (imm << 16) | 0xffff;
5647
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5655
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5656
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5662
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5663
if (op & 1 && op < 12) {
5664
tmp = neon_load_reg(rd, pass);
5666
/* The immediate value has already been inverted, so
5668
tcg_gen_andi_i32(tmp, tmp, imm);
5670
tcg_gen_ori_i32(tmp, tmp, imm);
5674
tmp = tcg_temp_new_i32();
5675
if (op == 14 && invert) {
5679
for (n = 0; n < 4; n++) {
5680
if (imm & (1 << (n + (pass & 1) * 4)))
5681
val |= 0xff << (n * 8);
5683
tcg_gen_movi_i32(tmp, val);
5685
tcg_gen_movi_i32(tmp, imm);
5688
neon_store_reg(rd, pass, tmp);
5691
} else { /* (insn & 0x00800010 == 0x00800000) */
5693
op = (insn >> 8) & 0xf;
5694
if ((insn & (1 << 6)) == 0) {
5695
/* Three registers of different lengths. */
5699
/* undefreq: bit 0 : UNDEF if size != 0
5700
* bit 1 : UNDEF if size == 0
5701
* bit 2 : UNDEF if U == 1
5702
* Note that [1:0] set implies 'always UNDEF'
5705
/* prewiden, src1_wide, src2_wide, undefreq */
5706
static const int neon_3reg_wide[16][4] = {
5707
{1, 0, 0, 0}, /* VADDL */
5708
{1, 1, 0, 0}, /* VADDW */
5709
{1, 0, 0, 0}, /* VSUBL */
5710
{1, 1, 0, 0}, /* VSUBW */
5711
{0, 1, 1, 0}, /* VADDHN */
5712
{0, 0, 0, 0}, /* VABAL */
5713
{0, 1, 1, 0}, /* VSUBHN */
5714
{0, 0, 0, 0}, /* VABDL */
5715
{0, 0, 0, 0}, /* VMLAL */
5716
{0, 0, 0, 6}, /* VQDMLAL */
5717
{0, 0, 0, 0}, /* VMLSL */
5718
{0, 0, 0, 6}, /* VQDMLSL */
5719
{0, 0, 0, 0}, /* Integer VMULL */
5720
{0, 0, 0, 2}, /* VQDMULL */
5721
{0, 0, 0, 5}, /* Polynomial VMULL */
5722
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5725
prewiden = neon_3reg_wide[op][0];
5726
src1_wide = neon_3reg_wide[op][1];
5727
src2_wide = neon_3reg_wide[op][2];
5728
undefreq = neon_3reg_wide[op][3];
5730
if (((undefreq & 1) && (size != 0)) ||
5731
((undefreq & 2) && (size == 0)) ||
5732
((undefreq & 4) && u)) {
5735
if ((src1_wide && (rn & 1)) ||
5736
(src2_wide && (rm & 1)) ||
5737
(!src2_wide && (rd & 1))) {
5741
/* Avoid overlapping operands. Wide source operands are
5742
always aligned so will never overlap with wide
5743
destinations in problematic ways. */
5744
if (rd == rm && !src2_wide) {
5745
tmp = neon_load_reg(rm, 1);
5746
neon_store_scratch(2, tmp);
5747
} else if (rd == rn && !src1_wide) {
5748
tmp = neon_load_reg(rn, 1);
5749
neon_store_scratch(2, tmp);
5751
TCGV_UNUSED_I32(tmp3);
5752
for (pass = 0; pass < 2; pass++) {
5754
neon_load_reg64(cpu_V0, rn + pass);
5755
TCGV_UNUSED_I32(tmp);
5757
if (pass == 1 && rd == rn) {
5758
tmp = neon_load_scratch(2);
5760
tmp = neon_load_reg(rn, pass);
5763
gen_neon_widen(cpu_V0, tmp, size, u);
5767
neon_load_reg64(cpu_V1, rm + pass);
5768
TCGV_UNUSED_I32(tmp2);
5770
if (pass == 1 && rd == rm) {
5771
tmp2 = neon_load_scratch(2);
5773
tmp2 = neon_load_reg(rm, pass);
5776
gen_neon_widen(cpu_V1, tmp2, size, u);
5780
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5781
gen_neon_addl(size);
5783
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5784
gen_neon_subl(size);
5786
case 5: case 7: /* VABAL, VABDL */
5787
switch ((size << 1) | u) {
5789
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5792
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5795
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5798
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5801
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5804
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5808
tcg_temp_free_i32(tmp2);
5809
tcg_temp_free_i32(tmp);
5811
case 8: case 9: case 10: case 11: case 12: case 13:
5812
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5813
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5815
case 14: /* Polynomial VMULL */
5816
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5817
tcg_temp_free_i32(tmp2);
5818
tcg_temp_free_i32(tmp);
5820
default: /* 15 is RESERVED: caught earlier */
5825
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5826
neon_store_reg64(cpu_V0, rd + pass);
5827
} else if (op == 5 || (op >= 8 && op <= 11)) {
5829
neon_load_reg64(cpu_V1, rd + pass);
5831
case 10: /* VMLSL */
5832
gen_neon_negl(cpu_V0, size);
5834
case 5: case 8: /* VABAL, VMLAL */
5835
gen_neon_addl(size);
5837
case 9: case 11: /* VQDMLAL, VQDMLSL */
5838
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5840
gen_neon_negl(cpu_V0, size);
5842
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5847
neon_store_reg64(cpu_V0, rd + pass);
5848
} else if (op == 4 || op == 6) {
5849
/* Narrowing operation. */
5850
tmp = tcg_temp_new_i32();
5854
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5857
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5860
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5861
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5868
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5871
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5874
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5875
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5876
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5884
neon_store_reg(rd, 0, tmp3);
5885
neon_store_reg(rd, 1, tmp);
5888
/* Write back the result. */
5889
neon_store_reg64(cpu_V0, rd + pass);
5893
/* Two registers and a scalar. NB that for ops of this form
5894
* the ARM ARM labels bit 24 as Q, but it is in our variable
5901
case 1: /* Float VMLA scalar */
5902
case 5: /* Floating point VMLS scalar */
5903
case 9: /* Floating point VMUL scalar */
5908
case 0: /* Integer VMLA scalar */
5909
case 4: /* Integer VMLS scalar */
5910
case 8: /* Integer VMUL scalar */
5911
case 12: /* VQDMULH scalar */
5912
case 13: /* VQRDMULH scalar */
5913
if (u && ((rd | rn) & 1)) {
5916
tmp = neon_get_scalar(size, rm);
5917
neon_store_scratch(0, tmp);
5918
for (pass = 0; pass < (u ? 4 : 2); pass++) {
5919
tmp = neon_load_scratch(0);
5920
tmp2 = neon_load_reg(rn, pass);
5923
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5925
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5927
} else if (op == 13) {
5929
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5931
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5933
} else if (op & 1) {
5934
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5935
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5936
tcg_temp_free_ptr(fpstatus);
5939
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5940
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5941
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5945
tcg_temp_free_i32(tmp2);
5948
tmp2 = neon_load_reg(rd, pass);
5951
gen_neon_add(size, tmp, tmp2);
5955
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5956
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5957
tcg_temp_free_ptr(fpstatus);
5961
gen_neon_rsb(size, tmp, tmp2);
5965
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5966
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5967
tcg_temp_free_ptr(fpstatus);
5973
tcg_temp_free_i32(tmp2);
5975
neon_store_reg(rd, pass, tmp);
5978
case 3: /* VQDMLAL scalar */
5979
case 7: /* VQDMLSL scalar */
5980
case 11: /* VQDMULL scalar */
5985
case 2: /* VMLAL sclar */
5986
case 6: /* VMLSL scalar */
5987
case 10: /* VMULL scalar */
5991
tmp2 = neon_get_scalar(size, rm);
5992
/* We need a copy of tmp2 because gen_neon_mull
5993
* deletes it during pass 0. */
5994
tmp4 = tcg_temp_new_i32();
5995
tcg_gen_mov_i32(tmp4, tmp2);
5996
tmp3 = neon_load_reg(rn, 1);
5998
for (pass = 0; pass < 2; pass++) {
6000
tmp = neon_load_reg(rn, 0);
6005
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6007
neon_load_reg64(cpu_V1, rd + pass);
6011
gen_neon_negl(cpu_V0, size);
6014
gen_neon_addl(size);
6017
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6019
gen_neon_negl(cpu_V0, size);
6021
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6027
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6032
neon_store_reg64(cpu_V0, rd + pass);
6037
default: /* 14 and 15 are RESERVED */
6041
} else { /* size == 3 */
6044
imm = (insn >> 8) & 0xf;
6049
if (q && ((rd | rn | rm) & 1)) {
6054
neon_load_reg64(cpu_V0, rn);
6056
neon_load_reg64(cpu_V1, rn + 1);
6058
} else if (imm == 8) {
6059
neon_load_reg64(cpu_V0, rn + 1);
6061
neon_load_reg64(cpu_V1, rm);
6064
tmp64 = tcg_temp_new_i64();
6066
neon_load_reg64(cpu_V0, rn);
6067
neon_load_reg64(tmp64, rn + 1);
6069
neon_load_reg64(cpu_V0, rn + 1);
6070
neon_load_reg64(tmp64, rm);
6072
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6073
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6074
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6076
neon_load_reg64(cpu_V1, rm);
6078
neon_load_reg64(cpu_V1, rm + 1);
6081
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6082
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6083
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6084
tcg_temp_free_i64(tmp64);
6087
neon_load_reg64(cpu_V0, rn);
6088
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6089
neon_load_reg64(cpu_V1, rm);
6090
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6091
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6093
neon_store_reg64(cpu_V0, rd);
6095
neon_store_reg64(cpu_V1, rd + 1);
6097
} else if ((insn & (1 << 11)) == 0) {
6098
/* Two register misc. */
6099
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6100
size = (insn >> 18) & 3;
6101
/* UNDEF for unknown op values and bad op-size combinations */
6102
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6105
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6106
q && ((rm | rd) & 1)) {
6110
case NEON_2RM_VREV64:
6111
for (pass = 0; pass < (q ? 2 : 1); pass++) {
6112
tmp = neon_load_reg(rm, pass * 2);
6113
tmp2 = neon_load_reg(rm, pass * 2 + 1);
6115
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6116
case 1: gen_swap_half(tmp); break;
6117
case 2: /* no-op */ break;
6120
neon_store_reg(rd, pass * 2 + 1, tmp);
6122
neon_store_reg(rd, pass * 2, tmp2);
6125
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6126
case 1: gen_swap_half(tmp2); break;
6129
neon_store_reg(rd, pass * 2, tmp2);
6133
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6134
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6135
for (pass = 0; pass < q + 1; pass++) {
6136
tmp = neon_load_reg(rm, pass * 2);
6137
gen_neon_widen(cpu_V0, tmp, size, op & 1);
6138
tmp = neon_load_reg(rm, pass * 2 + 1);
6139
gen_neon_widen(cpu_V1, tmp, size, op & 1);
6141
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6142
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6143
case 2: tcg_gen_add_i64(CPU_V001); break;
6146
if (op >= NEON_2RM_VPADAL) {
6148
neon_load_reg64(cpu_V1, rd + pass);
6149
gen_neon_addl(size);
6151
neon_store_reg64(cpu_V0, rd + pass);
6157
for (n = 0; n < (q ? 4 : 2); n += 2) {
6158
tmp = neon_load_reg(rm, n);
6159
tmp2 = neon_load_reg(rd, n + 1);
6160
neon_store_reg(rm, n, tmp2);
6161
neon_store_reg(rd, n + 1, tmp);
6168
if (gen_neon_unzip(rd, rm, size, q)) {
6173
if (gen_neon_zip(rd, rm, size, q)) {
6177
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6178
/* also VQMOVUN; op field and mnemonics don't line up */
6182
TCGV_UNUSED_I32(tmp2);
6183
for (pass = 0; pass < 2; pass++) {
6184
neon_load_reg64(cpu_V0, rm + pass);
6185
tmp = tcg_temp_new_i32();
6186
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6191
neon_store_reg(rd, 0, tmp2);
6192
neon_store_reg(rd, 1, tmp);
6196
case NEON_2RM_VSHLL:
6197
if (q || (rd & 1)) {
6200
tmp = neon_load_reg(rm, 0);
6201
tmp2 = neon_load_reg(rm, 1);
6202
for (pass = 0; pass < 2; pass++) {
6205
gen_neon_widen(cpu_V0, tmp, size, 1);
6206
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6207
neon_store_reg64(cpu_V0, rd + pass);
6210
case NEON_2RM_VCVT_F16_F32:
6211
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6215
tmp = tcg_temp_new_i32();
6216
tmp2 = tcg_temp_new_i32();
6217
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6218
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6219
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6220
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6221
tcg_gen_shli_i32(tmp2, tmp2, 16);
6222
tcg_gen_or_i32(tmp2, tmp2, tmp);
6223
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6224
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6225
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6226
neon_store_reg(rd, 0, tmp2);
6227
tmp2 = tcg_temp_new_i32();
6228
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6229
tcg_gen_shli_i32(tmp2, tmp2, 16);
6230
tcg_gen_or_i32(tmp2, tmp2, tmp);
6231
neon_store_reg(rd, 1, tmp2);
6232
tcg_temp_free_i32(tmp);
6234
case NEON_2RM_VCVT_F32_F16:
6235
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6239
tmp3 = tcg_temp_new_i32();
6240
tmp = neon_load_reg(rm, 0);
6241
tmp2 = neon_load_reg(rm, 1);
6242
tcg_gen_ext16u_i32(tmp3, tmp);
6243
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6244
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6245
tcg_gen_shri_i32(tmp3, tmp, 16);
6246
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6247
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6248
tcg_temp_free_i32(tmp);
6249
tcg_gen_ext16u_i32(tmp3, tmp2);
6250
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6251
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6252
tcg_gen_shri_i32(tmp3, tmp2, 16);
6253
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6254
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6255
tcg_temp_free_i32(tmp2);
6256
tcg_temp_free_i32(tmp3);
6260
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6261
if (neon_2rm_is_float_op(op)) {
6262
tcg_gen_ld_f32(cpu_F0s, cpu_env,
6263
neon_reg_offset(rm, pass));
6264
TCGV_UNUSED_I32(tmp);
6266
tmp = neon_load_reg(rm, pass);
6269
case NEON_2RM_VREV32:
6271
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6272
case 1: gen_swap_half(tmp); break;
6276
case NEON_2RM_VREV16:
6281
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6282
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6283
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6289
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6290
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6291
case 2: gen_helper_clz(tmp, tmp); break;
6296
gen_helper_neon_cnt_u8(tmp, tmp);
6299
tcg_gen_not_i32(tmp, tmp);
6301
case NEON_2RM_VQABS:
6304
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6307
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6310
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6315
case NEON_2RM_VQNEG:
6318
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6321
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6324
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6329
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6330
tmp2 = tcg_const_i32(0);
6332
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6333
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6334
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6337
tcg_temp_free_i32(tmp2);
6338
if (op == NEON_2RM_VCLE0) {
6339
tcg_gen_not_i32(tmp, tmp);
6342
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6343
tmp2 = tcg_const_i32(0);
6345
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6346
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6347
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6350
tcg_temp_free_i32(tmp2);
6351
if (op == NEON_2RM_VCLT0) {
6352
tcg_gen_not_i32(tmp, tmp);
6355
case NEON_2RM_VCEQ0:
6356
tmp2 = tcg_const_i32(0);
6358
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6359
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6360
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6363
tcg_temp_free_i32(tmp2);
6367
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6368
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6369
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6374
tmp2 = tcg_const_i32(0);
6375
gen_neon_rsb(size, tmp, tmp2);
6376
tcg_temp_free_i32(tmp2);
6378
case NEON_2RM_VCGT0_F:
6380
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6381
tmp2 = tcg_const_i32(0);
6382
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6383
tcg_temp_free_i32(tmp2);
6384
tcg_temp_free_ptr(fpstatus);
6387
case NEON_2RM_VCGE0_F:
6389
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6390
tmp2 = tcg_const_i32(0);
6391
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6392
tcg_temp_free_i32(tmp2);
6393
tcg_temp_free_ptr(fpstatus);
6396
case NEON_2RM_VCEQ0_F:
6398
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6399
tmp2 = tcg_const_i32(0);
6400
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6401
tcg_temp_free_i32(tmp2);
6402
tcg_temp_free_ptr(fpstatus);
6405
case NEON_2RM_VCLE0_F:
6407
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6408
tmp2 = tcg_const_i32(0);
6409
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6410
tcg_temp_free_i32(tmp2);
6411
tcg_temp_free_ptr(fpstatus);
6414
case NEON_2RM_VCLT0_F:
6416
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6417
tmp2 = tcg_const_i32(0);
6418
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6419
tcg_temp_free_i32(tmp2);
6420
tcg_temp_free_ptr(fpstatus);
6423
case NEON_2RM_VABS_F:
6426
case NEON_2RM_VNEG_F:
6430
tmp2 = neon_load_reg(rd, pass);
6431
neon_store_reg(rm, pass, tmp2);
6434
tmp2 = neon_load_reg(rd, pass);
6436
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6437
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6440
neon_store_reg(rm, pass, tmp2);
6442
case NEON_2RM_VRECPE:
6443
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6445
case NEON_2RM_VRSQRTE:
6446
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6448
case NEON_2RM_VRECPE_F:
6449
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6451
case NEON_2RM_VRSQRTE_F:
6452
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6454
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6457
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6460
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6461
gen_vfp_tosiz(0, 1);
6463
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6464
gen_vfp_touiz(0, 1);
6467
/* Reserved op values were caught by the
6468
* neon_2rm_sizes[] check earlier.
6472
if (neon_2rm_is_float_op(op)) {
6473
tcg_gen_st_f32(cpu_F0s, cpu_env,
6474
neon_reg_offset(rd, pass));
6476
neon_store_reg(rd, pass, tmp);
6481
} else if ((insn & (1 << 10)) == 0) {
6483
int n = ((insn >> 8) & 3) + 1;
6484
if ((rn + n) > 32) {
6485
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6486
* helper function running off the end of the register file.
6491
if (insn & (1 << 6)) {
6492
tmp = neon_load_reg(rd, 0);
6494
tmp = tcg_temp_new_i32();
6495
tcg_gen_movi_i32(tmp, 0);
6497
tmp2 = neon_load_reg(rm, 0);
6498
tmp4 = tcg_const_i32(rn);
6499
tmp5 = tcg_const_i32(n);
6500
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6501
tcg_temp_free_i32(tmp);
6502
if (insn & (1 << 6)) {
6503
tmp = neon_load_reg(rd, 1);
6505
tmp = tcg_temp_new_i32();
6506
tcg_gen_movi_i32(tmp, 0);
6508
tmp3 = neon_load_reg(rm, 1);
6509
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6510
tcg_temp_free_i32(tmp5);
6511
tcg_temp_free_i32(tmp4);
6512
neon_store_reg(rd, 0, tmp2);
6513
neon_store_reg(rd, 1, tmp3);
6514
tcg_temp_free_i32(tmp);
6515
} else if ((insn & 0x380) == 0) {
6517
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6520
if (insn & (1 << 19)) {
6521
tmp = neon_load_reg(rm, 1);
6523
tmp = neon_load_reg(rm, 0);
6525
if (insn & (1 << 16)) {
6526
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6527
} else if (insn & (1 << 17)) {
6528
if ((insn >> 18) & 1)
6529
gen_neon_dup_high16(tmp);
6531
gen_neon_dup_low16(tmp);
6533
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6534
tmp2 = tcg_temp_new_i32();
6535
tcg_gen_mov_i32(tmp2, tmp);
6536
neon_store_reg(rd, pass, tmp2);
6538
tcg_temp_free_i32(tmp);
6547
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6549
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6550
const ARMCPRegInfo *ri;
6552
cpnum = (insn >> 8) & 0xf;
6553
if (arm_feature(env, ARM_FEATURE_XSCALE)
6554
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6557
/* First check for coprocessor space used for actual instructions */
6561
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6562
return disas_iwmmxt_insn(env, s, insn);
6563
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6564
return disas_dsp_insn(env, s, insn);
6571
/* Otherwise treat as a generic register access */
6572
is64 = (insn & (1 << 25)) == 0;
6573
if (!is64 && ((insn & (1 << 4)) == 0)) {
6581
opc1 = (insn >> 4) & 0xf;
6583
rt2 = (insn >> 16) & 0xf;
6585
crn = (insn >> 16) & 0xf;
6586
opc1 = (insn >> 21) & 7;
6587
opc2 = (insn >> 5) & 7;
6590
isread = (insn >> 20) & 1;
6591
rt = (insn >> 12) & 0xf;
6593
ri = get_arm_cp_reginfo(s->cp_regs,
6594
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6596
/* Check access permissions */
6597
if (!cp_access_ok(s->current_pl, ri, isread)) {
6601
/* Handle special cases first */
6602
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6609
gen_set_pc_im(s, s->pc);
6610
s->is_jmp = DISAS_WFI;
6616
if (use_icount && (ri->type & ARM_CP_IO)) {
6625
if (ri->type & ARM_CP_CONST) {
6626
tmp64 = tcg_const_i64(ri->resetvalue);
6627
} else if (ri->readfn) {
6629
gen_set_pc_im(s, s->pc);
6630
tmp64 = tcg_temp_new_i64();
6631
tmpptr = tcg_const_ptr(ri);
6632
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6633
tcg_temp_free_ptr(tmpptr);
6635
tmp64 = tcg_temp_new_i64();
6636
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6638
tmp = tcg_temp_new_i32();
6639
tcg_gen_trunc_i64_i32(tmp, tmp64);
6640
store_reg(s, rt, tmp);
6641
tcg_gen_shri_i64(tmp64, tmp64, 32);
6642
tmp = tcg_temp_new_i32();
6643
tcg_gen_trunc_i64_i32(tmp, tmp64);
6644
tcg_temp_free_i64(tmp64);
6645
store_reg(s, rt2, tmp);
6648
if (ri->type & ARM_CP_CONST) {
6649
tmp = tcg_const_i32(ri->resetvalue);
6650
} else if (ri->readfn) {
6652
gen_set_pc_im(s, s->pc);
6653
tmp = tcg_temp_new_i32();
6654
tmpptr = tcg_const_ptr(ri);
6655
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6656
tcg_temp_free_ptr(tmpptr);
6658
tmp = load_cpu_offset(ri->fieldoffset);
6661
/* Destination register of r15 for 32 bit loads sets
6662
* the condition codes from the high 4 bits of the value
6665
tcg_temp_free_i32(tmp);
6667
store_reg(s, rt, tmp);
6672
if (ri->type & ARM_CP_CONST) {
6673
/* If not forbidden by access permissions, treat as WI */
6678
TCGv_i32 tmplo, tmphi;
6679
TCGv_i64 tmp64 = tcg_temp_new_i64();
6680
tmplo = load_reg(s, rt);
6681
tmphi = load_reg(s, rt2);
6682
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6683
tcg_temp_free_i32(tmplo);
6684
tcg_temp_free_i32(tmphi);
6686
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6687
gen_set_pc_im(s, s->pc);
6688
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6689
tcg_temp_free_ptr(tmpptr);
6691
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6693
tcg_temp_free_i64(tmp64);
6698
gen_set_pc_im(s, s->pc);
6699
tmp = load_reg(s, rt);
6700
tmpptr = tcg_const_ptr(ri);
6701
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6702
tcg_temp_free_ptr(tmpptr);
6703
tcg_temp_free_i32(tmp);
6705
TCGv_i32 tmp = load_reg(s, rt);
6706
store_cpu_offset(tmp, ri->fieldoffset);
6711
if (use_icount && (ri->type & ARM_CP_IO)) {
6712
/* I/O operations must end the TB here (whether read or write) */
6715
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6716
/* We default to ending the TB on a coprocessor register write,
6717
* but allow this to be suppressed by the register definition
6718
* (usually only necessary to work around guest bugs).
6730
/* Store a 64-bit value to a register pair. Clobbers val. */
6731
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6734
tmp = tcg_temp_new_i32();
6735
tcg_gen_trunc_i64_i32(tmp, val);
6736
store_reg(s, rlow, tmp);
6737
tmp = tcg_temp_new_i32();
6738
tcg_gen_shri_i64(val, val, 32);
6739
tcg_gen_trunc_i64_i32(tmp, val);
6740
store_reg(s, rhigh, tmp);
6743
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6744
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6749
/* Load value and extend to 64 bits. */
6750
tmp = tcg_temp_new_i64();
6751
tmp2 = load_reg(s, rlow);
6752
tcg_gen_extu_i32_i64(tmp, tmp2);
6753
tcg_temp_free_i32(tmp2);
6754
tcg_gen_add_i64(val, val, tmp);
6755
tcg_temp_free_i64(tmp);
6758
/* load and add a 64-bit value from a register pair. */
6759
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6765
/* Load 64-bit value rd:rn. */
6766
tmpl = load_reg(s, rlow);
6767
tmph = load_reg(s, rhigh);
6768
tmp = tcg_temp_new_i64();
6769
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6770
tcg_temp_free_i32(tmpl);
6771
tcg_temp_free_i32(tmph);
6772
tcg_gen_add_i64(val, val, tmp);
6773
tcg_temp_free_i64(tmp);
6776
/* Set N and Z flags from hi|lo. */
6777
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6779
tcg_gen_mov_i32(cpu_NF, hi);
6780
tcg_gen_or_i32(cpu_ZF, lo, hi);
6783
/* Load/Store exclusive instructions are implemented by remembering
6784
the value/address loaded, and seeing if these are the same
6785
when the store is performed. This should be sufficient to implement
6786
the architecturally mandated semantics, and avoids having to monitor
6789
In system emulation mode only one CPU will be running at once, so
6790
this sequence is effectively atomic. In user emulation mode we
6791
throw an exception and handle the atomic operation elsewhere. */
6792
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6793
TCGv_i32 addr, int size)
6795
TCGv_i32 tmp = tcg_temp_new_i32();
6799
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6802
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6806
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6813
TCGv_i32 tmp2 = tcg_temp_new_i32();
6814
TCGv_i32 tmp3 = tcg_temp_new_i32();
6816
tcg_gen_addi_i32(tmp2, addr, 4);
6817
gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6818
tcg_temp_free_i32(tmp2);
6819
tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
6820
store_reg(s, rt2, tmp3);
6822
tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
6825
store_reg(s, rt, tmp);
6826
tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
6829
static void gen_clrex(DisasContext *s)
6831
tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6834
#ifdef CONFIG_USER_ONLY
6835
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6836
TCGv_i32 addr, int size)
6838
tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
6839
tcg_gen_movi_i32(cpu_exclusive_info,
6840
size | (rd << 4) | (rt << 8) | (rt2 << 12));
6841
gen_exception_insn(s, 4, EXCP_STREX);
6844
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6845
TCGv_i32 addr, int size)
6848
TCGv_i64 val64, extaddr;
6852
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6858
fail_label = gen_new_label();
6859
done_label = gen_new_label();
6860
extaddr = tcg_temp_new_i64();
6861
tcg_gen_extu_i32_i64(extaddr, addr);
6862
tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
6863
tcg_temp_free_i64(extaddr);
6865
tmp = tcg_temp_new_i32();
6868
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6871
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6875
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6881
val64 = tcg_temp_new_i64();
6883
TCGv_i32 tmp2 = tcg_temp_new_i32();
6884
TCGv_i32 tmp3 = tcg_temp_new_i32();
6885
tcg_gen_addi_i32(tmp2, addr, 4);
6886
gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6887
tcg_temp_free_i32(tmp2);
6888
tcg_gen_concat_i32_i64(val64, tmp, tmp3);
6889
tcg_temp_free_i32(tmp3);
6891
tcg_gen_extu_i32_i64(val64, tmp);
6893
tcg_temp_free_i32(tmp);
6895
tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
6896
tcg_temp_free_i64(val64);
6898
tmp = load_reg(s, rt);
6901
gen_aa32_st8(tmp, addr, IS_USER(s));
6904
gen_aa32_st16(tmp, addr, IS_USER(s));
6908
gen_aa32_st32(tmp, addr, IS_USER(s));
6913
tcg_temp_free_i32(tmp);
6915
tcg_gen_addi_i32(addr, addr, 4);
6916
tmp = load_reg(s, rt2);
6917
gen_aa32_st32(tmp, addr, IS_USER(s));
6918
tcg_temp_free_i32(tmp);
6920
tcg_gen_movi_i32(cpu_R[rd], 0);
6921
tcg_gen_br(done_label);
6922
gen_set_label(fail_label);
6923
tcg_gen_movi_i32(cpu_R[rd], 1);
6924
gen_set_label(done_label);
6925
tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6932
* @mode: mode field from insn (which stack to store to)
6933
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6934
* @writeback: true if writeback bit set
6936
* Generate code for the SRS (Store Return State) insn.
6938
static void gen_srs(DisasContext *s,
6939
uint32_t mode, uint32_t amode, bool writeback)
6942
TCGv_i32 addr = tcg_temp_new_i32();
6943
TCGv_i32 tmp = tcg_const_i32(mode);
6944
gen_helper_get_r13_banked(addr, cpu_env, tmp);
6945
tcg_temp_free_i32(tmp);
6962
tcg_gen_addi_i32(addr, addr, offset);
6963
tmp = load_reg(s, 14);
6964
gen_aa32_st32(tmp, addr, 0);
6965
tcg_temp_free_i32(tmp);
6966
tmp = load_cpu_field(spsr);
6967
tcg_gen_addi_i32(addr, addr, 4);
6968
gen_aa32_st32(tmp, addr, 0);
6969
tcg_temp_free_i32(tmp);
6987
tcg_gen_addi_i32(addr, addr, offset);
6988
tmp = tcg_const_i32(mode);
6989
gen_helper_set_r13_banked(cpu_env, tmp, addr);
6990
tcg_temp_free_i32(tmp);
6992
tcg_temp_free_i32(addr);
6995
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6997
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7004
insn = arm_ldl_code(env, s->pc, s->bswap_code);
7007
/* M variants do not implement ARM mode. */
7012
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7013
* choose to UNDEF. In ARMv5 and above the space is used
7014
* for miscellaneous unconditional instructions.
7018
/* Unconditional instructions. */
7019
if (((insn >> 25) & 7) == 1) {
7020
/* NEON Data processing. */
7021
if (!arm_feature(env, ARM_FEATURE_NEON))
7024
if (disas_neon_data_insn(env, s, insn))
7028
if ((insn & 0x0f100000) == 0x04000000) {
7029
/* NEON load/store. */
7030
if (!arm_feature(env, ARM_FEATURE_NEON))
7033
if (disas_neon_ls_insn(env, s, insn))
7037
if ((insn & 0x0f000e10) == 0x0e000a00) {
7039
if (disas_vfp_insn(env, s, insn)) {
7044
if (((insn & 0x0f30f000) == 0x0510f000) ||
7045
((insn & 0x0f30f010) == 0x0710f000)) {
7046
if ((insn & (1 << 22)) == 0) {
7048
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7052
/* Otherwise PLD; v5TE+ */
7056
if (((insn & 0x0f70f000) == 0x0450f000) ||
7057
((insn & 0x0f70f010) == 0x0650f000)) {
7059
return; /* PLI; V7 */
7061
if (((insn & 0x0f700000) == 0x04100000) ||
7062
((insn & 0x0f700010) == 0x06100000)) {
7063
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7066
return; /* v7MP: Unallocated memory hint: must NOP */
7069
if ((insn & 0x0ffffdff) == 0x01010000) {
7072
if (((insn >> 9) & 1) != s->bswap_code) {
7073
/* Dynamic endianness switching not implemented. */
7074
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7078
} else if ((insn & 0x0fffff00) == 0x057ff000) {
7079
switch ((insn >> 4) & 0xf) {
7088
/* We don't emulate caches so these are a no-op. */
7093
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7099
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7101
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7107
rn = (insn >> 16) & 0xf;
7108
addr = load_reg(s, rn);
7109
i = (insn >> 23) & 3;
7111
case 0: offset = -4; break; /* DA */
7112
case 1: offset = 0; break; /* IA */
7113
case 2: offset = -8; break; /* DB */
7114
case 3: offset = 4; break; /* IB */
7118
tcg_gen_addi_i32(addr, addr, offset);
7119
/* Load PC into tmp and CPSR into tmp2. */
7120
tmp = tcg_temp_new_i32();
7121
gen_aa32_ld32u(tmp, addr, 0);
7122
tcg_gen_addi_i32(addr, addr, 4);
7123
tmp2 = tcg_temp_new_i32();
7124
gen_aa32_ld32u(tmp2, addr, 0);
7125
if (insn & (1 << 21)) {
7126
/* Base writeback. */
7128
case 0: offset = -8; break;
7129
case 1: offset = 4; break;
7130
case 2: offset = -4; break;
7131
case 3: offset = 0; break;
7135
tcg_gen_addi_i32(addr, addr, offset);
7136
store_reg(s, rn, addr);
7138
tcg_temp_free_i32(addr);
7140
gen_rfe(s, tmp, tmp2);
7142
} else if ((insn & 0x0e000000) == 0x0a000000) {
7143
/* branch link and change to thumb (blx <offset>) */
7146
val = (uint32_t)s->pc;
7147
tmp = tcg_temp_new_i32();
7148
tcg_gen_movi_i32(tmp, val);
7149
store_reg(s, 14, tmp);
7150
/* Sign-extend the 24-bit offset */
7151
offset = (((int32_t)insn) << 8) >> 8;
7152
/* offset * 4 + bit24 * 2 + (thumb bit) */
7153
val += (offset << 2) | ((insn >> 23) & 2) | 1;
7154
/* pipeline offset */
7156
/* protected by ARCH(5); above, near the start of uncond block */
7159
} else if ((insn & 0x0e000f00) == 0x0c000100) {
7160
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7161
/* iWMMXt register transfer. */
7162
if (env->cp15.c15_cpar & (1 << 1))
7163
if (!disas_iwmmxt_insn(env, s, insn))
7166
} else if ((insn & 0x0fe00000) == 0x0c400000) {
7167
/* Coprocessor double register transfer. */
7169
/* XXX doesn't belong in the trustzone patch: should just UNDEF? */
7170
cpu_abort(env, "unsupported coprocessor double register transfer\n");
7171
} else if ((insn & 0x0f000010) == 0x0e000010) {
7172
/* Additional coprocessor register transfer. */
7173
if (!disas_coproc_insn(env, s, insn)) {
7176
} else if ((insn & 0x0ff10020) == 0x01000000) {
7179
/* cps (privileged) */
7183
if (insn & (1 << 19)) {
7184
if (insn & (1 << 8))
7186
if (insn & (1 << 7))
7188
if (insn & (1 << 6))
7190
if (insn & (1 << 18))
7193
if (insn & (1 << 17)) {
7195
val |= (insn & 0x1f);
7198
gen_set_psr_im(s, mask, 0, val);
7205
/* if not always execute, we generate a conditional jump to
7207
s->condlabel = gen_new_label();
7208
arm_gen_test_cc(cond ^ 1, s->condlabel);
7211
if ((insn & 0x0f900000) == 0x03000000) {
7212
if ((insn & (1 << 21)) == 0) {
7214
rd = (insn >> 12) & 0xf;
7215
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7216
if ((insn & (1 << 22)) == 0) {
7218
tmp = tcg_temp_new_i32();
7219
tcg_gen_movi_i32(tmp, val);
7222
tmp = load_reg(s, rd);
7223
tcg_gen_ext16u_i32(tmp, tmp);
7224
tcg_gen_ori_i32(tmp, tmp, val << 16);
7226
store_reg(s, rd, tmp);
7228
if (((insn >> 12) & 0xf) != 0xf)
7230
if (((insn >> 16) & 0xf) == 0) {
7231
gen_nop_hint(s, insn & 0xff);
7233
/* CPSR = immediate */
7235
shift = ((insn >> 8) & 0xf) * 2;
7237
val = (val >> shift) | (val << (32 - shift));
7238
i = ((insn & (1 << 22)) != 0);
7239
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7243
} else if ((insn & 0x0f900000) == 0x01000000
7244
&& (insn & 0x00000090) != 0x00000090) {
7245
/* miscellaneous instructions */
7246
op1 = (insn >> 21) & 3;
7247
sh = (insn >> 4) & 0xf;
7250
case 0x0: /* move program status register */
7253
tmp = load_reg(s, rm);
7254
i = ((op1 & 2) != 0);
7255
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7259
rd = (insn >> 12) & 0xf;
7263
tmp = load_cpu_field(spsr);
7265
tmp = tcg_temp_new_i32();
7266
gen_helper_cpsr_read(tmp, cpu_env);
7268
store_reg(s, rd, tmp);
7273
/* branch/exchange thumb (bx). */
7275
tmp = load_reg(s, rm);
7277
} else if (op1 == 3) {
7280
rd = (insn >> 12) & 0xf;
7281
tmp = load_reg(s, rm);
7282
gen_helper_clz(tmp, tmp);
7283
store_reg(s, rd, tmp);
7291
/* Trivial implementation equivalent to bx. */
7292
tmp = load_reg(s, rm);
7303
/* branch link/exchange thumb (blx) */
7304
tmp = load_reg(s, rm);
7305
tmp2 = tcg_temp_new_i32();
7306
tcg_gen_movi_i32(tmp2, s->pc);
7307
store_reg(s, 14, tmp2);
7310
case 0x5: /* saturating add/subtract */
7312
rd = (insn >> 12) & 0xf;
7313
rn = (insn >> 16) & 0xf;
7314
tmp = load_reg(s, rm);
7315
tmp2 = load_reg(s, rn);
7317
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7319
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7321
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7322
tcg_temp_free_i32(tmp2);
7323
store_reg(s, rd, tmp);
7329
gen_exception_insn(s, 4, EXCP_BKPT);
7330
} else if (op1 == 3) {
7332
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
7340
case 0x8: /* signed multiply */
7345
rs = (insn >> 8) & 0xf;
7346
rn = (insn >> 12) & 0xf;
7347
rd = (insn >> 16) & 0xf;
7349
/* (32 * 16) >> 16 */
7350
tmp = load_reg(s, rm);
7351
tmp2 = load_reg(s, rs);
7353
tcg_gen_sari_i32(tmp2, tmp2, 16);
7356
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7357
tcg_gen_shri_i64(tmp64, tmp64, 16);
7358
tmp = tcg_temp_new_i32();
7359
tcg_gen_trunc_i64_i32(tmp, tmp64);
7360
tcg_temp_free_i64(tmp64);
7361
if ((sh & 2) == 0) {
7362
tmp2 = load_reg(s, rn);
7363
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7364
tcg_temp_free_i32(tmp2);
7366
store_reg(s, rd, tmp);
7369
tmp = load_reg(s, rm);
7370
tmp2 = load_reg(s, rs);
7371
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7372
tcg_temp_free_i32(tmp2);
7374
tmp64 = tcg_temp_new_i64();
7375
tcg_gen_ext_i32_i64(tmp64, tmp);
7376
tcg_temp_free_i32(tmp);
7377
gen_addq(s, tmp64, rn, rd);
7378
gen_storeq_reg(s, rn, rd, tmp64);
7379
tcg_temp_free_i64(tmp64);
7382
tmp2 = load_reg(s, rn);
7383
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7384
tcg_temp_free_i32(tmp2);
7386
store_reg(s, rd, tmp);
7393
} else if (((insn & 0x0e000000) == 0 &&
7394
(insn & 0x00000090) != 0x90) ||
7395
((insn & 0x0e000000) == (1 << 25))) {
7396
int set_cc, logic_cc, shiftop;
7398
op1 = (insn >> 21) & 0xf;
7399
set_cc = (insn >> 20) & 1;
7400
logic_cc = table_logic_cc[op1] & set_cc;
7402
/* data processing instruction */
7403
if (insn & (1 << 25)) {
7404
/* immediate operand */
7406
shift = ((insn >> 8) & 0xf) * 2;
7408
val = (val >> shift) | (val << (32 - shift));
7410
tmp2 = tcg_temp_new_i32();
7411
tcg_gen_movi_i32(tmp2, val);
7412
if (logic_cc && shift) {
7413
gen_set_CF_bit31(tmp2);
7418
tmp2 = load_reg(s, rm);
7419
shiftop = (insn >> 5) & 3;
7420
if (!(insn & (1 << 4))) {
7421
shift = (insn >> 7) & 0x1f;
7422
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7424
rs = (insn >> 8) & 0xf;
7425
tmp = load_reg(s, rs);
7426
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7429
if (op1 != 0x0f && op1 != 0x0d) {
7430
rn = (insn >> 16) & 0xf;
7431
tmp = load_reg(s, rn);
7433
TCGV_UNUSED_I32(tmp);
7435
rd = (insn >> 12) & 0xf;
7438
tcg_gen_and_i32(tmp, tmp, tmp2);
7442
store_reg_bx(env, s, rd, tmp);
7445
tcg_gen_xor_i32(tmp, tmp, tmp2);
7449
store_reg_bx(env, s, rd, tmp);
7452
if (set_cc && rd == 15) {
7453
/* SUBS r15, ... is used for exception return. */
7457
gen_sub_CC(tmp, tmp, tmp2);
7458
gen_exception_return(s, tmp);
7461
gen_sub_CC(tmp, tmp, tmp2);
7463
tcg_gen_sub_i32(tmp, tmp, tmp2);
7465
store_reg_bx(env, s, rd, tmp);
7470
gen_sub_CC(tmp, tmp2, tmp);
7472
tcg_gen_sub_i32(tmp, tmp2, tmp);
7474
store_reg_bx(env, s, rd, tmp);
7478
gen_add_CC(tmp, tmp, tmp2);
7480
tcg_gen_add_i32(tmp, tmp, tmp2);
7482
store_reg_bx(env, s, rd, tmp);
7486
gen_adc_CC(tmp, tmp, tmp2);
7488
gen_add_carry(tmp, tmp, tmp2);
7490
store_reg_bx(env, s, rd, tmp);
7494
gen_sbc_CC(tmp, tmp, tmp2);
7496
gen_sub_carry(tmp, tmp, tmp2);
7498
store_reg_bx(env, s, rd, tmp);
7502
gen_sbc_CC(tmp, tmp2, tmp);
7504
gen_sub_carry(tmp, tmp2, tmp);
7506
store_reg_bx(env, s, rd, tmp);
7510
tcg_gen_and_i32(tmp, tmp, tmp2);
7513
tcg_temp_free_i32(tmp);
7517
tcg_gen_xor_i32(tmp, tmp, tmp2);
7520
tcg_temp_free_i32(tmp);
7524
gen_sub_CC(tmp, tmp, tmp2);
7526
tcg_temp_free_i32(tmp);
7530
gen_add_CC(tmp, tmp, tmp2);
7532
tcg_temp_free_i32(tmp);
7535
tcg_gen_or_i32(tmp, tmp, tmp2);
7539
store_reg_bx(env, s, rd, tmp);
7542
if (logic_cc && rd == 15) {
7543
/* MOVS r15, ... is used for exception return. */
7547
gen_exception_return(s, tmp2);
7552
store_reg_bx(env, s, rd, tmp2);
7556
tcg_gen_andc_i32(tmp, tmp, tmp2);
7560
store_reg_bx(env, s, rd, tmp);
7564
tcg_gen_not_i32(tmp2, tmp2);
7568
store_reg_bx(env, s, rd, tmp2);
7571
if (op1 != 0x0f && op1 != 0x0d) {
7572
tcg_temp_free_i32(tmp2);
7575
/* other instructions */
7576
op1 = (insn >> 24) & 0xf;
7580
/* multiplies, extra load/stores */
7581
sh = (insn >> 5) & 3;
7584
rd = (insn >> 16) & 0xf;
7585
rn = (insn >> 12) & 0xf;
7586
rs = (insn >> 8) & 0xf;
7588
op1 = (insn >> 20) & 0xf;
7590
case 0: case 1: case 2: case 3: case 6:
7592
tmp = load_reg(s, rs);
7593
tmp2 = load_reg(s, rm);
7594
tcg_gen_mul_i32(tmp, tmp, tmp2);
7595
tcg_temp_free_i32(tmp2);
7596
if (insn & (1 << 22)) {
7597
/* Subtract (mls) */
7599
tmp2 = load_reg(s, rn);
7600
tcg_gen_sub_i32(tmp, tmp2, tmp);
7601
tcg_temp_free_i32(tmp2);
7602
} else if (insn & (1 << 21)) {
7604
tmp2 = load_reg(s, rn);
7605
tcg_gen_add_i32(tmp, tmp, tmp2);
7606
tcg_temp_free_i32(tmp2);
7608
if (insn & (1 << 20))
7610
store_reg(s, rd, tmp);
7613
/* 64 bit mul double accumulate (UMAAL) */
7615
tmp = load_reg(s, rs);
7616
tmp2 = load_reg(s, rm);
7617
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7618
gen_addq_lo(s, tmp64, rn);
7619
gen_addq_lo(s, tmp64, rd);
7620
gen_storeq_reg(s, rn, rd, tmp64);
7621
tcg_temp_free_i64(tmp64);
7623
case 8: case 9: case 10: case 11:
7624
case 12: case 13: case 14: case 15:
7625
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7626
tmp = load_reg(s, rs);
7627
tmp2 = load_reg(s, rm);
7628
if (insn & (1 << 22)) {
7629
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7631
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7633
if (insn & (1 << 21)) { /* mult accumulate */
7634
TCGv_i32 al = load_reg(s, rn);
7635
TCGv_i32 ah = load_reg(s, rd);
7636
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7637
tcg_temp_free_i32(al);
7638
tcg_temp_free_i32(ah);
7640
if (insn & (1 << 20)) {
7641
gen_logicq_cc(tmp, tmp2);
7643
store_reg(s, rn, tmp);
7644
store_reg(s, rd, tmp2);
7650
rn = (insn >> 16) & 0xf;
7651
rd = (insn >> 12) & 0xf;
7652
if (insn & (1 << 23)) {
7653
/* load/store exclusive */
7654
int op2 = (insn >> 8) & 3;
7655
op1 = (insn >> 21) & 0x3;
7658
case 0: /* lda/stl */
7664
case 1: /* reserved */
7666
case 2: /* ldaex/stlex */
7669
case 3: /* ldrex/strex */
7678
addr = tcg_temp_local_new_i32();
7679
load_reg_var(s, addr, rn);
7681
/* Since the emulation does not have barriers,
7682
the acquire/release semantics need no special
7685
if (insn & (1 << 20)) {
7686
tmp = tcg_temp_new_i32();
7689
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7692
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7695
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7700
store_reg(s, rd, tmp);
7703
tmp = load_reg(s, rm);
7706
gen_aa32_st32(tmp, addr, IS_USER(s));
7709
gen_aa32_st8(tmp, addr, IS_USER(s));
7712
gen_aa32_st16(tmp, addr, IS_USER(s));
7717
tcg_temp_free_i32(tmp);
7719
} else if (insn & (1 << 20)) {
7722
gen_load_exclusive(s, rd, 15, addr, 2);
7724
case 1: /* ldrexd */
7725
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7727
case 2: /* ldrexb */
7728
gen_load_exclusive(s, rd, 15, addr, 0);
7730
case 3: /* ldrexh */
7731
gen_load_exclusive(s, rd, 15, addr, 1);
7740
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7742
case 1: /* strexd */
7743
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7745
case 2: /* strexb */
7746
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7748
case 3: /* strexh */
7749
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7755
tcg_temp_free_i32(addr);
7757
/* SWP instruction */
7760
/* ??? This is not really atomic. However we know
7761
we never have multiple CPUs running in parallel,
7762
so it is good enough. */
7763
addr = load_reg(s, rn);
7764
tmp = load_reg(s, rm);
7765
tmp2 = tcg_temp_new_i32();
7766
if (insn & (1 << 22)) {
7767
gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7768
gen_aa32_st8(tmp, addr, IS_USER(s));
7770
gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7771
gen_aa32_st32(tmp, addr, IS_USER(s));
7773
tcg_temp_free_i32(tmp);
7774
tcg_temp_free_i32(addr);
7775
store_reg(s, rd, tmp2);
7781
/* Misc load/store */
7782
rn = (insn >> 16) & 0xf;
7783
rd = (insn >> 12) & 0xf;
7784
addr = load_reg(s, rn);
7785
if (insn & (1 << 24))
7786
gen_add_datah_offset(s, insn, 0, addr);
7788
if (insn & (1 << 20)) {
7790
tmp = tcg_temp_new_i32();
7793
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7796
gen_aa32_ld8s(tmp, addr, IS_USER(s));
7800
gen_aa32_ld16s(tmp, addr, IS_USER(s));
7804
} else if (sh & 2) {
7809
tmp = load_reg(s, rd);
7810
gen_aa32_st32(tmp, addr, IS_USER(s));
7811
tcg_temp_free_i32(tmp);
7812
tcg_gen_addi_i32(addr, addr, 4);
7813
tmp = load_reg(s, rd + 1);
7814
gen_aa32_st32(tmp, addr, IS_USER(s));
7815
tcg_temp_free_i32(tmp);
7819
tmp = tcg_temp_new_i32();
7820
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7821
store_reg(s, rd, tmp);
7822
tcg_gen_addi_i32(addr, addr, 4);
7823
tmp = tcg_temp_new_i32();
7824
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7828
address_offset = -4;
7831
tmp = load_reg(s, rd);
7832
gen_aa32_st16(tmp, addr, IS_USER(s));
7833
tcg_temp_free_i32(tmp);
7836
/* Perform base writeback before the loaded value to
7837
ensure correct behavior with overlapping index registers.
7838
ldrd with base writeback is is undefined if the
7839
destination and index registers overlap. */
7840
if (!(insn & (1 << 24))) {
7841
gen_add_datah_offset(s, insn, address_offset, addr);
7842
store_reg(s, rn, addr);
7843
} else if (insn & (1 << 21)) {
7845
tcg_gen_addi_i32(addr, addr, address_offset);
7846
store_reg(s, rn, addr);
7848
tcg_temp_free_i32(addr);
7851
/* Complete the load. */
7852
store_reg(s, rd, tmp);
7861
if (insn & (1 << 4)) {
7863
/* Armv6 Media instructions. */
7865
rn = (insn >> 16) & 0xf;
7866
rd = (insn >> 12) & 0xf;
7867
rs = (insn >> 8) & 0xf;
7868
switch ((insn >> 23) & 3) {
7869
case 0: /* Parallel add/subtract. */
7870
op1 = (insn >> 20) & 7;
7871
tmp = load_reg(s, rn);
7872
tmp2 = load_reg(s, rm);
7873
sh = (insn >> 5) & 7;
7874
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7876
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7877
tcg_temp_free_i32(tmp2);
7878
store_reg(s, rd, tmp);
7881
if ((insn & 0x00700020) == 0) {
7882
/* Halfword pack. */
7883
tmp = load_reg(s, rn);
7884
tmp2 = load_reg(s, rm);
7885
shift = (insn >> 7) & 0x1f;
7886
if (insn & (1 << 6)) {
7890
tcg_gen_sari_i32(tmp2, tmp2, shift);
7891
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7892
tcg_gen_ext16u_i32(tmp2, tmp2);
7896
tcg_gen_shli_i32(tmp2, tmp2, shift);
7897
tcg_gen_ext16u_i32(tmp, tmp);
7898
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7900
tcg_gen_or_i32(tmp, tmp, tmp2);
7901
tcg_temp_free_i32(tmp2);
7902
store_reg(s, rd, tmp);
7903
} else if ((insn & 0x00200020) == 0x00200000) {
7905
tmp = load_reg(s, rm);
7906
shift = (insn >> 7) & 0x1f;
7907
if (insn & (1 << 6)) {
7910
tcg_gen_sari_i32(tmp, tmp, shift);
7912
tcg_gen_shli_i32(tmp, tmp, shift);
7914
sh = (insn >> 16) & 0x1f;
7915
tmp2 = tcg_const_i32(sh);
7916
if (insn & (1 << 22))
7917
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7919
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7920
tcg_temp_free_i32(tmp2);
7921
store_reg(s, rd, tmp);
7922
} else if ((insn & 0x00300fe0) == 0x00200f20) {
7924
tmp = load_reg(s, rm);
7925
sh = (insn >> 16) & 0x1f;
7926
tmp2 = tcg_const_i32(sh);
7927
if (insn & (1 << 22))
7928
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7930
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7931
tcg_temp_free_i32(tmp2);
7932
store_reg(s, rd, tmp);
7933
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
7935
tmp = load_reg(s, rn);
7936
tmp2 = load_reg(s, rm);
7937
tmp3 = tcg_temp_new_i32();
7938
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7939
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7940
tcg_temp_free_i32(tmp3);
7941
tcg_temp_free_i32(tmp2);
7942
store_reg(s, rd, tmp);
7943
} else if ((insn & 0x000003e0) == 0x00000060) {
7944
tmp = load_reg(s, rm);
7945
shift = (insn >> 10) & 3;
7946
/* ??? In many cases it's not necessary to do a
7947
rotate, a shift is sufficient. */
7949
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7950
op1 = (insn >> 20) & 7;
7952
case 0: gen_sxtb16(tmp); break;
7953
case 2: gen_sxtb(tmp); break;
7954
case 3: gen_sxth(tmp); break;
7955
case 4: gen_uxtb16(tmp); break;
7956
case 6: gen_uxtb(tmp); break;
7957
case 7: gen_uxth(tmp); break;
7958
default: goto illegal_op;
7961
tmp2 = load_reg(s, rn);
7962
if ((op1 & 3) == 0) {
7963
gen_add16(tmp, tmp2);
7965
tcg_gen_add_i32(tmp, tmp, tmp2);
7966
tcg_temp_free_i32(tmp2);
7969
store_reg(s, rd, tmp);
7970
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
7972
tmp = load_reg(s, rm);
7973
if (insn & (1 << 22)) {
7974
if (insn & (1 << 7)) {
7978
gen_helper_rbit(tmp, tmp);
7981
if (insn & (1 << 7))
7984
tcg_gen_bswap32_i32(tmp, tmp);
7986
store_reg(s, rd, tmp);
7991
case 2: /* Multiplies (Type 3). */
7992
switch ((insn >> 20) & 0x7) {
7994
if (((insn >> 6) ^ (insn >> 7)) & 1) {
7995
/* op2 not 00x or 11x : UNDEF */
7998
/* Signed multiply most significant [accumulate].
7999
(SMMUL, SMMLA, SMMLS) */
8000
tmp = load_reg(s, rm);
8001
tmp2 = load_reg(s, rs);
8002
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8005
tmp = load_reg(s, rd);
8006
if (insn & (1 << 6)) {
8007
tmp64 = gen_subq_msw(tmp64, tmp);
8009
tmp64 = gen_addq_msw(tmp64, tmp);
8012
if (insn & (1 << 5)) {
8013
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8015
tcg_gen_shri_i64(tmp64, tmp64, 32);
8016
tmp = tcg_temp_new_i32();
8017
tcg_gen_trunc_i64_i32(tmp, tmp64);
8018
tcg_temp_free_i64(tmp64);
8019
store_reg(s, rn, tmp);
8023
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8024
if (insn & (1 << 7)) {
8027
tmp = load_reg(s, rm);
8028
tmp2 = load_reg(s, rs);
8029
if (insn & (1 << 5))
8030
gen_swap_half(tmp2);
8031
gen_smul_dual(tmp, tmp2);
8032
if (insn & (1 << 6)) {
8033
/* This subtraction cannot overflow. */
8034
tcg_gen_sub_i32(tmp, tmp, tmp2);
8036
/* This addition cannot overflow 32 bits;
8037
* however it may overflow considered as a signed
8038
* operation, in which case we must set the Q flag.
8040
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8042
tcg_temp_free_i32(tmp2);
8043
if (insn & (1 << 22)) {
8044
/* smlald, smlsld */
8045
tmp64 = tcg_temp_new_i64();
8046
tcg_gen_ext_i32_i64(tmp64, tmp);
8047
tcg_temp_free_i32(tmp);
8048
gen_addq(s, tmp64, rd, rn);
8049
gen_storeq_reg(s, rd, rn, tmp64);
8050
tcg_temp_free_i64(tmp64);
8052
/* smuad, smusd, smlad, smlsd */
8055
tmp2 = load_reg(s, rd);
8056
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8057
tcg_temp_free_i32(tmp2);
8059
store_reg(s, rn, tmp);
8065
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8068
if (((insn >> 5) & 7) || (rd != 15)) {
8071
tmp = load_reg(s, rm);
8072
tmp2 = load_reg(s, rs);
8073
if (insn & (1 << 21)) {
8074
gen_helper_udiv(tmp, tmp, tmp2);
8076
gen_helper_sdiv(tmp, tmp, tmp2);
8078
tcg_temp_free_i32(tmp2);
8079
store_reg(s, rn, tmp);
8086
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8088
case 0: /* Unsigned sum of absolute differences. */
8090
tmp = load_reg(s, rm);
8091
tmp2 = load_reg(s, rs);
8092
gen_helper_usad8(tmp, tmp, tmp2);
8093
tcg_temp_free_i32(tmp2);
8095
tmp2 = load_reg(s, rd);
8096
tcg_gen_add_i32(tmp, tmp, tmp2);
8097
tcg_temp_free_i32(tmp2);
8099
store_reg(s, rn, tmp);
8101
case 0x20: case 0x24: case 0x28: case 0x2c:
8102
/* Bitfield insert/clear. */
8104
shift = (insn >> 7) & 0x1f;
8105
i = (insn >> 16) & 0x1f;
8108
tmp = tcg_temp_new_i32();
8109
tcg_gen_movi_i32(tmp, 0);
8111
tmp = load_reg(s, rm);
8114
tmp2 = load_reg(s, rd);
8115
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8116
tcg_temp_free_i32(tmp2);
8118
store_reg(s, rd, tmp);
8120
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8121
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8123
tmp = load_reg(s, rm);
8124
shift = (insn >> 7) & 0x1f;
8125
i = ((insn >> 16) & 0x1f) + 1;
8130
gen_ubfx(tmp, shift, (1u << i) - 1);
8132
gen_sbfx(tmp, shift, i);
8135
store_reg(s, rd, tmp);
8145
/* Check for undefined extension instructions
8146
* per the ARM Bible IE:
8147
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8149
sh = (0xf << 20) | (0xf << 4);
8150
if (op1 == 0x7 && ((insn & sh) == sh))
8154
/* load/store byte/word */
8155
rn = (insn >> 16) & 0xf;
8156
rd = (insn >> 12) & 0xf;
8157
tmp2 = load_reg(s, rn);
8158
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8159
if (insn & (1 << 24))
8160
gen_add_data_offset(s, insn, tmp2);
8161
if (insn & (1 << 20)) {
8163
tmp = tcg_temp_new_i32();
8164
if (insn & (1 << 22)) {
8165
gen_aa32_ld8u(tmp, tmp2, i);
8167
gen_aa32_ld32u(tmp, tmp2, i);
8171
tmp = load_reg(s, rd);
8172
if (insn & (1 << 22)) {
8173
gen_aa32_st8(tmp, tmp2, i);
8175
gen_aa32_st32(tmp, tmp2, i);
8177
tcg_temp_free_i32(tmp);
8179
if (!(insn & (1 << 24))) {
8180
gen_add_data_offset(s, insn, tmp2);
8181
store_reg(s, rn, tmp2);
8182
} else if (insn & (1 << 21)) {
8183
store_reg(s, rn, tmp2);
8185
tcg_temp_free_i32(tmp2);
8187
if (insn & (1 << 20)) {
8188
/* Complete the load. */
8189
store_reg_from_load(env, s, rd, tmp);
8195
int j, n, user, loaded_base;
8196
TCGv_i32 loaded_var;
8197
/* load/store multiple words */
8198
/* XXX: store correct base if write back */
8200
if (insn & (1 << 22)) {
8202
goto illegal_op; /* only usable in supervisor mode */
8204
if ((insn & (1 << 15)) == 0)
8207
rn = (insn >> 16) & 0xf;
8208
addr = load_reg(s, rn);
8210
/* compute total size */
8212
TCGV_UNUSED_I32(loaded_var);
8215
if (insn & (1 << i))
8218
/* XXX: test invalid n == 0 case ? */
8219
if (insn & (1 << 23)) {
8220
if (insn & (1 << 24)) {
8222
tcg_gen_addi_i32(addr, addr, 4);
8224
/* post increment */
8227
if (insn & (1 << 24)) {
8229
tcg_gen_addi_i32(addr, addr, -(n * 4));
8231
/* post decrement */
8233
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8238
if (insn & (1 << i)) {
8239
if (insn & (1 << 20)) {
8241
tmp = tcg_temp_new_i32();
8242
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8244
tmp2 = tcg_const_i32(i);
8245
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8246
tcg_temp_free_i32(tmp2);
8247
tcg_temp_free_i32(tmp);
8248
} else if (i == rn) {
8252
store_reg_from_load(env, s, i, tmp);
8257
/* special case: r15 = PC + 8 */
8258
val = (long)s->pc + 4;
8259
tmp = tcg_temp_new_i32();
8260
tcg_gen_movi_i32(tmp, val);
8262
tmp = tcg_temp_new_i32();
8263
tmp2 = tcg_const_i32(i);
8264
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8265
tcg_temp_free_i32(tmp2);
8267
tmp = load_reg(s, i);
8269
gen_aa32_st32(tmp, addr, IS_USER(s));
8270
tcg_temp_free_i32(tmp);
8273
/* no need to add after the last transfer */
8275
tcg_gen_addi_i32(addr, addr, 4);
8278
if (insn & (1 << 21)) {
8280
if (insn & (1 << 23)) {
8281
if (insn & (1 << 24)) {
8284
/* post increment */
8285
tcg_gen_addi_i32(addr, addr, 4);
8288
if (insn & (1 << 24)) {
8291
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8293
/* post decrement */
8294
tcg_gen_addi_i32(addr, addr, -(n * 4));
8297
store_reg(s, rn, addr);
8299
tcg_temp_free_i32(addr);
8302
store_reg(s, rn, loaded_var);
8304
if ((insn & (1 << 22)) && !user) {
8305
/* Restore CPSR from SPSR. */
8306
tmp = load_cpu_field(spsr);
8307
gen_set_cpsr(tmp, 0xffffffff);
8308
tcg_temp_free_i32(tmp);
8309
s->is_jmp = DISAS_UPDATE;
8318
/* branch (and link) */
8319
val = (int32_t)s->pc;
8320
if (insn & (1 << 24)) {
8321
tmp = tcg_temp_new_i32();
8322
tcg_gen_movi_i32(tmp, val);
8323
store_reg(s, 14, tmp);
8325
offset = sextract32(insn << 2, 0, 26);
8333
if (((insn >> 8) & 0xe) == 10) {
8335
if (disas_vfp_insn(env, s, insn)) {
8338
} else if (disas_coproc_insn(env, s, insn)) {
8345
gen_set_pc_im(s, s->pc);
8346
s->is_jmp = DISAS_SWI;
8350
gen_exception_insn(s, 4, EXCP_UDEF);
8356
/* Return true if this is a Thumb-2 logical op. */
8358
thumb2_logic_op(int op)
8363
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8364
then set condition code flags based on the result of the operation.
8365
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8366
to the high bit of T1.
8367
Returns zero if the opcode is valid. */
8370
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8371
TCGv_i32 t0, TCGv_i32 t1)
8378
tcg_gen_and_i32(t0, t0, t1);
8382
tcg_gen_andc_i32(t0, t0, t1);
8386
tcg_gen_or_i32(t0, t0, t1);
8390
tcg_gen_orc_i32(t0, t0, t1);
8394
tcg_gen_xor_i32(t0, t0, t1);
8399
gen_add_CC(t0, t0, t1);
8401
tcg_gen_add_i32(t0, t0, t1);
8405
gen_adc_CC(t0, t0, t1);
8411
gen_sbc_CC(t0, t0, t1);
8413
gen_sub_carry(t0, t0, t1);
8418
gen_sub_CC(t0, t0, t1);
8420
tcg_gen_sub_i32(t0, t0, t1);
8424
gen_sub_CC(t0, t1, t0);
8426
tcg_gen_sub_i32(t0, t1, t0);
8428
default: /* 5, 6, 7, 9, 12, 15. */
8434
gen_set_CF_bit31(t1);
8439
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8441
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8443
uint32_t insn, imm, shift, offset;
8444
uint32_t rd, rn, rm, rs;
8455
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8456
|| arm_feature (env, ARM_FEATURE_M))) {
8457
/* Thumb-1 cores may need to treat bl and blx as a pair of
8458
16-bit instructions to get correct prefetch abort behavior. */
8460
if ((insn & (1 << 12)) == 0) {
8462
/* Second half of blx. */
8463
offset = ((insn & 0x7ff) << 1);
8464
tmp = load_reg(s, 14);
8465
tcg_gen_addi_i32(tmp, tmp, offset);
8466
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8468
tmp2 = tcg_temp_new_i32();
8469
tcg_gen_movi_i32(tmp2, s->pc | 1);
8470
store_reg(s, 14, tmp2);
8474
if (insn & (1 << 11)) {
8475
/* Second half of bl. */
8476
offset = ((insn & 0x7ff) << 1) | 1;
8477
tmp = load_reg(s, 14);
8478
tcg_gen_addi_i32(tmp, tmp, offset);
8480
tmp2 = tcg_temp_new_i32();
8481
tcg_gen_movi_i32(tmp2, s->pc | 1);
8482
store_reg(s, 14, tmp2);
8486
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8487
/* Instruction spans a page boundary. Implement it as two
8488
16-bit instructions in case the second half causes an
8490
offset = ((int32_t)insn << 21) >> 9;
8491
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8494
/* Fall through to 32-bit decode. */
8497
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8499
insn |= (uint32_t)insn_hw1 << 16;
8501
if ((insn & 0xf800e800) != 0xf000e800) {
8505
rn = (insn >> 16) & 0xf;
8506
rs = (insn >> 12) & 0xf;
8507
rd = (insn >> 8) & 0xf;
8509
switch ((insn >> 25) & 0xf) {
8510
case 0: case 1: case 2: case 3:
8511
/* 16-bit instructions. Should never happen. */
8514
if (insn & (1 << 22)) {
8515
/* Other load/store, table branch. */
8516
if (insn & 0x01200000) {
8517
/* Load/store doubleword. */
8519
addr = tcg_temp_new_i32();
8520
tcg_gen_movi_i32(addr, s->pc & ~3);
8522
addr = load_reg(s, rn);
8524
offset = (insn & 0xff) * 4;
8525
if ((insn & (1 << 23)) == 0)
8527
if (insn & (1 << 24)) {
8528
tcg_gen_addi_i32(addr, addr, offset);
8531
if (insn & (1 << 20)) {
8533
tmp = tcg_temp_new_i32();
8534
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8535
store_reg(s, rs, tmp);
8536
tcg_gen_addi_i32(addr, addr, 4);
8537
tmp = tcg_temp_new_i32();
8538
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8539
store_reg(s, rd, tmp);
8542
tmp = load_reg(s, rs);
8543
gen_aa32_st32(tmp, addr, IS_USER(s));
8544
tcg_temp_free_i32(tmp);
8545
tcg_gen_addi_i32(addr, addr, 4);
8546
tmp = load_reg(s, rd);
8547
gen_aa32_st32(tmp, addr, IS_USER(s));
8548
tcg_temp_free_i32(tmp);
8550
if (insn & (1 << 21)) {
8551
/* Base writeback. */
8554
tcg_gen_addi_i32(addr, addr, offset - 4);
8555
store_reg(s, rn, addr);
8557
tcg_temp_free_i32(addr);
8559
} else if ((insn & (1 << 23)) == 0) {
8560
/* Load/store exclusive word. */
8561
addr = tcg_temp_local_new_i32();
8562
load_reg_var(s, addr, rn);
8563
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8564
if (insn & (1 << 20)) {
8565
gen_load_exclusive(s, rs, 15, addr, 2);
8567
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8569
tcg_temp_free_i32(addr);
8570
} else if ((insn & (7 << 5)) == 0) {
8573
addr = tcg_temp_new_i32();
8574
tcg_gen_movi_i32(addr, s->pc);
8576
addr = load_reg(s, rn);
8578
tmp = load_reg(s, rm);
8579
tcg_gen_add_i32(addr, addr, tmp);
8580
if (insn & (1 << 4)) {
8582
tcg_gen_add_i32(addr, addr, tmp);
8583
tcg_temp_free_i32(tmp);
8584
tmp = tcg_temp_new_i32();
8585
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8587
tcg_temp_free_i32(tmp);
8588
tmp = tcg_temp_new_i32();
8589
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8591
tcg_temp_free_i32(addr);
8592
tcg_gen_shli_i32(tmp, tmp, 1);
8593
tcg_gen_addi_i32(tmp, tmp, s->pc);
8594
store_reg(s, 15, tmp);
8596
int op2 = (insn >> 6) & 0x3;
8597
op = (insn >> 4) & 0x3;
8602
/* Load/store exclusive byte/halfword/doubleword */
8609
/* Load-acquire/store-release */
8615
/* Load-acquire/store-release exclusive */
8619
addr = tcg_temp_local_new_i32();
8620
load_reg_var(s, addr, rn);
8622
if (insn & (1 << 20)) {
8623
tmp = tcg_temp_new_i32();
8626
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8629
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8632
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8637
store_reg(s, rs, tmp);
8639
tmp = load_reg(s, rs);
8642
gen_aa32_st8(tmp, addr, IS_USER(s));
8645
gen_aa32_st16(tmp, addr, IS_USER(s));
8648
gen_aa32_st32(tmp, addr, IS_USER(s));
8653
tcg_temp_free_i32(tmp);
8655
} else if (insn & (1 << 20)) {
8656
gen_load_exclusive(s, rs, rd, addr, op);
8658
gen_store_exclusive(s, rm, rs, rd, addr, op);
8660
tcg_temp_free_i32(addr);
8663
/* Load/store multiple, RFE, SRS. */
8664
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8665
/* RFE, SRS: not available in user mode or on M profile */
8666
if (IS_USER(s) || IS_M(env)) {
8669
if (insn & (1 << 20)) {
8671
addr = load_reg(s, rn);
8672
if ((insn & (1 << 24)) == 0)
8673
tcg_gen_addi_i32(addr, addr, -8);
8674
/* Load PC into tmp and CPSR into tmp2. */
8675
tmp = tcg_temp_new_i32();
8676
gen_aa32_ld32u(tmp, addr, 0);
8677
tcg_gen_addi_i32(addr, addr, 4);
8678
tmp2 = tcg_temp_new_i32();
8679
gen_aa32_ld32u(tmp2, addr, 0);
8680
if (insn & (1 << 21)) {
8681
/* Base writeback. */
8682
if (insn & (1 << 24)) {
8683
tcg_gen_addi_i32(addr, addr, 4);
8685
tcg_gen_addi_i32(addr, addr, -4);
8687
store_reg(s, rn, addr);
8689
tcg_temp_free_i32(addr);
8691
gen_rfe(s, tmp, tmp2);
8694
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8698
int i, loaded_base = 0;
8699
TCGv_i32 loaded_var;
8700
/* Load/store multiple. */
8701
addr = load_reg(s, rn);
8703
for (i = 0; i < 16; i++) {
8704
if (insn & (1 << i))
8707
if (insn & (1 << 24)) {
8708
tcg_gen_addi_i32(addr, addr, -offset);
8711
TCGV_UNUSED_I32(loaded_var);
8712
for (i = 0; i < 16; i++) {
8713
if ((insn & (1 << i)) == 0)
8715
if (insn & (1 << 20)) {
8717
tmp = tcg_temp_new_i32();
8718
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8721
} else if (i == rn) {
8725
store_reg(s, i, tmp);
8729
tmp = load_reg(s, i);
8730
gen_aa32_st32(tmp, addr, IS_USER(s));
8731
tcg_temp_free_i32(tmp);
8733
tcg_gen_addi_i32(addr, addr, 4);
8736
store_reg(s, rn, loaded_var);
8738
if (insn & (1 << 21)) {
8739
/* Base register writeback. */
8740
if (insn & (1 << 24)) {
8741
tcg_gen_addi_i32(addr, addr, -offset);
8743
/* Fault if writeback register is in register list. */
8744
if (insn & (1 << rn))
8746
store_reg(s, rn, addr);
8748
tcg_temp_free_i32(addr);
8755
op = (insn >> 21) & 0xf;
8757
/* Halfword pack. */
8758
tmp = load_reg(s, rn);
8759
tmp2 = load_reg(s, rm);
8760
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8761
if (insn & (1 << 5)) {
8765
tcg_gen_sari_i32(tmp2, tmp2, shift);
8766
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8767
tcg_gen_ext16u_i32(tmp2, tmp2);
8771
tcg_gen_shli_i32(tmp2, tmp2, shift);
8772
tcg_gen_ext16u_i32(tmp, tmp);
8773
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8775
tcg_gen_or_i32(tmp, tmp, tmp2);
8776
tcg_temp_free_i32(tmp2);
8777
store_reg(s, rd, tmp);
8779
/* Data processing register constant shift. */
8781
tmp = tcg_temp_new_i32();
8782
tcg_gen_movi_i32(tmp, 0);
8784
tmp = load_reg(s, rn);
8786
tmp2 = load_reg(s, rm);
8788
shiftop = (insn >> 4) & 3;
8789
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8790
conds = (insn & (1 << 20)) != 0;
8791
logic_cc = (conds && thumb2_logic_op(op));
8792
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8793
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8795
tcg_temp_free_i32(tmp2);
8797
store_reg(s, rd, tmp);
8799
tcg_temp_free_i32(tmp);
8803
case 13: /* Misc data processing. */
8804
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8805
if (op < 4 && (insn & 0xf000) != 0xf000)
8808
case 0: /* Register controlled shift. */
8809
tmp = load_reg(s, rn);
8810
tmp2 = load_reg(s, rm);
8811
if ((insn & 0x70) != 0)
8813
op = (insn >> 21) & 3;
8814
logic_cc = (insn & (1 << 20)) != 0;
8815
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8818
store_reg_bx(env, s, rd, tmp);
8820
case 1: /* Sign/zero extend. */
8821
tmp = load_reg(s, rm);
8822
shift = (insn >> 4) & 3;
8823
/* ??? In many cases it's not necessary to do a
8824
rotate, a shift is sufficient. */
8826
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8827
op = (insn >> 20) & 7;
8829
case 0: gen_sxth(tmp); break;
8830
case 1: gen_uxth(tmp); break;
8831
case 2: gen_sxtb16(tmp); break;
8832
case 3: gen_uxtb16(tmp); break;
8833
case 4: gen_sxtb(tmp); break;
8834
case 5: gen_uxtb(tmp); break;
8835
default: goto illegal_op;
8838
tmp2 = load_reg(s, rn);
8839
if ((op >> 1) == 1) {
8840
gen_add16(tmp, tmp2);
8842
tcg_gen_add_i32(tmp, tmp, tmp2);
8843
tcg_temp_free_i32(tmp2);
8846
store_reg(s, rd, tmp);
8848
case 2: /* SIMD add/subtract. */
8849
op = (insn >> 20) & 7;
8850
shift = (insn >> 4) & 7;
8851
if ((op & 3) == 3 || (shift & 3) == 3)
8853
tmp = load_reg(s, rn);
8854
tmp2 = load_reg(s, rm);
8855
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8856
tcg_temp_free_i32(tmp2);
8857
store_reg(s, rd, tmp);
8859
case 3: /* Other data processing. */
8860
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8862
/* Saturating add/subtract. */
8863
tmp = load_reg(s, rn);
8864
tmp2 = load_reg(s, rm);
8866
gen_helper_double_saturate(tmp, cpu_env, tmp);
8868
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8870
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8871
tcg_temp_free_i32(tmp2);
8873
tmp = load_reg(s, rn);
8875
case 0x0a: /* rbit */
8876
gen_helper_rbit(tmp, tmp);
8878
case 0x08: /* rev */
8879
tcg_gen_bswap32_i32(tmp, tmp);
8881
case 0x09: /* rev16 */
8884
case 0x0b: /* revsh */
8887
case 0x10: /* sel */
8888
tmp2 = load_reg(s, rm);
8889
tmp3 = tcg_temp_new_i32();
8890
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8891
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8892
tcg_temp_free_i32(tmp3);
8893
tcg_temp_free_i32(tmp2);
8895
case 0x18: /* clz */
8896
gen_helper_clz(tmp, tmp);
8902
store_reg(s, rd, tmp);
8904
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8905
op = (insn >> 4) & 0xf;
8906
tmp = load_reg(s, rn);
8907
tmp2 = load_reg(s, rm);
8908
switch ((insn >> 20) & 7) {
8909
case 0: /* 32 x 32 -> 32 */
8910
tcg_gen_mul_i32(tmp, tmp, tmp2);
8911
tcg_temp_free_i32(tmp2);
8913
tmp2 = load_reg(s, rs);
8915
tcg_gen_sub_i32(tmp, tmp2, tmp);
8917
tcg_gen_add_i32(tmp, tmp, tmp2);
8918
tcg_temp_free_i32(tmp2);
8921
case 1: /* 16 x 16 -> 32 */
8922
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8923
tcg_temp_free_i32(tmp2);
8925
tmp2 = load_reg(s, rs);
8926
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8927
tcg_temp_free_i32(tmp2);
8930
case 2: /* Dual multiply add. */
8931
case 4: /* Dual multiply subtract. */
8933
gen_swap_half(tmp2);
8934
gen_smul_dual(tmp, tmp2);
8935
if (insn & (1 << 22)) {
8936
/* This subtraction cannot overflow. */
8937
tcg_gen_sub_i32(tmp, tmp, tmp2);
8939
/* This addition cannot overflow 32 bits;
8940
* however it may overflow considered as a signed
8941
* operation, in which case we must set the Q flag.
8943
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8945
tcg_temp_free_i32(tmp2);
8948
tmp2 = load_reg(s, rs);
8949
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8950
tcg_temp_free_i32(tmp2);
8953
case 3: /* 32 * 16 -> 32msb */
8955
tcg_gen_sari_i32(tmp2, tmp2, 16);
8958
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8959
tcg_gen_shri_i64(tmp64, tmp64, 16);
8960
tmp = tcg_temp_new_i32();
8961
tcg_gen_trunc_i64_i32(tmp, tmp64);
8962
tcg_temp_free_i64(tmp64);
8965
tmp2 = load_reg(s, rs);
8966
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8967
tcg_temp_free_i32(tmp2);
8970
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8971
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8973
tmp = load_reg(s, rs);
8974
if (insn & (1 << 20)) {
8975
tmp64 = gen_addq_msw(tmp64, tmp);
8977
tmp64 = gen_subq_msw(tmp64, tmp);
8980
if (insn & (1 << 4)) {
8981
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8983
tcg_gen_shri_i64(tmp64, tmp64, 32);
8984
tmp = tcg_temp_new_i32();
8985
tcg_gen_trunc_i64_i32(tmp, tmp64);
8986
tcg_temp_free_i64(tmp64);
8988
case 7: /* Unsigned sum of absolute differences. */
8989
gen_helper_usad8(tmp, tmp, tmp2);
8990
tcg_temp_free_i32(tmp2);
8992
tmp2 = load_reg(s, rs);
8993
tcg_gen_add_i32(tmp, tmp, tmp2);
8994
tcg_temp_free_i32(tmp2);
8998
store_reg(s, rd, tmp);
9000
case 6: case 7: /* 64-bit multiply, Divide. */
9001
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9002
tmp = load_reg(s, rn);
9003
tmp2 = load_reg(s, rm);
9004
if ((op & 0x50) == 0x10) {
9006
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9010
gen_helper_udiv(tmp, tmp, tmp2);
9012
gen_helper_sdiv(tmp, tmp, tmp2);
9013
tcg_temp_free_i32(tmp2);
9014
store_reg(s, rd, tmp);
9015
} else if ((op & 0xe) == 0xc) {
9016
/* Dual multiply accumulate long. */
9018
gen_swap_half(tmp2);
9019
gen_smul_dual(tmp, tmp2);
9021
tcg_gen_sub_i32(tmp, tmp, tmp2);
9023
tcg_gen_add_i32(tmp, tmp, tmp2);
9025
tcg_temp_free_i32(tmp2);
9027
tmp64 = tcg_temp_new_i64();
9028
tcg_gen_ext_i32_i64(tmp64, tmp);
9029
tcg_temp_free_i32(tmp);
9030
gen_addq(s, tmp64, rs, rd);
9031
gen_storeq_reg(s, rs, rd, tmp64);
9032
tcg_temp_free_i64(tmp64);
9035
/* Unsigned 64-bit multiply */
9036
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9040
gen_mulxy(tmp, tmp2, op & 2, op & 1);
9041
tcg_temp_free_i32(tmp2);
9042
tmp64 = tcg_temp_new_i64();
9043
tcg_gen_ext_i32_i64(tmp64, tmp);
9044
tcg_temp_free_i32(tmp);
9046
/* Signed 64-bit multiply */
9047
tmp64 = gen_muls_i64_i32(tmp, tmp2);
9052
gen_addq_lo(s, tmp64, rs);
9053
gen_addq_lo(s, tmp64, rd);
9054
} else if (op & 0x40) {
9055
/* 64-bit accumulate. */
9056
gen_addq(s, tmp64, rs, rd);
9058
gen_storeq_reg(s, rs, rd, tmp64);
9059
tcg_temp_free_i64(tmp64);
9064
case 6: case 7: case 14: case 15:
9066
if (((insn >> 24) & 3) == 3) {
9067
/* Translate into the equivalent ARM encoding. */
9068
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9069
if (disas_neon_data_insn(env, s, insn))
9071
} else if (((insn >> 8) & 0xe) == 10) {
9072
if (disas_vfp_insn(env, s, insn)) {
9076
if (insn & (1 << 28))
9078
if (disas_coproc_insn (env, s, insn))
9082
case 8: case 9: case 10: case 11:
9083
if (insn & (1 << 15)) {
9084
/* Branches, misc control. */
9085
if (insn & 0x5000) {
9086
/* Unconditional branch. */
9087
/* signextend(hw1[10:0]) -> offset[:12]. */
9088
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9089
/* hw1[10:0] -> offset[11:1]. */
9090
offset |= (insn & 0x7ff) << 1;
9091
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9092
offset[24:22] already have the same value because of the
9093
sign extension above. */
9094
offset ^= ((~insn) & (1 << 13)) << 10;
9095
offset ^= ((~insn) & (1 << 11)) << 11;
9097
if (insn & (1 << 14)) {
9098
/* Branch and link. */
9099
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9103
if (insn & (1 << 12)) {
9108
offset &= ~(uint32_t)2;
9109
/* thumb2 bx, no need to check */
9110
gen_bx_im(s, offset);
9112
} else if (((insn >> 23) & 7) == 7) {
9114
if (insn & (1 << 13))
9117
if (insn & (1 << 26)) {
9118
/* Secure monitor call / smc (v6Z) */
9119
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
9125
op = (insn >> 20) & 7;
9127
case 0: /* msr cpsr. */
9129
tmp = load_reg(s, rn);
9130
addr = tcg_const_i32(insn & 0xff);
9131
gen_helper_v7m_msr(cpu_env, addr, tmp);
9132
tcg_temp_free_i32(addr);
9133
tcg_temp_free_i32(tmp);
9138
case 1: /* msr spsr. */
9141
tmp = load_reg(s, rn);
9143
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9147
case 2: /* cps, nop-hint. */
9148
if (((insn >> 8) & 7) == 0) {
9149
gen_nop_hint(s, insn & 0xff);
9151
/* Implemented as NOP in user mode. */
9156
if (insn & (1 << 10)) {
9157
if (insn & (1 << 7))
9159
if (insn & (1 << 6))
9161
if (insn & (1 << 5))
9163
if (insn & (1 << 9))
9164
imm = CPSR_A | CPSR_I | CPSR_F;
9166
if (insn & (1 << 8)) {
9168
imm |= (insn & 0x1f);
9171
gen_set_psr_im(s, offset, 0, imm);
9174
case 3: /* Special control operations. */
9176
op = (insn >> 4) & 0xf;
9184
/* These execute as NOPs. */
9191
/* Trivial implementation equivalent to bx. */
9192
tmp = load_reg(s, rn);
9195
case 5: /* Exception return. */
9199
if (rn != 14 || rd != 15) {
9202
tmp = load_reg(s, rn);
9203
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9204
gen_exception_return(s, tmp);
9206
case 6: /* mrs cpsr. */
9207
tmp = tcg_temp_new_i32();
9209
addr = tcg_const_i32(insn & 0xff);
9210
gen_helper_v7m_mrs(tmp, cpu_env, addr);
9211
tcg_temp_free_i32(addr);
9213
gen_helper_cpsr_read(tmp, cpu_env);
9215
store_reg(s, rd, tmp);
9217
case 7: /* mrs spsr. */
9218
/* Not accessible in user mode. */
9219
if (IS_USER(s) || IS_M(env))
9221
tmp = load_cpu_field(spsr);
9222
store_reg(s, rd, tmp);
9227
/* Conditional branch. */
9228
op = (insn >> 22) & 0xf;
9229
/* Generate a conditional jump to next instruction. */
9230
s->condlabel = gen_new_label();
9231
arm_gen_test_cc(op ^ 1, s->condlabel);
9234
/* offset[11:1] = insn[10:0] */
9235
offset = (insn & 0x7ff) << 1;
9236
/* offset[17:12] = insn[21:16]. */
9237
offset |= (insn & 0x003f0000) >> 4;
9238
/* offset[31:20] = insn[26]. */
9239
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9240
/* offset[18] = insn[13]. */
9241
offset |= (insn & (1 << 13)) << 5;
9242
/* offset[19] = insn[11]. */
9243
offset |= (insn & (1 << 11)) << 8;
9245
/* jump to the offset */
9246
gen_jmp(s, s->pc + offset);
9249
/* Data processing immediate. */
9250
if (insn & (1 << 25)) {
9251
if (insn & (1 << 24)) {
9252
if (insn & (1 << 20))
9254
/* Bitfield/Saturate. */
9255
op = (insn >> 21) & 7;
9257
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9259
tmp = tcg_temp_new_i32();
9260
tcg_gen_movi_i32(tmp, 0);
9262
tmp = load_reg(s, rn);
9265
case 2: /* Signed bitfield extract. */
9267
if (shift + imm > 32)
9270
gen_sbfx(tmp, shift, imm);
9272
case 6: /* Unsigned bitfield extract. */
9274
if (shift + imm > 32)
9277
gen_ubfx(tmp, shift, (1u << imm) - 1);
9279
case 3: /* Bitfield insert/clear. */
9282
imm = imm + 1 - shift;
9284
tmp2 = load_reg(s, rd);
9285
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9286
tcg_temp_free_i32(tmp2);
9291
default: /* Saturate. */
9294
tcg_gen_sari_i32(tmp, tmp, shift);
9296
tcg_gen_shli_i32(tmp, tmp, shift);
9298
tmp2 = tcg_const_i32(imm);
9301
if ((op & 1) && shift == 0)
9302
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9304
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9307
if ((op & 1) && shift == 0)
9308
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9310
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9312
tcg_temp_free_i32(tmp2);
9315
store_reg(s, rd, tmp);
9317
imm = ((insn & 0x04000000) >> 15)
9318
| ((insn & 0x7000) >> 4) | (insn & 0xff);
9319
if (insn & (1 << 22)) {
9320
/* 16-bit immediate. */
9321
imm |= (insn >> 4) & 0xf000;
9322
if (insn & (1 << 23)) {
9324
tmp = load_reg(s, rd);
9325
tcg_gen_ext16u_i32(tmp, tmp);
9326
tcg_gen_ori_i32(tmp, tmp, imm << 16);
9329
tmp = tcg_temp_new_i32();
9330
tcg_gen_movi_i32(tmp, imm);
9333
/* Add/sub 12-bit immediate. */
9335
offset = s->pc & ~(uint32_t)3;
9336
if (insn & (1 << 23))
9340
tmp = tcg_temp_new_i32();
9341
tcg_gen_movi_i32(tmp, offset);
9343
tmp = load_reg(s, rn);
9344
if (insn & (1 << 23))
9345
tcg_gen_subi_i32(tmp, tmp, imm);
9347
tcg_gen_addi_i32(tmp, tmp, imm);
9350
store_reg(s, rd, tmp);
9353
int shifter_out = 0;
9354
/* modified 12-bit immediate. */
9355
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9356
imm = (insn & 0xff);
9359
/* Nothing to do. */
9361
case 1: /* 00XY00XY */
9364
case 2: /* XY00XY00 */
9368
case 3: /* XYXYXYXY */
9372
default: /* Rotated constant. */
9373
shift = (shift << 1) | (imm >> 7);
9375
imm = imm << (32 - shift);
9379
tmp2 = tcg_temp_new_i32();
9380
tcg_gen_movi_i32(tmp2, imm);
9381
rn = (insn >> 16) & 0xf;
9383
tmp = tcg_temp_new_i32();
9384
tcg_gen_movi_i32(tmp, 0);
9386
tmp = load_reg(s, rn);
9388
op = (insn >> 21) & 0xf;
9389
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9390
shifter_out, tmp, tmp2))
9392
tcg_temp_free_i32(tmp2);
9393
rd = (insn >> 8) & 0xf;
9395
store_reg(s, rd, tmp);
9397
tcg_temp_free_i32(tmp);
9402
case 12: /* Load/store single data item. */
9407
if ((insn & 0x01100000) == 0x01000000) {
9408
if (disas_neon_ls_insn(env, s, insn))
9412
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9414
if (!(insn & (1 << 20))) {
9418
/* Byte or halfword load space with dest == r15 : memory hints.
9419
* Catch them early so we don't emit pointless addressing code.
9420
* This space is a mix of:
9421
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9422
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9424
* unallocated hints, which must be treated as NOPs
9425
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9426
* which is easiest for the decoding logic
9427
* Some space which must UNDEF
9429
int op1 = (insn >> 23) & 3;
9430
int op2 = (insn >> 6) & 0x3f;
9435
/* UNPREDICTABLE, unallocated hint or
9436
* PLD/PLDW/PLI (literal)
9441
return 0; /* PLD/PLDW/PLI or unallocated hint */
9443
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9444
return 0; /* PLD/PLDW/PLI or unallocated hint */
9446
/* UNDEF space, or an UNPREDICTABLE */
9452
addr = tcg_temp_new_i32();
9454
/* s->pc has already been incremented by 4. */
9455
imm = s->pc & 0xfffffffc;
9456
if (insn & (1 << 23))
9457
imm += insn & 0xfff;
9459
imm -= insn & 0xfff;
9460
tcg_gen_movi_i32(addr, imm);
9462
addr = load_reg(s, rn);
9463
if (insn & (1 << 23)) {
9464
/* Positive offset. */
9466
tcg_gen_addi_i32(addr, addr, imm);
9469
switch ((insn >> 8) & 0xf) {
9470
case 0x0: /* Shifted Register. */
9471
shift = (insn >> 4) & 0xf;
9473
tcg_temp_free_i32(addr);
9476
tmp = load_reg(s, rm);
9478
tcg_gen_shli_i32(tmp, tmp, shift);
9479
tcg_gen_add_i32(addr, addr, tmp);
9480
tcg_temp_free_i32(tmp);
9482
case 0xc: /* Negative offset. */
9483
tcg_gen_addi_i32(addr, addr, -imm);
9485
case 0xe: /* User privilege. */
9486
tcg_gen_addi_i32(addr, addr, imm);
9489
case 0x9: /* Post-decrement. */
9492
case 0xb: /* Post-increment. */
9496
case 0xd: /* Pre-decrement. */
9499
case 0xf: /* Pre-increment. */
9500
tcg_gen_addi_i32(addr, addr, imm);
9504
tcg_temp_free_i32(addr);
9509
if (insn & (1 << 20)) {
9511
tmp = tcg_temp_new_i32();
9514
gen_aa32_ld8u(tmp, addr, user);
9517
gen_aa32_ld8s(tmp, addr, user);
9520
gen_aa32_ld16u(tmp, addr, user);
9523
gen_aa32_ld16s(tmp, addr, user);
9526
gen_aa32_ld32u(tmp, addr, user);
9529
tcg_temp_free_i32(tmp);
9530
tcg_temp_free_i32(addr);
9536
store_reg(s, rs, tmp);
9540
tmp = load_reg(s, rs);
9543
gen_aa32_st8(tmp, addr, user);
9546
gen_aa32_st16(tmp, addr, user);
9549
gen_aa32_st32(tmp, addr, user);
9552
tcg_temp_free_i32(tmp);
9553
tcg_temp_free_i32(addr);
9556
tcg_temp_free_i32(tmp);
9559
tcg_gen_addi_i32(addr, addr, imm);
9561
store_reg(s, rn, addr);
9563
tcg_temp_free_i32(addr);
9575
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9577
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9584
if (s->condexec_mask) {
9585
cond = s->condexec_cond;
9586
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9587
s->condlabel = gen_new_label();
9588
arm_gen_test_cc(cond ^ 1, s->condlabel);
9593
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9596
switch (insn >> 12) {
9600
op = (insn >> 11) & 3;
9603
rn = (insn >> 3) & 7;
9604
tmp = load_reg(s, rn);
9605
if (insn & (1 << 10)) {
9607
tmp2 = tcg_temp_new_i32();
9608
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9611
rm = (insn >> 6) & 7;
9612
tmp2 = load_reg(s, rm);
9614
if (insn & (1 << 9)) {
9615
if (s->condexec_mask)
9616
tcg_gen_sub_i32(tmp, tmp, tmp2);
9618
gen_sub_CC(tmp, tmp, tmp2);
9620
if (s->condexec_mask)
9621
tcg_gen_add_i32(tmp, tmp, tmp2);
9623
gen_add_CC(tmp, tmp, tmp2);
9625
tcg_temp_free_i32(tmp2);
9626
store_reg(s, rd, tmp);
9628
/* shift immediate */
9629
rm = (insn >> 3) & 7;
9630
shift = (insn >> 6) & 0x1f;
9631
tmp = load_reg(s, rm);
9632
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9633
if (!s->condexec_mask)
9635
store_reg(s, rd, tmp);
9639
/* arithmetic large immediate */
9640
op = (insn >> 11) & 3;
9641
rd = (insn >> 8) & 0x7;
9642
if (op == 0) { /* mov */
9643
tmp = tcg_temp_new_i32();
9644
tcg_gen_movi_i32(tmp, insn & 0xff);
9645
if (!s->condexec_mask)
9647
store_reg(s, rd, tmp);
9649
tmp = load_reg(s, rd);
9650
tmp2 = tcg_temp_new_i32();
9651
tcg_gen_movi_i32(tmp2, insn & 0xff);
9654
gen_sub_CC(tmp, tmp, tmp2);
9655
tcg_temp_free_i32(tmp);
9656
tcg_temp_free_i32(tmp2);
9659
if (s->condexec_mask)
9660
tcg_gen_add_i32(tmp, tmp, tmp2);
9662
gen_add_CC(tmp, tmp, tmp2);
9663
tcg_temp_free_i32(tmp2);
9664
store_reg(s, rd, tmp);
9667
if (s->condexec_mask)
9668
tcg_gen_sub_i32(tmp, tmp, tmp2);
9670
gen_sub_CC(tmp, tmp, tmp2);
9671
tcg_temp_free_i32(tmp2);
9672
store_reg(s, rd, tmp);
9678
if (insn & (1 << 11)) {
9679
rd = (insn >> 8) & 7;
9680
/* load pc-relative. Bit 1 of PC is ignored. */
9681
val = s->pc + 2 + ((insn & 0xff) * 4);
9682
val &= ~(uint32_t)2;
9683
addr = tcg_temp_new_i32();
9684
tcg_gen_movi_i32(addr, val);
9685
tmp = tcg_temp_new_i32();
9686
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9687
tcg_temp_free_i32(addr);
9688
store_reg(s, rd, tmp);
9691
if (insn & (1 << 10)) {
9692
/* data processing extended or blx */
9693
rd = (insn & 7) | ((insn >> 4) & 8);
9694
rm = (insn >> 3) & 0xf;
9695
op = (insn >> 8) & 3;
9698
tmp = load_reg(s, rd);
9699
tmp2 = load_reg(s, rm);
9700
tcg_gen_add_i32(tmp, tmp, tmp2);
9701
tcg_temp_free_i32(tmp2);
9702
store_reg(s, rd, tmp);
9705
tmp = load_reg(s, rd);
9706
tmp2 = load_reg(s, rm);
9707
gen_sub_CC(tmp, tmp, tmp2);
9708
tcg_temp_free_i32(tmp2);
9709
tcg_temp_free_i32(tmp);
9711
case 2: /* mov/cpy */
9712
tmp = load_reg(s, rm);
9713
store_reg(s, rd, tmp);
9715
case 3:/* branch [and link] exchange thumb register */
9716
tmp = load_reg(s, rm);
9717
if (insn & (1 << 7)) {
9719
val = (uint32_t)s->pc | 1;
9720
tmp2 = tcg_temp_new_i32();
9721
tcg_gen_movi_i32(tmp2, val);
9722
store_reg(s, 14, tmp2);
9724
/* already thumb, no need to check */
9731
/* data processing register */
9733
rm = (insn >> 3) & 7;
9734
op = (insn >> 6) & 0xf;
9735
if (op == 2 || op == 3 || op == 4 || op == 7) {
9736
/* the shift/rotate ops want the operands backwards */
9745
if (op == 9) { /* neg */
9746
tmp = tcg_temp_new_i32();
9747
tcg_gen_movi_i32(tmp, 0);
9748
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9749
tmp = load_reg(s, rd);
9751
TCGV_UNUSED_I32(tmp);
9754
tmp2 = load_reg(s, rm);
9757
tcg_gen_and_i32(tmp, tmp, tmp2);
9758
if (!s->condexec_mask)
9762
tcg_gen_xor_i32(tmp, tmp, tmp2);
9763
if (!s->condexec_mask)
9767
if (s->condexec_mask) {
9768
gen_shl(tmp2, tmp2, tmp);
9770
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9775
if (s->condexec_mask) {
9776
gen_shr(tmp2, tmp2, tmp);
9778
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9783
if (s->condexec_mask) {
9784
gen_sar(tmp2, tmp2, tmp);
9786
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9791
if (s->condexec_mask) {
9794
gen_adc_CC(tmp, tmp, tmp2);
9798
if (s->condexec_mask) {
9799
gen_sub_carry(tmp, tmp, tmp2);
9801
gen_sbc_CC(tmp, tmp, tmp2);
9805
if (s->condexec_mask) {
9806
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9807
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9809
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9814
tcg_gen_and_i32(tmp, tmp, tmp2);
9819
if (s->condexec_mask)
9820
tcg_gen_neg_i32(tmp, tmp2);
9822
gen_sub_CC(tmp, tmp, tmp2);
9825
gen_sub_CC(tmp, tmp, tmp2);
9829
gen_add_CC(tmp, tmp, tmp2);
9833
tcg_gen_or_i32(tmp, tmp, tmp2);
9834
if (!s->condexec_mask)
9838
tcg_gen_mul_i32(tmp, tmp, tmp2);
9839
if (!s->condexec_mask)
9843
tcg_gen_andc_i32(tmp, tmp, tmp2);
9844
if (!s->condexec_mask)
9848
tcg_gen_not_i32(tmp2, tmp2);
9849
if (!s->condexec_mask)
9857
store_reg(s, rm, tmp2);
9859
tcg_temp_free_i32(tmp);
9861
store_reg(s, rd, tmp);
9862
tcg_temp_free_i32(tmp2);
9865
tcg_temp_free_i32(tmp);
9866
tcg_temp_free_i32(tmp2);
9871
/* load/store register offset. */
9873
rn = (insn >> 3) & 7;
9874
rm = (insn >> 6) & 7;
9875
op = (insn >> 9) & 7;
9876
addr = load_reg(s, rn);
9877
tmp = load_reg(s, rm);
9878
tcg_gen_add_i32(addr, addr, tmp);
9879
tcg_temp_free_i32(tmp);
9881
if (op < 3) { /* store */
9882
tmp = load_reg(s, rd);
9884
tmp = tcg_temp_new_i32();
9889
gen_aa32_st32(tmp, addr, IS_USER(s));
9892
gen_aa32_st16(tmp, addr, IS_USER(s));
9895
gen_aa32_st8(tmp, addr, IS_USER(s));
9898
gen_aa32_ld8s(tmp, addr, IS_USER(s));
9901
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9904
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9907
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9910
gen_aa32_ld16s(tmp, addr, IS_USER(s));
9913
if (op >= 3) { /* load */
9914
store_reg(s, rd, tmp);
9916
tcg_temp_free_i32(tmp);
9918
tcg_temp_free_i32(addr);
9922
/* load/store word immediate offset */
9924
rn = (insn >> 3) & 7;
9925
addr = load_reg(s, rn);
9926
val = (insn >> 4) & 0x7c;
9927
tcg_gen_addi_i32(addr, addr, val);
9929
if (insn & (1 << 11)) {
9931
tmp = tcg_temp_new_i32();
9932
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9933
store_reg(s, rd, tmp);
9936
tmp = load_reg(s, rd);
9937
gen_aa32_st32(tmp, addr, IS_USER(s));
9938
tcg_temp_free_i32(tmp);
9940
tcg_temp_free_i32(addr);
9944
/* load/store byte immediate offset */
9946
rn = (insn >> 3) & 7;
9947
addr = load_reg(s, rn);
9948
val = (insn >> 6) & 0x1f;
9949
tcg_gen_addi_i32(addr, addr, val);
9951
if (insn & (1 << 11)) {
9953
tmp = tcg_temp_new_i32();
9954
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9955
store_reg(s, rd, tmp);
9958
tmp = load_reg(s, rd);
9959
gen_aa32_st8(tmp, addr, IS_USER(s));
9960
tcg_temp_free_i32(tmp);
9962
tcg_temp_free_i32(addr);
9966
/* load/store halfword immediate offset */
9968
rn = (insn >> 3) & 7;
9969
addr = load_reg(s, rn);
9970
val = (insn >> 5) & 0x3e;
9971
tcg_gen_addi_i32(addr, addr, val);
9973
if (insn & (1 << 11)) {
9975
tmp = tcg_temp_new_i32();
9976
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9977
store_reg(s, rd, tmp);
9980
tmp = load_reg(s, rd);
9981
gen_aa32_st16(tmp, addr, IS_USER(s));
9982
tcg_temp_free_i32(tmp);
9984
tcg_temp_free_i32(addr);
9988
/* load/store from stack */
9989
rd = (insn >> 8) & 7;
9990
addr = load_reg(s, 13);
9991
val = (insn & 0xff) * 4;
9992
tcg_gen_addi_i32(addr, addr, val);
9994
if (insn & (1 << 11)) {
9996
tmp = tcg_temp_new_i32();
9997
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9998
store_reg(s, rd, tmp);
10001
tmp = load_reg(s, rd);
10002
gen_aa32_st32(tmp, addr, IS_USER(s));
10003
tcg_temp_free_i32(tmp);
10005
tcg_temp_free_i32(addr);
10009
/* add to high reg */
10010
rd = (insn >> 8) & 7;
10011
if (insn & (1 << 11)) {
10013
tmp = load_reg(s, 13);
10015
/* PC. bit 1 is ignored. */
10016
tmp = tcg_temp_new_i32();
10017
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10019
val = (insn & 0xff) * 4;
10020
tcg_gen_addi_i32(tmp, tmp, val);
10021
store_reg(s, rd, tmp);
10026
op = (insn >> 8) & 0xf;
10029
/* adjust stack pointer */
10030
tmp = load_reg(s, 13);
10031
val = (insn & 0x7f) * 4;
10032
if (insn & (1 << 7))
10033
val = -(int32_t)val;
10034
tcg_gen_addi_i32(tmp, tmp, val);
10035
store_reg(s, 13, tmp);
10038
case 2: /* sign/zero extend. */
10041
rm = (insn >> 3) & 7;
10042
tmp = load_reg(s, rm);
10043
switch ((insn >> 6) & 3) {
10044
case 0: gen_sxth(tmp); break;
10045
case 1: gen_sxtb(tmp); break;
10046
case 2: gen_uxth(tmp); break;
10047
case 3: gen_uxtb(tmp); break;
10049
store_reg(s, rd, tmp);
10051
case 4: case 5: case 0xc: case 0xd:
10053
addr = load_reg(s, 13);
10054
if (insn & (1 << 8))
10058
for (i = 0; i < 8; i++) {
10059
if (insn & (1 << i))
10062
if ((insn & (1 << 11)) == 0) {
10063
tcg_gen_addi_i32(addr, addr, -offset);
10065
for (i = 0; i < 8; i++) {
10066
if (insn & (1 << i)) {
10067
if (insn & (1 << 11)) {
10069
tmp = tcg_temp_new_i32();
10070
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10071
store_reg(s, i, tmp);
10074
tmp = load_reg(s, i);
10075
gen_aa32_st32(tmp, addr, IS_USER(s));
10076
tcg_temp_free_i32(tmp);
10078
/* advance to the next address. */
10079
tcg_gen_addi_i32(addr, addr, 4);
10082
TCGV_UNUSED_I32(tmp);
10083
if (insn & (1 << 8)) {
10084
if (insn & (1 << 11)) {
10086
tmp = tcg_temp_new_i32();
10087
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10088
/* don't set the pc until the rest of the instruction
10092
tmp = load_reg(s, 14);
10093
gen_aa32_st32(tmp, addr, IS_USER(s));
10094
tcg_temp_free_i32(tmp);
10096
tcg_gen_addi_i32(addr, addr, 4);
10098
if ((insn & (1 << 11)) == 0) {
10099
tcg_gen_addi_i32(addr, addr, -offset);
10101
/* write back the new stack pointer */
10102
store_reg(s, 13, addr);
10103
/* set the new PC value */
10104
if ((insn & 0x0900) == 0x0900) {
10105
store_reg_from_load(env, s, 15, tmp);
10109
case 1: case 3: case 9: case 11: /* czb */
10111
tmp = load_reg(s, rm);
10112
s->condlabel = gen_new_label();
10114
if (insn & (1 << 11))
10115
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10117
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10118
tcg_temp_free_i32(tmp);
10119
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10120
val = (uint32_t)s->pc + 2;
10125
case 15: /* IT, nop-hint. */
10126
if ((insn & 0xf) == 0) {
10127
gen_nop_hint(s, (insn >> 4) & 0xf);
10131
s->condexec_cond = (insn >> 4) & 0xe;
10132
s->condexec_mask = insn & 0x1f;
10133
/* No actual code generated for this insn, just setup state. */
10136
case 0xe: /* bkpt */
10138
gen_exception_insn(s, 2, EXCP_BKPT);
10141
case 0xa: /* rev */
10143
rn = (insn >> 3) & 0x7;
10145
tmp = load_reg(s, rn);
10146
switch ((insn >> 6) & 3) {
10147
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10148
case 1: gen_rev16(tmp); break;
10149
case 3: gen_revsh(tmp); break;
10150
default: goto illegal_op;
10152
store_reg(s, rd, tmp);
10156
switch ((insn >> 5) & 7) {
10160
if (((insn >> 3) & 1) != s->bswap_code) {
10161
/* Dynamic endianness switching not implemented. */
10162
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10173
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10176
addr = tcg_const_i32(19);
10177
gen_helper_v7m_msr(cpu_env, addr, tmp);
10178
tcg_temp_free_i32(addr);
10182
addr = tcg_const_i32(16);
10183
gen_helper_v7m_msr(cpu_env, addr, tmp);
10184
tcg_temp_free_i32(addr);
10186
tcg_temp_free_i32(tmp);
10189
if (insn & (1 << 4)) {
10190
shift = CPSR_A | CPSR_I | CPSR_F;
10194
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10209
/* load/store multiple */
10210
TCGv_i32 loaded_var;
10211
TCGV_UNUSED_I32(loaded_var);
10212
rn = (insn >> 8) & 0x7;
10213
addr = load_reg(s, rn);
10214
for (i = 0; i < 8; i++) {
10215
if (insn & (1 << i)) {
10216
if (insn & (1 << 11)) {
10218
tmp = tcg_temp_new_i32();
10219
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10223
store_reg(s, i, tmp);
10227
tmp = load_reg(s, i);
10228
gen_aa32_st32(tmp, addr, IS_USER(s));
10229
tcg_temp_free_i32(tmp);
10231
/* advance to the next address */
10232
tcg_gen_addi_i32(addr, addr, 4);
10235
if ((insn & (1 << rn)) == 0) {
10236
/* base reg not in list: base register writeback */
10237
store_reg(s, rn, addr);
10239
/* base reg in list: if load, complete it now */
10240
if (insn & (1 << 11)) {
10241
store_reg(s, rn, loaded_var);
10243
tcg_temp_free_i32(addr);
10248
/* conditional branch or swi */
10249
cond = (insn >> 8) & 0xf;
10255
gen_set_pc_im(s, s->pc);
10256
s->is_jmp = DISAS_SWI;
10259
/* generate a conditional jump to next instruction */
10260
s->condlabel = gen_new_label();
10261
arm_gen_test_cc(cond ^ 1, s->condlabel);
10264
/* jump to the offset */
10265
val = (uint32_t)s->pc + 2;
10266
offset = ((int32_t)insn << 24) >> 24;
10267
val += offset << 1;
10272
if (insn & (1 << 11)) {
10273
if (disas_thumb2_insn(env, s, insn))
10277
/* unconditional branch */
10278
val = (uint32_t)s->pc;
10279
offset = ((int32_t)insn << 21) >> 21;
10280
val += (offset << 1) + 2;
10285
if (disas_thumb2_insn(env, s, insn))
10291
gen_exception_insn(s, 4, EXCP_UDEF);
10295
gen_exception_insn(s, 2, EXCP_UDEF);
10298
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10299
basic block 'tb'. If search_pc is TRUE, also generate PC
10300
information for each intermediate instruction. */
10301
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10302
TranslationBlock *tb,
10305
CPUState *cs = CPU(cpu);
10306
CPUARMState *env = &cpu->env;
10307
DisasContext dc1, *dc = &dc1;
10309
uint16_t *gen_opc_end;
10311
target_ulong pc_start;
10312
target_ulong next_page_start;
10316
/* generate intermediate code */
10318
/* The A64 decoder has its own top level loop, because it doesn't need
10319
* the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10321
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10322
gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10330
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10332
dc->is_jmp = DISAS_NEXT;
10334
dc->singlestep_enabled = cs->singlestep_enabled;
10338
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10339
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10340
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10341
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10342
#if !defined(CONFIG_USER_ONLY)
10343
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10345
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10346
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10347
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10348
dc->cp_regs = cpu->cp_regs;
10349
dc->current_pl = arm_current_pl(env);
10351
cpu_F0s = tcg_temp_new_i32();
10352
cpu_F1s = tcg_temp_new_i32();
10353
cpu_F0d = tcg_temp_new_i64();
10354
cpu_F1d = tcg_temp_new_i64();
10357
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10358
cpu_M0 = tcg_temp_new_i64();
10359
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10362
max_insns = tb->cflags & CF_COUNT_MASK;
10363
if (max_insns == 0)
10364
max_insns = CF_COUNT_MASK;
10368
tcg_clear_temp_count();
10370
/* A note on handling of the condexec (IT) bits:
10372
* We want to avoid the overhead of having to write the updated condexec
10373
* bits back to the CPUARMState for every instruction in an IT block. So:
10374
* (1) if the condexec bits are not already zero then we write
10375
* zero back into the CPUARMState now. This avoids complications trying
10376
* to do it at the end of the block. (For example if we don't do this
10377
* it's hard to identify whether we can safely skip writing condexec
10378
* at the end of the TB, which we definitely want to do for the case
10379
* where a TB doesn't do anything with the IT state at all.)
10380
* (2) if we are going to leave the TB then we call gen_set_condexec()
10381
* which will write the correct value into CPUARMState if zero is wrong.
10382
* This is done both for leaving the TB at the end, and for leaving
10383
* it because of an exception we know will happen, which is done in
10384
* gen_exception_insn(). The latter is necessary because we need to
10385
* leave the TB with the PC/IT state just prior to execution of the
10386
* instruction which caused the exception.
10387
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10388
* then the CPUARMState will be wrong and we need to reset it.
10389
* This is handled in the same way as restoration of the
10390
* PC in these situations: we will be called again with search_pc=1
10391
* and generate a mapping of the condexec bits for each PC in
10392
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10393
* this to restore the condexec bits.
10395
* Note that there are no instructions which can read the condexec
10396
* bits, and none which can write non-static values to them, so
10397
* we don't need to care about whether CPUARMState is correct in the
10401
/* Reset the conditional execution bits immediately. This avoids
10402
complications trying to do it at the end of the block. */
10403
if (dc->condexec_mask || dc->condexec_cond)
10405
TCGv_i32 tmp = tcg_temp_new_i32();
10406
tcg_gen_movi_i32(tmp, 0);
10407
store_cpu_field(tmp, condexec_bits);
10410
#ifdef CONFIG_USER_ONLY
10411
/* Intercept jump to the magic kernel page. */
10412
if (dc->pc >= 0xffff0000) {
10413
/* We always get here via a jump, so know we are not in a
10414
conditional execution block. */
10415
gen_exception(EXCP_KERNEL_TRAP);
10416
dc->is_jmp = DISAS_UPDATE;
10420
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10421
/* We always get here via a jump, so know we are not in a
10422
conditional execution block. */
10423
gen_exception(EXCP_EXCEPTION_EXIT);
10424
dc->is_jmp = DISAS_UPDATE;
10429
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10430
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10431
if (bp->pc == dc->pc) {
10432
gen_exception_insn(dc, 0, EXCP_DEBUG);
10433
/* Advance PC so that clearing the breakpoint will
10434
invalidate this TB. */
10436
goto done_generating;
10441
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10445
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10447
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10448
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10449
tcg_ctx.gen_opc_instr_start[lj] = 1;
10450
tcg_ctx.gen_opc_icount[lj] = num_insns;
10453
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10456
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10457
tcg_gen_debug_insn_start(dc->pc);
10461
disas_thumb_insn(env, dc);
10462
if (dc->condexec_mask) {
10463
dc->condexec_cond = (dc->condexec_cond & 0xe)
10464
| ((dc->condexec_mask >> 4) & 1);
10465
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10466
if (dc->condexec_mask == 0) {
10467
dc->condexec_cond = 0;
10471
disas_arm_insn(env, dc);
10474
if (dc->condjmp && !dc->is_jmp) {
10475
gen_set_label(dc->condlabel);
10479
if (tcg_check_temp_count()) {
10480
fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10484
/* Translation stops when a conditional branch is encountered.
10485
* Otherwise the subsequent code could get translated several times.
10486
* Also stop translation when a page boundary is reached. This
10487
* ensures prefetch aborts occur at the right place. */
10489
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10490
!cs->singlestep_enabled &&
10492
dc->pc < next_page_start &&
10493
num_insns < max_insns);
10495
if (tb->cflags & CF_LAST_IO) {
10497
/* FIXME: This can theoretically happen with self-modifying
10499
cpu_abort(env, "IO on conditional branch instruction");
10504
/* At this stage dc->condjmp will only be set when the skipped
10505
instruction was a conditional branch or trap, and the PC has
10506
already been written. */
10507
if (unlikely(cs->singlestep_enabled)) {
10508
/* Make sure the pc is updated, and raise a debug exception. */
10510
gen_set_condexec(dc);
10511
if (dc->is_jmp == DISAS_SWI) {
10512
gen_exception(EXCP_SWI);
10513
} else if (dc->is_jmp == DISAS_SMC) {
10514
gen_exception(EXCP_SMC);
10516
gen_exception(EXCP_DEBUG);
10518
gen_set_label(dc->condlabel);
10520
if (dc->condjmp || !dc->is_jmp) {
10521
gen_set_pc_im(dc, dc->pc);
10524
gen_set_condexec(dc);
10525
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10526
gen_exception(EXCP_SWI);
10527
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10528
gen_exception(EXCP_SMC);
10530
/* FIXME: Single stepping a WFI insn will not halt
10532
gen_exception(EXCP_DEBUG);
10535
/* While branches must always occur at the end of an IT block,
10536
there are a few other things that can cause us to terminate
10537
the TB in the middle of an IT block:
10538
- Exception generating instructions (bkpt, swi, undefined).
10540
- Hardware watchpoints.
10541
Hardware breakpoints have already been handled and skip this code.
10543
gen_set_condexec(dc);
10544
switch(dc->is_jmp) {
10546
gen_goto_tb(dc, 1, dc->pc);
10551
/* indicate that the hash table must be used to find the next TB */
10552
tcg_gen_exit_tb(0);
10554
case DISAS_TB_JUMP:
10555
/* nothing more to generate */
10558
gen_helper_wfi(cpu_env);
10561
gen_exception(EXCP_SWI);
10564
gen_exception(EXCP_SMC);
10568
gen_set_label(dc->condlabel);
10569
gen_set_condexec(dc);
10570
gen_goto_tb(dc, 1, dc->pc);
10576
gen_tb_end(tb, num_insns);
10577
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10580
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10581
qemu_log("----------------\n");
10582
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10583
log_target_disas(env, pc_start, dc->pc - pc_start,
10584
dc->thumb | (dc->bswap_code << 1));
10589
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10592
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10594
tb->size = dc->pc - pc_start;
10595
tb->icount = num_insns;
10599
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10601
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10604
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10606
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10609
static const char *cpu_mode_names[16] = {
10610
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10611
"???", "???", "???", "und", "???", "???", "???", "sys"
10614
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10617
ARMCPU *cpu = ARM_CPU(cs);
10618
CPUARMState *env = &cpu->env;
10622
for(i=0;i<16;i++) {
10623
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10625
cpu_fprintf(f, "\n");
10627
cpu_fprintf(f, " ");
10629
psr = cpsr_read(env);
10630
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10632
psr & (1 << 31) ? 'N' : '-',
10633
psr & (1 << 30) ? 'Z' : '-',
10634
psr & (1 << 29) ? 'C' : '-',
10635
psr & (1 << 28) ? 'V' : '-',
10636
psr & CPSR_T ? 'T' : 'A',
10637
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10639
if (flags & CPU_DUMP_FPU) {
10640
int numvfpregs = 0;
10641
if (arm_feature(env, ARM_FEATURE_VFP)) {
10644
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10647
for (i = 0; i < numvfpregs; i++) {
10648
uint64_t v = float64_val(env->vfp.regs[i]);
10649
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10650
i * 2, (uint32_t)v,
10651
i * 2 + 1, (uint32_t)(v >> 32),
10654
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10658
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10661
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10662
env->condexec_bits = 0;
10664
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10665
env->condexec_bits = gen_opc_condexec_bits[pc_pos];