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
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2627
uint32_t cc = extract32(insn, 20, 2);
2630
TCGv_i64 frn, frm, dest;
2631
TCGv_i64 tmp, zero, zf, nf, vf;
2633
zero = tcg_const_i64(0);
2635
frn = tcg_temp_new_i64();
2636
frm = tcg_temp_new_i64();
2637
dest = tcg_temp_new_i64();
2639
zf = tcg_temp_new_i64();
2640
nf = tcg_temp_new_i64();
2641
vf = tcg_temp_new_i64();
2643
tcg_gen_extu_i32_i64(zf, cpu_ZF);
2644
tcg_gen_ext_i32_i64(nf, cpu_NF);
2645
tcg_gen_ext_i32_i64(vf, cpu_VF);
2647
tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2648
tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2651
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2655
tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2658
case 2: /* ge: N == V -> N ^ V == 0 */
2659
tmp = tcg_temp_new_i64();
2660
tcg_gen_xor_i64(tmp, vf, nf);
2661
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2663
tcg_temp_free_i64(tmp);
2665
case 3: /* gt: !Z && N == V */
2666
tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2668
tmp = tcg_temp_new_i64();
2669
tcg_gen_xor_i64(tmp, vf, nf);
2670
tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2672
tcg_temp_free_i64(tmp);
2675
tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2676
tcg_temp_free_i64(frn);
2677
tcg_temp_free_i64(frm);
2678
tcg_temp_free_i64(dest);
2680
tcg_temp_free_i64(zf);
2681
tcg_temp_free_i64(nf);
2682
tcg_temp_free_i64(vf);
2684
tcg_temp_free_i64(zero);
2686
TCGv_i32 frn, frm, dest;
2689
zero = tcg_const_i32(0);
2691
frn = tcg_temp_new_i32();
2692
frm = tcg_temp_new_i32();
2693
dest = tcg_temp_new_i32();
2694
tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2695
tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2698
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2702
tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2705
case 2: /* ge: N == V -> N ^ V == 0 */
2706
tmp = tcg_temp_new_i32();
2707
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2708
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2710
tcg_temp_free_i32(tmp);
2712
case 3: /* gt: !Z && N == V */
2713
tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2715
tmp = tcg_temp_new_i32();
2716
tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2717
tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2719
tcg_temp_free_i32(tmp);
2722
tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2723
tcg_temp_free_i32(frn);
2724
tcg_temp_free_i32(frm);
2725
tcg_temp_free_i32(dest);
2727
tcg_temp_free_i32(zero);
2733
static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2735
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2737
if (!arm_feature(env, ARM_FEATURE_V8)) {
2742
VFP_DREG_D(rd, insn);
2743
VFP_DREG_N(rn, insn);
2744
VFP_DREG_M(rm, insn);
2746
rd = VFP_SREG_D(insn);
2747
rn = VFP_SREG_N(insn);
2748
rm = VFP_SREG_M(insn);
2751
if ((insn & 0x0f800e50) == 0x0e000a00) {
2752
return handle_vsel(insn, rd, rn, rm, dp);
2757
/* Disassemble a VFP instruction. Returns nonzero if an error occurred
2758
(ie. an undefined instruction). */
2759
static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2761
uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2767
if (!arm_feature(env, ARM_FEATURE_VFP))
2770
if (!s->vfp_enabled) {
2771
/* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2772
if ((insn & 0x0fe00fff) != 0x0ee00a10)
2774
rn = (insn >> 16) & 0xf;
2775
if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2776
&& rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2780
if (extract32(insn, 28, 4) == 0xf) {
2781
/* Encodings with T=1 (Thumb) or unconditional (ARM):
2782
* only used in v8 and above.
2784
return disas_vfp_v8_insn(env, s, insn);
2787
dp = ((insn & 0xf00) == 0xb00);
2788
switch ((insn >> 24) & 0xf) {
2790
if (insn & (1 << 4)) {
2791
/* single register transfer */
2792
rd = (insn >> 12) & 0xf;
2797
VFP_DREG_N(rn, insn);
2800
if (insn & 0x00c00060
2801
&& !arm_feature(env, ARM_FEATURE_NEON))
2804
pass = (insn >> 21) & 1;
2805
if (insn & (1 << 22)) {
2807
offset = ((insn >> 5) & 3) * 8;
2808
} else if (insn & (1 << 5)) {
2810
offset = (insn & (1 << 6)) ? 16 : 0;
2815
if (insn & ARM_CP_RW_BIT) {
2817
tmp = neon_load_reg(rn, pass);
2821
tcg_gen_shri_i32(tmp, tmp, offset);
2822
if (insn & (1 << 23))
2828
if (insn & (1 << 23)) {
2830
tcg_gen_shri_i32(tmp, tmp, 16);
2836
tcg_gen_sari_i32(tmp, tmp, 16);
2845
store_reg(s, rd, tmp);
2848
tmp = load_reg(s, rd);
2849
if (insn & (1 << 23)) {
2852
gen_neon_dup_u8(tmp, 0);
2853
} else if (size == 1) {
2854
gen_neon_dup_low16(tmp);
2856
for (n = 0; n <= pass * 2; n++) {
2857
tmp2 = tcg_temp_new_i32();
2858
tcg_gen_mov_i32(tmp2, tmp);
2859
neon_store_reg(rn, n, tmp2);
2861
neon_store_reg(rn, n, tmp);
2866
tmp2 = neon_load_reg(rn, pass);
2867
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2868
tcg_temp_free_i32(tmp2);
2871
tmp2 = neon_load_reg(rn, pass);
2872
tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2873
tcg_temp_free_i32(tmp2);
2878
neon_store_reg(rn, pass, tmp);
2882
if ((insn & 0x6f) != 0x00)
2884
rn = VFP_SREG_N(insn);
2885
if (insn & ARM_CP_RW_BIT) {
2887
if (insn & (1 << 21)) {
2888
/* system register */
2893
/* VFP2 allows access to FSID from userspace.
2894
VFP3 restricts all id registers to privileged
2897
&& arm_feature(env, ARM_FEATURE_VFP3))
2899
tmp = load_cpu_field(vfp.xregs[rn]);
2904
tmp = load_cpu_field(vfp.xregs[rn]);
2906
case ARM_VFP_FPINST:
2907
case ARM_VFP_FPINST2:
2908
/* Not present in VFP3. */
2910
|| arm_feature(env, ARM_FEATURE_VFP3))
2912
tmp = load_cpu_field(vfp.xregs[rn]);
2916
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2917
tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2919
tmp = tcg_temp_new_i32();
2920
gen_helper_vfp_get_fpscr(tmp, cpu_env);
2926
|| !arm_feature(env, ARM_FEATURE_MVFR))
2928
tmp = load_cpu_field(vfp.xregs[rn]);
2934
gen_mov_F0_vreg(0, rn);
2935
tmp = gen_vfp_mrs();
2938
/* Set the 4 flag bits in the CPSR. */
2940
tcg_temp_free_i32(tmp);
2942
store_reg(s, rd, tmp);
2946
if (insn & (1 << 21)) {
2948
/* system register */
2953
/* Writes are ignored. */
2956
tmp = load_reg(s, rd);
2957
gen_helper_vfp_set_fpscr(cpu_env, tmp);
2958
tcg_temp_free_i32(tmp);
2964
/* TODO: VFP subarchitecture support.
2965
* For now, keep the EN bit only */
2966
tmp = load_reg(s, rd);
2967
tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2968
store_cpu_field(tmp, vfp.xregs[rn]);
2971
case ARM_VFP_FPINST:
2972
case ARM_VFP_FPINST2:
2973
tmp = load_reg(s, rd);
2974
store_cpu_field(tmp, vfp.xregs[rn]);
2980
tmp = load_reg(s, rd);
2982
gen_mov_vreg_F0(0, rn);
2987
/* data processing */
2988
/* The opcode is in bits 23, 21, 20 and 6. */
2989
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2993
rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2995
/* rn is register number */
2996
VFP_DREG_N(rn, insn);
2999
if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3000
/* Integer or single precision destination. */
3001
rd = VFP_SREG_D(insn);
3003
VFP_DREG_D(rd, insn);
3006
(((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3007
/* VCVT from int is always from S reg regardless of dp bit.
3008
* VCVT with immediate frac_bits has same format as SREG_M
3010
rm = VFP_SREG_M(insn);
3012
VFP_DREG_M(rm, insn);
3015
rn = VFP_SREG_N(insn);
3016
if (op == 15 && rn == 15) {
3017
/* Double precision destination. */
3018
VFP_DREG_D(rd, insn);
3020
rd = VFP_SREG_D(insn);
3022
/* NB that we implicitly rely on the encoding for the frac_bits
3023
* in VCVT of fixed to float being the same as that of an SREG_M
3025
rm = VFP_SREG_M(insn);
3028
veclen = s->vec_len;
3029
if (op == 15 && rn > 3)
3032
/* Shut up compiler warnings. */
3043
/* Figure out what type of vector operation this is. */
3044
if ((rd & bank_mask) == 0) {
3049
delta_d = (s->vec_stride >> 1) + 1;
3051
delta_d = s->vec_stride + 1;
3053
if ((rm & bank_mask) == 0) {
3054
/* mixed scalar/vector */
3063
/* Load the initial operands. */
3068
/* Integer source */
3069
gen_mov_F0_vreg(0, rm);
3074
gen_mov_F0_vreg(dp, rd);
3075
gen_mov_F1_vreg(dp, rm);
3079
/* Compare with zero */
3080
gen_mov_F0_vreg(dp, rd);
3091
/* Source and destination the same. */
3092
gen_mov_F0_vreg(dp, rd);
3098
/* VCVTB, VCVTT: only present with the halfprec extension,
3099
* UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3101
if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3104
/* Otherwise fall through */
3106
/* One source operand. */
3107
gen_mov_F0_vreg(dp, rm);
3111
/* Two source operands. */
3112
gen_mov_F0_vreg(dp, rn);
3113
gen_mov_F1_vreg(dp, rm);
3117
/* Perform the calculation. */
3119
case 0: /* VMLA: fd + (fn * fm) */
3120
/* Note that order of inputs to the add matters for NaNs */
3122
gen_mov_F0_vreg(dp, rd);
3125
case 1: /* VMLS: fd + -(fn * fm) */
3128
gen_mov_F0_vreg(dp, rd);
3131
case 2: /* VNMLS: -fd + (fn * fm) */
3132
/* Note that it isn't valid to replace (-A + B) with (B - A)
3133
* or similar plausible looking simplifications
3134
* because this will give wrong results for NaNs.
3137
gen_mov_F0_vreg(dp, rd);
3141
case 3: /* VNMLA: -fd + -(fn * fm) */
3144
gen_mov_F0_vreg(dp, rd);
3148
case 4: /* mul: fn * fm */
3151
case 5: /* nmul: -(fn * fm) */
3155
case 6: /* add: fn + fm */
3158
case 7: /* sub: fn - fm */
3161
case 8: /* div: fn / fm */
3164
case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3165
case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3166
case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3167
case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3168
/* These are fused multiply-add, and must be done as one
3169
* floating point operation with no rounding between the
3170
* multiplication and addition steps.
3171
* NB that doing the negations here as separate steps is
3172
* correct : an input NaN should come out with its sign bit
3173
* flipped if it is a negated-input.
3175
if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3183
gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3185
frd = tcg_temp_new_i64();
3186
tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3189
gen_helper_vfp_negd(frd, frd);
3191
fpst = get_fpstatus_ptr(0);
3192
gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3193
cpu_F1d, frd, fpst);
3194
tcg_temp_free_ptr(fpst);
3195
tcg_temp_free_i64(frd);
3201
gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3203
frd = tcg_temp_new_i32();
3204
tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3206
gen_helper_vfp_negs(frd, frd);
3208
fpst = get_fpstatus_ptr(0);
3209
gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3210
cpu_F1s, frd, fpst);
3211
tcg_temp_free_ptr(fpst);
3212
tcg_temp_free_i32(frd);
3215
case 14: /* fconst */
3216
if (!arm_feature(env, ARM_FEATURE_VFP3))
3219
n = (insn << 12) & 0x80000000;
3220
i = ((insn >> 12) & 0x70) | (insn & 0xf);
3227
tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3234
tcg_gen_movi_i32(cpu_F0s, n);
3237
case 15: /* extension space */
3251
case 4: /* vcvtb.f32.f16 */
3252
tmp = gen_vfp_mrs();
3253
tcg_gen_ext16u_i32(tmp, tmp);
3254
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3255
tcg_temp_free_i32(tmp);
3257
case 5: /* vcvtt.f32.f16 */
3258
tmp = gen_vfp_mrs();
3259
tcg_gen_shri_i32(tmp, tmp, 16);
3260
gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3261
tcg_temp_free_i32(tmp);
3263
case 6: /* vcvtb.f16.f32 */
3264
tmp = tcg_temp_new_i32();
3265
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3266
gen_mov_F0_vreg(0, rd);
3267
tmp2 = gen_vfp_mrs();
3268
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3269
tcg_gen_or_i32(tmp, tmp, tmp2);
3270
tcg_temp_free_i32(tmp2);
3273
case 7: /* vcvtt.f16.f32 */
3274
tmp = tcg_temp_new_i32();
3275
gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3276
tcg_gen_shli_i32(tmp, tmp, 16);
3277
gen_mov_F0_vreg(0, rd);
3278
tmp2 = gen_vfp_mrs();
3279
tcg_gen_ext16u_i32(tmp2, tmp2);
3280
tcg_gen_or_i32(tmp, tmp, tmp2);
3281
tcg_temp_free_i32(tmp2);
3293
case 11: /* cmpez */
3297
case 15: /* single<->double conversion */
3299
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3301
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3303
case 16: /* fuito */
3304
gen_vfp_uito(dp, 0);
3306
case 17: /* fsito */
3307
gen_vfp_sito(dp, 0);
3309
case 20: /* fshto */
3310
if (!arm_feature(env, ARM_FEATURE_VFP3))
3312
gen_vfp_shto(dp, 16 - rm, 0);
3314
case 21: /* fslto */
3315
if (!arm_feature(env, ARM_FEATURE_VFP3))
3317
gen_vfp_slto(dp, 32 - rm, 0);
3319
case 22: /* fuhto */
3320
if (!arm_feature(env, ARM_FEATURE_VFP3))
3322
gen_vfp_uhto(dp, 16 - rm, 0);
3324
case 23: /* fulto */
3325
if (!arm_feature(env, ARM_FEATURE_VFP3))
3327
gen_vfp_ulto(dp, 32 - rm, 0);
3329
case 24: /* ftoui */
3330
gen_vfp_toui(dp, 0);
3332
case 25: /* ftouiz */
3333
gen_vfp_touiz(dp, 0);
3335
case 26: /* ftosi */
3336
gen_vfp_tosi(dp, 0);
3338
case 27: /* ftosiz */
3339
gen_vfp_tosiz(dp, 0);
3341
case 28: /* ftosh */
3342
if (!arm_feature(env, ARM_FEATURE_VFP3))
3344
gen_vfp_tosh(dp, 16 - rm, 0);
3346
case 29: /* ftosl */
3347
if (!arm_feature(env, ARM_FEATURE_VFP3))
3349
gen_vfp_tosl(dp, 32 - rm, 0);
3351
case 30: /* ftouh */
3352
if (!arm_feature(env, ARM_FEATURE_VFP3))
3354
gen_vfp_touh(dp, 16 - rm, 0);
3356
case 31: /* ftoul */
3357
if (!arm_feature(env, ARM_FEATURE_VFP3))
3359
gen_vfp_toul(dp, 32 - rm, 0);
3361
default: /* undefined */
3365
default: /* undefined */
3369
/* Write back the result. */
3370
if (op == 15 && (rn >= 8 && rn <= 11))
3371
; /* Comparison, do nothing. */
3372
else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3373
/* VCVT double to int: always integer result. */
3374
gen_mov_vreg_F0(0, rd);
3375
else if (op == 15 && rn == 15)
3377
gen_mov_vreg_F0(!dp, rd);
3379
gen_mov_vreg_F0(dp, rd);
3381
/* break out of the loop if we have finished */
3385
if (op == 15 && delta_m == 0) {
3386
/* single source one-many */
3388
rd = ((rd + delta_d) & (bank_mask - 1))
3390
gen_mov_vreg_F0(dp, rd);
3394
/* Setup the next operands. */
3396
rd = ((rd + delta_d) & (bank_mask - 1))
3400
/* One source operand. */
3401
rm = ((rm + delta_m) & (bank_mask - 1))
3403
gen_mov_F0_vreg(dp, rm);
3405
/* Two source operands. */
3406
rn = ((rn + delta_d) & (bank_mask - 1))
3408
gen_mov_F0_vreg(dp, rn);
3410
rm = ((rm + delta_m) & (bank_mask - 1))
3412
gen_mov_F1_vreg(dp, rm);
3420
if ((insn & 0x03e00000) == 0x00400000) {
3421
/* two-register transfer */
3422
rn = (insn >> 16) & 0xf;
3423
rd = (insn >> 12) & 0xf;
3425
VFP_DREG_M(rm, insn);
3427
rm = VFP_SREG_M(insn);
3430
if (insn & ARM_CP_RW_BIT) {
3433
gen_mov_F0_vreg(0, rm * 2);
3434
tmp = gen_vfp_mrs();
3435
store_reg(s, rd, tmp);
3436
gen_mov_F0_vreg(0, rm * 2 + 1);
3437
tmp = gen_vfp_mrs();
3438
store_reg(s, rn, tmp);
3440
gen_mov_F0_vreg(0, rm);
3441
tmp = gen_vfp_mrs();
3442
store_reg(s, rd, tmp);
3443
gen_mov_F0_vreg(0, rm + 1);
3444
tmp = gen_vfp_mrs();
3445
store_reg(s, rn, tmp);
3450
tmp = load_reg(s, rd);
3452
gen_mov_vreg_F0(0, rm * 2);
3453
tmp = load_reg(s, rn);
3455
gen_mov_vreg_F0(0, rm * 2 + 1);
3457
tmp = load_reg(s, rd);
3459
gen_mov_vreg_F0(0, rm);
3460
tmp = load_reg(s, rn);
3462
gen_mov_vreg_F0(0, rm + 1);
3467
rn = (insn >> 16) & 0xf;
3469
VFP_DREG_D(rd, insn);
3471
rd = VFP_SREG_D(insn);
3472
if ((insn & 0x01200000) == 0x01000000) {
3473
/* Single load/store */
3474
offset = (insn & 0xff) << 2;
3475
if ((insn & (1 << 23)) == 0)
3477
if (s->thumb && rn == 15) {
3478
/* This is actually UNPREDICTABLE */
3479
addr = tcg_temp_new_i32();
3480
tcg_gen_movi_i32(addr, s->pc & ~2);
3482
addr = load_reg(s, rn);
3484
tcg_gen_addi_i32(addr, addr, offset);
3485
if (insn & (1 << 20)) {
3486
gen_vfp_ld(s, dp, addr);
3487
gen_mov_vreg_F0(dp, rd);
3489
gen_mov_F0_vreg(dp, rd);
3490
gen_vfp_st(s, dp, addr);
3492
tcg_temp_free_i32(addr);
3494
/* load/store multiple */
3495
int w = insn & (1 << 21);
3497
n = (insn >> 1) & 0x7f;
3501
if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3502
/* P == U , W == 1 => UNDEF */
3505
if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3506
/* UNPREDICTABLE cases for bad immediates: we choose to
3507
* UNDEF to avoid generating huge numbers of TCG ops
3511
if (rn == 15 && w) {
3512
/* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3516
if (s->thumb && rn == 15) {
3517
/* This is actually UNPREDICTABLE */
3518
addr = tcg_temp_new_i32();
3519
tcg_gen_movi_i32(addr, s->pc & ~2);
3521
addr = load_reg(s, rn);
3523
if (insn & (1 << 24)) /* pre-decrement */
3524
tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3530
for (i = 0; i < n; i++) {
3531
if (insn & ARM_CP_RW_BIT) {
3533
gen_vfp_ld(s, dp, addr);
3534
gen_mov_vreg_F0(dp, rd + i);
3537
gen_mov_F0_vreg(dp, rd + i);
3538
gen_vfp_st(s, dp, addr);
3540
tcg_gen_addi_i32(addr, addr, offset);
3544
if (insn & (1 << 24))
3545
offset = -offset * n;
3546
else if (dp && (insn & 1))
3552
tcg_gen_addi_i32(addr, addr, offset);
3553
store_reg(s, rn, addr);
3555
tcg_temp_free_i32(addr);
3561
/* Should never happen. */
3567
static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3569
TranslationBlock *tb;
3572
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3574
gen_set_pc_im(s, dest);
3575
tcg_gen_exit_tb((uintptr_t)tb + n);
3577
gen_set_pc_im(s, dest);
3582
static inline void gen_jmp (DisasContext *s, uint32_t dest)
3584
if (unlikely(s->singlestep_enabled)) {
3585
/* An indirect jump so that we still trigger the debug exception. */
3590
gen_goto_tb(s, 0, dest);
3591
s->is_jmp = DISAS_TB_JUMP;
3595
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3598
tcg_gen_sari_i32(t0, t0, 16);
3602
tcg_gen_sari_i32(t1, t1, 16);
3605
tcg_gen_mul_i32(t0, t0, t1);
3608
/* Return the mask of PSR bits set by a MSR instruction. */
3609
static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3613
if (flags & (1 << 0))
3615
if (flags & (1 << 1))
3617
if (flags & (1 << 2))
3619
if (flags & (1 << 3))
3622
/* Mask out undefined bits. */
3623
mask &= ~CPSR_RESERVED;
3624
if (!arm_feature(env, ARM_FEATURE_V4T))
3626
if (!arm_feature(env, ARM_FEATURE_V5))
3627
mask &= ~CPSR_Q; /* V5TE in reality*/
3628
if (!arm_feature(env, ARM_FEATURE_V6))
3629
mask &= ~(CPSR_E | CPSR_GE);
3630
if (!arm_feature(env, ARM_FEATURE_THUMB2))
3632
/* Mask out execution state bits. */
3635
/* Mask out privileged bits. */
3641
/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3642
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3646
/* ??? This is also undefined in system mode. */
3650
tmp = load_cpu_field(spsr);
3651
tcg_gen_andi_i32(tmp, tmp, ~mask);
3652
tcg_gen_andi_i32(t0, t0, mask);
3653
tcg_gen_or_i32(tmp, tmp, t0);
3654
store_cpu_field(tmp, spsr);
3656
gen_set_cpsr(t0, mask);
3658
tcg_temp_free_i32(t0);
3663
/* Returns nonzero if access to the PSR is not permitted. */
3664
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3667
tmp = tcg_temp_new_i32();
3668
tcg_gen_movi_i32(tmp, val);
3669
return gen_set_psr(s, mask, spsr, tmp);
3672
/* Generate an old-style exception return. Marks pc as dead. */
3673
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3676
store_reg(s, 15, pc);
3677
tmp = load_cpu_field(spsr);
3678
gen_set_cpsr(tmp, 0xffffffff);
3679
tcg_temp_free_i32(tmp);
3680
s->is_jmp = DISAS_UPDATE;
3683
/* Generate a v6 exception return. Marks both values as dead. */
3684
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3686
gen_set_cpsr(cpsr, 0xffffffff);
3687
tcg_temp_free_i32(cpsr);
3688
store_reg(s, 15, pc);
3689
s->is_jmp = DISAS_UPDATE;
3693
gen_set_condexec (DisasContext *s)
3695
if (s->condexec_mask) {
3696
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3697
TCGv_i32 tmp = tcg_temp_new_i32();
3698
tcg_gen_movi_i32(tmp, val);
3699
store_cpu_field(tmp, condexec_bits);
3703
static void gen_exception_insn(DisasContext *s, int offset, int excp)
3705
gen_set_condexec(s);
3706
gen_set_pc_im(s, s->pc - offset);
3707
gen_exception(excp);
3708
s->is_jmp = DISAS_JUMP;
3711
static void gen_nop_hint(DisasContext *s, int val)
3715
gen_set_pc_im(s, s->pc);
3716
s->is_jmp = DISAS_WFI;
3721
/* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3727
#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3729
static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3732
case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3733
case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3734
case 2: tcg_gen_add_i32(t0, t0, t1); break;
3739
static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3742
case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3743
case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3744
case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3749
/* 32-bit pairwise ops end up the same as the elementwise versions. */
3750
#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3751
#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3752
#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3753
#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3755
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
3756
switch ((size << 1) | u) { \
3758
gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3761
gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3764
gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3767
gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3770
gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3773
gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3775
default: return 1; \
3778
#define GEN_NEON_INTEGER_OP(name) do { \
3779
switch ((size << 1) | u) { \
3781
gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3784
gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3787
gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3790
gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3793
gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3796
gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3798
default: return 1; \
3801
static TCGv_i32 neon_load_scratch(int scratch)
3803
TCGv_i32 tmp = tcg_temp_new_i32();
3804
tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3808
static void neon_store_scratch(int scratch, TCGv_i32 var)
3810
tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3811
tcg_temp_free_i32(var);
3814
static inline TCGv_i32 neon_get_scalar(int size, int reg)
3818
tmp = neon_load_reg(reg & 7, reg >> 4);
3820
gen_neon_dup_high16(tmp);
3822
gen_neon_dup_low16(tmp);
3825
tmp = neon_load_reg(reg & 15, reg >> 4);
3830
static int gen_neon_unzip(int rd, int rm, int size, int q)
3833
if (!q && size == 2) {
3836
tmp = tcg_const_i32(rd);
3837
tmp2 = tcg_const_i32(rm);
3841
gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3844
gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3847
gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3855
gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3858
gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3864
tcg_temp_free_i32(tmp);
3865
tcg_temp_free_i32(tmp2);
3869
static int gen_neon_zip(int rd, int rm, int size, int q)
3872
if (!q && size == 2) {
3875
tmp = tcg_const_i32(rd);
3876
tmp2 = tcg_const_i32(rm);
3880
gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3883
gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3886
gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3894
gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3897
gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3903
tcg_temp_free_i32(tmp);
3904
tcg_temp_free_i32(tmp2);
3908
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3912
rd = tcg_temp_new_i32();
3913
tmp = tcg_temp_new_i32();
3915
tcg_gen_shli_i32(rd, t0, 8);
3916
tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3917
tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3918
tcg_gen_or_i32(rd, rd, tmp);
3920
tcg_gen_shri_i32(t1, t1, 8);
3921
tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3922
tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3923
tcg_gen_or_i32(t1, t1, tmp);
3924
tcg_gen_mov_i32(t0, rd);
3926
tcg_temp_free_i32(tmp);
3927
tcg_temp_free_i32(rd);
3930
static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3934
rd = tcg_temp_new_i32();
3935
tmp = tcg_temp_new_i32();
3937
tcg_gen_shli_i32(rd, t0, 16);
3938
tcg_gen_andi_i32(tmp, t1, 0xffff);
3939
tcg_gen_or_i32(rd, rd, tmp);
3940
tcg_gen_shri_i32(t1, t1, 16);
3941
tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3942
tcg_gen_or_i32(t1, t1, tmp);
3943
tcg_gen_mov_i32(t0, rd);
3945
tcg_temp_free_i32(tmp);
3946
tcg_temp_free_i32(rd);
3954
} neon_ls_element_type[11] = {
3968
/* Translate a NEON load/store element instruction. Return nonzero if the
3969
instruction is invalid. */
3970
static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
3989
if (!s->vfp_enabled)
3991
VFP_DREG_D(rd, insn);
3992
rn = (insn >> 16) & 0xf;
3994
load = (insn & (1 << 21)) != 0;
3995
if ((insn & (1 << 23)) == 0) {
3996
/* Load store all elements. */
3997
op = (insn >> 8) & 0xf;
3998
size = (insn >> 6) & 3;
4001
/* Catch UNDEF cases for bad values of align field */
4004
if (((insn >> 5) & 1) == 1) {
4009
if (((insn >> 4) & 3) == 3) {
4016
nregs = neon_ls_element_type[op].nregs;
4017
interleave = neon_ls_element_type[op].interleave;
4018
spacing = neon_ls_element_type[op].spacing;
4019
if (size == 3 && (interleave | spacing) != 1)
4021
addr = tcg_temp_new_i32();
4022
load_reg_var(s, addr, rn);
4023
stride = (1 << size) * interleave;
4024
for (reg = 0; reg < nregs; reg++) {
4025
if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4026
load_reg_var(s, addr, rn);
4027
tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4028
} else if (interleave == 2 && nregs == 4 && reg == 2) {
4029
load_reg_var(s, addr, rn);
4030
tcg_gen_addi_i32(addr, addr, 1 << size);
4033
tmp64 = tcg_temp_new_i64();
4035
gen_aa32_ld64(tmp64, addr, IS_USER(s));
4036
neon_store_reg64(tmp64, rd);
4038
neon_load_reg64(tmp64, rd);
4039
gen_aa32_st64(tmp64, addr, IS_USER(s));
4041
tcg_temp_free_i64(tmp64);
4042
tcg_gen_addi_i32(addr, addr, stride);
4044
for (pass = 0; pass < 2; pass++) {
4047
tmp = tcg_temp_new_i32();
4048
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4049
neon_store_reg(rd, pass, tmp);
4051
tmp = neon_load_reg(rd, pass);
4052
gen_aa32_st32(tmp, addr, IS_USER(s));
4053
tcg_temp_free_i32(tmp);
4055
tcg_gen_addi_i32(addr, addr, stride);
4056
} else if (size == 1) {
4058
tmp = tcg_temp_new_i32();
4059
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4060
tcg_gen_addi_i32(addr, addr, stride);
4061
tmp2 = tcg_temp_new_i32();
4062
gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4063
tcg_gen_addi_i32(addr, addr, stride);
4064
tcg_gen_shli_i32(tmp2, tmp2, 16);
4065
tcg_gen_or_i32(tmp, tmp, tmp2);
4066
tcg_temp_free_i32(tmp2);
4067
neon_store_reg(rd, pass, tmp);
4069
tmp = neon_load_reg(rd, pass);
4070
tmp2 = tcg_temp_new_i32();
4071
tcg_gen_shri_i32(tmp2, tmp, 16);
4072
gen_aa32_st16(tmp, addr, IS_USER(s));
4073
tcg_temp_free_i32(tmp);
4074
tcg_gen_addi_i32(addr, addr, stride);
4075
gen_aa32_st16(tmp2, addr, IS_USER(s));
4076
tcg_temp_free_i32(tmp2);
4077
tcg_gen_addi_i32(addr, addr, stride);
4079
} else /* size == 0 */ {
4081
TCGV_UNUSED_I32(tmp2);
4082
for (n = 0; n < 4; n++) {
4083
tmp = tcg_temp_new_i32();
4084
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4085
tcg_gen_addi_i32(addr, addr, stride);
4089
tcg_gen_shli_i32(tmp, tmp, n * 8);
4090
tcg_gen_or_i32(tmp2, tmp2, tmp);
4091
tcg_temp_free_i32(tmp);
4094
neon_store_reg(rd, pass, tmp2);
4096
tmp2 = neon_load_reg(rd, pass);
4097
for (n = 0; n < 4; n++) {
4098
tmp = tcg_temp_new_i32();
4100
tcg_gen_mov_i32(tmp, tmp2);
4102
tcg_gen_shri_i32(tmp, tmp2, n * 8);
4104
gen_aa32_st8(tmp, addr, IS_USER(s));
4105
tcg_temp_free_i32(tmp);
4106
tcg_gen_addi_i32(addr, addr, stride);
4108
tcg_temp_free_i32(tmp2);
4115
tcg_temp_free_i32(addr);
4118
size = (insn >> 10) & 3;
4120
/* Load single element to all lanes. */
4121
int a = (insn >> 4) & 1;
4125
size = (insn >> 6) & 3;
4126
nregs = ((insn >> 8) & 3) + 1;
4129
if (nregs != 4 || a == 0) {
4132
/* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4135
if (nregs == 1 && a == 1 && size == 0) {
4138
if (nregs == 3 && a == 1) {
4141
addr = tcg_temp_new_i32();
4142
load_reg_var(s, addr, rn);
4144
/* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4145
tmp = gen_load_and_replicate(s, addr, size);
4146
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4147
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4148
if (insn & (1 << 5)) {
4149
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4150
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4152
tcg_temp_free_i32(tmp);
4154
/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4155
stride = (insn & (1 << 5)) ? 2 : 1;
4156
for (reg = 0; reg < nregs; reg++) {
4157
tmp = gen_load_and_replicate(s, addr, size);
4158
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4159
tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4160
tcg_temp_free_i32(tmp);
4161
tcg_gen_addi_i32(addr, addr, 1 << size);
4165
tcg_temp_free_i32(addr);
4166
stride = (1 << size) * nregs;
4168
/* Single element. */
4169
int idx = (insn >> 4) & 0xf;
4170
pass = (insn >> 7) & 1;
4173
shift = ((insn >> 5) & 3) * 8;
4177
shift = ((insn >> 6) & 1) * 16;
4178
stride = (insn & (1 << 5)) ? 2 : 1;
4182
stride = (insn & (1 << 6)) ? 2 : 1;
4187
nregs = ((insn >> 8) & 3) + 1;
4188
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
4191
if (((idx & (1 << size)) != 0) ||
4192
(size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4197
if ((idx & 1) != 0) {
4202
if (size == 2 && (idx & 2) != 0) {
4207
if ((size == 2) && ((idx & 3) == 3)) {
4214
if ((rd + stride * (nregs - 1)) > 31) {
4215
/* Attempts to write off the end of the register file
4216
* are UNPREDICTABLE; we choose to UNDEF because otherwise
4217
* the neon_load_reg() would write off the end of the array.
4221
addr = tcg_temp_new_i32();
4222
load_reg_var(s, addr, rn);
4223
for (reg = 0; reg < nregs; reg++) {
4225
tmp = tcg_temp_new_i32();
4228
gen_aa32_ld8u(tmp, addr, IS_USER(s));
4231
gen_aa32_ld16u(tmp, addr, IS_USER(s));
4234
gen_aa32_ld32u(tmp, addr, IS_USER(s));
4236
default: /* Avoid compiler warnings. */
4240
tmp2 = neon_load_reg(rd, pass);
4241
tcg_gen_deposit_i32(tmp, tmp2, tmp,
4242
shift, size ? 16 : 8);
4243
tcg_temp_free_i32(tmp2);
4245
neon_store_reg(rd, pass, tmp);
4246
} else { /* Store */
4247
tmp = neon_load_reg(rd, pass);
4249
tcg_gen_shri_i32(tmp, tmp, shift);
4252
gen_aa32_st8(tmp, addr, IS_USER(s));
4255
gen_aa32_st16(tmp, addr, IS_USER(s));
4258
gen_aa32_st32(tmp, addr, IS_USER(s));
4261
tcg_temp_free_i32(tmp);
4264
tcg_gen_addi_i32(addr, addr, 1 << size);
4266
tcg_temp_free_i32(addr);
4267
stride = nregs * (1 << size);
4273
base = load_reg(s, rn);
4275
tcg_gen_addi_i32(base, base, stride);
4278
index = load_reg(s, rm);
4279
tcg_gen_add_i32(base, base, index);
4280
tcg_temp_free_i32(index);
4282
store_reg(s, rn, base);
4287
/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4288
static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4290
tcg_gen_and_i32(t, t, c);
4291
tcg_gen_andc_i32(f, f, c);
4292
tcg_gen_or_i32(dest, t, f);
4295
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4298
case 0: gen_helper_neon_narrow_u8(dest, src); break;
4299
case 1: gen_helper_neon_narrow_u16(dest, src); break;
4300
case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4305
static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4308
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4309
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4310
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4315
static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4318
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4319
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4320
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4325
static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4328
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4329
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4330
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4335
static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4341
case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4342
case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4347
case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4348
case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4355
case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4356
case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4361
case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4362
case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4369
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4373
case 0: gen_helper_neon_widen_u8(dest, src); break;
4374
case 1: gen_helper_neon_widen_u16(dest, src); break;
4375
case 2: tcg_gen_extu_i32_i64(dest, src); break;
4380
case 0: gen_helper_neon_widen_s8(dest, src); break;
4381
case 1: gen_helper_neon_widen_s16(dest, src); break;
4382
case 2: tcg_gen_ext_i32_i64(dest, src); break;
4386
tcg_temp_free_i32(src);
4389
static inline void gen_neon_addl(int size)
4392
case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4393
case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4394
case 2: tcg_gen_add_i64(CPU_V001); break;
4399
static inline void gen_neon_subl(int size)
4402
case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4403
case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4404
case 2: tcg_gen_sub_i64(CPU_V001); break;
4409
static inline void gen_neon_negl(TCGv_i64 var, int size)
4412
case 0: gen_helper_neon_negl_u16(var, var); break;
4413
case 1: gen_helper_neon_negl_u32(var, var); break;
4415
tcg_gen_neg_i64(var, var);
4421
static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4424
case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4425
case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4430
static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4435
switch ((size << 1) | u) {
4436
case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4437
case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4438
case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4439
case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4441
tmp = gen_muls_i64_i32(a, b);
4442
tcg_gen_mov_i64(dest, tmp);
4443
tcg_temp_free_i64(tmp);
4446
tmp = gen_mulu_i64_i32(a, b);
4447
tcg_gen_mov_i64(dest, tmp);
4448
tcg_temp_free_i64(tmp);
4453
/* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4454
Don't forget to clean them now. */
4456
tcg_temp_free_i32(a);
4457
tcg_temp_free_i32(b);
4461
static void gen_neon_narrow_op(int op, int u, int size,
4462
TCGv_i32 dest, TCGv_i64 src)
4466
gen_neon_unarrow_sats(size, dest, src);
4468
gen_neon_narrow(size, dest, src);
4472
gen_neon_narrow_satu(size, dest, src);
4474
gen_neon_narrow_sats(size, dest, src);
4479
/* Symbolic constants for op fields for Neon 3-register same-length.
4480
* The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4483
#define NEON_3R_VHADD 0
4484
#define NEON_3R_VQADD 1
4485
#define NEON_3R_VRHADD 2
4486
#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4487
#define NEON_3R_VHSUB 4
4488
#define NEON_3R_VQSUB 5
4489
#define NEON_3R_VCGT 6
4490
#define NEON_3R_VCGE 7
4491
#define NEON_3R_VSHL 8
4492
#define NEON_3R_VQSHL 9
4493
#define NEON_3R_VRSHL 10
4494
#define NEON_3R_VQRSHL 11
4495
#define NEON_3R_VMAX 12
4496
#define NEON_3R_VMIN 13
4497
#define NEON_3R_VABD 14
4498
#define NEON_3R_VABA 15
4499
#define NEON_3R_VADD_VSUB 16
4500
#define NEON_3R_VTST_VCEQ 17
4501
#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4502
#define NEON_3R_VMUL 19
4503
#define NEON_3R_VPMAX 20
4504
#define NEON_3R_VPMIN 21
4505
#define NEON_3R_VQDMULH_VQRDMULH 22
4506
#define NEON_3R_VPADD 23
4507
#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4508
#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4509
#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4510
#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4511
#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4512
#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4513
#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4515
static const uint8_t neon_3r_sizes[] = {
4516
[NEON_3R_VHADD] = 0x7,
4517
[NEON_3R_VQADD] = 0xf,
4518
[NEON_3R_VRHADD] = 0x7,
4519
[NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4520
[NEON_3R_VHSUB] = 0x7,
4521
[NEON_3R_VQSUB] = 0xf,
4522
[NEON_3R_VCGT] = 0x7,
4523
[NEON_3R_VCGE] = 0x7,
4524
[NEON_3R_VSHL] = 0xf,
4525
[NEON_3R_VQSHL] = 0xf,
4526
[NEON_3R_VRSHL] = 0xf,
4527
[NEON_3R_VQRSHL] = 0xf,
4528
[NEON_3R_VMAX] = 0x7,
4529
[NEON_3R_VMIN] = 0x7,
4530
[NEON_3R_VABD] = 0x7,
4531
[NEON_3R_VABA] = 0x7,
4532
[NEON_3R_VADD_VSUB] = 0xf,
4533
[NEON_3R_VTST_VCEQ] = 0x7,
4534
[NEON_3R_VML] = 0x7,
4535
[NEON_3R_VMUL] = 0x7,
4536
[NEON_3R_VPMAX] = 0x7,
4537
[NEON_3R_VPMIN] = 0x7,
4538
[NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4539
[NEON_3R_VPADD] = 0x7,
4540
[NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4541
[NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4542
[NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4543
[NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4544
[NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4545
[NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4546
[NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4549
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
4550
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4553
#define NEON_2RM_VREV64 0
4554
#define NEON_2RM_VREV32 1
4555
#define NEON_2RM_VREV16 2
4556
#define NEON_2RM_VPADDL 4
4557
#define NEON_2RM_VPADDL_U 5
4558
#define NEON_2RM_VCLS 8
4559
#define NEON_2RM_VCLZ 9
4560
#define NEON_2RM_VCNT 10
4561
#define NEON_2RM_VMVN 11
4562
#define NEON_2RM_VPADAL 12
4563
#define NEON_2RM_VPADAL_U 13
4564
#define NEON_2RM_VQABS 14
4565
#define NEON_2RM_VQNEG 15
4566
#define NEON_2RM_VCGT0 16
4567
#define NEON_2RM_VCGE0 17
4568
#define NEON_2RM_VCEQ0 18
4569
#define NEON_2RM_VCLE0 19
4570
#define NEON_2RM_VCLT0 20
4571
#define NEON_2RM_VABS 22
4572
#define NEON_2RM_VNEG 23
4573
#define NEON_2RM_VCGT0_F 24
4574
#define NEON_2RM_VCGE0_F 25
4575
#define NEON_2RM_VCEQ0_F 26
4576
#define NEON_2RM_VCLE0_F 27
4577
#define NEON_2RM_VCLT0_F 28
4578
#define NEON_2RM_VABS_F 30
4579
#define NEON_2RM_VNEG_F 31
4580
#define NEON_2RM_VSWP 32
4581
#define NEON_2RM_VTRN 33
4582
#define NEON_2RM_VUZP 34
4583
#define NEON_2RM_VZIP 35
4584
#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4585
#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4586
#define NEON_2RM_VSHLL 38
4587
#define NEON_2RM_VCVT_F16_F32 44
4588
#define NEON_2RM_VCVT_F32_F16 46
4589
#define NEON_2RM_VRECPE 56
4590
#define NEON_2RM_VRSQRTE 57
4591
#define NEON_2RM_VRECPE_F 58
4592
#define NEON_2RM_VRSQRTE_F 59
4593
#define NEON_2RM_VCVT_FS 60
4594
#define NEON_2RM_VCVT_FU 61
4595
#define NEON_2RM_VCVT_SF 62
4596
#define NEON_2RM_VCVT_UF 63
4598
static int neon_2rm_is_float_op(int op)
4600
/* Return true if this neon 2reg-misc op is float-to-float */
4601
return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4602
op >= NEON_2RM_VRECPE_F);
4605
/* Each entry in this array has bit n set if the insn allows
4606
* size value n (otherwise it will UNDEF). Since unallocated
4607
* op values will have no bits set they always UNDEF.
4609
static const uint8_t neon_2rm_sizes[] = {
4610
[NEON_2RM_VREV64] = 0x7,
4611
[NEON_2RM_VREV32] = 0x3,
4612
[NEON_2RM_VREV16] = 0x1,
4613
[NEON_2RM_VPADDL] = 0x7,
4614
[NEON_2RM_VPADDL_U] = 0x7,
4615
[NEON_2RM_VCLS] = 0x7,
4616
[NEON_2RM_VCLZ] = 0x7,
4617
[NEON_2RM_VCNT] = 0x1,
4618
[NEON_2RM_VMVN] = 0x1,
4619
[NEON_2RM_VPADAL] = 0x7,
4620
[NEON_2RM_VPADAL_U] = 0x7,
4621
[NEON_2RM_VQABS] = 0x7,
4622
[NEON_2RM_VQNEG] = 0x7,
4623
[NEON_2RM_VCGT0] = 0x7,
4624
[NEON_2RM_VCGE0] = 0x7,
4625
[NEON_2RM_VCEQ0] = 0x7,
4626
[NEON_2RM_VCLE0] = 0x7,
4627
[NEON_2RM_VCLT0] = 0x7,
4628
[NEON_2RM_VABS] = 0x7,
4629
[NEON_2RM_VNEG] = 0x7,
4630
[NEON_2RM_VCGT0_F] = 0x4,
4631
[NEON_2RM_VCGE0_F] = 0x4,
4632
[NEON_2RM_VCEQ0_F] = 0x4,
4633
[NEON_2RM_VCLE0_F] = 0x4,
4634
[NEON_2RM_VCLT0_F] = 0x4,
4635
[NEON_2RM_VABS_F] = 0x4,
4636
[NEON_2RM_VNEG_F] = 0x4,
4637
[NEON_2RM_VSWP] = 0x1,
4638
[NEON_2RM_VTRN] = 0x7,
4639
[NEON_2RM_VUZP] = 0x7,
4640
[NEON_2RM_VZIP] = 0x7,
4641
[NEON_2RM_VMOVN] = 0x7,
4642
[NEON_2RM_VQMOVN] = 0x7,
4643
[NEON_2RM_VSHLL] = 0x7,
4644
[NEON_2RM_VCVT_F16_F32] = 0x2,
4645
[NEON_2RM_VCVT_F32_F16] = 0x2,
4646
[NEON_2RM_VRECPE] = 0x4,
4647
[NEON_2RM_VRSQRTE] = 0x4,
4648
[NEON_2RM_VRECPE_F] = 0x4,
4649
[NEON_2RM_VRSQRTE_F] = 0x4,
4650
[NEON_2RM_VCVT_FS] = 0x4,
4651
[NEON_2RM_VCVT_FU] = 0x4,
4652
[NEON_2RM_VCVT_SF] = 0x4,
4653
[NEON_2RM_VCVT_UF] = 0x4,
4656
/* Translate a NEON data processing instruction. Return nonzero if the
4657
instruction is invalid.
4658
We process data in a mixture of 32-bit and 64-bit chunks.
4659
Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4661
static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4673
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4676
if (!s->vfp_enabled)
4678
q = (insn & (1 << 6)) != 0;
4679
u = (insn >> 24) & 1;
4680
VFP_DREG_D(rd, insn);
4681
VFP_DREG_N(rn, insn);
4682
VFP_DREG_M(rm, insn);
4683
size = (insn >> 20) & 3;
4684
if ((insn & (1 << 23)) == 0) {
4685
/* Three register same length. */
4686
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4687
/* Catch invalid op and bad size combinations: UNDEF */
4688
if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4691
/* All insns of this form UNDEF for either this condition or the
4692
* superset of cases "Q==1"; we catch the latter later.
4694
if (q && ((rd | rn | rm) & 1)) {
4697
if (size == 3 && op != NEON_3R_LOGIC) {
4698
/* 64-bit element instructions. */
4699
for (pass = 0; pass < (q ? 2 : 1); pass++) {
4700
neon_load_reg64(cpu_V0, rn + pass);
4701
neon_load_reg64(cpu_V1, rm + pass);
4705
gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4708
gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4714
gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4717
gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4723
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4725
gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4730
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4733
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4739
gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4741
gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4744
case NEON_3R_VQRSHL:
4746
gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4749
gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4753
case NEON_3R_VADD_VSUB:
4755
tcg_gen_sub_i64(CPU_V001);
4757
tcg_gen_add_i64(CPU_V001);
4763
neon_store_reg64(cpu_V0, rd + pass);
4772
case NEON_3R_VQRSHL:
4775
/* Shift instruction operands are reversed. */
4790
case NEON_3R_FLOAT_ARITH:
4791
pairwise = (u && size < 2); /* if VPADD (float) */
4793
case NEON_3R_FLOAT_MINMAX:
4794
pairwise = u; /* if VPMIN/VPMAX (float) */
4796
case NEON_3R_FLOAT_CMP:
4798
/* no encoding for U=0 C=1x */
4802
case NEON_3R_FLOAT_ACMP:
4807
case NEON_3R_VRECPS_VRSQRTS:
4813
if (u && (size != 0)) {
4814
/* UNDEF on invalid size for polynomial subcase */
4819
if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4827
if (pairwise && q) {
4828
/* All the pairwise insns UNDEF if Q is set */
4832
for (pass = 0; pass < (q ? 4 : 2); pass++) {
4837
tmp = neon_load_reg(rn, 0);
4838
tmp2 = neon_load_reg(rn, 1);
4840
tmp = neon_load_reg(rm, 0);
4841
tmp2 = neon_load_reg(rm, 1);
4845
tmp = neon_load_reg(rn, pass);
4846
tmp2 = neon_load_reg(rm, pass);
4850
GEN_NEON_INTEGER_OP(hadd);
4853
GEN_NEON_INTEGER_OP_ENV(qadd);
4855
case NEON_3R_VRHADD:
4856
GEN_NEON_INTEGER_OP(rhadd);
4858
case NEON_3R_LOGIC: /* Logic ops. */
4859
switch ((u << 2) | size) {
4861
tcg_gen_and_i32(tmp, tmp, tmp2);
4864
tcg_gen_andc_i32(tmp, tmp, tmp2);
4867
tcg_gen_or_i32(tmp, tmp, tmp2);
4870
tcg_gen_orc_i32(tmp, tmp, tmp2);
4873
tcg_gen_xor_i32(tmp, tmp, tmp2);
4876
tmp3 = neon_load_reg(rd, pass);
4877
gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4878
tcg_temp_free_i32(tmp3);
4881
tmp3 = neon_load_reg(rd, pass);
4882
gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4883
tcg_temp_free_i32(tmp3);
4886
tmp3 = neon_load_reg(rd, pass);
4887
gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4888
tcg_temp_free_i32(tmp3);
4893
GEN_NEON_INTEGER_OP(hsub);
4896
GEN_NEON_INTEGER_OP_ENV(qsub);
4899
GEN_NEON_INTEGER_OP(cgt);
4902
GEN_NEON_INTEGER_OP(cge);
4905
GEN_NEON_INTEGER_OP(shl);
4908
GEN_NEON_INTEGER_OP_ENV(qshl);
4911
GEN_NEON_INTEGER_OP(rshl);
4913
case NEON_3R_VQRSHL:
4914
GEN_NEON_INTEGER_OP_ENV(qrshl);
4917
GEN_NEON_INTEGER_OP(max);
4920
GEN_NEON_INTEGER_OP(min);
4923
GEN_NEON_INTEGER_OP(abd);
4926
GEN_NEON_INTEGER_OP(abd);
4927
tcg_temp_free_i32(tmp2);
4928
tmp2 = neon_load_reg(rd, pass);
4929
gen_neon_add(size, tmp, tmp2);
4931
case NEON_3R_VADD_VSUB:
4932
if (!u) { /* VADD */
4933
gen_neon_add(size, tmp, tmp2);
4936
case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4937
case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4938
case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4943
case NEON_3R_VTST_VCEQ:
4944
if (!u) { /* VTST */
4946
case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4947
case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4948
case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4953
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4954
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4955
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4960
case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4962
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4963
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4964
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4967
tcg_temp_free_i32(tmp2);
4968
tmp2 = neon_load_reg(rd, pass);
4970
gen_neon_rsb(size, tmp, tmp2);
4972
gen_neon_add(size, tmp, tmp2);
4976
if (u) { /* polynomial */
4977
gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4978
} else { /* Integer */
4980
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4981
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4982
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4988
GEN_NEON_INTEGER_OP(pmax);
4991
GEN_NEON_INTEGER_OP(pmin);
4993
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
4994
if (!u) { /* VQDMULH */
4997
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5000
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5004
} else { /* VQRDMULH */
5007
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5010
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5018
case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5019
case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5020
case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5024
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5026
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5027
switch ((u << 2) | size) {
5030
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5033
gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5036
gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5041
tcg_temp_free_ptr(fpstatus);
5044
case NEON_3R_FLOAT_MULTIPLY:
5046
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5047
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5049
tcg_temp_free_i32(tmp2);
5050
tmp2 = neon_load_reg(rd, pass);
5052
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5054
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5057
tcg_temp_free_ptr(fpstatus);
5060
case NEON_3R_FLOAT_CMP:
5062
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5064
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5067
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5069
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5072
tcg_temp_free_ptr(fpstatus);
5075
case NEON_3R_FLOAT_ACMP:
5077
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5079
gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5081
gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5083
tcg_temp_free_ptr(fpstatus);
5086
case NEON_3R_FLOAT_MINMAX:
5088
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5090
gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
5092
gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
5094
tcg_temp_free_ptr(fpstatus);
5097
case NEON_3R_VRECPS_VRSQRTS:
5099
gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5101
gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5105
/* VFMA, VFMS: fused multiply-add */
5106
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5107
TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5110
gen_helper_vfp_negs(tmp, tmp);
5112
gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5113
tcg_temp_free_i32(tmp3);
5114
tcg_temp_free_ptr(fpstatus);
5120
tcg_temp_free_i32(tmp2);
5122
/* Save the result. For elementwise operations we can put it
5123
straight into the destination register. For pairwise operations
5124
we have to be careful to avoid clobbering the source operands. */
5125
if (pairwise && rd == rm) {
5126
neon_store_scratch(pass, tmp);
5128
neon_store_reg(rd, pass, tmp);
5132
if (pairwise && rd == rm) {
5133
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5134
tmp = neon_load_scratch(pass);
5135
neon_store_reg(rd, pass, tmp);
5138
/* End of 3 register same size operations. */
5139
} else if (insn & (1 << 4)) {
5140
if ((insn & 0x00380080) != 0) {
5141
/* Two registers and shift. */
5142
op = (insn >> 8) & 0xf;
5143
if (insn & (1 << 7)) {
5151
while ((insn & (1 << (size + 19))) == 0)
5154
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5155
/* To avoid excessive duplication of ops we implement shift
5156
by immediate using the variable shift operations. */
5158
/* Shift by immediate:
5159
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5160
if (q && ((rd | rm) & 1)) {
5163
if (!u && (op == 4 || op == 6)) {
5166
/* Right shifts are encoded as N - shift, where N is the
5167
element size in bits. */
5169
shift = shift - (1 << (size + 3));
5177
imm = (uint8_t) shift;
5182
imm = (uint16_t) shift;
5193
for (pass = 0; pass < count; pass++) {
5195
neon_load_reg64(cpu_V0, rm + pass);
5196
tcg_gen_movi_i64(cpu_V1, imm);
5201
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5203
gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5208
gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5210
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5213
case 5: /* VSHL, VSLI */
5214
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5216
case 6: /* VQSHLU */
5217
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5222
gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5225
gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5230
if (op == 1 || op == 3) {
5232
neon_load_reg64(cpu_V1, rd + pass);
5233
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5234
} else if (op == 4 || (op == 5 && u)) {
5236
neon_load_reg64(cpu_V1, rd + pass);
5238
if (shift < -63 || shift > 63) {
5242
mask = 0xffffffffffffffffull >> -shift;
5244
mask = 0xffffffffffffffffull << shift;
5247
tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5248
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5250
neon_store_reg64(cpu_V0, rd + pass);
5251
} else { /* size < 3 */
5252
/* Operands in T0 and T1. */
5253
tmp = neon_load_reg(rm, pass);
5254
tmp2 = tcg_temp_new_i32();
5255
tcg_gen_movi_i32(tmp2, imm);
5259
GEN_NEON_INTEGER_OP(shl);
5263
GEN_NEON_INTEGER_OP(rshl);
5266
case 5: /* VSHL, VSLI */
5268
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5269
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5270
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5274
case 6: /* VQSHLU */
5277
gen_helper_neon_qshlu_s8(tmp, cpu_env,
5281
gen_helper_neon_qshlu_s16(tmp, cpu_env,
5285
gen_helper_neon_qshlu_s32(tmp, cpu_env,
5293
GEN_NEON_INTEGER_OP_ENV(qshl);
5296
tcg_temp_free_i32(tmp2);
5298
if (op == 1 || op == 3) {
5300
tmp2 = neon_load_reg(rd, pass);
5301
gen_neon_add(size, tmp, tmp2);
5302
tcg_temp_free_i32(tmp2);
5303
} else if (op == 4 || (op == 5 && u)) {
5308
mask = 0xff >> -shift;
5310
mask = (uint8_t)(0xff << shift);
5316
mask = 0xffff >> -shift;
5318
mask = (uint16_t)(0xffff << shift);
5322
if (shift < -31 || shift > 31) {
5326
mask = 0xffffffffu >> -shift;
5328
mask = 0xffffffffu << shift;
5334
tmp2 = neon_load_reg(rd, pass);
5335
tcg_gen_andi_i32(tmp, tmp, mask);
5336
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5337
tcg_gen_or_i32(tmp, tmp, tmp2);
5338
tcg_temp_free_i32(tmp2);
5340
neon_store_reg(rd, pass, tmp);
5343
} else if (op < 10) {
5344
/* Shift by immediate and narrow:
5345
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5346
int input_unsigned = (op == 8) ? !u : u;
5350
shift = shift - (1 << (size + 3));
5353
tmp64 = tcg_const_i64(shift);
5354
neon_load_reg64(cpu_V0, rm);
5355
neon_load_reg64(cpu_V1, rm + 1);
5356
for (pass = 0; pass < 2; pass++) {
5364
if (input_unsigned) {
5365
gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5367
gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5370
if (input_unsigned) {
5371
gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5373
gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5376
tmp = tcg_temp_new_i32();
5377
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5378
neon_store_reg(rd, pass, tmp);
5380
tcg_temp_free_i64(tmp64);
5383
imm = (uint16_t)shift;
5387
imm = (uint32_t)shift;
5389
tmp2 = tcg_const_i32(imm);
5390
tmp4 = neon_load_reg(rm + 1, 0);
5391
tmp5 = neon_load_reg(rm + 1, 1);
5392
for (pass = 0; pass < 2; pass++) {
5394
tmp = neon_load_reg(rm, 0);
5398
gen_neon_shift_narrow(size, tmp, tmp2, q,
5401
tmp3 = neon_load_reg(rm, 1);
5405
gen_neon_shift_narrow(size, tmp3, tmp2, q,
5407
tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5408
tcg_temp_free_i32(tmp);
5409
tcg_temp_free_i32(tmp3);
5410
tmp = tcg_temp_new_i32();
5411
gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5412
neon_store_reg(rd, pass, tmp);
5414
tcg_temp_free_i32(tmp2);
5416
} else if (op == 10) {
5418
if (q || (rd & 1)) {
5421
tmp = neon_load_reg(rm, 0);
5422
tmp2 = neon_load_reg(rm, 1);
5423
for (pass = 0; pass < 2; pass++) {
5427
gen_neon_widen(cpu_V0, tmp, size, u);
5430
/* The shift is less than the width of the source
5431
type, so we can just shift the whole register. */
5432
tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5433
/* Widen the result of shift: we need to clear
5434
* the potential overflow bits resulting from
5435
* left bits of the narrow input appearing as
5436
* right bits of left the neighbour narrow
5438
if (size < 2 || !u) {
5441
imm = (0xffu >> (8 - shift));
5443
} else if (size == 1) {
5444
imm = 0xffff >> (16 - shift);
5447
imm = 0xffffffff >> (32 - shift);
5450
imm64 = imm | (((uint64_t)imm) << 32);
5454
tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5457
neon_store_reg64(cpu_V0, rd + pass);
5459
} else if (op >= 14) {
5460
/* VCVT fixed-point. */
5461
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5464
/* We have already masked out the must-be-1 top bit of imm6,
5465
* hence this 32-shift where the ARM ARM has 64-imm6.
5468
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5469
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5472
gen_vfp_ulto(0, shift, 1);
5474
gen_vfp_slto(0, shift, 1);
5477
gen_vfp_toul(0, shift, 1);
5479
gen_vfp_tosl(0, shift, 1);
5481
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5486
} else { /* (insn & 0x00380080) == 0 */
5488
if (q && (rd & 1)) {
5492
op = (insn >> 8) & 0xf;
5493
/* One register and immediate. */
5494
imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5495
invert = (insn & (1 << 5)) != 0;
5496
/* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5497
* We choose to not special-case this and will behave as if a
5498
* valid constant encoding of 0 had been given.
5517
imm = (imm << 8) | (imm << 24);
5520
imm = (imm << 8) | 0xff;
5523
imm = (imm << 16) | 0xffff;
5526
imm |= (imm << 8) | (imm << 16) | (imm << 24);
5534
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5535
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5541
for (pass = 0; pass < (q ? 4 : 2); pass++) {
5542
if (op & 1 && op < 12) {
5543
tmp = neon_load_reg(rd, pass);
5545
/* The immediate value has already been inverted, so
5547
tcg_gen_andi_i32(tmp, tmp, imm);
5549
tcg_gen_ori_i32(tmp, tmp, imm);
5553
tmp = tcg_temp_new_i32();
5554
if (op == 14 && invert) {
5558
for (n = 0; n < 4; n++) {
5559
if (imm & (1 << (n + (pass & 1) * 4)))
5560
val |= 0xff << (n * 8);
5562
tcg_gen_movi_i32(tmp, val);
5564
tcg_gen_movi_i32(tmp, imm);
5567
neon_store_reg(rd, pass, tmp);
5570
} else { /* (insn & 0x00800010 == 0x00800000) */
5572
op = (insn >> 8) & 0xf;
5573
if ((insn & (1 << 6)) == 0) {
5574
/* Three registers of different lengths. */
5578
/* undefreq: bit 0 : UNDEF if size != 0
5579
* bit 1 : UNDEF if size == 0
5580
* bit 2 : UNDEF if U == 1
5581
* Note that [1:0] set implies 'always UNDEF'
5584
/* prewiden, src1_wide, src2_wide, undefreq */
5585
static const int neon_3reg_wide[16][4] = {
5586
{1, 0, 0, 0}, /* VADDL */
5587
{1, 1, 0, 0}, /* VADDW */
5588
{1, 0, 0, 0}, /* VSUBL */
5589
{1, 1, 0, 0}, /* VSUBW */
5590
{0, 1, 1, 0}, /* VADDHN */
5591
{0, 0, 0, 0}, /* VABAL */
5592
{0, 1, 1, 0}, /* VSUBHN */
5593
{0, 0, 0, 0}, /* VABDL */
5594
{0, 0, 0, 0}, /* VMLAL */
5595
{0, 0, 0, 6}, /* VQDMLAL */
5596
{0, 0, 0, 0}, /* VMLSL */
5597
{0, 0, 0, 6}, /* VQDMLSL */
5598
{0, 0, 0, 0}, /* Integer VMULL */
5599
{0, 0, 0, 2}, /* VQDMULL */
5600
{0, 0, 0, 5}, /* Polynomial VMULL */
5601
{0, 0, 0, 3}, /* Reserved: always UNDEF */
5604
prewiden = neon_3reg_wide[op][0];
5605
src1_wide = neon_3reg_wide[op][1];
5606
src2_wide = neon_3reg_wide[op][2];
5607
undefreq = neon_3reg_wide[op][3];
5609
if (((undefreq & 1) && (size != 0)) ||
5610
((undefreq & 2) && (size == 0)) ||
5611
((undefreq & 4) && u)) {
5614
if ((src1_wide && (rn & 1)) ||
5615
(src2_wide && (rm & 1)) ||
5616
(!src2_wide && (rd & 1))) {
5620
/* Avoid overlapping operands. Wide source operands are
5621
always aligned so will never overlap with wide
5622
destinations in problematic ways. */
5623
if (rd == rm && !src2_wide) {
5624
tmp = neon_load_reg(rm, 1);
5625
neon_store_scratch(2, tmp);
5626
} else if (rd == rn && !src1_wide) {
5627
tmp = neon_load_reg(rn, 1);
5628
neon_store_scratch(2, tmp);
5630
TCGV_UNUSED_I32(tmp3);
5631
for (pass = 0; pass < 2; pass++) {
5633
neon_load_reg64(cpu_V0, rn + pass);
5634
TCGV_UNUSED_I32(tmp);
5636
if (pass == 1 && rd == rn) {
5637
tmp = neon_load_scratch(2);
5639
tmp = neon_load_reg(rn, pass);
5642
gen_neon_widen(cpu_V0, tmp, size, u);
5646
neon_load_reg64(cpu_V1, rm + pass);
5647
TCGV_UNUSED_I32(tmp2);
5649
if (pass == 1 && rd == rm) {
5650
tmp2 = neon_load_scratch(2);
5652
tmp2 = neon_load_reg(rm, pass);
5655
gen_neon_widen(cpu_V1, tmp2, size, u);
5659
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5660
gen_neon_addl(size);
5662
case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5663
gen_neon_subl(size);
5665
case 5: case 7: /* VABAL, VABDL */
5666
switch ((size << 1) | u) {
5668
gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5671
gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5674
gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5677
gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5680
gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5683
gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5687
tcg_temp_free_i32(tmp2);
5688
tcg_temp_free_i32(tmp);
5690
case 8: case 9: case 10: case 11: case 12: case 13:
5691
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5692
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5694
case 14: /* Polynomial VMULL */
5695
gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5696
tcg_temp_free_i32(tmp2);
5697
tcg_temp_free_i32(tmp);
5699
default: /* 15 is RESERVED: caught earlier */
5704
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5705
neon_store_reg64(cpu_V0, rd + pass);
5706
} else if (op == 5 || (op >= 8 && op <= 11)) {
5708
neon_load_reg64(cpu_V1, rd + pass);
5710
case 10: /* VMLSL */
5711
gen_neon_negl(cpu_V0, size);
5713
case 5: case 8: /* VABAL, VMLAL */
5714
gen_neon_addl(size);
5716
case 9: case 11: /* VQDMLAL, VQDMLSL */
5717
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5719
gen_neon_negl(cpu_V0, size);
5721
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5726
neon_store_reg64(cpu_V0, rd + pass);
5727
} else if (op == 4 || op == 6) {
5728
/* Narrowing operation. */
5729
tmp = tcg_temp_new_i32();
5733
gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5736
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5739
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5740
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5747
gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5750
gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5753
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5754
tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5755
tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5763
neon_store_reg(rd, 0, tmp3);
5764
neon_store_reg(rd, 1, tmp);
5767
/* Write back the result. */
5768
neon_store_reg64(cpu_V0, rd + pass);
5772
/* Two registers and a scalar. NB that for ops of this form
5773
* the ARM ARM labels bit 24 as Q, but it is in our variable
5780
case 1: /* Float VMLA scalar */
5781
case 5: /* Floating point VMLS scalar */
5782
case 9: /* Floating point VMUL scalar */
5787
case 0: /* Integer VMLA scalar */
5788
case 4: /* Integer VMLS scalar */
5789
case 8: /* Integer VMUL scalar */
5790
case 12: /* VQDMULH scalar */
5791
case 13: /* VQRDMULH scalar */
5792
if (u && ((rd | rn) & 1)) {
5795
tmp = neon_get_scalar(size, rm);
5796
neon_store_scratch(0, tmp);
5797
for (pass = 0; pass < (u ? 4 : 2); pass++) {
5798
tmp = neon_load_scratch(0);
5799
tmp2 = neon_load_reg(rn, pass);
5802
gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5804
gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5806
} else if (op == 13) {
5808
gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5810
gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5812
} else if (op & 1) {
5813
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5814
gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5815
tcg_temp_free_ptr(fpstatus);
5818
case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5819
case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5820
case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5824
tcg_temp_free_i32(tmp2);
5827
tmp2 = neon_load_reg(rd, pass);
5830
gen_neon_add(size, tmp, tmp2);
5834
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5835
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5836
tcg_temp_free_ptr(fpstatus);
5840
gen_neon_rsb(size, tmp, tmp2);
5844
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5845
gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5846
tcg_temp_free_ptr(fpstatus);
5852
tcg_temp_free_i32(tmp2);
5854
neon_store_reg(rd, pass, tmp);
5857
case 3: /* VQDMLAL scalar */
5858
case 7: /* VQDMLSL scalar */
5859
case 11: /* VQDMULL scalar */
5864
case 2: /* VMLAL sclar */
5865
case 6: /* VMLSL scalar */
5866
case 10: /* VMULL scalar */
5870
tmp2 = neon_get_scalar(size, rm);
5871
/* We need a copy of tmp2 because gen_neon_mull
5872
* deletes it during pass 0. */
5873
tmp4 = tcg_temp_new_i32();
5874
tcg_gen_mov_i32(tmp4, tmp2);
5875
tmp3 = neon_load_reg(rn, 1);
5877
for (pass = 0; pass < 2; pass++) {
5879
tmp = neon_load_reg(rn, 0);
5884
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5886
neon_load_reg64(cpu_V1, rd + pass);
5890
gen_neon_negl(cpu_V0, size);
5893
gen_neon_addl(size);
5896
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5898
gen_neon_negl(cpu_V0, size);
5900
gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5906
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5911
neon_store_reg64(cpu_V0, rd + pass);
5916
default: /* 14 and 15 are RESERVED */
5920
} else { /* size == 3 */
5923
imm = (insn >> 8) & 0xf;
5928
if (q && ((rd | rn | rm) & 1)) {
5933
neon_load_reg64(cpu_V0, rn);
5935
neon_load_reg64(cpu_V1, rn + 1);
5937
} else if (imm == 8) {
5938
neon_load_reg64(cpu_V0, rn + 1);
5940
neon_load_reg64(cpu_V1, rm);
5943
tmp64 = tcg_temp_new_i64();
5945
neon_load_reg64(cpu_V0, rn);
5946
neon_load_reg64(tmp64, rn + 1);
5948
neon_load_reg64(cpu_V0, rn + 1);
5949
neon_load_reg64(tmp64, rm);
5951
tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5952
tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5953
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5955
neon_load_reg64(cpu_V1, rm);
5957
neon_load_reg64(cpu_V1, rm + 1);
5960
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5961
tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5962
tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5963
tcg_temp_free_i64(tmp64);
5966
neon_load_reg64(cpu_V0, rn);
5967
tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5968
neon_load_reg64(cpu_V1, rm);
5969
tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5970
tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5972
neon_store_reg64(cpu_V0, rd);
5974
neon_store_reg64(cpu_V1, rd + 1);
5976
} else if ((insn & (1 << 11)) == 0) {
5977
/* Two register misc. */
5978
op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5979
size = (insn >> 18) & 3;
5980
/* UNDEF for unknown op values and bad op-size combinations */
5981
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5984
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5985
q && ((rm | rd) & 1)) {
5989
case NEON_2RM_VREV64:
5990
for (pass = 0; pass < (q ? 2 : 1); pass++) {
5991
tmp = neon_load_reg(rm, pass * 2);
5992
tmp2 = neon_load_reg(rm, pass * 2 + 1);
5994
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5995
case 1: gen_swap_half(tmp); break;
5996
case 2: /* no-op */ break;
5999
neon_store_reg(rd, pass * 2 + 1, tmp);
6001
neon_store_reg(rd, pass * 2, tmp2);
6004
case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6005
case 1: gen_swap_half(tmp2); break;
6008
neon_store_reg(rd, pass * 2, tmp2);
6012
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6013
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6014
for (pass = 0; pass < q + 1; pass++) {
6015
tmp = neon_load_reg(rm, pass * 2);
6016
gen_neon_widen(cpu_V0, tmp, size, op & 1);
6017
tmp = neon_load_reg(rm, pass * 2 + 1);
6018
gen_neon_widen(cpu_V1, tmp, size, op & 1);
6020
case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6021
case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6022
case 2: tcg_gen_add_i64(CPU_V001); break;
6025
if (op >= NEON_2RM_VPADAL) {
6027
neon_load_reg64(cpu_V1, rd + pass);
6028
gen_neon_addl(size);
6030
neon_store_reg64(cpu_V0, rd + pass);
6036
for (n = 0; n < (q ? 4 : 2); n += 2) {
6037
tmp = neon_load_reg(rm, n);
6038
tmp2 = neon_load_reg(rd, n + 1);
6039
neon_store_reg(rm, n, tmp2);
6040
neon_store_reg(rd, n + 1, tmp);
6047
if (gen_neon_unzip(rd, rm, size, q)) {
6052
if (gen_neon_zip(rd, rm, size, q)) {
6056
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6057
/* also VQMOVUN; op field and mnemonics don't line up */
6061
TCGV_UNUSED_I32(tmp2);
6062
for (pass = 0; pass < 2; pass++) {
6063
neon_load_reg64(cpu_V0, rm + pass);
6064
tmp = tcg_temp_new_i32();
6065
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6070
neon_store_reg(rd, 0, tmp2);
6071
neon_store_reg(rd, 1, tmp);
6075
case NEON_2RM_VSHLL:
6076
if (q || (rd & 1)) {
6079
tmp = neon_load_reg(rm, 0);
6080
tmp2 = neon_load_reg(rm, 1);
6081
for (pass = 0; pass < 2; pass++) {
6084
gen_neon_widen(cpu_V0, tmp, size, 1);
6085
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6086
neon_store_reg64(cpu_V0, rd + pass);
6089
case NEON_2RM_VCVT_F16_F32:
6090
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6094
tmp = tcg_temp_new_i32();
6095
tmp2 = tcg_temp_new_i32();
6096
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6097
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6098
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6099
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6100
tcg_gen_shli_i32(tmp2, tmp2, 16);
6101
tcg_gen_or_i32(tmp2, tmp2, tmp);
6102
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6103
gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6104
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6105
neon_store_reg(rd, 0, tmp2);
6106
tmp2 = tcg_temp_new_i32();
6107
gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6108
tcg_gen_shli_i32(tmp2, tmp2, 16);
6109
tcg_gen_or_i32(tmp2, tmp2, tmp);
6110
neon_store_reg(rd, 1, tmp2);
6111
tcg_temp_free_i32(tmp);
6113
case NEON_2RM_VCVT_F32_F16:
6114
if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6118
tmp3 = tcg_temp_new_i32();
6119
tmp = neon_load_reg(rm, 0);
6120
tmp2 = neon_load_reg(rm, 1);
6121
tcg_gen_ext16u_i32(tmp3, tmp);
6122
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6123
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6124
tcg_gen_shri_i32(tmp3, tmp, 16);
6125
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6126
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6127
tcg_temp_free_i32(tmp);
6128
tcg_gen_ext16u_i32(tmp3, tmp2);
6129
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6130
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6131
tcg_gen_shri_i32(tmp3, tmp2, 16);
6132
gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6133
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6134
tcg_temp_free_i32(tmp2);
6135
tcg_temp_free_i32(tmp3);
6139
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6140
if (neon_2rm_is_float_op(op)) {
6141
tcg_gen_ld_f32(cpu_F0s, cpu_env,
6142
neon_reg_offset(rm, pass));
6143
TCGV_UNUSED_I32(tmp);
6145
tmp = neon_load_reg(rm, pass);
6148
case NEON_2RM_VREV32:
6150
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6151
case 1: gen_swap_half(tmp); break;
6155
case NEON_2RM_VREV16:
6160
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6161
case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6162
case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6168
case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6169
case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6170
case 2: gen_helper_clz(tmp, tmp); break;
6175
gen_helper_neon_cnt_u8(tmp, tmp);
6178
tcg_gen_not_i32(tmp, tmp);
6180
case NEON_2RM_VQABS:
6183
gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6186
gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6189
gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6194
case NEON_2RM_VQNEG:
6197
gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6200
gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6203
gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6208
case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6209
tmp2 = tcg_const_i32(0);
6211
case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6212
case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6213
case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6216
tcg_temp_free_i32(tmp2);
6217
if (op == NEON_2RM_VCLE0) {
6218
tcg_gen_not_i32(tmp, tmp);
6221
case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6222
tmp2 = tcg_const_i32(0);
6224
case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6225
case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6226
case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6229
tcg_temp_free_i32(tmp2);
6230
if (op == NEON_2RM_VCLT0) {
6231
tcg_gen_not_i32(tmp, tmp);
6234
case NEON_2RM_VCEQ0:
6235
tmp2 = tcg_const_i32(0);
6237
case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6238
case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6239
case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6242
tcg_temp_free_i32(tmp2);
6246
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6247
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6248
case 2: tcg_gen_abs_i32(tmp, tmp); break;
6253
tmp2 = tcg_const_i32(0);
6254
gen_neon_rsb(size, tmp, tmp2);
6255
tcg_temp_free_i32(tmp2);
6257
case NEON_2RM_VCGT0_F:
6259
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6260
tmp2 = tcg_const_i32(0);
6261
gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6262
tcg_temp_free_i32(tmp2);
6263
tcg_temp_free_ptr(fpstatus);
6266
case NEON_2RM_VCGE0_F:
6268
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6269
tmp2 = tcg_const_i32(0);
6270
gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6271
tcg_temp_free_i32(tmp2);
6272
tcg_temp_free_ptr(fpstatus);
6275
case NEON_2RM_VCEQ0_F:
6277
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6278
tmp2 = tcg_const_i32(0);
6279
gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6280
tcg_temp_free_i32(tmp2);
6281
tcg_temp_free_ptr(fpstatus);
6284
case NEON_2RM_VCLE0_F:
6286
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6287
tmp2 = tcg_const_i32(0);
6288
gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6289
tcg_temp_free_i32(tmp2);
6290
tcg_temp_free_ptr(fpstatus);
6293
case NEON_2RM_VCLT0_F:
6295
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6296
tmp2 = tcg_const_i32(0);
6297
gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6298
tcg_temp_free_i32(tmp2);
6299
tcg_temp_free_ptr(fpstatus);
6302
case NEON_2RM_VABS_F:
6305
case NEON_2RM_VNEG_F:
6309
tmp2 = neon_load_reg(rd, pass);
6310
neon_store_reg(rm, pass, tmp2);
6313
tmp2 = neon_load_reg(rd, pass);
6315
case 0: gen_neon_trn_u8(tmp, tmp2); break;
6316
case 1: gen_neon_trn_u16(tmp, tmp2); break;
6319
neon_store_reg(rm, pass, tmp2);
6321
case NEON_2RM_VRECPE:
6322
gen_helper_recpe_u32(tmp, tmp, cpu_env);
6324
case NEON_2RM_VRSQRTE:
6325
gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6327
case NEON_2RM_VRECPE_F:
6328
gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6330
case NEON_2RM_VRSQRTE_F:
6331
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6333
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6336
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6339
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6340
gen_vfp_tosiz(0, 1);
6342
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6343
gen_vfp_touiz(0, 1);
6346
/* Reserved op values were caught by the
6347
* neon_2rm_sizes[] check earlier.
6351
if (neon_2rm_is_float_op(op)) {
6352
tcg_gen_st_f32(cpu_F0s, cpu_env,
6353
neon_reg_offset(rd, pass));
6355
neon_store_reg(rd, pass, tmp);
6360
} else if ((insn & (1 << 10)) == 0) {
6362
int n = ((insn >> 8) & 3) + 1;
6363
if ((rn + n) > 32) {
6364
/* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6365
* helper function running off the end of the register file.
6370
if (insn & (1 << 6)) {
6371
tmp = neon_load_reg(rd, 0);
6373
tmp = tcg_temp_new_i32();
6374
tcg_gen_movi_i32(tmp, 0);
6376
tmp2 = neon_load_reg(rm, 0);
6377
tmp4 = tcg_const_i32(rn);
6378
tmp5 = tcg_const_i32(n);
6379
gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6380
tcg_temp_free_i32(tmp);
6381
if (insn & (1 << 6)) {
6382
tmp = neon_load_reg(rd, 1);
6384
tmp = tcg_temp_new_i32();
6385
tcg_gen_movi_i32(tmp, 0);
6387
tmp3 = neon_load_reg(rm, 1);
6388
gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6389
tcg_temp_free_i32(tmp5);
6390
tcg_temp_free_i32(tmp4);
6391
neon_store_reg(rd, 0, tmp2);
6392
neon_store_reg(rd, 1, tmp3);
6393
tcg_temp_free_i32(tmp);
6394
} else if ((insn & 0x380) == 0) {
6396
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6399
if (insn & (1 << 19)) {
6400
tmp = neon_load_reg(rm, 1);
6402
tmp = neon_load_reg(rm, 0);
6404
if (insn & (1 << 16)) {
6405
gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6406
} else if (insn & (1 << 17)) {
6407
if ((insn >> 18) & 1)
6408
gen_neon_dup_high16(tmp);
6410
gen_neon_dup_low16(tmp);
6412
for (pass = 0; pass < (q ? 4 : 2); pass++) {
6413
tmp2 = tcg_temp_new_i32();
6414
tcg_gen_mov_i32(tmp2, tmp);
6415
neon_store_reg(rd, pass, tmp2);
6417
tcg_temp_free_i32(tmp);
6426
static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6428
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6429
const ARMCPRegInfo *ri;
6430
ARMCPU *cpu = arm_env_get_cpu(env);
6432
cpnum = (insn >> 8) & 0xf;
6433
if (arm_feature(env, ARM_FEATURE_XSCALE)
6434
&& ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6437
/* First check for coprocessor space used for actual instructions */
6441
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6442
return disas_iwmmxt_insn(env, s, insn);
6443
} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6444
return disas_dsp_insn(env, s, insn);
6451
/* Otherwise treat as a generic register access */
6452
is64 = (insn & (1 << 25)) == 0;
6453
if (!is64 && ((insn & (1 << 4)) == 0)) {
6461
opc1 = (insn >> 4) & 0xf;
6463
rt2 = (insn >> 16) & 0xf;
6465
crn = (insn >> 16) & 0xf;
6466
opc1 = (insn >> 21) & 7;
6467
opc2 = (insn >> 5) & 7;
6470
isread = (insn >> 20) & 1;
6471
rt = (insn >> 12) & 0xf;
6473
ri = get_arm_cp_reginfo(cpu,
6474
ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6476
/* Check access permissions */
6477
if (!cp_access_ok(env, ri, isread)) {
6481
/* Handle special cases first */
6482
switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6489
gen_set_pc_im(s, s->pc);
6490
s->is_jmp = DISAS_WFI;
6496
if (use_icount && (ri->type & ARM_CP_IO)) {
6505
if (ri->type & ARM_CP_CONST) {
6506
tmp64 = tcg_const_i64(ri->resetvalue);
6507
} else if (ri->readfn) {
6509
gen_set_pc_im(s, s->pc);
6510
tmp64 = tcg_temp_new_i64();
6511
tmpptr = tcg_const_ptr(ri);
6512
gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6513
tcg_temp_free_ptr(tmpptr);
6515
tmp64 = tcg_temp_new_i64();
6516
tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6518
tmp = tcg_temp_new_i32();
6519
tcg_gen_trunc_i64_i32(tmp, tmp64);
6520
store_reg(s, rt, tmp);
6521
tcg_gen_shri_i64(tmp64, tmp64, 32);
6522
tmp = tcg_temp_new_i32();
6523
tcg_gen_trunc_i64_i32(tmp, tmp64);
6524
tcg_temp_free_i64(tmp64);
6525
store_reg(s, rt2, tmp);
6528
if (ri->type & ARM_CP_CONST) {
6529
tmp = tcg_const_i32(ri->resetvalue);
6530
} else if (ri->readfn) {
6532
gen_set_pc_im(s, s->pc);
6533
tmp = tcg_temp_new_i32();
6534
tmpptr = tcg_const_ptr(ri);
6535
gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6536
tcg_temp_free_ptr(tmpptr);
6538
tmp = load_cpu_offset(ri->fieldoffset);
6541
/* Destination register of r15 for 32 bit loads sets
6542
* the condition codes from the high 4 bits of the value
6545
tcg_temp_free_i32(tmp);
6547
store_reg(s, rt, tmp);
6552
if (ri->type & ARM_CP_CONST) {
6553
/* If not forbidden by access permissions, treat as WI */
6558
TCGv_i32 tmplo, tmphi;
6559
TCGv_i64 tmp64 = tcg_temp_new_i64();
6560
tmplo = load_reg(s, rt);
6561
tmphi = load_reg(s, rt2);
6562
tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6563
tcg_temp_free_i32(tmplo);
6564
tcg_temp_free_i32(tmphi);
6566
TCGv_ptr tmpptr = tcg_const_ptr(ri);
6567
gen_set_pc_im(s, s->pc);
6568
gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6569
tcg_temp_free_ptr(tmpptr);
6571
tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6573
tcg_temp_free_i64(tmp64);
6578
gen_set_pc_im(s, s->pc);
6579
tmp = load_reg(s, rt);
6580
tmpptr = tcg_const_ptr(ri);
6581
gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6582
tcg_temp_free_ptr(tmpptr);
6583
tcg_temp_free_i32(tmp);
6585
TCGv_i32 tmp = load_reg(s, rt);
6586
store_cpu_offset(tmp, ri->fieldoffset);
6591
if (use_icount && (ri->type & ARM_CP_IO)) {
6592
/* I/O operations must end the TB here (whether read or write) */
6595
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6596
/* We default to ending the TB on a coprocessor register write,
6597
* but allow this to be suppressed by the register definition
6598
* (usually only necessary to work around guest bugs).
6610
/* Store a 64-bit value to a register pair. Clobbers val. */
6611
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6614
tmp = tcg_temp_new_i32();
6615
tcg_gen_trunc_i64_i32(tmp, val);
6616
store_reg(s, rlow, tmp);
6617
tmp = tcg_temp_new_i32();
6618
tcg_gen_shri_i64(val, val, 32);
6619
tcg_gen_trunc_i64_i32(tmp, val);
6620
store_reg(s, rhigh, tmp);
6623
/* load a 32-bit value from a register and perform a 64-bit accumulate. */
6624
static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6629
/* Load value and extend to 64 bits. */
6630
tmp = tcg_temp_new_i64();
6631
tmp2 = load_reg(s, rlow);
6632
tcg_gen_extu_i32_i64(tmp, tmp2);
6633
tcg_temp_free_i32(tmp2);
6634
tcg_gen_add_i64(val, val, tmp);
6635
tcg_temp_free_i64(tmp);
6638
/* load and add a 64-bit value from a register pair. */
6639
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6645
/* Load 64-bit value rd:rn. */
6646
tmpl = load_reg(s, rlow);
6647
tmph = load_reg(s, rhigh);
6648
tmp = tcg_temp_new_i64();
6649
tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6650
tcg_temp_free_i32(tmpl);
6651
tcg_temp_free_i32(tmph);
6652
tcg_gen_add_i64(val, val, tmp);
6653
tcg_temp_free_i64(tmp);
6656
/* Set N and Z flags from hi|lo. */
6657
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6659
tcg_gen_mov_i32(cpu_NF, hi);
6660
tcg_gen_or_i32(cpu_ZF, lo, hi);
6663
/* Load/Store exclusive instructions are implemented by remembering
6664
the value/address loaded, and seeing if these are the same
6665
when the store is performed. This should be sufficient to implement
6666
the architecturally mandated semantics, and avoids having to monitor
6669
In system emulation mode only one CPU will be running at once, so
6670
this sequence is effectively atomic. In user emulation mode we
6671
throw an exception and handle the atomic operation elsewhere. */
6672
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6673
TCGv_i32 addr, int size)
6675
TCGv_i32 tmp = tcg_temp_new_i32();
6679
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6682
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6686
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6691
tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6692
store_reg(s, rt, tmp);
6694
TCGv_i32 tmp2 = tcg_temp_new_i32();
6695
tcg_gen_addi_i32(tmp2, addr, 4);
6696
tmp = tcg_temp_new_i32();
6697
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6698
tcg_temp_free_i32(tmp2);
6699
tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6700
store_reg(s, rt2, tmp);
6702
tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6705
static void gen_clrex(DisasContext *s)
6707
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6710
#ifdef CONFIG_USER_ONLY
6711
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6712
TCGv_i32 addr, int size)
6714
tcg_gen_mov_i32(cpu_exclusive_test, addr);
6715
tcg_gen_movi_i32(cpu_exclusive_info,
6716
size | (rd << 4) | (rt << 8) | (rt2 << 12));
6717
gen_exception_insn(s, 4, EXCP_STREX);
6720
static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6721
TCGv_i32 addr, int size)
6727
/* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6733
fail_label = gen_new_label();
6734
done_label = gen_new_label();
6735
tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6736
tmp = tcg_temp_new_i32();
6739
gen_aa32_ld8u(tmp, addr, IS_USER(s));
6742
gen_aa32_ld16u(tmp, addr, IS_USER(s));
6746
gen_aa32_ld32u(tmp, addr, IS_USER(s));
6751
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6752
tcg_temp_free_i32(tmp);
6754
TCGv_i32 tmp2 = tcg_temp_new_i32();
6755
tcg_gen_addi_i32(tmp2, addr, 4);
6756
tmp = tcg_temp_new_i32();
6757
gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6758
tcg_temp_free_i32(tmp2);
6759
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6760
tcg_temp_free_i32(tmp);
6762
tmp = load_reg(s, rt);
6765
gen_aa32_st8(tmp, addr, IS_USER(s));
6768
gen_aa32_st16(tmp, addr, IS_USER(s));
6772
gen_aa32_st32(tmp, addr, IS_USER(s));
6777
tcg_temp_free_i32(tmp);
6779
tcg_gen_addi_i32(addr, addr, 4);
6780
tmp = load_reg(s, rt2);
6781
gen_aa32_st32(tmp, addr, IS_USER(s));
6782
tcg_temp_free_i32(tmp);
6784
tcg_gen_movi_i32(cpu_R[rd], 0);
6785
tcg_gen_br(done_label);
6786
gen_set_label(fail_label);
6787
tcg_gen_movi_i32(cpu_R[rd], 1);
6788
gen_set_label(done_label);
6789
tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6796
* @mode: mode field from insn (which stack to store to)
6797
* @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6798
* @writeback: true if writeback bit set
6800
* Generate code for the SRS (Store Return State) insn.
6802
static void gen_srs(DisasContext *s,
6803
uint32_t mode, uint32_t amode, bool writeback)
6806
TCGv_i32 addr = tcg_temp_new_i32();
6807
TCGv_i32 tmp = tcg_const_i32(mode);
6808
gen_helper_get_r13_banked(addr, cpu_env, tmp);
6809
tcg_temp_free_i32(tmp);
6826
tcg_gen_addi_i32(addr, addr, offset);
6827
tmp = load_reg(s, 14);
6828
gen_aa32_st32(tmp, addr, 0);
6829
tcg_temp_free_i32(tmp);
6830
tmp = load_cpu_field(spsr);
6831
tcg_gen_addi_i32(addr, addr, 4);
6832
gen_aa32_st32(tmp, addr, 0);
6833
tcg_temp_free_i32(tmp);
6851
tcg_gen_addi_i32(addr, addr, offset);
6852
tmp = tcg_const_i32(mode);
6853
gen_helper_set_r13_banked(cpu_env, tmp, addr);
6854
tcg_temp_free_i32(tmp);
6856
tcg_temp_free_i32(addr);
6859
static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6861
unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6868
insn = arm_ldl_code(env, s->pc, s->bswap_code);
6871
/* M variants do not implement ARM mode. */
6876
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6877
* choose to UNDEF. In ARMv5 and above the space is used
6878
* for miscellaneous unconditional instructions.
6882
/* Unconditional instructions. */
6883
if (((insn >> 25) & 7) == 1) {
6884
/* NEON Data processing. */
6885
if (!arm_feature(env, ARM_FEATURE_NEON))
6888
if (disas_neon_data_insn(env, s, insn))
6892
if ((insn & 0x0f100000) == 0x04000000) {
6893
/* NEON load/store. */
6894
if (!arm_feature(env, ARM_FEATURE_NEON))
6897
if (disas_neon_ls_insn(env, s, insn))
6901
if ((insn & 0x0f000e10) == 0x0e000a00) {
6903
if (disas_vfp_insn(env, s, insn)) {
6908
if (((insn & 0x0f30f000) == 0x0510f000) ||
6909
((insn & 0x0f30f010) == 0x0710f000)) {
6910
if ((insn & (1 << 22)) == 0) {
6912
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6916
/* Otherwise PLD; v5TE+ */
6920
if (((insn & 0x0f70f000) == 0x0450f000) ||
6921
((insn & 0x0f70f010) == 0x0650f000)) {
6923
return; /* PLI; V7 */
6925
if (((insn & 0x0f700000) == 0x04100000) ||
6926
((insn & 0x0f700010) == 0x06100000)) {
6927
if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6930
return; /* v7MP: Unallocated memory hint: must NOP */
6933
if ((insn & 0x0ffffdff) == 0x01010000) {
6936
if (((insn >> 9) & 1) != s->bswap_code) {
6937
/* Dynamic endianness switching not implemented. */
6938
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
6942
} else if ((insn & 0x0fffff00) == 0x057ff000) {
6943
switch ((insn >> 4) & 0xf) {
6952
/* We don't emulate caches so these are a no-op. */
6957
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6963
gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
6965
} else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6971
rn = (insn >> 16) & 0xf;
6972
addr = load_reg(s, rn);
6973
i = (insn >> 23) & 3;
6975
case 0: offset = -4; break; /* DA */
6976
case 1: offset = 0; break; /* IA */
6977
case 2: offset = -8; break; /* DB */
6978
case 3: offset = 4; break; /* IB */
6982
tcg_gen_addi_i32(addr, addr, offset);
6983
/* Load PC into tmp and CPSR into tmp2. */
6984
tmp = tcg_temp_new_i32();
6985
gen_aa32_ld32u(tmp, addr, 0);
6986
tcg_gen_addi_i32(addr, addr, 4);
6987
tmp2 = tcg_temp_new_i32();
6988
gen_aa32_ld32u(tmp2, addr, 0);
6989
if (insn & (1 << 21)) {
6990
/* Base writeback. */
6992
case 0: offset = -8; break;
6993
case 1: offset = 4; break;
6994
case 2: offset = -4; break;
6995
case 3: offset = 0; break;
6999
tcg_gen_addi_i32(addr, addr, offset);
7000
store_reg(s, rn, addr);
7002
tcg_temp_free_i32(addr);
7004
gen_rfe(s, tmp, tmp2);
7006
} else if ((insn & 0x0e000000) == 0x0a000000) {
7007
/* branch link and change to thumb (blx <offset>) */
7010
val = (uint32_t)s->pc;
7011
tmp = tcg_temp_new_i32();
7012
tcg_gen_movi_i32(tmp, val);
7013
store_reg(s, 14, tmp);
7014
/* Sign-extend the 24-bit offset */
7015
offset = (((int32_t)insn) << 8) >> 8;
7016
/* offset * 4 + bit24 * 2 + (thumb bit) */
7017
val += (offset << 2) | ((insn >> 23) & 2) | 1;
7018
/* pipeline offset */
7020
/* protected by ARCH(5); above, near the start of uncond block */
7023
} else if ((insn & 0x0e000f00) == 0x0c000100) {
7024
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7025
/* iWMMXt register transfer. */
7026
if (env->cp15.c15_cpar & (1 << 1))
7027
if (!disas_iwmmxt_insn(env, s, insn))
7030
} else if ((insn & 0x0fe00000) == 0x0c400000) {
7031
/* Coprocessor double register transfer. */
7033
/* XXX doesn't belong in the trustzone patch: should just UNDEF? */
7034
cpu_abort(env, "unsupported coprocessor double register transfer\n");
7035
} else if ((insn & 0x0f000010) == 0x0e000010) {
7036
/* Additional coprocessor register transfer. */
7037
if (!disas_coproc_insn(env, s, insn)) {
7040
} else if ((insn & 0x0ff10020) == 0x01000000) {
7043
/* cps (privileged) */
7047
if (insn & (1 << 19)) {
7048
if (insn & (1 << 8))
7050
if (insn & (1 << 7))
7052
if (insn & (1 << 6))
7054
if (insn & (1 << 18))
7057
if (insn & (1 << 17)) {
7059
val |= (insn & 0x1f);
7062
gen_set_psr_im(s, mask, 0, val);
7069
/* if not always execute, we generate a conditional jump to
7071
s->condlabel = gen_new_label();
7072
gen_test_cc(cond ^ 1, s->condlabel);
7075
if ((insn & 0x0f900000) == 0x03000000) {
7076
if ((insn & (1 << 21)) == 0) {
7078
rd = (insn >> 12) & 0xf;
7079
val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7080
if ((insn & (1 << 22)) == 0) {
7082
tmp = tcg_temp_new_i32();
7083
tcg_gen_movi_i32(tmp, val);
7086
tmp = load_reg(s, rd);
7087
tcg_gen_ext16u_i32(tmp, tmp);
7088
tcg_gen_ori_i32(tmp, tmp, val << 16);
7090
store_reg(s, rd, tmp);
7092
if (((insn >> 12) & 0xf) != 0xf)
7094
if (((insn >> 16) & 0xf) == 0) {
7095
gen_nop_hint(s, insn & 0xff);
7097
/* CPSR = immediate */
7099
shift = ((insn >> 8) & 0xf) * 2;
7101
val = (val >> shift) | (val << (32 - shift));
7102
i = ((insn & (1 << 22)) != 0);
7103
if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7107
} else if ((insn & 0x0f900000) == 0x01000000
7108
&& (insn & 0x00000090) != 0x00000090) {
7109
/* miscellaneous instructions */
7110
op1 = (insn >> 21) & 3;
7111
sh = (insn >> 4) & 0xf;
7114
case 0x0: /* move program status register */
7117
tmp = load_reg(s, rm);
7118
i = ((op1 & 2) != 0);
7119
if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7123
rd = (insn >> 12) & 0xf;
7127
tmp = load_cpu_field(spsr);
7129
tmp = tcg_temp_new_i32();
7130
gen_helper_cpsr_read(tmp, cpu_env);
7132
store_reg(s, rd, tmp);
7137
/* branch/exchange thumb (bx). */
7139
tmp = load_reg(s, rm);
7141
} else if (op1 == 3) {
7144
rd = (insn >> 12) & 0xf;
7145
tmp = load_reg(s, rm);
7146
gen_helper_clz(tmp, tmp);
7147
store_reg(s, rd, tmp);
7155
/* Trivial implementation equivalent to bx. */
7156
tmp = load_reg(s, rm);
7167
/* branch link/exchange thumb (blx) */
7168
tmp = load_reg(s, rm);
7169
tmp2 = tcg_temp_new_i32();
7170
tcg_gen_movi_i32(tmp2, s->pc);
7171
store_reg(s, 14, tmp2);
7174
case 0x5: /* saturating add/subtract */
7176
rd = (insn >> 12) & 0xf;
7177
rn = (insn >> 16) & 0xf;
7178
tmp = load_reg(s, rm);
7179
tmp2 = load_reg(s, rn);
7181
gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7183
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7185
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7186
tcg_temp_free_i32(tmp2);
7187
store_reg(s, rd, tmp);
7193
gen_exception_insn(s, 4, EXCP_BKPT);
7194
} else if (op1 == 3) {
7196
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE) || IS_USER(s)) {
7204
case 0x8: /* signed multiply */
7209
rs = (insn >> 8) & 0xf;
7210
rn = (insn >> 12) & 0xf;
7211
rd = (insn >> 16) & 0xf;
7213
/* (32 * 16) >> 16 */
7214
tmp = load_reg(s, rm);
7215
tmp2 = load_reg(s, rs);
7217
tcg_gen_sari_i32(tmp2, tmp2, 16);
7220
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7221
tcg_gen_shri_i64(tmp64, tmp64, 16);
7222
tmp = tcg_temp_new_i32();
7223
tcg_gen_trunc_i64_i32(tmp, tmp64);
7224
tcg_temp_free_i64(tmp64);
7225
if ((sh & 2) == 0) {
7226
tmp2 = load_reg(s, rn);
7227
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7228
tcg_temp_free_i32(tmp2);
7230
store_reg(s, rd, tmp);
7233
tmp = load_reg(s, rm);
7234
tmp2 = load_reg(s, rs);
7235
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7236
tcg_temp_free_i32(tmp2);
7238
tmp64 = tcg_temp_new_i64();
7239
tcg_gen_ext_i32_i64(tmp64, tmp);
7240
tcg_temp_free_i32(tmp);
7241
gen_addq(s, tmp64, rn, rd);
7242
gen_storeq_reg(s, rn, rd, tmp64);
7243
tcg_temp_free_i64(tmp64);
7246
tmp2 = load_reg(s, rn);
7247
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7248
tcg_temp_free_i32(tmp2);
7250
store_reg(s, rd, tmp);
7257
} else if (((insn & 0x0e000000) == 0 &&
7258
(insn & 0x00000090) != 0x90) ||
7259
((insn & 0x0e000000) == (1 << 25))) {
7260
int set_cc, logic_cc, shiftop;
7262
op1 = (insn >> 21) & 0xf;
7263
set_cc = (insn >> 20) & 1;
7264
logic_cc = table_logic_cc[op1] & set_cc;
7266
/* data processing instruction */
7267
if (insn & (1 << 25)) {
7268
/* immediate operand */
7270
shift = ((insn >> 8) & 0xf) * 2;
7272
val = (val >> shift) | (val << (32 - shift));
7274
tmp2 = tcg_temp_new_i32();
7275
tcg_gen_movi_i32(tmp2, val);
7276
if (logic_cc && shift) {
7277
gen_set_CF_bit31(tmp2);
7282
tmp2 = load_reg(s, rm);
7283
shiftop = (insn >> 5) & 3;
7284
if (!(insn & (1 << 4))) {
7285
shift = (insn >> 7) & 0x1f;
7286
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7288
rs = (insn >> 8) & 0xf;
7289
tmp = load_reg(s, rs);
7290
gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7293
if (op1 != 0x0f && op1 != 0x0d) {
7294
rn = (insn >> 16) & 0xf;
7295
tmp = load_reg(s, rn);
7297
TCGV_UNUSED_I32(tmp);
7299
rd = (insn >> 12) & 0xf;
7302
tcg_gen_and_i32(tmp, tmp, tmp2);
7306
store_reg_bx(env, s, rd, tmp);
7309
tcg_gen_xor_i32(tmp, tmp, tmp2);
7313
store_reg_bx(env, s, rd, tmp);
7316
if (set_cc && rd == 15) {
7317
/* SUBS r15, ... is used for exception return. */
7321
gen_sub_CC(tmp, tmp, tmp2);
7322
gen_exception_return(s, tmp);
7325
gen_sub_CC(tmp, tmp, tmp2);
7327
tcg_gen_sub_i32(tmp, tmp, tmp2);
7329
store_reg_bx(env, s, rd, tmp);
7334
gen_sub_CC(tmp, tmp2, tmp);
7336
tcg_gen_sub_i32(tmp, tmp2, tmp);
7338
store_reg_bx(env, s, rd, tmp);
7342
gen_add_CC(tmp, tmp, tmp2);
7344
tcg_gen_add_i32(tmp, tmp, tmp2);
7346
store_reg_bx(env, s, rd, tmp);
7350
gen_adc_CC(tmp, tmp, tmp2);
7352
gen_add_carry(tmp, tmp, tmp2);
7354
store_reg_bx(env, s, rd, tmp);
7358
gen_sbc_CC(tmp, tmp, tmp2);
7360
gen_sub_carry(tmp, tmp, tmp2);
7362
store_reg_bx(env, s, rd, tmp);
7366
gen_sbc_CC(tmp, tmp2, tmp);
7368
gen_sub_carry(tmp, tmp2, tmp);
7370
store_reg_bx(env, s, rd, tmp);
7374
tcg_gen_and_i32(tmp, tmp, tmp2);
7377
tcg_temp_free_i32(tmp);
7381
tcg_gen_xor_i32(tmp, tmp, tmp2);
7384
tcg_temp_free_i32(tmp);
7388
gen_sub_CC(tmp, tmp, tmp2);
7390
tcg_temp_free_i32(tmp);
7394
gen_add_CC(tmp, tmp, tmp2);
7396
tcg_temp_free_i32(tmp);
7399
tcg_gen_or_i32(tmp, tmp, tmp2);
7403
store_reg_bx(env, s, rd, tmp);
7406
if (logic_cc && rd == 15) {
7407
/* MOVS r15, ... is used for exception return. */
7411
gen_exception_return(s, tmp2);
7416
store_reg_bx(env, s, rd, tmp2);
7420
tcg_gen_andc_i32(tmp, tmp, tmp2);
7424
store_reg_bx(env, s, rd, tmp);
7428
tcg_gen_not_i32(tmp2, tmp2);
7432
store_reg_bx(env, s, rd, tmp2);
7435
if (op1 != 0x0f && op1 != 0x0d) {
7436
tcg_temp_free_i32(tmp2);
7439
/* other instructions */
7440
op1 = (insn >> 24) & 0xf;
7444
/* multiplies, extra load/stores */
7445
sh = (insn >> 5) & 3;
7448
rd = (insn >> 16) & 0xf;
7449
rn = (insn >> 12) & 0xf;
7450
rs = (insn >> 8) & 0xf;
7452
op1 = (insn >> 20) & 0xf;
7454
case 0: case 1: case 2: case 3: case 6:
7456
tmp = load_reg(s, rs);
7457
tmp2 = load_reg(s, rm);
7458
tcg_gen_mul_i32(tmp, tmp, tmp2);
7459
tcg_temp_free_i32(tmp2);
7460
if (insn & (1 << 22)) {
7461
/* Subtract (mls) */
7463
tmp2 = load_reg(s, rn);
7464
tcg_gen_sub_i32(tmp, tmp2, tmp);
7465
tcg_temp_free_i32(tmp2);
7466
} else if (insn & (1 << 21)) {
7468
tmp2 = load_reg(s, rn);
7469
tcg_gen_add_i32(tmp, tmp, tmp2);
7470
tcg_temp_free_i32(tmp2);
7472
if (insn & (1 << 20))
7474
store_reg(s, rd, tmp);
7477
/* 64 bit mul double accumulate (UMAAL) */
7479
tmp = load_reg(s, rs);
7480
tmp2 = load_reg(s, rm);
7481
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7482
gen_addq_lo(s, tmp64, rn);
7483
gen_addq_lo(s, tmp64, rd);
7484
gen_storeq_reg(s, rn, rd, tmp64);
7485
tcg_temp_free_i64(tmp64);
7487
case 8: case 9: case 10: case 11:
7488
case 12: case 13: case 14: case 15:
7489
/* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7490
tmp = load_reg(s, rs);
7491
tmp2 = load_reg(s, rm);
7492
if (insn & (1 << 22)) {
7493
tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7495
tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7497
if (insn & (1 << 21)) { /* mult accumulate */
7498
TCGv_i32 al = load_reg(s, rn);
7499
TCGv_i32 ah = load_reg(s, rd);
7500
tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7501
tcg_temp_free_i32(al);
7502
tcg_temp_free_i32(ah);
7504
if (insn & (1 << 20)) {
7505
gen_logicq_cc(tmp, tmp2);
7507
store_reg(s, rn, tmp);
7508
store_reg(s, rd, tmp2);
7514
rn = (insn >> 16) & 0xf;
7515
rd = (insn >> 12) & 0xf;
7516
if (insn & (1 << 23)) {
7517
/* load/store exclusive */
7518
int op2 = (insn >> 8) & 3;
7519
op1 = (insn >> 21) & 0x3;
7522
case 0: /* lda/stl */
7528
case 1: /* reserved */
7530
case 2: /* ldaex/stlex */
7533
case 3: /* ldrex/strex */
7542
addr = tcg_temp_local_new_i32();
7543
load_reg_var(s, addr, rn);
7545
/* Since the emulation does not have barriers,
7546
the acquire/release semantics need no special
7549
if (insn & (1 << 20)) {
7550
tmp = tcg_temp_new_i32();
7553
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7556
gen_aa32_ld8u(tmp, addr, IS_USER(s));
7559
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7564
store_reg(s, rd, tmp);
7567
tmp = load_reg(s, rm);
7570
gen_aa32_st32(tmp, addr, IS_USER(s));
7573
gen_aa32_st8(tmp, addr, IS_USER(s));
7576
gen_aa32_st16(tmp, addr, IS_USER(s));
7581
tcg_temp_free_i32(tmp);
7583
} else if (insn & (1 << 20)) {
7586
gen_load_exclusive(s, rd, 15, addr, 2);
7588
case 1: /* ldrexd */
7589
gen_load_exclusive(s, rd, rd + 1, addr, 3);
7591
case 2: /* ldrexb */
7592
gen_load_exclusive(s, rd, 15, addr, 0);
7594
case 3: /* ldrexh */
7595
gen_load_exclusive(s, rd, 15, addr, 1);
7604
gen_store_exclusive(s, rd, rm, 15, addr, 2);
7606
case 1: /* strexd */
7607
gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7609
case 2: /* strexb */
7610
gen_store_exclusive(s, rd, rm, 15, addr, 0);
7612
case 3: /* strexh */
7613
gen_store_exclusive(s, rd, rm, 15, addr, 1);
7619
tcg_temp_free_i32(addr);
7621
/* SWP instruction */
7624
/* ??? This is not really atomic. However we know
7625
we never have multiple CPUs running in parallel,
7626
so it is good enough. */
7627
addr = load_reg(s, rn);
7628
tmp = load_reg(s, rm);
7629
tmp2 = tcg_temp_new_i32();
7630
if (insn & (1 << 22)) {
7631
gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7632
gen_aa32_st8(tmp, addr, IS_USER(s));
7634
gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7635
gen_aa32_st32(tmp, addr, IS_USER(s));
7637
tcg_temp_free_i32(tmp);
7638
tcg_temp_free_i32(addr);
7639
store_reg(s, rd, tmp2);
7645
/* Misc load/store */
7646
rn = (insn >> 16) & 0xf;
7647
rd = (insn >> 12) & 0xf;
7648
addr = load_reg(s, rn);
7649
if (insn & (1 << 24))
7650
gen_add_datah_offset(s, insn, 0, addr);
7652
if (insn & (1 << 20)) {
7654
tmp = tcg_temp_new_i32();
7657
gen_aa32_ld16u(tmp, addr, IS_USER(s));
7660
gen_aa32_ld8s(tmp, addr, IS_USER(s));
7664
gen_aa32_ld16s(tmp, addr, IS_USER(s));
7668
} else if (sh & 2) {
7673
tmp = load_reg(s, rd);
7674
gen_aa32_st32(tmp, addr, IS_USER(s));
7675
tcg_temp_free_i32(tmp);
7676
tcg_gen_addi_i32(addr, addr, 4);
7677
tmp = load_reg(s, rd + 1);
7678
gen_aa32_st32(tmp, addr, IS_USER(s));
7679
tcg_temp_free_i32(tmp);
7683
tmp = tcg_temp_new_i32();
7684
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7685
store_reg(s, rd, tmp);
7686
tcg_gen_addi_i32(addr, addr, 4);
7687
tmp = tcg_temp_new_i32();
7688
gen_aa32_ld32u(tmp, addr, IS_USER(s));
7692
address_offset = -4;
7695
tmp = load_reg(s, rd);
7696
gen_aa32_st16(tmp, addr, IS_USER(s));
7697
tcg_temp_free_i32(tmp);
7700
/* Perform base writeback before the loaded value to
7701
ensure correct behavior with overlapping index registers.
7702
ldrd with base writeback is is undefined if the
7703
destination and index registers overlap. */
7704
if (!(insn & (1 << 24))) {
7705
gen_add_datah_offset(s, insn, address_offset, addr);
7706
store_reg(s, rn, addr);
7707
} else if (insn & (1 << 21)) {
7709
tcg_gen_addi_i32(addr, addr, address_offset);
7710
store_reg(s, rn, addr);
7712
tcg_temp_free_i32(addr);
7715
/* Complete the load. */
7716
store_reg(s, rd, tmp);
7725
if (insn & (1 << 4)) {
7727
/* Armv6 Media instructions. */
7729
rn = (insn >> 16) & 0xf;
7730
rd = (insn >> 12) & 0xf;
7731
rs = (insn >> 8) & 0xf;
7732
switch ((insn >> 23) & 3) {
7733
case 0: /* Parallel add/subtract. */
7734
op1 = (insn >> 20) & 7;
7735
tmp = load_reg(s, rn);
7736
tmp2 = load_reg(s, rm);
7737
sh = (insn >> 5) & 7;
7738
if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7740
gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7741
tcg_temp_free_i32(tmp2);
7742
store_reg(s, rd, tmp);
7745
if ((insn & 0x00700020) == 0) {
7746
/* Halfword pack. */
7747
tmp = load_reg(s, rn);
7748
tmp2 = load_reg(s, rm);
7749
shift = (insn >> 7) & 0x1f;
7750
if (insn & (1 << 6)) {
7754
tcg_gen_sari_i32(tmp2, tmp2, shift);
7755
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7756
tcg_gen_ext16u_i32(tmp2, tmp2);
7760
tcg_gen_shli_i32(tmp2, tmp2, shift);
7761
tcg_gen_ext16u_i32(tmp, tmp);
7762
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7764
tcg_gen_or_i32(tmp, tmp, tmp2);
7765
tcg_temp_free_i32(tmp2);
7766
store_reg(s, rd, tmp);
7767
} else if ((insn & 0x00200020) == 0x00200000) {
7769
tmp = load_reg(s, rm);
7770
shift = (insn >> 7) & 0x1f;
7771
if (insn & (1 << 6)) {
7774
tcg_gen_sari_i32(tmp, tmp, shift);
7776
tcg_gen_shli_i32(tmp, tmp, shift);
7778
sh = (insn >> 16) & 0x1f;
7779
tmp2 = tcg_const_i32(sh);
7780
if (insn & (1 << 22))
7781
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7783
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7784
tcg_temp_free_i32(tmp2);
7785
store_reg(s, rd, tmp);
7786
} else if ((insn & 0x00300fe0) == 0x00200f20) {
7788
tmp = load_reg(s, rm);
7789
sh = (insn >> 16) & 0x1f;
7790
tmp2 = tcg_const_i32(sh);
7791
if (insn & (1 << 22))
7792
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7794
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7795
tcg_temp_free_i32(tmp2);
7796
store_reg(s, rd, tmp);
7797
} else if ((insn & 0x00700fe0) == 0x00000fa0) {
7799
tmp = load_reg(s, rn);
7800
tmp2 = load_reg(s, rm);
7801
tmp3 = tcg_temp_new_i32();
7802
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7803
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7804
tcg_temp_free_i32(tmp3);
7805
tcg_temp_free_i32(tmp2);
7806
store_reg(s, rd, tmp);
7807
} else if ((insn & 0x000003e0) == 0x00000060) {
7808
tmp = load_reg(s, rm);
7809
shift = (insn >> 10) & 3;
7810
/* ??? In many cases it's not necessary to do a
7811
rotate, a shift is sufficient. */
7813
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7814
op1 = (insn >> 20) & 7;
7816
case 0: gen_sxtb16(tmp); break;
7817
case 2: gen_sxtb(tmp); break;
7818
case 3: gen_sxth(tmp); break;
7819
case 4: gen_uxtb16(tmp); break;
7820
case 6: gen_uxtb(tmp); break;
7821
case 7: gen_uxth(tmp); break;
7822
default: goto illegal_op;
7825
tmp2 = load_reg(s, rn);
7826
if ((op1 & 3) == 0) {
7827
gen_add16(tmp, tmp2);
7829
tcg_gen_add_i32(tmp, tmp, tmp2);
7830
tcg_temp_free_i32(tmp2);
7833
store_reg(s, rd, tmp);
7834
} else if ((insn & 0x003f0f60) == 0x003f0f20) {
7836
tmp = load_reg(s, rm);
7837
if (insn & (1 << 22)) {
7838
if (insn & (1 << 7)) {
7842
gen_helper_rbit(tmp, tmp);
7845
if (insn & (1 << 7))
7848
tcg_gen_bswap32_i32(tmp, tmp);
7850
store_reg(s, rd, tmp);
7855
case 2: /* Multiplies (Type 3). */
7856
switch ((insn >> 20) & 0x7) {
7858
if (((insn >> 6) ^ (insn >> 7)) & 1) {
7859
/* op2 not 00x or 11x : UNDEF */
7862
/* Signed multiply most significant [accumulate].
7863
(SMMUL, SMMLA, SMMLS) */
7864
tmp = load_reg(s, rm);
7865
tmp2 = load_reg(s, rs);
7866
tmp64 = gen_muls_i64_i32(tmp, tmp2);
7869
tmp = load_reg(s, rd);
7870
if (insn & (1 << 6)) {
7871
tmp64 = gen_subq_msw(tmp64, tmp);
7873
tmp64 = gen_addq_msw(tmp64, tmp);
7876
if (insn & (1 << 5)) {
7877
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7879
tcg_gen_shri_i64(tmp64, tmp64, 32);
7880
tmp = tcg_temp_new_i32();
7881
tcg_gen_trunc_i64_i32(tmp, tmp64);
7882
tcg_temp_free_i64(tmp64);
7883
store_reg(s, rn, tmp);
7887
/* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7888
if (insn & (1 << 7)) {
7891
tmp = load_reg(s, rm);
7892
tmp2 = load_reg(s, rs);
7893
if (insn & (1 << 5))
7894
gen_swap_half(tmp2);
7895
gen_smul_dual(tmp, tmp2);
7896
if (insn & (1 << 6)) {
7897
/* This subtraction cannot overflow. */
7898
tcg_gen_sub_i32(tmp, tmp, tmp2);
7900
/* This addition cannot overflow 32 bits;
7901
* however it may overflow considered as a signed
7902
* operation, in which case we must set the Q flag.
7904
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7906
tcg_temp_free_i32(tmp2);
7907
if (insn & (1 << 22)) {
7908
/* smlald, smlsld */
7909
tmp64 = tcg_temp_new_i64();
7910
tcg_gen_ext_i32_i64(tmp64, tmp);
7911
tcg_temp_free_i32(tmp);
7912
gen_addq(s, tmp64, rd, rn);
7913
gen_storeq_reg(s, rd, rn, tmp64);
7914
tcg_temp_free_i64(tmp64);
7916
/* smuad, smusd, smlad, smlsd */
7919
tmp2 = load_reg(s, rd);
7920
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7921
tcg_temp_free_i32(tmp2);
7923
store_reg(s, rn, tmp);
7929
if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7932
if (((insn >> 5) & 7) || (rd != 15)) {
7935
tmp = load_reg(s, rm);
7936
tmp2 = load_reg(s, rs);
7937
if (insn & (1 << 21)) {
7938
gen_helper_udiv(tmp, tmp, tmp2);
7940
gen_helper_sdiv(tmp, tmp, tmp2);
7942
tcg_temp_free_i32(tmp2);
7943
store_reg(s, rn, tmp);
7950
op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7952
case 0: /* Unsigned sum of absolute differences. */
7954
tmp = load_reg(s, rm);
7955
tmp2 = load_reg(s, rs);
7956
gen_helper_usad8(tmp, tmp, tmp2);
7957
tcg_temp_free_i32(tmp2);
7959
tmp2 = load_reg(s, rd);
7960
tcg_gen_add_i32(tmp, tmp, tmp2);
7961
tcg_temp_free_i32(tmp2);
7963
store_reg(s, rn, tmp);
7965
case 0x20: case 0x24: case 0x28: case 0x2c:
7966
/* Bitfield insert/clear. */
7968
shift = (insn >> 7) & 0x1f;
7969
i = (insn >> 16) & 0x1f;
7972
tmp = tcg_temp_new_i32();
7973
tcg_gen_movi_i32(tmp, 0);
7975
tmp = load_reg(s, rm);
7978
tmp2 = load_reg(s, rd);
7979
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
7980
tcg_temp_free_i32(tmp2);
7982
store_reg(s, rd, tmp);
7984
case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7985
case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7987
tmp = load_reg(s, rm);
7988
shift = (insn >> 7) & 0x1f;
7989
i = ((insn >> 16) & 0x1f) + 1;
7994
gen_ubfx(tmp, shift, (1u << i) - 1);
7996
gen_sbfx(tmp, shift, i);
7999
store_reg(s, rd, tmp);
8009
/* Check for undefined extension instructions
8010
* per the ARM Bible IE:
8011
* xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8013
sh = (0xf << 20) | (0xf << 4);
8014
if (op1 == 0x7 && ((insn & sh) == sh))
8018
/* load/store byte/word */
8019
rn = (insn >> 16) & 0xf;
8020
rd = (insn >> 12) & 0xf;
8021
tmp2 = load_reg(s, rn);
8022
i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8023
if (insn & (1 << 24))
8024
gen_add_data_offset(s, insn, tmp2);
8025
if (insn & (1 << 20)) {
8027
tmp = tcg_temp_new_i32();
8028
if (insn & (1 << 22)) {
8029
gen_aa32_ld8u(tmp, tmp2, i);
8031
gen_aa32_ld32u(tmp, tmp2, i);
8035
tmp = load_reg(s, rd);
8036
if (insn & (1 << 22)) {
8037
gen_aa32_st8(tmp, tmp2, i);
8039
gen_aa32_st32(tmp, tmp2, i);
8041
tcg_temp_free_i32(tmp);
8043
if (!(insn & (1 << 24))) {
8044
gen_add_data_offset(s, insn, tmp2);
8045
store_reg(s, rn, tmp2);
8046
} else if (insn & (1 << 21)) {
8047
store_reg(s, rn, tmp2);
8049
tcg_temp_free_i32(tmp2);
8051
if (insn & (1 << 20)) {
8052
/* Complete the load. */
8053
store_reg_from_load(env, s, rd, tmp);
8059
int j, n, user, loaded_base;
8060
TCGv_i32 loaded_var;
8061
/* load/store multiple words */
8062
/* XXX: store correct base if write back */
8064
if (insn & (1 << 22)) {
8066
goto illegal_op; /* only usable in supervisor mode */
8068
if ((insn & (1 << 15)) == 0)
8071
rn = (insn >> 16) & 0xf;
8072
addr = load_reg(s, rn);
8074
/* compute total size */
8076
TCGV_UNUSED_I32(loaded_var);
8079
if (insn & (1 << i))
8082
/* XXX: test invalid n == 0 case ? */
8083
if (insn & (1 << 23)) {
8084
if (insn & (1 << 24)) {
8086
tcg_gen_addi_i32(addr, addr, 4);
8088
/* post increment */
8091
if (insn & (1 << 24)) {
8093
tcg_gen_addi_i32(addr, addr, -(n * 4));
8095
/* post decrement */
8097
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8102
if (insn & (1 << i)) {
8103
if (insn & (1 << 20)) {
8105
tmp = tcg_temp_new_i32();
8106
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8108
tmp2 = tcg_const_i32(i);
8109
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8110
tcg_temp_free_i32(tmp2);
8111
tcg_temp_free_i32(tmp);
8112
} else if (i == rn) {
8116
store_reg_from_load(env, s, i, tmp);
8121
/* special case: r15 = PC + 8 */
8122
val = (long)s->pc + 4;
8123
tmp = tcg_temp_new_i32();
8124
tcg_gen_movi_i32(tmp, val);
8126
tmp = tcg_temp_new_i32();
8127
tmp2 = tcg_const_i32(i);
8128
gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8129
tcg_temp_free_i32(tmp2);
8131
tmp = load_reg(s, i);
8133
gen_aa32_st32(tmp, addr, IS_USER(s));
8134
tcg_temp_free_i32(tmp);
8137
/* no need to add after the last transfer */
8139
tcg_gen_addi_i32(addr, addr, 4);
8142
if (insn & (1 << 21)) {
8144
if (insn & (1 << 23)) {
8145
if (insn & (1 << 24)) {
8148
/* post increment */
8149
tcg_gen_addi_i32(addr, addr, 4);
8152
if (insn & (1 << 24)) {
8155
tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8157
/* post decrement */
8158
tcg_gen_addi_i32(addr, addr, -(n * 4));
8161
store_reg(s, rn, addr);
8163
tcg_temp_free_i32(addr);
8166
store_reg(s, rn, loaded_var);
8168
if ((insn & (1 << 22)) && !user) {
8169
/* Restore CPSR from SPSR. */
8170
tmp = load_cpu_field(spsr);
8171
gen_set_cpsr(tmp, 0xffffffff);
8172
tcg_temp_free_i32(tmp);
8173
s->is_jmp = DISAS_UPDATE;
8182
/* branch (and link) */
8183
val = (int32_t)s->pc;
8184
if (insn & (1 << 24)) {
8185
tmp = tcg_temp_new_i32();
8186
tcg_gen_movi_i32(tmp, val);
8187
store_reg(s, 14, tmp);
8189
offset = sextract32(insn << 2, 0, 26);
8197
if (((insn >> 8) & 0xe) == 10) {
8199
if (disas_vfp_insn(env, s, insn)) {
8202
} else if (disas_coproc_insn(env, s, insn)) {
8209
gen_set_pc_im(s, s->pc);
8210
s->is_jmp = DISAS_SWI;
8214
gen_exception_insn(s, 4, EXCP_UDEF);
8220
/* Return true if this is a Thumb-2 logical op. */
8222
thumb2_logic_op(int op)
8227
/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8228
then set condition code flags based on the result of the operation.
8229
If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8230
to the high bit of T1.
8231
Returns zero if the opcode is valid. */
8234
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8235
TCGv_i32 t0, TCGv_i32 t1)
8242
tcg_gen_and_i32(t0, t0, t1);
8246
tcg_gen_andc_i32(t0, t0, t1);
8250
tcg_gen_or_i32(t0, t0, t1);
8254
tcg_gen_orc_i32(t0, t0, t1);
8258
tcg_gen_xor_i32(t0, t0, t1);
8263
gen_add_CC(t0, t0, t1);
8265
tcg_gen_add_i32(t0, t0, t1);
8269
gen_adc_CC(t0, t0, t1);
8275
gen_sbc_CC(t0, t0, t1);
8277
gen_sub_carry(t0, t0, t1);
8282
gen_sub_CC(t0, t0, t1);
8284
tcg_gen_sub_i32(t0, t0, t1);
8288
gen_sub_CC(t0, t1, t0);
8290
tcg_gen_sub_i32(t0, t1, t0);
8292
default: /* 5, 6, 7, 9, 12, 15. */
8298
gen_set_CF_bit31(t1);
8303
/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8305
static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8307
uint32_t insn, imm, shift, offset;
8308
uint32_t rd, rn, rm, rs;
8319
if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8320
|| arm_feature (env, ARM_FEATURE_M))) {
8321
/* Thumb-1 cores may need to treat bl and blx as a pair of
8322
16-bit instructions to get correct prefetch abort behavior. */
8324
if ((insn & (1 << 12)) == 0) {
8326
/* Second half of blx. */
8327
offset = ((insn & 0x7ff) << 1);
8328
tmp = load_reg(s, 14);
8329
tcg_gen_addi_i32(tmp, tmp, offset);
8330
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8332
tmp2 = tcg_temp_new_i32();
8333
tcg_gen_movi_i32(tmp2, s->pc | 1);
8334
store_reg(s, 14, tmp2);
8338
if (insn & (1 << 11)) {
8339
/* Second half of bl. */
8340
offset = ((insn & 0x7ff) << 1) | 1;
8341
tmp = load_reg(s, 14);
8342
tcg_gen_addi_i32(tmp, tmp, offset);
8344
tmp2 = tcg_temp_new_i32();
8345
tcg_gen_movi_i32(tmp2, s->pc | 1);
8346
store_reg(s, 14, tmp2);
8350
if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8351
/* Instruction spans a page boundary. Implement it as two
8352
16-bit instructions in case the second half causes an
8354
offset = ((int32_t)insn << 21) >> 9;
8355
tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8358
/* Fall through to 32-bit decode. */
8361
insn = arm_lduw_code(env, s->pc, s->bswap_code);
8363
insn |= (uint32_t)insn_hw1 << 16;
8365
if ((insn & 0xf800e800) != 0xf000e800) {
8369
rn = (insn >> 16) & 0xf;
8370
rs = (insn >> 12) & 0xf;
8371
rd = (insn >> 8) & 0xf;
8373
switch ((insn >> 25) & 0xf) {
8374
case 0: case 1: case 2: case 3:
8375
/* 16-bit instructions. Should never happen. */
8378
if (insn & (1 << 22)) {
8379
/* Other load/store, table branch. */
8380
if (insn & 0x01200000) {
8381
/* Load/store doubleword. */
8383
addr = tcg_temp_new_i32();
8384
tcg_gen_movi_i32(addr, s->pc & ~3);
8386
addr = load_reg(s, rn);
8388
offset = (insn & 0xff) * 4;
8389
if ((insn & (1 << 23)) == 0)
8391
if (insn & (1 << 24)) {
8392
tcg_gen_addi_i32(addr, addr, offset);
8395
if (insn & (1 << 20)) {
8397
tmp = tcg_temp_new_i32();
8398
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8399
store_reg(s, rs, tmp);
8400
tcg_gen_addi_i32(addr, addr, 4);
8401
tmp = tcg_temp_new_i32();
8402
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8403
store_reg(s, rd, tmp);
8406
tmp = load_reg(s, rs);
8407
gen_aa32_st32(tmp, addr, IS_USER(s));
8408
tcg_temp_free_i32(tmp);
8409
tcg_gen_addi_i32(addr, addr, 4);
8410
tmp = load_reg(s, rd);
8411
gen_aa32_st32(tmp, addr, IS_USER(s));
8412
tcg_temp_free_i32(tmp);
8414
if (insn & (1 << 21)) {
8415
/* Base writeback. */
8418
tcg_gen_addi_i32(addr, addr, offset - 4);
8419
store_reg(s, rn, addr);
8421
tcg_temp_free_i32(addr);
8423
} else if ((insn & (1 << 23)) == 0) {
8424
/* Load/store exclusive word. */
8425
addr = tcg_temp_local_new_i32();
8426
load_reg_var(s, addr, rn);
8427
tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8428
if (insn & (1 << 20)) {
8429
gen_load_exclusive(s, rs, 15, addr, 2);
8431
gen_store_exclusive(s, rd, rs, 15, addr, 2);
8433
tcg_temp_free_i32(addr);
8434
} else if ((insn & (7 << 5)) == 0) {
8437
addr = tcg_temp_new_i32();
8438
tcg_gen_movi_i32(addr, s->pc);
8440
addr = load_reg(s, rn);
8442
tmp = load_reg(s, rm);
8443
tcg_gen_add_i32(addr, addr, tmp);
8444
if (insn & (1 << 4)) {
8446
tcg_gen_add_i32(addr, addr, tmp);
8447
tcg_temp_free_i32(tmp);
8448
tmp = tcg_temp_new_i32();
8449
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8451
tcg_temp_free_i32(tmp);
8452
tmp = tcg_temp_new_i32();
8453
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8455
tcg_temp_free_i32(addr);
8456
tcg_gen_shli_i32(tmp, tmp, 1);
8457
tcg_gen_addi_i32(tmp, tmp, s->pc);
8458
store_reg(s, 15, tmp);
8460
int op2 = (insn >> 6) & 0x3;
8461
op = (insn >> 4) & 0x3;
8466
/* Load/store exclusive byte/halfword/doubleword */
8473
/* Load-acquire/store-release */
8479
/* Load-acquire/store-release exclusive */
8483
addr = tcg_temp_local_new_i32();
8484
load_reg_var(s, addr, rn);
8486
if (insn & (1 << 20)) {
8487
tmp = tcg_temp_new_i32();
8490
gen_aa32_ld8u(tmp, addr, IS_USER(s));
8493
gen_aa32_ld16u(tmp, addr, IS_USER(s));
8496
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8501
store_reg(s, rs, tmp);
8503
tmp = load_reg(s, rs);
8506
gen_aa32_st8(tmp, addr, IS_USER(s));
8509
gen_aa32_st16(tmp, addr, IS_USER(s));
8512
gen_aa32_st32(tmp, addr, IS_USER(s));
8517
tcg_temp_free_i32(tmp);
8519
} else if (insn & (1 << 20)) {
8520
gen_load_exclusive(s, rs, rd, addr, op);
8522
gen_store_exclusive(s, rm, rs, rd, addr, op);
8524
tcg_temp_free_i32(addr);
8527
/* Load/store multiple, RFE, SRS. */
8528
if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8529
/* RFE, SRS: not available in user mode or on M profile */
8530
if (IS_USER(s) || IS_M(env)) {
8533
if (insn & (1 << 20)) {
8535
addr = load_reg(s, rn);
8536
if ((insn & (1 << 24)) == 0)
8537
tcg_gen_addi_i32(addr, addr, -8);
8538
/* Load PC into tmp and CPSR into tmp2. */
8539
tmp = tcg_temp_new_i32();
8540
gen_aa32_ld32u(tmp, addr, 0);
8541
tcg_gen_addi_i32(addr, addr, 4);
8542
tmp2 = tcg_temp_new_i32();
8543
gen_aa32_ld32u(tmp2, addr, 0);
8544
if (insn & (1 << 21)) {
8545
/* Base writeback. */
8546
if (insn & (1 << 24)) {
8547
tcg_gen_addi_i32(addr, addr, 4);
8549
tcg_gen_addi_i32(addr, addr, -4);
8551
store_reg(s, rn, addr);
8553
tcg_temp_free_i32(addr);
8555
gen_rfe(s, tmp, tmp2);
8558
gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8562
int i, loaded_base = 0;
8563
TCGv_i32 loaded_var;
8564
/* Load/store multiple. */
8565
addr = load_reg(s, rn);
8567
for (i = 0; i < 16; i++) {
8568
if (insn & (1 << i))
8571
if (insn & (1 << 24)) {
8572
tcg_gen_addi_i32(addr, addr, -offset);
8575
TCGV_UNUSED_I32(loaded_var);
8576
for (i = 0; i < 16; i++) {
8577
if ((insn & (1 << i)) == 0)
8579
if (insn & (1 << 20)) {
8581
tmp = tcg_temp_new_i32();
8582
gen_aa32_ld32u(tmp, addr, IS_USER(s));
8585
} else if (i == rn) {
8589
store_reg(s, i, tmp);
8593
tmp = load_reg(s, i);
8594
gen_aa32_st32(tmp, addr, IS_USER(s));
8595
tcg_temp_free_i32(tmp);
8597
tcg_gen_addi_i32(addr, addr, 4);
8600
store_reg(s, rn, loaded_var);
8602
if (insn & (1 << 21)) {
8603
/* Base register writeback. */
8604
if (insn & (1 << 24)) {
8605
tcg_gen_addi_i32(addr, addr, -offset);
8607
/* Fault if writeback register is in register list. */
8608
if (insn & (1 << rn))
8610
store_reg(s, rn, addr);
8612
tcg_temp_free_i32(addr);
8619
op = (insn >> 21) & 0xf;
8621
/* Halfword pack. */
8622
tmp = load_reg(s, rn);
8623
tmp2 = load_reg(s, rm);
8624
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8625
if (insn & (1 << 5)) {
8629
tcg_gen_sari_i32(tmp2, tmp2, shift);
8630
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8631
tcg_gen_ext16u_i32(tmp2, tmp2);
8635
tcg_gen_shli_i32(tmp2, tmp2, shift);
8636
tcg_gen_ext16u_i32(tmp, tmp);
8637
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8639
tcg_gen_or_i32(tmp, tmp, tmp2);
8640
tcg_temp_free_i32(tmp2);
8641
store_reg(s, rd, tmp);
8643
/* Data processing register constant shift. */
8645
tmp = tcg_temp_new_i32();
8646
tcg_gen_movi_i32(tmp, 0);
8648
tmp = load_reg(s, rn);
8650
tmp2 = load_reg(s, rm);
8652
shiftop = (insn >> 4) & 3;
8653
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8654
conds = (insn & (1 << 20)) != 0;
8655
logic_cc = (conds && thumb2_logic_op(op));
8656
gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8657
if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8659
tcg_temp_free_i32(tmp2);
8661
store_reg(s, rd, tmp);
8663
tcg_temp_free_i32(tmp);
8667
case 13: /* Misc data processing. */
8668
op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8669
if (op < 4 && (insn & 0xf000) != 0xf000)
8672
case 0: /* Register controlled shift. */
8673
tmp = load_reg(s, rn);
8674
tmp2 = load_reg(s, rm);
8675
if ((insn & 0x70) != 0)
8677
op = (insn >> 21) & 3;
8678
logic_cc = (insn & (1 << 20)) != 0;
8679
gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8682
store_reg_bx(env, s, rd, tmp);
8684
case 1: /* Sign/zero extend. */
8685
tmp = load_reg(s, rm);
8686
shift = (insn >> 4) & 3;
8687
/* ??? In many cases it's not necessary to do a
8688
rotate, a shift is sufficient. */
8690
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8691
op = (insn >> 20) & 7;
8693
case 0: gen_sxth(tmp); break;
8694
case 1: gen_uxth(tmp); break;
8695
case 2: gen_sxtb16(tmp); break;
8696
case 3: gen_uxtb16(tmp); break;
8697
case 4: gen_sxtb(tmp); break;
8698
case 5: gen_uxtb(tmp); break;
8699
default: goto illegal_op;
8702
tmp2 = load_reg(s, rn);
8703
if ((op >> 1) == 1) {
8704
gen_add16(tmp, tmp2);
8706
tcg_gen_add_i32(tmp, tmp, tmp2);
8707
tcg_temp_free_i32(tmp2);
8710
store_reg(s, rd, tmp);
8712
case 2: /* SIMD add/subtract. */
8713
op = (insn >> 20) & 7;
8714
shift = (insn >> 4) & 7;
8715
if ((op & 3) == 3 || (shift & 3) == 3)
8717
tmp = load_reg(s, rn);
8718
tmp2 = load_reg(s, rm);
8719
gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8720
tcg_temp_free_i32(tmp2);
8721
store_reg(s, rd, tmp);
8723
case 3: /* Other data processing. */
8724
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8726
/* Saturating add/subtract. */
8727
tmp = load_reg(s, rn);
8728
tmp2 = load_reg(s, rm);
8730
gen_helper_double_saturate(tmp, cpu_env, tmp);
8732
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8734
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8735
tcg_temp_free_i32(tmp2);
8737
tmp = load_reg(s, rn);
8739
case 0x0a: /* rbit */
8740
gen_helper_rbit(tmp, tmp);
8742
case 0x08: /* rev */
8743
tcg_gen_bswap32_i32(tmp, tmp);
8745
case 0x09: /* rev16 */
8748
case 0x0b: /* revsh */
8751
case 0x10: /* sel */
8752
tmp2 = load_reg(s, rm);
8753
tmp3 = tcg_temp_new_i32();
8754
tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8755
gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8756
tcg_temp_free_i32(tmp3);
8757
tcg_temp_free_i32(tmp2);
8759
case 0x18: /* clz */
8760
gen_helper_clz(tmp, tmp);
8766
store_reg(s, rd, tmp);
8768
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8769
op = (insn >> 4) & 0xf;
8770
tmp = load_reg(s, rn);
8771
tmp2 = load_reg(s, rm);
8772
switch ((insn >> 20) & 7) {
8773
case 0: /* 32 x 32 -> 32 */
8774
tcg_gen_mul_i32(tmp, tmp, tmp2);
8775
tcg_temp_free_i32(tmp2);
8777
tmp2 = load_reg(s, rs);
8779
tcg_gen_sub_i32(tmp, tmp2, tmp);
8781
tcg_gen_add_i32(tmp, tmp, tmp2);
8782
tcg_temp_free_i32(tmp2);
8785
case 1: /* 16 x 16 -> 32 */
8786
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8787
tcg_temp_free_i32(tmp2);
8789
tmp2 = load_reg(s, rs);
8790
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8791
tcg_temp_free_i32(tmp2);
8794
case 2: /* Dual multiply add. */
8795
case 4: /* Dual multiply subtract. */
8797
gen_swap_half(tmp2);
8798
gen_smul_dual(tmp, tmp2);
8799
if (insn & (1 << 22)) {
8800
/* This subtraction cannot overflow. */
8801
tcg_gen_sub_i32(tmp, tmp, tmp2);
8803
/* This addition cannot overflow 32 bits;
8804
* however it may overflow considered as a signed
8805
* operation, in which case we must set the Q flag.
8807
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8809
tcg_temp_free_i32(tmp2);
8812
tmp2 = load_reg(s, rs);
8813
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8814
tcg_temp_free_i32(tmp2);
8817
case 3: /* 32 * 16 -> 32msb */
8819
tcg_gen_sari_i32(tmp2, tmp2, 16);
8822
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8823
tcg_gen_shri_i64(tmp64, tmp64, 16);
8824
tmp = tcg_temp_new_i32();
8825
tcg_gen_trunc_i64_i32(tmp, tmp64);
8826
tcg_temp_free_i64(tmp64);
8829
tmp2 = load_reg(s, rs);
8830
gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8831
tcg_temp_free_i32(tmp2);
8834
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8835
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8837
tmp = load_reg(s, rs);
8838
if (insn & (1 << 20)) {
8839
tmp64 = gen_addq_msw(tmp64, tmp);
8841
tmp64 = gen_subq_msw(tmp64, tmp);
8844
if (insn & (1 << 4)) {
8845
tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8847
tcg_gen_shri_i64(tmp64, tmp64, 32);
8848
tmp = tcg_temp_new_i32();
8849
tcg_gen_trunc_i64_i32(tmp, tmp64);
8850
tcg_temp_free_i64(tmp64);
8852
case 7: /* Unsigned sum of absolute differences. */
8853
gen_helper_usad8(tmp, tmp, tmp2);
8854
tcg_temp_free_i32(tmp2);
8856
tmp2 = load_reg(s, rs);
8857
tcg_gen_add_i32(tmp, tmp, tmp2);
8858
tcg_temp_free_i32(tmp2);
8862
store_reg(s, rd, tmp);
8864
case 6: case 7: /* 64-bit multiply, Divide. */
8865
op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8866
tmp = load_reg(s, rn);
8867
tmp2 = load_reg(s, rm);
8868
if ((op & 0x50) == 0x10) {
8870
if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8874
gen_helper_udiv(tmp, tmp, tmp2);
8876
gen_helper_sdiv(tmp, tmp, tmp2);
8877
tcg_temp_free_i32(tmp2);
8878
store_reg(s, rd, tmp);
8879
} else if ((op & 0xe) == 0xc) {
8880
/* Dual multiply accumulate long. */
8882
gen_swap_half(tmp2);
8883
gen_smul_dual(tmp, tmp2);
8885
tcg_gen_sub_i32(tmp, tmp, tmp2);
8887
tcg_gen_add_i32(tmp, tmp, tmp2);
8889
tcg_temp_free_i32(tmp2);
8891
tmp64 = tcg_temp_new_i64();
8892
tcg_gen_ext_i32_i64(tmp64, tmp);
8893
tcg_temp_free_i32(tmp);
8894
gen_addq(s, tmp64, rs, rd);
8895
gen_storeq_reg(s, rs, rd, tmp64);
8896
tcg_temp_free_i64(tmp64);
8899
/* Unsigned 64-bit multiply */
8900
tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8904
gen_mulxy(tmp, tmp2, op & 2, op & 1);
8905
tcg_temp_free_i32(tmp2);
8906
tmp64 = tcg_temp_new_i64();
8907
tcg_gen_ext_i32_i64(tmp64, tmp);
8908
tcg_temp_free_i32(tmp);
8910
/* Signed 64-bit multiply */
8911
tmp64 = gen_muls_i64_i32(tmp, tmp2);
8916
gen_addq_lo(s, tmp64, rs);
8917
gen_addq_lo(s, tmp64, rd);
8918
} else if (op & 0x40) {
8919
/* 64-bit accumulate. */
8920
gen_addq(s, tmp64, rs, rd);
8922
gen_storeq_reg(s, rs, rd, tmp64);
8923
tcg_temp_free_i64(tmp64);
8928
case 6: case 7: case 14: case 15:
8930
if (((insn >> 24) & 3) == 3) {
8931
/* Translate into the equivalent ARM encoding. */
8932
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8933
if (disas_neon_data_insn(env, s, insn))
8935
} else if (((insn >> 8) & 0xe) == 10) {
8936
if (disas_vfp_insn(env, s, insn)) {
8940
if (insn & (1 << 28))
8942
if (disas_coproc_insn (env, s, insn))
8946
case 8: case 9: case 10: case 11:
8947
if (insn & (1 << 15)) {
8948
/* Branches, misc control. */
8949
if (insn & 0x5000) {
8950
/* Unconditional branch. */
8951
/* signextend(hw1[10:0]) -> offset[:12]. */
8952
offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8953
/* hw1[10:0] -> offset[11:1]. */
8954
offset |= (insn & 0x7ff) << 1;
8955
/* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8956
offset[24:22] already have the same value because of the
8957
sign extension above. */
8958
offset ^= ((~insn) & (1 << 13)) << 10;
8959
offset ^= ((~insn) & (1 << 11)) << 11;
8961
if (insn & (1 << 14)) {
8962
/* Branch and link. */
8963
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8967
if (insn & (1 << 12)) {
8972
offset &= ~(uint32_t)2;
8973
/* thumb2 bx, no need to check */
8974
gen_bx_im(s, offset);
8976
} else if (((insn >> 23) & 7) == 7) {
8978
if (insn & (1 << 13))
8981
if (insn & (1 << 26)) {
8982
/* Secure monitor call / smc (v6Z) */
8983
if (!arm_feature(env, ARM_FEATURE_TRUSTZONE)
8989
op = (insn >> 20) & 7;
8991
case 0: /* msr cpsr. */
8993
tmp = load_reg(s, rn);
8994
addr = tcg_const_i32(insn & 0xff);
8995
gen_helper_v7m_msr(cpu_env, addr, tmp);
8996
tcg_temp_free_i32(addr);
8997
tcg_temp_free_i32(tmp);
9002
case 1: /* msr spsr. */
9005
tmp = load_reg(s, rn);
9007
msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9011
case 2: /* cps, nop-hint. */
9012
if (((insn >> 8) & 7) == 0) {
9013
gen_nop_hint(s, insn & 0xff);
9015
/* Implemented as NOP in user mode. */
9020
if (insn & (1 << 10)) {
9021
if (insn & (1 << 7))
9023
if (insn & (1 << 6))
9025
if (insn & (1 << 5))
9027
if (insn & (1 << 9))
9028
imm = CPSR_A | CPSR_I | CPSR_F;
9030
if (insn & (1 << 8)) {
9032
imm |= (insn & 0x1f);
9035
gen_set_psr_im(s, offset, 0, imm);
9038
case 3: /* Special control operations. */
9040
op = (insn >> 4) & 0xf;
9048
/* These execute as NOPs. */
9055
/* Trivial implementation equivalent to bx. */
9056
tmp = load_reg(s, rn);
9059
case 5: /* Exception return. */
9063
if (rn != 14 || rd != 15) {
9066
tmp = load_reg(s, rn);
9067
tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9068
gen_exception_return(s, tmp);
9070
case 6: /* mrs cpsr. */
9071
tmp = tcg_temp_new_i32();
9073
addr = tcg_const_i32(insn & 0xff);
9074
gen_helper_v7m_mrs(tmp, cpu_env, addr);
9075
tcg_temp_free_i32(addr);
9077
gen_helper_cpsr_read(tmp, cpu_env);
9079
store_reg(s, rd, tmp);
9081
case 7: /* mrs spsr. */
9082
/* Not accessible in user mode. */
9083
if (IS_USER(s) || IS_M(env))
9085
tmp = load_cpu_field(spsr);
9086
store_reg(s, rd, tmp);
9091
/* Conditional branch. */
9092
op = (insn >> 22) & 0xf;
9093
/* Generate a conditional jump to next instruction. */
9094
s->condlabel = gen_new_label();
9095
gen_test_cc(op ^ 1, s->condlabel);
9098
/* offset[11:1] = insn[10:0] */
9099
offset = (insn & 0x7ff) << 1;
9100
/* offset[17:12] = insn[21:16]. */
9101
offset |= (insn & 0x003f0000) >> 4;
9102
/* offset[31:20] = insn[26]. */
9103
offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9104
/* offset[18] = insn[13]. */
9105
offset |= (insn & (1 << 13)) << 5;
9106
/* offset[19] = insn[11]. */
9107
offset |= (insn & (1 << 11)) << 8;
9109
/* jump to the offset */
9110
gen_jmp(s, s->pc + offset);
9113
/* Data processing immediate. */
9114
if (insn & (1 << 25)) {
9115
if (insn & (1 << 24)) {
9116
if (insn & (1 << 20))
9118
/* Bitfield/Saturate. */
9119
op = (insn >> 21) & 7;
9121
shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9123
tmp = tcg_temp_new_i32();
9124
tcg_gen_movi_i32(tmp, 0);
9126
tmp = load_reg(s, rn);
9129
case 2: /* Signed bitfield extract. */
9131
if (shift + imm > 32)
9134
gen_sbfx(tmp, shift, imm);
9136
case 6: /* Unsigned bitfield extract. */
9138
if (shift + imm > 32)
9141
gen_ubfx(tmp, shift, (1u << imm) - 1);
9143
case 3: /* Bitfield insert/clear. */
9146
imm = imm + 1 - shift;
9148
tmp2 = load_reg(s, rd);
9149
tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9150
tcg_temp_free_i32(tmp2);
9155
default: /* Saturate. */
9158
tcg_gen_sari_i32(tmp, tmp, shift);
9160
tcg_gen_shli_i32(tmp, tmp, shift);
9162
tmp2 = tcg_const_i32(imm);
9165
if ((op & 1) && shift == 0)
9166
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9168
gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9171
if ((op & 1) && shift == 0)
9172
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9174
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9176
tcg_temp_free_i32(tmp2);
9179
store_reg(s, rd, tmp);
9181
imm = ((insn & 0x04000000) >> 15)
9182
| ((insn & 0x7000) >> 4) | (insn & 0xff);
9183
if (insn & (1 << 22)) {
9184
/* 16-bit immediate. */
9185
imm |= (insn >> 4) & 0xf000;
9186
if (insn & (1 << 23)) {
9188
tmp = load_reg(s, rd);
9189
tcg_gen_ext16u_i32(tmp, tmp);
9190
tcg_gen_ori_i32(tmp, tmp, imm << 16);
9193
tmp = tcg_temp_new_i32();
9194
tcg_gen_movi_i32(tmp, imm);
9197
/* Add/sub 12-bit immediate. */
9199
offset = s->pc & ~(uint32_t)3;
9200
if (insn & (1 << 23))
9204
tmp = tcg_temp_new_i32();
9205
tcg_gen_movi_i32(tmp, offset);
9207
tmp = load_reg(s, rn);
9208
if (insn & (1 << 23))
9209
tcg_gen_subi_i32(tmp, tmp, imm);
9211
tcg_gen_addi_i32(tmp, tmp, imm);
9214
store_reg(s, rd, tmp);
9217
int shifter_out = 0;
9218
/* modified 12-bit immediate. */
9219
shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9220
imm = (insn & 0xff);
9223
/* Nothing to do. */
9225
case 1: /* 00XY00XY */
9228
case 2: /* XY00XY00 */
9232
case 3: /* XYXYXYXY */
9236
default: /* Rotated constant. */
9237
shift = (shift << 1) | (imm >> 7);
9239
imm = imm << (32 - shift);
9243
tmp2 = tcg_temp_new_i32();
9244
tcg_gen_movi_i32(tmp2, imm);
9245
rn = (insn >> 16) & 0xf;
9247
tmp = tcg_temp_new_i32();
9248
tcg_gen_movi_i32(tmp, 0);
9250
tmp = load_reg(s, rn);
9252
op = (insn >> 21) & 0xf;
9253
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9254
shifter_out, tmp, tmp2))
9256
tcg_temp_free_i32(tmp2);
9257
rd = (insn >> 8) & 0xf;
9259
store_reg(s, rd, tmp);
9261
tcg_temp_free_i32(tmp);
9266
case 12: /* Load/store single data item. */
9271
if ((insn & 0x01100000) == 0x01000000) {
9272
if (disas_neon_ls_insn(env, s, insn))
9276
op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9278
if (!(insn & (1 << 20))) {
9282
/* Byte or halfword load space with dest == r15 : memory hints.
9283
* Catch them early so we don't emit pointless addressing code.
9284
* This space is a mix of:
9285
* PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9286
* the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9288
* unallocated hints, which must be treated as NOPs
9289
* UNPREDICTABLE space, which we NOP or UNDEF depending on
9290
* which is easiest for the decoding logic
9291
* Some space which must UNDEF
9293
int op1 = (insn >> 23) & 3;
9294
int op2 = (insn >> 6) & 0x3f;
9299
/* UNPREDICTABLE, unallocated hint or
9300
* PLD/PLDW/PLI (literal)
9305
return 0; /* PLD/PLDW/PLI or unallocated hint */
9307
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9308
return 0; /* PLD/PLDW/PLI or unallocated hint */
9310
/* UNDEF space, or an UNPREDICTABLE */
9316
addr = tcg_temp_new_i32();
9318
/* s->pc has already been incremented by 4. */
9319
imm = s->pc & 0xfffffffc;
9320
if (insn & (1 << 23))
9321
imm += insn & 0xfff;
9323
imm -= insn & 0xfff;
9324
tcg_gen_movi_i32(addr, imm);
9326
addr = load_reg(s, rn);
9327
if (insn & (1 << 23)) {
9328
/* Positive offset. */
9330
tcg_gen_addi_i32(addr, addr, imm);
9333
switch ((insn >> 8) & 0xf) {
9334
case 0x0: /* Shifted Register. */
9335
shift = (insn >> 4) & 0xf;
9337
tcg_temp_free_i32(addr);
9340
tmp = load_reg(s, rm);
9342
tcg_gen_shli_i32(tmp, tmp, shift);
9343
tcg_gen_add_i32(addr, addr, tmp);
9344
tcg_temp_free_i32(tmp);
9346
case 0xc: /* Negative offset. */
9347
tcg_gen_addi_i32(addr, addr, -imm);
9349
case 0xe: /* User privilege. */
9350
tcg_gen_addi_i32(addr, addr, imm);
9353
case 0x9: /* Post-decrement. */
9356
case 0xb: /* Post-increment. */
9360
case 0xd: /* Pre-decrement. */
9363
case 0xf: /* Pre-increment. */
9364
tcg_gen_addi_i32(addr, addr, imm);
9368
tcg_temp_free_i32(addr);
9373
if (insn & (1 << 20)) {
9375
tmp = tcg_temp_new_i32();
9378
gen_aa32_ld8u(tmp, addr, user);
9381
gen_aa32_ld8s(tmp, addr, user);
9384
gen_aa32_ld16u(tmp, addr, user);
9387
gen_aa32_ld16s(tmp, addr, user);
9390
gen_aa32_ld32u(tmp, addr, user);
9393
tcg_temp_free_i32(tmp);
9394
tcg_temp_free_i32(addr);
9400
store_reg(s, rs, tmp);
9404
tmp = load_reg(s, rs);
9407
gen_aa32_st8(tmp, addr, user);
9410
gen_aa32_st16(tmp, addr, user);
9413
gen_aa32_st32(tmp, addr, user);
9416
tcg_temp_free_i32(tmp);
9417
tcg_temp_free_i32(addr);
9420
tcg_temp_free_i32(tmp);
9423
tcg_gen_addi_i32(addr, addr, imm);
9425
store_reg(s, rn, addr);
9427
tcg_temp_free_i32(addr);
9439
static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9441
uint32_t val, insn, op, rm, rn, rd, shift, cond;
9448
if (s->condexec_mask) {
9449
cond = s->condexec_cond;
9450
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9451
s->condlabel = gen_new_label();
9452
gen_test_cc(cond ^ 1, s->condlabel);
9457
insn = arm_lduw_code(env, s->pc, s->bswap_code);
9460
switch (insn >> 12) {
9464
op = (insn >> 11) & 3;
9467
rn = (insn >> 3) & 7;
9468
tmp = load_reg(s, rn);
9469
if (insn & (1 << 10)) {
9471
tmp2 = tcg_temp_new_i32();
9472
tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9475
rm = (insn >> 6) & 7;
9476
tmp2 = load_reg(s, rm);
9478
if (insn & (1 << 9)) {
9479
if (s->condexec_mask)
9480
tcg_gen_sub_i32(tmp, tmp, tmp2);
9482
gen_sub_CC(tmp, tmp, tmp2);
9484
if (s->condexec_mask)
9485
tcg_gen_add_i32(tmp, tmp, tmp2);
9487
gen_add_CC(tmp, tmp, tmp2);
9489
tcg_temp_free_i32(tmp2);
9490
store_reg(s, rd, tmp);
9492
/* shift immediate */
9493
rm = (insn >> 3) & 7;
9494
shift = (insn >> 6) & 0x1f;
9495
tmp = load_reg(s, rm);
9496
gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9497
if (!s->condexec_mask)
9499
store_reg(s, rd, tmp);
9503
/* arithmetic large immediate */
9504
op = (insn >> 11) & 3;
9505
rd = (insn >> 8) & 0x7;
9506
if (op == 0) { /* mov */
9507
tmp = tcg_temp_new_i32();
9508
tcg_gen_movi_i32(tmp, insn & 0xff);
9509
if (!s->condexec_mask)
9511
store_reg(s, rd, tmp);
9513
tmp = load_reg(s, rd);
9514
tmp2 = tcg_temp_new_i32();
9515
tcg_gen_movi_i32(tmp2, insn & 0xff);
9518
gen_sub_CC(tmp, tmp, tmp2);
9519
tcg_temp_free_i32(tmp);
9520
tcg_temp_free_i32(tmp2);
9523
if (s->condexec_mask)
9524
tcg_gen_add_i32(tmp, tmp, tmp2);
9526
gen_add_CC(tmp, tmp, tmp2);
9527
tcg_temp_free_i32(tmp2);
9528
store_reg(s, rd, tmp);
9531
if (s->condexec_mask)
9532
tcg_gen_sub_i32(tmp, tmp, tmp2);
9534
gen_sub_CC(tmp, tmp, tmp2);
9535
tcg_temp_free_i32(tmp2);
9536
store_reg(s, rd, tmp);
9542
if (insn & (1 << 11)) {
9543
rd = (insn >> 8) & 7;
9544
/* load pc-relative. Bit 1 of PC is ignored. */
9545
val = s->pc + 2 + ((insn & 0xff) * 4);
9546
val &= ~(uint32_t)2;
9547
addr = tcg_temp_new_i32();
9548
tcg_gen_movi_i32(addr, val);
9549
tmp = tcg_temp_new_i32();
9550
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9551
tcg_temp_free_i32(addr);
9552
store_reg(s, rd, tmp);
9555
if (insn & (1 << 10)) {
9556
/* data processing extended or blx */
9557
rd = (insn & 7) | ((insn >> 4) & 8);
9558
rm = (insn >> 3) & 0xf;
9559
op = (insn >> 8) & 3;
9562
tmp = load_reg(s, rd);
9563
tmp2 = load_reg(s, rm);
9564
tcg_gen_add_i32(tmp, tmp, tmp2);
9565
tcg_temp_free_i32(tmp2);
9566
store_reg(s, rd, tmp);
9569
tmp = load_reg(s, rd);
9570
tmp2 = load_reg(s, rm);
9571
gen_sub_CC(tmp, tmp, tmp2);
9572
tcg_temp_free_i32(tmp2);
9573
tcg_temp_free_i32(tmp);
9575
case 2: /* mov/cpy */
9576
tmp = load_reg(s, rm);
9577
store_reg(s, rd, tmp);
9579
case 3:/* branch [and link] exchange thumb register */
9580
tmp = load_reg(s, rm);
9581
if (insn & (1 << 7)) {
9583
val = (uint32_t)s->pc | 1;
9584
tmp2 = tcg_temp_new_i32();
9585
tcg_gen_movi_i32(tmp2, val);
9586
store_reg(s, 14, tmp2);
9588
/* already thumb, no need to check */
9595
/* data processing register */
9597
rm = (insn >> 3) & 7;
9598
op = (insn >> 6) & 0xf;
9599
if (op == 2 || op == 3 || op == 4 || op == 7) {
9600
/* the shift/rotate ops want the operands backwards */
9609
if (op == 9) { /* neg */
9610
tmp = tcg_temp_new_i32();
9611
tcg_gen_movi_i32(tmp, 0);
9612
} else if (op != 0xf) { /* mvn doesn't read its first operand */
9613
tmp = load_reg(s, rd);
9615
TCGV_UNUSED_I32(tmp);
9618
tmp2 = load_reg(s, rm);
9621
tcg_gen_and_i32(tmp, tmp, tmp2);
9622
if (!s->condexec_mask)
9626
tcg_gen_xor_i32(tmp, tmp, tmp2);
9627
if (!s->condexec_mask)
9631
if (s->condexec_mask) {
9632
gen_shl(tmp2, tmp2, tmp);
9634
gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9639
if (s->condexec_mask) {
9640
gen_shr(tmp2, tmp2, tmp);
9642
gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9647
if (s->condexec_mask) {
9648
gen_sar(tmp2, tmp2, tmp);
9650
gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9655
if (s->condexec_mask) {
9658
gen_adc_CC(tmp, tmp, tmp2);
9662
if (s->condexec_mask) {
9663
gen_sub_carry(tmp, tmp, tmp2);
9665
gen_sbc_CC(tmp, tmp, tmp2);
9669
if (s->condexec_mask) {
9670
tcg_gen_andi_i32(tmp, tmp, 0x1f);
9671
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9673
gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9678
tcg_gen_and_i32(tmp, tmp, tmp2);
9683
if (s->condexec_mask)
9684
tcg_gen_neg_i32(tmp, tmp2);
9686
gen_sub_CC(tmp, tmp, tmp2);
9689
gen_sub_CC(tmp, tmp, tmp2);
9693
gen_add_CC(tmp, tmp, tmp2);
9697
tcg_gen_or_i32(tmp, tmp, tmp2);
9698
if (!s->condexec_mask)
9702
tcg_gen_mul_i32(tmp, tmp, tmp2);
9703
if (!s->condexec_mask)
9707
tcg_gen_andc_i32(tmp, tmp, tmp2);
9708
if (!s->condexec_mask)
9712
tcg_gen_not_i32(tmp2, tmp2);
9713
if (!s->condexec_mask)
9721
store_reg(s, rm, tmp2);
9723
tcg_temp_free_i32(tmp);
9725
store_reg(s, rd, tmp);
9726
tcg_temp_free_i32(tmp2);
9729
tcg_temp_free_i32(tmp);
9730
tcg_temp_free_i32(tmp2);
9735
/* load/store register offset. */
9737
rn = (insn >> 3) & 7;
9738
rm = (insn >> 6) & 7;
9739
op = (insn >> 9) & 7;
9740
addr = load_reg(s, rn);
9741
tmp = load_reg(s, rm);
9742
tcg_gen_add_i32(addr, addr, tmp);
9743
tcg_temp_free_i32(tmp);
9745
if (op < 3) { /* store */
9746
tmp = load_reg(s, rd);
9748
tmp = tcg_temp_new_i32();
9753
gen_aa32_st32(tmp, addr, IS_USER(s));
9756
gen_aa32_st16(tmp, addr, IS_USER(s));
9759
gen_aa32_st8(tmp, addr, IS_USER(s));
9762
gen_aa32_ld8s(tmp, addr, IS_USER(s));
9765
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9768
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9771
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9774
gen_aa32_ld16s(tmp, addr, IS_USER(s));
9777
if (op >= 3) { /* load */
9778
store_reg(s, rd, tmp);
9780
tcg_temp_free_i32(tmp);
9782
tcg_temp_free_i32(addr);
9786
/* load/store word immediate offset */
9788
rn = (insn >> 3) & 7;
9789
addr = load_reg(s, rn);
9790
val = (insn >> 4) & 0x7c;
9791
tcg_gen_addi_i32(addr, addr, val);
9793
if (insn & (1 << 11)) {
9795
tmp = tcg_temp_new_i32();
9796
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9797
store_reg(s, rd, tmp);
9800
tmp = load_reg(s, rd);
9801
gen_aa32_st32(tmp, addr, IS_USER(s));
9802
tcg_temp_free_i32(tmp);
9804
tcg_temp_free_i32(addr);
9808
/* load/store byte immediate offset */
9810
rn = (insn >> 3) & 7;
9811
addr = load_reg(s, rn);
9812
val = (insn >> 6) & 0x1f;
9813
tcg_gen_addi_i32(addr, addr, val);
9815
if (insn & (1 << 11)) {
9817
tmp = tcg_temp_new_i32();
9818
gen_aa32_ld8u(tmp, addr, IS_USER(s));
9819
store_reg(s, rd, tmp);
9822
tmp = load_reg(s, rd);
9823
gen_aa32_st8(tmp, addr, IS_USER(s));
9824
tcg_temp_free_i32(tmp);
9826
tcg_temp_free_i32(addr);
9830
/* load/store halfword immediate offset */
9832
rn = (insn >> 3) & 7;
9833
addr = load_reg(s, rn);
9834
val = (insn >> 5) & 0x3e;
9835
tcg_gen_addi_i32(addr, addr, val);
9837
if (insn & (1 << 11)) {
9839
tmp = tcg_temp_new_i32();
9840
gen_aa32_ld16u(tmp, addr, IS_USER(s));
9841
store_reg(s, rd, tmp);
9844
tmp = load_reg(s, rd);
9845
gen_aa32_st16(tmp, addr, IS_USER(s));
9846
tcg_temp_free_i32(tmp);
9848
tcg_temp_free_i32(addr);
9852
/* load/store from stack */
9853
rd = (insn >> 8) & 7;
9854
addr = load_reg(s, 13);
9855
val = (insn & 0xff) * 4;
9856
tcg_gen_addi_i32(addr, addr, val);
9858
if (insn & (1 << 11)) {
9860
tmp = tcg_temp_new_i32();
9861
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9862
store_reg(s, rd, tmp);
9865
tmp = load_reg(s, rd);
9866
gen_aa32_st32(tmp, addr, IS_USER(s));
9867
tcg_temp_free_i32(tmp);
9869
tcg_temp_free_i32(addr);
9873
/* add to high reg */
9874
rd = (insn >> 8) & 7;
9875
if (insn & (1 << 11)) {
9877
tmp = load_reg(s, 13);
9879
/* PC. bit 1 is ignored. */
9880
tmp = tcg_temp_new_i32();
9881
tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9883
val = (insn & 0xff) * 4;
9884
tcg_gen_addi_i32(tmp, tmp, val);
9885
store_reg(s, rd, tmp);
9890
op = (insn >> 8) & 0xf;
9893
/* adjust stack pointer */
9894
tmp = load_reg(s, 13);
9895
val = (insn & 0x7f) * 4;
9896
if (insn & (1 << 7))
9897
val = -(int32_t)val;
9898
tcg_gen_addi_i32(tmp, tmp, val);
9899
store_reg(s, 13, tmp);
9902
case 2: /* sign/zero extend. */
9905
rm = (insn >> 3) & 7;
9906
tmp = load_reg(s, rm);
9907
switch ((insn >> 6) & 3) {
9908
case 0: gen_sxth(tmp); break;
9909
case 1: gen_sxtb(tmp); break;
9910
case 2: gen_uxth(tmp); break;
9911
case 3: gen_uxtb(tmp); break;
9913
store_reg(s, rd, tmp);
9915
case 4: case 5: case 0xc: case 0xd:
9917
addr = load_reg(s, 13);
9918
if (insn & (1 << 8))
9922
for (i = 0; i < 8; i++) {
9923
if (insn & (1 << i))
9926
if ((insn & (1 << 11)) == 0) {
9927
tcg_gen_addi_i32(addr, addr, -offset);
9929
for (i = 0; i < 8; i++) {
9930
if (insn & (1 << i)) {
9931
if (insn & (1 << 11)) {
9933
tmp = tcg_temp_new_i32();
9934
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9935
store_reg(s, i, tmp);
9938
tmp = load_reg(s, i);
9939
gen_aa32_st32(tmp, addr, IS_USER(s));
9940
tcg_temp_free_i32(tmp);
9942
/* advance to the next address. */
9943
tcg_gen_addi_i32(addr, addr, 4);
9946
TCGV_UNUSED_I32(tmp);
9947
if (insn & (1 << 8)) {
9948
if (insn & (1 << 11)) {
9950
tmp = tcg_temp_new_i32();
9951
gen_aa32_ld32u(tmp, addr, IS_USER(s));
9952
/* don't set the pc until the rest of the instruction
9956
tmp = load_reg(s, 14);
9957
gen_aa32_st32(tmp, addr, IS_USER(s));
9958
tcg_temp_free_i32(tmp);
9960
tcg_gen_addi_i32(addr, addr, 4);
9962
if ((insn & (1 << 11)) == 0) {
9963
tcg_gen_addi_i32(addr, addr, -offset);
9965
/* write back the new stack pointer */
9966
store_reg(s, 13, addr);
9967
/* set the new PC value */
9968
if ((insn & 0x0900) == 0x0900) {
9969
store_reg_from_load(env, s, 15, tmp);
9973
case 1: case 3: case 9: case 11: /* czb */
9975
tmp = load_reg(s, rm);
9976
s->condlabel = gen_new_label();
9978
if (insn & (1 << 11))
9979
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9981
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9982
tcg_temp_free_i32(tmp);
9983
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9984
val = (uint32_t)s->pc + 2;
9989
case 15: /* IT, nop-hint. */
9990
if ((insn & 0xf) == 0) {
9991
gen_nop_hint(s, (insn >> 4) & 0xf);
9995
s->condexec_cond = (insn >> 4) & 0xe;
9996
s->condexec_mask = insn & 0x1f;
9997
/* No actual code generated for this insn, just setup state. */
10000
case 0xe: /* bkpt */
10002
gen_exception_insn(s, 2, EXCP_BKPT);
10005
case 0xa: /* rev */
10007
rn = (insn >> 3) & 0x7;
10009
tmp = load_reg(s, rn);
10010
switch ((insn >> 6) & 3) {
10011
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10012
case 1: gen_rev16(tmp); break;
10013
case 3: gen_revsh(tmp); break;
10014
default: goto illegal_op;
10016
store_reg(s, rd, tmp);
10020
switch ((insn >> 5) & 7) {
10024
if (((insn >> 3) & 1) != s->bswap_code) {
10025
/* Dynamic endianness switching not implemented. */
10026
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10037
tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10040
addr = tcg_const_i32(19);
10041
gen_helper_v7m_msr(cpu_env, addr, tmp);
10042
tcg_temp_free_i32(addr);
10046
addr = tcg_const_i32(16);
10047
gen_helper_v7m_msr(cpu_env, addr, tmp);
10048
tcg_temp_free_i32(addr);
10050
tcg_temp_free_i32(tmp);
10053
if (insn & (1 << 4)) {
10054
shift = CPSR_A | CPSR_I | CPSR_F;
10058
gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10073
/* load/store multiple */
10074
TCGv_i32 loaded_var;
10075
TCGV_UNUSED_I32(loaded_var);
10076
rn = (insn >> 8) & 0x7;
10077
addr = load_reg(s, rn);
10078
for (i = 0; i < 8; i++) {
10079
if (insn & (1 << i)) {
10080
if (insn & (1 << 11)) {
10082
tmp = tcg_temp_new_i32();
10083
gen_aa32_ld32u(tmp, addr, IS_USER(s));
10087
store_reg(s, i, tmp);
10091
tmp = load_reg(s, i);
10092
gen_aa32_st32(tmp, addr, IS_USER(s));
10093
tcg_temp_free_i32(tmp);
10095
/* advance to the next address */
10096
tcg_gen_addi_i32(addr, addr, 4);
10099
if ((insn & (1 << rn)) == 0) {
10100
/* base reg not in list: base register writeback */
10101
store_reg(s, rn, addr);
10103
/* base reg in list: if load, complete it now */
10104
if (insn & (1 << 11)) {
10105
store_reg(s, rn, loaded_var);
10107
tcg_temp_free_i32(addr);
10112
/* conditional branch or swi */
10113
cond = (insn >> 8) & 0xf;
10119
gen_set_pc_im(s, s->pc);
10120
s->is_jmp = DISAS_SWI;
10123
/* generate a conditional jump to next instruction */
10124
s->condlabel = gen_new_label();
10125
gen_test_cc(cond ^ 1, s->condlabel);
10128
/* jump to the offset */
10129
val = (uint32_t)s->pc + 2;
10130
offset = ((int32_t)insn << 24) >> 24;
10131
val += offset << 1;
10136
if (insn & (1 << 11)) {
10137
if (disas_thumb2_insn(env, s, insn))
10141
/* unconditional branch */
10142
val = (uint32_t)s->pc;
10143
offset = ((int32_t)insn << 21) >> 21;
10144
val += (offset << 1) + 2;
10149
if (disas_thumb2_insn(env, s, insn))
10155
gen_exception_insn(s, 4, EXCP_UDEF);
10159
gen_exception_insn(s, 2, EXCP_UDEF);
10162
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10163
basic block 'tb'. If search_pc is TRUE, also generate PC
10164
information for each intermediate instruction. */
10165
static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10166
TranslationBlock *tb,
10169
CPUState *cs = CPU(cpu);
10170
CPUARMState *env = &cpu->env;
10171
DisasContext dc1, *dc = &dc1;
10173
uint16_t *gen_opc_end;
10175
target_ulong pc_start;
10176
target_ulong next_page_start;
10180
/* generate intermediate code */
10185
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10187
dc->is_jmp = DISAS_NEXT;
10189
dc->singlestep_enabled = cs->singlestep_enabled;
10192
if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10195
dc->bswap_code = 0;
10196
dc->condexec_mask = 0;
10197
dc->condexec_cond = 0;
10198
#if !defined(CONFIG_USER_ONLY)
10201
dc->vfp_enabled = 0;
10203
dc->vec_stride = 0;
10206
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10207
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10208
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10209
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10210
#if !defined(CONFIG_USER_ONLY)
10211
dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10213
dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10214
dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10215
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10217
cpu_F0s = tcg_temp_new_i32();
10218
cpu_F1s = tcg_temp_new_i32();
10219
cpu_F0d = tcg_temp_new_i64();
10220
cpu_F1d = tcg_temp_new_i64();
10223
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10224
cpu_M0 = tcg_temp_new_i64();
10225
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10228
max_insns = tb->cflags & CF_COUNT_MASK;
10229
if (max_insns == 0)
10230
max_insns = CF_COUNT_MASK;
10234
tcg_clear_temp_count();
10236
/* A note on handling of the condexec (IT) bits:
10238
* We want to avoid the overhead of having to write the updated condexec
10239
* bits back to the CPUARMState for every instruction in an IT block. So:
10240
* (1) if the condexec bits are not already zero then we write
10241
* zero back into the CPUARMState now. This avoids complications trying
10242
* to do it at the end of the block. (For example if we don't do this
10243
* it's hard to identify whether we can safely skip writing condexec
10244
* at the end of the TB, which we definitely want to do for the case
10245
* where a TB doesn't do anything with the IT state at all.)
10246
* (2) if we are going to leave the TB then we call gen_set_condexec()
10247
* which will write the correct value into CPUARMState if zero is wrong.
10248
* This is done both for leaving the TB at the end, and for leaving
10249
* it because of an exception we know will happen, which is done in
10250
* gen_exception_insn(). The latter is necessary because we need to
10251
* leave the TB with the PC/IT state just prior to execution of the
10252
* instruction which caused the exception.
10253
* (3) if we leave the TB unexpectedly (eg a data abort on a load)
10254
* then the CPUARMState will be wrong and we need to reset it.
10255
* This is handled in the same way as restoration of the
10256
* PC in these situations: we will be called again with search_pc=1
10257
* and generate a mapping of the condexec bits for each PC in
10258
* gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10259
* this to restore the condexec bits.
10261
* Note that there are no instructions which can read the condexec
10262
* bits, and none which can write non-static values to them, so
10263
* we don't need to care about whether CPUARMState is correct in the
10267
/* Reset the conditional execution bits immediately. This avoids
10268
complications trying to do it at the end of the block. */
10269
if (dc->condexec_mask || dc->condexec_cond)
10271
TCGv_i32 tmp = tcg_temp_new_i32();
10272
tcg_gen_movi_i32(tmp, 0);
10273
store_cpu_field(tmp, condexec_bits);
10276
#ifdef CONFIG_USER_ONLY
10277
/* Intercept jump to the magic kernel page. */
10278
if (!dc->aarch64 && dc->pc >= 0xffff0000) {
10279
/* We always get here via a jump, so know we are not in a
10280
conditional execution block. */
10281
gen_exception(EXCP_KERNEL_TRAP);
10282
dc->is_jmp = DISAS_UPDATE;
10286
if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10287
/* We always get here via a jump, so know we are not in a
10288
conditional execution block. */
10289
gen_exception(EXCP_EXCEPTION_EXIT);
10290
dc->is_jmp = DISAS_UPDATE;
10295
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10296
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10297
if (bp->pc == dc->pc) {
10298
gen_exception_insn(dc, 0, EXCP_DEBUG);
10299
/* Advance PC so that clearing the breakpoint will
10300
invalidate this TB. */
10302
goto done_generating;
10307
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10311
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10313
tcg_ctx.gen_opc_pc[lj] = dc->pc;
10314
gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10315
tcg_ctx.gen_opc_instr_start[lj] = 1;
10316
tcg_ctx.gen_opc_icount[lj] = num_insns;
10319
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10322
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10323
tcg_gen_debug_insn_start(dc->pc);
10327
disas_a64_insn(env, dc);
10328
} else if (dc->thumb) {
10329
disas_thumb_insn(env, dc);
10330
if (dc->condexec_mask) {
10331
dc->condexec_cond = (dc->condexec_cond & 0xe)
10332
| ((dc->condexec_mask >> 4) & 1);
10333
dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10334
if (dc->condexec_mask == 0) {
10335
dc->condexec_cond = 0;
10339
disas_arm_insn(env, dc);
10342
if (dc->condjmp && !dc->is_jmp) {
10343
gen_set_label(dc->condlabel);
10347
if (tcg_check_temp_count()) {
10348
fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10352
/* Translation stops when a conditional branch is encountered.
10353
* Otherwise the subsequent code could get translated several times.
10354
* Also stop translation when a page boundary is reached. This
10355
* ensures prefetch aborts occur at the right place. */
10357
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10358
!cs->singlestep_enabled &&
10360
dc->pc < next_page_start &&
10361
num_insns < max_insns);
10363
if (tb->cflags & CF_LAST_IO) {
10365
/* FIXME: This can theoretically happen with self-modifying
10367
cpu_abort(env, "IO on conditional branch instruction");
10372
/* At this stage dc->condjmp will only be set when the skipped
10373
instruction was a conditional branch or trap, and the PC has
10374
already been written. */
10375
if (unlikely(cs->singlestep_enabled)) {
10376
/* Make sure the pc is updated, and raise a debug exception. */
10378
gen_set_condexec(dc);
10379
if (dc->is_jmp == DISAS_SWI) {
10380
gen_exception(EXCP_SWI);
10381
} else if (dc->is_jmp == DISAS_SMC) {
10382
gen_exception(EXCP_SMC);
10384
gen_exception(EXCP_DEBUG);
10386
gen_set_label(dc->condlabel);
10388
if (dc->condjmp || !dc->is_jmp) {
10389
gen_set_pc_im(dc, dc->pc);
10392
gen_set_condexec(dc);
10393
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10394
gen_exception(EXCP_SWI);
10395
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
10396
gen_exception(EXCP_SMC);
10398
/* FIXME: Single stepping a WFI insn will not halt
10400
gen_exception(EXCP_DEBUG);
10403
/* While branches must always occur at the end of an IT block,
10404
there are a few other things that can cause us to terminate
10405
the TB in the middle of an IT block:
10406
- Exception generating instructions (bkpt, swi, undefined).
10408
- Hardware watchpoints.
10409
Hardware breakpoints have already been handled and skip this code.
10411
gen_set_condexec(dc);
10412
switch(dc->is_jmp) {
10414
gen_goto_tb(dc, 1, dc->pc);
10419
/* indicate that the hash table must be used to find the next TB */
10420
tcg_gen_exit_tb(0);
10422
case DISAS_TB_JUMP:
10423
/* nothing more to generate */
10426
gen_helper_wfi(cpu_env);
10429
gen_exception(EXCP_SWI);
10432
gen_exception(EXCP_SMC);
10436
gen_set_label(dc->condlabel);
10437
gen_set_condexec(dc);
10438
gen_goto_tb(dc, 1, dc->pc);
10444
gen_tb_end(tb, num_insns);
10445
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
10448
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10449
qemu_log("----------------\n");
10450
qemu_log("IN: %s\n", lookup_symbol(pc_start));
10451
log_target_disas(env, pc_start, dc->pc - pc_start,
10452
dc->thumb | (dc->bswap_code << 1));
10457
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10460
tcg_ctx.gen_opc_instr_start[lj++] = 0;
10462
tb->size = dc->pc - pc_start;
10463
tb->icount = num_insns;
10467
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10469
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10472
void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10474
gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10477
static const char *cpu_mode_names[16] = {
10478
"usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10479
"???", "???", "???", "und", "???", "???", "???", "sys"
10482
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10485
ARMCPU *cpu = ARM_CPU(cs);
10486
CPUARMState *env = &cpu->env;
10490
for(i=0;i<16;i++) {
10491
cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10493
cpu_fprintf(f, "\n");
10495
cpu_fprintf(f, " ");
10497
psr = cpsr_read(env);
10498
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10500
psr & (1 << 31) ? 'N' : '-',
10501
psr & (1 << 30) ? 'Z' : '-',
10502
psr & (1 << 29) ? 'C' : '-',
10503
psr & (1 << 28) ? 'V' : '-',
10504
psr & CPSR_T ? 'T' : 'A',
10505
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10507
if (flags & CPU_DUMP_FPU) {
10508
int numvfpregs = 0;
10509
if (arm_feature(env, ARM_FEATURE_VFP)) {
10512
if (arm_feature(env, ARM_FEATURE_VFP3)) {
10515
for (i = 0; i < numvfpregs; i++) {
10516
uint64_t v = float64_val(env->vfp.regs[i]);
10517
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10518
i * 2, (uint32_t)v,
10519
i * 2 + 1, (uint32_t)(v >> 32),
10522
cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10526
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10529
env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10531
env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10533
env->condexec_bits = gen_opc_condexec_bits[pc_pos];