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 disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2776
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2778
if (!arm_feature(env, ARM_FEATURE_V8)) {
2783
VFP_DREG_D(rd, insn);
2784
VFP_DREG_N(rn, insn);
2785
VFP_DREG_M(rm, insn);
2787
rd = VFP_SREG_D(insn);
2788
rn = VFP_SREG_N(insn);
2789
rm = VFP_SREG_M(insn);
2792
if ((insn & 0x0f800e50) == 0x0e000a00) {
2793
return handle_vsel(insn, rd, rn, rm, dp);
2794
} else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2795
return handle_vminmaxnm(insn, rd, rn, rm, dp);
2800
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2801
(ie. an undefined instruction). */
2802
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2804
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2810
if (!arm_feature(env, ARM_FEATURE_VFP))
2813
if (!s->vfp_enabled) {
2814
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2815
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2817
rn = (insn >> 16) & 0xf;
2818
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2819
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2823
if (extract32(insn, 28, 4) == 0xf) {
2824
/* Encodings with T=1 (Thumb) or unconditional (ARM):
2825
* only used in v8 and above.
2827
return disas_vfp_v8_insn(env, s, insn);
2830
dp = ((insn & 0xf00) == 0xb00);
2831
switch ((insn >> 24) & 0xf) {
2833
if (insn & (1 << 4)) {
2834
/* single register transfer */
2835
rd = (insn >> 12) & 0xf;
2840
VFP_DREG_N(rn, insn);
2843
if (insn & 0x00c00060
2844
&& !arm_feature(env, ARM_FEATURE_NEON))
2847
pass = (insn >> 21) & 1;
2848
if (insn & (1 << 22)) {
2850
offset = ((insn >> 5) & 3) * 8;
2851
} else if (insn & (1 << 5)) {
2853
offset = (insn & (1 << 6)) ? 16 : 0;
2858
if (insn & ARM_CP_RW_BIT) {
2860
tmp = neon_load_reg(rn, pass);
2864
tcg_gen_shri_i32(tmp, tmp, offset);
2865
if (insn & (1 << 23))
2871
if (insn & (1 << 23)) {
2873
tcg_gen_shri_i32(tmp, tmp, 16);
2879
tcg_gen_sari_i32(tmp, tmp, 16);
2888
store_reg(s, rd, tmp);
2891
tmp = load_reg(s, rd);
2892
if (insn & (1 << 23)) {
2895
gen_neon_dup_u8(tmp, 0);
2896
} else if (size == 1) {
2897
gen_neon_dup_low16(tmp);
2899
for (n = 0; n <= pass * 2; n++) {
2900
tmp2 = tcg_temp_new_i32();
2901
tcg_gen_mov_i32(tmp2, tmp);
2902
neon_store_reg(rn, n, tmp2);
2904
neon_store_reg(rn, n, tmp);
2909
tmp2 = neon_load_reg(rn, pass);
2910
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2911
tcg_temp_free_i32(tmp2);
2914
tmp2 = neon_load_reg(rn, pass);
2915
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2916
tcg_temp_free_i32(tmp2);
2921
neon_store_reg(rn, pass, tmp);
2925
if ((insn & 0x6f) != 0x00)
2927
rn = VFP_SREG_N(insn);
2928
if (insn & ARM_CP_RW_BIT) {
2930
if (insn & (1 << 21)) {
2931
/* system register */
2936
/* VFP2 allows access to FSID from userspace.
2937
VFP3 restricts all id registers to privileged
2940
&& arm_feature(env, ARM_FEATURE_VFP3))
2942
tmp = load_cpu_field(vfp.xregs[rn]);
2947
tmp = load_cpu_field(vfp.xregs[rn]);
2949
case ARM_VFP_FPINST:
2950
case ARM_VFP_FPINST2:
2951
/* Not present in VFP3. */
2953
|| arm_feature(env, ARM_FEATURE_VFP3))
2955
tmp = load_cpu_field(vfp.xregs[rn]);
2959
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2960
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2962
tmp = tcg_temp_new_i32();
2963
gen_helper_vfp_get_fpscr(tmp, cpu_env);
2969
|| !arm_feature(env, ARM_FEATURE_MVFR))
2971
tmp = load_cpu_field(vfp.xregs[rn]);
2977
gen_mov_F0_vreg(0, rn);
2978
tmp = gen_vfp_mrs();
2981
/* Set the 4 flag bits in the CPSR. */
2983
tcg_temp_free_i32(tmp);
2985
store_reg(s, rd, tmp);
2989
if (insn & (1 << 21)) {
2991
/* system register */
2996
/* Writes are ignored. */
2999
tmp = load_reg(s, rd);
3000
gen_helper_vfp_set_fpscr(cpu_env, tmp);
3001
tcg_temp_free_i32(tmp);
3007
/* TODO: VFP subarchitecture support.
3008
* For now, keep the EN bit only */
3009
tmp = load_reg(s, rd);
3010
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3011
store_cpu_field(tmp, vfp.xregs[rn]);
3014
case ARM_VFP_FPINST:
3015
case ARM_VFP_FPINST2:
3016
tmp = load_reg(s, rd);
3017
store_cpu_field(tmp, vfp.xregs[rn]);
3023
tmp = load_reg(s, rd);
3025
gen_mov_vreg_F0(0, rn);
3030
/* data processing */
3031
/* The opcode is in bits 23, 21, 20 and 6. */
3032
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3036
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3038
/* rn is register number */
3039
VFP_DREG_N(rn, insn);
3042
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3043
/* Integer or single precision destination. */
3044
rd = VFP_SREG_D(insn);
3046
VFP_DREG_D(rd, insn);
3049
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3050
/* VCVT from int is always from S reg regardless of dp bit.
3051
* VCVT with immediate frac_bits has same format as SREG_M
3053
rm = VFP_SREG_M(insn);
3055
VFP_DREG_M(rm, insn);
3058
rn = VFP_SREG_N(insn);
3059
if (op == 15 && rn == 15) {
3060
/* Double precision destination. */
3061
VFP_DREG_D(rd, insn);
3063
rd = VFP_SREG_D(insn);
3065
/* NB that we implicitly rely on the encoding for the frac_bits
3066
* in VCVT of fixed to float being the same as that of an SREG_M
3068
rm = VFP_SREG_M(insn);
3071
veclen = s->vec_len;
3072
if (op == 15 && rn > 3)
3075
/* Shut up compiler warnings. */
3086
/* Figure out what type of vector operation this is. */
3087
if ((rd & bank_mask) == 0) {
3092
delta_d = (s->vec_stride >> 1) + 1;
3094
delta_d = s->vec_stride + 1;
3096
if ((rm & bank_mask) == 0) {
3097
/* mixed scalar/vector */
3106
/* Load the initial operands. */
3111
/* Integer source */
3112
gen_mov_F0_vreg(0, rm);
3117
gen_mov_F0_vreg(dp, rd);
3118
gen_mov_F1_vreg(dp, rm);
3122
/* Compare with zero */
3123
gen_mov_F0_vreg(dp, rd);
3134
/* Source and destination the same. */
3135
gen_mov_F0_vreg(dp, rd);
3141
/* VCVTB, VCVTT: only present with the halfprec extension,
3142
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3144
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3147
/* Otherwise fall through */
3149
/* One source operand. */
3150
gen_mov_F0_vreg(dp, rm);
3154
/* Two source operands. */
3155
gen_mov_F0_vreg(dp, rn);
3156
gen_mov_F1_vreg(dp, rm);
3160
/* Perform the calculation. */
3162
case 0: /* VMLA: fd + (fn * fm) */
3163
/* Note that order of inputs to the add matters for NaNs */
3165
gen_mov_F0_vreg(dp, rd);
3168
case 1: /* VMLS: fd + -(fn * fm) */
3171
gen_mov_F0_vreg(dp, rd);
3174
case 2: /* VNMLS: -fd + (fn * fm) */
3175
/* Note that it isn't valid to replace (-A + B) with (B - A)
3176
* or similar plausible looking simplifications
3177
* because this will give wrong results for NaNs.
3180
gen_mov_F0_vreg(dp, rd);
3184
case 3: /* VNMLA: -fd + -(fn * fm) */
3187
gen_mov_F0_vreg(dp, rd);
3191
case 4: /* mul: fn * fm */
3194
case 5: /* nmul: -(fn * fm) */
3198
case 6: /* add: fn + fm */
3201
case 7: /* sub: fn - fm */
3204
case 8: /* div: fn / fm */
3207
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3208
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3209
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3210
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3211
/* These are fused multiply-add, and must be done as one
3212
* floating point operation with no rounding between the
3213
* multiplication and addition steps.
3214
* NB that doing the negations here as separate steps is
3215
* correct : an input NaN should come out with its sign bit
3216
* flipped if it is a negated-input.
3218
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3226
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3228
frd = tcg_temp_new_i64();
3229
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3232
gen_helper_vfp_negd(frd, frd);
3234
fpst = get_fpstatus_ptr(0);
3235
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3236
cpu_F1d, frd, fpst);
3237
tcg_temp_free_ptr(fpst);
3238
tcg_temp_free_i64(frd);
3244
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3246
frd = tcg_temp_new_i32();
3247
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3249
gen_helper_vfp_negs(frd, frd);
3251
fpst = get_fpstatus_ptr(0);
3252
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3253
cpu_F1s, frd, fpst);
3254
tcg_temp_free_ptr(fpst);
3255
tcg_temp_free_i32(frd);
3258
case 14: /* fconst */
3259
if (!arm_feature(env, ARM_FEATURE_VFP3))
3262
n = (insn << 12) & 0x80000000;
3263
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3270
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3277
tcg_gen_movi_i32(cpu_F0s, n);
3280
case 15: /* extension space */
3294
case 4: /* vcvtb.f32.f16 */
3295
tmp = gen_vfp_mrs();
3296
tcg_gen_ext16u_i32(tmp, tmp);
3297
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3298
tcg_temp_free_i32(tmp);
3300
case 5: /* vcvtt.f32.f16 */
3301
tmp = gen_vfp_mrs();
3302
tcg_gen_shri_i32(tmp, tmp, 16);
3303
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3304
tcg_temp_free_i32(tmp);
3306
case 6: /* vcvtb.f16.f32 */
3307
tmp = tcg_temp_new_i32();
3308
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3309
gen_mov_F0_vreg(0, rd);
3310
tmp2 = gen_vfp_mrs();
3311
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3312
tcg_gen_or_i32(tmp, tmp, tmp2);
3313
tcg_temp_free_i32(tmp2);
3316
case 7: /* vcvtt.f16.f32 */
3317
tmp = tcg_temp_new_i32();
3318
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3319
tcg_gen_shli_i32(tmp, tmp, 16);
3320
gen_mov_F0_vreg(0, rd);
3321
tmp2 = gen_vfp_mrs();
3322
tcg_gen_ext16u_i32(tmp2, tmp2);
3323
tcg_gen_or_i32(tmp, tmp, tmp2);
3324
tcg_temp_free_i32(tmp2);
3336
case 11: /* cmpez */
3340
case 15: /* single<->double conversion */
3342
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3344
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3346
case 16: /* fuito */
3347
gen_vfp_uito(dp, 0);
3349
case 17: /* fsito */
3350
gen_vfp_sito(dp, 0);
3352
case 20: /* fshto */
3353
if (!arm_feature(env, ARM_FEATURE_VFP3))
3355
gen_vfp_shto(dp, 16 - rm, 0);
3357
case 21: /* fslto */
3358
if (!arm_feature(env, ARM_FEATURE_VFP3))
3360
gen_vfp_slto(dp, 32 - rm, 0);
3362
case 22: /* fuhto */
3363
if (!arm_feature(env, ARM_FEATURE_VFP3))
3365
gen_vfp_uhto(dp, 16 - rm, 0);
3367
case 23: /* fulto */
3368
if (!arm_feature(env, ARM_FEATURE_VFP3))
3370
gen_vfp_ulto(dp, 32 - rm, 0);
3372
case 24: /* ftoui */
3373
gen_vfp_toui(dp, 0);
3375
case 25: /* ftouiz */
3376
gen_vfp_touiz(dp, 0);
3378
case 26: /* ftosi */
3379
gen_vfp_tosi(dp, 0);
3381
case 27: /* ftosiz */
3382
gen_vfp_tosiz(dp, 0);
3384
case 28: /* ftosh */
3385
if (!arm_feature(env, ARM_FEATURE_VFP3))
3387
gen_vfp_tosh(dp, 16 - rm, 0);
3389
case 29: /* ftosl */
3390
if (!arm_feature(env, ARM_FEATURE_VFP3))
3392
gen_vfp_tosl(dp, 32 - rm, 0);
3394
case 30: /* ftouh */
3395
if (!arm_feature(env, ARM_FEATURE_VFP3))
3397
gen_vfp_touh(dp, 16 - rm, 0);
3399
case 31: /* ftoul */
3400
if (!arm_feature(env, ARM_FEATURE_VFP3))
3402
gen_vfp_toul(dp, 32 - rm, 0);
3404
default: /* undefined */
3408
default: /* undefined */
3412
/* Write back the result. */
3413
if (op == 15 && (rn >= 8 && rn <= 11))
3414
; /* Comparison, do nothing. */
3415
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3416
/* VCVT double to int: always integer result. */
3417
gen_mov_vreg_F0(0, rd);
3418
else if (op == 15 && rn == 15)
3420
gen_mov_vreg_F0(!dp, rd);
3422
gen_mov_vreg_F0(dp, rd);
3424
/* break out of the loop if we have finished */
3428
if (op == 15 && delta_m == 0) {
3429
/* single source one-many */
3431
rd = ((rd + delta_d) & (bank_mask - 1))
3433
gen_mov_vreg_F0(dp, rd);
3437
/* Setup the next operands. */
3439
rd = ((rd + delta_d) & (bank_mask - 1))
3443
/* One source operand. */
3444
rm = ((rm + delta_m) & (bank_mask - 1))
3446
gen_mov_F0_vreg(dp, rm);
3448
/* Two source operands. */
3449
rn = ((rn + delta_d) & (bank_mask - 1))
3451
gen_mov_F0_vreg(dp, rn);
3453
rm = ((rm + delta_m) & (bank_mask - 1))
3455
gen_mov_F1_vreg(dp, rm);
3463
if ((insn & 0x03e00000) == 0x00400000) {
3464
/* two-register transfer */
3465
rn = (insn >> 16) & 0xf;
3466
rd = (insn >> 12) & 0xf;
3468
VFP_DREG_M(rm, insn);
3470
rm = VFP_SREG_M(insn);
3473
if (insn & ARM_CP_RW_BIT) {
3476
gen_mov_F0_vreg(0, rm * 2);
3477
tmp = gen_vfp_mrs();
3478
store_reg(s, rd, tmp);
3479
gen_mov_F0_vreg(0, rm * 2 + 1);
3480
tmp = gen_vfp_mrs();
3481
store_reg(s, rn, tmp);
3483
gen_mov_F0_vreg(0, rm);
3484
tmp = gen_vfp_mrs();
3485
store_reg(s, rd, tmp);
3486
gen_mov_F0_vreg(0, rm + 1);
3487
tmp = gen_vfp_mrs();
3488
store_reg(s, rn, tmp);
3493
tmp = load_reg(s, rd);
3495
gen_mov_vreg_F0(0, rm * 2);
3496
tmp = load_reg(s, rn);
3498
gen_mov_vreg_F0(0, rm * 2 + 1);
3500
tmp = load_reg(s, rd);
3502
gen_mov_vreg_F0(0, rm);
3503
tmp = load_reg(s, rn);
3505
gen_mov_vreg_F0(0, rm + 1);
3510
rn = (insn >> 16) & 0xf;
3512
VFP_DREG_D(rd, insn);
3514
rd = VFP_SREG_D(insn);
3515
if ((insn & 0x01200000) == 0x01000000) {
3516
/* Single load/store */
3517
offset = (insn & 0xff) << 2;
3518
if ((insn & (1 << 23)) == 0)
3520
if (s->thumb && rn == 15) {
3521
/* This is actually UNPREDICTABLE */
3522
addr = tcg_temp_new_i32();
3523
tcg_gen_movi_i32(addr, s->pc & ~2);
3525
addr = load_reg(s, rn);
3527
tcg_gen_addi_i32(addr, addr, offset);
3528
if (insn & (1 << 20)) {
3529
gen_vfp_ld(s, dp, addr);
3530
gen_mov_vreg_F0(dp, rd);
3532
gen_mov_F0_vreg(dp, rd);
3533
gen_vfp_st(s, dp, addr);
3535
tcg_temp_free_i32(addr);
3537
/* load/store multiple */
3538
int w = insn & (1 << 21);
3540
n = (insn >> 1) & 0x7f;
3544
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3545
/* P == U , W == 1 => UNDEF */
3548
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3549
/* UNPREDICTABLE cases for bad immediates: we choose to
3550
* UNDEF to avoid generating huge numbers of TCG ops
3554
if (rn == 15 && w) {
3555
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3559
if (s->thumb && rn == 15) {
3560
/* This is actually UNPREDICTABLE */
3561
addr = tcg_temp_new_i32();
3562
tcg_gen_movi_i32(addr, s->pc & ~2);
3564
addr = load_reg(s, rn);
3566
if (insn & (1 << 24)) /* pre-decrement */
3567
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3573
for (i = 0; i < n; i++) {
3574
if (insn & ARM_CP_RW_BIT) {
3576
gen_vfp_ld(s, dp, addr);
3577
gen_mov_vreg_F0(dp, rd + i);
3580
gen_mov_F0_vreg(dp, rd + i);
3581
gen_vfp_st(s, dp, addr);
3583
tcg_gen_addi_i32(addr, addr, offset);
3587
if (insn & (1 << 24))
3588
offset = -offset * n;
3589
else if (dp && (insn & 1))
3595
tcg_gen_addi_i32(addr, addr, offset);
3596
store_reg(s, rn, addr);
3598
tcg_temp_free_i32(addr);
3604
/* Should never happen. */
3610
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3612
TranslationBlock *tb;
3615
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3617
gen_set_pc_im(s, dest);
3618
tcg_gen_exit_tb((uintptr_t)tb + n);
3620
gen_set_pc_im(s, dest);
3625
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3627
if (unlikely(s->singlestep_enabled)) {
3628
/* An indirect jump so that we still trigger the debug exception. */
3633
gen_goto_tb(s, 0, dest);
3634
s->is_jmp = DISAS_TB_JUMP;
3638
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3641
tcg_gen_sari_i32(t0, t0, 16);
3645
tcg_gen_sari_i32(t1, t1, 16);
3648
tcg_gen_mul_i32(t0, t0, t1);
3651
/* Return the mask of PSR bits set by a MSR instruction. */
3652
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3656
if (flags & (1 << 0))
3658
if (flags & (1 << 1))
3660
if (flags & (1 << 2))
3662
if (flags & (1 << 3))
3665
/* Mask out undefined bits. */
3666
mask &= ~CPSR_RESERVED;
3667
if (!arm_feature(env, ARM_FEATURE_V4T))
3669
if (!arm_feature(env, ARM_FEATURE_V5))
3670
mask &= ~CPSR_Q; /* V5TE in reality*/
3671
if (!arm_feature(env, ARM_FEATURE_V6))
3672
mask &= ~(CPSR_E | CPSR_GE);
3673
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3675
/* Mask out execution state bits. */
3678
/* Mask out privileged bits. */
3684
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3685
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3689
/* ??? This is also undefined in system mode. */
3693
tmp = load_cpu_field(spsr);
3694
tcg_gen_andi_i32(tmp, tmp, ~mask);
3695
tcg_gen_andi_i32(t0, t0, mask);
3696
tcg_gen_or_i32(tmp, tmp, t0);
3697
store_cpu_field(tmp, spsr);
3699
gen_set_cpsr(t0, mask);
3701
tcg_temp_free_i32(t0);
3706
/* Returns nonzero if access to the PSR is not permitted. */
3707
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3710
tmp = tcg_temp_new_i32();
3711
tcg_gen_movi_i32(tmp, val);
3712
return gen_set_psr(s, mask, spsr, tmp);
3715
/* Generate an old-style exception return. Marks pc as dead. */
3716
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3719
store_reg(s, 15, pc);
3720
tmp = load_cpu_field(spsr);
3721
gen_set_cpsr(tmp, 0xffffffff);
3722
tcg_temp_free_i32(tmp);
3723
s->is_jmp = DISAS_UPDATE;
3726
/* Generate a v6 exception return. Marks both values as dead. */
3727
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3729
gen_set_cpsr(cpsr, 0xffffffff);
3730
tcg_temp_free_i32(cpsr);
3731
store_reg(s, 15, pc);
3732
s->is_jmp = DISAS_UPDATE;
3736
gen_set_condexec (DisasContext *s)
3738
if (s->condexec_mask) {
3739
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3740
TCGv_i32 tmp = tcg_temp_new_i32();
3741
tcg_gen_movi_i32(tmp, val);
3742
store_cpu_field(tmp, condexec_bits);
3746
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3748
gen_set_condexec(s);
3749
gen_set_pc_im(s, s->pc - offset);
3750
gen_exception(excp);
3751
s->is_jmp = DISAS_JUMP;
3754
static void gen_nop_hint(DisasContext *s, int val)
3758
gen_set_pc_im(s, s->pc);
3759
s->is_jmp = DISAS_WFI;
3764
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3770
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3772
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3775
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3776
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3777
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3782
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3785
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3786
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3787
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3792
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3793
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3794
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3795
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3796
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3798
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3799
switch ((size << 1) | u) { \
3801
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3804
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3807
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3810
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3813
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3816
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3818
default: return 1; \
3821
#define GEN_NEON_INTEGER_OP(name) do { \
3822
switch ((size << 1) | u) { \
3824
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3827
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3830
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3833
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3836
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3839
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3841
default: return 1; \
3844
static TCGv_i32 neon_load_scratch(int scratch)
3846
TCGv_i32 tmp = tcg_temp_new_i32();
3847
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3851
static void neon_store_scratch(int scratch, TCGv_i32 var)
3853
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3854
tcg_temp_free_i32(var);
3857
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3861
tmp = neon_load_reg(reg & 7, reg >> 4);
3863
gen_neon_dup_high16(tmp);
3865
gen_neon_dup_low16(tmp);
3868
tmp = neon_load_reg(reg & 15, reg >> 4);
3873
static int gen_neon_unzip(int rd, int rm, int size, int q)
3876
if (!q && size == 2) {
3879
tmp = tcg_const_i32(rd);
3880
tmp2 = tcg_const_i32(rm);
3884
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3887
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3890
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3898
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3901
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3907
tcg_temp_free_i32(tmp);
3908
tcg_temp_free_i32(tmp2);
3912
static int gen_neon_zip(int rd, int rm, int size, int q)
3915
if (!q && size == 2) {
3918
tmp = tcg_const_i32(rd);
3919
tmp2 = tcg_const_i32(rm);
3923
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3926
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3929
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3937
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3940
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3946
tcg_temp_free_i32(tmp);
3947
tcg_temp_free_i32(tmp2);
3951
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3955
rd = tcg_temp_new_i32();
3956
tmp = tcg_temp_new_i32();
3958
tcg_gen_shli_i32(rd, t0, 8);
3959
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3960
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3961
tcg_gen_or_i32(rd, rd, tmp);
3963
tcg_gen_shri_i32(t1, t1, 8);
3964
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3965
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3966
tcg_gen_or_i32(t1, t1, tmp);
3967
tcg_gen_mov_i32(t0, rd);
3969
tcg_temp_free_i32(tmp);
3970
tcg_temp_free_i32(rd);
3973
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3977
rd = tcg_temp_new_i32();
3978
tmp = tcg_temp_new_i32();
3980
tcg_gen_shli_i32(rd, t0, 16);
3981
tcg_gen_andi_i32(tmp, t1, 0xffff);
3982
tcg_gen_or_i32(rd, rd, tmp);
3983
tcg_gen_shri_i32(t1, t1, 16);
3984
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3985
tcg_gen_or_i32(t1, t1, tmp);
3986
tcg_gen_mov_i32(t0, rd);
3988
tcg_temp_free_i32(tmp);
3989
tcg_temp_free_i32(rd);
3997
} neon_ls_element_type[11] = {
4011
/* Translate a NEON load/store element instruction. Return nonzero if the
4012
instruction is invalid. */
4013
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4032
if (!s->vfp_enabled)
4034
VFP_DREG_D(rd, insn);
4035
rn = (insn >> 16) & 0xf;
4037
load = (insn & (1 << 21)) != 0;
4038
if ((insn & (1 << 23)) == 0) {
4039
/* Load store all elements. */
4040
op = (insn >> 8) & 0xf;
4041
size = (insn >> 6) & 3;
4044
/* Catch UNDEF cases for bad values of align field */
4047
if (((insn >> 5) & 1) == 1) {
4052
if (((insn >> 4) & 3) == 3) {
4059
nregs = neon_ls_element_type[op].nregs;
4060
interleave = neon_ls_element_type[op].interleave;
4061
spacing = neon_ls_element_type[op].spacing;
4062
if (size == 3 && (interleave | spacing) != 1)
4064
addr = tcg_temp_new_i32();
4065
load_reg_var(s, addr, rn);
4066
stride = (1 << size) * interleave;
4067
for (reg = 0; reg < nregs; reg++) {
4068
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4069
load_reg_var(s, addr, rn);
4070
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4071
} else if (interleave == 2 && nregs == 4 && reg == 2) {
4072
load_reg_var(s, addr, rn);
4073
tcg_gen_addi_i32(addr, addr, 1 << size);
4076
tmp64 = tcg_temp_new_i64();
4078
gen_aa32_ld64(tmp64, addr, IS_USER(s));
4079
neon_store_reg64(tmp64, rd);
4081
neon_load_reg64(tmp64, rd);
4082
gen_aa32_st64(tmp64, addr, IS_USER(s));
4084
tcg_temp_free_i64(tmp64);
4085
tcg_gen_addi_i32(addr, addr, stride);
4087
for (pass = 0; pass < 2; pass++) {
4090
tmp = tcg_temp_new_i32();
4091
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4092
neon_store_reg(rd, pass, tmp);
4094
tmp = neon_load_reg(rd, pass);
4095
gen_aa32_st32(tmp, addr, IS_USER(s));
4096
tcg_temp_free_i32(tmp);
4098
tcg_gen_addi_i32(addr, addr, stride);
4099
} else if (size == 1) {
4101
tmp = tcg_temp_new_i32();
4102
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4103
tcg_gen_addi_i32(addr, addr, stride);
4104
tmp2 = tcg_temp_new_i32();
4105
gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4106
tcg_gen_addi_i32(addr, addr, stride);
4107
tcg_gen_shli_i32(tmp2, tmp2, 16);
4108
tcg_gen_or_i32(tmp, tmp, tmp2);
4109
tcg_temp_free_i32(tmp2);
4110
neon_store_reg(rd, pass, tmp);
4112
tmp = neon_load_reg(rd, pass);
4113
tmp2 = tcg_temp_new_i32();
4114
tcg_gen_shri_i32(tmp2, tmp, 16);
4115
gen_aa32_st16(tmp, addr, IS_USER(s));
4116
tcg_temp_free_i32(tmp);
4117
tcg_gen_addi_i32(addr, addr, stride);
4118
gen_aa32_st16(tmp2, addr, IS_USER(s));
4119
tcg_temp_free_i32(tmp2);
4120
tcg_gen_addi_i32(addr, addr, stride);
4122
} else /* size == 0 */ {
4124
TCGV_UNUSED_I32(tmp2);
4125
for (n = 0; n < 4; n++) {
4126
tmp = tcg_temp_new_i32();
4127
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4128
tcg_gen_addi_i32(addr, addr, stride);
4132
tcg_gen_shli_i32(tmp, tmp, n * 8);
4133
tcg_gen_or_i32(tmp2, tmp2, tmp);
4134
tcg_temp_free_i32(tmp);
4137
neon_store_reg(rd, pass, tmp2);
4139
tmp2 = neon_load_reg(rd, pass);
4140
for (n = 0; n < 4; n++) {
4141
tmp = tcg_temp_new_i32();
4143
tcg_gen_mov_i32(tmp, tmp2);
4145
tcg_gen_shri_i32(tmp, tmp2, n * 8);
4147
gen_aa32_st8(tmp, addr, IS_USER(s));
4148
tcg_temp_free_i32(tmp);
4149
tcg_gen_addi_i32(addr, addr, stride);
4151
tcg_temp_free_i32(tmp2);
4158
tcg_temp_free_i32(addr);
4161
size = (insn >> 10) & 3;
4163
/* Load single element to all lanes. */
4164
int a = (insn >> 4) & 1;
4168
size = (insn >> 6) & 3;
4169
nregs = ((insn >> 8) & 3) + 1;
4172
if (nregs != 4 || a == 0) {
4175
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4178
if (nregs == 1 && a == 1 && size == 0) {
4181
if (nregs == 3 && a == 1) {
4184
addr = tcg_temp_new_i32();
4185
load_reg_var(s, addr, rn);
4187
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4188
tmp = gen_load_and_replicate(s, addr, size);
4189
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4190
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4191
if (insn & (1 << 5)) {
4192
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4193
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4195
tcg_temp_free_i32(tmp);
4197
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4198
stride = (insn & (1 << 5)) ? 2 : 1;
4199
for (reg = 0; reg < nregs; reg++) {
4200
tmp = gen_load_and_replicate(s, addr, size);
4201
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4202
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4203
tcg_temp_free_i32(tmp);
4204
tcg_gen_addi_i32(addr, addr, 1 << size);
4208
tcg_temp_free_i32(addr);
4209
stride = (1 << size) * nregs;
4211
/* Single element. */
4212
int idx = (insn >> 4) & 0xf;
4213
pass = (insn >> 7) & 1;
4216
shift = ((insn >> 5) & 3) * 8;
4220
shift = ((insn >> 6) & 1) * 16;
4221
stride = (insn & (1 << 5)) ? 2 : 1;
4225
stride = (insn & (1 << 6)) ? 2 : 1;
4230
nregs = ((insn >> 8) & 3) + 1;
4231
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
4234
if (((idx & (1 << size)) != 0) ||
4235
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4240
if ((idx & 1) != 0) {
4245
if (size == 2 && (idx & 2) != 0) {
4250
if ((size == 2) && ((idx & 3) == 3)) {
4257
if ((rd + stride * (nregs - 1)) > 31) {
4258
/* Attempts to write off the end of the register file
4259
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4260
* the neon_load_reg() would write off the end of the array.
4264
addr = tcg_temp_new_i32();
4265
load_reg_var(s, addr, rn);
4266
for (reg = 0; reg < nregs; reg++) {
4268
tmp = tcg_temp_new_i32();
4271
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4274
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4277
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4279
default: /* Avoid compiler warnings. */
4283
tmp2 = neon_load_reg(rd, pass);
4284
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4285
shift, size ? 16 : 8);
4286
tcg_temp_free_i32(tmp2);
4288
neon_store_reg(rd, pass, tmp);
4289
} else { /* Store */
4290
tmp = neon_load_reg(rd, pass);
4292
tcg_gen_shri_i32(tmp, tmp, shift);
4295
gen_aa32_st8(tmp, addr, IS_USER(s));
4298
gen_aa32_st16(tmp, addr, IS_USER(s));
4301
gen_aa32_st32(tmp, addr, IS_USER(s));
4304
tcg_temp_free_i32(tmp);
4307
tcg_gen_addi_i32(addr, addr, 1 << size);
4309
tcg_temp_free_i32(addr);
4310
stride = nregs * (1 << size);
4316
base = load_reg(s, rn);
4318
tcg_gen_addi_i32(base, base, stride);
4321
index = load_reg(s, rm);
4322
tcg_gen_add_i32(base, base, index);
4323
tcg_temp_free_i32(index);
4325
store_reg(s, rn, base);
4330
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4331
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4333
tcg_gen_and_i32(t, t, c);
4334
tcg_gen_andc_i32(f, f, c);
4335
tcg_gen_or_i32(dest, t, f);
4338
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4341
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4342
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4343
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4348
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4351
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4352
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4353
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4358
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4361
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4362
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4363
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4368
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4371
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4372
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4373
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4378
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4384
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4385
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4390
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4391
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4398
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4399
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4404
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4405
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4412
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4416
case 0: gen_helper_neon_widen_u8(dest, src); break;
4417
case 1: gen_helper_neon_widen_u16(dest, src); break;
4418
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4423
case 0: gen_helper_neon_widen_s8(dest, src); break;
4424
case 1: gen_helper_neon_widen_s16(dest, src); break;
4425
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4429
tcg_temp_free_i32(src);
4432
static inline void gen_neon_addl(int size)
4435
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4436
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4437
case 2: tcg_gen_add_i64(CPU_V001); break;
4442
static inline void gen_neon_subl(int size)
4445
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4446
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4447
case 2: tcg_gen_sub_i64(CPU_V001); break;
4452
static inline void gen_neon_negl(TCGv_i64 var, int size)
4455
case 0: gen_helper_neon_negl_u16(var, var); break;
4456
case 1: gen_helper_neon_negl_u32(var, var); break;
4458
tcg_gen_neg_i64(var, var);
4464
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4467
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4468
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4473
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4478
switch ((size << 1) | u) {
4479
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4480
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4481
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4482
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4484
tmp = gen_muls_i64_i32(a, b);
4485
tcg_gen_mov_i64(dest, tmp);
4486
tcg_temp_free_i64(tmp);
4489
tmp = gen_mulu_i64_i32(a, b);
4490
tcg_gen_mov_i64(dest, tmp);
4491
tcg_temp_free_i64(tmp);
4496
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4497
Don't forget to clean them now. */
4499
tcg_temp_free_i32(a);
4500
tcg_temp_free_i32(b);
4504
static void gen_neon_narrow_op(int op, int u, int size,
4505
TCGv_i32 dest, TCGv_i64 src)
4509
gen_neon_unarrow_sats(size, dest, src);
4511
gen_neon_narrow(size, dest, src);
4515
gen_neon_narrow_satu(size, dest, src);
4517
gen_neon_narrow_sats(size, dest, src);
4522
/* Symbolic constants for op fields for Neon 3-register same-length.
4523
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4526
#define NEON_3R_VHADD 0
4527
#define NEON_3R_VQADD 1
4528
#define NEON_3R_VRHADD 2
4529
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4530
#define NEON_3R_VHSUB 4
4531
#define NEON_3R_VQSUB 5
4532
#define NEON_3R_VCGT 6
4533
#define NEON_3R_VCGE 7
4534
#define NEON_3R_VSHL 8
4535
#define NEON_3R_VQSHL 9
4536
#define NEON_3R_VRSHL 10
4537
#define NEON_3R_VQRSHL 11
4538
#define NEON_3R_VMAX 12
4539
#define NEON_3R_VMIN 13
4540
#define NEON_3R_VABD 14
4541
#define NEON_3R_VABA 15
4542
#define NEON_3R_VADD_VSUB 16
4543
#define NEON_3R_VTST_VCEQ 17
4544
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4545
#define NEON_3R_VMUL 19
4546
#define NEON_3R_VPMAX 20
4547
#define NEON_3R_VPMIN 21
4548
#define NEON_3R_VQDMULH_VQRDMULH 22
4549
#define NEON_3R_VPADD 23
4550
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4551
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4552
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4553
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4554
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4555
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4556
#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4558
static const uint8_t neon_3r_sizes[] = {
4559
[NEON_3R_VHADD] = 0x7,
4560
[NEON_3R_VQADD] = 0xf,
4561
[NEON_3R_VRHADD] = 0x7,
4562
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4563
[NEON_3R_VHSUB] = 0x7,
4564
[NEON_3R_VQSUB] = 0xf,
4565
[NEON_3R_VCGT] = 0x7,
4566
[NEON_3R_VCGE] = 0x7,
4567
[NEON_3R_VSHL] = 0xf,
4568
[NEON_3R_VQSHL] = 0xf,
4569
[NEON_3R_VRSHL] = 0xf,
4570
[NEON_3R_VQRSHL] = 0xf,
4571
[NEON_3R_VMAX] = 0x7,
4572
[NEON_3R_VMIN] = 0x7,
4573
[NEON_3R_VABD] = 0x7,
4574
[NEON_3R_VABA] = 0x7,
4575
[NEON_3R_VADD_VSUB] = 0xf,
4576
[NEON_3R_VTST_VCEQ] = 0x7,
4577
[NEON_3R_VML] = 0x7,
4578
[NEON_3R_VMUL] = 0x7,
4579
[NEON_3R_VPMAX] = 0x7,
4580
[NEON_3R_VPMIN] = 0x7,
4581
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4582
[NEON_3R_VPADD] = 0x7,
4583
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4584
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4585
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4586
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4587
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4588
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4589
[NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4592
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4593
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4596
#define NEON_2RM_VREV64 0
4597
#define NEON_2RM_VREV32 1
4598
#define NEON_2RM_VREV16 2
4599
#define NEON_2RM_VPADDL 4
4600
#define NEON_2RM_VPADDL_U 5
4601
#define NEON_2RM_VCLS 8
4602
#define NEON_2RM_VCLZ 9
4603
#define NEON_2RM_VCNT 10
4604
#define NEON_2RM_VMVN 11
4605
#define NEON_2RM_VPADAL 12
4606
#define NEON_2RM_VPADAL_U 13
4607
#define NEON_2RM_VQABS 14
4608
#define NEON_2RM_VQNEG 15
4609
#define NEON_2RM_VCGT0 16
4610
#define NEON_2RM_VCGE0 17
4611
#define NEON_2RM_VCEQ0 18
4612
#define NEON_2RM_VCLE0 19
4613
#define NEON_2RM_VCLT0 20
4614
#define NEON_2RM_VABS 22
4615
#define NEON_2RM_VNEG 23
4616
#define NEON_2RM_VCGT0_F 24
4617
#define NEON_2RM_VCGE0_F 25
4618
#define NEON_2RM_VCEQ0_F 26
4619
#define NEON_2RM_VCLE0_F 27
4620
#define NEON_2RM_VCLT0_F 28
4621
#define NEON_2RM_VABS_F 30
4622
#define NEON_2RM_VNEG_F 31
4623
#define NEON_2RM_VSWP 32
4624
#define NEON_2RM_VTRN 33
4625
#define NEON_2RM_VUZP 34
4626
#define NEON_2RM_VZIP 35
4627
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4628
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4629
#define NEON_2RM_VSHLL 38
4630
#define NEON_2RM_VCVT_F16_F32 44
4631
#define NEON_2RM_VCVT_F32_F16 46
4632
#define NEON_2RM_VRECPE 56
4633
#define NEON_2RM_VRSQRTE 57
4634
#define NEON_2RM_VRECPE_F 58
4635
#define NEON_2RM_VRSQRTE_F 59
4636
#define NEON_2RM_VCVT_FS 60
4637
#define NEON_2RM_VCVT_FU 61
4638
#define NEON_2RM_VCVT_SF 62
4639
#define NEON_2RM_VCVT_UF 63
4641
static int neon_2rm_is_float_op(int op)
4643
/* Return true if this neon 2reg-misc op is float-to-float */
4644
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4645
op >= NEON_2RM_VRECPE_F);
4648
/* Each entry in this array has bit n set if the insn allows
4649
* size value n (otherwise it will UNDEF). Since unallocated
4650
* op values will have no bits set they always UNDEF.
4652
static const uint8_t neon_2rm_sizes[] = {
4653
[NEON_2RM_VREV64] = 0x7,
4654
[NEON_2RM_VREV32] = 0x3,
4655
[NEON_2RM_VREV16] = 0x1,
4656
[NEON_2RM_VPADDL] = 0x7,
4657
[NEON_2RM_VPADDL_U] = 0x7,
4658
[NEON_2RM_VCLS] = 0x7,
4659
[NEON_2RM_VCLZ] = 0x7,
4660
[NEON_2RM_VCNT] = 0x1,
4661
[NEON_2RM_VMVN] = 0x1,
4662
[NEON_2RM_VPADAL] = 0x7,
4663
[NEON_2RM_VPADAL_U] = 0x7,
4664
[NEON_2RM_VQABS] = 0x7,
4665
[NEON_2RM_VQNEG] = 0x7,
4666
[NEON_2RM_VCGT0] = 0x7,
4667
[NEON_2RM_VCGE0] = 0x7,
4668
[NEON_2RM_VCEQ0] = 0x7,
4669
[NEON_2RM_VCLE0] = 0x7,
4670
[NEON_2RM_VCLT0] = 0x7,
4671
[NEON_2RM_VABS] = 0x7,
4672
[NEON_2RM_VNEG] = 0x7,
4673
[NEON_2RM_VCGT0_F] = 0x4,
4674
[NEON_2RM_VCGE0_F] = 0x4,
4675
[NEON_2RM_VCEQ0_F] = 0x4,
4676
[NEON_2RM_VCLE0_F] = 0x4,
4677
[NEON_2RM_VCLT0_F] = 0x4,
4678
[NEON_2RM_VABS_F] = 0x4,
4679
[NEON_2RM_VNEG_F] = 0x4,
4680
[NEON_2RM_VSWP] = 0x1,
4681
[NEON_2RM_VTRN] = 0x7,
4682
[NEON_2RM_VUZP] = 0x7,
4683
[NEON_2RM_VZIP] = 0x7,
4684
[NEON_2RM_VMOVN] = 0x7,
4685
[NEON_2RM_VQMOVN] = 0x7,
4686
[NEON_2RM_VSHLL] = 0x7,
4687
[NEON_2RM_VCVT_F16_F32] = 0x2,
4688
[NEON_2RM_VCVT_F32_F16] = 0x2,
4689
[NEON_2RM_VRECPE] = 0x4,
4690
[NEON_2RM_VRSQRTE] = 0x4,
4691
[NEON_2RM_VRECPE_F] = 0x4,
4692
[NEON_2RM_VRSQRTE_F] = 0x4,
4693
[NEON_2RM_VCVT_FS] = 0x4,
4694
[NEON_2RM_VCVT_FU] = 0x4,
4695
[NEON_2RM_VCVT_SF] = 0x4,
4696
[NEON_2RM_VCVT_UF] = 0x4,
4699
/* Translate a NEON data processing instruction. Return nonzero if the
4700
instruction is invalid.
4701
We process data in a mixture of 32-bit and 64-bit chunks.
4702
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4704
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4716
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4719
if (!s->vfp_enabled)
4721
q = (insn & (1 << 6)) != 0;
4722
u = (insn >> 24) & 1;
4723
VFP_DREG_D(rd, insn);
4724
VFP_DREG_N(rn, insn);
4725
VFP_DREG_M(rm, insn);
4726
size = (insn >> 20) & 3;
4727
if ((insn & (1 << 23)) == 0) {
4728
/* Three register same length. */
4729
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4730
/* Catch invalid op and bad size combinations: UNDEF */
4731
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4734
/* All insns of this form UNDEF for either this condition or the
4735
* superset of cases "Q==1"; we catch the latter later.
4737
if (q && ((rd | rn | rm) & 1)) {
4740
if (size == 3 && op != NEON_3R_LOGIC) {
4741
/* 64-bit element instructions. */
4742
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4743
neon_load_reg64(cpu_V0, rn + pass);
4744
neon_load_reg64(cpu_V1, rm + pass);
4748
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4751
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4757
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4760
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4766
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4768
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4773
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4776
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4782
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4784
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4787
case NEON_3R_VQRSHL:
4789
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4792
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4796
case NEON_3R_VADD_VSUB:
4798
tcg_gen_sub_i64(CPU_V001);
4800
tcg_gen_add_i64(CPU_V001);
4806
neon_store_reg64(cpu_V0, rd + pass);
4815
case NEON_3R_VQRSHL:
4818
/* Shift instruction operands are reversed. */
4833
case NEON_3R_FLOAT_ARITH:
4834
pairwise = (u && size < 2); /* if VPADD (float) */
4836
case NEON_3R_FLOAT_MINMAX:
4837
pairwise = u; /* if VPMIN/VPMAX (float) */
4839
case NEON_3R_FLOAT_CMP:
4841
/* no encoding for U=0 C=1x */
4845
case NEON_3R_FLOAT_ACMP:
4850
case NEON_3R_FLOAT_MISC:
4851
/* VMAXNM/VMINNM in ARMv8 */
4852
if (u && !arm_feature(env, ARM_FEATURE_V8)) {
4857
if (u && (size != 0)) {
4858
/* UNDEF on invalid size for polynomial subcase */
4863
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4871
if (pairwise && q) {
4872
/* All the pairwise insns UNDEF if Q is set */
4876
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4881
tmp = neon_load_reg(rn, 0);
4882
tmp2 = neon_load_reg(rn, 1);
4884
tmp = neon_load_reg(rm, 0);
4885
tmp2 = neon_load_reg(rm, 1);
4889
tmp = neon_load_reg(rn, pass);
4890
tmp2 = neon_load_reg(rm, pass);
4894
GEN_NEON_INTEGER_OP(hadd);
4897
GEN_NEON_INTEGER_OP_ENV(qadd);
4899
case NEON_3R_VRHADD:
4900
GEN_NEON_INTEGER_OP(rhadd);
4902
case NEON_3R_LOGIC: /* Logic ops. */
4903
switch ((u << 2) | size) {
4905
tcg_gen_and_i32(tmp, tmp, tmp2);
4908
tcg_gen_andc_i32(tmp, tmp, tmp2);
4911
tcg_gen_or_i32(tmp, tmp, tmp2);
4914
tcg_gen_orc_i32(tmp, tmp, tmp2);
4917
tcg_gen_xor_i32(tmp, tmp, tmp2);
4920
tmp3 = neon_load_reg(rd, pass);
4921
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4922
tcg_temp_free_i32(tmp3);
4925
tmp3 = neon_load_reg(rd, pass);
4926
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4927
tcg_temp_free_i32(tmp3);
4930
tmp3 = neon_load_reg(rd, pass);
4931
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4932
tcg_temp_free_i32(tmp3);
4937
GEN_NEON_INTEGER_OP(hsub);
4940
GEN_NEON_INTEGER_OP_ENV(qsub);
4943
GEN_NEON_INTEGER_OP(cgt);
4946
GEN_NEON_INTEGER_OP(cge);
4949
GEN_NEON_INTEGER_OP(shl);
4952
GEN_NEON_INTEGER_OP_ENV(qshl);
4955
GEN_NEON_INTEGER_OP(rshl);
4957
case NEON_3R_VQRSHL:
4958
GEN_NEON_INTEGER_OP_ENV(qrshl);
4961
GEN_NEON_INTEGER_OP(max);
4964
GEN_NEON_INTEGER_OP(min);
4967
GEN_NEON_INTEGER_OP(abd);
4970
GEN_NEON_INTEGER_OP(abd);
4971
tcg_temp_free_i32(tmp2);
4972
tmp2 = neon_load_reg(rd, pass);
4973
gen_neon_add(size, tmp, tmp2);
4975
case NEON_3R_VADD_VSUB:
4976
if (!u) { /* VADD */
4977
gen_neon_add(size, tmp, tmp2);
4980
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4981
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4982
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4987
case NEON_3R_VTST_VCEQ:
4988
if (!u) { /* VTST */
4990
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4991
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4992
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4997
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4998
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4999
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5004
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5006
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5007
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5008
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5011
tcg_temp_free_i32(tmp2);
5012
tmp2 = neon_load_reg(rd, pass);
5014
gen_neon_rsb(size, tmp, tmp2);
5016
gen_neon_add(size, tmp, tmp2);
5020
if (u) { /* polynomial */
5021
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5022
} else { /* Integer */
5024
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5025
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5026
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5032
GEN_NEON_INTEGER_OP(pmax);
5035
GEN_NEON_INTEGER_OP(pmin);
5037
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5038
if (!u) { /* VQDMULH */
5041
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5044
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5048
} else { /* VQRDMULH */
5051
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5054
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5062
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5063
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5064
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5068
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5070
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5071
switch ((u << 2) | size) {
5074
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5077
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5080
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5085
tcg_temp_free_ptr(fpstatus);
5088
case NEON_3R_FLOAT_MULTIPLY:
5090
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5091
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5093
tcg_temp_free_i32(tmp2);
5094
tmp2 = neon_load_reg(rd, pass);
5096
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5098
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5101
tcg_temp_free_ptr(fpstatus);
5104
case NEON_3R_FLOAT_CMP:
5106
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5108
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5111
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5113
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5116
tcg_temp_free_ptr(fpstatus);
5119
case NEON_3R_FLOAT_ACMP:
5121
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5123
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5125
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5127
tcg_temp_free_ptr(fpstatus);
5130
case NEON_3R_FLOAT_MINMAX:
5132
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5134
gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5136
gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5138
tcg_temp_free_ptr(fpstatus);
5141
case NEON_3R_FLOAT_MISC:
5144
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5146
gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5148
gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5150
tcg_temp_free_ptr(fpstatus);
5153
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5155
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5161
/* VFMA, VFMS: fused multiply-add */
5162
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5163
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5166
gen_helper_vfp_negs(tmp, tmp);
5168
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5169
tcg_temp_free_i32(tmp3);
5170
tcg_temp_free_ptr(fpstatus);
5176
tcg_temp_free_i32(tmp2);
5178
/* Save the result. For elementwise operations we can put it
5179
straight into the destination register. For pairwise operations
5180
we have to be careful to avoid clobbering the source operands. */
5181
if (pairwise && rd == rm) {
5182
neon_store_scratch(pass, tmp);
5184
neon_store_reg(rd, pass, tmp);
5188
if (pairwise && rd == rm) {
5189
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5190
tmp = neon_load_scratch(pass);
5191
neon_store_reg(rd, pass, tmp);
5194
/* End of 3 register same size operations. */
5195
} else if (insn & (1 << 4)) {
5196
if ((insn & 0x00380080) != 0) {
5197
/* Two registers and shift. */
5198
op = (insn >> 8) & 0xf;
5199
if (insn & (1 << 7)) {
5207
while ((insn & (1 << (size + 19))) == 0)
5210
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5211
/* To avoid excessive duplication of ops we implement shift
5212
by immediate using the variable shift operations. */
5214
/* Shift by immediate:
5215
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5216
if (q && ((rd | rm) & 1)) {
5219
if (!u && (op == 4 || op == 6)) {
5222
/* Right shifts are encoded as N - shift, where N is the
5223
element size in bits. */
5225
shift = shift - (1 << (size + 3));
5233
imm = (uint8_t) shift;
5238
imm = (uint16_t) shift;
5249
for (pass = 0; pass < count; pass++) {
5251
neon_load_reg64(cpu_V0, rm + pass);
5252
tcg_gen_movi_i64(cpu_V1, imm);
5257
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5259
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5264
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5266
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5269
case 5: /* VSHL, VSLI */
5270
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5272
case 6: /* VQSHLU */
5273
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5278
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5281
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5286
if (op == 1 || op == 3) {
5288
neon_load_reg64(cpu_V1, rd + pass);
5289
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5290
} else if (op == 4 || (op == 5 && u)) {
5292
neon_load_reg64(cpu_V1, rd + pass);
5294
if (shift < -63 || shift > 63) {
5298
mask = 0xffffffffffffffffull >> -shift;
5300
mask = 0xffffffffffffffffull << shift;
5303
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5304
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5306
neon_store_reg64(cpu_V0, rd + pass);
5307
} else { /* size < 3 */
5308
/* Operands in T0 and T1. */
5309
tmp = neon_load_reg(rm, pass);
5310
tmp2 = tcg_temp_new_i32();
5311
tcg_gen_movi_i32(tmp2, imm);
5315
GEN_NEON_INTEGER_OP(shl);
5319
GEN_NEON_INTEGER_OP(rshl);
5322
case 5: /* VSHL, VSLI */
5324
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5325
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5326
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5330
case 6: /* VQSHLU */
5333
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5337
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5341
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5349
GEN_NEON_INTEGER_OP_ENV(qshl);
5352
tcg_temp_free_i32(tmp2);
5354
if (op == 1 || op == 3) {
5356
tmp2 = neon_load_reg(rd, pass);
5357
gen_neon_add(size, tmp, tmp2);
5358
tcg_temp_free_i32(tmp2);
5359
} else if (op == 4 || (op == 5 && u)) {
5364
mask = 0xff >> -shift;
5366
mask = (uint8_t)(0xff << shift);
5372
mask = 0xffff >> -shift;
5374
mask = (uint16_t)(0xffff << shift);
5378
if (shift < -31 || shift > 31) {
5382
mask = 0xffffffffu >> -shift;
5384
mask = 0xffffffffu << shift;
5390
tmp2 = neon_load_reg(rd, pass);
5391
tcg_gen_andi_i32(tmp, tmp, mask);
5392
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5393
tcg_gen_or_i32(tmp, tmp, tmp2);
5394
tcg_temp_free_i32(tmp2);
5396
neon_store_reg(rd, pass, tmp);
5399
} else if (op < 10) {
5400
/* Shift by immediate and narrow:
5401
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5402
int input_unsigned = (op == 8) ? !u : u;
5406
shift = shift - (1 << (size + 3));
5409
tmp64 = tcg_const_i64(shift);
5410
neon_load_reg64(cpu_V0, rm);
5411
neon_load_reg64(cpu_V1, rm + 1);
5412
for (pass = 0; pass < 2; pass++) {
5420
if (input_unsigned) {
5421
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5423
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5426
if (input_unsigned) {
5427
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5429
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5432
tmp = tcg_temp_new_i32();
5433
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5434
neon_store_reg(rd, pass, tmp);
5436
tcg_temp_free_i64(tmp64);
5439
imm = (uint16_t)shift;
5443
imm = (uint32_t)shift;
5445
tmp2 = tcg_const_i32(imm);
5446
tmp4 = neon_load_reg(rm + 1, 0);
5447
tmp5 = neon_load_reg(rm + 1, 1);
5448
for (pass = 0; pass < 2; pass++) {
5450
tmp = neon_load_reg(rm, 0);
5454
gen_neon_shift_narrow(size, tmp, tmp2, q,
5457
tmp3 = neon_load_reg(rm, 1);
5461
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5463
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5464
tcg_temp_free_i32(tmp);
5465
tcg_temp_free_i32(tmp3);
5466
tmp = tcg_temp_new_i32();
5467
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5468
neon_store_reg(rd, pass, tmp);
5470
tcg_temp_free_i32(tmp2);
5472
} else if (op == 10) {
5474
if (q || (rd & 1)) {
5477
tmp = neon_load_reg(rm, 0);
5478
tmp2 = neon_load_reg(rm, 1);
5479
for (pass = 0; pass < 2; pass++) {
5483
gen_neon_widen(cpu_V0, tmp, size, u);
5486
/* The shift is less than the width of the source
5487
type, so we can just shift the whole register. */
5488
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5489
/* Widen the result of shift: we need to clear
5490
* the potential overflow bits resulting from
5491
* left bits of the narrow input appearing as
5492
* right bits of left the neighbour narrow
5494
if (size < 2 || !u) {
5497
imm = (0xffu >> (8 - shift));
5499
} else if (size == 1) {
5500
imm = 0xffff >> (16 - shift);
5503
imm = 0xffffffff >> (32 - shift);
5506
imm64 = imm | (((uint64_t)imm) << 32);
5510
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5513
neon_store_reg64(cpu_V0, rd + pass);
5515
} else if (op >= 14) {
5516
/* VCVT fixed-point. */
5517
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5520
/* We have already masked out the must-be-1 top bit of imm6,
5521
* hence this 32-shift where the ARM ARM has 64-imm6.
5524
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5525
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5528
gen_vfp_ulto(0, shift, 1);
5530
gen_vfp_slto(0, shift, 1);
5533
gen_vfp_toul(0, shift, 1);
5535
gen_vfp_tosl(0, shift, 1);
5537
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5542
} else { /* (insn & 0x00380080) == 0 */
5544
if (q && (rd & 1)) {
5548
op = (insn >> 8) & 0xf;
5549
/* One register and immediate. */
5550
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5551
invert = (insn & (1 << 5)) != 0;
5552
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5553
* We choose to not special-case this and will behave as if a
5554
* valid constant encoding of 0 had been given.
5573
imm = (imm << 8) | (imm << 24);
5576
imm = (imm << 8) | 0xff;
5579
imm = (imm << 16) | 0xffff;
5582
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5590
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5591
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5597
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5598
if (op & 1 && op < 12) {
5599
tmp = neon_load_reg(rd, pass);
5601
/* The immediate value has already been inverted, so
5603
tcg_gen_andi_i32(tmp, tmp, imm);
5605
tcg_gen_ori_i32(tmp, tmp, imm);
5609
tmp = tcg_temp_new_i32();
5610
if (op == 14 && invert) {
5614
for (n = 0; n < 4; n++) {
5615
if (imm & (1 << (n + (pass & 1) * 4)))
5616
val |= 0xff << (n * 8);
5618
tcg_gen_movi_i32(tmp, val);
5620
tcg_gen_movi_i32(tmp, imm);
5623
neon_store_reg(rd, pass, tmp);
5626
} else { /* (insn & 0x00800010 == 0x00800000) */
5628
op = (insn >> 8) & 0xf;
5629
if ((insn & (1 << 6)) == 0) {
5630
/* Three registers of different lengths. */
5634
/* undefreq: bit 0 : UNDEF if size != 0
5635
* bit 1 : UNDEF if size == 0
5636
* bit 2 : UNDEF if U == 1
5637
* Note that [1:0] set implies 'always UNDEF'
5640
/* prewiden, src1_wide, src2_wide, undefreq */
5641
static const int neon_3reg_wide[16][4] = {
5642
{1, 0, 0, 0}, /* VADDL */
5643
{1, 1, 0, 0}, /* VADDW */
5644
{1, 0, 0, 0}, /* VSUBL */
5645
{1, 1, 0, 0}, /* VSUBW */
5646
{0, 1, 1, 0}, /* VADDHN */
5647
{0, 0, 0, 0}, /* VABAL */
5648
{0, 1, 1, 0}, /* VSUBHN */
5649
{0, 0, 0, 0}, /* VABDL */
5650
{0, 0, 0, 0}, /* VMLAL */
5651
{0, 0, 0, 6}, /* VQDMLAL */
5652
{0, 0, 0, 0}, /* VMLSL */
5653
{0, 0, 0, 6}, /* VQDMLSL */
5654
{0, 0, 0, 0}, /* Integer VMULL */
5655
{0, 0, 0, 2}, /* VQDMULL */
5656
{0, 0, 0, 5}, /* Polynomial VMULL */
5657
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5660
prewiden = neon_3reg_wide[op][0];
5661
src1_wide = neon_3reg_wide[op][1];
5662
src2_wide = neon_3reg_wide[op][2];
5663
undefreq = neon_3reg_wide[op][3];
5665
if (((undefreq & 1) && (size != 0)) ||
5666
((undefreq & 2) && (size == 0)) ||
5667
((undefreq & 4) && u)) {
5670
if ((src1_wide && (rn & 1)) ||
5671
(src2_wide && (rm & 1)) ||
5672
(!src2_wide && (rd & 1))) {
5676
/* Avoid overlapping operands. Wide source operands are
5677
always aligned so will never overlap with wide
5678
destinations in problematic ways. */
5679
if (rd == rm && !src2_wide) {
5680
tmp = neon_load_reg(rm, 1);
5681
neon_store_scratch(2, tmp);
5682
} else if (rd == rn && !src1_wide) {
5683
tmp = neon_load_reg(rn, 1);
5684
neon_store_scratch(2, tmp);
5686
TCGV_UNUSED_I32(tmp3);
5687
for (pass = 0; pass < 2; pass++) {
5689
neon_load_reg64(cpu_V0, rn + pass);
5690
TCGV_UNUSED_I32(tmp);
5692
if (pass == 1 && rd == rn) {
5693
tmp = neon_load_scratch(2);
5695
tmp = neon_load_reg(rn, pass);
5698
gen_neon_widen(cpu_V0, tmp, size, u);
5702
neon_load_reg64(cpu_V1, rm + pass);
5703
TCGV_UNUSED_I32(tmp2);
5705
if (pass == 1 && rd == rm) {
5706
tmp2 = neon_load_scratch(2);
5708
tmp2 = neon_load_reg(rm, pass);
5711
gen_neon_widen(cpu_V1, tmp2, size, u);
5715
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5716
gen_neon_addl(size);
5718
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5719
gen_neon_subl(size);
5721
case 5: case 7: /* VABAL, VABDL */
5722
switch ((size << 1) | u) {
5724
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5727
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5730
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5733
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5736
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5739
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5743
tcg_temp_free_i32(tmp2);
5744
tcg_temp_free_i32(tmp);
5746
case 8: case 9: case 10: case 11: case 12: case 13:
5747
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5748
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5750
case 14: /* Polynomial VMULL */
5751
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5752
tcg_temp_free_i32(tmp2);
5753
tcg_temp_free_i32(tmp);
5755
default: /* 15 is RESERVED: caught earlier */
5760
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5761
neon_store_reg64(cpu_V0, rd + pass);
5762
} else if (op == 5 || (op >= 8 && op <= 11)) {
5764
neon_load_reg64(cpu_V1, rd + pass);
5766
case 10: /* VMLSL */
5767
gen_neon_negl(cpu_V0, size);
5769
case 5: case 8: /* VABAL, VMLAL */
5770
gen_neon_addl(size);
5772
case 9: case 11: /* VQDMLAL, VQDMLSL */
5773
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5775
gen_neon_negl(cpu_V0, size);
5777
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5782
neon_store_reg64(cpu_V0, rd + pass);
5783
} else if (op == 4 || op == 6) {
5784
/* Narrowing operation. */
5785
tmp = tcg_temp_new_i32();
5789
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5792
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5795
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5796
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5803
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5806
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5809
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5810
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5811
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5819
neon_store_reg(rd, 0, tmp3);
5820
neon_store_reg(rd, 1, tmp);
5823
/* Write back the result. */
5824
neon_store_reg64(cpu_V0, rd + pass);
5828
/* Two registers and a scalar. NB that for ops of this form
5829
* the ARM ARM labels bit 24 as Q, but it is in our variable
5836
case 1: /* Float VMLA scalar */
5837
case 5: /* Floating point VMLS scalar */
5838
case 9: /* Floating point VMUL scalar */
5843
case 0: /* Integer VMLA scalar */
5844
case 4: /* Integer VMLS scalar */
5845
case 8: /* Integer VMUL scalar */
5846
case 12: /* VQDMULH scalar */
5847
case 13: /* VQRDMULH scalar */
5848
if (u && ((rd | rn) & 1)) {
5851
tmp = neon_get_scalar(size, rm);
5852
neon_store_scratch(0, tmp);
5853
for (pass = 0; pass < (u ? 4 : 2); pass++) {
5854
tmp = neon_load_scratch(0);
5855
tmp2 = neon_load_reg(rn, pass);
5858
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5860
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5862
} else if (op == 13) {
5864
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5866
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5868
} else if (op & 1) {
5869
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5870
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5871
tcg_temp_free_ptr(fpstatus);
5874
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5875
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5876
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5880
tcg_temp_free_i32(tmp2);
5883
tmp2 = neon_load_reg(rd, pass);
5886
gen_neon_add(size, tmp, tmp2);
5890
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5891
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5892
tcg_temp_free_ptr(fpstatus);
5896
gen_neon_rsb(size, tmp, tmp2);
5900
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5901
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5902
tcg_temp_free_ptr(fpstatus);
5908
tcg_temp_free_i32(tmp2);
5910
neon_store_reg(rd, pass, tmp);
5913
case 3: /* VQDMLAL scalar */
5914
case 7: /* VQDMLSL scalar */
5915
case 11: /* VQDMULL scalar */
5920
case 2: /* VMLAL sclar */
5921
case 6: /* VMLSL scalar */
5922
case 10: /* VMULL scalar */
5926
tmp2 = neon_get_scalar(size, rm);
5927
/* We need a copy of tmp2 because gen_neon_mull
5928
* deletes it during pass 0. */
5929
tmp4 = tcg_temp_new_i32();
5930
tcg_gen_mov_i32(tmp4, tmp2);
5931
tmp3 = neon_load_reg(rn, 1);
5933
for (pass = 0; pass < 2; pass++) {
5935
tmp = neon_load_reg(rn, 0);
5940
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5942
neon_load_reg64(cpu_V1, rd + pass);
5946
gen_neon_negl(cpu_V0, size);
5949
gen_neon_addl(size);
5952
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5954
gen_neon_negl(cpu_V0, size);
5956
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5962
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5967
neon_store_reg64(cpu_V0, rd + pass);
5972
default: /* 14 and 15 are RESERVED */
5976
} else { /* size == 3 */
5979
imm = (insn >> 8) & 0xf;
5984
if (q && ((rd | rn | rm) & 1)) {
5989
neon_load_reg64(cpu_V0, rn);
5991
neon_load_reg64(cpu_V1, rn + 1);
5993
} else if (imm == 8) {
5994
neon_load_reg64(cpu_V0, rn + 1);
5996
neon_load_reg64(cpu_V1, rm);
5999
tmp64 = tcg_temp_new_i64();
6001
neon_load_reg64(cpu_V0, rn);
6002
neon_load_reg64(tmp64, rn + 1);
6004
neon_load_reg64(cpu_V0, rn + 1);
6005
neon_load_reg64(tmp64, rm);
6007
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6008
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6009
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6011
neon_load_reg64(cpu_V1, rm);
6013
neon_load_reg64(cpu_V1, rm + 1);
6016
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6017
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6018
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6019
tcg_temp_free_i64(tmp64);
6022
neon_load_reg64(cpu_V0, rn);
6023
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6024
neon_load_reg64(cpu_V1, rm);
6025
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6026
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6028
neon_store_reg64(cpu_V0, rd);
6030
neon_store_reg64(cpu_V1, rd + 1);
6032
} else if ((insn & (1 << 11)) == 0) {
6033
/* Two register misc. */
6034
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6035
size = (insn >> 18) & 3;
6036
/* UNDEF for unknown op values and bad op-size combinations */
6037
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6040
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6041
q && ((rm | rd) & 1)) {
6045
case NEON_2RM_VREV64:
6046
for (pass = 0; pass < (q ? 2 : 1); pass++) {
6047
tmp = neon_load_reg(rm, pass * 2);
6048
tmp2 = neon_load_reg(rm, pass * 2 + 1);
6050
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6051
case 1: gen_swap_half(tmp); break;
6052
case 2: /* no-op */ break;
6055
neon_store_reg(rd, pass * 2 + 1, tmp);
6057
neon_store_reg(rd, pass * 2, tmp2);
6060
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6061
case 1: gen_swap_half(tmp2); break;
6064
neon_store_reg(rd, pass * 2, tmp2);
6068
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6069
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6070
for (pass = 0; pass < q + 1; pass++) {
6071
tmp = neon_load_reg(rm, pass * 2);
6072
gen_neon_widen(cpu_V0, tmp, size, op & 1);
6073
tmp = neon_load_reg(rm, pass * 2 + 1);
6074
gen_neon_widen(cpu_V1, tmp, size, op & 1);
6076
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6077
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6078
case 2: tcg_gen_add_i64(CPU_V001); break;
6081
if (op >= NEON_2RM_VPADAL) {
6083
neon_load_reg64(cpu_V1, rd + pass);
6084
gen_neon_addl(size);
6086
neon_store_reg64(cpu_V0, rd + pass);
6092
for (n = 0; n < (q ? 4 : 2); n += 2) {
6093
tmp = neon_load_reg(rm, n);
6094
tmp2 = neon_load_reg(rd, n + 1);
6095
neon_store_reg(rm, n, tmp2);
6096
neon_store_reg(rd, n + 1, tmp);
6103
if (gen_neon_unzip(rd, rm, size, q)) {
6108
if (gen_neon_zip(rd, rm, size, q)) {
6112
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6113
/* also VQMOVUN; op field and mnemonics don't line up */
6117
TCGV_UNUSED_I32(tmp2);
6118
for (pass = 0; pass < 2; pass++) {
6119
neon_load_reg64(cpu_V0, rm + pass);
6120
tmp = tcg_temp_new_i32();
6121
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6126
neon_store_reg(rd, 0, tmp2);
6127
neon_store_reg(rd, 1, tmp);
6131
case NEON_2RM_VSHLL:
6132
if (q || (rd & 1)) {
6135
tmp = neon_load_reg(rm, 0);
6136
tmp2 = neon_load_reg(rm, 1);
6137
for (pass = 0; pass < 2; pass++) {
6140
gen_neon_widen(cpu_V0, tmp, size, 1);
6141
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6142
neon_store_reg64(cpu_V0, rd + pass);
6145
case NEON_2RM_VCVT_F16_F32:
6146
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6150
tmp = tcg_temp_new_i32();
6151
tmp2 = tcg_temp_new_i32();
6152
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6153
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6154
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6155
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6156
tcg_gen_shli_i32(tmp2, tmp2, 16);
6157
tcg_gen_or_i32(tmp2, tmp2, tmp);
6158
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6159
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6160
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6161
neon_store_reg(rd, 0, tmp2);
6162
tmp2 = tcg_temp_new_i32();
6163
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6164
tcg_gen_shli_i32(tmp2, tmp2, 16);
6165
tcg_gen_or_i32(tmp2, tmp2, tmp);
6166
neon_store_reg(rd, 1, tmp2);
6167
tcg_temp_free_i32(tmp);
6169
case NEON_2RM_VCVT_F32_F16:
6170
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6174
tmp3 = tcg_temp_new_i32();
6175
tmp = neon_load_reg(rm, 0);
6176
tmp2 = neon_load_reg(rm, 1);
6177
tcg_gen_ext16u_i32(tmp3, tmp);
6178
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6179
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6180
tcg_gen_shri_i32(tmp3, tmp, 16);
6181
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6182
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6183
tcg_temp_free_i32(tmp);
6184
tcg_gen_ext16u_i32(tmp3, tmp2);
6185
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6186
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6187
tcg_gen_shri_i32(tmp3, tmp2, 16);
6188
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6189
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6190
tcg_temp_free_i32(tmp2);
6191
tcg_temp_free_i32(tmp3);
6195
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6196
if (neon_2rm_is_float_op(op)) {
6197
tcg_gen_ld_f32(cpu_F0s, cpu_env,
6198
neon_reg_offset(rm, pass));
6199
TCGV_UNUSED_I32(tmp);
6201
tmp = neon_load_reg(rm, pass);
6204
case NEON_2RM_VREV32:
6206
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6207
case 1: gen_swap_half(tmp); break;
6211
case NEON_2RM_VREV16:
6216
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6217
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6218
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6224
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6225
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6226
case 2: gen_helper_clz(tmp, tmp); break;
6231
gen_helper_neon_cnt_u8(tmp, tmp);
6234
tcg_gen_not_i32(tmp, tmp);
6236
case NEON_2RM_VQABS:
6239
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6242
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6245
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6250
case NEON_2RM_VQNEG:
6253
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6256
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6259
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6264
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6265
tmp2 = tcg_const_i32(0);
6267
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6268
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6269
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6272
tcg_temp_free_i32(tmp2);
6273
if (op == NEON_2RM_VCLE0) {
6274
tcg_gen_not_i32(tmp, tmp);
6277
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6278
tmp2 = tcg_const_i32(0);
6280
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6281
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6282
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6285
tcg_temp_free_i32(tmp2);
6286
if (op == NEON_2RM_VCLT0) {
6287
tcg_gen_not_i32(tmp, tmp);
6290
case NEON_2RM_VCEQ0:
6291
tmp2 = tcg_const_i32(0);
6293
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6294
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6295
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6298
tcg_temp_free_i32(tmp2);
6302
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6303
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6304
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6309
tmp2 = tcg_const_i32(0);
6310
gen_neon_rsb(size, tmp, tmp2);
6311
tcg_temp_free_i32(tmp2);
6313
case NEON_2RM_VCGT0_F:
6315
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6316
tmp2 = tcg_const_i32(0);
6317
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6318
tcg_temp_free_i32(tmp2);
6319
tcg_temp_free_ptr(fpstatus);
6322
case NEON_2RM_VCGE0_F:
6324
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6325
tmp2 = tcg_const_i32(0);
6326
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6327
tcg_temp_free_i32(tmp2);
6328
tcg_temp_free_ptr(fpstatus);
6331
case NEON_2RM_VCEQ0_F:
6333
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6334
tmp2 = tcg_const_i32(0);
6335
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6336
tcg_temp_free_i32(tmp2);
6337
tcg_temp_free_ptr(fpstatus);
6340
case NEON_2RM_VCLE0_F:
6342
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6343
tmp2 = tcg_const_i32(0);
6344
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6345
tcg_temp_free_i32(tmp2);
6346
tcg_temp_free_ptr(fpstatus);
6349
case NEON_2RM_VCLT0_F:
6351
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6352
tmp2 = tcg_const_i32(0);
6353
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6354
tcg_temp_free_i32(tmp2);
6355
tcg_temp_free_ptr(fpstatus);
6358
case NEON_2RM_VABS_F:
6361
case NEON_2RM_VNEG_F:
6365
tmp2 = neon_load_reg(rd, pass);
6366
neon_store_reg(rm, pass, tmp2);
6369
tmp2 = neon_load_reg(rd, pass);
6371
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6372
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6375
neon_store_reg(rm, pass, tmp2);
6377
case NEON_2RM_VRECPE:
6378
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6380
case NEON_2RM_VRSQRTE:
6381
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6383
case NEON_2RM_VRECPE_F:
6384
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6386
case NEON_2RM_VRSQRTE_F:
6387
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6389
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6392
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6395
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6396
gen_vfp_tosiz(0, 1);
6398
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6399
gen_vfp_touiz(0, 1);
6402
/* Reserved op values were caught by the
6403
* neon_2rm_sizes[] check earlier.
6407
if (neon_2rm_is_float_op(op)) {
6408
tcg_gen_st_f32(cpu_F0s, cpu_env,
6409
neon_reg_offset(rd, pass));
6411
neon_store_reg(rd, pass, tmp);
6416
} else if ((insn & (1 << 10)) == 0) {
6418
int n = ((insn >> 8) & 3) + 1;
6419
if ((rn + n) > 32) {
6420
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6421
* helper function running off the end of the register file.
6426
if (insn & (1 << 6)) {
6427
tmp = neon_load_reg(rd, 0);
6429
tmp = tcg_temp_new_i32();
6430
tcg_gen_movi_i32(tmp, 0);
6432
tmp2 = neon_load_reg(rm, 0);
6433
tmp4 = tcg_const_i32(rn);
6434
tmp5 = tcg_const_i32(n);
6435
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6436
tcg_temp_free_i32(tmp);
6437
if (insn & (1 << 6)) {
6438
tmp = neon_load_reg(rd, 1);
6440
tmp = tcg_temp_new_i32();
6441
tcg_gen_movi_i32(tmp, 0);
6443
tmp3 = neon_load_reg(rm, 1);
6444
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6445
tcg_temp_free_i32(tmp5);
6446
tcg_temp_free_i32(tmp4);
6447
neon_store_reg(rd, 0, tmp2);
6448
neon_store_reg(rd, 1, tmp3);
6449
tcg_temp_free_i32(tmp);
6450
} else if ((insn & 0x380) == 0) {
6452
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6455
if (insn & (1 << 19)) {
6456
tmp = neon_load_reg(rm, 1);
6458
tmp = neon_load_reg(rm, 0);
6460
if (insn & (1 << 16)) {
6461
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6462
} else if (insn & (1 << 17)) {
6463
if ((insn >> 18) & 1)
6464
gen_neon_dup_high16(tmp);
6466
gen_neon_dup_low16(tmp);
6468
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6469
tmp2 = tcg_temp_new_i32();
6470
tcg_gen_mov_i32(tmp2, tmp);
6471
neon_store_reg(rd, pass, tmp2);
6473
tcg_temp_free_i32(tmp);
6482
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6484
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6485
const ARMCPRegInfo *ri;
6487
cpnum = (insn >> 8) & 0xf;
6488
if (arm_feature(env, ARM_FEATURE_XSCALE)
6489
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6492
/* First check for coprocessor space used for actual instructions */
6496
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6497
return disas_iwmmxt_insn(env, s, insn);
6498
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6499
return disas_dsp_insn(env, s, insn);
6506
/* Otherwise treat as a generic register access */
6507
is64 = (insn & (1 << 25)) == 0;
6508
if (!is64 && ((insn & (1 << 4)) == 0)) {
6516
opc1 = (insn >> 4) & 0xf;
6518
rt2 = (insn >> 16) & 0xf;
6520
crn = (insn >> 16) & 0xf;
6521
opc1 = (insn >> 21) & 7;
6522
opc2 = (insn >> 5) & 7;
6525
isread = (insn >> 20) & 1;
6526
rt = (insn >> 12) & 0xf;
6528
ri = get_arm_cp_reginfo(s->cp_regs,
6529
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6531
/* Check access permissions */
6532
if (!cp_access_ok(s->current_pl, ri, isread)) {
6536
/* Handle special cases first */
6537
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6544
gen_set_pc_im(s, s->pc);
6545
s->is_jmp = DISAS_WFI;
6551
if (use_icount && (ri->type & ARM_CP_IO)) {
6560
if (ri->type & ARM_CP_CONST) {
6561
tmp64 = tcg_const_i64(ri->resetvalue);
6562
} else if (ri->readfn) {
6564
gen_set_pc_im(s, s->pc);
6565
tmp64 = tcg_temp_new_i64();
6566
tmpptr = tcg_const_ptr(ri);
6567
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6568
tcg_temp_free_ptr(tmpptr);
6570
tmp64 = tcg_temp_new_i64();
6571
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6573
tmp = tcg_temp_new_i32();
6574
tcg_gen_trunc_i64_i32(tmp, tmp64);
6575
store_reg(s, rt, tmp);
6576
tcg_gen_shri_i64(tmp64, tmp64, 32);
6577
tmp = tcg_temp_new_i32();
6578
tcg_gen_trunc_i64_i32(tmp, tmp64);
6579
tcg_temp_free_i64(tmp64);
6580
store_reg(s, rt2, tmp);
6583
if (ri->type & ARM_CP_CONST) {
6584
tmp = tcg_const_i32(ri->resetvalue);
6585
} else if (ri->readfn) {
6587
gen_set_pc_im(s, s->pc);
6588
tmp = tcg_temp_new_i32();
6589
tmpptr = tcg_const_ptr(ri);
6590
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6591
tcg_temp_free_ptr(tmpptr);
6593
tmp = load_cpu_offset(ri->fieldoffset);
6596
/* Destination register of r15 for 32 bit loads sets
6597
* the condition codes from the high 4 bits of the value
6600
tcg_temp_free_i32(tmp);
6602
store_reg(s, rt, tmp);
6607
if (ri->type & ARM_CP_CONST) {
6608
/* If not forbidden by access permissions, treat as WI */
6613
TCGv_i32 tmplo, tmphi;
6614
TCGv_i64 tmp64 = tcg_temp_new_i64();
6615
tmplo = load_reg(s, rt);
6616
tmphi = load_reg(s, rt2);
6617
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6618
tcg_temp_free_i32(tmplo);
6619
tcg_temp_free_i32(tmphi);
6621
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6622
gen_set_pc_im(s, s->pc);
6623
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6624
tcg_temp_free_ptr(tmpptr);
6626
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6628
tcg_temp_free_i64(tmp64);
6633
gen_set_pc_im(s, s->pc);
6634
tmp = load_reg(s, rt);
6635
tmpptr = tcg_const_ptr(ri);
6636
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6637
tcg_temp_free_ptr(tmpptr);
6638
tcg_temp_free_i32(tmp);
6640
TCGv_i32 tmp = load_reg(s, rt);
6641
store_cpu_offset(tmp, ri->fieldoffset);
6646
if (use_icount && (ri->type & ARM_CP_IO)) {
6647
/* I/O operations must end the TB here (whether read or write) */
6650
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6651
/* We default to ending the TB on a coprocessor register write,
6652
* but allow this to be suppressed by the register definition
6653
* (usually only necessary to work around guest bugs).
6665
/* Store a 64-bit value to a register pair. Clobbers val. */
6666
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6669
tmp = tcg_temp_new_i32();
6670
tcg_gen_trunc_i64_i32(tmp, val);
6671
store_reg(s, rlow, tmp);
6672
tmp = tcg_temp_new_i32();
6673
tcg_gen_shri_i64(val, val, 32);
6674
tcg_gen_trunc_i64_i32(tmp, val);
6675
store_reg(s, rhigh, tmp);
6678
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6679
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6684
/* Load value and extend to 64 bits. */
6685
tmp = tcg_temp_new_i64();
6686
tmp2 = load_reg(s, rlow);
6687
tcg_gen_extu_i32_i64(tmp, tmp2);
6688
tcg_temp_free_i32(tmp2);
6689
tcg_gen_add_i64(val, val, tmp);
6690
tcg_temp_free_i64(tmp);
6693
/* load and add a 64-bit value from a register pair. */
6694
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6700
/* Load 64-bit value rd:rn. */
6701
tmpl = load_reg(s, rlow);
6702
tmph = load_reg(s, rhigh);
6703
tmp = tcg_temp_new_i64();
6704
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6705
tcg_temp_free_i32(tmpl);
6706
tcg_temp_free_i32(tmph);
6707
tcg_gen_add_i64(val, val, tmp);
6708
tcg_temp_free_i64(tmp);
6711
/* Set N and Z flags from hi|lo. */
6712
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6714
tcg_gen_mov_i32(cpu_NF, hi);
6715
tcg_gen_or_i32(cpu_ZF, lo, hi);
6718
/* Load/Store exclusive instructions are implemented by remembering
6719
the value/address loaded, and seeing if these are the same
6720
when the store is performed. This should be sufficient to implement
6721
the architecturally mandated semantics, and avoids having to monitor
6724
In system emulation mode only one CPU will be running at once, so
6725
this sequence is effectively atomic. In user emulation mode we
6726
throw an exception and handle the atomic operation elsewhere. */
6727
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6728
TCGv_i32 addr, int size)
6730
TCGv_i32 tmp = tcg_temp_new_i32();
6734
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6737
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6741
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6748
TCGv_i32 tmp2 = tcg_temp_new_i32();
6749
TCGv_i32 tmp3 = tcg_temp_new_i32();
6751
tcg_gen_addi_i32(tmp2, addr, 4);
6752
gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6753
tcg_temp_free_i32(tmp2);
6754
tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
6755
store_reg(s, rt2, tmp3);
6757
tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
6760
store_reg(s, rt, tmp);
6761
tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
6764
static void gen_clrex(DisasContext *s)
6766
tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6769
#ifdef CONFIG_USER_ONLY
6770
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6771
TCGv_i32 addr, int size)
6773
tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
6774
tcg_gen_movi_i32(cpu_exclusive_info,
6775
size | (rd << 4) | (rt << 8) | (rt2 << 12));
6776
gen_exception_insn(s, 4, EXCP_STREX);
6779
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6780
TCGv_i32 addr, int size)
6783
TCGv_i64 val64, extaddr;
6787
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6793
fail_label = gen_new_label();
6794
done_label = gen_new_label();
6795
extaddr = tcg_temp_new_i64();
6796
tcg_gen_extu_i32_i64(extaddr, addr);
6797
tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
6798
tcg_temp_free_i64(extaddr);
6800
tmp = tcg_temp_new_i32();
6803
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6806
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6810
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6816
val64 = tcg_temp_new_i64();
6818
TCGv_i32 tmp2 = tcg_temp_new_i32();
6819
TCGv_i32 tmp3 = tcg_temp_new_i32();
6820
tcg_gen_addi_i32(tmp2, addr, 4);
6821
gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
6822
tcg_temp_free_i32(tmp2);
6823
tcg_gen_concat_i32_i64(val64, tmp, tmp3);
6824
tcg_temp_free_i32(tmp3);
6826
tcg_gen_extu_i32_i64(val64, tmp);
6828
tcg_temp_free_i32(tmp);
6830
tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
6831
tcg_temp_free_i64(val64);
6833
tmp = load_reg(s, rt);
6836
gen_aa32_st8(tmp, addr, IS_USER(s));
6839
gen_aa32_st16(tmp, addr, IS_USER(s));
6843
gen_aa32_st32(tmp, addr, IS_USER(s));
6848
tcg_temp_free_i32(tmp);
6850
tcg_gen_addi_i32(addr, addr, 4);
6851
tmp = load_reg(s, rt2);
6852
gen_aa32_st32(tmp, addr, IS_USER(s));
6853
tcg_temp_free_i32(tmp);
6855
tcg_gen_movi_i32(cpu_R[rd], 0);
6856
tcg_gen_br(done_label);
6857
gen_set_label(fail_label);
6858
tcg_gen_movi_i32(cpu_R[rd], 1);
6859
gen_set_label(done_label);
6860
tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6867
* @mode: mode field from insn (which stack to store to)
6868
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6869
* @writeback: true if writeback bit set
6871
* Generate code for the SRS (Store Return State) insn.
6873
static void gen_srs(DisasContext *s,
6874
uint32_t mode, uint32_t amode, bool writeback)
6877
TCGv_i32 addr = tcg_temp_new_i32();
6878
TCGv_i32 tmp = tcg_const_i32(mode);
6879
gen_helper_get_r13_banked(addr, cpu_env, tmp);
6880
tcg_temp_free_i32(tmp);
6897
tcg_gen_addi_i32(addr, addr, offset);
6898
tmp = load_reg(s, 14);
6899
gen_aa32_st32(tmp, addr, 0);
6900
tcg_temp_free_i32(tmp);
6901
tmp = load_cpu_field(spsr);
6902
tcg_gen_addi_i32(addr, addr, 4);
6903
gen_aa32_st32(tmp, addr, 0);
6904
tcg_temp_free_i32(tmp);
6922
tcg_gen_addi_i32(addr, addr, offset);
6923
tmp = tcg_const_i32(mode);
6924
gen_helper_set_r13_banked(cpu_env, tmp, addr);
6925
tcg_temp_free_i32(tmp);
6927
tcg_temp_free_i32(addr);
6930
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6932
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6939
insn = arm_ldl_code(env, s->pc, s->bswap_code);
6942
/* M variants do not implement ARM mode. */
6947
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6948
* choose to UNDEF. In ARMv5 and above the space is used
6949
* for miscellaneous unconditional instructions.
6953
/* Unconditional instructions. */
6954
if (((insn >> 25) & 7) == 1) {
6955
/* NEON Data processing. */
6956
if (!arm_feature(env, ARM_FEATURE_NEON))
6959
if (disas_neon_data_insn(env, s, insn))
6963
if ((insn & 0x0f100000) == 0x04000000) {
6964
/* NEON load/store. */
6965
if (!arm_feature(env, ARM_FEATURE_NEON))
6968
if (disas_neon_ls_insn(env, s, insn))
6972
if ((insn & 0x0f000e10) == 0x0e000a00) {
6974
if (disas_vfp_insn(env, s, insn)) {
6979
if (((insn & 0x0f30f000) == 0x0510f000) ||
6980
((insn & 0x0f30f010) == 0x0710f000)) {
6981
if ((insn & (1 << 22)) == 0) {
6983
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6987
/* Otherwise PLD; v5TE+ */
6991
if (((insn & 0x0f70f000) == 0x0450f000) ||
6992
((insn & 0x0f70f010) == 0x0650f000)) {
6994
return; /* PLI; V7 */
6996
if (((insn & 0x0f700000) == 0x04100000) ||
6997
((insn & 0x0f700010) == 0x06100000)) {
6998
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7001
return; /* v7MP: Unallocated memory hint: must NOP */
7004
if ((insn & 0x0ffffdff) == 0x01010000) {
7007
if (((insn >> 9) & 1) != s->bswap_code) {
7008
/* Dynamic endianness switching not implemented. */
7009
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7013
} else if ((insn & 0x0fffff00) == 0x057ff000) {
7014
switch ((insn >> 4) & 0xf) {
7023
/* We don't emulate caches so these are a no-op. */
7028
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7034
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7036
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7042
rn = (insn >> 16) & 0xf;
7043
addr = load_reg(s, rn);
7044
i = (insn >> 23) & 3;
7046
case 0: offset = -4; break; /* DA */
7047
case 1: offset = 0; break; /* IA */
7048
case 2: offset = -8; break; /* DB */
7049
case 3: offset = 4; break; /* IB */
7053
tcg_gen_addi_i32(addr, addr, offset);
7054
/* Load PC into tmp and CPSR into tmp2. */
7055
tmp = tcg_temp_new_i32();
7056
gen_aa32_ld32u(tmp, addr, 0);
7057
tcg_gen_addi_i32(addr, addr, 4);
7058
tmp2 = tcg_temp_new_i32();
7059
gen_aa32_ld32u(tmp2, addr, 0);
7060
if (insn & (1 << 21)) {
7061
/* Base writeback. */
7063
case 0: offset = -8; break;
7064
case 1: offset = 4; break;
7065
case 2: offset = -4; break;
7066
case 3: offset = 0; break;
7070
tcg_gen_addi_i32(addr, addr, offset);
7071
store_reg(s, rn, addr);
7073
tcg_temp_free_i32(addr);
7075
gen_rfe(s, tmp, tmp2);
7077
} else if ((insn & 0x0e000000) == 0x0a000000) {
7078
/* branch link and change to thumb (blx <offset>) */
7081
val = (uint32_t)s->pc;
7082
tmp = tcg_temp_new_i32();
7083
tcg_gen_movi_i32(tmp, val);
7084
store_reg(s, 14, tmp);
7085
/* Sign-extend the 24-bit offset */
7086
offset = (((int32_t)insn) << 8) >> 8;
7087
/* offset * 4 + bit24 * 2 + (thumb bit) */
7088
val += (offset << 2) | ((insn >> 23) & 2) | 1;
7089
/* pipeline offset */
7091
/* protected by ARCH(5); above, near the start of uncond block */
7094
} else if ((insn & 0x0e000f00) == 0x0c000100) {
7095
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7096
/* iWMMXt register transfer. */
7097
if (env->cp15.c15_cpar & (1 << 1))
7098
if (!disas_iwmmxt_insn(env, s, insn))
7101
} else if ((insn & 0x0fe00000) == 0x0c400000) {
7102
/* Coprocessor double register transfer. */
7104
/* XXX doesn't belong in the trustzone patch: should just UNDEF? */
7105
cpu_abort(env, "unsupported coprocessor double register transfer\n");
7106
} else if ((insn & 0x0f000010) == 0x0e000010) {
7107
/* Additional coprocessor register transfer. */
7108
if (!disas_coproc_insn(env, s, insn)) {
7111
} else if ((insn & 0x0ff10020) == 0x01000000) {
7114
/* cps (privileged) */
7118
if (insn & (1 << 19)) {
7119
if (insn & (1 << 8))
7121
if (insn & (1 << 7))
7123
if (insn & (1 << 6))
7125
if (insn & (1 << 18))
7128
if (insn & (1 << 17)) {
7130
val |= (insn & 0x1f);
7133
gen_set_psr_im(s, mask, 0, val);
7140
/* if not always execute, we generate a conditional jump to
7142
s->condlabel = gen_new_label();
7143
arm_gen_test_cc(cond ^ 1, s->condlabel);
7146
if ((insn & 0x0f900000) == 0x03000000) {
7147
if ((insn & (1 << 21)) == 0) {
7149
rd = (insn >> 12) & 0xf;
7150
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7151
if ((insn & (1 << 22)) == 0) {
7153
tmp = tcg_temp_new_i32();
7154
tcg_gen_movi_i32(tmp, val);
7157
tmp = load_reg(s, rd);
7158
tcg_gen_ext16u_i32(tmp, tmp);
7159
tcg_gen_ori_i32(tmp, tmp, val << 16);
7161
store_reg(s, rd, tmp);
7163
if (((insn >> 12) & 0xf) != 0xf)
7165
if (((insn >> 16) & 0xf) == 0) {
7166
gen_nop_hint(s, insn & 0xff);
7168
/* CPSR = immediate */
7170
shift = ((insn >> 8) & 0xf) * 2;
7172
val = (val >> shift) | (val << (32 - shift));
7173
i = ((insn & (1 << 22)) != 0);
7174
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7178
} else if ((insn & 0x0f900000) == 0x01000000
7179
&& (insn & 0x00000090) != 0x00000090) {
7180
/* miscellaneous instructions */
7181
op1 = (insn >> 21) & 3;
7182
sh = (insn >> 4) & 0xf;
7185
case 0x0: /* move program status register */
7188
tmp = load_reg(s, rm);
7189
i = ((op1 & 2) != 0);
7190
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7194
rd = (insn >> 12) & 0xf;
7198
tmp = load_cpu_field(spsr);
7200
tmp = tcg_temp_new_i32();
7201
gen_helper_cpsr_read(tmp, cpu_env);
7203
store_reg(s, rd, tmp);
7208
/* branch/exchange thumb (bx). */
7210
tmp = load_reg(s, rm);
7212
} else if (op1 == 3) {
7215
rd = (insn >> 12) & 0xf;
7216
tmp = load_reg(s, rm);
7217
gen_helper_clz(tmp, tmp);
7218
store_reg(s, rd, tmp);
7226
/* Trivial implementation equivalent to bx. */
7227
tmp = load_reg(s, rm);
7238
/* branch link/exchange thumb (blx) */
7239
tmp = load_reg(s, rm);
7240
tmp2 = tcg_temp_new_i32();
7241
tcg_gen_movi_i32(tmp2, s->pc);
7242
store_reg(s, 14, tmp2);
7245
case 0x5: /* saturating add/subtract */
7247
rd = (insn >> 12) & 0xf;
7248
rn = (insn >> 16) & 0xf;
7249
tmp = load_reg(s, rm);
7250
tmp2 = load_reg(s, rn);
7252
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7254
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7256
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7257
tcg_temp_free_i32(tmp2);
7258
store_reg(s, rd, tmp);
7264
gen_exception_insn(s, 4, EXCP_BKPT);
7265
} else if (op1 == 3) {
7267
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
7275
case 0x8: /* signed multiply */
7280
rs = (insn >> 8) & 0xf;
7281
rn = (insn >> 12) & 0xf;
7282
rd = (insn >> 16) & 0xf;
7284
/* (32 * 16) >> 16 */
7285
tmp = load_reg(s, rm);
7286
tmp2 = load_reg(s, rs);
7288
tcg_gen_sari_i32(tmp2, tmp2, 16);
7291
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7292
tcg_gen_shri_i64(tmp64, tmp64, 16);
7293
tmp = tcg_temp_new_i32();
7294
tcg_gen_trunc_i64_i32(tmp, tmp64);
7295
tcg_temp_free_i64(tmp64);
7296
if ((sh & 2) == 0) {
7297
tmp2 = load_reg(s, rn);
7298
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7299
tcg_temp_free_i32(tmp2);
7301
store_reg(s, rd, tmp);
7304
tmp = load_reg(s, rm);
7305
tmp2 = load_reg(s, rs);
7306
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7307
tcg_temp_free_i32(tmp2);
7309
tmp64 = tcg_temp_new_i64();
7310
tcg_gen_ext_i32_i64(tmp64, tmp);
7311
tcg_temp_free_i32(tmp);
7312
gen_addq(s, tmp64, rn, rd);
7313
gen_storeq_reg(s, rn, rd, tmp64);
7314
tcg_temp_free_i64(tmp64);
7317
tmp2 = load_reg(s, rn);
7318
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7319
tcg_temp_free_i32(tmp2);
7321
store_reg(s, rd, tmp);
7328
} else if (((insn & 0x0e000000) == 0 &&
7329
(insn & 0x00000090) != 0x90) ||
7330
((insn & 0x0e000000) == (1 << 25))) {
7331
int set_cc, logic_cc, shiftop;
7333
op1 = (insn >> 21) & 0xf;
7334
set_cc = (insn >> 20) & 1;
7335
logic_cc = table_logic_cc[op1] & set_cc;
7337
/* data processing instruction */
7338
if (insn & (1 << 25)) {
7339
/* immediate operand */
7341
shift = ((insn >> 8) & 0xf) * 2;
7343
val = (val >> shift) | (val << (32 - shift));
7345
tmp2 = tcg_temp_new_i32();
7346
tcg_gen_movi_i32(tmp2, val);
7347
if (logic_cc && shift) {
7348
gen_set_CF_bit31(tmp2);
7353
tmp2 = load_reg(s, rm);
7354
shiftop = (insn >> 5) & 3;
7355
if (!(insn & (1 << 4))) {
7356
shift = (insn >> 7) & 0x1f;
7357
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7359
rs = (insn >> 8) & 0xf;
7360
tmp = load_reg(s, rs);
7361
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7364
if (op1 != 0x0f && op1 != 0x0d) {
7365
rn = (insn >> 16) & 0xf;
7366
tmp = load_reg(s, rn);
7368
TCGV_UNUSED_I32(tmp);
7370
rd = (insn >> 12) & 0xf;
7373
tcg_gen_and_i32(tmp, tmp, tmp2);
7377
store_reg_bx(env, s, rd, tmp);
7380
tcg_gen_xor_i32(tmp, tmp, tmp2);
7384
store_reg_bx(env, s, rd, tmp);
7387
if (set_cc && rd == 15) {
7388
/* SUBS r15, ... is used for exception return. */
7392
gen_sub_CC(tmp, tmp, tmp2);
7393
gen_exception_return(s, tmp);
7396
gen_sub_CC(tmp, tmp, tmp2);
7398
tcg_gen_sub_i32(tmp, tmp, tmp2);
7400
store_reg_bx(env, s, rd, tmp);
7405
gen_sub_CC(tmp, tmp2, tmp);
7407
tcg_gen_sub_i32(tmp, tmp2, tmp);
7409
store_reg_bx(env, s, rd, tmp);
7413
gen_add_CC(tmp, tmp, tmp2);
7415
tcg_gen_add_i32(tmp, tmp, tmp2);
7417
store_reg_bx(env, s, rd, tmp);
7421
gen_adc_CC(tmp, tmp, tmp2);
7423
gen_add_carry(tmp, tmp, tmp2);
7425
store_reg_bx(env, s, rd, tmp);
7429
gen_sbc_CC(tmp, tmp, tmp2);
7431
gen_sub_carry(tmp, tmp, tmp2);
7433
store_reg_bx(env, s, rd, tmp);
7437
gen_sbc_CC(tmp, tmp2, tmp);
7439
gen_sub_carry(tmp, tmp2, tmp);
7441
store_reg_bx(env, s, rd, tmp);
7445
tcg_gen_and_i32(tmp, tmp, tmp2);
7448
tcg_temp_free_i32(tmp);
7452
tcg_gen_xor_i32(tmp, tmp, tmp2);
7455
tcg_temp_free_i32(tmp);
7459
gen_sub_CC(tmp, tmp, tmp2);
7461
tcg_temp_free_i32(tmp);
7465
gen_add_CC(tmp, tmp, tmp2);
7467
tcg_temp_free_i32(tmp);
7470
tcg_gen_or_i32(tmp, tmp, tmp2);
7474
store_reg_bx(env, s, rd, tmp);
7477
if (logic_cc && rd == 15) {
7478
/* MOVS r15, ... is used for exception return. */
7482
gen_exception_return(s, tmp2);
7487
store_reg_bx(env, s, rd, tmp2);
7491
tcg_gen_andc_i32(tmp, tmp, tmp2);
7495
store_reg_bx(env, s, rd, tmp);
7499
tcg_gen_not_i32(tmp2, tmp2);
7503
store_reg_bx(env, s, rd, tmp2);
7506
if (op1 != 0x0f && op1 != 0x0d) {
7507
tcg_temp_free_i32(tmp2);
7510
/* other instructions */
7511
op1 = (insn >> 24) & 0xf;
7515
/* multiplies, extra load/stores */
7516
sh = (insn >> 5) & 3;
7519
rd = (insn >> 16) & 0xf;
7520
rn = (insn >> 12) & 0xf;
7521
rs = (insn >> 8) & 0xf;
7523
op1 = (insn >> 20) & 0xf;
7525
case 0: case 1: case 2: case 3: case 6:
7527
tmp = load_reg(s, rs);
7528
tmp2 = load_reg(s, rm);
7529
tcg_gen_mul_i32(tmp, tmp, tmp2);
7530
tcg_temp_free_i32(tmp2);
7531
if (insn & (1 << 22)) {
7532
/* Subtract (mls) */
7534
tmp2 = load_reg(s, rn);
7535
tcg_gen_sub_i32(tmp, tmp2, tmp);
7536
tcg_temp_free_i32(tmp2);
7537
} else if (insn & (1 << 21)) {
7539
tmp2 = load_reg(s, rn);
7540
tcg_gen_add_i32(tmp, tmp, tmp2);
7541
tcg_temp_free_i32(tmp2);
7543
if (insn & (1 << 20))
7545
store_reg(s, rd, tmp);
7548
/* 64 bit mul double accumulate (UMAAL) */
7550
tmp = load_reg(s, rs);
7551
tmp2 = load_reg(s, rm);
7552
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7553
gen_addq_lo(s, tmp64, rn);
7554
gen_addq_lo(s, tmp64, rd);
7555
gen_storeq_reg(s, rn, rd, tmp64);
7556
tcg_temp_free_i64(tmp64);
7558
case 8: case 9: case 10: case 11:
7559
case 12: case 13: case 14: case 15:
7560
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7561
tmp = load_reg(s, rs);
7562
tmp2 = load_reg(s, rm);
7563
if (insn & (1 << 22)) {
7564
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7566
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7568
if (insn & (1 << 21)) { /* mult accumulate */
7569
TCGv_i32 al = load_reg(s, rn);
7570
TCGv_i32 ah = load_reg(s, rd);
7571
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7572
tcg_temp_free_i32(al);
7573
tcg_temp_free_i32(ah);
7575
if (insn & (1 << 20)) {
7576
gen_logicq_cc(tmp, tmp2);
7578
store_reg(s, rn, tmp);
7579
store_reg(s, rd, tmp2);
7585
rn = (insn >> 16) & 0xf;
7586
rd = (insn >> 12) & 0xf;
7587
if (insn & (1 << 23)) {
7588
/* load/store exclusive */
7589
int op2 = (insn >> 8) & 3;
7590
op1 = (insn >> 21) & 0x3;
7593
case 0: /* lda/stl */
7599
case 1: /* reserved */
7601
case 2: /* ldaex/stlex */
7604
case 3: /* ldrex/strex */
7613
addr = tcg_temp_local_new_i32();
7614
load_reg_var(s, addr, rn);
7616
/* Since the emulation does not have barriers,
7617
the acquire/release semantics need no special
7620
if (insn & (1 << 20)) {
7621
tmp = tcg_temp_new_i32();
7624
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7627
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7630
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7635
store_reg(s, rd, tmp);
7638
tmp = load_reg(s, rm);
7641
gen_aa32_st32(tmp, addr, IS_USER(s));
7644
gen_aa32_st8(tmp, addr, IS_USER(s));
7647
gen_aa32_st16(tmp, addr, IS_USER(s));
7652
tcg_temp_free_i32(tmp);
7654
} else if (insn & (1 << 20)) {
7657
gen_load_exclusive(s, rd, 15, addr, 2);
7659
case 1: /* ldrexd */
7660
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7662
case 2: /* ldrexb */
7663
gen_load_exclusive(s, rd, 15, addr, 0);
7665
case 3: /* ldrexh */
7666
gen_load_exclusive(s, rd, 15, addr, 1);
7675
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7677
case 1: /* strexd */
7678
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7680
case 2: /* strexb */
7681
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7683
case 3: /* strexh */
7684
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7690
tcg_temp_free_i32(addr);
7692
/* SWP instruction */
7695
/* ??? This is not really atomic. However we know
7696
we never have multiple CPUs running in parallel,
7697
so it is good enough. */
7698
addr = load_reg(s, rn);
7699
tmp = load_reg(s, rm);
7700
tmp2 = tcg_temp_new_i32();
7701
if (insn & (1 << 22)) {
7702
gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7703
gen_aa32_st8(tmp, addr, IS_USER(s));
7705
gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7706
gen_aa32_st32(tmp, addr, IS_USER(s));
7708
tcg_temp_free_i32(tmp);
7709
tcg_temp_free_i32(addr);
7710
store_reg(s, rd, tmp2);
7716
/* Misc load/store */
7717
rn = (insn >> 16) & 0xf;
7718
rd = (insn >> 12) & 0xf;
7719
addr = load_reg(s, rn);
7720
if (insn & (1 << 24))
7721
gen_add_datah_offset(s, insn, 0, addr);
7723
if (insn & (1 << 20)) {
7725
tmp = tcg_temp_new_i32();
7728
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7731
gen_aa32_ld8s(tmp, addr, IS_USER(s));
7735
gen_aa32_ld16s(tmp, addr, IS_USER(s));
7739
} else if (sh & 2) {
7744
tmp = load_reg(s, rd);
7745
gen_aa32_st32(tmp, addr, IS_USER(s));
7746
tcg_temp_free_i32(tmp);
7747
tcg_gen_addi_i32(addr, addr, 4);
7748
tmp = load_reg(s, rd + 1);
7749
gen_aa32_st32(tmp, addr, IS_USER(s));
7750
tcg_temp_free_i32(tmp);
7754
tmp = tcg_temp_new_i32();
7755
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7756
store_reg(s, rd, tmp);
7757
tcg_gen_addi_i32(addr, addr, 4);
7758
tmp = tcg_temp_new_i32();
7759
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7763
address_offset = -4;
7766
tmp = load_reg(s, rd);
7767
gen_aa32_st16(tmp, addr, IS_USER(s));
7768
tcg_temp_free_i32(tmp);
7771
/* Perform base writeback before the loaded value to
7772
ensure correct behavior with overlapping index registers.
7773
ldrd with base writeback is is undefined if the
7774
destination and index registers overlap. */
7775
if (!(insn & (1 << 24))) {
7776
gen_add_datah_offset(s, insn, address_offset, addr);
7777
store_reg(s, rn, addr);
7778
} else if (insn & (1 << 21)) {
7780
tcg_gen_addi_i32(addr, addr, address_offset);
7781
store_reg(s, rn, addr);
7783
tcg_temp_free_i32(addr);
7786
/* Complete the load. */
7787
store_reg(s, rd, tmp);
7796
if (insn & (1 << 4)) {
7798
/* Armv6 Media instructions. */
7800
rn = (insn >> 16) & 0xf;
7801
rd = (insn >> 12) & 0xf;
7802
rs = (insn >> 8) & 0xf;
7803
switch ((insn >> 23) & 3) {
7804
case 0: /* Parallel add/subtract. */
7805
op1 = (insn >> 20) & 7;
7806
tmp = load_reg(s, rn);
7807
tmp2 = load_reg(s, rm);
7808
sh = (insn >> 5) & 7;
7809
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7811
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7812
tcg_temp_free_i32(tmp2);
7813
store_reg(s, rd, tmp);
7816
if ((insn & 0x00700020) == 0) {
7817
/* Halfword pack. */
7818
tmp = load_reg(s, rn);
7819
tmp2 = load_reg(s, rm);
7820
shift = (insn >> 7) & 0x1f;
7821
if (insn & (1 << 6)) {
7825
tcg_gen_sari_i32(tmp2, tmp2, shift);
7826
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7827
tcg_gen_ext16u_i32(tmp2, tmp2);
7831
tcg_gen_shli_i32(tmp2, tmp2, shift);
7832
tcg_gen_ext16u_i32(tmp, tmp);
7833
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7835
tcg_gen_or_i32(tmp, tmp, tmp2);
7836
tcg_temp_free_i32(tmp2);
7837
store_reg(s, rd, tmp);
7838
} else if ((insn & 0x00200020) == 0x00200000) {
7840
tmp = load_reg(s, rm);
7841
shift = (insn >> 7) & 0x1f;
7842
if (insn & (1 << 6)) {
7845
tcg_gen_sari_i32(tmp, tmp, shift);
7847
tcg_gen_shli_i32(tmp, tmp, shift);
7849
sh = (insn >> 16) & 0x1f;
7850
tmp2 = tcg_const_i32(sh);
7851
if (insn & (1 << 22))
7852
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7854
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7855
tcg_temp_free_i32(tmp2);
7856
store_reg(s, rd, tmp);
7857
} else if ((insn & 0x00300fe0) == 0x00200f20) {
7859
tmp = load_reg(s, rm);
7860
sh = (insn >> 16) & 0x1f;
7861
tmp2 = tcg_const_i32(sh);
7862
if (insn & (1 << 22))
7863
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7865
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7866
tcg_temp_free_i32(tmp2);
7867
store_reg(s, rd, tmp);
7868
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
7870
tmp = load_reg(s, rn);
7871
tmp2 = load_reg(s, rm);
7872
tmp3 = tcg_temp_new_i32();
7873
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7874
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7875
tcg_temp_free_i32(tmp3);
7876
tcg_temp_free_i32(tmp2);
7877
store_reg(s, rd, tmp);
7878
} else if ((insn & 0x000003e0) == 0x00000060) {
7879
tmp = load_reg(s, rm);
7880
shift = (insn >> 10) & 3;
7881
/* ??? In many cases it's not necessary to do a
7882
rotate, a shift is sufficient. */
7884
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7885
op1 = (insn >> 20) & 7;
7887
case 0: gen_sxtb16(tmp); break;
7888
case 2: gen_sxtb(tmp); break;
7889
case 3: gen_sxth(tmp); break;
7890
case 4: gen_uxtb16(tmp); break;
7891
case 6: gen_uxtb(tmp); break;
7892
case 7: gen_uxth(tmp); break;
7893
default: goto illegal_op;
7896
tmp2 = load_reg(s, rn);
7897
if ((op1 & 3) == 0) {
7898
gen_add16(tmp, tmp2);
7900
tcg_gen_add_i32(tmp, tmp, tmp2);
7901
tcg_temp_free_i32(tmp2);
7904
store_reg(s, rd, tmp);
7905
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
7907
tmp = load_reg(s, rm);
7908
if (insn & (1 << 22)) {
7909
if (insn & (1 << 7)) {
7913
gen_helper_rbit(tmp, tmp);
7916
if (insn & (1 << 7))
7919
tcg_gen_bswap32_i32(tmp, tmp);
7921
store_reg(s, rd, tmp);
7926
case 2: /* Multiplies (Type 3). */
7927
switch ((insn >> 20) & 0x7) {
7929
if (((insn >> 6) ^ (insn >> 7)) & 1) {
7930
/* op2 not 00x or 11x : UNDEF */
7933
/* Signed multiply most significant [accumulate].
7934
(SMMUL, SMMLA, SMMLS) */
7935
tmp = load_reg(s, rm);
7936
tmp2 = load_reg(s, rs);
7937
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7940
tmp = load_reg(s, rd);
7941
if (insn & (1 << 6)) {
7942
tmp64 = gen_subq_msw(tmp64, tmp);
7944
tmp64 = gen_addq_msw(tmp64, tmp);
7947
if (insn & (1 << 5)) {
7948
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7950
tcg_gen_shri_i64(tmp64, tmp64, 32);
7951
tmp = tcg_temp_new_i32();
7952
tcg_gen_trunc_i64_i32(tmp, tmp64);
7953
tcg_temp_free_i64(tmp64);
7954
store_reg(s, rn, tmp);
7958
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7959
if (insn & (1 << 7)) {
7962
tmp = load_reg(s, rm);
7963
tmp2 = load_reg(s, rs);
7964
if (insn & (1 << 5))
7965
gen_swap_half(tmp2);
7966
gen_smul_dual(tmp, tmp2);
7967
if (insn & (1 << 6)) {
7968
/* This subtraction cannot overflow. */
7969
tcg_gen_sub_i32(tmp, tmp, tmp2);
7971
/* This addition cannot overflow 32 bits;
7972
* however it may overflow considered as a signed
7973
* operation, in which case we must set the Q flag.
7975
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7977
tcg_temp_free_i32(tmp2);
7978
if (insn & (1 << 22)) {
7979
/* smlald, smlsld */
7980
tmp64 = tcg_temp_new_i64();
7981
tcg_gen_ext_i32_i64(tmp64, tmp);
7982
tcg_temp_free_i32(tmp);
7983
gen_addq(s, tmp64, rd, rn);
7984
gen_storeq_reg(s, rd, rn, tmp64);
7985
tcg_temp_free_i64(tmp64);
7987
/* smuad, smusd, smlad, smlsd */
7990
tmp2 = load_reg(s, rd);
7991
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7992
tcg_temp_free_i32(tmp2);
7994
store_reg(s, rn, tmp);
8000
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8003
if (((insn >> 5) & 7) || (rd != 15)) {
8006
tmp = load_reg(s, rm);
8007
tmp2 = load_reg(s, rs);
8008
if (insn & (1 << 21)) {
8009
gen_helper_udiv(tmp, tmp, tmp2);
8011
gen_helper_sdiv(tmp, tmp, tmp2);
8013
tcg_temp_free_i32(tmp2);
8014
store_reg(s, rn, tmp);
8021
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8023
case 0: /* Unsigned sum of absolute differences. */
8025
tmp = load_reg(s, rm);
8026
tmp2 = load_reg(s, rs);
8027
gen_helper_usad8(tmp, tmp, tmp2);
8028
tcg_temp_free_i32(tmp2);
8030
tmp2 = load_reg(s, rd);
8031
tcg_gen_add_i32(tmp, tmp, tmp2);
8032
tcg_temp_free_i32(tmp2);
8034
store_reg(s, rn, tmp);
8036
case 0x20: case 0x24: case 0x28: case 0x2c:
8037
/* Bitfield insert/clear. */
8039
shift = (insn >> 7) & 0x1f;
8040
i = (insn >> 16) & 0x1f;
8043
tmp = tcg_temp_new_i32();
8044
tcg_gen_movi_i32(tmp, 0);
8046
tmp = load_reg(s, rm);
8049
tmp2 = load_reg(s, rd);
8050
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8051
tcg_temp_free_i32(tmp2);
8053
store_reg(s, rd, tmp);
8055
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8056
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8058
tmp = load_reg(s, rm);
8059
shift = (insn >> 7) & 0x1f;
8060
i = ((insn >> 16) & 0x1f) + 1;
8065
gen_ubfx(tmp, shift, (1u << i) - 1);
8067
gen_sbfx(tmp, shift, i);
8070
store_reg(s, rd, tmp);
8080
/* Check for undefined extension instructions
8081
* per the ARM Bible IE:
8082
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8084
sh = (0xf << 20) | (0xf << 4);
8085
if (op1 == 0x7 && ((insn & sh) == sh))
8089
/* load/store byte/word */
8090
rn = (insn >> 16) & 0xf;
8091
rd = (insn >> 12) & 0xf;
8092
tmp2 = load_reg(s, rn);
8093
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8094
if (insn & (1 << 24))
8095
gen_add_data_offset(s, insn, tmp2);
8096
if (insn & (1 << 20)) {
8098
tmp = tcg_temp_new_i32();
8099
if (insn & (1 << 22)) {
8100
gen_aa32_ld8u(tmp, tmp2, i);
8102
gen_aa32_ld32u(tmp, tmp2, i);
8106
tmp = load_reg(s, rd);
8107
if (insn & (1 << 22)) {
8108
gen_aa32_st8(tmp, tmp2, i);
8110
gen_aa32_st32(tmp, tmp2, i);
8112
tcg_temp_free_i32(tmp);
8114
if (!(insn & (1 << 24))) {
8115
gen_add_data_offset(s, insn, tmp2);
8116
store_reg(s, rn, tmp2);
8117
} else if (insn & (1 << 21)) {
8118
store_reg(s, rn, tmp2);
8120
tcg_temp_free_i32(tmp2);
8122
if (insn & (1 << 20)) {
8123
/* Complete the load. */
8124
store_reg_from_load(env, s, rd, tmp);
8130
int j, n, user, loaded_base;
8131
TCGv_i32 loaded_var;
8132
/* load/store multiple words */
8133
/* XXX: store correct base if write back */
8135
if (insn & (1 << 22)) {
8137
goto illegal_op; /* only usable in supervisor mode */
8139
if ((insn & (1 << 15)) == 0)
8142
rn = (insn >> 16) & 0xf;
8143
addr = load_reg(s, rn);
8145
/* compute total size */
8147
TCGV_UNUSED_I32(loaded_var);
8150
if (insn & (1 << i))
8153
/* XXX: test invalid n == 0 case ? */
8154
if (insn & (1 << 23)) {
8155
if (insn & (1 << 24)) {
8157
tcg_gen_addi_i32(addr, addr, 4);
8159
/* post increment */
8162
if (insn & (1 << 24)) {
8164
tcg_gen_addi_i32(addr, addr, -(n * 4));
8166
/* post decrement */
8168
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8173
if (insn & (1 << i)) {
8174
if (insn & (1 << 20)) {
8176
tmp = tcg_temp_new_i32();
8177
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8179
tmp2 = tcg_const_i32(i);
8180
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8181
tcg_temp_free_i32(tmp2);
8182
tcg_temp_free_i32(tmp);
8183
} else if (i == rn) {
8187
store_reg_from_load(env, s, i, tmp);
8192
/* special case: r15 = PC + 8 */
8193
val = (long)s->pc + 4;
8194
tmp = tcg_temp_new_i32();
8195
tcg_gen_movi_i32(tmp, val);
8197
tmp = tcg_temp_new_i32();
8198
tmp2 = tcg_const_i32(i);
8199
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8200
tcg_temp_free_i32(tmp2);
8202
tmp = load_reg(s, i);
8204
gen_aa32_st32(tmp, addr, IS_USER(s));
8205
tcg_temp_free_i32(tmp);
8208
/* no need to add after the last transfer */
8210
tcg_gen_addi_i32(addr, addr, 4);
8213
if (insn & (1 << 21)) {
8215
if (insn & (1 << 23)) {
8216
if (insn & (1 << 24)) {
8219
/* post increment */
8220
tcg_gen_addi_i32(addr, addr, 4);
8223
if (insn & (1 << 24)) {
8226
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8228
/* post decrement */
8229
tcg_gen_addi_i32(addr, addr, -(n * 4));
8232
store_reg(s, rn, addr);
8234
tcg_temp_free_i32(addr);
8237
store_reg(s, rn, loaded_var);
8239
if ((insn & (1 << 22)) && !user) {
8240
/* Restore CPSR from SPSR. */
8241
tmp = load_cpu_field(spsr);
8242
gen_set_cpsr(tmp, 0xffffffff);
8243
tcg_temp_free_i32(tmp);
8244
s->is_jmp = DISAS_UPDATE;
8253
/* branch (and link) */
8254
val = (int32_t)s->pc;
8255
if (insn & (1 << 24)) {
8256
tmp = tcg_temp_new_i32();
8257
tcg_gen_movi_i32(tmp, val);
8258
store_reg(s, 14, tmp);
8260
offset = sextract32(insn << 2, 0, 26);
8268
if (((insn >> 8) & 0xe) == 10) {
8270
if (disas_vfp_insn(env, s, insn)) {
8273
} else if (disas_coproc_insn(env, s, insn)) {
8280
gen_set_pc_im(s, s->pc);
8281
s->is_jmp = DISAS_SWI;
8285
gen_exception_insn(s, 4, EXCP_UDEF);
8291
/* Return true if this is a Thumb-2 logical op. */
8293
thumb2_logic_op(int op)
8298
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8299
then set condition code flags based on the result of the operation.
8300
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8301
to the high bit of T1.
8302
Returns zero if the opcode is valid. */
8305
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8306
TCGv_i32 t0, TCGv_i32 t1)
8313
tcg_gen_and_i32(t0, t0, t1);
8317
tcg_gen_andc_i32(t0, t0, t1);
8321
tcg_gen_or_i32(t0, t0, t1);
8325
tcg_gen_orc_i32(t0, t0, t1);
8329
tcg_gen_xor_i32(t0, t0, t1);
8334
gen_add_CC(t0, t0, t1);
8336
tcg_gen_add_i32(t0, t0, t1);
8340
gen_adc_CC(t0, t0, t1);
8346
gen_sbc_CC(t0, t0, t1);
8348
gen_sub_carry(t0, t0, t1);
8353
gen_sub_CC(t0, t0, t1);
8355
tcg_gen_sub_i32(t0, t0, t1);
8359
gen_sub_CC(t0, t1, t0);
8361
tcg_gen_sub_i32(t0, t1, t0);
8363
default: /* 5, 6, 7, 9, 12, 15. */
8369
gen_set_CF_bit31(t1);
8374
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8376
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8378
uint32_t insn, imm, shift, offset;
8379
uint32_t rd, rn, rm, rs;
8390
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8391
|| arm_feature (env, ARM_FEATURE_M))) {
8392
/* Thumb-1 cores may need to treat bl and blx as a pair of
8393
16-bit instructions to get correct prefetch abort behavior. */
8395
if ((insn & (1 << 12)) == 0) {
8397
/* Second half of blx. */
8398
offset = ((insn & 0x7ff) << 1);
8399
tmp = load_reg(s, 14);
8400
tcg_gen_addi_i32(tmp, tmp, offset);
8401
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8403
tmp2 = tcg_temp_new_i32();
8404
tcg_gen_movi_i32(tmp2, s->pc | 1);
8405
store_reg(s, 14, tmp2);
8409
if (insn & (1 << 11)) {
8410
/* Second half of bl. */
8411
offset = ((insn & 0x7ff) << 1) | 1;
8412
tmp = load_reg(s, 14);
8413
tcg_gen_addi_i32(tmp, tmp, offset);
8415
tmp2 = tcg_temp_new_i32();
8416
tcg_gen_movi_i32(tmp2, s->pc | 1);
8417
store_reg(s, 14, tmp2);
8421
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8422
/* Instruction spans a page boundary. Implement it as two
8423
16-bit instructions in case the second half causes an
8425
offset = ((int32_t)insn << 21) >> 9;
8426
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8429
/* Fall through to 32-bit decode. */
8432
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8434
insn |= (uint32_t)insn_hw1 << 16;
8436
if ((insn & 0xf800e800) != 0xf000e800) {
8440
rn = (insn >> 16) & 0xf;
8441
rs = (insn >> 12) & 0xf;
8442
rd = (insn >> 8) & 0xf;
8444
switch ((insn >> 25) & 0xf) {
8445
case 0: case 1: case 2: case 3:
8446
/* 16-bit instructions. Should never happen. */
8449
if (insn & (1 << 22)) {
8450
/* Other load/store, table branch. */
8451
if (insn & 0x01200000) {
8452
/* Load/store doubleword. */
8454
addr = tcg_temp_new_i32();
8455
tcg_gen_movi_i32(addr, s->pc & ~3);
8457
addr = load_reg(s, rn);
8459
offset = (insn & 0xff) * 4;
8460
if ((insn & (1 << 23)) == 0)
8462
if (insn & (1 << 24)) {
8463
tcg_gen_addi_i32(addr, addr, offset);
8466
if (insn & (1 << 20)) {
8468
tmp = tcg_temp_new_i32();
8469
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8470
store_reg(s, rs, tmp);
8471
tcg_gen_addi_i32(addr, addr, 4);
8472
tmp = tcg_temp_new_i32();
8473
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8474
store_reg(s, rd, tmp);
8477
tmp = load_reg(s, rs);
8478
gen_aa32_st32(tmp, addr, IS_USER(s));
8479
tcg_temp_free_i32(tmp);
8480
tcg_gen_addi_i32(addr, addr, 4);
8481
tmp = load_reg(s, rd);
8482
gen_aa32_st32(tmp, addr, IS_USER(s));
8483
tcg_temp_free_i32(tmp);
8485
if (insn & (1 << 21)) {
8486
/* Base writeback. */
8489
tcg_gen_addi_i32(addr, addr, offset - 4);
8490
store_reg(s, rn, addr);
8492
tcg_temp_free_i32(addr);
8494
} else if ((insn & (1 << 23)) == 0) {
8495
/* Load/store exclusive word. */
8496
addr = tcg_temp_local_new_i32();
8497
load_reg_var(s, addr, rn);
8498
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8499
if (insn & (1 << 20)) {
8500
gen_load_exclusive(s, rs, 15, addr, 2);
8502
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8504
tcg_temp_free_i32(addr);
8505
} else if ((insn & (7 << 5)) == 0) {
8508
addr = tcg_temp_new_i32();
8509
tcg_gen_movi_i32(addr, s->pc);
8511
addr = load_reg(s, rn);
8513
tmp = load_reg(s, rm);
8514
tcg_gen_add_i32(addr, addr, tmp);
8515
if (insn & (1 << 4)) {
8517
tcg_gen_add_i32(addr, addr, tmp);
8518
tcg_temp_free_i32(tmp);
8519
tmp = tcg_temp_new_i32();
8520
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8522
tcg_temp_free_i32(tmp);
8523
tmp = tcg_temp_new_i32();
8524
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8526
tcg_temp_free_i32(addr);
8527
tcg_gen_shli_i32(tmp, tmp, 1);
8528
tcg_gen_addi_i32(tmp, tmp, s->pc);
8529
store_reg(s, 15, tmp);
8531
int op2 = (insn >> 6) & 0x3;
8532
op = (insn >> 4) & 0x3;
8537
/* Load/store exclusive byte/halfword/doubleword */
8544
/* Load-acquire/store-release */
8550
/* Load-acquire/store-release exclusive */
8554
addr = tcg_temp_local_new_i32();
8555
load_reg_var(s, addr, rn);
8557
if (insn & (1 << 20)) {
8558
tmp = tcg_temp_new_i32();
8561
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8564
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8567
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8572
store_reg(s, rs, tmp);
8574
tmp = load_reg(s, rs);
8577
gen_aa32_st8(tmp, addr, IS_USER(s));
8580
gen_aa32_st16(tmp, addr, IS_USER(s));
8583
gen_aa32_st32(tmp, addr, IS_USER(s));
8588
tcg_temp_free_i32(tmp);
8590
} else if (insn & (1 << 20)) {
8591
gen_load_exclusive(s, rs, rd, addr, op);
8593
gen_store_exclusive(s, rm, rs, rd, addr, op);
8595
tcg_temp_free_i32(addr);
8598
/* Load/store multiple, RFE, SRS. */
8599
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8600
/* RFE, SRS: not available in user mode or on M profile */
8601
if (IS_USER(s) || IS_M(env)) {
8604
if (insn & (1 << 20)) {
8606
addr = load_reg(s, rn);
8607
if ((insn & (1 << 24)) == 0)
8608
tcg_gen_addi_i32(addr, addr, -8);
8609
/* Load PC into tmp and CPSR into tmp2. */
8610
tmp = tcg_temp_new_i32();
8611
gen_aa32_ld32u(tmp, addr, 0);
8612
tcg_gen_addi_i32(addr, addr, 4);
8613
tmp2 = tcg_temp_new_i32();
8614
gen_aa32_ld32u(tmp2, addr, 0);
8615
if (insn & (1 << 21)) {
8616
/* Base writeback. */
8617
if (insn & (1 << 24)) {
8618
tcg_gen_addi_i32(addr, addr, 4);
8620
tcg_gen_addi_i32(addr, addr, -4);
8622
store_reg(s, rn, addr);
8624
tcg_temp_free_i32(addr);
8626
gen_rfe(s, tmp, tmp2);
8629
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8633
int i, loaded_base = 0;
8634
TCGv_i32 loaded_var;
8635
/* Load/store multiple. */
8636
addr = load_reg(s, rn);
8638
for (i = 0; i < 16; i++) {
8639
if (insn & (1 << i))
8642
if (insn & (1 << 24)) {
8643
tcg_gen_addi_i32(addr, addr, -offset);
8646
TCGV_UNUSED_I32(loaded_var);
8647
for (i = 0; i < 16; i++) {
8648
if ((insn & (1 << i)) == 0)
8650
if (insn & (1 << 20)) {
8652
tmp = tcg_temp_new_i32();
8653
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8656
} else if (i == rn) {
8660
store_reg(s, i, tmp);
8664
tmp = load_reg(s, i);
8665
gen_aa32_st32(tmp, addr, IS_USER(s));
8666
tcg_temp_free_i32(tmp);
8668
tcg_gen_addi_i32(addr, addr, 4);
8671
store_reg(s, rn, loaded_var);
8673
if (insn & (1 << 21)) {
8674
/* Base register writeback. */
8675
if (insn & (1 << 24)) {
8676
tcg_gen_addi_i32(addr, addr, -offset);
8678
/* Fault if writeback register is in register list. */
8679
if (insn & (1 << rn))
8681
store_reg(s, rn, addr);
8683
tcg_temp_free_i32(addr);
8690
op = (insn >> 21) & 0xf;
8692
/* Halfword pack. */
8693
tmp = load_reg(s, rn);
8694
tmp2 = load_reg(s, rm);
8695
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8696
if (insn & (1 << 5)) {
8700
tcg_gen_sari_i32(tmp2, tmp2, shift);
8701
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8702
tcg_gen_ext16u_i32(tmp2, tmp2);
8706
tcg_gen_shli_i32(tmp2, tmp2, shift);
8707
tcg_gen_ext16u_i32(tmp, tmp);
8708
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8710
tcg_gen_or_i32(tmp, tmp, tmp2);
8711
tcg_temp_free_i32(tmp2);
8712
store_reg(s, rd, tmp);
8714
/* Data processing register constant shift. */
8716
tmp = tcg_temp_new_i32();
8717
tcg_gen_movi_i32(tmp, 0);
8719
tmp = load_reg(s, rn);
8721
tmp2 = load_reg(s, rm);
8723
shiftop = (insn >> 4) & 3;
8724
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8725
conds = (insn & (1 << 20)) != 0;
8726
logic_cc = (conds && thumb2_logic_op(op));
8727
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8728
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8730
tcg_temp_free_i32(tmp2);
8732
store_reg(s, rd, tmp);
8734
tcg_temp_free_i32(tmp);
8738
case 13: /* Misc data processing. */
8739
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8740
if (op < 4 && (insn & 0xf000) != 0xf000)
8743
case 0: /* Register controlled shift. */
8744
tmp = load_reg(s, rn);
8745
tmp2 = load_reg(s, rm);
8746
if ((insn & 0x70) != 0)
8748
op = (insn >> 21) & 3;
8749
logic_cc = (insn & (1 << 20)) != 0;
8750
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8753
store_reg_bx(env, s, rd, tmp);
8755
case 1: /* Sign/zero extend. */
8756
tmp = load_reg(s, rm);
8757
shift = (insn >> 4) & 3;
8758
/* ??? In many cases it's not necessary to do a
8759
rotate, a shift is sufficient. */
8761
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8762
op = (insn >> 20) & 7;
8764
case 0: gen_sxth(tmp); break;
8765
case 1: gen_uxth(tmp); break;
8766
case 2: gen_sxtb16(tmp); break;
8767
case 3: gen_uxtb16(tmp); break;
8768
case 4: gen_sxtb(tmp); break;
8769
case 5: gen_uxtb(tmp); break;
8770
default: goto illegal_op;
8773
tmp2 = load_reg(s, rn);
8774
if ((op >> 1) == 1) {
8775
gen_add16(tmp, tmp2);
8777
tcg_gen_add_i32(tmp, tmp, tmp2);
8778
tcg_temp_free_i32(tmp2);
8781
store_reg(s, rd, tmp);
8783
case 2: /* SIMD add/subtract. */
8784
op = (insn >> 20) & 7;
8785
shift = (insn >> 4) & 7;
8786
if ((op & 3) == 3 || (shift & 3) == 3)
8788
tmp = load_reg(s, rn);
8789
tmp2 = load_reg(s, rm);
8790
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8791
tcg_temp_free_i32(tmp2);
8792
store_reg(s, rd, tmp);
8794
case 3: /* Other data processing. */
8795
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8797
/* Saturating add/subtract. */
8798
tmp = load_reg(s, rn);
8799
tmp2 = load_reg(s, rm);
8801
gen_helper_double_saturate(tmp, cpu_env, tmp);
8803
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8805
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8806
tcg_temp_free_i32(tmp2);
8808
tmp = load_reg(s, rn);
8810
case 0x0a: /* rbit */
8811
gen_helper_rbit(tmp, tmp);
8813
case 0x08: /* rev */
8814
tcg_gen_bswap32_i32(tmp, tmp);
8816
case 0x09: /* rev16 */
8819
case 0x0b: /* revsh */
8822
case 0x10: /* sel */
8823
tmp2 = load_reg(s, rm);
8824
tmp3 = tcg_temp_new_i32();
8825
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8826
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8827
tcg_temp_free_i32(tmp3);
8828
tcg_temp_free_i32(tmp2);
8830
case 0x18: /* clz */
8831
gen_helper_clz(tmp, tmp);
8837
store_reg(s, rd, tmp);
8839
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8840
op = (insn >> 4) & 0xf;
8841
tmp = load_reg(s, rn);
8842
tmp2 = load_reg(s, rm);
8843
switch ((insn >> 20) & 7) {
8844
case 0: /* 32 x 32 -> 32 */
8845
tcg_gen_mul_i32(tmp, tmp, tmp2);
8846
tcg_temp_free_i32(tmp2);
8848
tmp2 = load_reg(s, rs);
8850
tcg_gen_sub_i32(tmp, tmp2, tmp);
8852
tcg_gen_add_i32(tmp, tmp, tmp2);
8853
tcg_temp_free_i32(tmp2);
8856
case 1: /* 16 x 16 -> 32 */
8857
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8858
tcg_temp_free_i32(tmp2);
8860
tmp2 = load_reg(s, rs);
8861
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8862
tcg_temp_free_i32(tmp2);
8865
case 2: /* Dual multiply add. */
8866
case 4: /* Dual multiply subtract. */
8868
gen_swap_half(tmp2);
8869
gen_smul_dual(tmp, tmp2);
8870
if (insn & (1 << 22)) {
8871
/* This subtraction cannot overflow. */
8872
tcg_gen_sub_i32(tmp, tmp, tmp2);
8874
/* This addition cannot overflow 32 bits;
8875
* however it may overflow considered as a signed
8876
* operation, in which case we must set the Q flag.
8878
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8880
tcg_temp_free_i32(tmp2);
8883
tmp2 = load_reg(s, rs);
8884
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8885
tcg_temp_free_i32(tmp2);
8888
case 3: /* 32 * 16 -> 32msb */
8890
tcg_gen_sari_i32(tmp2, tmp2, 16);
8893
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8894
tcg_gen_shri_i64(tmp64, tmp64, 16);
8895
tmp = tcg_temp_new_i32();
8896
tcg_gen_trunc_i64_i32(tmp, tmp64);
8897
tcg_temp_free_i64(tmp64);
8900
tmp2 = load_reg(s, rs);
8901
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8902
tcg_temp_free_i32(tmp2);
8905
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8906
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8908
tmp = load_reg(s, rs);
8909
if (insn & (1 << 20)) {
8910
tmp64 = gen_addq_msw(tmp64, tmp);
8912
tmp64 = gen_subq_msw(tmp64, tmp);
8915
if (insn & (1 << 4)) {
8916
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8918
tcg_gen_shri_i64(tmp64, tmp64, 32);
8919
tmp = tcg_temp_new_i32();
8920
tcg_gen_trunc_i64_i32(tmp, tmp64);
8921
tcg_temp_free_i64(tmp64);
8923
case 7: /* Unsigned sum of absolute differences. */
8924
gen_helper_usad8(tmp, tmp, tmp2);
8925
tcg_temp_free_i32(tmp2);
8927
tmp2 = load_reg(s, rs);
8928
tcg_gen_add_i32(tmp, tmp, tmp2);
8929
tcg_temp_free_i32(tmp2);
8933
store_reg(s, rd, tmp);
8935
case 6: case 7: /* 64-bit multiply, Divide. */
8936
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8937
tmp = load_reg(s, rn);
8938
tmp2 = load_reg(s, rm);
8939
if ((op & 0x50) == 0x10) {
8941
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8945
gen_helper_udiv(tmp, tmp, tmp2);
8947
gen_helper_sdiv(tmp, tmp, tmp2);
8948
tcg_temp_free_i32(tmp2);
8949
store_reg(s, rd, tmp);
8950
} else if ((op & 0xe) == 0xc) {
8951
/* Dual multiply accumulate long. */
8953
gen_swap_half(tmp2);
8954
gen_smul_dual(tmp, tmp2);
8956
tcg_gen_sub_i32(tmp, tmp, tmp2);
8958
tcg_gen_add_i32(tmp, tmp, tmp2);
8960
tcg_temp_free_i32(tmp2);
8962
tmp64 = tcg_temp_new_i64();
8963
tcg_gen_ext_i32_i64(tmp64, tmp);
8964
tcg_temp_free_i32(tmp);
8965
gen_addq(s, tmp64, rs, rd);
8966
gen_storeq_reg(s, rs, rd, tmp64);
8967
tcg_temp_free_i64(tmp64);
8970
/* Unsigned 64-bit multiply */
8971
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8975
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8976
tcg_temp_free_i32(tmp2);
8977
tmp64 = tcg_temp_new_i64();
8978
tcg_gen_ext_i32_i64(tmp64, tmp);
8979
tcg_temp_free_i32(tmp);
8981
/* Signed 64-bit multiply */
8982
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8987
gen_addq_lo(s, tmp64, rs);
8988
gen_addq_lo(s, tmp64, rd);
8989
} else if (op & 0x40) {
8990
/* 64-bit accumulate. */
8991
gen_addq(s, tmp64, rs, rd);
8993
gen_storeq_reg(s, rs, rd, tmp64);
8994
tcg_temp_free_i64(tmp64);
8999
case 6: case 7: case 14: case 15:
9001
if (((insn >> 24) & 3) == 3) {
9002
/* Translate into the equivalent ARM encoding. */
9003
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9004
if (disas_neon_data_insn(env, s, insn))
9006
} else if (((insn >> 8) & 0xe) == 10) {
9007
if (disas_vfp_insn(env, s, insn)) {
9011
if (insn & (1 << 28))
9013
if (disas_coproc_insn (env, s, insn))
9017
case 8: case 9: case 10: case 11:
9018
if (insn & (1 << 15)) {
9019
/* Branches, misc control. */
9020
if (insn & 0x5000) {
9021
/* Unconditional branch. */
9022
/* signextend(hw1[10:0]) -> offset[:12]. */
9023
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9024
/* hw1[10:0] -> offset[11:1]. */
9025
offset |= (insn & 0x7ff) << 1;
9026
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9027
offset[24:22] already have the same value because of the
9028
sign extension above. */
9029
offset ^= ((~insn) & (1 << 13)) << 10;
9030
offset ^= ((~insn) & (1 << 11)) << 11;
9032
if (insn & (1 << 14)) {
9033
/* Branch and link. */
9034
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9038
if (insn & (1 << 12)) {
9043
offset &= ~(uint32_t)2;
9044
/* thumb2 bx, no need to check */
9045
gen_bx_im(s, offset);
9047
} else if (((insn >> 23) & 7) == 7) {
9049
if (insn & (1 << 13))
9052
if (insn & (1 << 26)) {
9053
/* Secure monitor call / smc (v6Z) */
9054
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
9060
op = (insn >> 20) & 7;
9062
case 0: /* msr cpsr. */
9064
tmp = load_reg(s, rn);
9065
addr = tcg_const_i32(insn & 0xff);
9066
gen_helper_v7m_msr(cpu_env, addr, tmp);
9067
tcg_temp_free_i32(addr);
9068
tcg_temp_free_i32(tmp);
9073
case 1: /* msr spsr. */
9076
tmp = load_reg(s, rn);
9078
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9082
case 2: /* cps, nop-hint. */
9083
if (((insn >> 8) & 7) == 0) {
9084
gen_nop_hint(s, insn & 0xff);
9086
/* Implemented as NOP in user mode. */
9091
if (insn & (1 << 10)) {
9092
if (insn & (1 << 7))
9094
if (insn & (1 << 6))
9096
if (insn & (1 << 5))
9098
if (insn & (1 << 9))
9099
imm = CPSR_A | CPSR_I | CPSR_F;
9101
if (insn & (1 << 8)) {
9103
imm |= (insn & 0x1f);
9106
gen_set_psr_im(s, offset, 0, imm);
9109
case 3: /* Special control operations. */
9111
op = (insn >> 4) & 0xf;
9119
/* These execute as NOPs. */
9126
/* Trivial implementation equivalent to bx. */
9127
tmp = load_reg(s, rn);
9130
case 5: /* Exception return. */
9134
if (rn != 14 || rd != 15) {
9137
tmp = load_reg(s, rn);
9138
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9139
gen_exception_return(s, tmp);
9141
case 6: /* mrs cpsr. */
9142
tmp = tcg_temp_new_i32();
9144
addr = tcg_const_i32(insn & 0xff);
9145
gen_helper_v7m_mrs(tmp, cpu_env, addr);
9146
tcg_temp_free_i32(addr);
9148
gen_helper_cpsr_read(tmp, cpu_env);
9150
store_reg(s, rd, tmp);
9152
case 7: /* mrs spsr. */
9153
/* Not accessible in user mode. */
9154
if (IS_USER(s) || IS_M(env))
9156
tmp = load_cpu_field(spsr);
9157
store_reg(s, rd, tmp);
9162
/* Conditional branch. */
9163
op = (insn >> 22) & 0xf;
9164
/* Generate a conditional jump to next instruction. */
9165
s->condlabel = gen_new_label();
9166
arm_gen_test_cc(op ^ 1, s->condlabel);
9169
/* offset[11:1] = insn[10:0] */
9170
offset = (insn & 0x7ff) << 1;
9171
/* offset[17:12] = insn[21:16]. */
9172
offset |= (insn & 0x003f0000) >> 4;
9173
/* offset[31:20] = insn[26]. */
9174
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9175
/* offset[18] = insn[13]. */
9176
offset |= (insn & (1 << 13)) << 5;
9177
/* offset[19] = insn[11]. */
9178
offset |= (insn & (1 << 11)) << 8;
9180
/* jump to the offset */
9181
gen_jmp(s, s->pc + offset);
9184
/* Data processing immediate. */
9185
if (insn & (1 << 25)) {
9186
if (insn & (1 << 24)) {
9187
if (insn & (1 << 20))
9189
/* Bitfield/Saturate. */
9190
op = (insn >> 21) & 7;
9192
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9194
tmp = tcg_temp_new_i32();
9195
tcg_gen_movi_i32(tmp, 0);
9197
tmp = load_reg(s, rn);
9200
case 2: /* Signed bitfield extract. */
9202
if (shift + imm > 32)
9205
gen_sbfx(tmp, shift, imm);
9207
case 6: /* Unsigned bitfield extract. */
9209
if (shift + imm > 32)
9212
gen_ubfx(tmp, shift, (1u << imm) - 1);
9214
case 3: /* Bitfield insert/clear. */
9217
imm = imm + 1 - shift;
9219
tmp2 = load_reg(s, rd);
9220
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9221
tcg_temp_free_i32(tmp2);
9226
default: /* Saturate. */
9229
tcg_gen_sari_i32(tmp, tmp, shift);
9231
tcg_gen_shli_i32(tmp, tmp, shift);
9233
tmp2 = tcg_const_i32(imm);
9236
if ((op & 1) && shift == 0)
9237
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9239
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9242
if ((op & 1) && shift == 0)
9243
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9245
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9247
tcg_temp_free_i32(tmp2);
9250
store_reg(s, rd, tmp);
9252
imm = ((insn & 0x04000000) >> 15)
9253
| ((insn & 0x7000) >> 4) | (insn & 0xff);
9254
if (insn & (1 << 22)) {
9255
/* 16-bit immediate. */
9256
imm |= (insn >> 4) & 0xf000;
9257
if (insn & (1 << 23)) {
9259
tmp = load_reg(s, rd);
9260
tcg_gen_ext16u_i32(tmp, tmp);
9261
tcg_gen_ori_i32(tmp, tmp, imm << 16);
9264
tmp = tcg_temp_new_i32();
9265
tcg_gen_movi_i32(tmp, imm);
9268
/* Add/sub 12-bit immediate. */
9270
offset = s->pc & ~(uint32_t)3;
9271
if (insn & (1 << 23))
9275
tmp = tcg_temp_new_i32();
9276
tcg_gen_movi_i32(tmp, offset);
9278
tmp = load_reg(s, rn);
9279
if (insn & (1 << 23))
9280
tcg_gen_subi_i32(tmp, tmp, imm);
9282
tcg_gen_addi_i32(tmp, tmp, imm);
9285
store_reg(s, rd, tmp);
9288
int shifter_out = 0;
9289
/* modified 12-bit immediate. */
9290
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9291
imm = (insn & 0xff);
9294
/* Nothing to do. */
9296
case 1: /* 00XY00XY */
9299
case 2: /* XY00XY00 */
9303
case 3: /* XYXYXYXY */
9307
default: /* Rotated constant. */
9308
shift = (shift << 1) | (imm >> 7);
9310
imm = imm << (32 - shift);
9314
tmp2 = tcg_temp_new_i32();
9315
tcg_gen_movi_i32(tmp2, imm);
9316
rn = (insn >> 16) & 0xf;
9318
tmp = tcg_temp_new_i32();
9319
tcg_gen_movi_i32(tmp, 0);
9321
tmp = load_reg(s, rn);
9323
op = (insn >> 21) & 0xf;
9324
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9325
shifter_out, tmp, tmp2))
9327
tcg_temp_free_i32(tmp2);
9328
rd = (insn >> 8) & 0xf;
9330
store_reg(s, rd, tmp);
9332
tcg_temp_free_i32(tmp);
9337
case 12: /* Load/store single data item. */
9342
if ((insn & 0x01100000) == 0x01000000) {
9343
if (disas_neon_ls_insn(env, s, insn))
9347
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9349
if (!(insn & (1 << 20))) {
9353
/* Byte or halfword load space with dest == r15 : memory hints.
9354
* Catch them early so we don't emit pointless addressing code.
9355
* This space is a mix of:
9356
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9357
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9359
* unallocated hints, which must be treated as NOPs
9360
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9361
* which is easiest for the decoding logic
9362
* Some space which must UNDEF
9364
int op1 = (insn >> 23) & 3;
9365
int op2 = (insn >> 6) & 0x3f;
9370
/* UNPREDICTABLE, unallocated hint or
9371
* PLD/PLDW/PLI (literal)
9376
return 0; /* PLD/PLDW/PLI or unallocated hint */
9378
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9379
return 0; /* PLD/PLDW/PLI or unallocated hint */
9381
/* UNDEF space, or an UNPREDICTABLE */
9387
addr = tcg_temp_new_i32();
9389
/* s->pc has already been incremented by 4. */
9390
imm = s->pc & 0xfffffffc;
9391
if (insn & (1 << 23))
9392
imm += insn & 0xfff;
9394
imm -= insn & 0xfff;
9395
tcg_gen_movi_i32(addr, imm);
9397
addr = load_reg(s, rn);
9398
if (insn & (1 << 23)) {
9399
/* Positive offset. */
9401
tcg_gen_addi_i32(addr, addr, imm);
9404
switch ((insn >> 8) & 0xf) {
9405
case 0x0: /* Shifted Register. */
9406
shift = (insn >> 4) & 0xf;
9408
tcg_temp_free_i32(addr);
9411
tmp = load_reg(s, rm);
9413
tcg_gen_shli_i32(tmp, tmp, shift);
9414
tcg_gen_add_i32(addr, addr, tmp);
9415
tcg_temp_free_i32(tmp);
9417
case 0xc: /* Negative offset. */
9418
tcg_gen_addi_i32(addr, addr, -imm);
9420
case 0xe: /* User privilege. */
9421
tcg_gen_addi_i32(addr, addr, imm);
9424
case 0x9: /* Post-decrement. */
9427
case 0xb: /* Post-increment. */
9431
case 0xd: /* Pre-decrement. */
9434
case 0xf: /* Pre-increment. */
9435
tcg_gen_addi_i32(addr, addr, imm);
9439
tcg_temp_free_i32(addr);
9444
if (insn & (1 << 20)) {
9446
tmp = tcg_temp_new_i32();
9449
gen_aa32_ld8u(tmp, addr, user);
9452
gen_aa32_ld8s(tmp, addr, user);
9455
gen_aa32_ld16u(tmp, addr, user);
9458
gen_aa32_ld16s(tmp, addr, user);
9461
gen_aa32_ld32u(tmp, addr, user);
9464
tcg_temp_free_i32(tmp);
9465
tcg_temp_free_i32(addr);
9471
store_reg(s, rs, tmp);
9475
tmp = load_reg(s, rs);
9478
gen_aa32_st8(tmp, addr, user);
9481
gen_aa32_st16(tmp, addr, user);
9484
gen_aa32_st32(tmp, addr, user);
9487
tcg_temp_free_i32(tmp);
9488
tcg_temp_free_i32(addr);
9491
tcg_temp_free_i32(tmp);
9494
tcg_gen_addi_i32(addr, addr, imm);
9496
store_reg(s, rn, addr);
9498
tcg_temp_free_i32(addr);
9510
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9512
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9519
if (s->condexec_mask) {
9520
cond = s->condexec_cond;
9521
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9522
s->condlabel = gen_new_label();
9523
arm_gen_test_cc(cond ^ 1, s->condlabel);
9528
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9531
switch (insn >> 12) {
9535
op = (insn >> 11) & 3;
9538
rn = (insn >> 3) & 7;
9539
tmp = load_reg(s, rn);
9540
if (insn & (1 << 10)) {
9542
tmp2 = tcg_temp_new_i32();
9543
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9546
rm = (insn >> 6) & 7;
9547
tmp2 = load_reg(s, rm);
9549
if (insn & (1 << 9)) {
9550
if (s->condexec_mask)
9551
tcg_gen_sub_i32(tmp, tmp, tmp2);
9553
gen_sub_CC(tmp, tmp, tmp2);
9555
if (s->condexec_mask)
9556
tcg_gen_add_i32(tmp, tmp, tmp2);
9558
gen_add_CC(tmp, tmp, tmp2);
9560
tcg_temp_free_i32(tmp2);
9561
store_reg(s, rd, tmp);
9563
/* shift immediate */
9564
rm = (insn >> 3) & 7;
9565
shift = (insn >> 6) & 0x1f;
9566
tmp = load_reg(s, rm);
9567
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9568
if (!s->condexec_mask)
9570
store_reg(s, rd, tmp);
9574
/* arithmetic large immediate */
9575
op = (insn >> 11) & 3;
9576
rd = (insn >> 8) & 0x7;
9577
if (op == 0) { /* mov */
9578
tmp = tcg_temp_new_i32();
9579
tcg_gen_movi_i32(tmp, insn & 0xff);
9580
if (!s->condexec_mask)
9582
store_reg(s, rd, tmp);
9584
tmp = load_reg(s, rd);
9585
tmp2 = tcg_temp_new_i32();
9586
tcg_gen_movi_i32(tmp2, insn & 0xff);
9589
gen_sub_CC(tmp, tmp, tmp2);
9590
tcg_temp_free_i32(tmp);
9591
tcg_temp_free_i32(tmp2);
9594
if (s->condexec_mask)
9595
tcg_gen_add_i32(tmp, tmp, tmp2);
9597
gen_add_CC(tmp, tmp, tmp2);
9598
tcg_temp_free_i32(tmp2);
9599
store_reg(s, rd, tmp);
9602
if (s->condexec_mask)
9603
tcg_gen_sub_i32(tmp, tmp, tmp2);
9605
gen_sub_CC(tmp, tmp, tmp2);
9606
tcg_temp_free_i32(tmp2);
9607
store_reg(s, rd, tmp);
9613
if (insn & (1 << 11)) {
9614
rd = (insn >> 8) & 7;
9615
/* load pc-relative. Bit 1 of PC is ignored. */
9616
val = s->pc + 2 + ((insn & 0xff) * 4);
9617
val &= ~(uint32_t)2;
9618
addr = tcg_temp_new_i32();
9619
tcg_gen_movi_i32(addr, val);
9620
tmp = tcg_temp_new_i32();
9621
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9622
tcg_temp_free_i32(addr);
9623
store_reg(s, rd, tmp);
9626
if (insn & (1 << 10)) {
9627
/* data processing extended or blx */
9628
rd = (insn & 7) | ((insn >> 4) & 8);
9629
rm = (insn >> 3) & 0xf;
9630
op = (insn >> 8) & 3;
9633
tmp = load_reg(s, rd);
9634
tmp2 = load_reg(s, rm);
9635
tcg_gen_add_i32(tmp, tmp, tmp2);
9636
tcg_temp_free_i32(tmp2);
9637
store_reg(s, rd, tmp);
9640
tmp = load_reg(s, rd);
9641
tmp2 = load_reg(s, rm);
9642
gen_sub_CC(tmp, tmp, tmp2);
9643
tcg_temp_free_i32(tmp2);
9644
tcg_temp_free_i32(tmp);
9646
case 2: /* mov/cpy */
9647
tmp = load_reg(s, rm);
9648
store_reg(s, rd, tmp);
9650
case 3:/* branch [and link] exchange thumb register */
9651
tmp = load_reg(s, rm);
9652
if (insn & (1 << 7)) {
9654
val = (uint32_t)s->pc | 1;
9655
tmp2 = tcg_temp_new_i32();
9656
tcg_gen_movi_i32(tmp2, val);
9657
store_reg(s, 14, tmp2);
9659
/* already thumb, no need to check */
9666
/* data processing register */
9668
rm = (insn >> 3) & 7;
9669
op = (insn >> 6) & 0xf;
9670
if (op == 2 || op == 3 || op == 4 || op == 7) {
9671
/* the shift/rotate ops want the operands backwards */
9680
if (op == 9) { /* neg */
9681
tmp = tcg_temp_new_i32();
9682
tcg_gen_movi_i32(tmp, 0);
9683
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9684
tmp = load_reg(s, rd);
9686
TCGV_UNUSED_I32(tmp);
9689
tmp2 = load_reg(s, rm);
9692
tcg_gen_and_i32(tmp, tmp, tmp2);
9693
if (!s->condexec_mask)
9697
tcg_gen_xor_i32(tmp, tmp, tmp2);
9698
if (!s->condexec_mask)
9702
if (s->condexec_mask) {
9703
gen_shl(tmp2, tmp2, tmp);
9705
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9710
if (s->condexec_mask) {
9711
gen_shr(tmp2, tmp2, tmp);
9713
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9718
if (s->condexec_mask) {
9719
gen_sar(tmp2, tmp2, tmp);
9721
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9726
if (s->condexec_mask) {
9729
gen_adc_CC(tmp, tmp, tmp2);
9733
if (s->condexec_mask) {
9734
gen_sub_carry(tmp, tmp, tmp2);
9736
gen_sbc_CC(tmp, tmp, tmp2);
9740
if (s->condexec_mask) {
9741
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9742
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9744
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9749
tcg_gen_and_i32(tmp, tmp, tmp2);
9754
if (s->condexec_mask)
9755
tcg_gen_neg_i32(tmp, tmp2);
9757
gen_sub_CC(tmp, tmp, tmp2);
9760
gen_sub_CC(tmp, tmp, tmp2);
9764
gen_add_CC(tmp, tmp, tmp2);
9768
tcg_gen_or_i32(tmp, tmp, tmp2);
9769
if (!s->condexec_mask)
9773
tcg_gen_mul_i32(tmp, tmp, tmp2);
9774
if (!s->condexec_mask)
9778
tcg_gen_andc_i32(tmp, tmp, tmp2);
9779
if (!s->condexec_mask)
9783
tcg_gen_not_i32(tmp2, tmp2);
9784
if (!s->condexec_mask)
9792
store_reg(s, rm, tmp2);
9794
tcg_temp_free_i32(tmp);
9796
store_reg(s, rd, tmp);
9797
tcg_temp_free_i32(tmp2);
9800
tcg_temp_free_i32(tmp);
9801
tcg_temp_free_i32(tmp2);
9806
/* load/store register offset. */
9808
rn = (insn >> 3) & 7;
9809
rm = (insn >> 6) & 7;
9810
op = (insn >> 9) & 7;
9811
addr = load_reg(s, rn);
9812
tmp = load_reg(s, rm);
9813
tcg_gen_add_i32(addr, addr, tmp);
9814
tcg_temp_free_i32(tmp);
9816
if (op < 3) { /* store */
9817
tmp = load_reg(s, rd);
9819
tmp = tcg_temp_new_i32();
9824
gen_aa32_st32(tmp, addr, IS_USER(s));
9827
gen_aa32_st16(tmp, addr, IS_USER(s));
9830
gen_aa32_st8(tmp, addr, IS_USER(s));
9833
gen_aa32_ld8s(tmp, addr, IS_USER(s));
9836
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9839
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9842
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9845
gen_aa32_ld16s(tmp, addr, IS_USER(s));
9848
if (op >= 3) { /* load */
9849
store_reg(s, rd, tmp);
9851
tcg_temp_free_i32(tmp);
9853
tcg_temp_free_i32(addr);
9857
/* load/store word immediate offset */
9859
rn = (insn >> 3) & 7;
9860
addr = load_reg(s, rn);
9861
val = (insn >> 4) & 0x7c;
9862
tcg_gen_addi_i32(addr, addr, val);
9864
if (insn & (1 << 11)) {
9866
tmp = tcg_temp_new_i32();
9867
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9868
store_reg(s, rd, tmp);
9871
tmp = load_reg(s, rd);
9872
gen_aa32_st32(tmp, addr, IS_USER(s));
9873
tcg_temp_free_i32(tmp);
9875
tcg_temp_free_i32(addr);
9879
/* load/store byte immediate offset */
9881
rn = (insn >> 3) & 7;
9882
addr = load_reg(s, rn);
9883
val = (insn >> 6) & 0x1f;
9884
tcg_gen_addi_i32(addr, addr, val);
9886
if (insn & (1 << 11)) {
9888
tmp = tcg_temp_new_i32();
9889
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9890
store_reg(s, rd, tmp);
9893
tmp = load_reg(s, rd);
9894
gen_aa32_st8(tmp, addr, IS_USER(s));
9895
tcg_temp_free_i32(tmp);
9897
tcg_temp_free_i32(addr);
9901
/* load/store halfword immediate offset */
9903
rn = (insn >> 3) & 7;
9904
addr = load_reg(s, rn);
9905
val = (insn >> 5) & 0x3e;
9906
tcg_gen_addi_i32(addr, addr, val);
9908
if (insn & (1 << 11)) {
9910
tmp = tcg_temp_new_i32();
9911
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9912
store_reg(s, rd, tmp);
9915
tmp = load_reg(s, rd);
9916
gen_aa32_st16(tmp, addr, IS_USER(s));
9917
tcg_temp_free_i32(tmp);
9919
tcg_temp_free_i32(addr);
9923
/* load/store from stack */
9924
rd = (insn >> 8) & 7;
9925
addr = load_reg(s, 13);
9926
val = (insn & 0xff) * 4;
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
/* add to high reg */
9945
rd = (insn >> 8) & 7;
9946
if (insn & (1 << 11)) {
9948
tmp = load_reg(s, 13);
9950
/* PC. bit 1 is ignored. */
9951
tmp = tcg_temp_new_i32();
9952
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9954
val = (insn & 0xff) * 4;
9955
tcg_gen_addi_i32(tmp, tmp, val);
9956
store_reg(s, rd, tmp);
9961
op = (insn >> 8) & 0xf;
9964
/* adjust stack pointer */
9965
tmp = load_reg(s, 13);
9966
val = (insn & 0x7f) * 4;
9967
if (insn & (1 << 7))
9968
val = -(int32_t)val;
9969
tcg_gen_addi_i32(tmp, tmp, val);
9970
store_reg(s, 13, tmp);
9973
case 2: /* sign/zero extend. */
9976
rm = (insn >> 3) & 7;
9977
tmp = load_reg(s, rm);
9978
switch ((insn >> 6) & 3) {
9979
case 0: gen_sxth(tmp); break;
9980
case 1: gen_sxtb(tmp); break;
9981
case 2: gen_uxth(tmp); break;
9982
case 3: gen_uxtb(tmp); break;
9984
store_reg(s, rd, tmp);
9986
case 4: case 5: case 0xc: case 0xd:
9988
addr = load_reg(s, 13);
9989
if (insn & (1 << 8))
9993
for (i = 0; i < 8; i++) {
9994
if (insn & (1 << i))
9997
if ((insn & (1 << 11)) == 0) {
9998
tcg_gen_addi_i32(addr, addr, -offset);
10000
for (i = 0; i < 8; i++) {
10001
if (insn & (1 << i)) {
10002
if (insn & (1 << 11)) {
10004
tmp = tcg_temp_new_i32();
10005
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10006
store_reg(s, i, tmp);
10009
tmp = load_reg(s, i);
10010
gen_aa32_st32(tmp, addr, IS_USER(s));
10011
tcg_temp_free_i32(tmp);
10013
/* advance to the next address. */
10014
tcg_gen_addi_i32(addr, addr, 4);
10017
TCGV_UNUSED_I32(tmp);
10018
if (insn & (1 << 8)) {
10019
if (insn & (1 << 11)) {
10021
tmp = tcg_temp_new_i32();
10022
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10023
/* don't set the pc until the rest of the instruction
10027
tmp = load_reg(s, 14);
10028
gen_aa32_st32(tmp, addr, IS_USER(s));
10029
tcg_temp_free_i32(tmp);
10031
tcg_gen_addi_i32(addr, addr, 4);
10033
if ((insn & (1 << 11)) == 0) {
10034
tcg_gen_addi_i32(addr, addr, -offset);
10036
/* write back the new stack pointer */
10037
store_reg(s, 13, addr);
10038
/* set the new PC value */
10039
if ((insn & 0x0900) == 0x0900) {
10040
store_reg_from_load(env, s, 15, tmp);
10044
case 1: case 3: case 9: case 11: /* czb */
10046
tmp = load_reg(s, rm);
10047
s->condlabel = gen_new_label();
10049
if (insn & (1 << 11))
10050
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10052
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10053
tcg_temp_free_i32(tmp);
10054
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10055
val = (uint32_t)s->pc + 2;
10060
case 15: /* IT, nop-hint. */
10061
if ((insn & 0xf) == 0) {
10062
gen_nop_hint(s, (insn >> 4) & 0xf);
10066
s->condexec_cond = (insn >> 4) & 0xe;
10067
s->condexec_mask = insn & 0x1f;
10068
/* No actual code generated for this insn, just setup state. */
10071
case 0xe: /* bkpt */
10073
gen_exception_insn(s, 2, EXCP_BKPT);
10076
case 0xa: /* rev */
10078
rn = (insn >> 3) & 0x7;
10080
tmp = load_reg(s, rn);
10081
switch ((insn >> 6) & 3) {
10082
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10083
case 1: gen_rev16(tmp); break;
10084
case 3: gen_revsh(tmp); break;
10085
default: goto illegal_op;
10087
store_reg(s, rd, tmp);
10091
switch ((insn >> 5) & 7) {
10095
if (((insn >> 3) & 1) != s->bswap_code) {
10096
/* Dynamic endianness switching not implemented. */
10097
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10108
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10111
addr = tcg_const_i32(19);
10112
gen_helper_v7m_msr(cpu_env, addr, tmp);
10113
tcg_temp_free_i32(addr);
10117
addr = tcg_const_i32(16);
10118
gen_helper_v7m_msr(cpu_env, addr, tmp);
10119
tcg_temp_free_i32(addr);
10121
tcg_temp_free_i32(tmp);
10124
if (insn & (1 << 4)) {
10125
shift = CPSR_A | CPSR_I | CPSR_F;
10129
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10144
/* load/store multiple */
10145
TCGv_i32 loaded_var;
10146
TCGV_UNUSED_I32(loaded_var);
10147
rn = (insn >> 8) & 0x7;
10148
addr = load_reg(s, rn);
10149
for (i = 0; i < 8; i++) {
10150
if (insn & (1 << i)) {
10151
if (insn & (1 << 11)) {
10153
tmp = tcg_temp_new_i32();
10154
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10158
store_reg(s, i, tmp);
10162
tmp = load_reg(s, i);
10163
gen_aa32_st32(tmp, addr, IS_USER(s));
10164
tcg_temp_free_i32(tmp);
10166
/* advance to the next address */
10167
tcg_gen_addi_i32(addr, addr, 4);
10170
if ((insn & (1 << rn)) == 0) {
10171
/* base reg not in list: base register writeback */
10172
store_reg(s, rn, addr);
10174
/* base reg in list: if load, complete it now */
10175
if (insn & (1 << 11)) {
10176
store_reg(s, rn, loaded_var);
10178
tcg_temp_free_i32(addr);
10183
/* conditional branch or swi */
10184
cond = (insn >> 8) & 0xf;
10190
gen_set_pc_im(s, s->pc);
10191
s->is_jmp = DISAS_SWI;
10194
/* generate a conditional jump to next instruction */
10195
s->condlabel = gen_new_label();
10196
arm_gen_test_cc(cond ^ 1, s->condlabel);
10199
/* jump to the offset */
10200
val = (uint32_t)s->pc + 2;
10201
offset = ((int32_t)insn << 24) >> 24;
10202
val += offset << 1;
10207
if (insn & (1 << 11)) {
10208
if (disas_thumb2_insn(env, s, insn))
10212
/* unconditional branch */
10213
val = (uint32_t)s->pc;
10214
offset = ((int32_t)insn << 21) >> 21;
10215
val += (offset << 1) + 2;
10220
if (disas_thumb2_insn(env, s, insn))
10226
gen_exception_insn(s, 4, EXCP_UDEF);
10230
gen_exception_insn(s, 2, EXCP_UDEF);
10233
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10234
basic block 'tb'. If search_pc is TRUE, also generate PC
10235
information for each intermediate instruction. */
10236
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10237
TranslationBlock *tb,
10240
CPUState *cs = CPU(cpu);
10241
CPUARMState *env = &cpu->env;
10242
DisasContext dc1, *dc = &dc1;
10244
uint16_t *gen_opc_end;
10246
target_ulong pc_start;
10247
target_ulong next_page_start;
10251
/* generate intermediate code */
10253
/* The A64 decoder has its own top level loop, because it doesn't need
10254
* the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10256
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10257
gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10265
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10267
dc->is_jmp = DISAS_NEXT;
10269
dc->singlestep_enabled = cs->singlestep_enabled;
10273
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10274
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10275
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10276
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10277
#if !defined(CONFIG_USER_ONLY)
10278
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10280
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10281
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10282
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10283
dc->cp_regs = cpu->cp_regs;
10284
dc->current_pl = arm_current_pl(env);
10286
cpu_F0s = tcg_temp_new_i32();
10287
cpu_F1s = tcg_temp_new_i32();
10288
cpu_F0d = tcg_temp_new_i64();
10289
cpu_F1d = tcg_temp_new_i64();
10292
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10293
cpu_M0 = tcg_temp_new_i64();
10294
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10297
max_insns = tb->cflags & CF_COUNT_MASK;
10298
if (max_insns == 0)
10299
max_insns = CF_COUNT_MASK;
10303
tcg_clear_temp_count();
10305
/* A note on handling of the condexec (IT) bits:
10307
* We want to avoid the overhead of having to write the updated condexec
10308
* bits back to the CPUARMState for every instruction in an IT block. So:
10309
* (1) if the condexec bits are not already zero then we write
10310
* zero back into the CPUARMState now. This avoids complications trying
10311
* to do it at the end of the block. (For example if we don't do this
10312
* it's hard to identify whether we can safely skip writing condexec
10313
* at the end of the TB, which we definitely want to do for the case
10314
* where a TB doesn't do anything with the IT state at all.)
10315
* (2) if we are going to leave the TB then we call gen_set_condexec()
10316
* which will write the correct value into CPUARMState if zero is wrong.
10317
* This is done both for leaving the TB at the end, and for leaving
10318
* it because of an exception we know will happen, which is done in
10319
* gen_exception_insn(). The latter is necessary because we need to
10320
* leave the TB with the PC/IT state just prior to execution of the
10321
* instruction which caused the exception.
10322
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10323
* then the CPUARMState will be wrong and we need to reset it.
10324
* This is handled in the same way as restoration of the
10325
* PC in these situations: we will be called again with search_pc=1
10326
* and generate a mapping of the condexec bits for each PC in
10327
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10328
* this to restore the condexec bits.
10330
* Note that there are no instructions which can read the condexec
10331
* bits, and none which can write non-static values to them, so
10332
* we don't need to care about whether CPUARMState is correct in the
10336
/* Reset the conditional execution bits immediately. This avoids
10337
complications trying to do it at the end of the block. */
10338
if (dc->condexec_mask || dc->condexec_cond)
10340
TCGv_i32 tmp = tcg_temp_new_i32();
10341
tcg_gen_movi_i32(tmp, 0);
10342
store_cpu_field(tmp, condexec_bits);
10345
#ifdef CONFIG_USER_ONLY
10346
/* Intercept jump to the magic kernel page. */
10347
if (dc->pc >= 0xffff0000) {
10348
/* We always get here via a jump, so know we are not in a
10349
conditional execution block. */
10350
gen_exception(EXCP_KERNEL_TRAP);
10351
dc->is_jmp = DISAS_UPDATE;
10355
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10356
/* We always get here via a jump, so know we are not in a
10357
conditional execution block. */
10358
gen_exception(EXCP_EXCEPTION_EXIT);
10359
dc->is_jmp = DISAS_UPDATE;
10364
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10365
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10366
if (bp->pc == dc->pc) {
10367
gen_exception_insn(dc, 0, EXCP_DEBUG);
10368
/* Advance PC so that clearing the breakpoint will
10369
invalidate this TB. */
10371
goto done_generating;
10376
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10380
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10382
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10383
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10384
tcg_ctx.gen_opc_instr_start[lj] = 1;
10385
tcg_ctx.gen_opc_icount[lj] = num_insns;
10388
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10391
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10392
tcg_gen_debug_insn_start(dc->pc);
10396
disas_thumb_insn(env, dc);
10397
if (dc->condexec_mask) {
10398
dc->condexec_cond = (dc->condexec_cond & 0xe)
10399
| ((dc->condexec_mask >> 4) & 1);
10400
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10401
if (dc->condexec_mask == 0) {
10402
dc->condexec_cond = 0;
10406
disas_arm_insn(env, dc);
10409
if (dc->condjmp && !dc->is_jmp) {
10410
gen_set_label(dc->condlabel);
10414
if (tcg_check_temp_count()) {
10415
fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10419
/* Translation stops when a conditional branch is encountered.
10420
* Otherwise the subsequent code could get translated several times.
10421
* Also stop translation when a page boundary is reached. This
10422
* ensures prefetch aborts occur at the right place. */
10424
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10425
!cs->singlestep_enabled &&
10427
dc->pc < next_page_start &&
10428
num_insns < max_insns);
10430
if (tb->cflags & CF_LAST_IO) {
10432
/* FIXME: This can theoretically happen with self-modifying
10434
cpu_abort(env, "IO on conditional branch instruction");
10439
/* At this stage dc->condjmp will only be set when the skipped
10440
instruction was a conditional branch or trap, and the PC has
10441
already been written. */
10442
if (unlikely(cs->singlestep_enabled)) {
10443
/* Make sure the pc is updated, and raise a debug exception. */
10445
gen_set_condexec(dc);
10446
if (dc->is_jmp == DISAS_SWI) {
10447
gen_exception(EXCP_SWI);
10448
} else if (dc->is_jmp == DISAS_SMC) {
10449
gen_exception(EXCP_SMC);
10451
gen_exception(EXCP_DEBUG);
10453
gen_set_label(dc->condlabel);
10455
if (dc->condjmp || !dc->is_jmp) {
10456
gen_set_pc_im(dc, dc->pc);
10459
gen_set_condexec(dc);
10460
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10461
gen_exception(EXCP_SWI);
10462
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10463
gen_exception(EXCP_SMC);
10465
/* FIXME: Single stepping a WFI insn will not halt
10467
gen_exception(EXCP_DEBUG);
10470
/* While branches must always occur at the end of an IT block,
10471
there are a few other things that can cause us to terminate
10472
the TB in the middle of an IT block:
10473
- Exception generating instructions (bkpt, swi, undefined).
10475
- Hardware watchpoints.
10476
Hardware breakpoints have already been handled and skip this code.
10478
gen_set_condexec(dc);
10479
switch(dc->is_jmp) {
10481
gen_goto_tb(dc, 1, dc->pc);
10486
/* indicate that the hash table must be used to find the next TB */
10487
tcg_gen_exit_tb(0);
10489
case DISAS_TB_JUMP:
10490
/* nothing more to generate */
10493
gen_helper_wfi(cpu_env);
10496
gen_exception(EXCP_SWI);
10499
gen_exception(EXCP_SMC);
10503
gen_set_label(dc->condlabel);
10504
gen_set_condexec(dc);
10505
gen_goto_tb(dc, 1, dc->pc);
10511
gen_tb_end(tb, num_insns);
10512
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10515
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10516
qemu_log("----------------\n");
10517
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10518
log_target_disas(env, pc_start, dc->pc - pc_start,
10519
dc->thumb | (dc->bswap_code << 1));
10524
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10527
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10529
tb->size = dc->pc - pc_start;
10530
tb->icount = num_insns;
10534
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10536
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10539
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10541
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10544
static const char *cpu_mode_names[16] = {
10545
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10546
"???", "???", "???", "und", "???", "???", "???", "sys"
10549
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10552
ARMCPU *cpu = ARM_CPU(cs);
10553
CPUARMState *env = &cpu->env;
10557
for(i=0;i<16;i++) {
10558
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10560
cpu_fprintf(f, "\n");
10562
cpu_fprintf(f, " ");
10564
psr = cpsr_read(env);
10565
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10567
psr & (1 << 31) ? 'N' : '-',
10568
psr & (1 << 30) ? 'Z' : '-',
10569
psr & (1 << 29) ? 'C' : '-',
10570
psr & (1 << 28) ? 'V' : '-',
10571
psr & CPSR_T ? 'T' : 'A',
10572
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10574
if (flags & CPU_DUMP_FPU) {
10575
int numvfpregs = 0;
10576
if (arm_feature(env, ARM_FEATURE_VFP)) {
10579
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10582
for (i = 0; i < numvfpregs; i++) {
10583
uint64_t v = float64_val(env->vfp.regs[i]);
10584
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10585
i * 2, (uint32_t)v,
10586
i * 2 + 1, (uint32_t)(v >> 32),
10589
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10593
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10596
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10597
env->condexec_bits = 0;
10599
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10600
env->condexec_bits = gen_opc_condexec_bits[pc_pos];