4
* Copyright (c) 2003 Fabrice Bellard
5
* Copyright (c) 2005-2007 CodeSourcery
6
* Copyright (c) 2007 OpenedHand, Ltd.
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
28
#include "disas/disas.h"
31
#include "qemu/bitops.h"
37
#define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38
#define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39
/* currently all emulated v5 cores are also v5TE, so don't bother */
40
#define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41
#define ENABLE_ARCH_5J 0
42
#define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43
#define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44
#define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45
#define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46
#define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48
#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50
#include "translate.h"
51
static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
53
#if defined(CONFIG_USER_ONLY)
56
#define IS_USER(s) (s->user)
59
/* These instructions trap after executing, so defer them until after the
60
conditional execution state has been updated. */
66
/* We reuse the same 64-bit temporaries for efficiency. */
67
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
68
static TCGv_i32 cpu_R[16];
69
static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
70
static TCGv_i32 cpu_exclusive_addr;
71
static TCGv_i32 cpu_exclusive_val;
72
static TCGv_i32 cpu_exclusive_high;
73
#ifdef CONFIG_USER_ONLY
74
static TCGv_i32 cpu_exclusive_test;
75
static TCGv_i32 cpu_exclusive_info;
78
/* FIXME: These should be removed. */
79
static TCGv_i32 cpu_F0s, cpu_F1s;
80
static TCGv_i64 cpu_F0d, cpu_F1d;
82
#include "exec/gen-icount.h"
84
static const char *regnames[] =
85
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
86
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
88
/* initialize TCG globals. */
89
void arm_translate_init(void)
93
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
95
for (i = 0; i < 16; i++) {
96
cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
97
offsetof(CPUARMState, regs[i]),
100
cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
101
cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
102
cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
103
cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
105
cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
106
offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
107
cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
108
offsetof(CPUARMState, exclusive_val), "exclusive_val");
109
cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
110
offsetof(CPUARMState, exclusive_high), "exclusive_high");
111
#ifdef CONFIG_USER_ONLY
112
cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
113
offsetof(CPUARMState, exclusive_test), "exclusive_test");
114
cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
115
offsetof(CPUARMState, exclusive_info), "exclusive_info");
118
a64_translate_init();
121
static inline TCGv_i32 load_cpu_offset(int offset)
123
TCGv_i32 tmp = tcg_temp_new_i32();
124
tcg_gen_ld_i32(tmp, cpu_env, offset);
128
#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
130
static inline void store_cpu_offset(TCGv_i32 var, int offset)
132
tcg_gen_st_i32(var, cpu_env, offset);
133
tcg_temp_free_i32(var);
136
#define store_cpu_field(var, name) \
137
store_cpu_offset(var, offsetof(CPUARMState, name))
139
/* Set a variable to the value of a CPU register. */
140
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
144
/* normally, since we updated PC, we need only to add one insn */
146
addr = (long)s->pc + 2;
148
addr = (long)s->pc + 4;
149
tcg_gen_movi_i32(var, addr);
151
tcg_gen_mov_i32(var, cpu_R[reg]);
155
/* Create a new temporary and set it to the value of a CPU register. */
156
static inline TCGv_i32 load_reg(DisasContext *s, int reg)
158
TCGv_i32 tmp = tcg_temp_new_i32();
159
load_reg_var(s, tmp, reg);
163
/* Set a CPU register. The source must be a temporary and will be
165
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
168
tcg_gen_andi_i32(var, var, ~1);
169
s->is_jmp = DISAS_JUMP;
171
tcg_gen_mov_i32(cpu_R[reg], var);
172
tcg_temp_free_i32(var);
175
/* Value extensions. */
176
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
177
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
178
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
179
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
181
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
182
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
185
static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
187
TCGv_i32 tmp_mask = tcg_const_i32(mask);
188
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
189
tcg_temp_free_i32(tmp_mask);
191
/* Set NZCV flags from the high 4 bits of var. */
192
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
194
static void gen_exception(int excp)
196
TCGv_i32 tmp = tcg_temp_new_i32();
197
tcg_gen_movi_i32(tmp, excp);
198
gen_helper_exception(cpu_env, tmp);
199
tcg_temp_free_i32(tmp);
202
static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
204
TCGv_i32 tmp1 = tcg_temp_new_i32();
205
TCGv_i32 tmp2 = tcg_temp_new_i32();
206
tcg_gen_ext16s_i32(tmp1, a);
207
tcg_gen_ext16s_i32(tmp2, b);
208
tcg_gen_mul_i32(tmp1, tmp1, tmp2);
209
tcg_temp_free_i32(tmp2);
210
tcg_gen_sari_i32(a, a, 16);
211
tcg_gen_sari_i32(b, b, 16);
212
tcg_gen_mul_i32(b, b, a);
213
tcg_gen_mov_i32(a, tmp1);
214
tcg_temp_free_i32(tmp1);
217
/* Byteswap each halfword. */
218
static void gen_rev16(TCGv_i32 var)
220
TCGv_i32 tmp = tcg_temp_new_i32();
221
tcg_gen_shri_i32(tmp, var, 8);
222
tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
223
tcg_gen_shli_i32(var, var, 8);
224
tcg_gen_andi_i32(var, var, 0xff00ff00);
225
tcg_gen_or_i32(var, var, tmp);
226
tcg_temp_free_i32(tmp);
229
/* Byteswap low halfword and sign extend. */
230
static void gen_revsh(TCGv_i32 var)
232
tcg_gen_ext16u_i32(var, var);
233
tcg_gen_bswap16_i32(var, var);
234
tcg_gen_ext16s_i32(var, var);
237
/* Unsigned bitfield extract. */
238
static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
241
tcg_gen_shri_i32(var, var, shift);
242
tcg_gen_andi_i32(var, var, mask);
245
/* Signed bitfield extract. */
246
static void gen_sbfx(TCGv_i32 var, int shift, int width)
251
tcg_gen_sari_i32(var, var, shift);
252
if (shift + width < 32) {
253
signbit = 1u << (width - 1);
254
tcg_gen_andi_i32(var, var, (1u << width) - 1);
255
tcg_gen_xori_i32(var, var, signbit);
256
tcg_gen_subi_i32(var, var, signbit);
260
/* Return (b << 32) + a. Mark inputs as dead */
261
static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
263
TCGv_i64 tmp64 = tcg_temp_new_i64();
265
tcg_gen_extu_i32_i64(tmp64, b);
266
tcg_temp_free_i32(b);
267
tcg_gen_shli_i64(tmp64, tmp64, 32);
268
tcg_gen_add_i64(a, tmp64, a);
270
tcg_temp_free_i64(tmp64);
274
/* Return (b << 32) - a. Mark inputs as dead. */
275
static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
277
TCGv_i64 tmp64 = tcg_temp_new_i64();
279
tcg_gen_extu_i32_i64(tmp64, b);
280
tcg_temp_free_i32(b);
281
tcg_gen_shli_i64(tmp64, tmp64, 32);
282
tcg_gen_sub_i64(a, tmp64, a);
284
tcg_temp_free_i64(tmp64);
288
/* 32x32->64 multiply. Marks inputs as dead. */
289
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
291
TCGv_i32 lo = tcg_temp_new_i32();
292
TCGv_i32 hi = tcg_temp_new_i32();
295
tcg_gen_mulu2_i32(lo, hi, a, b);
296
tcg_temp_free_i32(a);
297
tcg_temp_free_i32(b);
299
ret = tcg_temp_new_i64();
300
tcg_gen_concat_i32_i64(ret, lo, hi);
301
tcg_temp_free_i32(lo);
302
tcg_temp_free_i32(hi);
307
static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
309
TCGv_i32 lo = tcg_temp_new_i32();
310
TCGv_i32 hi = tcg_temp_new_i32();
313
tcg_gen_muls2_i32(lo, hi, a, b);
314
tcg_temp_free_i32(a);
315
tcg_temp_free_i32(b);
317
ret = tcg_temp_new_i64();
318
tcg_gen_concat_i32_i64(ret, lo, hi);
319
tcg_temp_free_i32(lo);
320
tcg_temp_free_i32(hi);
325
/* Swap low and high halfwords. */
326
static void gen_swap_half(TCGv_i32 var)
328
TCGv_i32 tmp = tcg_temp_new_i32();
329
tcg_gen_shri_i32(tmp, var, 16);
330
tcg_gen_shli_i32(var, var, 16);
331
tcg_gen_or_i32(var, var, tmp);
332
tcg_temp_free_i32(tmp);
335
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
336
tmp = (t0 ^ t1) & 0x8000;
339
t0 = (t0 + t1) ^ tmp;
342
static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
344
TCGv_i32 tmp = tcg_temp_new_i32();
345
tcg_gen_xor_i32(tmp, t0, t1);
346
tcg_gen_andi_i32(tmp, tmp, 0x8000);
347
tcg_gen_andi_i32(t0, t0, ~0x8000);
348
tcg_gen_andi_i32(t1, t1, ~0x8000);
349
tcg_gen_add_i32(t0, t0, t1);
350
tcg_gen_xor_i32(t0, t0, tmp);
351
tcg_temp_free_i32(tmp);
352
tcg_temp_free_i32(t1);
355
/* Set CF to the top bit of var. */
356
static void gen_set_CF_bit31(TCGv_i32 var)
358
tcg_gen_shri_i32(cpu_CF, var, 31);
361
/* Set N and Z flags from var. */
362
static inline void gen_logic_CC(TCGv_i32 var)
364
tcg_gen_mov_i32(cpu_NF, var);
365
tcg_gen_mov_i32(cpu_ZF, var);
369
static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
371
tcg_gen_add_i32(t0, t0, t1);
372
tcg_gen_add_i32(t0, t0, cpu_CF);
375
/* dest = T0 + T1 + CF. */
376
static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
378
tcg_gen_add_i32(dest, t0, t1);
379
tcg_gen_add_i32(dest, dest, cpu_CF);
382
/* dest = T0 - T1 + CF - 1. */
383
static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
385
tcg_gen_sub_i32(dest, t0, t1);
386
tcg_gen_add_i32(dest, dest, cpu_CF);
387
tcg_gen_subi_i32(dest, dest, 1);
390
/* dest = T0 + T1. Compute C, N, V and Z flags */
391
static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
393
TCGv_i32 tmp = tcg_temp_new_i32();
394
tcg_gen_movi_i32(tmp, 0);
395
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
396
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
397
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
398
tcg_gen_xor_i32(tmp, t0, t1);
399
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
400
tcg_temp_free_i32(tmp);
401
tcg_gen_mov_i32(dest, cpu_NF);
404
/* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
405
static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
407
TCGv_i32 tmp = tcg_temp_new_i32();
408
if (TCG_TARGET_HAS_add2_i32) {
409
tcg_gen_movi_i32(tmp, 0);
410
tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
411
tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
413
TCGv_i64 q0 = tcg_temp_new_i64();
414
TCGv_i64 q1 = tcg_temp_new_i64();
415
tcg_gen_extu_i32_i64(q0, t0);
416
tcg_gen_extu_i32_i64(q1, t1);
417
tcg_gen_add_i64(q0, q0, q1);
418
tcg_gen_extu_i32_i64(q1, cpu_CF);
419
tcg_gen_add_i64(q0, q0, q1);
420
tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
421
tcg_temp_free_i64(q0);
422
tcg_temp_free_i64(q1);
424
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
425
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
426
tcg_gen_xor_i32(tmp, t0, t1);
427
tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
428
tcg_temp_free_i32(tmp);
429
tcg_gen_mov_i32(dest, cpu_NF);
432
/* dest = T0 - T1. Compute C, N, V and Z flags */
433
static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
436
tcg_gen_sub_i32(cpu_NF, t0, t1);
437
tcg_gen_mov_i32(cpu_ZF, cpu_NF);
438
tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
439
tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
440
tmp = tcg_temp_new_i32();
441
tcg_gen_xor_i32(tmp, t0, t1);
442
tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
443
tcg_temp_free_i32(tmp);
444
tcg_gen_mov_i32(dest, cpu_NF);
447
/* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
448
static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
450
TCGv_i32 tmp = tcg_temp_new_i32();
451
tcg_gen_not_i32(tmp, t1);
452
gen_adc_CC(dest, t0, tmp);
453
tcg_temp_free_i32(tmp);
456
#define GEN_SHIFT(name) \
457
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
459
TCGv_i32 tmp1, tmp2, tmp3; \
460
tmp1 = tcg_temp_new_i32(); \
461
tcg_gen_andi_i32(tmp1, t1, 0xff); \
462
tmp2 = tcg_const_i32(0); \
463
tmp3 = tcg_const_i32(0x1f); \
464
tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
465
tcg_temp_free_i32(tmp3); \
466
tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
467
tcg_gen_##name##_i32(dest, tmp2, tmp1); \
468
tcg_temp_free_i32(tmp2); \
469
tcg_temp_free_i32(tmp1); \
475
static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
478
tmp1 = tcg_temp_new_i32();
479
tcg_gen_andi_i32(tmp1, t1, 0xff);
480
tmp2 = tcg_const_i32(0x1f);
481
tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
482
tcg_temp_free_i32(tmp2);
483
tcg_gen_sar_i32(dest, t0, tmp1);
484
tcg_temp_free_i32(tmp1);
487
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
489
TCGv_i32 c0 = tcg_const_i32(0);
490
TCGv_i32 tmp = tcg_temp_new_i32();
491
tcg_gen_neg_i32(tmp, src);
492
tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
493
tcg_temp_free_i32(c0);
494
tcg_temp_free_i32(tmp);
497
static void shifter_out_im(TCGv_i32 var, int shift)
500
tcg_gen_andi_i32(cpu_CF, var, 1);
502
tcg_gen_shri_i32(cpu_CF, var, shift);
504
tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
509
/* Shift by immediate. Includes special handling for shift == 0. */
510
static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
511
int shift, int flags)
517
shifter_out_im(var, 32 - shift);
518
tcg_gen_shli_i32(var, var, shift);
524
tcg_gen_shri_i32(cpu_CF, var, 31);
526
tcg_gen_movi_i32(var, 0);
529
shifter_out_im(var, shift - 1);
530
tcg_gen_shri_i32(var, var, shift);
537
shifter_out_im(var, shift - 1);
540
tcg_gen_sari_i32(var, var, shift);
542
case 3: /* ROR/RRX */
545
shifter_out_im(var, shift - 1);
546
tcg_gen_rotri_i32(var, var, shift); break;
548
TCGv_i32 tmp = tcg_temp_new_i32();
549
tcg_gen_shli_i32(tmp, cpu_CF, 31);
551
shifter_out_im(var, 0);
552
tcg_gen_shri_i32(var, var, 1);
553
tcg_gen_or_i32(var, var, tmp);
554
tcg_temp_free_i32(tmp);
559
static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
560
TCGv_i32 shift, int flags)
564
case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
565
case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
566
case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
567
case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
572
gen_shl(var, var, shift);
575
gen_shr(var, var, shift);
578
gen_sar(var, var, shift);
580
case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
581
tcg_gen_rotr_i32(var, var, shift); break;
584
tcg_temp_free_i32(shift);
587
#define PAS_OP(pfx) \
589
case 0: gen_pas_helper(glue(pfx,add16)); break; \
590
case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
591
case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
592
case 3: gen_pas_helper(glue(pfx,sub16)); break; \
593
case 4: gen_pas_helper(glue(pfx,add8)); break; \
594
case 7: gen_pas_helper(glue(pfx,sub8)); break; \
596
static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
601
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
603
tmp = tcg_temp_new_ptr();
604
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
606
tcg_temp_free_ptr(tmp);
609
tmp = tcg_temp_new_ptr();
610
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
612
tcg_temp_free_ptr(tmp);
614
#undef gen_pas_helper
615
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
628
#undef gen_pas_helper
633
/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
634
#define PAS_OP(pfx) \
636
case 0: gen_pas_helper(glue(pfx,add8)); break; \
637
case 1: gen_pas_helper(glue(pfx,add16)); break; \
638
case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
639
case 4: gen_pas_helper(glue(pfx,sub8)); break; \
640
case 5: gen_pas_helper(glue(pfx,sub16)); break; \
641
case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
643
static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
648
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
650
tmp = tcg_temp_new_ptr();
651
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
653
tcg_temp_free_ptr(tmp);
656
tmp = tcg_temp_new_ptr();
657
tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
659
tcg_temp_free_ptr(tmp);
661
#undef gen_pas_helper
662
#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
675
#undef gen_pas_helper
680
static void gen_test_cc(int cc, int label)
687
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
690
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
693
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
696
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
699
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
702
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
705
tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
708
tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
710
case 8: /* hi: C && !Z */
711
inv = gen_new_label();
712
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
713
tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
716
case 9: /* ls: !C || Z */
717
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
718
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
720
case 10: /* ge: N == V -> N ^ V == 0 */
721
tmp = tcg_temp_new_i32();
722
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
723
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
724
tcg_temp_free_i32(tmp);
726
case 11: /* lt: N != V -> N ^ V != 0 */
727
tmp = tcg_temp_new_i32();
728
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
729
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
730
tcg_temp_free_i32(tmp);
732
case 12: /* gt: !Z && N == V */
733
inv = gen_new_label();
734
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
735
tmp = tcg_temp_new_i32();
736
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
737
tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
738
tcg_temp_free_i32(tmp);
741
case 13: /* le: Z || N != V */
742
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
743
tmp = tcg_temp_new_i32();
744
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
745
tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
746
tcg_temp_free_i32(tmp);
749
fprintf(stderr, "Bad condition code 0x%x\n", cc);
754
static const uint8_t table_logic_cc[16] = {
773
/* Set PC and Thumb state from an immediate address. */
774
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
778
s->is_jmp = DISAS_UPDATE;
779
if (s->thumb != (addr & 1)) {
780
tmp = tcg_temp_new_i32();
781
tcg_gen_movi_i32(tmp, addr & 1);
782
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
783
tcg_temp_free_i32(tmp);
785
tcg_gen_movi_i32(cpu_R[15], addr & ~1);
788
/* Set PC and Thumb state from var. var is marked as dead. */
789
static inline void gen_bx(DisasContext *s, TCGv_i32 var)
791
s->is_jmp = DISAS_UPDATE;
792
tcg_gen_andi_i32(cpu_R[15], var, ~1);
793
tcg_gen_andi_i32(var, var, 1);
794
store_cpu_field(var, thumb);
797
/* Variant of store_reg which uses branch&exchange logic when storing
798
to r15 in ARM architecture v7 and above. The source must be a temporary
799
and will be marked as dead. */
800
static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
801
int reg, TCGv_i32 var)
803
if (reg == 15 && ENABLE_ARCH_7) {
806
store_reg(s, reg, var);
810
/* Variant of store_reg which uses branch&exchange logic when storing
811
* to r15 in ARM architecture v5T and above. This is used for storing
812
* the results of a LDR/LDM/POP into r15, and corresponds to the cases
813
* in the ARM ARM which use the LoadWritePC() pseudocode function. */
814
static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
815
int reg, TCGv_i32 var)
817
if (reg == 15 && ENABLE_ARCH_5) {
820
store_reg(s, reg, var);
824
/* Abstractions of "generate code to do a guest load/store for
825
* AArch32", where a vaddr is always 32 bits (and is zero
826
* extended if we're a 64 bit core) and data is also
827
* 32 bits unless specifically doing a 64 bit access.
828
* These functions work like tcg_gen_qemu_{ld,st}* except
829
* that their arguments are TCGv_i32 rather than TCGv.
831
#if TARGET_LONG_BITS == 32
833
#define DO_GEN_LD(OP) \
834
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
836
tcg_gen_qemu_##OP(val, addr, index); \
839
#define DO_GEN_ST(OP) \
840
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
842
tcg_gen_qemu_##OP(val, addr, index); \
845
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
847
tcg_gen_qemu_ld64(val, addr, index);
850
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
852
tcg_gen_qemu_st64(val, addr, index);
857
#define DO_GEN_LD(OP) \
858
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
860
TCGv addr64 = tcg_temp_new(); \
861
TCGv val64 = tcg_temp_new(); \
862
tcg_gen_extu_i32_i64(addr64, addr); \
863
tcg_gen_qemu_##OP(val64, addr64, index); \
864
tcg_temp_free(addr64); \
865
tcg_gen_trunc_i64_i32(val, val64); \
866
tcg_temp_free(val64); \
869
#define DO_GEN_ST(OP) \
870
static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
872
TCGv addr64 = tcg_temp_new(); \
873
TCGv val64 = tcg_temp_new(); \
874
tcg_gen_extu_i32_i64(addr64, addr); \
875
tcg_gen_extu_i32_i64(val64, val); \
876
tcg_gen_qemu_##OP(val64, addr64, index); \
877
tcg_temp_free(addr64); \
878
tcg_temp_free(val64); \
881
static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
883
TCGv addr64 = tcg_temp_new();
884
tcg_gen_extu_i32_i64(addr64, addr);
885
tcg_gen_qemu_ld64(val, addr64, index);
886
tcg_temp_free(addr64);
889
static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
891
TCGv addr64 = tcg_temp_new();
892
tcg_gen_extu_i32_i64(addr64, addr);
893
tcg_gen_qemu_st64(val, addr64, index);
894
tcg_temp_free(addr64);
908
static inline void gen_smc(CPUARMState *env, DisasContext *s)
910
tcg_gen_movi_i32(cpu_R[15], s->pc);
911
s->is_jmp = DISAS_SMC;
914
static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
917
gen_a64_set_pc_im(val);
919
tcg_gen_movi_i32(cpu_R[15], val);
923
/* Force a TB lookup after an instruction that changes the CPU state. */
924
static inline void gen_lookup_tb(DisasContext *s)
926
tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
927
s->is_jmp = DISAS_UPDATE;
930
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
933
int val, rm, shift, shiftop;
936
if (!(insn & (1 << 25))) {
939
if (!(insn & (1 << 23)))
942
tcg_gen_addi_i32(var, var, val);
946
shift = (insn >> 7) & 0x1f;
947
shiftop = (insn >> 5) & 3;
948
offset = load_reg(s, rm);
949
gen_arm_shift_im(offset, shiftop, shift, 0);
950
if (!(insn & (1 << 23)))
951
tcg_gen_sub_i32(var, var, offset);
953
tcg_gen_add_i32(var, var, offset);
954
tcg_temp_free_i32(offset);
958
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
959
int extra, TCGv_i32 var)
964
if (insn & (1 << 22)) {
966
val = (insn & 0xf) | ((insn >> 4) & 0xf0);
967
if (!(insn & (1 << 23)))
971
tcg_gen_addi_i32(var, var, val);
975
tcg_gen_addi_i32(var, var, extra);
977
offset = load_reg(s, rm);
978
if (!(insn & (1 << 23)))
979
tcg_gen_sub_i32(var, var, offset);
981
tcg_gen_add_i32(var, var, offset);
982
tcg_temp_free_i32(offset);
986
static TCGv_ptr get_fpstatus_ptr(int neon)
988
TCGv_ptr statusptr = tcg_temp_new_ptr();
991
offset = offsetof(CPUARMState, vfp.standard_fp_status);
993
offset = offsetof(CPUARMState, vfp.fp_status);
995
tcg_gen_addi_ptr(statusptr, cpu_env, offset);
999
#define VFP_OP2(name) \
1000
static inline void gen_vfp_##name(int dp) \
1002
TCGv_ptr fpst = get_fpstatus_ptr(0); \
1004
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1006
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1008
tcg_temp_free_ptr(fpst); \
1018
static inline void gen_vfp_F1_mul(int dp)
1020
/* Like gen_vfp_mul() but put result in F1 */
1021
TCGv_ptr fpst = get_fpstatus_ptr(0);
1023
gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1025
gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1027
tcg_temp_free_ptr(fpst);
1030
static inline void gen_vfp_F1_neg(int dp)
1032
/* Like gen_vfp_neg() but put result in F1 */
1034
gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1036
gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1040
static inline void gen_vfp_abs(int dp)
1043
gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1045
gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1048
static inline void gen_vfp_neg(int dp)
1051
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1053
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1056
static inline void gen_vfp_sqrt(int dp)
1059
gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1061
gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1064
static inline void gen_vfp_cmp(int dp)
1067
gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1069
gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1072
static inline void gen_vfp_cmpe(int dp)
1075
gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1077
gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1080
static inline void gen_vfp_F1_ld0(int dp)
1083
tcg_gen_movi_i64(cpu_F1d, 0);
1085
tcg_gen_movi_i32(cpu_F1s, 0);
1088
#define VFP_GEN_ITOF(name) \
1089
static inline void gen_vfp_##name(int dp, int neon) \
1091
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1093
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1095
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1097
tcg_temp_free_ptr(statusptr); \
1104
#define VFP_GEN_FTOI(name) \
1105
static inline void gen_vfp_##name(int dp, int neon) \
1107
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1109
gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1111
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1113
tcg_temp_free_ptr(statusptr); \
1122
#define VFP_GEN_FIX(name) \
1123
static inline void gen_vfp_##name(int dp, int shift, int neon) \
1125
TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1126
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1128
gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1130
gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1132
tcg_temp_free_i32(tmp_shift); \
1133
tcg_temp_free_ptr(statusptr); \
1145
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1148
gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1150
gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1154
static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1157
gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1159
gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1164
vfp_reg_offset (int dp, int reg)
1167
return offsetof(CPUARMState, vfp.regs[reg]);
1169
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1170
+ offsetof(CPU_DoubleU, l.upper);
1172
return offsetof(CPUARMState, vfp.regs[reg >> 1])
1173
+ offsetof(CPU_DoubleU, l.lower);
1177
/* Return the offset of a 32-bit piece of a NEON register.
1178
zero is the least significant end of the register. */
1180
neon_reg_offset (int reg, int n)
1184
return vfp_reg_offset(0, sreg);
1187
static TCGv_i32 neon_load_reg(int reg, int pass)
1189
TCGv_i32 tmp = tcg_temp_new_i32();
1190
tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1194
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1196
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1197
tcg_temp_free_i32(var);
1200
static inline void neon_load_reg64(TCGv_i64 var, int reg)
1202
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1205
static inline void neon_store_reg64(TCGv_i64 var, int reg)
1207
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1210
#define tcg_gen_ld_f32 tcg_gen_ld_i32
1211
#define tcg_gen_ld_f64 tcg_gen_ld_i64
1212
#define tcg_gen_st_f32 tcg_gen_st_i32
1213
#define tcg_gen_st_f64 tcg_gen_st_i64
1215
static inline void gen_mov_F0_vreg(int dp, int reg)
1218
tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1220
tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1223
static inline void gen_mov_F1_vreg(int dp, int reg)
1226
tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1228
tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1231
static inline void gen_mov_vreg_F0(int dp, int reg)
1234
tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1236
tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1239
#define ARM_CP_RW_BIT (1 << 20)
1241
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1243
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1246
static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1248
tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1251
static inline TCGv_i32 iwmmxt_load_creg(int reg)
1253
TCGv_i32 var = tcg_temp_new_i32();
1254
tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1258
static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1260
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1261
tcg_temp_free_i32(var);
1264
static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1266
iwmmxt_store_reg(cpu_M0, rn);
1269
static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1271
iwmmxt_load_reg(cpu_M0, rn);
1274
static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1276
iwmmxt_load_reg(cpu_V1, rn);
1277
tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1280
static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1282
iwmmxt_load_reg(cpu_V1, rn);
1283
tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1286
static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1288
iwmmxt_load_reg(cpu_V1, rn);
1289
tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1292
#define IWMMXT_OP(name) \
1293
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1295
iwmmxt_load_reg(cpu_V1, rn); \
1296
gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1299
#define IWMMXT_OP_ENV(name) \
1300
static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1302
iwmmxt_load_reg(cpu_V1, rn); \
1303
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1306
#define IWMMXT_OP_ENV_SIZE(name) \
1307
IWMMXT_OP_ENV(name##b) \
1308
IWMMXT_OP_ENV(name##w) \
1309
IWMMXT_OP_ENV(name##l)
1311
#define IWMMXT_OP_ENV1(name) \
1312
static inline void gen_op_iwmmxt_##name##_M0(void) \
1314
gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1328
IWMMXT_OP_ENV_SIZE(unpackl)
1329
IWMMXT_OP_ENV_SIZE(unpackh)
1331
IWMMXT_OP_ENV1(unpacklub)
1332
IWMMXT_OP_ENV1(unpackluw)
1333
IWMMXT_OP_ENV1(unpacklul)
1334
IWMMXT_OP_ENV1(unpackhub)
1335
IWMMXT_OP_ENV1(unpackhuw)
1336
IWMMXT_OP_ENV1(unpackhul)
1337
IWMMXT_OP_ENV1(unpacklsb)
1338
IWMMXT_OP_ENV1(unpacklsw)
1339
IWMMXT_OP_ENV1(unpacklsl)
1340
IWMMXT_OP_ENV1(unpackhsb)
1341
IWMMXT_OP_ENV1(unpackhsw)
1342
IWMMXT_OP_ENV1(unpackhsl)
1344
IWMMXT_OP_ENV_SIZE(cmpeq)
1345
IWMMXT_OP_ENV_SIZE(cmpgtu)
1346
IWMMXT_OP_ENV_SIZE(cmpgts)
1348
IWMMXT_OP_ENV_SIZE(mins)
1349
IWMMXT_OP_ENV_SIZE(minu)
1350
IWMMXT_OP_ENV_SIZE(maxs)
1351
IWMMXT_OP_ENV_SIZE(maxu)
1353
IWMMXT_OP_ENV_SIZE(subn)
1354
IWMMXT_OP_ENV_SIZE(addn)
1355
IWMMXT_OP_ENV_SIZE(subu)
1356
IWMMXT_OP_ENV_SIZE(addu)
1357
IWMMXT_OP_ENV_SIZE(subs)
1358
IWMMXT_OP_ENV_SIZE(adds)
1360
IWMMXT_OP_ENV(avgb0)
1361
IWMMXT_OP_ENV(avgb1)
1362
IWMMXT_OP_ENV(avgw0)
1363
IWMMXT_OP_ENV(avgw1)
1367
IWMMXT_OP_ENV(packuw)
1368
IWMMXT_OP_ENV(packul)
1369
IWMMXT_OP_ENV(packuq)
1370
IWMMXT_OP_ENV(packsw)
1371
IWMMXT_OP_ENV(packsl)
1372
IWMMXT_OP_ENV(packsq)
1374
static void gen_op_iwmmxt_set_mup(void)
1377
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1378
tcg_gen_ori_i32(tmp, tmp, 2);
1379
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1382
static void gen_op_iwmmxt_set_cup(void)
1385
tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1386
tcg_gen_ori_i32(tmp, tmp, 1);
1387
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1390
static void gen_op_iwmmxt_setpsr_nz(void)
1392
TCGv_i32 tmp = tcg_temp_new_i32();
1393
gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1394
store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1397
static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1399
iwmmxt_load_reg(cpu_V1, rn);
1400
tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1401
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1404
static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1411
rd = (insn >> 16) & 0xf;
1412
tmp = load_reg(s, rd);
1414
offset = (insn & 0xff) << ((insn >> 7) & 2);
1415
if (insn & (1 << 24)) {
1417
if (insn & (1 << 23))
1418
tcg_gen_addi_i32(tmp, tmp, offset);
1420
tcg_gen_addi_i32(tmp, tmp, -offset);
1421
tcg_gen_mov_i32(dest, tmp);
1422
if (insn & (1 << 21))
1423
store_reg(s, rd, tmp);
1425
tcg_temp_free_i32(tmp);
1426
} else if (insn & (1 << 21)) {
1428
tcg_gen_mov_i32(dest, tmp);
1429
if (insn & (1 << 23))
1430
tcg_gen_addi_i32(tmp, tmp, offset);
1432
tcg_gen_addi_i32(tmp, tmp, -offset);
1433
store_reg(s, rd, tmp);
1434
} else if (!(insn & (1 << 23)))
1439
static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1441
int rd = (insn >> 0) & 0xf;
1444
if (insn & (1 << 8)) {
1445
if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1448
tmp = iwmmxt_load_creg(rd);
1451
tmp = tcg_temp_new_i32();
1452
iwmmxt_load_reg(cpu_V0, rd);
1453
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1455
tcg_gen_andi_i32(tmp, tmp, mask);
1456
tcg_gen_mov_i32(dest, tmp);
1457
tcg_temp_free_i32(tmp);
1461
/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1462
(ie. an undefined instruction). */
1463
static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1466
int rdhi, rdlo, rd0, rd1, i;
1468
TCGv_i32 tmp, tmp2, tmp3;
1470
if ((insn & 0x0e000e00) == 0x0c000000) {
1471
if ((insn & 0x0fe00ff0) == 0x0c400000) {
1473
rdlo = (insn >> 12) & 0xf;
1474
rdhi = (insn >> 16) & 0xf;
1475
if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1476
iwmmxt_load_reg(cpu_V0, wrd);
1477
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1478
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1479
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1480
} else { /* TMCRR */
1481
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1482
iwmmxt_store_reg(cpu_V0, wrd);
1483
gen_op_iwmmxt_set_mup();
1488
wrd = (insn >> 12) & 0xf;
1489
addr = tcg_temp_new_i32();
1490
if (gen_iwmmxt_address(s, insn, addr)) {
1491
tcg_temp_free_i32(addr);
1494
if (insn & ARM_CP_RW_BIT) {
1495
if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1496
tmp = tcg_temp_new_i32();
1497
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1498
iwmmxt_store_creg(wrd, tmp);
1501
if (insn & (1 << 8)) {
1502
if (insn & (1 << 22)) { /* WLDRD */
1503
gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1505
} else { /* WLDRW wRd */
1506
tmp = tcg_temp_new_i32();
1507
gen_aa32_ld32u(tmp, addr, IS_USER(s));
1510
tmp = tcg_temp_new_i32();
1511
if (insn & (1 << 22)) { /* WLDRH */
1512
gen_aa32_ld16u(tmp, addr, IS_USER(s));
1513
} else { /* WLDRB */
1514
gen_aa32_ld8u(tmp, addr, IS_USER(s));
1518
tcg_gen_extu_i32_i64(cpu_M0, tmp);
1519
tcg_temp_free_i32(tmp);
1521
gen_op_iwmmxt_movq_wRn_M0(wrd);
1524
if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1525
tmp = iwmmxt_load_creg(wrd);
1526
gen_aa32_st32(tmp, addr, IS_USER(s));
1528
gen_op_iwmmxt_movq_M0_wRn(wrd);
1529
tmp = tcg_temp_new_i32();
1530
if (insn & (1 << 8)) {
1531
if (insn & (1 << 22)) { /* WSTRD */
1532
gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1533
} else { /* WSTRW wRd */
1534
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1535
gen_aa32_st32(tmp, addr, IS_USER(s));
1538
if (insn & (1 << 22)) { /* WSTRH */
1539
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1540
gen_aa32_st16(tmp, addr, IS_USER(s));
1541
} else { /* WSTRB */
1542
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1543
gen_aa32_st8(tmp, addr, IS_USER(s));
1547
tcg_temp_free_i32(tmp);
1549
tcg_temp_free_i32(addr);
1553
if ((insn & 0x0f000000) != 0x0e000000)
1556
switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1557
case 0x000: /* WOR */
1558
wrd = (insn >> 12) & 0xf;
1559
rd0 = (insn >> 0) & 0xf;
1560
rd1 = (insn >> 16) & 0xf;
1561
gen_op_iwmmxt_movq_M0_wRn(rd0);
1562
gen_op_iwmmxt_orq_M0_wRn(rd1);
1563
gen_op_iwmmxt_setpsr_nz();
1564
gen_op_iwmmxt_movq_wRn_M0(wrd);
1565
gen_op_iwmmxt_set_mup();
1566
gen_op_iwmmxt_set_cup();
1568
case 0x011: /* TMCR */
1571
rd = (insn >> 12) & 0xf;
1572
wrd = (insn >> 16) & 0xf;
1574
case ARM_IWMMXT_wCID:
1575
case ARM_IWMMXT_wCASF:
1577
case ARM_IWMMXT_wCon:
1578
gen_op_iwmmxt_set_cup();
1580
case ARM_IWMMXT_wCSSF:
1581
tmp = iwmmxt_load_creg(wrd);
1582
tmp2 = load_reg(s, rd);
1583
tcg_gen_andc_i32(tmp, tmp, tmp2);
1584
tcg_temp_free_i32(tmp2);
1585
iwmmxt_store_creg(wrd, tmp);
1587
case ARM_IWMMXT_wCGR0:
1588
case ARM_IWMMXT_wCGR1:
1589
case ARM_IWMMXT_wCGR2:
1590
case ARM_IWMMXT_wCGR3:
1591
gen_op_iwmmxt_set_cup();
1592
tmp = load_reg(s, rd);
1593
iwmmxt_store_creg(wrd, tmp);
1599
case 0x100: /* WXOR */
1600
wrd = (insn >> 12) & 0xf;
1601
rd0 = (insn >> 0) & 0xf;
1602
rd1 = (insn >> 16) & 0xf;
1603
gen_op_iwmmxt_movq_M0_wRn(rd0);
1604
gen_op_iwmmxt_xorq_M0_wRn(rd1);
1605
gen_op_iwmmxt_setpsr_nz();
1606
gen_op_iwmmxt_movq_wRn_M0(wrd);
1607
gen_op_iwmmxt_set_mup();
1608
gen_op_iwmmxt_set_cup();
1610
case 0x111: /* TMRC */
1613
rd = (insn >> 12) & 0xf;
1614
wrd = (insn >> 16) & 0xf;
1615
tmp = iwmmxt_load_creg(wrd);
1616
store_reg(s, rd, tmp);
1618
case 0x300: /* WANDN */
1619
wrd = (insn >> 12) & 0xf;
1620
rd0 = (insn >> 0) & 0xf;
1621
rd1 = (insn >> 16) & 0xf;
1622
gen_op_iwmmxt_movq_M0_wRn(rd0);
1623
tcg_gen_neg_i64(cpu_M0, cpu_M0);
1624
gen_op_iwmmxt_andq_M0_wRn(rd1);
1625
gen_op_iwmmxt_setpsr_nz();
1626
gen_op_iwmmxt_movq_wRn_M0(wrd);
1627
gen_op_iwmmxt_set_mup();
1628
gen_op_iwmmxt_set_cup();
1630
case 0x200: /* WAND */
1631
wrd = (insn >> 12) & 0xf;
1632
rd0 = (insn >> 0) & 0xf;
1633
rd1 = (insn >> 16) & 0xf;
1634
gen_op_iwmmxt_movq_M0_wRn(rd0);
1635
gen_op_iwmmxt_andq_M0_wRn(rd1);
1636
gen_op_iwmmxt_setpsr_nz();
1637
gen_op_iwmmxt_movq_wRn_M0(wrd);
1638
gen_op_iwmmxt_set_mup();
1639
gen_op_iwmmxt_set_cup();
1641
case 0x810: case 0xa10: /* WMADD */
1642
wrd = (insn >> 12) & 0xf;
1643
rd0 = (insn >> 0) & 0xf;
1644
rd1 = (insn >> 16) & 0xf;
1645
gen_op_iwmmxt_movq_M0_wRn(rd0);
1646
if (insn & (1 << 21))
1647
gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1649
gen_op_iwmmxt_madduq_M0_wRn(rd1);
1650
gen_op_iwmmxt_movq_wRn_M0(wrd);
1651
gen_op_iwmmxt_set_mup();
1653
case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1654
wrd = (insn >> 12) & 0xf;
1655
rd0 = (insn >> 16) & 0xf;
1656
rd1 = (insn >> 0) & 0xf;
1657
gen_op_iwmmxt_movq_M0_wRn(rd0);
1658
switch ((insn >> 22) & 3) {
1660
gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1663
gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1666
gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1671
gen_op_iwmmxt_movq_wRn_M0(wrd);
1672
gen_op_iwmmxt_set_mup();
1673
gen_op_iwmmxt_set_cup();
1675
case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1676
wrd = (insn >> 12) & 0xf;
1677
rd0 = (insn >> 16) & 0xf;
1678
rd1 = (insn >> 0) & 0xf;
1679
gen_op_iwmmxt_movq_M0_wRn(rd0);
1680
switch ((insn >> 22) & 3) {
1682
gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1685
gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1688
gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1693
gen_op_iwmmxt_movq_wRn_M0(wrd);
1694
gen_op_iwmmxt_set_mup();
1695
gen_op_iwmmxt_set_cup();
1697
case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1698
wrd = (insn >> 12) & 0xf;
1699
rd0 = (insn >> 16) & 0xf;
1700
rd1 = (insn >> 0) & 0xf;
1701
gen_op_iwmmxt_movq_M0_wRn(rd0);
1702
if (insn & (1 << 22))
1703
gen_op_iwmmxt_sadw_M0_wRn(rd1);
1705
gen_op_iwmmxt_sadb_M0_wRn(rd1);
1706
if (!(insn & (1 << 20)))
1707
gen_op_iwmmxt_addl_M0_wRn(wrd);
1708
gen_op_iwmmxt_movq_wRn_M0(wrd);
1709
gen_op_iwmmxt_set_mup();
1711
case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1712
wrd = (insn >> 12) & 0xf;
1713
rd0 = (insn >> 16) & 0xf;
1714
rd1 = (insn >> 0) & 0xf;
1715
gen_op_iwmmxt_movq_M0_wRn(rd0);
1716
if (insn & (1 << 21)) {
1717
if (insn & (1 << 20))
1718
gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1720
gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1722
if (insn & (1 << 20))
1723
gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1725
gen_op_iwmmxt_mululw_M0_wRn(rd1);
1727
gen_op_iwmmxt_movq_wRn_M0(wrd);
1728
gen_op_iwmmxt_set_mup();
1730
case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1731
wrd = (insn >> 12) & 0xf;
1732
rd0 = (insn >> 16) & 0xf;
1733
rd1 = (insn >> 0) & 0xf;
1734
gen_op_iwmmxt_movq_M0_wRn(rd0);
1735
if (insn & (1 << 21))
1736
gen_op_iwmmxt_macsw_M0_wRn(rd1);
1738
gen_op_iwmmxt_macuw_M0_wRn(rd1);
1739
if (!(insn & (1 << 20))) {
1740
iwmmxt_load_reg(cpu_V1, wrd);
1741
tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1743
gen_op_iwmmxt_movq_wRn_M0(wrd);
1744
gen_op_iwmmxt_set_mup();
1746
case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1747
wrd = (insn >> 12) & 0xf;
1748
rd0 = (insn >> 16) & 0xf;
1749
rd1 = (insn >> 0) & 0xf;
1750
gen_op_iwmmxt_movq_M0_wRn(rd0);
1751
switch ((insn >> 22) & 3) {
1753
gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1756
gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1759
gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1764
gen_op_iwmmxt_movq_wRn_M0(wrd);
1765
gen_op_iwmmxt_set_mup();
1766
gen_op_iwmmxt_set_cup();
1768
case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1769
wrd = (insn >> 12) & 0xf;
1770
rd0 = (insn >> 16) & 0xf;
1771
rd1 = (insn >> 0) & 0xf;
1772
gen_op_iwmmxt_movq_M0_wRn(rd0);
1773
if (insn & (1 << 22)) {
1774
if (insn & (1 << 20))
1775
gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1777
gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1779
if (insn & (1 << 20))
1780
gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1782
gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1784
gen_op_iwmmxt_movq_wRn_M0(wrd);
1785
gen_op_iwmmxt_set_mup();
1786
gen_op_iwmmxt_set_cup();
1788
case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1789
wrd = (insn >> 12) & 0xf;
1790
rd0 = (insn >> 16) & 0xf;
1791
rd1 = (insn >> 0) & 0xf;
1792
gen_op_iwmmxt_movq_M0_wRn(rd0);
1793
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1794
tcg_gen_andi_i32(tmp, tmp, 7);
1795
iwmmxt_load_reg(cpu_V1, rd1);
1796
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1797
tcg_temp_free_i32(tmp);
1798
gen_op_iwmmxt_movq_wRn_M0(wrd);
1799
gen_op_iwmmxt_set_mup();
1801
case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1802
if (((insn >> 6) & 3) == 3)
1804
rd = (insn >> 12) & 0xf;
1805
wrd = (insn >> 16) & 0xf;
1806
tmp = load_reg(s, rd);
1807
gen_op_iwmmxt_movq_M0_wRn(wrd);
1808
switch ((insn >> 6) & 3) {
1810
tmp2 = tcg_const_i32(0xff);
1811
tmp3 = tcg_const_i32((insn & 7) << 3);
1814
tmp2 = tcg_const_i32(0xffff);
1815
tmp3 = tcg_const_i32((insn & 3) << 4);
1818
tmp2 = tcg_const_i32(0xffffffff);
1819
tmp3 = tcg_const_i32((insn & 1) << 5);
1822
TCGV_UNUSED_I32(tmp2);
1823
TCGV_UNUSED_I32(tmp3);
1825
gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1826
tcg_temp_free_i32(tmp3);
1827
tcg_temp_free_i32(tmp2);
1828
tcg_temp_free_i32(tmp);
1829
gen_op_iwmmxt_movq_wRn_M0(wrd);
1830
gen_op_iwmmxt_set_mup();
1832
case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1833
rd = (insn >> 12) & 0xf;
1834
wrd = (insn >> 16) & 0xf;
1835
if (rd == 15 || ((insn >> 22) & 3) == 3)
1837
gen_op_iwmmxt_movq_M0_wRn(wrd);
1838
tmp = tcg_temp_new_i32();
1839
switch ((insn >> 22) & 3) {
1841
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1842
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1844
tcg_gen_ext8s_i32(tmp, tmp);
1846
tcg_gen_andi_i32(tmp, tmp, 0xff);
1850
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1851
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1853
tcg_gen_ext16s_i32(tmp, tmp);
1855
tcg_gen_andi_i32(tmp, tmp, 0xffff);
1859
tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1860
tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1863
store_reg(s, rd, tmp);
1865
case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1866
if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1868
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1869
switch ((insn >> 22) & 3) {
1871
tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1874
tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1877
tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1880
tcg_gen_shli_i32(tmp, tmp, 28);
1882
tcg_temp_free_i32(tmp);
1884
case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1885
if (((insn >> 6) & 3) == 3)
1887
rd = (insn >> 12) & 0xf;
1888
wrd = (insn >> 16) & 0xf;
1889
tmp = load_reg(s, rd);
1890
switch ((insn >> 6) & 3) {
1892
gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1895
gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1898
gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1901
tcg_temp_free_i32(tmp);
1902
gen_op_iwmmxt_movq_wRn_M0(wrd);
1903
gen_op_iwmmxt_set_mup();
1905
case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1906
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1908
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1909
tmp2 = tcg_temp_new_i32();
1910
tcg_gen_mov_i32(tmp2, tmp);
1911
switch ((insn >> 22) & 3) {
1913
for (i = 0; i < 7; i ++) {
1914
tcg_gen_shli_i32(tmp2, tmp2, 4);
1915
tcg_gen_and_i32(tmp, tmp, tmp2);
1919
for (i = 0; i < 3; i ++) {
1920
tcg_gen_shli_i32(tmp2, tmp2, 8);
1921
tcg_gen_and_i32(tmp, tmp, tmp2);
1925
tcg_gen_shli_i32(tmp2, tmp2, 16);
1926
tcg_gen_and_i32(tmp, tmp, tmp2);
1930
tcg_temp_free_i32(tmp2);
1931
tcg_temp_free_i32(tmp);
1933
case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1934
wrd = (insn >> 12) & 0xf;
1935
rd0 = (insn >> 16) & 0xf;
1936
gen_op_iwmmxt_movq_M0_wRn(rd0);
1937
switch ((insn >> 22) & 3) {
1939
gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1942
gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1945
gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1950
gen_op_iwmmxt_movq_wRn_M0(wrd);
1951
gen_op_iwmmxt_set_mup();
1953
case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1954
if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1956
tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1957
tmp2 = tcg_temp_new_i32();
1958
tcg_gen_mov_i32(tmp2, tmp);
1959
switch ((insn >> 22) & 3) {
1961
for (i = 0; i < 7; i ++) {
1962
tcg_gen_shli_i32(tmp2, tmp2, 4);
1963
tcg_gen_or_i32(tmp, tmp, tmp2);
1967
for (i = 0; i < 3; i ++) {
1968
tcg_gen_shli_i32(tmp2, tmp2, 8);
1969
tcg_gen_or_i32(tmp, tmp, tmp2);
1973
tcg_gen_shli_i32(tmp2, tmp2, 16);
1974
tcg_gen_or_i32(tmp, tmp, tmp2);
1978
tcg_temp_free_i32(tmp2);
1979
tcg_temp_free_i32(tmp);
1981
case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1982
rd = (insn >> 12) & 0xf;
1983
rd0 = (insn >> 16) & 0xf;
1984
if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1986
gen_op_iwmmxt_movq_M0_wRn(rd0);
1987
tmp = tcg_temp_new_i32();
1988
switch ((insn >> 22) & 3) {
1990
gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1993
gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1996
gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1999
store_reg(s, rd, tmp);
2001
case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2002
case 0x906: case 0xb06: case 0xd06: case 0xf06:
2003
wrd = (insn >> 12) & 0xf;
2004
rd0 = (insn >> 16) & 0xf;
2005
rd1 = (insn >> 0) & 0xf;
2006
gen_op_iwmmxt_movq_M0_wRn(rd0);
2007
switch ((insn >> 22) & 3) {
2009
if (insn & (1 << 21))
2010
gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2012
gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2015
if (insn & (1 << 21))
2016
gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2018
gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2021
if (insn & (1 << 21))
2022
gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2024
gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2029
gen_op_iwmmxt_movq_wRn_M0(wrd);
2030
gen_op_iwmmxt_set_mup();
2031
gen_op_iwmmxt_set_cup();
2033
case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2034
case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2035
wrd = (insn >> 12) & 0xf;
2036
rd0 = (insn >> 16) & 0xf;
2037
gen_op_iwmmxt_movq_M0_wRn(rd0);
2038
switch ((insn >> 22) & 3) {
2040
if (insn & (1 << 21))
2041
gen_op_iwmmxt_unpacklsb_M0();
2043
gen_op_iwmmxt_unpacklub_M0();
2046
if (insn & (1 << 21))
2047
gen_op_iwmmxt_unpacklsw_M0();
2049
gen_op_iwmmxt_unpackluw_M0();
2052
if (insn & (1 << 21))
2053
gen_op_iwmmxt_unpacklsl_M0();
2055
gen_op_iwmmxt_unpacklul_M0();
2060
gen_op_iwmmxt_movq_wRn_M0(wrd);
2061
gen_op_iwmmxt_set_mup();
2062
gen_op_iwmmxt_set_cup();
2064
case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2065
case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2066
wrd = (insn >> 12) & 0xf;
2067
rd0 = (insn >> 16) & 0xf;
2068
gen_op_iwmmxt_movq_M0_wRn(rd0);
2069
switch ((insn >> 22) & 3) {
2071
if (insn & (1 << 21))
2072
gen_op_iwmmxt_unpackhsb_M0();
2074
gen_op_iwmmxt_unpackhub_M0();
2077
if (insn & (1 << 21))
2078
gen_op_iwmmxt_unpackhsw_M0();
2080
gen_op_iwmmxt_unpackhuw_M0();
2083
if (insn & (1 << 21))
2084
gen_op_iwmmxt_unpackhsl_M0();
2086
gen_op_iwmmxt_unpackhul_M0();
2091
gen_op_iwmmxt_movq_wRn_M0(wrd);
2092
gen_op_iwmmxt_set_mup();
2093
gen_op_iwmmxt_set_cup();
2095
case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2096
case 0x214: case 0x614: case 0xa14: case 0xe14:
2097
if (((insn >> 22) & 3) == 0)
2099
wrd = (insn >> 12) & 0xf;
2100
rd0 = (insn >> 16) & 0xf;
2101
gen_op_iwmmxt_movq_M0_wRn(rd0);
2102
tmp = tcg_temp_new_i32();
2103
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2104
tcg_temp_free_i32(tmp);
2107
switch ((insn >> 22) & 3) {
2109
gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2112
gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2115
gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2118
tcg_temp_free_i32(tmp);
2119
gen_op_iwmmxt_movq_wRn_M0(wrd);
2120
gen_op_iwmmxt_set_mup();
2121
gen_op_iwmmxt_set_cup();
2123
case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2124
case 0x014: case 0x414: case 0x814: case 0xc14:
2125
if (((insn >> 22) & 3) == 0)
2127
wrd = (insn >> 12) & 0xf;
2128
rd0 = (insn >> 16) & 0xf;
2129
gen_op_iwmmxt_movq_M0_wRn(rd0);
2130
tmp = tcg_temp_new_i32();
2131
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2132
tcg_temp_free_i32(tmp);
2135
switch ((insn >> 22) & 3) {
2137
gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2140
gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2143
gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2146
tcg_temp_free_i32(tmp);
2147
gen_op_iwmmxt_movq_wRn_M0(wrd);
2148
gen_op_iwmmxt_set_mup();
2149
gen_op_iwmmxt_set_cup();
2151
case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2152
case 0x114: case 0x514: case 0x914: case 0xd14:
2153
if (((insn >> 22) & 3) == 0)
2155
wrd = (insn >> 12) & 0xf;
2156
rd0 = (insn >> 16) & 0xf;
2157
gen_op_iwmmxt_movq_M0_wRn(rd0);
2158
tmp = tcg_temp_new_i32();
2159
if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2160
tcg_temp_free_i32(tmp);
2163
switch ((insn >> 22) & 3) {
2165
gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2168
gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2171
gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2174
tcg_temp_free_i32(tmp);
2175
gen_op_iwmmxt_movq_wRn_M0(wrd);
2176
gen_op_iwmmxt_set_mup();
2177
gen_op_iwmmxt_set_cup();
2179
case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2180
case 0x314: case 0x714: case 0xb14: case 0xf14:
2181
if (((insn >> 22) & 3) == 0)
2183
wrd = (insn >> 12) & 0xf;
2184
rd0 = (insn >> 16) & 0xf;
2185
gen_op_iwmmxt_movq_M0_wRn(rd0);
2186
tmp = tcg_temp_new_i32();
2187
switch ((insn >> 22) & 3) {
2189
if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2190
tcg_temp_free_i32(tmp);
2193
gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2196
if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2197
tcg_temp_free_i32(tmp);
2200
gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2203
if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2204
tcg_temp_free_i32(tmp);
2207
gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2210
tcg_temp_free_i32(tmp);
2211
gen_op_iwmmxt_movq_wRn_M0(wrd);
2212
gen_op_iwmmxt_set_mup();
2213
gen_op_iwmmxt_set_cup();
2215
case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2216
case 0x916: case 0xb16: case 0xd16: case 0xf16:
2217
wrd = (insn >> 12) & 0xf;
2218
rd0 = (insn >> 16) & 0xf;
2219
rd1 = (insn >> 0) & 0xf;
2220
gen_op_iwmmxt_movq_M0_wRn(rd0);
2221
switch ((insn >> 22) & 3) {
2223
if (insn & (1 << 21))
2224
gen_op_iwmmxt_minsb_M0_wRn(rd1);
2226
gen_op_iwmmxt_minub_M0_wRn(rd1);
2229
if (insn & (1 << 21))
2230
gen_op_iwmmxt_minsw_M0_wRn(rd1);
2232
gen_op_iwmmxt_minuw_M0_wRn(rd1);
2235
if (insn & (1 << 21))
2236
gen_op_iwmmxt_minsl_M0_wRn(rd1);
2238
gen_op_iwmmxt_minul_M0_wRn(rd1);
2243
gen_op_iwmmxt_movq_wRn_M0(wrd);
2244
gen_op_iwmmxt_set_mup();
2246
case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2247
case 0x816: case 0xa16: case 0xc16: case 0xe16:
2248
wrd = (insn >> 12) & 0xf;
2249
rd0 = (insn >> 16) & 0xf;
2250
rd1 = (insn >> 0) & 0xf;
2251
gen_op_iwmmxt_movq_M0_wRn(rd0);
2252
switch ((insn >> 22) & 3) {
2254
if (insn & (1 << 21))
2255
gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2257
gen_op_iwmmxt_maxub_M0_wRn(rd1);
2260
if (insn & (1 << 21))
2261
gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2263
gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2266
if (insn & (1 << 21))
2267
gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2269
gen_op_iwmmxt_maxul_M0_wRn(rd1);
2274
gen_op_iwmmxt_movq_wRn_M0(wrd);
2275
gen_op_iwmmxt_set_mup();
2277
case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2278
case 0x402: case 0x502: case 0x602: case 0x702:
2279
wrd = (insn >> 12) & 0xf;
2280
rd0 = (insn >> 16) & 0xf;
2281
rd1 = (insn >> 0) & 0xf;
2282
gen_op_iwmmxt_movq_M0_wRn(rd0);
2283
tmp = tcg_const_i32((insn >> 20) & 3);
2284
iwmmxt_load_reg(cpu_V1, rd1);
2285
gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2286
tcg_temp_free_i32(tmp);
2287
gen_op_iwmmxt_movq_wRn_M0(wrd);
2288
gen_op_iwmmxt_set_mup();
2290
case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2291
case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2292
case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2293
case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2294
wrd = (insn >> 12) & 0xf;
2295
rd0 = (insn >> 16) & 0xf;
2296
rd1 = (insn >> 0) & 0xf;
2297
gen_op_iwmmxt_movq_M0_wRn(rd0);
2298
switch ((insn >> 20) & 0xf) {
2300
gen_op_iwmmxt_subnb_M0_wRn(rd1);
2303
gen_op_iwmmxt_subub_M0_wRn(rd1);
2306
gen_op_iwmmxt_subsb_M0_wRn(rd1);
2309
gen_op_iwmmxt_subnw_M0_wRn(rd1);
2312
gen_op_iwmmxt_subuw_M0_wRn(rd1);
2315
gen_op_iwmmxt_subsw_M0_wRn(rd1);
2318
gen_op_iwmmxt_subnl_M0_wRn(rd1);
2321
gen_op_iwmmxt_subul_M0_wRn(rd1);
2324
gen_op_iwmmxt_subsl_M0_wRn(rd1);
2329
gen_op_iwmmxt_movq_wRn_M0(wrd);
2330
gen_op_iwmmxt_set_mup();
2331
gen_op_iwmmxt_set_cup();
2333
case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2334
case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2335
case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2336
case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2337
wrd = (insn >> 12) & 0xf;
2338
rd0 = (insn >> 16) & 0xf;
2339
gen_op_iwmmxt_movq_M0_wRn(rd0);
2340
tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2341
gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2342
tcg_temp_free_i32(tmp);
2343
gen_op_iwmmxt_movq_wRn_M0(wrd);
2344
gen_op_iwmmxt_set_mup();
2345
gen_op_iwmmxt_set_cup();
2347
case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2348
case 0x418: case 0x518: case 0x618: case 0x718:
2349
case 0x818: case 0x918: case 0xa18: case 0xb18:
2350
case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2351
wrd = (insn >> 12) & 0xf;
2352
rd0 = (insn >> 16) & 0xf;
2353
rd1 = (insn >> 0) & 0xf;
2354
gen_op_iwmmxt_movq_M0_wRn(rd0);
2355
switch ((insn >> 20) & 0xf) {
2357
gen_op_iwmmxt_addnb_M0_wRn(rd1);
2360
gen_op_iwmmxt_addub_M0_wRn(rd1);
2363
gen_op_iwmmxt_addsb_M0_wRn(rd1);
2366
gen_op_iwmmxt_addnw_M0_wRn(rd1);
2369
gen_op_iwmmxt_adduw_M0_wRn(rd1);
2372
gen_op_iwmmxt_addsw_M0_wRn(rd1);
2375
gen_op_iwmmxt_addnl_M0_wRn(rd1);
2378
gen_op_iwmmxt_addul_M0_wRn(rd1);
2381
gen_op_iwmmxt_addsl_M0_wRn(rd1);
2386
gen_op_iwmmxt_movq_wRn_M0(wrd);
2387
gen_op_iwmmxt_set_mup();
2388
gen_op_iwmmxt_set_cup();
2390
case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2391
case 0x408: case 0x508: case 0x608: case 0x708:
2392
case 0x808: case 0x908: case 0xa08: case 0xb08:
2393
case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2394
if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2396
wrd = (insn >> 12) & 0xf;
2397
rd0 = (insn >> 16) & 0xf;
2398
rd1 = (insn >> 0) & 0xf;
2399
gen_op_iwmmxt_movq_M0_wRn(rd0);
2400
switch ((insn >> 22) & 3) {
2402
if (insn & (1 << 21))
2403
gen_op_iwmmxt_packsw_M0_wRn(rd1);
2405
gen_op_iwmmxt_packuw_M0_wRn(rd1);
2408
if (insn & (1 << 21))
2409
gen_op_iwmmxt_packsl_M0_wRn(rd1);
2411
gen_op_iwmmxt_packul_M0_wRn(rd1);
2414
if (insn & (1 << 21))
2415
gen_op_iwmmxt_packsq_M0_wRn(rd1);
2417
gen_op_iwmmxt_packuq_M0_wRn(rd1);
2420
gen_op_iwmmxt_movq_wRn_M0(wrd);
2421
gen_op_iwmmxt_set_mup();
2422
gen_op_iwmmxt_set_cup();
2424
case 0x201: case 0x203: case 0x205: case 0x207:
2425
case 0x209: case 0x20b: case 0x20d: case 0x20f:
2426
case 0x211: case 0x213: case 0x215: case 0x217:
2427
case 0x219: case 0x21b: case 0x21d: case 0x21f:
2428
wrd = (insn >> 5) & 0xf;
2429
rd0 = (insn >> 12) & 0xf;
2430
rd1 = (insn >> 0) & 0xf;
2431
if (rd0 == 0xf || rd1 == 0xf)
2433
gen_op_iwmmxt_movq_M0_wRn(wrd);
2434
tmp = load_reg(s, rd0);
2435
tmp2 = load_reg(s, rd1);
2436
switch ((insn >> 16) & 0xf) {
2437
case 0x0: /* TMIA */
2438
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2440
case 0x8: /* TMIAPH */
2441
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2443
case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2444
if (insn & (1 << 16))
2445
tcg_gen_shri_i32(tmp, tmp, 16);
2446
if (insn & (1 << 17))
2447
tcg_gen_shri_i32(tmp2, tmp2, 16);
2448
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2451
tcg_temp_free_i32(tmp2);
2452
tcg_temp_free_i32(tmp);
2455
tcg_temp_free_i32(tmp2);
2456
tcg_temp_free_i32(tmp);
2457
gen_op_iwmmxt_movq_wRn_M0(wrd);
2458
gen_op_iwmmxt_set_mup();
2467
/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2468
(ie. an undefined instruction). */
2469
static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2471
int acc, rd0, rd1, rdhi, rdlo;
2474
if ((insn & 0x0ff00f10) == 0x0e200010) {
2475
/* Multiply with Internal Accumulate Format */
2476
rd0 = (insn >> 12) & 0xf;
2478
acc = (insn >> 5) & 7;
2483
tmp = load_reg(s, rd0);
2484
tmp2 = load_reg(s, rd1);
2485
switch ((insn >> 16) & 0xf) {
2487
gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2489
case 0x8: /* MIAPH */
2490
gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2492
case 0xc: /* MIABB */
2493
case 0xd: /* MIABT */
2494
case 0xe: /* MIATB */
2495
case 0xf: /* MIATT */
2496
if (insn & (1 << 16))
2497
tcg_gen_shri_i32(tmp, tmp, 16);
2498
if (insn & (1 << 17))
2499
tcg_gen_shri_i32(tmp2, tmp2, 16);
2500
gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2505
tcg_temp_free_i32(tmp2);
2506
tcg_temp_free_i32(tmp);
2508
gen_op_iwmmxt_movq_wRn_M0(acc);
2512
if ((insn & 0x0fe00ff8) == 0x0c400000) {
2513
/* Internal Accumulator Access Format */
2514
rdhi = (insn >> 16) & 0xf;
2515
rdlo = (insn >> 12) & 0xf;
2521
if (insn & ARM_CP_RW_BIT) { /* MRA */
2522
iwmmxt_load_reg(cpu_V0, acc);
2523
tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2524
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2525
tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2526
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2528
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2529
iwmmxt_store_reg(cpu_V0, acc);
2537
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2538
#define VFP_SREG(insn, bigbit, smallbit) \
2539
((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2540
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2541
if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2542
reg = (((insn) >> (bigbit)) & 0x0f) \
2543
| (((insn) >> ((smallbit) - 4)) & 0x10); \
2545
if (insn & (1 << (smallbit))) \
2547
reg = ((insn) >> (bigbit)) & 0x0f; \
2550
#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2551
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2552
#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2553
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2554
#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2555
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2557
/* Move between integer and VFP cores. */
2558
static TCGv_i32 gen_vfp_mrs(void)
2560
TCGv_i32 tmp = tcg_temp_new_i32();
2561
tcg_gen_mov_i32(tmp, cpu_F0s);
2565
static void gen_vfp_msr(TCGv_i32 tmp)
2567
tcg_gen_mov_i32(cpu_F0s, tmp);
2568
tcg_temp_free_i32(tmp);
2571
static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2573
TCGv_i32 tmp = tcg_temp_new_i32();
2575
tcg_gen_shri_i32(var, var, shift);
2576
tcg_gen_ext8u_i32(var, var);
2577
tcg_gen_shli_i32(tmp, var, 8);
2578
tcg_gen_or_i32(var, var, tmp);
2579
tcg_gen_shli_i32(tmp, var, 16);
2580
tcg_gen_or_i32(var, var, tmp);
2581
tcg_temp_free_i32(tmp);
2584
static void gen_neon_dup_low16(TCGv_i32 var)
2586
TCGv_i32 tmp = tcg_temp_new_i32();
2587
tcg_gen_ext16u_i32(var, var);
2588
tcg_gen_shli_i32(tmp, var, 16);
2589
tcg_gen_or_i32(var, var, tmp);
2590
tcg_temp_free_i32(tmp);
2593
static void gen_neon_dup_high16(TCGv_i32 var)
2595
TCGv_i32 tmp = tcg_temp_new_i32();
2596
tcg_gen_andi_i32(var, var, 0xffff0000);
2597
tcg_gen_shri_i32(tmp, var, 16);
2598
tcg_gen_or_i32(var, var, tmp);
2599
tcg_temp_free_i32(tmp);
2602
static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2604
/* Load a single Neon element and replicate into a 32 bit TCG reg */
2605
TCGv_i32 tmp = tcg_temp_new_i32();
2608
gen_aa32_ld8u(tmp, addr, IS_USER(s));
2609
gen_neon_dup_u8(tmp, 0);
2612
gen_aa32_ld16u(tmp, addr, IS_USER(s));
2613
gen_neon_dup_low16(tmp);
2616
gen_aa32_ld32u(tmp, addr, IS_USER(s));
2618
default: /* Avoid compiler warnings. */
2624
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2625
(ie. an undefined instruction). */
2626
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2628
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2634
if (!arm_feature(env, ARM_FEATURE_VFP))
2637
if (!s->vfp_enabled) {
2638
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2639
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2641
rn = (insn >> 16) & 0xf;
2642
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2643
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2646
dp = ((insn & 0xf00) == 0xb00);
2647
switch ((insn >> 24) & 0xf) {
2649
if (insn & (1 << 4)) {
2650
/* single register transfer */
2651
rd = (insn >> 12) & 0xf;
2656
VFP_DREG_N(rn, insn);
2659
if (insn & 0x00c00060
2660
&& !arm_feature(env, ARM_FEATURE_NEON))
2663
pass = (insn >> 21) & 1;
2664
if (insn & (1 << 22)) {
2666
offset = ((insn >> 5) & 3) * 8;
2667
} else if (insn & (1 << 5)) {
2669
offset = (insn & (1 << 6)) ? 16 : 0;
2674
if (insn & ARM_CP_RW_BIT) {
2676
tmp = neon_load_reg(rn, pass);
2680
tcg_gen_shri_i32(tmp, tmp, offset);
2681
if (insn & (1 << 23))
2687
if (insn & (1 << 23)) {
2689
tcg_gen_shri_i32(tmp, tmp, 16);
2695
tcg_gen_sari_i32(tmp, tmp, 16);
2704
store_reg(s, rd, tmp);
2707
tmp = load_reg(s, rd);
2708
if (insn & (1 << 23)) {
2711
gen_neon_dup_u8(tmp, 0);
2712
} else if (size == 1) {
2713
gen_neon_dup_low16(tmp);
2715
for (n = 0; n <= pass * 2; n++) {
2716
tmp2 = tcg_temp_new_i32();
2717
tcg_gen_mov_i32(tmp2, tmp);
2718
neon_store_reg(rn, n, tmp2);
2720
neon_store_reg(rn, n, tmp);
2725
tmp2 = neon_load_reg(rn, pass);
2726
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2727
tcg_temp_free_i32(tmp2);
2730
tmp2 = neon_load_reg(rn, pass);
2731
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2732
tcg_temp_free_i32(tmp2);
2737
neon_store_reg(rn, pass, tmp);
2741
if ((insn & 0x6f) != 0x00)
2743
rn = VFP_SREG_N(insn);
2744
if (insn & ARM_CP_RW_BIT) {
2746
if (insn & (1 << 21)) {
2747
/* system register */
2752
/* VFP2 allows access to FSID from userspace.
2753
VFP3 restricts all id registers to privileged
2756
&& arm_feature(env, ARM_FEATURE_VFP3))
2758
tmp = load_cpu_field(vfp.xregs[rn]);
2763
tmp = load_cpu_field(vfp.xregs[rn]);
2765
case ARM_VFP_FPINST:
2766
case ARM_VFP_FPINST2:
2767
/* Not present in VFP3. */
2769
|| arm_feature(env, ARM_FEATURE_VFP3))
2771
tmp = load_cpu_field(vfp.xregs[rn]);
2775
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2776
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2778
tmp = tcg_temp_new_i32();
2779
gen_helper_vfp_get_fpscr(tmp, cpu_env);
2785
|| !arm_feature(env, ARM_FEATURE_MVFR))
2787
tmp = load_cpu_field(vfp.xregs[rn]);
2793
gen_mov_F0_vreg(0, rn);
2794
tmp = gen_vfp_mrs();
2797
/* Set the 4 flag bits in the CPSR. */
2799
tcg_temp_free_i32(tmp);
2801
store_reg(s, rd, tmp);
2805
if (insn & (1 << 21)) {
2807
/* system register */
2812
/* Writes are ignored. */
2815
tmp = load_reg(s, rd);
2816
gen_helper_vfp_set_fpscr(cpu_env, tmp);
2817
tcg_temp_free_i32(tmp);
2823
/* TODO: VFP subarchitecture support.
2824
* For now, keep the EN bit only */
2825
tmp = load_reg(s, rd);
2826
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2827
store_cpu_field(tmp, vfp.xregs[rn]);
2830
case ARM_VFP_FPINST:
2831
case ARM_VFP_FPINST2:
2832
tmp = load_reg(s, rd);
2833
store_cpu_field(tmp, vfp.xregs[rn]);
2839
tmp = load_reg(s, rd);
2841
gen_mov_vreg_F0(0, rn);
2846
/* data processing */
2847
/* The opcode is in bits 23, 21, 20 and 6. */
2848
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2852
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2854
/* rn is register number */
2855
VFP_DREG_N(rn, insn);
2858
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2859
/* Integer or single precision destination. */
2860
rd = VFP_SREG_D(insn);
2862
VFP_DREG_D(rd, insn);
2865
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2866
/* VCVT from int is always from S reg regardless of dp bit.
2867
* VCVT with immediate frac_bits has same format as SREG_M
2869
rm = VFP_SREG_M(insn);
2871
VFP_DREG_M(rm, insn);
2874
rn = VFP_SREG_N(insn);
2875
if (op == 15 && rn == 15) {
2876
/* Double precision destination. */
2877
VFP_DREG_D(rd, insn);
2879
rd = VFP_SREG_D(insn);
2881
/* NB that we implicitly rely on the encoding for the frac_bits
2882
* in VCVT of fixed to float being the same as that of an SREG_M
2884
rm = VFP_SREG_M(insn);
2887
veclen = s->vec_len;
2888
if (op == 15 && rn > 3)
2891
/* Shut up compiler warnings. */
2902
/* Figure out what type of vector operation this is. */
2903
if ((rd & bank_mask) == 0) {
2908
delta_d = (s->vec_stride >> 1) + 1;
2910
delta_d = s->vec_stride + 1;
2912
if ((rm & bank_mask) == 0) {
2913
/* mixed scalar/vector */
2922
/* Load the initial operands. */
2927
/* Integer source */
2928
gen_mov_F0_vreg(0, rm);
2933
gen_mov_F0_vreg(dp, rd);
2934
gen_mov_F1_vreg(dp, rm);
2938
/* Compare with zero */
2939
gen_mov_F0_vreg(dp, rd);
2950
/* Source and destination the same. */
2951
gen_mov_F0_vreg(dp, rd);
2957
/* VCVTB, VCVTT: only present with the halfprec extension,
2958
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2960
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
2963
/* Otherwise fall through */
2965
/* One source operand. */
2966
gen_mov_F0_vreg(dp, rm);
2970
/* Two source operands. */
2971
gen_mov_F0_vreg(dp, rn);
2972
gen_mov_F1_vreg(dp, rm);
2976
/* Perform the calculation. */
2978
case 0: /* VMLA: fd + (fn * fm) */
2979
/* Note that order of inputs to the add matters for NaNs */
2981
gen_mov_F0_vreg(dp, rd);
2984
case 1: /* VMLS: fd + -(fn * fm) */
2987
gen_mov_F0_vreg(dp, rd);
2990
case 2: /* VNMLS: -fd + (fn * fm) */
2991
/* Note that it isn't valid to replace (-A + B) with (B - A)
2992
* or similar plausible looking simplifications
2993
* because this will give wrong results for NaNs.
2996
gen_mov_F0_vreg(dp, rd);
3000
case 3: /* VNMLA: -fd + -(fn * fm) */
3003
gen_mov_F0_vreg(dp, rd);
3007
case 4: /* mul: fn * fm */
3010
case 5: /* nmul: -(fn * fm) */
3014
case 6: /* add: fn + fm */
3017
case 7: /* sub: fn - fm */
3020
case 8: /* div: fn / fm */
3023
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3024
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3025
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3026
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3027
/* These are fused multiply-add, and must be done as one
3028
* floating point operation with no rounding between the
3029
* multiplication and addition steps.
3030
* NB that doing the negations here as separate steps is
3031
* correct : an input NaN should come out with its sign bit
3032
* flipped if it is a negated-input.
3034
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3042
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3044
frd = tcg_temp_new_i64();
3045
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3048
gen_helper_vfp_negd(frd, frd);
3050
fpst = get_fpstatus_ptr(0);
3051
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3052
cpu_F1d, frd, fpst);
3053
tcg_temp_free_ptr(fpst);
3054
tcg_temp_free_i64(frd);
3060
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3062
frd = tcg_temp_new_i32();
3063
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3065
gen_helper_vfp_negs(frd, frd);
3067
fpst = get_fpstatus_ptr(0);
3068
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3069
cpu_F1s, frd, fpst);
3070
tcg_temp_free_ptr(fpst);
3071
tcg_temp_free_i32(frd);
3074
case 14: /* fconst */
3075
if (!arm_feature(env, ARM_FEATURE_VFP3))
3078
n = (insn << 12) & 0x80000000;
3079
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3086
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3093
tcg_gen_movi_i32(cpu_F0s, n);
3096
case 15: /* extension space */
3110
case 4: /* vcvtb.f32.f16 */
3111
tmp = gen_vfp_mrs();
3112
tcg_gen_ext16u_i32(tmp, tmp);
3113
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3114
tcg_temp_free_i32(tmp);
3116
case 5: /* vcvtt.f32.f16 */
3117
tmp = gen_vfp_mrs();
3118
tcg_gen_shri_i32(tmp, tmp, 16);
3119
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3120
tcg_temp_free_i32(tmp);
3122
case 6: /* vcvtb.f16.f32 */
3123
tmp = tcg_temp_new_i32();
3124
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3125
gen_mov_F0_vreg(0, rd);
3126
tmp2 = gen_vfp_mrs();
3127
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3128
tcg_gen_or_i32(tmp, tmp, tmp2);
3129
tcg_temp_free_i32(tmp2);
3132
case 7: /* vcvtt.f16.f32 */
3133
tmp = tcg_temp_new_i32();
3134
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3135
tcg_gen_shli_i32(tmp, tmp, 16);
3136
gen_mov_F0_vreg(0, rd);
3137
tmp2 = gen_vfp_mrs();
3138
tcg_gen_ext16u_i32(tmp2, tmp2);
3139
tcg_gen_or_i32(tmp, tmp, tmp2);
3140
tcg_temp_free_i32(tmp2);
3152
case 11: /* cmpez */
3156
case 15: /* single<->double conversion */
3158
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3160
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3162
case 16: /* fuito */
3163
gen_vfp_uito(dp, 0);
3165
case 17: /* fsito */
3166
gen_vfp_sito(dp, 0);
3168
case 20: /* fshto */
3169
if (!arm_feature(env, ARM_FEATURE_VFP3))
3171
gen_vfp_shto(dp, 16 - rm, 0);
3173
case 21: /* fslto */
3174
if (!arm_feature(env, ARM_FEATURE_VFP3))
3176
gen_vfp_slto(dp, 32 - rm, 0);
3178
case 22: /* fuhto */
3179
if (!arm_feature(env, ARM_FEATURE_VFP3))
3181
gen_vfp_uhto(dp, 16 - rm, 0);
3183
case 23: /* fulto */
3184
if (!arm_feature(env, ARM_FEATURE_VFP3))
3186
gen_vfp_ulto(dp, 32 - rm, 0);
3188
case 24: /* ftoui */
3189
gen_vfp_toui(dp, 0);
3191
case 25: /* ftouiz */
3192
gen_vfp_touiz(dp, 0);
3194
case 26: /* ftosi */
3195
gen_vfp_tosi(dp, 0);
3197
case 27: /* ftosiz */
3198
gen_vfp_tosiz(dp, 0);
3200
case 28: /* ftosh */
3201
if (!arm_feature(env, ARM_FEATURE_VFP3))
3203
gen_vfp_tosh(dp, 16 - rm, 0);
3205
case 29: /* ftosl */
3206
if (!arm_feature(env, ARM_FEATURE_VFP3))
3208
gen_vfp_tosl(dp, 32 - rm, 0);
3210
case 30: /* ftouh */
3211
if (!arm_feature(env, ARM_FEATURE_VFP3))
3213
gen_vfp_touh(dp, 16 - rm, 0);
3215
case 31: /* ftoul */
3216
if (!arm_feature(env, ARM_FEATURE_VFP3))
3218
gen_vfp_toul(dp, 32 - rm, 0);
3220
default: /* undefined */
3224
default: /* undefined */
3228
/* Write back the result. */
3229
if (op == 15 && (rn >= 8 && rn <= 11))
3230
; /* Comparison, do nothing. */
3231
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3232
/* VCVT double to int: always integer result. */
3233
gen_mov_vreg_F0(0, rd);
3234
else if (op == 15 && rn == 15)
3236
gen_mov_vreg_F0(!dp, rd);
3238
gen_mov_vreg_F0(dp, rd);
3240
/* break out of the loop if we have finished */
3244
if (op == 15 && delta_m == 0) {
3245
/* single source one-many */
3247
rd = ((rd + delta_d) & (bank_mask - 1))
3249
gen_mov_vreg_F0(dp, rd);
3253
/* Setup the next operands. */
3255
rd = ((rd + delta_d) & (bank_mask - 1))
3259
/* One source operand. */
3260
rm = ((rm + delta_m) & (bank_mask - 1))
3262
gen_mov_F0_vreg(dp, rm);
3264
/* Two source operands. */
3265
rn = ((rn + delta_d) & (bank_mask - 1))
3267
gen_mov_F0_vreg(dp, rn);
3269
rm = ((rm + delta_m) & (bank_mask - 1))
3271
gen_mov_F1_vreg(dp, rm);
3279
if ((insn & 0x03e00000) == 0x00400000) {
3280
/* two-register transfer */
3281
rn = (insn >> 16) & 0xf;
3282
rd = (insn >> 12) & 0xf;
3284
VFP_DREG_M(rm, insn);
3286
rm = VFP_SREG_M(insn);
3289
if (insn & ARM_CP_RW_BIT) {
3292
gen_mov_F0_vreg(0, rm * 2);
3293
tmp = gen_vfp_mrs();
3294
store_reg(s, rd, tmp);
3295
gen_mov_F0_vreg(0, rm * 2 + 1);
3296
tmp = gen_vfp_mrs();
3297
store_reg(s, rn, tmp);
3299
gen_mov_F0_vreg(0, rm);
3300
tmp = gen_vfp_mrs();
3301
store_reg(s, rd, tmp);
3302
gen_mov_F0_vreg(0, rm + 1);
3303
tmp = gen_vfp_mrs();
3304
store_reg(s, rn, tmp);
3309
tmp = load_reg(s, rd);
3311
gen_mov_vreg_F0(0, rm * 2);
3312
tmp = load_reg(s, rn);
3314
gen_mov_vreg_F0(0, rm * 2 + 1);
3316
tmp = load_reg(s, rd);
3318
gen_mov_vreg_F0(0, rm);
3319
tmp = load_reg(s, rn);
3321
gen_mov_vreg_F0(0, rm + 1);
3326
rn = (insn >> 16) & 0xf;
3328
VFP_DREG_D(rd, insn);
3330
rd = VFP_SREG_D(insn);
3331
if ((insn & 0x01200000) == 0x01000000) {
3332
/* Single load/store */
3333
offset = (insn & 0xff) << 2;
3334
if ((insn & (1 << 23)) == 0)
3336
if (s->thumb && rn == 15) {
3337
/* This is actually UNPREDICTABLE */
3338
addr = tcg_temp_new_i32();
3339
tcg_gen_movi_i32(addr, s->pc & ~2);
3341
addr = load_reg(s, rn);
3343
tcg_gen_addi_i32(addr, addr, offset);
3344
if (insn & (1 << 20)) {
3345
gen_vfp_ld(s, dp, addr);
3346
gen_mov_vreg_F0(dp, rd);
3348
gen_mov_F0_vreg(dp, rd);
3349
gen_vfp_st(s, dp, addr);
3351
tcg_temp_free_i32(addr);
3353
/* load/store multiple */
3354
int w = insn & (1 << 21);
3356
n = (insn >> 1) & 0x7f;
3360
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3361
/* P == U , W == 1 => UNDEF */
3364
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3365
/* UNPREDICTABLE cases for bad immediates: we choose to
3366
* UNDEF to avoid generating huge numbers of TCG ops
3370
if (rn == 15 && w) {
3371
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3375
if (s->thumb && rn == 15) {
3376
/* This is actually UNPREDICTABLE */
3377
addr = tcg_temp_new_i32();
3378
tcg_gen_movi_i32(addr, s->pc & ~2);
3380
addr = load_reg(s, rn);
3382
if (insn & (1 << 24)) /* pre-decrement */
3383
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3389
for (i = 0; i < n; i++) {
3390
if (insn & ARM_CP_RW_BIT) {
3392
gen_vfp_ld(s, dp, addr);
3393
gen_mov_vreg_F0(dp, rd + i);
3396
gen_mov_F0_vreg(dp, rd + i);
3397
gen_vfp_st(s, dp, addr);
3399
tcg_gen_addi_i32(addr, addr, offset);
3403
if (insn & (1 << 24))
3404
offset = -offset * n;
3405
else if (dp && (insn & 1))
3411
tcg_gen_addi_i32(addr, addr, offset);
3412
store_reg(s, rn, addr);
3414
tcg_temp_free_i32(addr);
3420
/* Should never happen. */
3426
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3428
TranslationBlock *tb;
3431
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3433
gen_set_pc_im(s, dest);
3434
tcg_gen_exit_tb((uintptr_t)tb + n);
3436
gen_set_pc_im(s, dest);
3441
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3443
if (unlikely(s->singlestep_enabled)) {
3444
/* An indirect jump so that we still trigger the debug exception. */
3449
gen_goto_tb(s, 0, dest);
3450
s->is_jmp = DISAS_TB_JUMP;
3454
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3457
tcg_gen_sari_i32(t0, t0, 16);
3461
tcg_gen_sari_i32(t1, t1, 16);
3464
tcg_gen_mul_i32(t0, t0, t1);
3467
/* Return the mask of PSR bits set by a MSR instruction. */
3468
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3472
if (flags & (1 << 0))
3474
if (flags & (1 << 1))
3476
if (flags & (1 << 2))
3478
if (flags & (1 << 3))
3481
/* Mask out undefined bits. */
3482
mask &= ~CPSR_RESERVED;
3483
if (!arm_feature(env, ARM_FEATURE_V4T))
3485
if (!arm_feature(env, ARM_FEATURE_V5))
3486
mask &= ~CPSR_Q; /* V5TE in reality*/
3487
if (!arm_feature(env, ARM_FEATURE_V6))
3488
mask &= ~(CPSR_E | CPSR_GE);
3489
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3491
/* Mask out execution state bits. */
3494
/* Mask out privileged bits. */
3500
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3501
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3505
/* ??? This is also undefined in system mode. */
3509
tmp = load_cpu_field(spsr);
3510
tcg_gen_andi_i32(tmp, tmp, ~mask);
3511
tcg_gen_andi_i32(t0, t0, mask);
3512
tcg_gen_or_i32(tmp, tmp, t0);
3513
store_cpu_field(tmp, spsr);
3515
gen_set_cpsr(t0, mask);
3517
tcg_temp_free_i32(t0);
3522
/* Returns nonzero if access to the PSR is not permitted. */
3523
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3526
tmp = tcg_temp_new_i32();
3527
tcg_gen_movi_i32(tmp, val);
3528
return gen_set_psr(s, mask, spsr, tmp);
3531
/* Generate an old-style exception return. Marks pc as dead. */
3532
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3535
store_reg(s, 15, pc);
3536
tmp = load_cpu_field(spsr);
3537
gen_set_cpsr(tmp, 0xffffffff);
3538
tcg_temp_free_i32(tmp);
3539
s->is_jmp = DISAS_UPDATE;
3542
/* Generate a v6 exception return. Marks both values as dead. */
3543
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3545
gen_set_cpsr(cpsr, 0xffffffff);
3546
tcg_temp_free_i32(cpsr);
3547
store_reg(s, 15, pc);
3548
s->is_jmp = DISAS_UPDATE;
3552
gen_set_condexec (DisasContext *s)
3554
if (s->condexec_mask) {
3555
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3556
TCGv_i32 tmp = tcg_temp_new_i32();
3557
tcg_gen_movi_i32(tmp, val);
3558
store_cpu_field(tmp, condexec_bits);
3562
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3564
gen_set_condexec(s);
3565
gen_set_pc_im(s, s->pc - offset);
3566
gen_exception(excp);
3567
s->is_jmp = DISAS_JUMP;
3570
static void gen_nop_hint(DisasContext *s, int val)
3574
gen_set_pc_im(s, s->pc);
3575
s->is_jmp = DISAS_WFI;
3580
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3586
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3588
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3591
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3592
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3593
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3598
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3601
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3602
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3603
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3608
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3609
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3610
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3611
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3612
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3614
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3615
switch ((size << 1) | u) { \
3617
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3620
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3623
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3626
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3629
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3632
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3634
default: return 1; \
3637
#define GEN_NEON_INTEGER_OP(name) do { \
3638
switch ((size << 1) | u) { \
3640
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3643
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3646
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3649
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3652
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3655
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3657
default: return 1; \
3660
static TCGv_i32 neon_load_scratch(int scratch)
3662
TCGv_i32 tmp = tcg_temp_new_i32();
3663
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3667
static void neon_store_scratch(int scratch, TCGv_i32 var)
3669
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3670
tcg_temp_free_i32(var);
3673
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3677
tmp = neon_load_reg(reg & 7, reg >> 4);
3679
gen_neon_dup_high16(tmp);
3681
gen_neon_dup_low16(tmp);
3684
tmp = neon_load_reg(reg & 15, reg >> 4);
3689
static int gen_neon_unzip(int rd, int rm, int size, int q)
3692
if (!q && size == 2) {
3695
tmp = tcg_const_i32(rd);
3696
tmp2 = tcg_const_i32(rm);
3700
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3703
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3706
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3714
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3717
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3723
tcg_temp_free_i32(tmp);
3724
tcg_temp_free_i32(tmp2);
3728
static int gen_neon_zip(int rd, int rm, int size, int q)
3731
if (!q && size == 2) {
3734
tmp = tcg_const_i32(rd);
3735
tmp2 = tcg_const_i32(rm);
3739
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3742
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3745
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3753
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3756
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3762
tcg_temp_free_i32(tmp);
3763
tcg_temp_free_i32(tmp2);
3767
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3771
rd = tcg_temp_new_i32();
3772
tmp = tcg_temp_new_i32();
3774
tcg_gen_shli_i32(rd, t0, 8);
3775
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3776
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3777
tcg_gen_or_i32(rd, rd, tmp);
3779
tcg_gen_shri_i32(t1, t1, 8);
3780
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3781
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3782
tcg_gen_or_i32(t1, t1, tmp);
3783
tcg_gen_mov_i32(t0, rd);
3785
tcg_temp_free_i32(tmp);
3786
tcg_temp_free_i32(rd);
3789
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3793
rd = tcg_temp_new_i32();
3794
tmp = tcg_temp_new_i32();
3796
tcg_gen_shli_i32(rd, t0, 16);
3797
tcg_gen_andi_i32(tmp, t1, 0xffff);
3798
tcg_gen_or_i32(rd, rd, tmp);
3799
tcg_gen_shri_i32(t1, t1, 16);
3800
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3801
tcg_gen_or_i32(t1, t1, tmp);
3802
tcg_gen_mov_i32(t0, rd);
3804
tcg_temp_free_i32(tmp);
3805
tcg_temp_free_i32(rd);
3813
} neon_ls_element_type[11] = {
3827
/* Translate a NEON load/store element instruction. Return nonzero if the
3828
instruction is invalid. */
3829
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
3848
if (!s->vfp_enabled)
3850
VFP_DREG_D(rd, insn);
3851
rn = (insn >> 16) & 0xf;
3853
load = (insn & (1 << 21)) != 0;
3854
if ((insn & (1 << 23)) == 0) {
3855
/* Load store all elements. */
3856
op = (insn >> 8) & 0xf;
3857
size = (insn >> 6) & 3;
3860
/* Catch UNDEF cases for bad values of align field */
3863
if (((insn >> 5) & 1) == 1) {
3868
if (((insn >> 4) & 3) == 3) {
3875
nregs = neon_ls_element_type[op].nregs;
3876
interleave = neon_ls_element_type[op].interleave;
3877
spacing = neon_ls_element_type[op].spacing;
3878
if (size == 3 && (interleave | spacing) != 1)
3880
addr = tcg_temp_new_i32();
3881
load_reg_var(s, addr, rn);
3882
stride = (1 << size) * interleave;
3883
for (reg = 0; reg < nregs; reg++) {
3884
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3885
load_reg_var(s, addr, rn);
3886
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3887
} else if (interleave == 2 && nregs == 4 && reg == 2) {
3888
load_reg_var(s, addr, rn);
3889
tcg_gen_addi_i32(addr, addr, 1 << size);
3892
tmp64 = tcg_temp_new_i64();
3894
gen_aa32_ld64(tmp64, addr, IS_USER(s));
3895
neon_store_reg64(tmp64, rd);
3897
neon_load_reg64(tmp64, rd);
3898
gen_aa32_st64(tmp64, addr, IS_USER(s));
3900
tcg_temp_free_i64(tmp64);
3901
tcg_gen_addi_i32(addr, addr, stride);
3903
for (pass = 0; pass < 2; pass++) {
3906
tmp = tcg_temp_new_i32();
3907
gen_aa32_ld32u(tmp, addr, IS_USER(s));
3908
neon_store_reg(rd, pass, tmp);
3910
tmp = neon_load_reg(rd, pass);
3911
gen_aa32_st32(tmp, addr, IS_USER(s));
3912
tcg_temp_free_i32(tmp);
3914
tcg_gen_addi_i32(addr, addr, stride);
3915
} else if (size == 1) {
3917
tmp = tcg_temp_new_i32();
3918
gen_aa32_ld16u(tmp, addr, IS_USER(s));
3919
tcg_gen_addi_i32(addr, addr, stride);
3920
tmp2 = tcg_temp_new_i32();
3921
gen_aa32_ld16u(tmp2, addr, IS_USER(s));
3922
tcg_gen_addi_i32(addr, addr, stride);
3923
tcg_gen_shli_i32(tmp2, tmp2, 16);
3924
tcg_gen_or_i32(tmp, tmp, tmp2);
3925
tcg_temp_free_i32(tmp2);
3926
neon_store_reg(rd, pass, tmp);
3928
tmp = neon_load_reg(rd, pass);
3929
tmp2 = tcg_temp_new_i32();
3930
tcg_gen_shri_i32(tmp2, tmp, 16);
3931
gen_aa32_st16(tmp, addr, IS_USER(s));
3932
tcg_temp_free_i32(tmp);
3933
tcg_gen_addi_i32(addr, addr, stride);
3934
gen_aa32_st16(tmp2, addr, IS_USER(s));
3935
tcg_temp_free_i32(tmp2);
3936
tcg_gen_addi_i32(addr, addr, stride);
3938
} else /* size == 0 */ {
3940
TCGV_UNUSED_I32(tmp2);
3941
for (n = 0; n < 4; n++) {
3942
tmp = tcg_temp_new_i32();
3943
gen_aa32_ld8u(tmp, addr, IS_USER(s));
3944
tcg_gen_addi_i32(addr, addr, stride);
3948
tcg_gen_shli_i32(tmp, tmp, n * 8);
3949
tcg_gen_or_i32(tmp2, tmp2, tmp);
3950
tcg_temp_free_i32(tmp);
3953
neon_store_reg(rd, pass, tmp2);
3955
tmp2 = neon_load_reg(rd, pass);
3956
for (n = 0; n < 4; n++) {
3957
tmp = tcg_temp_new_i32();
3959
tcg_gen_mov_i32(tmp, tmp2);
3961
tcg_gen_shri_i32(tmp, tmp2, n * 8);
3963
gen_aa32_st8(tmp, addr, IS_USER(s));
3964
tcg_temp_free_i32(tmp);
3965
tcg_gen_addi_i32(addr, addr, stride);
3967
tcg_temp_free_i32(tmp2);
3974
tcg_temp_free_i32(addr);
3977
size = (insn >> 10) & 3;
3979
/* Load single element to all lanes. */
3980
int a = (insn >> 4) & 1;
3984
size = (insn >> 6) & 3;
3985
nregs = ((insn >> 8) & 3) + 1;
3988
if (nregs != 4 || a == 0) {
3991
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3994
if (nregs == 1 && a == 1 && size == 0) {
3997
if (nregs == 3 && a == 1) {
4000
addr = tcg_temp_new_i32();
4001
load_reg_var(s, addr, rn);
4003
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4004
tmp = gen_load_and_replicate(s, addr, size);
4005
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4006
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4007
if (insn & (1 << 5)) {
4008
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4009
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4011
tcg_temp_free_i32(tmp);
4013
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4014
stride = (insn & (1 << 5)) ? 2 : 1;
4015
for (reg = 0; reg < nregs; reg++) {
4016
tmp = gen_load_and_replicate(s, addr, size);
4017
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4018
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4019
tcg_temp_free_i32(tmp);
4020
tcg_gen_addi_i32(addr, addr, 1 << size);
4024
tcg_temp_free_i32(addr);
4025
stride = (1 << size) * nregs;
4027
/* Single element. */
4028
int idx = (insn >> 4) & 0xf;
4029
pass = (insn >> 7) & 1;
4032
shift = ((insn >> 5) & 3) * 8;
4036
shift = ((insn >> 6) & 1) * 16;
4037
stride = (insn & (1 << 5)) ? 2 : 1;
4041
stride = (insn & (1 << 6)) ? 2 : 1;
4046
nregs = ((insn >> 8) & 3) + 1;
4047
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
4050
if (((idx & (1 << size)) != 0) ||
4051
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4056
if ((idx & 1) != 0) {
4061
if (size == 2 && (idx & 2) != 0) {
4066
if ((size == 2) && ((idx & 3) == 3)) {
4073
if ((rd + stride * (nregs - 1)) > 31) {
4074
/* Attempts to write off the end of the register file
4075
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4076
* the neon_load_reg() would write off the end of the array.
4080
addr = tcg_temp_new_i32();
4081
load_reg_var(s, addr, rn);
4082
for (reg = 0; reg < nregs; reg++) {
4084
tmp = tcg_temp_new_i32();
4087
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4090
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4093
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4095
default: /* Avoid compiler warnings. */
4099
tmp2 = neon_load_reg(rd, pass);
4100
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4101
shift, size ? 16 : 8);
4102
tcg_temp_free_i32(tmp2);
4104
neon_store_reg(rd, pass, tmp);
4105
} else { /* Store */
4106
tmp = neon_load_reg(rd, pass);
4108
tcg_gen_shri_i32(tmp, tmp, shift);
4111
gen_aa32_st8(tmp, addr, IS_USER(s));
4114
gen_aa32_st16(tmp, addr, IS_USER(s));
4117
gen_aa32_st32(tmp, addr, IS_USER(s));
4120
tcg_temp_free_i32(tmp);
4123
tcg_gen_addi_i32(addr, addr, 1 << size);
4125
tcg_temp_free_i32(addr);
4126
stride = nregs * (1 << size);
4132
base = load_reg(s, rn);
4134
tcg_gen_addi_i32(base, base, stride);
4137
index = load_reg(s, rm);
4138
tcg_gen_add_i32(base, base, index);
4139
tcg_temp_free_i32(index);
4141
store_reg(s, rn, base);
4146
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4147
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4149
tcg_gen_and_i32(t, t, c);
4150
tcg_gen_andc_i32(f, f, c);
4151
tcg_gen_or_i32(dest, t, f);
4154
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4157
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4158
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4159
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4164
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4167
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4168
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4169
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4174
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4177
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4178
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4179
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4184
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4187
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4188
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4189
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4194
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4200
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4201
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4206
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4207
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4214
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4215
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4220
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4221
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4228
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4232
case 0: gen_helper_neon_widen_u8(dest, src); break;
4233
case 1: gen_helper_neon_widen_u16(dest, src); break;
4234
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4239
case 0: gen_helper_neon_widen_s8(dest, src); break;
4240
case 1: gen_helper_neon_widen_s16(dest, src); break;
4241
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4245
tcg_temp_free_i32(src);
4248
static inline void gen_neon_addl(int size)
4251
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4252
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4253
case 2: tcg_gen_add_i64(CPU_V001); break;
4258
static inline void gen_neon_subl(int size)
4261
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4262
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4263
case 2: tcg_gen_sub_i64(CPU_V001); break;
4268
static inline void gen_neon_negl(TCGv_i64 var, int size)
4271
case 0: gen_helper_neon_negl_u16(var, var); break;
4272
case 1: gen_helper_neon_negl_u32(var, var); break;
4274
tcg_gen_neg_i64(var, var);
4280
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4283
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4284
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4289
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4294
switch ((size << 1) | u) {
4295
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4296
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4297
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4298
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4300
tmp = gen_muls_i64_i32(a, b);
4301
tcg_gen_mov_i64(dest, tmp);
4302
tcg_temp_free_i64(tmp);
4305
tmp = gen_mulu_i64_i32(a, b);
4306
tcg_gen_mov_i64(dest, tmp);
4307
tcg_temp_free_i64(tmp);
4312
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4313
Don't forget to clean them now. */
4315
tcg_temp_free_i32(a);
4316
tcg_temp_free_i32(b);
4320
static void gen_neon_narrow_op(int op, int u, int size,
4321
TCGv_i32 dest, TCGv_i64 src)
4325
gen_neon_unarrow_sats(size, dest, src);
4327
gen_neon_narrow(size, dest, src);
4331
gen_neon_narrow_satu(size, dest, src);
4333
gen_neon_narrow_sats(size, dest, src);
4338
/* Symbolic constants for op fields for Neon 3-register same-length.
4339
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4342
#define NEON_3R_VHADD 0
4343
#define NEON_3R_VQADD 1
4344
#define NEON_3R_VRHADD 2
4345
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4346
#define NEON_3R_VHSUB 4
4347
#define NEON_3R_VQSUB 5
4348
#define NEON_3R_VCGT 6
4349
#define NEON_3R_VCGE 7
4350
#define NEON_3R_VSHL 8
4351
#define NEON_3R_VQSHL 9
4352
#define NEON_3R_VRSHL 10
4353
#define NEON_3R_VQRSHL 11
4354
#define NEON_3R_VMAX 12
4355
#define NEON_3R_VMIN 13
4356
#define NEON_3R_VABD 14
4357
#define NEON_3R_VABA 15
4358
#define NEON_3R_VADD_VSUB 16
4359
#define NEON_3R_VTST_VCEQ 17
4360
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4361
#define NEON_3R_VMUL 19
4362
#define NEON_3R_VPMAX 20
4363
#define NEON_3R_VPMIN 21
4364
#define NEON_3R_VQDMULH_VQRDMULH 22
4365
#define NEON_3R_VPADD 23
4366
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4367
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4368
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4369
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4370
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4371
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4372
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4374
static const uint8_t neon_3r_sizes[] = {
4375
[NEON_3R_VHADD] = 0x7,
4376
[NEON_3R_VQADD] = 0xf,
4377
[NEON_3R_VRHADD] = 0x7,
4378
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4379
[NEON_3R_VHSUB] = 0x7,
4380
[NEON_3R_VQSUB] = 0xf,
4381
[NEON_3R_VCGT] = 0x7,
4382
[NEON_3R_VCGE] = 0x7,
4383
[NEON_3R_VSHL] = 0xf,
4384
[NEON_3R_VQSHL] = 0xf,
4385
[NEON_3R_VRSHL] = 0xf,
4386
[NEON_3R_VQRSHL] = 0xf,
4387
[NEON_3R_VMAX] = 0x7,
4388
[NEON_3R_VMIN] = 0x7,
4389
[NEON_3R_VABD] = 0x7,
4390
[NEON_3R_VABA] = 0x7,
4391
[NEON_3R_VADD_VSUB] = 0xf,
4392
[NEON_3R_VTST_VCEQ] = 0x7,
4393
[NEON_3R_VML] = 0x7,
4394
[NEON_3R_VMUL] = 0x7,
4395
[NEON_3R_VPMAX] = 0x7,
4396
[NEON_3R_VPMIN] = 0x7,
4397
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4398
[NEON_3R_VPADD] = 0x7,
4399
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4400
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4401
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4402
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4403
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4404
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4405
[NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4408
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4409
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4412
#define NEON_2RM_VREV64 0
4413
#define NEON_2RM_VREV32 1
4414
#define NEON_2RM_VREV16 2
4415
#define NEON_2RM_VPADDL 4
4416
#define NEON_2RM_VPADDL_U 5
4417
#define NEON_2RM_VCLS 8
4418
#define NEON_2RM_VCLZ 9
4419
#define NEON_2RM_VCNT 10
4420
#define NEON_2RM_VMVN 11
4421
#define NEON_2RM_VPADAL 12
4422
#define NEON_2RM_VPADAL_U 13
4423
#define NEON_2RM_VQABS 14
4424
#define NEON_2RM_VQNEG 15
4425
#define NEON_2RM_VCGT0 16
4426
#define NEON_2RM_VCGE0 17
4427
#define NEON_2RM_VCEQ0 18
4428
#define NEON_2RM_VCLE0 19
4429
#define NEON_2RM_VCLT0 20
4430
#define NEON_2RM_VABS 22
4431
#define NEON_2RM_VNEG 23
4432
#define NEON_2RM_VCGT0_F 24
4433
#define NEON_2RM_VCGE0_F 25
4434
#define NEON_2RM_VCEQ0_F 26
4435
#define NEON_2RM_VCLE0_F 27
4436
#define NEON_2RM_VCLT0_F 28
4437
#define NEON_2RM_VABS_F 30
4438
#define NEON_2RM_VNEG_F 31
4439
#define NEON_2RM_VSWP 32
4440
#define NEON_2RM_VTRN 33
4441
#define NEON_2RM_VUZP 34
4442
#define NEON_2RM_VZIP 35
4443
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4444
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4445
#define NEON_2RM_VSHLL 38
4446
#define NEON_2RM_VCVT_F16_F32 44
4447
#define NEON_2RM_VCVT_F32_F16 46
4448
#define NEON_2RM_VRECPE 56
4449
#define NEON_2RM_VRSQRTE 57
4450
#define NEON_2RM_VRECPE_F 58
4451
#define NEON_2RM_VRSQRTE_F 59
4452
#define NEON_2RM_VCVT_FS 60
4453
#define NEON_2RM_VCVT_FU 61
4454
#define NEON_2RM_VCVT_SF 62
4455
#define NEON_2RM_VCVT_UF 63
4457
static int neon_2rm_is_float_op(int op)
4459
/* Return true if this neon 2reg-misc op is float-to-float */
4460
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4461
op >= NEON_2RM_VRECPE_F);
4464
/* Each entry in this array has bit n set if the insn allows
4465
* size value n (otherwise it will UNDEF). Since unallocated
4466
* op values will have no bits set they always UNDEF.
4468
static const uint8_t neon_2rm_sizes[] = {
4469
[NEON_2RM_VREV64] = 0x7,
4470
[NEON_2RM_VREV32] = 0x3,
4471
[NEON_2RM_VREV16] = 0x1,
4472
[NEON_2RM_VPADDL] = 0x7,
4473
[NEON_2RM_VPADDL_U] = 0x7,
4474
[NEON_2RM_VCLS] = 0x7,
4475
[NEON_2RM_VCLZ] = 0x7,
4476
[NEON_2RM_VCNT] = 0x1,
4477
[NEON_2RM_VMVN] = 0x1,
4478
[NEON_2RM_VPADAL] = 0x7,
4479
[NEON_2RM_VPADAL_U] = 0x7,
4480
[NEON_2RM_VQABS] = 0x7,
4481
[NEON_2RM_VQNEG] = 0x7,
4482
[NEON_2RM_VCGT0] = 0x7,
4483
[NEON_2RM_VCGE0] = 0x7,
4484
[NEON_2RM_VCEQ0] = 0x7,
4485
[NEON_2RM_VCLE0] = 0x7,
4486
[NEON_2RM_VCLT0] = 0x7,
4487
[NEON_2RM_VABS] = 0x7,
4488
[NEON_2RM_VNEG] = 0x7,
4489
[NEON_2RM_VCGT0_F] = 0x4,
4490
[NEON_2RM_VCGE0_F] = 0x4,
4491
[NEON_2RM_VCEQ0_F] = 0x4,
4492
[NEON_2RM_VCLE0_F] = 0x4,
4493
[NEON_2RM_VCLT0_F] = 0x4,
4494
[NEON_2RM_VABS_F] = 0x4,
4495
[NEON_2RM_VNEG_F] = 0x4,
4496
[NEON_2RM_VSWP] = 0x1,
4497
[NEON_2RM_VTRN] = 0x7,
4498
[NEON_2RM_VUZP] = 0x7,
4499
[NEON_2RM_VZIP] = 0x7,
4500
[NEON_2RM_VMOVN] = 0x7,
4501
[NEON_2RM_VQMOVN] = 0x7,
4502
[NEON_2RM_VSHLL] = 0x7,
4503
[NEON_2RM_VCVT_F16_F32] = 0x2,
4504
[NEON_2RM_VCVT_F32_F16] = 0x2,
4505
[NEON_2RM_VRECPE] = 0x4,
4506
[NEON_2RM_VRSQRTE] = 0x4,
4507
[NEON_2RM_VRECPE_F] = 0x4,
4508
[NEON_2RM_VRSQRTE_F] = 0x4,
4509
[NEON_2RM_VCVT_FS] = 0x4,
4510
[NEON_2RM_VCVT_FU] = 0x4,
4511
[NEON_2RM_VCVT_SF] = 0x4,
4512
[NEON_2RM_VCVT_UF] = 0x4,
4515
/* Translate a NEON data processing instruction. Return nonzero if the
4516
instruction is invalid.
4517
We process data in a mixture of 32-bit and 64-bit chunks.
4518
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4520
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4532
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4535
if (!s->vfp_enabled)
4537
q = (insn & (1 << 6)) != 0;
4538
u = (insn >> 24) & 1;
4539
VFP_DREG_D(rd, insn);
4540
VFP_DREG_N(rn, insn);
4541
VFP_DREG_M(rm, insn);
4542
size = (insn >> 20) & 3;
4543
if ((insn & (1 << 23)) == 0) {
4544
/* Three register same length. */
4545
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4546
/* Catch invalid op and bad size combinations: UNDEF */
4547
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4550
/* All insns of this form UNDEF for either this condition or the
4551
* superset of cases "Q==1"; we catch the latter later.
4553
if (q && ((rd | rn | rm) & 1)) {
4556
if (size == 3 && op != NEON_3R_LOGIC) {
4557
/* 64-bit element instructions. */
4558
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4559
neon_load_reg64(cpu_V0, rn + pass);
4560
neon_load_reg64(cpu_V1, rm + pass);
4564
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4567
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4573
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4576
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4582
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4584
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4589
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4592
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4598
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4600
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4603
case NEON_3R_VQRSHL:
4605
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4608
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4612
case NEON_3R_VADD_VSUB:
4614
tcg_gen_sub_i64(CPU_V001);
4616
tcg_gen_add_i64(CPU_V001);
4622
neon_store_reg64(cpu_V0, rd + pass);
4631
case NEON_3R_VQRSHL:
4634
/* Shift instruction operands are reversed. */
4649
case NEON_3R_FLOAT_ARITH:
4650
pairwise = (u && size < 2); /* if VPADD (float) */
4652
case NEON_3R_FLOAT_MINMAX:
4653
pairwise = u; /* if VPMIN/VPMAX (float) */
4655
case NEON_3R_FLOAT_CMP:
4657
/* no encoding for U=0 C=1x */
4661
case NEON_3R_FLOAT_ACMP:
4666
case NEON_3R_VRECPS_VRSQRTS:
4672
if (u && (size != 0)) {
4673
/* UNDEF on invalid size for polynomial subcase */
4678
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4686
if (pairwise && q) {
4687
/* All the pairwise insns UNDEF if Q is set */
4691
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4696
tmp = neon_load_reg(rn, 0);
4697
tmp2 = neon_load_reg(rn, 1);
4699
tmp = neon_load_reg(rm, 0);
4700
tmp2 = neon_load_reg(rm, 1);
4704
tmp = neon_load_reg(rn, pass);
4705
tmp2 = neon_load_reg(rm, pass);
4709
GEN_NEON_INTEGER_OP(hadd);
4712
GEN_NEON_INTEGER_OP_ENV(qadd);
4714
case NEON_3R_VRHADD:
4715
GEN_NEON_INTEGER_OP(rhadd);
4717
case NEON_3R_LOGIC: /* Logic ops. */
4718
switch ((u << 2) | size) {
4720
tcg_gen_and_i32(tmp, tmp, tmp2);
4723
tcg_gen_andc_i32(tmp, tmp, tmp2);
4726
tcg_gen_or_i32(tmp, tmp, tmp2);
4729
tcg_gen_orc_i32(tmp, tmp, tmp2);
4732
tcg_gen_xor_i32(tmp, tmp, tmp2);
4735
tmp3 = neon_load_reg(rd, pass);
4736
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4737
tcg_temp_free_i32(tmp3);
4740
tmp3 = neon_load_reg(rd, pass);
4741
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4742
tcg_temp_free_i32(tmp3);
4745
tmp3 = neon_load_reg(rd, pass);
4746
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4747
tcg_temp_free_i32(tmp3);
4752
GEN_NEON_INTEGER_OP(hsub);
4755
GEN_NEON_INTEGER_OP_ENV(qsub);
4758
GEN_NEON_INTEGER_OP(cgt);
4761
GEN_NEON_INTEGER_OP(cge);
4764
GEN_NEON_INTEGER_OP(shl);
4767
GEN_NEON_INTEGER_OP_ENV(qshl);
4770
GEN_NEON_INTEGER_OP(rshl);
4772
case NEON_3R_VQRSHL:
4773
GEN_NEON_INTEGER_OP_ENV(qrshl);
4776
GEN_NEON_INTEGER_OP(max);
4779
GEN_NEON_INTEGER_OP(min);
4782
GEN_NEON_INTEGER_OP(abd);
4785
GEN_NEON_INTEGER_OP(abd);
4786
tcg_temp_free_i32(tmp2);
4787
tmp2 = neon_load_reg(rd, pass);
4788
gen_neon_add(size, tmp, tmp2);
4790
case NEON_3R_VADD_VSUB:
4791
if (!u) { /* VADD */
4792
gen_neon_add(size, tmp, tmp2);
4795
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4796
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4797
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4802
case NEON_3R_VTST_VCEQ:
4803
if (!u) { /* VTST */
4805
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4806
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4807
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4812
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4813
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4814
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4819
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4821
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4822
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4823
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4826
tcg_temp_free_i32(tmp2);
4827
tmp2 = neon_load_reg(rd, pass);
4829
gen_neon_rsb(size, tmp, tmp2);
4831
gen_neon_add(size, tmp, tmp2);
4835
if (u) { /* polynomial */
4836
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4837
} else { /* Integer */
4839
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4840
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4841
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4847
GEN_NEON_INTEGER_OP(pmax);
4850
GEN_NEON_INTEGER_OP(pmin);
4852
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
4853
if (!u) { /* VQDMULH */
4856
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
4859
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
4863
} else { /* VQRDMULH */
4866
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
4869
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
4877
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4878
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4879
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4883
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
4885
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4886
switch ((u << 2) | size) {
4889
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4892
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
4895
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
4900
tcg_temp_free_ptr(fpstatus);
4903
case NEON_3R_FLOAT_MULTIPLY:
4905
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4906
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
4908
tcg_temp_free_i32(tmp2);
4909
tmp2 = neon_load_reg(rd, pass);
4911
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4913
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
4916
tcg_temp_free_ptr(fpstatus);
4919
case NEON_3R_FLOAT_CMP:
4921
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4923
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
4926
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
4928
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
4931
tcg_temp_free_ptr(fpstatus);
4934
case NEON_3R_FLOAT_ACMP:
4936
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4938
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
4940
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
4942
tcg_temp_free_ptr(fpstatus);
4945
case NEON_3R_FLOAT_MINMAX:
4947
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4949
gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
4951
gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
4953
tcg_temp_free_ptr(fpstatus);
4956
case NEON_3R_VRECPS_VRSQRTS:
4958
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4960
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4964
/* VFMA, VFMS: fused multiply-add */
4965
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4966
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
4969
gen_helper_vfp_negs(tmp, tmp);
4971
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
4972
tcg_temp_free_i32(tmp3);
4973
tcg_temp_free_ptr(fpstatus);
4979
tcg_temp_free_i32(tmp2);
4981
/* Save the result. For elementwise operations we can put it
4982
straight into the destination register. For pairwise operations
4983
we have to be careful to avoid clobbering the source operands. */
4984
if (pairwise && rd == rm) {
4985
neon_store_scratch(pass, tmp);
4987
neon_store_reg(rd, pass, tmp);
4991
if (pairwise && rd == rm) {
4992
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4993
tmp = neon_load_scratch(pass);
4994
neon_store_reg(rd, pass, tmp);
4997
/* End of 3 register same size operations. */
4998
} else if (insn & (1 << 4)) {
4999
if ((insn & 0x00380080) != 0) {
5000
/* Two registers and shift. */
5001
op = (insn >> 8) & 0xf;
5002
if (insn & (1 << 7)) {
5010
while ((insn & (1 << (size + 19))) == 0)
5013
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5014
/* To avoid excessive duplication of ops we implement shift
5015
by immediate using the variable shift operations. */
5017
/* Shift by immediate:
5018
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5019
if (q && ((rd | rm) & 1)) {
5022
if (!u && (op == 4 || op == 6)) {
5025
/* Right shifts are encoded as N - shift, where N is the
5026
element size in bits. */
5028
shift = shift - (1 << (size + 3));
5036
imm = (uint8_t) shift;
5041
imm = (uint16_t) shift;
5052
for (pass = 0; pass < count; pass++) {
5054
neon_load_reg64(cpu_V0, rm + pass);
5055
tcg_gen_movi_i64(cpu_V1, imm);
5060
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5062
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5067
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5069
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5072
case 5: /* VSHL, VSLI */
5073
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5075
case 6: /* VQSHLU */
5076
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5081
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5084
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5089
if (op == 1 || op == 3) {
5091
neon_load_reg64(cpu_V1, rd + pass);
5092
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5093
} else if (op == 4 || (op == 5 && u)) {
5095
neon_load_reg64(cpu_V1, rd + pass);
5097
if (shift < -63 || shift > 63) {
5101
mask = 0xffffffffffffffffull >> -shift;
5103
mask = 0xffffffffffffffffull << shift;
5106
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5107
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5109
neon_store_reg64(cpu_V0, rd + pass);
5110
} else { /* size < 3 */
5111
/* Operands in T0 and T1. */
5112
tmp = neon_load_reg(rm, pass);
5113
tmp2 = tcg_temp_new_i32();
5114
tcg_gen_movi_i32(tmp2, imm);
5118
GEN_NEON_INTEGER_OP(shl);
5122
GEN_NEON_INTEGER_OP(rshl);
5125
case 5: /* VSHL, VSLI */
5127
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5128
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5129
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5133
case 6: /* VQSHLU */
5136
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5140
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5144
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5152
GEN_NEON_INTEGER_OP_ENV(qshl);
5155
tcg_temp_free_i32(tmp2);
5157
if (op == 1 || op == 3) {
5159
tmp2 = neon_load_reg(rd, pass);
5160
gen_neon_add(size, tmp, tmp2);
5161
tcg_temp_free_i32(tmp2);
5162
} else if (op == 4 || (op == 5 && u)) {
5167
mask = 0xff >> -shift;
5169
mask = (uint8_t)(0xff << shift);
5175
mask = 0xffff >> -shift;
5177
mask = (uint16_t)(0xffff << shift);
5181
if (shift < -31 || shift > 31) {
5185
mask = 0xffffffffu >> -shift;
5187
mask = 0xffffffffu << shift;
5193
tmp2 = neon_load_reg(rd, pass);
5194
tcg_gen_andi_i32(tmp, tmp, mask);
5195
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5196
tcg_gen_or_i32(tmp, tmp, tmp2);
5197
tcg_temp_free_i32(tmp2);
5199
neon_store_reg(rd, pass, tmp);
5202
} else if (op < 10) {
5203
/* Shift by immediate and narrow:
5204
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5205
int input_unsigned = (op == 8) ? !u : u;
5209
shift = shift - (1 << (size + 3));
5212
tmp64 = tcg_const_i64(shift);
5213
neon_load_reg64(cpu_V0, rm);
5214
neon_load_reg64(cpu_V1, rm + 1);
5215
for (pass = 0; pass < 2; pass++) {
5223
if (input_unsigned) {
5224
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5226
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5229
if (input_unsigned) {
5230
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5232
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5235
tmp = tcg_temp_new_i32();
5236
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5237
neon_store_reg(rd, pass, tmp);
5239
tcg_temp_free_i64(tmp64);
5242
imm = (uint16_t)shift;
5246
imm = (uint32_t)shift;
5248
tmp2 = tcg_const_i32(imm);
5249
tmp4 = neon_load_reg(rm + 1, 0);
5250
tmp5 = neon_load_reg(rm + 1, 1);
5251
for (pass = 0; pass < 2; pass++) {
5253
tmp = neon_load_reg(rm, 0);
5257
gen_neon_shift_narrow(size, tmp, tmp2, q,
5260
tmp3 = neon_load_reg(rm, 1);
5264
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5266
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5267
tcg_temp_free_i32(tmp);
5268
tcg_temp_free_i32(tmp3);
5269
tmp = tcg_temp_new_i32();
5270
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5271
neon_store_reg(rd, pass, tmp);
5273
tcg_temp_free_i32(tmp2);
5275
} else if (op == 10) {
5277
if (q || (rd & 1)) {
5280
tmp = neon_load_reg(rm, 0);
5281
tmp2 = neon_load_reg(rm, 1);
5282
for (pass = 0; pass < 2; pass++) {
5286
gen_neon_widen(cpu_V0, tmp, size, u);
5289
/* The shift is less than the width of the source
5290
type, so we can just shift the whole register. */
5291
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5292
/* Widen the result of shift: we need to clear
5293
* the potential overflow bits resulting from
5294
* left bits of the narrow input appearing as
5295
* right bits of left the neighbour narrow
5297
if (size < 2 || !u) {
5300
imm = (0xffu >> (8 - shift));
5302
} else if (size == 1) {
5303
imm = 0xffff >> (16 - shift);
5306
imm = 0xffffffff >> (32 - shift);
5309
imm64 = imm | (((uint64_t)imm) << 32);
5313
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5316
neon_store_reg64(cpu_V0, rd + pass);
5318
} else if (op >= 14) {
5319
/* VCVT fixed-point. */
5320
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5323
/* We have already masked out the must-be-1 top bit of imm6,
5324
* hence this 32-shift where the ARM ARM has 64-imm6.
5327
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5328
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5331
gen_vfp_ulto(0, shift, 1);
5333
gen_vfp_slto(0, shift, 1);
5336
gen_vfp_toul(0, shift, 1);
5338
gen_vfp_tosl(0, shift, 1);
5340
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5345
} else { /* (insn & 0x00380080) == 0 */
5347
if (q && (rd & 1)) {
5351
op = (insn >> 8) & 0xf;
5352
/* One register and immediate. */
5353
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5354
invert = (insn & (1 << 5)) != 0;
5355
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5356
* We choose to not special-case this and will behave as if a
5357
* valid constant encoding of 0 had been given.
5376
imm = (imm << 8) | (imm << 24);
5379
imm = (imm << 8) | 0xff;
5382
imm = (imm << 16) | 0xffff;
5385
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5393
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5394
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5400
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5401
if (op & 1 && op < 12) {
5402
tmp = neon_load_reg(rd, pass);
5404
/* The immediate value has already been inverted, so
5406
tcg_gen_andi_i32(tmp, tmp, imm);
5408
tcg_gen_ori_i32(tmp, tmp, imm);
5412
tmp = tcg_temp_new_i32();
5413
if (op == 14 && invert) {
5417
for (n = 0; n < 4; n++) {
5418
if (imm & (1 << (n + (pass & 1) * 4)))
5419
val |= 0xff << (n * 8);
5421
tcg_gen_movi_i32(tmp, val);
5423
tcg_gen_movi_i32(tmp, imm);
5426
neon_store_reg(rd, pass, tmp);
5429
} else { /* (insn & 0x00800010 == 0x00800000) */
5431
op = (insn >> 8) & 0xf;
5432
if ((insn & (1 << 6)) == 0) {
5433
/* Three registers of different lengths. */
5437
/* undefreq: bit 0 : UNDEF if size != 0
5438
* bit 1 : UNDEF if size == 0
5439
* bit 2 : UNDEF if U == 1
5440
* Note that [1:0] set implies 'always UNDEF'
5443
/* prewiden, src1_wide, src2_wide, undefreq */
5444
static const int neon_3reg_wide[16][4] = {
5445
{1, 0, 0, 0}, /* VADDL */
5446
{1, 1, 0, 0}, /* VADDW */
5447
{1, 0, 0, 0}, /* VSUBL */
5448
{1, 1, 0, 0}, /* VSUBW */
5449
{0, 1, 1, 0}, /* VADDHN */
5450
{0, 0, 0, 0}, /* VABAL */
5451
{0, 1, 1, 0}, /* VSUBHN */
5452
{0, 0, 0, 0}, /* VABDL */
5453
{0, 0, 0, 0}, /* VMLAL */
5454
{0, 0, 0, 6}, /* VQDMLAL */
5455
{0, 0, 0, 0}, /* VMLSL */
5456
{0, 0, 0, 6}, /* VQDMLSL */
5457
{0, 0, 0, 0}, /* Integer VMULL */
5458
{0, 0, 0, 2}, /* VQDMULL */
5459
{0, 0, 0, 5}, /* Polynomial VMULL */
5460
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5463
prewiden = neon_3reg_wide[op][0];
5464
src1_wide = neon_3reg_wide[op][1];
5465
src2_wide = neon_3reg_wide[op][2];
5466
undefreq = neon_3reg_wide[op][3];
5468
if (((undefreq & 1) && (size != 0)) ||
5469
((undefreq & 2) && (size == 0)) ||
5470
((undefreq & 4) && u)) {
5473
if ((src1_wide && (rn & 1)) ||
5474
(src2_wide && (rm & 1)) ||
5475
(!src2_wide && (rd & 1))) {
5479
/* Avoid overlapping operands. Wide source operands are
5480
always aligned so will never overlap with wide
5481
destinations in problematic ways. */
5482
if (rd == rm && !src2_wide) {
5483
tmp = neon_load_reg(rm, 1);
5484
neon_store_scratch(2, tmp);
5485
} else if (rd == rn && !src1_wide) {
5486
tmp = neon_load_reg(rn, 1);
5487
neon_store_scratch(2, tmp);
5489
TCGV_UNUSED_I32(tmp3);
5490
for (pass = 0; pass < 2; pass++) {
5492
neon_load_reg64(cpu_V0, rn + pass);
5493
TCGV_UNUSED_I32(tmp);
5495
if (pass == 1 && rd == rn) {
5496
tmp = neon_load_scratch(2);
5498
tmp = neon_load_reg(rn, pass);
5501
gen_neon_widen(cpu_V0, tmp, size, u);
5505
neon_load_reg64(cpu_V1, rm + pass);
5506
TCGV_UNUSED_I32(tmp2);
5508
if (pass == 1 && rd == rm) {
5509
tmp2 = neon_load_scratch(2);
5511
tmp2 = neon_load_reg(rm, pass);
5514
gen_neon_widen(cpu_V1, tmp2, size, u);
5518
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5519
gen_neon_addl(size);
5521
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5522
gen_neon_subl(size);
5524
case 5: case 7: /* VABAL, VABDL */
5525
switch ((size << 1) | u) {
5527
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5530
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5533
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5536
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5539
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5542
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5546
tcg_temp_free_i32(tmp2);
5547
tcg_temp_free_i32(tmp);
5549
case 8: case 9: case 10: case 11: case 12: case 13:
5550
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5551
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5553
case 14: /* Polynomial VMULL */
5554
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5555
tcg_temp_free_i32(tmp2);
5556
tcg_temp_free_i32(tmp);
5558
default: /* 15 is RESERVED: caught earlier */
5563
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5564
neon_store_reg64(cpu_V0, rd + pass);
5565
} else if (op == 5 || (op >= 8 && op <= 11)) {
5567
neon_load_reg64(cpu_V1, rd + pass);
5569
case 10: /* VMLSL */
5570
gen_neon_negl(cpu_V0, size);
5572
case 5: case 8: /* VABAL, VMLAL */
5573
gen_neon_addl(size);
5575
case 9: case 11: /* VQDMLAL, VQDMLSL */
5576
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5578
gen_neon_negl(cpu_V0, size);
5580
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5585
neon_store_reg64(cpu_V0, rd + pass);
5586
} else if (op == 4 || op == 6) {
5587
/* Narrowing operation. */
5588
tmp = tcg_temp_new_i32();
5592
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5595
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5598
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5599
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5606
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5609
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5612
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5613
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5614
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5622
neon_store_reg(rd, 0, tmp3);
5623
neon_store_reg(rd, 1, tmp);
5626
/* Write back the result. */
5627
neon_store_reg64(cpu_V0, rd + pass);
5631
/* Two registers and a scalar. NB that for ops of this form
5632
* the ARM ARM labels bit 24 as Q, but it is in our variable
5639
case 1: /* Float VMLA scalar */
5640
case 5: /* Floating point VMLS scalar */
5641
case 9: /* Floating point VMUL scalar */
5646
case 0: /* Integer VMLA scalar */
5647
case 4: /* Integer VMLS scalar */
5648
case 8: /* Integer VMUL scalar */
5649
case 12: /* VQDMULH scalar */
5650
case 13: /* VQRDMULH scalar */
5651
if (u && ((rd | rn) & 1)) {
5654
tmp = neon_get_scalar(size, rm);
5655
neon_store_scratch(0, tmp);
5656
for (pass = 0; pass < (u ? 4 : 2); pass++) {
5657
tmp = neon_load_scratch(0);
5658
tmp2 = neon_load_reg(rn, pass);
5661
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5663
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5665
} else if (op == 13) {
5667
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5669
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5671
} else if (op & 1) {
5672
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5673
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5674
tcg_temp_free_ptr(fpstatus);
5677
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5678
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5679
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5683
tcg_temp_free_i32(tmp2);
5686
tmp2 = neon_load_reg(rd, pass);
5689
gen_neon_add(size, tmp, tmp2);
5693
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5694
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5695
tcg_temp_free_ptr(fpstatus);
5699
gen_neon_rsb(size, tmp, tmp2);
5703
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5704
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5705
tcg_temp_free_ptr(fpstatus);
5711
tcg_temp_free_i32(tmp2);
5713
neon_store_reg(rd, pass, tmp);
5716
case 3: /* VQDMLAL scalar */
5717
case 7: /* VQDMLSL scalar */
5718
case 11: /* VQDMULL scalar */
5723
case 2: /* VMLAL sclar */
5724
case 6: /* VMLSL scalar */
5725
case 10: /* VMULL scalar */
5729
tmp2 = neon_get_scalar(size, rm);
5730
/* We need a copy of tmp2 because gen_neon_mull
5731
* deletes it during pass 0. */
5732
tmp4 = tcg_temp_new_i32();
5733
tcg_gen_mov_i32(tmp4, tmp2);
5734
tmp3 = neon_load_reg(rn, 1);
5736
for (pass = 0; pass < 2; pass++) {
5738
tmp = neon_load_reg(rn, 0);
5743
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5745
neon_load_reg64(cpu_V1, rd + pass);
5749
gen_neon_negl(cpu_V0, size);
5752
gen_neon_addl(size);
5755
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5757
gen_neon_negl(cpu_V0, size);
5759
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5765
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5770
neon_store_reg64(cpu_V0, rd + pass);
5775
default: /* 14 and 15 are RESERVED */
5779
} else { /* size == 3 */
5782
imm = (insn >> 8) & 0xf;
5787
if (q && ((rd | rn | rm) & 1)) {
5792
neon_load_reg64(cpu_V0, rn);
5794
neon_load_reg64(cpu_V1, rn + 1);
5796
} else if (imm == 8) {
5797
neon_load_reg64(cpu_V0, rn + 1);
5799
neon_load_reg64(cpu_V1, rm);
5802
tmp64 = tcg_temp_new_i64();
5804
neon_load_reg64(cpu_V0, rn);
5805
neon_load_reg64(tmp64, rn + 1);
5807
neon_load_reg64(cpu_V0, rn + 1);
5808
neon_load_reg64(tmp64, rm);
5810
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5811
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5812
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5814
neon_load_reg64(cpu_V1, rm);
5816
neon_load_reg64(cpu_V1, rm + 1);
5819
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5820
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5821
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5822
tcg_temp_free_i64(tmp64);
5825
neon_load_reg64(cpu_V0, rn);
5826
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5827
neon_load_reg64(cpu_V1, rm);
5828
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5829
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5831
neon_store_reg64(cpu_V0, rd);
5833
neon_store_reg64(cpu_V1, rd + 1);
5835
} else if ((insn & (1 << 11)) == 0) {
5836
/* Two register misc. */
5837
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5838
size = (insn >> 18) & 3;
5839
/* UNDEF for unknown op values and bad op-size combinations */
5840
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5843
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5844
q && ((rm | rd) & 1)) {
5848
case NEON_2RM_VREV64:
5849
for (pass = 0; pass < (q ? 2 : 1); pass++) {
5850
tmp = neon_load_reg(rm, pass * 2);
5851
tmp2 = neon_load_reg(rm, pass * 2 + 1);
5853
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5854
case 1: gen_swap_half(tmp); break;
5855
case 2: /* no-op */ break;
5858
neon_store_reg(rd, pass * 2 + 1, tmp);
5860
neon_store_reg(rd, pass * 2, tmp2);
5863
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5864
case 1: gen_swap_half(tmp2); break;
5867
neon_store_reg(rd, pass * 2, tmp2);
5871
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5872
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5873
for (pass = 0; pass < q + 1; pass++) {
5874
tmp = neon_load_reg(rm, pass * 2);
5875
gen_neon_widen(cpu_V0, tmp, size, op & 1);
5876
tmp = neon_load_reg(rm, pass * 2 + 1);
5877
gen_neon_widen(cpu_V1, tmp, size, op & 1);
5879
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5880
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5881
case 2: tcg_gen_add_i64(CPU_V001); break;
5884
if (op >= NEON_2RM_VPADAL) {
5886
neon_load_reg64(cpu_V1, rd + pass);
5887
gen_neon_addl(size);
5889
neon_store_reg64(cpu_V0, rd + pass);
5895
for (n = 0; n < (q ? 4 : 2); n += 2) {
5896
tmp = neon_load_reg(rm, n);
5897
tmp2 = neon_load_reg(rd, n + 1);
5898
neon_store_reg(rm, n, tmp2);
5899
neon_store_reg(rd, n + 1, tmp);
5906
if (gen_neon_unzip(rd, rm, size, q)) {
5911
if (gen_neon_zip(rd, rm, size, q)) {
5915
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5916
/* also VQMOVUN; op field and mnemonics don't line up */
5920
TCGV_UNUSED_I32(tmp2);
5921
for (pass = 0; pass < 2; pass++) {
5922
neon_load_reg64(cpu_V0, rm + pass);
5923
tmp = tcg_temp_new_i32();
5924
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5929
neon_store_reg(rd, 0, tmp2);
5930
neon_store_reg(rd, 1, tmp);
5934
case NEON_2RM_VSHLL:
5935
if (q || (rd & 1)) {
5938
tmp = neon_load_reg(rm, 0);
5939
tmp2 = neon_load_reg(rm, 1);
5940
for (pass = 0; pass < 2; pass++) {
5943
gen_neon_widen(cpu_V0, tmp, size, 1);
5944
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5945
neon_store_reg64(cpu_V0, rd + pass);
5948
case NEON_2RM_VCVT_F16_F32:
5949
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5953
tmp = tcg_temp_new_i32();
5954
tmp2 = tcg_temp_new_i32();
5955
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5956
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5957
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5958
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5959
tcg_gen_shli_i32(tmp2, tmp2, 16);
5960
tcg_gen_or_i32(tmp2, tmp2, tmp);
5961
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5962
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5963
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5964
neon_store_reg(rd, 0, tmp2);
5965
tmp2 = tcg_temp_new_i32();
5966
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5967
tcg_gen_shli_i32(tmp2, tmp2, 16);
5968
tcg_gen_or_i32(tmp2, tmp2, tmp);
5969
neon_store_reg(rd, 1, tmp2);
5970
tcg_temp_free_i32(tmp);
5972
case NEON_2RM_VCVT_F32_F16:
5973
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5977
tmp3 = tcg_temp_new_i32();
5978
tmp = neon_load_reg(rm, 0);
5979
tmp2 = neon_load_reg(rm, 1);
5980
tcg_gen_ext16u_i32(tmp3, tmp);
5981
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5982
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5983
tcg_gen_shri_i32(tmp3, tmp, 16);
5984
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5985
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5986
tcg_temp_free_i32(tmp);
5987
tcg_gen_ext16u_i32(tmp3, tmp2);
5988
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5989
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5990
tcg_gen_shri_i32(tmp3, tmp2, 16);
5991
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5992
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5993
tcg_temp_free_i32(tmp2);
5994
tcg_temp_free_i32(tmp3);
5998
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5999
if (neon_2rm_is_float_op(op)) {
6000
tcg_gen_ld_f32(cpu_F0s, cpu_env,
6001
neon_reg_offset(rm, pass));
6002
TCGV_UNUSED_I32(tmp);
6004
tmp = neon_load_reg(rm, pass);
6007
case NEON_2RM_VREV32:
6009
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6010
case 1: gen_swap_half(tmp); break;
6014
case NEON_2RM_VREV16:
6019
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6020
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6021
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6027
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6028
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6029
case 2: gen_helper_clz(tmp, tmp); break;
6034
gen_helper_neon_cnt_u8(tmp, tmp);
6037
tcg_gen_not_i32(tmp, tmp);
6039
case NEON_2RM_VQABS:
6042
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6045
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6048
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6053
case NEON_2RM_VQNEG:
6056
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6059
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6062
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6067
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6068
tmp2 = tcg_const_i32(0);
6070
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6071
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6072
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6075
tcg_temp_free_i32(tmp2);
6076
if (op == NEON_2RM_VCLE0) {
6077
tcg_gen_not_i32(tmp, tmp);
6080
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6081
tmp2 = tcg_const_i32(0);
6083
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6084
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6085
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6088
tcg_temp_free_i32(tmp2);
6089
if (op == NEON_2RM_VCLT0) {
6090
tcg_gen_not_i32(tmp, tmp);
6093
case NEON_2RM_VCEQ0:
6094
tmp2 = tcg_const_i32(0);
6096
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6097
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6098
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6101
tcg_temp_free_i32(tmp2);
6105
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6106
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6107
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6112
tmp2 = tcg_const_i32(0);
6113
gen_neon_rsb(size, tmp, tmp2);
6114
tcg_temp_free_i32(tmp2);
6116
case NEON_2RM_VCGT0_F:
6118
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6119
tmp2 = tcg_const_i32(0);
6120
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6121
tcg_temp_free_i32(tmp2);
6122
tcg_temp_free_ptr(fpstatus);
6125
case NEON_2RM_VCGE0_F:
6127
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6128
tmp2 = tcg_const_i32(0);
6129
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6130
tcg_temp_free_i32(tmp2);
6131
tcg_temp_free_ptr(fpstatus);
6134
case NEON_2RM_VCEQ0_F:
6136
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6137
tmp2 = tcg_const_i32(0);
6138
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6139
tcg_temp_free_i32(tmp2);
6140
tcg_temp_free_ptr(fpstatus);
6143
case NEON_2RM_VCLE0_F:
6145
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6146
tmp2 = tcg_const_i32(0);
6147
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6148
tcg_temp_free_i32(tmp2);
6149
tcg_temp_free_ptr(fpstatus);
6152
case NEON_2RM_VCLT0_F:
6154
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6155
tmp2 = tcg_const_i32(0);
6156
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6157
tcg_temp_free_i32(tmp2);
6158
tcg_temp_free_ptr(fpstatus);
6161
case NEON_2RM_VABS_F:
6164
case NEON_2RM_VNEG_F:
6168
tmp2 = neon_load_reg(rd, pass);
6169
neon_store_reg(rm, pass, tmp2);
6172
tmp2 = neon_load_reg(rd, pass);
6174
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6175
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6178
neon_store_reg(rm, pass, tmp2);
6180
case NEON_2RM_VRECPE:
6181
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6183
case NEON_2RM_VRSQRTE:
6184
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6186
case NEON_2RM_VRECPE_F:
6187
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6189
case NEON_2RM_VRSQRTE_F:
6190
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6192
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6195
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6198
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6199
gen_vfp_tosiz(0, 1);
6201
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6202
gen_vfp_touiz(0, 1);
6205
/* Reserved op values were caught by the
6206
* neon_2rm_sizes[] check earlier.
6210
if (neon_2rm_is_float_op(op)) {
6211
tcg_gen_st_f32(cpu_F0s, cpu_env,
6212
neon_reg_offset(rd, pass));
6214
neon_store_reg(rd, pass, tmp);
6219
} else if ((insn & (1 << 10)) == 0) {
6221
int n = ((insn >> 8) & 3) + 1;
6222
if ((rn + n) > 32) {
6223
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6224
* helper function running off the end of the register file.
6229
if (insn & (1 << 6)) {
6230
tmp = neon_load_reg(rd, 0);
6232
tmp = tcg_temp_new_i32();
6233
tcg_gen_movi_i32(tmp, 0);
6235
tmp2 = neon_load_reg(rm, 0);
6236
tmp4 = tcg_const_i32(rn);
6237
tmp5 = tcg_const_i32(n);
6238
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6239
tcg_temp_free_i32(tmp);
6240
if (insn & (1 << 6)) {
6241
tmp = neon_load_reg(rd, 1);
6243
tmp = tcg_temp_new_i32();
6244
tcg_gen_movi_i32(tmp, 0);
6246
tmp3 = neon_load_reg(rm, 1);
6247
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6248
tcg_temp_free_i32(tmp5);
6249
tcg_temp_free_i32(tmp4);
6250
neon_store_reg(rd, 0, tmp2);
6251
neon_store_reg(rd, 1, tmp3);
6252
tcg_temp_free_i32(tmp);
6253
} else if ((insn & 0x380) == 0) {
6255
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6258
if (insn & (1 << 19)) {
6259
tmp = neon_load_reg(rm, 1);
6261
tmp = neon_load_reg(rm, 0);
6263
if (insn & (1 << 16)) {
6264
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6265
} else if (insn & (1 << 17)) {
6266
if ((insn >> 18) & 1)
6267
gen_neon_dup_high16(tmp);
6269
gen_neon_dup_low16(tmp);
6271
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6272
tmp2 = tcg_temp_new_i32();
6273
tcg_gen_mov_i32(tmp2, tmp);
6274
neon_store_reg(rd, pass, tmp2);
6276
tcg_temp_free_i32(tmp);
6285
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6287
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6288
const ARMCPRegInfo *ri;
6289
ARMCPU *cpu = arm_env_get_cpu(env);
6291
cpnum = (insn >> 8) & 0xf;
6292
if (arm_feature(env, ARM_FEATURE_XSCALE)
6293
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6296
/* First check for coprocessor space used for actual instructions */
6300
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6301
return disas_iwmmxt_insn(env, s, insn);
6302
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6303
return disas_dsp_insn(env, s, insn);
6308
return disas_vfp_insn (env, s, insn);
6313
/* Otherwise treat as a generic register access */
6314
is64 = (insn & (1 << 25)) == 0;
6315
if (!is64 && ((insn & (1 << 4)) == 0)) {
6323
opc1 = (insn >> 4) & 0xf;
6325
rt2 = (insn >> 16) & 0xf;
6327
crn = (insn >> 16) & 0xf;
6328
opc1 = (insn >> 21) & 7;
6329
opc2 = (insn >> 5) & 7;
6332
isread = (insn >> 20) & 1;
6333
rt = (insn >> 12) & 0xf;
6335
ri = get_arm_cp_reginfo(cpu,
6336
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6338
/* Check access permissions */
6339
if (!cp_access_ok(env, ri, isread)) {
6343
/* Handle special cases first */
6344
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6351
gen_set_pc_im(s, s->pc);
6352
s->is_jmp = DISAS_WFI;
6358
if (use_icount && (ri->type & ARM_CP_IO)) {
6367
if (ri->type & ARM_CP_CONST) {
6368
tmp64 = tcg_const_i64(ri->resetvalue);
6369
} else if (ri->readfn) {
6371
gen_set_pc_im(s, s->pc);
6372
tmp64 = tcg_temp_new_i64();
6373
tmpptr = tcg_const_ptr(ri);
6374
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6375
tcg_temp_free_ptr(tmpptr);
6377
tmp64 = tcg_temp_new_i64();
6378
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6380
tmp = tcg_temp_new_i32();
6381
tcg_gen_trunc_i64_i32(tmp, tmp64);
6382
store_reg(s, rt, tmp);
6383
tcg_gen_shri_i64(tmp64, tmp64, 32);
6384
tmp = tcg_temp_new_i32();
6385
tcg_gen_trunc_i64_i32(tmp, tmp64);
6386
tcg_temp_free_i64(tmp64);
6387
store_reg(s, rt2, tmp);
6390
if (ri->type & ARM_CP_CONST) {
6391
tmp = tcg_const_i32(ri->resetvalue);
6392
} else if (ri->readfn) {
6394
gen_set_pc_im(s, s->pc);
6395
tmp = tcg_temp_new_i32();
6396
tmpptr = tcg_const_ptr(ri);
6397
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6398
tcg_temp_free_ptr(tmpptr);
6400
tmp = load_cpu_offset(ri->fieldoffset);
6403
/* Destination register of r15 for 32 bit loads sets
6404
* the condition codes from the high 4 bits of the value
6407
tcg_temp_free_i32(tmp);
6409
store_reg(s, rt, tmp);
6414
if (ri->type & ARM_CP_CONST) {
6415
/* If not forbidden by access permissions, treat as WI */
6420
TCGv_i32 tmplo, tmphi;
6421
TCGv_i64 tmp64 = tcg_temp_new_i64();
6422
tmplo = load_reg(s, rt);
6423
tmphi = load_reg(s, rt2);
6424
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6425
tcg_temp_free_i32(tmplo);
6426
tcg_temp_free_i32(tmphi);
6428
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6429
gen_set_pc_im(s, s->pc);
6430
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6431
tcg_temp_free_ptr(tmpptr);
6433
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6435
tcg_temp_free_i64(tmp64);
6440
gen_set_pc_im(s, s->pc);
6441
tmp = load_reg(s, rt);
6442
tmpptr = tcg_const_ptr(ri);
6443
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6444
tcg_temp_free_ptr(tmpptr);
6445
tcg_temp_free_i32(tmp);
6447
TCGv_i32 tmp = load_reg(s, rt);
6448
store_cpu_offset(tmp, ri->fieldoffset);
6453
if (use_icount && (ri->type & ARM_CP_IO)) {
6454
/* I/O operations must end the TB here (whether read or write) */
6457
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6458
/* We default to ending the TB on a coprocessor register write,
6459
* but allow this to be suppressed by the register definition
6460
* (usually only necessary to work around guest bugs).
6472
/* Store a 64-bit value to a register pair. Clobbers val. */
6473
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6476
tmp = tcg_temp_new_i32();
6477
tcg_gen_trunc_i64_i32(tmp, val);
6478
store_reg(s, rlow, tmp);
6479
tmp = tcg_temp_new_i32();
6480
tcg_gen_shri_i64(val, val, 32);
6481
tcg_gen_trunc_i64_i32(tmp, val);
6482
store_reg(s, rhigh, tmp);
6485
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6486
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6491
/* Load value and extend to 64 bits. */
6492
tmp = tcg_temp_new_i64();
6493
tmp2 = load_reg(s, rlow);
6494
tcg_gen_extu_i32_i64(tmp, tmp2);
6495
tcg_temp_free_i32(tmp2);
6496
tcg_gen_add_i64(val, val, tmp);
6497
tcg_temp_free_i64(tmp);
6500
/* load and add a 64-bit value from a register pair. */
6501
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6507
/* Load 64-bit value rd:rn. */
6508
tmpl = load_reg(s, rlow);
6509
tmph = load_reg(s, rhigh);
6510
tmp = tcg_temp_new_i64();
6511
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6512
tcg_temp_free_i32(tmpl);
6513
tcg_temp_free_i32(tmph);
6514
tcg_gen_add_i64(val, val, tmp);
6515
tcg_temp_free_i64(tmp);
6518
/* Set N and Z flags from hi|lo. */
6519
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6521
tcg_gen_mov_i32(cpu_NF, hi);
6522
tcg_gen_or_i32(cpu_ZF, lo, hi);
6525
/* Load/Store exclusive instructions are implemented by remembering
6526
the value/address loaded, and seeing if these are the same
6527
when the store is performed. This should be sufficient to implement
6528
the architecturally mandated semantics, and avoids having to monitor
6531
In system emulation mode only one CPU will be running at once, so
6532
this sequence is effectively atomic. In user emulation mode we
6533
throw an exception and handle the atomic operation elsewhere. */
6534
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6535
TCGv_i32 addr, int size)
6537
TCGv_i32 tmp = tcg_temp_new_i32();
6541
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6544
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6548
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6553
tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6554
store_reg(s, rt, tmp);
6556
TCGv_i32 tmp2 = tcg_temp_new_i32();
6557
tcg_gen_addi_i32(tmp2, addr, 4);
6558
tmp = tcg_temp_new_i32();
6559
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6560
tcg_temp_free_i32(tmp2);
6561
tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6562
store_reg(s, rt2, tmp);
6564
tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6567
static void gen_clrex(DisasContext *s)
6569
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6572
#ifdef CONFIG_USER_ONLY
6573
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6574
TCGv_i32 addr, int size)
6576
tcg_gen_mov_i32(cpu_exclusive_test, addr);
6577
tcg_gen_movi_i32(cpu_exclusive_info,
6578
size | (rd << 4) | (rt << 8) | (rt2 << 12));
6579
gen_exception_insn(s, 4, EXCP_STREX);
6582
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6583
TCGv_i32 addr, int size)
6589
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6595
fail_label = gen_new_label();
6596
done_label = gen_new_label();
6597
tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6598
tmp = tcg_temp_new_i32();
6601
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6604
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6608
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6613
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6614
tcg_temp_free_i32(tmp);
6616
TCGv_i32 tmp2 = tcg_temp_new_i32();
6617
tcg_gen_addi_i32(tmp2, addr, 4);
6618
tmp = tcg_temp_new_i32();
6619
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6620
tcg_temp_free_i32(tmp2);
6621
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6622
tcg_temp_free_i32(tmp);
6624
tmp = load_reg(s, rt);
6627
gen_aa32_st8(tmp, addr, IS_USER(s));
6630
gen_aa32_st16(tmp, addr, IS_USER(s));
6634
gen_aa32_st32(tmp, addr, IS_USER(s));
6639
tcg_temp_free_i32(tmp);
6641
tcg_gen_addi_i32(addr, addr, 4);
6642
tmp = load_reg(s, rt2);
6643
gen_aa32_st32(tmp, addr, IS_USER(s));
6644
tcg_temp_free_i32(tmp);
6646
tcg_gen_movi_i32(cpu_R[rd], 0);
6647
tcg_gen_br(done_label);
6648
gen_set_label(fail_label);
6649
tcg_gen_movi_i32(cpu_R[rd], 1);
6650
gen_set_label(done_label);
6651
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6658
* @mode: mode field from insn (which stack to store to)
6659
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6660
* @writeback: true if writeback bit set
6662
* Generate code for the SRS (Store Return State) insn.
6664
static void gen_srs(DisasContext *s,
6665
uint32_t mode, uint32_t amode, bool writeback)
6668
TCGv_i32 addr = tcg_temp_new_i32();
6669
TCGv_i32 tmp = tcg_const_i32(mode);
6670
gen_helper_get_r13_banked(addr, cpu_env, tmp);
6671
tcg_temp_free_i32(tmp);
6688
tcg_gen_addi_i32(addr, addr, offset);
6689
tmp = load_reg(s, 14);
6690
gen_aa32_st32(tmp, addr, 0);
6691
tcg_temp_free_i32(tmp);
6692
tmp = load_cpu_field(spsr);
6693
tcg_gen_addi_i32(addr, addr, 4);
6694
gen_aa32_st32(tmp, addr, 0);
6695
tcg_temp_free_i32(tmp);
6713
tcg_gen_addi_i32(addr, addr, offset);
6714
tmp = tcg_const_i32(mode);
6715
gen_helper_set_r13_banked(cpu_env, tmp, addr);
6716
tcg_temp_free_i32(tmp);
6718
tcg_temp_free_i32(addr);
6721
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6723
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6730
insn = arm_ldl_code(env, s->pc, s->bswap_code);
6733
/* M variants do not implement ARM mode. */
6738
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6739
* choose to UNDEF. In ARMv5 and above the space is used
6740
* for miscellaneous unconditional instructions.
6744
/* Unconditional instructions. */
6745
if (((insn >> 25) & 7) == 1) {
6746
/* NEON Data processing. */
6747
if (!arm_feature(env, ARM_FEATURE_NEON))
6750
if (disas_neon_data_insn(env, s, insn))
6754
if ((insn & 0x0f100000) == 0x04000000) {
6755
/* NEON load/store. */
6756
if (!arm_feature(env, ARM_FEATURE_NEON))
6759
if (disas_neon_ls_insn(env, s, insn))
6763
if (((insn & 0x0f30f000) == 0x0510f000) ||
6764
((insn & 0x0f30f010) == 0x0710f000)) {
6765
if ((insn & (1 << 22)) == 0) {
6767
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6771
/* Otherwise PLD; v5TE+ */
6775
if (((insn & 0x0f70f000) == 0x0450f000) ||
6776
((insn & 0x0f70f010) == 0x0650f000)) {
6778
return; /* PLI; V7 */
6780
if (((insn & 0x0f700000) == 0x04100000) ||
6781
((insn & 0x0f700010) == 0x06100000)) {
6782
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6785
return; /* v7MP: Unallocated memory hint: must NOP */
6788
if ((insn & 0x0ffffdff) == 0x01010000) {
6791
if (((insn >> 9) & 1) != s->bswap_code) {
6792
/* Dynamic endianness switching not implemented. */
6793
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
6797
} else if ((insn & 0x0fffff00) == 0x057ff000) {
6798
switch ((insn >> 4) & 0xf) {
6807
/* We don't emulate caches so these are a no-op. */
6812
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6818
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
6820
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6826
rn = (insn >> 16) & 0xf;
6827
addr = load_reg(s, rn);
6828
i = (insn >> 23) & 3;
6830
case 0: offset = -4; break; /* DA */
6831
case 1: offset = 0; break; /* IA */
6832
case 2: offset = -8; break; /* DB */
6833
case 3: offset = 4; break; /* IB */
6837
tcg_gen_addi_i32(addr, addr, offset);
6838
/* Load PC into tmp and CPSR into tmp2. */
6839
tmp = tcg_temp_new_i32();
6840
gen_aa32_ld32u(tmp, addr, 0);
6841
tcg_gen_addi_i32(addr, addr, 4);
6842
tmp2 = tcg_temp_new_i32();
6843
gen_aa32_ld32u(tmp2, addr, 0);
6844
if (insn & (1 << 21)) {
6845
/* Base writeback. */
6847
case 0: offset = -8; break;
6848
case 1: offset = 4; break;
6849
case 2: offset = -4; break;
6850
case 3: offset = 0; break;
6854
tcg_gen_addi_i32(addr, addr, offset);
6855
store_reg(s, rn, addr);
6857
tcg_temp_free_i32(addr);
6859
gen_rfe(s, tmp, tmp2);
6861
} else if ((insn & 0x0e000000) == 0x0a000000) {
6862
/* branch link and change to thumb (blx <offset>) */
6865
val = (uint32_t)s->pc;
6866
tmp = tcg_temp_new_i32();
6867
tcg_gen_movi_i32(tmp, val);
6868
store_reg(s, 14, tmp);
6869
/* Sign-extend the 24-bit offset */
6870
offset = (((int32_t)insn) << 8) >> 8;
6871
/* offset * 4 + bit24 * 2 + (thumb bit) */
6872
val += (offset << 2) | ((insn >> 23) & 2) | 1;
6873
/* pipeline offset */
6875
/* protected by ARCH(5); above, near the start of uncond block */
6878
} else if ((insn & 0x0e000f00) == 0x0c000100) {
6879
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6880
/* iWMMXt register transfer. */
6881
if (env->cp15.c15_cpar & (1 << 1))
6882
if (!disas_iwmmxt_insn(env, s, insn))
6885
} else if ((insn & 0x0fe00000) == 0x0c400000) {
6886
/* Coprocessor double register transfer. */
6888
/* XXX doesn't belong in the trustzone patch: should just UNDEF? */
6889
cpu_abort(env, "unsupported coprocessor double register transfer\n");
6890
} else if ((insn & 0x0f000010) == 0x0e000010) {
6891
/* Additional coprocessor register transfer. */
6892
if (!disas_coproc_insn(env, s, insn)) {
6895
} else if ((insn & 0x0ff10020) == 0x01000000) {
6898
/* cps (privileged) */
6902
if (insn & (1 << 19)) {
6903
if (insn & (1 << 8))
6905
if (insn & (1 << 7))
6907
if (insn & (1 << 6))
6909
if (insn & (1 << 18))
6912
if (insn & (1 << 17)) {
6914
val |= (insn & 0x1f);
6917
gen_set_psr_im(s, mask, 0, val);
6924
/* if not always execute, we generate a conditional jump to
6926
s->condlabel = gen_new_label();
6927
gen_test_cc(cond ^ 1, s->condlabel);
6930
if ((insn & 0x0f900000) == 0x03000000) {
6931
if ((insn & (1 << 21)) == 0) {
6933
rd = (insn >> 12) & 0xf;
6934
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6935
if ((insn & (1 << 22)) == 0) {
6937
tmp = tcg_temp_new_i32();
6938
tcg_gen_movi_i32(tmp, val);
6941
tmp = load_reg(s, rd);
6942
tcg_gen_ext16u_i32(tmp, tmp);
6943
tcg_gen_ori_i32(tmp, tmp, val << 16);
6945
store_reg(s, rd, tmp);
6947
if (((insn >> 12) & 0xf) != 0xf)
6949
if (((insn >> 16) & 0xf) == 0) {
6950
gen_nop_hint(s, insn & 0xff);
6952
/* CPSR = immediate */
6954
shift = ((insn >> 8) & 0xf) * 2;
6956
val = (val >> shift) | (val << (32 - shift));
6957
i = ((insn & (1 << 22)) != 0);
6958
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6962
} else if ((insn & 0x0f900000) == 0x01000000
6963
&& (insn & 0x00000090) != 0x00000090) {
6964
/* miscellaneous instructions */
6965
op1 = (insn >> 21) & 3;
6966
sh = (insn >> 4) & 0xf;
6969
case 0x0: /* move program status register */
6972
tmp = load_reg(s, rm);
6973
i = ((op1 & 2) != 0);
6974
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6978
rd = (insn >> 12) & 0xf;
6982
tmp = load_cpu_field(spsr);
6984
tmp = tcg_temp_new_i32();
6985
gen_helper_cpsr_read(tmp, cpu_env);
6987
store_reg(s, rd, tmp);
6992
/* branch/exchange thumb (bx). */
6994
tmp = load_reg(s, rm);
6996
} else if (op1 == 3) {
6999
rd = (insn >> 12) & 0xf;
7000
tmp = load_reg(s, rm);
7001
gen_helper_clz(tmp, tmp);
7002
store_reg(s, rd, tmp);
7010
/* Trivial implementation equivalent to bx. */
7011
tmp = load_reg(s, rm);
7022
/* branch link/exchange thumb (blx) */
7023
tmp = load_reg(s, rm);
7024
tmp2 = tcg_temp_new_i32();
7025
tcg_gen_movi_i32(tmp2, s->pc);
7026
store_reg(s, 14, tmp2);
7029
case 0x5: /* saturating add/subtract */
7031
rd = (insn >> 12) & 0xf;
7032
rn = (insn >> 16) & 0xf;
7033
tmp = load_reg(s, rm);
7034
tmp2 = load_reg(s, rn);
7036
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7038
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7040
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7041
tcg_temp_free_i32(tmp2);
7042
store_reg(s, rd, tmp);
7048
gen_exception_insn(s, 4, EXCP_BKPT);
7049
} else if (op1 == 3) {
7051
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
7059
case 0x8: /* signed multiply */
7064
rs = (insn >> 8) & 0xf;
7065
rn = (insn >> 12) & 0xf;
7066
rd = (insn >> 16) & 0xf;
7068
/* (32 * 16) >> 16 */
7069
tmp = load_reg(s, rm);
7070
tmp2 = load_reg(s, rs);
7072
tcg_gen_sari_i32(tmp2, tmp2, 16);
7075
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7076
tcg_gen_shri_i64(tmp64, tmp64, 16);
7077
tmp = tcg_temp_new_i32();
7078
tcg_gen_trunc_i64_i32(tmp, tmp64);
7079
tcg_temp_free_i64(tmp64);
7080
if ((sh & 2) == 0) {
7081
tmp2 = load_reg(s, rn);
7082
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7083
tcg_temp_free_i32(tmp2);
7085
store_reg(s, rd, tmp);
7088
tmp = load_reg(s, rm);
7089
tmp2 = load_reg(s, rs);
7090
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7091
tcg_temp_free_i32(tmp2);
7093
tmp64 = tcg_temp_new_i64();
7094
tcg_gen_ext_i32_i64(tmp64, tmp);
7095
tcg_temp_free_i32(tmp);
7096
gen_addq(s, tmp64, rn, rd);
7097
gen_storeq_reg(s, rn, rd, tmp64);
7098
tcg_temp_free_i64(tmp64);
7101
tmp2 = load_reg(s, rn);
7102
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7103
tcg_temp_free_i32(tmp2);
7105
store_reg(s, rd, tmp);
7112
} else if (((insn & 0x0e000000) == 0 &&
7113
(insn & 0x00000090) != 0x90) ||
7114
((insn & 0x0e000000) == (1 << 25))) {
7115
int set_cc, logic_cc, shiftop;
7117
op1 = (insn >> 21) & 0xf;
7118
set_cc = (insn >> 20) & 1;
7119
logic_cc = table_logic_cc[op1] & set_cc;
7121
/* data processing instruction */
7122
if (insn & (1 << 25)) {
7123
/* immediate operand */
7125
shift = ((insn >> 8) & 0xf) * 2;
7127
val = (val >> shift) | (val << (32 - shift));
7129
tmp2 = tcg_temp_new_i32();
7130
tcg_gen_movi_i32(tmp2, val);
7131
if (logic_cc && shift) {
7132
gen_set_CF_bit31(tmp2);
7137
tmp2 = load_reg(s, rm);
7138
shiftop = (insn >> 5) & 3;
7139
if (!(insn & (1 << 4))) {
7140
shift = (insn >> 7) & 0x1f;
7141
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7143
rs = (insn >> 8) & 0xf;
7144
tmp = load_reg(s, rs);
7145
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7148
if (op1 != 0x0f && op1 != 0x0d) {
7149
rn = (insn >> 16) & 0xf;
7150
tmp = load_reg(s, rn);
7152
TCGV_UNUSED_I32(tmp);
7154
rd = (insn >> 12) & 0xf;
7157
tcg_gen_and_i32(tmp, tmp, tmp2);
7161
store_reg_bx(env, s, rd, tmp);
7164
tcg_gen_xor_i32(tmp, tmp, tmp2);
7168
store_reg_bx(env, s, rd, tmp);
7171
if (set_cc && rd == 15) {
7172
/* SUBS r15, ... is used for exception return. */
7176
gen_sub_CC(tmp, tmp, tmp2);
7177
gen_exception_return(s, tmp);
7180
gen_sub_CC(tmp, tmp, tmp2);
7182
tcg_gen_sub_i32(tmp, tmp, tmp2);
7184
store_reg_bx(env, s, rd, tmp);
7189
gen_sub_CC(tmp, tmp2, tmp);
7191
tcg_gen_sub_i32(tmp, tmp2, tmp);
7193
store_reg_bx(env, s, rd, tmp);
7197
gen_add_CC(tmp, tmp, tmp2);
7199
tcg_gen_add_i32(tmp, tmp, tmp2);
7201
store_reg_bx(env, s, rd, tmp);
7205
gen_adc_CC(tmp, tmp, tmp2);
7207
gen_add_carry(tmp, tmp, tmp2);
7209
store_reg_bx(env, s, rd, tmp);
7213
gen_sbc_CC(tmp, tmp, tmp2);
7215
gen_sub_carry(tmp, tmp, tmp2);
7217
store_reg_bx(env, s, rd, tmp);
7221
gen_sbc_CC(tmp, tmp2, tmp);
7223
gen_sub_carry(tmp, tmp2, tmp);
7225
store_reg_bx(env, s, rd, tmp);
7229
tcg_gen_and_i32(tmp, tmp, tmp2);
7232
tcg_temp_free_i32(tmp);
7236
tcg_gen_xor_i32(tmp, tmp, tmp2);
7239
tcg_temp_free_i32(tmp);
7243
gen_sub_CC(tmp, tmp, tmp2);
7245
tcg_temp_free_i32(tmp);
7249
gen_add_CC(tmp, tmp, tmp2);
7251
tcg_temp_free_i32(tmp);
7254
tcg_gen_or_i32(tmp, tmp, tmp2);
7258
store_reg_bx(env, s, rd, tmp);
7261
if (logic_cc && rd == 15) {
7262
/* MOVS r15, ... is used for exception return. */
7266
gen_exception_return(s, tmp2);
7271
store_reg_bx(env, s, rd, tmp2);
7275
tcg_gen_andc_i32(tmp, tmp, tmp2);
7279
store_reg_bx(env, s, rd, tmp);
7283
tcg_gen_not_i32(tmp2, tmp2);
7287
store_reg_bx(env, s, rd, tmp2);
7290
if (op1 != 0x0f && op1 != 0x0d) {
7291
tcg_temp_free_i32(tmp2);
7294
/* other instructions */
7295
op1 = (insn >> 24) & 0xf;
7299
/* multiplies, extra load/stores */
7300
sh = (insn >> 5) & 3;
7303
rd = (insn >> 16) & 0xf;
7304
rn = (insn >> 12) & 0xf;
7305
rs = (insn >> 8) & 0xf;
7307
op1 = (insn >> 20) & 0xf;
7309
case 0: case 1: case 2: case 3: case 6:
7311
tmp = load_reg(s, rs);
7312
tmp2 = load_reg(s, rm);
7313
tcg_gen_mul_i32(tmp, tmp, tmp2);
7314
tcg_temp_free_i32(tmp2);
7315
if (insn & (1 << 22)) {
7316
/* Subtract (mls) */
7318
tmp2 = load_reg(s, rn);
7319
tcg_gen_sub_i32(tmp, tmp2, tmp);
7320
tcg_temp_free_i32(tmp2);
7321
} else if (insn & (1 << 21)) {
7323
tmp2 = load_reg(s, rn);
7324
tcg_gen_add_i32(tmp, tmp, tmp2);
7325
tcg_temp_free_i32(tmp2);
7327
if (insn & (1 << 20))
7329
store_reg(s, rd, tmp);
7332
/* 64 bit mul double accumulate (UMAAL) */
7334
tmp = load_reg(s, rs);
7335
tmp2 = load_reg(s, rm);
7336
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7337
gen_addq_lo(s, tmp64, rn);
7338
gen_addq_lo(s, tmp64, rd);
7339
gen_storeq_reg(s, rn, rd, tmp64);
7340
tcg_temp_free_i64(tmp64);
7342
case 8: case 9: case 10: case 11:
7343
case 12: case 13: case 14: case 15:
7344
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7345
tmp = load_reg(s, rs);
7346
tmp2 = load_reg(s, rm);
7347
if (insn & (1 << 22)) {
7348
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7350
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7352
if (insn & (1 << 21)) { /* mult accumulate */
7353
TCGv_i32 al = load_reg(s, rn);
7354
TCGv_i32 ah = load_reg(s, rd);
7355
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7356
tcg_temp_free_i32(al);
7357
tcg_temp_free_i32(ah);
7359
if (insn & (1 << 20)) {
7360
gen_logicq_cc(tmp, tmp2);
7362
store_reg(s, rn, tmp);
7363
store_reg(s, rd, tmp2);
7369
rn = (insn >> 16) & 0xf;
7370
rd = (insn >> 12) & 0xf;
7371
if (insn & (1 << 23)) {
7372
/* load/store exclusive */
7373
int op2 = (insn >> 8) & 3;
7374
op1 = (insn >> 21) & 0x3;
7377
case 0: /* lda/stl */
7383
case 1: /* reserved */
7385
case 2: /* ldaex/stlex */
7388
case 3: /* ldrex/strex */
7397
addr = tcg_temp_local_new_i32();
7398
load_reg_var(s, addr, rn);
7400
/* Since the emulation does not have barriers,
7401
the acquire/release semantics need no special
7404
if (insn & (1 << 20)) {
7405
tmp = tcg_temp_new_i32();
7408
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7411
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7414
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7419
store_reg(s, rd, tmp);
7422
tmp = load_reg(s, rm);
7425
gen_aa32_st32(tmp, addr, IS_USER(s));
7428
gen_aa32_st8(tmp, addr, IS_USER(s));
7431
gen_aa32_st16(tmp, addr, IS_USER(s));
7436
tcg_temp_free_i32(tmp);
7438
} else if (insn & (1 << 20)) {
7441
gen_load_exclusive(s, rd, 15, addr, 2);
7443
case 1: /* ldrexd */
7444
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7446
case 2: /* ldrexb */
7447
gen_load_exclusive(s, rd, 15, addr, 0);
7449
case 3: /* ldrexh */
7450
gen_load_exclusive(s, rd, 15, addr, 1);
7459
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7461
case 1: /* strexd */
7462
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7464
case 2: /* strexb */
7465
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7467
case 3: /* strexh */
7468
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7474
tcg_temp_free_i32(addr);
7476
/* SWP instruction */
7479
/* ??? This is not really atomic. However we know
7480
we never have multiple CPUs running in parallel,
7481
so it is good enough. */
7482
addr = load_reg(s, rn);
7483
tmp = load_reg(s, rm);
7484
tmp2 = tcg_temp_new_i32();
7485
if (insn & (1 << 22)) {
7486
gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7487
gen_aa32_st8(tmp, addr, IS_USER(s));
7489
gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7490
gen_aa32_st32(tmp, addr, IS_USER(s));
7492
tcg_temp_free_i32(tmp);
7493
tcg_temp_free_i32(addr);
7494
store_reg(s, rd, tmp2);
7500
/* Misc load/store */
7501
rn = (insn >> 16) & 0xf;
7502
rd = (insn >> 12) & 0xf;
7503
addr = load_reg(s, rn);
7504
if (insn & (1 << 24))
7505
gen_add_datah_offset(s, insn, 0, addr);
7507
if (insn & (1 << 20)) {
7509
tmp = tcg_temp_new_i32();
7512
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7515
gen_aa32_ld8s(tmp, addr, IS_USER(s));
7519
gen_aa32_ld16s(tmp, addr, IS_USER(s));
7523
} else if (sh & 2) {
7528
tmp = load_reg(s, rd);
7529
gen_aa32_st32(tmp, addr, IS_USER(s));
7530
tcg_temp_free_i32(tmp);
7531
tcg_gen_addi_i32(addr, addr, 4);
7532
tmp = load_reg(s, rd + 1);
7533
gen_aa32_st32(tmp, addr, IS_USER(s));
7534
tcg_temp_free_i32(tmp);
7538
tmp = tcg_temp_new_i32();
7539
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7540
store_reg(s, rd, tmp);
7541
tcg_gen_addi_i32(addr, addr, 4);
7542
tmp = tcg_temp_new_i32();
7543
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7547
address_offset = -4;
7550
tmp = load_reg(s, rd);
7551
gen_aa32_st16(tmp, addr, IS_USER(s));
7552
tcg_temp_free_i32(tmp);
7555
/* Perform base writeback before the loaded value to
7556
ensure correct behavior with overlapping index registers.
7557
ldrd with base writeback is is undefined if the
7558
destination and index registers overlap. */
7559
if (!(insn & (1 << 24))) {
7560
gen_add_datah_offset(s, insn, address_offset, addr);
7561
store_reg(s, rn, addr);
7562
} else if (insn & (1 << 21)) {
7564
tcg_gen_addi_i32(addr, addr, address_offset);
7565
store_reg(s, rn, addr);
7567
tcg_temp_free_i32(addr);
7570
/* Complete the load. */
7571
store_reg(s, rd, tmp);
7580
if (insn & (1 << 4)) {
7582
/* Armv6 Media instructions. */
7584
rn = (insn >> 16) & 0xf;
7585
rd = (insn >> 12) & 0xf;
7586
rs = (insn >> 8) & 0xf;
7587
switch ((insn >> 23) & 3) {
7588
case 0: /* Parallel add/subtract. */
7589
op1 = (insn >> 20) & 7;
7590
tmp = load_reg(s, rn);
7591
tmp2 = load_reg(s, rm);
7592
sh = (insn >> 5) & 7;
7593
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7595
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7596
tcg_temp_free_i32(tmp2);
7597
store_reg(s, rd, tmp);
7600
if ((insn & 0x00700020) == 0) {
7601
/* Halfword pack. */
7602
tmp = load_reg(s, rn);
7603
tmp2 = load_reg(s, rm);
7604
shift = (insn >> 7) & 0x1f;
7605
if (insn & (1 << 6)) {
7609
tcg_gen_sari_i32(tmp2, tmp2, shift);
7610
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7611
tcg_gen_ext16u_i32(tmp2, tmp2);
7615
tcg_gen_shli_i32(tmp2, tmp2, shift);
7616
tcg_gen_ext16u_i32(tmp, tmp);
7617
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7619
tcg_gen_or_i32(tmp, tmp, tmp2);
7620
tcg_temp_free_i32(tmp2);
7621
store_reg(s, rd, tmp);
7622
} else if ((insn & 0x00200020) == 0x00200000) {
7624
tmp = load_reg(s, rm);
7625
shift = (insn >> 7) & 0x1f;
7626
if (insn & (1 << 6)) {
7629
tcg_gen_sari_i32(tmp, tmp, shift);
7631
tcg_gen_shli_i32(tmp, tmp, shift);
7633
sh = (insn >> 16) & 0x1f;
7634
tmp2 = tcg_const_i32(sh);
7635
if (insn & (1 << 22))
7636
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7638
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7639
tcg_temp_free_i32(tmp2);
7640
store_reg(s, rd, tmp);
7641
} else if ((insn & 0x00300fe0) == 0x00200f20) {
7643
tmp = load_reg(s, rm);
7644
sh = (insn >> 16) & 0x1f;
7645
tmp2 = tcg_const_i32(sh);
7646
if (insn & (1 << 22))
7647
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7649
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7650
tcg_temp_free_i32(tmp2);
7651
store_reg(s, rd, tmp);
7652
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
7654
tmp = load_reg(s, rn);
7655
tmp2 = load_reg(s, rm);
7656
tmp3 = tcg_temp_new_i32();
7657
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7658
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7659
tcg_temp_free_i32(tmp3);
7660
tcg_temp_free_i32(tmp2);
7661
store_reg(s, rd, tmp);
7662
} else if ((insn & 0x000003e0) == 0x00000060) {
7663
tmp = load_reg(s, rm);
7664
shift = (insn >> 10) & 3;
7665
/* ??? In many cases it's not necessary to do a
7666
rotate, a shift is sufficient. */
7668
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7669
op1 = (insn >> 20) & 7;
7671
case 0: gen_sxtb16(tmp); break;
7672
case 2: gen_sxtb(tmp); break;
7673
case 3: gen_sxth(tmp); break;
7674
case 4: gen_uxtb16(tmp); break;
7675
case 6: gen_uxtb(tmp); break;
7676
case 7: gen_uxth(tmp); break;
7677
default: goto illegal_op;
7680
tmp2 = load_reg(s, rn);
7681
if ((op1 & 3) == 0) {
7682
gen_add16(tmp, tmp2);
7684
tcg_gen_add_i32(tmp, tmp, tmp2);
7685
tcg_temp_free_i32(tmp2);
7688
store_reg(s, rd, tmp);
7689
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
7691
tmp = load_reg(s, rm);
7692
if (insn & (1 << 22)) {
7693
if (insn & (1 << 7)) {
7697
gen_helper_rbit(tmp, tmp);
7700
if (insn & (1 << 7))
7703
tcg_gen_bswap32_i32(tmp, tmp);
7705
store_reg(s, rd, tmp);
7710
case 2: /* Multiplies (Type 3). */
7711
switch ((insn >> 20) & 0x7) {
7713
if (((insn >> 6) ^ (insn >> 7)) & 1) {
7714
/* op2 not 00x or 11x : UNDEF */
7717
/* Signed multiply most significant [accumulate].
7718
(SMMUL, SMMLA, SMMLS) */
7719
tmp = load_reg(s, rm);
7720
tmp2 = load_reg(s, rs);
7721
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7724
tmp = load_reg(s, rd);
7725
if (insn & (1 << 6)) {
7726
tmp64 = gen_subq_msw(tmp64, tmp);
7728
tmp64 = gen_addq_msw(tmp64, tmp);
7731
if (insn & (1 << 5)) {
7732
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7734
tcg_gen_shri_i64(tmp64, tmp64, 32);
7735
tmp = tcg_temp_new_i32();
7736
tcg_gen_trunc_i64_i32(tmp, tmp64);
7737
tcg_temp_free_i64(tmp64);
7738
store_reg(s, rn, tmp);
7742
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7743
if (insn & (1 << 7)) {
7746
tmp = load_reg(s, rm);
7747
tmp2 = load_reg(s, rs);
7748
if (insn & (1 << 5))
7749
gen_swap_half(tmp2);
7750
gen_smul_dual(tmp, tmp2);
7751
if (insn & (1 << 6)) {
7752
/* This subtraction cannot overflow. */
7753
tcg_gen_sub_i32(tmp, tmp, tmp2);
7755
/* This addition cannot overflow 32 bits;
7756
* however it may overflow considered as a signed
7757
* operation, in which case we must set the Q flag.
7759
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7761
tcg_temp_free_i32(tmp2);
7762
if (insn & (1 << 22)) {
7763
/* smlald, smlsld */
7764
tmp64 = tcg_temp_new_i64();
7765
tcg_gen_ext_i32_i64(tmp64, tmp);
7766
tcg_temp_free_i32(tmp);
7767
gen_addq(s, tmp64, rd, rn);
7768
gen_storeq_reg(s, rd, rn, tmp64);
7769
tcg_temp_free_i64(tmp64);
7771
/* smuad, smusd, smlad, smlsd */
7774
tmp2 = load_reg(s, rd);
7775
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7776
tcg_temp_free_i32(tmp2);
7778
store_reg(s, rn, tmp);
7784
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7787
if (((insn >> 5) & 7) || (rd != 15)) {
7790
tmp = load_reg(s, rm);
7791
tmp2 = load_reg(s, rs);
7792
if (insn & (1 << 21)) {
7793
gen_helper_udiv(tmp, tmp, tmp2);
7795
gen_helper_sdiv(tmp, tmp, tmp2);
7797
tcg_temp_free_i32(tmp2);
7798
store_reg(s, rn, tmp);
7805
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7807
case 0: /* Unsigned sum of absolute differences. */
7809
tmp = load_reg(s, rm);
7810
tmp2 = load_reg(s, rs);
7811
gen_helper_usad8(tmp, tmp, tmp2);
7812
tcg_temp_free_i32(tmp2);
7814
tmp2 = load_reg(s, rd);
7815
tcg_gen_add_i32(tmp, tmp, tmp2);
7816
tcg_temp_free_i32(tmp2);
7818
store_reg(s, rn, tmp);
7820
case 0x20: case 0x24: case 0x28: case 0x2c:
7821
/* Bitfield insert/clear. */
7823
shift = (insn >> 7) & 0x1f;
7824
i = (insn >> 16) & 0x1f;
7827
tmp = tcg_temp_new_i32();
7828
tcg_gen_movi_i32(tmp, 0);
7830
tmp = load_reg(s, rm);
7833
tmp2 = load_reg(s, rd);
7834
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
7835
tcg_temp_free_i32(tmp2);
7837
store_reg(s, rd, tmp);
7839
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7840
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7842
tmp = load_reg(s, rm);
7843
shift = (insn >> 7) & 0x1f;
7844
i = ((insn >> 16) & 0x1f) + 1;
7849
gen_ubfx(tmp, shift, (1u << i) - 1);
7851
gen_sbfx(tmp, shift, i);
7854
store_reg(s, rd, tmp);
7864
/* Check for undefined extension instructions
7865
* per the ARM Bible IE:
7866
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7868
sh = (0xf << 20) | (0xf << 4);
7869
if (op1 == 0x7 && ((insn & sh) == sh))
7873
/* load/store byte/word */
7874
rn = (insn >> 16) & 0xf;
7875
rd = (insn >> 12) & 0xf;
7876
tmp2 = load_reg(s, rn);
7877
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7878
if (insn & (1 << 24))
7879
gen_add_data_offset(s, insn, tmp2);
7880
if (insn & (1 << 20)) {
7882
tmp = tcg_temp_new_i32();
7883
if (insn & (1 << 22)) {
7884
gen_aa32_ld8u(tmp, tmp2, i);
7886
gen_aa32_ld32u(tmp, tmp2, i);
7890
tmp = load_reg(s, rd);
7891
if (insn & (1 << 22)) {
7892
gen_aa32_st8(tmp, tmp2, i);
7894
gen_aa32_st32(tmp, tmp2, i);
7896
tcg_temp_free_i32(tmp);
7898
if (!(insn & (1 << 24))) {
7899
gen_add_data_offset(s, insn, tmp2);
7900
store_reg(s, rn, tmp2);
7901
} else if (insn & (1 << 21)) {
7902
store_reg(s, rn, tmp2);
7904
tcg_temp_free_i32(tmp2);
7906
if (insn & (1 << 20)) {
7907
/* Complete the load. */
7908
store_reg_from_load(env, s, rd, tmp);
7914
int j, n, user, loaded_base;
7915
TCGv_i32 loaded_var;
7916
/* load/store multiple words */
7917
/* XXX: store correct base if write back */
7919
if (insn & (1 << 22)) {
7921
goto illegal_op; /* only usable in supervisor mode */
7923
if ((insn & (1 << 15)) == 0)
7926
rn = (insn >> 16) & 0xf;
7927
addr = load_reg(s, rn);
7929
/* compute total size */
7931
TCGV_UNUSED_I32(loaded_var);
7934
if (insn & (1 << i))
7937
/* XXX: test invalid n == 0 case ? */
7938
if (insn & (1 << 23)) {
7939
if (insn & (1 << 24)) {
7941
tcg_gen_addi_i32(addr, addr, 4);
7943
/* post increment */
7946
if (insn & (1 << 24)) {
7948
tcg_gen_addi_i32(addr, addr, -(n * 4));
7950
/* post decrement */
7952
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7957
if (insn & (1 << i)) {
7958
if (insn & (1 << 20)) {
7960
tmp = tcg_temp_new_i32();
7961
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7963
tmp2 = tcg_const_i32(i);
7964
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
7965
tcg_temp_free_i32(tmp2);
7966
tcg_temp_free_i32(tmp);
7967
} else if (i == rn) {
7971
store_reg_from_load(env, s, i, tmp);
7976
/* special case: r15 = PC + 8 */
7977
val = (long)s->pc + 4;
7978
tmp = tcg_temp_new_i32();
7979
tcg_gen_movi_i32(tmp, val);
7981
tmp = tcg_temp_new_i32();
7982
tmp2 = tcg_const_i32(i);
7983
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
7984
tcg_temp_free_i32(tmp2);
7986
tmp = load_reg(s, i);
7988
gen_aa32_st32(tmp, addr, IS_USER(s));
7989
tcg_temp_free_i32(tmp);
7992
/* no need to add after the last transfer */
7994
tcg_gen_addi_i32(addr, addr, 4);
7997
if (insn & (1 << 21)) {
7999
if (insn & (1 << 23)) {
8000
if (insn & (1 << 24)) {
8003
/* post increment */
8004
tcg_gen_addi_i32(addr, addr, 4);
8007
if (insn & (1 << 24)) {
8010
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8012
/* post decrement */
8013
tcg_gen_addi_i32(addr, addr, -(n * 4));
8016
store_reg(s, rn, addr);
8018
tcg_temp_free_i32(addr);
8021
store_reg(s, rn, loaded_var);
8023
if ((insn & (1 << 22)) && !user) {
8024
/* Restore CPSR from SPSR. */
8025
tmp = load_cpu_field(spsr);
8026
gen_set_cpsr(tmp, 0xffffffff);
8027
tcg_temp_free_i32(tmp);
8028
s->is_jmp = DISAS_UPDATE;
8037
/* branch (and link) */
8038
val = (int32_t)s->pc;
8039
if (insn & (1 << 24)) {
8040
tmp = tcg_temp_new_i32();
8041
tcg_gen_movi_i32(tmp, val);
8042
store_reg(s, 14, tmp);
8044
offset = sextract32(insn << 2, 0, 26);
8053
if (disas_coproc_insn(env, s, insn))
8058
gen_set_pc_im(s, s->pc);
8059
s->is_jmp = DISAS_SWI;
8063
gen_exception_insn(s, 4, EXCP_UDEF);
8069
/* Return true if this is a Thumb-2 logical op. */
8071
thumb2_logic_op(int op)
8076
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8077
then set condition code flags based on the result of the operation.
8078
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8079
to the high bit of T1.
8080
Returns zero if the opcode is valid. */
8083
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8084
TCGv_i32 t0, TCGv_i32 t1)
8091
tcg_gen_and_i32(t0, t0, t1);
8095
tcg_gen_andc_i32(t0, t0, t1);
8099
tcg_gen_or_i32(t0, t0, t1);
8103
tcg_gen_orc_i32(t0, t0, t1);
8107
tcg_gen_xor_i32(t0, t0, t1);
8112
gen_add_CC(t0, t0, t1);
8114
tcg_gen_add_i32(t0, t0, t1);
8118
gen_adc_CC(t0, t0, t1);
8124
gen_sbc_CC(t0, t0, t1);
8126
gen_sub_carry(t0, t0, t1);
8131
gen_sub_CC(t0, t0, t1);
8133
tcg_gen_sub_i32(t0, t0, t1);
8137
gen_sub_CC(t0, t1, t0);
8139
tcg_gen_sub_i32(t0, t1, t0);
8141
default: /* 5, 6, 7, 9, 12, 15. */
8147
gen_set_CF_bit31(t1);
8152
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8154
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8156
uint32_t insn, imm, shift, offset;
8157
uint32_t rd, rn, rm, rs;
8168
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8169
|| arm_feature (env, ARM_FEATURE_M))) {
8170
/* Thumb-1 cores may need to treat bl and blx as a pair of
8171
16-bit instructions to get correct prefetch abort behavior. */
8173
if ((insn & (1 << 12)) == 0) {
8175
/* Second half of blx. */
8176
offset = ((insn & 0x7ff) << 1);
8177
tmp = load_reg(s, 14);
8178
tcg_gen_addi_i32(tmp, tmp, offset);
8179
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8181
tmp2 = tcg_temp_new_i32();
8182
tcg_gen_movi_i32(tmp2, s->pc | 1);
8183
store_reg(s, 14, tmp2);
8187
if (insn & (1 << 11)) {
8188
/* Second half of bl. */
8189
offset = ((insn & 0x7ff) << 1) | 1;
8190
tmp = load_reg(s, 14);
8191
tcg_gen_addi_i32(tmp, tmp, offset);
8193
tmp2 = tcg_temp_new_i32();
8194
tcg_gen_movi_i32(tmp2, s->pc | 1);
8195
store_reg(s, 14, tmp2);
8199
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8200
/* Instruction spans a page boundary. Implement it as two
8201
16-bit instructions in case the second half causes an
8203
offset = ((int32_t)insn << 21) >> 9;
8204
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8207
/* Fall through to 32-bit decode. */
8210
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8212
insn |= (uint32_t)insn_hw1 << 16;
8214
if ((insn & 0xf800e800) != 0xf000e800) {
8218
rn = (insn >> 16) & 0xf;
8219
rs = (insn >> 12) & 0xf;
8220
rd = (insn >> 8) & 0xf;
8222
switch ((insn >> 25) & 0xf) {
8223
case 0: case 1: case 2: case 3:
8224
/* 16-bit instructions. Should never happen. */
8227
if (insn & (1 << 22)) {
8228
/* Other load/store, table branch. */
8229
if (insn & 0x01200000) {
8230
/* Load/store doubleword. */
8232
addr = tcg_temp_new_i32();
8233
tcg_gen_movi_i32(addr, s->pc & ~3);
8235
addr = load_reg(s, rn);
8237
offset = (insn & 0xff) * 4;
8238
if ((insn & (1 << 23)) == 0)
8240
if (insn & (1 << 24)) {
8241
tcg_gen_addi_i32(addr, addr, offset);
8244
if (insn & (1 << 20)) {
8246
tmp = tcg_temp_new_i32();
8247
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8248
store_reg(s, rs, tmp);
8249
tcg_gen_addi_i32(addr, addr, 4);
8250
tmp = tcg_temp_new_i32();
8251
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8252
store_reg(s, rd, tmp);
8255
tmp = load_reg(s, rs);
8256
gen_aa32_st32(tmp, addr, IS_USER(s));
8257
tcg_temp_free_i32(tmp);
8258
tcg_gen_addi_i32(addr, addr, 4);
8259
tmp = load_reg(s, rd);
8260
gen_aa32_st32(tmp, addr, IS_USER(s));
8261
tcg_temp_free_i32(tmp);
8263
if (insn & (1 << 21)) {
8264
/* Base writeback. */
8267
tcg_gen_addi_i32(addr, addr, offset - 4);
8268
store_reg(s, rn, addr);
8270
tcg_temp_free_i32(addr);
8272
} else if ((insn & (1 << 23)) == 0) {
8273
/* Load/store exclusive word. */
8274
addr = tcg_temp_local_new_i32();
8275
load_reg_var(s, addr, rn);
8276
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8277
if (insn & (1 << 20)) {
8278
gen_load_exclusive(s, rs, 15, addr, 2);
8280
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8282
tcg_temp_free_i32(addr);
8283
} else if ((insn & (7 << 5)) == 0) {
8286
addr = tcg_temp_new_i32();
8287
tcg_gen_movi_i32(addr, s->pc);
8289
addr = load_reg(s, rn);
8291
tmp = load_reg(s, rm);
8292
tcg_gen_add_i32(addr, addr, tmp);
8293
if (insn & (1 << 4)) {
8295
tcg_gen_add_i32(addr, addr, tmp);
8296
tcg_temp_free_i32(tmp);
8297
tmp = tcg_temp_new_i32();
8298
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8300
tcg_temp_free_i32(tmp);
8301
tmp = tcg_temp_new_i32();
8302
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8304
tcg_temp_free_i32(addr);
8305
tcg_gen_shli_i32(tmp, tmp, 1);
8306
tcg_gen_addi_i32(tmp, tmp, s->pc);
8307
store_reg(s, 15, tmp);
8309
int op2 = (insn >> 6) & 0x3;
8310
op = (insn >> 4) & 0x3;
8315
/* Load/store exclusive byte/halfword/doubleword */
8322
/* Load-acquire/store-release */
8328
/* Load-acquire/store-release exclusive */
8332
addr = tcg_temp_local_new_i32();
8333
load_reg_var(s, addr, rn);
8335
if (insn & (1 << 20)) {
8336
tmp = tcg_temp_new_i32();
8339
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8342
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8345
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8350
store_reg(s, rs, tmp);
8352
tmp = load_reg(s, rs);
8355
gen_aa32_st8(tmp, addr, IS_USER(s));
8358
gen_aa32_st16(tmp, addr, IS_USER(s));
8361
gen_aa32_st32(tmp, addr, IS_USER(s));
8366
tcg_temp_free_i32(tmp);
8368
} else if (insn & (1 << 20)) {
8369
gen_load_exclusive(s, rs, rd, addr, op);
8371
gen_store_exclusive(s, rm, rs, rd, addr, op);
8373
tcg_temp_free_i32(addr);
8376
/* Load/store multiple, RFE, SRS. */
8377
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8378
/* RFE, SRS: not available in user mode or on M profile */
8379
if (IS_USER(s) || IS_M(env)) {
8382
if (insn & (1 << 20)) {
8384
addr = load_reg(s, rn);
8385
if ((insn & (1 << 24)) == 0)
8386
tcg_gen_addi_i32(addr, addr, -8);
8387
/* Load PC into tmp and CPSR into tmp2. */
8388
tmp = tcg_temp_new_i32();
8389
gen_aa32_ld32u(tmp, addr, 0);
8390
tcg_gen_addi_i32(addr, addr, 4);
8391
tmp2 = tcg_temp_new_i32();
8392
gen_aa32_ld32u(tmp2, addr, 0);
8393
if (insn & (1 << 21)) {
8394
/* Base writeback. */
8395
if (insn & (1 << 24)) {
8396
tcg_gen_addi_i32(addr, addr, 4);
8398
tcg_gen_addi_i32(addr, addr, -4);
8400
store_reg(s, rn, addr);
8402
tcg_temp_free_i32(addr);
8404
gen_rfe(s, tmp, tmp2);
8407
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8411
int i, loaded_base = 0;
8412
TCGv_i32 loaded_var;
8413
/* Load/store multiple. */
8414
addr = load_reg(s, rn);
8416
for (i = 0; i < 16; i++) {
8417
if (insn & (1 << i))
8420
if (insn & (1 << 24)) {
8421
tcg_gen_addi_i32(addr, addr, -offset);
8424
TCGV_UNUSED_I32(loaded_var);
8425
for (i = 0; i < 16; i++) {
8426
if ((insn & (1 << i)) == 0)
8428
if (insn & (1 << 20)) {
8430
tmp = tcg_temp_new_i32();
8431
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8434
} else if (i == rn) {
8438
store_reg(s, i, tmp);
8442
tmp = load_reg(s, i);
8443
gen_aa32_st32(tmp, addr, IS_USER(s));
8444
tcg_temp_free_i32(tmp);
8446
tcg_gen_addi_i32(addr, addr, 4);
8449
store_reg(s, rn, loaded_var);
8451
if (insn & (1 << 21)) {
8452
/* Base register writeback. */
8453
if (insn & (1 << 24)) {
8454
tcg_gen_addi_i32(addr, addr, -offset);
8456
/* Fault if writeback register is in register list. */
8457
if (insn & (1 << rn))
8459
store_reg(s, rn, addr);
8461
tcg_temp_free_i32(addr);
8468
op = (insn >> 21) & 0xf;
8470
/* Halfword pack. */
8471
tmp = load_reg(s, rn);
8472
tmp2 = load_reg(s, rm);
8473
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8474
if (insn & (1 << 5)) {
8478
tcg_gen_sari_i32(tmp2, tmp2, shift);
8479
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8480
tcg_gen_ext16u_i32(tmp2, tmp2);
8484
tcg_gen_shli_i32(tmp2, tmp2, shift);
8485
tcg_gen_ext16u_i32(tmp, tmp);
8486
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8488
tcg_gen_or_i32(tmp, tmp, tmp2);
8489
tcg_temp_free_i32(tmp2);
8490
store_reg(s, rd, tmp);
8492
/* Data processing register constant shift. */
8494
tmp = tcg_temp_new_i32();
8495
tcg_gen_movi_i32(tmp, 0);
8497
tmp = load_reg(s, rn);
8499
tmp2 = load_reg(s, rm);
8501
shiftop = (insn >> 4) & 3;
8502
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8503
conds = (insn & (1 << 20)) != 0;
8504
logic_cc = (conds && thumb2_logic_op(op));
8505
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8506
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8508
tcg_temp_free_i32(tmp2);
8510
store_reg(s, rd, tmp);
8512
tcg_temp_free_i32(tmp);
8516
case 13: /* Misc data processing. */
8517
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8518
if (op < 4 && (insn & 0xf000) != 0xf000)
8521
case 0: /* Register controlled shift. */
8522
tmp = load_reg(s, rn);
8523
tmp2 = load_reg(s, rm);
8524
if ((insn & 0x70) != 0)
8526
op = (insn >> 21) & 3;
8527
logic_cc = (insn & (1 << 20)) != 0;
8528
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8531
store_reg_bx(env, s, rd, tmp);
8533
case 1: /* Sign/zero extend. */
8534
tmp = load_reg(s, rm);
8535
shift = (insn >> 4) & 3;
8536
/* ??? In many cases it's not necessary to do a
8537
rotate, a shift is sufficient. */
8539
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8540
op = (insn >> 20) & 7;
8542
case 0: gen_sxth(tmp); break;
8543
case 1: gen_uxth(tmp); break;
8544
case 2: gen_sxtb16(tmp); break;
8545
case 3: gen_uxtb16(tmp); break;
8546
case 4: gen_sxtb(tmp); break;
8547
case 5: gen_uxtb(tmp); break;
8548
default: goto illegal_op;
8551
tmp2 = load_reg(s, rn);
8552
if ((op >> 1) == 1) {
8553
gen_add16(tmp, tmp2);
8555
tcg_gen_add_i32(tmp, tmp, tmp2);
8556
tcg_temp_free_i32(tmp2);
8559
store_reg(s, rd, tmp);
8561
case 2: /* SIMD add/subtract. */
8562
op = (insn >> 20) & 7;
8563
shift = (insn >> 4) & 7;
8564
if ((op & 3) == 3 || (shift & 3) == 3)
8566
tmp = load_reg(s, rn);
8567
tmp2 = load_reg(s, rm);
8568
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8569
tcg_temp_free_i32(tmp2);
8570
store_reg(s, rd, tmp);
8572
case 3: /* Other data processing. */
8573
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8575
/* Saturating add/subtract. */
8576
tmp = load_reg(s, rn);
8577
tmp2 = load_reg(s, rm);
8579
gen_helper_double_saturate(tmp, cpu_env, tmp);
8581
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8583
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8584
tcg_temp_free_i32(tmp2);
8586
tmp = load_reg(s, rn);
8588
case 0x0a: /* rbit */
8589
gen_helper_rbit(tmp, tmp);
8591
case 0x08: /* rev */
8592
tcg_gen_bswap32_i32(tmp, tmp);
8594
case 0x09: /* rev16 */
8597
case 0x0b: /* revsh */
8600
case 0x10: /* sel */
8601
tmp2 = load_reg(s, rm);
8602
tmp3 = tcg_temp_new_i32();
8603
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8604
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8605
tcg_temp_free_i32(tmp3);
8606
tcg_temp_free_i32(tmp2);
8608
case 0x18: /* clz */
8609
gen_helper_clz(tmp, tmp);
8615
store_reg(s, rd, tmp);
8617
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8618
op = (insn >> 4) & 0xf;
8619
tmp = load_reg(s, rn);
8620
tmp2 = load_reg(s, rm);
8621
switch ((insn >> 20) & 7) {
8622
case 0: /* 32 x 32 -> 32 */
8623
tcg_gen_mul_i32(tmp, tmp, tmp2);
8624
tcg_temp_free_i32(tmp2);
8626
tmp2 = load_reg(s, rs);
8628
tcg_gen_sub_i32(tmp, tmp2, tmp);
8630
tcg_gen_add_i32(tmp, tmp, tmp2);
8631
tcg_temp_free_i32(tmp2);
8634
case 1: /* 16 x 16 -> 32 */
8635
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8636
tcg_temp_free_i32(tmp2);
8638
tmp2 = load_reg(s, rs);
8639
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8640
tcg_temp_free_i32(tmp2);
8643
case 2: /* Dual multiply add. */
8644
case 4: /* Dual multiply subtract. */
8646
gen_swap_half(tmp2);
8647
gen_smul_dual(tmp, tmp2);
8648
if (insn & (1 << 22)) {
8649
/* This subtraction cannot overflow. */
8650
tcg_gen_sub_i32(tmp, tmp, tmp2);
8652
/* This addition cannot overflow 32 bits;
8653
* however it may overflow considered as a signed
8654
* operation, in which case we must set the Q flag.
8656
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8658
tcg_temp_free_i32(tmp2);
8661
tmp2 = load_reg(s, rs);
8662
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8663
tcg_temp_free_i32(tmp2);
8666
case 3: /* 32 * 16 -> 32msb */
8668
tcg_gen_sari_i32(tmp2, tmp2, 16);
8671
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8672
tcg_gen_shri_i64(tmp64, tmp64, 16);
8673
tmp = tcg_temp_new_i32();
8674
tcg_gen_trunc_i64_i32(tmp, tmp64);
8675
tcg_temp_free_i64(tmp64);
8678
tmp2 = load_reg(s, rs);
8679
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8680
tcg_temp_free_i32(tmp2);
8683
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8684
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8686
tmp = load_reg(s, rs);
8687
if (insn & (1 << 20)) {
8688
tmp64 = gen_addq_msw(tmp64, tmp);
8690
tmp64 = gen_subq_msw(tmp64, tmp);
8693
if (insn & (1 << 4)) {
8694
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8696
tcg_gen_shri_i64(tmp64, tmp64, 32);
8697
tmp = tcg_temp_new_i32();
8698
tcg_gen_trunc_i64_i32(tmp, tmp64);
8699
tcg_temp_free_i64(tmp64);
8701
case 7: /* Unsigned sum of absolute differences. */
8702
gen_helper_usad8(tmp, tmp, tmp2);
8703
tcg_temp_free_i32(tmp2);
8705
tmp2 = load_reg(s, rs);
8706
tcg_gen_add_i32(tmp, tmp, tmp2);
8707
tcg_temp_free_i32(tmp2);
8711
store_reg(s, rd, tmp);
8713
case 6: case 7: /* 64-bit multiply, Divide. */
8714
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8715
tmp = load_reg(s, rn);
8716
tmp2 = load_reg(s, rm);
8717
if ((op & 0x50) == 0x10) {
8719
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8723
gen_helper_udiv(tmp, tmp, tmp2);
8725
gen_helper_sdiv(tmp, tmp, tmp2);
8726
tcg_temp_free_i32(tmp2);
8727
store_reg(s, rd, tmp);
8728
} else if ((op & 0xe) == 0xc) {
8729
/* Dual multiply accumulate long. */
8731
gen_swap_half(tmp2);
8732
gen_smul_dual(tmp, tmp2);
8734
tcg_gen_sub_i32(tmp, tmp, tmp2);
8736
tcg_gen_add_i32(tmp, tmp, tmp2);
8738
tcg_temp_free_i32(tmp2);
8740
tmp64 = tcg_temp_new_i64();
8741
tcg_gen_ext_i32_i64(tmp64, tmp);
8742
tcg_temp_free_i32(tmp);
8743
gen_addq(s, tmp64, rs, rd);
8744
gen_storeq_reg(s, rs, rd, tmp64);
8745
tcg_temp_free_i64(tmp64);
8748
/* Unsigned 64-bit multiply */
8749
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8753
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8754
tcg_temp_free_i32(tmp2);
8755
tmp64 = tcg_temp_new_i64();
8756
tcg_gen_ext_i32_i64(tmp64, tmp);
8757
tcg_temp_free_i32(tmp);
8759
/* Signed 64-bit multiply */
8760
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8765
gen_addq_lo(s, tmp64, rs);
8766
gen_addq_lo(s, tmp64, rd);
8767
} else if (op & 0x40) {
8768
/* 64-bit accumulate. */
8769
gen_addq(s, tmp64, rs, rd);
8771
gen_storeq_reg(s, rs, rd, tmp64);
8772
tcg_temp_free_i64(tmp64);
8777
case 6: case 7: case 14: case 15:
8779
if (((insn >> 24) & 3) == 3) {
8780
/* Translate into the equivalent ARM encoding. */
8781
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8782
if (disas_neon_data_insn(env, s, insn))
8785
if (insn & (1 << 28))
8787
if (disas_coproc_insn (env, s, insn))
8791
case 8: case 9: case 10: case 11:
8792
if (insn & (1 << 15)) {
8793
/* Branches, misc control. */
8794
if (insn & 0x5000) {
8795
/* Unconditional branch. */
8796
/* signextend(hw1[10:0]) -> offset[:12]. */
8797
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8798
/* hw1[10:0] -> offset[11:1]. */
8799
offset |= (insn & 0x7ff) << 1;
8800
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8801
offset[24:22] already have the same value because of the
8802
sign extension above. */
8803
offset ^= ((~insn) & (1 << 13)) << 10;
8804
offset ^= ((~insn) & (1 << 11)) << 11;
8806
if (insn & (1 << 14)) {
8807
/* Branch and link. */
8808
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8812
if (insn & (1 << 12)) {
8817
offset &= ~(uint32_t)2;
8818
/* thumb2 bx, no need to check */
8819
gen_bx_im(s, offset);
8821
} else if (((insn >> 23) & 7) == 7) {
8823
if (insn & (1 << 13))
8826
if (insn & (1 << 26)) {
8827
/* Secure monitor call / smc (v6Z) */
8828
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
8834
op = (insn >> 20) & 7;
8836
case 0: /* msr cpsr. */
8838
tmp = load_reg(s, rn);
8839
addr = tcg_const_i32(insn & 0xff);
8840
gen_helper_v7m_msr(cpu_env, addr, tmp);
8841
tcg_temp_free_i32(addr);
8842
tcg_temp_free_i32(tmp);
8847
case 1: /* msr spsr. */
8850
tmp = load_reg(s, rn);
8852
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8856
case 2: /* cps, nop-hint. */
8857
if (((insn >> 8) & 7) == 0) {
8858
gen_nop_hint(s, insn & 0xff);
8860
/* Implemented as NOP in user mode. */
8865
if (insn & (1 << 10)) {
8866
if (insn & (1 << 7))
8868
if (insn & (1 << 6))
8870
if (insn & (1 << 5))
8872
if (insn & (1 << 9))
8873
imm = CPSR_A | CPSR_I | CPSR_F;
8875
if (insn & (1 << 8)) {
8877
imm |= (insn & 0x1f);
8880
gen_set_psr_im(s, offset, 0, imm);
8883
case 3: /* Special control operations. */
8885
op = (insn >> 4) & 0xf;
8893
/* These execute as NOPs. */
8900
/* Trivial implementation equivalent to bx. */
8901
tmp = load_reg(s, rn);
8904
case 5: /* Exception return. */
8908
if (rn != 14 || rd != 15) {
8911
tmp = load_reg(s, rn);
8912
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8913
gen_exception_return(s, tmp);
8915
case 6: /* mrs cpsr. */
8916
tmp = tcg_temp_new_i32();
8918
addr = tcg_const_i32(insn & 0xff);
8919
gen_helper_v7m_mrs(tmp, cpu_env, addr);
8920
tcg_temp_free_i32(addr);
8922
gen_helper_cpsr_read(tmp, cpu_env);
8924
store_reg(s, rd, tmp);
8926
case 7: /* mrs spsr. */
8927
/* Not accessible in user mode. */
8928
if (IS_USER(s) || IS_M(env))
8930
tmp = load_cpu_field(spsr);
8931
store_reg(s, rd, tmp);
8936
/* Conditional branch. */
8937
op = (insn >> 22) & 0xf;
8938
/* Generate a conditional jump to next instruction. */
8939
s->condlabel = gen_new_label();
8940
gen_test_cc(op ^ 1, s->condlabel);
8943
/* offset[11:1] = insn[10:0] */
8944
offset = (insn & 0x7ff) << 1;
8945
/* offset[17:12] = insn[21:16]. */
8946
offset |= (insn & 0x003f0000) >> 4;
8947
/* offset[31:20] = insn[26]. */
8948
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8949
/* offset[18] = insn[13]. */
8950
offset |= (insn & (1 << 13)) << 5;
8951
/* offset[19] = insn[11]. */
8952
offset |= (insn & (1 << 11)) << 8;
8954
/* jump to the offset */
8955
gen_jmp(s, s->pc + offset);
8958
/* Data processing immediate. */
8959
if (insn & (1 << 25)) {
8960
if (insn & (1 << 24)) {
8961
if (insn & (1 << 20))
8963
/* Bitfield/Saturate. */
8964
op = (insn >> 21) & 7;
8966
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8968
tmp = tcg_temp_new_i32();
8969
tcg_gen_movi_i32(tmp, 0);
8971
tmp = load_reg(s, rn);
8974
case 2: /* Signed bitfield extract. */
8976
if (shift + imm > 32)
8979
gen_sbfx(tmp, shift, imm);
8981
case 6: /* Unsigned bitfield extract. */
8983
if (shift + imm > 32)
8986
gen_ubfx(tmp, shift, (1u << imm) - 1);
8988
case 3: /* Bitfield insert/clear. */
8991
imm = imm + 1 - shift;
8993
tmp2 = load_reg(s, rd);
8994
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
8995
tcg_temp_free_i32(tmp2);
9000
default: /* Saturate. */
9003
tcg_gen_sari_i32(tmp, tmp, shift);
9005
tcg_gen_shli_i32(tmp, tmp, shift);
9007
tmp2 = tcg_const_i32(imm);
9010
if ((op & 1) && shift == 0)
9011
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9013
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9016
if ((op & 1) && shift == 0)
9017
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9019
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9021
tcg_temp_free_i32(tmp2);
9024
store_reg(s, rd, tmp);
9026
imm = ((insn & 0x04000000) >> 15)
9027
| ((insn & 0x7000) >> 4) | (insn & 0xff);
9028
if (insn & (1 << 22)) {
9029
/* 16-bit immediate. */
9030
imm |= (insn >> 4) & 0xf000;
9031
if (insn & (1 << 23)) {
9033
tmp = load_reg(s, rd);
9034
tcg_gen_ext16u_i32(tmp, tmp);
9035
tcg_gen_ori_i32(tmp, tmp, imm << 16);
9038
tmp = tcg_temp_new_i32();
9039
tcg_gen_movi_i32(tmp, imm);
9042
/* Add/sub 12-bit immediate. */
9044
offset = s->pc & ~(uint32_t)3;
9045
if (insn & (1 << 23))
9049
tmp = tcg_temp_new_i32();
9050
tcg_gen_movi_i32(tmp, offset);
9052
tmp = load_reg(s, rn);
9053
if (insn & (1 << 23))
9054
tcg_gen_subi_i32(tmp, tmp, imm);
9056
tcg_gen_addi_i32(tmp, tmp, imm);
9059
store_reg(s, rd, tmp);
9062
int shifter_out = 0;
9063
/* modified 12-bit immediate. */
9064
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9065
imm = (insn & 0xff);
9068
/* Nothing to do. */
9070
case 1: /* 00XY00XY */
9073
case 2: /* XY00XY00 */
9077
case 3: /* XYXYXYXY */
9081
default: /* Rotated constant. */
9082
shift = (shift << 1) | (imm >> 7);
9084
imm = imm << (32 - shift);
9088
tmp2 = tcg_temp_new_i32();
9089
tcg_gen_movi_i32(tmp2, imm);
9090
rn = (insn >> 16) & 0xf;
9092
tmp = tcg_temp_new_i32();
9093
tcg_gen_movi_i32(tmp, 0);
9095
tmp = load_reg(s, rn);
9097
op = (insn >> 21) & 0xf;
9098
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9099
shifter_out, tmp, tmp2))
9101
tcg_temp_free_i32(tmp2);
9102
rd = (insn >> 8) & 0xf;
9104
store_reg(s, rd, tmp);
9106
tcg_temp_free_i32(tmp);
9111
case 12: /* Load/store single data item. */
9116
if ((insn & 0x01100000) == 0x01000000) {
9117
if (disas_neon_ls_insn(env, s, insn))
9121
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9123
if (!(insn & (1 << 20))) {
9127
/* Byte or halfword load space with dest == r15 : memory hints.
9128
* Catch them early so we don't emit pointless addressing code.
9129
* This space is a mix of:
9130
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9131
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9133
* unallocated hints, which must be treated as NOPs
9134
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9135
* which is easiest for the decoding logic
9136
* Some space which must UNDEF
9138
int op1 = (insn >> 23) & 3;
9139
int op2 = (insn >> 6) & 0x3f;
9144
/* UNPREDICTABLE, unallocated hint or
9145
* PLD/PLDW/PLI (literal)
9150
return 0; /* PLD/PLDW/PLI or unallocated hint */
9152
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9153
return 0; /* PLD/PLDW/PLI or unallocated hint */
9155
/* UNDEF space, or an UNPREDICTABLE */
9161
addr = tcg_temp_new_i32();
9163
/* s->pc has already been incremented by 4. */
9164
imm = s->pc & 0xfffffffc;
9165
if (insn & (1 << 23))
9166
imm += insn & 0xfff;
9168
imm -= insn & 0xfff;
9169
tcg_gen_movi_i32(addr, imm);
9171
addr = load_reg(s, rn);
9172
if (insn & (1 << 23)) {
9173
/* Positive offset. */
9175
tcg_gen_addi_i32(addr, addr, imm);
9178
switch ((insn >> 8) & 0xf) {
9179
case 0x0: /* Shifted Register. */
9180
shift = (insn >> 4) & 0xf;
9182
tcg_temp_free_i32(addr);
9185
tmp = load_reg(s, rm);
9187
tcg_gen_shli_i32(tmp, tmp, shift);
9188
tcg_gen_add_i32(addr, addr, tmp);
9189
tcg_temp_free_i32(tmp);
9191
case 0xc: /* Negative offset. */
9192
tcg_gen_addi_i32(addr, addr, -imm);
9194
case 0xe: /* User privilege. */
9195
tcg_gen_addi_i32(addr, addr, imm);
9198
case 0x9: /* Post-decrement. */
9201
case 0xb: /* Post-increment. */
9205
case 0xd: /* Pre-decrement. */
9208
case 0xf: /* Pre-increment. */
9209
tcg_gen_addi_i32(addr, addr, imm);
9213
tcg_temp_free_i32(addr);
9218
if (insn & (1 << 20)) {
9220
tmp = tcg_temp_new_i32();
9223
gen_aa32_ld8u(tmp, addr, user);
9226
gen_aa32_ld8s(tmp, addr, user);
9229
gen_aa32_ld16u(tmp, addr, user);
9232
gen_aa32_ld16s(tmp, addr, user);
9235
gen_aa32_ld32u(tmp, addr, user);
9238
tcg_temp_free_i32(tmp);
9239
tcg_temp_free_i32(addr);
9245
store_reg(s, rs, tmp);
9249
tmp = load_reg(s, rs);
9252
gen_aa32_st8(tmp, addr, user);
9255
gen_aa32_st16(tmp, addr, user);
9258
gen_aa32_st32(tmp, addr, user);
9261
tcg_temp_free_i32(tmp);
9262
tcg_temp_free_i32(addr);
9265
tcg_temp_free_i32(tmp);
9268
tcg_gen_addi_i32(addr, addr, imm);
9270
store_reg(s, rn, addr);
9272
tcg_temp_free_i32(addr);
9284
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9286
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9293
if (s->condexec_mask) {
9294
cond = s->condexec_cond;
9295
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9296
s->condlabel = gen_new_label();
9297
gen_test_cc(cond ^ 1, s->condlabel);
9302
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9305
switch (insn >> 12) {
9309
op = (insn >> 11) & 3;
9312
rn = (insn >> 3) & 7;
9313
tmp = load_reg(s, rn);
9314
if (insn & (1 << 10)) {
9316
tmp2 = tcg_temp_new_i32();
9317
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9320
rm = (insn >> 6) & 7;
9321
tmp2 = load_reg(s, rm);
9323
if (insn & (1 << 9)) {
9324
if (s->condexec_mask)
9325
tcg_gen_sub_i32(tmp, tmp, tmp2);
9327
gen_sub_CC(tmp, tmp, tmp2);
9329
if (s->condexec_mask)
9330
tcg_gen_add_i32(tmp, tmp, tmp2);
9332
gen_add_CC(tmp, tmp, tmp2);
9334
tcg_temp_free_i32(tmp2);
9335
store_reg(s, rd, tmp);
9337
/* shift immediate */
9338
rm = (insn >> 3) & 7;
9339
shift = (insn >> 6) & 0x1f;
9340
tmp = load_reg(s, rm);
9341
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9342
if (!s->condexec_mask)
9344
store_reg(s, rd, tmp);
9348
/* arithmetic large immediate */
9349
op = (insn >> 11) & 3;
9350
rd = (insn >> 8) & 0x7;
9351
if (op == 0) { /* mov */
9352
tmp = tcg_temp_new_i32();
9353
tcg_gen_movi_i32(tmp, insn & 0xff);
9354
if (!s->condexec_mask)
9356
store_reg(s, rd, tmp);
9358
tmp = load_reg(s, rd);
9359
tmp2 = tcg_temp_new_i32();
9360
tcg_gen_movi_i32(tmp2, insn & 0xff);
9363
gen_sub_CC(tmp, tmp, tmp2);
9364
tcg_temp_free_i32(tmp);
9365
tcg_temp_free_i32(tmp2);
9368
if (s->condexec_mask)
9369
tcg_gen_add_i32(tmp, tmp, tmp2);
9371
gen_add_CC(tmp, tmp, tmp2);
9372
tcg_temp_free_i32(tmp2);
9373
store_reg(s, rd, tmp);
9376
if (s->condexec_mask)
9377
tcg_gen_sub_i32(tmp, tmp, tmp2);
9379
gen_sub_CC(tmp, tmp, tmp2);
9380
tcg_temp_free_i32(tmp2);
9381
store_reg(s, rd, tmp);
9387
if (insn & (1 << 11)) {
9388
rd = (insn >> 8) & 7;
9389
/* load pc-relative. Bit 1 of PC is ignored. */
9390
val = s->pc + 2 + ((insn & 0xff) * 4);
9391
val &= ~(uint32_t)2;
9392
addr = tcg_temp_new_i32();
9393
tcg_gen_movi_i32(addr, val);
9394
tmp = tcg_temp_new_i32();
9395
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9396
tcg_temp_free_i32(addr);
9397
store_reg(s, rd, tmp);
9400
if (insn & (1 << 10)) {
9401
/* data processing extended or blx */
9402
rd = (insn & 7) | ((insn >> 4) & 8);
9403
rm = (insn >> 3) & 0xf;
9404
op = (insn >> 8) & 3;
9407
tmp = load_reg(s, rd);
9408
tmp2 = load_reg(s, rm);
9409
tcg_gen_add_i32(tmp, tmp, tmp2);
9410
tcg_temp_free_i32(tmp2);
9411
store_reg(s, rd, tmp);
9414
tmp = load_reg(s, rd);
9415
tmp2 = load_reg(s, rm);
9416
gen_sub_CC(tmp, tmp, tmp2);
9417
tcg_temp_free_i32(tmp2);
9418
tcg_temp_free_i32(tmp);
9420
case 2: /* mov/cpy */
9421
tmp = load_reg(s, rm);
9422
store_reg(s, rd, tmp);
9424
case 3:/* branch [and link] exchange thumb register */
9425
tmp = load_reg(s, rm);
9426
if (insn & (1 << 7)) {
9428
val = (uint32_t)s->pc | 1;
9429
tmp2 = tcg_temp_new_i32();
9430
tcg_gen_movi_i32(tmp2, val);
9431
store_reg(s, 14, tmp2);
9433
/* already thumb, no need to check */
9440
/* data processing register */
9442
rm = (insn >> 3) & 7;
9443
op = (insn >> 6) & 0xf;
9444
if (op == 2 || op == 3 || op == 4 || op == 7) {
9445
/* the shift/rotate ops want the operands backwards */
9454
if (op == 9) { /* neg */
9455
tmp = tcg_temp_new_i32();
9456
tcg_gen_movi_i32(tmp, 0);
9457
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9458
tmp = load_reg(s, rd);
9460
TCGV_UNUSED_I32(tmp);
9463
tmp2 = load_reg(s, rm);
9466
tcg_gen_and_i32(tmp, tmp, tmp2);
9467
if (!s->condexec_mask)
9471
tcg_gen_xor_i32(tmp, tmp, tmp2);
9472
if (!s->condexec_mask)
9476
if (s->condexec_mask) {
9477
gen_shl(tmp2, tmp2, tmp);
9479
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9484
if (s->condexec_mask) {
9485
gen_shr(tmp2, tmp2, tmp);
9487
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9492
if (s->condexec_mask) {
9493
gen_sar(tmp2, tmp2, tmp);
9495
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9500
if (s->condexec_mask) {
9503
gen_adc_CC(tmp, tmp, tmp2);
9507
if (s->condexec_mask) {
9508
gen_sub_carry(tmp, tmp, tmp2);
9510
gen_sbc_CC(tmp, tmp, tmp2);
9514
if (s->condexec_mask) {
9515
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9516
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9518
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9523
tcg_gen_and_i32(tmp, tmp, tmp2);
9528
if (s->condexec_mask)
9529
tcg_gen_neg_i32(tmp, tmp2);
9531
gen_sub_CC(tmp, tmp, tmp2);
9534
gen_sub_CC(tmp, tmp, tmp2);
9538
gen_add_CC(tmp, tmp, tmp2);
9542
tcg_gen_or_i32(tmp, tmp, tmp2);
9543
if (!s->condexec_mask)
9547
tcg_gen_mul_i32(tmp, tmp, tmp2);
9548
if (!s->condexec_mask)
9552
tcg_gen_andc_i32(tmp, tmp, tmp2);
9553
if (!s->condexec_mask)
9557
tcg_gen_not_i32(tmp2, tmp2);
9558
if (!s->condexec_mask)
9566
store_reg(s, rm, tmp2);
9568
tcg_temp_free_i32(tmp);
9570
store_reg(s, rd, tmp);
9571
tcg_temp_free_i32(tmp2);
9574
tcg_temp_free_i32(tmp);
9575
tcg_temp_free_i32(tmp2);
9580
/* load/store register offset. */
9582
rn = (insn >> 3) & 7;
9583
rm = (insn >> 6) & 7;
9584
op = (insn >> 9) & 7;
9585
addr = load_reg(s, rn);
9586
tmp = load_reg(s, rm);
9587
tcg_gen_add_i32(addr, addr, tmp);
9588
tcg_temp_free_i32(tmp);
9590
if (op < 3) { /* store */
9591
tmp = load_reg(s, rd);
9593
tmp = tcg_temp_new_i32();
9598
gen_aa32_st32(tmp, addr, IS_USER(s));
9601
gen_aa32_st16(tmp, addr, IS_USER(s));
9604
gen_aa32_st8(tmp, addr, IS_USER(s));
9607
gen_aa32_ld8s(tmp, addr, IS_USER(s));
9610
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9613
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9616
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9619
gen_aa32_ld16s(tmp, addr, IS_USER(s));
9622
if (op >= 3) { /* load */
9623
store_reg(s, rd, tmp);
9625
tcg_temp_free_i32(tmp);
9627
tcg_temp_free_i32(addr);
9631
/* load/store word immediate offset */
9633
rn = (insn >> 3) & 7;
9634
addr = load_reg(s, rn);
9635
val = (insn >> 4) & 0x7c;
9636
tcg_gen_addi_i32(addr, addr, val);
9638
if (insn & (1 << 11)) {
9640
tmp = tcg_temp_new_i32();
9641
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9642
store_reg(s, rd, tmp);
9645
tmp = load_reg(s, rd);
9646
gen_aa32_st32(tmp, addr, IS_USER(s));
9647
tcg_temp_free_i32(tmp);
9649
tcg_temp_free_i32(addr);
9653
/* load/store byte immediate offset */
9655
rn = (insn >> 3) & 7;
9656
addr = load_reg(s, rn);
9657
val = (insn >> 6) & 0x1f;
9658
tcg_gen_addi_i32(addr, addr, val);
9660
if (insn & (1 << 11)) {
9662
tmp = tcg_temp_new_i32();
9663
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9664
store_reg(s, rd, tmp);
9667
tmp = load_reg(s, rd);
9668
gen_aa32_st8(tmp, addr, IS_USER(s));
9669
tcg_temp_free_i32(tmp);
9671
tcg_temp_free_i32(addr);
9675
/* load/store halfword immediate offset */
9677
rn = (insn >> 3) & 7;
9678
addr = load_reg(s, rn);
9679
val = (insn >> 5) & 0x3e;
9680
tcg_gen_addi_i32(addr, addr, val);
9682
if (insn & (1 << 11)) {
9684
tmp = tcg_temp_new_i32();
9685
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9686
store_reg(s, rd, tmp);
9689
tmp = load_reg(s, rd);
9690
gen_aa32_st16(tmp, addr, IS_USER(s));
9691
tcg_temp_free_i32(tmp);
9693
tcg_temp_free_i32(addr);
9697
/* load/store from stack */
9698
rd = (insn >> 8) & 7;
9699
addr = load_reg(s, 13);
9700
val = (insn & 0xff) * 4;
9701
tcg_gen_addi_i32(addr, addr, val);
9703
if (insn & (1 << 11)) {
9705
tmp = tcg_temp_new_i32();
9706
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9707
store_reg(s, rd, tmp);
9710
tmp = load_reg(s, rd);
9711
gen_aa32_st32(tmp, addr, IS_USER(s));
9712
tcg_temp_free_i32(tmp);
9714
tcg_temp_free_i32(addr);
9718
/* add to high reg */
9719
rd = (insn >> 8) & 7;
9720
if (insn & (1 << 11)) {
9722
tmp = load_reg(s, 13);
9724
/* PC. bit 1 is ignored. */
9725
tmp = tcg_temp_new_i32();
9726
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9728
val = (insn & 0xff) * 4;
9729
tcg_gen_addi_i32(tmp, tmp, val);
9730
store_reg(s, rd, tmp);
9735
op = (insn >> 8) & 0xf;
9738
/* adjust stack pointer */
9739
tmp = load_reg(s, 13);
9740
val = (insn & 0x7f) * 4;
9741
if (insn & (1 << 7))
9742
val = -(int32_t)val;
9743
tcg_gen_addi_i32(tmp, tmp, val);
9744
store_reg(s, 13, tmp);
9747
case 2: /* sign/zero extend. */
9750
rm = (insn >> 3) & 7;
9751
tmp = load_reg(s, rm);
9752
switch ((insn >> 6) & 3) {
9753
case 0: gen_sxth(tmp); break;
9754
case 1: gen_sxtb(tmp); break;
9755
case 2: gen_uxth(tmp); break;
9756
case 3: gen_uxtb(tmp); break;
9758
store_reg(s, rd, tmp);
9760
case 4: case 5: case 0xc: case 0xd:
9762
addr = load_reg(s, 13);
9763
if (insn & (1 << 8))
9767
for (i = 0; i < 8; i++) {
9768
if (insn & (1 << i))
9771
if ((insn & (1 << 11)) == 0) {
9772
tcg_gen_addi_i32(addr, addr, -offset);
9774
for (i = 0; i < 8; i++) {
9775
if (insn & (1 << i)) {
9776
if (insn & (1 << 11)) {
9778
tmp = tcg_temp_new_i32();
9779
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9780
store_reg(s, i, tmp);
9783
tmp = load_reg(s, i);
9784
gen_aa32_st32(tmp, addr, IS_USER(s));
9785
tcg_temp_free_i32(tmp);
9787
/* advance to the next address. */
9788
tcg_gen_addi_i32(addr, addr, 4);
9791
TCGV_UNUSED_I32(tmp);
9792
if (insn & (1 << 8)) {
9793
if (insn & (1 << 11)) {
9795
tmp = tcg_temp_new_i32();
9796
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9797
/* don't set the pc until the rest of the instruction
9801
tmp = load_reg(s, 14);
9802
gen_aa32_st32(tmp, addr, IS_USER(s));
9803
tcg_temp_free_i32(tmp);
9805
tcg_gen_addi_i32(addr, addr, 4);
9807
if ((insn & (1 << 11)) == 0) {
9808
tcg_gen_addi_i32(addr, addr, -offset);
9810
/* write back the new stack pointer */
9811
store_reg(s, 13, addr);
9812
/* set the new PC value */
9813
if ((insn & 0x0900) == 0x0900) {
9814
store_reg_from_load(env, s, 15, tmp);
9818
case 1: case 3: case 9: case 11: /* czb */
9820
tmp = load_reg(s, rm);
9821
s->condlabel = gen_new_label();
9823
if (insn & (1 << 11))
9824
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9826
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9827
tcg_temp_free_i32(tmp);
9828
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9829
val = (uint32_t)s->pc + 2;
9834
case 15: /* IT, nop-hint. */
9835
if ((insn & 0xf) == 0) {
9836
gen_nop_hint(s, (insn >> 4) & 0xf);
9840
s->condexec_cond = (insn >> 4) & 0xe;
9841
s->condexec_mask = insn & 0x1f;
9842
/* No actual code generated for this insn, just setup state. */
9845
case 0xe: /* bkpt */
9847
gen_exception_insn(s, 2, EXCP_BKPT);
9852
rn = (insn >> 3) & 0x7;
9854
tmp = load_reg(s, rn);
9855
switch ((insn >> 6) & 3) {
9856
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9857
case 1: gen_rev16(tmp); break;
9858
case 3: gen_revsh(tmp); break;
9859
default: goto illegal_op;
9861
store_reg(s, rd, tmp);
9865
switch ((insn >> 5) & 7) {
9869
if (((insn >> 3) & 1) != s->bswap_code) {
9870
/* Dynamic endianness switching not implemented. */
9871
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
9882
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9885
addr = tcg_const_i32(19);
9886
gen_helper_v7m_msr(cpu_env, addr, tmp);
9887
tcg_temp_free_i32(addr);
9891
addr = tcg_const_i32(16);
9892
gen_helper_v7m_msr(cpu_env, addr, tmp);
9893
tcg_temp_free_i32(addr);
9895
tcg_temp_free_i32(tmp);
9898
if (insn & (1 << 4)) {
9899
shift = CPSR_A | CPSR_I | CPSR_F;
9903
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9918
/* load/store multiple */
9919
TCGv_i32 loaded_var;
9920
TCGV_UNUSED_I32(loaded_var);
9921
rn = (insn >> 8) & 0x7;
9922
addr = load_reg(s, rn);
9923
for (i = 0; i < 8; i++) {
9924
if (insn & (1 << i)) {
9925
if (insn & (1 << 11)) {
9927
tmp = tcg_temp_new_i32();
9928
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9932
store_reg(s, i, tmp);
9936
tmp = load_reg(s, i);
9937
gen_aa32_st32(tmp, addr, IS_USER(s));
9938
tcg_temp_free_i32(tmp);
9940
/* advance to the next address */
9941
tcg_gen_addi_i32(addr, addr, 4);
9944
if ((insn & (1 << rn)) == 0) {
9945
/* base reg not in list: base register writeback */
9946
store_reg(s, rn, addr);
9948
/* base reg in list: if load, complete it now */
9949
if (insn & (1 << 11)) {
9950
store_reg(s, rn, loaded_var);
9952
tcg_temp_free_i32(addr);
9957
/* conditional branch or swi */
9958
cond = (insn >> 8) & 0xf;
9964
gen_set_pc_im(s, s->pc);
9965
s->is_jmp = DISAS_SWI;
9968
/* generate a conditional jump to next instruction */
9969
s->condlabel = gen_new_label();
9970
gen_test_cc(cond ^ 1, s->condlabel);
9973
/* jump to the offset */
9974
val = (uint32_t)s->pc + 2;
9975
offset = ((int32_t)insn << 24) >> 24;
9981
if (insn & (1 << 11)) {
9982
if (disas_thumb2_insn(env, s, insn))
9986
/* unconditional branch */
9987
val = (uint32_t)s->pc;
9988
offset = ((int32_t)insn << 21) >> 21;
9989
val += (offset << 1) + 2;
9994
if (disas_thumb2_insn(env, s, insn))
10000
gen_exception_insn(s, 4, EXCP_UDEF);
10004
gen_exception_insn(s, 2, EXCP_UDEF);
10007
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10008
basic block 'tb'. If search_pc is TRUE, also generate PC
10009
information for each intermediate instruction. */
10010
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10011
TranslationBlock *tb,
10014
CPUState *cs = CPU(cpu);
10015
CPUARMState *env = &cpu->env;
10016
DisasContext dc1, *dc = &dc1;
10018
uint16_t *gen_opc_end;
10020
target_ulong pc_start;
10021
target_ulong next_page_start;
10025
/* generate intermediate code */
10030
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10032
dc->is_jmp = DISAS_NEXT;
10034
dc->singlestep_enabled = cs->singlestep_enabled;
10037
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10040
dc->bswap_code = 0;
10041
dc->condexec_mask = 0;
10042
dc->condexec_cond = 0;
10043
#if !defined(CONFIG_USER_ONLY)
10046
dc->vfp_enabled = 0;
10048
dc->vec_stride = 0;
10051
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10052
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10053
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10054
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10055
#if !defined(CONFIG_USER_ONLY)
10056
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10058
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10059
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10060
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10062
cpu_F0s = tcg_temp_new_i32();
10063
cpu_F1s = tcg_temp_new_i32();
10064
cpu_F0d = tcg_temp_new_i64();
10065
cpu_F1d = tcg_temp_new_i64();
10068
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10069
cpu_M0 = tcg_temp_new_i64();
10070
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10073
max_insns = tb->cflags & CF_COUNT_MASK;
10074
if (max_insns == 0)
10075
max_insns = CF_COUNT_MASK;
10079
tcg_clear_temp_count();
10081
/* A note on handling of the condexec (IT) bits:
10083
* We want to avoid the overhead of having to write the updated condexec
10084
* bits back to the CPUARMState for every instruction in an IT block. So:
10085
* (1) if the condexec bits are not already zero then we write
10086
* zero back into the CPUARMState now. This avoids complications trying
10087
* to do it at the end of the block. (For example if we don't do this
10088
* it's hard to identify whether we can safely skip writing condexec
10089
* at the end of the TB, which we definitely want to do for the case
10090
* where a TB doesn't do anything with the IT state at all.)
10091
* (2) if we are going to leave the TB then we call gen_set_condexec()
10092
* which will write the correct value into CPUARMState if zero is wrong.
10093
* This is done both for leaving the TB at the end, and for leaving
10094
* it because of an exception we know will happen, which is done in
10095
* gen_exception_insn(). The latter is necessary because we need to
10096
* leave the TB with the PC/IT state just prior to execution of the
10097
* instruction which caused the exception.
10098
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10099
* then the CPUARMState will be wrong and we need to reset it.
10100
* This is handled in the same way as restoration of the
10101
* PC in these situations: we will be called again with search_pc=1
10102
* and generate a mapping of the condexec bits for each PC in
10103
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10104
* this to restore the condexec bits.
10106
* Note that there are no instructions which can read the condexec
10107
* bits, and none which can write non-static values to them, so
10108
* we don't need to care about whether CPUARMState is correct in the
10112
/* Reset the conditional execution bits immediately. This avoids
10113
complications trying to do it at the end of the block. */
10114
if (dc->condexec_mask || dc->condexec_cond)
10116
TCGv_i32 tmp = tcg_temp_new_i32();
10117
tcg_gen_movi_i32(tmp, 0);
10118
store_cpu_field(tmp, condexec_bits);
10121
#ifdef CONFIG_USER_ONLY
10122
/* Intercept jump to the magic kernel page. */
10123
if (!dc->aarch64 && dc->pc >= 0xffff0000) {
10124
/* We always get here via a jump, so know we are not in a
10125
conditional execution block. */
10126
gen_exception(EXCP_KERNEL_TRAP);
10127
dc->is_jmp = DISAS_UPDATE;
10131
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10132
/* We always get here via a jump, so know we are not in a
10133
conditional execution block. */
10134
gen_exception(EXCP_EXCEPTION_EXIT);
10135
dc->is_jmp = DISAS_UPDATE;
10140
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10141
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10142
if (bp->pc == dc->pc) {
10143
gen_exception_insn(dc, 0, EXCP_DEBUG);
10144
/* Advance PC so that clearing the breakpoint will
10145
invalidate this TB. */
10147
goto done_generating;
10152
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10156
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10158
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10159
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10160
tcg_ctx.gen_opc_instr_start[lj] = 1;
10161
tcg_ctx.gen_opc_icount[lj] = num_insns;
10164
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10167
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10168
tcg_gen_debug_insn_start(dc->pc);
10172
disas_a64_insn(env, dc);
10173
} else if (dc->thumb) {
10174
disas_thumb_insn(env, dc);
10175
if (dc->condexec_mask) {
10176
dc->condexec_cond = (dc->condexec_cond & 0xe)
10177
| ((dc->condexec_mask >> 4) & 1);
10178
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10179
if (dc->condexec_mask == 0) {
10180
dc->condexec_cond = 0;
10184
disas_arm_insn(env, dc);
10187
if (dc->condjmp && !dc->is_jmp) {
10188
gen_set_label(dc->condlabel);
10192
if (tcg_check_temp_count()) {
10193
fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10197
/* Translation stops when a conditional branch is encountered.
10198
* Otherwise the subsequent code could get translated several times.
10199
* Also stop translation when a page boundary is reached. This
10200
* ensures prefetch aborts occur at the right place. */
10202
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10203
!cs->singlestep_enabled &&
10205
dc->pc < next_page_start &&
10206
num_insns < max_insns);
10208
if (tb->cflags & CF_LAST_IO) {
10210
/* FIXME: This can theoretically happen with self-modifying
10212
cpu_abort(env, "IO on conditional branch instruction");
10217
/* At this stage dc->condjmp will only be set when the skipped
10218
instruction was a conditional branch or trap, and the PC has
10219
already been written. */
10220
if (unlikely(cs->singlestep_enabled)) {
10221
/* Make sure the pc is updated, and raise a debug exception. */
10223
gen_set_condexec(dc);
10224
if (dc->is_jmp == DISAS_SWI) {
10225
gen_exception(EXCP_SWI);
10226
} else if (dc->is_jmp == DISAS_SMC) {
10227
gen_exception(EXCP_SMC);
10229
gen_exception(EXCP_DEBUG);
10231
gen_set_label(dc->condlabel);
10233
if (dc->condjmp || !dc->is_jmp) {
10234
gen_set_pc_im(dc, dc->pc);
10237
gen_set_condexec(dc);
10238
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10239
gen_exception(EXCP_SWI);
10240
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10241
gen_exception(EXCP_SMC);
10243
/* FIXME: Single stepping a WFI insn will not halt
10245
gen_exception(EXCP_DEBUG);
10248
/* While branches must always occur at the end of an IT block,
10249
there are a few other things that can cause us to terminate
10250
the TB in the middle of an IT block:
10251
- Exception generating instructions (bkpt, swi, undefined).
10253
- Hardware watchpoints.
10254
Hardware breakpoints have already been handled and skip this code.
10256
gen_set_condexec(dc);
10257
switch(dc->is_jmp) {
10259
gen_goto_tb(dc, 1, dc->pc);
10264
/* indicate that the hash table must be used to find the next TB */
10265
tcg_gen_exit_tb(0);
10267
case DISAS_TB_JUMP:
10268
/* nothing more to generate */
10271
gen_helper_wfi(cpu_env);
10274
gen_exception(EXCP_SWI);
10277
gen_exception(EXCP_SMC);
10281
gen_set_label(dc->condlabel);
10282
gen_set_condexec(dc);
10283
gen_goto_tb(dc, 1, dc->pc);
10289
gen_tb_end(tb, num_insns);
10290
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10293
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10294
qemu_log("----------------\n");
10295
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10296
log_target_disas(env, pc_start, dc->pc - pc_start,
10297
dc->thumb | (dc->bswap_code << 1));
10302
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10305
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10307
tb->size = dc->pc - pc_start;
10308
tb->icount = num_insns;
10312
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10314
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10317
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10319
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10322
static const char *cpu_mode_names[16] = {
10323
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10324
"???", "???", "???", "und", "???", "???", "???", "sys"
10327
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10330
ARMCPU *cpu = ARM_CPU(cs);
10331
CPUARMState *env = &cpu->env;
10335
for(i=0;i<16;i++) {
10336
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10338
cpu_fprintf(f, "\n");
10340
cpu_fprintf(f, " ");
10342
psr = cpsr_read(env);
10343
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10345
psr & (1 << 31) ? 'N' : '-',
10346
psr & (1 << 30) ? 'Z' : '-',
10347
psr & (1 << 29) ? 'C' : '-',
10348
psr & (1 << 28) ? 'V' : '-',
10349
psr & CPSR_T ? 'T' : 'A',
10350
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10352
if (flags & CPU_DUMP_FPU) {
10353
int numvfpregs = 0;
10354
if (arm_feature(env, ARM_FEATURE_VFP)) {
10357
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10360
for (i = 0; i < numvfpregs; i++) {
10361
uint64_t v = float64_val(env->vfp.regs[i]);
10362
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10363
i * 2, (uint32_t)v,
10364
i * 2 + 1, (uint32_t)(v >> 32),
10367
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10371
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10374
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10376
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10378
env->condexec_bits = gen_opc_condexec_bits[pc_pos];