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"
36
#define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
37
#define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
38
/* currently all emulated v5 cores are also v5TE, so don't bother */
39
#define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
40
#define ENABLE_ARCH_5J 0
41
#define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
42
#define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
43
#define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
44
#define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
45
#define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
47
#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
49
/* internal defines */
50
typedef struct DisasContext {
53
/* Nonzero if this instruction has been conditionally skipped. */
55
/* The label that will be jumped to when the instruction is skipped. */
57
/* Thumb-2 conditional execution bits. */
60
struct TranslationBlock *tb;
61
int singlestep_enabled;
64
#if !defined(CONFIG_USER_ONLY)
72
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
74
#if defined(CONFIG_USER_ONLY)
77
#define IS_USER(s) (s->user)
80
/* These instructions trap after executing, so defer them until after the
81
conditional execution state has been updated. */
86
static TCGv_ptr cpu_env;
87
/* We reuse the same 64-bit temporaries for efficiency. */
88
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
89
static TCGv_i32 cpu_R[16];
90
static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
91
static TCGv_i32 cpu_exclusive_addr;
92
static TCGv_i32 cpu_exclusive_val;
93
static TCGv_i32 cpu_exclusive_high;
94
#ifdef CONFIG_USER_ONLY
95
static TCGv_i32 cpu_exclusive_test;
96
static TCGv_i32 cpu_exclusive_info;
99
/* FIXME: These should be removed. */
100
static TCGv_i32 cpu_F0s, cpu_F1s;
101
static TCGv_i64 cpu_F0d, cpu_F1d;
103
#include "exec/gen-icount.h"
105
static const char *regnames[] =
106
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
107
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
109
/* initialize TCG globals. */
110
void arm_translate_init(void)
114
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
116
for (i = 0; i < 16; i++) {
117
cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
118
offsetof(CPUARMState, regs[i]),
121
cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
122
cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
123
cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
124
cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
126
cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
127
offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
128
cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
129
offsetof(CPUARMState, exclusive_val), "exclusive_val");
130
cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
131
offsetof(CPUARMState, exclusive_high), "exclusive_high");
132
#ifdef CONFIG_USER_ONLY
133
cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
134
offsetof(CPUARMState, exclusive_test), "exclusive_test");
135
cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
136
offsetof(CPUARMState, exclusive_info), "exclusive_info");
143
static inline TCGv_i32 load_cpu_offset(int offset)
145
TCGv_i32 tmp = tcg_temp_new_i32();
146
tcg_gen_ld_i32(tmp, cpu_env, offset);
150
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
152
static inline void store_cpu_offset(TCGv_i32 var, int offset)
154
tcg_gen_st_i32(var, cpu_env, offset);
155
tcg_temp_free_i32(var);
158
#define store_cpu_field(var, name) \
159
store_cpu_offset(var, offsetof(CPUARMState, name))
161
/* Set a variable to the value of a CPU register. */
162
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
166
/* normally, since we updated PC, we need only to add one insn */
168
addr = (long)s->pc + 2;
170
addr = (long)s->pc + 4;
171
tcg_gen_movi_i32(var, addr);
173
tcg_gen_mov_i32(var, cpu_R[reg]);
177
/* Create a new temporary and set it to the value of a CPU register. */
178
static inline TCGv_i32 load_reg(DisasContext *s, int reg)
180
TCGv_i32 tmp = tcg_temp_new_i32();
181
load_reg_var(s, tmp, reg);
185
/* Set a CPU register. The source must be a temporary and will be
187
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
190
tcg_gen_andi_i32(var, var, ~1);
191
s->is_jmp = DISAS_JUMP;
193
tcg_gen_mov_i32(cpu_R[reg], var);
194
tcg_temp_free_i32(var);
197
/* Value extensions. */
198
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
199
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
200
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
201
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
203
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
204
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
207
static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
209
TCGv_i32 tmp_mask = tcg_const_i32(mask);
210
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
211
tcg_temp_free_i32(tmp_mask);
213
/* Set NZCV flags from the high 4 bits of var. */
214
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
216
static void gen_exception(int excp)
218
TCGv_i32 tmp = tcg_temp_new_i32();
219
tcg_gen_movi_i32(tmp, excp);
220
gen_helper_exception(cpu_env, tmp);
221
tcg_temp_free_i32(tmp);
224
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
226
TCGv_i32 tmp1 = tcg_temp_new_i32();
227
TCGv_i32 tmp2 = tcg_temp_new_i32();
228
tcg_gen_ext16s_i32(tmp1, a);
229
tcg_gen_ext16s_i32(tmp2, b);
230
tcg_gen_mul_i32(tmp1, tmp1, tmp2);
231
tcg_temp_free_i32(tmp2);
232
tcg_gen_sari_i32(a, a, 16);
233
tcg_gen_sari_i32(b, b, 16);
234
tcg_gen_mul_i32(b, b, a);
235
tcg_gen_mov_i32(a, tmp1);
236
tcg_temp_free_i32(tmp1);
239
/* Byteswap each halfword. */
240
static void gen_rev16(TCGv_i32 var)
242
TCGv_i32 tmp = tcg_temp_new_i32();
243
tcg_gen_shri_i32(tmp, var, 8);
244
tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
245
tcg_gen_shli_i32(var, var, 8);
246
tcg_gen_andi_i32(var, var, 0xff00ff00);
247
tcg_gen_or_i32(var, var, tmp);
248
tcg_temp_free_i32(tmp);
251
/* Byteswap low halfword and sign extend. */
252
static void gen_revsh(TCGv_i32 var)
254
tcg_gen_ext16u_i32(var, var);
255
tcg_gen_bswap16_i32(var, var);
256
tcg_gen_ext16s_i32(var, var);
259
/* Unsigned bitfield extract. */
260
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
263
tcg_gen_shri_i32(var, var, shift);
264
tcg_gen_andi_i32(var, var, mask);
267
/* Signed bitfield extract. */
268
static void gen_sbfx(TCGv_i32 var, int shift, int width)
273
tcg_gen_sari_i32(var, var, shift);
274
if (shift + width < 32) {
275
signbit = 1u << (width - 1);
276
tcg_gen_andi_i32(var, var, (1u << width) - 1);
277
tcg_gen_xori_i32(var, var, signbit);
278
tcg_gen_subi_i32(var, var, signbit);
282
/* Return (b << 32) + a. Mark inputs as dead */
283
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
285
TCGv_i64 tmp64 = tcg_temp_new_i64();
287
tcg_gen_extu_i32_i64(tmp64, b);
288
tcg_temp_free_i32(b);
289
tcg_gen_shli_i64(tmp64, tmp64, 32);
290
tcg_gen_add_i64(a, tmp64, a);
292
tcg_temp_free_i64(tmp64);
296
/* Return (b << 32) - a. Mark inputs as dead. */
297
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
299
TCGv_i64 tmp64 = tcg_temp_new_i64();
301
tcg_gen_extu_i32_i64(tmp64, b);
302
tcg_temp_free_i32(b);
303
tcg_gen_shli_i64(tmp64, tmp64, 32);
304
tcg_gen_sub_i64(a, tmp64, a);
306
tcg_temp_free_i64(tmp64);
310
/* 32x32->64 multiply. Marks inputs as dead. */
311
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
313
TCGv_i32 lo = tcg_temp_new_i32();
314
TCGv_i32 hi = tcg_temp_new_i32();
317
tcg_gen_mulu2_i32(lo, hi, a, b);
318
tcg_temp_free_i32(a);
319
tcg_temp_free_i32(b);
321
ret = tcg_temp_new_i64();
322
tcg_gen_concat_i32_i64(ret, lo, hi);
323
tcg_temp_free_i32(lo);
324
tcg_temp_free_i32(hi);
329
static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
331
TCGv_i32 lo = tcg_temp_new_i32();
332
TCGv_i32 hi = tcg_temp_new_i32();
335
tcg_gen_muls2_i32(lo, hi, a, b);
336
tcg_temp_free_i32(a);
337
tcg_temp_free_i32(b);
339
ret = tcg_temp_new_i64();
340
tcg_gen_concat_i32_i64(ret, lo, hi);
341
tcg_temp_free_i32(lo);
342
tcg_temp_free_i32(hi);
347
/* Swap low and high halfwords. */
348
static void gen_swap_half(TCGv_i32 var)
350
TCGv_i32 tmp = tcg_temp_new_i32();
351
tcg_gen_shri_i32(tmp, var, 16);
352
tcg_gen_shli_i32(var, var, 16);
353
tcg_gen_or_i32(var, var, tmp);
354
tcg_temp_free_i32(tmp);
357
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
358
tmp = (t0 ^ t1) & 0x8000;
361
t0 = (t0 + t1) ^ tmp;
364
static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
366
TCGv_i32 tmp = tcg_temp_new_i32();
367
tcg_gen_xor_i32(tmp, t0, t1);
368
tcg_gen_andi_i32(tmp, tmp, 0x8000);
369
tcg_gen_andi_i32(t0, t0, ~0x8000);
370
tcg_gen_andi_i32(t1, t1, ~0x8000);
371
tcg_gen_add_i32(t0, t0, t1);
372
tcg_gen_xor_i32(t0, t0, tmp);
373
tcg_temp_free_i32(tmp);
374
tcg_temp_free_i32(t1);
377
/* Set CF to the top bit of var. */
378
static void gen_set_CF_bit31(TCGv_i32 var)
380
tcg_gen_shri_i32(cpu_CF, var, 31);
383
/* Set N and Z flags from var. */
384
static inline void gen_logic_CC(TCGv_i32 var)
386
tcg_gen_mov_i32(cpu_NF, var);
387
tcg_gen_mov_i32(cpu_ZF, var);
391
static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
393
tcg_gen_add_i32(t0, t0, t1);
394
tcg_gen_add_i32(t0, t0, cpu_CF);
397
/* dest = T0 + T1 + CF. */
398
static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
400
tcg_gen_add_i32(dest, t0, t1);
401
tcg_gen_add_i32(dest, dest, cpu_CF);
404
/* dest = T0 - T1 + CF - 1. */
405
static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
407
tcg_gen_sub_i32(dest, t0, t1);
408
tcg_gen_add_i32(dest, dest, cpu_CF);
409
tcg_gen_subi_i32(dest, dest, 1);
412
/* dest = T0 + T1. Compute C, N, V and Z flags */
413
static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
415
TCGv_i32 tmp = tcg_temp_new_i32();
416
tcg_gen_movi_i32(tmp, 0);
417
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
418
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
419
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
420
tcg_gen_xor_i32(tmp, t0, t1);
421
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
422
tcg_temp_free_i32(tmp);
423
tcg_gen_mov_i32(dest, cpu_NF);
426
/* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
427
static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
429
TCGv_i32 tmp = tcg_temp_new_i32();
430
if (TCG_TARGET_HAS_add2_i32) {
431
tcg_gen_movi_i32(tmp, 0);
432
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
433
tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
435
TCGv_i64 q0 = tcg_temp_new_i64();
436
TCGv_i64 q1 = tcg_temp_new_i64();
437
tcg_gen_extu_i32_i64(q0, t0);
438
tcg_gen_extu_i32_i64(q1, t1);
439
tcg_gen_add_i64(q0, q0, q1);
440
tcg_gen_extu_i32_i64(q1, cpu_CF);
441
tcg_gen_add_i64(q0, q0, q1);
442
tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
443
tcg_temp_free_i64(q0);
444
tcg_temp_free_i64(q1);
446
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
447
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
448
tcg_gen_xor_i32(tmp, t0, t1);
449
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
450
tcg_temp_free_i32(tmp);
451
tcg_gen_mov_i32(dest, cpu_NF);
454
/* dest = T0 - T1. Compute C, N, V and Z flags */
455
static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
458
tcg_gen_sub_i32(cpu_NF, t0, t1);
459
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
460
tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
461
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
462
tmp = tcg_temp_new_i32();
463
tcg_gen_xor_i32(tmp, t0, t1);
464
tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
465
tcg_temp_free_i32(tmp);
466
tcg_gen_mov_i32(dest, cpu_NF);
469
/* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
470
static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
472
TCGv_i32 tmp = tcg_temp_new_i32();
473
tcg_gen_not_i32(tmp, t1);
474
gen_adc_CC(dest, t0, tmp);
475
tcg_temp_free_i32(tmp);
478
#define GEN_SHIFT(name) \
479
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
481
TCGv_i32 tmp1, tmp2, tmp3; \
482
tmp1 = tcg_temp_new_i32(); \
483
tcg_gen_andi_i32(tmp1, t1, 0xff); \
484
tmp2 = tcg_const_i32(0); \
485
tmp3 = tcg_const_i32(0x1f); \
486
tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
487
tcg_temp_free_i32(tmp3); \
488
tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
489
tcg_gen_##name##_i32(dest, tmp2, tmp1); \
490
tcg_temp_free_i32(tmp2); \
491
tcg_temp_free_i32(tmp1); \
497
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
500
tmp1 = tcg_temp_new_i32();
501
tcg_gen_andi_i32(tmp1, t1, 0xff);
502
tmp2 = tcg_const_i32(0x1f);
503
tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
504
tcg_temp_free_i32(tmp2);
505
tcg_gen_sar_i32(dest, t0, tmp1);
506
tcg_temp_free_i32(tmp1);
509
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
511
TCGv_i32 c0 = tcg_const_i32(0);
512
TCGv_i32 tmp = tcg_temp_new_i32();
513
tcg_gen_neg_i32(tmp, src);
514
tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
515
tcg_temp_free_i32(c0);
516
tcg_temp_free_i32(tmp);
519
static void shifter_out_im(TCGv_i32 var, int shift)
522
tcg_gen_andi_i32(cpu_CF, var, 1);
524
tcg_gen_shri_i32(cpu_CF, var, shift);
526
tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
531
/* Shift by immediate. Includes special handling for shift == 0. */
532
static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
533
int shift, int flags)
539
shifter_out_im(var, 32 - shift);
540
tcg_gen_shli_i32(var, var, shift);
546
tcg_gen_shri_i32(cpu_CF, var, 31);
548
tcg_gen_movi_i32(var, 0);
551
shifter_out_im(var, shift - 1);
552
tcg_gen_shri_i32(var, var, shift);
559
shifter_out_im(var, shift - 1);
562
tcg_gen_sari_i32(var, var, shift);
564
case 3: /* ROR/RRX */
567
shifter_out_im(var, shift - 1);
568
tcg_gen_rotri_i32(var, var, shift); break;
570
TCGv_i32 tmp = tcg_temp_new_i32();
571
tcg_gen_shli_i32(tmp, cpu_CF, 31);
573
shifter_out_im(var, 0);
574
tcg_gen_shri_i32(var, var, 1);
575
tcg_gen_or_i32(var, var, tmp);
576
tcg_temp_free_i32(tmp);
581
static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
582
TCGv_i32 shift, int flags)
586
case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
587
case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
588
case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
589
case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
594
gen_shl(var, var, shift);
597
gen_shr(var, var, shift);
600
gen_sar(var, var, shift);
602
case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
603
tcg_gen_rotr_i32(var, var, shift); break;
606
tcg_temp_free_i32(shift);
609
#define PAS_OP(pfx) \
611
case 0: gen_pas_helper(glue(pfx,add16)); break; \
612
case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
613
case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
614
case 3: gen_pas_helper(glue(pfx,sub16)); break; \
615
case 4: gen_pas_helper(glue(pfx,add8)); break; \
616
case 7: gen_pas_helper(glue(pfx,sub8)); break; \
618
static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
623
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
625
tmp = tcg_temp_new_ptr();
626
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
628
tcg_temp_free_ptr(tmp);
631
tmp = tcg_temp_new_ptr();
632
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
634
tcg_temp_free_ptr(tmp);
636
#undef gen_pas_helper
637
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
650
#undef gen_pas_helper
655
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
656
#define PAS_OP(pfx) \
658
case 0: gen_pas_helper(glue(pfx,add8)); break; \
659
case 1: gen_pas_helper(glue(pfx,add16)); break; \
660
case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
661
case 4: gen_pas_helper(glue(pfx,sub8)); break; \
662
case 5: gen_pas_helper(glue(pfx,sub16)); break; \
663
case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
665
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
670
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
672
tmp = tcg_temp_new_ptr();
673
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
675
tcg_temp_free_ptr(tmp);
678
tmp = tcg_temp_new_ptr();
679
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
681
tcg_temp_free_ptr(tmp);
683
#undef gen_pas_helper
684
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
697
#undef gen_pas_helper
702
static void gen_test_cc(int cc, int label)
709
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
712
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
715
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
718
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
721
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
724
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
727
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
730
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
732
case 8: /* hi: C && !Z */
733
inv = gen_new_label();
734
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
735
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
738
case 9: /* ls: !C || Z */
739
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
740
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
742
case 10: /* ge: N == V -> N ^ V == 0 */
743
tmp = tcg_temp_new_i32();
744
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
745
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
746
tcg_temp_free_i32(tmp);
748
case 11: /* lt: N != V -> N ^ V != 0 */
749
tmp = tcg_temp_new_i32();
750
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
751
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
752
tcg_temp_free_i32(tmp);
754
case 12: /* gt: !Z && N == V */
755
inv = gen_new_label();
756
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
757
tmp = tcg_temp_new_i32();
758
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
759
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
760
tcg_temp_free_i32(tmp);
763
case 13: /* le: Z || N != V */
764
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
765
tmp = tcg_temp_new_i32();
766
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
767
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
768
tcg_temp_free_i32(tmp);
771
fprintf(stderr, "Bad condition code 0x%x\n", cc);
776
static const uint8_t table_logic_cc[16] = {
795
/* Set PC and Thumb state from an immediate address. */
796
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
800
s->is_jmp = DISAS_UPDATE;
801
if (s->thumb != (addr & 1)) {
802
tmp = tcg_temp_new_i32();
803
tcg_gen_movi_i32(tmp, addr & 1);
804
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
805
tcg_temp_free_i32(tmp);
807
tcg_gen_movi_i32(cpu_R[15], addr & ~1);
810
/* Set PC and Thumb state from var. var is marked as dead. */
811
static inline void gen_bx(DisasContext *s, TCGv_i32 var)
813
s->is_jmp = DISAS_UPDATE;
814
tcg_gen_andi_i32(cpu_R[15], var, ~1);
815
tcg_gen_andi_i32(var, var, 1);
816
store_cpu_field(var, thumb);
819
/* Variant of store_reg which uses branch&exchange logic when storing
820
to r15 in ARM architecture v7 and above. The source must be a temporary
821
and will be marked as dead. */
822
static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
823
int reg, TCGv_i32 var)
825
if (reg == 15 && ENABLE_ARCH_7) {
828
store_reg(s, reg, var);
832
/* Variant of store_reg which uses branch&exchange logic when storing
833
* to r15 in ARM architecture v5T and above. This is used for storing
834
* the results of a LDR/LDM/POP into r15, and corresponds to the cases
835
* in the ARM ARM which use the LoadWritePC() pseudocode function. */
836
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
837
int reg, TCGv_i32 var)
839
if (reg == 15 && ENABLE_ARCH_5) {
842
store_reg(s, reg, var);
846
static inline void gen_smc(CPUARMState *env, DisasContext *s)
848
tcg_gen_movi_i32(cpu_R[15], s->pc);
849
s->is_jmp = DISAS_SMC;
852
static inline void gen_set_pc_im(uint32_t val)
854
tcg_gen_movi_i32(cpu_R[15], val);
857
/* Force a TB lookup after an instruction that changes the CPU state. */
858
static inline void gen_lookup_tb(DisasContext *s)
860
tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
861
s->is_jmp = DISAS_UPDATE;
864
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
867
int val, rm, shift, shiftop;
870
if (!(insn & (1 << 25))) {
873
if (!(insn & (1 << 23)))
876
tcg_gen_addi_i32(var, var, val);
880
shift = (insn >> 7) & 0x1f;
881
shiftop = (insn >> 5) & 3;
882
offset = load_reg(s, rm);
883
gen_arm_shift_im(offset, shiftop, shift, 0);
884
if (!(insn & (1 << 23)))
885
tcg_gen_sub_i32(var, var, offset);
887
tcg_gen_add_i32(var, var, offset);
888
tcg_temp_free_i32(offset);
892
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
893
int extra, TCGv_i32 var)
898
if (insn & (1 << 22)) {
900
val = (insn & 0xf) | ((insn >> 4) & 0xf0);
901
if (!(insn & (1 << 23)))
905
tcg_gen_addi_i32(var, var, val);
909
tcg_gen_addi_i32(var, var, extra);
911
offset = load_reg(s, rm);
912
if (!(insn & (1 << 23)))
913
tcg_gen_sub_i32(var, var, offset);
915
tcg_gen_add_i32(var, var, offset);
916
tcg_temp_free_i32(offset);
920
static TCGv_ptr get_fpstatus_ptr(int neon)
922
TCGv_ptr statusptr = tcg_temp_new_ptr();
925
offset = offsetof(CPUARMState, vfp.standard_fp_status);
927
offset = offsetof(CPUARMState, vfp.fp_status);
929
tcg_gen_addi_ptr(statusptr, cpu_env, offset);
933
#define VFP_OP2(name) \
934
static inline void gen_vfp_##name(int dp) \
936
TCGv_ptr fpst = get_fpstatus_ptr(0); \
938
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
940
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
942
tcg_temp_free_ptr(fpst); \
952
static inline void gen_vfp_F1_mul(int dp)
954
/* Like gen_vfp_mul() but put result in F1 */
955
TCGv_ptr fpst = get_fpstatus_ptr(0);
957
gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
959
gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
961
tcg_temp_free_ptr(fpst);
964
static inline void gen_vfp_F1_neg(int dp)
966
/* Like gen_vfp_neg() but put result in F1 */
968
gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
970
gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
974
static inline void gen_vfp_abs(int dp)
977
gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
979
gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
982
static inline void gen_vfp_neg(int dp)
985
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
987
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
990
static inline void gen_vfp_sqrt(int dp)
993
gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
995
gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
998
static inline void gen_vfp_cmp(int dp)
1001
gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1003
gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1006
static inline void gen_vfp_cmpe(int dp)
1009
gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1011
gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1014
static inline void gen_vfp_F1_ld0(int dp)
1017
tcg_gen_movi_i64(cpu_F1d, 0);
1019
tcg_gen_movi_i32(cpu_F1s, 0);
1022
#define VFP_GEN_ITOF(name) \
1023
static inline void gen_vfp_##name(int dp, int neon) \
1025
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1027
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1029
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1031
tcg_temp_free_ptr(statusptr); \
1038
#define VFP_GEN_FTOI(name) \
1039
static inline void gen_vfp_##name(int dp, int neon) \
1041
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1043
gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1045
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1047
tcg_temp_free_ptr(statusptr); \
1056
#define VFP_GEN_FIX(name) \
1057
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1059
TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1060
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1062
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1064
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1066
tcg_temp_free_i32(tmp_shift); \
1067
tcg_temp_free_ptr(statusptr); \
1079
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1082
tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1084
tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1087
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1090
tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1092
tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1096
vfp_reg_offset (int dp, int reg)
1099
return offsetof(CPUARMState, vfp.regs[reg]);
1101
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1102
+ offsetof(CPU_DoubleU, l.upper);
1104
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1105
+ offsetof(CPU_DoubleU, l.lower);
1109
/* Return the offset of a 32-bit piece of a NEON register.
1110
zero is the least significant end of the register. */
1112
neon_reg_offset (int reg, int n)
1116
return vfp_reg_offset(0, sreg);
1119
static TCGv_i32 neon_load_reg(int reg, int pass)
1121
TCGv_i32 tmp = tcg_temp_new_i32();
1122
tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1126
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1128
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1129
tcg_temp_free_i32(var);
1132
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1134
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1137
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1139
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1142
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1143
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1144
#define tcg_gen_st_f32 tcg_gen_st_i32
1145
#define tcg_gen_st_f64 tcg_gen_st_i64
1147
static inline void gen_mov_F0_vreg(int dp, int reg)
1150
tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1152
tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1155
static inline void gen_mov_F1_vreg(int dp, int reg)
1158
tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1160
tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1163
static inline void gen_mov_vreg_F0(int dp, int reg)
1166
tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1168
tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1171
#define ARM_CP_RW_BIT (1 << 20)
1173
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1175
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1178
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1180
tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1183
static inline TCGv_i32 iwmmxt_load_creg(int reg)
1185
TCGv_i32 var = tcg_temp_new_i32();
1186
tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1190
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1192
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1193
tcg_temp_free_i32(var);
1196
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1198
iwmmxt_store_reg(cpu_M0, rn);
1201
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1203
iwmmxt_load_reg(cpu_M0, rn);
1206
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1208
iwmmxt_load_reg(cpu_V1, rn);
1209
tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1212
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1214
iwmmxt_load_reg(cpu_V1, rn);
1215
tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1218
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1220
iwmmxt_load_reg(cpu_V1, rn);
1221
tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1224
#define IWMMXT_OP(name) \
1225
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1227
iwmmxt_load_reg(cpu_V1, rn); \
1228
gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1231
#define IWMMXT_OP_ENV(name) \
1232
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1234
iwmmxt_load_reg(cpu_V1, rn); \
1235
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1238
#define IWMMXT_OP_ENV_SIZE(name) \
1239
IWMMXT_OP_ENV(name##b) \
1240
IWMMXT_OP_ENV(name##w) \
1241
IWMMXT_OP_ENV(name##l)
1243
#define IWMMXT_OP_ENV1(name) \
1244
static inline void gen_op_iwmmxt_##name##_M0(void) \
1246
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1260
IWMMXT_OP_ENV_SIZE(unpackl)
1261
IWMMXT_OP_ENV_SIZE(unpackh)
1263
IWMMXT_OP_ENV1(unpacklub)
1264
IWMMXT_OP_ENV1(unpackluw)
1265
IWMMXT_OP_ENV1(unpacklul)
1266
IWMMXT_OP_ENV1(unpackhub)
1267
IWMMXT_OP_ENV1(unpackhuw)
1268
IWMMXT_OP_ENV1(unpackhul)
1269
IWMMXT_OP_ENV1(unpacklsb)
1270
IWMMXT_OP_ENV1(unpacklsw)
1271
IWMMXT_OP_ENV1(unpacklsl)
1272
IWMMXT_OP_ENV1(unpackhsb)
1273
IWMMXT_OP_ENV1(unpackhsw)
1274
IWMMXT_OP_ENV1(unpackhsl)
1276
IWMMXT_OP_ENV_SIZE(cmpeq)
1277
IWMMXT_OP_ENV_SIZE(cmpgtu)
1278
IWMMXT_OP_ENV_SIZE(cmpgts)
1280
IWMMXT_OP_ENV_SIZE(mins)
1281
IWMMXT_OP_ENV_SIZE(minu)
1282
IWMMXT_OP_ENV_SIZE(maxs)
1283
IWMMXT_OP_ENV_SIZE(maxu)
1285
IWMMXT_OP_ENV_SIZE(subn)
1286
IWMMXT_OP_ENV_SIZE(addn)
1287
IWMMXT_OP_ENV_SIZE(subu)
1288
IWMMXT_OP_ENV_SIZE(addu)
1289
IWMMXT_OP_ENV_SIZE(subs)
1290
IWMMXT_OP_ENV_SIZE(adds)
1292
IWMMXT_OP_ENV(avgb0)
1293
IWMMXT_OP_ENV(avgb1)
1294
IWMMXT_OP_ENV(avgw0)
1295
IWMMXT_OP_ENV(avgw1)
1299
IWMMXT_OP_ENV(packuw)
1300
IWMMXT_OP_ENV(packul)
1301
IWMMXT_OP_ENV(packuq)
1302
IWMMXT_OP_ENV(packsw)
1303
IWMMXT_OP_ENV(packsl)
1304
IWMMXT_OP_ENV(packsq)
1306
static void gen_op_iwmmxt_set_mup(void)
1309
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1310
tcg_gen_ori_i32(tmp, tmp, 2);
1311
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1314
static void gen_op_iwmmxt_set_cup(void)
1317
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1318
tcg_gen_ori_i32(tmp, tmp, 1);
1319
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1322
static void gen_op_iwmmxt_setpsr_nz(void)
1324
TCGv_i32 tmp = tcg_temp_new_i32();
1325
gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1326
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1329
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1331
iwmmxt_load_reg(cpu_V1, rn);
1332
tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1333
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1336
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1343
rd = (insn >> 16) & 0xf;
1344
tmp = load_reg(s, rd);
1346
offset = (insn & 0xff) << ((insn >> 7) & 2);
1347
if (insn & (1 << 24)) {
1349
if (insn & (1 << 23))
1350
tcg_gen_addi_i32(tmp, tmp, offset);
1352
tcg_gen_addi_i32(tmp, tmp, -offset);
1353
tcg_gen_mov_i32(dest, tmp);
1354
if (insn & (1 << 21))
1355
store_reg(s, rd, tmp);
1357
tcg_temp_free_i32(tmp);
1358
} else if (insn & (1 << 21)) {
1360
tcg_gen_mov_i32(dest, tmp);
1361
if (insn & (1 << 23))
1362
tcg_gen_addi_i32(tmp, tmp, offset);
1364
tcg_gen_addi_i32(tmp, tmp, -offset);
1365
store_reg(s, rd, tmp);
1366
} else if (!(insn & (1 << 23)))
1371
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1373
int rd = (insn >> 0) & 0xf;
1376
if (insn & (1 << 8)) {
1377
if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1380
tmp = iwmmxt_load_creg(rd);
1383
tmp = tcg_temp_new_i32();
1384
iwmmxt_load_reg(cpu_V0, rd);
1385
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1387
tcg_gen_andi_i32(tmp, tmp, mask);
1388
tcg_gen_mov_i32(dest, tmp);
1389
tcg_temp_free_i32(tmp);
1393
/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1394
(ie. an undefined instruction). */
1395
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1398
int rdhi, rdlo, rd0, rd1, i;
1400
TCGv_i32 tmp, tmp2, tmp3;
1402
if ((insn & 0x0e000e00) == 0x0c000000) {
1403
if ((insn & 0x0fe00ff0) == 0x0c400000) {
1405
rdlo = (insn >> 12) & 0xf;
1406
rdhi = (insn >> 16) & 0xf;
1407
if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1408
iwmmxt_load_reg(cpu_V0, wrd);
1409
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1410
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1411
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1412
} else { /* TMCRR */
1413
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1414
iwmmxt_store_reg(cpu_V0, wrd);
1415
gen_op_iwmmxt_set_mup();
1420
wrd = (insn >> 12) & 0xf;
1421
addr = tcg_temp_new_i32();
1422
if (gen_iwmmxt_address(s, insn, addr)) {
1423
tcg_temp_free_i32(addr);
1426
if (insn & ARM_CP_RW_BIT) {
1427
if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1428
tmp = tcg_temp_new_i32();
1429
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
1430
iwmmxt_store_creg(wrd, tmp);
1433
if (insn & (1 << 8)) {
1434
if (insn & (1 << 22)) { /* WLDRD */
1435
tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s));
1437
} else { /* WLDRW wRd */
1438
tmp = tcg_temp_new_i32();
1439
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
1442
tmp = tcg_temp_new_i32();
1443
if (insn & (1 << 22)) { /* WLDRH */
1444
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
1445
} else { /* WLDRB */
1446
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
1450
tcg_gen_extu_i32_i64(cpu_M0, tmp);
1451
tcg_temp_free_i32(tmp);
1453
gen_op_iwmmxt_movq_wRn_M0(wrd);
1456
if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1457
tmp = iwmmxt_load_creg(wrd);
1458
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
1460
gen_op_iwmmxt_movq_M0_wRn(wrd);
1461
tmp = tcg_temp_new_i32();
1462
if (insn & (1 << 8)) {
1463
if (insn & (1 << 22)) { /* WSTRD */
1464
tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s));
1465
} else { /* WSTRW wRd */
1466
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1467
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
1470
if (insn & (1 << 22)) { /* WSTRH */
1471
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1472
tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
1473
} else { /* WSTRB */
1474
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1475
tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
1479
tcg_temp_free_i32(tmp);
1481
tcg_temp_free_i32(addr);
1485
if ((insn & 0x0f000000) != 0x0e000000)
1488
switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1489
case 0x000: /* WOR */
1490
wrd = (insn >> 12) & 0xf;
1491
rd0 = (insn >> 0) & 0xf;
1492
rd1 = (insn >> 16) & 0xf;
1493
gen_op_iwmmxt_movq_M0_wRn(rd0);
1494
gen_op_iwmmxt_orq_M0_wRn(rd1);
1495
gen_op_iwmmxt_setpsr_nz();
1496
gen_op_iwmmxt_movq_wRn_M0(wrd);
1497
gen_op_iwmmxt_set_mup();
1498
gen_op_iwmmxt_set_cup();
1500
case 0x011: /* TMCR */
1503
rd = (insn >> 12) & 0xf;
1504
wrd = (insn >> 16) & 0xf;
1506
case ARM_IWMMXT_wCID:
1507
case ARM_IWMMXT_wCASF:
1509
case ARM_IWMMXT_wCon:
1510
gen_op_iwmmxt_set_cup();
1512
case ARM_IWMMXT_wCSSF:
1513
tmp = iwmmxt_load_creg(wrd);
1514
tmp2 = load_reg(s, rd);
1515
tcg_gen_andc_i32(tmp, tmp, tmp2);
1516
tcg_temp_free_i32(tmp2);
1517
iwmmxt_store_creg(wrd, tmp);
1519
case ARM_IWMMXT_wCGR0:
1520
case ARM_IWMMXT_wCGR1:
1521
case ARM_IWMMXT_wCGR2:
1522
case ARM_IWMMXT_wCGR3:
1523
gen_op_iwmmxt_set_cup();
1524
tmp = load_reg(s, rd);
1525
iwmmxt_store_creg(wrd, tmp);
1531
case 0x100: /* WXOR */
1532
wrd = (insn >> 12) & 0xf;
1533
rd0 = (insn >> 0) & 0xf;
1534
rd1 = (insn >> 16) & 0xf;
1535
gen_op_iwmmxt_movq_M0_wRn(rd0);
1536
gen_op_iwmmxt_xorq_M0_wRn(rd1);
1537
gen_op_iwmmxt_setpsr_nz();
1538
gen_op_iwmmxt_movq_wRn_M0(wrd);
1539
gen_op_iwmmxt_set_mup();
1540
gen_op_iwmmxt_set_cup();
1542
case 0x111: /* TMRC */
1545
rd = (insn >> 12) & 0xf;
1546
wrd = (insn >> 16) & 0xf;
1547
tmp = iwmmxt_load_creg(wrd);
1548
store_reg(s, rd, tmp);
1550
case 0x300: /* WANDN */
1551
wrd = (insn >> 12) & 0xf;
1552
rd0 = (insn >> 0) & 0xf;
1553
rd1 = (insn >> 16) & 0xf;
1554
gen_op_iwmmxt_movq_M0_wRn(rd0);
1555
tcg_gen_neg_i64(cpu_M0, cpu_M0);
1556
gen_op_iwmmxt_andq_M0_wRn(rd1);
1557
gen_op_iwmmxt_setpsr_nz();
1558
gen_op_iwmmxt_movq_wRn_M0(wrd);
1559
gen_op_iwmmxt_set_mup();
1560
gen_op_iwmmxt_set_cup();
1562
case 0x200: /* WAND */
1563
wrd = (insn >> 12) & 0xf;
1564
rd0 = (insn >> 0) & 0xf;
1565
rd1 = (insn >> 16) & 0xf;
1566
gen_op_iwmmxt_movq_M0_wRn(rd0);
1567
gen_op_iwmmxt_andq_M0_wRn(rd1);
1568
gen_op_iwmmxt_setpsr_nz();
1569
gen_op_iwmmxt_movq_wRn_M0(wrd);
1570
gen_op_iwmmxt_set_mup();
1571
gen_op_iwmmxt_set_cup();
1573
case 0x810: case 0xa10: /* WMADD */
1574
wrd = (insn >> 12) & 0xf;
1575
rd0 = (insn >> 0) & 0xf;
1576
rd1 = (insn >> 16) & 0xf;
1577
gen_op_iwmmxt_movq_M0_wRn(rd0);
1578
if (insn & (1 << 21))
1579
gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1581
gen_op_iwmmxt_madduq_M0_wRn(rd1);
1582
gen_op_iwmmxt_movq_wRn_M0(wrd);
1583
gen_op_iwmmxt_set_mup();
1585
case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1586
wrd = (insn >> 12) & 0xf;
1587
rd0 = (insn >> 16) & 0xf;
1588
rd1 = (insn >> 0) & 0xf;
1589
gen_op_iwmmxt_movq_M0_wRn(rd0);
1590
switch ((insn >> 22) & 3) {
1592
gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1595
gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1598
gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1603
gen_op_iwmmxt_movq_wRn_M0(wrd);
1604
gen_op_iwmmxt_set_mup();
1605
gen_op_iwmmxt_set_cup();
1607
case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1608
wrd = (insn >> 12) & 0xf;
1609
rd0 = (insn >> 16) & 0xf;
1610
rd1 = (insn >> 0) & 0xf;
1611
gen_op_iwmmxt_movq_M0_wRn(rd0);
1612
switch ((insn >> 22) & 3) {
1614
gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1617
gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1620
gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1625
gen_op_iwmmxt_movq_wRn_M0(wrd);
1626
gen_op_iwmmxt_set_mup();
1627
gen_op_iwmmxt_set_cup();
1629
case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1630
wrd = (insn >> 12) & 0xf;
1631
rd0 = (insn >> 16) & 0xf;
1632
rd1 = (insn >> 0) & 0xf;
1633
gen_op_iwmmxt_movq_M0_wRn(rd0);
1634
if (insn & (1 << 22))
1635
gen_op_iwmmxt_sadw_M0_wRn(rd1);
1637
gen_op_iwmmxt_sadb_M0_wRn(rd1);
1638
if (!(insn & (1 << 20)))
1639
gen_op_iwmmxt_addl_M0_wRn(wrd);
1640
gen_op_iwmmxt_movq_wRn_M0(wrd);
1641
gen_op_iwmmxt_set_mup();
1643
case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1644
wrd = (insn >> 12) & 0xf;
1645
rd0 = (insn >> 16) & 0xf;
1646
rd1 = (insn >> 0) & 0xf;
1647
gen_op_iwmmxt_movq_M0_wRn(rd0);
1648
if (insn & (1 << 21)) {
1649
if (insn & (1 << 20))
1650
gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1652
gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1654
if (insn & (1 << 20))
1655
gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1657
gen_op_iwmmxt_mululw_M0_wRn(rd1);
1659
gen_op_iwmmxt_movq_wRn_M0(wrd);
1660
gen_op_iwmmxt_set_mup();
1662
case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1663
wrd = (insn >> 12) & 0xf;
1664
rd0 = (insn >> 16) & 0xf;
1665
rd1 = (insn >> 0) & 0xf;
1666
gen_op_iwmmxt_movq_M0_wRn(rd0);
1667
if (insn & (1 << 21))
1668
gen_op_iwmmxt_macsw_M0_wRn(rd1);
1670
gen_op_iwmmxt_macuw_M0_wRn(rd1);
1671
if (!(insn & (1 << 20))) {
1672
iwmmxt_load_reg(cpu_V1, wrd);
1673
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1675
gen_op_iwmmxt_movq_wRn_M0(wrd);
1676
gen_op_iwmmxt_set_mup();
1678
case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1679
wrd = (insn >> 12) & 0xf;
1680
rd0 = (insn >> 16) & 0xf;
1681
rd1 = (insn >> 0) & 0xf;
1682
gen_op_iwmmxt_movq_M0_wRn(rd0);
1683
switch ((insn >> 22) & 3) {
1685
gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1688
gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1691
gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1696
gen_op_iwmmxt_movq_wRn_M0(wrd);
1697
gen_op_iwmmxt_set_mup();
1698
gen_op_iwmmxt_set_cup();
1700
case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1701
wrd = (insn >> 12) & 0xf;
1702
rd0 = (insn >> 16) & 0xf;
1703
rd1 = (insn >> 0) & 0xf;
1704
gen_op_iwmmxt_movq_M0_wRn(rd0);
1705
if (insn & (1 << 22)) {
1706
if (insn & (1 << 20))
1707
gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1709
gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1711
if (insn & (1 << 20))
1712
gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1714
gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1716
gen_op_iwmmxt_movq_wRn_M0(wrd);
1717
gen_op_iwmmxt_set_mup();
1718
gen_op_iwmmxt_set_cup();
1720
case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1721
wrd = (insn >> 12) & 0xf;
1722
rd0 = (insn >> 16) & 0xf;
1723
rd1 = (insn >> 0) & 0xf;
1724
gen_op_iwmmxt_movq_M0_wRn(rd0);
1725
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1726
tcg_gen_andi_i32(tmp, tmp, 7);
1727
iwmmxt_load_reg(cpu_V1, rd1);
1728
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1729
tcg_temp_free_i32(tmp);
1730
gen_op_iwmmxt_movq_wRn_M0(wrd);
1731
gen_op_iwmmxt_set_mup();
1733
case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1734
if (((insn >> 6) & 3) == 3)
1736
rd = (insn >> 12) & 0xf;
1737
wrd = (insn >> 16) & 0xf;
1738
tmp = load_reg(s, rd);
1739
gen_op_iwmmxt_movq_M0_wRn(wrd);
1740
switch ((insn >> 6) & 3) {
1742
tmp2 = tcg_const_i32(0xff);
1743
tmp3 = tcg_const_i32((insn & 7) << 3);
1746
tmp2 = tcg_const_i32(0xffff);
1747
tmp3 = tcg_const_i32((insn & 3) << 4);
1750
tmp2 = tcg_const_i32(0xffffffff);
1751
tmp3 = tcg_const_i32((insn & 1) << 5);
1754
TCGV_UNUSED_I32(tmp2);
1755
TCGV_UNUSED_I32(tmp3);
1757
gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1758
tcg_temp_free_i32(tmp3);
1759
tcg_temp_free_i32(tmp2);
1760
tcg_temp_free_i32(tmp);
1761
gen_op_iwmmxt_movq_wRn_M0(wrd);
1762
gen_op_iwmmxt_set_mup();
1764
case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1765
rd = (insn >> 12) & 0xf;
1766
wrd = (insn >> 16) & 0xf;
1767
if (rd == 15 || ((insn >> 22) & 3) == 3)
1769
gen_op_iwmmxt_movq_M0_wRn(wrd);
1770
tmp = tcg_temp_new_i32();
1771
switch ((insn >> 22) & 3) {
1773
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1774
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1776
tcg_gen_ext8s_i32(tmp, tmp);
1778
tcg_gen_andi_i32(tmp, tmp, 0xff);
1782
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1783
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1785
tcg_gen_ext16s_i32(tmp, tmp);
1787
tcg_gen_andi_i32(tmp, tmp, 0xffff);
1791
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1792
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1795
store_reg(s, rd, tmp);
1797
case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1798
if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1800
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1801
switch ((insn >> 22) & 3) {
1803
tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1806
tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1809
tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1812
tcg_gen_shli_i32(tmp, tmp, 28);
1814
tcg_temp_free_i32(tmp);
1816
case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1817
if (((insn >> 6) & 3) == 3)
1819
rd = (insn >> 12) & 0xf;
1820
wrd = (insn >> 16) & 0xf;
1821
tmp = load_reg(s, rd);
1822
switch ((insn >> 6) & 3) {
1824
gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1827
gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1830
gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1833
tcg_temp_free_i32(tmp);
1834
gen_op_iwmmxt_movq_wRn_M0(wrd);
1835
gen_op_iwmmxt_set_mup();
1837
case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1838
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1840
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1841
tmp2 = tcg_temp_new_i32();
1842
tcg_gen_mov_i32(tmp2, tmp);
1843
switch ((insn >> 22) & 3) {
1845
for (i = 0; i < 7; i ++) {
1846
tcg_gen_shli_i32(tmp2, tmp2, 4);
1847
tcg_gen_and_i32(tmp, tmp, tmp2);
1851
for (i = 0; i < 3; i ++) {
1852
tcg_gen_shli_i32(tmp2, tmp2, 8);
1853
tcg_gen_and_i32(tmp, tmp, tmp2);
1857
tcg_gen_shli_i32(tmp2, tmp2, 16);
1858
tcg_gen_and_i32(tmp, tmp, tmp2);
1862
tcg_temp_free_i32(tmp2);
1863
tcg_temp_free_i32(tmp);
1865
case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1866
wrd = (insn >> 12) & 0xf;
1867
rd0 = (insn >> 16) & 0xf;
1868
gen_op_iwmmxt_movq_M0_wRn(rd0);
1869
switch ((insn >> 22) & 3) {
1871
gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1874
gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1877
gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1882
gen_op_iwmmxt_movq_wRn_M0(wrd);
1883
gen_op_iwmmxt_set_mup();
1885
case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1886
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1888
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1889
tmp2 = tcg_temp_new_i32();
1890
tcg_gen_mov_i32(tmp2, tmp);
1891
switch ((insn >> 22) & 3) {
1893
for (i = 0; i < 7; i ++) {
1894
tcg_gen_shli_i32(tmp2, tmp2, 4);
1895
tcg_gen_or_i32(tmp, tmp, tmp2);
1899
for (i = 0; i < 3; i ++) {
1900
tcg_gen_shli_i32(tmp2, tmp2, 8);
1901
tcg_gen_or_i32(tmp, tmp, tmp2);
1905
tcg_gen_shli_i32(tmp2, tmp2, 16);
1906
tcg_gen_or_i32(tmp, tmp, tmp2);
1910
tcg_temp_free_i32(tmp2);
1911
tcg_temp_free_i32(tmp);
1913
case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1914
rd = (insn >> 12) & 0xf;
1915
rd0 = (insn >> 16) & 0xf;
1916
if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1918
gen_op_iwmmxt_movq_M0_wRn(rd0);
1919
tmp = tcg_temp_new_i32();
1920
switch ((insn >> 22) & 3) {
1922
gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1925
gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1928
gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1931
store_reg(s, rd, tmp);
1933
case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1934
case 0x906: case 0xb06: case 0xd06: case 0xf06:
1935
wrd = (insn >> 12) & 0xf;
1936
rd0 = (insn >> 16) & 0xf;
1937
rd1 = (insn >> 0) & 0xf;
1938
gen_op_iwmmxt_movq_M0_wRn(rd0);
1939
switch ((insn >> 22) & 3) {
1941
if (insn & (1 << 21))
1942
gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1944
gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1947
if (insn & (1 << 21))
1948
gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1950
gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
1953
if (insn & (1 << 21))
1954
gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
1956
gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
1961
gen_op_iwmmxt_movq_wRn_M0(wrd);
1962
gen_op_iwmmxt_set_mup();
1963
gen_op_iwmmxt_set_cup();
1965
case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1966
case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1967
wrd = (insn >> 12) & 0xf;
1968
rd0 = (insn >> 16) & 0xf;
1969
gen_op_iwmmxt_movq_M0_wRn(rd0);
1970
switch ((insn >> 22) & 3) {
1972
if (insn & (1 << 21))
1973
gen_op_iwmmxt_unpacklsb_M0();
1975
gen_op_iwmmxt_unpacklub_M0();
1978
if (insn & (1 << 21))
1979
gen_op_iwmmxt_unpacklsw_M0();
1981
gen_op_iwmmxt_unpackluw_M0();
1984
if (insn & (1 << 21))
1985
gen_op_iwmmxt_unpacklsl_M0();
1987
gen_op_iwmmxt_unpacklul_M0();
1992
gen_op_iwmmxt_movq_wRn_M0(wrd);
1993
gen_op_iwmmxt_set_mup();
1994
gen_op_iwmmxt_set_cup();
1996
case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
1997
case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
1998
wrd = (insn >> 12) & 0xf;
1999
rd0 = (insn >> 16) & 0xf;
2000
gen_op_iwmmxt_movq_M0_wRn(rd0);
2001
switch ((insn >> 22) & 3) {
2003
if (insn & (1 << 21))
2004
gen_op_iwmmxt_unpackhsb_M0();
2006
gen_op_iwmmxt_unpackhub_M0();
2009
if (insn & (1 << 21))
2010
gen_op_iwmmxt_unpackhsw_M0();
2012
gen_op_iwmmxt_unpackhuw_M0();
2015
if (insn & (1 << 21))
2016
gen_op_iwmmxt_unpackhsl_M0();
2018
gen_op_iwmmxt_unpackhul_M0();
2023
gen_op_iwmmxt_movq_wRn_M0(wrd);
2024
gen_op_iwmmxt_set_mup();
2025
gen_op_iwmmxt_set_cup();
2027
case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2028
case 0x214: case 0x614: case 0xa14: case 0xe14:
2029
if (((insn >> 22) & 3) == 0)
2031
wrd = (insn >> 12) & 0xf;
2032
rd0 = (insn >> 16) & 0xf;
2033
gen_op_iwmmxt_movq_M0_wRn(rd0);
2034
tmp = tcg_temp_new_i32();
2035
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2036
tcg_temp_free_i32(tmp);
2039
switch ((insn >> 22) & 3) {
2041
gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2044
gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2047
gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2050
tcg_temp_free_i32(tmp);
2051
gen_op_iwmmxt_movq_wRn_M0(wrd);
2052
gen_op_iwmmxt_set_mup();
2053
gen_op_iwmmxt_set_cup();
2055
case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2056
case 0x014: case 0x414: case 0x814: case 0xc14:
2057
if (((insn >> 22) & 3) == 0)
2059
wrd = (insn >> 12) & 0xf;
2060
rd0 = (insn >> 16) & 0xf;
2061
gen_op_iwmmxt_movq_M0_wRn(rd0);
2062
tmp = tcg_temp_new_i32();
2063
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2064
tcg_temp_free_i32(tmp);
2067
switch ((insn >> 22) & 3) {
2069
gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2072
gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2075
gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2078
tcg_temp_free_i32(tmp);
2079
gen_op_iwmmxt_movq_wRn_M0(wrd);
2080
gen_op_iwmmxt_set_mup();
2081
gen_op_iwmmxt_set_cup();
2083
case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2084
case 0x114: case 0x514: case 0x914: case 0xd14:
2085
if (((insn >> 22) & 3) == 0)
2087
wrd = (insn >> 12) & 0xf;
2088
rd0 = (insn >> 16) & 0xf;
2089
gen_op_iwmmxt_movq_M0_wRn(rd0);
2090
tmp = tcg_temp_new_i32();
2091
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2092
tcg_temp_free_i32(tmp);
2095
switch ((insn >> 22) & 3) {
2097
gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2100
gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2103
gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2106
tcg_temp_free_i32(tmp);
2107
gen_op_iwmmxt_movq_wRn_M0(wrd);
2108
gen_op_iwmmxt_set_mup();
2109
gen_op_iwmmxt_set_cup();
2111
case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2112
case 0x314: case 0x714: case 0xb14: case 0xf14:
2113
if (((insn >> 22) & 3) == 0)
2115
wrd = (insn >> 12) & 0xf;
2116
rd0 = (insn >> 16) & 0xf;
2117
gen_op_iwmmxt_movq_M0_wRn(rd0);
2118
tmp = tcg_temp_new_i32();
2119
switch ((insn >> 22) & 3) {
2121
if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2122
tcg_temp_free_i32(tmp);
2125
gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2128
if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2129
tcg_temp_free_i32(tmp);
2132
gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2135
if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2136
tcg_temp_free_i32(tmp);
2139
gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2142
tcg_temp_free_i32(tmp);
2143
gen_op_iwmmxt_movq_wRn_M0(wrd);
2144
gen_op_iwmmxt_set_mup();
2145
gen_op_iwmmxt_set_cup();
2147
case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2148
case 0x916: case 0xb16: case 0xd16: case 0xf16:
2149
wrd = (insn >> 12) & 0xf;
2150
rd0 = (insn >> 16) & 0xf;
2151
rd1 = (insn >> 0) & 0xf;
2152
gen_op_iwmmxt_movq_M0_wRn(rd0);
2153
switch ((insn >> 22) & 3) {
2155
if (insn & (1 << 21))
2156
gen_op_iwmmxt_minsb_M0_wRn(rd1);
2158
gen_op_iwmmxt_minub_M0_wRn(rd1);
2161
if (insn & (1 << 21))
2162
gen_op_iwmmxt_minsw_M0_wRn(rd1);
2164
gen_op_iwmmxt_minuw_M0_wRn(rd1);
2167
if (insn & (1 << 21))
2168
gen_op_iwmmxt_minsl_M0_wRn(rd1);
2170
gen_op_iwmmxt_minul_M0_wRn(rd1);
2175
gen_op_iwmmxt_movq_wRn_M0(wrd);
2176
gen_op_iwmmxt_set_mup();
2178
case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2179
case 0x816: case 0xa16: case 0xc16: case 0xe16:
2180
wrd = (insn >> 12) & 0xf;
2181
rd0 = (insn >> 16) & 0xf;
2182
rd1 = (insn >> 0) & 0xf;
2183
gen_op_iwmmxt_movq_M0_wRn(rd0);
2184
switch ((insn >> 22) & 3) {
2186
if (insn & (1 << 21))
2187
gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2189
gen_op_iwmmxt_maxub_M0_wRn(rd1);
2192
if (insn & (1 << 21))
2193
gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2195
gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2198
if (insn & (1 << 21))
2199
gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2201
gen_op_iwmmxt_maxul_M0_wRn(rd1);
2206
gen_op_iwmmxt_movq_wRn_M0(wrd);
2207
gen_op_iwmmxt_set_mup();
2209
case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2210
case 0x402: case 0x502: case 0x602: case 0x702:
2211
wrd = (insn >> 12) & 0xf;
2212
rd0 = (insn >> 16) & 0xf;
2213
rd1 = (insn >> 0) & 0xf;
2214
gen_op_iwmmxt_movq_M0_wRn(rd0);
2215
tmp = tcg_const_i32((insn >> 20) & 3);
2216
iwmmxt_load_reg(cpu_V1, rd1);
2217
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2218
tcg_temp_free_i32(tmp);
2219
gen_op_iwmmxt_movq_wRn_M0(wrd);
2220
gen_op_iwmmxt_set_mup();
2222
case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2223
case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2224
case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2225
case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2226
wrd = (insn >> 12) & 0xf;
2227
rd0 = (insn >> 16) & 0xf;
2228
rd1 = (insn >> 0) & 0xf;
2229
gen_op_iwmmxt_movq_M0_wRn(rd0);
2230
switch ((insn >> 20) & 0xf) {
2232
gen_op_iwmmxt_subnb_M0_wRn(rd1);
2235
gen_op_iwmmxt_subub_M0_wRn(rd1);
2238
gen_op_iwmmxt_subsb_M0_wRn(rd1);
2241
gen_op_iwmmxt_subnw_M0_wRn(rd1);
2244
gen_op_iwmmxt_subuw_M0_wRn(rd1);
2247
gen_op_iwmmxt_subsw_M0_wRn(rd1);
2250
gen_op_iwmmxt_subnl_M0_wRn(rd1);
2253
gen_op_iwmmxt_subul_M0_wRn(rd1);
2256
gen_op_iwmmxt_subsl_M0_wRn(rd1);
2261
gen_op_iwmmxt_movq_wRn_M0(wrd);
2262
gen_op_iwmmxt_set_mup();
2263
gen_op_iwmmxt_set_cup();
2265
case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2266
case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2267
case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2268
case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2269
wrd = (insn >> 12) & 0xf;
2270
rd0 = (insn >> 16) & 0xf;
2271
gen_op_iwmmxt_movq_M0_wRn(rd0);
2272
tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2273
gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2274
tcg_temp_free_i32(tmp);
2275
gen_op_iwmmxt_movq_wRn_M0(wrd);
2276
gen_op_iwmmxt_set_mup();
2277
gen_op_iwmmxt_set_cup();
2279
case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2280
case 0x418: case 0x518: case 0x618: case 0x718:
2281
case 0x818: case 0x918: case 0xa18: case 0xb18:
2282
case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2283
wrd = (insn >> 12) & 0xf;
2284
rd0 = (insn >> 16) & 0xf;
2285
rd1 = (insn >> 0) & 0xf;
2286
gen_op_iwmmxt_movq_M0_wRn(rd0);
2287
switch ((insn >> 20) & 0xf) {
2289
gen_op_iwmmxt_addnb_M0_wRn(rd1);
2292
gen_op_iwmmxt_addub_M0_wRn(rd1);
2295
gen_op_iwmmxt_addsb_M0_wRn(rd1);
2298
gen_op_iwmmxt_addnw_M0_wRn(rd1);
2301
gen_op_iwmmxt_adduw_M0_wRn(rd1);
2304
gen_op_iwmmxt_addsw_M0_wRn(rd1);
2307
gen_op_iwmmxt_addnl_M0_wRn(rd1);
2310
gen_op_iwmmxt_addul_M0_wRn(rd1);
2313
gen_op_iwmmxt_addsl_M0_wRn(rd1);
2318
gen_op_iwmmxt_movq_wRn_M0(wrd);
2319
gen_op_iwmmxt_set_mup();
2320
gen_op_iwmmxt_set_cup();
2322
case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2323
case 0x408: case 0x508: case 0x608: case 0x708:
2324
case 0x808: case 0x908: case 0xa08: case 0xb08:
2325
case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2326
if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2328
wrd = (insn >> 12) & 0xf;
2329
rd0 = (insn >> 16) & 0xf;
2330
rd1 = (insn >> 0) & 0xf;
2331
gen_op_iwmmxt_movq_M0_wRn(rd0);
2332
switch ((insn >> 22) & 3) {
2334
if (insn & (1 << 21))
2335
gen_op_iwmmxt_packsw_M0_wRn(rd1);
2337
gen_op_iwmmxt_packuw_M0_wRn(rd1);
2340
if (insn & (1 << 21))
2341
gen_op_iwmmxt_packsl_M0_wRn(rd1);
2343
gen_op_iwmmxt_packul_M0_wRn(rd1);
2346
if (insn & (1 << 21))
2347
gen_op_iwmmxt_packsq_M0_wRn(rd1);
2349
gen_op_iwmmxt_packuq_M0_wRn(rd1);
2352
gen_op_iwmmxt_movq_wRn_M0(wrd);
2353
gen_op_iwmmxt_set_mup();
2354
gen_op_iwmmxt_set_cup();
2356
case 0x201: case 0x203: case 0x205: case 0x207:
2357
case 0x209: case 0x20b: case 0x20d: case 0x20f:
2358
case 0x211: case 0x213: case 0x215: case 0x217:
2359
case 0x219: case 0x21b: case 0x21d: case 0x21f:
2360
wrd = (insn >> 5) & 0xf;
2361
rd0 = (insn >> 12) & 0xf;
2362
rd1 = (insn >> 0) & 0xf;
2363
if (rd0 == 0xf || rd1 == 0xf)
2365
gen_op_iwmmxt_movq_M0_wRn(wrd);
2366
tmp = load_reg(s, rd0);
2367
tmp2 = load_reg(s, rd1);
2368
switch ((insn >> 16) & 0xf) {
2369
case 0x0: /* TMIA */
2370
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2372
case 0x8: /* TMIAPH */
2373
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2375
case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2376
if (insn & (1 << 16))
2377
tcg_gen_shri_i32(tmp, tmp, 16);
2378
if (insn & (1 << 17))
2379
tcg_gen_shri_i32(tmp2, tmp2, 16);
2380
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2383
tcg_temp_free_i32(tmp2);
2384
tcg_temp_free_i32(tmp);
2387
tcg_temp_free_i32(tmp2);
2388
tcg_temp_free_i32(tmp);
2389
gen_op_iwmmxt_movq_wRn_M0(wrd);
2390
gen_op_iwmmxt_set_mup();
2399
/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2400
(ie. an undefined instruction). */
2401
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2403
int acc, rd0, rd1, rdhi, rdlo;
2406
if ((insn & 0x0ff00f10) == 0x0e200010) {
2407
/* Multiply with Internal Accumulate Format */
2408
rd0 = (insn >> 12) & 0xf;
2410
acc = (insn >> 5) & 7;
2415
tmp = load_reg(s, rd0);
2416
tmp2 = load_reg(s, rd1);
2417
switch ((insn >> 16) & 0xf) {
2419
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2421
case 0x8: /* MIAPH */
2422
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2424
case 0xc: /* MIABB */
2425
case 0xd: /* MIABT */
2426
case 0xe: /* MIATB */
2427
case 0xf: /* MIATT */
2428
if (insn & (1 << 16))
2429
tcg_gen_shri_i32(tmp, tmp, 16);
2430
if (insn & (1 << 17))
2431
tcg_gen_shri_i32(tmp2, tmp2, 16);
2432
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2437
tcg_temp_free_i32(tmp2);
2438
tcg_temp_free_i32(tmp);
2440
gen_op_iwmmxt_movq_wRn_M0(acc);
2444
if ((insn & 0x0fe00ff8) == 0x0c400000) {
2445
/* Internal Accumulator Access Format */
2446
rdhi = (insn >> 16) & 0xf;
2447
rdlo = (insn >> 12) & 0xf;
2453
if (insn & ARM_CP_RW_BIT) { /* MRA */
2454
iwmmxt_load_reg(cpu_V0, acc);
2455
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2456
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2457
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2458
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2460
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2461
iwmmxt_store_reg(cpu_V0, acc);
2469
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2470
#define VFP_SREG(insn, bigbit, smallbit) \
2471
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2472
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2473
if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2474
reg = (((insn) >> (bigbit)) & 0x0f) \
2475
| (((insn) >> ((smallbit) - 4)) & 0x10); \
2477
if (insn & (1 << (smallbit))) \
2479
reg = ((insn) >> (bigbit)) & 0x0f; \
2482
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2483
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2484
#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2485
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2486
#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2487
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2489
/* Move between integer and VFP cores. */
2490
static TCGv_i32 gen_vfp_mrs(void)
2492
TCGv_i32 tmp = tcg_temp_new_i32();
2493
tcg_gen_mov_i32(tmp, cpu_F0s);
2497
static void gen_vfp_msr(TCGv_i32 tmp)
2499
tcg_gen_mov_i32(cpu_F0s, tmp);
2500
tcg_temp_free_i32(tmp);
2503
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2505
TCGv_i32 tmp = tcg_temp_new_i32();
2507
tcg_gen_shri_i32(var, var, shift);
2508
tcg_gen_ext8u_i32(var, var);
2509
tcg_gen_shli_i32(tmp, var, 8);
2510
tcg_gen_or_i32(var, var, tmp);
2511
tcg_gen_shli_i32(tmp, var, 16);
2512
tcg_gen_or_i32(var, var, tmp);
2513
tcg_temp_free_i32(tmp);
2516
static void gen_neon_dup_low16(TCGv_i32 var)
2518
TCGv_i32 tmp = tcg_temp_new_i32();
2519
tcg_gen_ext16u_i32(var, var);
2520
tcg_gen_shli_i32(tmp, var, 16);
2521
tcg_gen_or_i32(var, var, tmp);
2522
tcg_temp_free_i32(tmp);
2525
static void gen_neon_dup_high16(TCGv_i32 var)
2527
TCGv_i32 tmp = tcg_temp_new_i32();
2528
tcg_gen_andi_i32(var, var, 0xffff0000);
2529
tcg_gen_shri_i32(tmp, var, 16);
2530
tcg_gen_or_i32(var, var, tmp);
2531
tcg_temp_free_i32(tmp);
2534
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2536
/* Load a single Neon element and replicate into a 32 bit TCG reg */
2537
TCGv_i32 tmp = tcg_temp_new_i32();
2540
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
2541
gen_neon_dup_u8(tmp, 0);
2544
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
2545
gen_neon_dup_low16(tmp);
2548
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
2550
default: /* Avoid compiler warnings. */
2556
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2557
(ie. an undefined instruction). */
2558
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2560
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2566
if (!arm_feature(env, ARM_FEATURE_VFP))
2569
if (!s->vfp_enabled) {
2570
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2571
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2573
rn = (insn >> 16) & 0xf;
2574
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2575
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2578
dp = ((insn & 0xf00) == 0xb00);
2579
switch ((insn >> 24) & 0xf) {
2581
if (insn & (1 << 4)) {
2582
/* single register transfer */
2583
rd = (insn >> 12) & 0xf;
2588
VFP_DREG_N(rn, insn);
2591
if (insn & 0x00c00060
2592
&& !arm_feature(env, ARM_FEATURE_NEON))
2595
pass = (insn >> 21) & 1;
2596
if (insn & (1 << 22)) {
2598
offset = ((insn >> 5) & 3) * 8;
2599
} else if (insn & (1 << 5)) {
2601
offset = (insn & (1 << 6)) ? 16 : 0;
2606
if (insn & ARM_CP_RW_BIT) {
2608
tmp = neon_load_reg(rn, pass);
2612
tcg_gen_shri_i32(tmp, tmp, offset);
2613
if (insn & (1 << 23))
2619
if (insn & (1 << 23)) {
2621
tcg_gen_shri_i32(tmp, tmp, 16);
2627
tcg_gen_sari_i32(tmp, tmp, 16);
2636
store_reg(s, rd, tmp);
2639
tmp = load_reg(s, rd);
2640
if (insn & (1 << 23)) {
2643
gen_neon_dup_u8(tmp, 0);
2644
} else if (size == 1) {
2645
gen_neon_dup_low16(tmp);
2647
for (n = 0; n <= pass * 2; n++) {
2648
tmp2 = tcg_temp_new_i32();
2649
tcg_gen_mov_i32(tmp2, tmp);
2650
neon_store_reg(rn, n, tmp2);
2652
neon_store_reg(rn, n, tmp);
2657
tmp2 = neon_load_reg(rn, pass);
2658
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2659
tcg_temp_free_i32(tmp2);
2662
tmp2 = neon_load_reg(rn, pass);
2663
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2664
tcg_temp_free_i32(tmp2);
2669
neon_store_reg(rn, pass, tmp);
2673
if ((insn & 0x6f) != 0x00)
2675
rn = VFP_SREG_N(insn);
2676
if (insn & ARM_CP_RW_BIT) {
2678
if (insn & (1 << 21)) {
2679
/* system register */
2684
/* VFP2 allows access to FSID from userspace.
2685
VFP3 restricts all id registers to privileged
2688
&& arm_feature(env, ARM_FEATURE_VFP3))
2690
tmp = load_cpu_field(vfp.xregs[rn]);
2695
tmp = load_cpu_field(vfp.xregs[rn]);
2697
case ARM_VFP_FPINST:
2698
case ARM_VFP_FPINST2:
2699
/* Not present in VFP3. */
2701
|| arm_feature(env, ARM_FEATURE_VFP3))
2703
tmp = load_cpu_field(vfp.xregs[rn]);
2707
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2708
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2710
tmp = tcg_temp_new_i32();
2711
gen_helper_vfp_get_fpscr(tmp, cpu_env);
2717
|| !arm_feature(env, ARM_FEATURE_MVFR))
2719
tmp = load_cpu_field(vfp.xregs[rn]);
2725
gen_mov_F0_vreg(0, rn);
2726
tmp = gen_vfp_mrs();
2729
/* Set the 4 flag bits in the CPSR. */
2731
tcg_temp_free_i32(tmp);
2733
store_reg(s, rd, tmp);
2737
if (insn & (1 << 21)) {
2739
/* system register */
2744
/* Writes are ignored. */
2747
tmp = load_reg(s, rd);
2748
gen_helper_vfp_set_fpscr(cpu_env, tmp);
2749
tcg_temp_free_i32(tmp);
2755
/* TODO: VFP subarchitecture support.
2756
* For now, keep the EN bit only */
2757
tmp = load_reg(s, rd);
2758
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2759
store_cpu_field(tmp, vfp.xregs[rn]);
2762
case ARM_VFP_FPINST:
2763
case ARM_VFP_FPINST2:
2764
tmp = load_reg(s, rd);
2765
store_cpu_field(tmp, vfp.xregs[rn]);
2771
tmp = load_reg(s, rd);
2773
gen_mov_vreg_F0(0, rn);
2778
/* data processing */
2779
/* The opcode is in bits 23, 21, 20 and 6. */
2780
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2784
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2786
/* rn is register number */
2787
VFP_DREG_N(rn, insn);
2790
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2791
/* Integer or single precision destination. */
2792
rd = VFP_SREG_D(insn);
2794
VFP_DREG_D(rd, insn);
2797
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2798
/* VCVT from int is always from S reg regardless of dp bit.
2799
* VCVT with immediate frac_bits has same format as SREG_M
2801
rm = VFP_SREG_M(insn);
2803
VFP_DREG_M(rm, insn);
2806
rn = VFP_SREG_N(insn);
2807
if (op == 15 && rn == 15) {
2808
/* Double precision destination. */
2809
VFP_DREG_D(rd, insn);
2811
rd = VFP_SREG_D(insn);
2813
/* NB that we implicitly rely on the encoding for the frac_bits
2814
* in VCVT of fixed to float being the same as that of an SREG_M
2816
rm = VFP_SREG_M(insn);
2819
veclen = s->vec_len;
2820
if (op == 15 && rn > 3)
2823
/* Shut up compiler warnings. */
2834
/* Figure out what type of vector operation this is. */
2835
if ((rd & bank_mask) == 0) {
2840
delta_d = (s->vec_stride >> 1) + 1;
2842
delta_d = s->vec_stride + 1;
2844
if ((rm & bank_mask) == 0) {
2845
/* mixed scalar/vector */
2854
/* Load the initial operands. */
2859
/* Integer source */
2860
gen_mov_F0_vreg(0, rm);
2865
gen_mov_F0_vreg(dp, rd);
2866
gen_mov_F1_vreg(dp, rm);
2870
/* Compare with zero */
2871
gen_mov_F0_vreg(dp, rd);
2882
/* Source and destination the same. */
2883
gen_mov_F0_vreg(dp, rd);
2889
/* VCVTB, VCVTT: only present with the halfprec extension,
2890
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2892
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
2895
/* Otherwise fall through */
2897
/* One source operand. */
2898
gen_mov_F0_vreg(dp, rm);
2902
/* Two source operands. */
2903
gen_mov_F0_vreg(dp, rn);
2904
gen_mov_F1_vreg(dp, rm);
2908
/* Perform the calculation. */
2910
case 0: /* VMLA: fd + (fn * fm) */
2911
/* Note that order of inputs to the add matters for NaNs */
2913
gen_mov_F0_vreg(dp, rd);
2916
case 1: /* VMLS: fd + -(fn * fm) */
2919
gen_mov_F0_vreg(dp, rd);
2922
case 2: /* VNMLS: -fd + (fn * fm) */
2923
/* Note that it isn't valid to replace (-A + B) with (B - A)
2924
* or similar plausible looking simplifications
2925
* because this will give wrong results for NaNs.
2928
gen_mov_F0_vreg(dp, rd);
2932
case 3: /* VNMLA: -fd + -(fn * fm) */
2935
gen_mov_F0_vreg(dp, rd);
2939
case 4: /* mul: fn * fm */
2942
case 5: /* nmul: -(fn * fm) */
2946
case 6: /* add: fn + fm */
2949
case 7: /* sub: fn - fm */
2952
case 8: /* div: fn / fm */
2955
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
2956
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
2957
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
2958
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
2959
/* These are fused multiply-add, and must be done as one
2960
* floating point operation with no rounding between the
2961
* multiplication and addition steps.
2962
* NB that doing the negations here as separate steps is
2963
* correct : an input NaN should come out with its sign bit
2964
* flipped if it is a negated-input.
2966
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
2974
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
2976
frd = tcg_temp_new_i64();
2977
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
2980
gen_helper_vfp_negd(frd, frd);
2982
fpst = get_fpstatus_ptr(0);
2983
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
2984
cpu_F1d, frd, fpst);
2985
tcg_temp_free_ptr(fpst);
2986
tcg_temp_free_i64(frd);
2992
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
2994
frd = tcg_temp_new_i32();
2995
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
2997
gen_helper_vfp_negs(frd, frd);
2999
fpst = get_fpstatus_ptr(0);
3000
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3001
cpu_F1s, frd, fpst);
3002
tcg_temp_free_ptr(fpst);
3003
tcg_temp_free_i32(frd);
3006
case 14: /* fconst */
3007
if (!arm_feature(env, ARM_FEATURE_VFP3))
3010
n = (insn << 12) & 0x80000000;
3011
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3018
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3025
tcg_gen_movi_i32(cpu_F0s, n);
3028
case 15: /* extension space */
3042
case 4: /* vcvtb.f32.f16 */
3043
tmp = gen_vfp_mrs();
3044
tcg_gen_ext16u_i32(tmp, tmp);
3045
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3046
tcg_temp_free_i32(tmp);
3048
case 5: /* vcvtt.f32.f16 */
3049
tmp = gen_vfp_mrs();
3050
tcg_gen_shri_i32(tmp, tmp, 16);
3051
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3052
tcg_temp_free_i32(tmp);
3054
case 6: /* vcvtb.f16.f32 */
3055
tmp = tcg_temp_new_i32();
3056
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3057
gen_mov_F0_vreg(0, rd);
3058
tmp2 = gen_vfp_mrs();
3059
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3060
tcg_gen_or_i32(tmp, tmp, tmp2);
3061
tcg_temp_free_i32(tmp2);
3064
case 7: /* vcvtt.f16.f32 */
3065
tmp = tcg_temp_new_i32();
3066
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3067
tcg_gen_shli_i32(tmp, tmp, 16);
3068
gen_mov_F0_vreg(0, rd);
3069
tmp2 = gen_vfp_mrs();
3070
tcg_gen_ext16u_i32(tmp2, tmp2);
3071
tcg_gen_or_i32(tmp, tmp, tmp2);
3072
tcg_temp_free_i32(tmp2);
3084
case 11: /* cmpez */
3088
case 15: /* single<->double conversion */
3090
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3092
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3094
case 16: /* fuito */
3095
gen_vfp_uito(dp, 0);
3097
case 17: /* fsito */
3098
gen_vfp_sito(dp, 0);
3100
case 20: /* fshto */
3101
if (!arm_feature(env, ARM_FEATURE_VFP3))
3103
gen_vfp_shto(dp, 16 - rm, 0);
3105
case 21: /* fslto */
3106
if (!arm_feature(env, ARM_FEATURE_VFP3))
3108
gen_vfp_slto(dp, 32 - rm, 0);
3110
case 22: /* fuhto */
3111
if (!arm_feature(env, ARM_FEATURE_VFP3))
3113
gen_vfp_uhto(dp, 16 - rm, 0);
3115
case 23: /* fulto */
3116
if (!arm_feature(env, ARM_FEATURE_VFP3))
3118
gen_vfp_ulto(dp, 32 - rm, 0);
3120
case 24: /* ftoui */
3121
gen_vfp_toui(dp, 0);
3123
case 25: /* ftouiz */
3124
gen_vfp_touiz(dp, 0);
3126
case 26: /* ftosi */
3127
gen_vfp_tosi(dp, 0);
3129
case 27: /* ftosiz */
3130
gen_vfp_tosiz(dp, 0);
3132
case 28: /* ftosh */
3133
if (!arm_feature(env, ARM_FEATURE_VFP3))
3135
gen_vfp_tosh(dp, 16 - rm, 0);
3137
case 29: /* ftosl */
3138
if (!arm_feature(env, ARM_FEATURE_VFP3))
3140
gen_vfp_tosl(dp, 32 - rm, 0);
3142
case 30: /* ftouh */
3143
if (!arm_feature(env, ARM_FEATURE_VFP3))
3145
gen_vfp_touh(dp, 16 - rm, 0);
3147
case 31: /* ftoul */
3148
if (!arm_feature(env, ARM_FEATURE_VFP3))
3150
gen_vfp_toul(dp, 32 - rm, 0);
3152
default: /* undefined */
3156
default: /* undefined */
3160
/* Write back the result. */
3161
if (op == 15 && (rn >= 8 && rn <= 11))
3162
; /* Comparison, do nothing. */
3163
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3164
/* VCVT double to int: always integer result. */
3165
gen_mov_vreg_F0(0, rd);
3166
else if (op == 15 && rn == 15)
3168
gen_mov_vreg_F0(!dp, rd);
3170
gen_mov_vreg_F0(dp, rd);
3172
/* break out of the loop if we have finished */
3176
if (op == 15 && delta_m == 0) {
3177
/* single source one-many */
3179
rd = ((rd + delta_d) & (bank_mask - 1))
3181
gen_mov_vreg_F0(dp, rd);
3185
/* Setup the next operands. */
3187
rd = ((rd + delta_d) & (bank_mask - 1))
3191
/* One source operand. */
3192
rm = ((rm + delta_m) & (bank_mask - 1))
3194
gen_mov_F0_vreg(dp, rm);
3196
/* Two source operands. */
3197
rn = ((rn + delta_d) & (bank_mask - 1))
3199
gen_mov_F0_vreg(dp, rn);
3201
rm = ((rm + delta_m) & (bank_mask - 1))
3203
gen_mov_F1_vreg(dp, rm);
3211
if ((insn & 0x03e00000) == 0x00400000) {
3212
/* two-register transfer */
3213
rn = (insn >> 16) & 0xf;
3214
rd = (insn >> 12) & 0xf;
3216
VFP_DREG_M(rm, insn);
3218
rm = VFP_SREG_M(insn);
3221
if (insn & ARM_CP_RW_BIT) {
3224
gen_mov_F0_vreg(0, rm * 2);
3225
tmp = gen_vfp_mrs();
3226
store_reg(s, rd, tmp);
3227
gen_mov_F0_vreg(0, rm * 2 + 1);
3228
tmp = gen_vfp_mrs();
3229
store_reg(s, rn, tmp);
3231
gen_mov_F0_vreg(0, rm);
3232
tmp = gen_vfp_mrs();
3233
store_reg(s, rd, tmp);
3234
gen_mov_F0_vreg(0, rm + 1);
3235
tmp = gen_vfp_mrs();
3236
store_reg(s, rn, tmp);
3241
tmp = load_reg(s, rd);
3243
gen_mov_vreg_F0(0, rm * 2);
3244
tmp = load_reg(s, rn);
3246
gen_mov_vreg_F0(0, rm * 2 + 1);
3248
tmp = load_reg(s, rd);
3250
gen_mov_vreg_F0(0, rm);
3251
tmp = load_reg(s, rn);
3253
gen_mov_vreg_F0(0, rm + 1);
3258
rn = (insn >> 16) & 0xf;
3260
VFP_DREG_D(rd, insn);
3262
rd = VFP_SREG_D(insn);
3263
if ((insn & 0x01200000) == 0x01000000) {
3264
/* Single load/store */
3265
offset = (insn & 0xff) << 2;
3266
if ((insn & (1 << 23)) == 0)
3268
if (s->thumb && rn == 15) {
3269
/* This is actually UNPREDICTABLE */
3270
addr = tcg_temp_new_i32();
3271
tcg_gen_movi_i32(addr, s->pc & ~2);
3273
addr = load_reg(s, rn);
3275
tcg_gen_addi_i32(addr, addr, offset);
3276
if (insn & (1 << 20)) {
3277
gen_vfp_ld(s, dp, addr);
3278
gen_mov_vreg_F0(dp, rd);
3280
gen_mov_F0_vreg(dp, rd);
3281
gen_vfp_st(s, dp, addr);
3283
tcg_temp_free_i32(addr);
3285
/* load/store multiple */
3286
int w = insn & (1 << 21);
3288
n = (insn >> 1) & 0x7f;
3292
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3293
/* P == U , W == 1 => UNDEF */
3296
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3297
/* UNPREDICTABLE cases for bad immediates: we choose to
3298
* UNDEF to avoid generating huge numbers of TCG ops
3302
if (rn == 15 && w) {
3303
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3307
if (s->thumb && rn == 15) {
3308
/* This is actually UNPREDICTABLE */
3309
addr = tcg_temp_new_i32();
3310
tcg_gen_movi_i32(addr, s->pc & ~2);
3312
addr = load_reg(s, rn);
3314
if (insn & (1 << 24)) /* pre-decrement */
3315
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3321
for (i = 0; i < n; i++) {
3322
if (insn & ARM_CP_RW_BIT) {
3324
gen_vfp_ld(s, dp, addr);
3325
gen_mov_vreg_F0(dp, rd + i);
3328
gen_mov_F0_vreg(dp, rd + i);
3329
gen_vfp_st(s, dp, addr);
3331
tcg_gen_addi_i32(addr, addr, offset);
3335
if (insn & (1 << 24))
3336
offset = -offset * n;
3337
else if (dp && (insn & 1))
3343
tcg_gen_addi_i32(addr, addr, offset);
3344
store_reg(s, rn, addr);
3346
tcg_temp_free_i32(addr);
3352
/* Should never happen. */
3358
static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3360
TranslationBlock *tb;
3363
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3365
gen_set_pc_im(dest);
3366
tcg_gen_exit_tb((tcg_target_long)tb + n);
3368
gen_set_pc_im(dest);
3373
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3375
if (unlikely(s->singlestep_enabled)) {
3376
/* An indirect jump so that we still trigger the debug exception. */
3381
gen_goto_tb(s, 0, dest);
3382
s->is_jmp = DISAS_TB_JUMP;
3386
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3389
tcg_gen_sari_i32(t0, t0, 16);
3393
tcg_gen_sari_i32(t1, t1, 16);
3396
tcg_gen_mul_i32(t0, t0, t1);
3399
/* Return the mask of PSR bits set by a MSR instruction. */
3400
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3404
if (flags & (1 << 0))
3406
if (flags & (1 << 1))
3408
if (flags & (1 << 2))
3410
if (flags & (1 << 3))
3413
/* Mask out undefined bits. */
3414
mask &= ~CPSR_RESERVED;
3415
if (!arm_feature(env, ARM_FEATURE_V4T))
3417
if (!arm_feature(env, ARM_FEATURE_V5))
3418
mask &= ~CPSR_Q; /* V5TE in reality*/
3419
if (!arm_feature(env, ARM_FEATURE_V6))
3420
mask &= ~(CPSR_E | CPSR_GE);
3421
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3423
/* Mask out execution state bits. */
3426
/* Mask out privileged bits. */
3432
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3433
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3437
/* ??? This is also undefined in system mode. */
3441
tmp = load_cpu_field(spsr);
3442
tcg_gen_andi_i32(tmp, tmp, ~mask);
3443
tcg_gen_andi_i32(t0, t0, mask);
3444
tcg_gen_or_i32(tmp, tmp, t0);
3445
store_cpu_field(tmp, spsr);
3447
gen_set_cpsr(t0, mask);
3449
tcg_temp_free_i32(t0);
3454
/* Returns nonzero if access to the PSR is not permitted. */
3455
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3458
tmp = tcg_temp_new_i32();
3459
tcg_gen_movi_i32(tmp, val);
3460
return gen_set_psr(s, mask, spsr, tmp);
3463
/* Generate an old-style exception return. Marks pc as dead. */
3464
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3467
store_reg(s, 15, pc);
3468
tmp = load_cpu_field(spsr);
3469
gen_set_cpsr(tmp, 0xffffffff);
3470
tcg_temp_free_i32(tmp);
3471
s->is_jmp = DISAS_UPDATE;
3474
/* Generate a v6 exception return. Marks both values as dead. */
3475
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3477
gen_set_cpsr(cpsr, 0xffffffff);
3478
tcg_temp_free_i32(cpsr);
3479
store_reg(s, 15, pc);
3480
s->is_jmp = DISAS_UPDATE;
3484
gen_set_condexec (DisasContext *s)
3486
if (s->condexec_mask) {
3487
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3488
TCGv_i32 tmp = tcg_temp_new_i32();
3489
tcg_gen_movi_i32(tmp, val);
3490
store_cpu_field(tmp, condexec_bits);
3494
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3496
gen_set_condexec(s);
3497
gen_set_pc_im(s->pc - offset);
3498
gen_exception(excp);
3499
s->is_jmp = DISAS_JUMP;
3502
static void gen_nop_hint(DisasContext *s, int val)
3506
gen_set_pc_im(s->pc);
3507
s->is_jmp = DISAS_WFI;
3512
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3518
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3520
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3523
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3524
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3525
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3530
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3533
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3534
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3535
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3540
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3541
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3542
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3543
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3544
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3546
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3547
switch ((size << 1) | u) { \
3549
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3552
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3555
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3558
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3561
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3564
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3566
default: return 1; \
3569
#define GEN_NEON_INTEGER_OP(name) do { \
3570
switch ((size << 1) | u) { \
3572
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3575
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3578
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3581
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3584
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3587
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3589
default: return 1; \
3592
static TCGv_i32 neon_load_scratch(int scratch)
3594
TCGv_i32 tmp = tcg_temp_new_i32();
3595
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3599
static void neon_store_scratch(int scratch, TCGv_i32 var)
3601
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3602
tcg_temp_free_i32(var);
3605
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3609
tmp = neon_load_reg(reg & 7, reg >> 4);
3611
gen_neon_dup_high16(tmp);
3613
gen_neon_dup_low16(tmp);
3616
tmp = neon_load_reg(reg & 15, reg >> 4);
3621
static int gen_neon_unzip(int rd, int rm, int size, int q)
3624
if (!q && size == 2) {
3627
tmp = tcg_const_i32(rd);
3628
tmp2 = tcg_const_i32(rm);
3632
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3635
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3638
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3646
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3649
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3655
tcg_temp_free_i32(tmp);
3656
tcg_temp_free_i32(tmp2);
3660
static int gen_neon_zip(int rd, int rm, int size, int q)
3663
if (!q && size == 2) {
3666
tmp = tcg_const_i32(rd);
3667
tmp2 = tcg_const_i32(rm);
3671
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3674
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3677
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3685
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3688
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3694
tcg_temp_free_i32(tmp);
3695
tcg_temp_free_i32(tmp2);
3699
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3703
rd = tcg_temp_new_i32();
3704
tmp = tcg_temp_new_i32();
3706
tcg_gen_shli_i32(rd, t0, 8);
3707
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3708
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3709
tcg_gen_or_i32(rd, rd, tmp);
3711
tcg_gen_shri_i32(t1, t1, 8);
3712
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3713
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3714
tcg_gen_or_i32(t1, t1, tmp);
3715
tcg_gen_mov_i32(t0, rd);
3717
tcg_temp_free_i32(tmp);
3718
tcg_temp_free_i32(rd);
3721
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3725
rd = tcg_temp_new_i32();
3726
tmp = tcg_temp_new_i32();
3728
tcg_gen_shli_i32(rd, t0, 16);
3729
tcg_gen_andi_i32(tmp, t1, 0xffff);
3730
tcg_gen_or_i32(rd, rd, tmp);
3731
tcg_gen_shri_i32(t1, t1, 16);
3732
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3733
tcg_gen_or_i32(t1, t1, tmp);
3734
tcg_gen_mov_i32(t0, rd);
3736
tcg_temp_free_i32(tmp);
3737
tcg_temp_free_i32(rd);
3745
} neon_ls_element_type[11] = {
3759
/* Translate a NEON load/store element instruction. Return nonzero if the
3760
instruction is invalid. */
3761
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
3780
if (!s->vfp_enabled)
3782
VFP_DREG_D(rd, insn);
3783
rn = (insn >> 16) & 0xf;
3785
load = (insn & (1 << 21)) != 0;
3786
if ((insn & (1 << 23)) == 0) {
3787
/* Load store all elements. */
3788
op = (insn >> 8) & 0xf;
3789
size = (insn >> 6) & 3;
3792
/* Catch UNDEF cases for bad values of align field */
3795
if (((insn >> 5) & 1) == 1) {
3800
if (((insn >> 4) & 3) == 3) {
3807
nregs = neon_ls_element_type[op].nregs;
3808
interleave = neon_ls_element_type[op].interleave;
3809
spacing = neon_ls_element_type[op].spacing;
3810
if (size == 3 && (interleave | spacing) != 1)
3812
addr = tcg_temp_new_i32();
3813
load_reg_var(s, addr, rn);
3814
stride = (1 << size) * interleave;
3815
for (reg = 0; reg < nregs; reg++) {
3816
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3817
load_reg_var(s, addr, rn);
3818
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3819
} else if (interleave == 2 && nregs == 4 && reg == 2) {
3820
load_reg_var(s, addr, rn);
3821
tcg_gen_addi_i32(addr, addr, 1 << size);
3824
tmp64 = tcg_temp_new_i64();
3826
tcg_gen_qemu_ld64(tmp64, addr, IS_USER(s));
3827
neon_store_reg64(tmp64, rd);
3829
neon_load_reg64(tmp64, rd);
3830
tcg_gen_qemu_st64(tmp64, addr, IS_USER(s));
3832
tcg_temp_free_i64(tmp64);
3833
tcg_gen_addi_i32(addr, addr, stride);
3835
for (pass = 0; pass < 2; pass++) {
3838
tmp = tcg_temp_new_i32();
3839
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
3840
neon_store_reg(rd, pass, tmp);
3842
tmp = neon_load_reg(rd, pass);
3843
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
3844
tcg_temp_free_i32(tmp);
3846
tcg_gen_addi_i32(addr, addr, stride);
3847
} else if (size == 1) {
3849
tmp = tcg_temp_new_i32();
3850
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
3851
tcg_gen_addi_i32(addr, addr, stride);
3852
tmp2 = tcg_temp_new_i32();
3853
tcg_gen_qemu_ld16u(tmp2, addr, IS_USER(s));
3854
tcg_gen_addi_i32(addr, addr, stride);
3855
tcg_gen_shli_i32(tmp2, tmp2, 16);
3856
tcg_gen_or_i32(tmp, tmp, tmp2);
3857
tcg_temp_free_i32(tmp2);
3858
neon_store_reg(rd, pass, tmp);
3860
tmp = neon_load_reg(rd, pass);
3861
tmp2 = tcg_temp_new_i32();
3862
tcg_gen_shri_i32(tmp2, tmp, 16);
3863
tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
3864
tcg_temp_free_i32(tmp);
3865
tcg_gen_addi_i32(addr, addr, stride);
3866
tcg_gen_qemu_st16(tmp2, addr, IS_USER(s));
3867
tcg_temp_free_i32(tmp2);
3868
tcg_gen_addi_i32(addr, addr, stride);
3870
} else /* size == 0 */ {
3872
TCGV_UNUSED_I32(tmp2);
3873
for (n = 0; n < 4; n++) {
3874
tmp = tcg_temp_new_i32();
3875
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
3876
tcg_gen_addi_i32(addr, addr, stride);
3880
tcg_gen_shli_i32(tmp, tmp, n * 8);
3881
tcg_gen_or_i32(tmp2, tmp2, tmp);
3882
tcg_temp_free_i32(tmp);
3885
neon_store_reg(rd, pass, tmp2);
3887
tmp2 = neon_load_reg(rd, pass);
3888
for (n = 0; n < 4; n++) {
3889
tmp = tcg_temp_new_i32();
3891
tcg_gen_mov_i32(tmp, tmp2);
3893
tcg_gen_shri_i32(tmp, tmp2, n * 8);
3895
tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
3896
tcg_temp_free_i32(tmp);
3897
tcg_gen_addi_i32(addr, addr, stride);
3899
tcg_temp_free_i32(tmp2);
3906
tcg_temp_free_i32(addr);
3909
size = (insn >> 10) & 3;
3911
/* Load single element to all lanes. */
3912
int a = (insn >> 4) & 1;
3916
size = (insn >> 6) & 3;
3917
nregs = ((insn >> 8) & 3) + 1;
3920
if (nregs != 4 || a == 0) {
3923
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3926
if (nregs == 1 && a == 1 && size == 0) {
3929
if (nregs == 3 && a == 1) {
3932
addr = tcg_temp_new_i32();
3933
load_reg_var(s, addr, rn);
3935
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3936
tmp = gen_load_and_replicate(s, addr, size);
3937
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
3938
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
3939
if (insn & (1 << 5)) {
3940
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
3941
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
3943
tcg_temp_free_i32(tmp);
3945
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3946
stride = (insn & (1 << 5)) ? 2 : 1;
3947
for (reg = 0; reg < nregs; reg++) {
3948
tmp = gen_load_and_replicate(s, addr, size);
3949
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
3950
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
3951
tcg_temp_free_i32(tmp);
3952
tcg_gen_addi_i32(addr, addr, 1 << size);
3956
tcg_temp_free_i32(addr);
3957
stride = (1 << size) * nregs;
3959
/* Single element. */
3960
int idx = (insn >> 4) & 0xf;
3961
pass = (insn >> 7) & 1;
3964
shift = ((insn >> 5) & 3) * 8;
3968
shift = ((insn >> 6) & 1) * 16;
3969
stride = (insn & (1 << 5)) ? 2 : 1;
3973
stride = (insn & (1 << 6)) ? 2 : 1;
3978
nregs = ((insn >> 8) & 3) + 1;
3979
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
3982
if (((idx & (1 << size)) != 0) ||
3983
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3988
if ((idx & 1) != 0) {
3993
if (size == 2 && (idx & 2) != 0) {
3998
if ((size == 2) && ((idx & 3) == 3)) {
4005
if ((rd + stride * (nregs - 1)) > 31) {
4006
/* Attempts to write off the end of the register file
4007
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4008
* the neon_load_reg() would write off the end of the array.
4012
addr = tcg_temp_new_i32();
4013
load_reg_var(s, addr, rn);
4014
for (reg = 0; reg < nregs; reg++) {
4016
tmp = tcg_temp_new_i32();
4019
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
4022
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
4025
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
4027
default: /* Avoid compiler warnings. */
4031
tmp2 = neon_load_reg(rd, pass);
4032
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4033
shift, size ? 16 : 8);
4034
tcg_temp_free_i32(tmp2);
4036
neon_store_reg(rd, pass, tmp);
4037
} else { /* Store */
4038
tmp = neon_load_reg(rd, pass);
4040
tcg_gen_shri_i32(tmp, tmp, shift);
4043
tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
4046
tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
4049
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
4052
tcg_temp_free_i32(tmp);
4055
tcg_gen_addi_i32(addr, addr, 1 << size);
4057
tcg_temp_free_i32(addr);
4058
stride = nregs * (1 << size);
4064
base = load_reg(s, rn);
4066
tcg_gen_addi_i32(base, base, stride);
4069
index = load_reg(s, rm);
4070
tcg_gen_add_i32(base, base, index);
4071
tcg_temp_free_i32(index);
4073
store_reg(s, rn, base);
4078
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4079
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4081
tcg_gen_and_i32(t, t, c);
4082
tcg_gen_andc_i32(f, f, c);
4083
tcg_gen_or_i32(dest, t, f);
4086
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4089
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4090
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4091
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4096
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4099
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4100
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4101
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4106
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4109
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4110
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4111
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4116
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4119
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4120
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4121
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4126
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4132
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4133
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4138
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4139
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4146
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4147
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4152
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4153
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4160
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4164
case 0: gen_helper_neon_widen_u8(dest, src); break;
4165
case 1: gen_helper_neon_widen_u16(dest, src); break;
4166
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4171
case 0: gen_helper_neon_widen_s8(dest, src); break;
4172
case 1: gen_helper_neon_widen_s16(dest, src); break;
4173
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4177
tcg_temp_free_i32(src);
4180
static inline void gen_neon_addl(int size)
4183
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4184
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4185
case 2: tcg_gen_add_i64(CPU_V001); break;
4190
static inline void gen_neon_subl(int size)
4193
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4194
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4195
case 2: tcg_gen_sub_i64(CPU_V001); break;
4200
static inline void gen_neon_negl(TCGv_i64 var, int size)
4203
case 0: gen_helper_neon_negl_u16(var, var); break;
4204
case 1: gen_helper_neon_negl_u32(var, var); break;
4206
tcg_gen_neg_i64(var, var);
4212
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4215
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4216
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4221
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4226
switch ((size << 1) | u) {
4227
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4228
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4229
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4230
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4232
tmp = gen_muls_i64_i32(a, b);
4233
tcg_gen_mov_i64(dest, tmp);
4234
tcg_temp_free_i64(tmp);
4237
tmp = gen_mulu_i64_i32(a, b);
4238
tcg_gen_mov_i64(dest, tmp);
4239
tcg_temp_free_i64(tmp);
4244
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4245
Don't forget to clean them now. */
4247
tcg_temp_free_i32(a);
4248
tcg_temp_free_i32(b);
4252
static void gen_neon_narrow_op(int op, int u, int size,
4253
TCGv_i32 dest, TCGv_i64 src)
4257
gen_neon_unarrow_sats(size, dest, src);
4259
gen_neon_narrow(size, dest, src);
4263
gen_neon_narrow_satu(size, dest, src);
4265
gen_neon_narrow_sats(size, dest, src);
4270
/* Symbolic constants for op fields for Neon 3-register same-length.
4271
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4274
#define NEON_3R_VHADD 0
4275
#define NEON_3R_VQADD 1
4276
#define NEON_3R_VRHADD 2
4277
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4278
#define NEON_3R_VHSUB 4
4279
#define NEON_3R_VQSUB 5
4280
#define NEON_3R_VCGT 6
4281
#define NEON_3R_VCGE 7
4282
#define NEON_3R_VSHL 8
4283
#define NEON_3R_VQSHL 9
4284
#define NEON_3R_VRSHL 10
4285
#define NEON_3R_VQRSHL 11
4286
#define NEON_3R_VMAX 12
4287
#define NEON_3R_VMIN 13
4288
#define NEON_3R_VABD 14
4289
#define NEON_3R_VABA 15
4290
#define NEON_3R_VADD_VSUB 16
4291
#define NEON_3R_VTST_VCEQ 17
4292
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4293
#define NEON_3R_VMUL 19
4294
#define NEON_3R_VPMAX 20
4295
#define NEON_3R_VPMIN 21
4296
#define NEON_3R_VQDMULH_VQRDMULH 22
4297
#define NEON_3R_VPADD 23
4298
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4299
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4300
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4301
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4302
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4303
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4304
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4306
static const uint8_t neon_3r_sizes[] = {
4307
[NEON_3R_VHADD] = 0x7,
4308
[NEON_3R_VQADD] = 0xf,
4309
[NEON_3R_VRHADD] = 0x7,
4310
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4311
[NEON_3R_VHSUB] = 0x7,
4312
[NEON_3R_VQSUB] = 0xf,
4313
[NEON_3R_VCGT] = 0x7,
4314
[NEON_3R_VCGE] = 0x7,
4315
[NEON_3R_VSHL] = 0xf,
4316
[NEON_3R_VQSHL] = 0xf,
4317
[NEON_3R_VRSHL] = 0xf,
4318
[NEON_3R_VQRSHL] = 0xf,
4319
[NEON_3R_VMAX] = 0x7,
4320
[NEON_3R_VMIN] = 0x7,
4321
[NEON_3R_VABD] = 0x7,
4322
[NEON_3R_VABA] = 0x7,
4323
[NEON_3R_VADD_VSUB] = 0xf,
4324
[NEON_3R_VTST_VCEQ] = 0x7,
4325
[NEON_3R_VML] = 0x7,
4326
[NEON_3R_VMUL] = 0x7,
4327
[NEON_3R_VPMAX] = 0x7,
4328
[NEON_3R_VPMIN] = 0x7,
4329
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4330
[NEON_3R_VPADD] = 0x7,
4331
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4332
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4333
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4334
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4335
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4336
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4337
[NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4340
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4341
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4344
#define NEON_2RM_VREV64 0
4345
#define NEON_2RM_VREV32 1
4346
#define NEON_2RM_VREV16 2
4347
#define NEON_2RM_VPADDL 4
4348
#define NEON_2RM_VPADDL_U 5
4349
#define NEON_2RM_VCLS 8
4350
#define NEON_2RM_VCLZ 9
4351
#define NEON_2RM_VCNT 10
4352
#define NEON_2RM_VMVN 11
4353
#define NEON_2RM_VPADAL 12
4354
#define NEON_2RM_VPADAL_U 13
4355
#define NEON_2RM_VQABS 14
4356
#define NEON_2RM_VQNEG 15
4357
#define NEON_2RM_VCGT0 16
4358
#define NEON_2RM_VCGE0 17
4359
#define NEON_2RM_VCEQ0 18
4360
#define NEON_2RM_VCLE0 19
4361
#define NEON_2RM_VCLT0 20
4362
#define NEON_2RM_VABS 22
4363
#define NEON_2RM_VNEG 23
4364
#define NEON_2RM_VCGT0_F 24
4365
#define NEON_2RM_VCGE0_F 25
4366
#define NEON_2RM_VCEQ0_F 26
4367
#define NEON_2RM_VCLE0_F 27
4368
#define NEON_2RM_VCLT0_F 28
4369
#define NEON_2RM_VABS_F 30
4370
#define NEON_2RM_VNEG_F 31
4371
#define NEON_2RM_VSWP 32
4372
#define NEON_2RM_VTRN 33
4373
#define NEON_2RM_VUZP 34
4374
#define NEON_2RM_VZIP 35
4375
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4376
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4377
#define NEON_2RM_VSHLL 38
4378
#define NEON_2RM_VCVT_F16_F32 44
4379
#define NEON_2RM_VCVT_F32_F16 46
4380
#define NEON_2RM_VRECPE 56
4381
#define NEON_2RM_VRSQRTE 57
4382
#define NEON_2RM_VRECPE_F 58
4383
#define NEON_2RM_VRSQRTE_F 59
4384
#define NEON_2RM_VCVT_FS 60
4385
#define NEON_2RM_VCVT_FU 61
4386
#define NEON_2RM_VCVT_SF 62
4387
#define NEON_2RM_VCVT_UF 63
4389
static int neon_2rm_is_float_op(int op)
4391
/* Return true if this neon 2reg-misc op is float-to-float */
4392
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4393
op >= NEON_2RM_VRECPE_F);
4396
/* Each entry in this array has bit n set if the insn allows
4397
* size value n (otherwise it will UNDEF). Since unallocated
4398
* op values will have no bits set they always UNDEF.
4400
static const uint8_t neon_2rm_sizes[] = {
4401
[NEON_2RM_VREV64] = 0x7,
4402
[NEON_2RM_VREV32] = 0x3,
4403
[NEON_2RM_VREV16] = 0x1,
4404
[NEON_2RM_VPADDL] = 0x7,
4405
[NEON_2RM_VPADDL_U] = 0x7,
4406
[NEON_2RM_VCLS] = 0x7,
4407
[NEON_2RM_VCLZ] = 0x7,
4408
[NEON_2RM_VCNT] = 0x1,
4409
[NEON_2RM_VMVN] = 0x1,
4410
[NEON_2RM_VPADAL] = 0x7,
4411
[NEON_2RM_VPADAL_U] = 0x7,
4412
[NEON_2RM_VQABS] = 0x7,
4413
[NEON_2RM_VQNEG] = 0x7,
4414
[NEON_2RM_VCGT0] = 0x7,
4415
[NEON_2RM_VCGE0] = 0x7,
4416
[NEON_2RM_VCEQ0] = 0x7,
4417
[NEON_2RM_VCLE0] = 0x7,
4418
[NEON_2RM_VCLT0] = 0x7,
4419
[NEON_2RM_VABS] = 0x7,
4420
[NEON_2RM_VNEG] = 0x7,
4421
[NEON_2RM_VCGT0_F] = 0x4,
4422
[NEON_2RM_VCGE0_F] = 0x4,
4423
[NEON_2RM_VCEQ0_F] = 0x4,
4424
[NEON_2RM_VCLE0_F] = 0x4,
4425
[NEON_2RM_VCLT0_F] = 0x4,
4426
[NEON_2RM_VABS_F] = 0x4,
4427
[NEON_2RM_VNEG_F] = 0x4,
4428
[NEON_2RM_VSWP] = 0x1,
4429
[NEON_2RM_VTRN] = 0x7,
4430
[NEON_2RM_VUZP] = 0x7,
4431
[NEON_2RM_VZIP] = 0x7,
4432
[NEON_2RM_VMOVN] = 0x7,
4433
[NEON_2RM_VQMOVN] = 0x7,
4434
[NEON_2RM_VSHLL] = 0x7,
4435
[NEON_2RM_VCVT_F16_F32] = 0x2,
4436
[NEON_2RM_VCVT_F32_F16] = 0x2,
4437
[NEON_2RM_VRECPE] = 0x4,
4438
[NEON_2RM_VRSQRTE] = 0x4,
4439
[NEON_2RM_VRECPE_F] = 0x4,
4440
[NEON_2RM_VRSQRTE_F] = 0x4,
4441
[NEON_2RM_VCVT_FS] = 0x4,
4442
[NEON_2RM_VCVT_FU] = 0x4,
4443
[NEON_2RM_VCVT_SF] = 0x4,
4444
[NEON_2RM_VCVT_UF] = 0x4,
4447
/* Translate a NEON data processing instruction. Return nonzero if the
4448
instruction is invalid.
4449
We process data in a mixture of 32-bit and 64-bit chunks.
4450
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4452
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4464
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4467
if (!s->vfp_enabled)
4469
q = (insn & (1 << 6)) != 0;
4470
u = (insn >> 24) & 1;
4471
VFP_DREG_D(rd, insn);
4472
VFP_DREG_N(rn, insn);
4473
VFP_DREG_M(rm, insn);
4474
size = (insn >> 20) & 3;
4475
if ((insn & (1 << 23)) == 0) {
4476
/* Three register same length. */
4477
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4478
/* Catch invalid op and bad size combinations: UNDEF */
4479
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4482
/* All insns of this form UNDEF for either this condition or the
4483
* superset of cases "Q==1"; we catch the latter later.
4485
if (q && ((rd | rn | rm) & 1)) {
4488
if (size == 3 && op != NEON_3R_LOGIC) {
4489
/* 64-bit element instructions. */
4490
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4491
neon_load_reg64(cpu_V0, rn + pass);
4492
neon_load_reg64(cpu_V1, rm + pass);
4496
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4499
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4505
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4508
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4514
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4516
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4521
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4524
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4530
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4532
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4535
case NEON_3R_VQRSHL:
4537
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4540
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4544
case NEON_3R_VADD_VSUB:
4546
tcg_gen_sub_i64(CPU_V001);
4548
tcg_gen_add_i64(CPU_V001);
4554
neon_store_reg64(cpu_V0, rd + pass);
4563
case NEON_3R_VQRSHL:
4566
/* Shift instruction operands are reversed. */
4581
case NEON_3R_FLOAT_ARITH:
4582
pairwise = (u && size < 2); /* if VPADD (float) */
4584
case NEON_3R_FLOAT_MINMAX:
4585
pairwise = u; /* if VPMIN/VPMAX (float) */
4587
case NEON_3R_FLOAT_CMP:
4589
/* no encoding for U=0 C=1x */
4593
case NEON_3R_FLOAT_ACMP:
4598
case NEON_3R_VRECPS_VRSQRTS:
4604
if (u && (size != 0)) {
4605
/* UNDEF on invalid size for polynomial subcase */
4610
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4618
if (pairwise && q) {
4619
/* All the pairwise insns UNDEF if Q is set */
4623
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4628
tmp = neon_load_reg(rn, 0);
4629
tmp2 = neon_load_reg(rn, 1);
4631
tmp = neon_load_reg(rm, 0);
4632
tmp2 = neon_load_reg(rm, 1);
4636
tmp = neon_load_reg(rn, pass);
4637
tmp2 = neon_load_reg(rm, pass);
4641
GEN_NEON_INTEGER_OP(hadd);
4644
GEN_NEON_INTEGER_OP_ENV(qadd);
4646
case NEON_3R_VRHADD:
4647
GEN_NEON_INTEGER_OP(rhadd);
4649
case NEON_3R_LOGIC: /* Logic ops. */
4650
switch ((u << 2) | size) {
4652
tcg_gen_and_i32(tmp, tmp, tmp2);
4655
tcg_gen_andc_i32(tmp, tmp, tmp2);
4658
tcg_gen_or_i32(tmp, tmp, tmp2);
4661
tcg_gen_orc_i32(tmp, tmp, tmp2);
4664
tcg_gen_xor_i32(tmp, tmp, tmp2);
4667
tmp3 = neon_load_reg(rd, pass);
4668
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4669
tcg_temp_free_i32(tmp3);
4672
tmp3 = neon_load_reg(rd, pass);
4673
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4674
tcg_temp_free_i32(tmp3);
4677
tmp3 = neon_load_reg(rd, pass);
4678
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4679
tcg_temp_free_i32(tmp3);
4684
GEN_NEON_INTEGER_OP(hsub);
4687
GEN_NEON_INTEGER_OP_ENV(qsub);
4690
GEN_NEON_INTEGER_OP(cgt);
4693
GEN_NEON_INTEGER_OP(cge);
4696
GEN_NEON_INTEGER_OP(shl);
4699
GEN_NEON_INTEGER_OP_ENV(qshl);
4702
GEN_NEON_INTEGER_OP(rshl);
4704
case NEON_3R_VQRSHL:
4705
GEN_NEON_INTEGER_OP_ENV(qrshl);
4708
GEN_NEON_INTEGER_OP(max);
4711
GEN_NEON_INTEGER_OP(min);
4714
GEN_NEON_INTEGER_OP(abd);
4717
GEN_NEON_INTEGER_OP(abd);
4718
tcg_temp_free_i32(tmp2);
4719
tmp2 = neon_load_reg(rd, pass);
4720
gen_neon_add(size, tmp, tmp2);
4722
case NEON_3R_VADD_VSUB:
4723
if (!u) { /* VADD */
4724
gen_neon_add(size, tmp, tmp2);
4727
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4728
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4729
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4734
case NEON_3R_VTST_VCEQ:
4735
if (!u) { /* VTST */
4737
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4738
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4739
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4744
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4745
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4746
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4751
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4753
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4754
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4755
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4758
tcg_temp_free_i32(tmp2);
4759
tmp2 = neon_load_reg(rd, pass);
4761
gen_neon_rsb(size, tmp, tmp2);
4763
gen_neon_add(size, tmp, tmp2);
4767
if (u) { /* polynomial */
4768
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4769
} else { /* Integer */
4771
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4772
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4773
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4779
GEN_NEON_INTEGER_OP(pmax);
4782
GEN_NEON_INTEGER_OP(pmin);
4784
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
4785
if (!u) { /* VQDMULH */
4788
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
4791
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
4795
} else { /* VQRDMULH */
4798
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
4801
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
4809
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4810
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4811
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4815
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
4817
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4818
switch ((u << 2) | size) {
4821
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4824
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
4827
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
4832
tcg_temp_free_ptr(fpstatus);
4835
case NEON_3R_FLOAT_MULTIPLY:
4837
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4838
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
4840
tcg_temp_free_i32(tmp2);
4841
tmp2 = neon_load_reg(rd, pass);
4843
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4845
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
4848
tcg_temp_free_ptr(fpstatus);
4851
case NEON_3R_FLOAT_CMP:
4853
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4855
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
4858
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
4860
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
4863
tcg_temp_free_ptr(fpstatus);
4866
case NEON_3R_FLOAT_ACMP:
4868
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4870
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
4872
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
4874
tcg_temp_free_ptr(fpstatus);
4877
case NEON_3R_FLOAT_MINMAX:
4879
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4881
gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
4883
gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
4885
tcg_temp_free_ptr(fpstatus);
4888
case NEON_3R_VRECPS_VRSQRTS:
4890
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4892
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4896
/* VFMA, VFMS: fused multiply-add */
4897
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4898
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
4901
gen_helper_vfp_negs(tmp, tmp);
4903
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
4904
tcg_temp_free_i32(tmp3);
4905
tcg_temp_free_ptr(fpstatus);
4911
tcg_temp_free_i32(tmp2);
4913
/* Save the result. For elementwise operations we can put it
4914
straight into the destination register. For pairwise operations
4915
we have to be careful to avoid clobbering the source operands. */
4916
if (pairwise && rd == rm) {
4917
neon_store_scratch(pass, tmp);
4919
neon_store_reg(rd, pass, tmp);
4923
if (pairwise && rd == rm) {
4924
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4925
tmp = neon_load_scratch(pass);
4926
neon_store_reg(rd, pass, tmp);
4929
/* End of 3 register same size operations. */
4930
} else if (insn & (1 << 4)) {
4931
if ((insn & 0x00380080) != 0) {
4932
/* Two registers and shift. */
4933
op = (insn >> 8) & 0xf;
4934
if (insn & (1 << 7)) {
4942
while ((insn & (1 << (size + 19))) == 0)
4945
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4946
/* To avoid excessive duplication of ops we implement shift
4947
by immediate using the variable shift operations. */
4949
/* Shift by immediate:
4950
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4951
if (q && ((rd | rm) & 1)) {
4954
if (!u && (op == 4 || op == 6)) {
4957
/* Right shifts are encoded as N - shift, where N is the
4958
element size in bits. */
4960
shift = shift - (1 << (size + 3));
4968
imm = (uint8_t) shift;
4973
imm = (uint16_t) shift;
4984
for (pass = 0; pass < count; pass++) {
4986
neon_load_reg64(cpu_V0, rm + pass);
4987
tcg_gen_movi_i64(cpu_V1, imm);
4992
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4994
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4999
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5001
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5004
case 5: /* VSHL, VSLI */
5005
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5007
case 6: /* VQSHLU */
5008
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5013
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5016
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5021
if (op == 1 || op == 3) {
5023
neon_load_reg64(cpu_V1, rd + pass);
5024
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5025
} else if (op == 4 || (op == 5 && u)) {
5027
neon_load_reg64(cpu_V1, rd + pass);
5029
if (shift < -63 || shift > 63) {
5033
mask = 0xffffffffffffffffull >> -shift;
5035
mask = 0xffffffffffffffffull << shift;
5038
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5039
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5041
neon_store_reg64(cpu_V0, rd + pass);
5042
} else { /* size < 3 */
5043
/* Operands in T0 and T1. */
5044
tmp = neon_load_reg(rm, pass);
5045
tmp2 = tcg_temp_new_i32();
5046
tcg_gen_movi_i32(tmp2, imm);
5050
GEN_NEON_INTEGER_OP(shl);
5054
GEN_NEON_INTEGER_OP(rshl);
5057
case 5: /* VSHL, VSLI */
5059
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5060
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5061
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5065
case 6: /* VQSHLU */
5068
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5072
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5076
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5084
GEN_NEON_INTEGER_OP_ENV(qshl);
5087
tcg_temp_free_i32(tmp2);
5089
if (op == 1 || op == 3) {
5091
tmp2 = neon_load_reg(rd, pass);
5092
gen_neon_add(size, tmp, tmp2);
5093
tcg_temp_free_i32(tmp2);
5094
} else if (op == 4 || (op == 5 && u)) {
5099
mask = 0xff >> -shift;
5101
mask = (uint8_t)(0xff << shift);
5107
mask = 0xffff >> -shift;
5109
mask = (uint16_t)(0xffff << shift);
5113
if (shift < -31 || shift > 31) {
5117
mask = 0xffffffffu >> -shift;
5119
mask = 0xffffffffu << shift;
5125
tmp2 = neon_load_reg(rd, pass);
5126
tcg_gen_andi_i32(tmp, tmp, mask);
5127
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5128
tcg_gen_or_i32(tmp, tmp, tmp2);
5129
tcg_temp_free_i32(tmp2);
5131
neon_store_reg(rd, pass, tmp);
5134
} else if (op < 10) {
5135
/* Shift by immediate and narrow:
5136
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5137
int input_unsigned = (op == 8) ? !u : u;
5141
shift = shift - (1 << (size + 3));
5144
tmp64 = tcg_const_i64(shift);
5145
neon_load_reg64(cpu_V0, rm);
5146
neon_load_reg64(cpu_V1, rm + 1);
5147
for (pass = 0; pass < 2; pass++) {
5155
if (input_unsigned) {
5156
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5158
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5161
if (input_unsigned) {
5162
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5164
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5167
tmp = tcg_temp_new_i32();
5168
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5169
neon_store_reg(rd, pass, tmp);
5171
tcg_temp_free_i64(tmp64);
5174
imm = (uint16_t)shift;
5178
imm = (uint32_t)shift;
5180
tmp2 = tcg_const_i32(imm);
5181
tmp4 = neon_load_reg(rm + 1, 0);
5182
tmp5 = neon_load_reg(rm + 1, 1);
5183
for (pass = 0; pass < 2; pass++) {
5185
tmp = neon_load_reg(rm, 0);
5189
gen_neon_shift_narrow(size, tmp, tmp2, q,
5192
tmp3 = neon_load_reg(rm, 1);
5196
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5198
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5199
tcg_temp_free_i32(tmp);
5200
tcg_temp_free_i32(tmp3);
5201
tmp = tcg_temp_new_i32();
5202
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5203
neon_store_reg(rd, pass, tmp);
5205
tcg_temp_free_i32(tmp2);
5207
} else if (op == 10) {
5209
if (q || (rd & 1)) {
5212
tmp = neon_load_reg(rm, 0);
5213
tmp2 = neon_load_reg(rm, 1);
5214
for (pass = 0; pass < 2; pass++) {
5218
gen_neon_widen(cpu_V0, tmp, size, u);
5221
/* The shift is less than the width of the source
5222
type, so we can just shift the whole register. */
5223
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5224
/* Widen the result of shift: we need to clear
5225
* the potential overflow bits resulting from
5226
* left bits of the narrow input appearing as
5227
* right bits of left the neighbour narrow
5229
if (size < 2 || !u) {
5232
imm = (0xffu >> (8 - shift));
5234
} else if (size == 1) {
5235
imm = 0xffff >> (16 - shift);
5238
imm = 0xffffffff >> (32 - shift);
5241
imm64 = imm | (((uint64_t)imm) << 32);
5245
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5248
neon_store_reg64(cpu_V0, rd + pass);
5250
} else if (op >= 14) {
5251
/* VCVT fixed-point. */
5252
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5255
/* We have already masked out the must-be-1 top bit of imm6,
5256
* hence this 32-shift where the ARM ARM has 64-imm6.
5259
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5260
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5263
gen_vfp_ulto(0, shift, 1);
5265
gen_vfp_slto(0, shift, 1);
5268
gen_vfp_toul(0, shift, 1);
5270
gen_vfp_tosl(0, shift, 1);
5272
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5277
} else { /* (insn & 0x00380080) == 0 */
5279
if (q && (rd & 1)) {
5283
op = (insn >> 8) & 0xf;
5284
/* One register and immediate. */
5285
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5286
invert = (insn & (1 << 5)) != 0;
5287
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5288
* We choose to not special-case this and will behave as if a
5289
* valid constant encoding of 0 had been given.
5308
imm = (imm << 8) | (imm << 24);
5311
imm = (imm << 8) | 0xff;
5314
imm = (imm << 16) | 0xffff;
5317
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5325
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5326
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5332
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5333
if (op & 1 && op < 12) {
5334
tmp = neon_load_reg(rd, pass);
5336
/* The immediate value has already been inverted, so
5338
tcg_gen_andi_i32(tmp, tmp, imm);
5340
tcg_gen_ori_i32(tmp, tmp, imm);
5344
tmp = tcg_temp_new_i32();
5345
if (op == 14 && invert) {
5349
for (n = 0; n < 4; n++) {
5350
if (imm & (1 << (n + (pass & 1) * 4)))
5351
val |= 0xff << (n * 8);
5353
tcg_gen_movi_i32(tmp, val);
5355
tcg_gen_movi_i32(tmp, imm);
5358
neon_store_reg(rd, pass, tmp);
5361
} else { /* (insn & 0x00800010 == 0x00800000) */
5363
op = (insn >> 8) & 0xf;
5364
if ((insn & (1 << 6)) == 0) {
5365
/* Three registers of different lengths. */
5369
/* undefreq: bit 0 : UNDEF if size != 0
5370
* bit 1 : UNDEF if size == 0
5371
* bit 2 : UNDEF if U == 1
5372
* Note that [1:0] set implies 'always UNDEF'
5375
/* prewiden, src1_wide, src2_wide, undefreq */
5376
static const int neon_3reg_wide[16][4] = {
5377
{1, 0, 0, 0}, /* VADDL */
5378
{1, 1, 0, 0}, /* VADDW */
5379
{1, 0, 0, 0}, /* VSUBL */
5380
{1, 1, 0, 0}, /* VSUBW */
5381
{0, 1, 1, 0}, /* VADDHN */
5382
{0, 0, 0, 0}, /* VABAL */
5383
{0, 1, 1, 0}, /* VSUBHN */
5384
{0, 0, 0, 0}, /* VABDL */
5385
{0, 0, 0, 0}, /* VMLAL */
5386
{0, 0, 0, 6}, /* VQDMLAL */
5387
{0, 0, 0, 0}, /* VMLSL */
5388
{0, 0, 0, 6}, /* VQDMLSL */
5389
{0, 0, 0, 0}, /* Integer VMULL */
5390
{0, 0, 0, 2}, /* VQDMULL */
5391
{0, 0, 0, 5}, /* Polynomial VMULL */
5392
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5395
prewiden = neon_3reg_wide[op][0];
5396
src1_wide = neon_3reg_wide[op][1];
5397
src2_wide = neon_3reg_wide[op][2];
5398
undefreq = neon_3reg_wide[op][3];
5400
if (((undefreq & 1) && (size != 0)) ||
5401
((undefreq & 2) && (size == 0)) ||
5402
((undefreq & 4) && u)) {
5405
if ((src1_wide && (rn & 1)) ||
5406
(src2_wide && (rm & 1)) ||
5407
(!src2_wide && (rd & 1))) {
5411
/* Avoid overlapping operands. Wide source operands are
5412
always aligned so will never overlap with wide
5413
destinations in problematic ways. */
5414
if (rd == rm && !src2_wide) {
5415
tmp = neon_load_reg(rm, 1);
5416
neon_store_scratch(2, tmp);
5417
} else if (rd == rn && !src1_wide) {
5418
tmp = neon_load_reg(rn, 1);
5419
neon_store_scratch(2, tmp);
5421
TCGV_UNUSED_I32(tmp3);
5422
for (pass = 0; pass < 2; pass++) {
5424
neon_load_reg64(cpu_V0, rn + pass);
5425
TCGV_UNUSED_I32(tmp);
5427
if (pass == 1 && rd == rn) {
5428
tmp = neon_load_scratch(2);
5430
tmp = neon_load_reg(rn, pass);
5433
gen_neon_widen(cpu_V0, tmp, size, u);
5437
neon_load_reg64(cpu_V1, rm + pass);
5438
TCGV_UNUSED_I32(tmp2);
5440
if (pass == 1 && rd == rm) {
5441
tmp2 = neon_load_scratch(2);
5443
tmp2 = neon_load_reg(rm, pass);
5446
gen_neon_widen(cpu_V1, tmp2, size, u);
5450
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5451
gen_neon_addl(size);
5453
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5454
gen_neon_subl(size);
5456
case 5: case 7: /* VABAL, VABDL */
5457
switch ((size << 1) | u) {
5459
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5462
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5465
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5468
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5471
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5474
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5478
tcg_temp_free_i32(tmp2);
5479
tcg_temp_free_i32(tmp);
5481
case 8: case 9: case 10: case 11: case 12: case 13:
5482
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5483
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5485
case 14: /* Polynomial VMULL */
5486
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5487
tcg_temp_free_i32(tmp2);
5488
tcg_temp_free_i32(tmp);
5490
default: /* 15 is RESERVED: caught earlier */
5495
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5496
neon_store_reg64(cpu_V0, rd + pass);
5497
} else if (op == 5 || (op >= 8 && op <= 11)) {
5499
neon_load_reg64(cpu_V1, rd + pass);
5501
case 10: /* VMLSL */
5502
gen_neon_negl(cpu_V0, size);
5504
case 5: case 8: /* VABAL, VMLAL */
5505
gen_neon_addl(size);
5507
case 9: case 11: /* VQDMLAL, VQDMLSL */
5508
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5510
gen_neon_negl(cpu_V0, size);
5512
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5517
neon_store_reg64(cpu_V0, rd + pass);
5518
} else if (op == 4 || op == 6) {
5519
/* Narrowing operation. */
5520
tmp = tcg_temp_new_i32();
5524
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5527
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5530
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5531
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5538
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5541
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5544
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5545
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5546
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5554
neon_store_reg(rd, 0, tmp3);
5555
neon_store_reg(rd, 1, tmp);
5558
/* Write back the result. */
5559
neon_store_reg64(cpu_V0, rd + pass);
5563
/* Two registers and a scalar. NB that for ops of this form
5564
* the ARM ARM labels bit 24 as Q, but it is in our variable
5571
case 1: /* Float VMLA scalar */
5572
case 5: /* Floating point VMLS scalar */
5573
case 9: /* Floating point VMUL scalar */
5578
case 0: /* Integer VMLA scalar */
5579
case 4: /* Integer VMLS scalar */
5580
case 8: /* Integer VMUL scalar */
5581
case 12: /* VQDMULH scalar */
5582
case 13: /* VQRDMULH scalar */
5583
if (u && ((rd | rn) & 1)) {
5586
tmp = neon_get_scalar(size, rm);
5587
neon_store_scratch(0, tmp);
5588
for (pass = 0; pass < (u ? 4 : 2); pass++) {
5589
tmp = neon_load_scratch(0);
5590
tmp2 = neon_load_reg(rn, pass);
5593
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5595
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5597
} else if (op == 13) {
5599
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5601
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5603
} else if (op & 1) {
5604
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5605
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5606
tcg_temp_free_ptr(fpstatus);
5609
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5610
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5611
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5615
tcg_temp_free_i32(tmp2);
5618
tmp2 = neon_load_reg(rd, pass);
5621
gen_neon_add(size, tmp, tmp2);
5625
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5626
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5627
tcg_temp_free_ptr(fpstatus);
5631
gen_neon_rsb(size, tmp, tmp2);
5635
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5636
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5637
tcg_temp_free_ptr(fpstatus);
5643
tcg_temp_free_i32(tmp2);
5645
neon_store_reg(rd, pass, tmp);
5648
case 3: /* VQDMLAL scalar */
5649
case 7: /* VQDMLSL scalar */
5650
case 11: /* VQDMULL scalar */
5655
case 2: /* VMLAL sclar */
5656
case 6: /* VMLSL scalar */
5657
case 10: /* VMULL scalar */
5661
tmp2 = neon_get_scalar(size, rm);
5662
/* We need a copy of tmp2 because gen_neon_mull
5663
* deletes it during pass 0. */
5664
tmp4 = tcg_temp_new_i32();
5665
tcg_gen_mov_i32(tmp4, tmp2);
5666
tmp3 = neon_load_reg(rn, 1);
5668
for (pass = 0; pass < 2; pass++) {
5670
tmp = neon_load_reg(rn, 0);
5675
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5677
neon_load_reg64(cpu_V1, rd + pass);
5681
gen_neon_negl(cpu_V0, size);
5684
gen_neon_addl(size);
5687
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5689
gen_neon_negl(cpu_V0, size);
5691
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5697
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5702
neon_store_reg64(cpu_V0, rd + pass);
5707
default: /* 14 and 15 are RESERVED */
5711
} else { /* size == 3 */
5714
imm = (insn >> 8) & 0xf;
5719
if (q && ((rd | rn | rm) & 1)) {
5724
neon_load_reg64(cpu_V0, rn);
5726
neon_load_reg64(cpu_V1, rn + 1);
5728
} else if (imm == 8) {
5729
neon_load_reg64(cpu_V0, rn + 1);
5731
neon_load_reg64(cpu_V1, rm);
5734
tmp64 = tcg_temp_new_i64();
5736
neon_load_reg64(cpu_V0, rn);
5737
neon_load_reg64(tmp64, rn + 1);
5739
neon_load_reg64(cpu_V0, rn + 1);
5740
neon_load_reg64(tmp64, rm);
5742
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5743
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5744
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5746
neon_load_reg64(cpu_V1, rm);
5748
neon_load_reg64(cpu_V1, rm + 1);
5751
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5752
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5753
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5754
tcg_temp_free_i64(tmp64);
5757
neon_load_reg64(cpu_V0, rn);
5758
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5759
neon_load_reg64(cpu_V1, rm);
5760
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5761
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5763
neon_store_reg64(cpu_V0, rd);
5765
neon_store_reg64(cpu_V1, rd + 1);
5767
} else if ((insn & (1 << 11)) == 0) {
5768
/* Two register misc. */
5769
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5770
size = (insn >> 18) & 3;
5771
/* UNDEF for unknown op values and bad op-size combinations */
5772
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5775
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5776
q && ((rm | rd) & 1)) {
5780
case NEON_2RM_VREV64:
5781
for (pass = 0; pass < (q ? 2 : 1); pass++) {
5782
tmp = neon_load_reg(rm, pass * 2);
5783
tmp2 = neon_load_reg(rm, pass * 2 + 1);
5785
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5786
case 1: gen_swap_half(tmp); break;
5787
case 2: /* no-op */ break;
5790
neon_store_reg(rd, pass * 2 + 1, tmp);
5792
neon_store_reg(rd, pass * 2, tmp2);
5795
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5796
case 1: gen_swap_half(tmp2); break;
5799
neon_store_reg(rd, pass * 2, tmp2);
5803
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5804
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5805
for (pass = 0; pass < q + 1; pass++) {
5806
tmp = neon_load_reg(rm, pass * 2);
5807
gen_neon_widen(cpu_V0, tmp, size, op & 1);
5808
tmp = neon_load_reg(rm, pass * 2 + 1);
5809
gen_neon_widen(cpu_V1, tmp, size, op & 1);
5811
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5812
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5813
case 2: tcg_gen_add_i64(CPU_V001); break;
5816
if (op >= NEON_2RM_VPADAL) {
5818
neon_load_reg64(cpu_V1, rd + pass);
5819
gen_neon_addl(size);
5821
neon_store_reg64(cpu_V0, rd + pass);
5827
for (n = 0; n < (q ? 4 : 2); n += 2) {
5828
tmp = neon_load_reg(rm, n);
5829
tmp2 = neon_load_reg(rd, n + 1);
5830
neon_store_reg(rm, n, tmp2);
5831
neon_store_reg(rd, n + 1, tmp);
5838
if (gen_neon_unzip(rd, rm, size, q)) {
5843
if (gen_neon_zip(rd, rm, size, q)) {
5847
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5848
/* also VQMOVUN; op field and mnemonics don't line up */
5852
TCGV_UNUSED_I32(tmp2);
5853
for (pass = 0; pass < 2; pass++) {
5854
neon_load_reg64(cpu_V0, rm + pass);
5855
tmp = tcg_temp_new_i32();
5856
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5861
neon_store_reg(rd, 0, tmp2);
5862
neon_store_reg(rd, 1, tmp);
5866
case NEON_2RM_VSHLL:
5867
if (q || (rd & 1)) {
5870
tmp = neon_load_reg(rm, 0);
5871
tmp2 = neon_load_reg(rm, 1);
5872
for (pass = 0; pass < 2; pass++) {
5875
gen_neon_widen(cpu_V0, tmp, size, 1);
5876
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5877
neon_store_reg64(cpu_V0, rd + pass);
5880
case NEON_2RM_VCVT_F16_F32:
5881
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5885
tmp = tcg_temp_new_i32();
5886
tmp2 = tcg_temp_new_i32();
5887
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5888
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5889
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5890
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5891
tcg_gen_shli_i32(tmp2, tmp2, 16);
5892
tcg_gen_or_i32(tmp2, tmp2, tmp);
5893
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5894
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5895
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5896
neon_store_reg(rd, 0, tmp2);
5897
tmp2 = tcg_temp_new_i32();
5898
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5899
tcg_gen_shli_i32(tmp2, tmp2, 16);
5900
tcg_gen_or_i32(tmp2, tmp2, tmp);
5901
neon_store_reg(rd, 1, tmp2);
5902
tcg_temp_free_i32(tmp);
5904
case NEON_2RM_VCVT_F32_F16:
5905
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5909
tmp3 = tcg_temp_new_i32();
5910
tmp = neon_load_reg(rm, 0);
5911
tmp2 = neon_load_reg(rm, 1);
5912
tcg_gen_ext16u_i32(tmp3, tmp);
5913
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5914
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5915
tcg_gen_shri_i32(tmp3, tmp, 16);
5916
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5917
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5918
tcg_temp_free_i32(tmp);
5919
tcg_gen_ext16u_i32(tmp3, tmp2);
5920
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5921
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5922
tcg_gen_shri_i32(tmp3, tmp2, 16);
5923
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5924
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5925
tcg_temp_free_i32(tmp2);
5926
tcg_temp_free_i32(tmp3);
5930
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5931
if (neon_2rm_is_float_op(op)) {
5932
tcg_gen_ld_f32(cpu_F0s, cpu_env,
5933
neon_reg_offset(rm, pass));
5934
TCGV_UNUSED_I32(tmp);
5936
tmp = neon_load_reg(rm, pass);
5939
case NEON_2RM_VREV32:
5941
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5942
case 1: gen_swap_half(tmp); break;
5946
case NEON_2RM_VREV16:
5951
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5952
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5953
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5959
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5960
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5961
case 2: gen_helper_clz(tmp, tmp); break;
5966
gen_helper_neon_cnt_u8(tmp, tmp);
5969
tcg_gen_not_i32(tmp, tmp);
5971
case NEON_2RM_VQABS:
5974
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
5977
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
5980
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
5985
case NEON_2RM_VQNEG:
5988
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
5991
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
5994
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
5999
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6000
tmp2 = tcg_const_i32(0);
6002
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6003
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6004
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6007
tcg_temp_free_i32(tmp2);
6008
if (op == NEON_2RM_VCLE0) {
6009
tcg_gen_not_i32(tmp, tmp);
6012
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6013
tmp2 = tcg_const_i32(0);
6015
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6016
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6017
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6020
tcg_temp_free_i32(tmp2);
6021
if (op == NEON_2RM_VCLT0) {
6022
tcg_gen_not_i32(tmp, tmp);
6025
case NEON_2RM_VCEQ0:
6026
tmp2 = tcg_const_i32(0);
6028
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6029
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6030
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6033
tcg_temp_free_i32(tmp2);
6037
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6038
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6039
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6044
tmp2 = tcg_const_i32(0);
6045
gen_neon_rsb(size, tmp, tmp2);
6046
tcg_temp_free_i32(tmp2);
6048
case NEON_2RM_VCGT0_F:
6050
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6051
tmp2 = tcg_const_i32(0);
6052
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6053
tcg_temp_free_i32(tmp2);
6054
tcg_temp_free_ptr(fpstatus);
6057
case NEON_2RM_VCGE0_F:
6059
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6060
tmp2 = tcg_const_i32(0);
6061
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6062
tcg_temp_free_i32(tmp2);
6063
tcg_temp_free_ptr(fpstatus);
6066
case NEON_2RM_VCEQ0_F:
6068
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6069
tmp2 = tcg_const_i32(0);
6070
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6071
tcg_temp_free_i32(tmp2);
6072
tcg_temp_free_ptr(fpstatus);
6075
case NEON_2RM_VCLE0_F:
6077
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6078
tmp2 = tcg_const_i32(0);
6079
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6080
tcg_temp_free_i32(tmp2);
6081
tcg_temp_free_ptr(fpstatus);
6084
case NEON_2RM_VCLT0_F:
6086
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6087
tmp2 = tcg_const_i32(0);
6088
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6089
tcg_temp_free_i32(tmp2);
6090
tcg_temp_free_ptr(fpstatus);
6093
case NEON_2RM_VABS_F:
6096
case NEON_2RM_VNEG_F:
6100
tmp2 = neon_load_reg(rd, pass);
6101
neon_store_reg(rm, pass, tmp2);
6104
tmp2 = neon_load_reg(rd, pass);
6106
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6107
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6110
neon_store_reg(rm, pass, tmp2);
6112
case NEON_2RM_VRECPE:
6113
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6115
case NEON_2RM_VRSQRTE:
6116
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6118
case NEON_2RM_VRECPE_F:
6119
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6121
case NEON_2RM_VRSQRTE_F:
6122
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6124
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6127
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6130
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6131
gen_vfp_tosiz(0, 1);
6133
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6134
gen_vfp_touiz(0, 1);
6137
/* Reserved op values were caught by the
6138
* neon_2rm_sizes[] check earlier.
6142
if (neon_2rm_is_float_op(op)) {
6143
tcg_gen_st_f32(cpu_F0s, cpu_env,
6144
neon_reg_offset(rd, pass));
6146
neon_store_reg(rd, pass, tmp);
6151
} else if ((insn & (1 << 10)) == 0) {
6153
int n = ((insn >> 8) & 3) + 1;
6154
if ((rn + n) > 32) {
6155
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6156
* helper function running off the end of the register file.
6161
if (insn & (1 << 6)) {
6162
tmp = neon_load_reg(rd, 0);
6164
tmp = tcg_temp_new_i32();
6165
tcg_gen_movi_i32(tmp, 0);
6167
tmp2 = neon_load_reg(rm, 0);
6168
tmp4 = tcg_const_i32(rn);
6169
tmp5 = tcg_const_i32(n);
6170
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6171
tcg_temp_free_i32(tmp);
6172
if (insn & (1 << 6)) {
6173
tmp = neon_load_reg(rd, 1);
6175
tmp = tcg_temp_new_i32();
6176
tcg_gen_movi_i32(tmp, 0);
6178
tmp3 = neon_load_reg(rm, 1);
6179
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6180
tcg_temp_free_i32(tmp5);
6181
tcg_temp_free_i32(tmp4);
6182
neon_store_reg(rd, 0, tmp2);
6183
neon_store_reg(rd, 1, tmp3);
6184
tcg_temp_free_i32(tmp);
6185
} else if ((insn & 0x380) == 0) {
6187
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6190
if (insn & (1 << 19)) {
6191
tmp = neon_load_reg(rm, 1);
6193
tmp = neon_load_reg(rm, 0);
6195
if (insn & (1 << 16)) {
6196
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6197
} else if (insn & (1 << 17)) {
6198
if ((insn >> 18) & 1)
6199
gen_neon_dup_high16(tmp);
6201
gen_neon_dup_low16(tmp);
6203
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6204
tmp2 = tcg_temp_new_i32();
6205
tcg_gen_mov_i32(tmp2, tmp);
6206
neon_store_reg(rd, pass, tmp2);
6208
tcg_temp_free_i32(tmp);
6217
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6219
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6220
const ARMCPRegInfo *ri;
6221
ARMCPU *cpu = arm_env_get_cpu(env);
6223
cpnum = (insn >> 8) & 0xf;
6224
if (arm_feature(env, ARM_FEATURE_XSCALE)
6225
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6228
/* First check for coprocessor space used for actual instructions */
6232
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6233
return disas_iwmmxt_insn(env, s, insn);
6234
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6235
return disas_dsp_insn(env, s, insn);
6240
return disas_vfp_insn (env, s, insn);
6245
/* Otherwise treat as a generic register access */
6246
is64 = (insn & (1 << 25)) == 0;
6247
if (!is64 && ((insn & (1 << 4)) == 0)) {
6255
opc1 = (insn >> 4) & 0xf;
6257
rt2 = (insn >> 16) & 0xf;
6259
crn = (insn >> 16) & 0xf;
6260
opc1 = (insn >> 21) & 7;
6261
opc2 = (insn >> 5) & 7;
6264
isread = (insn >> 20) & 1;
6265
rt = (insn >> 12) & 0xf;
6267
ri = get_arm_cp_reginfo(cpu,
6268
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6270
/* Check access permissions */
6271
if (!cp_access_ok(env, ri, isread)) {
6275
/* Handle special cases first */
6276
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6283
gen_set_pc_im(s->pc);
6284
s->is_jmp = DISAS_WFI;
6295
if (ri->type & ARM_CP_CONST) {
6296
tmp64 = tcg_const_i64(ri->resetvalue);
6297
} else if (ri->readfn) {
6299
gen_set_pc_im(s->pc);
6300
tmp64 = tcg_temp_new_i64();
6301
tmpptr = tcg_const_ptr(ri);
6302
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6303
tcg_temp_free_ptr(tmpptr);
6305
tmp64 = tcg_temp_new_i64();
6306
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6308
tmp = tcg_temp_new_i32();
6309
tcg_gen_trunc_i64_i32(tmp, tmp64);
6310
store_reg(s, rt, tmp);
6311
tcg_gen_shri_i64(tmp64, tmp64, 32);
6312
tmp = tcg_temp_new_i32();
6313
tcg_gen_trunc_i64_i32(tmp, tmp64);
6314
tcg_temp_free_i64(tmp64);
6315
store_reg(s, rt2, tmp);
6318
if (ri->type & ARM_CP_CONST) {
6319
tmp = tcg_const_i32(ri->resetvalue);
6320
} else if (ri->readfn) {
6322
gen_set_pc_im(s->pc);
6323
tmp = tcg_temp_new_i32();
6324
tmpptr = tcg_const_ptr(ri);
6325
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6326
tcg_temp_free_ptr(tmpptr);
6328
tmp = load_cpu_offset(ri->fieldoffset);
6331
/* Destination register of r15 for 32 bit loads sets
6332
* the condition codes from the high 4 bits of the value
6335
tcg_temp_free_i32(tmp);
6337
store_reg(s, rt, tmp);
6342
if (ri->type & ARM_CP_CONST) {
6343
/* If not forbidden by access permissions, treat as WI */
6348
TCGv_i32 tmplo, tmphi;
6349
TCGv_i64 tmp64 = tcg_temp_new_i64();
6350
tmplo = load_reg(s, rt);
6351
tmphi = load_reg(s, rt2);
6352
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6353
tcg_temp_free_i32(tmplo);
6354
tcg_temp_free_i32(tmphi);
6356
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6357
gen_set_pc_im(s->pc);
6358
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6359
tcg_temp_free_ptr(tmpptr);
6361
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6363
tcg_temp_free_i64(tmp64);
6368
gen_set_pc_im(s->pc);
6369
tmp = load_reg(s, rt);
6370
tmpptr = tcg_const_ptr(ri);
6371
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6372
tcg_temp_free_ptr(tmpptr);
6373
tcg_temp_free_i32(tmp);
6375
TCGv_i32 tmp = load_reg(s, rt);
6376
store_cpu_offset(tmp, ri->fieldoffset);
6379
/* We default to ending the TB on a coprocessor register write,
6380
* but allow this to be suppressed by the register definition
6381
* (usually only necessary to work around guest bugs).
6383
if (!(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6394
/* Store a 64-bit value to a register pair. Clobbers val. */
6395
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6398
tmp = tcg_temp_new_i32();
6399
tcg_gen_trunc_i64_i32(tmp, val);
6400
store_reg(s, rlow, tmp);
6401
tmp = tcg_temp_new_i32();
6402
tcg_gen_shri_i64(val, val, 32);
6403
tcg_gen_trunc_i64_i32(tmp, val);
6404
store_reg(s, rhigh, tmp);
6407
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6408
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6413
/* Load value and extend to 64 bits. */
6414
tmp = tcg_temp_new_i64();
6415
tmp2 = load_reg(s, rlow);
6416
tcg_gen_extu_i32_i64(tmp, tmp2);
6417
tcg_temp_free_i32(tmp2);
6418
tcg_gen_add_i64(val, val, tmp);
6419
tcg_temp_free_i64(tmp);
6422
/* load and add a 64-bit value from a register pair. */
6423
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6429
/* Load 64-bit value rd:rn. */
6430
tmpl = load_reg(s, rlow);
6431
tmph = load_reg(s, rhigh);
6432
tmp = tcg_temp_new_i64();
6433
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6434
tcg_temp_free_i32(tmpl);
6435
tcg_temp_free_i32(tmph);
6436
tcg_gen_add_i64(val, val, tmp);
6437
tcg_temp_free_i64(tmp);
6440
/* Set N and Z flags from hi|lo. */
6441
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6443
tcg_gen_mov_i32(cpu_NF, hi);
6444
tcg_gen_or_i32(cpu_ZF, lo, hi);
6447
/* Load/Store exclusive instructions are implemented by remembering
6448
the value/address loaded, and seeing if these are the same
6449
when the store is performed. This should be sufficient to implement
6450
the architecturally mandated semantics, and avoids having to monitor
6453
In system emulation mode only one CPU will be running at once, so
6454
this sequence is effectively atomic. In user emulation mode we
6455
throw an exception and handle the atomic operation elsewhere. */
6456
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6457
TCGv_i32 addr, int size)
6459
TCGv_i32 tmp = tcg_temp_new_i32();
6463
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
6466
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
6470
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
6475
tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6476
store_reg(s, rt, tmp);
6478
TCGv_i32 tmp2 = tcg_temp_new_i32();
6479
tcg_gen_addi_i32(tmp2, addr, 4);
6480
tmp = tcg_temp_new_i32();
6481
tcg_gen_qemu_ld32u(tmp, tmp2, IS_USER(s));
6482
tcg_temp_free_i32(tmp2);
6483
tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6484
store_reg(s, rt2, tmp);
6486
tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6489
static void gen_clrex(DisasContext *s)
6491
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6494
#ifdef CONFIG_USER_ONLY
6495
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6496
TCGv_i32 addr, int size)
6498
tcg_gen_mov_i32(cpu_exclusive_test, addr);
6499
tcg_gen_movi_i32(cpu_exclusive_info,
6500
size | (rd << 4) | (rt << 8) | (rt2 << 12));
6501
gen_exception_insn(s, 4, EXCP_STREX);
6504
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6505
TCGv_i32 addr, int size)
6511
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6517
fail_label = gen_new_label();
6518
done_label = gen_new_label();
6519
tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6520
tmp = tcg_temp_new_i32();
6523
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
6526
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
6530
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
6535
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6536
tcg_temp_free_i32(tmp);
6538
TCGv_i32 tmp2 = tcg_temp_new_i32();
6539
tcg_gen_addi_i32(tmp2, addr, 4);
6540
tmp = tcg_temp_new_i32();
6541
tcg_gen_qemu_ld32u(tmp, tmp2, IS_USER(s));
6542
tcg_temp_free_i32(tmp2);
6543
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6544
tcg_temp_free_i32(tmp);
6546
tmp = load_reg(s, rt);
6549
tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
6552
tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
6556
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
6561
tcg_temp_free_i32(tmp);
6563
tcg_gen_addi_i32(addr, addr, 4);
6564
tmp = load_reg(s, rt2);
6565
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
6566
tcg_temp_free_i32(tmp);
6568
tcg_gen_movi_i32(cpu_R[rd], 0);
6569
tcg_gen_br(done_label);
6570
gen_set_label(fail_label);
6571
tcg_gen_movi_i32(cpu_R[rd], 1);
6572
gen_set_label(done_label);
6573
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6580
* @mode: mode field from insn (which stack to store to)
6581
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6582
* @writeback: true if writeback bit set
6584
* Generate code for the SRS (Store Return State) insn.
6586
static void gen_srs(DisasContext *s,
6587
uint32_t mode, uint32_t amode, bool writeback)
6590
TCGv_i32 addr = tcg_temp_new_i32();
6591
TCGv_i32 tmp = tcg_const_i32(mode);
6592
gen_helper_get_r13_banked(addr, cpu_env, tmp);
6593
tcg_temp_free_i32(tmp);
6610
tcg_gen_addi_i32(addr, addr, offset);
6611
tmp = load_reg(s, 14);
6612
tcg_gen_qemu_st32(tmp, addr, 0);
6613
tcg_temp_free_i32(tmp);
6614
tmp = load_cpu_field(spsr);
6615
tcg_gen_addi_i32(addr, addr, 4);
6616
tcg_gen_qemu_st32(tmp, addr, 0);
6617
tcg_temp_free_i32(tmp);
6635
tcg_gen_addi_i32(addr, addr, offset);
6636
tmp = tcg_const_i32(mode);
6637
gen_helper_set_r13_banked(cpu_env, tmp, addr);
6638
tcg_temp_free_i32(tmp);
6640
tcg_temp_free_i32(addr);
6643
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6645
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6652
insn = arm_ldl_code(env, s->pc, s->bswap_code);
6655
/* M variants do not implement ARM mode. */
6660
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6661
* choose to UNDEF. In ARMv5 and above the space is used
6662
* for miscellaneous unconditional instructions.
6666
/* Unconditional instructions. */
6667
if (((insn >> 25) & 7) == 1) {
6668
/* NEON Data processing. */
6669
if (!arm_feature(env, ARM_FEATURE_NEON))
6672
if (disas_neon_data_insn(env, s, insn))
6676
if ((insn & 0x0f100000) == 0x04000000) {
6677
/* NEON load/store. */
6678
if (!arm_feature(env, ARM_FEATURE_NEON))
6681
if (disas_neon_ls_insn(env, s, insn))
6685
if (((insn & 0x0f30f000) == 0x0510f000) ||
6686
((insn & 0x0f30f010) == 0x0710f000)) {
6687
if ((insn & (1 << 22)) == 0) {
6689
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6693
/* Otherwise PLD; v5TE+ */
6697
if (((insn & 0x0f70f000) == 0x0450f000) ||
6698
((insn & 0x0f70f010) == 0x0650f000)) {
6700
return; /* PLI; V7 */
6702
if (((insn & 0x0f700000) == 0x04100000) ||
6703
((insn & 0x0f700010) == 0x06100000)) {
6704
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6707
return; /* v7MP: Unallocated memory hint: must NOP */
6710
if ((insn & 0x0ffffdff) == 0x01010000) {
6713
if (((insn >> 9) & 1) != s->bswap_code) {
6714
/* Dynamic endianness switching not implemented. */
6718
} else if ((insn & 0x0fffff00) == 0x057ff000) {
6719
switch ((insn >> 4) & 0xf) {
6728
/* We don't emulate caches so these are a no-op. */
6733
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6739
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
6741
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6747
rn = (insn >> 16) & 0xf;
6748
addr = load_reg(s, rn);
6749
i = (insn >> 23) & 3;
6751
case 0: offset = -4; break; /* DA */
6752
case 1: offset = 0; break; /* IA */
6753
case 2: offset = -8; break; /* DB */
6754
case 3: offset = 4; break; /* IB */
6758
tcg_gen_addi_i32(addr, addr, offset);
6759
/* Load PC into tmp and CPSR into tmp2. */
6760
tmp = tcg_temp_new_i32();
6761
tcg_gen_qemu_ld32u(tmp, addr, 0);
6762
tcg_gen_addi_i32(addr, addr, 4);
6763
tmp2 = tcg_temp_new_i32();
6764
tcg_gen_qemu_ld32u(tmp2, addr, 0);
6765
if (insn & (1 << 21)) {
6766
/* Base writeback. */
6768
case 0: offset = -8; break;
6769
case 1: offset = 4; break;
6770
case 2: offset = -4; break;
6771
case 3: offset = 0; break;
6775
tcg_gen_addi_i32(addr, addr, offset);
6776
store_reg(s, rn, addr);
6778
tcg_temp_free_i32(addr);
6780
gen_rfe(s, tmp, tmp2);
6782
} else if ((insn & 0x0e000000) == 0x0a000000) {
6783
/* branch link and change to thumb (blx <offset>) */
6786
val = (uint32_t)s->pc;
6787
tmp = tcg_temp_new_i32();
6788
tcg_gen_movi_i32(tmp, val);
6789
store_reg(s, 14, tmp);
6790
/* Sign-extend the 24-bit offset */
6791
offset = (((int32_t)insn) << 8) >> 8;
6792
/* offset * 4 + bit24 * 2 + (thumb bit) */
6793
val += (offset << 2) | ((insn >> 23) & 2) | 1;
6794
/* pipeline offset */
6796
/* protected by ARCH(5); above, near the start of uncond block */
6799
} else if ((insn & 0x0e000f00) == 0x0c000100) {
6800
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6801
/* iWMMXt register transfer. */
6802
if (env->cp15.c15_cpar & (1 << 1))
6803
if (!disas_iwmmxt_insn(env, s, insn))
6806
} else if ((insn & 0x0fe00000) == 0x0c400000) {
6807
/* Coprocessor double register transfer. */
6809
/* XXX doesn't belong in the trustzone patch: should just UNDEF? */
6810
cpu_abort(env, "unsupported coprocessor double register transfer\n");
6811
} else if ((insn & 0x0f000010) == 0x0e000010) {
6812
/* Additional coprocessor register transfer. */
6813
if (!disas_coproc_insn(env, s, insn)) {
6816
} else if ((insn & 0x0ff10020) == 0x01000000) {
6819
/* cps (privileged) */
6823
if (insn & (1 << 19)) {
6824
if (insn & (1 << 8))
6826
if (insn & (1 << 7))
6828
if (insn & (1 << 6))
6830
if (insn & (1 << 18))
6833
if (insn & (1 << 17)) {
6835
val |= (insn & 0x1f);
6838
gen_set_psr_im(s, mask, 0, val);
6845
/* if not always execute, we generate a conditional jump to
6847
s->condlabel = gen_new_label();
6848
gen_test_cc(cond ^ 1, s->condlabel);
6851
if ((insn & 0x0f900000) == 0x03000000) {
6852
if ((insn & (1 << 21)) == 0) {
6854
rd = (insn >> 12) & 0xf;
6855
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6856
if ((insn & (1 << 22)) == 0) {
6858
tmp = tcg_temp_new_i32();
6859
tcg_gen_movi_i32(tmp, val);
6862
tmp = load_reg(s, rd);
6863
tcg_gen_ext16u_i32(tmp, tmp);
6864
tcg_gen_ori_i32(tmp, tmp, val << 16);
6866
store_reg(s, rd, tmp);
6868
if (((insn >> 12) & 0xf) != 0xf)
6870
if (((insn >> 16) & 0xf) == 0) {
6871
gen_nop_hint(s, insn & 0xff);
6873
/* CPSR = immediate */
6875
shift = ((insn >> 8) & 0xf) * 2;
6877
val = (val >> shift) | (val << (32 - shift));
6878
i = ((insn & (1 << 22)) != 0);
6879
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6883
} else if ((insn & 0x0f900000) == 0x01000000
6884
&& (insn & 0x00000090) != 0x00000090) {
6885
/* miscellaneous instructions */
6886
op1 = (insn >> 21) & 3;
6887
sh = (insn >> 4) & 0xf;
6890
case 0x0: /* move program status register */
6893
tmp = load_reg(s, rm);
6894
i = ((op1 & 2) != 0);
6895
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6899
rd = (insn >> 12) & 0xf;
6903
tmp = load_cpu_field(spsr);
6905
tmp = tcg_temp_new_i32();
6906
gen_helper_cpsr_read(tmp, cpu_env);
6908
store_reg(s, rd, tmp);
6913
/* branch/exchange thumb (bx). */
6915
tmp = load_reg(s, rm);
6917
} else if (op1 == 3) {
6920
rd = (insn >> 12) & 0xf;
6921
tmp = load_reg(s, rm);
6922
gen_helper_clz(tmp, tmp);
6923
store_reg(s, rd, tmp);
6931
/* Trivial implementation equivalent to bx. */
6932
tmp = load_reg(s, rm);
6943
/* branch link/exchange thumb (blx) */
6944
tmp = load_reg(s, rm);
6945
tmp2 = tcg_temp_new_i32();
6946
tcg_gen_movi_i32(tmp2, s->pc);
6947
store_reg(s, 14, tmp2);
6950
case 0x5: /* saturating add/subtract */
6952
rd = (insn >> 12) & 0xf;
6953
rn = (insn >> 16) & 0xf;
6954
tmp = load_reg(s, rm);
6955
tmp2 = load_reg(s, rn);
6957
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
6959
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
6961
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
6962
tcg_temp_free_i32(tmp2);
6963
store_reg(s, rd, tmp);
6969
gen_exception_insn(s, 4, EXCP_BKPT);
6970
} else if (op1 == 3) {
6972
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
6980
case 0x8: /* signed multiply */
6985
rs = (insn >> 8) & 0xf;
6986
rn = (insn >> 12) & 0xf;
6987
rd = (insn >> 16) & 0xf;
6989
/* (32 * 16) >> 16 */
6990
tmp = load_reg(s, rm);
6991
tmp2 = load_reg(s, rs);
6993
tcg_gen_sari_i32(tmp2, tmp2, 16);
6996
tmp64 = gen_muls_i64_i32(tmp, tmp2);
6997
tcg_gen_shri_i64(tmp64, tmp64, 16);
6998
tmp = tcg_temp_new_i32();
6999
tcg_gen_trunc_i64_i32(tmp, tmp64);
7000
tcg_temp_free_i64(tmp64);
7001
if ((sh & 2) == 0) {
7002
tmp2 = load_reg(s, rn);
7003
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7004
tcg_temp_free_i32(tmp2);
7006
store_reg(s, rd, tmp);
7009
tmp = load_reg(s, rm);
7010
tmp2 = load_reg(s, rs);
7011
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7012
tcg_temp_free_i32(tmp2);
7014
tmp64 = tcg_temp_new_i64();
7015
tcg_gen_ext_i32_i64(tmp64, tmp);
7016
tcg_temp_free_i32(tmp);
7017
gen_addq(s, tmp64, rn, rd);
7018
gen_storeq_reg(s, rn, rd, tmp64);
7019
tcg_temp_free_i64(tmp64);
7022
tmp2 = load_reg(s, rn);
7023
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7024
tcg_temp_free_i32(tmp2);
7026
store_reg(s, rd, tmp);
7033
} else if (((insn & 0x0e000000) == 0 &&
7034
(insn & 0x00000090) != 0x90) ||
7035
((insn & 0x0e000000) == (1 << 25))) {
7036
int set_cc, logic_cc, shiftop;
7038
op1 = (insn >> 21) & 0xf;
7039
set_cc = (insn >> 20) & 1;
7040
logic_cc = table_logic_cc[op1] & set_cc;
7042
/* data processing instruction */
7043
if (insn & (1 << 25)) {
7044
/* immediate operand */
7046
shift = ((insn >> 8) & 0xf) * 2;
7048
val = (val >> shift) | (val << (32 - shift));
7050
tmp2 = tcg_temp_new_i32();
7051
tcg_gen_movi_i32(tmp2, val);
7052
if (logic_cc && shift) {
7053
gen_set_CF_bit31(tmp2);
7058
tmp2 = load_reg(s, rm);
7059
shiftop = (insn >> 5) & 3;
7060
if (!(insn & (1 << 4))) {
7061
shift = (insn >> 7) & 0x1f;
7062
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7064
rs = (insn >> 8) & 0xf;
7065
tmp = load_reg(s, rs);
7066
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7069
if (op1 != 0x0f && op1 != 0x0d) {
7070
rn = (insn >> 16) & 0xf;
7071
tmp = load_reg(s, rn);
7073
TCGV_UNUSED_I32(tmp);
7075
rd = (insn >> 12) & 0xf;
7078
tcg_gen_and_i32(tmp, tmp, tmp2);
7082
store_reg_bx(env, s, rd, tmp);
7085
tcg_gen_xor_i32(tmp, tmp, tmp2);
7089
store_reg_bx(env, s, rd, tmp);
7092
if (set_cc && rd == 15) {
7093
/* SUBS r15, ... is used for exception return. */
7097
gen_sub_CC(tmp, tmp, tmp2);
7098
gen_exception_return(s, tmp);
7101
gen_sub_CC(tmp, tmp, tmp2);
7103
tcg_gen_sub_i32(tmp, tmp, tmp2);
7105
store_reg_bx(env, s, rd, tmp);
7110
gen_sub_CC(tmp, tmp2, tmp);
7112
tcg_gen_sub_i32(tmp, tmp2, tmp);
7114
store_reg_bx(env, s, rd, tmp);
7118
gen_add_CC(tmp, tmp, tmp2);
7120
tcg_gen_add_i32(tmp, tmp, tmp2);
7122
store_reg_bx(env, s, rd, tmp);
7126
gen_adc_CC(tmp, tmp, tmp2);
7128
gen_add_carry(tmp, tmp, tmp2);
7130
store_reg_bx(env, s, rd, tmp);
7134
gen_sbc_CC(tmp, tmp, tmp2);
7136
gen_sub_carry(tmp, tmp, tmp2);
7138
store_reg_bx(env, s, rd, tmp);
7142
gen_sbc_CC(tmp, tmp2, tmp);
7144
gen_sub_carry(tmp, tmp2, tmp);
7146
store_reg_bx(env, s, rd, tmp);
7150
tcg_gen_and_i32(tmp, tmp, tmp2);
7153
tcg_temp_free_i32(tmp);
7157
tcg_gen_xor_i32(tmp, tmp, tmp2);
7160
tcg_temp_free_i32(tmp);
7164
gen_sub_CC(tmp, tmp, tmp2);
7166
tcg_temp_free_i32(tmp);
7170
gen_add_CC(tmp, tmp, tmp2);
7172
tcg_temp_free_i32(tmp);
7175
tcg_gen_or_i32(tmp, tmp, tmp2);
7179
store_reg_bx(env, s, rd, tmp);
7182
if (logic_cc && rd == 15) {
7183
/* MOVS r15, ... is used for exception return. */
7187
gen_exception_return(s, tmp2);
7192
store_reg_bx(env, s, rd, tmp2);
7196
tcg_gen_andc_i32(tmp, tmp, tmp2);
7200
store_reg_bx(env, s, rd, tmp);
7204
tcg_gen_not_i32(tmp2, tmp2);
7208
store_reg_bx(env, s, rd, tmp2);
7211
if (op1 != 0x0f && op1 != 0x0d) {
7212
tcg_temp_free_i32(tmp2);
7215
/* other instructions */
7216
op1 = (insn >> 24) & 0xf;
7220
/* multiplies, extra load/stores */
7221
sh = (insn >> 5) & 3;
7224
rd = (insn >> 16) & 0xf;
7225
rn = (insn >> 12) & 0xf;
7226
rs = (insn >> 8) & 0xf;
7228
op1 = (insn >> 20) & 0xf;
7230
case 0: case 1: case 2: case 3: case 6:
7232
tmp = load_reg(s, rs);
7233
tmp2 = load_reg(s, rm);
7234
tcg_gen_mul_i32(tmp, tmp, tmp2);
7235
tcg_temp_free_i32(tmp2);
7236
if (insn & (1 << 22)) {
7237
/* Subtract (mls) */
7239
tmp2 = load_reg(s, rn);
7240
tcg_gen_sub_i32(tmp, tmp2, tmp);
7241
tcg_temp_free_i32(tmp2);
7242
} else if (insn & (1 << 21)) {
7244
tmp2 = load_reg(s, rn);
7245
tcg_gen_add_i32(tmp, tmp, tmp2);
7246
tcg_temp_free_i32(tmp2);
7248
if (insn & (1 << 20))
7250
store_reg(s, rd, tmp);
7253
/* 64 bit mul double accumulate (UMAAL) */
7255
tmp = load_reg(s, rs);
7256
tmp2 = load_reg(s, rm);
7257
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7258
gen_addq_lo(s, tmp64, rn);
7259
gen_addq_lo(s, tmp64, rd);
7260
gen_storeq_reg(s, rn, rd, tmp64);
7261
tcg_temp_free_i64(tmp64);
7263
case 8: case 9: case 10: case 11:
7264
case 12: case 13: case 14: case 15:
7265
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7266
tmp = load_reg(s, rs);
7267
tmp2 = load_reg(s, rm);
7268
if (insn & (1 << 22)) {
7269
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7271
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7273
if (insn & (1 << 21)) { /* mult accumulate */
7274
TCGv_i32 al = load_reg(s, rn);
7275
TCGv_i32 ah = load_reg(s, rd);
7276
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7277
tcg_temp_free_i32(al);
7278
tcg_temp_free_i32(ah);
7280
if (insn & (1 << 20)) {
7281
gen_logicq_cc(tmp, tmp2);
7283
store_reg(s, rn, tmp);
7284
store_reg(s, rd, tmp2);
7290
rn = (insn >> 16) & 0xf;
7291
rd = (insn >> 12) & 0xf;
7292
if (insn & (1 << 23)) {
7293
/* load/store exclusive */
7294
int op2 = (insn >> 8) & 3;
7295
op1 = (insn >> 21) & 0x3;
7298
case 0: /* lda/stl */
7304
case 1: /* reserved */
7306
case 2: /* ldaex/stlex */
7309
case 3: /* ldrex/strex */
7318
addr = tcg_temp_local_new_i32();
7319
load_reg_var(s, addr, rn);
7321
/* Since the emulation does not have barriers,
7322
the acquire/release semantics need no special
7325
if (insn & (1 << 20)) {
7326
tmp = tcg_temp_new_i32();
7329
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
7332
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
7335
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
7340
store_reg(s, rd, tmp);
7343
tmp = load_reg(s, rm);
7346
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
7349
tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
7352
tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
7357
tcg_temp_free_i32(tmp);
7359
} else if (insn & (1 << 20)) {
7362
gen_load_exclusive(s, rd, 15, addr, 2);
7364
case 1: /* ldrexd */
7365
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7367
case 2: /* ldrexb */
7368
gen_load_exclusive(s, rd, 15, addr, 0);
7370
case 3: /* ldrexh */
7371
gen_load_exclusive(s, rd, 15, addr, 1);
7380
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7382
case 1: /* strexd */
7383
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7385
case 2: /* strexb */
7386
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7388
case 3: /* strexh */
7389
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7395
tcg_temp_free_i32(addr);
7397
/* SWP instruction */
7400
/* ??? This is not really atomic. However we know
7401
we never have multiple CPUs running in parallel,
7402
so it is good enough. */
7403
addr = load_reg(s, rn);
7404
tmp = load_reg(s, rm);
7405
tmp2 = tcg_temp_new_i32();
7406
if (insn & (1 << 22)) {
7407
tcg_gen_qemu_ld8u(tmp2, addr, IS_USER(s));
7408
tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
7410
tcg_gen_qemu_ld32u(tmp2, addr, IS_USER(s));
7411
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
7413
tcg_temp_free_i32(tmp);
7414
tcg_temp_free_i32(addr);
7415
store_reg(s, rd, tmp2);
7421
/* Misc load/store */
7422
rn = (insn >> 16) & 0xf;
7423
rd = (insn >> 12) & 0xf;
7424
addr = load_reg(s, rn);
7425
if (insn & (1 << 24))
7426
gen_add_datah_offset(s, insn, 0, addr);
7428
if (insn & (1 << 20)) {
7430
tmp = tcg_temp_new_i32();
7433
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
7436
tcg_gen_qemu_ld8s(tmp, addr, IS_USER(s));
7440
tcg_gen_qemu_ld16s(tmp, addr, IS_USER(s));
7444
} else if (sh & 2) {
7449
tmp = load_reg(s, rd);
7450
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
7451
tcg_temp_free_i32(tmp);
7452
tcg_gen_addi_i32(addr, addr, 4);
7453
tmp = load_reg(s, rd + 1);
7454
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
7455
tcg_temp_free_i32(tmp);
7459
tmp = tcg_temp_new_i32();
7460
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
7461
store_reg(s, rd, tmp);
7462
tcg_gen_addi_i32(addr, addr, 4);
7463
tmp = tcg_temp_new_i32();
7464
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
7468
address_offset = -4;
7471
tmp = load_reg(s, rd);
7472
tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
7473
tcg_temp_free_i32(tmp);
7476
/* Perform base writeback before the loaded value to
7477
ensure correct behavior with overlapping index registers.
7478
ldrd with base writeback is is undefined if the
7479
destination and index registers overlap. */
7480
if (!(insn & (1 << 24))) {
7481
gen_add_datah_offset(s, insn, address_offset, addr);
7482
store_reg(s, rn, addr);
7483
} else if (insn & (1 << 21)) {
7485
tcg_gen_addi_i32(addr, addr, address_offset);
7486
store_reg(s, rn, addr);
7488
tcg_temp_free_i32(addr);
7491
/* Complete the load. */
7492
store_reg(s, rd, tmp);
7501
if (insn & (1 << 4)) {
7503
/* Armv6 Media instructions. */
7505
rn = (insn >> 16) & 0xf;
7506
rd = (insn >> 12) & 0xf;
7507
rs = (insn >> 8) & 0xf;
7508
switch ((insn >> 23) & 3) {
7509
case 0: /* Parallel add/subtract. */
7510
op1 = (insn >> 20) & 7;
7511
tmp = load_reg(s, rn);
7512
tmp2 = load_reg(s, rm);
7513
sh = (insn >> 5) & 7;
7514
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7516
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7517
tcg_temp_free_i32(tmp2);
7518
store_reg(s, rd, tmp);
7521
if ((insn & 0x00700020) == 0) {
7522
/* Halfword pack. */
7523
tmp = load_reg(s, rn);
7524
tmp2 = load_reg(s, rm);
7525
shift = (insn >> 7) & 0x1f;
7526
if (insn & (1 << 6)) {
7530
tcg_gen_sari_i32(tmp2, tmp2, shift);
7531
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7532
tcg_gen_ext16u_i32(tmp2, tmp2);
7536
tcg_gen_shli_i32(tmp2, tmp2, shift);
7537
tcg_gen_ext16u_i32(tmp, tmp);
7538
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7540
tcg_gen_or_i32(tmp, tmp, tmp2);
7541
tcg_temp_free_i32(tmp2);
7542
store_reg(s, rd, tmp);
7543
} else if ((insn & 0x00200020) == 0x00200000) {
7545
tmp = load_reg(s, rm);
7546
shift = (insn >> 7) & 0x1f;
7547
if (insn & (1 << 6)) {
7550
tcg_gen_sari_i32(tmp, tmp, shift);
7552
tcg_gen_shli_i32(tmp, tmp, shift);
7554
sh = (insn >> 16) & 0x1f;
7555
tmp2 = tcg_const_i32(sh);
7556
if (insn & (1 << 22))
7557
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7559
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7560
tcg_temp_free_i32(tmp2);
7561
store_reg(s, rd, tmp);
7562
} else if ((insn & 0x00300fe0) == 0x00200f20) {
7564
tmp = load_reg(s, rm);
7565
sh = (insn >> 16) & 0x1f;
7566
tmp2 = tcg_const_i32(sh);
7567
if (insn & (1 << 22))
7568
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7570
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7571
tcg_temp_free_i32(tmp2);
7572
store_reg(s, rd, tmp);
7573
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
7575
tmp = load_reg(s, rn);
7576
tmp2 = load_reg(s, rm);
7577
tmp3 = tcg_temp_new_i32();
7578
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7579
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7580
tcg_temp_free_i32(tmp3);
7581
tcg_temp_free_i32(tmp2);
7582
store_reg(s, rd, tmp);
7583
} else if ((insn & 0x000003e0) == 0x00000060) {
7584
tmp = load_reg(s, rm);
7585
shift = (insn >> 10) & 3;
7586
/* ??? In many cases it's not necessary to do a
7587
rotate, a shift is sufficient. */
7589
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7590
op1 = (insn >> 20) & 7;
7592
case 0: gen_sxtb16(tmp); break;
7593
case 2: gen_sxtb(tmp); break;
7594
case 3: gen_sxth(tmp); break;
7595
case 4: gen_uxtb16(tmp); break;
7596
case 6: gen_uxtb(tmp); break;
7597
case 7: gen_uxth(tmp); break;
7598
default: goto illegal_op;
7601
tmp2 = load_reg(s, rn);
7602
if ((op1 & 3) == 0) {
7603
gen_add16(tmp, tmp2);
7605
tcg_gen_add_i32(tmp, tmp, tmp2);
7606
tcg_temp_free_i32(tmp2);
7609
store_reg(s, rd, tmp);
7610
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
7612
tmp = load_reg(s, rm);
7613
if (insn & (1 << 22)) {
7614
if (insn & (1 << 7)) {
7618
gen_helper_rbit(tmp, tmp);
7621
if (insn & (1 << 7))
7624
tcg_gen_bswap32_i32(tmp, tmp);
7626
store_reg(s, rd, tmp);
7631
case 2: /* Multiplies (Type 3). */
7632
switch ((insn >> 20) & 0x7) {
7634
if (((insn >> 6) ^ (insn >> 7)) & 1) {
7635
/* op2 not 00x or 11x : UNDEF */
7638
/* Signed multiply most significant [accumulate].
7639
(SMMUL, SMMLA, SMMLS) */
7640
tmp = load_reg(s, rm);
7641
tmp2 = load_reg(s, rs);
7642
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7645
tmp = load_reg(s, rd);
7646
if (insn & (1 << 6)) {
7647
tmp64 = gen_subq_msw(tmp64, tmp);
7649
tmp64 = gen_addq_msw(tmp64, tmp);
7652
if (insn & (1 << 5)) {
7653
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7655
tcg_gen_shri_i64(tmp64, tmp64, 32);
7656
tmp = tcg_temp_new_i32();
7657
tcg_gen_trunc_i64_i32(tmp, tmp64);
7658
tcg_temp_free_i64(tmp64);
7659
store_reg(s, rn, tmp);
7663
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7664
if (insn & (1 << 7)) {
7667
tmp = load_reg(s, rm);
7668
tmp2 = load_reg(s, rs);
7669
if (insn & (1 << 5))
7670
gen_swap_half(tmp2);
7671
gen_smul_dual(tmp, tmp2);
7672
if (insn & (1 << 6)) {
7673
/* This subtraction cannot overflow. */
7674
tcg_gen_sub_i32(tmp, tmp, tmp2);
7676
/* This addition cannot overflow 32 bits;
7677
* however it may overflow considered as a signed
7678
* operation, in which case we must set the Q flag.
7680
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7682
tcg_temp_free_i32(tmp2);
7683
if (insn & (1 << 22)) {
7684
/* smlald, smlsld */
7685
tmp64 = tcg_temp_new_i64();
7686
tcg_gen_ext_i32_i64(tmp64, tmp);
7687
tcg_temp_free_i32(tmp);
7688
gen_addq(s, tmp64, rd, rn);
7689
gen_storeq_reg(s, rd, rn, tmp64);
7690
tcg_temp_free_i64(tmp64);
7692
/* smuad, smusd, smlad, smlsd */
7695
tmp2 = load_reg(s, rd);
7696
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7697
tcg_temp_free_i32(tmp2);
7699
store_reg(s, rn, tmp);
7705
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7708
if (((insn >> 5) & 7) || (rd != 15)) {
7711
tmp = load_reg(s, rm);
7712
tmp2 = load_reg(s, rs);
7713
if (insn & (1 << 21)) {
7714
gen_helper_udiv(tmp, tmp, tmp2);
7716
gen_helper_sdiv(tmp, tmp, tmp2);
7718
tcg_temp_free_i32(tmp2);
7719
store_reg(s, rn, tmp);
7726
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7728
case 0: /* Unsigned sum of absolute differences. */
7730
tmp = load_reg(s, rm);
7731
tmp2 = load_reg(s, rs);
7732
gen_helper_usad8(tmp, tmp, tmp2);
7733
tcg_temp_free_i32(tmp2);
7735
tmp2 = load_reg(s, rd);
7736
tcg_gen_add_i32(tmp, tmp, tmp2);
7737
tcg_temp_free_i32(tmp2);
7739
store_reg(s, rn, tmp);
7741
case 0x20: case 0x24: case 0x28: case 0x2c:
7742
/* Bitfield insert/clear. */
7744
shift = (insn >> 7) & 0x1f;
7745
i = (insn >> 16) & 0x1f;
7748
tmp = tcg_temp_new_i32();
7749
tcg_gen_movi_i32(tmp, 0);
7751
tmp = load_reg(s, rm);
7754
tmp2 = load_reg(s, rd);
7755
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
7756
tcg_temp_free_i32(tmp2);
7758
store_reg(s, rd, tmp);
7760
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7761
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7763
tmp = load_reg(s, rm);
7764
shift = (insn >> 7) & 0x1f;
7765
i = ((insn >> 16) & 0x1f) + 1;
7770
gen_ubfx(tmp, shift, (1u << i) - 1);
7772
gen_sbfx(tmp, shift, i);
7775
store_reg(s, rd, tmp);
7785
/* Check for undefined extension instructions
7786
* per the ARM Bible IE:
7787
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7789
sh = (0xf << 20) | (0xf << 4);
7790
if (op1 == 0x7 && ((insn & sh) == sh))
7794
/* load/store byte/word */
7795
rn = (insn >> 16) & 0xf;
7796
rd = (insn >> 12) & 0xf;
7797
tmp2 = load_reg(s, rn);
7798
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7799
if (insn & (1 << 24))
7800
gen_add_data_offset(s, insn, tmp2);
7801
if (insn & (1 << 20)) {
7803
tmp = tcg_temp_new_i32();
7804
if (insn & (1 << 22)) {
7805
tcg_gen_qemu_ld8u(tmp, tmp2, i);
7807
tcg_gen_qemu_ld32u(tmp, tmp2, i);
7811
tmp = load_reg(s, rd);
7812
if (insn & (1 << 22)) {
7813
tcg_gen_qemu_st8(tmp, tmp2, i);
7815
tcg_gen_qemu_st32(tmp, tmp2, i);
7817
tcg_temp_free_i32(tmp);
7819
if (!(insn & (1 << 24))) {
7820
gen_add_data_offset(s, insn, tmp2);
7821
store_reg(s, rn, tmp2);
7822
} else if (insn & (1 << 21)) {
7823
store_reg(s, rn, tmp2);
7825
tcg_temp_free_i32(tmp2);
7827
if (insn & (1 << 20)) {
7828
/* Complete the load. */
7829
store_reg_from_load(env, s, rd, tmp);
7835
int j, n, user, loaded_base;
7836
TCGv_i32 loaded_var;
7837
/* load/store multiple words */
7838
/* XXX: store correct base if write back */
7840
if (insn & (1 << 22)) {
7842
goto illegal_op; /* only usable in supervisor mode */
7844
if ((insn & (1 << 15)) == 0)
7847
rn = (insn >> 16) & 0xf;
7848
addr = load_reg(s, rn);
7850
/* compute total size */
7852
TCGV_UNUSED_I32(loaded_var);
7855
if (insn & (1 << i))
7858
/* XXX: test invalid n == 0 case ? */
7859
if (insn & (1 << 23)) {
7860
if (insn & (1 << 24)) {
7862
tcg_gen_addi_i32(addr, addr, 4);
7864
/* post increment */
7867
if (insn & (1 << 24)) {
7869
tcg_gen_addi_i32(addr, addr, -(n * 4));
7871
/* post decrement */
7873
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7878
if (insn & (1 << i)) {
7879
if (insn & (1 << 20)) {
7881
tmp = tcg_temp_new_i32();
7882
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
7884
tmp2 = tcg_const_i32(i);
7885
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
7886
tcg_temp_free_i32(tmp2);
7887
tcg_temp_free_i32(tmp);
7888
} else if (i == rn) {
7892
store_reg_from_load(env, s, i, tmp);
7897
/* special case: r15 = PC + 8 */
7898
val = (long)s->pc + 4;
7899
tmp = tcg_temp_new_i32();
7900
tcg_gen_movi_i32(tmp, val);
7902
tmp = tcg_temp_new_i32();
7903
tmp2 = tcg_const_i32(i);
7904
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
7905
tcg_temp_free_i32(tmp2);
7907
tmp = load_reg(s, i);
7909
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
7910
tcg_temp_free_i32(tmp);
7913
/* no need to add after the last transfer */
7915
tcg_gen_addi_i32(addr, addr, 4);
7918
if (insn & (1 << 21)) {
7920
if (insn & (1 << 23)) {
7921
if (insn & (1 << 24)) {
7924
/* post increment */
7925
tcg_gen_addi_i32(addr, addr, 4);
7928
if (insn & (1 << 24)) {
7931
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7933
/* post decrement */
7934
tcg_gen_addi_i32(addr, addr, -(n * 4));
7937
store_reg(s, rn, addr);
7939
tcg_temp_free_i32(addr);
7942
store_reg(s, rn, loaded_var);
7944
if ((insn & (1 << 22)) && !user) {
7945
/* Restore CPSR from SPSR. */
7946
tmp = load_cpu_field(spsr);
7947
gen_set_cpsr(tmp, 0xffffffff);
7948
tcg_temp_free_i32(tmp);
7949
s->is_jmp = DISAS_UPDATE;
7958
/* branch (and link) */
7959
val = (int32_t)s->pc;
7960
if (insn & (1 << 24)) {
7961
tmp = tcg_temp_new_i32();
7962
tcg_gen_movi_i32(tmp, val);
7963
store_reg(s, 14, tmp);
7965
offset = (((int32_t)insn << 8) >> 8);
7966
val += (offset << 2) + 4;
7974
if (disas_coproc_insn(env, s, insn))
7979
gen_set_pc_im(s->pc);
7980
s->is_jmp = DISAS_SWI;
7984
gen_exception_insn(s, 4, EXCP_UDEF);
7990
/* Return true if this is a Thumb-2 logical op. */
7992
thumb2_logic_op(int op)
7997
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7998
then set condition code flags based on the result of the operation.
7999
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8000
to the high bit of T1.
8001
Returns zero if the opcode is valid. */
8004
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8005
TCGv_i32 t0, TCGv_i32 t1)
8012
tcg_gen_and_i32(t0, t0, t1);
8016
tcg_gen_andc_i32(t0, t0, t1);
8020
tcg_gen_or_i32(t0, t0, t1);
8024
tcg_gen_orc_i32(t0, t0, t1);
8028
tcg_gen_xor_i32(t0, t0, t1);
8033
gen_add_CC(t0, t0, t1);
8035
tcg_gen_add_i32(t0, t0, t1);
8039
gen_adc_CC(t0, t0, t1);
8045
gen_sbc_CC(t0, t0, t1);
8047
gen_sub_carry(t0, t0, t1);
8052
gen_sub_CC(t0, t0, t1);
8054
tcg_gen_sub_i32(t0, t0, t1);
8058
gen_sub_CC(t0, t1, t0);
8060
tcg_gen_sub_i32(t0, t1, t0);
8062
default: /* 5, 6, 7, 9, 12, 15. */
8068
gen_set_CF_bit31(t1);
8073
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8075
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8077
uint32_t insn, imm, shift, offset;
8078
uint32_t rd, rn, rm, rs;
8089
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8090
|| arm_feature (env, ARM_FEATURE_M))) {
8091
/* Thumb-1 cores may need to treat bl and blx as a pair of
8092
16-bit instructions to get correct prefetch abort behavior. */
8094
if ((insn & (1 << 12)) == 0) {
8096
/* Second half of blx. */
8097
offset = ((insn & 0x7ff) << 1);
8098
tmp = load_reg(s, 14);
8099
tcg_gen_addi_i32(tmp, tmp, offset);
8100
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8102
tmp2 = tcg_temp_new_i32();
8103
tcg_gen_movi_i32(tmp2, s->pc | 1);
8104
store_reg(s, 14, tmp2);
8108
if (insn & (1 << 11)) {
8109
/* Second half of bl. */
8110
offset = ((insn & 0x7ff) << 1) | 1;
8111
tmp = load_reg(s, 14);
8112
tcg_gen_addi_i32(tmp, tmp, offset);
8114
tmp2 = tcg_temp_new_i32();
8115
tcg_gen_movi_i32(tmp2, s->pc | 1);
8116
store_reg(s, 14, tmp2);
8120
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8121
/* Instruction spans a page boundary. Implement it as two
8122
16-bit instructions in case the second half causes an
8124
offset = ((int32_t)insn << 21) >> 9;
8125
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8128
/* Fall through to 32-bit decode. */
8131
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8133
insn |= (uint32_t)insn_hw1 << 16;
8135
if ((insn & 0xf800e800) != 0xf000e800) {
8139
rn = (insn >> 16) & 0xf;
8140
rs = (insn >> 12) & 0xf;
8141
rd = (insn >> 8) & 0xf;
8143
switch ((insn >> 25) & 0xf) {
8144
case 0: case 1: case 2: case 3:
8145
/* 16-bit instructions. Should never happen. */
8148
if (insn & (1 << 22)) {
8149
/* Other load/store, table branch. */
8150
if (insn & 0x01200000) {
8151
/* Load/store doubleword. */
8153
addr = tcg_temp_new_i32();
8154
tcg_gen_movi_i32(addr, s->pc & ~3);
8156
addr = load_reg(s, rn);
8158
offset = (insn & 0xff) * 4;
8159
if ((insn & (1 << 23)) == 0)
8161
if (insn & (1 << 24)) {
8162
tcg_gen_addi_i32(addr, addr, offset);
8165
if (insn & (1 << 20)) {
8167
tmp = tcg_temp_new_i32();
8168
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
8169
store_reg(s, rs, tmp);
8170
tcg_gen_addi_i32(addr, addr, 4);
8171
tmp = tcg_temp_new_i32();
8172
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
8173
store_reg(s, rd, tmp);
8176
tmp = load_reg(s, rs);
8177
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
8178
tcg_temp_free_i32(tmp);
8179
tcg_gen_addi_i32(addr, addr, 4);
8180
tmp = load_reg(s, rd);
8181
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
8182
tcg_temp_free_i32(tmp);
8184
if (insn & (1 << 21)) {
8185
/* Base writeback. */
8188
tcg_gen_addi_i32(addr, addr, offset - 4);
8189
store_reg(s, rn, addr);
8191
tcg_temp_free_i32(addr);
8193
} else if ((insn & (1 << 23)) == 0) {
8194
/* Load/store exclusive word. */
8195
addr = tcg_temp_local_new_i32();
8196
load_reg_var(s, addr, rn);
8197
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8198
if (insn & (1 << 20)) {
8199
gen_load_exclusive(s, rs, 15, addr, 2);
8201
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8203
tcg_temp_free_i32(addr);
8204
} else if ((insn & (7 << 5)) == 0) {
8207
addr = tcg_temp_new_i32();
8208
tcg_gen_movi_i32(addr, s->pc);
8210
addr = load_reg(s, rn);
8212
tmp = load_reg(s, rm);
8213
tcg_gen_add_i32(addr, addr, tmp);
8214
if (insn & (1 << 4)) {
8216
tcg_gen_add_i32(addr, addr, tmp);
8217
tcg_temp_free_i32(tmp);
8218
tmp = tcg_temp_new_i32();
8219
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
8221
tcg_temp_free_i32(tmp);
8222
tmp = tcg_temp_new_i32();
8223
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
8225
tcg_temp_free_i32(addr);
8226
tcg_gen_shli_i32(tmp, tmp, 1);
8227
tcg_gen_addi_i32(tmp, tmp, s->pc);
8228
store_reg(s, 15, tmp);
8230
int op2 = (insn >> 6) & 0x3;
8231
op = (insn >> 4) & 0x3;
8236
/* Load/store exclusive byte/halfword/doubleword */
8243
/* Load-acquire/store-release */
8249
/* Load-acquire/store-release exclusive */
8253
addr = tcg_temp_local_new_i32();
8254
load_reg_var(s, addr, rn);
8256
if (insn & (1 << 20)) {
8257
tmp = tcg_temp_new_i32();
8260
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
8263
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
8266
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
8271
store_reg(s, rs, tmp);
8273
tmp = load_reg(s, rs);
8276
tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
8279
tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
8282
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
8287
tcg_temp_free_i32(tmp);
8289
} else if (insn & (1 << 20)) {
8290
gen_load_exclusive(s, rs, rd, addr, op);
8292
gen_store_exclusive(s, rm, rs, rd, addr, op);
8294
tcg_temp_free_i32(addr);
8297
/* Load/store multiple, RFE, SRS. */
8298
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8299
/* RFE, SRS: not available in user mode or on M profile */
8300
if (IS_USER(s) || IS_M(env)) {
8303
if (insn & (1 << 20)) {
8305
addr = load_reg(s, rn);
8306
if ((insn & (1 << 24)) == 0)
8307
tcg_gen_addi_i32(addr, addr, -8);
8308
/* Load PC into tmp and CPSR into tmp2. */
8309
tmp = tcg_temp_new_i32();
8310
tcg_gen_qemu_ld32u(tmp, addr, 0);
8311
tcg_gen_addi_i32(addr, addr, 4);
8312
tmp2 = tcg_temp_new_i32();
8313
tcg_gen_qemu_ld32u(tmp2, addr, 0);
8314
if (insn & (1 << 21)) {
8315
/* Base writeback. */
8316
if (insn & (1 << 24)) {
8317
tcg_gen_addi_i32(addr, addr, 4);
8319
tcg_gen_addi_i32(addr, addr, -4);
8321
store_reg(s, rn, addr);
8323
tcg_temp_free_i32(addr);
8325
gen_rfe(s, tmp, tmp2);
8328
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8332
int i, loaded_base = 0;
8333
TCGv_i32 loaded_var;
8334
/* Load/store multiple. */
8335
addr = load_reg(s, rn);
8337
for (i = 0; i < 16; i++) {
8338
if (insn & (1 << i))
8341
if (insn & (1 << 24)) {
8342
tcg_gen_addi_i32(addr, addr, -offset);
8345
TCGV_UNUSED_I32(loaded_var);
8346
for (i = 0; i < 16; i++) {
8347
if ((insn & (1 << i)) == 0)
8349
if (insn & (1 << 20)) {
8351
tmp = tcg_temp_new_i32();
8352
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
8355
} else if (i == rn) {
8359
store_reg(s, i, tmp);
8363
tmp = load_reg(s, i);
8364
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
8365
tcg_temp_free_i32(tmp);
8367
tcg_gen_addi_i32(addr, addr, 4);
8370
store_reg(s, rn, loaded_var);
8372
if (insn & (1 << 21)) {
8373
/* Base register writeback. */
8374
if (insn & (1 << 24)) {
8375
tcg_gen_addi_i32(addr, addr, -offset);
8377
/* Fault if writeback register is in register list. */
8378
if (insn & (1 << rn))
8380
store_reg(s, rn, addr);
8382
tcg_temp_free_i32(addr);
8389
op = (insn >> 21) & 0xf;
8391
/* Halfword pack. */
8392
tmp = load_reg(s, rn);
8393
tmp2 = load_reg(s, rm);
8394
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8395
if (insn & (1 << 5)) {
8399
tcg_gen_sari_i32(tmp2, tmp2, shift);
8400
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8401
tcg_gen_ext16u_i32(tmp2, tmp2);
8405
tcg_gen_shli_i32(tmp2, tmp2, shift);
8406
tcg_gen_ext16u_i32(tmp, tmp);
8407
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8409
tcg_gen_or_i32(tmp, tmp, tmp2);
8410
tcg_temp_free_i32(tmp2);
8411
store_reg(s, rd, tmp);
8413
/* Data processing register constant shift. */
8415
tmp = tcg_temp_new_i32();
8416
tcg_gen_movi_i32(tmp, 0);
8418
tmp = load_reg(s, rn);
8420
tmp2 = load_reg(s, rm);
8422
shiftop = (insn >> 4) & 3;
8423
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8424
conds = (insn & (1 << 20)) != 0;
8425
logic_cc = (conds && thumb2_logic_op(op));
8426
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8427
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8429
tcg_temp_free_i32(tmp2);
8431
store_reg(s, rd, tmp);
8433
tcg_temp_free_i32(tmp);
8437
case 13: /* Misc data processing. */
8438
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8439
if (op < 4 && (insn & 0xf000) != 0xf000)
8442
case 0: /* Register controlled shift. */
8443
tmp = load_reg(s, rn);
8444
tmp2 = load_reg(s, rm);
8445
if ((insn & 0x70) != 0)
8447
op = (insn >> 21) & 3;
8448
logic_cc = (insn & (1 << 20)) != 0;
8449
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8452
store_reg_bx(env, s, rd, tmp);
8454
case 1: /* Sign/zero extend. */
8455
tmp = load_reg(s, rm);
8456
shift = (insn >> 4) & 3;
8457
/* ??? In many cases it's not necessary to do a
8458
rotate, a shift is sufficient. */
8460
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8461
op = (insn >> 20) & 7;
8463
case 0: gen_sxth(tmp); break;
8464
case 1: gen_uxth(tmp); break;
8465
case 2: gen_sxtb16(tmp); break;
8466
case 3: gen_uxtb16(tmp); break;
8467
case 4: gen_sxtb(tmp); break;
8468
case 5: gen_uxtb(tmp); break;
8469
default: goto illegal_op;
8472
tmp2 = load_reg(s, rn);
8473
if ((op >> 1) == 1) {
8474
gen_add16(tmp, tmp2);
8476
tcg_gen_add_i32(tmp, tmp, tmp2);
8477
tcg_temp_free_i32(tmp2);
8480
store_reg(s, rd, tmp);
8482
case 2: /* SIMD add/subtract. */
8483
op = (insn >> 20) & 7;
8484
shift = (insn >> 4) & 7;
8485
if ((op & 3) == 3 || (shift & 3) == 3)
8487
tmp = load_reg(s, rn);
8488
tmp2 = load_reg(s, rm);
8489
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8490
tcg_temp_free_i32(tmp2);
8491
store_reg(s, rd, tmp);
8493
case 3: /* Other data processing. */
8494
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8496
/* Saturating add/subtract. */
8497
tmp = load_reg(s, rn);
8498
tmp2 = load_reg(s, rm);
8500
gen_helper_double_saturate(tmp, cpu_env, tmp);
8502
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8504
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8505
tcg_temp_free_i32(tmp2);
8507
tmp = load_reg(s, rn);
8509
case 0x0a: /* rbit */
8510
gen_helper_rbit(tmp, tmp);
8512
case 0x08: /* rev */
8513
tcg_gen_bswap32_i32(tmp, tmp);
8515
case 0x09: /* rev16 */
8518
case 0x0b: /* revsh */
8521
case 0x10: /* sel */
8522
tmp2 = load_reg(s, rm);
8523
tmp3 = tcg_temp_new_i32();
8524
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8525
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8526
tcg_temp_free_i32(tmp3);
8527
tcg_temp_free_i32(tmp2);
8529
case 0x18: /* clz */
8530
gen_helper_clz(tmp, tmp);
8536
store_reg(s, rd, tmp);
8538
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8539
op = (insn >> 4) & 0xf;
8540
tmp = load_reg(s, rn);
8541
tmp2 = load_reg(s, rm);
8542
switch ((insn >> 20) & 7) {
8543
case 0: /* 32 x 32 -> 32 */
8544
tcg_gen_mul_i32(tmp, tmp, tmp2);
8545
tcg_temp_free_i32(tmp2);
8547
tmp2 = load_reg(s, rs);
8549
tcg_gen_sub_i32(tmp, tmp2, tmp);
8551
tcg_gen_add_i32(tmp, tmp, tmp2);
8552
tcg_temp_free_i32(tmp2);
8555
case 1: /* 16 x 16 -> 32 */
8556
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8557
tcg_temp_free_i32(tmp2);
8559
tmp2 = load_reg(s, rs);
8560
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8561
tcg_temp_free_i32(tmp2);
8564
case 2: /* Dual multiply add. */
8565
case 4: /* Dual multiply subtract. */
8567
gen_swap_half(tmp2);
8568
gen_smul_dual(tmp, tmp2);
8569
if (insn & (1 << 22)) {
8570
/* This subtraction cannot overflow. */
8571
tcg_gen_sub_i32(tmp, tmp, tmp2);
8573
/* This addition cannot overflow 32 bits;
8574
* however it may overflow considered as a signed
8575
* operation, in which case we must set the Q flag.
8577
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8579
tcg_temp_free_i32(tmp2);
8582
tmp2 = load_reg(s, rs);
8583
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8584
tcg_temp_free_i32(tmp2);
8587
case 3: /* 32 * 16 -> 32msb */
8589
tcg_gen_sari_i32(tmp2, tmp2, 16);
8592
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8593
tcg_gen_shri_i64(tmp64, tmp64, 16);
8594
tmp = tcg_temp_new_i32();
8595
tcg_gen_trunc_i64_i32(tmp, tmp64);
8596
tcg_temp_free_i64(tmp64);
8599
tmp2 = load_reg(s, rs);
8600
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8601
tcg_temp_free_i32(tmp2);
8604
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8605
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8607
tmp = load_reg(s, rs);
8608
if (insn & (1 << 20)) {
8609
tmp64 = gen_addq_msw(tmp64, tmp);
8611
tmp64 = gen_subq_msw(tmp64, tmp);
8614
if (insn & (1 << 4)) {
8615
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8617
tcg_gen_shri_i64(tmp64, tmp64, 32);
8618
tmp = tcg_temp_new_i32();
8619
tcg_gen_trunc_i64_i32(tmp, tmp64);
8620
tcg_temp_free_i64(tmp64);
8622
case 7: /* Unsigned sum of absolute differences. */
8623
gen_helper_usad8(tmp, tmp, tmp2);
8624
tcg_temp_free_i32(tmp2);
8626
tmp2 = load_reg(s, rs);
8627
tcg_gen_add_i32(tmp, tmp, tmp2);
8628
tcg_temp_free_i32(tmp2);
8632
store_reg(s, rd, tmp);
8634
case 6: case 7: /* 64-bit multiply, Divide. */
8635
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8636
tmp = load_reg(s, rn);
8637
tmp2 = load_reg(s, rm);
8638
if ((op & 0x50) == 0x10) {
8640
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8644
gen_helper_udiv(tmp, tmp, tmp2);
8646
gen_helper_sdiv(tmp, tmp, tmp2);
8647
tcg_temp_free_i32(tmp2);
8648
store_reg(s, rd, tmp);
8649
} else if ((op & 0xe) == 0xc) {
8650
/* Dual multiply accumulate long. */
8652
gen_swap_half(tmp2);
8653
gen_smul_dual(tmp, tmp2);
8655
tcg_gen_sub_i32(tmp, tmp, tmp2);
8657
tcg_gen_add_i32(tmp, tmp, tmp2);
8659
tcg_temp_free_i32(tmp2);
8661
tmp64 = tcg_temp_new_i64();
8662
tcg_gen_ext_i32_i64(tmp64, tmp);
8663
tcg_temp_free_i32(tmp);
8664
gen_addq(s, tmp64, rs, rd);
8665
gen_storeq_reg(s, rs, rd, tmp64);
8666
tcg_temp_free_i64(tmp64);
8669
/* Unsigned 64-bit multiply */
8670
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8674
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8675
tcg_temp_free_i32(tmp2);
8676
tmp64 = tcg_temp_new_i64();
8677
tcg_gen_ext_i32_i64(tmp64, tmp);
8678
tcg_temp_free_i32(tmp);
8680
/* Signed 64-bit multiply */
8681
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8686
gen_addq_lo(s, tmp64, rs);
8687
gen_addq_lo(s, tmp64, rd);
8688
} else if (op & 0x40) {
8689
/* 64-bit accumulate. */
8690
gen_addq(s, tmp64, rs, rd);
8692
gen_storeq_reg(s, rs, rd, tmp64);
8693
tcg_temp_free_i64(tmp64);
8698
case 6: case 7: case 14: case 15:
8700
if (((insn >> 24) & 3) == 3) {
8701
/* Translate into the equivalent ARM encoding. */
8702
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8703
if (disas_neon_data_insn(env, s, insn))
8706
if (insn & (1 << 28))
8708
if (disas_coproc_insn (env, s, insn))
8712
case 8: case 9: case 10: case 11:
8713
if (insn & (1 << 15)) {
8714
/* Branches, misc control. */
8715
if (insn & 0x5000) {
8716
/* Unconditional branch. */
8717
/* signextend(hw1[10:0]) -> offset[:12]. */
8718
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8719
/* hw1[10:0] -> offset[11:1]. */
8720
offset |= (insn & 0x7ff) << 1;
8721
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8722
offset[24:22] already have the same value because of the
8723
sign extension above. */
8724
offset ^= ((~insn) & (1 << 13)) << 10;
8725
offset ^= ((~insn) & (1 << 11)) << 11;
8727
if (insn & (1 << 14)) {
8728
/* Branch and link. */
8729
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8733
if (insn & (1 << 12)) {
8738
offset &= ~(uint32_t)2;
8739
/* thumb2 bx, no need to check */
8740
gen_bx_im(s, offset);
8742
} else if (((insn >> 23) & 7) == 7) {
8744
if (insn & (1 << 13))
8747
if (insn & (1 << 26)) {
8748
/* Secure monitor call / smc (v6Z) */
8749
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
8755
op = (insn >> 20) & 7;
8757
case 0: /* msr cpsr. */
8759
tmp = load_reg(s, rn);
8760
addr = tcg_const_i32(insn & 0xff);
8761
gen_helper_v7m_msr(cpu_env, addr, tmp);
8762
tcg_temp_free_i32(addr);
8763
tcg_temp_free_i32(tmp);
8768
case 1: /* msr spsr. */
8771
tmp = load_reg(s, rn);
8773
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8777
case 2: /* cps, nop-hint. */
8778
if (((insn >> 8) & 7) == 0) {
8779
gen_nop_hint(s, insn & 0xff);
8781
/* Implemented as NOP in user mode. */
8786
if (insn & (1 << 10)) {
8787
if (insn & (1 << 7))
8789
if (insn & (1 << 6))
8791
if (insn & (1 << 5))
8793
if (insn & (1 << 9))
8794
imm = CPSR_A | CPSR_I | CPSR_F;
8796
if (insn & (1 << 8)) {
8798
imm |= (insn & 0x1f);
8801
gen_set_psr_im(s, offset, 0, imm);
8804
case 3: /* Special control operations. */
8806
op = (insn >> 4) & 0xf;
8814
/* These execute as NOPs. */
8821
/* Trivial implementation equivalent to bx. */
8822
tmp = load_reg(s, rn);
8825
case 5: /* Exception return. */
8829
if (rn != 14 || rd != 15) {
8832
tmp = load_reg(s, rn);
8833
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8834
gen_exception_return(s, tmp);
8836
case 6: /* mrs cpsr. */
8837
tmp = tcg_temp_new_i32();
8839
addr = tcg_const_i32(insn & 0xff);
8840
gen_helper_v7m_mrs(tmp, cpu_env, addr);
8841
tcg_temp_free_i32(addr);
8843
gen_helper_cpsr_read(tmp, cpu_env);
8845
store_reg(s, rd, tmp);
8847
case 7: /* mrs spsr. */
8848
/* Not accessible in user mode. */
8849
if (IS_USER(s) || IS_M(env))
8851
tmp = load_cpu_field(spsr);
8852
store_reg(s, rd, tmp);
8857
/* Conditional branch. */
8858
op = (insn >> 22) & 0xf;
8859
/* Generate a conditional jump to next instruction. */
8860
s->condlabel = gen_new_label();
8861
gen_test_cc(op ^ 1, s->condlabel);
8864
/* offset[11:1] = insn[10:0] */
8865
offset = (insn & 0x7ff) << 1;
8866
/* offset[17:12] = insn[21:16]. */
8867
offset |= (insn & 0x003f0000) >> 4;
8868
/* offset[31:20] = insn[26]. */
8869
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8870
/* offset[18] = insn[13]. */
8871
offset |= (insn & (1 << 13)) << 5;
8872
/* offset[19] = insn[11]. */
8873
offset |= (insn & (1 << 11)) << 8;
8875
/* jump to the offset */
8876
gen_jmp(s, s->pc + offset);
8879
/* Data processing immediate. */
8880
if (insn & (1 << 25)) {
8881
if (insn & (1 << 24)) {
8882
if (insn & (1 << 20))
8884
/* Bitfield/Saturate. */
8885
op = (insn >> 21) & 7;
8887
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8889
tmp = tcg_temp_new_i32();
8890
tcg_gen_movi_i32(tmp, 0);
8892
tmp = load_reg(s, rn);
8895
case 2: /* Signed bitfield extract. */
8897
if (shift + imm > 32)
8900
gen_sbfx(tmp, shift, imm);
8902
case 6: /* Unsigned bitfield extract. */
8904
if (shift + imm > 32)
8907
gen_ubfx(tmp, shift, (1u << imm) - 1);
8909
case 3: /* Bitfield insert/clear. */
8912
imm = imm + 1 - shift;
8914
tmp2 = load_reg(s, rd);
8915
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
8916
tcg_temp_free_i32(tmp2);
8921
default: /* Saturate. */
8924
tcg_gen_sari_i32(tmp, tmp, shift);
8926
tcg_gen_shli_i32(tmp, tmp, shift);
8928
tmp2 = tcg_const_i32(imm);
8931
if ((op & 1) && shift == 0)
8932
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8934
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8937
if ((op & 1) && shift == 0)
8938
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8940
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8942
tcg_temp_free_i32(tmp2);
8945
store_reg(s, rd, tmp);
8947
imm = ((insn & 0x04000000) >> 15)
8948
| ((insn & 0x7000) >> 4) | (insn & 0xff);
8949
if (insn & (1 << 22)) {
8950
/* 16-bit immediate. */
8951
imm |= (insn >> 4) & 0xf000;
8952
if (insn & (1 << 23)) {
8954
tmp = load_reg(s, rd);
8955
tcg_gen_ext16u_i32(tmp, tmp);
8956
tcg_gen_ori_i32(tmp, tmp, imm << 16);
8959
tmp = tcg_temp_new_i32();
8960
tcg_gen_movi_i32(tmp, imm);
8963
/* Add/sub 12-bit immediate. */
8965
offset = s->pc & ~(uint32_t)3;
8966
if (insn & (1 << 23))
8970
tmp = tcg_temp_new_i32();
8971
tcg_gen_movi_i32(tmp, offset);
8973
tmp = load_reg(s, rn);
8974
if (insn & (1 << 23))
8975
tcg_gen_subi_i32(tmp, tmp, imm);
8977
tcg_gen_addi_i32(tmp, tmp, imm);
8980
store_reg(s, rd, tmp);
8983
int shifter_out = 0;
8984
/* modified 12-bit immediate. */
8985
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8986
imm = (insn & 0xff);
8989
/* Nothing to do. */
8991
case 1: /* 00XY00XY */
8994
case 2: /* XY00XY00 */
8998
case 3: /* XYXYXYXY */
9002
default: /* Rotated constant. */
9003
shift = (shift << 1) | (imm >> 7);
9005
imm = imm << (32 - shift);
9009
tmp2 = tcg_temp_new_i32();
9010
tcg_gen_movi_i32(tmp2, imm);
9011
rn = (insn >> 16) & 0xf;
9013
tmp = tcg_temp_new_i32();
9014
tcg_gen_movi_i32(tmp, 0);
9016
tmp = load_reg(s, rn);
9018
op = (insn >> 21) & 0xf;
9019
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9020
shifter_out, tmp, tmp2))
9022
tcg_temp_free_i32(tmp2);
9023
rd = (insn >> 8) & 0xf;
9025
store_reg(s, rd, tmp);
9027
tcg_temp_free_i32(tmp);
9032
case 12: /* Load/store single data item. */
9037
if ((insn & 0x01100000) == 0x01000000) {
9038
if (disas_neon_ls_insn(env, s, insn))
9042
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9044
if (!(insn & (1 << 20))) {
9048
/* Byte or halfword load space with dest == r15 : memory hints.
9049
* Catch them early so we don't emit pointless addressing code.
9050
* This space is a mix of:
9051
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9052
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9054
* unallocated hints, which must be treated as NOPs
9055
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9056
* which is easiest for the decoding logic
9057
* Some space which must UNDEF
9059
int op1 = (insn >> 23) & 3;
9060
int op2 = (insn >> 6) & 0x3f;
9065
/* UNPREDICTABLE, unallocated hint or
9066
* PLD/PLDW/PLI (literal)
9071
return 0; /* PLD/PLDW/PLI or unallocated hint */
9073
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9074
return 0; /* PLD/PLDW/PLI or unallocated hint */
9076
/* UNDEF space, or an UNPREDICTABLE */
9082
addr = tcg_temp_new_i32();
9084
/* s->pc has already been incremented by 4. */
9085
imm = s->pc & 0xfffffffc;
9086
if (insn & (1 << 23))
9087
imm += insn & 0xfff;
9089
imm -= insn & 0xfff;
9090
tcg_gen_movi_i32(addr, imm);
9092
addr = load_reg(s, rn);
9093
if (insn & (1 << 23)) {
9094
/* Positive offset. */
9096
tcg_gen_addi_i32(addr, addr, imm);
9099
switch ((insn >> 8) & 0xf) {
9100
case 0x0: /* Shifted Register. */
9101
shift = (insn >> 4) & 0xf;
9103
tcg_temp_free_i32(addr);
9106
tmp = load_reg(s, rm);
9108
tcg_gen_shli_i32(tmp, tmp, shift);
9109
tcg_gen_add_i32(addr, addr, tmp);
9110
tcg_temp_free_i32(tmp);
9112
case 0xc: /* Negative offset. */
9113
tcg_gen_addi_i32(addr, addr, -imm);
9115
case 0xe: /* User privilege. */
9116
tcg_gen_addi_i32(addr, addr, imm);
9119
case 0x9: /* Post-decrement. */
9122
case 0xb: /* Post-increment. */
9126
case 0xd: /* Pre-decrement. */
9129
case 0xf: /* Pre-increment. */
9130
tcg_gen_addi_i32(addr, addr, imm);
9134
tcg_temp_free_i32(addr);
9139
if (insn & (1 << 20)) {
9141
tmp = tcg_temp_new_i32();
9144
tcg_gen_qemu_ld8u(tmp, addr, user);
9147
tcg_gen_qemu_ld8s(tmp, addr, user);
9150
tcg_gen_qemu_ld16u(tmp, addr, user);
9153
tcg_gen_qemu_ld16s(tmp, addr, user);
9156
tcg_gen_qemu_ld32u(tmp, addr, user);
9159
tcg_temp_free_i32(tmp);
9160
tcg_temp_free_i32(addr);
9166
store_reg(s, rs, tmp);
9170
tmp = load_reg(s, rs);
9173
tcg_gen_qemu_st8(tmp, addr, user);
9176
tcg_gen_qemu_st16(tmp, addr, user);
9179
tcg_gen_qemu_st32(tmp, addr, user);
9182
tcg_temp_free_i32(tmp);
9183
tcg_temp_free_i32(addr);
9186
tcg_temp_free_i32(tmp);
9189
tcg_gen_addi_i32(addr, addr, imm);
9191
store_reg(s, rn, addr);
9193
tcg_temp_free_i32(addr);
9205
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9207
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9214
if (s->condexec_mask) {
9215
cond = s->condexec_cond;
9216
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9217
s->condlabel = gen_new_label();
9218
gen_test_cc(cond ^ 1, s->condlabel);
9223
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9226
switch (insn >> 12) {
9230
op = (insn >> 11) & 3;
9233
rn = (insn >> 3) & 7;
9234
tmp = load_reg(s, rn);
9235
if (insn & (1 << 10)) {
9237
tmp2 = tcg_temp_new_i32();
9238
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9241
rm = (insn >> 6) & 7;
9242
tmp2 = load_reg(s, rm);
9244
if (insn & (1 << 9)) {
9245
if (s->condexec_mask)
9246
tcg_gen_sub_i32(tmp, tmp, tmp2);
9248
gen_sub_CC(tmp, tmp, tmp2);
9250
if (s->condexec_mask)
9251
tcg_gen_add_i32(tmp, tmp, tmp2);
9253
gen_add_CC(tmp, tmp, tmp2);
9255
tcg_temp_free_i32(tmp2);
9256
store_reg(s, rd, tmp);
9258
/* shift immediate */
9259
rm = (insn >> 3) & 7;
9260
shift = (insn >> 6) & 0x1f;
9261
tmp = load_reg(s, rm);
9262
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9263
if (!s->condexec_mask)
9265
store_reg(s, rd, tmp);
9269
/* arithmetic large immediate */
9270
op = (insn >> 11) & 3;
9271
rd = (insn >> 8) & 0x7;
9272
if (op == 0) { /* mov */
9273
tmp = tcg_temp_new_i32();
9274
tcg_gen_movi_i32(tmp, insn & 0xff);
9275
if (!s->condexec_mask)
9277
store_reg(s, rd, tmp);
9279
tmp = load_reg(s, rd);
9280
tmp2 = tcg_temp_new_i32();
9281
tcg_gen_movi_i32(tmp2, insn & 0xff);
9284
gen_sub_CC(tmp, tmp, tmp2);
9285
tcg_temp_free_i32(tmp);
9286
tcg_temp_free_i32(tmp2);
9289
if (s->condexec_mask)
9290
tcg_gen_add_i32(tmp, tmp, tmp2);
9292
gen_add_CC(tmp, tmp, tmp2);
9293
tcg_temp_free_i32(tmp2);
9294
store_reg(s, rd, tmp);
9297
if (s->condexec_mask)
9298
tcg_gen_sub_i32(tmp, tmp, tmp2);
9300
gen_sub_CC(tmp, tmp, tmp2);
9301
tcg_temp_free_i32(tmp2);
9302
store_reg(s, rd, tmp);
9308
if (insn & (1 << 11)) {
9309
rd = (insn >> 8) & 7;
9310
/* load pc-relative. Bit 1 of PC is ignored. */
9311
val = s->pc + 2 + ((insn & 0xff) * 4);
9312
val &= ~(uint32_t)2;
9313
addr = tcg_temp_new_i32();
9314
tcg_gen_movi_i32(addr, val);
9315
tmp = tcg_temp_new_i32();
9316
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
9317
tcg_temp_free_i32(addr);
9318
store_reg(s, rd, tmp);
9321
if (insn & (1 << 10)) {
9322
/* data processing extended or blx */
9323
rd = (insn & 7) | ((insn >> 4) & 8);
9324
rm = (insn >> 3) & 0xf;
9325
op = (insn >> 8) & 3;
9328
tmp = load_reg(s, rd);
9329
tmp2 = load_reg(s, rm);
9330
tcg_gen_add_i32(tmp, tmp, tmp2);
9331
tcg_temp_free_i32(tmp2);
9332
store_reg(s, rd, tmp);
9335
tmp = load_reg(s, rd);
9336
tmp2 = load_reg(s, rm);
9337
gen_sub_CC(tmp, tmp, tmp2);
9338
tcg_temp_free_i32(tmp2);
9339
tcg_temp_free_i32(tmp);
9341
case 2: /* mov/cpy */
9342
tmp = load_reg(s, rm);
9343
store_reg(s, rd, tmp);
9345
case 3:/* branch [and link] exchange thumb register */
9346
tmp = load_reg(s, rm);
9347
if (insn & (1 << 7)) {
9349
val = (uint32_t)s->pc | 1;
9350
tmp2 = tcg_temp_new_i32();
9351
tcg_gen_movi_i32(tmp2, val);
9352
store_reg(s, 14, tmp2);
9354
/* already thumb, no need to check */
9361
/* data processing register */
9363
rm = (insn >> 3) & 7;
9364
op = (insn >> 6) & 0xf;
9365
if (op == 2 || op == 3 || op == 4 || op == 7) {
9366
/* the shift/rotate ops want the operands backwards */
9375
if (op == 9) { /* neg */
9376
tmp = tcg_temp_new_i32();
9377
tcg_gen_movi_i32(tmp, 0);
9378
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9379
tmp = load_reg(s, rd);
9381
TCGV_UNUSED_I32(tmp);
9384
tmp2 = load_reg(s, rm);
9387
tcg_gen_and_i32(tmp, tmp, tmp2);
9388
if (!s->condexec_mask)
9392
tcg_gen_xor_i32(tmp, tmp, tmp2);
9393
if (!s->condexec_mask)
9397
if (s->condexec_mask) {
9398
gen_shl(tmp2, tmp2, tmp);
9400
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9405
if (s->condexec_mask) {
9406
gen_shr(tmp2, tmp2, tmp);
9408
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9413
if (s->condexec_mask) {
9414
gen_sar(tmp2, tmp2, tmp);
9416
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9421
if (s->condexec_mask) {
9424
gen_adc_CC(tmp, tmp, tmp2);
9428
if (s->condexec_mask) {
9429
gen_sub_carry(tmp, tmp, tmp2);
9431
gen_sbc_CC(tmp, tmp, tmp2);
9435
if (s->condexec_mask) {
9436
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9437
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9439
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9444
tcg_gen_and_i32(tmp, tmp, tmp2);
9449
if (s->condexec_mask)
9450
tcg_gen_neg_i32(tmp, tmp2);
9452
gen_sub_CC(tmp, tmp, tmp2);
9455
gen_sub_CC(tmp, tmp, tmp2);
9459
gen_add_CC(tmp, tmp, tmp2);
9463
tcg_gen_or_i32(tmp, tmp, tmp2);
9464
if (!s->condexec_mask)
9468
tcg_gen_mul_i32(tmp, tmp, tmp2);
9469
if (!s->condexec_mask)
9473
tcg_gen_andc_i32(tmp, tmp, tmp2);
9474
if (!s->condexec_mask)
9478
tcg_gen_not_i32(tmp2, tmp2);
9479
if (!s->condexec_mask)
9487
store_reg(s, rm, tmp2);
9489
tcg_temp_free_i32(tmp);
9491
store_reg(s, rd, tmp);
9492
tcg_temp_free_i32(tmp2);
9495
tcg_temp_free_i32(tmp);
9496
tcg_temp_free_i32(tmp2);
9501
/* load/store register offset. */
9503
rn = (insn >> 3) & 7;
9504
rm = (insn >> 6) & 7;
9505
op = (insn >> 9) & 7;
9506
addr = load_reg(s, rn);
9507
tmp = load_reg(s, rm);
9508
tcg_gen_add_i32(addr, addr, tmp);
9509
tcg_temp_free_i32(tmp);
9511
if (op < 3) { /* store */
9512
tmp = load_reg(s, rd);
9514
tmp = tcg_temp_new_i32();
9519
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
9522
tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
9525
tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
9528
tcg_gen_qemu_ld8s(tmp, addr, IS_USER(s));
9531
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
9534
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
9537
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
9540
tcg_gen_qemu_ld16s(tmp, addr, IS_USER(s));
9543
if (op >= 3) { /* load */
9544
store_reg(s, rd, tmp);
9546
tcg_temp_free_i32(tmp);
9548
tcg_temp_free_i32(addr);
9552
/* load/store word immediate offset */
9554
rn = (insn >> 3) & 7;
9555
addr = load_reg(s, rn);
9556
val = (insn >> 4) & 0x7c;
9557
tcg_gen_addi_i32(addr, addr, val);
9559
if (insn & (1 << 11)) {
9561
tmp = tcg_temp_new_i32();
9562
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
9563
store_reg(s, rd, tmp);
9566
tmp = load_reg(s, rd);
9567
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
9568
tcg_temp_free_i32(tmp);
9570
tcg_temp_free_i32(addr);
9574
/* load/store byte immediate offset */
9576
rn = (insn >> 3) & 7;
9577
addr = load_reg(s, rn);
9578
val = (insn >> 6) & 0x1f;
9579
tcg_gen_addi_i32(addr, addr, val);
9581
if (insn & (1 << 11)) {
9583
tmp = tcg_temp_new_i32();
9584
tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s));
9585
store_reg(s, rd, tmp);
9588
tmp = load_reg(s, rd);
9589
tcg_gen_qemu_st8(tmp, addr, IS_USER(s));
9590
tcg_temp_free_i32(tmp);
9592
tcg_temp_free_i32(addr);
9596
/* load/store halfword immediate offset */
9598
rn = (insn >> 3) & 7;
9599
addr = load_reg(s, rn);
9600
val = (insn >> 5) & 0x3e;
9601
tcg_gen_addi_i32(addr, addr, val);
9603
if (insn & (1 << 11)) {
9605
tmp = tcg_temp_new_i32();
9606
tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s));
9607
store_reg(s, rd, tmp);
9610
tmp = load_reg(s, rd);
9611
tcg_gen_qemu_st16(tmp, addr, IS_USER(s));
9612
tcg_temp_free_i32(tmp);
9614
tcg_temp_free_i32(addr);
9618
/* load/store from stack */
9619
rd = (insn >> 8) & 7;
9620
addr = load_reg(s, 13);
9621
val = (insn & 0xff) * 4;
9622
tcg_gen_addi_i32(addr, addr, val);
9624
if (insn & (1 << 11)) {
9626
tmp = tcg_temp_new_i32();
9627
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
9628
store_reg(s, rd, tmp);
9631
tmp = load_reg(s, rd);
9632
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
9633
tcg_temp_free_i32(tmp);
9635
tcg_temp_free_i32(addr);
9639
/* add to high reg */
9640
rd = (insn >> 8) & 7;
9641
if (insn & (1 << 11)) {
9643
tmp = load_reg(s, 13);
9645
/* PC. bit 1 is ignored. */
9646
tmp = tcg_temp_new_i32();
9647
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9649
val = (insn & 0xff) * 4;
9650
tcg_gen_addi_i32(tmp, tmp, val);
9651
store_reg(s, rd, tmp);
9656
op = (insn >> 8) & 0xf;
9659
/* adjust stack pointer */
9660
tmp = load_reg(s, 13);
9661
val = (insn & 0x7f) * 4;
9662
if (insn & (1 << 7))
9663
val = -(int32_t)val;
9664
tcg_gen_addi_i32(tmp, tmp, val);
9665
store_reg(s, 13, tmp);
9668
case 2: /* sign/zero extend. */
9671
rm = (insn >> 3) & 7;
9672
tmp = load_reg(s, rm);
9673
switch ((insn >> 6) & 3) {
9674
case 0: gen_sxth(tmp); break;
9675
case 1: gen_sxtb(tmp); break;
9676
case 2: gen_uxth(tmp); break;
9677
case 3: gen_uxtb(tmp); break;
9679
store_reg(s, rd, tmp);
9681
case 4: case 5: case 0xc: case 0xd:
9683
addr = load_reg(s, 13);
9684
if (insn & (1 << 8))
9688
for (i = 0; i < 8; i++) {
9689
if (insn & (1 << i))
9692
if ((insn & (1 << 11)) == 0) {
9693
tcg_gen_addi_i32(addr, addr, -offset);
9695
for (i = 0; i < 8; i++) {
9696
if (insn & (1 << i)) {
9697
if (insn & (1 << 11)) {
9699
tmp = tcg_temp_new_i32();
9700
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
9701
store_reg(s, i, tmp);
9704
tmp = load_reg(s, i);
9705
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
9706
tcg_temp_free_i32(tmp);
9708
/* advance to the next address. */
9709
tcg_gen_addi_i32(addr, addr, 4);
9712
TCGV_UNUSED_I32(tmp);
9713
if (insn & (1 << 8)) {
9714
if (insn & (1 << 11)) {
9716
tmp = tcg_temp_new_i32();
9717
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
9718
/* don't set the pc until the rest of the instruction
9722
tmp = load_reg(s, 14);
9723
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
9724
tcg_temp_free_i32(tmp);
9726
tcg_gen_addi_i32(addr, addr, 4);
9728
if ((insn & (1 << 11)) == 0) {
9729
tcg_gen_addi_i32(addr, addr, -offset);
9731
/* write back the new stack pointer */
9732
store_reg(s, 13, addr);
9733
/* set the new PC value */
9734
if ((insn & 0x0900) == 0x0900) {
9735
store_reg_from_load(env, s, 15, tmp);
9739
case 1: case 3: case 9: case 11: /* czb */
9741
tmp = load_reg(s, rm);
9742
s->condlabel = gen_new_label();
9744
if (insn & (1 << 11))
9745
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9747
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9748
tcg_temp_free_i32(tmp);
9749
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9750
val = (uint32_t)s->pc + 2;
9755
case 15: /* IT, nop-hint. */
9756
if ((insn & 0xf) == 0) {
9757
gen_nop_hint(s, (insn >> 4) & 0xf);
9761
s->condexec_cond = (insn >> 4) & 0xe;
9762
s->condexec_mask = insn & 0x1f;
9763
/* No actual code generated for this insn, just setup state. */
9766
case 0xe: /* bkpt */
9768
gen_exception_insn(s, 2, EXCP_BKPT);
9773
rn = (insn >> 3) & 0x7;
9775
tmp = load_reg(s, rn);
9776
switch ((insn >> 6) & 3) {
9777
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9778
case 1: gen_rev16(tmp); break;
9779
case 3: gen_revsh(tmp); break;
9780
default: goto illegal_op;
9782
store_reg(s, rd, tmp);
9786
switch ((insn >> 5) & 7) {
9790
if (((insn >> 3) & 1) != s->bswap_code) {
9791
/* Dynamic endianness switching not implemented. */
9802
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9805
addr = tcg_const_i32(19);
9806
gen_helper_v7m_msr(cpu_env, addr, tmp);
9807
tcg_temp_free_i32(addr);
9811
addr = tcg_const_i32(16);
9812
gen_helper_v7m_msr(cpu_env, addr, tmp);
9813
tcg_temp_free_i32(addr);
9815
tcg_temp_free_i32(tmp);
9818
if (insn & (1 << 4)) {
9819
shift = CPSR_A | CPSR_I | CPSR_F;
9823
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9838
/* load/store multiple */
9839
TCGv_i32 loaded_var;
9840
TCGV_UNUSED_I32(loaded_var);
9841
rn = (insn >> 8) & 0x7;
9842
addr = load_reg(s, rn);
9843
for (i = 0; i < 8; i++) {
9844
if (insn & (1 << i)) {
9845
if (insn & (1 << 11)) {
9847
tmp = tcg_temp_new_i32();
9848
tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
9852
store_reg(s, i, tmp);
9856
tmp = load_reg(s, i);
9857
tcg_gen_qemu_st32(tmp, addr, IS_USER(s));
9858
tcg_temp_free_i32(tmp);
9860
/* advance to the next address */
9861
tcg_gen_addi_i32(addr, addr, 4);
9864
if ((insn & (1 << rn)) == 0) {
9865
/* base reg not in list: base register writeback */
9866
store_reg(s, rn, addr);
9868
/* base reg in list: if load, complete it now */
9869
if (insn & (1 << 11)) {
9870
store_reg(s, rn, loaded_var);
9872
tcg_temp_free_i32(addr);
9877
/* conditional branch or swi */
9878
cond = (insn >> 8) & 0xf;
9884
gen_set_pc_im(s->pc);
9885
s->is_jmp = DISAS_SWI;
9888
/* generate a conditional jump to next instruction */
9889
s->condlabel = gen_new_label();
9890
gen_test_cc(cond ^ 1, s->condlabel);
9893
/* jump to the offset */
9894
val = (uint32_t)s->pc + 2;
9895
offset = ((int32_t)insn << 24) >> 24;
9901
if (insn & (1 << 11)) {
9902
if (disas_thumb2_insn(env, s, insn))
9906
/* unconditional branch */
9907
val = (uint32_t)s->pc;
9908
offset = ((int32_t)insn << 21) >> 21;
9909
val += (offset << 1) + 2;
9914
if (disas_thumb2_insn(env, s, insn))
9920
gen_exception_insn(s, 4, EXCP_UDEF);
9924
gen_exception_insn(s, 2, EXCP_UDEF);
9927
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9928
basic block 'tb'. If search_pc is TRUE, also generate PC
9929
information for each intermediate instruction. */
9930
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
9931
TranslationBlock *tb,
9934
CPUState *cs = CPU(cpu);
9935
CPUARMState *env = &cpu->env;
9936
DisasContext dc1, *dc = &dc1;
9938
uint16_t *gen_opc_end;
9940
target_ulong pc_start;
9941
uint32_t next_page_start;
9945
/* generate intermediate code */
9950
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
9952
dc->is_jmp = DISAS_NEXT;
9954
dc->singlestep_enabled = cs->singlestep_enabled;
9956
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9957
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
9958
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9959
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9960
#if !defined(CONFIG_USER_ONLY)
9961
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9963
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9964
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9965
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9966
cpu_F0s = tcg_temp_new_i32();
9967
cpu_F1s = tcg_temp_new_i32();
9968
cpu_F0d = tcg_temp_new_i64();
9969
cpu_F1d = tcg_temp_new_i64();
9972
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9973
cpu_M0 = tcg_temp_new_i64();
9974
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9977
max_insns = tb->cflags & CF_COUNT_MASK;
9979
max_insns = CF_COUNT_MASK;
9983
tcg_clear_temp_count();
9985
/* A note on handling of the condexec (IT) bits:
9987
* We want to avoid the overhead of having to write the updated condexec
9988
* bits back to the CPUARMState for every instruction in an IT block. So:
9989
* (1) if the condexec bits are not already zero then we write
9990
* zero back into the CPUARMState now. This avoids complications trying
9991
* to do it at the end of the block. (For example if we don't do this
9992
* it's hard to identify whether we can safely skip writing condexec
9993
* at the end of the TB, which we definitely want to do for the case
9994
* where a TB doesn't do anything with the IT state at all.)
9995
* (2) if we are going to leave the TB then we call gen_set_condexec()
9996
* which will write the correct value into CPUARMState if zero is wrong.
9997
* This is done both for leaving the TB at the end, and for leaving
9998
* it because of an exception we know will happen, which is done in
9999
* gen_exception_insn(). The latter is necessary because we need to
10000
* leave the TB with the PC/IT state just prior to execution of the
10001
* instruction which caused the exception.
10002
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10003
* then the CPUARMState will be wrong and we need to reset it.
10004
* This is handled in the same way as restoration of the
10005
* PC in these situations: we will be called again with search_pc=1
10006
* and generate a mapping of the condexec bits for each PC in
10007
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10008
* this to restore the condexec bits.
10010
* Note that there are no instructions which can read the condexec
10011
* bits, and none which can write non-static values to them, so
10012
* we don't need to care about whether CPUARMState is correct in the
10016
/* Reset the conditional execution bits immediately. This avoids
10017
complications trying to do it at the end of the block. */
10018
if (dc->condexec_mask || dc->condexec_cond)
10020
TCGv_i32 tmp = tcg_temp_new_i32();
10021
tcg_gen_movi_i32(tmp, 0);
10022
store_cpu_field(tmp, condexec_bits);
10025
#ifdef CONFIG_USER_ONLY
10026
/* Intercept jump to the magic kernel page. */
10027
if (dc->pc >= 0xffff0000) {
10028
/* We always get here via a jump, so know we are not in a
10029
conditional execution block. */
10030
gen_exception(EXCP_KERNEL_TRAP);
10031
dc->is_jmp = DISAS_UPDATE;
10035
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10036
/* We always get here via a jump, so know we are not in a
10037
conditional execution block. */
10038
gen_exception(EXCP_EXCEPTION_EXIT);
10039
dc->is_jmp = DISAS_UPDATE;
10044
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10045
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10046
if (bp->pc == dc->pc) {
10047
gen_exception_insn(dc, 0, EXCP_DEBUG);
10048
/* Advance PC so that clearing the breakpoint will
10049
invalidate this TB. */
10051
goto done_generating;
10056
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10060
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10062
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10063
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10064
tcg_ctx.gen_opc_instr_start[lj] = 1;
10065
tcg_ctx.gen_opc_icount[lj] = num_insns;
10068
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10071
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10072
tcg_gen_debug_insn_start(dc->pc);
10076
disas_thumb_insn(env, dc);
10077
if (dc->condexec_mask) {
10078
dc->condexec_cond = (dc->condexec_cond & 0xe)
10079
| ((dc->condexec_mask >> 4) & 1);
10080
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10081
if (dc->condexec_mask == 0) {
10082
dc->condexec_cond = 0;
10086
disas_arm_insn(env, dc);
10089
if (dc->condjmp && !dc->is_jmp) {
10090
gen_set_label(dc->condlabel);
10094
if (tcg_check_temp_count()) {
10095
fprintf(stderr, "TCG temporary leak before %08x\n", dc->pc);
10098
/* Translation stops when a conditional branch is encountered.
10099
* Otherwise the subsequent code could get translated several times.
10100
* Also stop translation when a page boundary is reached. This
10101
* ensures prefetch aborts occur at the right place. */
10103
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10104
!cs->singlestep_enabled &&
10106
dc->pc < next_page_start &&
10107
num_insns < max_insns);
10109
if (tb->cflags & CF_LAST_IO) {
10111
/* FIXME: This can theoretically happen with self-modifying
10113
cpu_abort(env, "IO on conditional branch instruction");
10118
/* At this stage dc->condjmp will only be set when the skipped
10119
instruction was a conditional branch or trap, and the PC has
10120
already been written. */
10121
if (unlikely(cs->singlestep_enabled)) {
10122
/* Make sure the pc is updated, and raise a debug exception. */
10124
gen_set_condexec(dc);
10125
if (dc->is_jmp == DISAS_SWI) {
10126
gen_exception(EXCP_SWI);
10127
} else if (dc->is_jmp == DISAS_SMC) {
10128
gen_exception(EXCP_SMC);
10130
gen_exception(EXCP_DEBUG);
10132
gen_set_label(dc->condlabel);
10134
if (dc->condjmp || !dc->is_jmp) {
10135
gen_set_pc_im(dc->pc);
10138
gen_set_condexec(dc);
10139
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10140
gen_exception(EXCP_SWI);
10141
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10142
gen_exception(EXCP_SMC);
10144
/* FIXME: Single stepping a WFI insn will not halt
10146
gen_exception(EXCP_DEBUG);
10149
/* While branches must always occur at the end of an IT block,
10150
there are a few other things that can cause us to terminate
10151
the TB in the middle of an IT block:
10152
- Exception generating instructions (bkpt, swi, undefined).
10154
- Hardware watchpoints.
10155
Hardware breakpoints have already been handled and skip this code.
10157
gen_set_condexec(dc);
10158
switch(dc->is_jmp) {
10160
gen_goto_tb(dc, 1, dc->pc);
10165
/* indicate that the hash table must be used to find the next TB */
10166
tcg_gen_exit_tb(0);
10168
case DISAS_TB_JUMP:
10169
/* nothing more to generate */
10172
gen_helper_wfi(cpu_env);
10175
gen_exception(EXCP_SWI);
10178
gen_exception(EXCP_SMC);
10182
gen_set_label(dc->condlabel);
10183
gen_set_condexec(dc);
10184
gen_goto_tb(dc, 1, dc->pc);
10190
gen_tb_end(tb, num_insns);
10191
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10194
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10195
qemu_log("----------------\n");
10196
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10197
log_target_disas(env, pc_start, dc->pc - pc_start,
10198
dc->thumb | (dc->bswap_code << 1));
10203
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10206
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10208
tb->size = dc->pc - pc_start;
10209
tb->icount = num_insns;
10213
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10215
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10218
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10220
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10223
static const char *cpu_mode_names[16] = {
10224
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10225
"???", "???", "???", "und", "???", "???", "???", "sys"
10228
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10231
ARMCPU *cpu = ARM_CPU(cs);
10232
CPUARMState *env = &cpu->env;
10236
for(i=0;i<16;i++) {
10237
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10239
cpu_fprintf(f, "\n");
10241
cpu_fprintf(f, " ");
10243
psr = cpsr_read(env);
10244
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10246
psr & (1 << 31) ? 'N' : '-',
10247
psr & (1 << 30) ? 'Z' : '-',
10248
psr & (1 << 29) ? 'C' : '-',
10249
psr & (1 << 28) ? 'V' : '-',
10250
psr & CPSR_T ? 'T' : 'A',
10251
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10253
if (flags & CPU_DUMP_FPU) {
10254
int numvfpregs = 0;
10255
if (arm_feature(env, ARM_FEATURE_VFP)) {
10258
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10261
for (i = 0; i < numvfpregs; i++) {
10262
uint64_t v = float64_val(env->vfp.regs[i]);
10263
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10264
i * 2, (uint32_t)v,
10265
i * 2 + 1, (uint32_t)(v >> 32),
10268
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10272
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10274
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10275
env->condexec_bits = gen_opc_condexec_bits[pc_pos];