4
* Copyright (c) 2003 Fabrice Bellard
5
* Copyright (c) 2005-2007 CodeSourcery
6
* Copyright (c) 2007 OpenedHand, Ltd.
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
28
#include "disas/disas.h"
31
#include "qemu/bitops.h"
37
#define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38
#define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39
/* currently all emulated v5 cores are also v5TE, so don't bother */
40
#define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41
#define ENABLE_ARCH_5J 0
42
#define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43
#define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44
#define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45
#define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46
#define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48
#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50
#include "translate.h"
51
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
53
/* These instructions trap after executing, so defer them until after the
54
conditional execution state has been updated. */
59
#if defined(CONFIG_USER_ONLY)
62
#define IS_USER(s) (s->user)
66
/* We reuse the same 64-bit temporaries for efficiency. */
67
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
68
static TCGv_i32 cpu_R[16];
69
static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
70
static TCGv_i64 cpu_exclusive_addr;
71
static TCGv_i64 cpu_exclusive_val;
72
#ifdef CONFIG_USER_ONLY
73
static TCGv_i64 cpu_exclusive_test;
74
static TCGv_i32 cpu_exclusive_info;
77
/* FIXME: These should be removed. */
78
static TCGv_i32 cpu_F0s, cpu_F1s;
79
static TCGv_i64 cpu_F0d, cpu_F1d;
81
#include "exec/gen-icount.h"
83
static const char *regnames[] =
84
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
85
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
87
/* initialize TCG globals. */
88
void arm_translate_init(void)
92
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
94
for (i = 0; i < 16; i++) {
95
cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
96
offsetof(CPUARMState, regs[i]),
99
cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
100
cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
101
cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
102
cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
104
cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
105
offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
106
cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
107
offsetof(CPUARMState, exclusive_val), "exclusive_val");
108
#ifdef CONFIG_USER_ONLY
109
cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
110
offsetof(CPUARMState, exclusive_test), "exclusive_test");
111
cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
112
offsetof(CPUARMState, exclusive_info), "exclusive_info");
115
a64_translate_init();
118
static inline TCGv_i32 load_cpu_offset(int offset)
120
TCGv_i32 tmp = tcg_temp_new_i32();
121
tcg_gen_ld_i32(tmp, cpu_env, offset);
125
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
127
static inline void store_cpu_offset(TCGv_i32 var, int offset)
129
tcg_gen_st_i32(var, cpu_env, offset);
130
tcg_temp_free_i32(var);
133
#define store_cpu_field(var, name) \
134
store_cpu_offset(var, offsetof(CPUARMState, name))
136
/* Set a variable to the value of a CPU register. */
137
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
141
/* normally, since we updated PC, we need only to add one insn */
143
addr = (long)s->pc + 2;
145
addr = (long)s->pc + 4;
146
tcg_gen_movi_i32(var, addr);
148
tcg_gen_mov_i32(var, cpu_R[reg]);
152
/* Create a new temporary and set it to the value of a CPU register. */
153
static inline TCGv_i32 load_reg(DisasContext *s, int reg)
155
TCGv_i32 tmp = tcg_temp_new_i32();
156
load_reg_var(s, tmp, reg);
160
/* Set a CPU register. The source must be a temporary and will be
162
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
165
tcg_gen_andi_i32(var, var, ~1);
166
s->is_jmp = DISAS_JUMP;
168
tcg_gen_mov_i32(cpu_R[reg], var);
169
tcg_temp_free_i32(var);
172
/* Value extensions. */
173
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
174
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
175
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
176
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
178
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
179
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
182
static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
184
TCGv_i32 tmp_mask = tcg_const_i32(mask);
185
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
186
tcg_temp_free_i32(tmp_mask);
188
/* Set NZCV flags from the high 4 bits of var. */
189
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
191
static void gen_exception(int excp)
193
TCGv_i32 tmp = tcg_temp_new_i32();
194
tcg_gen_movi_i32(tmp, excp);
195
gen_helper_exception(cpu_env, tmp);
196
tcg_temp_free_i32(tmp);
199
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
201
TCGv_i32 tmp1 = tcg_temp_new_i32();
202
TCGv_i32 tmp2 = tcg_temp_new_i32();
203
tcg_gen_ext16s_i32(tmp1, a);
204
tcg_gen_ext16s_i32(tmp2, b);
205
tcg_gen_mul_i32(tmp1, tmp1, tmp2);
206
tcg_temp_free_i32(tmp2);
207
tcg_gen_sari_i32(a, a, 16);
208
tcg_gen_sari_i32(b, b, 16);
209
tcg_gen_mul_i32(b, b, a);
210
tcg_gen_mov_i32(a, tmp1);
211
tcg_temp_free_i32(tmp1);
214
/* Byteswap each halfword. */
215
static void gen_rev16(TCGv_i32 var)
217
TCGv_i32 tmp = tcg_temp_new_i32();
218
tcg_gen_shri_i32(tmp, var, 8);
219
tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
220
tcg_gen_shli_i32(var, var, 8);
221
tcg_gen_andi_i32(var, var, 0xff00ff00);
222
tcg_gen_or_i32(var, var, tmp);
223
tcg_temp_free_i32(tmp);
226
/* Byteswap low halfword and sign extend. */
227
static void gen_revsh(TCGv_i32 var)
229
tcg_gen_ext16u_i32(var, var);
230
tcg_gen_bswap16_i32(var, var);
231
tcg_gen_ext16s_i32(var, var);
234
/* Unsigned bitfield extract. */
235
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
238
tcg_gen_shri_i32(var, var, shift);
239
tcg_gen_andi_i32(var, var, mask);
242
/* Signed bitfield extract. */
243
static void gen_sbfx(TCGv_i32 var, int shift, int width)
248
tcg_gen_sari_i32(var, var, shift);
249
if (shift + width < 32) {
250
signbit = 1u << (width - 1);
251
tcg_gen_andi_i32(var, var, (1u << width) - 1);
252
tcg_gen_xori_i32(var, var, signbit);
253
tcg_gen_subi_i32(var, var, signbit);
257
/* Return (b << 32) + a. Mark inputs as dead */
258
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
260
TCGv_i64 tmp64 = tcg_temp_new_i64();
262
tcg_gen_extu_i32_i64(tmp64, b);
263
tcg_temp_free_i32(b);
264
tcg_gen_shli_i64(tmp64, tmp64, 32);
265
tcg_gen_add_i64(a, tmp64, a);
267
tcg_temp_free_i64(tmp64);
271
/* Return (b << 32) - a. Mark inputs as dead. */
272
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
274
TCGv_i64 tmp64 = tcg_temp_new_i64();
276
tcg_gen_extu_i32_i64(tmp64, b);
277
tcg_temp_free_i32(b);
278
tcg_gen_shli_i64(tmp64, tmp64, 32);
279
tcg_gen_sub_i64(a, tmp64, a);
281
tcg_temp_free_i64(tmp64);
285
/* 32x32->64 multiply. Marks inputs as dead. */
286
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
288
TCGv_i32 lo = tcg_temp_new_i32();
289
TCGv_i32 hi = tcg_temp_new_i32();
292
tcg_gen_mulu2_i32(lo, hi, a, b);
293
tcg_temp_free_i32(a);
294
tcg_temp_free_i32(b);
296
ret = tcg_temp_new_i64();
297
tcg_gen_concat_i32_i64(ret, lo, hi);
298
tcg_temp_free_i32(lo);
299
tcg_temp_free_i32(hi);
304
static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
306
TCGv_i32 lo = tcg_temp_new_i32();
307
TCGv_i32 hi = tcg_temp_new_i32();
310
tcg_gen_muls2_i32(lo, hi, a, b);
311
tcg_temp_free_i32(a);
312
tcg_temp_free_i32(b);
314
ret = tcg_temp_new_i64();
315
tcg_gen_concat_i32_i64(ret, lo, hi);
316
tcg_temp_free_i32(lo);
317
tcg_temp_free_i32(hi);
322
/* Swap low and high halfwords. */
323
static void gen_swap_half(TCGv_i32 var)
325
TCGv_i32 tmp = tcg_temp_new_i32();
326
tcg_gen_shri_i32(tmp, var, 16);
327
tcg_gen_shli_i32(var, var, 16);
328
tcg_gen_or_i32(var, var, tmp);
329
tcg_temp_free_i32(tmp);
332
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
333
tmp = (t0 ^ t1) & 0x8000;
336
t0 = (t0 + t1) ^ tmp;
339
static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
341
TCGv_i32 tmp = tcg_temp_new_i32();
342
tcg_gen_xor_i32(tmp, t0, t1);
343
tcg_gen_andi_i32(tmp, tmp, 0x8000);
344
tcg_gen_andi_i32(t0, t0, ~0x8000);
345
tcg_gen_andi_i32(t1, t1, ~0x8000);
346
tcg_gen_add_i32(t0, t0, t1);
347
tcg_gen_xor_i32(t0, t0, tmp);
348
tcg_temp_free_i32(tmp);
349
tcg_temp_free_i32(t1);
352
/* Set CF to the top bit of var. */
353
static void gen_set_CF_bit31(TCGv_i32 var)
355
tcg_gen_shri_i32(cpu_CF, var, 31);
358
/* Set N and Z flags from var. */
359
static inline void gen_logic_CC(TCGv_i32 var)
361
tcg_gen_mov_i32(cpu_NF, var);
362
tcg_gen_mov_i32(cpu_ZF, var);
366
static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
368
tcg_gen_add_i32(t0, t0, t1);
369
tcg_gen_add_i32(t0, t0, cpu_CF);
372
/* dest = T0 + T1 + CF. */
373
static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
375
tcg_gen_add_i32(dest, t0, t1);
376
tcg_gen_add_i32(dest, dest, cpu_CF);
379
/* dest = T0 - T1 + CF - 1. */
380
static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
382
tcg_gen_sub_i32(dest, t0, t1);
383
tcg_gen_add_i32(dest, dest, cpu_CF);
384
tcg_gen_subi_i32(dest, dest, 1);
387
/* dest = T0 + T1. Compute C, N, V and Z flags */
388
static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
390
TCGv_i32 tmp = tcg_temp_new_i32();
391
tcg_gen_movi_i32(tmp, 0);
392
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
393
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
394
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
395
tcg_gen_xor_i32(tmp, t0, t1);
396
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
397
tcg_temp_free_i32(tmp);
398
tcg_gen_mov_i32(dest, cpu_NF);
401
/* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
402
static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
404
TCGv_i32 tmp = tcg_temp_new_i32();
405
if (TCG_TARGET_HAS_add2_i32) {
406
tcg_gen_movi_i32(tmp, 0);
407
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
408
tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
410
TCGv_i64 q0 = tcg_temp_new_i64();
411
TCGv_i64 q1 = tcg_temp_new_i64();
412
tcg_gen_extu_i32_i64(q0, t0);
413
tcg_gen_extu_i32_i64(q1, t1);
414
tcg_gen_add_i64(q0, q0, q1);
415
tcg_gen_extu_i32_i64(q1, cpu_CF);
416
tcg_gen_add_i64(q0, q0, q1);
417
tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
418
tcg_temp_free_i64(q0);
419
tcg_temp_free_i64(q1);
421
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
422
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
423
tcg_gen_xor_i32(tmp, t0, t1);
424
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
425
tcg_temp_free_i32(tmp);
426
tcg_gen_mov_i32(dest, cpu_NF);
429
/* dest = T0 - T1. Compute C, N, V and Z flags */
430
static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
433
tcg_gen_sub_i32(cpu_NF, t0, t1);
434
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
435
tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
436
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
437
tmp = tcg_temp_new_i32();
438
tcg_gen_xor_i32(tmp, t0, t1);
439
tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
440
tcg_temp_free_i32(tmp);
441
tcg_gen_mov_i32(dest, cpu_NF);
444
/* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
445
static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
447
TCGv_i32 tmp = tcg_temp_new_i32();
448
tcg_gen_not_i32(tmp, t1);
449
gen_adc_CC(dest, t0, tmp);
450
tcg_temp_free_i32(tmp);
453
#define GEN_SHIFT(name) \
454
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
456
TCGv_i32 tmp1, tmp2, tmp3; \
457
tmp1 = tcg_temp_new_i32(); \
458
tcg_gen_andi_i32(tmp1, t1, 0xff); \
459
tmp2 = tcg_const_i32(0); \
460
tmp3 = tcg_const_i32(0x1f); \
461
tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
462
tcg_temp_free_i32(tmp3); \
463
tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
464
tcg_gen_##name##_i32(dest, tmp2, tmp1); \
465
tcg_temp_free_i32(tmp2); \
466
tcg_temp_free_i32(tmp1); \
472
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
475
tmp1 = tcg_temp_new_i32();
476
tcg_gen_andi_i32(tmp1, t1, 0xff);
477
tmp2 = tcg_const_i32(0x1f);
478
tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
479
tcg_temp_free_i32(tmp2);
480
tcg_gen_sar_i32(dest, t0, tmp1);
481
tcg_temp_free_i32(tmp1);
484
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
486
TCGv_i32 c0 = tcg_const_i32(0);
487
TCGv_i32 tmp = tcg_temp_new_i32();
488
tcg_gen_neg_i32(tmp, src);
489
tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
490
tcg_temp_free_i32(c0);
491
tcg_temp_free_i32(tmp);
494
static void shifter_out_im(TCGv_i32 var, int shift)
497
tcg_gen_andi_i32(cpu_CF, var, 1);
499
tcg_gen_shri_i32(cpu_CF, var, shift);
501
tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
506
/* Shift by immediate. Includes special handling for shift == 0. */
507
static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
508
int shift, int flags)
514
shifter_out_im(var, 32 - shift);
515
tcg_gen_shli_i32(var, var, shift);
521
tcg_gen_shri_i32(cpu_CF, var, 31);
523
tcg_gen_movi_i32(var, 0);
526
shifter_out_im(var, shift - 1);
527
tcg_gen_shri_i32(var, var, shift);
534
shifter_out_im(var, shift - 1);
537
tcg_gen_sari_i32(var, var, shift);
539
case 3: /* ROR/RRX */
542
shifter_out_im(var, shift - 1);
543
tcg_gen_rotri_i32(var, var, shift); break;
545
TCGv_i32 tmp = tcg_temp_new_i32();
546
tcg_gen_shli_i32(tmp, cpu_CF, 31);
548
shifter_out_im(var, 0);
549
tcg_gen_shri_i32(var, var, 1);
550
tcg_gen_or_i32(var, var, tmp);
551
tcg_temp_free_i32(tmp);
556
static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
557
TCGv_i32 shift, int flags)
561
case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
562
case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
563
case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
564
case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
569
gen_shl(var, var, shift);
572
gen_shr(var, var, shift);
575
gen_sar(var, var, shift);
577
case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
578
tcg_gen_rotr_i32(var, var, shift); break;
581
tcg_temp_free_i32(shift);
584
#define PAS_OP(pfx) \
586
case 0: gen_pas_helper(glue(pfx,add16)); break; \
587
case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
588
case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
589
case 3: gen_pas_helper(glue(pfx,sub16)); break; \
590
case 4: gen_pas_helper(glue(pfx,add8)); break; \
591
case 7: gen_pas_helper(glue(pfx,sub8)); break; \
593
static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
598
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
600
tmp = tcg_temp_new_ptr();
601
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
603
tcg_temp_free_ptr(tmp);
606
tmp = tcg_temp_new_ptr();
607
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
609
tcg_temp_free_ptr(tmp);
611
#undef gen_pas_helper
612
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
625
#undef gen_pas_helper
630
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
631
#define PAS_OP(pfx) \
633
case 0: gen_pas_helper(glue(pfx,add8)); break; \
634
case 1: gen_pas_helper(glue(pfx,add16)); break; \
635
case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
636
case 4: gen_pas_helper(glue(pfx,sub8)); break; \
637
case 5: gen_pas_helper(glue(pfx,sub16)); break; \
638
case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
640
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
645
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
647
tmp = tcg_temp_new_ptr();
648
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
650
tcg_temp_free_ptr(tmp);
653
tmp = tcg_temp_new_ptr();
654
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
656
tcg_temp_free_ptr(tmp);
658
#undef gen_pas_helper
659
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
672
#undef gen_pas_helper
678
* generate a conditional branch based on ARM condition code cc.
679
* This is common between ARM and Aarch64 targets.
681
void arm_gen_test_cc(int cc, int label)
688
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
691
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
694
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
697
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
700
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
703
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
706
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
709
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
711
case 8: /* hi: C && !Z */
712
inv = gen_new_label();
713
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
714
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
717
case 9: /* ls: !C || Z */
718
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
719
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
721
case 10: /* ge: N == V -> N ^ V == 0 */
722
tmp = tcg_temp_new_i32();
723
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
724
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
725
tcg_temp_free_i32(tmp);
727
case 11: /* lt: N != V -> N ^ V != 0 */
728
tmp = tcg_temp_new_i32();
729
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
730
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
731
tcg_temp_free_i32(tmp);
733
case 12: /* gt: !Z && N == V */
734
inv = gen_new_label();
735
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
736
tmp = tcg_temp_new_i32();
737
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
738
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
739
tcg_temp_free_i32(tmp);
742
case 13: /* le: Z || N != V */
743
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
744
tmp = tcg_temp_new_i32();
745
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
746
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
747
tcg_temp_free_i32(tmp);
750
fprintf(stderr, "Bad condition code 0x%x\n", cc);
755
static const uint8_t table_logic_cc[16] = {
774
/* Set PC and Thumb state from an immediate address. */
775
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
779
s->is_jmp = DISAS_UPDATE;
780
if (s->thumb != (addr & 1)) {
781
tmp = tcg_temp_new_i32();
782
tcg_gen_movi_i32(tmp, addr & 1);
783
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
784
tcg_temp_free_i32(tmp);
786
tcg_gen_movi_i32(cpu_R[15], addr & ~1);
789
/* Set PC and Thumb state from var. var is marked as dead. */
790
static inline void gen_bx(DisasContext *s, TCGv_i32 var)
792
s->is_jmp = DISAS_UPDATE;
793
tcg_gen_andi_i32(cpu_R[15], var, ~1);
794
tcg_gen_andi_i32(var, var, 1);
795
store_cpu_field(var, thumb);
798
/* Variant of store_reg which uses branch&exchange logic when storing
799
to r15 in ARM architecture v7 and above. The source must be a temporary
800
and will be marked as dead. */
801
static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
802
int reg, TCGv_i32 var)
804
if (reg == 15 && ENABLE_ARCH_7) {
807
store_reg(s, reg, var);
811
/* Variant of store_reg which uses branch&exchange logic when storing
812
* to r15 in ARM architecture v5T and above. This is used for storing
813
* the results of a LDR/LDM/POP into r15, and corresponds to the cases
814
* in the ARM ARM which use the LoadWritePC() pseudocode function. */
815
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
816
int reg, TCGv_i32 var)
818
if (reg == 15 && ENABLE_ARCH_5) {
821
store_reg(s, reg, var);
825
/* Abstractions of "generate code to do a guest load/store for
826
* AArch32", where a vaddr is always 32 bits (and is zero
827
* extended if we're a 64 bit core) and data is also
828
* 32 bits unless specifically doing a 64 bit access.
829
* These functions work like tcg_gen_qemu_{ld,st}* except
830
* that the address argument is TCGv_i32 rather than TCGv.
832
#if TARGET_LONG_BITS == 32
834
#define DO_GEN_LD(SUFF, OPC) \
835
static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
837
tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
840
#define DO_GEN_ST(SUFF, OPC) \
841
static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
843
tcg_gen_qemu_st_i32(val, addr, index, OPC); \
846
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
848
tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
851
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
853
tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
858
#define DO_GEN_LD(SUFF, OPC) \
859
static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
861
TCGv addr64 = tcg_temp_new(); \
862
tcg_gen_extu_i32_i64(addr64, addr); \
863
tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
864
tcg_temp_free(addr64); \
867
#define DO_GEN_ST(SUFF, OPC) \
868
static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
870
TCGv addr64 = tcg_temp_new(); \
871
tcg_gen_extu_i32_i64(addr64, addr); \
872
tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
873
tcg_temp_free(addr64); \
876
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
878
TCGv addr64 = tcg_temp_new();
879
tcg_gen_extu_i32_i64(addr64, addr);
880
tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
881
tcg_temp_free(addr64);
884
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
886
TCGv addr64 = tcg_temp_new();
887
tcg_gen_extu_i32_i64(addr64, addr);
888
tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
889
tcg_temp_free(addr64);
896
DO_GEN_LD(16s, MO_TESW)
897
DO_GEN_LD(16u, MO_TEUW)
898
DO_GEN_LD(32u, MO_TEUL)
900
DO_GEN_ST(16, MO_TEUW)
901
DO_GEN_ST(32, MO_TEUL)
903
static inline void gen_smc(CPUARMState *env, DisasContext *s)
905
tcg_gen_movi_i32(cpu_R[15], s->pc);
906
s->is_jmp = DISAS_SMC;
909
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
911
tcg_gen_movi_i32(cpu_R[15], val);
914
/* Force a TB lookup after an instruction that changes the CPU state. */
915
static inline void gen_lookup_tb(DisasContext *s)
917
tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
918
s->is_jmp = DISAS_UPDATE;
921
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
924
int val, rm, shift, shiftop;
927
if (!(insn & (1 << 25))) {
930
if (!(insn & (1 << 23)))
933
tcg_gen_addi_i32(var, var, val);
937
shift = (insn >> 7) & 0x1f;
938
shiftop = (insn >> 5) & 3;
939
offset = load_reg(s, rm);
940
gen_arm_shift_im(offset, shiftop, shift, 0);
941
if (!(insn & (1 << 23)))
942
tcg_gen_sub_i32(var, var, offset);
944
tcg_gen_add_i32(var, var, offset);
945
tcg_temp_free_i32(offset);
949
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
950
int extra, TCGv_i32 var)
955
if (insn & (1 << 22)) {
957
val = (insn & 0xf) | ((insn >> 4) & 0xf0);
958
if (!(insn & (1 << 23)))
962
tcg_gen_addi_i32(var, var, val);
966
tcg_gen_addi_i32(var, var, extra);
968
offset = load_reg(s, rm);
969
if (!(insn & (1 << 23)))
970
tcg_gen_sub_i32(var, var, offset);
972
tcg_gen_add_i32(var, var, offset);
973
tcg_temp_free_i32(offset);
977
static TCGv_ptr get_fpstatus_ptr(int neon)
979
TCGv_ptr statusptr = tcg_temp_new_ptr();
982
offset = offsetof(CPUARMState, vfp.standard_fp_status);
984
offset = offsetof(CPUARMState, vfp.fp_status);
986
tcg_gen_addi_ptr(statusptr, cpu_env, offset);
990
#define VFP_OP2(name) \
991
static inline void gen_vfp_##name(int dp) \
993
TCGv_ptr fpst = get_fpstatus_ptr(0); \
995
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
997
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
999
tcg_temp_free_ptr(fpst); \
1009
static inline void gen_vfp_F1_mul(int dp)
1011
/* Like gen_vfp_mul() but put result in F1 */
1012
TCGv_ptr fpst = get_fpstatus_ptr(0);
1014
gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1016
gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1018
tcg_temp_free_ptr(fpst);
1021
static inline void gen_vfp_F1_neg(int dp)
1023
/* Like gen_vfp_neg() but put result in F1 */
1025
gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1027
gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1031
static inline void gen_vfp_abs(int dp)
1034
gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1036
gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1039
static inline void gen_vfp_neg(int dp)
1042
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1044
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1047
static inline void gen_vfp_sqrt(int dp)
1050
gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1052
gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1055
static inline void gen_vfp_cmp(int dp)
1058
gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1060
gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1063
static inline void gen_vfp_cmpe(int dp)
1066
gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1068
gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1071
static inline void gen_vfp_F1_ld0(int dp)
1074
tcg_gen_movi_i64(cpu_F1d, 0);
1076
tcg_gen_movi_i32(cpu_F1s, 0);
1079
#define VFP_GEN_ITOF(name) \
1080
static inline void gen_vfp_##name(int dp, int neon) \
1082
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1084
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1086
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1088
tcg_temp_free_ptr(statusptr); \
1095
#define VFP_GEN_FTOI(name) \
1096
static inline void gen_vfp_##name(int dp, int neon) \
1098
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1100
gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1102
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1104
tcg_temp_free_ptr(statusptr); \
1113
#define VFP_GEN_FIX(name, round) \
1114
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1116
TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1117
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1119
gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1122
gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1125
tcg_temp_free_i32(tmp_shift); \
1126
tcg_temp_free_ptr(statusptr); \
1128
VFP_GEN_FIX(tosh, _round_to_zero)
1129
VFP_GEN_FIX(tosl, _round_to_zero)
1130
VFP_GEN_FIX(touh, _round_to_zero)
1131
VFP_GEN_FIX(toul, _round_to_zero)
1138
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1141
gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1143
gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1147
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1150
gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1152
gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1157
vfp_reg_offset (int dp, int reg)
1160
return offsetof(CPUARMState, vfp.regs[reg]);
1162
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1163
+ offsetof(CPU_DoubleU, l.upper);
1165
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1166
+ offsetof(CPU_DoubleU, l.lower);
1170
/* Return the offset of a 32-bit piece of a NEON register.
1171
zero is the least significant end of the register. */
1173
neon_reg_offset (int reg, int n)
1177
return vfp_reg_offset(0, sreg);
1180
static TCGv_i32 neon_load_reg(int reg, int pass)
1182
TCGv_i32 tmp = tcg_temp_new_i32();
1183
tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1187
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1189
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1190
tcg_temp_free_i32(var);
1193
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1195
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1198
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1200
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1203
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1204
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1205
#define tcg_gen_st_f32 tcg_gen_st_i32
1206
#define tcg_gen_st_f64 tcg_gen_st_i64
1208
static inline void gen_mov_F0_vreg(int dp, int reg)
1211
tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1213
tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1216
static inline void gen_mov_F1_vreg(int dp, int reg)
1219
tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1221
tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1224
static inline void gen_mov_vreg_F0(int dp, int reg)
1227
tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1229
tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1232
#define ARM_CP_RW_BIT (1 << 20)
1234
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1236
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1239
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1241
tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1244
static inline TCGv_i32 iwmmxt_load_creg(int reg)
1246
TCGv_i32 var = tcg_temp_new_i32();
1247
tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1251
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1253
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1254
tcg_temp_free_i32(var);
1257
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1259
iwmmxt_store_reg(cpu_M0, rn);
1262
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1264
iwmmxt_load_reg(cpu_M0, rn);
1267
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1269
iwmmxt_load_reg(cpu_V1, rn);
1270
tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1273
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1275
iwmmxt_load_reg(cpu_V1, rn);
1276
tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1279
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1281
iwmmxt_load_reg(cpu_V1, rn);
1282
tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1285
#define IWMMXT_OP(name) \
1286
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1288
iwmmxt_load_reg(cpu_V1, rn); \
1289
gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1292
#define IWMMXT_OP_ENV(name) \
1293
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1295
iwmmxt_load_reg(cpu_V1, rn); \
1296
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1299
#define IWMMXT_OP_ENV_SIZE(name) \
1300
IWMMXT_OP_ENV(name##b) \
1301
IWMMXT_OP_ENV(name##w) \
1302
IWMMXT_OP_ENV(name##l)
1304
#define IWMMXT_OP_ENV1(name) \
1305
static inline void gen_op_iwmmxt_##name##_M0(void) \
1307
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1321
IWMMXT_OP_ENV_SIZE(unpackl)
1322
IWMMXT_OP_ENV_SIZE(unpackh)
1324
IWMMXT_OP_ENV1(unpacklub)
1325
IWMMXT_OP_ENV1(unpackluw)
1326
IWMMXT_OP_ENV1(unpacklul)
1327
IWMMXT_OP_ENV1(unpackhub)
1328
IWMMXT_OP_ENV1(unpackhuw)
1329
IWMMXT_OP_ENV1(unpackhul)
1330
IWMMXT_OP_ENV1(unpacklsb)
1331
IWMMXT_OP_ENV1(unpacklsw)
1332
IWMMXT_OP_ENV1(unpacklsl)
1333
IWMMXT_OP_ENV1(unpackhsb)
1334
IWMMXT_OP_ENV1(unpackhsw)
1335
IWMMXT_OP_ENV1(unpackhsl)
1337
IWMMXT_OP_ENV_SIZE(cmpeq)
1338
IWMMXT_OP_ENV_SIZE(cmpgtu)
1339
IWMMXT_OP_ENV_SIZE(cmpgts)
1341
IWMMXT_OP_ENV_SIZE(mins)
1342
IWMMXT_OP_ENV_SIZE(minu)
1343
IWMMXT_OP_ENV_SIZE(maxs)
1344
IWMMXT_OP_ENV_SIZE(maxu)
1346
IWMMXT_OP_ENV_SIZE(subn)
1347
IWMMXT_OP_ENV_SIZE(addn)
1348
IWMMXT_OP_ENV_SIZE(subu)
1349
IWMMXT_OP_ENV_SIZE(addu)
1350
IWMMXT_OP_ENV_SIZE(subs)
1351
IWMMXT_OP_ENV_SIZE(adds)
1353
IWMMXT_OP_ENV(avgb0)
1354
IWMMXT_OP_ENV(avgb1)
1355
IWMMXT_OP_ENV(avgw0)
1356
IWMMXT_OP_ENV(avgw1)
1360
IWMMXT_OP_ENV(packuw)
1361
IWMMXT_OP_ENV(packul)
1362
IWMMXT_OP_ENV(packuq)
1363
IWMMXT_OP_ENV(packsw)
1364
IWMMXT_OP_ENV(packsl)
1365
IWMMXT_OP_ENV(packsq)
1367
static void gen_op_iwmmxt_set_mup(void)
1370
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1371
tcg_gen_ori_i32(tmp, tmp, 2);
1372
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1375
static void gen_op_iwmmxt_set_cup(void)
1378
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1379
tcg_gen_ori_i32(tmp, tmp, 1);
1380
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1383
static void gen_op_iwmmxt_setpsr_nz(void)
1385
TCGv_i32 tmp = tcg_temp_new_i32();
1386
gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1387
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1390
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1392
iwmmxt_load_reg(cpu_V1, rn);
1393
tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1394
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1397
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1404
rd = (insn >> 16) & 0xf;
1405
tmp = load_reg(s, rd);
1407
offset = (insn & 0xff) << ((insn >> 7) & 2);
1408
if (insn & (1 << 24)) {
1410
if (insn & (1 << 23))
1411
tcg_gen_addi_i32(tmp, tmp, offset);
1413
tcg_gen_addi_i32(tmp, tmp, -offset);
1414
tcg_gen_mov_i32(dest, tmp);
1415
if (insn & (1 << 21))
1416
store_reg(s, rd, tmp);
1418
tcg_temp_free_i32(tmp);
1419
} else if (insn & (1 << 21)) {
1421
tcg_gen_mov_i32(dest, tmp);
1422
if (insn & (1 << 23))
1423
tcg_gen_addi_i32(tmp, tmp, offset);
1425
tcg_gen_addi_i32(tmp, tmp, -offset);
1426
store_reg(s, rd, tmp);
1427
} else if (!(insn & (1 << 23)))
1432
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1434
int rd = (insn >> 0) & 0xf;
1437
if (insn & (1 << 8)) {
1438
if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1441
tmp = iwmmxt_load_creg(rd);
1444
tmp = tcg_temp_new_i32();
1445
iwmmxt_load_reg(cpu_V0, rd);
1446
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1448
tcg_gen_andi_i32(tmp, tmp, mask);
1449
tcg_gen_mov_i32(dest, tmp);
1450
tcg_temp_free_i32(tmp);
1454
/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1455
(ie. an undefined instruction). */
1456
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1459
int rdhi, rdlo, rd0, rd1, i;
1461
TCGv_i32 tmp, tmp2, tmp3;
1463
if ((insn & 0x0e000e00) == 0x0c000000) {
1464
if ((insn & 0x0fe00ff0) == 0x0c400000) {
1466
rdlo = (insn >> 12) & 0xf;
1467
rdhi = (insn >> 16) & 0xf;
1468
if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1469
iwmmxt_load_reg(cpu_V0, wrd);
1470
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1471
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1472
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1473
} else { /* TMCRR */
1474
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1475
iwmmxt_store_reg(cpu_V0, wrd);
1476
gen_op_iwmmxt_set_mup();
1481
wrd = (insn >> 12) & 0xf;
1482
addr = tcg_temp_new_i32();
1483
if (gen_iwmmxt_address(s, insn, addr)) {
1484
tcg_temp_free_i32(addr);
1487
if (insn & ARM_CP_RW_BIT) {
1488
if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1489
tmp = tcg_temp_new_i32();
1490
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1491
iwmmxt_store_creg(wrd, tmp);
1494
if (insn & (1 << 8)) {
1495
if (insn & (1 << 22)) { /* WLDRD */
1496
gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1498
} else { /* WLDRW wRd */
1499
tmp = tcg_temp_new_i32();
1500
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1503
tmp = tcg_temp_new_i32();
1504
if (insn & (1 << 22)) { /* WLDRH */
1505
gen_aa32_ld16u(tmp, addr, IS_USER(s));
1506
} else { /* WLDRB */
1507
gen_aa32_ld8u(tmp, addr, IS_USER(s));
1511
tcg_gen_extu_i32_i64(cpu_M0, tmp);
1512
tcg_temp_free_i32(tmp);
1514
gen_op_iwmmxt_movq_wRn_M0(wrd);
1517
if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1518
tmp = iwmmxt_load_creg(wrd);
1519
gen_aa32_st32(tmp, addr, IS_USER(s));
1521
gen_op_iwmmxt_movq_M0_wRn(wrd);
1522
tmp = tcg_temp_new_i32();
1523
if (insn & (1 << 8)) {
1524
if (insn & (1 << 22)) { /* WSTRD */
1525
gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1526
} else { /* WSTRW wRd */
1527
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1528
gen_aa32_st32(tmp, addr, IS_USER(s));
1531
if (insn & (1 << 22)) { /* WSTRH */
1532
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1533
gen_aa32_st16(tmp, addr, IS_USER(s));
1534
} else { /* WSTRB */
1535
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1536
gen_aa32_st8(tmp, addr, IS_USER(s));
1540
tcg_temp_free_i32(tmp);
1542
tcg_temp_free_i32(addr);
1546
if ((insn & 0x0f000000) != 0x0e000000)
1549
switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1550
case 0x000: /* WOR */
1551
wrd = (insn >> 12) & 0xf;
1552
rd0 = (insn >> 0) & 0xf;
1553
rd1 = (insn >> 16) & 0xf;
1554
gen_op_iwmmxt_movq_M0_wRn(rd0);
1555
gen_op_iwmmxt_orq_M0_wRn(rd1);
1556
gen_op_iwmmxt_setpsr_nz();
1557
gen_op_iwmmxt_movq_wRn_M0(wrd);
1558
gen_op_iwmmxt_set_mup();
1559
gen_op_iwmmxt_set_cup();
1561
case 0x011: /* TMCR */
1564
rd = (insn >> 12) & 0xf;
1565
wrd = (insn >> 16) & 0xf;
1567
case ARM_IWMMXT_wCID:
1568
case ARM_IWMMXT_wCASF:
1570
case ARM_IWMMXT_wCon:
1571
gen_op_iwmmxt_set_cup();
1573
case ARM_IWMMXT_wCSSF:
1574
tmp = iwmmxt_load_creg(wrd);
1575
tmp2 = load_reg(s, rd);
1576
tcg_gen_andc_i32(tmp, tmp, tmp2);
1577
tcg_temp_free_i32(tmp2);
1578
iwmmxt_store_creg(wrd, tmp);
1580
case ARM_IWMMXT_wCGR0:
1581
case ARM_IWMMXT_wCGR1:
1582
case ARM_IWMMXT_wCGR2:
1583
case ARM_IWMMXT_wCGR3:
1584
gen_op_iwmmxt_set_cup();
1585
tmp = load_reg(s, rd);
1586
iwmmxt_store_creg(wrd, tmp);
1592
case 0x100: /* WXOR */
1593
wrd = (insn >> 12) & 0xf;
1594
rd0 = (insn >> 0) & 0xf;
1595
rd1 = (insn >> 16) & 0xf;
1596
gen_op_iwmmxt_movq_M0_wRn(rd0);
1597
gen_op_iwmmxt_xorq_M0_wRn(rd1);
1598
gen_op_iwmmxt_setpsr_nz();
1599
gen_op_iwmmxt_movq_wRn_M0(wrd);
1600
gen_op_iwmmxt_set_mup();
1601
gen_op_iwmmxt_set_cup();
1603
case 0x111: /* TMRC */
1606
rd = (insn >> 12) & 0xf;
1607
wrd = (insn >> 16) & 0xf;
1608
tmp = iwmmxt_load_creg(wrd);
1609
store_reg(s, rd, tmp);
1611
case 0x300: /* WANDN */
1612
wrd = (insn >> 12) & 0xf;
1613
rd0 = (insn >> 0) & 0xf;
1614
rd1 = (insn >> 16) & 0xf;
1615
gen_op_iwmmxt_movq_M0_wRn(rd0);
1616
tcg_gen_neg_i64(cpu_M0, cpu_M0);
1617
gen_op_iwmmxt_andq_M0_wRn(rd1);
1618
gen_op_iwmmxt_setpsr_nz();
1619
gen_op_iwmmxt_movq_wRn_M0(wrd);
1620
gen_op_iwmmxt_set_mup();
1621
gen_op_iwmmxt_set_cup();
1623
case 0x200: /* WAND */
1624
wrd = (insn >> 12) & 0xf;
1625
rd0 = (insn >> 0) & 0xf;
1626
rd1 = (insn >> 16) & 0xf;
1627
gen_op_iwmmxt_movq_M0_wRn(rd0);
1628
gen_op_iwmmxt_andq_M0_wRn(rd1);
1629
gen_op_iwmmxt_setpsr_nz();
1630
gen_op_iwmmxt_movq_wRn_M0(wrd);
1631
gen_op_iwmmxt_set_mup();
1632
gen_op_iwmmxt_set_cup();
1634
case 0x810: case 0xa10: /* WMADD */
1635
wrd = (insn >> 12) & 0xf;
1636
rd0 = (insn >> 0) & 0xf;
1637
rd1 = (insn >> 16) & 0xf;
1638
gen_op_iwmmxt_movq_M0_wRn(rd0);
1639
if (insn & (1 << 21))
1640
gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1642
gen_op_iwmmxt_madduq_M0_wRn(rd1);
1643
gen_op_iwmmxt_movq_wRn_M0(wrd);
1644
gen_op_iwmmxt_set_mup();
1646
case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1647
wrd = (insn >> 12) & 0xf;
1648
rd0 = (insn >> 16) & 0xf;
1649
rd1 = (insn >> 0) & 0xf;
1650
gen_op_iwmmxt_movq_M0_wRn(rd0);
1651
switch ((insn >> 22) & 3) {
1653
gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1656
gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1659
gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1664
gen_op_iwmmxt_movq_wRn_M0(wrd);
1665
gen_op_iwmmxt_set_mup();
1666
gen_op_iwmmxt_set_cup();
1668
case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1669
wrd = (insn >> 12) & 0xf;
1670
rd0 = (insn >> 16) & 0xf;
1671
rd1 = (insn >> 0) & 0xf;
1672
gen_op_iwmmxt_movq_M0_wRn(rd0);
1673
switch ((insn >> 22) & 3) {
1675
gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1678
gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1681
gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1686
gen_op_iwmmxt_movq_wRn_M0(wrd);
1687
gen_op_iwmmxt_set_mup();
1688
gen_op_iwmmxt_set_cup();
1690
case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1691
wrd = (insn >> 12) & 0xf;
1692
rd0 = (insn >> 16) & 0xf;
1693
rd1 = (insn >> 0) & 0xf;
1694
gen_op_iwmmxt_movq_M0_wRn(rd0);
1695
if (insn & (1 << 22))
1696
gen_op_iwmmxt_sadw_M0_wRn(rd1);
1698
gen_op_iwmmxt_sadb_M0_wRn(rd1);
1699
if (!(insn & (1 << 20)))
1700
gen_op_iwmmxt_addl_M0_wRn(wrd);
1701
gen_op_iwmmxt_movq_wRn_M0(wrd);
1702
gen_op_iwmmxt_set_mup();
1704
case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1705
wrd = (insn >> 12) & 0xf;
1706
rd0 = (insn >> 16) & 0xf;
1707
rd1 = (insn >> 0) & 0xf;
1708
gen_op_iwmmxt_movq_M0_wRn(rd0);
1709
if (insn & (1 << 21)) {
1710
if (insn & (1 << 20))
1711
gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1713
gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1715
if (insn & (1 << 20))
1716
gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1718
gen_op_iwmmxt_mululw_M0_wRn(rd1);
1720
gen_op_iwmmxt_movq_wRn_M0(wrd);
1721
gen_op_iwmmxt_set_mup();
1723
case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1724
wrd = (insn >> 12) & 0xf;
1725
rd0 = (insn >> 16) & 0xf;
1726
rd1 = (insn >> 0) & 0xf;
1727
gen_op_iwmmxt_movq_M0_wRn(rd0);
1728
if (insn & (1 << 21))
1729
gen_op_iwmmxt_macsw_M0_wRn(rd1);
1731
gen_op_iwmmxt_macuw_M0_wRn(rd1);
1732
if (!(insn & (1 << 20))) {
1733
iwmmxt_load_reg(cpu_V1, wrd);
1734
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1736
gen_op_iwmmxt_movq_wRn_M0(wrd);
1737
gen_op_iwmmxt_set_mup();
1739
case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1740
wrd = (insn >> 12) & 0xf;
1741
rd0 = (insn >> 16) & 0xf;
1742
rd1 = (insn >> 0) & 0xf;
1743
gen_op_iwmmxt_movq_M0_wRn(rd0);
1744
switch ((insn >> 22) & 3) {
1746
gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1749
gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1752
gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1757
gen_op_iwmmxt_movq_wRn_M0(wrd);
1758
gen_op_iwmmxt_set_mup();
1759
gen_op_iwmmxt_set_cup();
1761
case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1762
wrd = (insn >> 12) & 0xf;
1763
rd0 = (insn >> 16) & 0xf;
1764
rd1 = (insn >> 0) & 0xf;
1765
gen_op_iwmmxt_movq_M0_wRn(rd0);
1766
if (insn & (1 << 22)) {
1767
if (insn & (1 << 20))
1768
gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1770
gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1772
if (insn & (1 << 20))
1773
gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1775
gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1777
gen_op_iwmmxt_movq_wRn_M0(wrd);
1778
gen_op_iwmmxt_set_mup();
1779
gen_op_iwmmxt_set_cup();
1781
case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1782
wrd = (insn >> 12) & 0xf;
1783
rd0 = (insn >> 16) & 0xf;
1784
rd1 = (insn >> 0) & 0xf;
1785
gen_op_iwmmxt_movq_M0_wRn(rd0);
1786
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1787
tcg_gen_andi_i32(tmp, tmp, 7);
1788
iwmmxt_load_reg(cpu_V1, rd1);
1789
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1790
tcg_temp_free_i32(tmp);
1791
gen_op_iwmmxt_movq_wRn_M0(wrd);
1792
gen_op_iwmmxt_set_mup();
1794
case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1795
if (((insn >> 6) & 3) == 3)
1797
rd = (insn >> 12) & 0xf;
1798
wrd = (insn >> 16) & 0xf;
1799
tmp = load_reg(s, rd);
1800
gen_op_iwmmxt_movq_M0_wRn(wrd);
1801
switch ((insn >> 6) & 3) {
1803
tmp2 = tcg_const_i32(0xff);
1804
tmp3 = tcg_const_i32((insn & 7) << 3);
1807
tmp2 = tcg_const_i32(0xffff);
1808
tmp3 = tcg_const_i32((insn & 3) << 4);
1811
tmp2 = tcg_const_i32(0xffffffff);
1812
tmp3 = tcg_const_i32((insn & 1) << 5);
1815
TCGV_UNUSED_I32(tmp2);
1816
TCGV_UNUSED_I32(tmp3);
1818
gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1819
tcg_temp_free_i32(tmp3);
1820
tcg_temp_free_i32(tmp2);
1821
tcg_temp_free_i32(tmp);
1822
gen_op_iwmmxt_movq_wRn_M0(wrd);
1823
gen_op_iwmmxt_set_mup();
1825
case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1826
rd = (insn >> 12) & 0xf;
1827
wrd = (insn >> 16) & 0xf;
1828
if (rd == 15 || ((insn >> 22) & 3) == 3)
1830
gen_op_iwmmxt_movq_M0_wRn(wrd);
1831
tmp = tcg_temp_new_i32();
1832
switch ((insn >> 22) & 3) {
1834
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1835
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1837
tcg_gen_ext8s_i32(tmp, tmp);
1839
tcg_gen_andi_i32(tmp, tmp, 0xff);
1843
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1844
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1846
tcg_gen_ext16s_i32(tmp, tmp);
1848
tcg_gen_andi_i32(tmp, tmp, 0xffff);
1852
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1853
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1856
store_reg(s, rd, tmp);
1858
case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1859
if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1861
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1862
switch ((insn >> 22) & 3) {
1864
tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1867
tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1870
tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1873
tcg_gen_shli_i32(tmp, tmp, 28);
1875
tcg_temp_free_i32(tmp);
1877
case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1878
if (((insn >> 6) & 3) == 3)
1880
rd = (insn >> 12) & 0xf;
1881
wrd = (insn >> 16) & 0xf;
1882
tmp = load_reg(s, rd);
1883
switch ((insn >> 6) & 3) {
1885
gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1888
gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1891
gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1894
tcg_temp_free_i32(tmp);
1895
gen_op_iwmmxt_movq_wRn_M0(wrd);
1896
gen_op_iwmmxt_set_mup();
1898
case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1899
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1901
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1902
tmp2 = tcg_temp_new_i32();
1903
tcg_gen_mov_i32(tmp2, tmp);
1904
switch ((insn >> 22) & 3) {
1906
for (i = 0; i < 7; i ++) {
1907
tcg_gen_shli_i32(tmp2, tmp2, 4);
1908
tcg_gen_and_i32(tmp, tmp, tmp2);
1912
for (i = 0; i < 3; i ++) {
1913
tcg_gen_shli_i32(tmp2, tmp2, 8);
1914
tcg_gen_and_i32(tmp, tmp, tmp2);
1918
tcg_gen_shli_i32(tmp2, tmp2, 16);
1919
tcg_gen_and_i32(tmp, tmp, tmp2);
1923
tcg_temp_free_i32(tmp2);
1924
tcg_temp_free_i32(tmp);
1926
case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1927
wrd = (insn >> 12) & 0xf;
1928
rd0 = (insn >> 16) & 0xf;
1929
gen_op_iwmmxt_movq_M0_wRn(rd0);
1930
switch ((insn >> 22) & 3) {
1932
gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1935
gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1938
gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1943
gen_op_iwmmxt_movq_wRn_M0(wrd);
1944
gen_op_iwmmxt_set_mup();
1946
case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1947
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1949
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1950
tmp2 = tcg_temp_new_i32();
1951
tcg_gen_mov_i32(tmp2, tmp);
1952
switch ((insn >> 22) & 3) {
1954
for (i = 0; i < 7; i ++) {
1955
tcg_gen_shli_i32(tmp2, tmp2, 4);
1956
tcg_gen_or_i32(tmp, tmp, tmp2);
1960
for (i = 0; i < 3; i ++) {
1961
tcg_gen_shli_i32(tmp2, tmp2, 8);
1962
tcg_gen_or_i32(tmp, tmp, tmp2);
1966
tcg_gen_shli_i32(tmp2, tmp2, 16);
1967
tcg_gen_or_i32(tmp, tmp, tmp2);
1971
tcg_temp_free_i32(tmp2);
1972
tcg_temp_free_i32(tmp);
1974
case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1975
rd = (insn >> 12) & 0xf;
1976
rd0 = (insn >> 16) & 0xf;
1977
if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1979
gen_op_iwmmxt_movq_M0_wRn(rd0);
1980
tmp = tcg_temp_new_i32();
1981
switch ((insn >> 22) & 3) {
1983
gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1986
gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1989
gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1992
store_reg(s, rd, tmp);
1994
case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1995
case 0x906: case 0xb06: case 0xd06: case 0xf06:
1996
wrd = (insn >> 12) & 0xf;
1997
rd0 = (insn >> 16) & 0xf;
1998
rd1 = (insn >> 0) & 0xf;
1999
gen_op_iwmmxt_movq_M0_wRn(rd0);
2000
switch ((insn >> 22) & 3) {
2002
if (insn & (1 << 21))
2003
gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2005
gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2008
if (insn & (1 << 21))
2009
gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2011
gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2014
if (insn & (1 << 21))
2015
gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2017
gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2022
gen_op_iwmmxt_movq_wRn_M0(wrd);
2023
gen_op_iwmmxt_set_mup();
2024
gen_op_iwmmxt_set_cup();
2026
case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2027
case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2028
wrd = (insn >> 12) & 0xf;
2029
rd0 = (insn >> 16) & 0xf;
2030
gen_op_iwmmxt_movq_M0_wRn(rd0);
2031
switch ((insn >> 22) & 3) {
2033
if (insn & (1 << 21))
2034
gen_op_iwmmxt_unpacklsb_M0();
2036
gen_op_iwmmxt_unpacklub_M0();
2039
if (insn & (1 << 21))
2040
gen_op_iwmmxt_unpacklsw_M0();
2042
gen_op_iwmmxt_unpackluw_M0();
2045
if (insn & (1 << 21))
2046
gen_op_iwmmxt_unpacklsl_M0();
2048
gen_op_iwmmxt_unpacklul_M0();
2053
gen_op_iwmmxt_movq_wRn_M0(wrd);
2054
gen_op_iwmmxt_set_mup();
2055
gen_op_iwmmxt_set_cup();
2057
case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2058
case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2059
wrd = (insn >> 12) & 0xf;
2060
rd0 = (insn >> 16) & 0xf;
2061
gen_op_iwmmxt_movq_M0_wRn(rd0);
2062
switch ((insn >> 22) & 3) {
2064
if (insn & (1 << 21))
2065
gen_op_iwmmxt_unpackhsb_M0();
2067
gen_op_iwmmxt_unpackhub_M0();
2070
if (insn & (1 << 21))
2071
gen_op_iwmmxt_unpackhsw_M0();
2073
gen_op_iwmmxt_unpackhuw_M0();
2076
if (insn & (1 << 21))
2077
gen_op_iwmmxt_unpackhsl_M0();
2079
gen_op_iwmmxt_unpackhul_M0();
2084
gen_op_iwmmxt_movq_wRn_M0(wrd);
2085
gen_op_iwmmxt_set_mup();
2086
gen_op_iwmmxt_set_cup();
2088
case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2089
case 0x214: case 0x614: case 0xa14: case 0xe14:
2090
if (((insn >> 22) & 3) == 0)
2092
wrd = (insn >> 12) & 0xf;
2093
rd0 = (insn >> 16) & 0xf;
2094
gen_op_iwmmxt_movq_M0_wRn(rd0);
2095
tmp = tcg_temp_new_i32();
2096
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2097
tcg_temp_free_i32(tmp);
2100
switch ((insn >> 22) & 3) {
2102
gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2105
gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2108
gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2111
tcg_temp_free_i32(tmp);
2112
gen_op_iwmmxt_movq_wRn_M0(wrd);
2113
gen_op_iwmmxt_set_mup();
2114
gen_op_iwmmxt_set_cup();
2116
case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2117
case 0x014: case 0x414: case 0x814: case 0xc14:
2118
if (((insn >> 22) & 3) == 0)
2120
wrd = (insn >> 12) & 0xf;
2121
rd0 = (insn >> 16) & 0xf;
2122
gen_op_iwmmxt_movq_M0_wRn(rd0);
2123
tmp = tcg_temp_new_i32();
2124
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2125
tcg_temp_free_i32(tmp);
2128
switch ((insn >> 22) & 3) {
2130
gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2133
gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2136
gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2139
tcg_temp_free_i32(tmp);
2140
gen_op_iwmmxt_movq_wRn_M0(wrd);
2141
gen_op_iwmmxt_set_mup();
2142
gen_op_iwmmxt_set_cup();
2144
case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2145
case 0x114: case 0x514: case 0x914: case 0xd14:
2146
if (((insn >> 22) & 3) == 0)
2148
wrd = (insn >> 12) & 0xf;
2149
rd0 = (insn >> 16) & 0xf;
2150
gen_op_iwmmxt_movq_M0_wRn(rd0);
2151
tmp = tcg_temp_new_i32();
2152
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2153
tcg_temp_free_i32(tmp);
2156
switch ((insn >> 22) & 3) {
2158
gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2161
gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2164
gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2167
tcg_temp_free_i32(tmp);
2168
gen_op_iwmmxt_movq_wRn_M0(wrd);
2169
gen_op_iwmmxt_set_mup();
2170
gen_op_iwmmxt_set_cup();
2172
case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2173
case 0x314: case 0x714: case 0xb14: case 0xf14:
2174
if (((insn >> 22) & 3) == 0)
2176
wrd = (insn >> 12) & 0xf;
2177
rd0 = (insn >> 16) & 0xf;
2178
gen_op_iwmmxt_movq_M0_wRn(rd0);
2179
tmp = tcg_temp_new_i32();
2180
switch ((insn >> 22) & 3) {
2182
if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2183
tcg_temp_free_i32(tmp);
2186
gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2189
if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2190
tcg_temp_free_i32(tmp);
2193
gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2196
if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2197
tcg_temp_free_i32(tmp);
2200
gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2203
tcg_temp_free_i32(tmp);
2204
gen_op_iwmmxt_movq_wRn_M0(wrd);
2205
gen_op_iwmmxt_set_mup();
2206
gen_op_iwmmxt_set_cup();
2208
case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2209
case 0x916: case 0xb16: case 0xd16: case 0xf16:
2210
wrd = (insn >> 12) & 0xf;
2211
rd0 = (insn >> 16) & 0xf;
2212
rd1 = (insn >> 0) & 0xf;
2213
gen_op_iwmmxt_movq_M0_wRn(rd0);
2214
switch ((insn >> 22) & 3) {
2216
if (insn & (1 << 21))
2217
gen_op_iwmmxt_minsb_M0_wRn(rd1);
2219
gen_op_iwmmxt_minub_M0_wRn(rd1);
2222
if (insn & (1 << 21))
2223
gen_op_iwmmxt_minsw_M0_wRn(rd1);
2225
gen_op_iwmmxt_minuw_M0_wRn(rd1);
2228
if (insn & (1 << 21))
2229
gen_op_iwmmxt_minsl_M0_wRn(rd1);
2231
gen_op_iwmmxt_minul_M0_wRn(rd1);
2236
gen_op_iwmmxt_movq_wRn_M0(wrd);
2237
gen_op_iwmmxt_set_mup();
2239
case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2240
case 0x816: case 0xa16: case 0xc16: case 0xe16:
2241
wrd = (insn >> 12) & 0xf;
2242
rd0 = (insn >> 16) & 0xf;
2243
rd1 = (insn >> 0) & 0xf;
2244
gen_op_iwmmxt_movq_M0_wRn(rd0);
2245
switch ((insn >> 22) & 3) {
2247
if (insn & (1 << 21))
2248
gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2250
gen_op_iwmmxt_maxub_M0_wRn(rd1);
2253
if (insn & (1 << 21))
2254
gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2256
gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2259
if (insn & (1 << 21))
2260
gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2262
gen_op_iwmmxt_maxul_M0_wRn(rd1);
2267
gen_op_iwmmxt_movq_wRn_M0(wrd);
2268
gen_op_iwmmxt_set_mup();
2270
case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2271
case 0x402: case 0x502: case 0x602: case 0x702:
2272
wrd = (insn >> 12) & 0xf;
2273
rd0 = (insn >> 16) & 0xf;
2274
rd1 = (insn >> 0) & 0xf;
2275
gen_op_iwmmxt_movq_M0_wRn(rd0);
2276
tmp = tcg_const_i32((insn >> 20) & 3);
2277
iwmmxt_load_reg(cpu_V1, rd1);
2278
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2279
tcg_temp_free_i32(tmp);
2280
gen_op_iwmmxt_movq_wRn_M0(wrd);
2281
gen_op_iwmmxt_set_mup();
2283
case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2284
case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2285
case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2286
case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2287
wrd = (insn >> 12) & 0xf;
2288
rd0 = (insn >> 16) & 0xf;
2289
rd1 = (insn >> 0) & 0xf;
2290
gen_op_iwmmxt_movq_M0_wRn(rd0);
2291
switch ((insn >> 20) & 0xf) {
2293
gen_op_iwmmxt_subnb_M0_wRn(rd1);
2296
gen_op_iwmmxt_subub_M0_wRn(rd1);
2299
gen_op_iwmmxt_subsb_M0_wRn(rd1);
2302
gen_op_iwmmxt_subnw_M0_wRn(rd1);
2305
gen_op_iwmmxt_subuw_M0_wRn(rd1);
2308
gen_op_iwmmxt_subsw_M0_wRn(rd1);
2311
gen_op_iwmmxt_subnl_M0_wRn(rd1);
2314
gen_op_iwmmxt_subul_M0_wRn(rd1);
2317
gen_op_iwmmxt_subsl_M0_wRn(rd1);
2322
gen_op_iwmmxt_movq_wRn_M0(wrd);
2323
gen_op_iwmmxt_set_mup();
2324
gen_op_iwmmxt_set_cup();
2326
case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2327
case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2328
case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2329
case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2330
wrd = (insn >> 12) & 0xf;
2331
rd0 = (insn >> 16) & 0xf;
2332
gen_op_iwmmxt_movq_M0_wRn(rd0);
2333
tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2334
gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2335
tcg_temp_free_i32(tmp);
2336
gen_op_iwmmxt_movq_wRn_M0(wrd);
2337
gen_op_iwmmxt_set_mup();
2338
gen_op_iwmmxt_set_cup();
2340
case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2341
case 0x418: case 0x518: case 0x618: case 0x718:
2342
case 0x818: case 0x918: case 0xa18: case 0xb18:
2343
case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2344
wrd = (insn >> 12) & 0xf;
2345
rd0 = (insn >> 16) & 0xf;
2346
rd1 = (insn >> 0) & 0xf;
2347
gen_op_iwmmxt_movq_M0_wRn(rd0);
2348
switch ((insn >> 20) & 0xf) {
2350
gen_op_iwmmxt_addnb_M0_wRn(rd1);
2353
gen_op_iwmmxt_addub_M0_wRn(rd1);
2356
gen_op_iwmmxt_addsb_M0_wRn(rd1);
2359
gen_op_iwmmxt_addnw_M0_wRn(rd1);
2362
gen_op_iwmmxt_adduw_M0_wRn(rd1);
2365
gen_op_iwmmxt_addsw_M0_wRn(rd1);
2368
gen_op_iwmmxt_addnl_M0_wRn(rd1);
2371
gen_op_iwmmxt_addul_M0_wRn(rd1);
2374
gen_op_iwmmxt_addsl_M0_wRn(rd1);
2379
gen_op_iwmmxt_movq_wRn_M0(wrd);
2380
gen_op_iwmmxt_set_mup();
2381
gen_op_iwmmxt_set_cup();
2383
case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2384
case 0x408: case 0x508: case 0x608: case 0x708:
2385
case 0x808: case 0x908: case 0xa08: case 0xb08:
2386
case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2387
if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2389
wrd = (insn >> 12) & 0xf;
2390
rd0 = (insn >> 16) & 0xf;
2391
rd1 = (insn >> 0) & 0xf;
2392
gen_op_iwmmxt_movq_M0_wRn(rd0);
2393
switch ((insn >> 22) & 3) {
2395
if (insn & (1 << 21))
2396
gen_op_iwmmxt_packsw_M0_wRn(rd1);
2398
gen_op_iwmmxt_packuw_M0_wRn(rd1);
2401
if (insn & (1 << 21))
2402
gen_op_iwmmxt_packsl_M0_wRn(rd1);
2404
gen_op_iwmmxt_packul_M0_wRn(rd1);
2407
if (insn & (1 << 21))
2408
gen_op_iwmmxt_packsq_M0_wRn(rd1);
2410
gen_op_iwmmxt_packuq_M0_wRn(rd1);
2413
gen_op_iwmmxt_movq_wRn_M0(wrd);
2414
gen_op_iwmmxt_set_mup();
2415
gen_op_iwmmxt_set_cup();
2417
case 0x201: case 0x203: case 0x205: case 0x207:
2418
case 0x209: case 0x20b: case 0x20d: case 0x20f:
2419
case 0x211: case 0x213: case 0x215: case 0x217:
2420
case 0x219: case 0x21b: case 0x21d: case 0x21f:
2421
wrd = (insn >> 5) & 0xf;
2422
rd0 = (insn >> 12) & 0xf;
2423
rd1 = (insn >> 0) & 0xf;
2424
if (rd0 == 0xf || rd1 == 0xf)
2426
gen_op_iwmmxt_movq_M0_wRn(wrd);
2427
tmp = load_reg(s, rd0);
2428
tmp2 = load_reg(s, rd1);
2429
switch ((insn >> 16) & 0xf) {
2430
case 0x0: /* TMIA */
2431
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2433
case 0x8: /* TMIAPH */
2434
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2436
case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2437
if (insn & (1 << 16))
2438
tcg_gen_shri_i32(tmp, tmp, 16);
2439
if (insn & (1 << 17))
2440
tcg_gen_shri_i32(tmp2, tmp2, 16);
2441
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2444
tcg_temp_free_i32(tmp2);
2445
tcg_temp_free_i32(tmp);
2448
tcg_temp_free_i32(tmp2);
2449
tcg_temp_free_i32(tmp);
2450
gen_op_iwmmxt_movq_wRn_M0(wrd);
2451
gen_op_iwmmxt_set_mup();
2460
/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2461
(ie. an undefined instruction). */
2462
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2464
int acc, rd0, rd1, rdhi, rdlo;
2467
if ((insn & 0x0ff00f10) == 0x0e200010) {
2468
/* Multiply with Internal Accumulate Format */
2469
rd0 = (insn >> 12) & 0xf;
2471
acc = (insn >> 5) & 7;
2476
tmp = load_reg(s, rd0);
2477
tmp2 = load_reg(s, rd1);
2478
switch ((insn >> 16) & 0xf) {
2480
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2482
case 0x8: /* MIAPH */
2483
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2485
case 0xc: /* MIABB */
2486
case 0xd: /* MIABT */
2487
case 0xe: /* MIATB */
2488
case 0xf: /* MIATT */
2489
if (insn & (1 << 16))
2490
tcg_gen_shri_i32(tmp, tmp, 16);
2491
if (insn & (1 << 17))
2492
tcg_gen_shri_i32(tmp2, tmp2, 16);
2493
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2498
tcg_temp_free_i32(tmp2);
2499
tcg_temp_free_i32(tmp);
2501
gen_op_iwmmxt_movq_wRn_M0(acc);
2505
if ((insn & 0x0fe00ff8) == 0x0c400000) {
2506
/* Internal Accumulator Access Format */
2507
rdhi = (insn >> 16) & 0xf;
2508
rdlo = (insn >> 12) & 0xf;
2514
if (insn & ARM_CP_RW_BIT) { /* MRA */
2515
iwmmxt_load_reg(cpu_V0, acc);
2516
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2517
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2518
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2519
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2521
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2522
iwmmxt_store_reg(cpu_V0, acc);
2530
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2531
#define VFP_SREG(insn, bigbit, smallbit) \
2532
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2533
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2534
if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2535
reg = (((insn) >> (bigbit)) & 0x0f) \
2536
| (((insn) >> ((smallbit) - 4)) & 0x10); \
2538
if (insn & (1 << (smallbit))) \
2540
reg = ((insn) >> (bigbit)) & 0x0f; \
2543
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2544
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2545
#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2546
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2547
#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2548
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2550
/* Move between integer and VFP cores. */
2551
static TCGv_i32 gen_vfp_mrs(void)
2553
TCGv_i32 tmp = tcg_temp_new_i32();
2554
tcg_gen_mov_i32(tmp, cpu_F0s);
2558
static void gen_vfp_msr(TCGv_i32 tmp)
2560
tcg_gen_mov_i32(cpu_F0s, tmp);
2561
tcg_temp_free_i32(tmp);
2564
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2566
TCGv_i32 tmp = tcg_temp_new_i32();
2568
tcg_gen_shri_i32(var, var, shift);
2569
tcg_gen_ext8u_i32(var, var);
2570
tcg_gen_shli_i32(tmp, var, 8);
2571
tcg_gen_or_i32(var, var, tmp);
2572
tcg_gen_shli_i32(tmp, var, 16);
2573
tcg_gen_or_i32(var, var, tmp);
2574
tcg_temp_free_i32(tmp);
2577
static void gen_neon_dup_low16(TCGv_i32 var)
2579
TCGv_i32 tmp = tcg_temp_new_i32();
2580
tcg_gen_ext16u_i32(var, var);
2581
tcg_gen_shli_i32(tmp, var, 16);
2582
tcg_gen_or_i32(var, var, tmp);
2583
tcg_temp_free_i32(tmp);
2586
static void gen_neon_dup_high16(TCGv_i32 var)
2588
TCGv_i32 tmp = tcg_temp_new_i32();
2589
tcg_gen_andi_i32(var, var, 0xffff0000);
2590
tcg_gen_shri_i32(tmp, var, 16);
2591
tcg_gen_or_i32(var, var, tmp);
2592
tcg_temp_free_i32(tmp);
2595
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2597
/* Load a single Neon element and replicate into a 32 bit TCG reg */
2598
TCGv_i32 tmp = tcg_temp_new_i32();
2601
gen_aa32_ld8u(tmp, addr, IS_USER(s));
2602
gen_neon_dup_u8(tmp, 0);
2605
gen_aa32_ld16u(tmp, addr, IS_USER(s));
2606
gen_neon_dup_low16(tmp);
2609
gen_aa32_ld32u(tmp, addr, IS_USER(s));
2611
default: /* Avoid compiler warnings. */
2617
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2620
uint32_t cc = extract32(insn, 20, 2);
2623
TCGv_i64 frn, frm, dest;
2624
TCGv_i64 tmp, zero, zf, nf, vf;
2626
zero = tcg_const_i64(0);
2628
frn = tcg_temp_new_i64();
2629
frm = tcg_temp_new_i64();
2630
dest = tcg_temp_new_i64();
2632
zf = tcg_temp_new_i64();
2633
nf = tcg_temp_new_i64();
2634
vf = tcg_temp_new_i64();
2636
tcg_gen_extu_i32_i64(zf, cpu_ZF);
2637
tcg_gen_ext_i32_i64(nf, cpu_NF);
2638
tcg_gen_ext_i32_i64(vf, cpu_VF);
2640
tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2641
tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2644
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2648
tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2651
case 2: /* ge: N == V -> N ^ V == 0 */
2652
tmp = tcg_temp_new_i64();
2653
tcg_gen_xor_i64(tmp, vf, nf);
2654
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2656
tcg_temp_free_i64(tmp);
2658
case 3: /* gt: !Z && N == V */
2659
tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2661
tmp = tcg_temp_new_i64();
2662
tcg_gen_xor_i64(tmp, vf, nf);
2663
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2665
tcg_temp_free_i64(tmp);
2668
tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2669
tcg_temp_free_i64(frn);
2670
tcg_temp_free_i64(frm);
2671
tcg_temp_free_i64(dest);
2673
tcg_temp_free_i64(zf);
2674
tcg_temp_free_i64(nf);
2675
tcg_temp_free_i64(vf);
2677
tcg_temp_free_i64(zero);
2679
TCGv_i32 frn, frm, dest;
2682
zero = tcg_const_i32(0);
2684
frn = tcg_temp_new_i32();
2685
frm = tcg_temp_new_i32();
2686
dest = tcg_temp_new_i32();
2687
tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2688
tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2691
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2695
tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2698
case 2: /* ge: N == V -> N ^ V == 0 */
2699
tmp = tcg_temp_new_i32();
2700
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2701
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2703
tcg_temp_free_i32(tmp);
2705
case 3: /* gt: !Z && N == V */
2706
tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2708
tmp = tcg_temp_new_i32();
2709
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2710
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2712
tcg_temp_free_i32(tmp);
2715
tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2716
tcg_temp_free_i32(frn);
2717
tcg_temp_free_i32(frm);
2718
tcg_temp_free_i32(dest);
2720
tcg_temp_free_i32(zero);
2726
static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2727
uint32_t rm, uint32_t dp)
2729
uint32_t vmin = extract32(insn, 6, 1);
2730
TCGv_ptr fpst = get_fpstatus_ptr(0);
2733
TCGv_i64 frn, frm, dest;
2735
frn = tcg_temp_new_i64();
2736
frm = tcg_temp_new_i64();
2737
dest = tcg_temp_new_i64();
2739
tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2740
tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2742
gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2744
gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2746
tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2747
tcg_temp_free_i64(frn);
2748
tcg_temp_free_i64(frm);
2749
tcg_temp_free_i64(dest);
2751
TCGv_i32 frn, frm, dest;
2753
frn = tcg_temp_new_i32();
2754
frm = tcg_temp_new_i32();
2755
dest = tcg_temp_new_i32();
2757
tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2758
tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2760
gen_helper_vfp_minnums(dest, frn, frm, fpst);
2762
gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2764
tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2765
tcg_temp_free_i32(frn);
2766
tcg_temp_free_i32(frm);
2767
tcg_temp_free_i32(dest);
2770
tcg_temp_free_ptr(fpst);
2774
static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2777
TCGv_ptr fpst = get_fpstatus_ptr(0);
2780
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2781
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2786
tcg_op = tcg_temp_new_i64();
2787
tcg_res = tcg_temp_new_i64();
2788
tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2789
gen_helper_rintd(tcg_res, tcg_op, fpst);
2790
tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2791
tcg_temp_free_i64(tcg_op);
2792
tcg_temp_free_i64(tcg_res);
2796
tcg_op = tcg_temp_new_i32();
2797
tcg_res = tcg_temp_new_i32();
2798
tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2799
gen_helper_rints(tcg_res, tcg_op, fpst);
2800
tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2801
tcg_temp_free_i32(tcg_op);
2802
tcg_temp_free_i32(tcg_res);
2805
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2806
tcg_temp_free_i32(tcg_rmode);
2808
tcg_temp_free_ptr(fpst);
2812
static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2815
bool is_signed = extract32(insn, 7, 1);
2816
TCGv_ptr fpst = get_fpstatus_ptr(0);
2817
TCGv_i32 tcg_rmode, tcg_shift;
2819
tcg_shift = tcg_const_i32(0);
2821
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2822
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2825
TCGv_i64 tcg_double, tcg_res;
2827
/* Rd is encoded as a single precision register even when the source
2828
* is double precision.
2830
rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2831
tcg_double = tcg_temp_new_i64();
2832
tcg_res = tcg_temp_new_i64();
2833
tcg_tmp = tcg_temp_new_i32();
2834
tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2836
gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2838
gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2840
tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res);
2841
tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2842
tcg_temp_free_i32(tcg_tmp);
2843
tcg_temp_free_i64(tcg_res);
2844
tcg_temp_free_i64(tcg_double);
2846
TCGv_i32 tcg_single, tcg_res;
2847
tcg_single = tcg_temp_new_i32();
2848
tcg_res = tcg_temp_new_i32();
2849
tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2851
gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2853
gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
2855
tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
2856
tcg_temp_free_i32(tcg_res);
2857
tcg_temp_free_i32(tcg_single);
2860
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2861
tcg_temp_free_i32(tcg_rmode);
2863
tcg_temp_free_i32(tcg_shift);
2865
tcg_temp_free_ptr(fpst);
2870
/* Table for converting the most common AArch32 encoding of
2871
* rounding mode to arm_fprounding order (which matches the
2872
* common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2874
static const uint8_t fp_decode_rm[] = {
2881
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2883
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2885
if (!arm_feature(env, ARM_FEATURE_V8)) {
2890
VFP_DREG_D(rd, insn);
2891
VFP_DREG_N(rn, insn);
2892
VFP_DREG_M(rm, insn);
2894
rd = VFP_SREG_D(insn);
2895
rn = VFP_SREG_N(insn);
2896
rm = VFP_SREG_M(insn);
2899
if ((insn & 0x0f800e50) == 0x0e000a00) {
2900
return handle_vsel(insn, rd, rn, rm, dp);
2901
} else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2902
return handle_vminmaxnm(insn, rd, rn, rm, dp);
2903
} else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
2904
/* VRINTA, VRINTN, VRINTP, VRINTM */
2905
int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2906
return handle_vrint(insn, rd, rm, dp, rounding);
2907
} else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
2908
/* VCVTA, VCVTN, VCVTP, VCVTM */
2909
int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2910
return handle_vcvt(insn, rd, rm, dp, rounding);
2915
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2916
(ie. an undefined instruction). */
2917
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2919
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2925
if (!arm_feature(env, ARM_FEATURE_VFP))
2928
if (!s->vfp_enabled) {
2929
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2930
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2932
rn = (insn >> 16) & 0xf;
2933
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2934
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2938
if (extract32(insn, 28, 4) == 0xf) {
2939
/* Encodings with T=1 (Thumb) or unconditional (ARM):
2940
* only used in v8 and above.
2942
return disas_vfp_v8_insn(env, s, insn);
2945
dp = ((insn & 0xf00) == 0xb00);
2946
switch ((insn >> 24) & 0xf) {
2948
if (insn & (1 << 4)) {
2949
/* single register transfer */
2950
rd = (insn >> 12) & 0xf;
2955
VFP_DREG_N(rn, insn);
2958
if (insn & 0x00c00060
2959
&& !arm_feature(env, ARM_FEATURE_NEON))
2962
pass = (insn >> 21) & 1;
2963
if (insn & (1 << 22)) {
2965
offset = ((insn >> 5) & 3) * 8;
2966
} else if (insn & (1 << 5)) {
2968
offset = (insn & (1 << 6)) ? 16 : 0;
2973
if (insn & ARM_CP_RW_BIT) {
2975
tmp = neon_load_reg(rn, pass);
2979
tcg_gen_shri_i32(tmp, tmp, offset);
2980
if (insn & (1 << 23))
2986
if (insn & (1 << 23)) {
2988
tcg_gen_shri_i32(tmp, tmp, 16);
2994
tcg_gen_sari_i32(tmp, tmp, 16);
3003
store_reg(s, rd, tmp);
3006
tmp = load_reg(s, rd);
3007
if (insn & (1 << 23)) {
3010
gen_neon_dup_u8(tmp, 0);
3011
} else if (size == 1) {
3012
gen_neon_dup_low16(tmp);
3014
for (n = 0; n <= pass * 2; n++) {
3015
tmp2 = tcg_temp_new_i32();
3016
tcg_gen_mov_i32(tmp2, tmp);
3017
neon_store_reg(rn, n, tmp2);
3019
neon_store_reg(rn, n, tmp);
3024
tmp2 = neon_load_reg(rn, pass);
3025
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3026
tcg_temp_free_i32(tmp2);
3029
tmp2 = neon_load_reg(rn, pass);
3030
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3031
tcg_temp_free_i32(tmp2);
3036
neon_store_reg(rn, pass, tmp);
3040
if ((insn & 0x6f) != 0x00)
3042
rn = VFP_SREG_N(insn);
3043
if (insn & ARM_CP_RW_BIT) {
3045
if (insn & (1 << 21)) {
3046
/* system register */
3051
/* VFP2 allows access to FSID from userspace.
3052
VFP3 restricts all id registers to privileged
3055
&& arm_feature(env, ARM_FEATURE_VFP3))
3057
tmp = load_cpu_field(vfp.xregs[rn]);
3062
tmp = load_cpu_field(vfp.xregs[rn]);
3064
case ARM_VFP_FPINST:
3065
case ARM_VFP_FPINST2:
3066
/* Not present in VFP3. */
3068
|| arm_feature(env, ARM_FEATURE_VFP3))
3070
tmp = load_cpu_field(vfp.xregs[rn]);
3074
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3075
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3077
tmp = tcg_temp_new_i32();
3078
gen_helper_vfp_get_fpscr(tmp, cpu_env);
3084
|| !arm_feature(env, ARM_FEATURE_MVFR))
3086
tmp = load_cpu_field(vfp.xregs[rn]);
3092
gen_mov_F0_vreg(0, rn);
3093
tmp = gen_vfp_mrs();
3096
/* Set the 4 flag bits in the CPSR. */
3098
tcg_temp_free_i32(tmp);
3100
store_reg(s, rd, tmp);
3104
if (insn & (1 << 21)) {
3106
/* system register */
3111
/* Writes are ignored. */
3114
tmp = load_reg(s, rd);
3115
gen_helper_vfp_set_fpscr(cpu_env, tmp);
3116
tcg_temp_free_i32(tmp);
3122
/* TODO: VFP subarchitecture support.
3123
* For now, keep the EN bit only */
3124
tmp = load_reg(s, rd);
3125
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3126
store_cpu_field(tmp, vfp.xregs[rn]);
3129
case ARM_VFP_FPINST:
3130
case ARM_VFP_FPINST2:
3131
tmp = load_reg(s, rd);
3132
store_cpu_field(tmp, vfp.xregs[rn]);
3138
tmp = load_reg(s, rd);
3140
gen_mov_vreg_F0(0, rn);
3145
/* data processing */
3146
/* The opcode is in bits 23, 21, 20 and 6. */
3147
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3151
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3153
/* rn is register number */
3154
VFP_DREG_N(rn, insn);
3157
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3158
/* Integer or single precision destination. */
3159
rd = VFP_SREG_D(insn);
3161
VFP_DREG_D(rd, insn);
3164
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3165
/* VCVT from int is always from S reg regardless of dp bit.
3166
* VCVT with immediate frac_bits has same format as SREG_M
3168
rm = VFP_SREG_M(insn);
3170
VFP_DREG_M(rm, insn);
3173
rn = VFP_SREG_N(insn);
3174
if (op == 15 && rn == 15) {
3175
/* Double precision destination. */
3176
VFP_DREG_D(rd, insn);
3178
rd = VFP_SREG_D(insn);
3180
/* NB that we implicitly rely on the encoding for the frac_bits
3181
* in VCVT of fixed to float being the same as that of an SREG_M
3183
rm = VFP_SREG_M(insn);
3186
veclen = s->vec_len;
3187
if (op == 15 && rn > 3)
3190
/* Shut up compiler warnings. */
3201
/* Figure out what type of vector operation this is. */
3202
if ((rd & bank_mask) == 0) {
3207
delta_d = (s->vec_stride >> 1) + 1;
3209
delta_d = s->vec_stride + 1;
3211
if ((rm & bank_mask) == 0) {
3212
/* mixed scalar/vector */
3221
/* Load the initial operands. */
3226
/* Integer source */
3227
gen_mov_F0_vreg(0, rm);
3232
gen_mov_F0_vreg(dp, rd);
3233
gen_mov_F1_vreg(dp, rm);
3237
/* Compare with zero */
3238
gen_mov_F0_vreg(dp, rd);
3249
/* Source and destination the same. */
3250
gen_mov_F0_vreg(dp, rd);
3256
/* VCVTB, VCVTT: only present with the halfprec extension,
3257
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3259
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3262
/* Otherwise fall through */
3264
/* One source operand. */
3265
gen_mov_F0_vreg(dp, rm);
3269
/* Two source operands. */
3270
gen_mov_F0_vreg(dp, rn);
3271
gen_mov_F1_vreg(dp, rm);
3275
/* Perform the calculation. */
3277
case 0: /* VMLA: fd + (fn * fm) */
3278
/* Note that order of inputs to the add matters for NaNs */
3280
gen_mov_F0_vreg(dp, rd);
3283
case 1: /* VMLS: fd + -(fn * fm) */
3286
gen_mov_F0_vreg(dp, rd);
3289
case 2: /* VNMLS: -fd + (fn * fm) */
3290
/* Note that it isn't valid to replace (-A + B) with (B - A)
3291
* or similar plausible looking simplifications
3292
* because this will give wrong results for NaNs.
3295
gen_mov_F0_vreg(dp, rd);
3299
case 3: /* VNMLA: -fd + -(fn * fm) */
3302
gen_mov_F0_vreg(dp, rd);
3306
case 4: /* mul: fn * fm */
3309
case 5: /* nmul: -(fn * fm) */
3313
case 6: /* add: fn + fm */
3316
case 7: /* sub: fn - fm */
3319
case 8: /* div: fn / fm */
3322
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3323
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3324
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3325
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3326
/* These are fused multiply-add, and must be done as one
3327
* floating point operation with no rounding between the
3328
* multiplication and addition steps.
3329
* NB that doing the negations here as separate steps is
3330
* correct : an input NaN should come out with its sign bit
3331
* flipped if it is a negated-input.
3333
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3341
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3343
frd = tcg_temp_new_i64();
3344
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3347
gen_helper_vfp_negd(frd, frd);
3349
fpst = get_fpstatus_ptr(0);
3350
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3351
cpu_F1d, frd, fpst);
3352
tcg_temp_free_ptr(fpst);
3353
tcg_temp_free_i64(frd);
3359
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3361
frd = tcg_temp_new_i32();
3362
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3364
gen_helper_vfp_negs(frd, frd);
3366
fpst = get_fpstatus_ptr(0);
3367
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3368
cpu_F1s, frd, fpst);
3369
tcg_temp_free_ptr(fpst);
3370
tcg_temp_free_i32(frd);
3373
case 14: /* fconst */
3374
if (!arm_feature(env, ARM_FEATURE_VFP3))
3377
n = (insn << 12) & 0x80000000;
3378
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3385
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3392
tcg_gen_movi_i32(cpu_F0s, n);
3395
case 15: /* extension space */
3409
case 4: /* vcvtb.f32.f16 */
3410
tmp = gen_vfp_mrs();
3411
tcg_gen_ext16u_i32(tmp, tmp);
3412
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3413
tcg_temp_free_i32(tmp);
3415
case 5: /* vcvtt.f32.f16 */
3416
tmp = gen_vfp_mrs();
3417
tcg_gen_shri_i32(tmp, tmp, 16);
3418
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3419
tcg_temp_free_i32(tmp);
3421
case 6: /* vcvtb.f16.f32 */
3422
tmp = tcg_temp_new_i32();
3423
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3424
gen_mov_F0_vreg(0, rd);
3425
tmp2 = gen_vfp_mrs();
3426
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3427
tcg_gen_or_i32(tmp, tmp, tmp2);
3428
tcg_temp_free_i32(tmp2);
3431
case 7: /* vcvtt.f16.f32 */
3432
tmp = tcg_temp_new_i32();
3433
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3434
tcg_gen_shli_i32(tmp, tmp, 16);
3435
gen_mov_F0_vreg(0, rd);
3436
tmp2 = gen_vfp_mrs();
3437
tcg_gen_ext16u_i32(tmp2, tmp2);
3438
tcg_gen_or_i32(tmp, tmp, tmp2);
3439
tcg_temp_free_i32(tmp2);
3451
case 11: /* cmpez */
3455
case 12: /* vrintr */
3457
TCGv_ptr fpst = get_fpstatus_ptr(0);
3459
gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3461
gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3463
tcg_temp_free_ptr(fpst);
3466
case 13: /* vrintz */
3468
TCGv_ptr fpst = get_fpstatus_ptr(0);
3470
tcg_rmode = tcg_const_i32(float_round_to_zero);
3471
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3473
gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3475
gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3477
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3478
tcg_temp_free_i32(tcg_rmode);
3479
tcg_temp_free_ptr(fpst);
3482
case 14: /* vrintx */
3484
TCGv_ptr fpst = get_fpstatus_ptr(0);
3486
gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3488
gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3490
tcg_temp_free_ptr(fpst);
3493
case 15: /* single<->double conversion */
3495
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3497
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3499
case 16: /* fuito */
3500
gen_vfp_uito(dp, 0);
3502
case 17: /* fsito */
3503
gen_vfp_sito(dp, 0);
3505
case 20: /* fshto */
3506
if (!arm_feature(env, ARM_FEATURE_VFP3))
3508
gen_vfp_shto(dp, 16 - rm, 0);
3510
case 21: /* fslto */
3511
if (!arm_feature(env, ARM_FEATURE_VFP3))
3513
gen_vfp_slto(dp, 32 - rm, 0);
3515
case 22: /* fuhto */
3516
if (!arm_feature(env, ARM_FEATURE_VFP3))
3518
gen_vfp_uhto(dp, 16 - rm, 0);
3520
case 23: /* fulto */
3521
if (!arm_feature(env, ARM_FEATURE_VFP3))
3523
gen_vfp_ulto(dp, 32 - rm, 0);
3525
case 24: /* ftoui */
3526
gen_vfp_toui(dp, 0);
3528
case 25: /* ftouiz */
3529
gen_vfp_touiz(dp, 0);
3531
case 26: /* ftosi */
3532
gen_vfp_tosi(dp, 0);
3534
case 27: /* ftosiz */
3535
gen_vfp_tosiz(dp, 0);
3537
case 28: /* ftosh */
3538
if (!arm_feature(env, ARM_FEATURE_VFP3))
3540
gen_vfp_tosh(dp, 16 - rm, 0);
3542
case 29: /* ftosl */
3543
if (!arm_feature(env, ARM_FEATURE_VFP3))
3545
gen_vfp_tosl(dp, 32 - rm, 0);
3547
case 30: /* ftouh */
3548
if (!arm_feature(env, ARM_FEATURE_VFP3))
3550
gen_vfp_touh(dp, 16 - rm, 0);
3552
case 31: /* ftoul */
3553
if (!arm_feature(env, ARM_FEATURE_VFP3))
3555
gen_vfp_toul(dp, 32 - rm, 0);
3557
default: /* undefined */
3561
default: /* undefined */
3565
/* Write back the result. */
3566
if (op == 15 && (rn >= 8 && rn <= 11))
3567
; /* Comparison, do nothing. */
3568
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3569
/* VCVT double to int: always integer result. */
3570
gen_mov_vreg_F0(0, rd);
3571
else if (op == 15 && rn == 15)
3573
gen_mov_vreg_F0(!dp, rd);
3575
gen_mov_vreg_F0(dp, rd);
3577
/* break out of the loop if we have finished */
3581
if (op == 15 && delta_m == 0) {
3582
/* single source one-many */
3584
rd = ((rd + delta_d) & (bank_mask - 1))
3586
gen_mov_vreg_F0(dp, rd);
3590
/* Setup the next operands. */
3592
rd = ((rd + delta_d) & (bank_mask - 1))
3596
/* One source operand. */
3597
rm = ((rm + delta_m) & (bank_mask - 1))
3599
gen_mov_F0_vreg(dp, rm);
3601
/* Two source operands. */
3602
rn = ((rn + delta_d) & (bank_mask - 1))
3604
gen_mov_F0_vreg(dp, rn);
3606
rm = ((rm + delta_m) & (bank_mask - 1))
3608
gen_mov_F1_vreg(dp, rm);
3616
if ((insn & 0x03e00000) == 0x00400000) {
3617
/* two-register transfer */
3618
rn = (insn >> 16) & 0xf;
3619
rd = (insn >> 12) & 0xf;
3621
VFP_DREG_M(rm, insn);
3623
rm = VFP_SREG_M(insn);
3626
if (insn & ARM_CP_RW_BIT) {
3629
gen_mov_F0_vreg(0, rm * 2);
3630
tmp = gen_vfp_mrs();
3631
store_reg(s, rd, tmp);
3632
gen_mov_F0_vreg(0, rm * 2 + 1);
3633
tmp = gen_vfp_mrs();
3634
store_reg(s, rn, tmp);
3636
gen_mov_F0_vreg(0, rm);
3637
tmp = gen_vfp_mrs();
3638
store_reg(s, rd, tmp);
3639
gen_mov_F0_vreg(0, rm + 1);
3640
tmp = gen_vfp_mrs();
3641
store_reg(s, rn, tmp);
3646
tmp = load_reg(s, rd);
3648
gen_mov_vreg_F0(0, rm * 2);
3649
tmp = load_reg(s, rn);
3651
gen_mov_vreg_F0(0, rm * 2 + 1);
3653
tmp = load_reg(s, rd);
3655
gen_mov_vreg_F0(0, rm);
3656
tmp = load_reg(s, rn);
3658
gen_mov_vreg_F0(0, rm + 1);
3663
rn = (insn >> 16) & 0xf;
3665
VFP_DREG_D(rd, insn);
3667
rd = VFP_SREG_D(insn);
3668
if ((insn & 0x01200000) == 0x01000000) {
3669
/* Single load/store */
3670
offset = (insn & 0xff) << 2;
3671
if ((insn & (1 << 23)) == 0)
3673
if (s->thumb && rn == 15) {
3674
/* This is actually UNPREDICTABLE */
3675
addr = tcg_temp_new_i32();
3676
tcg_gen_movi_i32(addr, s->pc & ~2);
3678
addr = load_reg(s, rn);
3680
tcg_gen_addi_i32(addr, addr, offset);
3681
if (insn & (1 << 20)) {
3682
gen_vfp_ld(s, dp, addr);
3683
gen_mov_vreg_F0(dp, rd);
3685
gen_mov_F0_vreg(dp, rd);
3686
gen_vfp_st(s, dp, addr);
3688
tcg_temp_free_i32(addr);
3690
/* load/store multiple */
3691
int w = insn & (1 << 21);
3693
n = (insn >> 1) & 0x7f;
3697
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3698
/* P == U , W == 1 => UNDEF */
3701
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3702
/* UNPREDICTABLE cases for bad immediates: we choose to
3703
* UNDEF to avoid generating huge numbers of TCG ops
3707
if (rn == 15 && w) {
3708
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3712
if (s->thumb && rn == 15) {
3713
/* This is actually UNPREDICTABLE */
3714
addr = tcg_temp_new_i32();
3715
tcg_gen_movi_i32(addr, s->pc & ~2);
3717
addr = load_reg(s, rn);
3719
if (insn & (1 << 24)) /* pre-decrement */
3720
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3726
for (i = 0; i < n; i++) {
3727
if (insn & ARM_CP_RW_BIT) {
3729
gen_vfp_ld(s, dp, addr);
3730
gen_mov_vreg_F0(dp, rd + i);
3733
gen_mov_F0_vreg(dp, rd + i);
3734
gen_vfp_st(s, dp, addr);
3736
tcg_gen_addi_i32(addr, addr, offset);
3740
if (insn & (1 << 24))
3741
offset = -offset * n;
3742
else if (dp && (insn & 1))
3748
tcg_gen_addi_i32(addr, addr, offset);
3749
store_reg(s, rn, addr);
3751
tcg_temp_free_i32(addr);
3757
/* Should never happen. */
3763
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3765
TranslationBlock *tb;
3768
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3770
gen_set_pc_im(s, dest);
3771
tcg_gen_exit_tb((uintptr_t)tb + n);
3773
gen_set_pc_im(s, dest);
3778
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3780
if (unlikely(s->singlestep_enabled)) {
3781
/* An indirect jump so that we still trigger the debug exception. */
3786
gen_goto_tb(s, 0, dest);
3787
s->is_jmp = DISAS_TB_JUMP;
3791
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3794
tcg_gen_sari_i32(t0, t0, 16);
3798
tcg_gen_sari_i32(t1, t1, 16);
3801
tcg_gen_mul_i32(t0, t0, t1);
3804
/* Return the mask of PSR bits set by a MSR instruction. */
3805
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3809
if (flags & (1 << 0))
3811
if (flags & (1 << 1))
3813
if (flags & (1 << 2))
3815
if (flags & (1 << 3))
3818
/* Mask out undefined bits. */
3819
mask &= ~CPSR_RESERVED;
3820
if (!arm_feature(env, ARM_FEATURE_V4T))
3822
if (!arm_feature(env, ARM_FEATURE_V5))
3823
mask &= ~CPSR_Q; /* V5TE in reality*/
3824
if (!arm_feature(env, ARM_FEATURE_V6))
3825
mask &= ~(CPSR_E | CPSR_GE);
3826
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3828
/* Mask out execution state bits. */
3831
/* Mask out privileged bits. */
3837
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3838
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3842
/* ??? This is also undefined in system mode. */
3846
tmp = load_cpu_field(spsr);
3847
tcg_gen_andi_i32(tmp, tmp, ~mask);
3848
tcg_gen_andi_i32(t0, t0, mask);
3849
tcg_gen_or_i32(tmp, tmp, t0);
3850
store_cpu_field(tmp, spsr);
3852
gen_set_cpsr(t0, mask);
3854
tcg_temp_free_i32(t0);
3859
/* Returns nonzero if access to the PSR is not permitted. */
3860
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3863
tmp = tcg_temp_new_i32();
3864
tcg_gen_movi_i32(tmp, val);
3865
return gen_set_psr(s, mask, spsr, tmp);
3868
/* Generate an old-style exception return. Marks pc as dead. */
3869
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3872
store_reg(s, 15, pc);
3873
tmp = load_cpu_field(spsr);
3874
gen_set_cpsr(tmp, 0xffffffff);
3875
tcg_temp_free_i32(tmp);
3876
s->is_jmp = DISAS_UPDATE;
3879
/* Generate a v6 exception return. Marks both values as dead. */
3880
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3882
gen_set_cpsr(cpsr, 0xffffffff);
3883
tcg_temp_free_i32(cpsr);
3884
store_reg(s, 15, pc);
3885
s->is_jmp = DISAS_UPDATE;
3889
gen_set_condexec (DisasContext *s)
3891
if (s->condexec_mask) {
3892
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3893
TCGv_i32 tmp = tcg_temp_new_i32();
3894
tcg_gen_movi_i32(tmp, val);
3895
store_cpu_field(tmp, condexec_bits);
3899
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3901
gen_set_condexec(s);
3902
gen_set_pc_im(s, s->pc - offset);
3903
gen_exception(excp);
3904
s->is_jmp = DISAS_JUMP;
3907
static void gen_nop_hint(DisasContext *s, int val)
3911
gen_set_pc_im(s, s->pc);
3912
s->is_jmp = DISAS_WFI;
3917
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3923
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3925
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3928
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3929
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3930
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3935
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3938
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3939
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3940
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3945
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3946
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3947
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3948
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3949
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3951
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3952
switch ((size << 1) | u) { \
3954
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3957
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3960
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3963
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3966
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3969
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3971
default: return 1; \
3974
#define GEN_NEON_INTEGER_OP(name) do { \
3975
switch ((size << 1) | u) { \
3977
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3980
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3983
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3986
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3989
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3992
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3994
default: return 1; \
3997
static TCGv_i32 neon_load_scratch(int scratch)
3999
TCGv_i32 tmp = tcg_temp_new_i32();
4000
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4004
static void neon_store_scratch(int scratch, TCGv_i32 var)
4006
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4007
tcg_temp_free_i32(var);
4010
static inline TCGv_i32 neon_get_scalar(int size, int reg)
4014
tmp = neon_load_reg(reg & 7, reg >> 4);
4016
gen_neon_dup_high16(tmp);
4018
gen_neon_dup_low16(tmp);
4021
tmp = neon_load_reg(reg & 15, reg >> 4);
4026
static int gen_neon_unzip(int rd, int rm, int size, int q)
4029
if (!q && size == 2) {
4032
tmp = tcg_const_i32(rd);
4033
tmp2 = tcg_const_i32(rm);
4037
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4040
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4043
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4051
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4054
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4060
tcg_temp_free_i32(tmp);
4061
tcg_temp_free_i32(tmp2);
4065
static int gen_neon_zip(int rd, int rm, int size, int q)
4068
if (!q && size == 2) {
4071
tmp = tcg_const_i32(rd);
4072
tmp2 = tcg_const_i32(rm);
4076
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4079
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4082
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4090
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4093
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4099
tcg_temp_free_i32(tmp);
4100
tcg_temp_free_i32(tmp2);
4104
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4108
rd = tcg_temp_new_i32();
4109
tmp = tcg_temp_new_i32();
4111
tcg_gen_shli_i32(rd, t0, 8);
4112
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4113
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4114
tcg_gen_or_i32(rd, rd, tmp);
4116
tcg_gen_shri_i32(t1, t1, 8);
4117
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4118
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4119
tcg_gen_or_i32(t1, t1, tmp);
4120
tcg_gen_mov_i32(t0, rd);
4122
tcg_temp_free_i32(tmp);
4123
tcg_temp_free_i32(rd);
4126
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4130
rd = tcg_temp_new_i32();
4131
tmp = tcg_temp_new_i32();
4133
tcg_gen_shli_i32(rd, t0, 16);
4134
tcg_gen_andi_i32(tmp, t1, 0xffff);
4135
tcg_gen_or_i32(rd, rd, tmp);
4136
tcg_gen_shri_i32(t1, t1, 16);
4137
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4138
tcg_gen_or_i32(t1, t1, tmp);
4139
tcg_gen_mov_i32(t0, rd);
4141
tcg_temp_free_i32(tmp);
4142
tcg_temp_free_i32(rd);
4150
} neon_ls_element_type[11] = {
4164
/* Translate a NEON load/store element instruction. Return nonzero if the
4165
instruction is invalid. */
4166
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4185
if (!s->vfp_enabled)
4187
VFP_DREG_D(rd, insn);
4188
rn = (insn >> 16) & 0xf;
4190
load = (insn & (1 << 21)) != 0;
4191
if ((insn & (1 << 23)) == 0) {
4192
/* Load store all elements. */
4193
op = (insn >> 8) & 0xf;
4194
size = (insn >> 6) & 3;
4197
/* Catch UNDEF cases for bad values of align field */
4200
if (((insn >> 5) & 1) == 1) {
4205
if (((insn >> 4) & 3) == 3) {
4212
nregs = neon_ls_element_type[op].nregs;
4213
interleave = neon_ls_element_type[op].interleave;
4214
spacing = neon_ls_element_type[op].spacing;
4215
if (size == 3 && (interleave | spacing) != 1)
4217
addr = tcg_temp_new_i32();
4218
load_reg_var(s, addr, rn);
4219
stride = (1 << size) * interleave;
4220
for (reg = 0; reg < nregs; reg++) {
4221
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4222
load_reg_var(s, addr, rn);
4223
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4224
} else if (interleave == 2 && nregs == 4 && reg == 2) {
4225
load_reg_var(s, addr, rn);
4226
tcg_gen_addi_i32(addr, addr, 1 << size);
4229
tmp64 = tcg_temp_new_i64();
4231
gen_aa32_ld64(tmp64, addr, IS_USER(s));
4232
neon_store_reg64(tmp64, rd);
4234
neon_load_reg64(tmp64, rd);
4235
gen_aa32_st64(tmp64, addr, IS_USER(s));
4237
tcg_temp_free_i64(tmp64);
4238
tcg_gen_addi_i32(addr, addr, stride);
4240
for (pass = 0; pass < 2; pass++) {
4243
tmp = tcg_temp_new_i32();
4244
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4245
neon_store_reg(rd, pass, tmp);
4247
tmp = neon_load_reg(rd, pass);
4248
gen_aa32_st32(tmp, addr, IS_USER(s));
4249
tcg_temp_free_i32(tmp);
4251
tcg_gen_addi_i32(addr, addr, stride);
4252
} else if (size == 1) {
4254
tmp = tcg_temp_new_i32();
4255
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4256
tcg_gen_addi_i32(addr, addr, stride);
4257
tmp2 = tcg_temp_new_i32();
4258
gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4259
tcg_gen_addi_i32(addr, addr, stride);
4260
tcg_gen_shli_i32(tmp2, tmp2, 16);
4261
tcg_gen_or_i32(tmp, tmp, tmp2);
4262
tcg_temp_free_i32(tmp2);
4263
neon_store_reg(rd, pass, tmp);
4265
tmp = neon_load_reg(rd, pass);
4266
tmp2 = tcg_temp_new_i32();
4267
tcg_gen_shri_i32(tmp2, tmp, 16);
4268
gen_aa32_st16(tmp, addr, IS_USER(s));
4269
tcg_temp_free_i32(tmp);
4270
tcg_gen_addi_i32(addr, addr, stride);
4271
gen_aa32_st16(tmp2, addr, IS_USER(s));
4272
tcg_temp_free_i32(tmp2);
4273
tcg_gen_addi_i32(addr, addr, stride);
4275
} else /* size == 0 */ {
4277
TCGV_UNUSED_I32(tmp2);
4278
for (n = 0; n < 4; n++) {
4279
tmp = tcg_temp_new_i32();
4280
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4281
tcg_gen_addi_i32(addr, addr, stride);
4285
tcg_gen_shli_i32(tmp, tmp, n * 8);
4286
tcg_gen_or_i32(tmp2, tmp2, tmp);
4287
tcg_temp_free_i32(tmp);
4290
neon_store_reg(rd, pass, tmp2);
4292
tmp2 = neon_load_reg(rd, pass);
4293
for (n = 0; n < 4; n++) {
4294
tmp = tcg_temp_new_i32();
4296
tcg_gen_mov_i32(tmp, tmp2);
4298
tcg_gen_shri_i32(tmp, tmp2, n * 8);
4300
gen_aa32_st8(tmp, addr, IS_USER(s));
4301
tcg_temp_free_i32(tmp);
4302
tcg_gen_addi_i32(addr, addr, stride);
4304
tcg_temp_free_i32(tmp2);
4311
tcg_temp_free_i32(addr);
4314
size = (insn >> 10) & 3;
4316
/* Load single element to all lanes. */
4317
int a = (insn >> 4) & 1;
4321
size = (insn >> 6) & 3;
4322
nregs = ((insn >> 8) & 3) + 1;
4325
if (nregs != 4 || a == 0) {
4328
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4331
if (nregs == 1 && a == 1 && size == 0) {
4334
if (nregs == 3 && a == 1) {
4337
addr = tcg_temp_new_i32();
4338
load_reg_var(s, addr, rn);
4340
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4341
tmp = gen_load_and_replicate(s, addr, size);
4342
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4343
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4344
if (insn & (1 << 5)) {
4345
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4346
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4348
tcg_temp_free_i32(tmp);
4350
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4351
stride = (insn & (1 << 5)) ? 2 : 1;
4352
for (reg = 0; reg < nregs; reg++) {
4353
tmp = gen_load_and_replicate(s, addr, size);
4354
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4355
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4356
tcg_temp_free_i32(tmp);
4357
tcg_gen_addi_i32(addr, addr, 1 << size);
4361
tcg_temp_free_i32(addr);
4362
stride = (1 << size) * nregs;
4364
/* Single element. */
4365
int idx = (insn >> 4) & 0xf;
4366
pass = (insn >> 7) & 1;
4369
shift = ((insn >> 5) & 3) * 8;
4373
shift = ((insn >> 6) & 1) * 16;
4374
stride = (insn & (1 << 5)) ? 2 : 1;
4378
stride = (insn & (1 << 6)) ? 2 : 1;
4383
nregs = ((insn >> 8) & 3) + 1;
4384
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
4387
if (((idx & (1 << size)) != 0) ||
4388
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4393
if ((idx & 1) != 0) {
4398
if (size == 2 && (idx & 2) != 0) {
4403
if ((size == 2) && ((idx & 3) == 3)) {
4410
if ((rd + stride * (nregs - 1)) > 31) {
4411
/* Attempts to write off the end of the register file
4412
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4413
* the neon_load_reg() would write off the end of the array.
4417
addr = tcg_temp_new_i32();
4418
load_reg_var(s, addr, rn);
4419
for (reg = 0; reg < nregs; reg++) {
4421
tmp = tcg_temp_new_i32();
4424
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4427
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4430
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4432
default: /* Avoid compiler warnings. */
4436
tmp2 = neon_load_reg(rd, pass);
4437
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4438
shift, size ? 16 : 8);
4439
tcg_temp_free_i32(tmp2);
4441
neon_store_reg(rd, pass, tmp);
4442
} else { /* Store */
4443
tmp = neon_load_reg(rd, pass);
4445
tcg_gen_shri_i32(tmp, tmp, shift);
4448
gen_aa32_st8(tmp, addr, IS_USER(s));
4451
gen_aa32_st16(tmp, addr, IS_USER(s));
4454
gen_aa32_st32(tmp, addr, IS_USER(s));
4457
tcg_temp_free_i32(tmp);
4460
tcg_gen_addi_i32(addr, addr, 1 << size);
4462
tcg_temp_free_i32(addr);
4463
stride = nregs * (1 << size);
4469
base = load_reg(s, rn);
4471
tcg_gen_addi_i32(base, base, stride);
4474
index = load_reg(s, rm);
4475
tcg_gen_add_i32(base, base, index);
4476
tcg_temp_free_i32(index);
4478
store_reg(s, rn, base);
4483
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4484
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4486
tcg_gen_and_i32(t, t, c);
4487
tcg_gen_andc_i32(f, f, c);
4488
tcg_gen_or_i32(dest, t, f);
4491
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4494
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4495
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4496
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4501
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4504
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4505
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4506
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4511
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4514
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4515
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4516
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4521
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4524
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4525
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4526
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4531
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4537
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4538
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4543
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4544
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4551
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4552
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4557
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4558
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4565
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4569
case 0: gen_helper_neon_widen_u8(dest, src); break;
4570
case 1: gen_helper_neon_widen_u16(dest, src); break;
4571
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4576
case 0: gen_helper_neon_widen_s8(dest, src); break;
4577
case 1: gen_helper_neon_widen_s16(dest, src); break;
4578
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4582
tcg_temp_free_i32(src);
4585
static inline void gen_neon_addl(int size)
4588
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4589
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4590
case 2: tcg_gen_add_i64(CPU_V001); break;
4595
static inline void gen_neon_subl(int size)
4598
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4599
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4600
case 2: tcg_gen_sub_i64(CPU_V001); break;
4605
static inline void gen_neon_negl(TCGv_i64 var, int size)
4608
case 0: gen_helper_neon_negl_u16(var, var); break;
4609
case 1: gen_helper_neon_negl_u32(var, var); break;
4611
tcg_gen_neg_i64(var, var);
4617
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4620
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4621
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4626
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4631
switch ((size << 1) | u) {
4632
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4633
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4634
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4635
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4637
tmp = gen_muls_i64_i32(a, b);
4638
tcg_gen_mov_i64(dest, tmp);
4639
tcg_temp_free_i64(tmp);
4642
tmp = gen_mulu_i64_i32(a, b);
4643
tcg_gen_mov_i64(dest, tmp);
4644
tcg_temp_free_i64(tmp);
4649
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4650
Don't forget to clean them now. */
4652
tcg_temp_free_i32(a);
4653
tcg_temp_free_i32(b);
4657
static void gen_neon_narrow_op(int op, int u, int size,
4658
TCGv_i32 dest, TCGv_i64 src)
4662
gen_neon_unarrow_sats(size, dest, src);
4664
gen_neon_narrow(size, dest, src);
4668
gen_neon_narrow_satu(size, dest, src);
4670
gen_neon_narrow_sats(size, dest, src);
4675
/* Symbolic constants for op fields for Neon 3-register same-length.
4676
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4679
#define NEON_3R_VHADD 0
4680
#define NEON_3R_VQADD 1
4681
#define NEON_3R_VRHADD 2
4682
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4683
#define NEON_3R_VHSUB 4
4684
#define NEON_3R_VQSUB 5
4685
#define NEON_3R_VCGT 6
4686
#define NEON_3R_VCGE 7
4687
#define NEON_3R_VSHL 8
4688
#define NEON_3R_VQSHL 9
4689
#define NEON_3R_VRSHL 10
4690
#define NEON_3R_VQRSHL 11
4691
#define NEON_3R_VMAX 12
4692
#define NEON_3R_VMIN 13
4693
#define NEON_3R_VABD 14
4694
#define NEON_3R_VABA 15
4695
#define NEON_3R_VADD_VSUB 16
4696
#define NEON_3R_VTST_VCEQ 17
4697
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4698
#define NEON_3R_VMUL 19
4699
#define NEON_3R_VPMAX 20
4700
#define NEON_3R_VPMIN 21
4701
#define NEON_3R_VQDMULH_VQRDMULH 22
4702
#define NEON_3R_VPADD 23
4703
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4704
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4705
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4706
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4707
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4708
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4709
#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4711
static const uint8_t neon_3r_sizes[] = {
4712
[NEON_3R_VHADD] = 0x7,
4713
[NEON_3R_VQADD] = 0xf,
4714
[NEON_3R_VRHADD] = 0x7,
4715
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4716
[NEON_3R_VHSUB] = 0x7,
4717
[NEON_3R_VQSUB] = 0xf,
4718
[NEON_3R_VCGT] = 0x7,
4719
[NEON_3R_VCGE] = 0x7,
4720
[NEON_3R_VSHL] = 0xf,
4721
[NEON_3R_VQSHL] = 0xf,
4722
[NEON_3R_VRSHL] = 0xf,
4723
[NEON_3R_VQRSHL] = 0xf,
4724
[NEON_3R_VMAX] = 0x7,
4725
[NEON_3R_VMIN] = 0x7,
4726
[NEON_3R_VABD] = 0x7,
4727
[NEON_3R_VABA] = 0x7,
4728
[NEON_3R_VADD_VSUB] = 0xf,
4729
[NEON_3R_VTST_VCEQ] = 0x7,
4730
[NEON_3R_VML] = 0x7,
4731
[NEON_3R_VMUL] = 0x7,
4732
[NEON_3R_VPMAX] = 0x7,
4733
[NEON_3R_VPMIN] = 0x7,
4734
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4735
[NEON_3R_VPADD] = 0x7,
4736
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4737
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4738
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4739
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4740
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4741
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4742
[NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4745
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4746
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4749
#define NEON_2RM_VREV64 0
4750
#define NEON_2RM_VREV32 1
4751
#define NEON_2RM_VREV16 2
4752
#define NEON_2RM_VPADDL 4
4753
#define NEON_2RM_VPADDL_U 5
4754
#define NEON_2RM_VCLS 8
4755
#define NEON_2RM_VCLZ 9
4756
#define NEON_2RM_VCNT 10
4757
#define NEON_2RM_VMVN 11
4758
#define NEON_2RM_VPADAL 12
4759
#define NEON_2RM_VPADAL_U 13
4760
#define NEON_2RM_VQABS 14
4761
#define NEON_2RM_VQNEG 15
4762
#define NEON_2RM_VCGT0 16
4763
#define NEON_2RM_VCGE0 17
4764
#define NEON_2RM_VCEQ0 18
4765
#define NEON_2RM_VCLE0 19
4766
#define NEON_2RM_VCLT0 20
4767
#define NEON_2RM_VABS 22
4768
#define NEON_2RM_VNEG 23
4769
#define NEON_2RM_VCGT0_F 24
4770
#define NEON_2RM_VCGE0_F 25
4771
#define NEON_2RM_VCEQ0_F 26
4772
#define NEON_2RM_VCLE0_F 27
4773
#define NEON_2RM_VCLT0_F 28
4774
#define NEON_2RM_VABS_F 30
4775
#define NEON_2RM_VNEG_F 31
4776
#define NEON_2RM_VSWP 32
4777
#define NEON_2RM_VTRN 33
4778
#define NEON_2RM_VUZP 34
4779
#define NEON_2RM_VZIP 35
4780
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4781
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4782
#define NEON_2RM_VSHLL 38
4783
#define NEON_2RM_VRINTN 40
4784
#define NEON_2RM_VRINTX 41
4785
#define NEON_2RM_VRINTA 42
4786
#define NEON_2RM_VRINTZ 43
4787
#define NEON_2RM_VCVT_F16_F32 44
4788
#define NEON_2RM_VRINTM 45
4789
#define NEON_2RM_VCVT_F32_F16 46
4790
#define NEON_2RM_VRINTP 47
4791
#define NEON_2RM_VCVTAU 48
4792
#define NEON_2RM_VCVTAS 49
4793
#define NEON_2RM_VCVTNU 50
4794
#define NEON_2RM_VCVTNS 51
4795
#define NEON_2RM_VCVTPU 52
4796
#define NEON_2RM_VCVTPS 53
4797
#define NEON_2RM_VCVTMU 54
4798
#define NEON_2RM_VCVTMS 55
4799
#define NEON_2RM_VRECPE 56
4800
#define NEON_2RM_VRSQRTE 57
4801
#define NEON_2RM_VRECPE_F 58
4802
#define NEON_2RM_VRSQRTE_F 59
4803
#define NEON_2RM_VCVT_FS 60
4804
#define NEON_2RM_VCVT_FU 61
4805
#define NEON_2RM_VCVT_SF 62
4806
#define NEON_2RM_VCVT_UF 63
4808
static int neon_2rm_is_float_op(int op)
4810
/* Return true if this neon 2reg-misc op is float-to-float */
4811
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4812
(op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4813
op == NEON_2RM_VRINTM ||
4814
(op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4815
op >= NEON_2RM_VRECPE_F);
4818
/* Each entry in this array has bit n set if the insn allows
4819
* size value n (otherwise it will UNDEF). Since unallocated
4820
* op values will have no bits set they always UNDEF.
4822
static const uint8_t neon_2rm_sizes[] = {
4823
[NEON_2RM_VREV64] = 0x7,
4824
[NEON_2RM_VREV32] = 0x3,
4825
[NEON_2RM_VREV16] = 0x1,
4826
[NEON_2RM_VPADDL] = 0x7,
4827
[NEON_2RM_VPADDL_U] = 0x7,
4828
[NEON_2RM_VCLS] = 0x7,
4829
[NEON_2RM_VCLZ] = 0x7,
4830
[NEON_2RM_VCNT] = 0x1,
4831
[NEON_2RM_VMVN] = 0x1,
4832
[NEON_2RM_VPADAL] = 0x7,
4833
[NEON_2RM_VPADAL_U] = 0x7,
4834
[NEON_2RM_VQABS] = 0x7,
4835
[NEON_2RM_VQNEG] = 0x7,
4836
[NEON_2RM_VCGT0] = 0x7,
4837
[NEON_2RM_VCGE0] = 0x7,
4838
[NEON_2RM_VCEQ0] = 0x7,
4839
[NEON_2RM_VCLE0] = 0x7,
4840
[NEON_2RM_VCLT0] = 0x7,
4841
[NEON_2RM_VABS] = 0x7,
4842
[NEON_2RM_VNEG] = 0x7,
4843
[NEON_2RM_VCGT0_F] = 0x4,
4844
[NEON_2RM_VCGE0_F] = 0x4,
4845
[NEON_2RM_VCEQ0_F] = 0x4,
4846
[NEON_2RM_VCLE0_F] = 0x4,
4847
[NEON_2RM_VCLT0_F] = 0x4,
4848
[NEON_2RM_VABS_F] = 0x4,
4849
[NEON_2RM_VNEG_F] = 0x4,
4850
[NEON_2RM_VSWP] = 0x1,
4851
[NEON_2RM_VTRN] = 0x7,
4852
[NEON_2RM_VUZP] = 0x7,
4853
[NEON_2RM_VZIP] = 0x7,
4854
[NEON_2RM_VMOVN] = 0x7,
4855
[NEON_2RM_VQMOVN] = 0x7,
4856
[NEON_2RM_VSHLL] = 0x7,
4857
[NEON_2RM_VRINTN] = 0x4,
4858
[NEON_2RM_VRINTX] = 0x4,
4859
[NEON_2RM_VRINTA] = 0x4,
4860
[NEON_2RM_VRINTZ] = 0x4,
4861
[NEON_2RM_VCVT_F16_F32] = 0x2,
4862
[NEON_2RM_VRINTM] = 0x4,
4863
[NEON_2RM_VCVT_F32_F16] = 0x2,
4864
[NEON_2RM_VRINTP] = 0x4,
4865
[NEON_2RM_VCVTAU] = 0x4,
4866
[NEON_2RM_VCVTAS] = 0x4,
4867
[NEON_2RM_VCVTNU] = 0x4,
4868
[NEON_2RM_VCVTNS] = 0x4,
4869
[NEON_2RM_VCVTPU] = 0x4,
4870
[NEON_2RM_VCVTPS] = 0x4,
4871
[NEON_2RM_VCVTMU] = 0x4,
4872
[NEON_2RM_VCVTMS] = 0x4,
4873
[NEON_2RM_VRECPE] = 0x4,
4874
[NEON_2RM_VRSQRTE] = 0x4,
4875
[NEON_2RM_VRECPE_F] = 0x4,
4876
[NEON_2RM_VRSQRTE_F] = 0x4,
4877
[NEON_2RM_VCVT_FS] = 0x4,
4878
[NEON_2RM_VCVT_FU] = 0x4,
4879
[NEON_2RM_VCVT_SF] = 0x4,
4880
[NEON_2RM_VCVT_UF] = 0x4,
4883
/* Translate a NEON data processing instruction. Return nonzero if the
4884
instruction is invalid.
4885
We process data in a mixture of 32-bit and 64-bit chunks.
4886
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4888
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4900
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4903
if (!s->vfp_enabled)
4905
q = (insn & (1 << 6)) != 0;
4906
u = (insn >> 24) & 1;
4907
VFP_DREG_D(rd, insn);
4908
VFP_DREG_N(rn, insn);
4909
VFP_DREG_M(rm, insn);
4910
size = (insn >> 20) & 3;
4911
if ((insn & (1 << 23)) == 0) {
4912
/* Three register same length. */
4913
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4914
/* Catch invalid op and bad size combinations: UNDEF */
4915
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4918
/* All insns of this form UNDEF for either this condition or the
4919
* superset of cases "Q==1"; we catch the latter later.
4921
if (q && ((rd | rn | rm) & 1)) {
4924
if (size == 3 && op != NEON_3R_LOGIC) {
4925
/* 64-bit element instructions. */
4926
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4927
neon_load_reg64(cpu_V0, rn + pass);
4928
neon_load_reg64(cpu_V1, rm + pass);
4932
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4935
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4941
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4944
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4950
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4952
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4957
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4960
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4966
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4968
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4971
case NEON_3R_VQRSHL:
4973
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4976
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4980
case NEON_3R_VADD_VSUB:
4982
tcg_gen_sub_i64(CPU_V001);
4984
tcg_gen_add_i64(CPU_V001);
4990
neon_store_reg64(cpu_V0, rd + pass);
4999
case NEON_3R_VQRSHL:
5002
/* Shift instruction operands are reversed. */
5017
case NEON_3R_FLOAT_ARITH:
5018
pairwise = (u && size < 2); /* if VPADD (float) */
5020
case NEON_3R_FLOAT_MINMAX:
5021
pairwise = u; /* if VPMIN/VPMAX (float) */
5023
case NEON_3R_FLOAT_CMP:
5025
/* no encoding for U=0 C=1x */
5029
case NEON_3R_FLOAT_ACMP:
5034
case NEON_3R_FLOAT_MISC:
5035
/* VMAXNM/VMINNM in ARMv8 */
5036
if (u && !arm_feature(env, ARM_FEATURE_V8)) {
5041
if (u && (size != 0)) {
5042
/* UNDEF on invalid size for polynomial subcase */
5047
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
5055
if (pairwise && q) {
5056
/* All the pairwise insns UNDEF if Q is set */
5060
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5065
tmp = neon_load_reg(rn, 0);
5066
tmp2 = neon_load_reg(rn, 1);
5068
tmp = neon_load_reg(rm, 0);
5069
tmp2 = neon_load_reg(rm, 1);
5073
tmp = neon_load_reg(rn, pass);
5074
tmp2 = neon_load_reg(rm, pass);
5078
GEN_NEON_INTEGER_OP(hadd);
5081
GEN_NEON_INTEGER_OP_ENV(qadd);
5083
case NEON_3R_VRHADD:
5084
GEN_NEON_INTEGER_OP(rhadd);
5086
case NEON_3R_LOGIC: /* Logic ops. */
5087
switch ((u << 2) | size) {
5089
tcg_gen_and_i32(tmp, tmp, tmp2);
5092
tcg_gen_andc_i32(tmp, tmp, tmp2);
5095
tcg_gen_or_i32(tmp, tmp, tmp2);
5098
tcg_gen_orc_i32(tmp, tmp, tmp2);
5101
tcg_gen_xor_i32(tmp, tmp, tmp2);
5104
tmp3 = neon_load_reg(rd, pass);
5105
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5106
tcg_temp_free_i32(tmp3);
5109
tmp3 = neon_load_reg(rd, pass);
5110
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5111
tcg_temp_free_i32(tmp3);
5114
tmp3 = neon_load_reg(rd, pass);
5115
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5116
tcg_temp_free_i32(tmp3);
5121
GEN_NEON_INTEGER_OP(hsub);
5124
GEN_NEON_INTEGER_OP_ENV(qsub);
5127
GEN_NEON_INTEGER_OP(cgt);
5130
GEN_NEON_INTEGER_OP(cge);
5133
GEN_NEON_INTEGER_OP(shl);
5136
GEN_NEON_INTEGER_OP_ENV(qshl);
5139
GEN_NEON_INTEGER_OP(rshl);
5141
case NEON_3R_VQRSHL:
5142
GEN_NEON_INTEGER_OP_ENV(qrshl);
5145
GEN_NEON_INTEGER_OP(max);
5148
GEN_NEON_INTEGER_OP(min);
5151
GEN_NEON_INTEGER_OP(abd);
5154
GEN_NEON_INTEGER_OP(abd);
5155
tcg_temp_free_i32(tmp2);
5156
tmp2 = neon_load_reg(rd, pass);
5157
gen_neon_add(size, tmp, tmp2);
5159
case NEON_3R_VADD_VSUB:
5160
if (!u) { /* VADD */
5161
gen_neon_add(size, tmp, tmp2);
5164
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5165
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5166
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5171
case NEON_3R_VTST_VCEQ:
5172
if (!u) { /* VTST */
5174
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5175
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5176
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5181
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5182
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5183
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5188
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5190
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5191
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5192
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5195
tcg_temp_free_i32(tmp2);
5196
tmp2 = neon_load_reg(rd, pass);
5198
gen_neon_rsb(size, tmp, tmp2);
5200
gen_neon_add(size, tmp, tmp2);
5204
if (u) { /* polynomial */
5205
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5206
} else { /* Integer */
5208
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5209
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5210
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5216
GEN_NEON_INTEGER_OP(pmax);
5219
GEN_NEON_INTEGER_OP(pmin);
5221
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5222
if (!u) { /* VQDMULH */
5225
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5228
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5232
} else { /* VQRDMULH */
5235
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5238
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5246
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5247
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5248
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5252
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5254
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5255
switch ((u << 2) | size) {
5258
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5261
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5264
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5269
tcg_temp_free_ptr(fpstatus);
5272
case NEON_3R_FLOAT_MULTIPLY:
5274
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5275
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5277
tcg_temp_free_i32(tmp2);
5278
tmp2 = neon_load_reg(rd, pass);
5280
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5282
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5285
tcg_temp_free_ptr(fpstatus);
5288
case NEON_3R_FLOAT_CMP:
5290
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5292
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5295
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5297
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5300
tcg_temp_free_ptr(fpstatus);
5303
case NEON_3R_FLOAT_ACMP:
5305
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5307
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5309
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5311
tcg_temp_free_ptr(fpstatus);
5314
case NEON_3R_FLOAT_MINMAX:
5316
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5318
gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5320
gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5322
tcg_temp_free_ptr(fpstatus);
5325
case NEON_3R_FLOAT_MISC:
5328
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5330
gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5332
gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5334
tcg_temp_free_ptr(fpstatus);
5337
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5339
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5345
/* VFMA, VFMS: fused multiply-add */
5346
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5347
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5350
gen_helper_vfp_negs(tmp, tmp);
5352
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5353
tcg_temp_free_i32(tmp3);
5354
tcg_temp_free_ptr(fpstatus);
5360
tcg_temp_free_i32(tmp2);
5362
/* Save the result. For elementwise operations we can put it
5363
straight into the destination register. For pairwise operations
5364
we have to be careful to avoid clobbering the source operands. */
5365
if (pairwise && rd == rm) {
5366
neon_store_scratch(pass, tmp);
5368
neon_store_reg(rd, pass, tmp);
5372
if (pairwise && rd == rm) {
5373
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5374
tmp = neon_load_scratch(pass);
5375
neon_store_reg(rd, pass, tmp);
5378
/* End of 3 register same size operations. */
5379
} else if (insn & (1 << 4)) {
5380
if ((insn & 0x00380080) != 0) {
5381
/* Two registers and shift. */
5382
op = (insn >> 8) & 0xf;
5383
if (insn & (1 << 7)) {
5391
while ((insn & (1 << (size + 19))) == 0)
5394
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5395
/* To avoid excessive duplication of ops we implement shift
5396
by immediate using the variable shift operations. */
5398
/* Shift by immediate:
5399
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5400
if (q && ((rd | rm) & 1)) {
5403
if (!u && (op == 4 || op == 6)) {
5406
/* Right shifts are encoded as N - shift, where N is the
5407
element size in bits. */
5409
shift = shift - (1 << (size + 3));
5417
imm = (uint8_t) shift;
5422
imm = (uint16_t) shift;
5433
for (pass = 0; pass < count; pass++) {
5435
neon_load_reg64(cpu_V0, rm + pass);
5436
tcg_gen_movi_i64(cpu_V1, imm);
5441
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5443
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5448
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5450
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5453
case 5: /* VSHL, VSLI */
5454
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5456
case 6: /* VQSHLU */
5457
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5462
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5465
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5470
if (op == 1 || op == 3) {
5472
neon_load_reg64(cpu_V1, rd + pass);
5473
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5474
} else if (op == 4 || (op == 5 && u)) {
5476
neon_load_reg64(cpu_V1, rd + pass);
5478
if (shift < -63 || shift > 63) {
5482
mask = 0xffffffffffffffffull >> -shift;
5484
mask = 0xffffffffffffffffull << shift;
5487
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5488
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5490
neon_store_reg64(cpu_V0, rd + pass);
5491
} else { /* size < 3 */
5492
/* Operands in T0 and T1. */
5493
tmp = neon_load_reg(rm, pass);
5494
tmp2 = tcg_temp_new_i32();
5495
tcg_gen_movi_i32(tmp2, imm);
5499
GEN_NEON_INTEGER_OP(shl);
5503
GEN_NEON_INTEGER_OP(rshl);
5506
case 5: /* VSHL, VSLI */
5508
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5509
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5510
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5514
case 6: /* VQSHLU */
5517
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5521
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5525
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5533
GEN_NEON_INTEGER_OP_ENV(qshl);
5536
tcg_temp_free_i32(tmp2);
5538
if (op == 1 || op == 3) {
5540
tmp2 = neon_load_reg(rd, pass);
5541
gen_neon_add(size, tmp, tmp2);
5542
tcg_temp_free_i32(tmp2);
5543
} else if (op == 4 || (op == 5 && u)) {
5548
mask = 0xff >> -shift;
5550
mask = (uint8_t)(0xff << shift);
5556
mask = 0xffff >> -shift;
5558
mask = (uint16_t)(0xffff << shift);
5562
if (shift < -31 || shift > 31) {
5566
mask = 0xffffffffu >> -shift;
5568
mask = 0xffffffffu << shift;
5574
tmp2 = neon_load_reg(rd, pass);
5575
tcg_gen_andi_i32(tmp, tmp, mask);
5576
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5577
tcg_gen_or_i32(tmp, tmp, tmp2);
5578
tcg_temp_free_i32(tmp2);
5580
neon_store_reg(rd, pass, tmp);
5583
} else if (op < 10) {
5584
/* Shift by immediate and narrow:
5585
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5586
int input_unsigned = (op == 8) ? !u : u;
5590
shift = shift - (1 << (size + 3));
5593
tmp64 = tcg_const_i64(shift);
5594
neon_load_reg64(cpu_V0, rm);
5595
neon_load_reg64(cpu_V1, rm + 1);
5596
for (pass = 0; pass < 2; pass++) {
5604
if (input_unsigned) {
5605
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5607
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5610
if (input_unsigned) {
5611
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5613
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5616
tmp = tcg_temp_new_i32();
5617
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5618
neon_store_reg(rd, pass, tmp);
5620
tcg_temp_free_i64(tmp64);
5623
imm = (uint16_t)shift;
5627
imm = (uint32_t)shift;
5629
tmp2 = tcg_const_i32(imm);
5630
tmp4 = neon_load_reg(rm + 1, 0);
5631
tmp5 = neon_load_reg(rm + 1, 1);
5632
for (pass = 0; pass < 2; pass++) {
5634
tmp = neon_load_reg(rm, 0);
5638
gen_neon_shift_narrow(size, tmp, tmp2, q,
5641
tmp3 = neon_load_reg(rm, 1);
5645
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5647
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5648
tcg_temp_free_i32(tmp);
5649
tcg_temp_free_i32(tmp3);
5650
tmp = tcg_temp_new_i32();
5651
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5652
neon_store_reg(rd, pass, tmp);
5654
tcg_temp_free_i32(tmp2);
5656
} else if (op == 10) {
5658
if (q || (rd & 1)) {
5661
tmp = neon_load_reg(rm, 0);
5662
tmp2 = neon_load_reg(rm, 1);
5663
for (pass = 0; pass < 2; pass++) {
5667
gen_neon_widen(cpu_V0, tmp, size, u);
5670
/* The shift is less than the width of the source
5671
type, so we can just shift the whole register. */
5672
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5673
/* Widen the result of shift: we need to clear
5674
* the potential overflow bits resulting from
5675
* left bits of the narrow input appearing as
5676
* right bits of left the neighbour narrow
5678
if (size < 2 || !u) {
5681
imm = (0xffu >> (8 - shift));
5683
} else if (size == 1) {
5684
imm = 0xffff >> (16 - shift);
5687
imm = 0xffffffff >> (32 - shift);
5690
imm64 = imm | (((uint64_t)imm) << 32);
5694
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5697
neon_store_reg64(cpu_V0, rd + pass);
5699
} else if (op >= 14) {
5700
/* VCVT fixed-point. */
5701
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5704
/* We have already masked out the must-be-1 top bit of imm6,
5705
* hence this 32-shift where the ARM ARM has 64-imm6.
5708
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5709
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5712
gen_vfp_ulto(0, shift, 1);
5714
gen_vfp_slto(0, shift, 1);
5717
gen_vfp_toul(0, shift, 1);
5719
gen_vfp_tosl(0, shift, 1);
5721
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5726
} else { /* (insn & 0x00380080) == 0 */
5728
if (q && (rd & 1)) {
5732
op = (insn >> 8) & 0xf;
5733
/* One register and immediate. */
5734
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5735
invert = (insn & (1 << 5)) != 0;
5736
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5737
* We choose to not special-case this and will behave as if a
5738
* valid constant encoding of 0 had been given.
5757
imm = (imm << 8) | (imm << 24);
5760
imm = (imm << 8) | 0xff;
5763
imm = (imm << 16) | 0xffff;
5766
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5774
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5775
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5781
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5782
if (op & 1 && op < 12) {
5783
tmp = neon_load_reg(rd, pass);
5785
/* The immediate value has already been inverted, so
5787
tcg_gen_andi_i32(tmp, tmp, imm);
5789
tcg_gen_ori_i32(tmp, tmp, imm);
5793
tmp = tcg_temp_new_i32();
5794
if (op == 14 && invert) {
5798
for (n = 0; n < 4; n++) {
5799
if (imm & (1 << (n + (pass & 1) * 4)))
5800
val |= 0xff << (n * 8);
5802
tcg_gen_movi_i32(tmp, val);
5804
tcg_gen_movi_i32(tmp, imm);
5807
neon_store_reg(rd, pass, tmp);
5810
} else { /* (insn & 0x00800010 == 0x00800000) */
5812
op = (insn >> 8) & 0xf;
5813
if ((insn & (1 << 6)) == 0) {
5814
/* Three registers of different lengths. */
5818
/* undefreq: bit 0 : UNDEF if size != 0
5819
* bit 1 : UNDEF if size == 0
5820
* bit 2 : UNDEF if U == 1
5821
* Note that [1:0] set implies 'always UNDEF'
5824
/* prewiden, src1_wide, src2_wide, undefreq */
5825
static const int neon_3reg_wide[16][4] = {
5826
{1, 0, 0, 0}, /* VADDL */
5827
{1, 1, 0, 0}, /* VADDW */
5828
{1, 0, 0, 0}, /* VSUBL */
5829
{1, 1, 0, 0}, /* VSUBW */
5830
{0, 1, 1, 0}, /* VADDHN */
5831
{0, 0, 0, 0}, /* VABAL */
5832
{0, 1, 1, 0}, /* VSUBHN */
5833
{0, 0, 0, 0}, /* VABDL */
5834
{0, 0, 0, 0}, /* VMLAL */
5835
{0, 0, 0, 6}, /* VQDMLAL */
5836
{0, 0, 0, 0}, /* VMLSL */
5837
{0, 0, 0, 6}, /* VQDMLSL */
5838
{0, 0, 0, 0}, /* Integer VMULL */
5839
{0, 0, 0, 2}, /* VQDMULL */
5840
{0, 0, 0, 5}, /* Polynomial VMULL */
5841
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5844
prewiden = neon_3reg_wide[op][0];
5845
src1_wide = neon_3reg_wide[op][1];
5846
src2_wide = neon_3reg_wide[op][2];
5847
undefreq = neon_3reg_wide[op][3];
5849
if (((undefreq & 1) && (size != 0)) ||
5850
((undefreq & 2) && (size == 0)) ||
5851
((undefreq & 4) && u)) {
5854
if ((src1_wide && (rn & 1)) ||
5855
(src2_wide && (rm & 1)) ||
5856
(!src2_wide && (rd & 1))) {
5860
/* Avoid overlapping operands. Wide source operands are
5861
always aligned so will never overlap with wide
5862
destinations in problematic ways. */
5863
if (rd == rm && !src2_wide) {
5864
tmp = neon_load_reg(rm, 1);
5865
neon_store_scratch(2, tmp);
5866
} else if (rd == rn && !src1_wide) {
5867
tmp = neon_load_reg(rn, 1);
5868
neon_store_scratch(2, tmp);
5870
TCGV_UNUSED_I32(tmp3);
5871
for (pass = 0; pass < 2; pass++) {
5873
neon_load_reg64(cpu_V0, rn + pass);
5874
TCGV_UNUSED_I32(tmp);
5876
if (pass == 1 && rd == rn) {
5877
tmp = neon_load_scratch(2);
5879
tmp = neon_load_reg(rn, pass);
5882
gen_neon_widen(cpu_V0, tmp, size, u);
5886
neon_load_reg64(cpu_V1, rm + pass);
5887
TCGV_UNUSED_I32(tmp2);
5889
if (pass == 1 && rd == rm) {
5890
tmp2 = neon_load_scratch(2);
5892
tmp2 = neon_load_reg(rm, pass);
5895
gen_neon_widen(cpu_V1, tmp2, size, u);
5899
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5900
gen_neon_addl(size);
5902
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5903
gen_neon_subl(size);
5905
case 5: case 7: /* VABAL, VABDL */
5906
switch ((size << 1) | u) {
5908
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5911
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5914
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5917
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5920
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5923
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5927
tcg_temp_free_i32(tmp2);
5928
tcg_temp_free_i32(tmp);
5930
case 8: case 9: case 10: case 11: case 12: case 13:
5931
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5932
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5934
case 14: /* Polynomial VMULL */
5935
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5936
tcg_temp_free_i32(tmp2);
5937
tcg_temp_free_i32(tmp);
5939
default: /* 15 is RESERVED: caught earlier */
5944
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5945
neon_store_reg64(cpu_V0, rd + pass);
5946
} else if (op == 5 || (op >= 8 && op <= 11)) {
5948
neon_load_reg64(cpu_V1, rd + pass);
5950
case 10: /* VMLSL */
5951
gen_neon_negl(cpu_V0, size);
5953
case 5: case 8: /* VABAL, VMLAL */
5954
gen_neon_addl(size);
5956
case 9: case 11: /* VQDMLAL, VQDMLSL */
5957
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5959
gen_neon_negl(cpu_V0, size);
5961
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5966
neon_store_reg64(cpu_V0, rd + pass);
5967
} else if (op == 4 || op == 6) {
5968
/* Narrowing operation. */
5969
tmp = tcg_temp_new_i32();
5973
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5976
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5979
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5980
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5987
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5990
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5993
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5994
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5995
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6003
neon_store_reg(rd, 0, tmp3);
6004
neon_store_reg(rd, 1, tmp);
6007
/* Write back the result. */
6008
neon_store_reg64(cpu_V0, rd + pass);
6012
/* Two registers and a scalar. NB that for ops of this form
6013
* the ARM ARM labels bit 24 as Q, but it is in our variable
6020
case 1: /* Float VMLA scalar */
6021
case 5: /* Floating point VMLS scalar */
6022
case 9: /* Floating point VMUL scalar */
6027
case 0: /* Integer VMLA scalar */
6028
case 4: /* Integer VMLS scalar */
6029
case 8: /* Integer VMUL scalar */
6030
case 12: /* VQDMULH scalar */
6031
case 13: /* VQRDMULH scalar */
6032
if (u && ((rd | rn) & 1)) {
6035
tmp = neon_get_scalar(size, rm);
6036
neon_store_scratch(0, tmp);
6037
for (pass = 0; pass < (u ? 4 : 2); pass++) {
6038
tmp = neon_load_scratch(0);
6039
tmp2 = neon_load_reg(rn, pass);
6042
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6044
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6046
} else if (op == 13) {
6048
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6050
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6052
} else if (op & 1) {
6053
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6054
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6055
tcg_temp_free_ptr(fpstatus);
6058
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6059
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6060
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6064
tcg_temp_free_i32(tmp2);
6067
tmp2 = neon_load_reg(rd, pass);
6070
gen_neon_add(size, tmp, tmp2);
6074
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6075
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6076
tcg_temp_free_ptr(fpstatus);
6080
gen_neon_rsb(size, tmp, tmp2);
6084
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6085
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6086
tcg_temp_free_ptr(fpstatus);
6092
tcg_temp_free_i32(tmp2);
6094
neon_store_reg(rd, pass, tmp);
6097
case 3: /* VQDMLAL scalar */
6098
case 7: /* VQDMLSL scalar */
6099
case 11: /* VQDMULL scalar */
6104
case 2: /* VMLAL sclar */
6105
case 6: /* VMLSL scalar */
6106
case 10: /* VMULL scalar */
6110
tmp2 = neon_get_scalar(size, rm);
6111
/* We need a copy of tmp2 because gen_neon_mull
6112
* deletes it during pass 0. */
6113
tmp4 = tcg_temp_new_i32();
6114
tcg_gen_mov_i32(tmp4, tmp2);
6115
tmp3 = neon_load_reg(rn, 1);
6117
for (pass = 0; pass < 2; pass++) {
6119
tmp = neon_load_reg(rn, 0);
6124
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6126
neon_load_reg64(cpu_V1, rd + pass);
6130
gen_neon_negl(cpu_V0, size);
6133
gen_neon_addl(size);
6136
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6138
gen_neon_negl(cpu_V0, size);
6140
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6146
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6151
neon_store_reg64(cpu_V0, rd + pass);
6156
default: /* 14 and 15 are RESERVED */
6160
} else { /* size == 3 */
6163
imm = (insn >> 8) & 0xf;
6168
if (q && ((rd | rn | rm) & 1)) {
6173
neon_load_reg64(cpu_V0, rn);
6175
neon_load_reg64(cpu_V1, rn + 1);
6177
} else if (imm == 8) {
6178
neon_load_reg64(cpu_V0, rn + 1);
6180
neon_load_reg64(cpu_V1, rm);
6183
tmp64 = tcg_temp_new_i64();
6185
neon_load_reg64(cpu_V0, rn);
6186
neon_load_reg64(tmp64, rn + 1);
6188
neon_load_reg64(cpu_V0, rn + 1);
6189
neon_load_reg64(tmp64, rm);
6191
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6192
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6193
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6195
neon_load_reg64(cpu_V1, rm);
6197
neon_load_reg64(cpu_V1, rm + 1);
6200
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6201
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6202
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6203
tcg_temp_free_i64(tmp64);
6206
neon_load_reg64(cpu_V0, rn);
6207
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6208
neon_load_reg64(cpu_V1, rm);
6209
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6210
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6212
neon_store_reg64(cpu_V0, rd);
6214
neon_store_reg64(cpu_V1, rd + 1);
6216
} else if ((insn & (1 << 11)) == 0) {
6217
/* Two register misc. */
6218
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6219
size = (insn >> 18) & 3;
6220
/* UNDEF for unknown op values and bad op-size combinations */
6221
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6224
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6225
q && ((rm | rd) & 1)) {
6229
case NEON_2RM_VREV64:
6230
for (pass = 0; pass < (q ? 2 : 1); pass++) {
6231
tmp = neon_load_reg(rm, pass * 2);
6232
tmp2 = neon_load_reg(rm, pass * 2 + 1);
6234
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6235
case 1: gen_swap_half(tmp); break;
6236
case 2: /* no-op */ break;
6239
neon_store_reg(rd, pass * 2 + 1, tmp);
6241
neon_store_reg(rd, pass * 2, tmp2);
6244
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6245
case 1: gen_swap_half(tmp2); break;
6248
neon_store_reg(rd, pass * 2, tmp2);
6252
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6253
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6254
for (pass = 0; pass < q + 1; pass++) {
6255
tmp = neon_load_reg(rm, pass * 2);
6256
gen_neon_widen(cpu_V0, tmp, size, op & 1);
6257
tmp = neon_load_reg(rm, pass * 2 + 1);
6258
gen_neon_widen(cpu_V1, tmp, size, op & 1);
6260
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6261
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6262
case 2: tcg_gen_add_i64(CPU_V001); break;
6265
if (op >= NEON_2RM_VPADAL) {
6267
neon_load_reg64(cpu_V1, rd + pass);
6268
gen_neon_addl(size);
6270
neon_store_reg64(cpu_V0, rd + pass);
6276
for (n = 0; n < (q ? 4 : 2); n += 2) {
6277
tmp = neon_load_reg(rm, n);
6278
tmp2 = neon_load_reg(rd, n + 1);
6279
neon_store_reg(rm, n, tmp2);
6280
neon_store_reg(rd, n + 1, tmp);
6287
if (gen_neon_unzip(rd, rm, size, q)) {
6292
if (gen_neon_zip(rd, rm, size, q)) {
6296
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6297
/* also VQMOVUN; op field and mnemonics don't line up */
6301
TCGV_UNUSED_I32(tmp2);
6302
for (pass = 0; pass < 2; pass++) {
6303
neon_load_reg64(cpu_V0, rm + pass);
6304
tmp = tcg_temp_new_i32();
6305
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6310
neon_store_reg(rd, 0, tmp2);
6311
neon_store_reg(rd, 1, tmp);
6315
case NEON_2RM_VSHLL:
6316
if (q || (rd & 1)) {
6319
tmp = neon_load_reg(rm, 0);
6320
tmp2 = neon_load_reg(rm, 1);
6321
for (pass = 0; pass < 2; pass++) {
6324
gen_neon_widen(cpu_V0, tmp, size, 1);
6325
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6326
neon_store_reg64(cpu_V0, rd + pass);
6329
case NEON_2RM_VCVT_F16_F32:
6330
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6334
tmp = tcg_temp_new_i32();
6335
tmp2 = tcg_temp_new_i32();
6336
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6337
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6338
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6339
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6340
tcg_gen_shli_i32(tmp2, tmp2, 16);
6341
tcg_gen_or_i32(tmp2, tmp2, tmp);
6342
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6343
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6344
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6345
neon_store_reg(rd, 0, tmp2);
6346
tmp2 = tcg_temp_new_i32();
6347
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6348
tcg_gen_shli_i32(tmp2, tmp2, 16);
6349
tcg_gen_or_i32(tmp2, tmp2, tmp);
6350
neon_store_reg(rd, 1, tmp2);
6351
tcg_temp_free_i32(tmp);
6353
case NEON_2RM_VCVT_F32_F16:
6354
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6358
tmp3 = tcg_temp_new_i32();
6359
tmp = neon_load_reg(rm, 0);
6360
tmp2 = neon_load_reg(rm, 1);
6361
tcg_gen_ext16u_i32(tmp3, tmp);
6362
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6363
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6364
tcg_gen_shri_i32(tmp3, tmp, 16);
6365
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6366
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6367
tcg_temp_free_i32(tmp);
6368
tcg_gen_ext16u_i32(tmp3, tmp2);
6369
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6370
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6371
tcg_gen_shri_i32(tmp3, tmp2, 16);
6372
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6373
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6374
tcg_temp_free_i32(tmp2);
6375
tcg_temp_free_i32(tmp3);
6379
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6380
if (neon_2rm_is_float_op(op)) {
6381
tcg_gen_ld_f32(cpu_F0s, cpu_env,
6382
neon_reg_offset(rm, pass));
6383
TCGV_UNUSED_I32(tmp);
6385
tmp = neon_load_reg(rm, pass);
6388
case NEON_2RM_VREV32:
6390
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6391
case 1: gen_swap_half(tmp); break;
6395
case NEON_2RM_VREV16:
6400
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6401
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6402
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6408
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6409
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6410
case 2: gen_helper_clz(tmp, tmp); break;
6415
gen_helper_neon_cnt_u8(tmp, tmp);
6418
tcg_gen_not_i32(tmp, tmp);
6420
case NEON_2RM_VQABS:
6423
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6426
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6429
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6434
case NEON_2RM_VQNEG:
6437
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6440
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6443
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6448
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6449
tmp2 = tcg_const_i32(0);
6451
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6452
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6453
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6456
tcg_temp_free_i32(tmp2);
6457
if (op == NEON_2RM_VCLE0) {
6458
tcg_gen_not_i32(tmp, tmp);
6461
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6462
tmp2 = tcg_const_i32(0);
6464
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6465
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6466
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6469
tcg_temp_free_i32(tmp2);
6470
if (op == NEON_2RM_VCLT0) {
6471
tcg_gen_not_i32(tmp, tmp);
6474
case NEON_2RM_VCEQ0:
6475
tmp2 = tcg_const_i32(0);
6477
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6478
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6479
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6482
tcg_temp_free_i32(tmp2);
6486
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6487
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6488
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6493
tmp2 = tcg_const_i32(0);
6494
gen_neon_rsb(size, tmp, tmp2);
6495
tcg_temp_free_i32(tmp2);
6497
case NEON_2RM_VCGT0_F:
6499
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6500
tmp2 = tcg_const_i32(0);
6501
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6502
tcg_temp_free_i32(tmp2);
6503
tcg_temp_free_ptr(fpstatus);
6506
case NEON_2RM_VCGE0_F:
6508
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6509
tmp2 = tcg_const_i32(0);
6510
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6511
tcg_temp_free_i32(tmp2);
6512
tcg_temp_free_ptr(fpstatus);
6515
case NEON_2RM_VCEQ0_F:
6517
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6518
tmp2 = tcg_const_i32(0);
6519
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6520
tcg_temp_free_i32(tmp2);
6521
tcg_temp_free_ptr(fpstatus);
6524
case NEON_2RM_VCLE0_F:
6526
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6527
tmp2 = tcg_const_i32(0);
6528
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6529
tcg_temp_free_i32(tmp2);
6530
tcg_temp_free_ptr(fpstatus);
6533
case NEON_2RM_VCLT0_F:
6535
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6536
tmp2 = tcg_const_i32(0);
6537
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6538
tcg_temp_free_i32(tmp2);
6539
tcg_temp_free_ptr(fpstatus);
6542
case NEON_2RM_VABS_F:
6545
case NEON_2RM_VNEG_F:
6549
tmp2 = neon_load_reg(rd, pass);
6550
neon_store_reg(rm, pass, tmp2);
6553
tmp2 = neon_load_reg(rd, pass);
6555
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6556
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6559
neon_store_reg(rm, pass, tmp2);
6561
case NEON_2RM_VRINTN:
6562
case NEON_2RM_VRINTA:
6563
case NEON_2RM_VRINTM:
6564
case NEON_2RM_VRINTP:
6565
case NEON_2RM_VRINTZ:
6568
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6571
if (op == NEON_2RM_VRINTZ) {
6572
rmode = FPROUNDING_ZERO;
6574
rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6577
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6578
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6580
gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6581
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6583
tcg_temp_free_ptr(fpstatus);
6584
tcg_temp_free_i32(tcg_rmode);
6587
case NEON_2RM_VRINTX:
6589
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6590
gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6591
tcg_temp_free_ptr(fpstatus);
6594
case NEON_2RM_VCVTAU:
6595
case NEON_2RM_VCVTAS:
6596
case NEON_2RM_VCVTNU:
6597
case NEON_2RM_VCVTNS:
6598
case NEON_2RM_VCVTPU:
6599
case NEON_2RM_VCVTPS:
6600
case NEON_2RM_VCVTMU:
6601
case NEON_2RM_VCVTMS:
6603
bool is_signed = !extract32(insn, 7, 1);
6604
TCGv_ptr fpst = get_fpstatus_ptr(1);
6605
TCGv_i32 tcg_rmode, tcg_shift;
6606
int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6608
tcg_shift = tcg_const_i32(0);
6609
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6610
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6614
gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6617
gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6621
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6623
tcg_temp_free_i32(tcg_rmode);
6624
tcg_temp_free_i32(tcg_shift);
6625
tcg_temp_free_ptr(fpst);
6628
case NEON_2RM_VRECPE:
6629
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6631
case NEON_2RM_VRSQRTE:
6632
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6634
case NEON_2RM_VRECPE_F:
6635
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6637
case NEON_2RM_VRSQRTE_F:
6638
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6640
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6643
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6646
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6647
gen_vfp_tosiz(0, 1);
6649
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6650
gen_vfp_touiz(0, 1);
6653
/* Reserved op values were caught by the
6654
* neon_2rm_sizes[] check earlier.
6658
if (neon_2rm_is_float_op(op)) {
6659
tcg_gen_st_f32(cpu_F0s, cpu_env,
6660
neon_reg_offset(rd, pass));
6662
neon_store_reg(rd, pass, tmp);
6667
} else if ((insn & (1 << 10)) == 0) {
6669
int n = ((insn >> 8) & 3) + 1;
6670
if ((rn + n) > 32) {
6671
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6672
* helper function running off the end of the register file.
6677
if (insn & (1 << 6)) {
6678
tmp = neon_load_reg(rd, 0);
6680
tmp = tcg_temp_new_i32();
6681
tcg_gen_movi_i32(tmp, 0);
6683
tmp2 = neon_load_reg(rm, 0);
6684
tmp4 = tcg_const_i32(rn);
6685
tmp5 = tcg_const_i32(n);
6686
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6687
tcg_temp_free_i32(tmp);
6688
if (insn & (1 << 6)) {
6689
tmp = neon_load_reg(rd, 1);
6691
tmp = tcg_temp_new_i32();
6692
tcg_gen_movi_i32(tmp, 0);
6694
tmp3 = neon_load_reg(rm, 1);
6695
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6696
tcg_temp_free_i32(tmp5);
6697
tcg_temp_free_i32(tmp4);
6698
neon_store_reg(rd, 0, tmp2);
6699
neon_store_reg(rd, 1, tmp3);
6700
tcg_temp_free_i32(tmp);
6701
} else if ((insn & 0x380) == 0) {
6703
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6706
if (insn & (1 << 19)) {
6707
tmp = neon_load_reg(rm, 1);
6709
tmp = neon_load_reg(rm, 0);
6711
if (insn & (1 << 16)) {
6712
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6713
} else if (insn & (1 << 17)) {
6714
if ((insn >> 18) & 1)
6715
gen_neon_dup_high16(tmp);
6717
gen_neon_dup_low16(tmp);
6719
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6720
tmp2 = tcg_temp_new_i32();
6721
tcg_gen_mov_i32(tmp2, tmp);
6722
neon_store_reg(rd, pass, tmp2);
6724
tcg_temp_free_i32(tmp);
6733
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6735
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6736
const ARMCPRegInfo *ri;
6738
cpnum = (insn >> 8) & 0xf;
6739
if (arm_feature(env, ARM_FEATURE_XSCALE)
6740
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6743
/* First check for coprocessor space used for actual instructions */
6747
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6748
return disas_iwmmxt_insn(env, s, insn);
6749
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6750
return disas_dsp_insn(env, s, insn);
6757
/* Otherwise treat as a generic register access */
6758
is64 = (insn & (1 << 25)) == 0;
6759
if (!is64 && ((insn & (1 << 4)) == 0)) {
6767
opc1 = (insn >> 4) & 0xf;
6769
rt2 = (insn >> 16) & 0xf;
6771
crn = (insn >> 16) & 0xf;
6772
opc1 = (insn >> 21) & 7;
6773
opc2 = (insn >> 5) & 7;
6776
isread = (insn >> 20) & 1;
6777
rt = (insn >> 12) & 0xf;
6779
ri = get_arm_cp_reginfo(s->cp_regs,
6780
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6782
/* Check access permissions */
6783
if (!cp_access_ok(s->current_pl, ri, isread)) {
6787
/* Handle special cases first */
6788
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6795
gen_set_pc_im(s, s->pc);
6796
s->is_jmp = DISAS_WFI;
6802
if (use_icount && (ri->type & ARM_CP_IO)) {
6811
if (ri->type & ARM_CP_CONST) {
6812
tmp64 = tcg_const_i64(ri->resetvalue);
6813
} else if (ri->readfn) {
6815
gen_set_pc_im(s, s->pc);
6816
tmp64 = tcg_temp_new_i64();
6817
tmpptr = tcg_const_ptr(ri);
6818
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6819
tcg_temp_free_ptr(tmpptr);
6821
tmp64 = tcg_temp_new_i64();
6822
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6824
tmp = tcg_temp_new_i32();
6825
tcg_gen_trunc_i64_i32(tmp, tmp64);
6826
store_reg(s, rt, tmp);
6827
tcg_gen_shri_i64(tmp64, tmp64, 32);
6828
tmp = tcg_temp_new_i32();
6829
tcg_gen_trunc_i64_i32(tmp, tmp64);
6830
tcg_temp_free_i64(tmp64);
6831
store_reg(s, rt2, tmp);
6834
if (ri->type & ARM_CP_CONST) {
6835
tmp = tcg_const_i32(ri->resetvalue);
6836
} else if (ri->readfn) {
6838
gen_set_pc_im(s, s->pc);
6839
tmp = tcg_temp_new_i32();
6840
tmpptr = tcg_const_ptr(ri);
6841
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6842
tcg_temp_free_ptr(tmpptr);
6844
tmp = load_cpu_offset(ri->fieldoffset);
6847
/* Destination register of r15 for 32 bit loads sets
6848
* the condition codes from the high 4 bits of the value
6851
tcg_temp_free_i32(tmp);
6853
store_reg(s, rt, tmp);
6858
if (ri->type & ARM_CP_CONST) {
6859
/* If not forbidden by access permissions, treat as WI */
6864
TCGv_i32 tmplo, tmphi;
6865
TCGv_i64 tmp64 = tcg_temp_new_i64();
6866
tmplo = load_reg(s, rt);
6867
tmphi = load_reg(s, rt2);
6868
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6869
tcg_temp_free_i32(tmplo);
6870
tcg_temp_free_i32(tmphi);
6872
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6873
gen_set_pc_im(s, s->pc);
6874
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6875
tcg_temp_free_ptr(tmpptr);
6877
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6879
tcg_temp_free_i64(tmp64);
6884
gen_set_pc_im(s, s->pc);
6885
tmp = load_reg(s, rt);
6886
tmpptr = tcg_const_ptr(ri);
6887
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6888
tcg_temp_free_ptr(tmpptr);
6889
tcg_temp_free_i32(tmp);
6891
TCGv_i32 tmp = load_reg(s, rt);
6892
store_cpu_offset(tmp, ri->fieldoffset);
6897
if (use_icount && (ri->type & ARM_CP_IO)) {
6898
/* I/O operations must end the TB here (whether read or write) */
6901
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6902
/* We default to ending the TB on a coprocessor register write,
6903
* but allow this to be suppressed by the register definition
6904
* (usually only necessary to work around guest bugs).
6916
/* Store a 64-bit value to a register pair. Clobbers val. */
6917
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6920
tmp = tcg_temp_new_i32();
6921
tcg_gen_trunc_i64_i32(tmp, val);
6922
store_reg(s, rlow, tmp);
6923
tmp = tcg_temp_new_i32();
6924
tcg_gen_shri_i64(val, val, 32);
6925
tcg_gen_trunc_i64_i32(tmp, val);
6926
store_reg(s, rhigh, tmp);
6929
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6930
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6935
/* Load value and extend to 64 bits. */
6936
tmp = tcg_temp_new_i64();
6937
tmp2 = load_reg(s, rlow);
6938
tcg_gen_extu_i32_i64(tmp, tmp2);
6939
tcg_temp_free_i32(tmp2);
6940
tcg_gen_add_i64(val, val, tmp);
6941
tcg_temp_free_i64(tmp);
6944
/* load and add a 64-bit value from a register pair. */
6945
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6951
/* Load 64-bit value rd:rn. */
6952
tmpl = load_reg(s, rlow);
6953
tmph = load_reg(s, rhigh);
6954
tmp = tcg_temp_new_i64();
6955
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6956
tcg_temp_free_i32(tmpl);
6957
tcg_temp_free_i32(tmph);
6958
tcg_gen_add_i64(val, val, tmp);
6959
tcg_temp_free_i64(tmp);
6962
/* Set N and Z flags from hi|lo. */
6963
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6965
tcg_gen_mov_i32(cpu_NF, hi);
6966
tcg_gen_or_i32(cpu_ZF, lo, hi);
6969
/* Load/Store exclusive instructions are implemented by remembering
6970
the value/address loaded, and seeing if these are the same
6971
when the store is performed. This should be sufficient to implement
6972
the architecturally mandated semantics, and avoids having to monitor
6975
In system emulation mode only one CPU will be running at once, so
6976
this sequence is effectively atomic. In user emulation mode we
6977
throw an exception and handle the atomic operation elsewhere. */
6978
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6979
TCGv_i32 addr, int size)
6981
TCGv_i32 tmp = tcg_temp_new_i32();
6985
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6988
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6992
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6999
TCGv_i32 tmp2 = tcg_temp_new_i32();
7000
TCGv_i32 tmp3 = tcg_temp_new_i32();
7002
tcg_gen_addi_i32(tmp2, addr, 4);
7003
gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7004
tcg_temp_free_i32(tmp2);
7005
tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7006
store_reg(s, rt2, tmp3);
7008
tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7011
store_reg(s, rt, tmp);
7012
tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7015
static void gen_clrex(DisasContext *s)
7017
tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7020
#ifdef CONFIG_USER_ONLY
7021
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7022
TCGv_i32 addr, int size)
7024
tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7025
tcg_gen_movi_i32(cpu_exclusive_info,
7026
size | (rd << 4) | (rt << 8) | (rt2 << 12));
7027
gen_exception_insn(s, 4, EXCP_STREX);
7030
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7031
TCGv_i32 addr, int size)
7034
TCGv_i64 val64, extaddr;
7038
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7044
fail_label = gen_new_label();
7045
done_label = gen_new_label();
7046
extaddr = tcg_temp_new_i64();
7047
tcg_gen_extu_i32_i64(extaddr, addr);
7048
tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7049
tcg_temp_free_i64(extaddr);
7051
tmp = tcg_temp_new_i32();
7054
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7057
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7061
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7067
val64 = tcg_temp_new_i64();
7069
TCGv_i32 tmp2 = tcg_temp_new_i32();
7070
TCGv_i32 tmp3 = tcg_temp_new_i32();
7071
tcg_gen_addi_i32(tmp2, addr, 4);
7072
gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7073
tcg_temp_free_i32(tmp2);
7074
tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7075
tcg_temp_free_i32(tmp3);
7077
tcg_gen_extu_i32_i64(val64, tmp);
7079
tcg_temp_free_i32(tmp);
7081
tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7082
tcg_temp_free_i64(val64);
7084
tmp = load_reg(s, rt);
7087
gen_aa32_st8(tmp, addr, IS_USER(s));
7090
gen_aa32_st16(tmp, addr, IS_USER(s));
7094
gen_aa32_st32(tmp, addr, IS_USER(s));
7099
tcg_temp_free_i32(tmp);
7101
tcg_gen_addi_i32(addr, addr, 4);
7102
tmp = load_reg(s, rt2);
7103
gen_aa32_st32(tmp, addr, IS_USER(s));
7104
tcg_temp_free_i32(tmp);
7106
tcg_gen_movi_i32(cpu_R[rd], 0);
7107
tcg_gen_br(done_label);
7108
gen_set_label(fail_label);
7109
tcg_gen_movi_i32(cpu_R[rd], 1);
7110
gen_set_label(done_label);
7111
tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7118
* @mode: mode field from insn (which stack to store to)
7119
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7120
* @writeback: true if writeback bit set
7122
* Generate code for the SRS (Store Return State) insn.
7124
static void gen_srs(DisasContext *s,
7125
uint32_t mode, uint32_t amode, bool writeback)
7128
TCGv_i32 addr = tcg_temp_new_i32();
7129
TCGv_i32 tmp = tcg_const_i32(mode);
7130
gen_helper_get_r13_banked(addr, cpu_env, tmp);
7131
tcg_temp_free_i32(tmp);
7148
tcg_gen_addi_i32(addr, addr, offset);
7149
tmp = load_reg(s, 14);
7150
gen_aa32_st32(tmp, addr, 0);
7151
tcg_temp_free_i32(tmp);
7152
tmp = load_cpu_field(spsr);
7153
tcg_gen_addi_i32(addr, addr, 4);
7154
gen_aa32_st32(tmp, addr, 0);
7155
tcg_temp_free_i32(tmp);
7173
tcg_gen_addi_i32(addr, addr, offset);
7174
tmp = tcg_const_i32(mode);
7175
gen_helper_set_r13_banked(cpu_env, tmp, addr);
7176
tcg_temp_free_i32(tmp);
7178
tcg_temp_free_i32(addr);
7181
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
7183
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7190
insn = arm_ldl_code(env, s->pc, s->bswap_code);
7193
/* M variants do not implement ARM mode. */
7198
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7199
* choose to UNDEF. In ARMv5 and above the space is used
7200
* for miscellaneous unconditional instructions.
7204
/* Unconditional instructions. */
7205
if (((insn >> 25) & 7) == 1) {
7206
/* NEON Data processing. */
7207
if (!arm_feature(env, ARM_FEATURE_NEON))
7210
if (disas_neon_data_insn(env, s, insn))
7214
if ((insn & 0x0f100000) == 0x04000000) {
7215
/* NEON load/store. */
7216
if (!arm_feature(env, ARM_FEATURE_NEON))
7219
if (disas_neon_ls_insn(env, s, insn))
7223
if ((insn & 0x0f000e10) == 0x0e000a00) {
7225
if (disas_vfp_insn(env, s, insn)) {
7230
if (((insn & 0x0f30f000) == 0x0510f000) ||
7231
((insn & 0x0f30f010) == 0x0710f000)) {
7232
if ((insn & (1 << 22)) == 0) {
7234
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7238
/* Otherwise PLD; v5TE+ */
7242
if (((insn & 0x0f70f000) == 0x0450f000) ||
7243
((insn & 0x0f70f010) == 0x0650f000)) {
7245
return; /* PLI; V7 */
7247
if (((insn & 0x0f700000) == 0x04100000) ||
7248
((insn & 0x0f700010) == 0x06100000)) {
7249
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7252
return; /* v7MP: Unallocated memory hint: must NOP */
7255
if ((insn & 0x0ffffdff) == 0x01010000) {
7258
if (((insn >> 9) & 1) != s->bswap_code) {
7259
/* Dynamic endianness switching not implemented. */
7260
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7264
} else if ((insn & 0x0fffff00) == 0x057ff000) {
7265
switch ((insn >> 4) & 0xf) {
7274
/* We don't emulate caches so these are a no-op. */
7279
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7285
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7287
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7293
rn = (insn >> 16) & 0xf;
7294
addr = load_reg(s, rn);
7295
i = (insn >> 23) & 3;
7297
case 0: offset = -4; break; /* DA */
7298
case 1: offset = 0; break; /* IA */
7299
case 2: offset = -8; break; /* DB */
7300
case 3: offset = 4; break; /* IB */
7304
tcg_gen_addi_i32(addr, addr, offset);
7305
/* Load PC into tmp and CPSR into tmp2. */
7306
tmp = tcg_temp_new_i32();
7307
gen_aa32_ld32u(tmp, addr, 0);
7308
tcg_gen_addi_i32(addr, addr, 4);
7309
tmp2 = tcg_temp_new_i32();
7310
gen_aa32_ld32u(tmp2, addr, 0);
7311
if (insn & (1 << 21)) {
7312
/* Base writeback. */
7314
case 0: offset = -8; break;
7315
case 1: offset = 4; break;
7316
case 2: offset = -4; break;
7317
case 3: offset = 0; break;
7321
tcg_gen_addi_i32(addr, addr, offset);
7322
store_reg(s, rn, addr);
7324
tcg_temp_free_i32(addr);
7326
gen_rfe(s, tmp, tmp2);
7328
} else if ((insn & 0x0e000000) == 0x0a000000) {
7329
/* branch link and change to thumb (blx <offset>) */
7332
val = (uint32_t)s->pc;
7333
tmp = tcg_temp_new_i32();
7334
tcg_gen_movi_i32(tmp, val);
7335
store_reg(s, 14, tmp);
7336
/* Sign-extend the 24-bit offset */
7337
offset = (((int32_t)insn) << 8) >> 8;
7338
/* offset * 4 + bit24 * 2 + (thumb bit) */
7339
val += (offset << 2) | ((insn >> 23) & 2) | 1;
7340
/* pipeline offset */
7342
/* protected by ARCH(5); above, near the start of uncond block */
7345
} else if ((insn & 0x0e000f00) == 0x0c000100) {
7346
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7347
/* iWMMXt register transfer. */
7348
if (env->cp15.c15_cpar & (1 << 1))
7349
if (!disas_iwmmxt_insn(env, s, insn))
7352
} else if ((insn & 0x0fe00000) == 0x0c400000) {
7353
/* Coprocessor double register transfer. */
7355
/* XXX doesn't belong in the trustzone patch: should just UNDEF? */
7356
cpu_abort(env, "unsupported coprocessor double register transfer\n");
7357
} else if ((insn & 0x0f000010) == 0x0e000010) {
7358
/* Additional coprocessor register transfer. */
7359
if (!disas_coproc_insn(env, s, insn)) {
7362
} else if ((insn & 0x0ff10020) == 0x01000000) {
7365
/* cps (privileged) */
7369
if (insn & (1 << 19)) {
7370
if (insn & (1 << 8))
7372
if (insn & (1 << 7))
7374
if (insn & (1 << 6))
7376
if (insn & (1 << 18))
7379
if (insn & (1 << 17)) {
7381
val |= (insn & 0x1f);
7384
gen_set_psr_im(s, mask, 0, val);
7391
/* if not always execute, we generate a conditional jump to
7393
s->condlabel = gen_new_label();
7394
arm_gen_test_cc(cond ^ 1, s->condlabel);
7397
if ((insn & 0x0f900000) == 0x03000000) {
7398
if ((insn & (1 << 21)) == 0) {
7400
rd = (insn >> 12) & 0xf;
7401
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7402
if ((insn & (1 << 22)) == 0) {
7404
tmp = tcg_temp_new_i32();
7405
tcg_gen_movi_i32(tmp, val);
7408
tmp = load_reg(s, rd);
7409
tcg_gen_ext16u_i32(tmp, tmp);
7410
tcg_gen_ori_i32(tmp, tmp, val << 16);
7412
store_reg(s, rd, tmp);
7414
if (((insn >> 12) & 0xf) != 0xf)
7416
if (((insn >> 16) & 0xf) == 0) {
7417
gen_nop_hint(s, insn & 0xff);
7419
/* CPSR = immediate */
7421
shift = ((insn >> 8) & 0xf) * 2;
7423
val = (val >> shift) | (val << (32 - shift));
7424
i = ((insn & (1 << 22)) != 0);
7425
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7429
} else if ((insn & 0x0f900000) == 0x01000000
7430
&& (insn & 0x00000090) != 0x00000090) {
7431
/* miscellaneous instructions */
7432
op1 = (insn >> 21) & 3;
7433
sh = (insn >> 4) & 0xf;
7436
case 0x0: /* move program status register */
7439
tmp = load_reg(s, rm);
7440
i = ((op1 & 2) != 0);
7441
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7445
rd = (insn >> 12) & 0xf;
7449
tmp = load_cpu_field(spsr);
7451
tmp = tcg_temp_new_i32();
7452
gen_helper_cpsr_read(tmp, cpu_env);
7454
store_reg(s, rd, tmp);
7459
/* branch/exchange thumb (bx). */
7461
tmp = load_reg(s, rm);
7463
} else if (op1 == 3) {
7466
rd = (insn >> 12) & 0xf;
7467
tmp = load_reg(s, rm);
7468
gen_helper_clz(tmp, tmp);
7469
store_reg(s, rd, tmp);
7477
/* Trivial implementation equivalent to bx. */
7478
tmp = load_reg(s, rm);
7489
/* branch link/exchange thumb (blx) */
7490
tmp = load_reg(s, rm);
7491
tmp2 = tcg_temp_new_i32();
7492
tcg_gen_movi_i32(tmp2, s->pc);
7493
store_reg(s, 14, tmp2);
7496
case 0x5: /* saturating add/subtract */
7498
rd = (insn >> 12) & 0xf;
7499
rn = (insn >> 16) & 0xf;
7500
tmp = load_reg(s, rm);
7501
tmp2 = load_reg(s, rn);
7503
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7505
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7507
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7508
tcg_temp_free_i32(tmp2);
7509
store_reg(s, rd, tmp);
7515
gen_exception_insn(s, 4, EXCP_BKPT);
7516
} else if (op1 == 3) {
7518
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
7526
case 0x8: /* signed multiply */
7531
rs = (insn >> 8) & 0xf;
7532
rn = (insn >> 12) & 0xf;
7533
rd = (insn >> 16) & 0xf;
7535
/* (32 * 16) >> 16 */
7536
tmp = load_reg(s, rm);
7537
tmp2 = load_reg(s, rs);
7539
tcg_gen_sari_i32(tmp2, tmp2, 16);
7542
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7543
tcg_gen_shri_i64(tmp64, tmp64, 16);
7544
tmp = tcg_temp_new_i32();
7545
tcg_gen_trunc_i64_i32(tmp, tmp64);
7546
tcg_temp_free_i64(tmp64);
7547
if ((sh & 2) == 0) {
7548
tmp2 = load_reg(s, rn);
7549
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7550
tcg_temp_free_i32(tmp2);
7552
store_reg(s, rd, tmp);
7555
tmp = load_reg(s, rm);
7556
tmp2 = load_reg(s, rs);
7557
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7558
tcg_temp_free_i32(tmp2);
7560
tmp64 = tcg_temp_new_i64();
7561
tcg_gen_ext_i32_i64(tmp64, tmp);
7562
tcg_temp_free_i32(tmp);
7563
gen_addq(s, tmp64, rn, rd);
7564
gen_storeq_reg(s, rn, rd, tmp64);
7565
tcg_temp_free_i64(tmp64);
7568
tmp2 = load_reg(s, rn);
7569
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7570
tcg_temp_free_i32(tmp2);
7572
store_reg(s, rd, tmp);
7579
} else if (((insn & 0x0e000000) == 0 &&
7580
(insn & 0x00000090) != 0x90) ||
7581
((insn & 0x0e000000) == (1 << 25))) {
7582
int set_cc, logic_cc, shiftop;
7584
op1 = (insn >> 21) & 0xf;
7585
set_cc = (insn >> 20) & 1;
7586
logic_cc = table_logic_cc[op1] & set_cc;
7588
/* data processing instruction */
7589
if (insn & (1 << 25)) {
7590
/* immediate operand */
7592
shift = ((insn >> 8) & 0xf) * 2;
7594
val = (val >> shift) | (val << (32 - shift));
7596
tmp2 = tcg_temp_new_i32();
7597
tcg_gen_movi_i32(tmp2, val);
7598
if (logic_cc && shift) {
7599
gen_set_CF_bit31(tmp2);
7604
tmp2 = load_reg(s, rm);
7605
shiftop = (insn >> 5) & 3;
7606
if (!(insn & (1 << 4))) {
7607
shift = (insn >> 7) & 0x1f;
7608
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7610
rs = (insn >> 8) & 0xf;
7611
tmp = load_reg(s, rs);
7612
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7615
if (op1 != 0x0f && op1 != 0x0d) {
7616
rn = (insn >> 16) & 0xf;
7617
tmp = load_reg(s, rn);
7619
TCGV_UNUSED_I32(tmp);
7621
rd = (insn >> 12) & 0xf;
7624
tcg_gen_and_i32(tmp, tmp, tmp2);
7628
store_reg_bx(env, s, rd, tmp);
7631
tcg_gen_xor_i32(tmp, tmp, tmp2);
7635
store_reg_bx(env, s, rd, tmp);
7638
if (set_cc && rd == 15) {
7639
/* SUBS r15, ... is used for exception return. */
7643
gen_sub_CC(tmp, tmp, tmp2);
7644
gen_exception_return(s, tmp);
7647
gen_sub_CC(tmp, tmp, tmp2);
7649
tcg_gen_sub_i32(tmp, tmp, tmp2);
7651
store_reg_bx(env, s, rd, tmp);
7656
gen_sub_CC(tmp, tmp2, tmp);
7658
tcg_gen_sub_i32(tmp, tmp2, tmp);
7660
store_reg_bx(env, s, rd, tmp);
7664
gen_add_CC(tmp, tmp, tmp2);
7666
tcg_gen_add_i32(tmp, tmp, tmp2);
7668
store_reg_bx(env, s, rd, tmp);
7672
gen_adc_CC(tmp, tmp, tmp2);
7674
gen_add_carry(tmp, tmp, tmp2);
7676
store_reg_bx(env, s, rd, tmp);
7680
gen_sbc_CC(tmp, tmp, tmp2);
7682
gen_sub_carry(tmp, tmp, tmp2);
7684
store_reg_bx(env, s, rd, tmp);
7688
gen_sbc_CC(tmp, tmp2, tmp);
7690
gen_sub_carry(tmp, tmp2, tmp);
7692
store_reg_bx(env, s, rd, tmp);
7696
tcg_gen_and_i32(tmp, tmp, tmp2);
7699
tcg_temp_free_i32(tmp);
7703
tcg_gen_xor_i32(tmp, tmp, tmp2);
7706
tcg_temp_free_i32(tmp);
7710
gen_sub_CC(tmp, tmp, tmp2);
7712
tcg_temp_free_i32(tmp);
7716
gen_add_CC(tmp, tmp, tmp2);
7718
tcg_temp_free_i32(tmp);
7721
tcg_gen_or_i32(tmp, tmp, tmp2);
7725
store_reg_bx(env, s, rd, tmp);
7728
if (logic_cc && rd == 15) {
7729
/* MOVS r15, ... is used for exception return. */
7733
gen_exception_return(s, tmp2);
7738
store_reg_bx(env, s, rd, tmp2);
7742
tcg_gen_andc_i32(tmp, tmp, tmp2);
7746
store_reg_bx(env, s, rd, tmp);
7750
tcg_gen_not_i32(tmp2, tmp2);
7754
store_reg_bx(env, s, rd, tmp2);
7757
if (op1 != 0x0f && op1 != 0x0d) {
7758
tcg_temp_free_i32(tmp2);
7761
/* other instructions */
7762
op1 = (insn >> 24) & 0xf;
7766
/* multiplies, extra load/stores */
7767
sh = (insn >> 5) & 3;
7770
rd = (insn >> 16) & 0xf;
7771
rn = (insn >> 12) & 0xf;
7772
rs = (insn >> 8) & 0xf;
7774
op1 = (insn >> 20) & 0xf;
7776
case 0: case 1: case 2: case 3: case 6:
7778
tmp = load_reg(s, rs);
7779
tmp2 = load_reg(s, rm);
7780
tcg_gen_mul_i32(tmp, tmp, tmp2);
7781
tcg_temp_free_i32(tmp2);
7782
if (insn & (1 << 22)) {
7783
/* Subtract (mls) */
7785
tmp2 = load_reg(s, rn);
7786
tcg_gen_sub_i32(tmp, tmp2, tmp);
7787
tcg_temp_free_i32(tmp2);
7788
} else if (insn & (1 << 21)) {
7790
tmp2 = load_reg(s, rn);
7791
tcg_gen_add_i32(tmp, tmp, tmp2);
7792
tcg_temp_free_i32(tmp2);
7794
if (insn & (1 << 20))
7796
store_reg(s, rd, tmp);
7799
/* 64 bit mul double accumulate (UMAAL) */
7801
tmp = load_reg(s, rs);
7802
tmp2 = load_reg(s, rm);
7803
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7804
gen_addq_lo(s, tmp64, rn);
7805
gen_addq_lo(s, tmp64, rd);
7806
gen_storeq_reg(s, rn, rd, tmp64);
7807
tcg_temp_free_i64(tmp64);
7809
case 8: case 9: case 10: case 11:
7810
case 12: case 13: case 14: case 15:
7811
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7812
tmp = load_reg(s, rs);
7813
tmp2 = load_reg(s, rm);
7814
if (insn & (1 << 22)) {
7815
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7817
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7819
if (insn & (1 << 21)) { /* mult accumulate */
7820
TCGv_i32 al = load_reg(s, rn);
7821
TCGv_i32 ah = load_reg(s, rd);
7822
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7823
tcg_temp_free_i32(al);
7824
tcg_temp_free_i32(ah);
7826
if (insn & (1 << 20)) {
7827
gen_logicq_cc(tmp, tmp2);
7829
store_reg(s, rn, tmp);
7830
store_reg(s, rd, tmp2);
7836
rn = (insn >> 16) & 0xf;
7837
rd = (insn >> 12) & 0xf;
7838
if (insn & (1 << 23)) {
7839
/* load/store exclusive */
7840
int op2 = (insn >> 8) & 3;
7841
op1 = (insn >> 21) & 0x3;
7844
case 0: /* lda/stl */
7850
case 1: /* reserved */
7852
case 2: /* ldaex/stlex */
7855
case 3: /* ldrex/strex */
7864
addr = tcg_temp_local_new_i32();
7865
load_reg_var(s, addr, rn);
7867
/* Since the emulation does not have barriers,
7868
the acquire/release semantics need no special
7871
if (insn & (1 << 20)) {
7872
tmp = tcg_temp_new_i32();
7875
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7878
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7881
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7886
store_reg(s, rd, tmp);
7889
tmp = load_reg(s, rm);
7892
gen_aa32_st32(tmp, addr, IS_USER(s));
7895
gen_aa32_st8(tmp, addr, IS_USER(s));
7898
gen_aa32_st16(tmp, addr, IS_USER(s));
7903
tcg_temp_free_i32(tmp);
7905
} else if (insn & (1 << 20)) {
7908
gen_load_exclusive(s, rd, 15, addr, 2);
7910
case 1: /* ldrexd */
7911
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7913
case 2: /* ldrexb */
7914
gen_load_exclusive(s, rd, 15, addr, 0);
7916
case 3: /* ldrexh */
7917
gen_load_exclusive(s, rd, 15, addr, 1);
7926
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7928
case 1: /* strexd */
7929
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7931
case 2: /* strexb */
7932
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7934
case 3: /* strexh */
7935
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7941
tcg_temp_free_i32(addr);
7943
/* SWP instruction */
7946
/* ??? This is not really atomic. However we know
7947
we never have multiple CPUs running in parallel,
7948
so it is good enough. */
7949
addr = load_reg(s, rn);
7950
tmp = load_reg(s, rm);
7951
tmp2 = tcg_temp_new_i32();
7952
if (insn & (1 << 22)) {
7953
gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7954
gen_aa32_st8(tmp, addr, IS_USER(s));
7956
gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7957
gen_aa32_st32(tmp, addr, IS_USER(s));
7959
tcg_temp_free_i32(tmp);
7960
tcg_temp_free_i32(addr);
7961
store_reg(s, rd, tmp2);
7967
/* Misc load/store */
7968
rn = (insn >> 16) & 0xf;
7969
rd = (insn >> 12) & 0xf;
7970
addr = load_reg(s, rn);
7971
if (insn & (1 << 24))
7972
gen_add_datah_offset(s, insn, 0, addr);
7974
if (insn & (1 << 20)) {
7976
tmp = tcg_temp_new_i32();
7979
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7982
gen_aa32_ld8s(tmp, addr, IS_USER(s));
7986
gen_aa32_ld16s(tmp, addr, IS_USER(s));
7990
} else if (sh & 2) {
7995
tmp = load_reg(s, rd);
7996
gen_aa32_st32(tmp, addr, IS_USER(s));
7997
tcg_temp_free_i32(tmp);
7998
tcg_gen_addi_i32(addr, addr, 4);
7999
tmp = load_reg(s, rd + 1);
8000
gen_aa32_st32(tmp, addr, IS_USER(s));
8001
tcg_temp_free_i32(tmp);
8005
tmp = tcg_temp_new_i32();
8006
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8007
store_reg(s, rd, tmp);
8008
tcg_gen_addi_i32(addr, addr, 4);
8009
tmp = tcg_temp_new_i32();
8010
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8014
address_offset = -4;
8017
tmp = load_reg(s, rd);
8018
gen_aa32_st16(tmp, addr, IS_USER(s));
8019
tcg_temp_free_i32(tmp);
8022
/* Perform base writeback before the loaded value to
8023
ensure correct behavior with overlapping index registers.
8024
ldrd with base writeback is is undefined if the
8025
destination and index registers overlap. */
8026
if (!(insn & (1 << 24))) {
8027
gen_add_datah_offset(s, insn, address_offset, addr);
8028
store_reg(s, rn, addr);
8029
} else if (insn & (1 << 21)) {
8031
tcg_gen_addi_i32(addr, addr, address_offset);
8032
store_reg(s, rn, addr);
8034
tcg_temp_free_i32(addr);
8037
/* Complete the load. */
8038
store_reg(s, rd, tmp);
8047
if (insn & (1 << 4)) {
8049
/* Armv6 Media instructions. */
8051
rn = (insn >> 16) & 0xf;
8052
rd = (insn >> 12) & 0xf;
8053
rs = (insn >> 8) & 0xf;
8054
switch ((insn >> 23) & 3) {
8055
case 0: /* Parallel add/subtract. */
8056
op1 = (insn >> 20) & 7;
8057
tmp = load_reg(s, rn);
8058
tmp2 = load_reg(s, rm);
8059
sh = (insn >> 5) & 7;
8060
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8062
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8063
tcg_temp_free_i32(tmp2);
8064
store_reg(s, rd, tmp);
8067
if ((insn & 0x00700020) == 0) {
8068
/* Halfword pack. */
8069
tmp = load_reg(s, rn);
8070
tmp2 = load_reg(s, rm);
8071
shift = (insn >> 7) & 0x1f;
8072
if (insn & (1 << 6)) {
8076
tcg_gen_sari_i32(tmp2, tmp2, shift);
8077
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8078
tcg_gen_ext16u_i32(tmp2, tmp2);
8082
tcg_gen_shli_i32(tmp2, tmp2, shift);
8083
tcg_gen_ext16u_i32(tmp, tmp);
8084
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8086
tcg_gen_or_i32(tmp, tmp, tmp2);
8087
tcg_temp_free_i32(tmp2);
8088
store_reg(s, rd, tmp);
8089
} else if ((insn & 0x00200020) == 0x00200000) {
8091
tmp = load_reg(s, rm);
8092
shift = (insn >> 7) & 0x1f;
8093
if (insn & (1 << 6)) {
8096
tcg_gen_sari_i32(tmp, tmp, shift);
8098
tcg_gen_shli_i32(tmp, tmp, shift);
8100
sh = (insn >> 16) & 0x1f;
8101
tmp2 = tcg_const_i32(sh);
8102
if (insn & (1 << 22))
8103
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8105
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8106
tcg_temp_free_i32(tmp2);
8107
store_reg(s, rd, tmp);
8108
} else if ((insn & 0x00300fe0) == 0x00200f20) {
8110
tmp = load_reg(s, rm);
8111
sh = (insn >> 16) & 0x1f;
8112
tmp2 = tcg_const_i32(sh);
8113
if (insn & (1 << 22))
8114
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8116
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8117
tcg_temp_free_i32(tmp2);
8118
store_reg(s, rd, tmp);
8119
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
8121
tmp = load_reg(s, rn);
8122
tmp2 = load_reg(s, rm);
8123
tmp3 = tcg_temp_new_i32();
8124
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8125
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8126
tcg_temp_free_i32(tmp3);
8127
tcg_temp_free_i32(tmp2);
8128
store_reg(s, rd, tmp);
8129
} else if ((insn & 0x000003e0) == 0x00000060) {
8130
tmp = load_reg(s, rm);
8131
shift = (insn >> 10) & 3;
8132
/* ??? In many cases it's not necessary to do a
8133
rotate, a shift is sufficient. */
8135
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8136
op1 = (insn >> 20) & 7;
8138
case 0: gen_sxtb16(tmp); break;
8139
case 2: gen_sxtb(tmp); break;
8140
case 3: gen_sxth(tmp); break;
8141
case 4: gen_uxtb16(tmp); break;
8142
case 6: gen_uxtb(tmp); break;
8143
case 7: gen_uxth(tmp); break;
8144
default: goto illegal_op;
8147
tmp2 = load_reg(s, rn);
8148
if ((op1 & 3) == 0) {
8149
gen_add16(tmp, tmp2);
8151
tcg_gen_add_i32(tmp, tmp, tmp2);
8152
tcg_temp_free_i32(tmp2);
8155
store_reg(s, rd, tmp);
8156
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
8158
tmp = load_reg(s, rm);
8159
if (insn & (1 << 22)) {
8160
if (insn & (1 << 7)) {
8164
gen_helper_rbit(tmp, tmp);
8167
if (insn & (1 << 7))
8170
tcg_gen_bswap32_i32(tmp, tmp);
8172
store_reg(s, rd, tmp);
8177
case 2: /* Multiplies (Type 3). */
8178
switch ((insn >> 20) & 0x7) {
8180
if (((insn >> 6) ^ (insn >> 7)) & 1) {
8181
/* op2 not 00x or 11x : UNDEF */
8184
/* Signed multiply most significant [accumulate].
8185
(SMMUL, SMMLA, SMMLS) */
8186
tmp = load_reg(s, rm);
8187
tmp2 = load_reg(s, rs);
8188
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8191
tmp = load_reg(s, rd);
8192
if (insn & (1 << 6)) {
8193
tmp64 = gen_subq_msw(tmp64, tmp);
8195
tmp64 = gen_addq_msw(tmp64, tmp);
8198
if (insn & (1 << 5)) {
8199
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8201
tcg_gen_shri_i64(tmp64, tmp64, 32);
8202
tmp = tcg_temp_new_i32();
8203
tcg_gen_trunc_i64_i32(tmp, tmp64);
8204
tcg_temp_free_i64(tmp64);
8205
store_reg(s, rn, tmp);
8209
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8210
if (insn & (1 << 7)) {
8213
tmp = load_reg(s, rm);
8214
tmp2 = load_reg(s, rs);
8215
if (insn & (1 << 5))
8216
gen_swap_half(tmp2);
8217
gen_smul_dual(tmp, tmp2);
8218
if (insn & (1 << 6)) {
8219
/* This subtraction cannot overflow. */
8220
tcg_gen_sub_i32(tmp, tmp, tmp2);
8222
/* This addition cannot overflow 32 bits;
8223
* however it may overflow considered as a signed
8224
* operation, in which case we must set the Q flag.
8226
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8228
tcg_temp_free_i32(tmp2);
8229
if (insn & (1 << 22)) {
8230
/* smlald, smlsld */
8231
tmp64 = tcg_temp_new_i64();
8232
tcg_gen_ext_i32_i64(tmp64, tmp);
8233
tcg_temp_free_i32(tmp);
8234
gen_addq(s, tmp64, rd, rn);
8235
gen_storeq_reg(s, rd, rn, tmp64);
8236
tcg_temp_free_i64(tmp64);
8238
/* smuad, smusd, smlad, smlsd */
8241
tmp2 = load_reg(s, rd);
8242
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8243
tcg_temp_free_i32(tmp2);
8245
store_reg(s, rn, tmp);
8251
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8254
if (((insn >> 5) & 7) || (rd != 15)) {
8257
tmp = load_reg(s, rm);
8258
tmp2 = load_reg(s, rs);
8259
if (insn & (1 << 21)) {
8260
gen_helper_udiv(tmp, tmp, tmp2);
8262
gen_helper_sdiv(tmp, tmp, tmp2);
8264
tcg_temp_free_i32(tmp2);
8265
store_reg(s, rn, tmp);
8272
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8274
case 0: /* Unsigned sum of absolute differences. */
8276
tmp = load_reg(s, rm);
8277
tmp2 = load_reg(s, rs);
8278
gen_helper_usad8(tmp, tmp, tmp2);
8279
tcg_temp_free_i32(tmp2);
8281
tmp2 = load_reg(s, rd);
8282
tcg_gen_add_i32(tmp, tmp, tmp2);
8283
tcg_temp_free_i32(tmp2);
8285
store_reg(s, rn, tmp);
8287
case 0x20: case 0x24: case 0x28: case 0x2c:
8288
/* Bitfield insert/clear. */
8290
shift = (insn >> 7) & 0x1f;
8291
i = (insn >> 16) & 0x1f;
8294
tmp = tcg_temp_new_i32();
8295
tcg_gen_movi_i32(tmp, 0);
8297
tmp = load_reg(s, rm);
8300
tmp2 = load_reg(s, rd);
8301
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8302
tcg_temp_free_i32(tmp2);
8304
store_reg(s, rd, tmp);
8306
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8307
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8309
tmp = load_reg(s, rm);
8310
shift = (insn >> 7) & 0x1f;
8311
i = ((insn >> 16) & 0x1f) + 1;
8316
gen_ubfx(tmp, shift, (1u << i) - 1);
8318
gen_sbfx(tmp, shift, i);
8321
store_reg(s, rd, tmp);
8331
/* Check for undefined extension instructions
8332
* per the ARM Bible IE:
8333
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8335
sh = (0xf << 20) | (0xf << 4);
8336
if (op1 == 0x7 && ((insn & sh) == sh))
8340
/* load/store byte/word */
8341
rn = (insn >> 16) & 0xf;
8342
rd = (insn >> 12) & 0xf;
8343
tmp2 = load_reg(s, rn);
8344
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8345
if (insn & (1 << 24))
8346
gen_add_data_offset(s, insn, tmp2);
8347
if (insn & (1 << 20)) {
8349
tmp = tcg_temp_new_i32();
8350
if (insn & (1 << 22)) {
8351
gen_aa32_ld8u(tmp, tmp2, i);
8353
gen_aa32_ld32u(tmp, tmp2, i);
8357
tmp = load_reg(s, rd);
8358
if (insn & (1 << 22)) {
8359
gen_aa32_st8(tmp, tmp2, i);
8361
gen_aa32_st32(tmp, tmp2, i);
8363
tcg_temp_free_i32(tmp);
8365
if (!(insn & (1 << 24))) {
8366
gen_add_data_offset(s, insn, tmp2);
8367
store_reg(s, rn, tmp2);
8368
} else if (insn & (1 << 21)) {
8369
store_reg(s, rn, tmp2);
8371
tcg_temp_free_i32(tmp2);
8373
if (insn & (1 << 20)) {
8374
/* Complete the load. */
8375
store_reg_from_load(env, s, rd, tmp);
8381
int j, n, user, loaded_base;
8382
TCGv_i32 loaded_var;
8383
/* load/store multiple words */
8384
/* XXX: store correct base if write back */
8386
if (insn & (1 << 22)) {
8388
goto illegal_op; /* only usable in supervisor mode */
8390
if ((insn & (1 << 15)) == 0)
8393
rn = (insn >> 16) & 0xf;
8394
addr = load_reg(s, rn);
8396
/* compute total size */
8398
TCGV_UNUSED_I32(loaded_var);
8401
if (insn & (1 << i))
8404
/* XXX: test invalid n == 0 case ? */
8405
if (insn & (1 << 23)) {
8406
if (insn & (1 << 24)) {
8408
tcg_gen_addi_i32(addr, addr, 4);
8410
/* post increment */
8413
if (insn & (1 << 24)) {
8415
tcg_gen_addi_i32(addr, addr, -(n * 4));
8417
/* post decrement */
8419
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8424
if (insn & (1 << i)) {
8425
if (insn & (1 << 20)) {
8427
tmp = tcg_temp_new_i32();
8428
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8430
tmp2 = tcg_const_i32(i);
8431
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8432
tcg_temp_free_i32(tmp2);
8433
tcg_temp_free_i32(tmp);
8434
} else if (i == rn) {
8438
store_reg_from_load(env, s, i, tmp);
8443
/* special case: r15 = PC + 8 */
8444
val = (long)s->pc + 4;
8445
tmp = tcg_temp_new_i32();
8446
tcg_gen_movi_i32(tmp, val);
8448
tmp = tcg_temp_new_i32();
8449
tmp2 = tcg_const_i32(i);
8450
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8451
tcg_temp_free_i32(tmp2);
8453
tmp = load_reg(s, i);
8455
gen_aa32_st32(tmp, addr, IS_USER(s));
8456
tcg_temp_free_i32(tmp);
8459
/* no need to add after the last transfer */
8461
tcg_gen_addi_i32(addr, addr, 4);
8464
if (insn & (1 << 21)) {
8466
if (insn & (1 << 23)) {
8467
if (insn & (1 << 24)) {
8470
/* post increment */
8471
tcg_gen_addi_i32(addr, addr, 4);
8474
if (insn & (1 << 24)) {
8477
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8479
/* post decrement */
8480
tcg_gen_addi_i32(addr, addr, -(n * 4));
8483
store_reg(s, rn, addr);
8485
tcg_temp_free_i32(addr);
8488
store_reg(s, rn, loaded_var);
8490
if ((insn & (1 << 22)) && !user) {
8491
/* Restore CPSR from SPSR. */
8492
tmp = load_cpu_field(spsr);
8493
gen_set_cpsr(tmp, 0xffffffff);
8494
tcg_temp_free_i32(tmp);
8495
s->is_jmp = DISAS_UPDATE;
8504
/* branch (and link) */
8505
val = (int32_t)s->pc;
8506
if (insn & (1 << 24)) {
8507
tmp = tcg_temp_new_i32();
8508
tcg_gen_movi_i32(tmp, val);
8509
store_reg(s, 14, tmp);
8511
offset = sextract32(insn << 2, 0, 26);
8519
if (((insn >> 8) & 0xe) == 10) {
8521
if (disas_vfp_insn(env, s, insn)) {
8524
} else if (disas_coproc_insn(env, s, insn)) {
8531
gen_set_pc_im(s, s->pc);
8532
s->is_jmp = DISAS_SWI;
8536
gen_exception_insn(s, 4, EXCP_UDEF);
8542
/* Return true if this is a Thumb-2 logical op. */
8544
thumb2_logic_op(int op)
8549
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8550
then set condition code flags based on the result of the operation.
8551
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8552
to the high bit of T1.
8553
Returns zero if the opcode is valid. */
8556
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8557
TCGv_i32 t0, TCGv_i32 t1)
8564
tcg_gen_and_i32(t0, t0, t1);
8568
tcg_gen_andc_i32(t0, t0, t1);
8572
tcg_gen_or_i32(t0, t0, t1);
8576
tcg_gen_orc_i32(t0, t0, t1);
8580
tcg_gen_xor_i32(t0, t0, t1);
8585
gen_add_CC(t0, t0, t1);
8587
tcg_gen_add_i32(t0, t0, t1);
8591
gen_adc_CC(t0, t0, t1);
8597
gen_sbc_CC(t0, t0, t1);
8599
gen_sub_carry(t0, t0, t1);
8604
gen_sub_CC(t0, t0, t1);
8606
tcg_gen_sub_i32(t0, t0, t1);
8610
gen_sub_CC(t0, t1, t0);
8612
tcg_gen_sub_i32(t0, t1, t0);
8614
default: /* 5, 6, 7, 9, 12, 15. */
8620
gen_set_CF_bit31(t1);
8625
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8627
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8629
uint32_t insn, imm, shift, offset;
8630
uint32_t rd, rn, rm, rs;
8641
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8642
|| arm_feature (env, ARM_FEATURE_M))) {
8643
/* Thumb-1 cores may need to treat bl and blx as a pair of
8644
16-bit instructions to get correct prefetch abort behavior. */
8646
if ((insn & (1 << 12)) == 0) {
8648
/* Second half of blx. */
8649
offset = ((insn & 0x7ff) << 1);
8650
tmp = load_reg(s, 14);
8651
tcg_gen_addi_i32(tmp, tmp, offset);
8652
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8654
tmp2 = tcg_temp_new_i32();
8655
tcg_gen_movi_i32(tmp2, s->pc | 1);
8656
store_reg(s, 14, tmp2);
8660
if (insn & (1 << 11)) {
8661
/* Second half of bl. */
8662
offset = ((insn & 0x7ff) << 1) | 1;
8663
tmp = load_reg(s, 14);
8664
tcg_gen_addi_i32(tmp, tmp, offset);
8666
tmp2 = tcg_temp_new_i32();
8667
tcg_gen_movi_i32(tmp2, s->pc | 1);
8668
store_reg(s, 14, tmp2);
8672
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8673
/* Instruction spans a page boundary. Implement it as two
8674
16-bit instructions in case the second half causes an
8676
offset = ((int32_t)insn << 21) >> 9;
8677
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8680
/* Fall through to 32-bit decode. */
8683
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8685
insn |= (uint32_t)insn_hw1 << 16;
8687
if ((insn & 0xf800e800) != 0xf000e800) {
8691
rn = (insn >> 16) & 0xf;
8692
rs = (insn >> 12) & 0xf;
8693
rd = (insn >> 8) & 0xf;
8695
switch ((insn >> 25) & 0xf) {
8696
case 0: case 1: case 2: case 3:
8697
/* 16-bit instructions. Should never happen. */
8700
if (insn & (1 << 22)) {
8701
/* Other load/store, table branch. */
8702
if (insn & 0x01200000) {
8703
/* Load/store doubleword. */
8705
addr = tcg_temp_new_i32();
8706
tcg_gen_movi_i32(addr, s->pc & ~3);
8708
addr = load_reg(s, rn);
8710
offset = (insn & 0xff) * 4;
8711
if ((insn & (1 << 23)) == 0)
8713
if (insn & (1 << 24)) {
8714
tcg_gen_addi_i32(addr, addr, offset);
8717
if (insn & (1 << 20)) {
8719
tmp = tcg_temp_new_i32();
8720
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8721
store_reg(s, rs, tmp);
8722
tcg_gen_addi_i32(addr, addr, 4);
8723
tmp = tcg_temp_new_i32();
8724
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8725
store_reg(s, rd, tmp);
8728
tmp = load_reg(s, rs);
8729
gen_aa32_st32(tmp, addr, IS_USER(s));
8730
tcg_temp_free_i32(tmp);
8731
tcg_gen_addi_i32(addr, addr, 4);
8732
tmp = load_reg(s, rd);
8733
gen_aa32_st32(tmp, addr, IS_USER(s));
8734
tcg_temp_free_i32(tmp);
8736
if (insn & (1 << 21)) {
8737
/* Base writeback. */
8740
tcg_gen_addi_i32(addr, addr, offset - 4);
8741
store_reg(s, rn, addr);
8743
tcg_temp_free_i32(addr);
8745
} else if ((insn & (1 << 23)) == 0) {
8746
/* Load/store exclusive word. */
8747
addr = tcg_temp_local_new_i32();
8748
load_reg_var(s, addr, rn);
8749
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8750
if (insn & (1 << 20)) {
8751
gen_load_exclusive(s, rs, 15, addr, 2);
8753
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8755
tcg_temp_free_i32(addr);
8756
} else if ((insn & (7 << 5)) == 0) {
8759
addr = tcg_temp_new_i32();
8760
tcg_gen_movi_i32(addr, s->pc);
8762
addr = load_reg(s, rn);
8764
tmp = load_reg(s, rm);
8765
tcg_gen_add_i32(addr, addr, tmp);
8766
if (insn & (1 << 4)) {
8768
tcg_gen_add_i32(addr, addr, tmp);
8769
tcg_temp_free_i32(tmp);
8770
tmp = tcg_temp_new_i32();
8771
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8773
tcg_temp_free_i32(tmp);
8774
tmp = tcg_temp_new_i32();
8775
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8777
tcg_temp_free_i32(addr);
8778
tcg_gen_shli_i32(tmp, tmp, 1);
8779
tcg_gen_addi_i32(tmp, tmp, s->pc);
8780
store_reg(s, 15, tmp);
8782
int op2 = (insn >> 6) & 0x3;
8783
op = (insn >> 4) & 0x3;
8788
/* Load/store exclusive byte/halfword/doubleword */
8795
/* Load-acquire/store-release */
8801
/* Load-acquire/store-release exclusive */
8805
addr = tcg_temp_local_new_i32();
8806
load_reg_var(s, addr, rn);
8808
if (insn & (1 << 20)) {
8809
tmp = tcg_temp_new_i32();
8812
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8815
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8818
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8823
store_reg(s, rs, tmp);
8825
tmp = load_reg(s, rs);
8828
gen_aa32_st8(tmp, addr, IS_USER(s));
8831
gen_aa32_st16(tmp, addr, IS_USER(s));
8834
gen_aa32_st32(tmp, addr, IS_USER(s));
8839
tcg_temp_free_i32(tmp);
8841
} else if (insn & (1 << 20)) {
8842
gen_load_exclusive(s, rs, rd, addr, op);
8844
gen_store_exclusive(s, rm, rs, rd, addr, op);
8846
tcg_temp_free_i32(addr);
8849
/* Load/store multiple, RFE, SRS. */
8850
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8851
/* RFE, SRS: not available in user mode or on M profile */
8852
if (IS_USER(s) || IS_M(env)) {
8855
if (insn & (1 << 20)) {
8857
addr = load_reg(s, rn);
8858
if ((insn & (1 << 24)) == 0)
8859
tcg_gen_addi_i32(addr, addr, -8);
8860
/* Load PC into tmp and CPSR into tmp2. */
8861
tmp = tcg_temp_new_i32();
8862
gen_aa32_ld32u(tmp, addr, 0);
8863
tcg_gen_addi_i32(addr, addr, 4);
8864
tmp2 = tcg_temp_new_i32();
8865
gen_aa32_ld32u(tmp2, addr, 0);
8866
if (insn & (1 << 21)) {
8867
/* Base writeback. */
8868
if (insn & (1 << 24)) {
8869
tcg_gen_addi_i32(addr, addr, 4);
8871
tcg_gen_addi_i32(addr, addr, -4);
8873
store_reg(s, rn, addr);
8875
tcg_temp_free_i32(addr);
8877
gen_rfe(s, tmp, tmp2);
8880
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8884
int i, loaded_base = 0;
8885
TCGv_i32 loaded_var;
8886
/* Load/store multiple. */
8887
addr = load_reg(s, rn);
8889
for (i = 0; i < 16; i++) {
8890
if (insn & (1 << i))
8893
if (insn & (1 << 24)) {
8894
tcg_gen_addi_i32(addr, addr, -offset);
8897
TCGV_UNUSED_I32(loaded_var);
8898
for (i = 0; i < 16; i++) {
8899
if ((insn & (1 << i)) == 0)
8901
if (insn & (1 << 20)) {
8903
tmp = tcg_temp_new_i32();
8904
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8907
} else if (i == rn) {
8911
store_reg(s, i, tmp);
8915
tmp = load_reg(s, i);
8916
gen_aa32_st32(tmp, addr, IS_USER(s));
8917
tcg_temp_free_i32(tmp);
8919
tcg_gen_addi_i32(addr, addr, 4);
8922
store_reg(s, rn, loaded_var);
8924
if (insn & (1 << 21)) {
8925
/* Base register writeback. */
8926
if (insn & (1 << 24)) {
8927
tcg_gen_addi_i32(addr, addr, -offset);
8929
/* Fault if writeback register is in register list. */
8930
if (insn & (1 << rn))
8932
store_reg(s, rn, addr);
8934
tcg_temp_free_i32(addr);
8941
op = (insn >> 21) & 0xf;
8943
/* Halfword pack. */
8944
tmp = load_reg(s, rn);
8945
tmp2 = load_reg(s, rm);
8946
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8947
if (insn & (1 << 5)) {
8951
tcg_gen_sari_i32(tmp2, tmp2, shift);
8952
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8953
tcg_gen_ext16u_i32(tmp2, tmp2);
8957
tcg_gen_shli_i32(tmp2, tmp2, shift);
8958
tcg_gen_ext16u_i32(tmp, tmp);
8959
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8961
tcg_gen_or_i32(tmp, tmp, tmp2);
8962
tcg_temp_free_i32(tmp2);
8963
store_reg(s, rd, tmp);
8965
/* Data processing register constant shift. */
8967
tmp = tcg_temp_new_i32();
8968
tcg_gen_movi_i32(tmp, 0);
8970
tmp = load_reg(s, rn);
8972
tmp2 = load_reg(s, rm);
8974
shiftop = (insn >> 4) & 3;
8975
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8976
conds = (insn & (1 << 20)) != 0;
8977
logic_cc = (conds && thumb2_logic_op(op));
8978
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8979
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8981
tcg_temp_free_i32(tmp2);
8983
store_reg(s, rd, tmp);
8985
tcg_temp_free_i32(tmp);
8989
case 13: /* Misc data processing. */
8990
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8991
if (op < 4 && (insn & 0xf000) != 0xf000)
8994
case 0: /* Register controlled shift. */
8995
tmp = load_reg(s, rn);
8996
tmp2 = load_reg(s, rm);
8997
if ((insn & 0x70) != 0)
8999
op = (insn >> 21) & 3;
9000
logic_cc = (insn & (1 << 20)) != 0;
9001
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9004
store_reg_bx(env, s, rd, tmp);
9006
case 1: /* Sign/zero extend. */
9007
tmp = load_reg(s, rm);
9008
shift = (insn >> 4) & 3;
9009
/* ??? In many cases it's not necessary to do a
9010
rotate, a shift is sufficient. */
9012
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9013
op = (insn >> 20) & 7;
9015
case 0: gen_sxth(tmp); break;
9016
case 1: gen_uxth(tmp); break;
9017
case 2: gen_sxtb16(tmp); break;
9018
case 3: gen_uxtb16(tmp); break;
9019
case 4: gen_sxtb(tmp); break;
9020
case 5: gen_uxtb(tmp); break;
9021
default: goto illegal_op;
9024
tmp2 = load_reg(s, rn);
9025
if ((op >> 1) == 1) {
9026
gen_add16(tmp, tmp2);
9028
tcg_gen_add_i32(tmp, tmp, tmp2);
9029
tcg_temp_free_i32(tmp2);
9032
store_reg(s, rd, tmp);
9034
case 2: /* SIMD add/subtract. */
9035
op = (insn >> 20) & 7;
9036
shift = (insn >> 4) & 7;
9037
if ((op & 3) == 3 || (shift & 3) == 3)
9039
tmp = load_reg(s, rn);
9040
tmp2 = load_reg(s, rm);
9041
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9042
tcg_temp_free_i32(tmp2);
9043
store_reg(s, rd, tmp);
9045
case 3: /* Other data processing. */
9046
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9048
/* Saturating add/subtract. */
9049
tmp = load_reg(s, rn);
9050
tmp2 = load_reg(s, rm);
9052
gen_helper_double_saturate(tmp, cpu_env, tmp);
9054
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9056
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9057
tcg_temp_free_i32(tmp2);
9059
tmp = load_reg(s, rn);
9061
case 0x0a: /* rbit */
9062
gen_helper_rbit(tmp, tmp);
9064
case 0x08: /* rev */
9065
tcg_gen_bswap32_i32(tmp, tmp);
9067
case 0x09: /* rev16 */
9070
case 0x0b: /* revsh */
9073
case 0x10: /* sel */
9074
tmp2 = load_reg(s, rm);
9075
tmp3 = tcg_temp_new_i32();
9076
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9077
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9078
tcg_temp_free_i32(tmp3);
9079
tcg_temp_free_i32(tmp2);
9081
case 0x18: /* clz */
9082
gen_helper_clz(tmp, tmp);
9088
store_reg(s, rd, tmp);
9090
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9091
op = (insn >> 4) & 0xf;
9092
tmp = load_reg(s, rn);
9093
tmp2 = load_reg(s, rm);
9094
switch ((insn >> 20) & 7) {
9095
case 0: /* 32 x 32 -> 32 */
9096
tcg_gen_mul_i32(tmp, tmp, tmp2);
9097
tcg_temp_free_i32(tmp2);
9099
tmp2 = load_reg(s, rs);
9101
tcg_gen_sub_i32(tmp, tmp2, tmp);
9103
tcg_gen_add_i32(tmp, tmp, tmp2);
9104
tcg_temp_free_i32(tmp2);
9107
case 1: /* 16 x 16 -> 32 */
9108
gen_mulxy(tmp, tmp2, op & 2, op & 1);
9109
tcg_temp_free_i32(tmp2);
9111
tmp2 = load_reg(s, rs);
9112
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9113
tcg_temp_free_i32(tmp2);
9116
case 2: /* Dual multiply add. */
9117
case 4: /* Dual multiply subtract. */
9119
gen_swap_half(tmp2);
9120
gen_smul_dual(tmp, tmp2);
9121
if (insn & (1 << 22)) {
9122
/* This subtraction cannot overflow. */
9123
tcg_gen_sub_i32(tmp, tmp, tmp2);
9125
/* This addition cannot overflow 32 bits;
9126
* however it may overflow considered as a signed
9127
* operation, in which case we must set the Q flag.
9129
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9131
tcg_temp_free_i32(tmp2);
9134
tmp2 = load_reg(s, rs);
9135
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9136
tcg_temp_free_i32(tmp2);
9139
case 3: /* 32 * 16 -> 32msb */
9141
tcg_gen_sari_i32(tmp2, tmp2, 16);
9144
tmp64 = gen_muls_i64_i32(tmp, tmp2);
9145
tcg_gen_shri_i64(tmp64, tmp64, 16);
9146
tmp = tcg_temp_new_i32();
9147
tcg_gen_trunc_i64_i32(tmp, tmp64);
9148
tcg_temp_free_i64(tmp64);
9151
tmp2 = load_reg(s, rs);
9152
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9153
tcg_temp_free_i32(tmp2);
9156
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9157
tmp64 = gen_muls_i64_i32(tmp, tmp2);
9159
tmp = load_reg(s, rs);
9160
if (insn & (1 << 20)) {
9161
tmp64 = gen_addq_msw(tmp64, tmp);
9163
tmp64 = gen_subq_msw(tmp64, tmp);
9166
if (insn & (1 << 4)) {
9167
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9169
tcg_gen_shri_i64(tmp64, tmp64, 32);
9170
tmp = tcg_temp_new_i32();
9171
tcg_gen_trunc_i64_i32(tmp, tmp64);
9172
tcg_temp_free_i64(tmp64);
9174
case 7: /* Unsigned sum of absolute differences. */
9175
gen_helper_usad8(tmp, tmp, tmp2);
9176
tcg_temp_free_i32(tmp2);
9178
tmp2 = load_reg(s, rs);
9179
tcg_gen_add_i32(tmp, tmp, tmp2);
9180
tcg_temp_free_i32(tmp2);
9184
store_reg(s, rd, tmp);
9186
case 6: case 7: /* 64-bit multiply, Divide. */
9187
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9188
tmp = load_reg(s, rn);
9189
tmp2 = load_reg(s, rm);
9190
if ((op & 0x50) == 0x10) {
9192
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9196
gen_helper_udiv(tmp, tmp, tmp2);
9198
gen_helper_sdiv(tmp, tmp, tmp2);
9199
tcg_temp_free_i32(tmp2);
9200
store_reg(s, rd, tmp);
9201
} else if ((op & 0xe) == 0xc) {
9202
/* Dual multiply accumulate long. */
9204
gen_swap_half(tmp2);
9205
gen_smul_dual(tmp, tmp2);
9207
tcg_gen_sub_i32(tmp, tmp, tmp2);
9209
tcg_gen_add_i32(tmp, tmp, tmp2);
9211
tcg_temp_free_i32(tmp2);
9213
tmp64 = tcg_temp_new_i64();
9214
tcg_gen_ext_i32_i64(tmp64, tmp);
9215
tcg_temp_free_i32(tmp);
9216
gen_addq(s, tmp64, rs, rd);
9217
gen_storeq_reg(s, rs, rd, tmp64);
9218
tcg_temp_free_i64(tmp64);
9221
/* Unsigned 64-bit multiply */
9222
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9226
gen_mulxy(tmp, tmp2, op & 2, op & 1);
9227
tcg_temp_free_i32(tmp2);
9228
tmp64 = tcg_temp_new_i64();
9229
tcg_gen_ext_i32_i64(tmp64, tmp);
9230
tcg_temp_free_i32(tmp);
9232
/* Signed 64-bit multiply */
9233
tmp64 = gen_muls_i64_i32(tmp, tmp2);
9238
gen_addq_lo(s, tmp64, rs);
9239
gen_addq_lo(s, tmp64, rd);
9240
} else if (op & 0x40) {
9241
/* 64-bit accumulate. */
9242
gen_addq(s, tmp64, rs, rd);
9244
gen_storeq_reg(s, rs, rd, tmp64);
9245
tcg_temp_free_i64(tmp64);
9250
case 6: case 7: case 14: case 15:
9252
if (((insn >> 24) & 3) == 3) {
9253
/* Translate into the equivalent ARM encoding. */
9254
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9255
if (disas_neon_data_insn(env, s, insn))
9257
} else if (((insn >> 8) & 0xe) == 10) {
9258
if (disas_vfp_insn(env, s, insn)) {
9262
if (insn & (1 << 28))
9264
if (disas_coproc_insn (env, s, insn))
9268
case 8: case 9: case 10: case 11:
9269
if (insn & (1 << 15)) {
9270
/* Branches, misc control. */
9271
if (insn & 0x5000) {
9272
/* Unconditional branch. */
9273
/* signextend(hw1[10:0]) -> offset[:12]. */
9274
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9275
/* hw1[10:0] -> offset[11:1]. */
9276
offset |= (insn & 0x7ff) << 1;
9277
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9278
offset[24:22] already have the same value because of the
9279
sign extension above. */
9280
offset ^= ((~insn) & (1 << 13)) << 10;
9281
offset ^= ((~insn) & (1 << 11)) << 11;
9283
if (insn & (1 << 14)) {
9284
/* Branch and link. */
9285
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9289
if (insn & (1 << 12)) {
9294
offset &= ~(uint32_t)2;
9295
/* thumb2 bx, no need to check */
9296
gen_bx_im(s, offset);
9298
} else if (((insn >> 23) & 7) == 7) {
9300
if (insn & (1 << 13))
9303
if (insn & (1 << 26)) {
9304
/* Secure monitor call / smc (v6Z) */
9305
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
9311
op = (insn >> 20) & 7;
9313
case 0: /* msr cpsr. */
9315
tmp = load_reg(s, rn);
9316
addr = tcg_const_i32(insn & 0xff);
9317
gen_helper_v7m_msr(cpu_env, addr, tmp);
9318
tcg_temp_free_i32(addr);
9319
tcg_temp_free_i32(tmp);
9324
case 1: /* msr spsr. */
9327
tmp = load_reg(s, rn);
9329
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9333
case 2: /* cps, nop-hint. */
9334
if (((insn >> 8) & 7) == 0) {
9335
gen_nop_hint(s, insn & 0xff);
9337
/* Implemented as NOP in user mode. */
9342
if (insn & (1 << 10)) {
9343
if (insn & (1 << 7))
9345
if (insn & (1 << 6))
9347
if (insn & (1 << 5))
9349
if (insn & (1 << 9))
9350
imm = CPSR_A | CPSR_I | CPSR_F;
9352
if (insn & (1 << 8)) {
9354
imm |= (insn & 0x1f);
9357
gen_set_psr_im(s, offset, 0, imm);
9360
case 3: /* Special control operations. */
9362
op = (insn >> 4) & 0xf;
9370
/* These execute as NOPs. */
9377
/* Trivial implementation equivalent to bx. */
9378
tmp = load_reg(s, rn);
9381
case 5: /* Exception return. */
9385
if (rn != 14 || rd != 15) {
9388
tmp = load_reg(s, rn);
9389
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9390
gen_exception_return(s, tmp);
9392
case 6: /* mrs cpsr. */
9393
tmp = tcg_temp_new_i32();
9395
addr = tcg_const_i32(insn & 0xff);
9396
gen_helper_v7m_mrs(tmp, cpu_env, addr);
9397
tcg_temp_free_i32(addr);
9399
gen_helper_cpsr_read(tmp, cpu_env);
9401
store_reg(s, rd, tmp);
9403
case 7: /* mrs spsr. */
9404
/* Not accessible in user mode. */
9405
if (IS_USER(s) || IS_M(env))
9407
tmp = load_cpu_field(spsr);
9408
store_reg(s, rd, tmp);
9413
/* Conditional branch. */
9414
op = (insn >> 22) & 0xf;
9415
/* Generate a conditional jump to next instruction. */
9416
s->condlabel = gen_new_label();
9417
arm_gen_test_cc(op ^ 1, s->condlabel);
9420
/* offset[11:1] = insn[10:0] */
9421
offset = (insn & 0x7ff) << 1;
9422
/* offset[17:12] = insn[21:16]. */
9423
offset |= (insn & 0x003f0000) >> 4;
9424
/* offset[31:20] = insn[26]. */
9425
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9426
/* offset[18] = insn[13]. */
9427
offset |= (insn & (1 << 13)) << 5;
9428
/* offset[19] = insn[11]. */
9429
offset |= (insn & (1 << 11)) << 8;
9431
/* jump to the offset */
9432
gen_jmp(s, s->pc + offset);
9435
/* Data processing immediate. */
9436
if (insn & (1 << 25)) {
9437
if (insn & (1 << 24)) {
9438
if (insn & (1 << 20))
9440
/* Bitfield/Saturate. */
9441
op = (insn >> 21) & 7;
9443
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9445
tmp = tcg_temp_new_i32();
9446
tcg_gen_movi_i32(tmp, 0);
9448
tmp = load_reg(s, rn);
9451
case 2: /* Signed bitfield extract. */
9453
if (shift + imm > 32)
9456
gen_sbfx(tmp, shift, imm);
9458
case 6: /* Unsigned bitfield extract. */
9460
if (shift + imm > 32)
9463
gen_ubfx(tmp, shift, (1u << imm) - 1);
9465
case 3: /* Bitfield insert/clear. */
9468
imm = imm + 1 - shift;
9470
tmp2 = load_reg(s, rd);
9471
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9472
tcg_temp_free_i32(tmp2);
9477
default: /* Saturate. */
9480
tcg_gen_sari_i32(tmp, tmp, shift);
9482
tcg_gen_shli_i32(tmp, tmp, shift);
9484
tmp2 = tcg_const_i32(imm);
9487
if ((op & 1) && shift == 0)
9488
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9490
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9493
if ((op & 1) && shift == 0)
9494
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9496
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9498
tcg_temp_free_i32(tmp2);
9501
store_reg(s, rd, tmp);
9503
imm = ((insn & 0x04000000) >> 15)
9504
| ((insn & 0x7000) >> 4) | (insn & 0xff);
9505
if (insn & (1 << 22)) {
9506
/* 16-bit immediate. */
9507
imm |= (insn >> 4) & 0xf000;
9508
if (insn & (1 << 23)) {
9510
tmp = load_reg(s, rd);
9511
tcg_gen_ext16u_i32(tmp, tmp);
9512
tcg_gen_ori_i32(tmp, tmp, imm << 16);
9515
tmp = tcg_temp_new_i32();
9516
tcg_gen_movi_i32(tmp, imm);
9519
/* Add/sub 12-bit immediate. */
9521
offset = s->pc & ~(uint32_t)3;
9522
if (insn & (1 << 23))
9526
tmp = tcg_temp_new_i32();
9527
tcg_gen_movi_i32(tmp, offset);
9529
tmp = load_reg(s, rn);
9530
if (insn & (1 << 23))
9531
tcg_gen_subi_i32(tmp, tmp, imm);
9533
tcg_gen_addi_i32(tmp, tmp, imm);
9536
store_reg(s, rd, tmp);
9539
int shifter_out = 0;
9540
/* modified 12-bit immediate. */
9541
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9542
imm = (insn & 0xff);
9545
/* Nothing to do. */
9547
case 1: /* 00XY00XY */
9550
case 2: /* XY00XY00 */
9554
case 3: /* XYXYXYXY */
9558
default: /* Rotated constant. */
9559
shift = (shift << 1) | (imm >> 7);
9561
imm = imm << (32 - shift);
9565
tmp2 = tcg_temp_new_i32();
9566
tcg_gen_movi_i32(tmp2, imm);
9567
rn = (insn >> 16) & 0xf;
9569
tmp = tcg_temp_new_i32();
9570
tcg_gen_movi_i32(tmp, 0);
9572
tmp = load_reg(s, rn);
9574
op = (insn >> 21) & 0xf;
9575
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9576
shifter_out, tmp, tmp2))
9578
tcg_temp_free_i32(tmp2);
9579
rd = (insn >> 8) & 0xf;
9581
store_reg(s, rd, tmp);
9583
tcg_temp_free_i32(tmp);
9588
case 12: /* Load/store single data item. */
9593
if ((insn & 0x01100000) == 0x01000000) {
9594
if (disas_neon_ls_insn(env, s, insn))
9598
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9600
if (!(insn & (1 << 20))) {
9604
/* Byte or halfword load space with dest == r15 : memory hints.
9605
* Catch them early so we don't emit pointless addressing code.
9606
* This space is a mix of:
9607
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9608
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9610
* unallocated hints, which must be treated as NOPs
9611
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9612
* which is easiest for the decoding logic
9613
* Some space which must UNDEF
9615
int op1 = (insn >> 23) & 3;
9616
int op2 = (insn >> 6) & 0x3f;
9621
/* UNPREDICTABLE, unallocated hint or
9622
* PLD/PLDW/PLI (literal)
9627
return 0; /* PLD/PLDW/PLI or unallocated hint */
9629
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9630
return 0; /* PLD/PLDW/PLI or unallocated hint */
9632
/* UNDEF space, or an UNPREDICTABLE */
9638
addr = tcg_temp_new_i32();
9640
/* s->pc has already been incremented by 4. */
9641
imm = s->pc & 0xfffffffc;
9642
if (insn & (1 << 23))
9643
imm += insn & 0xfff;
9645
imm -= insn & 0xfff;
9646
tcg_gen_movi_i32(addr, imm);
9648
addr = load_reg(s, rn);
9649
if (insn & (1 << 23)) {
9650
/* Positive offset. */
9652
tcg_gen_addi_i32(addr, addr, imm);
9655
switch ((insn >> 8) & 0xf) {
9656
case 0x0: /* Shifted Register. */
9657
shift = (insn >> 4) & 0xf;
9659
tcg_temp_free_i32(addr);
9662
tmp = load_reg(s, rm);
9664
tcg_gen_shli_i32(tmp, tmp, shift);
9665
tcg_gen_add_i32(addr, addr, tmp);
9666
tcg_temp_free_i32(tmp);
9668
case 0xc: /* Negative offset. */
9669
tcg_gen_addi_i32(addr, addr, -imm);
9671
case 0xe: /* User privilege. */
9672
tcg_gen_addi_i32(addr, addr, imm);
9675
case 0x9: /* Post-decrement. */
9678
case 0xb: /* Post-increment. */
9682
case 0xd: /* Pre-decrement. */
9685
case 0xf: /* Pre-increment. */
9686
tcg_gen_addi_i32(addr, addr, imm);
9690
tcg_temp_free_i32(addr);
9695
if (insn & (1 << 20)) {
9697
tmp = tcg_temp_new_i32();
9700
gen_aa32_ld8u(tmp, addr, user);
9703
gen_aa32_ld8s(tmp, addr, user);
9706
gen_aa32_ld16u(tmp, addr, user);
9709
gen_aa32_ld16s(tmp, addr, user);
9712
gen_aa32_ld32u(tmp, addr, user);
9715
tcg_temp_free_i32(tmp);
9716
tcg_temp_free_i32(addr);
9722
store_reg(s, rs, tmp);
9726
tmp = load_reg(s, rs);
9729
gen_aa32_st8(tmp, addr, user);
9732
gen_aa32_st16(tmp, addr, user);
9735
gen_aa32_st32(tmp, addr, user);
9738
tcg_temp_free_i32(tmp);
9739
tcg_temp_free_i32(addr);
9742
tcg_temp_free_i32(tmp);
9745
tcg_gen_addi_i32(addr, addr, imm);
9747
store_reg(s, rn, addr);
9749
tcg_temp_free_i32(addr);
9761
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9763
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9770
if (s->condexec_mask) {
9771
cond = s->condexec_cond;
9772
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9773
s->condlabel = gen_new_label();
9774
arm_gen_test_cc(cond ^ 1, s->condlabel);
9779
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9782
switch (insn >> 12) {
9786
op = (insn >> 11) & 3;
9789
rn = (insn >> 3) & 7;
9790
tmp = load_reg(s, rn);
9791
if (insn & (1 << 10)) {
9793
tmp2 = tcg_temp_new_i32();
9794
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9797
rm = (insn >> 6) & 7;
9798
tmp2 = load_reg(s, rm);
9800
if (insn & (1 << 9)) {
9801
if (s->condexec_mask)
9802
tcg_gen_sub_i32(tmp, tmp, tmp2);
9804
gen_sub_CC(tmp, tmp, tmp2);
9806
if (s->condexec_mask)
9807
tcg_gen_add_i32(tmp, tmp, tmp2);
9809
gen_add_CC(tmp, tmp, tmp2);
9811
tcg_temp_free_i32(tmp2);
9812
store_reg(s, rd, tmp);
9814
/* shift immediate */
9815
rm = (insn >> 3) & 7;
9816
shift = (insn >> 6) & 0x1f;
9817
tmp = load_reg(s, rm);
9818
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9819
if (!s->condexec_mask)
9821
store_reg(s, rd, tmp);
9825
/* arithmetic large immediate */
9826
op = (insn >> 11) & 3;
9827
rd = (insn >> 8) & 0x7;
9828
if (op == 0) { /* mov */
9829
tmp = tcg_temp_new_i32();
9830
tcg_gen_movi_i32(tmp, insn & 0xff);
9831
if (!s->condexec_mask)
9833
store_reg(s, rd, tmp);
9835
tmp = load_reg(s, rd);
9836
tmp2 = tcg_temp_new_i32();
9837
tcg_gen_movi_i32(tmp2, insn & 0xff);
9840
gen_sub_CC(tmp, tmp, tmp2);
9841
tcg_temp_free_i32(tmp);
9842
tcg_temp_free_i32(tmp2);
9845
if (s->condexec_mask)
9846
tcg_gen_add_i32(tmp, tmp, tmp2);
9848
gen_add_CC(tmp, tmp, tmp2);
9849
tcg_temp_free_i32(tmp2);
9850
store_reg(s, rd, tmp);
9853
if (s->condexec_mask)
9854
tcg_gen_sub_i32(tmp, tmp, tmp2);
9856
gen_sub_CC(tmp, tmp, tmp2);
9857
tcg_temp_free_i32(tmp2);
9858
store_reg(s, rd, tmp);
9864
if (insn & (1 << 11)) {
9865
rd = (insn >> 8) & 7;
9866
/* load pc-relative. Bit 1 of PC is ignored. */
9867
val = s->pc + 2 + ((insn & 0xff) * 4);
9868
val &= ~(uint32_t)2;
9869
addr = tcg_temp_new_i32();
9870
tcg_gen_movi_i32(addr, val);
9871
tmp = tcg_temp_new_i32();
9872
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9873
tcg_temp_free_i32(addr);
9874
store_reg(s, rd, tmp);
9877
if (insn & (1 << 10)) {
9878
/* data processing extended or blx */
9879
rd = (insn & 7) | ((insn >> 4) & 8);
9880
rm = (insn >> 3) & 0xf;
9881
op = (insn >> 8) & 3;
9884
tmp = load_reg(s, rd);
9885
tmp2 = load_reg(s, rm);
9886
tcg_gen_add_i32(tmp, tmp, tmp2);
9887
tcg_temp_free_i32(tmp2);
9888
store_reg(s, rd, tmp);
9891
tmp = load_reg(s, rd);
9892
tmp2 = load_reg(s, rm);
9893
gen_sub_CC(tmp, tmp, tmp2);
9894
tcg_temp_free_i32(tmp2);
9895
tcg_temp_free_i32(tmp);
9897
case 2: /* mov/cpy */
9898
tmp = load_reg(s, rm);
9899
store_reg(s, rd, tmp);
9901
case 3:/* branch [and link] exchange thumb register */
9902
tmp = load_reg(s, rm);
9903
if (insn & (1 << 7)) {
9905
val = (uint32_t)s->pc | 1;
9906
tmp2 = tcg_temp_new_i32();
9907
tcg_gen_movi_i32(tmp2, val);
9908
store_reg(s, 14, tmp2);
9910
/* already thumb, no need to check */
9917
/* data processing register */
9919
rm = (insn >> 3) & 7;
9920
op = (insn >> 6) & 0xf;
9921
if (op == 2 || op == 3 || op == 4 || op == 7) {
9922
/* the shift/rotate ops want the operands backwards */
9931
if (op == 9) { /* neg */
9932
tmp = tcg_temp_new_i32();
9933
tcg_gen_movi_i32(tmp, 0);
9934
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9935
tmp = load_reg(s, rd);
9937
TCGV_UNUSED_I32(tmp);
9940
tmp2 = load_reg(s, rm);
9943
tcg_gen_and_i32(tmp, tmp, tmp2);
9944
if (!s->condexec_mask)
9948
tcg_gen_xor_i32(tmp, tmp, tmp2);
9949
if (!s->condexec_mask)
9953
if (s->condexec_mask) {
9954
gen_shl(tmp2, tmp2, tmp);
9956
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9961
if (s->condexec_mask) {
9962
gen_shr(tmp2, tmp2, tmp);
9964
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9969
if (s->condexec_mask) {
9970
gen_sar(tmp2, tmp2, tmp);
9972
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9977
if (s->condexec_mask) {
9980
gen_adc_CC(tmp, tmp, tmp2);
9984
if (s->condexec_mask) {
9985
gen_sub_carry(tmp, tmp, tmp2);
9987
gen_sbc_CC(tmp, tmp, tmp2);
9991
if (s->condexec_mask) {
9992
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9993
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9995
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10000
tcg_gen_and_i32(tmp, tmp, tmp2);
10004
case 0x9: /* neg */
10005
if (s->condexec_mask)
10006
tcg_gen_neg_i32(tmp, tmp2);
10008
gen_sub_CC(tmp, tmp, tmp2);
10010
case 0xa: /* cmp */
10011
gen_sub_CC(tmp, tmp, tmp2);
10014
case 0xb: /* cmn */
10015
gen_add_CC(tmp, tmp, tmp2);
10018
case 0xc: /* orr */
10019
tcg_gen_or_i32(tmp, tmp, tmp2);
10020
if (!s->condexec_mask)
10023
case 0xd: /* mul */
10024
tcg_gen_mul_i32(tmp, tmp, tmp2);
10025
if (!s->condexec_mask)
10028
case 0xe: /* bic */
10029
tcg_gen_andc_i32(tmp, tmp, tmp2);
10030
if (!s->condexec_mask)
10033
case 0xf: /* mvn */
10034
tcg_gen_not_i32(tmp2, tmp2);
10035
if (!s->condexec_mask)
10036
gen_logic_CC(tmp2);
10043
store_reg(s, rm, tmp2);
10045
tcg_temp_free_i32(tmp);
10047
store_reg(s, rd, tmp);
10048
tcg_temp_free_i32(tmp2);
10051
tcg_temp_free_i32(tmp);
10052
tcg_temp_free_i32(tmp2);
10057
/* load/store register offset. */
10059
rn = (insn >> 3) & 7;
10060
rm = (insn >> 6) & 7;
10061
op = (insn >> 9) & 7;
10062
addr = load_reg(s, rn);
10063
tmp = load_reg(s, rm);
10064
tcg_gen_add_i32(addr, addr, tmp);
10065
tcg_temp_free_i32(tmp);
10067
if (op < 3) { /* store */
10068
tmp = load_reg(s, rd);
10070
tmp = tcg_temp_new_i32();
10075
gen_aa32_st32(tmp, addr, IS_USER(s));
10078
gen_aa32_st16(tmp, addr, IS_USER(s));
10081
gen_aa32_st8(tmp, addr, IS_USER(s));
10083
case 3: /* ldrsb */
10084
gen_aa32_ld8s(tmp, addr, IS_USER(s));
10087
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10090
gen_aa32_ld16u(tmp, addr, IS_USER(s));
10093
gen_aa32_ld8u(tmp, addr, IS_USER(s));
10095
case 7: /* ldrsh */
10096
gen_aa32_ld16s(tmp, addr, IS_USER(s));
10099
if (op >= 3) { /* load */
10100
store_reg(s, rd, tmp);
10102
tcg_temp_free_i32(tmp);
10104
tcg_temp_free_i32(addr);
10108
/* load/store word immediate offset */
10110
rn = (insn >> 3) & 7;
10111
addr = load_reg(s, rn);
10112
val = (insn >> 4) & 0x7c;
10113
tcg_gen_addi_i32(addr, addr, val);
10115
if (insn & (1 << 11)) {
10117
tmp = tcg_temp_new_i32();
10118
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10119
store_reg(s, rd, tmp);
10122
tmp = load_reg(s, rd);
10123
gen_aa32_st32(tmp, addr, IS_USER(s));
10124
tcg_temp_free_i32(tmp);
10126
tcg_temp_free_i32(addr);
10130
/* load/store byte immediate offset */
10132
rn = (insn >> 3) & 7;
10133
addr = load_reg(s, rn);
10134
val = (insn >> 6) & 0x1f;
10135
tcg_gen_addi_i32(addr, addr, val);
10137
if (insn & (1 << 11)) {
10139
tmp = tcg_temp_new_i32();
10140
gen_aa32_ld8u(tmp, addr, IS_USER(s));
10141
store_reg(s, rd, tmp);
10144
tmp = load_reg(s, rd);
10145
gen_aa32_st8(tmp, addr, IS_USER(s));
10146
tcg_temp_free_i32(tmp);
10148
tcg_temp_free_i32(addr);
10152
/* load/store halfword immediate offset */
10154
rn = (insn >> 3) & 7;
10155
addr = load_reg(s, rn);
10156
val = (insn >> 5) & 0x3e;
10157
tcg_gen_addi_i32(addr, addr, val);
10159
if (insn & (1 << 11)) {
10161
tmp = tcg_temp_new_i32();
10162
gen_aa32_ld16u(tmp, addr, IS_USER(s));
10163
store_reg(s, rd, tmp);
10166
tmp = load_reg(s, rd);
10167
gen_aa32_st16(tmp, addr, IS_USER(s));
10168
tcg_temp_free_i32(tmp);
10170
tcg_temp_free_i32(addr);
10174
/* load/store from stack */
10175
rd = (insn >> 8) & 7;
10176
addr = load_reg(s, 13);
10177
val = (insn & 0xff) * 4;
10178
tcg_gen_addi_i32(addr, addr, val);
10180
if (insn & (1 << 11)) {
10182
tmp = tcg_temp_new_i32();
10183
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10184
store_reg(s, rd, tmp);
10187
tmp = load_reg(s, rd);
10188
gen_aa32_st32(tmp, addr, IS_USER(s));
10189
tcg_temp_free_i32(tmp);
10191
tcg_temp_free_i32(addr);
10195
/* add to high reg */
10196
rd = (insn >> 8) & 7;
10197
if (insn & (1 << 11)) {
10199
tmp = load_reg(s, 13);
10201
/* PC. bit 1 is ignored. */
10202
tmp = tcg_temp_new_i32();
10203
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10205
val = (insn & 0xff) * 4;
10206
tcg_gen_addi_i32(tmp, tmp, val);
10207
store_reg(s, rd, tmp);
10212
op = (insn >> 8) & 0xf;
10215
/* adjust stack pointer */
10216
tmp = load_reg(s, 13);
10217
val = (insn & 0x7f) * 4;
10218
if (insn & (1 << 7))
10219
val = -(int32_t)val;
10220
tcg_gen_addi_i32(tmp, tmp, val);
10221
store_reg(s, 13, tmp);
10224
case 2: /* sign/zero extend. */
10227
rm = (insn >> 3) & 7;
10228
tmp = load_reg(s, rm);
10229
switch ((insn >> 6) & 3) {
10230
case 0: gen_sxth(tmp); break;
10231
case 1: gen_sxtb(tmp); break;
10232
case 2: gen_uxth(tmp); break;
10233
case 3: gen_uxtb(tmp); break;
10235
store_reg(s, rd, tmp);
10237
case 4: case 5: case 0xc: case 0xd:
10239
addr = load_reg(s, 13);
10240
if (insn & (1 << 8))
10244
for (i = 0; i < 8; i++) {
10245
if (insn & (1 << i))
10248
if ((insn & (1 << 11)) == 0) {
10249
tcg_gen_addi_i32(addr, addr, -offset);
10251
for (i = 0; i < 8; i++) {
10252
if (insn & (1 << i)) {
10253
if (insn & (1 << 11)) {
10255
tmp = tcg_temp_new_i32();
10256
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10257
store_reg(s, i, tmp);
10260
tmp = load_reg(s, i);
10261
gen_aa32_st32(tmp, addr, IS_USER(s));
10262
tcg_temp_free_i32(tmp);
10264
/* advance to the next address. */
10265
tcg_gen_addi_i32(addr, addr, 4);
10268
TCGV_UNUSED_I32(tmp);
10269
if (insn & (1 << 8)) {
10270
if (insn & (1 << 11)) {
10272
tmp = tcg_temp_new_i32();
10273
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10274
/* don't set the pc until the rest of the instruction
10278
tmp = load_reg(s, 14);
10279
gen_aa32_st32(tmp, addr, IS_USER(s));
10280
tcg_temp_free_i32(tmp);
10282
tcg_gen_addi_i32(addr, addr, 4);
10284
if ((insn & (1 << 11)) == 0) {
10285
tcg_gen_addi_i32(addr, addr, -offset);
10287
/* write back the new stack pointer */
10288
store_reg(s, 13, addr);
10289
/* set the new PC value */
10290
if ((insn & 0x0900) == 0x0900) {
10291
store_reg_from_load(env, s, 15, tmp);
10295
case 1: case 3: case 9: case 11: /* czb */
10297
tmp = load_reg(s, rm);
10298
s->condlabel = gen_new_label();
10300
if (insn & (1 << 11))
10301
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10303
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10304
tcg_temp_free_i32(tmp);
10305
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10306
val = (uint32_t)s->pc + 2;
10311
case 15: /* IT, nop-hint. */
10312
if ((insn & 0xf) == 0) {
10313
gen_nop_hint(s, (insn >> 4) & 0xf);
10317
s->condexec_cond = (insn >> 4) & 0xe;
10318
s->condexec_mask = insn & 0x1f;
10319
/* No actual code generated for this insn, just setup state. */
10322
case 0xe: /* bkpt */
10324
gen_exception_insn(s, 2, EXCP_BKPT);
10327
case 0xa: /* rev */
10329
rn = (insn >> 3) & 0x7;
10331
tmp = load_reg(s, rn);
10332
switch ((insn >> 6) & 3) {
10333
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10334
case 1: gen_rev16(tmp); break;
10335
case 3: gen_revsh(tmp); break;
10336
default: goto illegal_op;
10338
store_reg(s, rd, tmp);
10342
switch ((insn >> 5) & 7) {
10346
if (((insn >> 3) & 1) != s->bswap_code) {
10347
/* Dynamic endianness switching not implemented. */
10348
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10359
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10362
addr = tcg_const_i32(19);
10363
gen_helper_v7m_msr(cpu_env, addr, tmp);
10364
tcg_temp_free_i32(addr);
10368
addr = tcg_const_i32(16);
10369
gen_helper_v7m_msr(cpu_env, addr, tmp);
10370
tcg_temp_free_i32(addr);
10372
tcg_temp_free_i32(tmp);
10375
if (insn & (1 << 4)) {
10376
shift = CPSR_A | CPSR_I | CPSR_F;
10380
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10395
/* load/store multiple */
10396
TCGv_i32 loaded_var;
10397
TCGV_UNUSED_I32(loaded_var);
10398
rn = (insn >> 8) & 0x7;
10399
addr = load_reg(s, rn);
10400
for (i = 0; i < 8; i++) {
10401
if (insn & (1 << i)) {
10402
if (insn & (1 << 11)) {
10404
tmp = tcg_temp_new_i32();
10405
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10409
store_reg(s, i, tmp);
10413
tmp = load_reg(s, i);
10414
gen_aa32_st32(tmp, addr, IS_USER(s));
10415
tcg_temp_free_i32(tmp);
10417
/* advance to the next address */
10418
tcg_gen_addi_i32(addr, addr, 4);
10421
if ((insn & (1 << rn)) == 0) {
10422
/* base reg not in list: base register writeback */
10423
store_reg(s, rn, addr);
10425
/* base reg in list: if load, complete it now */
10426
if (insn & (1 << 11)) {
10427
store_reg(s, rn, loaded_var);
10429
tcg_temp_free_i32(addr);
10434
/* conditional branch or swi */
10435
cond = (insn >> 8) & 0xf;
10441
gen_set_pc_im(s, s->pc);
10442
s->is_jmp = DISAS_SWI;
10445
/* generate a conditional jump to next instruction */
10446
s->condlabel = gen_new_label();
10447
arm_gen_test_cc(cond ^ 1, s->condlabel);
10450
/* jump to the offset */
10451
val = (uint32_t)s->pc + 2;
10452
offset = ((int32_t)insn << 24) >> 24;
10453
val += offset << 1;
10458
if (insn & (1 << 11)) {
10459
if (disas_thumb2_insn(env, s, insn))
10463
/* unconditional branch */
10464
val = (uint32_t)s->pc;
10465
offset = ((int32_t)insn << 21) >> 21;
10466
val += (offset << 1) + 2;
10471
if (disas_thumb2_insn(env, s, insn))
10477
gen_exception_insn(s, 4, EXCP_UDEF);
10481
gen_exception_insn(s, 2, EXCP_UDEF);
10484
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10485
basic block 'tb'. If search_pc is TRUE, also generate PC
10486
information for each intermediate instruction. */
10487
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10488
TranslationBlock *tb,
10491
CPUState *cs = CPU(cpu);
10492
CPUARMState *env = &cpu->env;
10493
DisasContext dc1, *dc = &dc1;
10495
uint16_t *gen_opc_end;
10497
target_ulong pc_start;
10498
target_ulong next_page_start;
10502
/* generate intermediate code */
10504
/* The A64 decoder has its own top level loop, because it doesn't need
10505
* the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10507
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10508
gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10516
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10518
dc->is_jmp = DISAS_NEXT;
10520
dc->singlestep_enabled = cs->singlestep_enabled;
10524
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10525
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10526
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10527
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10528
#if !defined(CONFIG_USER_ONLY)
10529
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10531
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10532
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10533
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10534
dc->cp_regs = cpu->cp_regs;
10535
dc->current_pl = arm_current_pl(env);
10537
cpu_F0s = tcg_temp_new_i32();
10538
cpu_F1s = tcg_temp_new_i32();
10539
cpu_F0d = tcg_temp_new_i64();
10540
cpu_F1d = tcg_temp_new_i64();
10543
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10544
cpu_M0 = tcg_temp_new_i64();
10545
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10548
max_insns = tb->cflags & CF_COUNT_MASK;
10549
if (max_insns == 0)
10550
max_insns = CF_COUNT_MASK;
10554
tcg_clear_temp_count();
10556
/* A note on handling of the condexec (IT) bits:
10558
* We want to avoid the overhead of having to write the updated condexec
10559
* bits back to the CPUARMState for every instruction in an IT block. So:
10560
* (1) if the condexec bits are not already zero then we write
10561
* zero back into the CPUARMState now. This avoids complications trying
10562
* to do it at the end of the block. (For example if we don't do this
10563
* it's hard to identify whether we can safely skip writing condexec
10564
* at the end of the TB, which we definitely want to do for the case
10565
* where a TB doesn't do anything with the IT state at all.)
10566
* (2) if we are going to leave the TB then we call gen_set_condexec()
10567
* which will write the correct value into CPUARMState if zero is wrong.
10568
* This is done both for leaving the TB at the end, and for leaving
10569
* it because of an exception we know will happen, which is done in
10570
* gen_exception_insn(). The latter is necessary because we need to
10571
* leave the TB with the PC/IT state just prior to execution of the
10572
* instruction which caused the exception.
10573
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10574
* then the CPUARMState will be wrong and we need to reset it.
10575
* This is handled in the same way as restoration of the
10576
* PC in these situations: we will be called again with search_pc=1
10577
* and generate a mapping of the condexec bits for each PC in
10578
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10579
* this to restore the condexec bits.
10581
* Note that there are no instructions which can read the condexec
10582
* bits, and none which can write non-static values to them, so
10583
* we don't need to care about whether CPUARMState is correct in the
10587
/* Reset the conditional execution bits immediately. This avoids
10588
complications trying to do it at the end of the block. */
10589
if (dc->condexec_mask || dc->condexec_cond)
10591
TCGv_i32 tmp = tcg_temp_new_i32();
10592
tcg_gen_movi_i32(tmp, 0);
10593
store_cpu_field(tmp, condexec_bits);
10596
#ifdef CONFIG_USER_ONLY
10597
/* Intercept jump to the magic kernel page. */
10598
if (dc->pc >= 0xffff0000) {
10599
/* We always get here via a jump, so know we are not in a
10600
conditional execution block. */
10601
gen_exception(EXCP_KERNEL_TRAP);
10602
dc->is_jmp = DISAS_UPDATE;
10606
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10607
/* We always get here via a jump, so know we are not in a
10608
conditional execution block. */
10609
gen_exception(EXCP_EXCEPTION_EXIT);
10610
dc->is_jmp = DISAS_UPDATE;
10615
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10616
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10617
if (bp->pc == dc->pc) {
10618
gen_exception_insn(dc, 0, EXCP_DEBUG);
10619
/* Advance PC so that clearing the breakpoint will
10620
invalidate this TB. */
10622
goto done_generating;
10627
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10631
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10633
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10634
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10635
tcg_ctx.gen_opc_instr_start[lj] = 1;
10636
tcg_ctx.gen_opc_icount[lj] = num_insns;
10639
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10642
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10643
tcg_gen_debug_insn_start(dc->pc);
10647
disas_thumb_insn(env, dc);
10648
if (dc->condexec_mask) {
10649
dc->condexec_cond = (dc->condexec_cond & 0xe)
10650
| ((dc->condexec_mask >> 4) & 1);
10651
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10652
if (dc->condexec_mask == 0) {
10653
dc->condexec_cond = 0;
10657
disas_arm_insn(env, dc);
10660
if (dc->condjmp && !dc->is_jmp) {
10661
gen_set_label(dc->condlabel);
10665
if (tcg_check_temp_count()) {
10666
fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10670
/* Translation stops when a conditional branch is encountered.
10671
* Otherwise the subsequent code could get translated several times.
10672
* Also stop translation when a page boundary is reached. This
10673
* ensures prefetch aborts occur at the right place. */
10675
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10676
!cs->singlestep_enabled &&
10678
dc->pc < next_page_start &&
10679
num_insns < max_insns);
10681
if (tb->cflags & CF_LAST_IO) {
10683
/* FIXME: This can theoretically happen with self-modifying
10685
cpu_abort(env, "IO on conditional branch instruction");
10690
/* At this stage dc->condjmp will only be set when the skipped
10691
instruction was a conditional branch or trap, and the PC has
10692
already been written. */
10693
if (unlikely(cs->singlestep_enabled)) {
10694
/* Make sure the pc is updated, and raise a debug exception. */
10696
gen_set_condexec(dc);
10697
if (dc->is_jmp == DISAS_SWI) {
10698
gen_exception(EXCP_SWI);
10699
} else if (dc->is_jmp == DISAS_SMC) {
10700
gen_exception(EXCP_SMC);
10702
gen_exception(EXCP_DEBUG);
10704
gen_set_label(dc->condlabel);
10706
if (dc->condjmp || !dc->is_jmp) {
10707
gen_set_pc_im(dc, dc->pc);
10710
gen_set_condexec(dc);
10711
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10712
gen_exception(EXCP_SWI);
10713
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10714
gen_exception(EXCP_SMC);
10716
/* FIXME: Single stepping a WFI insn will not halt
10718
gen_exception(EXCP_DEBUG);
10721
/* While branches must always occur at the end of an IT block,
10722
there are a few other things that can cause us to terminate
10723
the TB in the middle of an IT block:
10724
- Exception generating instructions (bkpt, swi, undefined).
10726
- Hardware watchpoints.
10727
Hardware breakpoints have already been handled and skip this code.
10729
gen_set_condexec(dc);
10730
switch(dc->is_jmp) {
10732
gen_goto_tb(dc, 1, dc->pc);
10737
/* indicate that the hash table must be used to find the next TB */
10738
tcg_gen_exit_tb(0);
10740
case DISAS_TB_JUMP:
10741
/* nothing more to generate */
10744
gen_helper_wfi(cpu_env);
10747
gen_exception(EXCP_SWI);
10750
gen_exception(EXCP_SMC);
10754
gen_set_label(dc->condlabel);
10755
gen_set_condexec(dc);
10756
gen_goto_tb(dc, 1, dc->pc);
10762
gen_tb_end(tb, num_insns);
10763
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10766
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10767
qemu_log("----------------\n");
10768
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10769
log_target_disas(env, pc_start, dc->pc - pc_start,
10770
dc->thumb | (dc->bswap_code << 1));
10775
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10778
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10780
tb->size = dc->pc - pc_start;
10781
tb->icount = num_insns;
10785
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10787
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10790
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10792
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10795
static const char *cpu_mode_names[16] = {
10796
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10797
"???", "???", "???", "und", "???", "???", "???", "sys"
10800
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10803
ARMCPU *cpu = ARM_CPU(cs);
10804
CPUARMState *env = &cpu->env;
10808
for(i=0;i<16;i++) {
10809
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10811
cpu_fprintf(f, "\n");
10813
cpu_fprintf(f, " ");
10815
psr = cpsr_read(env);
10816
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10818
psr & (1 << 31) ? 'N' : '-',
10819
psr & (1 << 30) ? 'Z' : '-',
10820
psr & (1 << 29) ? 'C' : '-',
10821
psr & (1 << 28) ? 'V' : '-',
10822
psr & CPSR_T ? 'T' : 'A',
10823
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10825
if (flags & CPU_DUMP_FPU) {
10826
int numvfpregs = 0;
10827
if (arm_feature(env, ARM_FEATURE_VFP)) {
10830
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10833
for (i = 0; i < numvfpregs; i++) {
10834
uint64_t v = float64_val(env->vfp.regs[i]);
10835
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10836
i * 2, (uint32_t)v,
10837
i * 2 + 1, (uint32_t)(v >> 32),
10840
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10844
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10847
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10848
env->condexec_bits = 0;
10850
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10851
env->condexec_bits = gen_opc_condexec_bits[pc_pos];