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
#if defined(CONFIG_USER_ONLY)
56
#define IS_USER(s) (s->user)
59
/* These instructions trap after executing, so defer them until after the
60
conditional execution state has been updated. */
65
/* We reuse the same 64-bit temporaries for efficiency. */
66
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
67
static TCGv_i32 cpu_R[16];
68
static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
69
static TCGv_i32 cpu_exclusive_addr;
70
static TCGv_i32 cpu_exclusive_val;
71
static TCGv_i32 cpu_exclusive_high;
72
#ifdef CONFIG_USER_ONLY
73
static TCGv_i32 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_i32(TCG_AREG0,
105
offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
106
cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
107
offsetof(CPUARMState, exclusive_val), "exclusive_val");
108
cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
109
offsetof(CPUARMState, exclusive_high), "exclusive_high");
110
#ifdef CONFIG_USER_ONLY
111
cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
112
offsetof(CPUARMState, exclusive_test), "exclusive_test");
113
cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
114
offsetof(CPUARMState, exclusive_info), "exclusive_info");
117
a64_translate_init();
120
static inline TCGv_i32 load_cpu_offset(int offset)
122
TCGv_i32 tmp = tcg_temp_new_i32();
123
tcg_gen_ld_i32(tmp, cpu_env, offset);
127
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
129
static inline void store_cpu_offset(TCGv_i32 var, int offset)
131
tcg_gen_st_i32(var, cpu_env, offset);
132
tcg_temp_free_i32(var);
135
#define store_cpu_field(var, name) \
136
store_cpu_offset(var, offsetof(CPUARMState, name))
138
/* Set a variable to the value of a CPU register. */
139
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
143
/* normally, since we updated PC, we need only to add one insn */
145
addr = (long)s->pc + 2;
147
addr = (long)s->pc + 4;
148
tcg_gen_movi_i32(var, addr);
150
tcg_gen_mov_i32(var, cpu_R[reg]);
154
/* Create a new temporary and set it to the value of a CPU register. */
155
static inline TCGv_i32 load_reg(DisasContext *s, int reg)
157
TCGv_i32 tmp = tcg_temp_new_i32();
158
load_reg_var(s, tmp, reg);
162
/* Set a CPU register. The source must be a temporary and will be
164
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
167
tcg_gen_andi_i32(var, var, ~1);
168
s->is_jmp = DISAS_JUMP;
170
tcg_gen_mov_i32(cpu_R[reg], var);
171
tcg_temp_free_i32(var);
174
/* Value extensions. */
175
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
176
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
177
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
178
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
180
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
181
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
184
static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
186
TCGv_i32 tmp_mask = tcg_const_i32(mask);
187
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
188
tcg_temp_free_i32(tmp_mask);
190
/* Set NZCV flags from the high 4 bits of var. */
191
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
193
static void gen_exception(int excp)
195
TCGv_i32 tmp = tcg_temp_new_i32();
196
tcg_gen_movi_i32(tmp, excp);
197
gen_helper_exception(cpu_env, tmp);
198
tcg_temp_free_i32(tmp);
201
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
203
TCGv_i32 tmp1 = tcg_temp_new_i32();
204
TCGv_i32 tmp2 = tcg_temp_new_i32();
205
tcg_gen_ext16s_i32(tmp1, a);
206
tcg_gen_ext16s_i32(tmp2, b);
207
tcg_gen_mul_i32(tmp1, tmp1, tmp2);
208
tcg_temp_free_i32(tmp2);
209
tcg_gen_sari_i32(a, a, 16);
210
tcg_gen_sari_i32(b, b, 16);
211
tcg_gen_mul_i32(b, b, a);
212
tcg_gen_mov_i32(a, tmp1);
213
tcg_temp_free_i32(tmp1);
216
/* Byteswap each halfword. */
217
static void gen_rev16(TCGv_i32 var)
219
TCGv_i32 tmp = tcg_temp_new_i32();
220
tcg_gen_shri_i32(tmp, var, 8);
221
tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
222
tcg_gen_shli_i32(var, var, 8);
223
tcg_gen_andi_i32(var, var, 0xff00ff00);
224
tcg_gen_or_i32(var, var, tmp);
225
tcg_temp_free_i32(tmp);
228
/* Byteswap low halfword and sign extend. */
229
static void gen_revsh(TCGv_i32 var)
231
tcg_gen_ext16u_i32(var, var);
232
tcg_gen_bswap16_i32(var, var);
233
tcg_gen_ext16s_i32(var, var);
236
/* Unsigned bitfield extract. */
237
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
240
tcg_gen_shri_i32(var, var, shift);
241
tcg_gen_andi_i32(var, var, mask);
244
/* Signed bitfield extract. */
245
static void gen_sbfx(TCGv_i32 var, int shift, int width)
250
tcg_gen_sari_i32(var, var, shift);
251
if (shift + width < 32) {
252
signbit = 1u << (width - 1);
253
tcg_gen_andi_i32(var, var, (1u << width) - 1);
254
tcg_gen_xori_i32(var, var, signbit);
255
tcg_gen_subi_i32(var, var, signbit);
259
/* Return (b << 32) + a. Mark inputs as dead */
260
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
262
TCGv_i64 tmp64 = tcg_temp_new_i64();
264
tcg_gen_extu_i32_i64(tmp64, b);
265
tcg_temp_free_i32(b);
266
tcg_gen_shli_i64(tmp64, tmp64, 32);
267
tcg_gen_add_i64(a, tmp64, a);
269
tcg_temp_free_i64(tmp64);
273
/* Return (b << 32) - a. Mark inputs as dead. */
274
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
276
TCGv_i64 tmp64 = tcg_temp_new_i64();
278
tcg_gen_extu_i32_i64(tmp64, b);
279
tcg_temp_free_i32(b);
280
tcg_gen_shli_i64(tmp64, tmp64, 32);
281
tcg_gen_sub_i64(a, tmp64, a);
283
tcg_temp_free_i64(tmp64);
287
/* 32x32->64 multiply. Marks inputs as dead. */
288
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
290
TCGv_i32 lo = tcg_temp_new_i32();
291
TCGv_i32 hi = tcg_temp_new_i32();
294
tcg_gen_mulu2_i32(lo, hi, a, b);
295
tcg_temp_free_i32(a);
296
tcg_temp_free_i32(b);
298
ret = tcg_temp_new_i64();
299
tcg_gen_concat_i32_i64(ret, lo, hi);
300
tcg_temp_free_i32(lo);
301
tcg_temp_free_i32(hi);
306
static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
308
TCGv_i32 lo = tcg_temp_new_i32();
309
TCGv_i32 hi = tcg_temp_new_i32();
312
tcg_gen_muls2_i32(lo, hi, a, b);
313
tcg_temp_free_i32(a);
314
tcg_temp_free_i32(b);
316
ret = tcg_temp_new_i64();
317
tcg_gen_concat_i32_i64(ret, lo, hi);
318
tcg_temp_free_i32(lo);
319
tcg_temp_free_i32(hi);
324
/* Swap low and high halfwords. */
325
static void gen_swap_half(TCGv_i32 var)
327
TCGv_i32 tmp = tcg_temp_new_i32();
328
tcg_gen_shri_i32(tmp, var, 16);
329
tcg_gen_shli_i32(var, var, 16);
330
tcg_gen_or_i32(var, var, tmp);
331
tcg_temp_free_i32(tmp);
334
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
335
tmp = (t0 ^ t1) & 0x8000;
338
t0 = (t0 + t1) ^ tmp;
341
static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
343
TCGv_i32 tmp = tcg_temp_new_i32();
344
tcg_gen_xor_i32(tmp, t0, t1);
345
tcg_gen_andi_i32(tmp, tmp, 0x8000);
346
tcg_gen_andi_i32(t0, t0, ~0x8000);
347
tcg_gen_andi_i32(t1, t1, ~0x8000);
348
tcg_gen_add_i32(t0, t0, t1);
349
tcg_gen_xor_i32(t0, t0, tmp);
350
tcg_temp_free_i32(tmp);
351
tcg_temp_free_i32(t1);
354
/* Set CF to the top bit of var. */
355
static void gen_set_CF_bit31(TCGv_i32 var)
357
tcg_gen_shri_i32(cpu_CF, var, 31);
360
/* Set N and Z flags from var. */
361
static inline void gen_logic_CC(TCGv_i32 var)
363
tcg_gen_mov_i32(cpu_NF, var);
364
tcg_gen_mov_i32(cpu_ZF, var);
368
static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
370
tcg_gen_add_i32(t0, t0, t1);
371
tcg_gen_add_i32(t0, t0, cpu_CF);
374
/* dest = T0 + T1 + CF. */
375
static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
377
tcg_gen_add_i32(dest, t0, t1);
378
tcg_gen_add_i32(dest, dest, cpu_CF);
381
/* dest = T0 - T1 + CF - 1. */
382
static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
384
tcg_gen_sub_i32(dest, t0, t1);
385
tcg_gen_add_i32(dest, dest, cpu_CF);
386
tcg_gen_subi_i32(dest, dest, 1);
389
/* dest = T0 + T1. Compute C, N, V and Z flags */
390
static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
392
TCGv_i32 tmp = tcg_temp_new_i32();
393
tcg_gen_movi_i32(tmp, 0);
394
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
395
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
396
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
397
tcg_gen_xor_i32(tmp, t0, t1);
398
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
399
tcg_temp_free_i32(tmp);
400
tcg_gen_mov_i32(dest, cpu_NF);
403
/* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
404
static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
406
TCGv_i32 tmp = tcg_temp_new_i32();
407
if (TCG_TARGET_HAS_add2_i32) {
408
tcg_gen_movi_i32(tmp, 0);
409
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
410
tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
412
TCGv_i64 q0 = tcg_temp_new_i64();
413
TCGv_i64 q1 = tcg_temp_new_i64();
414
tcg_gen_extu_i32_i64(q0, t0);
415
tcg_gen_extu_i32_i64(q1, t1);
416
tcg_gen_add_i64(q0, q0, q1);
417
tcg_gen_extu_i32_i64(q1, cpu_CF);
418
tcg_gen_add_i64(q0, q0, q1);
419
tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
420
tcg_temp_free_i64(q0);
421
tcg_temp_free_i64(q1);
423
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
424
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
425
tcg_gen_xor_i32(tmp, t0, t1);
426
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
427
tcg_temp_free_i32(tmp);
428
tcg_gen_mov_i32(dest, cpu_NF);
431
/* dest = T0 - T1. Compute C, N, V and Z flags */
432
static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
435
tcg_gen_sub_i32(cpu_NF, t0, t1);
436
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
437
tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
438
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
439
tmp = tcg_temp_new_i32();
440
tcg_gen_xor_i32(tmp, t0, t1);
441
tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
442
tcg_temp_free_i32(tmp);
443
tcg_gen_mov_i32(dest, cpu_NF);
446
/* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
447
static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
449
TCGv_i32 tmp = tcg_temp_new_i32();
450
tcg_gen_not_i32(tmp, t1);
451
gen_adc_CC(dest, t0, tmp);
452
tcg_temp_free_i32(tmp);
455
#define GEN_SHIFT(name) \
456
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
458
TCGv_i32 tmp1, tmp2, tmp3; \
459
tmp1 = tcg_temp_new_i32(); \
460
tcg_gen_andi_i32(tmp1, t1, 0xff); \
461
tmp2 = tcg_const_i32(0); \
462
tmp3 = tcg_const_i32(0x1f); \
463
tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
464
tcg_temp_free_i32(tmp3); \
465
tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
466
tcg_gen_##name##_i32(dest, tmp2, tmp1); \
467
tcg_temp_free_i32(tmp2); \
468
tcg_temp_free_i32(tmp1); \
474
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
477
tmp1 = tcg_temp_new_i32();
478
tcg_gen_andi_i32(tmp1, t1, 0xff);
479
tmp2 = tcg_const_i32(0x1f);
480
tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
481
tcg_temp_free_i32(tmp2);
482
tcg_gen_sar_i32(dest, t0, tmp1);
483
tcg_temp_free_i32(tmp1);
486
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
488
TCGv_i32 c0 = tcg_const_i32(0);
489
TCGv_i32 tmp = tcg_temp_new_i32();
490
tcg_gen_neg_i32(tmp, src);
491
tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
492
tcg_temp_free_i32(c0);
493
tcg_temp_free_i32(tmp);
496
static void shifter_out_im(TCGv_i32 var, int shift)
499
tcg_gen_andi_i32(cpu_CF, var, 1);
501
tcg_gen_shri_i32(cpu_CF, var, shift);
503
tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
508
/* Shift by immediate. Includes special handling for shift == 0. */
509
static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
510
int shift, int flags)
516
shifter_out_im(var, 32 - shift);
517
tcg_gen_shli_i32(var, var, shift);
523
tcg_gen_shri_i32(cpu_CF, var, 31);
525
tcg_gen_movi_i32(var, 0);
528
shifter_out_im(var, shift - 1);
529
tcg_gen_shri_i32(var, var, shift);
536
shifter_out_im(var, shift - 1);
539
tcg_gen_sari_i32(var, var, shift);
541
case 3: /* ROR/RRX */
544
shifter_out_im(var, shift - 1);
545
tcg_gen_rotri_i32(var, var, shift); break;
547
TCGv_i32 tmp = tcg_temp_new_i32();
548
tcg_gen_shli_i32(tmp, cpu_CF, 31);
550
shifter_out_im(var, 0);
551
tcg_gen_shri_i32(var, var, 1);
552
tcg_gen_or_i32(var, var, tmp);
553
tcg_temp_free_i32(tmp);
558
static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
559
TCGv_i32 shift, int flags)
563
case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
564
case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
565
case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
566
case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
571
gen_shl(var, var, shift);
574
gen_shr(var, var, shift);
577
gen_sar(var, var, shift);
579
case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
580
tcg_gen_rotr_i32(var, var, shift); break;
583
tcg_temp_free_i32(shift);
586
#define PAS_OP(pfx) \
588
case 0: gen_pas_helper(glue(pfx,add16)); break; \
589
case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
590
case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
591
case 3: gen_pas_helper(glue(pfx,sub16)); break; \
592
case 4: gen_pas_helper(glue(pfx,add8)); break; \
593
case 7: gen_pas_helper(glue(pfx,sub8)); break; \
595
static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
600
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
602
tmp = tcg_temp_new_ptr();
603
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
605
tcg_temp_free_ptr(tmp);
608
tmp = tcg_temp_new_ptr();
609
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
611
tcg_temp_free_ptr(tmp);
613
#undef gen_pas_helper
614
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
627
#undef gen_pas_helper
632
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
633
#define PAS_OP(pfx) \
635
case 0: gen_pas_helper(glue(pfx,add8)); break; \
636
case 1: gen_pas_helper(glue(pfx,add16)); break; \
637
case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
638
case 4: gen_pas_helper(glue(pfx,sub8)); break; \
639
case 5: gen_pas_helper(glue(pfx,sub16)); break; \
640
case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
642
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
647
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
649
tmp = tcg_temp_new_ptr();
650
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
652
tcg_temp_free_ptr(tmp);
655
tmp = tcg_temp_new_ptr();
656
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
658
tcg_temp_free_ptr(tmp);
660
#undef gen_pas_helper
661
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
674
#undef gen_pas_helper
679
static void gen_test_cc(int cc, int label)
686
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
689
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
692
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
695
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
698
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
701
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
704
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
707
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
709
case 8: /* hi: C && !Z */
710
inv = gen_new_label();
711
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
712
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
715
case 9: /* ls: !C || Z */
716
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
717
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
719
case 10: /* ge: N == V -> N ^ V == 0 */
720
tmp = tcg_temp_new_i32();
721
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
722
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
723
tcg_temp_free_i32(tmp);
725
case 11: /* lt: N != V -> N ^ V != 0 */
726
tmp = tcg_temp_new_i32();
727
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
728
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
729
tcg_temp_free_i32(tmp);
731
case 12: /* gt: !Z && N == V */
732
inv = gen_new_label();
733
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
734
tmp = tcg_temp_new_i32();
735
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
736
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
737
tcg_temp_free_i32(tmp);
740
case 13: /* le: Z || N != V */
741
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
742
tmp = tcg_temp_new_i32();
743
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
744
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
745
tcg_temp_free_i32(tmp);
748
fprintf(stderr, "Bad condition code 0x%x\n", cc);
753
static const uint8_t table_logic_cc[16] = {
772
/* Set PC and Thumb state from an immediate address. */
773
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
777
s->is_jmp = DISAS_UPDATE;
778
if (s->thumb != (addr & 1)) {
779
tmp = tcg_temp_new_i32();
780
tcg_gen_movi_i32(tmp, addr & 1);
781
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
782
tcg_temp_free_i32(tmp);
784
tcg_gen_movi_i32(cpu_R[15], addr & ~1);
787
/* Set PC and Thumb state from var. var is marked as dead. */
788
static inline void gen_bx(DisasContext *s, TCGv_i32 var)
790
s->is_jmp = DISAS_UPDATE;
791
tcg_gen_andi_i32(cpu_R[15], var, ~1);
792
tcg_gen_andi_i32(var, var, 1);
793
store_cpu_field(var, thumb);
796
/* Variant of store_reg which uses branch&exchange logic when storing
797
to r15 in ARM architecture v7 and above. The source must be a temporary
798
and will be marked as dead. */
799
static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
800
int reg, TCGv_i32 var)
802
if (reg == 15 && ENABLE_ARCH_7) {
805
store_reg(s, reg, var);
809
/* Variant of store_reg which uses branch&exchange logic when storing
810
* to r15 in ARM architecture v5T and above. This is used for storing
811
* the results of a LDR/LDM/POP into r15, and corresponds to the cases
812
* in the ARM ARM which use the LoadWritePC() pseudocode function. */
813
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
814
int reg, TCGv_i32 var)
816
if (reg == 15 && ENABLE_ARCH_5) {
819
store_reg(s, reg, var);
823
/* Abstractions of "generate code to do a guest load/store for
824
* AArch32", where a vaddr is always 32 bits (and is zero
825
* extended if we're a 64 bit core) and data is also
826
* 32 bits unless specifically doing a 64 bit access.
827
* These functions work like tcg_gen_qemu_{ld,st}* except
828
* that their arguments are TCGv_i32 rather than TCGv.
830
#if TARGET_LONG_BITS == 32
832
#define DO_GEN_LD(OP) \
833
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
835
tcg_gen_qemu_##OP(val, addr, index); \
838
#define DO_GEN_ST(OP) \
839
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
841
tcg_gen_qemu_##OP(val, addr, index); \
844
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
846
tcg_gen_qemu_ld64(val, addr, index);
849
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
851
tcg_gen_qemu_st64(val, addr, index);
856
#define DO_GEN_LD(OP) \
857
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
859
TCGv addr64 = tcg_temp_new(); \
860
TCGv val64 = tcg_temp_new(); \
861
tcg_gen_extu_i32_i64(addr64, addr); \
862
tcg_gen_qemu_##OP(val64, addr64, index); \
863
tcg_temp_free(addr64); \
864
tcg_gen_trunc_i64_i32(val, val64); \
865
tcg_temp_free(val64); \
868
#define DO_GEN_ST(OP) \
869
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
871
TCGv addr64 = tcg_temp_new(); \
872
TCGv val64 = tcg_temp_new(); \
873
tcg_gen_extu_i32_i64(addr64, addr); \
874
tcg_gen_extu_i32_i64(val64, val); \
875
tcg_gen_qemu_##OP(val64, addr64, index); \
876
tcg_temp_free(addr64); \
877
tcg_temp_free(val64); \
880
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
882
TCGv addr64 = tcg_temp_new();
883
tcg_gen_extu_i32_i64(addr64, addr);
884
tcg_gen_qemu_ld64(val, addr64, index);
885
tcg_temp_free(addr64);
888
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
890
TCGv addr64 = tcg_temp_new();
891
tcg_gen_extu_i32_i64(addr64, addr);
892
tcg_gen_qemu_st64(val, addr64, index);
893
tcg_temp_free(addr64);
907
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
910
gen_a64_set_pc_im(val);
912
tcg_gen_movi_i32(cpu_R[15], val);
916
/* Force a TB lookup after an instruction that changes the CPU state. */
917
static inline void gen_lookup_tb(DisasContext *s)
919
tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
920
s->is_jmp = DISAS_UPDATE;
923
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
926
int val, rm, shift, shiftop;
929
if (!(insn & (1 << 25))) {
932
if (!(insn & (1 << 23)))
935
tcg_gen_addi_i32(var, var, val);
939
shift = (insn >> 7) & 0x1f;
940
shiftop = (insn >> 5) & 3;
941
offset = load_reg(s, rm);
942
gen_arm_shift_im(offset, shiftop, shift, 0);
943
if (!(insn & (1 << 23)))
944
tcg_gen_sub_i32(var, var, offset);
946
tcg_gen_add_i32(var, var, offset);
947
tcg_temp_free_i32(offset);
951
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
952
int extra, TCGv_i32 var)
957
if (insn & (1 << 22)) {
959
val = (insn & 0xf) | ((insn >> 4) & 0xf0);
960
if (!(insn & (1 << 23)))
964
tcg_gen_addi_i32(var, var, val);
968
tcg_gen_addi_i32(var, var, extra);
970
offset = load_reg(s, rm);
971
if (!(insn & (1 << 23)))
972
tcg_gen_sub_i32(var, var, offset);
974
tcg_gen_add_i32(var, var, offset);
975
tcg_temp_free_i32(offset);
979
static TCGv_ptr get_fpstatus_ptr(int neon)
981
TCGv_ptr statusptr = tcg_temp_new_ptr();
984
offset = offsetof(CPUARMState, vfp.standard_fp_status);
986
offset = offsetof(CPUARMState, vfp.fp_status);
988
tcg_gen_addi_ptr(statusptr, cpu_env, offset);
992
#define VFP_OP2(name) \
993
static inline void gen_vfp_##name(int dp) \
995
TCGv_ptr fpst = get_fpstatus_ptr(0); \
997
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
999
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1001
tcg_temp_free_ptr(fpst); \
1011
static inline void gen_vfp_F1_mul(int dp)
1013
/* Like gen_vfp_mul() but put result in F1 */
1014
TCGv_ptr fpst = get_fpstatus_ptr(0);
1016
gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1018
gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1020
tcg_temp_free_ptr(fpst);
1023
static inline void gen_vfp_F1_neg(int dp)
1025
/* Like gen_vfp_neg() but put result in F1 */
1027
gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1029
gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1033
static inline void gen_vfp_abs(int dp)
1036
gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1038
gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1041
static inline void gen_vfp_neg(int dp)
1044
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1046
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1049
static inline void gen_vfp_sqrt(int dp)
1052
gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1054
gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1057
static inline void gen_vfp_cmp(int dp)
1060
gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1062
gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1065
static inline void gen_vfp_cmpe(int dp)
1068
gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1070
gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1073
static inline void gen_vfp_F1_ld0(int dp)
1076
tcg_gen_movi_i64(cpu_F1d, 0);
1078
tcg_gen_movi_i32(cpu_F1s, 0);
1081
#define VFP_GEN_ITOF(name) \
1082
static inline void gen_vfp_##name(int dp, int neon) \
1084
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1086
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1088
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1090
tcg_temp_free_ptr(statusptr); \
1097
#define VFP_GEN_FTOI(name) \
1098
static inline void gen_vfp_##name(int dp, int neon) \
1100
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1102
gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1104
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1106
tcg_temp_free_ptr(statusptr); \
1115
#define VFP_GEN_FIX(name) \
1116
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1118
TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1119
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1121
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1123
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1125
tcg_temp_free_i32(tmp_shift); \
1126
tcg_temp_free_ptr(statusptr); \
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
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2618
(ie. an undefined instruction). */
2619
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2621
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2627
if (!arm_feature(env, ARM_FEATURE_VFP))
2630
if (!s->vfp_enabled) {
2631
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2632
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2634
rn = (insn >> 16) & 0xf;
2635
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2636
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2639
dp = ((insn & 0xf00) == 0xb00);
2640
switch ((insn >> 24) & 0xf) {
2642
if (insn & (1 << 4)) {
2643
/* single register transfer */
2644
rd = (insn >> 12) & 0xf;
2649
VFP_DREG_N(rn, insn);
2652
if (insn & 0x00c00060
2653
&& !arm_feature(env, ARM_FEATURE_NEON))
2656
pass = (insn >> 21) & 1;
2657
if (insn & (1 << 22)) {
2659
offset = ((insn >> 5) & 3) * 8;
2660
} else if (insn & (1 << 5)) {
2662
offset = (insn & (1 << 6)) ? 16 : 0;
2667
if (insn & ARM_CP_RW_BIT) {
2669
tmp = neon_load_reg(rn, pass);
2673
tcg_gen_shri_i32(tmp, tmp, offset);
2674
if (insn & (1 << 23))
2680
if (insn & (1 << 23)) {
2682
tcg_gen_shri_i32(tmp, tmp, 16);
2688
tcg_gen_sari_i32(tmp, tmp, 16);
2697
store_reg(s, rd, tmp);
2700
tmp = load_reg(s, rd);
2701
if (insn & (1 << 23)) {
2704
gen_neon_dup_u8(tmp, 0);
2705
} else if (size == 1) {
2706
gen_neon_dup_low16(tmp);
2708
for (n = 0; n <= pass * 2; n++) {
2709
tmp2 = tcg_temp_new_i32();
2710
tcg_gen_mov_i32(tmp2, tmp);
2711
neon_store_reg(rn, n, tmp2);
2713
neon_store_reg(rn, n, tmp);
2718
tmp2 = neon_load_reg(rn, pass);
2719
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2720
tcg_temp_free_i32(tmp2);
2723
tmp2 = neon_load_reg(rn, pass);
2724
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2725
tcg_temp_free_i32(tmp2);
2730
neon_store_reg(rn, pass, tmp);
2734
if ((insn & 0x6f) != 0x00)
2736
rn = VFP_SREG_N(insn);
2737
if (insn & ARM_CP_RW_BIT) {
2739
if (insn & (1 << 21)) {
2740
/* system register */
2745
/* VFP2 allows access to FSID from userspace.
2746
VFP3 restricts all id registers to privileged
2749
&& arm_feature(env, ARM_FEATURE_VFP3))
2751
tmp = load_cpu_field(vfp.xregs[rn]);
2756
tmp = load_cpu_field(vfp.xregs[rn]);
2758
case ARM_VFP_FPINST:
2759
case ARM_VFP_FPINST2:
2760
/* Not present in VFP3. */
2762
|| arm_feature(env, ARM_FEATURE_VFP3))
2764
tmp = load_cpu_field(vfp.xregs[rn]);
2768
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2769
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2771
tmp = tcg_temp_new_i32();
2772
gen_helper_vfp_get_fpscr(tmp, cpu_env);
2778
|| !arm_feature(env, ARM_FEATURE_MVFR))
2780
tmp = load_cpu_field(vfp.xregs[rn]);
2786
gen_mov_F0_vreg(0, rn);
2787
tmp = gen_vfp_mrs();
2790
/* Set the 4 flag bits in the CPSR. */
2792
tcg_temp_free_i32(tmp);
2794
store_reg(s, rd, tmp);
2798
if (insn & (1 << 21)) {
2800
/* system register */
2805
/* Writes are ignored. */
2808
tmp = load_reg(s, rd);
2809
gen_helper_vfp_set_fpscr(cpu_env, tmp);
2810
tcg_temp_free_i32(tmp);
2816
/* TODO: VFP subarchitecture support.
2817
* For now, keep the EN bit only */
2818
tmp = load_reg(s, rd);
2819
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2820
store_cpu_field(tmp, vfp.xregs[rn]);
2823
case ARM_VFP_FPINST:
2824
case ARM_VFP_FPINST2:
2825
tmp = load_reg(s, rd);
2826
store_cpu_field(tmp, vfp.xregs[rn]);
2832
tmp = load_reg(s, rd);
2834
gen_mov_vreg_F0(0, rn);
2839
/* data processing */
2840
/* The opcode is in bits 23, 21, 20 and 6. */
2841
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2845
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2847
/* rn is register number */
2848
VFP_DREG_N(rn, insn);
2851
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2852
/* Integer or single precision destination. */
2853
rd = VFP_SREG_D(insn);
2855
VFP_DREG_D(rd, insn);
2858
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2859
/* VCVT from int is always from S reg regardless of dp bit.
2860
* VCVT with immediate frac_bits has same format as SREG_M
2862
rm = VFP_SREG_M(insn);
2864
VFP_DREG_M(rm, insn);
2867
rn = VFP_SREG_N(insn);
2868
if (op == 15 && rn == 15) {
2869
/* Double precision destination. */
2870
VFP_DREG_D(rd, insn);
2872
rd = VFP_SREG_D(insn);
2874
/* NB that we implicitly rely on the encoding for the frac_bits
2875
* in VCVT of fixed to float being the same as that of an SREG_M
2877
rm = VFP_SREG_M(insn);
2880
veclen = s->vec_len;
2881
if (op == 15 && rn > 3)
2884
/* Shut up compiler warnings. */
2895
/* Figure out what type of vector operation this is. */
2896
if ((rd & bank_mask) == 0) {
2901
delta_d = (s->vec_stride >> 1) + 1;
2903
delta_d = s->vec_stride + 1;
2905
if ((rm & bank_mask) == 0) {
2906
/* mixed scalar/vector */
2915
/* Load the initial operands. */
2920
/* Integer source */
2921
gen_mov_F0_vreg(0, rm);
2926
gen_mov_F0_vreg(dp, rd);
2927
gen_mov_F1_vreg(dp, rm);
2931
/* Compare with zero */
2932
gen_mov_F0_vreg(dp, rd);
2943
/* Source and destination the same. */
2944
gen_mov_F0_vreg(dp, rd);
2950
/* VCVTB, VCVTT: only present with the halfprec extension,
2951
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2953
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
2956
/* Otherwise fall through */
2958
/* One source operand. */
2959
gen_mov_F0_vreg(dp, rm);
2963
/* Two source operands. */
2964
gen_mov_F0_vreg(dp, rn);
2965
gen_mov_F1_vreg(dp, rm);
2969
/* Perform the calculation. */
2971
case 0: /* VMLA: fd + (fn * fm) */
2972
/* Note that order of inputs to the add matters for NaNs */
2974
gen_mov_F0_vreg(dp, rd);
2977
case 1: /* VMLS: fd + -(fn * fm) */
2980
gen_mov_F0_vreg(dp, rd);
2983
case 2: /* VNMLS: -fd + (fn * fm) */
2984
/* Note that it isn't valid to replace (-A + B) with (B - A)
2985
* or similar plausible looking simplifications
2986
* because this will give wrong results for NaNs.
2989
gen_mov_F0_vreg(dp, rd);
2993
case 3: /* VNMLA: -fd + -(fn * fm) */
2996
gen_mov_F0_vreg(dp, rd);
3000
case 4: /* mul: fn * fm */
3003
case 5: /* nmul: -(fn * fm) */
3007
case 6: /* add: fn + fm */
3010
case 7: /* sub: fn - fm */
3013
case 8: /* div: fn / fm */
3016
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3017
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3018
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3019
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3020
/* These are fused multiply-add, and must be done as one
3021
* floating point operation with no rounding between the
3022
* multiplication and addition steps.
3023
* NB that doing the negations here as separate steps is
3024
* correct : an input NaN should come out with its sign bit
3025
* flipped if it is a negated-input.
3027
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3035
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3037
frd = tcg_temp_new_i64();
3038
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3041
gen_helper_vfp_negd(frd, frd);
3043
fpst = get_fpstatus_ptr(0);
3044
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3045
cpu_F1d, frd, fpst);
3046
tcg_temp_free_ptr(fpst);
3047
tcg_temp_free_i64(frd);
3053
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3055
frd = tcg_temp_new_i32();
3056
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3058
gen_helper_vfp_negs(frd, frd);
3060
fpst = get_fpstatus_ptr(0);
3061
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3062
cpu_F1s, frd, fpst);
3063
tcg_temp_free_ptr(fpst);
3064
tcg_temp_free_i32(frd);
3067
case 14: /* fconst */
3068
if (!arm_feature(env, ARM_FEATURE_VFP3))
3071
n = (insn << 12) & 0x80000000;
3072
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3079
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3086
tcg_gen_movi_i32(cpu_F0s, n);
3089
case 15: /* extension space */
3103
case 4: /* vcvtb.f32.f16 */
3104
tmp = gen_vfp_mrs();
3105
tcg_gen_ext16u_i32(tmp, tmp);
3106
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3107
tcg_temp_free_i32(tmp);
3109
case 5: /* vcvtt.f32.f16 */
3110
tmp = gen_vfp_mrs();
3111
tcg_gen_shri_i32(tmp, tmp, 16);
3112
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3113
tcg_temp_free_i32(tmp);
3115
case 6: /* vcvtb.f16.f32 */
3116
tmp = tcg_temp_new_i32();
3117
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3118
gen_mov_F0_vreg(0, rd);
3119
tmp2 = gen_vfp_mrs();
3120
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3121
tcg_gen_or_i32(tmp, tmp, tmp2);
3122
tcg_temp_free_i32(tmp2);
3125
case 7: /* vcvtt.f16.f32 */
3126
tmp = tcg_temp_new_i32();
3127
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3128
tcg_gen_shli_i32(tmp, tmp, 16);
3129
gen_mov_F0_vreg(0, rd);
3130
tmp2 = gen_vfp_mrs();
3131
tcg_gen_ext16u_i32(tmp2, tmp2);
3132
tcg_gen_or_i32(tmp, tmp, tmp2);
3133
tcg_temp_free_i32(tmp2);
3145
case 11: /* cmpez */
3149
case 15: /* single<->double conversion */
3151
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3153
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3155
case 16: /* fuito */
3156
gen_vfp_uito(dp, 0);
3158
case 17: /* fsito */
3159
gen_vfp_sito(dp, 0);
3161
case 20: /* fshto */
3162
if (!arm_feature(env, ARM_FEATURE_VFP3))
3164
gen_vfp_shto(dp, 16 - rm, 0);
3166
case 21: /* fslto */
3167
if (!arm_feature(env, ARM_FEATURE_VFP3))
3169
gen_vfp_slto(dp, 32 - rm, 0);
3171
case 22: /* fuhto */
3172
if (!arm_feature(env, ARM_FEATURE_VFP3))
3174
gen_vfp_uhto(dp, 16 - rm, 0);
3176
case 23: /* fulto */
3177
if (!arm_feature(env, ARM_FEATURE_VFP3))
3179
gen_vfp_ulto(dp, 32 - rm, 0);
3181
case 24: /* ftoui */
3182
gen_vfp_toui(dp, 0);
3184
case 25: /* ftouiz */
3185
gen_vfp_touiz(dp, 0);
3187
case 26: /* ftosi */
3188
gen_vfp_tosi(dp, 0);
3190
case 27: /* ftosiz */
3191
gen_vfp_tosiz(dp, 0);
3193
case 28: /* ftosh */
3194
if (!arm_feature(env, ARM_FEATURE_VFP3))
3196
gen_vfp_tosh(dp, 16 - rm, 0);
3198
case 29: /* ftosl */
3199
if (!arm_feature(env, ARM_FEATURE_VFP3))
3201
gen_vfp_tosl(dp, 32 - rm, 0);
3203
case 30: /* ftouh */
3204
if (!arm_feature(env, ARM_FEATURE_VFP3))
3206
gen_vfp_touh(dp, 16 - rm, 0);
3208
case 31: /* ftoul */
3209
if (!arm_feature(env, ARM_FEATURE_VFP3))
3211
gen_vfp_toul(dp, 32 - rm, 0);
3213
default: /* undefined */
3217
default: /* undefined */
3221
/* Write back the result. */
3222
if (op == 15 && (rn >= 8 && rn <= 11))
3223
; /* Comparison, do nothing. */
3224
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3225
/* VCVT double to int: always integer result. */
3226
gen_mov_vreg_F0(0, rd);
3227
else if (op == 15 && rn == 15)
3229
gen_mov_vreg_F0(!dp, rd);
3231
gen_mov_vreg_F0(dp, rd);
3233
/* break out of the loop if we have finished */
3237
if (op == 15 && delta_m == 0) {
3238
/* single source one-many */
3240
rd = ((rd + delta_d) & (bank_mask - 1))
3242
gen_mov_vreg_F0(dp, rd);
3246
/* Setup the next operands. */
3248
rd = ((rd + delta_d) & (bank_mask - 1))
3252
/* One source operand. */
3253
rm = ((rm + delta_m) & (bank_mask - 1))
3255
gen_mov_F0_vreg(dp, rm);
3257
/* Two source operands. */
3258
rn = ((rn + delta_d) & (bank_mask - 1))
3260
gen_mov_F0_vreg(dp, rn);
3262
rm = ((rm + delta_m) & (bank_mask - 1))
3264
gen_mov_F1_vreg(dp, rm);
3272
if ((insn & 0x03e00000) == 0x00400000) {
3273
/* two-register transfer */
3274
rn = (insn >> 16) & 0xf;
3275
rd = (insn >> 12) & 0xf;
3277
VFP_DREG_M(rm, insn);
3279
rm = VFP_SREG_M(insn);
3282
if (insn & ARM_CP_RW_BIT) {
3285
gen_mov_F0_vreg(0, rm * 2);
3286
tmp = gen_vfp_mrs();
3287
store_reg(s, rd, tmp);
3288
gen_mov_F0_vreg(0, rm * 2 + 1);
3289
tmp = gen_vfp_mrs();
3290
store_reg(s, rn, tmp);
3292
gen_mov_F0_vreg(0, rm);
3293
tmp = gen_vfp_mrs();
3294
store_reg(s, rd, tmp);
3295
gen_mov_F0_vreg(0, rm + 1);
3296
tmp = gen_vfp_mrs();
3297
store_reg(s, rn, tmp);
3302
tmp = load_reg(s, rd);
3304
gen_mov_vreg_F0(0, rm * 2);
3305
tmp = load_reg(s, rn);
3307
gen_mov_vreg_F0(0, rm * 2 + 1);
3309
tmp = load_reg(s, rd);
3311
gen_mov_vreg_F0(0, rm);
3312
tmp = load_reg(s, rn);
3314
gen_mov_vreg_F0(0, rm + 1);
3319
rn = (insn >> 16) & 0xf;
3321
VFP_DREG_D(rd, insn);
3323
rd = VFP_SREG_D(insn);
3324
if ((insn & 0x01200000) == 0x01000000) {
3325
/* Single load/store */
3326
offset = (insn & 0xff) << 2;
3327
if ((insn & (1 << 23)) == 0)
3329
if (s->thumb && rn == 15) {
3330
/* This is actually UNPREDICTABLE */
3331
addr = tcg_temp_new_i32();
3332
tcg_gen_movi_i32(addr, s->pc & ~2);
3334
addr = load_reg(s, rn);
3336
tcg_gen_addi_i32(addr, addr, offset);
3337
if (insn & (1 << 20)) {
3338
gen_vfp_ld(s, dp, addr);
3339
gen_mov_vreg_F0(dp, rd);
3341
gen_mov_F0_vreg(dp, rd);
3342
gen_vfp_st(s, dp, addr);
3344
tcg_temp_free_i32(addr);
3346
/* load/store multiple */
3347
int w = insn & (1 << 21);
3349
n = (insn >> 1) & 0x7f;
3353
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3354
/* P == U , W == 1 => UNDEF */
3357
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3358
/* UNPREDICTABLE cases for bad immediates: we choose to
3359
* UNDEF to avoid generating huge numbers of TCG ops
3363
if (rn == 15 && w) {
3364
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3368
if (s->thumb && rn == 15) {
3369
/* This is actually UNPREDICTABLE */
3370
addr = tcg_temp_new_i32();
3371
tcg_gen_movi_i32(addr, s->pc & ~2);
3373
addr = load_reg(s, rn);
3375
if (insn & (1 << 24)) /* pre-decrement */
3376
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3382
for (i = 0; i < n; i++) {
3383
if (insn & ARM_CP_RW_BIT) {
3385
gen_vfp_ld(s, dp, addr);
3386
gen_mov_vreg_F0(dp, rd + i);
3389
gen_mov_F0_vreg(dp, rd + i);
3390
gen_vfp_st(s, dp, addr);
3392
tcg_gen_addi_i32(addr, addr, offset);
3396
if (insn & (1 << 24))
3397
offset = -offset * n;
3398
else if (dp && (insn & 1))
3404
tcg_gen_addi_i32(addr, addr, offset);
3405
store_reg(s, rn, addr);
3407
tcg_temp_free_i32(addr);
3413
/* Should never happen. */
3419
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3421
TranslationBlock *tb;
3424
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3426
gen_set_pc_im(s, dest);
3427
tcg_gen_exit_tb((uintptr_t)tb + n);
3429
gen_set_pc_im(s, dest);
3434
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3436
if (unlikely(s->singlestep_enabled)) {
3437
/* An indirect jump so that we still trigger the debug exception. */
3442
gen_goto_tb(s, 0, dest);
3443
s->is_jmp = DISAS_TB_JUMP;
3447
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3450
tcg_gen_sari_i32(t0, t0, 16);
3454
tcg_gen_sari_i32(t1, t1, 16);
3457
tcg_gen_mul_i32(t0, t0, t1);
3460
/* Return the mask of PSR bits set by a MSR instruction. */
3461
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3465
if (flags & (1 << 0))
3467
if (flags & (1 << 1))
3469
if (flags & (1 << 2))
3471
if (flags & (1 << 3))
3474
/* Mask out undefined bits. */
3475
mask &= ~CPSR_RESERVED;
3476
if (!arm_feature(env, ARM_FEATURE_V4T))
3478
if (!arm_feature(env, ARM_FEATURE_V5))
3479
mask &= ~CPSR_Q; /* V5TE in reality*/
3480
if (!arm_feature(env, ARM_FEATURE_V6))
3481
mask &= ~(CPSR_E | CPSR_GE);
3482
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3484
/* Mask out execution state bits. */
3487
/* Mask out privileged bits. */
3493
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3494
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3498
/* ??? This is also undefined in system mode. */
3502
tmp = load_cpu_field(spsr);
3503
tcg_gen_andi_i32(tmp, tmp, ~mask);
3504
tcg_gen_andi_i32(t0, t0, mask);
3505
tcg_gen_or_i32(tmp, tmp, t0);
3506
store_cpu_field(tmp, spsr);
3508
gen_set_cpsr(t0, mask);
3510
tcg_temp_free_i32(t0);
3515
/* Returns nonzero if access to the PSR is not permitted. */
3516
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3519
tmp = tcg_temp_new_i32();
3520
tcg_gen_movi_i32(tmp, val);
3521
return gen_set_psr(s, mask, spsr, tmp);
3524
/* Generate an old-style exception return. Marks pc as dead. */
3525
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3528
store_reg(s, 15, pc);
3529
tmp = load_cpu_field(spsr);
3530
gen_set_cpsr(tmp, 0xffffffff);
3531
tcg_temp_free_i32(tmp);
3532
s->is_jmp = DISAS_UPDATE;
3535
/* Generate a v6 exception return. Marks both values as dead. */
3536
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3538
gen_set_cpsr(cpsr, 0xffffffff);
3539
tcg_temp_free_i32(cpsr);
3540
store_reg(s, 15, pc);
3541
s->is_jmp = DISAS_UPDATE;
3545
gen_set_condexec (DisasContext *s)
3547
if (s->condexec_mask) {
3548
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3549
TCGv_i32 tmp = tcg_temp_new_i32();
3550
tcg_gen_movi_i32(tmp, val);
3551
store_cpu_field(tmp, condexec_bits);
3555
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3557
gen_set_condexec(s);
3558
gen_set_pc_im(s, s->pc - offset);
3559
gen_exception(excp);
3560
s->is_jmp = DISAS_JUMP;
3563
static void gen_nop_hint(DisasContext *s, int val)
3567
gen_set_pc_im(s, s->pc);
3568
s->is_jmp = DISAS_WFI;
3573
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3579
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3581
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3584
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3585
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3586
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3591
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3594
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3595
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3596
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3601
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3602
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3603
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3604
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3605
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3607
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3608
switch ((size << 1) | u) { \
3610
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3613
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3616
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3619
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3622
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3625
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3627
default: return 1; \
3630
#define GEN_NEON_INTEGER_OP(name) do { \
3631
switch ((size << 1) | u) { \
3633
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3636
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3639
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3642
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3645
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3648
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3650
default: return 1; \
3653
static TCGv_i32 neon_load_scratch(int scratch)
3655
TCGv_i32 tmp = tcg_temp_new_i32();
3656
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3660
static void neon_store_scratch(int scratch, TCGv_i32 var)
3662
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3663
tcg_temp_free_i32(var);
3666
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3670
tmp = neon_load_reg(reg & 7, reg >> 4);
3672
gen_neon_dup_high16(tmp);
3674
gen_neon_dup_low16(tmp);
3677
tmp = neon_load_reg(reg & 15, reg >> 4);
3682
static int gen_neon_unzip(int rd, int rm, int size, int q)
3685
if (!q && size == 2) {
3688
tmp = tcg_const_i32(rd);
3689
tmp2 = tcg_const_i32(rm);
3693
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3696
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3699
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3707
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3710
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3716
tcg_temp_free_i32(tmp);
3717
tcg_temp_free_i32(tmp2);
3721
static int gen_neon_zip(int rd, int rm, int size, int q)
3724
if (!q && size == 2) {
3727
tmp = tcg_const_i32(rd);
3728
tmp2 = tcg_const_i32(rm);
3732
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3735
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3738
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3746
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3749
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3755
tcg_temp_free_i32(tmp);
3756
tcg_temp_free_i32(tmp2);
3760
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3764
rd = tcg_temp_new_i32();
3765
tmp = tcg_temp_new_i32();
3767
tcg_gen_shli_i32(rd, t0, 8);
3768
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3769
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3770
tcg_gen_or_i32(rd, rd, tmp);
3772
tcg_gen_shri_i32(t1, t1, 8);
3773
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3774
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3775
tcg_gen_or_i32(t1, t1, tmp);
3776
tcg_gen_mov_i32(t0, rd);
3778
tcg_temp_free_i32(tmp);
3779
tcg_temp_free_i32(rd);
3782
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3786
rd = tcg_temp_new_i32();
3787
tmp = tcg_temp_new_i32();
3789
tcg_gen_shli_i32(rd, t0, 16);
3790
tcg_gen_andi_i32(tmp, t1, 0xffff);
3791
tcg_gen_or_i32(rd, rd, tmp);
3792
tcg_gen_shri_i32(t1, t1, 16);
3793
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3794
tcg_gen_or_i32(t1, t1, tmp);
3795
tcg_gen_mov_i32(t0, rd);
3797
tcg_temp_free_i32(tmp);
3798
tcg_temp_free_i32(rd);
3806
} neon_ls_element_type[11] = {
3820
/* Translate a NEON load/store element instruction. Return nonzero if the
3821
instruction is invalid. */
3822
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
3841
if (!s->vfp_enabled)
3843
VFP_DREG_D(rd, insn);
3844
rn = (insn >> 16) & 0xf;
3846
load = (insn & (1 << 21)) != 0;
3847
if ((insn & (1 << 23)) == 0) {
3848
/* Load store all elements. */
3849
op = (insn >> 8) & 0xf;
3850
size = (insn >> 6) & 3;
3853
/* Catch UNDEF cases for bad values of align field */
3856
if (((insn >> 5) & 1) == 1) {
3861
if (((insn >> 4) & 3) == 3) {
3868
nregs = neon_ls_element_type[op].nregs;
3869
interleave = neon_ls_element_type[op].interleave;
3870
spacing = neon_ls_element_type[op].spacing;
3871
if (size == 3 && (interleave | spacing) != 1)
3873
addr = tcg_temp_new_i32();
3874
load_reg_var(s, addr, rn);
3875
stride = (1 << size) * interleave;
3876
for (reg = 0; reg < nregs; reg++) {
3877
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3878
load_reg_var(s, addr, rn);
3879
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3880
} else if (interleave == 2 && nregs == 4 && reg == 2) {
3881
load_reg_var(s, addr, rn);
3882
tcg_gen_addi_i32(addr, addr, 1 << size);
3885
tmp64 = tcg_temp_new_i64();
3887
gen_aa32_ld64(tmp64, addr, IS_USER(s));
3888
neon_store_reg64(tmp64, rd);
3890
neon_load_reg64(tmp64, rd);
3891
gen_aa32_st64(tmp64, addr, IS_USER(s));
3893
tcg_temp_free_i64(tmp64);
3894
tcg_gen_addi_i32(addr, addr, stride);
3896
for (pass = 0; pass < 2; pass++) {
3899
tmp = tcg_temp_new_i32();
3900
gen_aa32_ld32u(tmp, addr, IS_USER(s));
3901
neon_store_reg(rd, pass, tmp);
3903
tmp = neon_load_reg(rd, pass);
3904
gen_aa32_st32(tmp, addr, IS_USER(s));
3905
tcg_temp_free_i32(tmp);
3907
tcg_gen_addi_i32(addr, addr, stride);
3908
} else if (size == 1) {
3910
tmp = tcg_temp_new_i32();
3911
gen_aa32_ld16u(tmp, addr, IS_USER(s));
3912
tcg_gen_addi_i32(addr, addr, stride);
3913
tmp2 = tcg_temp_new_i32();
3914
gen_aa32_ld16u(tmp2, addr, IS_USER(s));
3915
tcg_gen_addi_i32(addr, addr, stride);
3916
tcg_gen_shli_i32(tmp2, tmp2, 16);
3917
tcg_gen_or_i32(tmp, tmp, tmp2);
3918
tcg_temp_free_i32(tmp2);
3919
neon_store_reg(rd, pass, tmp);
3921
tmp = neon_load_reg(rd, pass);
3922
tmp2 = tcg_temp_new_i32();
3923
tcg_gen_shri_i32(tmp2, tmp, 16);
3924
gen_aa32_st16(tmp, addr, IS_USER(s));
3925
tcg_temp_free_i32(tmp);
3926
tcg_gen_addi_i32(addr, addr, stride);
3927
gen_aa32_st16(tmp2, addr, IS_USER(s));
3928
tcg_temp_free_i32(tmp2);
3929
tcg_gen_addi_i32(addr, addr, stride);
3931
} else /* size == 0 */ {
3933
TCGV_UNUSED_I32(tmp2);
3934
for (n = 0; n < 4; n++) {
3935
tmp = tcg_temp_new_i32();
3936
gen_aa32_ld8u(tmp, addr, IS_USER(s));
3937
tcg_gen_addi_i32(addr, addr, stride);
3941
tcg_gen_shli_i32(tmp, tmp, n * 8);
3942
tcg_gen_or_i32(tmp2, tmp2, tmp);
3943
tcg_temp_free_i32(tmp);
3946
neon_store_reg(rd, pass, tmp2);
3948
tmp2 = neon_load_reg(rd, pass);
3949
for (n = 0; n < 4; n++) {
3950
tmp = tcg_temp_new_i32();
3952
tcg_gen_mov_i32(tmp, tmp2);
3954
tcg_gen_shri_i32(tmp, tmp2, n * 8);
3956
gen_aa32_st8(tmp, addr, IS_USER(s));
3957
tcg_temp_free_i32(tmp);
3958
tcg_gen_addi_i32(addr, addr, stride);
3960
tcg_temp_free_i32(tmp2);
3967
tcg_temp_free_i32(addr);
3970
size = (insn >> 10) & 3;
3972
/* Load single element to all lanes. */
3973
int a = (insn >> 4) & 1;
3977
size = (insn >> 6) & 3;
3978
nregs = ((insn >> 8) & 3) + 1;
3981
if (nregs != 4 || a == 0) {
3984
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3987
if (nregs == 1 && a == 1 && size == 0) {
3990
if (nregs == 3 && a == 1) {
3993
addr = tcg_temp_new_i32();
3994
load_reg_var(s, addr, rn);
3996
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3997
tmp = gen_load_and_replicate(s, addr, size);
3998
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
3999
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4000
if (insn & (1 << 5)) {
4001
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4002
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4004
tcg_temp_free_i32(tmp);
4006
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4007
stride = (insn & (1 << 5)) ? 2 : 1;
4008
for (reg = 0; reg < nregs; reg++) {
4009
tmp = gen_load_and_replicate(s, addr, size);
4010
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4011
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4012
tcg_temp_free_i32(tmp);
4013
tcg_gen_addi_i32(addr, addr, 1 << size);
4017
tcg_temp_free_i32(addr);
4018
stride = (1 << size) * nregs;
4020
/* Single element. */
4021
int idx = (insn >> 4) & 0xf;
4022
pass = (insn >> 7) & 1;
4025
shift = ((insn >> 5) & 3) * 8;
4029
shift = ((insn >> 6) & 1) * 16;
4030
stride = (insn & (1 << 5)) ? 2 : 1;
4034
stride = (insn & (1 << 6)) ? 2 : 1;
4039
nregs = ((insn >> 8) & 3) + 1;
4040
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
4043
if (((idx & (1 << size)) != 0) ||
4044
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4049
if ((idx & 1) != 0) {
4054
if (size == 2 && (idx & 2) != 0) {
4059
if ((size == 2) && ((idx & 3) == 3)) {
4066
if ((rd + stride * (nregs - 1)) > 31) {
4067
/* Attempts to write off the end of the register file
4068
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4069
* the neon_load_reg() would write off the end of the array.
4073
addr = tcg_temp_new_i32();
4074
load_reg_var(s, addr, rn);
4075
for (reg = 0; reg < nregs; reg++) {
4077
tmp = tcg_temp_new_i32();
4080
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4083
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4086
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4088
default: /* Avoid compiler warnings. */
4092
tmp2 = neon_load_reg(rd, pass);
4093
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4094
shift, size ? 16 : 8);
4095
tcg_temp_free_i32(tmp2);
4097
neon_store_reg(rd, pass, tmp);
4098
} else { /* Store */
4099
tmp = neon_load_reg(rd, pass);
4101
tcg_gen_shri_i32(tmp, tmp, shift);
4104
gen_aa32_st8(tmp, addr, IS_USER(s));
4107
gen_aa32_st16(tmp, addr, IS_USER(s));
4110
gen_aa32_st32(tmp, addr, IS_USER(s));
4113
tcg_temp_free_i32(tmp);
4116
tcg_gen_addi_i32(addr, addr, 1 << size);
4118
tcg_temp_free_i32(addr);
4119
stride = nregs * (1 << size);
4125
base = load_reg(s, rn);
4127
tcg_gen_addi_i32(base, base, stride);
4130
index = load_reg(s, rm);
4131
tcg_gen_add_i32(base, base, index);
4132
tcg_temp_free_i32(index);
4134
store_reg(s, rn, base);
4139
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4140
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4142
tcg_gen_and_i32(t, t, c);
4143
tcg_gen_andc_i32(f, f, c);
4144
tcg_gen_or_i32(dest, t, f);
4147
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4150
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4151
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4152
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4157
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4160
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4161
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4162
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4167
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4170
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4171
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4172
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4177
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4180
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4181
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4182
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4187
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4193
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4194
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4199
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4200
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4207
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4208
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4213
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4214
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4221
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4225
case 0: gen_helper_neon_widen_u8(dest, src); break;
4226
case 1: gen_helper_neon_widen_u16(dest, src); break;
4227
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4232
case 0: gen_helper_neon_widen_s8(dest, src); break;
4233
case 1: gen_helper_neon_widen_s16(dest, src); break;
4234
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4238
tcg_temp_free_i32(src);
4241
static inline void gen_neon_addl(int size)
4244
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4245
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4246
case 2: tcg_gen_add_i64(CPU_V001); break;
4251
static inline void gen_neon_subl(int size)
4254
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4255
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4256
case 2: tcg_gen_sub_i64(CPU_V001); break;
4261
static inline void gen_neon_negl(TCGv_i64 var, int size)
4264
case 0: gen_helper_neon_negl_u16(var, var); break;
4265
case 1: gen_helper_neon_negl_u32(var, var); break;
4267
tcg_gen_neg_i64(var, var);
4273
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4276
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4277
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4282
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4287
switch ((size << 1) | u) {
4288
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4289
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4290
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4291
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4293
tmp = gen_muls_i64_i32(a, b);
4294
tcg_gen_mov_i64(dest, tmp);
4295
tcg_temp_free_i64(tmp);
4298
tmp = gen_mulu_i64_i32(a, b);
4299
tcg_gen_mov_i64(dest, tmp);
4300
tcg_temp_free_i64(tmp);
4305
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4306
Don't forget to clean them now. */
4308
tcg_temp_free_i32(a);
4309
tcg_temp_free_i32(b);
4313
static void gen_neon_narrow_op(int op, int u, int size,
4314
TCGv_i32 dest, TCGv_i64 src)
4318
gen_neon_unarrow_sats(size, dest, src);
4320
gen_neon_narrow(size, dest, src);
4324
gen_neon_narrow_satu(size, dest, src);
4326
gen_neon_narrow_sats(size, dest, src);
4331
/* Symbolic constants for op fields for Neon 3-register same-length.
4332
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4335
#define NEON_3R_VHADD 0
4336
#define NEON_3R_VQADD 1
4337
#define NEON_3R_VRHADD 2
4338
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4339
#define NEON_3R_VHSUB 4
4340
#define NEON_3R_VQSUB 5
4341
#define NEON_3R_VCGT 6
4342
#define NEON_3R_VCGE 7
4343
#define NEON_3R_VSHL 8
4344
#define NEON_3R_VQSHL 9
4345
#define NEON_3R_VRSHL 10
4346
#define NEON_3R_VQRSHL 11
4347
#define NEON_3R_VMAX 12
4348
#define NEON_3R_VMIN 13
4349
#define NEON_3R_VABD 14
4350
#define NEON_3R_VABA 15
4351
#define NEON_3R_VADD_VSUB 16
4352
#define NEON_3R_VTST_VCEQ 17
4353
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4354
#define NEON_3R_VMUL 19
4355
#define NEON_3R_VPMAX 20
4356
#define NEON_3R_VPMIN 21
4357
#define NEON_3R_VQDMULH_VQRDMULH 22
4358
#define NEON_3R_VPADD 23
4359
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4360
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4361
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4362
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4363
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4364
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4365
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4367
static const uint8_t neon_3r_sizes[] = {
4368
[NEON_3R_VHADD] = 0x7,
4369
[NEON_3R_VQADD] = 0xf,
4370
[NEON_3R_VRHADD] = 0x7,
4371
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4372
[NEON_3R_VHSUB] = 0x7,
4373
[NEON_3R_VQSUB] = 0xf,
4374
[NEON_3R_VCGT] = 0x7,
4375
[NEON_3R_VCGE] = 0x7,
4376
[NEON_3R_VSHL] = 0xf,
4377
[NEON_3R_VQSHL] = 0xf,
4378
[NEON_3R_VRSHL] = 0xf,
4379
[NEON_3R_VQRSHL] = 0xf,
4380
[NEON_3R_VMAX] = 0x7,
4381
[NEON_3R_VMIN] = 0x7,
4382
[NEON_3R_VABD] = 0x7,
4383
[NEON_3R_VABA] = 0x7,
4384
[NEON_3R_VADD_VSUB] = 0xf,
4385
[NEON_3R_VTST_VCEQ] = 0x7,
4386
[NEON_3R_VML] = 0x7,
4387
[NEON_3R_VMUL] = 0x7,
4388
[NEON_3R_VPMAX] = 0x7,
4389
[NEON_3R_VPMIN] = 0x7,
4390
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4391
[NEON_3R_VPADD] = 0x7,
4392
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4393
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4394
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4395
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4396
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4397
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4398
[NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4401
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4402
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4405
#define NEON_2RM_VREV64 0
4406
#define NEON_2RM_VREV32 1
4407
#define NEON_2RM_VREV16 2
4408
#define NEON_2RM_VPADDL 4
4409
#define NEON_2RM_VPADDL_U 5
4410
#define NEON_2RM_VCLS 8
4411
#define NEON_2RM_VCLZ 9
4412
#define NEON_2RM_VCNT 10
4413
#define NEON_2RM_VMVN 11
4414
#define NEON_2RM_VPADAL 12
4415
#define NEON_2RM_VPADAL_U 13
4416
#define NEON_2RM_VQABS 14
4417
#define NEON_2RM_VQNEG 15
4418
#define NEON_2RM_VCGT0 16
4419
#define NEON_2RM_VCGE0 17
4420
#define NEON_2RM_VCEQ0 18
4421
#define NEON_2RM_VCLE0 19
4422
#define NEON_2RM_VCLT0 20
4423
#define NEON_2RM_VABS 22
4424
#define NEON_2RM_VNEG 23
4425
#define NEON_2RM_VCGT0_F 24
4426
#define NEON_2RM_VCGE0_F 25
4427
#define NEON_2RM_VCEQ0_F 26
4428
#define NEON_2RM_VCLE0_F 27
4429
#define NEON_2RM_VCLT0_F 28
4430
#define NEON_2RM_VABS_F 30
4431
#define NEON_2RM_VNEG_F 31
4432
#define NEON_2RM_VSWP 32
4433
#define NEON_2RM_VTRN 33
4434
#define NEON_2RM_VUZP 34
4435
#define NEON_2RM_VZIP 35
4436
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4437
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4438
#define NEON_2RM_VSHLL 38
4439
#define NEON_2RM_VCVT_F16_F32 44
4440
#define NEON_2RM_VCVT_F32_F16 46
4441
#define NEON_2RM_VRECPE 56
4442
#define NEON_2RM_VRSQRTE 57
4443
#define NEON_2RM_VRECPE_F 58
4444
#define NEON_2RM_VRSQRTE_F 59
4445
#define NEON_2RM_VCVT_FS 60
4446
#define NEON_2RM_VCVT_FU 61
4447
#define NEON_2RM_VCVT_SF 62
4448
#define NEON_2RM_VCVT_UF 63
4450
static int neon_2rm_is_float_op(int op)
4452
/* Return true if this neon 2reg-misc op is float-to-float */
4453
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4454
op >= NEON_2RM_VRECPE_F);
4457
/* Each entry in this array has bit n set if the insn allows
4458
* size value n (otherwise it will UNDEF). Since unallocated
4459
* op values will have no bits set they always UNDEF.
4461
static const uint8_t neon_2rm_sizes[] = {
4462
[NEON_2RM_VREV64] = 0x7,
4463
[NEON_2RM_VREV32] = 0x3,
4464
[NEON_2RM_VREV16] = 0x1,
4465
[NEON_2RM_VPADDL] = 0x7,
4466
[NEON_2RM_VPADDL_U] = 0x7,
4467
[NEON_2RM_VCLS] = 0x7,
4468
[NEON_2RM_VCLZ] = 0x7,
4469
[NEON_2RM_VCNT] = 0x1,
4470
[NEON_2RM_VMVN] = 0x1,
4471
[NEON_2RM_VPADAL] = 0x7,
4472
[NEON_2RM_VPADAL_U] = 0x7,
4473
[NEON_2RM_VQABS] = 0x7,
4474
[NEON_2RM_VQNEG] = 0x7,
4475
[NEON_2RM_VCGT0] = 0x7,
4476
[NEON_2RM_VCGE0] = 0x7,
4477
[NEON_2RM_VCEQ0] = 0x7,
4478
[NEON_2RM_VCLE0] = 0x7,
4479
[NEON_2RM_VCLT0] = 0x7,
4480
[NEON_2RM_VABS] = 0x7,
4481
[NEON_2RM_VNEG] = 0x7,
4482
[NEON_2RM_VCGT0_F] = 0x4,
4483
[NEON_2RM_VCGE0_F] = 0x4,
4484
[NEON_2RM_VCEQ0_F] = 0x4,
4485
[NEON_2RM_VCLE0_F] = 0x4,
4486
[NEON_2RM_VCLT0_F] = 0x4,
4487
[NEON_2RM_VABS_F] = 0x4,
4488
[NEON_2RM_VNEG_F] = 0x4,
4489
[NEON_2RM_VSWP] = 0x1,
4490
[NEON_2RM_VTRN] = 0x7,
4491
[NEON_2RM_VUZP] = 0x7,
4492
[NEON_2RM_VZIP] = 0x7,
4493
[NEON_2RM_VMOVN] = 0x7,
4494
[NEON_2RM_VQMOVN] = 0x7,
4495
[NEON_2RM_VSHLL] = 0x7,
4496
[NEON_2RM_VCVT_F16_F32] = 0x2,
4497
[NEON_2RM_VCVT_F32_F16] = 0x2,
4498
[NEON_2RM_VRECPE] = 0x4,
4499
[NEON_2RM_VRSQRTE] = 0x4,
4500
[NEON_2RM_VRECPE_F] = 0x4,
4501
[NEON_2RM_VRSQRTE_F] = 0x4,
4502
[NEON_2RM_VCVT_FS] = 0x4,
4503
[NEON_2RM_VCVT_FU] = 0x4,
4504
[NEON_2RM_VCVT_SF] = 0x4,
4505
[NEON_2RM_VCVT_UF] = 0x4,
4508
/* Translate a NEON data processing instruction. Return nonzero if the
4509
instruction is invalid.
4510
We process data in a mixture of 32-bit and 64-bit chunks.
4511
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4513
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4525
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4528
if (!s->vfp_enabled)
4530
q = (insn & (1 << 6)) != 0;
4531
u = (insn >> 24) & 1;
4532
VFP_DREG_D(rd, insn);
4533
VFP_DREG_N(rn, insn);
4534
VFP_DREG_M(rm, insn);
4535
size = (insn >> 20) & 3;
4536
if ((insn & (1 << 23)) == 0) {
4537
/* Three register same length. */
4538
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4539
/* Catch invalid op and bad size combinations: UNDEF */
4540
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4543
/* All insns of this form UNDEF for either this condition or the
4544
* superset of cases "Q==1"; we catch the latter later.
4546
if (q && ((rd | rn | rm) & 1)) {
4549
if (size == 3 && op != NEON_3R_LOGIC) {
4550
/* 64-bit element instructions. */
4551
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4552
neon_load_reg64(cpu_V0, rn + pass);
4553
neon_load_reg64(cpu_V1, rm + pass);
4557
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4560
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4566
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4569
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4575
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4577
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4582
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4585
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4591
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4593
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4596
case NEON_3R_VQRSHL:
4598
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4601
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4605
case NEON_3R_VADD_VSUB:
4607
tcg_gen_sub_i64(CPU_V001);
4609
tcg_gen_add_i64(CPU_V001);
4615
neon_store_reg64(cpu_V0, rd + pass);
4624
case NEON_3R_VQRSHL:
4627
/* Shift instruction operands are reversed. */
4642
case NEON_3R_FLOAT_ARITH:
4643
pairwise = (u && size < 2); /* if VPADD (float) */
4645
case NEON_3R_FLOAT_MINMAX:
4646
pairwise = u; /* if VPMIN/VPMAX (float) */
4648
case NEON_3R_FLOAT_CMP:
4650
/* no encoding for U=0 C=1x */
4654
case NEON_3R_FLOAT_ACMP:
4659
case NEON_3R_VRECPS_VRSQRTS:
4665
if (u && (size != 0)) {
4666
/* UNDEF on invalid size for polynomial subcase */
4671
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4679
if (pairwise && q) {
4680
/* All the pairwise insns UNDEF if Q is set */
4684
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4689
tmp = neon_load_reg(rn, 0);
4690
tmp2 = neon_load_reg(rn, 1);
4692
tmp = neon_load_reg(rm, 0);
4693
tmp2 = neon_load_reg(rm, 1);
4697
tmp = neon_load_reg(rn, pass);
4698
tmp2 = neon_load_reg(rm, pass);
4702
GEN_NEON_INTEGER_OP(hadd);
4705
GEN_NEON_INTEGER_OP_ENV(qadd);
4707
case NEON_3R_VRHADD:
4708
GEN_NEON_INTEGER_OP(rhadd);
4710
case NEON_3R_LOGIC: /* Logic ops. */
4711
switch ((u << 2) | size) {
4713
tcg_gen_and_i32(tmp, tmp, tmp2);
4716
tcg_gen_andc_i32(tmp, tmp, tmp2);
4719
tcg_gen_or_i32(tmp, tmp, tmp2);
4722
tcg_gen_orc_i32(tmp, tmp, tmp2);
4725
tcg_gen_xor_i32(tmp, tmp, tmp2);
4728
tmp3 = neon_load_reg(rd, pass);
4729
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4730
tcg_temp_free_i32(tmp3);
4733
tmp3 = neon_load_reg(rd, pass);
4734
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4735
tcg_temp_free_i32(tmp3);
4738
tmp3 = neon_load_reg(rd, pass);
4739
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4740
tcg_temp_free_i32(tmp3);
4745
GEN_NEON_INTEGER_OP(hsub);
4748
GEN_NEON_INTEGER_OP_ENV(qsub);
4751
GEN_NEON_INTEGER_OP(cgt);
4754
GEN_NEON_INTEGER_OP(cge);
4757
GEN_NEON_INTEGER_OP(shl);
4760
GEN_NEON_INTEGER_OP_ENV(qshl);
4763
GEN_NEON_INTEGER_OP(rshl);
4765
case NEON_3R_VQRSHL:
4766
GEN_NEON_INTEGER_OP_ENV(qrshl);
4769
GEN_NEON_INTEGER_OP(max);
4772
GEN_NEON_INTEGER_OP(min);
4775
GEN_NEON_INTEGER_OP(abd);
4778
GEN_NEON_INTEGER_OP(abd);
4779
tcg_temp_free_i32(tmp2);
4780
tmp2 = neon_load_reg(rd, pass);
4781
gen_neon_add(size, tmp, tmp2);
4783
case NEON_3R_VADD_VSUB:
4784
if (!u) { /* VADD */
4785
gen_neon_add(size, tmp, tmp2);
4788
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4789
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4790
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4795
case NEON_3R_VTST_VCEQ:
4796
if (!u) { /* VTST */
4798
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4799
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4800
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4805
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4806
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4807
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4812
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4814
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4815
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4816
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4819
tcg_temp_free_i32(tmp2);
4820
tmp2 = neon_load_reg(rd, pass);
4822
gen_neon_rsb(size, tmp, tmp2);
4824
gen_neon_add(size, tmp, tmp2);
4828
if (u) { /* polynomial */
4829
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4830
} else { /* Integer */
4832
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4833
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4834
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4840
GEN_NEON_INTEGER_OP(pmax);
4843
GEN_NEON_INTEGER_OP(pmin);
4845
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
4846
if (!u) { /* VQDMULH */
4849
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
4852
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
4856
} else { /* VQRDMULH */
4859
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
4862
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
4870
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4871
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4872
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4876
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
4878
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4879
switch ((u << 2) | size) {
4882
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4885
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
4888
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
4893
tcg_temp_free_ptr(fpstatus);
4896
case NEON_3R_FLOAT_MULTIPLY:
4898
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4899
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
4901
tcg_temp_free_i32(tmp2);
4902
tmp2 = neon_load_reg(rd, pass);
4904
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4906
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
4909
tcg_temp_free_ptr(fpstatus);
4912
case NEON_3R_FLOAT_CMP:
4914
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4916
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
4919
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
4921
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
4924
tcg_temp_free_ptr(fpstatus);
4927
case NEON_3R_FLOAT_ACMP:
4929
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4931
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
4933
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
4935
tcg_temp_free_ptr(fpstatus);
4938
case NEON_3R_FLOAT_MINMAX:
4940
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4942
gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
4944
gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
4946
tcg_temp_free_ptr(fpstatus);
4949
case NEON_3R_VRECPS_VRSQRTS:
4951
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4953
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4957
/* VFMA, VFMS: fused multiply-add */
4958
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4959
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
4962
gen_helper_vfp_negs(tmp, tmp);
4964
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
4965
tcg_temp_free_i32(tmp3);
4966
tcg_temp_free_ptr(fpstatus);
4972
tcg_temp_free_i32(tmp2);
4974
/* Save the result. For elementwise operations we can put it
4975
straight into the destination register. For pairwise operations
4976
we have to be careful to avoid clobbering the source operands. */
4977
if (pairwise && rd == rm) {
4978
neon_store_scratch(pass, tmp);
4980
neon_store_reg(rd, pass, tmp);
4984
if (pairwise && rd == rm) {
4985
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4986
tmp = neon_load_scratch(pass);
4987
neon_store_reg(rd, pass, tmp);
4990
/* End of 3 register same size operations. */
4991
} else if (insn & (1 << 4)) {
4992
if ((insn & 0x00380080) != 0) {
4993
/* Two registers and shift. */
4994
op = (insn >> 8) & 0xf;
4995
if (insn & (1 << 7)) {
5003
while ((insn & (1 << (size + 19))) == 0)
5006
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5007
/* To avoid excessive duplication of ops we implement shift
5008
by immediate using the variable shift operations. */
5010
/* Shift by immediate:
5011
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5012
if (q && ((rd | rm) & 1)) {
5015
if (!u && (op == 4 || op == 6)) {
5018
/* Right shifts are encoded as N - shift, where N is the
5019
element size in bits. */
5021
shift = shift - (1 << (size + 3));
5029
imm = (uint8_t) shift;
5034
imm = (uint16_t) shift;
5045
for (pass = 0; pass < count; pass++) {
5047
neon_load_reg64(cpu_V0, rm + pass);
5048
tcg_gen_movi_i64(cpu_V1, imm);
5053
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5055
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5060
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5062
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5065
case 5: /* VSHL, VSLI */
5066
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5068
case 6: /* VQSHLU */
5069
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5074
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5077
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5082
if (op == 1 || op == 3) {
5084
neon_load_reg64(cpu_V1, rd + pass);
5085
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5086
} else if (op == 4 || (op == 5 && u)) {
5088
neon_load_reg64(cpu_V1, rd + pass);
5090
if (shift < -63 || shift > 63) {
5094
mask = 0xffffffffffffffffull >> -shift;
5096
mask = 0xffffffffffffffffull << shift;
5099
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5100
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5102
neon_store_reg64(cpu_V0, rd + pass);
5103
} else { /* size < 3 */
5104
/* Operands in T0 and T1. */
5105
tmp = neon_load_reg(rm, pass);
5106
tmp2 = tcg_temp_new_i32();
5107
tcg_gen_movi_i32(tmp2, imm);
5111
GEN_NEON_INTEGER_OP(shl);
5115
GEN_NEON_INTEGER_OP(rshl);
5118
case 5: /* VSHL, VSLI */
5120
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5121
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5122
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5126
case 6: /* VQSHLU */
5129
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5133
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5137
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5145
GEN_NEON_INTEGER_OP_ENV(qshl);
5148
tcg_temp_free_i32(tmp2);
5150
if (op == 1 || op == 3) {
5152
tmp2 = neon_load_reg(rd, pass);
5153
gen_neon_add(size, tmp, tmp2);
5154
tcg_temp_free_i32(tmp2);
5155
} else if (op == 4 || (op == 5 && u)) {
5160
mask = 0xff >> -shift;
5162
mask = (uint8_t)(0xff << shift);
5168
mask = 0xffff >> -shift;
5170
mask = (uint16_t)(0xffff << shift);
5174
if (shift < -31 || shift > 31) {
5178
mask = 0xffffffffu >> -shift;
5180
mask = 0xffffffffu << shift;
5186
tmp2 = neon_load_reg(rd, pass);
5187
tcg_gen_andi_i32(tmp, tmp, mask);
5188
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5189
tcg_gen_or_i32(tmp, tmp, tmp2);
5190
tcg_temp_free_i32(tmp2);
5192
neon_store_reg(rd, pass, tmp);
5195
} else if (op < 10) {
5196
/* Shift by immediate and narrow:
5197
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5198
int input_unsigned = (op == 8) ? !u : u;
5202
shift = shift - (1 << (size + 3));
5205
tmp64 = tcg_const_i64(shift);
5206
neon_load_reg64(cpu_V0, rm);
5207
neon_load_reg64(cpu_V1, rm + 1);
5208
for (pass = 0; pass < 2; pass++) {
5216
if (input_unsigned) {
5217
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5219
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5222
if (input_unsigned) {
5223
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5225
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5228
tmp = tcg_temp_new_i32();
5229
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5230
neon_store_reg(rd, pass, tmp);
5232
tcg_temp_free_i64(tmp64);
5235
imm = (uint16_t)shift;
5239
imm = (uint32_t)shift;
5241
tmp2 = tcg_const_i32(imm);
5242
tmp4 = neon_load_reg(rm + 1, 0);
5243
tmp5 = neon_load_reg(rm + 1, 1);
5244
for (pass = 0; pass < 2; pass++) {
5246
tmp = neon_load_reg(rm, 0);
5250
gen_neon_shift_narrow(size, tmp, tmp2, q,
5253
tmp3 = neon_load_reg(rm, 1);
5257
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5259
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5260
tcg_temp_free_i32(tmp);
5261
tcg_temp_free_i32(tmp3);
5262
tmp = tcg_temp_new_i32();
5263
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5264
neon_store_reg(rd, pass, tmp);
5266
tcg_temp_free_i32(tmp2);
5268
} else if (op == 10) {
5270
if (q || (rd & 1)) {
5273
tmp = neon_load_reg(rm, 0);
5274
tmp2 = neon_load_reg(rm, 1);
5275
for (pass = 0; pass < 2; pass++) {
5279
gen_neon_widen(cpu_V0, tmp, size, u);
5282
/* The shift is less than the width of the source
5283
type, so we can just shift the whole register. */
5284
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5285
/* Widen the result of shift: we need to clear
5286
* the potential overflow bits resulting from
5287
* left bits of the narrow input appearing as
5288
* right bits of left the neighbour narrow
5290
if (size < 2 || !u) {
5293
imm = (0xffu >> (8 - shift));
5295
} else if (size == 1) {
5296
imm = 0xffff >> (16 - shift);
5299
imm = 0xffffffff >> (32 - shift);
5302
imm64 = imm | (((uint64_t)imm) << 32);
5306
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5309
neon_store_reg64(cpu_V0, rd + pass);
5311
} else if (op >= 14) {
5312
/* VCVT fixed-point. */
5313
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5316
/* We have already masked out the must-be-1 top bit of imm6,
5317
* hence this 32-shift where the ARM ARM has 64-imm6.
5320
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5321
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5324
gen_vfp_ulto(0, shift, 1);
5326
gen_vfp_slto(0, shift, 1);
5329
gen_vfp_toul(0, shift, 1);
5331
gen_vfp_tosl(0, shift, 1);
5333
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5338
} else { /* (insn & 0x00380080) == 0 */
5340
if (q && (rd & 1)) {
5344
op = (insn >> 8) & 0xf;
5345
/* One register and immediate. */
5346
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5347
invert = (insn & (1 << 5)) != 0;
5348
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5349
* We choose to not special-case this and will behave as if a
5350
* valid constant encoding of 0 had been given.
5369
imm = (imm << 8) | (imm << 24);
5372
imm = (imm << 8) | 0xff;
5375
imm = (imm << 16) | 0xffff;
5378
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5386
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5387
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5393
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5394
if (op & 1 && op < 12) {
5395
tmp = neon_load_reg(rd, pass);
5397
/* The immediate value has already been inverted, so
5399
tcg_gen_andi_i32(tmp, tmp, imm);
5401
tcg_gen_ori_i32(tmp, tmp, imm);
5405
tmp = tcg_temp_new_i32();
5406
if (op == 14 && invert) {
5410
for (n = 0; n < 4; n++) {
5411
if (imm & (1 << (n + (pass & 1) * 4)))
5412
val |= 0xff << (n * 8);
5414
tcg_gen_movi_i32(tmp, val);
5416
tcg_gen_movi_i32(tmp, imm);
5419
neon_store_reg(rd, pass, tmp);
5422
} else { /* (insn & 0x00800010 == 0x00800000) */
5424
op = (insn >> 8) & 0xf;
5425
if ((insn & (1 << 6)) == 0) {
5426
/* Three registers of different lengths. */
5430
/* undefreq: bit 0 : UNDEF if size != 0
5431
* bit 1 : UNDEF if size == 0
5432
* bit 2 : UNDEF if U == 1
5433
* Note that [1:0] set implies 'always UNDEF'
5436
/* prewiden, src1_wide, src2_wide, undefreq */
5437
static const int neon_3reg_wide[16][4] = {
5438
{1, 0, 0, 0}, /* VADDL */
5439
{1, 1, 0, 0}, /* VADDW */
5440
{1, 0, 0, 0}, /* VSUBL */
5441
{1, 1, 0, 0}, /* VSUBW */
5442
{0, 1, 1, 0}, /* VADDHN */
5443
{0, 0, 0, 0}, /* VABAL */
5444
{0, 1, 1, 0}, /* VSUBHN */
5445
{0, 0, 0, 0}, /* VABDL */
5446
{0, 0, 0, 0}, /* VMLAL */
5447
{0, 0, 0, 6}, /* VQDMLAL */
5448
{0, 0, 0, 0}, /* VMLSL */
5449
{0, 0, 0, 6}, /* VQDMLSL */
5450
{0, 0, 0, 0}, /* Integer VMULL */
5451
{0, 0, 0, 2}, /* VQDMULL */
5452
{0, 0, 0, 5}, /* Polynomial VMULL */
5453
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5456
prewiden = neon_3reg_wide[op][0];
5457
src1_wide = neon_3reg_wide[op][1];
5458
src2_wide = neon_3reg_wide[op][2];
5459
undefreq = neon_3reg_wide[op][3];
5461
if (((undefreq & 1) && (size != 0)) ||
5462
((undefreq & 2) && (size == 0)) ||
5463
((undefreq & 4) && u)) {
5466
if ((src1_wide && (rn & 1)) ||
5467
(src2_wide && (rm & 1)) ||
5468
(!src2_wide && (rd & 1))) {
5472
/* Avoid overlapping operands. Wide source operands are
5473
always aligned so will never overlap with wide
5474
destinations in problematic ways. */
5475
if (rd == rm && !src2_wide) {
5476
tmp = neon_load_reg(rm, 1);
5477
neon_store_scratch(2, tmp);
5478
} else if (rd == rn && !src1_wide) {
5479
tmp = neon_load_reg(rn, 1);
5480
neon_store_scratch(2, tmp);
5482
TCGV_UNUSED_I32(tmp3);
5483
for (pass = 0; pass < 2; pass++) {
5485
neon_load_reg64(cpu_V0, rn + pass);
5486
TCGV_UNUSED_I32(tmp);
5488
if (pass == 1 && rd == rn) {
5489
tmp = neon_load_scratch(2);
5491
tmp = neon_load_reg(rn, pass);
5494
gen_neon_widen(cpu_V0, tmp, size, u);
5498
neon_load_reg64(cpu_V1, rm + pass);
5499
TCGV_UNUSED_I32(tmp2);
5501
if (pass == 1 && rd == rm) {
5502
tmp2 = neon_load_scratch(2);
5504
tmp2 = neon_load_reg(rm, pass);
5507
gen_neon_widen(cpu_V1, tmp2, size, u);
5511
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5512
gen_neon_addl(size);
5514
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5515
gen_neon_subl(size);
5517
case 5: case 7: /* VABAL, VABDL */
5518
switch ((size << 1) | u) {
5520
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5523
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5526
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5529
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5532
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5535
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5539
tcg_temp_free_i32(tmp2);
5540
tcg_temp_free_i32(tmp);
5542
case 8: case 9: case 10: case 11: case 12: case 13:
5543
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5544
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5546
case 14: /* Polynomial VMULL */
5547
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5548
tcg_temp_free_i32(tmp2);
5549
tcg_temp_free_i32(tmp);
5551
default: /* 15 is RESERVED: caught earlier */
5556
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5557
neon_store_reg64(cpu_V0, rd + pass);
5558
} else if (op == 5 || (op >= 8 && op <= 11)) {
5560
neon_load_reg64(cpu_V1, rd + pass);
5562
case 10: /* VMLSL */
5563
gen_neon_negl(cpu_V0, size);
5565
case 5: case 8: /* VABAL, VMLAL */
5566
gen_neon_addl(size);
5568
case 9: case 11: /* VQDMLAL, VQDMLSL */
5569
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5571
gen_neon_negl(cpu_V0, size);
5573
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5578
neon_store_reg64(cpu_V0, rd + pass);
5579
} else if (op == 4 || op == 6) {
5580
/* Narrowing operation. */
5581
tmp = tcg_temp_new_i32();
5585
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5588
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5591
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5592
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5599
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5602
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5605
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5606
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5607
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5615
neon_store_reg(rd, 0, tmp3);
5616
neon_store_reg(rd, 1, tmp);
5619
/* Write back the result. */
5620
neon_store_reg64(cpu_V0, rd + pass);
5624
/* Two registers and a scalar. NB that for ops of this form
5625
* the ARM ARM labels bit 24 as Q, but it is in our variable
5632
case 1: /* Float VMLA scalar */
5633
case 5: /* Floating point VMLS scalar */
5634
case 9: /* Floating point VMUL scalar */
5639
case 0: /* Integer VMLA scalar */
5640
case 4: /* Integer VMLS scalar */
5641
case 8: /* Integer VMUL scalar */
5642
case 12: /* VQDMULH scalar */
5643
case 13: /* VQRDMULH scalar */
5644
if (u && ((rd | rn) & 1)) {
5647
tmp = neon_get_scalar(size, rm);
5648
neon_store_scratch(0, tmp);
5649
for (pass = 0; pass < (u ? 4 : 2); pass++) {
5650
tmp = neon_load_scratch(0);
5651
tmp2 = neon_load_reg(rn, pass);
5654
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5656
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5658
} else if (op == 13) {
5660
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5662
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5664
} else if (op & 1) {
5665
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5666
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5667
tcg_temp_free_ptr(fpstatus);
5670
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5671
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5672
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5676
tcg_temp_free_i32(tmp2);
5679
tmp2 = neon_load_reg(rd, pass);
5682
gen_neon_add(size, tmp, tmp2);
5686
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5687
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5688
tcg_temp_free_ptr(fpstatus);
5692
gen_neon_rsb(size, tmp, tmp2);
5696
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5697
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5698
tcg_temp_free_ptr(fpstatus);
5704
tcg_temp_free_i32(tmp2);
5706
neon_store_reg(rd, pass, tmp);
5709
case 3: /* VQDMLAL scalar */
5710
case 7: /* VQDMLSL scalar */
5711
case 11: /* VQDMULL scalar */
5716
case 2: /* VMLAL sclar */
5717
case 6: /* VMLSL scalar */
5718
case 10: /* VMULL scalar */
5722
tmp2 = neon_get_scalar(size, rm);
5723
/* We need a copy of tmp2 because gen_neon_mull
5724
* deletes it during pass 0. */
5725
tmp4 = tcg_temp_new_i32();
5726
tcg_gen_mov_i32(tmp4, tmp2);
5727
tmp3 = neon_load_reg(rn, 1);
5729
for (pass = 0; pass < 2; pass++) {
5731
tmp = neon_load_reg(rn, 0);
5736
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5738
neon_load_reg64(cpu_V1, rd + pass);
5742
gen_neon_negl(cpu_V0, size);
5745
gen_neon_addl(size);
5748
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5750
gen_neon_negl(cpu_V0, size);
5752
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5758
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5763
neon_store_reg64(cpu_V0, rd + pass);
5768
default: /* 14 and 15 are RESERVED */
5772
} else { /* size == 3 */
5775
imm = (insn >> 8) & 0xf;
5780
if (q && ((rd | rn | rm) & 1)) {
5785
neon_load_reg64(cpu_V0, rn);
5787
neon_load_reg64(cpu_V1, rn + 1);
5789
} else if (imm == 8) {
5790
neon_load_reg64(cpu_V0, rn + 1);
5792
neon_load_reg64(cpu_V1, rm);
5795
tmp64 = tcg_temp_new_i64();
5797
neon_load_reg64(cpu_V0, rn);
5798
neon_load_reg64(tmp64, rn + 1);
5800
neon_load_reg64(cpu_V0, rn + 1);
5801
neon_load_reg64(tmp64, rm);
5803
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5804
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5805
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5807
neon_load_reg64(cpu_V1, rm);
5809
neon_load_reg64(cpu_V1, rm + 1);
5812
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5813
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5814
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5815
tcg_temp_free_i64(tmp64);
5818
neon_load_reg64(cpu_V0, rn);
5819
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5820
neon_load_reg64(cpu_V1, rm);
5821
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5822
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5824
neon_store_reg64(cpu_V0, rd);
5826
neon_store_reg64(cpu_V1, rd + 1);
5828
} else if ((insn & (1 << 11)) == 0) {
5829
/* Two register misc. */
5830
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5831
size = (insn >> 18) & 3;
5832
/* UNDEF for unknown op values and bad op-size combinations */
5833
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5836
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5837
q && ((rm | rd) & 1)) {
5841
case NEON_2RM_VREV64:
5842
for (pass = 0; pass < (q ? 2 : 1); pass++) {
5843
tmp = neon_load_reg(rm, pass * 2);
5844
tmp2 = neon_load_reg(rm, pass * 2 + 1);
5846
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5847
case 1: gen_swap_half(tmp); break;
5848
case 2: /* no-op */ break;
5851
neon_store_reg(rd, pass * 2 + 1, tmp);
5853
neon_store_reg(rd, pass * 2, tmp2);
5856
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5857
case 1: gen_swap_half(tmp2); break;
5860
neon_store_reg(rd, pass * 2, tmp2);
5864
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5865
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5866
for (pass = 0; pass < q + 1; pass++) {
5867
tmp = neon_load_reg(rm, pass * 2);
5868
gen_neon_widen(cpu_V0, tmp, size, op & 1);
5869
tmp = neon_load_reg(rm, pass * 2 + 1);
5870
gen_neon_widen(cpu_V1, tmp, size, op & 1);
5872
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5873
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5874
case 2: tcg_gen_add_i64(CPU_V001); break;
5877
if (op >= NEON_2RM_VPADAL) {
5879
neon_load_reg64(cpu_V1, rd + pass);
5880
gen_neon_addl(size);
5882
neon_store_reg64(cpu_V0, rd + pass);
5888
for (n = 0; n < (q ? 4 : 2); n += 2) {
5889
tmp = neon_load_reg(rm, n);
5890
tmp2 = neon_load_reg(rd, n + 1);
5891
neon_store_reg(rm, n, tmp2);
5892
neon_store_reg(rd, n + 1, tmp);
5899
if (gen_neon_unzip(rd, rm, size, q)) {
5904
if (gen_neon_zip(rd, rm, size, q)) {
5908
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5909
/* also VQMOVUN; op field and mnemonics don't line up */
5913
TCGV_UNUSED_I32(tmp2);
5914
for (pass = 0; pass < 2; pass++) {
5915
neon_load_reg64(cpu_V0, rm + pass);
5916
tmp = tcg_temp_new_i32();
5917
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5922
neon_store_reg(rd, 0, tmp2);
5923
neon_store_reg(rd, 1, tmp);
5927
case NEON_2RM_VSHLL:
5928
if (q || (rd & 1)) {
5931
tmp = neon_load_reg(rm, 0);
5932
tmp2 = neon_load_reg(rm, 1);
5933
for (pass = 0; pass < 2; pass++) {
5936
gen_neon_widen(cpu_V0, tmp, size, 1);
5937
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5938
neon_store_reg64(cpu_V0, rd + pass);
5941
case NEON_2RM_VCVT_F16_F32:
5942
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5946
tmp = tcg_temp_new_i32();
5947
tmp2 = tcg_temp_new_i32();
5948
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5949
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5950
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5951
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5952
tcg_gen_shli_i32(tmp2, tmp2, 16);
5953
tcg_gen_or_i32(tmp2, tmp2, tmp);
5954
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5955
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5956
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5957
neon_store_reg(rd, 0, tmp2);
5958
tmp2 = tcg_temp_new_i32();
5959
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5960
tcg_gen_shli_i32(tmp2, tmp2, 16);
5961
tcg_gen_or_i32(tmp2, tmp2, tmp);
5962
neon_store_reg(rd, 1, tmp2);
5963
tcg_temp_free_i32(tmp);
5965
case NEON_2RM_VCVT_F32_F16:
5966
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5970
tmp3 = tcg_temp_new_i32();
5971
tmp = neon_load_reg(rm, 0);
5972
tmp2 = neon_load_reg(rm, 1);
5973
tcg_gen_ext16u_i32(tmp3, tmp);
5974
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5975
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5976
tcg_gen_shri_i32(tmp3, tmp, 16);
5977
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5978
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5979
tcg_temp_free_i32(tmp);
5980
tcg_gen_ext16u_i32(tmp3, tmp2);
5981
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5982
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5983
tcg_gen_shri_i32(tmp3, tmp2, 16);
5984
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5985
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5986
tcg_temp_free_i32(tmp2);
5987
tcg_temp_free_i32(tmp3);
5991
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5992
if (neon_2rm_is_float_op(op)) {
5993
tcg_gen_ld_f32(cpu_F0s, cpu_env,
5994
neon_reg_offset(rm, pass));
5995
TCGV_UNUSED_I32(tmp);
5997
tmp = neon_load_reg(rm, pass);
6000
case NEON_2RM_VREV32:
6002
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6003
case 1: gen_swap_half(tmp); break;
6007
case NEON_2RM_VREV16:
6012
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6013
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6014
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6020
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6021
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6022
case 2: gen_helper_clz(tmp, tmp); break;
6027
gen_helper_neon_cnt_u8(tmp, tmp);
6030
tcg_gen_not_i32(tmp, tmp);
6032
case NEON_2RM_VQABS:
6035
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6038
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6041
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6046
case NEON_2RM_VQNEG:
6049
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6052
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6055
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6060
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6061
tmp2 = tcg_const_i32(0);
6063
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6064
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6065
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6068
tcg_temp_free_i32(tmp2);
6069
if (op == NEON_2RM_VCLE0) {
6070
tcg_gen_not_i32(tmp, tmp);
6073
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6074
tmp2 = tcg_const_i32(0);
6076
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6077
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6078
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6081
tcg_temp_free_i32(tmp2);
6082
if (op == NEON_2RM_VCLT0) {
6083
tcg_gen_not_i32(tmp, tmp);
6086
case NEON_2RM_VCEQ0:
6087
tmp2 = tcg_const_i32(0);
6089
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6090
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6091
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6094
tcg_temp_free_i32(tmp2);
6098
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6099
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6100
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6105
tmp2 = tcg_const_i32(0);
6106
gen_neon_rsb(size, tmp, tmp2);
6107
tcg_temp_free_i32(tmp2);
6109
case NEON_2RM_VCGT0_F:
6111
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6112
tmp2 = tcg_const_i32(0);
6113
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6114
tcg_temp_free_i32(tmp2);
6115
tcg_temp_free_ptr(fpstatus);
6118
case NEON_2RM_VCGE0_F:
6120
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6121
tmp2 = tcg_const_i32(0);
6122
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6123
tcg_temp_free_i32(tmp2);
6124
tcg_temp_free_ptr(fpstatus);
6127
case NEON_2RM_VCEQ0_F:
6129
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6130
tmp2 = tcg_const_i32(0);
6131
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6132
tcg_temp_free_i32(tmp2);
6133
tcg_temp_free_ptr(fpstatus);
6136
case NEON_2RM_VCLE0_F:
6138
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6139
tmp2 = tcg_const_i32(0);
6140
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6141
tcg_temp_free_i32(tmp2);
6142
tcg_temp_free_ptr(fpstatus);
6145
case NEON_2RM_VCLT0_F:
6147
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6148
tmp2 = tcg_const_i32(0);
6149
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6150
tcg_temp_free_i32(tmp2);
6151
tcg_temp_free_ptr(fpstatus);
6154
case NEON_2RM_VABS_F:
6157
case NEON_2RM_VNEG_F:
6161
tmp2 = neon_load_reg(rd, pass);
6162
neon_store_reg(rm, pass, tmp2);
6165
tmp2 = neon_load_reg(rd, pass);
6167
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6168
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6171
neon_store_reg(rm, pass, tmp2);
6173
case NEON_2RM_VRECPE:
6174
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6176
case NEON_2RM_VRSQRTE:
6177
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6179
case NEON_2RM_VRECPE_F:
6180
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6182
case NEON_2RM_VRSQRTE_F:
6183
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6185
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6188
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6191
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6192
gen_vfp_tosiz(0, 1);
6194
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6195
gen_vfp_touiz(0, 1);
6198
/* Reserved op values were caught by the
6199
* neon_2rm_sizes[] check earlier.
6203
if (neon_2rm_is_float_op(op)) {
6204
tcg_gen_st_f32(cpu_F0s, cpu_env,
6205
neon_reg_offset(rd, pass));
6207
neon_store_reg(rd, pass, tmp);
6212
} else if ((insn & (1 << 10)) == 0) {
6214
int n = ((insn >> 8) & 3) + 1;
6215
if ((rn + n) > 32) {
6216
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6217
* helper function running off the end of the register file.
6222
if (insn & (1 << 6)) {
6223
tmp = neon_load_reg(rd, 0);
6225
tmp = tcg_temp_new_i32();
6226
tcg_gen_movi_i32(tmp, 0);
6228
tmp2 = neon_load_reg(rm, 0);
6229
tmp4 = tcg_const_i32(rn);
6230
tmp5 = tcg_const_i32(n);
6231
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6232
tcg_temp_free_i32(tmp);
6233
if (insn & (1 << 6)) {
6234
tmp = neon_load_reg(rd, 1);
6236
tmp = tcg_temp_new_i32();
6237
tcg_gen_movi_i32(tmp, 0);
6239
tmp3 = neon_load_reg(rm, 1);
6240
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6241
tcg_temp_free_i32(tmp5);
6242
tcg_temp_free_i32(tmp4);
6243
neon_store_reg(rd, 0, tmp2);
6244
neon_store_reg(rd, 1, tmp3);
6245
tcg_temp_free_i32(tmp);
6246
} else if ((insn & 0x380) == 0) {
6248
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6251
if (insn & (1 << 19)) {
6252
tmp = neon_load_reg(rm, 1);
6254
tmp = neon_load_reg(rm, 0);
6256
if (insn & (1 << 16)) {
6257
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6258
} else if (insn & (1 << 17)) {
6259
if ((insn >> 18) & 1)
6260
gen_neon_dup_high16(tmp);
6262
gen_neon_dup_low16(tmp);
6264
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6265
tmp2 = tcg_temp_new_i32();
6266
tcg_gen_mov_i32(tmp2, tmp);
6267
neon_store_reg(rd, pass, tmp2);
6269
tcg_temp_free_i32(tmp);
6278
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6280
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6281
const ARMCPRegInfo *ri;
6282
ARMCPU *cpu = arm_env_get_cpu(env);
6284
cpnum = (insn >> 8) & 0xf;
6285
if (arm_feature(env, ARM_FEATURE_XSCALE)
6286
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6289
/* First check for coprocessor space used for actual instructions */
6293
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6294
return disas_iwmmxt_insn(env, s, insn);
6295
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6296
return disas_dsp_insn(env, s, insn);
6301
return disas_vfp_insn (env, s, insn);
6306
/* Otherwise treat as a generic register access */
6307
is64 = (insn & (1 << 25)) == 0;
6308
if (!is64 && ((insn & (1 << 4)) == 0)) {
6316
opc1 = (insn >> 4) & 0xf;
6318
rt2 = (insn >> 16) & 0xf;
6320
crn = (insn >> 16) & 0xf;
6321
opc1 = (insn >> 21) & 7;
6322
opc2 = (insn >> 5) & 7;
6325
isread = (insn >> 20) & 1;
6326
rt = (insn >> 12) & 0xf;
6328
ri = get_arm_cp_reginfo(cpu,
6329
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6331
/* Check access permissions */
6332
if (!cp_access_ok(env, ri, isread)) {
6336
/* Handle special cases first */
6337
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6344
gen_set_pc_im(s, s->pc);
6345
s->is_jmp = DISAS_WFI;
6351
if (use_icount && (ri->type & ARM_CP_IO)) {
6360
if (ri->type & ARM_CP_CONST) {
6361
tmp64 = tcg_const_i64(ri->resetvalue);
6362
} else if (ri->readfn) {
6364
gen_set_pc_im(s, s->pc);
6365
tmp64 = tcg_temp_new_i64();
6366
tmpptr = tcg_const_ptr(ri);
6367
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6368
tcg_temp_free_ptr(tmpptr);
6370
tmp64 = tcg_temp_new_i64();
6371
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6373
tmp = tcg_temp_new_i32();
6374
tcg_gen_trunc_i64_i32(tmp, tmp64);
6375
store_reg(s, rt, tmp);
6376
tcg_gen_shri_i64(tmp64, tmp64, 32);
6377
tmp = tcg_temp_new_i32();
6378
tcg_gen_trunc_i64_i32(tmp, tmp64);
6379
tcg_temp_free_i64(tmp64);
6380
store_reg(s, rt2, tmp);
6383
if (ri->type & ARM_CP_CONST) {
6384
tmp = tcg_const_i32(ri->resetvalue);
6385
} else if (ri->readfn) {
6387
gen_set_pc_im(s, s->pc);
6388
tmp = tcg_temp_new_i32();
6389
tmpptr = tcg_const_ptr(ri);
6390
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6391
tcg_temp_free_ptr(tmpptr);
6393
tmp = load_cpu_offset(ri->fieldoffset);
6396
/* Destination register of r15 for 32 bit loads sets
6397
* the condition codes from the high 4 bits of the value
6400
tcg_temp_free_i32(tmp);
6402
store_reg(s, rt, tmp);
6407
if (ri->type & ARM_CP_CONST) {
6408
/* If not forbidden by access permissions, treat as WI */
6413
TCGv_i32 tmplo, tmphi;
6414
TCGv_i64 tmp64 = tcg_temp_new_i64();
6415
tmplo = load_reg(s, rt);
6416
tmphi = load_reg(s, rt2);
6417
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6418
tcg_temp_free_i32(tmplo);
6419
tcg_temp_free_i32(tmphi);
6421
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6422
gen_set_pc_im(s, s->pc);
6423
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6424
tcg_temp_free_ptr(tmpptr);
6426
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6428
tcg_temp_free_i64(tmp64);
6433
gen_set_pc_im(s, s->pc);
6434
tmp = load_reg(s, rt);
6435
tmpptr = tcg_const_ptr(ri);
6436
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6437
tcg_temp_free_ptr(tmpptr);
6438
tcg_temp_free_i32(tmp);
6440
TCGv_i32 tmp = load_reg(s, rt);
6441
store_cpu_offset(tmp, ri->fieldoffset);
6446
if (use_icount && (ri->type & ARM_CP_IO)) {
6447
/* I/O operations must end the TB here (whether read or write) */
6450
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6451
/* We default to ending the TB on a coprocessor register write,
6452
* but allow this to be suppressed by the register definition
6453
* (usually only necessary to work around guest bugs).
6465
/* Store a 64-bit value to a register pair. Clobbers val. */
6466
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6469
tmp = tcg_temp_new_i32();
6470
tcg_gen_trunc_i64_i32(tmp, val);
6471
store_reg(s, rlow, tmp);
6472
tmp = tcg_temp_new_i32();
6473
tcg_gen_shri_i64(val, val, 32);
6474
tcg_gen_trunc_i64_i32(tmp, val);
6475
store_reg(s, rhigh, tmp);
6478
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6479
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6484
/* Load value and extend to 64 bits. */
6485
tmp = tcg_temp_new_i64();
6486
tmp2 = load_reg(s, rlow);
6487
tcg_gen_extu_i32_i64(tmp, tmp2);
6488
tcg_temp_free_i32(tmp2);
6489
tcg_gen_add_i64(val, val, tmp);
6490
tcg_temp_free_i64(tmp);
6493
/* load and add a 64-bit value from a register pair. */
6494
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6500
/* Load 64-bit value rd:rn. */
6501
tmpl = load_reg(s, rlow);
6502
tmph = load_reg(s, rhigh);
6503
tmp = tcg_temp_new_i64();
6504
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6505
tcg_temp_free_i32(tmpl);
6506
tcg_temp_free_i32(tmph);
6507
tcg_gen_add_i64(val, val, tmp);
6508
tcg_temp_free_i64(tmp);
6511
/* Set N and Z flags from hi|lo. */
6512
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6514
tcg_gen_mov_i32(cpu_NF, hi);
6515
tcg_gen_or_i32(cpu_ZF, lo, hi);
6518
/* Load/Store exclusive instructions are implemented by remembering
6519
the value/address loaded, and seeing if these are the same
6520
when the store is performed. This should be sufficient to implement
6521
the architecturally mandated semantics, and avoids having to monitor
6524
In system emulation mode only one CPU will be running at once, so
6525
this sequence is effectively atomic. In user emulation mode we
6526
throw an exception and handle the atomic operation elsewhere. */
6527
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6528
TCGv_i32 addr, int size)
6530
TCGv_i32 tmp = tcg_temp_new_i32();
6534
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6537
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6541
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6546
tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6547
store_reg(s, rt, tmp);
6549
TCGv_i32 tmp2 = tcg_temp_new_i32();
6550
tcg_gen_addi_i32(tmp2, addr, 4);
6551
tmp = tcg_temp_new_i32();
6552
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6553
tcg_temp_free_i32(tmp2);
6554
tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6555
store_reg(s, rt2, tmp);
6557
tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6560
static void gen_clrex(DisasContext *s)
6562
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6565
#ifdef CONFIG_USER_ONLY
6566
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6567
TCGv_i32 addr, int size)
6569
tcg_gen_mov_i32(cpu_exclusive_test, addr);
6570
tcg_gen_movi_i32(cpu_exclusive_info,
6571
size | (rd << 4) | (rt << 8) | (rt2 << 12));
6572
gen_exception_insn(s, 4, EXCP_STREX);
6575
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6576
TCGv_i32 addr, int size)
6582
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6588
fail_label = gen_new_label();
6589
done_label = gen_new_label();
6590
tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6591
tmp = tcg_temp_new_i32();
6594
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6597
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6601
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6606
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6607
tcg_temp_free_i32(tmp);
6609
TCGv_i32 tmp2 = tcg_temp_new_i32();
6610
tcg_gen_addi_i32(tmp2, addr, 4);
6611
tmp = tcg_temp_new_i32();
6612
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6613
tcg_temp_free_i32(tmp2);
6614
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6615
tcg_temp_free_i32(tmp);
6617
tmp = load_reg(s, rt);
6620
gen_aa32_st8(tmp, addr, IS_USER(s));
6623
gen_aa32_st16(tmp, addr, IS_USER(s));
6627
gen_aa32_st32(tmp, addr, IS_USER(s));
6632
tcg_temp_free_i32(tmp);
6634
tcg_gen_addi_i32(addr, addr, 4);
6635
tmp = load_reg(s, rt2);
6636
gen_aa32_st32(tmp, addr, IS_USER(s));
6637
tcg_temp_free_i32(tmp);
6639
tcg_gen_movi_i32(cpu_R[rd], 0);
6640
tcg_gen_br(done_label);
6641
gen_set_label(fail_label);
6642
tcg_gen_movi_i32(cpu_R[rd], 1);
6643
gen_set_label(done_label);
6644
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6651
* @mode: mode field from insn (which stack to store to)
6652
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6653
* @writeback: true if writeback bit set
6655
* Generate code for the SRS (Store Return State) insn.
6657
static void gen_srs(DisasContext *s,
6658
uint32_t mode, uint32_t amode, bool writeback)
6661
TCGv_i32 addr = tcg_temp_new_i32();
6662
TCGv_i32 tmp = tcg_const_i32(mode);
6663
gen_helper_get_r13_banked(addr, cpu_env, tmp);
6664
tcg_temp_free_i32(tmp);
6681
tcg_gen_addi_i32(addr, addr, offset);
6682
tmp = load_reg(s, 14);
6683
gen_aa32_st32(tmp, addr, 0);
6684
tcg_temp_free_i32(tmp);
6685
tmp = load_cpu_field(spsr);
6686
tcg_gen_addi_i32(addr, addr, 4);
6687
gen_aa32_st32(tmp, addr, 0);
6688
tcg_temp_free_i32(tmp);
6706
tcg_gen_addi_i32(addr, addr, offset);
6707
tmp = tcg_const_i32(mode);
6708
gen_helper_set_r13_banked(cpu_env, tmp, addr);
6709
tcg_temp_free_i32(tmp);
6711
tcg_temp_free_i32(addr);
6714
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6716
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6723
insn = arm_ldl_code(env, s->pc, s->bswap_code);
6726
/* M variants do not implement ARM mode. */
6731
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6732
* choose to UNDEF. In ARMv5 and above the space is used
6733
* for miscellaneous unconditional instructions.
6737
/* Unconditional instructions. */
6738
if (((insn >> 25) & 7) == 1) {
6739
/* NEON Data processing. */
6740
if (!arm_feature(env, ARM_FEATURE_NEON))
6743
if (disas_neon_data_insn(env, s, insn))
6747
if ((insn & 0x0f100000) == 0x04000000) {
6748
/* NEON load/store. */
6749
if (!arm_feature(env, ARM_FEATURE_NEON))
6752
if (disas_neon_ls_insn(env, s, insn))
6756
if (((insn & 0x0f30f000) == 0x0510f000) ||
6757
((insn & 0x0f30f010) == 0x0710f000)) {
6758
if ((insn & (1 << 22)) == 0) {
6760
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6764
/* Otherwise PLD; v5TE+ */
6768
if (((insn & 0x0f70f000) == 0x0450f000) ||
6769
((insn & 0x0f70f010) == 0x0650f000)) {
6771
return; /* PLI; V7 */
6773
if (((insn & 0x0f700000) == 0x04100000) ||
6774
((insn & 0x0f700010) == 0x06100000)) {
6775
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6778
return; /* v7MP: Unallocated memory hint: must NOP */
6781
if ((insn & 0x0ffffdff) == 0x01010000) {
6784
if (((insn >> 9) & 1) != s->bswap_code) {
6785
/* Dynamic endianness switching not implemented. */
6786
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
6790
} else if ((insn & 0x0fffff00) == 0x057ff000) {
6791
switch ((insn >> 4) & 0xf) {
6800
/* We don't emulate caches so these are a no-op. */
6805
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6811
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
6813
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6819
rn = (insn >> 16) & 0xf;
6820
addr = load_reg(s, rn);
6821
i = (insn >> 23) & 3;
6823
case 0: offset = -4; break; /* DA */
6824
case 1: offset = 0; break; /* IA */
6825
case 2: offset = -8; break; /* DB */
6826
case 3: offset = 4; break; /* IB */
6830
tcg_gen_addi_i32(addr, addr, offset);
6831
/* Load PC into tmp and CPSR into tmp2. */
6832
tmp = tcg_temp_new_i32();
6833
gen_aa32_ld32u(tmp, addr, 0);
6834
tcg_gen_addi_i32(addr, addr, 4);
6835
tmp2 = tcg_temp_new_i32();
6836
gen_aa32_ld32u(tmp2, addr, 0);
6837
if (insn & (1 << 21)) {
6838
/* Base writeback. */
6840
case 0: offset = -8; break;
6841
case 1: offset = 4; break;
6842
case 2: offset = -4; break;
6843
case 3: offset = 0; break;
6847
tcg_gen_addi_i32(addr, addr, offset);
6848
store_reg(s, rn, addr);
6850
tcg_temp_free_i32(addr);
6852
gen_rfe(s, tmp, tmp2);
6854
} else if ((insn & 0x0e000000) == 0x0a000000) {
6855
/* branch link and change to thumb (blx <offset>) */
6858
val = (uint32_t)s->pc;
6859
tmp = tcg_temp_new_i32();
6860
tcg_gen_movi_i32(tmp, val);
6861
store_reg(s, 14, tmp);
6862
/* Sign-extend the 24-bit offset */
6863
offset = (((int32_t)insn) << 8) >> 8;
6864
/* offset * 4 + bit24 * 2 + (thumb bit) */
6865
val += (offset << 2) | ((insn >> 23) & 2) | 1;
6866
/* pipeline offset */
6868
/* protected by ARCH(5); above, near the start of uncond block */
6871
} else if ((insn & 0x0e000f00) == 0x0c000100) {
6872
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6873
/* iWMMXt register transfer. */
6874
if (env->cp15.c15_cpar & (1 << 1))
6875
if (!disas_iwmmxt_insn(env, s, insn))
6878
} else if ((insn & 0x0fe00000) == 0x0c400000) {
6879
/* Coprocessor double register transfer. */
6881
} else if ((insn & 0x0f000010) == 0x0e000010) {
6882
/* Additional coprocessor register transfer. */
6883
} else if ((insn & 0x0ff10020) == 0x01000000) {
6886
/* cps (privileged) */
6890
if (insn & (1 << 19)) {
6891
if (insn & (1 << 8))
6893
if (insn & (1 << 7))
6895
if (insn & (1 << 6))
6897
if (insn & (1 << 18))
6900
if (insn & (1 << 17)) {
6902
val |= (insn & 0x1f);
6905
gen_set_psr_im(s, mask, 0, val);
6912
/* if not always execute, we generate a conditional jump to
6914
s->condlabel = gen_new_label();
6915
gen_test_cc(cond ^ 1, s->condlabel);
6918
if ((insn & 0x0f900000) == 0x03000000) {
6919
if ((insn & (1 << 21)) == 0) {
6921
rd = (insn >> 12) & 0xf;
6922
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6923
if ((insn & (1 << 22)) == 0) {
6925
tmp = tcg_temp_new_i32();
6926
tcg_gen_movi_i32(tmp, val);
6929
tmp = load_reg(s, rd);
6930
tcg_gen_ext16u_i32(tmp, tmp);
6931
tcg_gen_ori_i32(tmp, tmp, val << 16);
6933
store_reg(s, rd, tmp);
6935
if (((insn >> 12) & 0xf) != 0xf)
6937
if (((insn >> 16) & 0xf) == 0) {
6938
gen_nop_hint(s, insn & 0xff);
6940
/* CPSR = immediate */
6942
shift = ((insn >> 8) & 0xf) * 2;
6944
val = (val >> shift) | (val << (32 - shift));
6945
i = ((insn & (1 << 22)) != 0);
6946
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6950
} else if ((insn & 0x0f900000) == 0x01000000
6951
&& (insn & 0x00000090) != 0x00000090) {
6952
/* miscellaneous instructions */
6953
op1 = (insn >> 21) & 3;
6954
sh = (insn >> 4) & 0xf;
6957
case 0x0: /* move program status register */
6960
tmp = load_reg(s, rm);
6961
i = ((op1 & 2) != 0);
6962
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6966
rd = (insn >> 12) & 0xf;
6970
tmp = load_cpu_field(spsr);
6972
tmp = tcg_temp_new_i32();
6973
gen_helper_cpsr_read(tmp, cpu_env);
6975
store_reg(s, rd, tmp);
6980
/* branch/exchange thumb (bx). */
6982
tmp = load_reg(s, rm);
6984
} else if (op1 == 3) {
6987
rd = (insn >> 12) & 0xf;
6988
tmp = load_reg(s, rm);
6989
gen_helper_clz(tmp, tmp);
6990
store_reg(s, rd, tmp);
6998
/* Trivial implementation equivalent to bx. */
6999
tmp = load_reg(s, rm);
7010
/* branch link/exchange thumb (blx) */
7011
tmp = load_reg(s, rm);
7012
tmp2 = tcg_temp_new_i32();
7013
tcg_gen_movi_i32(tmp2, s->pc);
7014
store_reg(s, 14, tmp2);
7017
case 0x5: /* saturating add/subtract */
7019
rd = (insn >> 12) & 0xf;
7020
rn = (insn >> 16) & 0xf;
7021
tmp = load_reg(s, rm);
7022
tmp2 = load_reg(s, rn);
7024
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7026
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7028
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7029
tcg_temp_free_i32(tmp2);
7030
store_reg(s, rd, tmp);
7033
/* SMC instruction (op1 == 3)
7034
and undefined instructions (op1 == 0 || op1 == 2)
7041
gen_exception_insn(s, 4, EXCP_BKPT);
7043
case 0x8: /* signed multiply */
7048
rs = (insn >> 8) & 0xf;
7049
rn = (insn >> 12) & 0xf;
7050
rd = (insn >> 16) & 0xf;
7052
/* (32 * 16) >> 16 */
7053
tmp = load_reg(s, rm);
7054
tmp2 = load_reg(s, rs);
7056
tcg_gen_sari_i32(tmp2, tmp2, 16);
7059
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7060
tcg_gen_shri_i64(tmp64, tmp64, 16);
7061
tmp = tcg_temp_new_i32();
7062
tcg_gen_trunc_i64_i32(tmp, tmp64);
7063
tcg_temp_free_i64(tmp64);
7064
if ((sh & 2) == 0) {
7065
tmp2 = load_reg(s, rn);
7066
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7067
tcg_temp_free_i32(tmp2);
7069
store_reg(s, rd, tmp);
7072
tmp = load_reg(s, rm);
7073
tmp2 = load_reg(s, rs);
7074
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7075
tcg_temp_free_i32(tmp2);
7077
tmp64 = tcg_temp_new_i64();
7078
tcg_gen_ext_i32_i64(tmp64, tmp);
7079
tcg_temp_free_i32(tmp);
7080
gen_addq(s, tmp64, rn, rd);
7081
gen_storeq_reg(s, rn, rd, tmp64);
7082
tcg_temp_free_i64(tmp64);
7085
tmp2 = load_reg(s, rn);
7086
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7087
tcg_temp_free_i32(tmp2);
7089
store_reg(s, rd, tmp);
7096
} else if (((insn & 0x0e000000) == 0 &&
7097
(insn & 0x00000090) != 0x90) ||
7098
((insn & 0x0e000000) == (1 << 25))) {
7099
int set_cc, logic_cc, shiftop;
7101
op1 = (insn >> 21) & 0xf;
7102
set_cc = (insn >> 20) & 1;
7103
logic_cc = table_logic_cc[op1] & set_cc;
7105
/* data processing instruction */
7106
if (insn & (1 << 25)) {
7107
/* immediate operand */
7109
shift = ((insn >> 8) & 0xf) * 2;
7111
val = (val >> shift) | (val << (32 - shift));
7113
tmp2 = tcg_temp_new_i32();
7114
tcg_gen_movi_i32(tmp2, val);
7115
if (logic_cc && shift) {
7116
gen_set_CF_bit31(tmp2);
7121
tmp2 = load_reg(s, rm);
7122
shiftop = (insn >> 5) & 3;
7123
if (!(insn & (1 << 4))) {
7124
shift = (insn >> 7) & 0x1f;
7125
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7127
rs = (insn >> 8) & 0xf;
7128
tmp = load_reg(s, rs);
7129
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7132
if (op1 != 0x0f && op1 != 0x0d) {
7133
rn = (insn >> 16) & 0xf;
7134
tmp = load_reg(s, rn);
7136
TCGV_UNUSED_I32(tmp);
7138
rd = (insn >> 12) & 0xf;
7141
tcg_gen_and_i32(tmp, tmp, tmp2);
7145
store_reg_bx(env, s, rd, tmp);
7148
tcg_gen_xor_i32(tmp, tmp, tmp2);
7152
store_reg_bx(env, s, rd, tmp);
7155
if (set_cc && rd == 15) {
7156
/* SUBS r15, ... is used for exception return. */
7160
gen_sub_CC(tmp, tmp, tmp2);
7161
gen_exception_return(s, tmp);
7164
gen_sub_CC(tmp, tmp, tmp2);
7166
tcg_gen_sub_i32(tmp, tmp, tmp2);
7168
store_reg_bx(env, s, rd, tmp);
7173
gen_sub_CC(tmp, tmp2, tmp);
7175
tcg_gen_sub_i32(tmp, tmp2, tmp);
7177
store_reg_bx(env, s, rd, tmp);
7181
gen_add_CC(tmp, tmp, tmp2);
7183
tcg_gen_add_i32(tmp, tmp, tmp2);
7185
store_reg_bx(env, s, rd, tmp);
7189
gen_adc_CC(tmp, tmp, tmp2);
7191
gen_add_carry(tmp, tmp, tmp2);
7193
store_reg_bx(env, s, rd, tmp);
7197
gen_sbc_CC(tmp, tmp, tmp2);
7199
gen_sub_carry(tmp, tmp, tmp2);
7201
store_reg_bx(env, s, rd, tmp);
7205
gen_sbc_CC(tmp, tmp2, tmp);
7207
gen_sub_carry(tmp, tmp2, tmp);
7209
store_reg_bx(env, s, rd, tmp);
7213
tcg_gen_and_i32(tmp, tmp, tmp2);
7216
tcg_temp_free_i32(tmp);
7220
tcg_gen_xor_i32(tmp, tmp, tmp2);
7223
tcg_temp_free_i32(tmp);
7227
gen_sub_CC(tmp, tmp, tmp2);
7229
tcg_temp_free_i32(tmp);
7233
gen_add_CC(tmp, tmp, tmp2);
7235
tcg_temp_free_i32(tmp);
7238
tcg_gen_or_i32(tmp, tmp, tmp2);
7242
store_reg_bx(env, s, rd, tmp);
7245
if (logic_cc && rd == 15) {
7246
/* MOVS r15, ... is used for exception return. */
7250
gen_exception_return(s, tmp2);
7255
store_reg_bx(env, s, rd, tmp2);
7259
tcg_gen_andc_i32(tmp, tmp, tmp2);
7263
store_reg_bx(env, s, rd, tmp);
7267
tcg_gen_not_i32(tmp2, tmp2);
7271
store_reg_bx(env, s, rd, tmp2);
7274
if (op1 != 0x0f && op1 != 0x0d) {
7275
tcg_temp_free_i32(tmp2);
7278
/* other instructions */
7279
op1 = (insn >> 24) & 0xf;
7283
/* multiplies, extra load/stores */
7284
sh = (insn >> 5) & 3;
7287
rd = (insn >> 16) & 0xf;
7288
rn = (insn >> 12) & 0xf;
7289
rs = (insn >> 8) & 0xf;
7291
op1 = (insn >> 20) & 0xf;
7293
case 0: case 1: case 2: case 3: case 6:
7295
tmp = load_reg(s, rs);
7296
tmp2 = load_reg(s, rm);
7297
tcg_gen_mul_i32(tmp, tmp, tmp2);
7298
tcg_temp_free_i32(tmp2);
7299
if (insn & (1 << 22)) {
7300
/* Subtract (mls) */
7302
tmp2 = load_reg(s, rn);
7303
tcg_gen_sub_i32(tmp, tmp2, tmp);
7304
tcg_temp_free_i32(tmp2);
7305
} else if (insn & (1 << 21)) {
7307
tmp2 = load_reg(s, rn);
7308
tcg_gen_add_i32(tmp, tmp, tmp2);
7309
tcg_temp_free_i32(tmp2);
7311
if (insn & (1 << 20))
7313
store_reg(s, rd, tmp);
7316
/* 64 bit mul double accumulate (UMAAL) */
7318
tmp = load_reg(s, rs);
7319
tmp2 = load_reg(s, rm);
7320
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7321
gen_addq_lo(s, tmp64, rn);
7322
gen_addq_lo(s, tmp64, rd);
7323
gen_storeq_reg(s, rn, rd, tmp64);
7324
tcg_temp_free_i64(tmp64);
7326
case 8: case 9: case 10: case 11:
7327
case 12: case 13: case 14: case 15:
7328
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7329
tmp = load_reg(s, rs);
7330
tmp2 = load_reg(s, rm);
7331
if (insn & (1 << 22)) {
7332
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7334
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7336
if (insn & (1 << 21)) { /* mult accumulate */
7337
TCGv_i32 al = load_reg(s, rn);
7338
TCGv_i32 ah = load_reg(s, rd);
7339
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7340
tcg_temp_free_i32(al);
7341
tcg_temp_free_i32(ah);
7343
if (insn & (1 << 20)) {
7344
gen_logicq_cc(tmp, tmp2);
7346
store_reg(s, rn, tmp);
7347
store_reg(s, rd, tmp2);
7353
rn = (insn >> 16) & 0xf;
7354
rd = (insn >> 12) & 0xf;
7355
if (insn & (1 << 23)) {
7356
/* load/store exclusive */
7357
int op2 = (insn >> 8) & 3;
7358
op1 = (insn >> 21) & 0x3;
7361
case 0: /* lda/stl */
7367
case 1: /* reserved */
7369
case 2: /* ldaex/stlex */
7372
case 3: /* ldrex/strex */
7381
addr = tcg_temp_local_new_i32();
7382
load_reg_var(s, addr, rn);
7384
/* Since the emulation does not have barriers,
7385
the acquire/release semantics need no special
7388
if (insn & (1 << 20)) {
7389
tmp = tcg_temp_new_i32();
7392
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7395
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7398
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7403
store_reg(s, rd, tmp);
7406
tmp = load_reg(s, rm);
7409
gen_aa32_st32(tmp, addr, IS_USER(s));
7412
gen_aa32_st8(tmp, addr, IS_USER(s));
7415
gen_aa32_st16(tmp, addr, IS_USER(s));
7420
tcg_temp_free_i32(tmp);
7422
} else if (insn & (1 << 20)) {
7425
gen_load_exclusive(s, rd, 15, addr, 2);
7427
case 1: /* ldrexd */
7428
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7430
case 2: /* ldrexb */
7431
gen_load_exclusive(s, rd, 15, addr, 0);
7433
case 3: /* ldrexh */
7434
gen_load_exclusive(s, rd, 15, addr, 1);
7443
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7445
case 1: /* strexd */
7446
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7448
case 2: /* strexb */
7449
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7451
case 3: /* strexh */
7452
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7458
tcg_temp_free_i32(addr);
7460
/* SWP instruction */
7463
/* ??? This is not really atomic. However we know
7464
we never have multiple CPUs running in parallel,
7465
so it is good enough. */
7466
addr = load_reg(s, rn);
7467
tmp = load_reg(s, rm);
7468
tmp2 = tcg_temp_new_i32();
7469
if (insn & (1 << 22)) {
7470
gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7471
gen_aa32_st8(tmp, addr, IS_USER(s));
7473
gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7474
gen_aa32_st32(tmp, addr, IS_USER(s));
7476
tcg_temp_free_i32(tmp);
7477
tcg_temp_free_i32(addr);
7478
store_reg(s, rd, tmp2);
7484
/* Misc load/store */
7485
rn = (insn >> 16) & 0xf;
7486
rd = (insn >> 12) & 0xf;
7487
addr = load_reg(s, rn);
7488
if (insn & (1 << 24))
7489
gen_add_datah_offset(s, insn, 0, addr);
7491
if (insn & (1 << 20)) {
7493
tmp = tcg_temp_new_i32();
7496
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7499
gen_aa32_ld8s(tmp, addr, IS_USER(s));
7503
gen_aa32_ld16s(tmp, addr, IS_USER(s));
7507
} else if (sh & 2) {
7512
tmp = load_reg(s, rd);
7513
gen_aa32_st32(tmp, addr, IS_USER(s));
7514
tcg_temp_free_i32(tmp);
7515
tcg_gen_addi_i32(addr, addr, 4);
7516
tmp = load_reg(s, rd + 1);
7517
gen_aa32_st32(tmp, addr, IS_USER(s));
7518
tcg_temp_free_i32(tmp);
7522
tmp = tcg_temp_new_i32();
7523
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7524
store_reg(s, rd, tmp);
7525
tcg_gen_addi_i32(addr, addr, 4);
7526
tmp = tcg_temp_new_i32();
7527
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7531
address_offset = -4;
7534
tmp = load_reg(s, rd);
7535
gen_aa32_st16(tmp, addr, IS_USER(s));
7536
tcg_temp_free_i32(tmp);
7539
/* Perform base writeback before the loaded value to
7540
ensure correct behavior with overlapping index registers.
7541
ldrd with base writeback is is undefined if the
7542
destination and index registers overlap. */
7543
if (!(insn & (1 << 24))) {
7544
gen_add_datah_offset(s, insn, address_offset, addr);
7545
store_reg(s, rn, addr);
7546
} else if (insn & (1 << 21)) {
7548
tcg_gen_addi_i32(addr, addr, address_offset);
7549
store_reg(s, rn, addr);
7551
tcg_temp_free_i32(addr);
7554
/* Complete the load. */
7555
store_reg(s, rd, tmp);
7564
if (insn & (1 << 4)) {
7566
/* Armv6 Media instructions. */
7568
rn = (insn >> 16) & 0xf;
7569
rd = (insn >> 12) & 0xf;
7570
rs = (insn >> 8) & 0xf;
7571
switch ((insn >> 23) & 3) {
7572
case 0: /* Parallel add/subtract. */
7573
op1 = (insn >> 20) & 7;
7574
tmp = load_reg(s, rn);
7575
tmp2 = load_reg(s, rm);
7576
sh = (insn >> 5) & 7;
7577
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7579
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7580
tcg_temp_free_i32(tmp2);
7581
store_reg(s, rd, tmp);
7584
if ((insn & 0x00700020) == 0) {
7585
/* Halfword pack. */
7586
tmp = load_reg(s, rn);
7587
tmp2 = load_reg(s, rm);
7588
shift = (insn >> 7) & 0x1f;
7589
if (insn & (1 << 6)) {
7593
tcg_gen_sari_i32(tmp2, tmp2, shift);
7594
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7595
tcg_gen_ext16u_i32(tmp2, tmp2);
7599
tcg_gen_shli_i32(tmp2, tmp2, shift);
7600
tcg_gen_ext16u_i32(tmp, tmp);
7601
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7603
tcg_gen_or_i32(tmp, tmp, tmp2);
7604
tcg_temp_free_i32(tmp2);
7605
store_reg(s, rd, tmp);
7606
} else if ((insn & 0x00200020) == 0x00200000) {
7608
tmp = load_reg(s, rm);
7609
shift = (insn >> 7) & 0x1f;
7610
if (insn & (1 << 6)) {
7613
tcg_gen_sari_i32(tmp, tmp, shift);
7615
tcg_gen_shli_i32(tmp, tmp, shift);
7617
sh = (insn >> 16) & 0x1f;
7618
tmp2 = tcg_const_i32(sh);
7619
if (insn & (1 << 22))
7620
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7622
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7623
tcg_temp_free_i32(tmp2);
7624
store_reg(s, rd, tmp);
7625
} else if ((insn & 0x00300fe0) == 0x00200f20) {
7627
tmp = load_reg(s, rm);
7628
sh = (insn >> 16) & 0x1f;
7629
tmp2 = tcg_const_i32(sh);
7630
if (insn & (1 << 22))
7631
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7633
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7634
tcg_temp_free_i32(tmp2);
7635
store_reg(s, rd, tmp);
7636
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
7638
tmp = load_reg(s, rn);
7639
tmp2 = load_reg(s, rm);
7640
tmp3 = tcg_temp_new_i32();
7641
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7642
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7643
tcg_temp_free_i32(tmp3);
7644
tcg_temp_free_i32(tmp2);
7645
store_reg(s, rd, tmp);
7646
} else if ((insn & 0x000003e0) == 0x00000060) {
7647
tmp = load_reg(s, rm);
7648
shift = (insn >> 10) & 3;
7649
/* ??? In many cases it's not necessary to do a
7650
rotate, a shift is sufficient. */
7652
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7653
op1 = (insn >> 20) & 7;
7655
case 0: gen_sxtb16(tmp); break;
7656
case 2: gen_sxtb(tmp); break;
7657
case 3: gen_sxth(tmp); break;
7658
case 4: gen_uxtb16(tmp); break;
7659
case 6: gen_uxtb(tmp); break;
7660
case 7: gen_uxth(tmp); break;
7661
default: goto illegal_op;
7664
tmp2 = load_reg(s, rn);
7665
if ((op1 & 3) == 0) {
7666
gen_add16(tmp, tmp2);
7668
tcg_gen_add_i32(tmp, tmp, tmp2);
7669
tcg_temp_free_i32(tmp2);
7672
store_reg(s, rd, tmp);
7673
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
7675
tmp = load_reg(s, rm);
7676
if (insn & (1 << 22)) {
7677
if (insn & (1 << 7)) {
7681
gen_helper_rbit(tmp, tmp);
7684
if (insn & (1 << 7))
7687
tcg_gen_bswap32_i32(tmp, tmp);
7689
store_reg(s, rd, tmp);
7694
case 2: /* Multiplies (Type 3). */
7695
switch ((insn >> 20) & 0x7) {
7697
if (((insn >> 6) ^ (insn >> 7)) & 1) {
7698
/* op2 not 00x or 11x : UNDEF */
7701
/* Signed multiply most significant [accumulate].
7702
(SMMUL, SMMLA, SMMLS) */
7703
tmp = load_reg(s, rm);
7704
tmp2 = load_reg(s, rs);
7705
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7708
tmp = load_reg(s, rd);
7709
if (insn & (1 << 6)) {
7710
tmp64 = gen_subq_msw(tmp64, tmp);
7712
tmp64 = gen_addq_msw(tmp64, tmp);
7715
if (insn & (1 << 5)) {
7716
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7718
tcg_gen_shri_i64(tmp64, tmp64, 32);
7719
tmp = tcg_temp_new_i32();
7720
tcg_gen_trunc_i64_i32(tmp, tmp64);
7721
tcg_temp_free_i64(tmp64);
7722
store_reg(s, rn, tmp);
7726
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7727
if (insn & (1 << 7)) {
7730
tmp = load_reg(s, rm);
7731
tmp2 = load_reg(s, rs);
7732
if (insn & (1 << 5))
7733
gen_swap_half(tmp2);
7734
gen_smul_dual(tmp, tmp2);
7735
if (insn & (1 << 6)) {
7736
/* This subtraction cannot overflow. */
7737
tcg_gen_sub_i32(tmp, tmp, tmp2);
7739
/* This addition cannot overflow 32 bits;
7740
* however it may overflow considered as a signed
7741
* operation, in which case we must set the Q flag.
7743
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7745
tcg_temp_free_i32(tmp2);
7746
if (insn & (1 << 22)) {
7747
/* smlald, smlsld */
7748
tmp64 = tcg_temp_new_i64();
7749
tcg_gen_ext_i32_i64(tmp64, tmp);
7750
tcg_temp_free_i32(tmp);
7751
gen_addq(s, tmp64, rd, rn);
7752
gen_storeq_reg(s, rd, rn, tmp64);
7753
tcg_temp_free_i64(tmp64);
7755
/* smuad, smusd, smlad, smlsd */
7758
tmp2 = load_reg(s, rd);
7759
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7760
tcg_temp_free_i32(tmp2);
7762
store_reg(s, rn, tmp);
7768
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7771
if (((insn >> 5) & 7) || (rd != 15)) {
7774
tmp = load_reg(s, rm);
7775
tmp2 = load_reg(s, rs);
7776
if (insn & (1 << 21)) {
7777
gen_helper_udiv(tmp, tmp, tmp2);
7779
gen_helper_sdiv(tmp, tmp, tmp2);
7781
tcg_temp_free_i32(tmp2);
7782
store_reg(s, rn, tmp);
7789
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7791
case 0: /* Unsigned sum of absolute differences. */
7793
tmp = load_reg(s, rm);
7794
tmp2 = load_reg(s, rs);
7795
gen_helper_usad8(tmp, tmp, tmp2);
7796
tcg_temp_free_i32(tmp2);
7798
tmp2 = load_reg(s, rd);
7799
tcg_gen_add_i32(tmp, tmp, tmp2);
7800
tcg_temp_free_i32(tmp2);
7802
store_reg(s, rn, tmp);
7804
case 0x20: case 0x24: case 0x28: case 0x2c:
7805
/* Bitfield insert/clear. */
7807
shift = (insn >> 7) & 0x1f;
7808
i = (insn >> 16) & 0x1f;
7811
tmp = tcg_temp_new_i32();
7812
tcg_gen_movi_i32(tmp, 0);
7814
tmp = load_reg(s, rm);
7817
tmp2 = load_reg(s, rd);
7818
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
7819
tcg_temp_free_i32(tmp2);
7821
store_reg(s, rd, tmp);
7823
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7824
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7826
tmp = load_reg(s, rm);
7827
shift = (insn >> 7) & 0x1f;
7828
i = ((insn >> 16) & 0x1f) + 1;
7833
gen_ubfx(tmp, shift, (1u << i) - 1);
7835
gen_sbfx(tmp, shift, i);
7838
store_reg(s, rd, tmp);
7848
/* Check for undefined extension instructions
7849
* per the ARM Bible IE:
7850
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7852
sh = (0xf << 20) | (0xf << 4);
7853
if (op1 == 0x7 && ((insn & sh) == sh))
7857
/* load/store byte/word */
7858
rn = (insn >> 16) & 0xf;
7859
rd = (insn >> 12) & 0xf;
7860
tmp2 = load_reg(s, rn);
7861
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7862
if (insn & (1 << 24))
7863
gen_add_data_offset(s, insn, tmp2);
7864
if (insn & (1 << 20)) {
7866
tmp = tcg_temp_new_i32();
7867
if (insn & (1 << 22)) {
7868
gen_aa32_ld8u(tmp, tmp2, i);
7870
gen_aa32_ld32u(tmp, tmp2, i);
7874
tmp = load_reg(s, rd);
7875
if (insn & (1 << 22)) {
7876
gen_aa32_st8(tmp, tmp2, i);
7878
gen_aa32_st32(tmp, tmp2, i);
7880
tcg_temp_free_i32(tmp);
7882
if (!(insn & (1 << 24))) {
7883
gen_add_data_offset(s, insn, tmp2);
7884
store_reg(s, rn, tmp2);
7885
} else if (insn & (1 << 21)) {
7886
store_reg(s, rn, tmp2);
7888
tcg_temp_free_i32(tmp2);
7890
if (insn & (1 << 20)) {
7891
/* Complete the load. */
7892
store_reg_from_load(env, s, rd, tmp);
7898
int j, n, user, loaded_base;
7899
TCGv_i32 loaded_var;
7900
/* load/store multiple words */
7901
/* XXX: store correct base if write back */
7903
if (insn & (1 << 22)) {
7905
goto illegal_op; /* only usable in supervisor mode */
7907
if ((insn & (1 << 15)) == 0)
7910
rn = (insn >> 16) & 0xf;
7911
addr = load_reg(s, rn);
7913
/* compute total size */
7915
TCGV_UNUSED_I32(loaded_var);
7918
if (insn & (1 << i))
7921
/* XXX: test invalid n == 0 case ? */
7922
if (insn & (1 << 23)) {
7923
if (insn & (1 << 24)) {
7925
tcg_gen_addi_i32(addr, addr, 4);
7927
/* post increment */
7930
if (insn & (1 << 24)) {
7932
tcg_gen_addi_i32(addr, addr, -(n * 4));
7934
/* post decrement */
7936
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7941
if (insn & (1 << i)) {
7942
if (insn & (1 << 20)) {
7944
tmp = tcg_temp_new_i32();
7945
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7947
tmp2 = tcg_const_i32(i);
7948
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
7949
tcg_temp_free_i32(tmp2);
7950
tcg_temp_free_i32(tmp);
7951
} else if (i == rn) {
7955
store_reg_from_load(env, s, i, tmp);
7960
/* special case: r15 = PC + 8 */
7961
val = (long)s->pc + 4;
7962
tmp = tcg_temp_new_i32();
7963
tcg_gen_movi_i32(tmp, val);
7965
tmp = tcg_temp_new_i32();
7966
tmp2 = tcg_const_i32(i);
7967
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
7968
tcg_temp_free_i32(tmp2);
7970
tmp = load_reg(s, i);
7972
gen_aa32_st32(tmp, addr, IS_USER(s));
7973
tcg_temp_free_i32(tmp);
7976
/* no need to add after the last transfer */
7978
tcg_gen_addi_i32(addr, addr, 4);
7981
if (insn & (1 << 21)) {
7983
if (insn & (1 << 23)) {
7984
if (insn & (1 << 24)) {
7987
/* post increment */
7988
tcg_gen_addi_i32(addr, addr, 4);
7991
if (insn & (1 << 24)) {
7994
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7996
/* post decrement */
7997
tcg_gen_addi_i32(addr, addr, -(n * 4));
8000
store_reg(s, rn, addr);
8002
tcg_temp_free_i32(addr);
8005
store_reg(s, rn, loaded_var);
8007
if ((insn & (1 << 22)) && !user) {
8008
/* Restore CPSR from SPSR. */
8009
tmp = load_cpu_field(spsr);
8010
gen_set_cpsr(tmp, 0xffffffff);
8011
tcg_temp_free_i32(tmp);
8012
s->is_jmp = DISAS_UPDATE;
8021
/* branch (and link) */
8022
val = (int32_t)s->pc;
8023
if (insn & (1 << 24)) {
8024
tmp = tcg_temp_new_i32();
8025
tcg_gen_movi_i32(tmp, val);
8026
store_reg(s, 14, tmp);
8028
offset = sextract32(insn << 2, 0, 26);
8037
if (disas_coproc_insn(env, s, insn))
8042
gen_set_pc_im(s, s->pc);
8043
s->is_jmp = DISAS_SWI;
8047
gen_exception_insn(s, 4, EXCP_UDEF);
8053
/* Return true if this is a Thumb-2 logical op. */
8055
thumb2_logic_op(int op)
8060
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8061
then set condition code flags based on the result of the operation.
8062
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8063
to the high bit of T1.
8064
Returns zero if the opcode is valid. */
8067
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8068
TCGv_i32 t0, TCGv_i32 t1)
8075
tcg_gen_and_i32(t0, t0, t1);
8079
tcg_gen_andc_i32(t0, t0, t1);
8083
tcg_gen_or_i32(t0, t0, t1);
8087
tcg_gen_orc_i32(t0, t0, t1);
8091
tcg_gen_xor_i32(t0, t0, t1);
8096
gen_add_CC(t0, t0, t1);
8098
tcg_gen_add_i32(t0, t0, t1);
8102
gen_adc_CC(t0, t0, t1);
8108
gen_sbc_CC(t0, t0, t1);
8110
gen_sub_carry(t0, t0, t1);
8115
gen_sub_CC(t0, t0, t1);
8117
tcg_gen_sub_i32(t0, t0, t1);
8121
gen_sub_CC(t0, t1, t0);
8123
tcg_gen_sub_i32(t0, t1, t0);
8125
default: /* 5, 6, 7, 9, 12, 15. */
8131
gen_set_CF_bit31(t1);
8136
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8138
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8140
uint32_t insn, imm, shift, offset;
8141
uint32_t rd, rn, rm, rs;
8152
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8153
|| arm_feature (env, ARM_FEATURE_M))) {
8154
/* Thumb-1 cores may need to treat bl and blx as a pair of
8155
16-bit instructions to get correct prefetch abort behavior. */
8157
if ((insn & (1 << 12)) == 0) {
8159
/* Second half of blx. */
8160
offset = ((insn & 0x7ff) << 1);
8161
tmp = load_reg(s, 14);
8162
tcg_gen_addi_i32(tmp, tmp, offset);
8163
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8165
tmp2 = tcg_temp_new_i32();
8166
tcg_gen_movi_i32(tmp2, s->pc | 1);
8167
store_reg(s, 14, tmp2);
8171
if (insn & (1 << 11)) {
8172
/* Second half of bl. */
8173
offset = ((insn & 0x7ff) << 1) | 1;
8174
tmp = load_reg(s, 14);
8175
tcg_gen_addi_i32(tmp, tmp, offset);
8177
tmp2 = tcg_temp_new_i32();
8178
tcg_gen_movi_i32(tmp2, s->pc | 1);
8179
store_reg(s, 14, tmp2);
8183
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8184
/* Instruction spans a page boundary. Implement it as two
8185
16-bit instructions in case the second half causes an
8187
offset = ((int32_t)insn << 21) >> 9;
8188
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8191
/* Fall through to 32-bit decode. */
8194
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8196
insn |= (uint32_t)insn_hw1 << 16;
8198
if ((insn & 0xf800e800) != 0xf000e800) {
8202
rn = (insn >> 16) & 0xf;
8203
rs = (insn >> 12) & 0xf;
8204
rd = (insn >> 8) & 0xf;
8206
switch ((insn >> 25) & 0xf) {
8207
case 0: case 1: case 2: case 3:
8208
/* 16-bit instructions. Should never happen. */
8211
if (insn & (1 << 22)) {
8212
/* Other load/store, table branch. */
8213
if (insn & 0x01200000) {
8214
/* Load/store doubleword. */
8216
addr = tcg_temp_new_i32();
8217
tcg_gen_movi_i32(addr, s->pc & ~3);
8219
addr = load_reg(s, rn);
8221
offset = (insn & 0xff) * 4;
8222
if ((insn & (1 << 23)) == 0)
8224
if (insn & (1 << 24)) {
8225
tcg_gen_addi_i32(addr, addr, offset);
8228
if (insn & (1 << 20)) {
8230
tmp = tcg_temp_new_i32();
8231
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8232
store_reg(s, rs, tmp);
8233
tcg_gen_addi_i32(addr, addr, 4);
8234
tmp = tcg_temp_new_i32();
8235
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8236
store_reg(s, rd, tmp);
8239
tmp = load_reg(s, rs);
8240
gen_aa32_st32(tmp, addr, IS_USER(s));
8241
tcg_temp_free_i32(tmp);
8242
tcg_gen_addi_i32(addr, addr, 4);
8243
tmp = load_reg(s, rd);
8244
gen_aa32_st32(tmp, addr, IS_USER(s));
8245
tcg_temp_free_i32(tmp);
8247
if (insn & (1 << 21)) {
8248
/* Base writeback. */
8251
tcg_gen_addi_i32(addr, addr, offset - 4);
8252
store_reg(s, rn, addr);
8254
tcg_temp_free_i32(addr);
8256
} else if ((insn & (1 << 23)) == 0) {
8257
/* Load/store exclusive word. */
8258
addr = tcg_temp_local_new_i32();
8259
load_reg_var(s, addr, rn);
8260
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8261
if (insn & (1 << 20)) {
8262
gen_load_exclusive(s, rs, 15, addr, 2);
8264
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8266
tcg_temp_free_i32(addr);
8267
} else if ((insn & (7 << 5)) == 0) {
8270
addr = tcg_temp_new_i32();
8271
tcg_gen_movi_i32(addr, s->pc);
8273
addr = load_reg(s, rn);
8275
tmp = load_reg(s, rm);
8276
tcg_gen_add_i32(addr, addr, tmp);
8277
if (insn & (1 << 4)) {
8279
tcg_gen_add_i32(addr, addr, tmp);
8280
tcg_temp_free_i32(tmp);
8281
tmp = tcg_temp_new_i32();
8282
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8284
tcg_temp_free_i32(tmp);
8285
tmp = tcg_temp_new_i32();
8286
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8288
tcg_temp_free_i32(addr);
8289
tcg_gen_shli_i32(tmp, tmp, 1);
8290
tcg_gen_addi_i32(tmp, tmp, s->pc);
8291
store_reg(s, 15, tmp);
8293
int op2 = (insn >> 6) & 0x3;
8294
op = (insn >> 4) & 0x3;
8299
/* Load/store exclusive byte/halfword/doubleword */
8306
/* Load-acquire/store-release */
8312
/* Load-acquire/store-release exclusive */
8316
addr = tcg_temp_local_new_i32();
8317
load_reg_var(s, addr, rn);
8319
if (insn & (1 << 20)) {
8320
tmp = tcg_temp_new_i32();
8323
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8326
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8329
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8334
store_reg(s, rs, tmp);
8336
tmp = load_reg(s, rs);
8339
gen_aa32_st8(tmp, addr, IS_USER(s));
8342
gen_aa32_st16(tmp, addr, IS_USER(s));
8345
gen_aa32_st32(tmp, addr, IS_USER(s));
8350
tcg_temp_free_i32(tmp);
8352
} else if (insn & (1 << 20)) {
8353
gen_load_exclusive(s, rs, rd, addr, op);
8355
gen_store_exclusive(s, rm, rs, rd, addr, op);
8357
tcg_temp_free_i32(addr);
8360
/* Load/store multiple, RFE, SRS. */
8361
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8362
/* RFE, SRS: not available in user mode or on M profile */
8363
if (IS_USER(s) || IS_M(env)) {
8366
if (insn & (1 << 20)) {
8368
addr = load_reg(s, rn);
8369
if ((insn & (1 << 24)) == 0)
8370
tcg_gen_addi_i32(addr, addr, -8);
8371
/* Load PC into tmp and CPSR into tmp2. */
8372
tmp = tcg_temp_new_i32();
8373
gen_aa32_ld32u(tmp, addr, 0);
8374
tcg_gen_addi_i32(addr, addr, 4);
8375
tmp2 = tcg_temp_new_i32();
8376
gen_aa32_ld32u(tmp2, addr, 0);
8377
if (insn & (1 << 21)) {
8378
/* Base writeback. */
8379
if (insn & (1 << 24)) {
8380
tcg_gen_addi_i32(addr, addr, 4);
8382
tcg_gen_addi_i32(addr, addr, -4);
8384
store_reg(s, rn, addr);
8386
tcg_temp_free_i32(addr);
8388
gen_rfe(s, tmp, tmp2);
8391
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8395
int i, loaded_base = 0;
8396
TCGv_i32 loaded_var;
8397
/* Load/store multiple. */
8398
addr = load_reg(s, rn);
8400
for (i = 0; i < 16; i++) {
8401
if (insn & (1 << i))
8404
if (insn & (1 << 24)) {
8405
tcg_gen_addi_i32(addr, addr, -offset);
8408
TCGV_UNUSED_I32(loaded_var);
8409
for (i = 0; i < 16; i++) {
8410
if ((insn & (1 << i)) == 0)
8412
if (insn & (1 << 20)) {
8414
tmp = tcg_temp_new_i32();
8415
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8418
} else if (i == rn) {
8422
store_reg(s, i, tmp);
8426
tmp = load_reg(s, i);
8427
gen_aa32_st32(tmp, addr, IS_USER(s));
8428
tcg_temp_free_i32(tmp);
8430
tcg_gen_addi_i32(addr, addr, 4);
8433
store_reg(s, rn, loaded_var);
8435
if (insn & (1 << 21)) {
8436
/* Base register writeback. */
8437
if (insn & (1 << 24)) {
8438
tcg_gen_addi_i32(addr, addr, -offset);
8440
/* Fault if writeback register is in register list. */
8441
if (insn & (1 << rn))
8443
store_reg(s, rn, addr);
8445
tcg_temp_free_i32(addr);
8452
op = (insn >> 21) & 0xf;
8454
/* Halfword pack. */
8455
tmp = load_reg(s, rn);
8456
tmp2 = load_reg(s, rm);
8457
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8458
if (insn & (1 << 5)) {
8462
tcg_gen_sari_i32(tmp2, tmp2, shift);
8463
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8464
tcg_gen_ext16u_i32(tmp2, tmp2);
8468
tcg_gen_shli_i32(tmp2, tmp2, shift);
8469
tcg_gen_ext16u_i32(tmp, tmp);
8470
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8472
tcg_gen_or_i32(tmp, tmp, tmp2);
8473
tcg_temp_free_i32(tmp2);
8474
store_reg(s, rd, tmp);
8476
/* Data processing register constant shift. */
8478
tmp = tcg_temp_new_i32();
8479
tcg_gen_movi_i32(tmp, 0);
8481
tmp = load_reg(s, rn);
8483
tmp2 = load_reg(s, rm);
8485
shiftop = (insn >> 4) & 3;
8486
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8487
conds = (insn & (1 << 20)) != 0;
8488
logic_cc = (conds && thumb2_logic_op(op));
8489
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8490
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8492
tcg_temp_free_i32(tmp2);
8494
store_reg(s, rd, tmp);
8496
tcg_temp_free_i32(tmp);
8500
case 13: /* Misc data processing. */
8501
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8502
if (op < 4 && (insn & 0xf000) != 0xf000)
8505
case 0: /* Register controlled shift. */
8506
tmp = load_reg(s, rn);
8507
tmp2 = load_reg(s, rm);
8508
if ((insn & 0x70) != 0)
8510
op = (insn >> 21) & 3;
8511
logic_cc = (insn & (1 << 20)) != 0;
8512
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8515
store_reg_bx(env, s, rd, tmp);
8517
case 1: /* Sign/zero extend. */
8518
tmp = load_reg(s, rm);
8519
shift = (insn >> 4) & 3;
8520
/* ??? In many cases it's not necessary to do a
8521
rotate, a shift is sufficient. */
8523
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8524
op = (insn >> 20) & 7;
8526
case 0: gen_sxth(tmp); break;
8527
case 1: gen_uxth(tmp); break;
8528
case 2: gen_sxtb16(tmp); break;
8529
case 3: gen_uxtb16(tmp); break;
8530
case 4: gen_sxtb(tmp); break;
8531
case 5: gen_uxtb(tmp); break;
8532
default: goto illegal_op;
8535
tmp2 = load_reg(s, rn);
8536
if ((op >> 1) == 1) {
8537
gen_add16(tmp, tmp2);
8539
tcg_gen_add_i32(tmp, tmp, tmp2);
8540
tcg_temp_free_i32(tmp2);
8543
store_reg(s, rd, tmp);
8545
case 2: /* SIMD add/subtract. */
8546
op = (insn >> 20) & 7;
8547
shift = (insn >> 4) & 7;
8548
if ((op & 3) == 3 || (shift & 3) == 3)
8550
tmp = load_reg(s, rn);
8551
tmp2 = load_reg(s, rm);
8552
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8553
tcg_temp_free_i32(tmp2);
8554
store_reg(s, rd, tmp);
8556
case 3: /* Other data processing. */
8557
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8559
/* Saturating add/subtract. */
8560
tmp = load_reg(s, rn);
8561
tmp2 = load_reg(s, rm);
8563
gen_helper_double_saturate(tmp, cpu_env, tmp);
8565
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8567
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8568
tcg_temp_free_i32(tmp2);
8570
tmp = load_reg(s, rn);
8572
case 0x0a: /* rbit */
8573
gen_helper_rbit(tmp, tmp);
8575
case 0x08: /* rev */
8576
tcg_gen_bswap32_i32(tmp, tmp);
8578
case 0x09: /* rev16 */
8581
case 0x0b: /* revsh */
8584
case 0x10: /* sel */
8585
tmp2 = load_reg(s, rm);
8586
tmp3 = tcg_temp_new_i32();
8587
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8588
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8589
tcg_temp_free_i32(tmp3);
8590
tcg_temp_free_i32(tmp2);
8592
case 0x18: /* clz */
8593
gen_helper_clz(tmp, tmp);
8599
store_reg(s, rd, tmp);
8601
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8602
op = (insn >> 4) & 0xf;
8603
tmp = load_reg(s, rn);
8604
tmp2 = load_reg(s, rm);
8605
switch ((insn >> 20) & 7) {
8606
case 0: /* 32 x 32 -> 32 */
8607
tcg_gen_mul_i32(tmp, tmp, tmp2);
8608
tcg_temp_free_i32(tmp2);
8610
tmp2 = load_reg(s, rs);
8612
tcg_gen_sub_i32(tmp, tmp2, tmp);
8614
tcg_gen_add_i32(tmp, tmp, tmp2);
8615
tcg_temp_free_i32(tmp2);
8618
case 1: /* 16 x 16 -> 32 */
8619
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8620
tcg_temp_free_i32(tmp2);
8622
tmp2 = load_reg(s, rs);
8623
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8624
tcg_temp_free_i32(tmp2);
8627
case 2: /* Dual multiply add. */
8628
case 4: /* Dual multiply subtract. */
8630
gen_swap_half(tmp2);
8631
gen_smul_dual(tmp, tmp2);
8632
if (insn & (1 << 22)) {
8633
/* This subtraction cannot overflow. */
8634
tcg_gen_sub_i32(tmp, tmp, tmp2);
8636
/* This addition cannot overflow 32 bits;
8637
* however it may overflow considered as a signed
8638
* operation, in which case we must set the Q flag.
8640
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8642
tcg_temp_free_i32(tmp2);
8645
tmp2 = load_reg(s, rs);
8646
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8647
tcg_temp_free_i32(tmp2);
8650
case 3: /* 32 * 16 -> 32msb */
8652
tcg_gen_sari_i32(tmp2, tmp2, 16);
8655
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8656
tcg_gen_shri_i64(tmp64, tmp64, 16);
8657
tmp = tcg_temp_new_i32();
8658
tcg_gen_trunc_i64_i32(tmp, tmp64);
8659
tcg_temp_free_i64(tmp64);
8662
tmp2 = load_reg(s, rs);
8663
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8664
tcg_temp_free_i32(tmp2);
8667
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8668
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8670
tmp = load_reg(s, rs);
8671
if (insn & (1 << 20)) {
8672
tmp64 = gen_addq_msw(tmp64, tmp);
8674
tmp64 = gen_subq_msw(tmp64, tmp);
8677
if (insn & (1 << 4)) {
8678
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8680
tcg_gen_shri_i64(tmp64, tmp64, 32);
8681
tmp = tcg_temp_new_i32();
8682
tcg_gen_trunc_i64_i32(tmp, tmp64);
8683
tcg_temp_free_i64(tmp64);
8685
case 7: /* Unsigned sum of absolute differences. */
8686
gen_helper_usad8(tmp, tmp, tmp2);
8687
tcg_temp_free_i32(tmp2);
8689
tmp2 = load_reg(s, rs);
8690
tcg_gen_add_i32(tmp, tmp, tmp2);
8691
tcg_temp_free_i32(tmp2);
8695
store_reg(s, rd, tmp);
8697
case 6: case 7: /* 64-bit multiply, Divide. */
8698
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8699
tmp = load_reg(s, rn);
8700
tmp2 = load_reg(s, rm);
8701
if ((op & 0x50) == 0x10) {
8703
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8707
gen_helper_udiv(tmp, tmp, tmp2);
8709
gen_helper_sdiv(tmp, tmp, tmp2);
8710
tcg_temp_free_i32(tmp2);
8711
store_reg(s, rd, tmp);
8712
} else if ((op & 0xe) == 0xc) {
8713
/* Dual multiply accumulate long. */
8715
gen_swap_half(tmp2);
8716
gen_smul_dual(tmp, tmp2);
8718
tcg_gen_sub_i32(tmp, tmp, tmp2);
8720
tcg_gen_add_i32(tmp, tmp, tmp2);
8722
tcg_temp_free_i32(tmp2);
8724
tmp64 = tcg_temp_new_i64();
8725
tcg_gen_ext_i32_i64(tmp64, tmp);
8726
tcg_temp_free_i32(tmp);
8727
gen_addq(s, tmp64, rs, rd);
8728
gen_storeq_reg(s, rs, rd, tmp64);
8729
tcg_temp_free_i64(tmp64);
8732
/* Unsigned 64-bit multiply */
8733
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8737
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8738
tcg_temp_free_i32(tmp2);
8739
tmp64 = tcg_temp_new_i64();
8740
tcg_gen_ext_i32_i64(tmp64, tmp);
8741
tcg_temp_free_i32(tmp);
8743
/* Signed 64-bit multiply */
8744
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8749
gen_addq_lo(s, tmp64, rs);
8750
gen_addq_lo(s, tmp64, rd);
8751
} else if (op & 0x40) {
8752
/* 64-bit accumulate. */
8753
gen_addq(s, tmp64, rs, rd);
8755
gen_storeq_reg(s, rs, rd, tmp64);
8756
tcg_temp_free_i64(tmp64);
8761
case 6: case 7: case 14: case 15:
8763
if (((insn >> 24) & 3) == 3) {
8764
/* Translate into the equivalent ARM encoding. */
8765
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8766
if (disas_neon_data_insn(env, s, insn))
8769
if (insn & (1 << 28))
8771
if (disas_coproc_insn (env, s, insn))
8775
case 8: case 9: case 10: case 11:
8776
if (insn & (1 << 15)) {
8777
/* Branches, misc control. */
8778
if (insn & 0x5000) {
8779
/* Unconditional branch. */
8780
/* signextend(hw1[10:0]) -> offset[:12]. */
8781
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8782
/* hw1[10:0] -> offset[11:1]. */
8783
offset |= (insn & 0x7ff) << 1;
8784
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8785
offset[24:22] already have the same value because of the
8786
sign extension above. */
8787
offset ^= ((~insn) & (1 << 13)) << 10;
8788
offset ^= ((~insn) & (1 << 11)) << 11;
8790
if (insn & (1 << 14)) {
8791
/* Branch and link. */
8792
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8796
if (insn & (1 << 12)) {
8801
offset &= ~(uint32_t)2;
8802
/* thumb2 bx, no need to check */
8803
gen_bx_im(s, offset);
8805
} else if (((insn >> 23) & 7) == 7) {
8807
if (insn & (1 << 13))
8810
if (insn & (1 << 26)) {
8811
/* Secure monitor call (v6Z) */
8812
qemu_log_mask(LOG_UNIMP,
8813
"arm: unimplemented secure monitor call\n");
8814
goto illegal_op; /* not implemented. */
8816
op = (insn >> 20) & 7;
8818
case 0: /* msr cpsr. */
8820
tmp = load_reg(s, rn);
8821
addr = tcg_const_i32(insn & 0xff);
8822
gen_helper_v7m_msr(cpu_env, addr, tmp);
8823
tcg_temp_free_i32(addr);
8824
tcg_temp_free_i32(tmp);
8829
case 1: /* msr spsr. */
8832
tmp = load_reg(s, rn);
8834
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8838
case 2: /* cps, nop-hint. */
8839
if (((insn >> 8) & 7) == 0) {
8840
gen_nop_hint(s, insn & 0xff);
8842
/* Implemented as NOP in user mode. */
8847
if (insn & (1 << 10)) {
8848
if (insn & (1 << 7))
8850
if (insn & (1 << 6))
8852
if (insn & (1 << 5))
8854
if (insn & (1 << 9))
8855
imm = CPSR_A | CPSR_I | CPSR_F;
8857
if (insn & (1 << 8)) {
8859
imm |= (insn & 0x1f);
8862
gen_set_psr_im(s, offset, 0, imm);
8865
case 3: /* Special control operations. */
8867
op = (insn >> 4) & 0xf;
8875
/* These execute as NOPs. */
8882
/* Trivial implementation equivalent to bx. */
8883
tmp = load_reg(s, rn);
8886
case 5: /* Exception return. */
8890
if (rn != 14 || rd != 15) {
8893
tmp = load_reg(s, rn);
8894
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8895
gen_exception_return(s, tmp);
8897
case 6: /* mrs cpsr. */
8898
tmp = tcg_temp_new_i32();
8900
addr = tcg_const_i32(insn & 0xff);
8901
gen_helper_v7m_mrs(tmp, cpu_env, addr);
8902
tcg_temp_free_i32(addr);
8904
gen_helper_cpsr_read(tmp, cpu_env);
8906
store_reg(s, rd, tmp);
8908
case 7: /* mrs spsr. */
8909
/* Not accessible in user mode. */
8910
if (IS_USER(s) || IS_M(env))
8912
tmp = load_cpu_field(spsr);
8913
store_reg(s, rd, tmp);
8918
/* Conditional branch. */
8919
op = (insn >> 22) & 0xf;
8920
/* Generate a conditional jump to next instruction. */
8921
s->condlabel = gen_new_label();
8922
gen_test_cc(op ^ 1, s->condlabel);
8925
/* offset[11:1] = insn[10:0] */
8926
offset = (insn & 0x7ff) << 1;
8927
/* offset[17:12] = insn[21:16]. */
8928
offset |= (insn & 0x003f0000) >> 4;
8929
/* offset[31:20] = insn[26]. */
8930
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8931
/* offset[18] = insn[13]. */
8932
offset |= (insn & (1 << 13)) << 5;
8933
/* offset[19] = insn[11]. */
8934
offset |= (insn & (1 << 11)) << 8;
8936
/* jump to the offset */
8937
gen_jmp(s, s->pc + offset);
8940
/* Data processing immediate. */
8941
if (insn & (1 << 25)) {
8942
if (insn & (1 << 24)) {
8943
if (insn & (1 << 20))
8945
/* Bitfield/Saturate. */
8946
op = (insn >> 21) & 7;
8948
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8950
tmp = tcg_temp_new_i32();
8951
tcg_gen_movi_i32(tmp, 0);
8953
tmp = load_reg(s, rn);
8956
case 2: /* Signed bitfield extract. */
8958
if (shift + imm > 32)
8961
gen_sbfx(tmp, shift, imm);
8963
case 6: /* Unsigned bitfield extract. */
8965
if (shift + imm > 32)
8968
gen_ubfx(tmp, shift, (1u << imm) - 1);
8970
case 3: /* Bitfield insert/clear. */
8973
imm = imm + 1 - shift;
8975
tmp2 = load_reg(s, rd);
8976
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
8977
tcg_temp_free_i32(tmp2);
8982
default: /* Saturate. */
8985
tcg_gen_sari_i32(tmp, tmp, shift);
8987
tcg_gen_shli_i32(tmp, tmp, shift);
8989
tmp2 = tcg_const_i32(imm);
8992
if ((op & 1) && shift == 0)
8993
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8995
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8998
if ((op & 1) && shift == 0)
8999
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9001
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9003
tcg_temp_free_i32(tmp2);
9006
store_reg(s, rd, tmp);
9008
imm = ((insn & 0x04000000) >> 15)
9009
| ((insn & 0x7000) >> 4) | (insn & 0xff);
9010
if (insn & (1 << 22)) {
9011
/* 16-bit immediate. */
9012
imm |= (insn >> 4) & 0xf000;
9013
if (insn & (1 << 23)) {
9015
tmp = load_reg(s, rd);
9016
tcg_gen_ext16u_i32(tmp, tmp);
9017
tcg_gen_ori_i32(tmp, tmp, imm << 16);
9020
tmp = tcg_temp_new_i32();
9021
tcg_gen_movi_i32(tmp, imm);
9024
/* Add/sub 12-bit immediate. */
9026
offset = s->pc & ~(uint32_t)3;
9027
if (insn & (1 << 23))
9031
tmp = tcg_temp_new_i32();
9032
tcg_gen_movi_i32(tmp, offset);
9034
tmp = load_reg(s, rn);
9035
if (insn & (1 << 23))
9036
tcg_gen_subi_i32(tmp, tmp, imm);
9038
tcg_gen_addi_i32(tmp, tmp, imm);
9041
store_reg(s, rd, tmp);
9044
int shifter_out = 0;
9045
/* modified 12-bit immediate. */
9046
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9047
imm = (insn & 0xff);
9050
/* Nothing to do. */
9052
case 1: /* 00XY00XY */
9055
case 2: /* XY00XY00 */
9059
case 3: /* XYXYXYXY */
9063
default: /* Rotated constant. */
9064
shift = (shift << 1) | (imm >> 7);
9066
imm = imm << (32 - shift);
9070
tmp2 = tcg_temp_new_i32();
9071
tcg_gen_movi_i32(tmp2, imm);
9072
rn = (insn >> 16) & 0xf;
9074
tmp = tcg_temp_new_i32();
9075
tcg_gen_movi_i32(tmp, 0);
9077
tmp = load_reg(s, rn);
9079
op = (insn >> 21) & 0xf;
9080
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9081
shifter_out, tmp, tmp2))
9083
tcg_temp_free_i32(tmp2);
9084
rd = (insn >> 8) & 0xf;
9086
store_reg(s, rd, tmp);
9088
tcg_temp_free_i32(tmp);
9093
case 12: /* Load/store single data item. */
9098
if ((insn & 0x01100000) == 0x01000000) {
9099
if (disas_neon_ls_insn(env, s, insn))
9103
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9105
if (!(insn & (1 << 20))) {
9109
/* Byte or halfword load space with dest == r15 : memory hints.
9110
* Catch them early so we don't emit pointless addressing code.
9111
* This space is a mix of:
9112
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9113
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9115
* unallocated hints, which must be treated as NOPs
9116
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9117
* which is easiest for the decoding logic
9118
* Some space which must UNDEF
9120
int op1 = (insn >> 23) & 3;
9121
int op2 = (insn >> 6) & 0x3f;
9126
/* UNPREDICTABLE, unallocated hint or
9127
* PLD/PLDW/PLI (literal)
9132
return 0; /* PLD/PLDW/PLI or unallocated hint */
9134
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9135
return 0; /* PLD/PLDW/PLI or unallocated hint */
9137
/* UNDEF space, or an UNPREDICTABLE */
9143
addr = tcg_temp_new_i32();
9145
/* s->pc has already been incremented by 4. */
9146
imm = s->pc & 0xfffffffc;
9147
if (insn & (1 << 23))
9148
imm += insn & 0xfff;
9150
imm -= insn & 0xfff;
9151
tcg_gen_movi_i32(addr, imm);
9153
addr = load_reg(s, rn);
9154
if (insn & (1 << 23)) {
9155
/* Positive offset. */
9157
tcg_gen_addi_i32(addr, addr, imm);
9160
switch ((insn >> 8) & 0xf) {
9161
case 0x0: /* Shifted Register. */
9162
shift = (insn >> 4) & 0xf;
9164
tcg_temp_free_i32(addr);
9167
tmp = load_reg(s, rm);
9169
tcg_gen_shli_i32(tmp, tmp, shift);
9170
tcg_gen_add_i32(addr, addr, tmp);
9171
tcg_temp_free_i32(tmp);
9173
case 0xc: /* Negative offset. */
9174
tcg_gen_addi_i32(addr, addr, -imm);
9176
case 0xe: /* User privilege. */
9177
tcg_gen_addi_i32(addr, addr, imm);
9180
case 0x9: /* Post-decrement. */
9183
case 0xb: /* Post-increment. */
9187
case 0xd: /* Pre-decrement. */
9190
case 0xf: /* Pre-increment. */
9191
tcg_gen_addi_i32(addr, addr, imm);
9195
tcg_temp_free_i32(addr);
9200
if (insn & (1 << 20)) {
9202
tmp = tcg_temp_new_i32();
9205
gen_aa32_ld8u(tmp, addr, user);
9208
gen_aa32_ld8s(tmp, addr, user);
9211
gen_aa32_ld16u(tmp, addr, user);
9214
gen_aa32_ld16s(tmp, addr, user);
9217
gen_aa32_ld32u(tmp, addr, user);
9220
tcg_temp_free_i32(tmp);
9221
tcg_temp_free_i32(addr);
9227
store_reg(s, rs, tmp);
9231
tmp = load_reg(s, rs);
9234
gen_aa32_st8(tmp, addr, user);
9237
gen_aa32_st16(tmp, addr, user);
9240
gen_aa32_st32(tmp, addr, user);
9243
tcg_temp_free_i32(tmp);
9244
tcg_temp_free_i32(addr);
9247
tcg_temp_free_i32(tmp);
9250
tcg_gen_addi_i32(addr, addr, imm);
9252
store_reg(s, rn, addr);
9254
tcg_temp_free_i32(addr);
9266
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9268
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9275
if (s->condexec_mask) {
9276
cond = s->condexec_cond;
9277
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9278
s->condlabel = gen_new_label();
9279
gen_test_cc(cond ^ 1, s->condlabel);
9284
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9287
switch (insn >> 12) {
9291
op = (insn >> 11) & 3;
9294
rn = (insn >> 3) & 7;
9295
tmp = load_reg(s, rn);
9296
if (insn & (1 << 10)) {
9298
tmp2 = tcg_temp_new_i32();
9299
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9302
rm = (insn >> 6) & 7;
9303
tmp2 = load_reg(s, rm);
9305
if (insn & (1 << 9)) {
9306
if (s->condexec_mask)
9307
tcg_gen_sub_i32(tmp, tmp, tmp2);
9309
gen_sub_CC(tmp, tmp, tmp2);
9311
if (s->condexec_mask)
9312
tcg_gen_add_i32(tmp, tmp, tmp2);
9314
gen_add_CC(tmp, tmp, tmp2);
9316
tcg_temp_free_i32(tmp2);
9317
store_reg(s, rd, tmp);
9319
/* shift immediate */
9320
rm = (insn >> 3) & 7;
9321
shift = (insn >> 6) & 0x1f;
9322
tmp = load_reg(s, rm);
9323
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9324
if (!s->condexec_mask)
9326
store_reg(s, rd, tmp);
9330
/* arithmetic large immediate */
9331
op = (insn >> 11) & 3;
9332
rd = (insn >> 8) & 0x7;
9333
if (op == 0) { /* mov */
9334
tmp = tcg_temp_new_i32();
9335
tcg_gen_movi_i32(tmp, insn & 0xff);
9336
if (!s->condexec_mask)
9338
store_reg(s, rd, tmp);
9340
tmp = load_reg(s, rd);
9341
tmp2 = tcg_temp_new_i32();
9342
tcg_gen_movi_i32(tmp2, insn & 0xff);
9345
gen_sub_CC(tmp, tmp, tmp2);
9346
tcg_temp_free_i32(tmp);
9347
tcg_temp_free_i32(tmp2);
9350
if (s->condexec_mask)
9351
tcg_gen_add_i32(tmp, tmp, tmp2);
9353
gen_add_CC(tmp, tmp, tmp2);
9354
tcg_temp_free_i32(tmp2);
9355
store_reg(s, rd, tmp);
9358
if (s->condexec_mask)
9359
tcg_gen_sub_i32(tmp, tmp, tmp2);
9361
gen_sub_CC(tmp, tmp, tmp2);
9362
tcg_temp_free_i32(tmp2);
9363
store_reg(s, rd, tmp);
9369
if (insn & (1 << 11)) {
9370
rd = (insn >> 8) & 7;
9371
/* load pc-relative. Bit 1 of PC is ignored. */
9372
val = s->pc + 2 + ((insn & 0xff) * 4);
9373
val &= ~(uint32_t)2;
9374
addr = tcg_temp_new_i32();
9375
tcg_gen_movi_i32(addr, val);
9376
tmp = tcg_temp_new_i32();
9377
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9378
tcg_temp_free_i32(addr);
9379
store_reg(s, rd, tmp);
9382
if (insn & (1 << 10)) {
9383
/* data processing extended or blx */
9384
rd = (insn & 7) | ((insn >> 4) & 8);
9385
rm = (insn >> 3) & 0xf;
9386
op = (insn >> 8) & 3;
9389
tmp = load_reg(s, rd);
9390
tmp2 = load_reg(s, rm);
9391
tcg_gen_add_i32(tmp, tmp, tmp2);
9392
tcg_temp_free_i32(tmp2);
9393
store_reg(s, rd, tmp);
9396
tmp = load_reg(s, rd);
9397
tmp2 = load_reg(s, rm);
9398
gen_sub_CC(tmp, tmp, tmp2);
9399
tcg_temp_free_i32(tmp2);
9400
tcg_temp_free_i32(tmp);
9402
case 2: /* mov/cpy */
9403
tmp = load_reg(s, rm);
9404
store_reg(s, rd, tmp);
9406
case 3:/* branch [and link] exchange thumb register */
9407
tmp = load_reg(s, rm);
9408
if (insn & (1 << 7)) {
9410
val = (uint32_t)s->pc | 1;
9411
tmp2 = tcg_temp_new_i32();
9412
tcg_gen_movi_i32(tmp2, val);
9413
store_reg(s, 14, tmp2);
9415
/* already thumb, no need to check */
9422
/* data processing register */
9424
rm = (insn >> 3) & 7;
9425
op = (insn >> 6) & 0xf;
9426
if (op == 2 || op == 3 || op == 4 || op == 7) {
9427
/* the shift/rotate ops want the operands backwards */
9436
if (op == 9) { /* neg */
9437
tmp = tcg_temp_new_i32();
9438
tcg_gen_movi_i32(tmp, 0);
9439
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9440
tmp = load_reg(s, rd);
9442
TCGV_UNUSED_I32(tmp);
9445
tmp2 = load_reg(s, rm);
9448
tcg_gen_and_i32(tmp, tmp, tmp2);
9449
if (!s->condexec_mask)
9453
tcg_gen_xor_i32(tmp, tmp, tmp2);
9454
if (!s->condexec_mask)
9458
if (s->condexec_mask) {
9459
gen_shl(tmp2, tmp2, tmp);
9461
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9466
if (s->condexec_mask) {
9467
gen_shr(tmp2, tmp2, tmp);
9469
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9474
if (s->condexec_mask) {
9475
gen_sar(tmp2, tmp2, tmp);
9477
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9482
if (s->condexec_mask) {
9485
gen_adc_CC(tmp, tmp, tmp2);
9489
if (s->condexec_mask) {
9490
gen_sub_carry(tmp, tmp, tmp2);
9492
gen_sbc_CC(tmp, tmp, tmp2);
9496
if (s->condexec_mask) {
9497
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9498
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9500
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9505
tcg_gen_and_i32(tmp, tmp, tmp2);
9510
if (s->condexec_mask)
9511
tcg_gen_neg_i32(tmp, tmp2);
9513
gen_sub_CC(tmp, tmp, tmp2);
9516
gen_sub_CC(tmp, tmp, tmp2);
9520
gen_add_CC(tmp, tmp, tmp2);
9524
tcg_gen_or_i32(tmp, tmp, tmp2);
9525
if (!s->condexec_mask)
9529
tcg_gen_mul_i32(tmp, tmp, tmp2);
9530
if (!s->condexec_mask)
9534
tcg_gen_andc_i32(tmp, tmp, tmp2);
9535
if (!s->condexec_mask)
9539
tcg_gen_not_i32(tmp2, tmp2);
9540
if (!s->condexec_mask)
9548
store_reg(s, rm, tmp2);
9550
tcg_temp_free_i32(tmp);
9552
store_reg(s, rd, tmp);
9553
tcg_temp_free_i32(tmp2);
9556
tcg_temp_free_i32(tmp);
9557
tcg_temp_free_i32(tmp2);
9562
/* load/store register offset. */
9564
rn = (insn >> 3) & 7;
9565
rm = (insn >> 6) & 7;
9566
op = (insn >> 9) & 7;
9567
addr = load_reg(s, rn);
9568
tmp = load_reg(s, rm);
9569
tcg_gen_add_i32(addr, addr, tmp);
9570
tcg_temp_free_i32(tmp);
9572
if (op < 3) { /* store */
9573
tmp = load_reg(s, rd);
9575
tmp = tcg_temp_new_i32();
9580
gen_aa32_st32(tmp, addr, IS_USER(s));
9583
gen_aa32_st16(tmp, addr, IS_USER(s));
9586
gen_aa32_st8(tmp, addr, IS_USER(s));
9589
gen_aa32_ld8s(tmp, addr, IS_USER(s));
9592
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9595
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9598
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9601
gen_aa32_ld16s(tmp, addr, IS_USER(s));
9604
if (op >= 3) { /* load */
9605
store_reg(s, rd, tmp);
9607
tcg_temp_free_i32(tmp);
9609
tcg_temp_free_i32(addr);
9613
/* load/store word immediate offset */
9615
rn = (insn >> 3) & 7;
9616
addr = load_reg(s, rn);
9617
val = (insn >> 4) & 0x7c;
9618
tcg_gen_addi_i32(addr, addr, val);
9620
if (insn & (1 << 11)) {
9622
tmp = tcg_temp_new_i32();
9623
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9624
store_reg(s, rd, tmp);
9627
tmp = load_reg(s, rd);
9628
gen_aa32_st32(tmp, addr, IS_USER(s));
9629
tcg_temp_free_i32(tmp);
9631
tcg_temp_free_i32(addr);
9635
/* load/store byte immediate offset */
9637
rn = (insn >> 3) & 7;
9638
addr = load_reg(s, rn);
9639
val = (insn >> 6) & 0x1f;
9640
tcg_gen_addi_i32(addr, addr, val);
9642
if (insn & (1 << 11)) {
9644
tmp = tcg_temp_new_i32();
9645
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9646
store_reg(s, rd, tmp);
9649
tmp = load_reg(s, rd);
9650
gen_aa32_st8(tmp, addr, IS_USER(s));
9651
tcg_temp_free_i32(tmp);
9653
tcg_temp_free_i32(addr);
9657
/* load/store halfword immediate offset */
9659
rn = (insn >> 3) & 7;
9660
addr = load_reg(s, rn);
9661
val = (insn >> 5) & 0x3e;
9662
tcg_gen_addi_i32(addr, addr, val);
9664
if (insn & (1 << 11)) {
9666
tmp = tcg_temp_new_i32();
9667
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9668
store_reg(s, rd, tmp);
9671
tmp = load_reg(s, rd);
9672
gen_aa32_st16(tmp, addr, IS_USER(s));
9673
tcg_temp_free_i32(tmp);
9675
tcg_temp_free_i32(addr);
9679
/* load/store from stack */
9680
rd = (insn >> 8) & 7;
9681
addr = load_reg(s, 13);
9682
val = (insn & 0xff) * 4;
9683
tcg_gen_addi_i32(addr, addr, val);
9685
if (insn & (1 << 11)) {
9687
tmp = tcg_temp_new_i32();
9688
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9689
store_reg(s, rd, tmp);
9692
tmp = load_reg(s, rd);
9693
gen_aa32_st32(tmp, addr, IS_USER(s));
9694
tcg_temp_free_i32(tmp);
9696
tcg_temp_free_i32(addr);
9700
/* add to high reg */
9701
rd = (insn >> 8) & 7;
9702
if (insn & (1 << 11)) {
9704
tmp = load_reg(s, 13);
9706
/* PC. bit 1 is ignored. */
9707
tmp = tcg_temp_new_i32();
9708
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9710
val = (insn & 0xff) * 4;
9711
tcg_gen_addi_i32(tmp, tmp, val);
9712
store_reg(s, rd, tmp);
9717
op = (insn >> 8) & 0xf;
9720
/* adjust stack pointer */
9721
tmp = load_reg(s, 13);
9722
val = (insn & 0x7f) * 4;
9723
if (insn & (1 << 7))
9724
val = -(int32_t)val;
9725
tcg_gen_addi_i32(tmp, tmp, val);
9726
store_reg(s, 13, tmp);
9729
case 2: /* sign/zero extend. */
9732
rm = (insn >> 3) & 7;
9733
tmp = load_reg(s, rm);
9734
switch ((insn >> 6) & 3) {
9735
case 0: gen_sxth(tmp); break;
9736
case 1: gen_sxtb(tmp); break;
9737
case 2: gen_uxth(tmp); break;
9738
case 3: gen_uxtb(tmp); break;
9740
store_reg(s, rd, tmp);
9742
case 4: case 5: case 0xc: case 0xd:
9744
addr = load_reg(s, 13);
9745
if (insn & (1 << 8))
9749
for (i = 0; i < 8; i++) {
9750
if (insn & (1 << i))
9753
if ((insn & (1 << 11)) == 0) {
9754
tcg_gen_addi_i32(addr, addr, -offset);
9756
for (i = 0; i < 8; i++) {
9757
if (insn & (1 << i)) {
9758
if (insn & (1 << 11)) {
9760
tmp = tcg_temp_new_i32();
9761
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9762
store_reg(s, i, tmp);
9765
tmp = load_reg(s, i);
9766
gen_aa32_st32(tmp, addr, IS_USER(s));
9767
tcg_temp_free_i32(tmp);
9769
/* advance to the next address. */
9770
tcg_gen_addi_i32(addr, addr, 4);
9773
TCGV_UNUSED_I32(tmp);
9774
if (insn & (1 << 8)) {
9775
if (insn & (1 << 11)) {
9777
tmp = tcg_temp_new_i32();
9778
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9779
/* don't set the pc until the rest of the instruction
9783
tmp = load_reg(s, 14);
9784
gen_aa32_st32(tmp, addr, IS_USER(s));
9785
tcg_temp_free_i32(tmp);
9787
tcg_gen_addi_i32(addr, addr, 4);
9789
if ((insn & (1 << 11)) == 0) {
9790
tcg_gen_addi_i32(addr, addr, -offset);
9792
/* write back the new stack pointer */
9793
store_reg(s, 13, addr);
9794
/* set the new PC value */
9795
if ((insn & 0x0900) == 0x0900) {
9796
store_reg_from_load(env, s, 15, tmp);
9800
case 1: case 3: case 9: case 11: /* czb */
9802
tmp = load_reg(s, rm);
9803
s->condlabel = gen_new_label();
9805
if (insn & (1 << 11))
9806
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9808
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9809
tcg_temp_free_i32(tmp);
9810
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9811
val = (uint32_t)s->pc + 2;
9816
case 15: /* IT, nop-hint. */
9817
if ((insn & 0xf) == 0) {
9818
gen_nop_hint(s, (insn >> 4) & 0xf);
9822
s->condexec_cond = (insn >> 4) & 0xe;
9823
s->condexec_mask = insn & 0x1f;
9824
/* No actual code generated for this insn, just setup state. */
9827
case 0xe: /* bkpt */
9829
gen_exception_insn(s, 2, EXCP_BKPT);
9834
rn = (insn >> 3) & 0x7;
9836
tmp = load_reg(s, rn);
9837
switch ((insn >> 6) & 3) {
9838
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9839
case 1: gen_rev16(tmp); break;
9840
case 3: gen_revsh(tmp); break;
9841
default: goto illegal_op;
9843
store_reg(s, rd, tmp);
9847
switch ((insn >> 5) & 7) {
9851
if (((insn >> 3) & 1) != s->bswap_code) {
9852
/* Dynamic endianness switching not implemented. */
9853
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
9864
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9867
addr = tcg_const_i32(19);
9868
gen_helper_v7m_msr(cpu_env, addr, tmp);
9869
tcg_temp_free_i32(addr);
9873
addr = tcg_const_i32(16);
9874
gen_helper_v7m_msr(cpu_env, addr, tmp);
9875
tcg_temp_free_i32(addr);
9877
tcg_temp_free_i32(tmp);
9880
if (insn & (1 << 4)) {
9881
shift = CPSR_A | CPSR_I | CPSR_F;
9885
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9900
/* load/store multiple */
9901
TCGv_i32 loaded_var;
9902
TCGV_UNUSED_I32(loaded_var);
9903
rn = (insn >> 8) & 0x7;
9904
addr = load_reg(s, rn);
9905
for (i = 0; i < 8; i++) {
9906
if (insn & (1 << i)) {
9907
if (insn & (1 << 11)) {
9909
tmp = tcg_temp_new_i32();
9910
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9914
store_reg(s, i, tmp);
9918
tmp = load_reg(s, i);
9919
gen_aa32_st32(tmp, addr, IS_USER(s));
9920
tcg_temp_free_i32(tmp);
9922
/* advance to the next address */
9923
tcg_gen_addi_i32(addr, addr, 4);
9926
if ((insn & (1 << rn)) == 0) {
9927
/* base reg not in list: base register writeback */
9928
store_reg(s, rn, addr);
9930
/* base reg in list: if load, complete it now */
9931
if (insn & (1 << 11)) {
9932
store_reg(s, rn, loaded_var);
9934
tcg_temp_free_i32(addr);
9939
/* conditional branch or swi */
9940
cond = (insn >> 8) & 0xf;
9946
gen_set_pc_im(s, s->pc);
9947
s->is_jmp = DISAS_SWI;
9950
/* generate a conditional jump to next instruction */
9951
s->condlabel = gen_new_label();
9952
gen_test_cc(cond ^ 1, s->condlabel);
9955
/* jump to the offset */
9956
val = (uint32_t)s->pc + 2;
9957
offset = ((int32_t)insn << 24) >> 24;
9963
if (insn & (1 << 11)) {
9964
if (disas_thumb2_insn(env, s, insn))
9968
/* unconditional branch */
9969
val = (uint32_t)s->pc;
9970
offset = ((int32_t)insn << 21) >> 21;
9971
val += (offset << 1) + 2;
9976
if (disas_thumb2_insn(env, s, insn))
9982
gen_exception_insn(s, 4, EXCP_UDEF);
9986
gen_exception_insn(s, 2, EXCP_UDEF);
9989
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9990
basic block 'tb'. If search_pc is TRUE, also generate PC
9991
information for each intermediate instruction. */
9992
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
9993
TranslationBlock *tb,
9996
CPUState *cs = CPU(cpu);
9997
CPUARMState *env = &cpu->env;
9998
DisasContext dc1, *dc = &dc1;
10000
uint16_t *gen_opc_end;
10002
target_ulong pc_start;
10003
target_ulong next_page_start;
10007
/* generate intermediate code */
10012
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10014
dc->is_jmp = DISAS_NEXT;
10016
dc->singlestep_enabled = cs->singlestep_enabled;
10019
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10022
dc->bswap_code = 0;
10023
dc->condexec_mask = 0;
10024
dc->condexec_cond = 0;
10025
#if !defined(CONFIG_USER_ONLY)
10028
dc->vfp_enabled = 0;
10030
dc->vec_stride = 0;
10033
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10034
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10035
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10036
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10037
#if !defined(CONFIG_USER_ONLY)
10038
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10040
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10041
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10042
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10044
cpu_F0s = tcg_temp_new_i32();
10045
cpu_F1s = tcg_temp_new_i32();
10046
cpu_F0d = tcg_temp_new_i64();
10047
cpu_F1d = tcg_temp_new_i64();
10050
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10051
cpu_M0 = tcg_temp_new_i64();
10052
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10055
max_insns = tb->cflags & CF_COUNT_MASK;
10056
if (max_insns == 0)
10057
max_insns = CF_COUNT_MASK;
10061
tcg_clear_temp_count();
10063
/* A note on handling of the condexec (IT) bits:
10065
* We want to avoid the overhead of having to write the updated condexec
10066
* bits back to the CPUARMState for every instruction in an IT block. So:
10067
* (1) if the condexec bits are not already zero then we write
10068
* zero back into the CPUARMState now. This avoids complications trying
10069
* to do it at the end of the block. (For example if we don't do this
10070
* it's hard to identify whether we can safely skip writing condexec
10071
* at the end of the TB, which we definitely want to do for the case
10072
* where a TB doesn't do anything with the IT state at all.)
10073
* (2) if we are going to leave the TB then we call gen_set_condexec()
10074
* which will write the correct value into CPUARMState if zero is wrong.
10075
* This is done both for leaving the TB at the end, and for leaving
10076
* it because of an exception we know will happen, which is done in
10077
* gen_exception_insn(). The latter is necessary because we need to
10078
* leave the TB with the PC/IT state just prior to execution of the
10079
* instruction which caused the exception.
10080
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10081
* then the CPUARMState will be wrong and we need to reset it.
10082
* This is handled in the same way as restoration of the
10083
* PC in these situations: we will be called again with search_pc=1
10084
* and generate a mapping of the condexec bits for each PC in
10085
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10086
* this to restore the condexec bits.
10088
* Note that there are no instructions which can read the condexec
10089
* bits, and none which can write non-static values to them, so
10090
* we don't need to care about whether CPUARMState is correct in the
10094
/* Reset the conditional execution bits immediately. This avoids
10095
complications trying to do it at the end of the block. */
10096
if (dc->condexec_mask || dc->condexec_cond)
10098
TCGv_i32 tmp = tcg_temp_new_i32();
10099
tcg_gen_movi_i32(tmp, 0);
10100
store_cpu_field(tmp, condexec_bits);
10103
#ifdef CONFIG_USER_ONLY
10104
/* Intercept jump to the magic kernel page. */
10105
if (!dc->aarch64 && dc->pc >= 0xffff0000) {
10106
/* We always get here via a jump, so know we are not in a
10107
conditional execution block. */
10108
gen_exception(EXCP_KERNEL_TRAP);
10109
dc->is_jmp = DISAS_UPDATE;
10113
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10114
/* We always get here via a jump, so know we are not in a
10115
conditional execution block. */
10116
gen_exception(EXCP_EXCEPTION_EXIT);
10117
dc->is_jmp = DISAS_UPDATE;
10122
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10123
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10124
if (bp->pc == dc->pc) {
10125
gen_exception_insn(dc, 0, EXCP_DEBUG);
10126
/* Advance PC so that clearing the breakpoint will
10127
invalidate this TB. */
10129
goto done_generating;
10134
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10138
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10140
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10141
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10142
tcg_ctx.gen_opc_instr_start[lj] = 1;
10143
tcg_ctx.gen_opc_icount[lj] = num_insns;
10146
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10149
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10150
tcg_gen_debug_insn_start(dc->pc);
10154
disas_a64_insn(env, dc);
10155
} else if (dc->thumb) {
10156
disas_thumb_insn(env, dc);
10157
if (dc->condexec_mask) {
10158
dc->condexec_cond = (dc->condexec_cond & 0xe)
10159
| ((dc->condexec_mask >> 4) & 1);
10160
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10161
if (dc->condexec_mask == 0) {
10162
dc->condexec_cond = 0;
10166
disas_arm_insn(env, dc);
10169
if (dc->condjmp && !dc->is_jmp) {
10170
gen_set_label(dc->condlabel);
10174
if (tcg_check_temp_count()) {
10175
fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10179
/* Translation stops when a conditional branch is encountered.
10180
* Otherwise the subsequent code could get translated several times.
10181
* Also stop translation when a page boundary is reached. This
10182
* ensures prefetch aborts occur at the right place. */
10184
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10185
!cs->singlestep_enabled &&
10187
dc->pc < next_page_start &&
10188
num_insns < max_insns);
10190
if (tb->cflags & CF_LAST_IO) {
10192
/* FIXME: This can theoretically happen with self-modifying
10194
cpu_abort(env, "IO on conditional branch instruction");
10199
/* At this stage dc->condjmp will only be set when the skipped
10200
instruction was a conditional branch or trap, and the PC has
10201
already been written. */
10202
if (unlikely(cs->singlestep_enabled)) {
10203
/* Make sure the pc is updated, and raise a debug exception. */
10205
gen_set_condexec(dc);
10206
if (dc->is_jmp == DISAS_SWI) {
10207
gen_exception(EXCP_SWI);
10209
gen_exception(EXCP_DEBUG);
10211
gen_set_label(dc->condlabel);
10213
if (dc->condjmp || !dc->is_jmp) {
10214
gen_set_pc_im(dc, dc->pc);
10217
gen_set_condexec(dc);
10218
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10219
gen_exception(EXCP_SWI);
10221
/* FIXME: Single stepping a WFI insn will not halt
10223
gen_exception(EXCP_DEBUG);
10226
/* While branches must always occur at the end of an IT block,
10227
there are a few other things that can cause us to terminate
10228
the TB in the middle of an IT block:
10229
- Exception generating instructions (bkpt, swi, undefined).
10231
- Hardware watchpoints.
10232
Hardware breakpoints have already been handled and skip this code.
10234
gen_set_condexec(dc);
10235
switch(dc->is_jmp) {
10237
gen_goto_tb(dc, 1, dc->pc);
10242
/* indicate that the hash table must be used to find the next TB */
10243
tcg_gen_exit_tb(0);
10245
case DISAS_TB_JUMP:
10246
/* nothing more to generate */
10249
gen_helper_wfi(cpu_env);
10252
gen_exception(EXCP_SWI);
10256
gen_set_label(dc->condlabel);
10257
gen_set_condexec(dc);
10258
gen_goto_tb(dc, 1, dc->pc);
10264
gen_tb_end(tb, num_insns);
10265
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10268
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10269
qemu_log("----------------\n");
10270
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10271
log_target_disas(env, pc_start, dc->pc - pc_start,
10272
dc->thumb | (dc->bswap_code << 1));
10277
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10280
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10282
tb->size = dc->pc - pc_start;
10283
tb->icount = num_insns;
10287
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10289
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10292
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10294
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10297
static const char *cpu_mode_names[16] = {
10298
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10299
"???", "???", "???", "und", "???", "???", "???", "sys"
10302
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10305
ARMCPU *cpu = ARM_CPU(cs);
10306
CPUARMState *env = &cpu->env;
10310
for(i=0;i<16;i++) {
10311
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10313
cpu_fprintf(f, "\n");
10315
cpu_fprintf(f, " ");
10317
psr = cpsr_read(env);
10318
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10320
psr & (1 << 31) ? 'N' : '-',
10321
psr & (1 << 30) ? 'Z' : '-',
10322
psr & (1 << 29) ? 'C' : '-',
10323
psr & (1 << 28) ? 'V' : '-',
10324
psr & CPSR_T ? 'T' : 'A',
10325
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10327
if (flags & CPU_DUMP_FPU) {
10328
int numvfpregs = 0;
10329
if (arm_feature(env, ARM_FEATURE_VFP)) {
10332
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10335
for (i = 0; i < numvfpregs; i++) {
10336
uint64_t v = float64_val(env->vfp.regs[i]);
10337
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10338
i * 2, (uint32_t)v,
10339
i * 2 + 1, (uint32_t)(v >> 32),
10342
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10346
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10349
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10351
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10353
env->condexec_bits = gen_opc_condexec_bits[pc_pos];